Re: [PATCH v6 1/7] drm: atmel-hlcdc: add flag and driver ops to differentiate XLCDC and HLCDC IP

2023-10-04 Thread Manikandan.M
On 03/10/23 5:46 pm, claudiu beznea wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the 
> content is safe
> 
> On 03.10.2023 07:18, manikanda...@microchip.com wrote:
>> On 28/09/23 11:31 am, claudiu beznea wrote:
>>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the 
>>> content is safe
>>>
>>> Hi, Manikandan,
>>>
>>> On 27.09.2023 12:47, Manikandan Muralidharan wrote:
 +void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
 + struct atmel_hlcdc_plane_state *state);
 +void atmel_xlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
 + struct atmel_hlcdc_plane_state *state);
 +void update_hlcdc_buffers(struct atmel_hlcdc_plane *plane,
 +   struct atmel_hlcdc_plane_state *state,
 +   u32 sr, int i);
 +void update_xlcdc_buffers(struct atmel_hlcdc_plane *plane,
 +   struct atmel_hlcdc_plane_state *state,
 +   u32 sr, int i);
 +void hlcdc_atomic_disable(struct atmel_hlcdc_plane *plane);
 +void xlcdc_atomic_disable(struct atmel_hlcdc_plane *plane);
 +void
 +atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
 +   struct atmel_hlcdc_plane_state 
 *state);
 +void
 +atmel_xlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
 +   struct atmel_hlcdc_plane_state 
 *state);
 +void hlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
 +  struct atmel_hlcdc_dc *dc);
 +void xlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
 +  struct atmel_hlcdc_dc *dc);
 +void hlcdc_csc_init(struct atmel_hlcdc_plane *plane,
 + const struct atmel_hlcdc_layer_desc *desc);
 +void xlcdc_csc_init(struct atmel_hlcdc_plane *plane,
 + const struct atmel_hlcdc_layer_desc *desc);
 +void hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
 +const struct atmel_hlcdc_layer_desc *desc);
 +void xlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
 +const struct atmel_hlcdc_layer_desc *desc);
 +
>>>
>>> These are still here... Isn't the solution I proposed to you in the
>>> previous version good enough?
>> Hi Claudiu
>>
>> These changes were integrated in the current patch set based on the
>> solution which you proposed in the previous series.
>> The XLCDC and HLCDC functions calls are moved to IP specific driver->ops
>> and their function declarations are made here in atmel_hlcdc_dc.h
>> Rest of the changes are integrated in Patch 4/7.
> 
> I still think (and I've checked it last time) you can remove these
> declaration. See comment from previous version:
> 
> "You can get rid of these and keep the function definitions static to
> atmel_hlcdc_plane.c if you define struct atmel_lcdc_dc_ops objects directly
> to atmel_hlcdc_plane.c. In atmel_hlcdc_dc.c you can have something like:
> 
> extern const struct atmel_lcdc_dc_ops  atmel_hlcdc_ops;
> extern const struct atmel_lcdc_dc_ops  atmel_xlcdc_ops;
> "
Hi Claudiu

Thank you. I will integrate the changes in the next version.
> 
>>>
>>> Thank you,
>>> Claudiu Beznea
>>

-- 
Thanks and Regards,
Manikandan M.



[Bug 213917] Screen starts flickering when laptop(amdgpu) wakes up after suspend.

2023-10-04 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=213917

ker...@mail.niknah.com changed:

   What|Removed |Added

 CC||ker...@mail.niknah.com

--- Comment #3 from ker...@mail.niknah.com ---
When I change the resolution or come back from suspend it flickers with random
dots.  https://youtu.be/9hXqSQjU080

It works again when I either switch the mode back to the old resolution or
press ctrl-alt-f8 & alt-f2

It's only a problem on the laptop eDP display, external usb-c display is ok.

In kernel 6.5.5, it goes away when I press ctrl-alt-f8 & alt-f2 or when I
switch the mode back.

In kernel 6.5.1, I couldn't fix it with ctrl-alt-f8 & alt-f2, it only goes away
when I switch back to the previous mode.

AMD Ryzen 7 4800U with Radeon Graphics

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

Re: [PATCH v4 02/10] drm/sched: Convert drm scheduler to use a work queue rather than kthread

2023-10-04 Thread Luben Tuikov
On 2023-10-04 23:33, Matthew Brost wrote:
> On Tue, Sep 26, 2023 at 11:32:10PM -0400, Luben Tuikov wrote:
>> Hi,
>>
>> On 2023-09-19 01:01, Matthew Brost wrote:
>>> In XE, the new Intel GPU driver, a choice has made to have a 1 to 1
>>> mapping between a drm_gpu_scheduler and drm_sched_entity. At first this
>>> seems a bit odd but let us explain the reasoning below.
>>>
>>> 1. In XE the submission order from multiple drm_sched_entity is not
>>> guaranteed to be the same completion even if targeting the same hardware
>>> engine. This is because in XE we have a firmware scheduler, the GuC,
>>> which allowed to reorder, timeslice, and preempt submissions. If a using
>>> shared drm_gpu_scheduler across multiple drm_sched_entity, the TDR falls
>>> apart as the TDR expects submission order == completion order. Using a
>>> dedicated drm_gpu_scheduler per drm_sched_entity solve this problem.
>>>
>>> 2. In XE submissions are done via programming a ring buffer (circular
>>> buffer), a drm_gpu_scheduler provides a limit on number of jobs, if the
>>> limit of number jobs is set to RING_SIZE / MAX_SIZE_PER_JOB we get flow
>>> control on the ring for free.
>>>
>>> A problem with this design is currently a drm_gpu_scheduler uses a
>>> kthread for submission / job cleanup. This doesn't scale if a large
>>> number of drm_gpu_scheduler are used. To work around the scaling issue,
>>> use a worker rather than kthread for submission / job cleanup.
>>>
>>> v2:
>>>   - (Rob Clark) Fix msm build
>>>   - Pass in run work queue
>>> v3:
>>>   - (Boris) don't have loop in worker
>>> v4:
>>>   - (Tvrtko) break out submit ready, stop, start helpers into own patch
>>> v5:
>>>   - (Boris) default to ordered work queue
>>>
>>> Signed-off-by: Matthew Brost 
>>> ---
>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |   2 +-
>>>  drivers/gpu/drm/etnaviv/etnaviv_sched.c|   2 +-
>>>  drivers/gpu/drm/lima/lima_sched.c  |   2 +-
>>>  drivers/gpu/drm/msm/msm_ringbuffer.c   |   2 +-
>>>  drivers/gpu/drm/nouveau/nouveau_sched.c|   2 +-
>>>  drivers/gpu/drm/panfrost/panfrost_job.c|   2 +-
>>>  drivers/gpu/drm/scheduler/sched_main.c | 118 ++---
>>>  drivers/gpu/drm/v3d/v3d_sched.c|  10 +-
>>>  include/drm/gpu_scheduler.h|  14 ++-
>>>  9 files changed, 79 insertions(+), 75 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>>> index e366f61c3aed..16f3cfe1574a 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>>> @@ -2279,7 +2279,7 @@ static int amdgpu_device_init_schedulers(struct 
>>> amdgpu_device *adev)
>>> break;
>>> }
>>>  
>>> -   r = drm_sched_init(&ring->sched, &amdgpu_sched_ops,
>>> +   r = drm_sched_init(&ring->sched, &amdgpu_sched_ops, NULL,
>>>ring->num_hw_submission, 0,
>>>timeout, adev->reset_domain->wq,
>>>ring->sched_score, ring->name,
>>> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c 
>>> b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
>>> index 345fec6cb1a4..618a804ddc34 100644
>>> --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
>>> +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
>>> @@ -134,7 +134,7 @@ int etnaviv_sched_init(struct etnaviv_gpu *gpu)
>>>  {
>>> int ret;
>>>  
>>> -   ret = drm_sched_init(&gpu->sched, &etnaviv_sched_ops,
>>> +   ret = drm_sched_init(&gpu->sched, &etnaviv_sched_ops, NULL,
>>>  etnaviv_hw_jobs_limit, etnaviv_job_hang_limit,
>>>  msecs_to_jiffies(500), NULL, NULL,
>>>  dev_name(gpu->dev), gpu->dev);
>>> diff --git a/drivers/gpu/drm/lima/lima_sched.c 
>>> b/drivers/gpu/drm/lima/lima_sched.c
>>> index ffd91a5ee299..8d858aed0e56 100644
>>> --- a/drivers/gpu/drm/lima/lima_sched.c
>>> +++ b/drivers/gpu/drm/lima/lima_sched.c
>>> @@ -488,7 +488,7 @@ int lima_sched_pipe_init(struct lima_sched_pipe *pipe, 
>>> const char *name)
>>>  
>>> INIT_WORK(&pipe->recover_work, lima_sched_recover_work);
>>>  
>>> -   return drm_sched_init(&pipe->base, &lima_sched_ops, 1,
>>> +   return drm_sched_init(&pipe->base, &lima_sched_ops, NULL, 1,
>>>   lima_job_hang_limit,
>>>   msecs_to_jiffies(timeout), NULL,
>>>   NULL, name, pipe->ldev->dev);
>>> diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c 
>>> b/drivers/gpu/drm/msm/msm_ringbuffer.c
>>> index 40c0bc35a44c..b8865e61b40f 100644
>>> --- a/drivers/gpu/drm/msm/msm_ringbuffer.c
>>> +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c
>>> @@ -94,7 +94,7 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu 
>>> *gpu, int id,
>>>  /* currently managing hangcheck ourselves: */
>>> sched_timeout = MAX_SCHEDULE_TIMEOUT;
>>>  
>>> -   ret = drm_sched_init(&ring->sched, &msm_sched_ops,
>

Re: [PATCH v4 08/10] drm/sched: Submit job before starting TDR

2023-10-04 Thread Matthew Brost
On Fri, Sep 29, 2023 at 05:58:46PM -0400, Luben Tuikov wrote:
> Hi,
> 
> On 2023-09-19 01:01, Matthew Brost wrote:
> > If the TDR is set to a value, it can fire before a job is submitted in
> > drm_sched_main. The job should be always be submitted before the TDR
> > fires, fix this ordering.
> > 
> > v2:
> >   - Add to pending list before run_job, start TDR after (Luben, Boris)
> > 
> > Signed-off-by: Matthew Brost 
> > ---
> >  drivers/gpu/drm/scheduler/sched_main.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
> > b/drivers/gpu/drm/scheduler/sched_main.c
> > index a5cc9b6c2faa..e8a3e6033f66 100644
> > --- a/drivers/gpu/drm/scheduler/sched_main.c
> > +++ b/drivers/gpu/drm/scheduler/sched_main.c
> > @@ -517,7 +517,6 @@ static void drm_sched_job_begin(struct drm_sched_job 
> > *s_job)
> >  
> > spin_lock(&sched->job_list_lock);
> > list_add_tail(&s_job->list, &sched->pending_list);
> > -   drm_sched_start_timeout(sched);
> > spin_unlock(&sched->job_list_lock);
> >  }
> >  
> > @@ -1138,6 +1137,7 @@ static void drm_sched_run_job_work(struct work_struct 
> > *w)
> > fence = sched->ops->run_job(sched_job);
> > complete_all(&entity->entity_idle);
> > drm_sched_fence_scheduled(s_fence, fence);
> > +   drm_sched_start_timeout_unlocked(sched);
> >  
> > if (!IS_ERR_OR_NULL(fence)) {
> > /* Drop for original kref_init of the fence */
> 
> No.
> 
> See Message-ID: ,
> and Message-ID: <8e5eab14-9e55-42c9-b6ea-02fcc5912...@amd.com>,
> and Message-ID: <24bc965f-61fb-4b92-9afa-360ca85a5...@amd.com>.

See reply to previous patch, will drop this.

Matt

> -- 
> Regards,
> Luben
> 


Re: [PATCH v4 05/10] drm/sched: Split free_job into own work item

2023-10-04 Thread Matthew Brost
On Thu, Sep 28, 2023 at 12:14:12PM -0400, Luben Tuikov wrote:
> On 2023-09-19 01:01, Matthew Brost wrote:
> > Rather than call free_job and run_job in same work item have a dedicated
> > work item for each. This aligns with the design and intended use of work
> > queues.
> > 
> > v2:
> >- Test for DMA_FENCE_FLAG_TIMESTAMP_BIT before setting
> >  timestamp in free_job() work item (Danilo)
> > v3:
> >   - Drop forward dec of drm_sched_select_entity (Boris)
> >   - Return in drm_sched_run_job_work if entity NULL (Boris)
> > 
> > Signed-off-by: Matthew Brost 
> > ---
> >  drivers/gpu/drm/scheduler/sched_main.c | 290 +++--
> >  include/drm/gpu_scheduler.h|   8 +-
> >  2 files changed, 182 insertions(+), 116 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
> > b/drivers/gpu/drm/scheduler/sched_main.c
> > index 588c735f7498..1e21d234fb5c 100644
> > --- a/drivers/gpu/drm/scheduler/sched_main.c
> > +++ b/drivers/gpu/drm/scheduler/sched_main.c
> > @@ -213,11 +213,12 @@ void drm_sched_rq_remove_entity(struct drm_sched_rq 
> > *rq,
> >   * drm_sched_rq_select_entity_rr - Select an entity which could provide a 
> > job to run
> >   *
> >   * @rq: scheduler run queue to check.
> > + * @dequeue: dequeue selected entity
> 
> Change this to "peek" as indicated below.
> 
> >   *
> >   * Try to find a ready entity, returns NULL if none found.
> >   */
> >  static struct drm_sched_entity *
> > -drm_sched_rq_select_entity_rr(struct drm_sched_rq *rq)
> > +drm_sched_rq_select_entity_rr(struct drm_sched_rq *rq, bool dequeue)
> >  {
> > struct drm_sched_entity *entity;
> >  
> > @@ -227,8 +228,10 @@ drm_sched_rq_select_entity_rr(struct drm_sched_rq *rq)
> > if (entity) {
> > list_for_each_entry_continue(entity, &rq->entities, list) {
> > if (drm_sched_entity_is_ready(entity)) {
> > -   rq->current_entity = entity;
> > -   reinit_completion(&entity->entity_idle);
> > +   if (dequeue) {
> > +   rq->current_entity = entity;
> > +   reinit_completion(&entity->entity_idle);
> > +   }
> 
> Please rename "dequeue" or invert its logic, as from this patch it seems that
> it is hiding (gating out) current behaviour.
> 
> Ideally, I'd prefer it be inverted, so that current behaviour, i.e. what 
> people
> are used to the rq_select_entity_*() to do, is default--preserved.
> 
> Perhaps use "peek" as the name of this new variable, to indicate that
> we're not setting it to be the current entity.
> 
> I prefer "peek" to others, as the former tells me "Hey, I'm only
> peeking at the rq and not really doing the default behaviour I've been
> doing which you're used to." So, probably use "peek". ("Peek" also has 
> historical
> significance...).
> 

Peek it is. Will change.

> > spin_unlock(&rq->lock);
> > return entity;
> > }
> > @@ -238,8 +241,10 @@ drm_sched_rq_select_entity_rr(struct drm_sched_rq *rq)
> > list_for_each_entry(entity, &rq->entities, list) {
> >  
> > if (drm_sched_entity_is_ready(entity)) {
> > -   rq->current_entity = entity;
> > -   reinit_completion(&entity->entity_idle);
> > +   if (dequeue) {
> 
>   if (!peek) {
> 

+1

> > +   rq->current_entity = entity;
> > +   reinit_completion(&entity->entity_idle);
> > +   }
> > spin_unlock(&rq->lock);
> > return entity;
> > }
> > @@ -257,11 +262,12 @@ drm_sched_rq_select_entity_rr(struct drm_sched_rq *rq)
> >   * drm_sched_rq_select_entity_fifo - Select an entity which provides a job 
> > to run
> >   *
> >   * @rq: scheduler run queue to check.
> > + * @dequeue: dequeue selected entity
> 
> * @peek: Just find, don't set to current.
>

+1
 
> >   *
> >   * Find oldest waiting ready entity, returns NULL if none found.>   */
> >  static struct drm_sched_entity *
> > -drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq)
> > +drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq, bool dequeue)
> >  {
> > struct rb_node *rb;
> >  
> > @@ -271,8 +277,10 @@ drm_sched_rq_select_entity_fifo(struct drm_sched_rq 
> > *rq)
> >  
> > entity = rb_entry(rb, struct drm_sched_entity, rb_tree_node);
> > if (drm_sched_entity_is_ready(entity)) {
> > -   rq->current_entity = entity;
> > -   reinit_completion(&entity->entity_idle);
> > +   if (dequeue) {
> 
>   if (!peek) {
> 
> > +   rq->current_entity = entity;
> > +   reinit_completion(&entity->entity_idle);
> > +   }
> > break;
> >

Re: [PATCH v4 04/10] drm/sched: Add DRM_SCHED_POLICY_SINGLE_ENTITY scheduling policy

2023-10-04 Thread Matthew Brost
On Wed, Sep 27, 2023 at 10:36:49AM -0400, Luben Tuikov wrote:
> Hi,
> 
> On 2023-09-19 01:01, Matthew Brost wrote:
> > DRM_SCHED_POLICY_SINGLE_ENTITY creates a 1 to 1 relationship between
> > scheduler and entity. No priorities or run queue used in this mode.
> > Intended for devices with firmware schedulers.
> > 
> > v2:
> >   - Drop sched / rq union (Luben)
> > v3:
> >   - Don't pick entity if stopped in drm_sched_select_entity (Danilo)
> > 
> > Signed-off-by: Matthew Brost 
> > ---
> >  drivers/gpu/drm/scheduler/sched_entity.c | 69 ++--
> >  drivers/gpu/drm/scheduler/sched_fence.c  |  2 +-
> >  drivers/gpu/drm/scheduler/sched_main.c   | 64 +++---
> >  include/drm/gpu_scheduler.h  |  8 +++
> >  4 files changed, 120 insertions(+), 23 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/scheduler/sched_entity.c 
> > b/drivers/gpu/drm/scheduler/sched_entity.c
> > index cf42e2265d64..437c50867c99 100644
> > --- a/drivers/gpu/drm/scheduler/sched_entity.c
> > +++ b/drivers/gpu/drm/scheduler/sched_entity.c
> > @@ -83,6 +83,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
> > memset(entity, 0, sizeof(struct drm_sched_entity));
> > INIT_LIST_HEAD(&entity->list);
> > entity->rq = NULL;
> > +   entity->single_sched = NULL;
> > entity->guilty = guilty;
> > entity->num_sched_list = num_sched_list;
> > entity->priority = priority;
> > @@ -90,8 +91,17 @@ int drm_sched_entity_init(struct drm_sched_entity 
> > *entity,
> > RCU_INIT_POINTER(entity->last_scheduled, NULL);
> > RB_CLEAR_NODE(&entity->rb_tree_node);
> >  
> > -   if(num_sched_list)
> > -   entity->rq = &sched_list[0]->sched_rq[entity->priority];
> > +   if (num_sched_list) {
> > +   if (sched_list[0]->sched_policy !=
> > +   DRM_SCHED_POLICY_SINGLE_ENTITY) {
> > +   entity->rq = &sched_list[0]->sched_rq[entity->priority];
> > +   } else {
> > +   if (num_sched_list != 1 || sched_list[0]->single_entity)
> > +   return -EINVAL;
> > +   sched_list[0]->single_entity = entity;
> > +   entity->single_sched = sched_list[0];
> > +   }
> > +   }
> 
> So much (checking for) negativity...:-)
> Perhaps the simplified form below?
> 
>   if (num_sched_list) {
>   if (sched_list[0]->sched_policy !=
>   DRM_SCHED_POLICY_SINGLE_ENTITY) {
>   entity->rq = &sched_list[0]->sched_rq[entity->priority];
>   } else if (num_sched_list == 1 && 
> !sched_list[0]->single_entity) {
>   sched_list[0]->single_entity = entity;
>   entity->single_sched = sched_list[0];
>   } else {
>   return -EINVAL;
>   }
>   }
> 

Will change.

> >  
> > init_completion(&entity->entity_idle);
> >  
> > @@ -124,7 +134,8 @@ void drm_sched_entity_modify_sched(struct 
> > drm_sched_entity *entity,
> > struct drm_gpu_scheduler **sched_list,
> > unsigned int num_sched_list)
> >  {
> > -   WARN_ON(!num_sched_list || !sched_list);
> > +   WARN_ON(!num_sched_list || !sched_list ||
> > +   !!entity->single_sched);
> >  
> > entity->sched_list = sched_list;
> > entity->num_sched_list = num_sched_list;
> > @@ -231,13 +242,15 @@ static void drm_sched_entity_kill(struct 
> > drm_sched_entity *entity)
> >  {
> > struct drm_sched_job *job;
> > struct dma_fence *prev;
> > +   bool single_entity = !!entity->single_sched;
> >  
> > -   if (!entity->rq)
> > +   if (!entity->rq && !single_entity)
> > return;
> >  
> > spin_lock(&entity->rq_lock);
> > entity->stopped = true;
> > -   drm_sched_rq_remove_entity(entity->rq, entity);
> > +   if (!single_entity)
> > +   drm_sched_rq_remove_entity(entity->rq, entity);
> > spin_unlock(&entity->rq_lock);
> >  
> > /* Make sure this entity is not used by the scheduler at the moment */
> > @@ -259,6 +272,20 @@ static void drm_sched_entity_kill(struct 
> > drm_sched_entity *entity)
> > dma_fence_put(prev);
> >  }
> >  
> > +/**
> > + * drm_sched_entity_to_scheduler - Schedule entity to GPU scheduler
> 
> Please use verbs. Please?
> 
> Fix:
> /**
>  * drm_sched_entity_to_scheduler - Map a schedule entity to a GPU scheduler
> 
> > + * @entity: scheduler entity
> > + *
> > + * Returns GPU scheduler for the entity
> 
> Fix:
> * Given an entity, return its GPU scheduler.
>

Yep.
 
> > + */
> > +struct drm_gpu_scheduler *
> > +drm_sched_entity_to_scheduler(struct drm_sched_entity *entity)
> > +{
> > +   bool single_entity = !!entity->single_sched;
> > +
> > +   return single_entity ? entity->single_sched : entity->rq->sched;
> > +}
> > +
> >  /**
> >   * drm_sched_entity_flush - Flush a context entity
> >   *
> > @@ -276,11 +303,12 @@ long drm_sched_entity_flush(struct drm_sched_entity 
> > *en

linux-next: build warning after merge of the drm-misc-fixes tree

2023-10-04 Thread Stephen Rothwell
Hi all,

After merging the drm-misc-fixes tree, today's linux-next build (htmldocs)
produced this warning:

include/uapi/drm/nouveau_drm.h:49: warning: Cannot understand  * 
@NOUVEAU_GETPARAM_EXEC_PUSH_MAX
 on line 49 - I thought it was a doc line

Introduced by commit

  d59e75eef52d ("drm/nouveau: exec: report max pushs through getparam")

-- 
Cheers,
Stephen Rothwell


pgpSYsaJ3l_S2.pgp
Description: OpenPGP digital signature


linux-next: build warning after merge of the drm-misc tree

2023-10-04 Thread Stephen Rothwell
Hi all,

After merging the drm-misc tree, today's linux-next build (htmldocs)
produced this warning:

Documentation/gpu/panfrost.rst: WARNING: document isn't included in any toctree

Introduced by commit

  f11b0417eec2 ("drm/panfrost: Add fdinfo support GPU load metrics")

-- 
Cheers,
Stephen Rothwell


pgp_FiWLwkaWF.pgp
Description: OpenPGP digital signature


[pull] amdgpu drm-fixes-6.6

2023-10-04 Thread Alex Deucher
Hi Dave, Daniel,

Fixes for 6.6.

The following changes since commit 8a749fd1a8720d4619c91c8b6e7528c0a355c0aa:

  Linux 6.6-rc4 (2023-10-01 14:15:13 -0700)

are available in the Git repository at:

  https://gitlab.freedesktop.org/agd5f/linux.git 
tags/amd-drm-fixes-6.6-2023-10-04

for you to fetch changes up to b206011bf05069797df1f4c5ce639398728978e2:

  drm/amd/display: apply edge-case DISPCLK WDIVIDER changes to master OTG pipes 
only (2023-10-04 22:55:05 -0400)


amd-drm-fixes-6.6-2023-10-04:

amdgpu:
- Add missing unique_id for GC 11.0.3
- Fix memory leak in FRU error path
- Fix PCIe link reporting on some SMU 11 parts
- Fix ACPI _PR3 detection
- Fix DISPCLK WDIVIDER handling in OTG code


Kenneth Feng (1):
  drm/amd/pm: add unique_id for gc 11.0.3

Luben Tuikov (1):
  drm/amdgpu: Fix a memory leak

Mario Limonciello (2):
  drm/amd: Fix logic error in sienna_cichlid_update_pcie_parameters()
  drm/amd: Fix detection of _PR3 on the PCIe root port

Samson Tam (1):
  drm/amd/display: apply edge-case DISPCLK WDIVIDER changes to master OTG 
pipes only

 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c |  1 +
 .../amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c   |  4 +--
 .../amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c   |  4 +--
 drivers/gpu/drm/amd/pm/amdgpu_pm.c |  1 +
 .../drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c| 41 --
 6 files changed, 30 insertions(+), 23 deletions(-)


Re: [PATCH v4 2/4] drm/panic: Add a drm panic handler

2023-10-04 Thread kernel test robot
Hi Jocelyn,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 2dde18cd1d8fac735875f2e4987f11817cc0bc2c]

url:
https://github.com/intel-lab-lkp/linux/commits/Jocelyn-Falempe/drm-format-helper-Export-line-conversion-helper-for-drm_panic/20231003-222642
base:   2dde18cd1d8fac735875f2e4987f11817cc0bc2c
patch link:
https://lore.kernel.org/r/20231003142508.190246-3-jfalempe%40redhat.com
patch subject: [PATCH v4 2/4] drm/panic: Add a drm panic handler
config: i386-randconfig-063-20231005 
(https://download.01.org/0day-ci/archive/20231005/202310051128.nptc5nyw-...@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20231005/202310051128.nptc5nyw-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202310051128.nptc5nyw-...@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/gpu/drm/drm_panic.c:339:23: sparse: sparse: symbol 
>> 'drm_panic_notifier' was not declared. Should it be static?

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


Re: [PATCH v4 02/10] drm/sched: Convert drm scheduler to use a work queue rather than kthread

2023-10-04 Thread Matthew Brost
On Tue, Sep 26, 2023 at 11:32:10PM -0400, Luben Tuikov wrote:
> Hi,
> 
> On 2023-09-19 01:01, Matthew Brost wrote:
> > In XE, the new Intel GPU driver, a choice has made to have a 1 to 1
> > mapping between a drm_gpu_scheduler and drm_sched_entity. At first this
> > seems a bit odd but let us explain the reasoning below.
> > 
> > 1. In XE the submission order from multiple drm_sched_entity is not
> > guaranteed to be the same completion even if targeting the same hardware
> > engine. This is because in XE we have a firmware scheduler, the GuC,
> > which allowed to reorder, timeslice, and preempt submissions. If a using
> > shared drm_gpu_scheduler across multiple drm_sched_entity, the TDR falls
> > apart as the TDR expects submission order == completion order. Using a
> > dedicated drm_gpu_scheduler per drm_sched_entity solve this problem.
> > 
> > 2. In XE submissions are done via programming a ring buffer (circular
> > buffer), a drm_gpu_scheduler provides a limit on number of jobs, if the
> > limit of number jobs is set to RING_SIZE / MAX_SIZE_PER_JOB we get flow
> > control on the ring for free.
> > 
> > A problem with this design is currently a drm_gpu_scheduler uses a
> > kthread for submission / job cleanup. This doesn't scale if a large
> > number of drm_gpu_scheduler are used. To work around the scaling issue,
> > use a worker rather than kthread for submission / job cleanup.
> > 
> > v2:
> >   - (Rob Clark) Fix msm build
> >   - Pass in run work queue
> > v3:
> >   - (Boris) don't have loop in worker
> > v4:
> >   - (Tvrtko) break out submit ready, stop, start helpers into own patch
> > v5:
> >   - (Boris) default to ordered work queue
> > 
> > Signed-off-by: Matthew Brost 
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |   2 +-
> >  drivers/gpu/drm/etnaviv/etnaviv_sched.c|   2 +-
> >  drivers/gpu/drm/lima/lima_sched.c  |   2 +-
> >  drivers/gpu/drm/msm/msm_ringbuffer.c   |   2 +-
> >  drivers/gpu/drm/nouveau/nouveau_sched.c|   2 +-
> >  drivers/gpu/drm/panfrost/panfrost_job.c|   2 +-
> >  drivers/gpu/drm/scheduler/sched_main.c | 118 ++---
> >  drivers/gpu/drm/v3d/v3d_sched.c|  10 +-
> >  include/drm/gpu_scheduler.h|  14 ++-
> >  9 files changed, 79 insertions(+), 75 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > index e366f61c3aed..16f3cfe1574a 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > @@ -2279,7 +2279,7 @@ static int amdgpu_device_init_schedulers(struct 
> > amdgpu_device *adev)
> > break;
> > }
> >  
> > -   r = drm_sched_init(&ring->sched, &amdgpu_sched_ops,
> > +   r = drm_sched_init(&ring->sched, &amdgpu_sched_ops, NULL,
> >ring->num_hw_submission, 0,
> >timeout, adev->reset_domain->wq,
> >ring->sched_score, ring->name,
> > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c 
> > b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> > index 345fec6cb1a4..618a804ddc34 100644
> > --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> > +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> > @@ -134,7 +134,7 @@ int etnaviv_sched_init(struct etnaviv_gpu *gpu)
> >  {
> > int ret;
> >  
> > -   ret = drm_sched_init(&gpu->sched, &etnaviv_sched_ops,
> > +   ret = drm_sched_init(&gpu->sched, &etnaviv_sched_ops, NULL,
> >  etnaviv_hw_jobs_limit, etnaviv_job_hang_limit,
> >  msecs_to_jiffies(500), NULL, NULL,
> >  dev_name(gpu->dev), gpu->dev);
> > diff --git a/drivers/gpu/drm/lima/lima_sched.c 
> > b/drivers/gpu/drm/lima/lima_sched.c
> > index ffd91a5ee299..8d858aed0e56 100644
> > --- a/drivers/gpu/drm/lima/lima_sched.c
> > +++ b/drivers/gpu/drm/lima/lima_sched.c
> > @@ -488,7 +488,7 @@ int lima_sched_pipe_init(struct lima_sched_pipe *pipe, 
> > const char *name)
> >  
> > INIT_WORK(&pipe->recover_work, lima_sched_recover_work);
> >  
> > -   return drm_sched_init(&pipe->base, &lima_sched_ops, 1,
> > +   return drm_sched_init(&pipe->base, &lima_sched_ops, NULL, 1,
> >   lima_job_hang_limit,
> >   msecs_to_jiffies(timeout), NULL,
> >   NULL, name, pipe->ldev->dev);
> > diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c 
> > b/drivers/gpu/drm/msm/msm_ringbuffer.c
> > index 40c0bc35a44c..b8865e61b40f 100644
> > --- a/drivers/gpu/drm/msm/msm_ringbuffer.c
> > +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c
> > @@ -94,7 +94,7 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu 
> > *gpu, int id,
> >  /* currently managing hangcheck ourselves: */
> > sched_timeout = MAX_SCHEDULE_TIMEOUT;
> >  
> > -   ret = drm_sched_init(&ring->sched, &msm_sched_ops,
> > +   ret = drm_sched_init(&ring->sched

Re: [PATCH v4 09/10] drm/sched: Add helper to queue TDR immediately for current and future jobs

2023-10-04 Thread Matthew Brost
On Fri, Sep 29, 2023 at 06:44:53PM -0400, Luben Tuikov wrote:
> On 2023-09-19 01:01, Matthew Brost wrote:
> > Add helper to queue TDR immediately for current and future jobs. This
> > will be used in XE, new Intel GPU driver, to trigger the TDR to cleanup
> 
> Please use present tense, "is", in code, comments, commits, etc.
> 
> Is it "XE" or is it "Xe"? I always thought it was "Xe".
> 

Yea should be 'Xe'.

>   This is used in Xe, a new Intel GPU driver, to trigger a TDR to clean up
> 

Will fix.

> Code, comments, commits, etc., immediately become history, and it's a bit
> ambitious to use future tense in something which immediately becomes
> history. It's much better to describe what is happening now, including the 
> patch
> in question (any patch, ftm) is considered "now"/"current state" as well.
>

Got it.

> > a drm_scheduler that encounter error[.]> 
> > v2:
> >  - Drop timeout args, rename function, use mod delayed work (Luben)
> > 
> > Signed-off-by: Matthew Brost 
> > ---
> >  drivers/gpu/drm/scheduler/sched_main.c | 19 ++-
> >  include/drm/gpu_scheduler.h|  1 +
> >  2 files changed, 19 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
> > b/drivers/gpu/drm/scheduler/sched_main.c
> > index e8a3e6033f66..88ef8be2d3c7 100644
> > --- a/drivers/gpu/drm/scheduler/sched_main.c
> > +++ b/drivers/gpu/drm/scheduler/sched_main.c
> > @@ -435,7 +435,7 @@ static void drm_sched_start_timeout(struct 
> > drm_gpu_scheduler *sched)
> >  
> > if (sched->timeout != MAX_SCHEDULE_TIMEOUT &&
> > !list_empty(&sched->pending_list))
> > -   queue_delayed_work(sched->timeout_wq, &sched->work_tdr, 
> > sched->timeout);
> > +   mod_delayed_work(sched->timeout_wq, &sched->work_tdr, 
> > sched->timeout);
> >  }
> >  
> >  static void drm_sched_start_timeout_unlocked(struct drm_gpu_scheduler 
> > *sched)
> > @@ -445,6 +445,23 @@ static void drm_sched_start_timeout_unlocked(struct 
> > drm_gpu_scheduler *sched)
> > spin_unlock(&sched->job_list_lock);
> >  }
> >  
> > +/**
> > + * drm_sched_tdr_queue_imm: - immediately start timeout handler including 
> > future
> > + * jobs
> 
> Let's not mention "including future jobs", since we don't know the future.
> But we can sneak "jobs" into the description like this:
> 
>  * drm_sched_tdr_queue_imm - immediately start job timeout handler
> 
> :-)
>

Will change.
 
> > + *
> > + * @sched: scheduler where the timeout handling should be started.
> 
> "where" --> "for which"
> The former denotes a location, like in space-time, and the latter
> denotes an object, like a scheduler, a spaceship, a bicycle, etc.
>

+1
 
> > + *
> > + * Start timeout handling immediately for current and future jobs
> 
>  * Start timeout handling immediately for the named scheduler.
>

+1

> > + */
> > +void drm_sched_tdr_queue_imm(struct drm_gpu_scheduler *sched)
> > +{
> > +   spin_lock(&sched->job_list_lock);
> > +   sched->timeout = 0;
> > +   drm_sched_start_timeout(sched);
> > +   spin_unlock(&sched->job_list_lock);
> > +}
> > +EXPORT_SYMBOL(drm_sched_tdr_queue_imm);
> > +
> >  /**
> >   * drm_sched_fault - immediately start timeout handler
> >   *
> > diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
> > index 7e6c121003ca..27f5778bbd6d 100644
> > --- a/include/drm/gpu_scheduler.h
> > +++ b/include/drm/gpu_scheduler.h
> > @@ -568,6 +568,7 @@ void drm_sched_entity_modify_sched(struct 
> > drm_sched_entity *entity,
> > struct drm_gpu_scheduler **sched_list,
> > unsigned int num_sched_list);
> >  
> > +void drm_sched_tdr_queue_imm(struct drm_gpu_scheduler *sched);
> >  void drm_sched_job_cleanup(struct drm_sched_job *job);
> >  void drm_sched_wakeup_if_can_queue(struct drm_gpu_scheduler *sched);
> >  bool drm_sched_submit_ready(struct drm_gpu_scheduler *sched);
> 
> Looks good!
> 
> Fix the above, for an immediate R-B. :-)

Thanks for the review, will fix all of this.

Matt

> -- 
> Regards,
> Luben
> 


Re: [PATCH v4 07/10] drm/sched: Start submission before TDR in drm_sched_start

2023-10-04 Thread Luben Tuikov
On 2023-10-04 23:11, Matthew Brost wrote:
> On Sat, Sep 30, 2023 at 03:48:07PM -0400, Luben Tuikov wrote:
>> On 2023-09-29 17:53, Luben Tuikov wrote:
>>> Hi,
>>>
>>> On 2023-09-19 01:01, Matthew Brost wrote:
 If the TDR is set to a very small value it can fire before the
 submission is started in the function drm_sched_start. The submission is
 expected to running when the TDR fires, fix this ordering so this
 expectation is always met.

 Signed-off-by: Matthew Brost 
 ---
  drivers/gpu/drm/scheduler/sched_main.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

 diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
 b/drivers/gpu/drm/scheduler/sched_main.c
 index 09ef07b9e9d5..a5cc9b6c2faa 100644
 --- a/drivers/gpu/drm/scheduler/sched_main.c
 +++ b/drivers/gpu/drm/scheduler/sched_main.c
 @@ -684,10 +684,10 @@ void drm_sched_start(struct drm_gpu_scheduler 
 *sched, bool full_recovery)
drm_sched_job_done(s_job, -ECANCELED);
}
  
 +  drm_sched_submit_start(sched);
 +
if (full_recovery)
drm_sched_start_timeout_unlocked(sched);
 -
 -  drm_sched_submit_start(sched);
  }
  EXPORT_SYMBOL(drm_sched_start);
>>>
>>> No.
>>>
> 
> I don't think we will ever agree on this but I pulled out this patch and
> the next in Xe. It seems to work without these changes, I believe
> understand why and think it should actually work without this change. If
> for some reason it didn't work, I know how I can work around this in the
> Xe submission backend.
> 
> With this, I will drop these in the next rev.
> 
> But more on why I disagree below...
> 
>>> A timeout timer should be started before we submit anything down to the 
>>> hardware.
>>> See Message-ID: ,
>>> and Message-ID: <8e5eab14-9e55-42c9-b6ea-02fcc5912...@amd.com>.
>>>
>>> You shouldn't start TDR at an arbitrarily late time after job
>>> submission to the hardware. To close this, the timer is started
>>> before jobs are submitted to the hardware.
>>>
>>> One possibility is to increase the timeout timer value.
> 
> No matter what the timeout value is there will always be a race of TDR
> firing before run_job() is called.

It's not a "race".

In all software and firmware I've seen, a timeout timer is started _before_
a command is submitted to firmware or hardware, respectively.

> 
>>
>> If we went with this general change as we see here and in the subsequent 
>> patch--starting
>> the TDR _after_ submitting jobs for execution to the hardware--this is what 
>> generally happens,
>> 1. submit one or many jobs for execution;
>> 2. one or many jobs may execute, complete, hang, etc.;
>> 3. at some arbitrary time in the future, start TDR.
>> Which means that the timeout doesn't necessarily track the time allotted for 
>> a job to finish
>> executing in the hardware. It ends up larger than intended.
> 
> Yes, conversely it can be smaller the way it is coded now. Kinda just a
> matter of opinion on which one to prefer.

It should be large enough to contain the command/task/job making it to the 
hardware.
We want to make sure there's no runaway job, _for_ the amount of time allotted
to each job.
-- 
Regards,
Luben



Re: [PATCH v4 07/10] drm/sched: Start submission before TDR in drm_sched_start

2023-10-04 Thread Matthew Brost
On Sat, Sep 30, 2023 at 03:48:07PM -0400, Luben Tuikov wrote:
> On 2023-09-29 17:53, Luben Tuikov wrote:
> > Hi,
> > 
> > On 2023-09-19 01:01, Matthew Brost wrote:
> >> If the TDR is set to a very small value it can fire before the
> >> submission is started in the function drm_sched_start. The submission is
> >> expected to running when the TDR fires, fix this ordering so this
> >> expectation is always met.
> >>
> >> Signed-off-by: Matthew Brost 
> >> ---
> >>  drivers/gpu/drm/scheduler/sched_main.c | 4 ++--
> >>  1 file changed, 2 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
> >> b/drivers/gpu/drm/scheduler/sched_main.c
> >> index 09ef07b9e9d5..a5cc9b6c2faa 100644
> >> --- a/drivers/gpu/drm/scheduler/sched_main.c
> >> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> >> @@ -684,10 +684,10 @@ void drm_sched_start(struct drm_gpu_scheduler 
> >> *sched, bool full_recovery)
> >>drm_sched_job_done(s_job, -ECANCELED);
> >>}
> >>  
> >> +  drm_sched_submit_start(sched);
> >> +
> >>if (full_recovery)
> >>drm_sched_start_timeout_unlocked(sched);
> >> -
> >> -  drm_sched_submit_start(sched);
> >>  }
> >>  EXPORT_SYMBOL(drm_sched_start);
> > 
> > No.
> > 

I don't think we will ever agree on this but I pulled out this patch and
the next in Xe. It seems to work without these changes, I believe
understand why and think it should actually work without this change. If
for some reason it didn't work, I know how I can work around this in the
Xe submission backend.

With this, I will drop these in the next rev.

But more on why I disagree below...

> > A timeout timer should be started before we submit anything down to the 
> > hardware.
> > See Message-ID: ,
> > and Message-ID: <8e5eab14-9e55-42c9-b6ea-02fcc5912...@amd.com>.
> > 
> > You shouldn't start TDR at an arbitrarily late time after job
> > submission to the hardware. To close this, the timer is started
> > before jobs are submitted to the hardware.
> > 
> > One possibility is to increase the timeout timer value.

No matter what the timeout value is there will always be a race of TDR
firing before run_job() is called.

> 
> If we went with this general change as we see here and in the subsequent 
> patch--starting
> the TDR _after_ submitting jobs for execution to the hardware--this is what 
> generally happens,
> 1. submit one or many jobs for execution;
> 2. one or many jobs may execute, complete, hang, etc.;
> 3. at some arbitrary time in the future, start TDR.
> Which means that the timeout doesn't necessarily track the time allotted for 
> a job to finish
> executing in the hardware. It ends up larger than intended.

Yes, conversely it can be smaller the way it is coded now. Kinda just a
matter of opinion on which one to prefer.

Matt

> -- 
> Regards,
> Luben
> 


RE: bulk_move in ttm_resource manager

2023-10-04 Thread Zeng, Oak

> -Original Message-
> From: Christian König 
> Sent: Wednesday, October 4, 2023 8:45 AM
> To: Thomas Hellström ; Zeng, Oak
> 
> Cc: intel...@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Subject: Re: bulk_move in ttm_resource manager
> 
> Am 04.10.23 um 09:17 schrieb Thomas Hellström:
> > On Wed, 2023-10-04 at 03:52 +, Zeng, Oak wrote:
> >> Hi Christian,
> >>
> >> As a follow up to this thread:
> >> https://www.spinics.net/lists/dri-devel/msg410740.html, I started the
> >> work of moving the lru out of ttm_resource_manager and make it a
> >> common library for both ttm and svm. While look into the details of
> >> the bulk_move in ttm resource manager, I found a potential problem:
> >>
> >> For simplicity, let’s say we only have one memory type and one
> >> priority, so ttm resource manager only maintains one global lru list.
> >> Let’s say this list has 10 nodes, node1 to node10.
> >>
> >> But the lru_bulk_move is per vm. Let’s say vm1 has a bulk_move
> >> covering node range [node4, node7] and vm2 has a bulk_move covering
> >> node range [node6, node9]. Notice those two range has an overlap.
> >> Since two vm can simultaneously add nodes to lru, I think this
> >> scenario can happen.
> 
> That can't happen. See what ttm_resource_move_to_lru_tail() does when
> the BO has a bulk move associated with it.

I spent more time reading the codes and I am convinced the codes guarantee all 
nodes in a bulk move range are all belongs to one vm. Yes each time when we add 
a node to bulk move range, ttm_resource_move_to_lru_tail (and other helpers 
such as ttm_resource_add_bulk_move) moves the newly added node to the tail of 
bulk move. When the first node is added to the bulk move, the first and last 
pointer of the bulk move both point to the same first node - this is the 
initial condition that nodes in a bulk move are not separated. Eventually when 
new nodes are added, we always move them to the tail of the bulk move. So after 
the move, all nodes in a bulk move are still not separated (by nodes from other 
vm). 

I doubt whether this implementation of bulk move can actually cut LRU 
maintenance overhead. Even though we can move bulk nodes at once at the end, 
but when *each* node are added to LRU or moved in LRU, we moved them to the 
tail of bulk move range due to above bulk move restriction(when bulk move is 
enabled) - this is already link list operation. Why not just add node to the 
tail of LRU, or just move node to LRU tail when node is touched by GPU?
 
> 
> >>
> >> Now if we perform a bulk move for vm1, moving [node4, node7] to the
> >> tail of the lru list. The lru after this bulk move will be: node1,
> >> node2, node3,node8,node9, node10, node4, node5, node6, node7. Now
> >> notice that for vm2’s bulk_move, the first pointer  (pointing to
> >> node6) is actually after the last pointer (pointing to node9), which
> >> doesn’t make sense.
> >>
> >> Is this a real problem? As I understand it, with this issue, we only
> >> mess up the lru list order, but there won’t be any functional
> >> problem. If it is a real problem, should we make the bulk_move global
> >> instead of per vm based?
> >>
> >> Thanks,
> >> Oak
> >>
> > FWIW I have a patch set that converts the TTM bulk move code to using
> > sublists; a list item is either a resource or a sublist, and when
> > performing a bulk move essentially the sublist is moved. Bumping
> > resource LRU within a VM would touch only the sublist.
> 
> That sounds like my very first attempt at bulk moves which we abandoned
> for various reasons.
> 
> That's easily >5years ago, but the history of that should still be on
> the mailing list if I'm not completely mistaken.

So for my refactor work, I plan to do it based on the current upstream 
implementation. I will revisit if we end up using the sublists.

Regards,
Oak

> 
> Regards,
> Christian.
> 
> >
> > Currently functionality and TTM API is essentially the same but when
> > experimenting with LRU traversal for exhaustive WW-locking eviction
> > this concept was easier to use. Also hopefully this would reduce
> > fragility and improve understanding since a scenario like the above
> > could really never happen...
> >
> > Let me know if I should send it out as an RFC.
> >
> > Code is here:
> > https://gitlab.freedesktop.org/drm/xe/kernel/-
> /merge_requests/351/commits
> >
> > /Thomas
> >
> >
> >
> >
> >



RE: [RFC PATCH 3/3] drm/virtio: drm_gem_plane_helper_prepare_fb for obj synchronization

2023-10-04 Thread Kim, Dongwon
Hi Dmitry,

Resource flush is what is waiting for the fence to be signaled. 

(in current code before my patches are applied)
static void virtio_gpu_resource_flush(struct drm_plane *plane,
  uint32_t x, uint32_t y,
  uint32_t width, uint32_t height)
..
virtio_gpu_notify(vgdev);

dma_fence_wait_timeout(&vgfb->fence->f, true,
   msecs_to_jiffies(50));
...

We use gtk on the host.

Thanks!

-Original Message-
From: Dmitry Osipenko  
Sent: Wednesday, October 4, 2023 4:32 PM
To: Kim, Dongwon ; dri-devel@lists.freedesktop.org
Cc: Kasireddy, Vivek ; kra...@redhat.com
Subject: Re: [RFC PATCH 3/3] drm/virtio: drm_gem_plane_helper_prepare_fb for 
obj synchronization

On 9/6/23 00:08, Kim, Dongwon wrote:
> 
> I don't believe the guest will start rendering on the same FB while 
> host is consuming it because the virtio-gpu driver on the guest won't 
> release the FB for the next frame before it gets the virtio resp for 
> the resource flush command and the host (QEMU) will hold the response 
> until the rendering is finished.

The virgl_cmd_set_scanout() shouldn't hold the response if you're using SDL 
because frame swapping won't be vsynced. It may hold the response implicitly if 
you're using GTK for the Qemu's display. Are you using SDL?

--
Best regards,
Dmitry



Re: [RFC PATCH 3/3] drm/virtio: drm_gem_plane_helper_prepare_fb for obj synchronization

2023-10-04 Thread Dmitry Osipenko
On 9/6/23 00:08, Kim, Dongwon wrote:
> 
> I don't believe the guest will start rendering on the same FB while host is
> consuming it because the virtio-gpu driver on the guest won't release
> the FB for the next
> frame before it gets the virtio resp for the resource flush command and
> the host (QEMU)
> will hold the response until the rendering is finished.

The virgl_cmd_set_scanout() shouldn't hold the response if you're using
SDL because frame swapping won't be vsynced. It may hold the response
implicitly if you're using GTK for the Qemu's display. Are you using SDL?

-- 
Best regards,
Dmitry



Re: [Intel-gfx] [RFC PATCH] drm/i915/gt: Do not treat MCR locking timeouts as errors

2023-10-04 Thread Matt Roper
On Wed, Oct 04, 2023 at 10:58:32PM +0200, Andi Shyti wrote:
> Hi Matt,
> 
> > > > > > > The MCR steering semaphore is a shared lock entry between i915
> > > > > > > and various firmware components.
> > > > > > > 
> > > > > > > Getting the lock might sinchronize on some shared resources.
> > > > > > > Sometimes though, it might happen that the firmware forgets to
> > > > > > > unlock causing unnecessary noise in the driver which keeps doing
> > > > > > > what was supposed to do, ignoring the problem.
> > > > > > > 
> > > > > > > Do not consider this failure as an error, but just print a debug
> > > > > > > message stating that the MCR locking has been skipped.
> > > > > > > 
> > > > > > > On the driver side we still have spinlocks that make sure that
> > > > > > > the access to the resources is serialized.
> > > > > > > 
> > > > > > > Signed-off-by: Andi Shyti 
> > > > > > > Cc: Jonathan Cavitt 
> > > > > > > Cc: Matt Roper 
> > > > > > > Cc: Nirmoy Das 
> > > > > > > ---
> > > > > > >drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 6 ++
> > > > > > >1 file changed, 2 insertions(+), 4 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
> > > > > > > b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > > > > > > index 326c2ed1d99b..51eb693df39b 100644
> > > > > > > --- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > > > > > > +++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > > > > > > @@ -395,10 +395,8 @@ void intel_gt_mcr_lock(struct intel_gt *gt, 
> > > > > > > unsigned long *flags)
> > > > > > >* would indicate some hardware/firmware is misbehaving 
> > > > > > > and not
> > > > > > >* releasing it properly.
> > > > > > >*/
> > > > > > > - if (err == -ETIMEDOUT) {
> > > > > > > - gt_err_ratelimited(gt, "hardware MCR steering semaphore 
> > > > > > > timed out");
> > > > > > > - add_taint_for_CI(gt->i915, TAINT_WARN);  /* CI is now 
> > > > > > > unreliable */
> > > > > > > - }
> > > > > > > + if (err == -ETIMEDOUT)
> > > > > > > + gt_dbg(gt, "hardware MCR steering semaphore timed out");
> > > > > > >}
> > > > > > >/**
> > > > > > Are we sure this does not warrant a level higher than dbg, such as
> > > > > > notice/warn?
> > > > > We might make it a warn, but this doesn't change much the economy
> > > > > of the driver as we will keep doing what we were supposed to do.
> > > > > 
> > > > > > Because how can we be sure the two entities will not stomp on
> > > > > > each other toes if we failed to obtain lock?
> > > > > So far, in all the research I've done, no one looks like using
> > > > > MCR lock, but yet someone is stuck in it.
> > > > 
> > > > If someone has the lock then that someone thinks they are using it. Just
> > > > because you can't see what someone piece of IFWI is doing doesn't mean 
> > > > it
> > > > isn't doing it. And if it is a genuinely missing unlock then it needs 
> > > > to be
> > > > tracked down and fixed with an IFWI update otherwise the system is 
> > > > going to
> > > > be unstable from that point on.
> > > 
> > > But I'm not changing here the behavior of the driver. The driver
> > > will keep doing what was doing before.
> > > 
> > > Because this most probably won't be noticed by the user, then I
> > > don't see why it should shout out loud that the system is
> > > unusable when most probably it is.
> > 
> > That's like saying that any random race condition isn't likely to be
> > noticed by the user so it's not a big deal if we're missing a few
> > mutexes or spinlocks somewhere...even though there's likely to be no
> > user-visible impact to any race condition 99% of the time, it's the 1%
> > that winds up being absolutely catastrophic.
> 
> Not really... normally if you hit a spinlock/mutex race
> condition, you end up in a deadlock and stall the system. In this
> case, I agree that the lock should be sorted out by the hardware,
> but in the meantime i915 is *already* ignoring it.
> 
> I'm not making any behavioral change with this patch.
> 
> What I'm trying to say is that if the system doesn't crash, then
> let it go... don't crash it on purpose just because there is a
> locking situation and we think it has a catastrophic effect, but
> in reality is not producing anything (like practically in our
> case, you can check the CI results[*]).
> 
> [*] https://patchwork.freedesktop.org/patch/560733/?series=124599&rev=1

But hiding the error message is the opposite of the direction we should
be moving.  If anything we need to be escalating this harder, for
example by wedging the GT to truly prevent if from being used further.
We obviously don't want a BUG() or something that would crash the whole
system and potentially cause non-graphics data loss, but we really
shouldn't let regular operation keep going.  The goal of ignoring the
the semaphore and moving forward is that we keep the system alive for a
developer to gather more debug information.

If this is ever seen in the wild

Re: [Intel-gfx] [RFC PATCH] drm/i915/gt: Do not treat MCR locking timeouts as errors

2023-10-04 Thread John Harrison

On 10/4/2023 13:58, Andi Shyti wrote:

Hi Matt,


The MCR steering semaphore is a shared lock entry between i915
and various firmware components.

Getting the lock might sinchronize on some shared resources.
Sometimes though, it might happen that the firmware forgets to
unlock causing unnecessary noise in the driver which keeps doing
what was supposed to do, ignoring the problem.

Do not consider this failure as an error, but just print a debug
message stating that the MCR locking has been skipped.

On the driver side we still have spinlocks that make sure that
the access to the resources is serialized.

Signed-off-by: Andi Shyti 
Cc: Jonathan Cavitt 
Cc: Matt Roper 
Cc: Nirmoy Das 
---
drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 6 ++
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
index 326c2ed1d99b..51eb693df39b 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
@@ -395,10 +395,8 @@ void intel_gt_mcr_lock(struct intel_gt *gt, unsigned long 
*flags)
 * would indicate some hardware/firmware is misbehaving and not
 * releasing it properly.
 */
-   if (err == -ETIMEDOUT) {
-   gt_err_ratelimited(gt, "hardware MCR steering semaphore timed 
out");
-   add_taint_for_CI(gt->i915, TAINT_WARN);  /* CI is now 
unreliable */
-   }
+   if (err == -ETIMEDOUT)
+   gt_dbg(gt, "hardware MCR steering semaphore timed out");
}
/**

Are we sure this does not warrant a level higher than dbg, such as
notice/warn?

We might make it a warn, but this doesn't change much the economy
of the driver as we will keep doing what we were supposed to do.


Because how can we be sure the two entities will not stomp on
each other toes if we failed to obtain lock?

So far, in all the research I've done, no one looks like using
MCR lock, but yet someone is stuck in it.

If someone has the lock then that someone thinks they are using it. Just
because you can't see what someone piece of IFWI is doing doesn't mean it
isn't doing it. And if it is a genuinely missing unlock then it needs to be
tracked down and fixed with an IFWI update otherwise the system is going to
be unstable from that point on.

But I'm not changing here the behavior of the driver. The driver
will keep doing what was doing before.

Because this most probably won't be noticed by the user, then I
don't see why it should shout out loud that the system is
unusable when most probably it is.

That's like saying that any random race condition isn't likely to be
noticed by the user so it's not a big deal if we're missing a few
mutexes or spinlocks somewhere...even though there's likely to be no
user-visible impact to any race condition 99% of the time, it's the 1%
that winds up being absolutely catastrophic.

Not really... normally if you hit a spinlock/mutex race
condition, you end up in a deadlock and stall the system. In this
case, I agree that the lock should be sorted out by the hardware,
but in the meantime i915 is *already* ignoring it.
Um, "a deadlock and stall the system" is exactly what is happening here. 
To prevent a total hang, we are ignoring the deadlock and proceeding 
anyway. Essentially moving to the situation of having a critical section 
which is not protected by the mutex at all.  No matter how you phrase 
it, that is a critical section failure and you do not know how the 1% 
failure might manifest.




I'm not making any behavioral change with this patch.

What I'm trying to say is that if the system doesn't crash, then
let it go... don't crash it on purpose just because there is a
locking situation and we think it has a catastrophic effect, but
in reality is not producing anything (like practically in our
case, you can check the CI results[*]).
We are not going to 'crash it on purpose'. We are printing out an error 
message to say that an error has occurred. Which it has. And as above, 
just because you haven't noticed hitting a catastrophic race condition 
yet doesn't mean that it isn't there.


John.



[*] https://patchwork.freedesktop.org/patch/560733/?series=124599&rev=1


If we're not obtaining the MCR lock as expected and are simply moving
forward to force our own steering (possibly at the same time firmware is
programming steering to a different value), you probably won't actually
see a problem either because the operations won't wind up interleaving
in a problematic order, or because the driver and the firmware both
happen to be trying to steer to the same instance (e.g., instance #0 is
a quite common target).  But even if they're hard to hit, the
possibility for a major problem is still there and basically we need to
consider the whole platform to be in an unknown, unstable state once
we've detected one of these issues.

Based on some earlier experiments, it sounds like the problem at the
moment is that we've just been too h

Re: [Intel-gfx] [RFC PATCH] drm/i915/gt: Do not treat MCR locking timeouts as errors

2023-10-04 Thread John Harrison

On 10/4/2023 13:09, Andi Shyti wrote:

Hi John,


The MCR steering semaphore is a shared lock entry between i915
and various firmware components.

Getting the lock might sinchronize on some shared resources.
Sometimes though, it might happen that the firmware forgets to
unlock causing unnecessary noise in the driver which keeps doing
what was supposed to do, ignoring the problem.

Do not consider this failure as an error, but just print a debug
message stating that the MCR locking has been skipped.

On the driver side we still have spinlocks that make sure that
the access to the resources is serialized.

Signed-off-by: Andi Shyti 
Cc: Jonathan Cavitt 
Cc: Matt Roper 
Cc: Nirmoy Das 
---
 drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
index 326c2ed1d99b..51eb693df39b 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
@@ -395,10 +395,8 @@ void intel_gt_mcr_lock(struct intel_gt *gt, unsigned long 
*flags)
 * would indicate some hardware/firmware is misbehaving and not
 * releasing it properly.
 */
-   if (err == -ETIMEDOUT) {
-   gt_err_ratelimited(gt, "hardware MCR steering semaphore timed 
out");
-   add_taint_for_CI(gt->i915, TAINT_WARN);  /* CI is now 
unreliable */
-   }
+   if (err == -ETIMEDOUT)
+   gt_dbg(gt, "hardware MCR steering semaphore timed out");
 }
 /**

Are we sure this does not warrant a level higher than dbg, such as
notice/warn?

We might make it a warn, but this doesn't change much the economy
of the driver as we will keep doing what we were supposed to do.


Because how can we be sure the two entities will not stomp on
each other toes if we failed to obtain lock?

So far, in all the research I've done, no one looks like using
MCR lock, but yet someone is stuck in it.

If someone has the lock then that someone thinks they are using it. Just
because you can't see what someone piece of IFWI is doing doesn't mean it
isn't doing it. And if it is a genuinely missing unlock then it needs to be
tracked down and fixed with an IFWI update otherwise the system is going to
be unstable from that point on.

But I'm not changing here the behavior of the driver. The driver
will keep doing what was doing before.

And what it is doing is dangerous and can lead to unpredictable results
because a critical section resource access is no longer wrapped with a
critical section lock. Hence there is an error message to say Here Be
Dragons.

hehe!

What are you suggesting, then? Should we reset the GT after
hitting the MCR lock issue?
No. I'm suggesting that you don't hide the issue by removing the error 
message. It is there for a reason. Just because that reason is being hit 
doesn't mean you should remove the message.




We could, but I rather prefer to work with what's available.


Because this most probably won't be noticed by the user, then I
don't see why it should shout out loud that the system is
unusable when most probably it is.

Just because a race condition is hard to hit doesn't mean it won't be hit.

We are hitting it, constantly, but it's not producing any effect.
Even when raising the MCR wait timeout. Which means that most
probably someone is having a nap on the lock.
No. You are hitting the lock contention problem constantly and so far 
are not seeing any *visible* effect.


The point is that there is still a potential race condition which you 
haven't hit yet which could lead to data corruption, page faults, 
crashes, etc. (because a TLB invalidation access went to the wrong 
target) or the CPU/GPU melting itself of the board (because a power 
management access went to the wrong target).





The point of shouting out loud is that we know for a fact a problem has
occurred. That problem might lead to nothing or it might lead to subtle data
corruption, gross crashes or anything in between.

yes, agree... the message still stays, though, with a bit of a
lower catastrophy.


BTW, at my understanding this is not an IFWI problem. We checked
with different version of IFWI and the issue is the same.

Which implies it is a driver bug after all? In which case you absolutely
should not be papering over it in the driver.

This section is serialized by a spinlock and besides I haven't
found any place else except for the TLB invalidation and the
resume where we can incur a locking situation.
There is a bug somewhere. Either it is IFWI or it is KMD. You can't say 
"I can't find a problem therefore there is no problem".


John.




Thanks a lot for your inputs and discussion!
Andi




Re: [PATCH 0/5] drm/amd/display: Remove migrate-disable and move memory allocation.

2023-10-04 Thread Hamza Mahfooz

On 9/21/23 10:15, Sebastian Andrzej Siewior wrote:

Hi,

I stumbled uppon the amdgpu driver via a bugzilla report. The actual fix
is #4 + #5 and the rest was made while looking at the code.

Sebastian


I have applied the series, thanks!





--
Hamza



Re: [PATCH 0/5] drm/amd/display: Remove migrate-disable and move memory allocation.

2023-10-04 Thread Rodrigo Siqueira Jordao




On 9/21/23 08:15, Sebastian Andrzej Siewior wrote:

Hi,

I stumbled uppon the amdgpu driver via a bugzilla report. The actual fix
is #4 + #5 and the rest was made while looking at the code.

Sebastian




Hi Sebastian,

Thanks a lot for this patchset. We tested it on multiple devices, and 
everything looks good. I also reviewed it and lgtm.


Reviewed-by: Rodrigo Siqueira 

Thanks
Siqueira


Re: [Intel-gfx] [RFC PATCH] drm/i915/gt: Do not treat MCR locking timeouts as errors

2023-10-04 Thread Andi Shyti
Hi Matt,

> > > > > > The MCR steering semaphore is a shared lock entry between i915
> > > > > > and various firmware components.
> > > > > > 
> > > > > > Getting the lock might sinchronize on some shared resources.
> > > > > > Sometimes though, it might happen that the firmware forgets to
> > > > > > unlock causing unnecessary noise in the driver which keeps doing
> > > > > > what was supposed to do, ignoring the problem.
> > > > > > 
> > > > > > Do not consider this failure as an error, but just print a debug
> > > > > > message stating that the MCR locking has been skipped.
> > > > > > 
> > > > > > On the driver side we still have spinlocks that make sure that
> > > > > > the access to the resources is serialized.
> > > > > > 
> > > > > > Signed-off-by: Andi Shyti 
> > > > > > Cc: Jonathan Cavitt 
> > > > > > Cc: Matt Roper 
> > > > > > Cc: Nirmoy Das 
> > > > > > ---
> > > > > >drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 6 ++
> > > > > >1 file changed, 2 insertions(+), 4 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
> > > > > > b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > > > > > index 326c2ed1d99b..51eb693df39b 100644
> > > > > > --- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > > > > > +++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > > > > > @@ -395,10 +395,8 @@ void intel_gt_mcr_lock(struct intel_gt *gt, 
> > > > > > unsigned long *flags)
> > > > > >  * would indicate some hardware/firmware is misbehaving and not
> > > > > >  * releasing it properly.
> > > > > >  */
> > > > > > -   if (err == -ETIMEDOUT) {
> > > > > > -   gt_err_ratelimited(gt, "hardware MCR steering semaphore 
> > > > > > timed out");
> > > > > > -   add_taint_for_CI(gt->i915, TAINT_WARN);  /* CI is now 
> > > > > > unreliable */
> > > > > > -   }
> > > > > > +   if (err == -ETIMEDOUT)
> > > > > > +   gt_dbg(gt, "hardware MCR steering semaphore timed out");
> > > > > >}
> > > > > >/**
> > > > > Are we sure this does not warrant a level higher than dbg, such as
> > > > > notice/warn?
> > > > We might make it a warn, but this doesn't change much the economy
> > > > of the driver as we will keep doing what we were supposed to do.
> > > > 
> > > > > Because how can we be sure the two entities will not stomp on
> > > > > each other toes if we failed to obtain lock?
> > > > So far, in all the research I've done, no one looks like using
> > > > MCR lock, but yet someone is stuck in it.
> > > 
> > > If someone has the lock then that someone thinks they are using it. Just
> > > because you can't see what someone piece of IFWI is doing doesn't mean it
> > > isn't doing it. And if it is a genuinely missing unlock then it needs to 
> > > be
> > > tracked down and fixed with an IFWI update otherwise the system is going 
> > > to
> > > be unstable from that point on.
> > 
> > But I'm not changing here the behavior of the driver. The driver
> > will keep doing what was doing before.
> > 
> > Because this most probably won't be noticed by the user, then I
> > don't see why it should shout out loud that the system is
> > unusable when most probably it is.
> 
> That's like saying that any random race condition isn't likely to be
> noticed by the user so it's not a big deal if we're missing a few
> mutexes or spinlocks somewhere...even though there's likely to be no
> user-visible impact to any race condition 99% of the time, it's the 1%
> that winds up being absolutely catastrophic.

Not really... normally if you hit a spinlock/mutex race
condition, you end up in a deadlock and stall the system. In this
case, I agree that the lock should be sorted out by the hardware,
but in the meantime i915 is *already* ignoring it.

I'm not making any behavioral change with this patch.

What I'm trying to say is that if the system doesn't crash, then
let it go... don't crash it on purpose just because there is a
locking situation and we think it has a catastrophic effect, but
in reality is not producing anything (like practically in our
case, you can check the CI results[*]).

[*] https://patchwork.freedesktop.org/patch/560733/?series=124599&rev=1

> If we're not obtaining the MCR lock as expected and are simply moving
> forward to force our own steering (possibly at the same time firmware is
> programming steering to a different value), you probably won't actually
> see a problem either because the operations won't wind up interleaving
> in a problematic order, or because the driver and the firmware both
> happen to be trying to steer to the same instance (e.g., instance #0 is
> a quite common target).  But even if they're hard to hit, the
> possibility for a major problem is still there and basically we need to
> consider the whole platform to be in an unknown, unstable state once
> we've detected one of these issues.
> 
> Based on some earlier experiments, it sounds like the problem at the
> moment is that we've just been too hasty with deciding that the lock is
> 

Re: [Intel-gfx] [RFC PATCH] drm/i915/gt: Do not treat MCR locking timeouts as errors

2023-10-04 Thread Andi Shyti
Hi John,

> > > > > > The MCR steering semaphore is a shared lock entry between i915
> > > > > > and various firmware components.
> > > > > > 
> > > > > > Getting the lock might sinchronize on some shared resources.
> > > > > > Sometimes though, it might happen that the firmware forgets to
> > > > > > unlock causing unnecessary noise in the driver which keeps doing
> > > > > > what was supposed to do, ignoring the problem.
> > > > > > 
> > > > > > Do not consider this failure as an error, but just print a debug
> > > > > > message stating that the MCR locking has been skipped.
> > > > > > 
> > > > > > On the driver side we still have spinlocks that make sure that
> > > > > > the access to the resources is serialized.
> > > > > > 
> > > > > > Signed-off-by: Andi Shyti 
> > > > > > Cc: Jonathan Cavitt 
> > > > > > Cc: Matt Roper 
> > > > > > Cc: Nirmoy Das 
> > > > > > ---
> > > > > > drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 6 ++
> > > > > > 1 file changed, 2 insertions(+), 4 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
> > > > > > b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > > > > > index 326c2ed1d99b..51eb693df39b 100644
> > > > > > --- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > > > > > +++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > > > > > @@ -395,10 +395,8 @@ void intel_gt_mcr_lock(struct intel_gt *gt, 
> > > > > > unsigned long *flags)
> > > > > >  * would indicate some hardware/firmware is misbehaving 
> > > > > > and not
> > > > > >  * releasing it properly.
> > > > > >  */
> > > > > > -   if (err == -ETIMEDOUT) {
> > > > > > -   gt_err_ratelimited(gt, "hardware MCR steering semaphore 
> > > > > > timed out");
> > > > > > -   add_taint_for_CI(gt->i915, TAINT_WARN);  /* CI is now 
> > > > > > unreliable */
> > > > > > -   }
> > > > > > +   if (err == -ETIMEDOUT)
> > > > > > +   gt_dbg(gt, "hardware MCR steering semaphore timed out");
> > > > > > }
> > > > > > /**
> > > > > Are we sure this does not warrant a level higher than dbg, such as
> > > > > notice/warn?
> > > > We might make it a warn, but this doesn't change much the economy
> > > > of the driver as we will keep doing what we were supposed to do.
> > > > 
> > > > > Because how can we be sure the two entities will not stomp on
> > > > > each other toes if we failed to obtain lock?
> > > > So far, in all the research I've done, no one looks like using
> > > > MCR lock, but yet someone is stuck in it.
> > > If someone has the lock then that someone thinks they are using it. Just
> > > because you can't see what someone piece of IFWI is doing doesn't mean it
> > > isn't doing it. And if it is a genuinely missing unlock then it needs to 
> > > be
> > > tracked down and fixed with an IFWI update otherwise the system is going 
> > > to
> > > be unstable from that point on.
> > But I'm not changing here the behavior of the driver. The driver
> > will keep doing what was doing before.
> And what it is doing is dangerous and can lead to unpredictable results
> because a critical section resource access is no longer wrapped with a
> critical section lock. Hence there is an error message to say Here Be
> Dragons.

hehe!

What are you suggesting, then? Should we reset the GT after
hitting the MCR lock issue?

We could, but I rather prefer to work with what's available.

> > Because this most probably won't be noticed by the user, then I
> > don't see why it should shout out loud that the system is
> > unusable when most probably it is.
> Just because a race condition is hard to hit doesn't mean it won't be hit.

We are hitting it, constantly, but it's not producing any effect.
Even when raising the MCR wait timeout. Which means that most
probably someone is having a nap on the lock.

> The point of shouting out loud is that we know for a fact a problem has
> occurred. That problem might lead to nothing or it might lead to subtle data
> corruption, gross crashes or anything in between.

yes, agree... the message still stays, though, with a bit of a
lower catastrophy.

> > BTW, at my understanding this is not an IFWI problem. We checked
> > with different version of IFWI and the issue is the same.
> Which implies it is a driver bug after all? In which case you absolutely
> should not be papering over it in the driver.

This section is serialized by a spinlock and besides I haven't
found any place else except for the TLB invalidation and the
resume where we can incur a locking situation.

Thanks a lot for your inputs and discussion!
Andi


Re: [Intel-gfx] [RFC PATCH] drm/i915/gt: Do not treat MCR locking timeouts as errors

2023-10-04 Thread Matt Roper
On Wed, Oct 04, 2023 at 09:35:27PM +0200, Andi Shyti wrote:
> Hi John,
> 
> > > > > The MCR steering semaphore is a shared lock entry between i915
> > > > > and various firmware components.
> > > > > 
> > > > > Getting the lock might sinchronize on some shared resources.
> > > > > Sometimes though, it might happen that the firmware forgets to
> > > > > unlock causing unnecessary noise in the driver which keeps doing
> > > > > what was supposed to do, ignoring the problem.
> > > > > 
> > > > > Do not consider this failure as an error, but just print a debug
> > > > > message stating that the MCR locking has been skipped.
> > > > > 
> > > > > On the driver side we still have spinlocks that make sure that
> > > > > the access to the resources is serialized.
> > > > > 
> > > > > Signed-off-by: Andi Shyti 
> > > > > Cc: Jonathan Cavitt 
> > > > > Cc: Matt Roper 
> > > > > Cc: Nirmoy Das 
> > > > > ---
> > > > >drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 6 ++
> > > > >1 file changed, 2 insertions(+), 4 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
> > > > > b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > > > > index 326c2ed1d99b..51eb693df39b 100644
> > > > > --- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > > > > +++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > > > > @@ -395,10 +395,8 @@ void intel_gt_mcr_lock(struct intel_gt *gt, 
> > > > > unsigned long *flags)
> > > > >* would indicate some hardware/firmware is misbehaving and not
> > > > >* releasing it properly.
> > > > >*/
> > > > > - if (err == -ETIMEDOUT) {
> > > > > - gt_err_ratelimited(gt, "hardware MCR steering semaphore 
> > > > > timed out");
> > > > > - add_taint_for_CI(gt->i915, TAINT_WARN);  /* CI is now 
> > > > > unreliable */
> > > > > - }
> > > > > + if (err == -ETIMEDOUT)
> > > > > + gt_dbg(gt, "hardware MCR steering semaphore timed out");
> > > > >}
> > > > >/**
> > > > Are we sure this does not warrant a level higher than dbg, such as
> > > > notice/warn?
> > > We might make it a warn, but this doesn't change much the economy
> > > of the driver as we will keep doing what we were supposed to do.
> > > 
> > > > Because how can we be sure the two entities will not stomp on
> > > > each other toes if we failed to obtain lock?
> > > So far, in all the research I've done, no one looks like using
> > > MCR lock, but yet someone is stuck in it.
> > 
> > If someone has the lock then that someone thinks they are using it. Just
> > because you can't see what someone piece of IFWI is doing doesn't mean it
> > isn't doing it. And if it is a genuinely missing unlock then it needs to be
> > tracked down and fixed with an IFWI update otherwise the system is going to
> > be unstable from that point on.
> 
> But I'm not changing here the behavior of the driver. The driver
> will keep doing what was doing before.
> 
> Because this most probably won't be noticed by the user, then I
> don't see why it should shout out loud that the system is
> unusable when most probably it is.

That's like saying that any random race condition isn't likely to be
noticed by the user so it's not a big deal if we're missing a few
mutexes or spinlocks somewhere...even though there's likely to be no
user-visible impact to any race condition 99% of the time, it's the 1%
that winds up being absolutely catastrophic.

If we're not obtaining the MCR lock as expected and are simply moving
forward to force our own steering (possibly at the same time firmware is
programming steering to a different value), you probably won't actually
see a problem either because the operations won't wind up interleaving
in a problematic order, or because the driver and the firmware both
happen to be trying to steer to the same instance (e.g., instance #0 is
a quite common target).  But even if they're hard to hit, the
possibility for a major problem is still there and basically we need to
consider the whole platform to be in an unknown, unstable state once
we've detected one of these issues.

Based on some earlier experiments, it sounds like the problem at the
moment is that we've just been too hasty with deciding that the lock is
"stuck."  There's no formal guidance on what an appropriate timeout is,
but Jonathan's patch to increase the timeout by 10x (from 100ms to 1s)
should hopefully take care of those cases and prevent us from causing
any unprotected races.  If we have any other problems where the lock is
truly stuck (as was seen after an S3 resume), that's a critical error
that needs to be escalated to whichever component is the culprit --- any
such system simply cannot be used safely.  Even if the KMD didn't notice
such stuck semaphores itself, one misbehaving firmware agent could still
block other firmware agents and cause major problems for the health of
the system.

> 
> BTW, at my understanding this is not an IFWI problem. We checked
> with different version of IFWI and

Re: [PATCH 3/3] drm/rect: fix kernel-doc typos

2023-10-04 Thread Simon Ser
Reviewed-by: Simon Ser 


Re: [Intel-gfx] [RFC PATCH] drm/i915/gt: Do not treat MCR locking timeouts as errors

2023-10-04 Thread John Harrison

On 10/4/2023 12:35, Andi Shyti wrote:

Hi John,


The MCR steering semaphore is a shared lock entry between i915
and various firmware components.

Getting the lock might sinchronize on some shared resources.
Sometimes though, it might happen that the firmware forgets to
unlock causing unnecessary noise in the driver which keeps doing
what was supposed to do, ignoring the problem.

Do not consider this failure as an error, but just print a debug
message stating that the MCR locking has been skipped.

On the driver side we still have spinlocks that make sure that
the access to the resources is serialized.

Signed-off-by: Andi Shyti 
Cc: Jonathan Cavitt 
Cc: Matt Roper 
Cc: Nirmoy Das 
---
drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 6 ++
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
index 326c2ed1d99b..51eb693df39b 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
@@ -395,10 +395,8 @@ void intel_gt_mcr_lock(struct intel_gt *gt, unsigned long 
*flags)
 * would indicate some hardware/firmware is misbehaving and not
 * releasing it properly.
 */
-   if (err == -ETIMEDOUT) {
-   gt_err_ratelimited(gt, "hardware MCR steering semaphore timed 
out");
-   add_taint_for_CI(gt->i915, TAINT_WARN);  /* CI is now 
unreliable */
-   }
+   if (err == -ETIMEDOUT)
+   gt_dbg(gt, "hardware MCR steering semaphore timed out");
}
/**

Are we sure this does not warrant a level higher than dbg, such as
notice/warn?

We might make it a warn, but this doesn't change much the economy
of the driver as we will keep doing what we were supposed to do.


Because how can we be sure the two entities will not stomp on
each other toes if we failed to obtain lock?

So far, in all the research I've done, no one looks like using
MCR lock, but yet someone is stuck in it.

If someone has the lock then that someone thinks they are using it. Just
because you can't see what someone piece of IFWI is doing doesn't mean it
isn't doing it. And if it is a genuinely missing unlock then it needs to be
tracked down and fixed with an IFWI update otherwise the system is going to
be unstable from that point on.

But I'm not changing here the behavior of the driver. The driver
will keep doing what was doing before.
And what it is doing is dangerous and can lead to unpredictable results 
because a critical section resource access is no longer wrapped with a 
critical section lock. Hence there is an error message to say Here Be 
Dragons.





Because this most probably won't be noticed by the user, then I
don't see why it should shout out loud that the system is
unusable when most probably it is.

Just because a race condition is hard to hit doesn't mean it won't be hit.

The point of shouting out loud is that we know for a fact a problem has 
occurred. That problem might lead to nothing or it might lead to subtle 
data corruption, gross crashes or anything in between.




BTW, at my understanding this is not an IFWI problem. We checked
with different version of IFWI and the issue is the same.
Which implies it is a driver bug after all? In which case you absolutely 
should not be papering over it in the driver.




Besides we received reports also from systems that are not using
IFWI at all.
There is no system that does not use IFWI. Integrated or discrete, all 
systems have an IFWI. It's just part of the main BIOS on an integrated 
platform.


John.




(How can we be sure about
"forgot to unlock" vs "in prolonged active use"?

There is a patch from Jonathan that is testing a different
timeout.


Or if we can be sure, can
we force unlock and take the lock for the driver explicitly?)

I sent a patch with this solution and Matt turned it down.

Presumably because both forcing a lock and ignoring a failed lock are Bad
Things to be doing!
Just because some entity out of our control isn't playing friendly doesn't
mean we can ignore the problem. The lock is there for a reason. If someone
else owns the lock then any steered access by i915 is potentially going to
be routed to the wrong register as the other entity re-directs the steering
behind out back. That is why there is an error message being printed.
Because things are quite possibly going to fail in some unknown manner.

Yes, agree. This has been already discussed here[*] where I sent
such RFC for the sole purpose of receiving some opinions and
check how CI would behave.

BTW, we are already doing this during the GT resume[**]... it's a
bit of a different context, but it still forces the release of
the lock.

This patch, anyway, is not doing this.

Thanks a lot,
Andi

[*] https://patchwork.freedesktop.org/series/124402/
[**] 37280ef5c1c4 ("drm/i915: Clean steer semaphore on resume")




Re: [PATCH] drm/atomic: Perform blocking commits on workqueue

2023-10-04 Thread Ray Strode
Hi,

On Wed, Oct 4, 2023 at 1:28 PM Ville Syrjälä
 wrote:
> No one really seemed all that interested in it. I'd still like to get
> it in, if for no other reason than to make things operate more uniformly.
> Though there are lots of legacy codepaths left that still hold the locks
> over the whole commit, but those could be fixed up as a followup.

Ah I see what you're saying.

> > > execpt I went further and moved the flush past the unlock in the end.
> >
> > Is that necessary? I was wondering about that but there's this comment
> > in the code:
>
> I'm not really sure there is any point in doing this otherwise.
> It would just change which thread executes the code but everything
> else would still get blocked on the locks the same as before.

Well in my case, I just want driver work to not charge the process cpu time.

But I get what you're saying, Checking if new configurations are valid
shouldnt block on existing configurations getting applied.

Doing it outside the locks isn't necessary to prevents deadlocks, it's
necessary because you're trying to avoid contention when there doesn't
need to be contention.

Your patchset sort of has a different goal, but it solves the issue I
care about at the same time.

I'd be happy if it went in... Daniel, Dave, what are your takes on this?

--Ray


Re: [Intel-gfx] [RFC PATCH] drm/i915/gt: Do not treat MCR locking timeouts as errors

2023-10-04 Thread Andi Shyti
Hi John,

> > > > The MCR steering semaphore is a shared lock entry between i915
> > > > and various firmware components.
> > > > 
> > > > Getting the lock might sinchronize on some shared resources.
> > > > Sometimes though, it might happen that the firmware forgets to
> > > > unlock causing unnecessary noise in the driver which keeps doing
> > > > what was supposed to do, ignoring the problem.
> > > > 
> > > > Do not consider this failure as an error, but just print a debug
> > > > message stating that the MCR locking has been skipped.
> > > > 
> > > > On the driver side we still have spinlocks that make sure that
> > > > the access to the resources is serialized.
> > > > 
> > > > Signed-off-by: Andi Shyti 
> > > > Cc: Jonathan Cavitt 
> > > > Cc: Matt Roper 
> > > > Cc: Nirmoy Das 
> > > > ---
> > > >drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 6 ++
> > > >1 file changed, 2 insertions(+), 4 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
> > > > b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > > > index 326c2ed1d99b..51eb693df39b 100644
> > > > --- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > > > +++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > > > @@ -395,10 +395,8 @@ void intel_gt_mcr_lock(struct intel_gt *gt, 
> > > > unsigned long *flags)
> > > >  * would indicate some hardware/firmware is misbehaving and not
> > > >  * releasing it properly.
> > > >  */
> > > > -   if (err == -ETIMEDOUT) {
> > > > -   gt_err_ratelimited(gt, "hardware MCR steering semaphore 
> > > > timed out");
> > > > -   add_taint_for_CI(gt->i915, TAINT_WARN);  /* CI is now 
> > > > unreliable */
> > > > -   }
> > > > +   if (err == -ETIMEDOUT)
> > > > +   gt_dbg(gt, "hardware MCR steering semaphore timed out");
> > > >}
> > > >/**
> > > Are we sure this does not warrant a level higher than dbg, such as
> > > notice/warn?
> > We might make it a warn, but this doesn't change much the economy
> > of the driver as we will keep doing what we were supposed to do.
> > 
> > > Because how can we be sure the two entities will not stomp on
> > > each other toes if we failed to obtain lock?
> > So far, in all the research I've done, no one looks like using
> > MCR lock, but yet someone is stuck in it.
> 
> If someone has the lock then that someone thinks they are using it. Just
> because you can't see what someone piece of IFWI is doing doesn't mean it
> isn't doing it. And if it is a genuinely missing unlock then it needs to be
> tracked down and fixed with an IFWI update otherwise the system is going to
> be unstable from that point on.

But I'm not changing here the behavior of the driver. The driver
will keep doing what was doing before.

Because this most probably won't be noticed by the user, then I
don't see why it should shout out loud that the system is
unusable when most probably it is.

BTW, at my understanding this is not an IFWI problem. We checked
with different version of IFWI and the issue is the same.

Besides we received reports also from systems that are not using
IFWI at all.

> 
> > 
> > > (How can we be sure about
> > > "forgot to unlock" vs "in prolonged active use"?
> > There is a patch from Jonathan that is testing a different
> > timeout.
> > 
> > > Or if we can be sure, can
> > > we force unlock and take the lock for the driver explicitly?)
> > I sent a patch with this solution and Matt turned it down.
> 
> Presumably because both forcing a lock and ignoring a failed lock are Bad
> Things to be doing!
> Just because some entity out of our control isn't playing friendly doesn't
> mean we can ignore the problem. The lock is there for a reason. If someone
> else owns the lock then any steered access by i915 is potentially going to
> be routed to the wrong register as the other entity re-directs the steering
> behind out back. That is why there is an error message being printed.
> Because things are quite possibly going to fail in some unknown manner.

Yes, agree. This has been already discussed here[*] where I sent
such RFC for the sole purpose of receiving some opinions and
check how CI would behave.

BTW, we are already doing this during the GT resume[**]... it's a
bit of a different context, but it still forces the release of
the lock.

This patch, anyway, is not doing this.

Thanks a lot,
Andi

[*] https://patchwork.freedesktop.org/series/124402/
[**] 37280ef5c1c4 ("drm/i915: Clean steer semaphore on resume")


Re: [Intel-gfx] [RFC PATCH] drm/i915/gt: Do not treat MCR locking timeouts as errors

2023-10-04 Thread John Harrison

On 10/4/2023 07:08, Andi Shyti wrote:

Hi Tvrtko,


The MCR steering semaphore is a shared lock entry between i915
and various firmware components.

Getting the lock might sinchronize on some shared resources.
Sometimes though, it might happen that the firmware forgets to
unlock causing unnecessary noise in the driver which keeps doing
what was supposed to do, ignoring the problem.

Do not consider this failure as an error, but just print a debug
message stating that the MCR locking has been skipped.

On the driver side we still have spinlocks that make sure that
the access to the resources is serialized.

Signed-off-by: Andi Shyti 
Cc: Jonathan Cavitt 
Cc: Matt Roper 
Cc: Nirmoy Das 
---
   drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 6 ++
   1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
index 326c2ed1d99b..51eb693df39b 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
@@ -395,10 +395,8 @@ void intel_gt_mcr_lock(struct intel_gt *gt, unsigned long 
*flags)
 * would indicate some hardware/firmware is misbehaving and not
 * releasing it properly.
 */
-   if (err == -ETIMEDOUT) {
-   gt_err_ratelimited(gt, "hardware MCR steering semaphore timed 
out");
-   add_taint_for_CI(gt->i915, TAINT_WARN);  /* CI is now 
unreliable */
-   }
+   if (err == -ETIMEDOUT)
+   gt_dbg(gt, "hardware MCR steering semaphore timed out");
   }
   /**

Are we sure this does not warrant a level higher than dbg, such as
notice/warn?

We might make it a warn, but this doesn't change much the economy
of the driver as we will keep doing what we were supposed to do.


Because how can we be sure the two entities will not stomp on
each other toes if we failed to obtain lock?

So far, in all the research I've done, no one looks like using
MCR lock, but yet someone is stuck in it.
If someone has the lock then that someone thinks they are using it. Just 
because you can't see what someone piece of IFWI is doing doesn't mean 
it isn't doing it. And if it is a genuinely missing unlock then it needs 
to be tracked down and fixed with an IFWI update otherwise the system is 
going to be unstable from that point on.





(How can we be sure about
"forgot to unlock" vs "in prolonged active use"?

There is a patch from Jonathan that is testing a different
timeout.


Or if we can be sure, can
we force unlock and take the lock for the driver explicitly?)

I sent a patch with this solution and Matt turned it down.
Presumably because both forcing a lock and ignoring a failed lock are 
Bad Things to be doing!


Just because some entity out of our control isn't playing friendly 
doesn't mean we can ignore the problem. The lock is there for a reason. 
If someone else owns the lock then any steered access by i915 is 
potentially going to be routed to the wrong register as the other entity 
re-directs the steering behind out back. That is why there is an error 
message being printed. Because things are quite possibly going to fail 
in some unknown manner.


John.



Andi




[PATCH 6.5 314/321] drm/meson: fix memory leak on ->hpd_notify callback

2023-10-04 Thread Greg Kroah-Hartman
6.5-stable review patch.  If anyone has any objections, please let me know.

--

From: Jani Nikula 

commit 099f0af9d98231bb74956ce92508e87cbcb896be upstream.

The EDID returned by drm_bridge_get_edid() needs to be freed.

Fixes: 0af5e0b41110 ("drm/meson: encoder_hdmi: switch to bridge 
DRM_BRIDGE_ATTACH_NO_CONNECTOR")
Cc: Neil Armstrong 
Cc: Sam Ravnborg 
Cc: Martin Blumenstingl 
Cc: Neil Armstrong 
Cc: Kevin Hilman 
Cc: Jerome Brunet 
Cc: dri-devel@lists.freedesktop.org
Cc: linux-amlo...@lists.infradead.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: sta...@vger.kernel.org # v5.17+
Signed-off-by: Jani Nikula 
Reviewed-by: Neil Armstrong 
Signed-off-by: Neil Armstrong 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20230914131015.2472029-1-jani.nik...@intel.com
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/gpu/drm/meson/meson_encoder_hdmi.c |2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
@@ -332,6 +332,8 @@ static void meson_encoder_hdmi_hpd_notif
return;
 

cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid);
+
+   kfree(edid);
} else
cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier);
 }




Re: [PATCH drm-misc-next v5 4/6] drm/gpuvm: track/lock/validate external/evicted objects

2023-10-04 Thread Danilo Krummrich




On 10/4/23 19:57, Thomas Hellström wrote:

On Wed, 2023-10-04 at 19:17 +0200, Danilo Krummrich wrote:

On 10/4/23 17:29, Thomas Hellström wrote:


On Wed, 2023-10-04 at 14:57 +0200, Danilo Krummrich wrote:

On 10/3/23 11:11, Thomas Hellström wrote:




+
+/**
+ * drm_gpuvm_bo_evict() - add / remove a &drm_gpuvm_bo to
/
from the &drm_gpuvms
+ * evicted list
+ * @vm_bo: the &drm_gpuvm_bo to add or remove
+ * @evict: indicates whether the object is evicted
+ *
+ * Adds a &drm_gpuvm_bo to or removes it from the
&drm_gpuvms
evicted list.
+ */
+void
+drm_gpuvm_bo_evict(struct drm_gpuvm_bo *vm_bo, bool evict)
+{
+    struct drm_gem_object *obj = vm_bo->obj;
+
+    dma_resv_assert_held(obj->resv);
+
+    /* Always lock list transactions, even if
DRM_GPUVM_RESV_PROTECTED is
+ * set. This is required to protect multiple
concurrent
calls to
+ * drm_gpuvm_bo_evict() with BOs with different
dma_resv.
+ */


This doesn't work. The RESV_PROTECTED case requires the
evicted
flag we discussed before. The list is either protected by the
spinlock or the resv. Otherwise a list add could race with a
list
removal elsewhere.


I think it does unless I miss something, but it might be a bit
subtle
though.

Concurrent drm_gpuvm_bo_evict() are protected by the spinlock.
Additionally, when
drm_gpuvm_bo_evict() is called we hold the dma-resv of the
corresponding GEM object.

In drm_gpuvm_validate() I assert that we hold *all* dma-resv,
which
implies that no
one can call drm_gpuvm_bo_evict() on any of the VM's objects and
no
one can add a new
one and directly call drm_gpuvm_bo_evict() on it either.


But translated into how the data (the list in this case) is
protected
it becomes

"Either the spinlock and the bo resv of a single list item OR the
bo
resvs of all bos that can potentially be on the list",

while this is certainly possible to assert, any new / future code
that
manipulates the evict list will probably get this wrong and as a
result
the code becomes pretty fragile. I think drm_gpuvm_bo_destroy()
already
gets it wrong in that it, while holding a single resv, doesn't take
the
spinlock.


That's true and I don't like it either. Unfortunately, with the dma-
resv
locking scheme we can't really protect the evict list without the
drm_gpuvm_bo::evicted trick properly.

But as pointed out in my other reply, I'm a bit worried about the
drm_gpuvm_bo::evicted trick being too restrictive, but maybe it's
fine
doing it in the RESV_PROTECTED case.


Ah, indeed. I misread that as discussing the current code rather than
the drm_gpuvm_bo::evicted trick. If validating only a subset, or a
range, then with the drm_gpuvm_bo::evicted trick would be valid only
for that subset.

But the current code would break because the condition of locking "the
resvs of all bos that can potentially be on the list" doesn't hold
anymore, and you'd get list corruption.

What *would* work, though, is the solution currently in xe, The
original evict list, and a staging evict list whose items are copied
over on validation. The staging evict list being protected by the
spinlock, the original evict list by the resv, and they'd use separate
list heads in the drm_gpuvm_bo, but that is yet another complication.

But I think if this becomes an issue, those VMs (perhaps OpenGL UMD
VMs) only wanting to validate a subset, would simply initially rely on
the current non-RESV solution. It looks like it's only a matter of
flipping the flag on a per-vm basis.


If such a driver locks a range it can also just validate all locked
objects I guess.

And for everything else, we still have the spinlock protected variant,
where drivers can freely move things around by just taking the spinlock.

I think I will go ahead and add drm_gpuvm_bo::evicted, plus the helpers
I mentioned.



/Thomas






So I think that needs fixing, and if keeping that protection I
think it
needs to be documented with the list member and ideally an assert.
But
also note that lockdep_assert_held will typically give false true
for
dma_resv locks; as long as the first dma_resv lock locked in a
drm_exec
sequence  remains locked, lockdep thinks *all* dma_resv locks are
held.
(or something along those lines), so the resv lockdep asserts are
currently pretty useless.

/Thomas







Thanks,

Thomas
















[PATCH 6.1 256/259] drm/meson: fix memory leak on ->hpd_notify callback

2023-10-04 Thread Greg Kroah-Hartman
6.1-stable review patch.  If anyone has any objections, please let me know.

--

From: Jani Nikula 

commit 099f0af9d98231bb74956ce92508e87cbcb896be upstream.

The EDID returned by drm_bridge_get_edid() needs to be freed.

Fixes: 0af5e0b41110 ("drm/meson: encoder_hdmi: switch to bridge 
DRM_BRIDGE_ATTACH_NO_CONNECTOR")
Cc: Neil Armstrong 
Cc: Sam Ravnborg 
Cc: Martin Blumenstingl 
Cc: Neil Armstrong 
Cc: Kevin Hilman 
Cc: Jerome Brunet 
Cc: dri-devel@lists.freedesktop.org
Cc: linux-amlo...@lists.infradead.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: sta...@vger.kernel.org # v5.17+
Signed-off-by: Jani Nikula 
Reviewed-by: Neil Armstrong 
Signed-off-by: Neil Armstrong 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20230914131015.2472029-1-jani.nik...@intel.com
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/gpu/drm/meson/meson_encoder_hdmi.c |2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
@@ -332,6 +332,8 @@ static void meson_encoder_hdmi_hpd_notif
return;
 

cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid);
+
+   kfree(edid);
} else
cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier);
 }




[PATCH 5.15 182/183] drm/meson: fix memory leak on ->hpd_notify callback

2023-10-04 Thread Greg Kroah-Hartman
5.15-stable review patch.  If anyone has any objections, please let me know.

--

From: Jani Nikula 

commit 099f0af9d98231bb74956ce92508e87cbcb896be upstream.

The EDID returned by drm_bridge_get_edid() needs to be freed.

Fixes: 0af5e0b41110 ("drm/meson: encoder_hdmi: switch to bridge 
DRM_BRIDGE_ATTACH_NO_CONNECTOR")
Cc: Neil Armstrong 
Cc: Sam Ravnborg 
Cc: Martin Blumenstingl 
Cc: Neil Armstrong 
Cc: Kevin Hilman 
Cc: Jerome Brunet 
Cc: dri-devel@lists.freedesktop.org
Cc: linux-amlo...@lists.infradead.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: sta...@vger.kernel.org # v5.17+
Signed-off-by: Jani Nikula 
Reviewed-by: Neil Armstrong 
Signed-off-by: Neil Armstrong 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20230914131015.2472029-1-jani.nik...@intel.com
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/gpu/drm/meson/meson_encoder_hdmi.c |2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
@@ -326,6 +326,8 @@ static void meson_encoder_hdmi_hpd_notif
return;
 

cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid);
+
+   kfree(edid);
} else
cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier);
 }




Re: [Intel-gfx] [PATCH v4 3/3] drm/i915/gt: Timeout when waiting for idle in suspending

2023-10-04 Thread Teres Alexis, Alan Previn
On Thu, 2023-09-28 at 13:46 +0100, Tvrtko Ursulin wrote:
> On 27/09/2023 17:36, Teres Alexis, Alan Previn wrote:
> > Thanks for taking the time to review this Tvrtko, replies inline below.
alan:snip

> > > 
> > > Main concern is that we need to be sure there are no possible
> > > ill-effects, like letting the GPU/GuC scribble on some memory we
> > > unmapped (or will unmap), having let the suspend continue after timing
> > > out, and not perhaps doing the forced wedge like wait_for_suspend() does
> > > on the existing timeout path.
> > alan: this will not happen because the held wakeref is never force-released
> > after the timeout - so what happens is the kernel would bail the suspend.
> 
> How does it know to fail the suspend when there is no error code 
> returned with this timeout? Maybe a stupid question.. my knowledge of 
> suspend-resume paths was not great even before I forgot it all.
alan:Tvrtko, you and I both sir. (apologies for the tardy response yet again 
busy week).
So i did trace back the gt->wakeref before i posted these patches and 
discovered that
runtime get/put call, i believe that the first 'get' leads to 
__intel_wakeref_get_first
which calls intel_runtime_pm_get via rpm_get helper and eventually executes a
pm_runtime_get_sync(rpm->kdev); (hanging off i915). (ofc, there is a 
corresponding
for '_put_last') - so non-first, non-last increases the counter for the gt...
but this last miss will mean kernel knows i915 hasnt 'put' everything.

alan:snip
> > 
> > Recap: so in both cases (original vs this patch), if we had a buggy 
> > gt-wakeref leak,
> > we dont get invalid guc-accesses, but without this patch, we wait forever,
> > and with this patch, we get some messages and eventually bail the suspend.
> 
> It is not possible to wait for lost G2H in something like 
> intel_uc_suspend() and simply declare "bad things happened" if it times 
> out there, and forcibly clean it all up? (Which would include releasing 
> all the abandoned pm refs, so this patch wouldn't be needed.)
> 
alan: I'm not sure if intel_uc_suspend should be held up by gt-level wakeref
check unless huc/guc/gsc-uc are the only ones ever taking a gt wakeref. 

As we already know, what we do know from a uc-perspective:
-  ensure the outstanding guc related workers is flushed which we didnt before
(addressed by patch #1).
- any further late H2G-SchedDisable is not leaking wakerefs when calling H2G
and not realizing it failed (addressed by patch #2).
- (we already), "forcibly clean it all up" at the end of the intel_uc_suspend
when we do the guc reset and cleanup all guc-ids. (pre-existing upstream code)
- we previously didnt have a coherrent guarantee that "this is the end" i.e. no
more new request after intel_uc_suspend. I mean by code logic, we thought we did
(thats why intel_uc_suspend ends wth a guc reset), but we now know otherwise.
So we that fix by adding the additional rcu_barrier (also part of patch #2).

That said, patch-3 is NOT fixing a bug in guc -its about "if we ever have
a future racy gt-wakeref late-leak somewhere - no matter which subsystem
took it (guc is not the only subsystem taking gt wakerefs), we at
least don't hang forever in this code. Ofc, based on that, even without
patch-3 i am confident the issue is resolved anyway.
So we could just drop patch-3 is you prefer?

...alan


Re: [PATCH drm-misc-next v5 4/6] drm/gpuvm: track/lock/validate external/evicted objects

2023-10-04 Thread Thomas Hellström
On Wed, 2023-10-04 at 19:17 +0200, Danilo Krummrich wrote:
> On 10/4/23 17:29, Thomas Hellström wrote:
> > 
> > On Wed, 2023-10-04 at 14:57 +0200, Danilo Krummrich wrote:
> > > On 10/3/23 11:11, Thomas Hellström wrote:
> > > 
> > > 
> > > 
> > > > > > +
> > > > > > +/**
> > > > > > + * drm_gpuvm_bo_evict() - add / remove a &drm_gpuvm_bo to
> > > > > > /
> > > > > > from the &drm_gpuvms
> > > > > > + * evicted list
> > > > > > + * @vm_bo: the &drm_gpuvm_bo to add or remove
> > > > > > + * @evict: indicates whether the object is evicted
> > > > > > + *
> > > > > > + * Adds a &drm_gpuvm_bo to or removes it from the
> > > > > > &drm_gpuvms
> > > > > > evicted list.
> > > > > > + */
> > > > > > +void
> > > > > > +drm_gpuvm_bo_evict(struct drm_gpuvm_bo *vm_bo, bool evict)
> > > > > > +{
> > > > > > +    struct drm_gem_object *obj = vm_bo->obj;
> > > > > > +
> > > > > > +    dma_resv_assert_held(obj->resv);
> > > > > > +
> > > > > > +    /* Always lock list transactions, even if
> > > > > > DRM_GPUVM_RESV_PROTECTED is
> > > > > > + * set. This is required to protect multiple
> > > > > > concurrent
> > > > > > calls to
> > > > > > + * drm_gpuvm_bo_evict() with BOs with different
> > > > > > dma_resv.
> > > > > > + */
> > > > > 
> > > > > This doesn't work. The RESV_PROTECTED case requires the
> > > > > evicted
> > > > > flag we discussed before. The list is either protected by the
> > > > > spinlock or the resv. Otherwise a list add could race with a
> > > > > list
> > > > > removal elsewhere.
> > > 
> > > I think it does unless I miss something, but it might be a bit
> > > subtle
> > > though.
> > > 
> > > Concurrent drm_gpuvm_bo_evict() are protected by the spinlock.
> > > Additionally, when
> > > drm_gpuvm_bo_evict() is called we hold the dma-resv of the
> > > corresponding GEM object.
> > > 
> > > In drm_gpuvm_validate() I assert that we hold *all* dma-resv,
> > > which
> > > implies that no
> > > one can call drm_gpuvm_bo_evict() on any of the VM's objects and
> > > no
> > > one can add a new
> > > one and directly call drm_gpuvm_bo_evict() on it either.
> > 
> > But translated into how the data (the list in this case) is
> > protected
> > it becomes
> > 
> > "Either the spinlock and the bo resv of a single list item OR the
> > bo
> > resvs of all bos that can potentially be on the list",
> > 
> > while this is certainly possible to assert, any new / future code
> > that
> > manipulates the evict list will probably get this wrong and as a
> > result
> > the code becomes pretty fragile. I think drm_gpuvm_bo_destroy()
> > already
> > gets it wrong in that it, while holding a single resv, doesn't take
> > the
> > spinlock.
> 
> That's true and I don't like it either. Unfortunately, with the dma-
> resv
> locking scheme we can't really protect the evict list without the
> drm_gpuvm_bo::evicted trick properly.
> 
> But as pointed out in my other reply, I'm a bit worried about the
> drm_gpuvm_bo::evicted trick being too restrictive, but maybe it's
> fine
> doing it in the RESV_PROTECTED case.

Ah, indeed. I misread that as discussing the current code rather than
the drm_gpuvm_bo::evicted trick. If validating only a subset, or a
range, then with the drm_gpuvm_bo::evicted trick would be valid only
for that subset.

But the current code would break because the condition of locking "the
resvs of all bos that can potentially be on the list" doesn't hold
anymore, and you'd get list corruption.

What *would* work, though, is the solution currently in xe, The
original evict list, and a staging evict list whose items are copied
over on validation. The staging evict list being protected by the
spinlock, the original evict list by the resv, and they'd use separate
list heads in the drm_gpuvm_bo, but that is yet another complication.

But I think if this becomes an issue, those VMs (perhaps OpenGL UMD
VMs) only wanting to validate a subset, would simply initially rely on
the current non-RESV solution. It looks like it's only a matter of
flipping the flag on a per-vm basis.

/Thomas


> 
> > 
> > So I think that needs fixing, and if keeping that protection I
> > think it
> > needs to be documented with the list member and ideally an assert.
> > But
> > also note that lockdep_assert_held will typically give false true
> > for
> > dma_resv locks; as long as the first dma_resv lock locked in a
> > drm_exec
> > sequence  remains locked, lockdep thinks *all* dma_resv locks are
> > held.
> > (or something along those lines), so the resv lockdep asserts are
> > currently pretty useless.
> > 
> > /Thomas
> > 
> > 
> > 
> > > 
> > > > > 
> > > > > Thanks,
> > > > > 
> > > > > Thomas
> > > > > 
> > > > > 
> > > > 
> > > 
> > 
> 



Re: [PATCH] drm/amdgpu: Annotate struct amdgpu_bo_list with __counted_by

2023-10-04 Thread Luben Tuikov
On 2023-10-03 19:29, Kees Cook wrote:
> Prepare for the coming implementation by GCC and Clang of the __counted_by
> attribute. Flexible array members annotated with __counted_by can have
> their accesses bounds-checked at run-time via CONFIG_UBSAN_BOUNDS (for
> array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family
> functions).
> 
> As found with Coccinelle[1], add __counted_by for struct amdgpu_bo_list.
> Additionally, since the element count member must be set before accessing
> the annotated flexible array member, move its initialization earlier.
> 
> Cc: Alex Deucher 
> Cc: "Christian König" 
> Cc: "Pan, Xinhui" 
> Cc: David Airlie 
> Cc: Daniel Vetter 
> Cc: "Gustavo A. R. Silva" 
> Cc: Luben Tuikov 
> Cc: Christophe JAILLET 
> Cc: Felix Kuehling 
> Cc: amd-...@lists.freedesktop.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-harden...@vger.kernel.org
> Link: 
> https://github.com/kees/kernel-tools/blob/trunk/coccinelle/examples/counted_by.cocci
>  [1]
> Signed-off-by: Kees Cook 

Reviewed-by: Luben Tuikov 
-- 
Regards,
Luben

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> index 6f5b641b631e..781e5c5ce04d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> @@ -84,6 +84,7 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev, 
> struct drm_file *filp,
>  
>   kref_init(&list->refcount);
>  
> + list->num_entries = num_entries;
>   array = list->entries;
>  
>   for (i = 0; i < num_entries; ++i) {
> @@ -129,7 +130,6 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev, 
> struct drm_file *filp,
>   }
>  
>   list->first_userptr = first_userptr;
> - list->num_entries = num_entries;
>   sort(array, last_entry, sizeof(struct amdgpu_bo_list_entry),
>amdgpu_bo_list_entry_cmp, NULL);
>  
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
> index 6a703be45d04..555cd6d877c3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
> @@ -56,7 +56,7 @@ struct amdgpu_bo_list {
>*/
>   struct mutex bo_list_mutex;
>  
> - struct amdgpu_bo_list_entry entries[];
> + struct amdgpu_bo_list_entry entries[] __counted_by(num_entries);
>  };
>  
>  int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,



Re: [PATCH] drm/atomic: Perform blocking commits on workqueue

2023-10-04 Thread Ville Syrjälä
On Thu, Sep 28, 2023 at 03:33:46PM -0400, Ray Strode wrote:
> hI,
> 
> On Thu, Sep 28, 2023 at 11:05 AM Ville Syrjälä
>  wrote:
> > Here's my earlier take on this: 
> > https://patchwork.freedesktop.org/series/108668/
> 
> Nice. Was there push back? Why didn't it go in?

No one really seemed all that interested in it. I'd still like to get
it in, if for no other reason than to make things operate more uniformly.
Though there are lots of legacy codepaths left that still hold the locks
over the whole commit, but those could be fixed up as a followup.

> 
> > execpt I went further and moved the flush past the unlock in the end.
> 
> Is that necessary? I was wondering about that but there's this comment
> in the code:

I'm not really sure there is any point in doing this otherwise. 
It would just change which thread executes the code but everything
else would still get blocked on the locks the same as before.

> 
> *  ... Locks, especially struct
>  * &drm_modeset_lock, should not be held in worker threads or any other
>  * asynchronous context used to commit the hardware state.
> 
> So it made me think there would be no locks held, and then I threw a
> scratch build
> at someone who reported it didn't deadlock and solved their issue.
> 
> --Ray

-- 
Ville Syrjälä
Intel


Re: [PATCH drm-misc-next v5 4/6] drm/gpuvm: track/lock/validate external/evicted objects

2023-10-04 Thread Danilo Krummrich

On 10/4/23 17:29, Thomas Hellström wrote:


On Wed, 2023-10-04 at 14:57 +0200, Danilo Krummrich wrote:

On 10/3/23 11:11, Thomas Hellström wrote:




+
+/**
+ * drm_gpuvm_bo_evict() - add / remove a &drm_gpuvm_bo to /
from the &drm_gpuvms
+ * evicted list
+ * @vm_bo: the &drm_gpuvm_bo to add or remove
+ * @evict: indicates whether the object is evicted
+ *
+ * Adds a &drm_gpuvm_bo to or removes it from the &drm_gpuvms
evicted list.
+ */
+void
+drm_gpuvm_bo_evict(struct drm_gpuvm_bo *vm_bo, bool evict)
+{
+    struct drm_gem_object *obj = vm_bo->obj;
+
+    dma_resv_assert_held(obj->resv);
+
+    /* Always lock list transactions, even if
DRM_GPUVM_RESV_PROTECTED is
+ * set. This is required to protect multiple concurrent
calls to
+ * drm_gpuvm_bo_evict() with BOs with different dma_resv.
+ */


This doesn't work. The RESV_PROTECTED case requires the evicted
flag we discussed before. The list is either protected by the
spinlock or the resv. Otherwise a list add could race with a list
removal elsewhere.


I think it does unless I miss something, but it might be a bit subtle
though.

Concurrent drm_gpuvm_bo_evict() are protected by the spinlock.
Additionally, when
drm_gpuvm_bo_evict() is called we hold the dma-resv of the
corresponding GEM object.

In drm_gpuvm_validate() I assert that we hold *all* dma-resv, which
implies that no
one can call drm_gpuvm_bo_evict() on any of the VM's objects and no
one can add a new
one and directly call drm_gpuvm_bo_evict() on it either.


But translated into how the data (the list in this case) is protected
it becomes

"Either the spinlock and the bo resv of a single list item OR the bo
resvs of all bos that can potentially be on the list",

while this is certainly possible to assert, any new / future code that
manipulates the evict list will probably get this wrong and as a result
the code becomes pretty fragile. I think drm_gpuvm_bo_destroy() already
gets it wrong in that it, while holding a single resv, doesn't take the
spinlock.


That's true and I don't like it either. Unfortunately, with the dma-resv
locking scheme we can't really protect the evict list without the
drm_gpuvm_bo::evicted trick properly.

But as pointed out in my other reply, I'm a bit worried about the
drm_gpuvm_bo::evicted trick being too restrictive, but maybe it's fine
doing it in the RESV_PROTECTED case.



So I think that needs fixing, and if keeping that protection I think it
needs to be documented with the list member and ideally an assert. But
also note that lockdep_assert_held will typically give false true for
dma_resv locks; as long as the first dma_resv lock locked in a drm_exec
sequence  remains locked, lockdep thinks *all* dma_resv locks are held.
(or something along those lines), so the resv lockdep asserts are
currently pretty useless.

/Thomas







Thanks,

Thomas












Re: [PATCH v3 2/2] drm/amdkfd: get doorbell's absolute offset based on the db size

2023-10-04 Thread Yadav, Arvind



On 10/4/2023 10:29 PM, Felix Kuehling wrote:


On 2023-10-04 12:16, Arvind Yadav wrote:

This patch is to align the absolute doorbell offset
based on the doorbell's size. So that doorbell offset
will be aligned for both 32 bit and 64 bit.

v2:
- Addressed the review comment from Felix.
v3:
- Adding doorbell_size as parameter to get db absolute offset.

Cc: Christian Koenig 
Cc: Alex Deucher 
Signed-off-by: Shashank Sharma 
Signed-off-by: Arvind Yadav 


The final result looks good to me. But please squash the two patches 
into one. The first patch on its own breaks the build, and that's 
something we don't want to commit to the branch history as it makes 
tracking regressions (e.g. with git bisect) very hard or impossible.


More nit-picks inline.

Sure, we can have one patch.




---
  .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c   |  6 +-
  drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c   | 13 +++--
  .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c  |  4 +++-
  3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c

index 0d3d538b64eb..690ff131fe4b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -346,6 +346,7 @@ static int allocate_doorbell(struct 
qcm_process_device *qpd,

   uint32_t const *restore_id)
  {
  struct kfd_node *dev = qpd->dqm->dev;
+    uint32_t doorbell_size;
    if (!KFD_IS_SOC15(dev)) {
  /* On pre-SOC15 chips we need to use the queue ID to
@@ -405,9 +406,12 @@ static int allocate_doorbell(struct 
qcm_process_device *qpd,

  }
  }
  +    doorbell_size = dev->kfd->device_info.doorbell_size;
+
  q->properties.doorbell_off = 
amdgpu_doorbell_index_on_bar(dev->adev,

    qpd->proc_doorbells,
-  q->doorbell_id);
+  q->doorbell_id,
+  doorbell_size);


You don't need a local variable for doorbell size that's only used 
once. Just pass dev->kfd->device_info.doorbell_size directly.


I have used local variable to make the code cleaner but I will remove 
local variable.



  return 0;
  }
  diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c

index 7b38537c7c99..59dd76c4b138 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
@@ -161,7 +161,10 @@ void __iomem *kfd_get_kernel_doorbell(struct 
kfd_dev *kfd,

  if (inx >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)
  return NULL;
  -    *doorbell_off = amdgpu_doorbell_index_on_bar(kfd->adev, 
kfd->doorbells, inx);

+    *doorbell_off = amdgpu_doorbell_index_on_bar(kfd->adev,
+ kfd->doorbells,
+ inx,
+ kfd->device_info.doorbell_size);
  inx *= 2;
    pr_debug("Get kernel queue doorbell\n"
@@ -233,6 +236,7 @@ phys_addr_t kfd_get_process_doorbells(struct 
kfd_process_device *pdd)

  {
  struct amdgpu_device *adev = pdd->dev->adev;
  uint32_t first_db_index;
+    uint32_t doorbell_size;
    if (!pdd->qpd.proc_doorbells) {
  if (kfd_alloc_process_doorbells(pdd->dev->kfd, pdd))
@@ -240,7 +244,12 @@ phys_addr_t kfd_get_process_doorbells(struct 
kfd_process_device *pdd)

  return 0;
  }
  -    first_db_index = amdgpu_doorbell_index_on_bar(adev, 
pdd->qpd.proc_doorbells, 0);

+    doorbell_size = pdd->dev->kfd->device_info.doorbell_size;
+
+    first_db_index = amdgpu_doorbell_index_on_bar(adev,
+  pdd->qpd.proc_doorbells,
+  0,
+  doorbell_size);


Same as above, no local variable needed.

Noted,




  return adev->doorbell.base + first_db_index * sizeof(uint32_t);
  }
  diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c

index adb5e4bdc0b2..010cd8e8e6a1 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -375,9 +375,11 @@ int pqm_create_queue(struct 
process_queue_manager *pqm,

   * relative doorbell index = Absolute doorbell index -
   * absolute index of first doorbell in the page.
   */
+    uint32_t doorbell_size = 
pdd->dev->kfd->device_info.doorbell_size;
  uint32_t first_db_index = 
amdgpu_doorbell_index_on_bar(pdd->dev->adev,

pdd->qpd.proc_doorbells,
-   0);
+   0,
+   doorbell_size);


No local variable needed.


Noted,

Thanks
~Arvind


Regards,
  Felix



    *p_doorbell_offset_in_process = (q->properties.doorbell_off
  - first_db_i

Re: [Intel-gfx] [PATCH] drm/dp: switch drm_dp_downstream_*() helpers to struct drm_edid

2023-10-04 Thread Ville Syrjälä
On Wed, Oct 04, 2023 at 07:21:49PM +0300, Jani Nikula wrote:
> Prefer struct drm_edid where possible. With limited users for the
> drm_dp_downstream_*() helpers, this is fairly straightforward.
> 
> Signed-off-by: Jani Nikula 

Reviewed-by: Ville Syrjälä 

> ---
>  drivers/gpu/drm/display/drm_dp_helper.c   | 39 ++-
>  .../drm/i915/display/intel_display_debugfs.c  |  3 +-
>  drivers/gpu/drm/i915/display/intel_dp.c   | 10 ++---
>  include/drm/display/drm_dp_helper.h   | 12 +++---
>  4 files changed, 31 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
> b/drivers/gpu/drm/display/drm_dp_helper.c
> index 8a1b64c57dfd..f3680f4e6970 100644
> --- a/drivers/gpu/drm/display/drm_dp_helper.c
> +++ b/drivers/gpu/drm/display/drm_dp_helper.c
> @@ -746,8 +746,11 @@ int drm_dp_dpcd_read_phy_link_status(struct drm_dp_aux 
> *aux,
>  }
>  EXPORT_SYMBOL(drm_dp_dpcd_read_phy_link_status);
>  
> -static bool is_edid_digital_input_dp(const struct edid *edid)
> +static bool is_edid_digital_input_dp(const struct drm_edid *drm_edid)
>  {
> + /* FIXME: get rid of drm_edid_raw() */
> + const struct edid *edid = drm_edid_raw(drm_edid);
> +
>   return edid && edid->revision >= 4 &&
>   edid->input & DRM_EDID_INPUT_DIGITAL &&
>   (edid->input & DRM_EDID_DIGITAL_TYPE_MASK) == 
> DRM_EDID_DIGITAL_TYPE_DP;
> @@ -779,13 +782,13 @@ EXPORT_SYMBOL(drm_dp_downstream_is_type);
>   * drm_dp_downstream_is_tmds() - is the downstream facing port TMDS?
>   * @dpcd: DisplayPort configuration data
>   * @port_cap: port capabilities
> - * @edid: EDID
> + * @drm_edid: EDID
>   *
>   * Returns: whether the downstream facing port is TMDS (HDMI/DVI).
>   */
>  bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
>  const u8 port_cap[4],
> -const struct edid *edid)
> +const struct drm_edid *drm_edid)
>  {
>   if (dpcd[DP_DPCD_REV] < 0x11) {
>   switch (dpcd[DP_DOWNSTREAMPORT_PRESENT] & 
> DP_DWN_STRM_PORT_TYPE_MASK) {
> @@ -798,7 +801,7 @@ bool drm_dp_downstream_is_tmds(const u8 
> dpcd[DP_RECEIVER_CAP_SIZE],
>  
>   switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
>   case DP_DS_PORT_TYPE_DP_DUALMODE:
> - if (is_edid_digital_input_dp(edid))
> + if (is_edid_digital_input_dp(drm_edid))
>   return false;
>   fallthrough;
>   case DP_DS_PORT_TYPE_DVI:
> @@ -1036,14 +1039,14 @@ EXPORT_SYMBOL(drm_dp_downstream_max_dotclock);
>   * drm_dp_downstream_max_tmds_clock() - extract downstream facing port max 
> TMDS clock
>   * @dpcd: DisplayPort configuration data
>   * @port_cap: port capabilities
> - * @edid: EDID
> + * @drm_edid: EDID
>   *
>   * Returns: HDMI/DVI downstream facing port max TMDS clock in kHz on success,
>   * or 0 if max TMDS clock not defined
>   */
>  int drm_dp_downstream_max_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
>const u8 port_cap[4],
> -  const struct edid *edid)
> +  const struct drm_edid *drm_edid)
>  {
>   if (!drm_dp_is_branch(dpcd))
>   return 0;
> @@ -1059,7 +1062,7 @@ int drm_dp_downstream_max_tmds_clock(const u8 
> dpcd[DP_RECEIVER_CAP_SIZE],
>  
>   switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
>   case DP_DS_PORT_TYPE_DP_DUALMODE:
> - if (is_edid_digital_input_dp(edid))
> + if (is_edid_digital_input_dp(drm_edid))
>   return 0;
>   /*
>* It's left up to the driver to check the
> @@ -1101,14 +1104,14 @@ EXPORT_SYMBOL(drm_dp_downstream_max_tmds_clock);
>   * drm_dp_downstream_min_tmds_clock() - extract downstream facing port min 
> TMDS clock
>   * @dpcd: DisplayPort configuration data
>   * @port_cap: port capabilities
> - * @edid: EDID
> + * @drm_edid: EDID
>   *
>   * Returns: HDMI/DVI downstream facing port min TMDS clock in kHz on success,
>   * or 0 if max TMDS clock not defined
>   */
>  int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
>const u8 port_cap[4],
> -  const struct edid *edid)
> +  const struct drm_edid *drm_edid)
>  {
>   if (!drm_dp_is_branch(dpcd))
>   return 0;
> @@ -1124,7 +1127,7 @@ int drm_dp_downstream_min_tmds_clock(const u8 
> dpcd[DP_RECEIVER_CAP_SIZE],
>  
>   switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
>   case DP_DS_PORT_TYPE_DP_DUALMODE:
> - if (is_edid_digital_input_dp(edid))
> + if (is_edid_digital_input_dp(drm_edid))
>   return 0;
>   fallthrough;
>   case DP_DS_PORT_TYPE_DVI:
> @@ -1145,13 +1148,13 @@ EXPORT_SYMBOL(drm_dp_downstream_min_tmds_clock);
>   *   bits per component
>   *

Patch "drm/meson: fix memory leak on ->hpd_notify callback" has been added to the 6.5-stable tree

2023-10-04 Thread gregkh


This is a note to let you know that I've just added the patch titled

drm/meson: fix memory leak on ->hpd_notify callback

to the 6.5-stable tree which can be found at:

http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
 drm-meson-fix-memory-leak-on-hpd_notify-callback.patch
and it can be found in the queue-6.5 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let  know about it.


>From 099f0af9d98231bb74956ce92508e87cbcb896be Mon Sep 17 00:00:00 2001
From: Jani Nikula 
Date: Thu, 14 Sep 2023 16:10:15 +0300
Subject: drm/meson: fix memory leak on ->hpd_notify callback

From: Jani Nikula 

commit 099f0af9d98231bb74956ce92508e87cbcb896be upstream.

The EDID returned by drm_bridge_get_edid() needs to be freed.

Fixes: 0af5e0b41110 ("drm/meson: encoder_hdmi: switch to bridge 
DRM_BRIDGE_ATTACH_NO_CONNECTOR")
Cc: Neil Armstrong 
Cc: Sam Ravnborg 
Cc: Martin Blumenstingl 
Cc: Neil Armstrong 
Cc: Kevin Hilman 
Cc: Jerome Brunet 
Cc: dri-devel@lists.freedesktop.org
Cc: linux-amlo...@lists.infradead.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: sta...@vger.kernel.org # v5.17+
Signed-off-by: Jani Nikula 
Reviewed-by: Neil Armstrong 
Signed-off-by: Neil Armstrong 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20230914131015.2472029-1-jani.nik...@intel.com
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/gpu/drm/meson/meson_encoder_hdmi.c |2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
@@ -332,6 +332,8 @@ static void meson_encoder_hdmi_hpd_notif
return;
 

cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid);
+
+   kfree(edid);
} else
cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier);
 }


Patches currently in stable-queue which might be from jani.nik...@intel.com are

queue-6.5/drm-meson-fix-memory-leak-on-hpd_notify-callback.patch


Patch "drm/meson: fix memory leak on ->hpd_notify callback" has been added to the 6.1-stable tree

2023-10-04 Thread gregkh


This is a note to let you know that I've just added the patch titled

drm/meson: fix memory leak on ->hpd_notify callback

to the 6.1-stable tree which can be found at:

http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
 drm-meson-fix-memory-leak-on-hpd_notify-callback.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let  know about it.


>From 099f0af9d98231bb74956ce92508e87cbcb896be Mon Sep 17 00:00:00 2001
From: Jani Nikula 
Date: Thu, 14 Sep 2023 16:10:15 +0300
Subject: drm/meson: fix memory leak on ->hpd_notify callback

From: Jani Nikula 

commit 099f0af9d98231bb74956ce92508e87cbcb896be upstream.

The EDID returned by drm_bridge_get_edid() needs to be freed.

Fixes: 0af5e0b41110 ("drm/meson: encoder_hdmi: switch to bridge 
DRM_BRIDGE_ATTACH_NO_CONNECTOR")
Cc: Neil Armstrong 
Cc: Sam Ravnborg 
Cc: Martin Blumenstingl 
Cc: Neil Armstrong 
Cc: Kevin Hilman 
Cc: Jerome Brunet 
Cc: dri-devel@lists.freedesktop.org
Cc: linux-amlo...@lists.infradead.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: sta...@vger.kernel.org # v5.17+
Signed-off-by: Jani Nikula 
Reviewed-by: Neil Armstrong 
Signed-off-by: Neil Armstrong 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20230914131015.2472029-1-jani.nik...@intel.com
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/gpu/drm/meson/meson_encoder_hdmi.c |2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
@@ -332,6 +332,8 @@ static void meson_encoder_hdmi_hpd_notif
return;
 

cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid);
+
+   kfree(edid);
} else
cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier);
 }


Patches currently in stable-queue which might be from jani.nik...@intel.com are

queue-6.1/drm-meson-fix-memory-leak-on-hpd_notify-callback.patch


Re: [PATCH v3 2/2] drm/amdkfd: get doorbell's absolute offset based on the db size

2023-10-04 Thread Felix Kuehling



On 2023-10-04 12:16, Arvind Yadav wrote:

This patch is to align the absolute doorbell offset
based on the doorbell's size. So that doorbell offset
will be aligned for both 32 bit and 64 bit.

v2:
- Addressed the review comment from Felix.
v3:
- Adding doorbell_size as parameter to get db absolute offset.

Cc: Christian Koenig 
Cc: Alex Deucher 
Signed-off-by: Shashank Sharma 
Signed-off-by: Arvind Yadav 


The final result looks good to me. But please squash the two patches 
into one. The first patch on its own breaks the build, and that's 
something we don't want to commit to the branch history as it makes 
tracking regressions (e.g. with git bisect) very hard or impossible.


More nit-picks inline.



---
  .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c   |  6 +-
  drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c   | 13 +++--
  .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c  |  4 +++-
  3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 0d3d538b64eb..690ff131fe4b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -346,6 +346,7 @@ static int allocate_doorbell(struct qcm_process_device *qpd,
 uint32_t const *restore_id)
  {
struct kfd_node *dev = qpd->dqm->dev;
+   uint32_t doorbell_size;
  
  	if (!KFD_IS_SOC15(dev)) {

/* On pre-SOC15 chips we need to use the queue ID to
@@ -405,9 +406,12 @@ static int allocate_doorbell(struct qcm_process_device 
*qpd,
}
}
  
+	doorbell_size = dev->kfd->device_info.doorbell_size;

+
q->properties.doorbell_off = amdgpu_doorbell_index_on_bar(dev->adev,
  
qpd->proc_doorbells,
- 
q->doorbell_id);
+ 
q->doorbell_id,
+ 
doorbell_size);


You don't need a local variable for doorbell size that's only used once. 
Just pass dev->kfd->device_info.doorbell_size directly.




return 0;
  }
  
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c

index 7b38537c7c99..59dd76c4b138 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
@@ -161,7 +161,10 @@ void __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
if (inx >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)
return NULL;
  
-	*doorbell_off = amdgpu_doorbell_index_on_bar(kfd->adev, kfd->doorbells, inx);

+   *doorbell_off = amdgpu_doorbell_index_on_bar(kfd->adev,
+kfd->doorbells,
+inx,
+
kfd->device_info.doorbell_size);
inx *= 2;
  
  	pr_debug("Get kernel queue doorbell\n"

@@ -233,6 +236,7 @@ phys_addr_t kfd_get_process_doorbells(struct 
kfd_process_device *pdd)
  {
struct amdgpu_device *adev = pdd->dev->adev;
uint32_t first_db_index;
+   uint32_t doorbell_size;
  
  	if (!pdd->qpd.proc_doorbells) {

if (kfd_alloc_process_doorbells(pdd->dev->kfd, pdd))
@@ -240,7 +244,12 @@ phys_addr_t kfd_get_process_doorbells(struct 
kfd_process_device *pdd)
return 0;
}
  
-	first_db_index = amdgpu_doorbell_index_on_bar(adev, pdd->qpd.proc_doorbells, 0);

+   doorbell_size = pdd->dev->kfd->device_info.doorbell_size;
+
+   first_db_index = amdgpu_doorbell_index_on_bar(adev,
+ pdd->qpd.proc_doorbells,
+ 0,
+ doorbell_size);


Same as above, no local variable needed.



return adev->doorbell.base + first_db_index * sizeof(uint32_t);
  }
  
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c

index adb5e4bdc0b2..010cd8e8e6a1 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -375,9 +375,11 @@ int pqm_create_queue(struct process_queue_manager *pqm,
 * relative doorbell index = Absolute doorbell index -
 * absolute index of first doorbell in the page.
 */
+   uint32_t doorbell_size = 
pdd->dev->kfd->device_info.doorbell_size;
uint32_t first_db_index = 
amdgpu_doorbell_index_on_bar(pdd->dev->adev,
   
pdd->qpd.proc_doorbells,
- 

Re: [PATCH v4 2/3] drm/i915/guc: Close deregister-context race against CT-loss

2023-10-04 Thread Teres Alexis, Alan Previn
On Wed, 2023-10-04 at 06:34 +, Gupta, Anshuman wrote:
> 
> > -Original Message-
> > From: Teres Alexis, Alan Previn  > @@ -289,6 +289,13 @@ int intel_gt_resume(struct intel_gt *gt)
> > 
> >  static void wait_for_suspend(struct intel_gt *gt)  {
> > +   /*
> > +* On rare occasions, we've observed the fence completion trigger
> > +* free_engines asynchronously via rcu_call. Ensure those are done.
> > +* This path is only called on suspend, so it's an acceptable cost.
> > +*/
> > +   rcu_barrier();
> Let's add the barrier after the end of prepare suspend and at start of late 
> suspend.
> To make sure we don't have any async destroy from any user request or any 
> internal  kmd request during i915 suspend?
> Br,
> Anshuman Gupta.
alan: some thoughts: actuallly wait_fos_suspend is being called at from both 
intel_gt_suspend_prepare
and intel_gt_suspend_late. so putting the barrier in above location would get 
hit for both steps.
However, because wait_for_suspend may optionally wedge the system if 
outstanding requests were stuck
for more than I915_GT_SUSPEND_IDLE_TIMEOUT, wouldnt it be better to add the 
barrier before that
check (i.e. in above location) as opposed to after the return from 
wait_for_suspend at the end
of suspend_prepare - which would defeat the purpose of even checking that 
intel_gt_wait_for_idle
from within wait_for_suspend? (which is existing code). Perhaps we need to get 
one last test on this?



[PATCH v5 7/7] drm/msm/dp: move of_dp_aux_populate_bus() to eDP probe()

2023-10-04 Thread Kuogee Hsieh
Currently eDP population is done at msm_dp_modeset_init() which happen
at binding time. Move eDP population to be done at display probe time
so that probe deferral cases can be handled effectively.
wait_for_hpd_asserted callback is added during drm_dp_aux_init()
to ensure eDP's HPD is up before proceeding eDP population.

Changes in v5:
-- inline dp_display_auxbus_population() and delete it

Changes in v4:
-- delete duplicate initialize code to dp_aux before drm_dp_aux_register()
-- delete of_get_child_by_name(dev->of_node, "aux-bus") and inline the function
-- not initialize rc = 0

Changes in v3:
-- add done_probing callback into devm_of_dp_aux_populate_bus()

Signed-off-by: Kuogee Hsieh 
---
 drivers/gpu/drm/msm/dp/dp_aux.c | 34 -
 drivers/gpu/drm/msm/dp/dp_display.c | 59 +++--
 2 files changed, 51 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
index 10b6eeb..03f4951 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.c
+++ b/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -479,7 +479,6 @@ void dp_aux_deinit(struct drm_dp_aux *dp_aux)
 
 int dp_aux_register(struct drm_dp_aux *dp_aux)
 {
-   struct dp_aux_private *aux;
int ret;
 
if (!dp_aux) {
@@ -487,12 +486,7 @@ int dp_aux_register(struct drm_dp_aux *dp_aux)
return -EINVAL;
}
 
-   aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
-
-   aux->dp_aux.name = "dpu_dp_aux";
-   aux->dp_aux.dev = aux->dev;
-   aux->dp_aux.transfer = dp_aux_transfer;
-   ret = drm_dp_aux_register(&aux->dp_aux);
+   ret = drm_dp_aux_register(dp_aux);
if (ret) {
DRM_ERROR("%s: failed to register drm aux: %d\n", __func__,
ret);
@@ -507,6 +501,21 @@ void dp_aux_unregister(struct drm_dp_aux *dp_aux)
drm_dp_aux_unregister(dp_aux);
 }
 
+static int dp_wait_hpd_asserted(struct drm_dp_aux *dp_aux,
+unsigned long wait_us)
+{
+   int ret;
+   struct dp_aux_private *aux;
+
+   aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
+
+   pm_runtime_get_sync(aux->dev);
+   ret = dp_catalog_aux_wait_for_hpd_connect_state(aux->catalog);
+   pm_runtime_put_sync(aux->dev);
+
+   return ret;
+}
+
 struct drm_dp_aux *dp_aux_get(struct device *dev, struct dp_catalog *catalog,
  bool is_edp)
 {
@@ -530,6 +539,17 @@ struct drm_dp_aux *dp_aux_get(struct device *dev, struct 
dp_catalog *catalog,
aux->catalog = catalog;
aux->retry_cnt = 0;
 
+   /*
+* Use the drm_dp_aux_init() to use the aux adapter
+* before registering AUX with the DRM device so that
+* msm eDP panel can be detected by generic_dep_panel_probe().
+*/
+   aux->dp_aux.name = "dpu_dp_aux";
+   aux->dp_aux.dev = dev;
+   aux->dp_aux.transfer = dp_aux_transfer;
+   aux->dp_aux.wait_hpd_asserted = dp_wait_hpd_asserted;
+   drm_dp_aux_init(&aux->dp_aux);
+
return &aux->dp_aux;
 }
 
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 79e56d9..df15145 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1207,6 +1207,17 @@ static const struct msm_dp_desc 
*dp_display_get_desc(struct platform_device *pde
return NULL;
 }
 
+static int dp_auxbus_done_probe(struct drm_dp_aux *aux)
+{
+   int rc;
+
+   rc = component_add(aux->dev, &dp_display_comp_ops);
+   if (rc)
+   DRM_ERROR("eDP component add failed, rc=%d\n", rc);
+
+   return rc;
+}
+
 static int dp_display_probe(struct platform_device *pdev)
 {
int rc = 0;
@@ -1272,10 +1283,18 @@ static int dp_display_probe(struct platform_device 
*pdev)
if (rc)
goto err;
 
-   rc = component_add(&pdev->dev, &dp_display_comp_ops);
-   if (rc) {
-   DRM_ERROR("component add failed, rc=%d\n", rc);
-   goto err;
+   if (dp->dp_display.is_edp) {
+   rc = devm_of_dp_aux_populate_bus(dp->aux, dp_auxbus_done_probe);
+   if (rc) {
+   DRM_ERROR("eDP auxbus population failed, rc=%d\n", rc);
+   goto err;
+   }
+   } else {
+   rc = component_add(&pdev->dev, &dp_display_comp_ops);
+   if (rc) {
+   DRM_ERROR("component add failed, rc=%d\n", rc);
+   goto err;
+   }
}
 
return rc;
@@ -1291,7 +1310,6 @@ static int dp_display_remove(struct platform_device *pdev)
 
component_del(&pdev->dev, &dp_display_comp_ops);
dp_display_deinit_sub_modules(dp);
-
platform_set_drvdata(pdev, NULL);
 
return 0;
@@ -1388,29 +1406,8 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
 {
int rc;
struct dp_display_private *dp_pri

[PATCH v5 6/7] drm/msm/dp: delete EV_HPD_INIT_SETUP

2023-10-04 Thread Kuogee Hsieh
EV_HPD_INIT_SETUP flag is used to trigger the initialization of external
DP host controller. Since external DP host controller initialization had
been incorporated into pm_runtime_resume(), this flag became obsolete.
msm_dp_irq_postinstall() which triggers EV_HPD_INIT_SETUP event is
obsoleted accordingly.

Changes in v4:
-- reworded commit text
-- drop EV_HPD_INIT_SETUP
-- drop msm_dp_irq_postinstall()

Changes in v3:
-- drop EV_HPD_INIT_SETUP and msm_dp_irq_postinstall()

Signed-off-by: Kuogee Hsieh 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  4 
 drivers/gpu/drm/msm/dp/dp_display.c | 16 
 drivers/gpu/drm/msm/msm_drv.h   |  5 -
 3 files changed, 25 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index aa6ba2c..146f263 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -869,7 +869,6 @@ static int dpu_irq_postinstall(struct msm_kms *kms)
 {
struct msm_drm_private *priv;
struct dpu_kms *dpu_kms = to_dpu_kms(kms);
-   int i;
 
if (!dpu_kms || !dpu_kms->dev)
return -EINVAL;
@@ -878,9 +877,6 @@ static int dpu_irq_postinstall(struct msm_kms *kms)
if (!priv)
return -EINVAL;
 
-   for (i = 0; i < ARRAY_SIZE(priv->dp); i++)
-   msm_dp_irq_postinstall(priv->dp[i]);
-
return 0;
 }
 
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 42efe148b..79e56d9 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -54,7 +54,6 @@ enum {
 enum {
EV_NO_EVENT,
/* hpd events */
-   EV_HPD_INIT_SETUP,
EV_HPD_PLUG_INT,
EV_IRQ_HPD_INT,
EV_HPD_UNPLUG_INT,
@@ -1089,8 +1088,6 @@ static int hpd_event_thread(void *data)
spin_unlock_irqrestore(&dp_priv->event_lock, flag);
 
switch (todo->event_id) {
-   case EV_HPD_INIT_SETUP:
-   break;
case EV_HPD_PLUG_INT:
dp_hpd_plug_handle(dp_priv, todo->data);
break;
@@ -1359,19 +1356,6 @@ void __exit msm_dp_unregister(void)
platform_driver_unregister(&dp_display_driver);
 }
 
-void msm_dp_irq_postinstall(struct msm_dp *dp_display)
-{
-   struct dp_display_private *dp;
-
-   if (!dp_display)
-   return;
-
-   dp = container_of(dp_display, struct dp_display_private, dp_display);
-
-   if (!dp_display->is_edp)
-   dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 0);
-}
-
 bool msm_dp_wide_bus_available(const struct msm_dp *dp_display)
 {
struct dp_display_private *dp;
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 02fd6c7..30723da 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -384,7 +384,6 @@ int __init msm_dp_register(void);
 void __exit msm_dp_unregister(void);
 int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
 struct drm_encoder *encoder);
-void msm_dp_irq_postinstall(struct msm_dp *dp_display);
 void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp 
*dp_display);
 
 void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor);
@@ -405,10 +404,6 @@ static inline int msm_dp_modeset_init(struct msm_dp 
*dp_display,
return -EINVAL;
 }
 
-static inline void msm_dp_irq_postinstall(struct msm_dp *dp_display)
-{
-}
-
 static inline void msm_dp_snapshot(struct msm_disp_state *disp_state, struct 
msm_dp *dp_display)
 {
 }
-- 
2.7.4



[PATCH v5 5/7] drm/msm/dp: incorporate pm_runtime framework into DP driver

2023-10-04 Thread Kuogee Hsieh
Currently DP driver is executed independent of PM runtime framework.
This leads msm eDP panel can not being detected by edp_panel driver during
generic_edp_panel_probe() due to AUX DPCD read failed at edp panel driver.
Incorporate PM runtime framework into DP driver so that host controller's
power and clocks are enable/disable through PM runtime mechanism.
Once PM runtime framework is incorporated into DP driver, waking up device
from power up path is not necessary. Hence remove it.

After incorporating pm_runtime framework into eDP/DP driver, dp_pm_suspend()
to handle power off both DP phy and controller during suspend and
dp_pm_resume() to handle power on both DP phy and controller during resume
are not necessary. Therefore both dp_pm_suspend() and dp_pm_resume() are
dropped and replace with dp_pm_runtime_suspend() and dp_pm_runtime_resume()
respectively.

Changes in v5:
-- remove pm_runtime_put_autosuspend feature, use pm_runtime_put_sync() directly
-- squash add pm_runtime_force_suspend()/resume() patch into this patch

Changes in v4:
-- reworded commit text to explain why pm_framework is required for edp panel
-- reworded commit text to explain autosuspend is choiced
-- delete EV_POWER_PM_GET and PM_EV_POWER_PUT from changes #3
-- delete dp_display_pm_get() and dp_display_pm_Put() from changes #3
-- return value from pm_runtime_resume_and_get() directly
-- check return value of devm_pm_runtime_enable()
-- delete pm_runtime_xxx from dp_display_remove()
-- drop dp_display_host_init() from EV_HPD_INIT_SETUP
-- drop both dp_pm_prepare() and dp_pm_compete() from this change
-- delete ST_SUSPENDED state
-- rewording commit text to add more details regrading the purpose
   of this change

Changes in v3:
-- incorporate removing pm_runtime_xx() from dp_pwer.c to this patch
-- use pm_runtime_resume_and_get() instead of pm_runtime_get()
-- error checking pm_runtime_resume_and_get() return value
-- add EV_POWER_PM_GET and PM_EV_POWER_PUT to handle HPD_GPIO case
-- replace dp_pm_suspend() with pm_runtime_force_suspend()
-- replace dp_pm_resume() with pm_runtime_force_resume()

Signed-off-by: Kuogee Hsieh 
Reported-by: kernel test robot 
---
 drivers/gpu/drm/msm/dp/dp_aux.c |   5 ++
 drivers/gpu/drm/msm/dp/dp_display.c | 166 
 drivers/gpu/drm/msm/dp/dp_power.c   |  16 
 drivers/gpu/drm/msm/dp/dp_power.h   |  11 ---
 4 files changed, 59 insertions(+), 139 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
index 8e3b677..10b6eeb 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.c
+++ b/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -291,6 +291,10 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux,
return -EINVAL;
}
 
+   ret = pm_runtime_resume_and_get(dp_aux->dev);
+   if (ret)
+   return  ret;
+
mutex_lock(&aux->mutex);
if (!aux->initted) {
ret = -EIO;
@@ -364,6 +368,7 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux,
 
 exit:
mutex_unlock(&aux->mutex);
+   pm_runtime_put_sync(dp_aux->dev);
 
return ret;
 }
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index e4942fc..42efe148b 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -49,7 +49,6 @@ enum {
ST_CONNECTED,
ST_DISCONNECT_PENDING,
ST_DISPLAY_OFF,
-   ST_SUSPENDED,
 };
 
 enum {
@@ -310,15 +309,10 @@ static void dp_display_unbind(struct device *dev, struct 
device *master,
struct dp_display_private *dp = dev_get_dp_display_private(dev);
struct msm_drm_private *priv = dev_get_drvdata(master);
 
-   /* disable all HPD interrupts */
-   if (dp->core_initialized)
-   dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, 
false);
-
kthread_stop(dp->ev_tsk);
 
of_dp_aux_depopulate_bus(dp->aux);
 
-   dp_power_client_deinit(dp->power);
dp_unregister_audio_driver(dev, dp->audio);
dp_aux_unregister(dp->aux);
dp->drm_dev = NULL;
@@ -559,7 +553,7 @@ static int dp_hpd_plug_handle(struct dp_display_private 
*dp, u32 data)
drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
dp->dp_display.connector_type, state);
 
-   if (state == ST_DISPLAY_OFF || state == ST_SUSPENDED) {
+   if (state == ST_DISPLAY_OFF) {
mutex_unlock(&dp->event_mutex);
return 0;
}
@@ -576,6 +570,14 @@ static int dp_hpd_plug_handle(struct dp_display_private 
*dp, u32 data)
return 0;
}
 
+   if (!dp->dp_display.is_edp) {
+   ret = pm_runtime_resume_and_get(&dp->pdev->dev);
+   if (ret) {
+   DRM_ERROR("failed to pm_runtime_resume\n");
+   return ret;
+   }
+   }
+
ret = dp_display_usbpd_configure_cb(&dp->pdev->dev);
if (ret) { 

[PATCH v5 4/7] drm/msm/dp: move parser->parse() and dp_power_client_init() to probe

2023-10-04 Thread Kuogee Hsieh
Original both parser->parse() and dp_power_client_init() are done at
dp_display_bind() since eDP population is done at binding time.
In the preparation of having eDP population done at probe() time,
move both function from dp_display_bind() to dp_display_probe().

Changes in v4:
-- explain why parser->parse() and dp_power_client_init() are moved to probe 
time
-- tear down sub modules if failed

Changes in v4:
-- split this patch out of "incorporate pm_runtime framework into DP driver" 
patch

Signed-off-by: Kuogee Hsieh 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 22 --
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 32663ea..e4942fc 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -276,11 +276,6 @@ static int dp_display_bind(struct device *dev, struct 
device *master,
dp->dp_display.drm_dev = drm;
priv->dp[dp->id] = &dp->dp_display;
 
-   rc = dp->parser->parse(dp->parser);
-   if (rc) {
-   DRM_ERROR("device tree parsing failed\n");
-   goto end;
-   }
 
 
dp->drm_dev = drm;
@@ -291,11 +286,6 @@ static int dp_display_bind(struct device *dev, struct 
device *master,
goto end;
}
 
-   rc = dp_power_client_init(dp->power);
-   if (rc) {
-   DRM_ERROR("Power client create failed\n");
-   goto end;
-   }
 
rc = dp_register_audio_driver(dev, dp->audio);
if (rc) {
@@ -1250,6 +1240,18 @@ static int dp_display_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
}
 
+   rc = dp->parser->parse(dp->parser);
+   if (rc) {
+   DRM_ERROR("device tree parsing failed\n");
+   goto err;
+   }
+
+   rc = dp_power_client_init(dp->power);
+   if (rc) {
+   DRM_ERROR("Power client create failed\n");
+   goto err;
+   }
+
/* setup event q */
mutex_init(&dp->event_mutex);
init_waitqueue_head(&dp->event_q);
-- 
2.7.4



[PATCH v5 2/7] drm/msm/dp: rename is_connected with link_ready

2023-10-04 Thread Kuogee Hsieh
The is_connected flag is set to true after DP mainlink successfully
finishes link training to enter into ST_MAINLINK_READY state rather
than being set after the DP dongle is connected. Rename the
is_connected flag with link_ready flag to match the state of DP
driver's state machine.

Changes in v5:
-- reworded commit text according to review comments from change #4

Changes in v4:
-- reworded commit text

Signed-off-by: Kuogee Hsieh 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 19 +--
 drivers/gpu/drm/msm/dp/dp_display.h |  2 +-
 drivers/gpu/drm/msm/dp/dp_drm.c | 14 +++---
 3 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 940da48..9e51876 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -367,12 +367,11 @@ static void dp_display_send_hpd_event(struct msm_dp 
*dp_display)
drm_helper_hpd_irq_event(connector->dev);
 }
 
-
 static int dp_display_send_hpd_notification(struct dp_display_private *dp,
bool hpd)
 {
-   if ((hpd && dp->dp_display.is_connected) ||
-   (!hpd && !dp->dp_display.is_connected)) {
+   if ((hpd && dp->dp_display.link_ready) ||
+   (!hpd && !dp->dp_display.link_ready)) {
drm_dbg_dp(dp->drm_dev, "HPD already %s\n",
(hpd ? "on" : "off"));
return 0;
@@ -382,7 +381,7 @@ static int dp_display_send_hpd_notification(struct 
dp_display_private *dp,
if (!hpd)
dp->panel->video_test = false;
 
-   dp->dp_display.is_connected = hpd;
+   dp->dp_display.link_ready = hpd;
 
drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n",
dp->dp_display.connector_type, hpd);
@@ -922,7 +921,7 @@ int dp_display_set_plugged_cb(struct msm_dp *dp_display,
 
dp_display->plugged_cb = fn;
dp_display->codec_dev = codec_dev;
-   plugged = dp_display->is_connected;
+   plugged = dp_display->link_ready;
dp_display_handle_plugged_change(dp_display, plugged);
 
return 0;
@@ -1355,16 +1354,16 @@ static int dp_pm_resume(struct device *dev)
 * also only signal audio when disconnected
 */
if (dp->link->sink_count) {
-   dp->dp_display.is_connected = true;
+   dp->dp_display.link_ready = true;
} else {
-   dp->dp_display.is_connected = false;
+   dp->dp_display.link_ready = false;
dp_display_handle_plugged_change(dp_display, false);
}
 
drm_dbg_dp(dp->drm_dev,
"After, type=%d sink=%d conn=%d core_init=%d phy_init=%d 
power=%d\n",
dp->dp_display.connector_type, dp->link->sink_count,
-   dp->dp_display.is_connected, dp->core_initialized,
+   dp->dp_display.link_ready, dp->core_initialized,
dp->phy_initialized, dp_display->power_on);
 
mutex_unlock(&dp->event_mutex);
@@ -1757,8 +1756,8 @@ void dp_bridge_hpd_notify(struct drm_bridge *bridge,
return;
}
 
-   if (!dp_display->is_connected && status == connector_status_connected)
+   if (!dp_display->link_ready && status == connector_status_connected)
dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);
-   else if (dp_display->is_connected && status == 
connector_status_disconnected)
+   else if (dp_display->link_ready && status == 
connector_status_disconnected)
dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
 }
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h 
b/drivers/gpu/drm/msm/dp/dp_display.h
index b3c08de..d65693e 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -16,7 +16,7 @@ struct msm_dp {
struct drm_bridge *bridge;
struct drm_connector *connector;
struct drm_bridge *next_bridge;
-   bool is_connected;
+   bool link_ready;
bool audio_enabled;
bool power_on;
unsigned int connector_type;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 785d766..ee945ca 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -24,10 +24,10 @@ static enum drm_connector_status dp_bridge_detect(struct 
drm_bridge *bridge)
 
dp = to_dp_bridge(bridge)->dp_display;
 
-   drm_dbg_dp(dp->drm_dev, "is_connected = %s\n",
-   (dp->is_connected) ? "true" : "false");
+   drm_dbg_dp(dp->drm_dev, "link_ready = %s\n",
+   (dp->link_ready) ? "true" : "false");
 
-   return (dp->is_connected) ? connector_status_connected :
+   return (dp->link_ready) ? connector_status_connected :
connector_status_disconnected;
 }
 
@@ -40,8 +40,8 @@ static int dp_bridge_atomic_check(struct drm_bridge *bridge,
 
dp = t

[PATCH v5 3/7] drm/msm/dp: use drm_bridge_hpd_notify() to report HPD status changes

2023-10-04 Thread Kuogee Hsieh
Currently DP driver use drm_helper_hpd_irq_event(), bypassing drm bridge
framework, to report HPD status changes to user space frame work.
Replace it with drm_bridge_hpd_notify() since DP driver is part of drm
bridge.

Signed-off-by: Kuogee Hsieh 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 20 ++--
 1 file changed, 2 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 9e51876..32663ea 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -356,26 +356,10 @@ static bool dp_display_is_sink_count_zero(struct 
dp_display_private *dp)
(dp->link->sink_count == 0);
 }
 
-static void dp_display_send_hpd_event(struct msm_dp *dp_display)
-{
-   struct dp_display_private *dp;
-   struct drm_connector *connector;
-
-   dp = container_of(dp_display, struct dp_display_private, dp_display);
-
-   connector = dp->dp_display.connector;
-   drm_helper_hpd_irq_event(connector->dev);
-}
-
 static int dp_display_send_hpd_notification(struct dp_display_private *dp,
bool hpd)
 {
-   if ((hpd && dp->dp_display.link_ready) ||
-   (!hpd && !dp->dp_display.link_ready)) {
-   drm_dbg_dp(dp->drm_dev, "HPD already %s\n",
-   (hpd ? "on" : "off"));
-   return 0;
-   }
+   struct drm_bridge *bridge = dp->dp_display.bridge;
 
/* reset video pattern flag on disconnect */
if (!hpd)
@@ -385,7 +369,7 @@ static int dp_display_send_hpd_notification(struct 
dp_display_private *dp,
 
drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n",
dp->dp_display.connector_type, hpd);
-   dp_display_send_hpd_event(&dp->dp_display);
+   drm_bridge_hpd_notify(bridge, dp->dp_display.link_ready);
 
return 0;
 }
-- 
2.7.4



[PATCH v5 1/7] drm/msm/dp: tie dp_display_irq_handler() with dp driver

2023-10-04 Thread Kuogee Hsieh
Currently the dp_display_request_irq() is executed at msm_dp_modeset_init()
which ties irq registering to the DPU device's life cycle, while depending on
resources that are released as the DP device is torn down. Move register DP
driver irq handler to dp_display_probe() to have dp_display_irq_handler()
IRQ tied with DP device. In addition, use platform_get_irq() to retrieve irq
number from platform device directly.

Changes in v5:
-- reworded commit text as review comments at change #4
-- tear down component if failed at dp_display_request_irq()

Changes in v4:
-- delete dp->irq check at dp_display_request_irq()

Changes in v3:
-- move calling dp_display_irq_handler() to probe

Signed-off-by: Kuogee Hsieh 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 32 +---
 drivers/gpu/drm/msm/dp/dp_display.h |  1 -
 2 files changed, 13 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 76f1395..940da48 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1193,26 +1193,18 @@ static irqreturn_t dp_display_irq_handler(int irq, void 
*dev_id)
return ret;
 }
 
-int dp_display_request_irq(struct msm_dp *dp_display)
+static int dp_display_request_irq(struct dp_display_private *dp)
 {
int rc = 0;
-   struct dp_display_private *dp;
-
-   if (!dp_display) {
-   DRM_ERROR("invalid input\n");
-   return -EINVAL;
-   }
-
-   dp = container_of(dp_display, struct dp_display_private, dp_display);
+   struct device *dev = &dp->pdev->dev;
 
-   dp->irq = irq_of_parse_and_map(dp->pdev->dev.of_node, 0);
+   dp->irq = platform_get_irq(dp->pdev, 0);
if (!dp->irq) {
DRM_ERROR("failed to get irq\n");
return -EINVAL;
}
 
-   rc = devm_request_irq(dp_display->drm_dev->dev, dp->irq,
-   dp_display_irq_handler,
+   rc = devm_request_irq(dev, dp->irq, dp_display_irq_handler,
IRQF_TRIGGER_HIGH, "dp_display_isr", dp);
if (rc < 0) {
DRM_ERROR("failed to request IRQ%u: %d\n",
@@ -1287,13 +1279,21 @@ static int dp_display_probe(struct platform_device 
*pdev)
 
platform_set_drvdata(pdev, &dp->dp_display);
 
+   rc = dp_display_request_irq(dp);
+   if (rc)
+   goto err;
+
rc = component_add(&pdev->dev, &dp_display_comp_ops);
if (rc) {
DRM_ERROR("component add failed, rc=%d\n", rc);
-   dp_display_deinit_sub_modules(dp);
+   goto err;
}
 
return rc;
+
+err:
+   dp_display_deinit_sub_modules(dp);
+   return rc;
 }
 
 static int dp_display_remove(struct platform_device *pdev)
@@ -1549,12 +1549,6 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, 
struct drm_device *dev,
 
dp_priv = container_of(dp_display, struct dp_display_private, 
dp_display);
 
-   ret = dp_display_request_irq(dp_display);
-   if (ret) {
-   DRM_ERROR("request_irq failed, ret=%d\n", ret);
-   return ret;
-   }
-
ret = dp_display_get_next_bridge(dp_display);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h 
b/drivers/gpu/drm/msm/dp/dp_display.h
index 1e9415a..b3c08de 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -35,7 +35,6 @@ struct msm_dp {
 int dp_display_set_plugged_cb(struct msm_dp *dp_display,
hdmi_codec_plugged_cb fn, struct device *codec_dev);
 int dp_display_get_modes(struct msm_dp *dp_display);
-int dp_display_request_irq(struct msm_dp *dp_display);
 bool dp_display_check_video_test(struct msm_dp *dp_display);
 int dp_display_get_test_bpp(struct msm_dp *dp_display);
 void dp_display_signal_audio_start(struct msm_dp *dp_display);
-- 
2.7.4



[PATCH v5 0/7] incorporate pm runtime framework and eDP clean up

2023-10-04 Thread Kuogee Hsieh
The purpose of this patch series is to incorporate pm runtime framework
into MSM eDP/DP driver so that eDP panel can be detected by DRM eDP panel
driver during system probe time. During incorporating procedure, original
customized pm realted fucntions, such as dp_pm_prepare(), dp_pm_suspend(),
dp_pm_resume() and dp_pm_prepare(), are removed and replaced with functions
provided by pm runtiem framework such as pm_runtime_force_suspend() and
pm_runtime_force_resume(). In addition, both eDP aux-bus and irq handler
are bound at system probe time too.

Kuogee Hsieh (7):
  drm/msm/dp: tie dp_display_irq_handler() with dp driver
  drm/msm/dp: rename is_connected with link_ready
  drm/msm/dp: use drm_bridge_hpd_notify() to report HPD status changes
  drm/msm/dp: move parser->parse() and dp_power_client_init() to probe
  drm/msm/dp: incorporate pm_runtime framework into DP driver
  drm/msm/dp: delete EV_HPD_INIT_SETUP
  drm/msm/dp: move of_dp_aux_populate_bus() to eDP probe()

 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |   4 -
 drivers/gpu/drm/msm/dp/dp_aux.c |  39 +++-
 drivers/gpu/drm/msm/dp/dp_display.c | 318 +++-
 drivers/gpu/drm/msm/dp/dp_display.h |   3 +-
 drivers/gpu/drm/msm/dp/dp_drm.c |  14 +-
 drivers/gpu/drm/msm/dp/dp_power.c   |  16 --
 drivers/gpu/drm/msm/dp/dp_power.h   |  11 --
 drivers/gpu/drm/msm/msm_drv.h   |   5 -
 8 files changed, 146 insertions(+), 264 deletions(-)

-- 
2.7.4



[PATCH] drm/dp: switch drm_dp_downstream_*() helpers to struct drm_edid

2023-10-04 Thread Jani Nikula
Prefer struct drm_edid where possible. With limited users for the
drm_dp_downstream_*() helpers, this is fairly straightforward.

Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/display/drm_dp_helper.c   | 39 ++-
 .../drm/i915/display/intel_display_debugfs.c  |  3 +-
 drivers/gpu/drm/i915/display/intel_dp.c   | 10 ++---
 include/drm/display/drm_dp_helper.h   | 12 +++---
 4 files changed, 31 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index 8a1b64c57dfd..f3680f4e6970 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -746,8 +746,11 @@ int drm_dp_dpcd_read_phy_link_status(struct drm_dp_aux 
*aux,
 }
 EXPORT_SYMBOL(drm_dp_dpcd_read_phy_link_status);
 
-static bool is_edid_digital_input_dp(const struct edid *edid)
+static bool is_edid_digital_input_dp(const struct drm_edid *drm_edid)
 {
+   /* FIXME: get rid of drm_edid_raw() */
+   const struct edid *edid = drm_edid_raw(drm_edid);
+
return edid && edid->revision >= 4 &&
edid->input & DRM_EDID_INPUT_DIGITAL &&
(edid->input & DRM_EDID_DIGITAL_TYPE_MASK) == 
DRM_EDID_DIGITAL_TYPE_DP;
@@ -779,13 +782,13 @@ EXPORT_SYMBOL(drm_dp_downstream_is_type);
  * drm_dp_downstream_is_tmds() - is the downstream facing port TMDS?
  * @dpcd: DisplayPort configuration data
  * @port_cap: port capabilities
- * @edid: EDID
+ * @drm_edid: EDID
  *
  * Returns: whether the downstream facing port is TMDS (HDMI/DVI).
  */
 bool drm_dp_downstream_is_tmds(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
   const u8 port_cap[4],
-  const struct edid *edid)
+  const struct drm_edid *drm_edid)
 {
if (dpcd[DP_DPCD_REV] < 0x11) {
switch (dpcd[DP_DOWNSTREAMPORT_PRESENT] & 
DP_DWN_STRM_PORT_TYPE_MASK) {
@@ -798,7 +801,7 @@ bool drm_dp_downstream_is_tmds(const u8 
dpcd[DP_RECEIVER_CAP_SIZE],
 
switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
case DP_DS_PORT_TYPE_DP_DUALMODE:
-   if (is_edid_digital_input_dp(edid))
+   if (is_edid_digital_input_dp(drm_edid))
return false;
fallthrough;
case DP_DS_PORT_TYPE_DVI:
@@ -1036,14 +1039,14 @@ EXPORT_SYMBOL(drm_dp_downstream_max_dotclock);
  * drm_dp_downstream_max_tmds_clock() - extract downstream facing port max 
TMDS clock
  * @dpcd: DisplayPort configuration data
  * @port_cap: port capabilities
- * @edid: EDID
+ * @drm_edid: EDID
  *
  * Returns: HDMI/DVI downstream facing port max TMDS clock in kHz on success,
  * or 0 if max TMDS clock not defined
  */
 int drm_dp_downstream_max_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 const u8 port_cap[4],
-const struct edid *edid)
+const struct drm_edid *drm_edid)
 {
if (!drm_dp_is_branch(dpcd))
return 0;
@@ -1059,7 +1062,7 @@ int drm_dp_downstream_max_tmds_clock(const u8 
dpcd[DP_RECEIVER_CAP_SIZE],
 
switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
case DP_DS_PORT_TYPE_DP_DUALMODE:
-   if (is_edid_digital_input_dp(edid))
+   if (is_edid_digital_input_dp(drm_edid))
return 0;
/*
 * It's left up to the driver to check the
@@ -1101,14 +1104,14 @@ EXPORT_SYMBOL(drm_dp_downstream_max_tmds_clock);
  * drm_dp_downstream_min_tmds_clock() - extract downstream facing port min 
TMDS clock
  * @dpcd: DisplayPort configuration data
  * @port_cap: port capabilities
- * @edid: EDID
+ * @drm_edid: EDID
  *
  * Returns: HDMI/DVI downstream facing port min TMDS clock in kHz on success,
  * or 0 if max TMDS clock not defined
  */
 int drm_dp_downstream_min_tmds_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
 const u8 port_cap[4],
-const struct edid *edid)
+const struct drm_edid *drm_edid)
 {
if (!drm_dp_is_branch(dpcd))
return 0;
@@ -1124,7 +1127,7 @@ int drm_dp_downstream_min_tmds_clock(const u8 
dpcd[DP_RECEIVER_CAP_SIZE],
 
switch (port_cap[0] & DP_DS_PORT_TYPE_MASK) {
case DP_DS_PORT_TYPE_DP_DUALMODE:
-   if (is_edid_digital_input_dp(edid))
+   if (is_edid_digital_input_dp(drm_edid))
return 0;
fallthrough;
case DP_DS_PORT_TYPE_DVI:
@@ -1145,13 +1148,13 @@ EXPORT_SYMBOL(drm_dp_downstream_min_tmds_clock);
  *   bits per component
  * @dpcd: DisplayPort configuration data
  * @port_cap: downstream facing port capabilities
- * @edid: EDID
+ * @drm_edid: EDID
  *
  * Returns: Max bpc on success or 0 if max bpc not defined
  */
 int drm_dp_downstream_max_bpc(const u8 dpcd[DP_

Patch "drm/meson: fix memory leak on ->hpd_notify callback" has been added to the 5.15-stable tree

2023-10-04 Thread gregkh


This is a note to let you know that I've just added the patch titled

drm/meson: fix memory leak on ->hpd_notify callback

to the 5.15-stable tree which can be found at:

http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
 drm-meson-fix-memory-leak-on-hpd_notify-callback.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let  know about it.


>From 099f0af9d98231bb74956ce92508e87cbcb896be Mon Sep 17 00:00:00 2001
From: Jani Nikula 
Date: Thu, 14 Sep 2023 16:10:15 +0300
Subject: drm/meson: fix memory leak on ->hpd_notify callback

From: Jani Nikula 

commit 099f0af9d98231bb74956ce92508e87cbcb896be upstream.

The EDID returned by drm_bridge_get_edid() needs to be freed.

Fixes: 0af5e0b41110 ("drm/meson: encoder_hdmi: switch to bridge 
DRM_BRIDGE_ATTACH_NO_CONNECTOR")
Cc: Neil Armstrong 
Cc: Sam Ravnborg 
Cc: Martin Blumenstingl 
Cc: Neil Armstrong 
Cc: Kevin Hilman 
Cc: Jerome Brunet 
Cc: dri-devel@lists.freedesktop.org
Cc: linux-amlo...@lists.infradead.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: sta...@vger.kernel.org # v5.17+
Signed-off-by: Jani Nikula 
Reviewed-by: Neil Armstrong 
Signed-off-by: Neil Armstrong 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20230914131015.2472029-1-jani.nik...@intel.com
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/gpu/drm/meson/meson_encoder_hdmi.c |2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
@@ -326,6 +326,8 @@ static void meson_encoder_hdmi_hpd_notif
return;
 

cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid);
+
+   kfree(edid);
} else
cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier);
 }


Patches currently in stable-queue which might be from jani.nik...@intel.com are

queue-5.15/drm-meson-fix-memory-leak-on-hpd_notify-callback.patch


Re: [Intel-gfx] [PATCH v2] drm/i915: Reduce MCR lock surface

2023-10-04 Thread Nirmoy Das

Hi Rodrigo,

On 10/4/2023 4:37 PM, Rodrigo Vivi wrote:

On Wed, Oct 04, 2023 at 03:54:59PM +0200, Nirmoy Das wrote:

Hi Rodrigo,

On 10/4/2023 2:44 PM, Rodrigo Vivi wrote:

On Wed, Oct 04, 2023 at 02:04:07PM +0200, Nirmoy Das wrote:

Take the mcr lock only when driver needs to write into a mcr based
tlb based registers.

To prevent GT reset interference, employ gt->reset.mutex instead, since
intel_gt_mcr_multicast_write relies on gt->uncore->lock not being held.

This looks a lot like protecting code and not protecting data [1]

But to be really honest I'm afraid we were already doing this before
this patch but with 2 other locks instead.

I haven't thought about that but yes, the issue was there already.



[1] - https://blog.ffwll.ch/2022/07/locking-engineering.html


v2: remove unused var, flags.

Signed-off-by: Nirmoy Das 
---
   drivers/gpu/drm/i915/gt/intel_tlb.c | 13 +
   1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_tlb.c 
b/drivers/gpu/drm/i915/gt/intel_tlb.c
index 139608c30d97..0ad905df4a98 100644
--- a/drivers/gpu/drm/i915/gt/intel_tlb.c
+++ b/drivers/gpu/drm/i915/gt/intel_tlb.c
@@ -52,15 +52,13 @@ static void mmio_invalidate_full(struct intel_gt *gt)
struct intel_engine_cs *engine;
intel_engine_mask_t awake, tmp;
enum intel_engine_id id;
-   unsigned long flags;
if (GRAPHICS_VER(i915) < 8)
return;
intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
-   intel_gt_mcr_lock(gt, &flags);
-   spin_lock(&uncore->lock); /* serialise invalidate with GT reset */
+   mutex_lock(>->reset.mutex);/* serialise invalidate with GT reset */

I'm still looking at this and the commit message above and trying to understand
why we are doing this and changing the previous 2 by this other one. why?


We need the MCR lock only for intel_gt_mcr_multicast_*() so I am not
replacing the two locks here but moving the mcr lock down

where we were doing intel_gt_mcr_multicast_write_fw()


why s/spin_lock(&uncore->lock)/mutex_lock(>->reset.mutex):

intel_gt_mcr_multicast_*() expects gt->uncore->lock to be not held

is there any lockdep assert or primitive that we could/should do
that to avoid this same issue in the future?


We have locdep asserts for those mcr functions.



anyway, this is also another thing that it is important for the
commit message.

and why is that? what I have in mind goes along with the comment
above intel_de_read_fw():
"""
Access to registers should
  * therefore generally be serialised, by either the dev_priv->uncore.lock or
"""


Yes, the commit message should've been more clear.


Anyways, please ignore this patch. I need to find a better way and it 
also didn't fix the issue completely that I was working on.



Thanks,

Nirmoy




and to
achieve this, I could do something like:

if (engine->tlb_inv.mcr) {

      spin_unlock(&uncore->lock);

  intel_gt_mcr_lock(gt, &flags);

  intel_gt_mcr_multicast_write_fw

  intel_gt_mcr_unlock(gt, flags);

     spin_lock(&uncore->lock);

}

Or take gt->reset.mutex instead which should block any concurrent gt reset.

If this is not acceptable then I can pick the above 1st option but I am not
sure how safe is it do release uncore->lock and then take it back again.

hmm... probably the gt_reset one is better than releasing and grabbing it
again.


awake = 0;
for_each_engine(engine, gt, id) {
@@ -68,9 +66,9 @@ static void mmio_invalidate_full(struct intel_gt *gt)
continue;
if (engine->tlb_inv.mcr)
-   intel_gt_mcr_multicast_write_fw(gt,
-   
engine->tlb_inv.reg.mcr_reg,
-   
engine->tlb_inv.request);
+   intel_gt_mcr_multicast_write(gt,
+
engine->tlb_inv.reg.mcr_reg,
+engine->tlb_inv.request);

you are already taking the forcewake_all domain above, so you wouldn't
need to convert this to the variant that grabs the forcewake underneath.

Also this is not mentioned in the commit message above.

intel_gt_mcr_multicast_write() takes the mcr lock for us, helps replacing 
multiple lines into one.
Will there be any side-effects for that ?

hmm... I can't forsee side-effects here... but I'm asking myself why on the non
MCR ones we are using the global forcewake_all and the _fw to start with.
Maybe there was a reason for that? Because in general we should prefer the non 
_fw
variants to start with. Maybe we should dig into the history there to understand
why the line below started with the intel_uncore_write_fw below?


I should've added that the commit message.

I'm even wondering if this should be 2 separated patches?!


Regards,
Nirmoy



else
intel_uncore_write_fw(uncore,
  

[PATCH v3 2/2] drm/amdkfd: get doorbell's absolute offset based on the db size

2023-10-04 Thread Arvind Yadav
This patch is to align the absolute doorbell offset
based on the doorbell's size. So that doorbell offset
will be aligned for both 32 bit and 64 bit.

v2:
- Addressed the review comment from Felix.
v3:
- Adding doorbell_size as parameter to get db absolute offset.

Cc: Christian Koenig 
Cc: Alex Deucher 
Signed-off-by: Shashank Sharma 
Signed-off-by: Arvind Yadav 
---
 .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c   |  6 +-
 drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c   | 13 +++--
 .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c  |  4 +++-
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 0d3d538b64eb..690ff131fe4b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -346,6 +346,7 @@ static int allocate_doorbell(struct qcm_process_device *qpd,
 uint32_t const *restore_id)
 {
struct kfd_node *dev = qpd->dqm->dev;
+   uint32_t doorbell_size;
 
if (!KFD_IS_SOC15(dev)) {
/* On pre-SOC15 chips we need to use the queue ID to
@@ -405,9 +406,12 @@ static int allocate_doorbell(struct qcm_process_device 
*qpd,
}
}
 
+   doorbell_size = dev->kfd->device_info.doorbell_size;
+
q->properties.doorbell_off = amdgpu_doorbell_index_on_bar(dev->adev,
  
qpd->proc_doorbells,
- 
q->doorbell_id);
+ 
q->doorbell_id,
+ 
doorbell_size);
return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
index 7b38537c7c99..59dd76c4b138 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
@@ -161,7 +161,10 @@ void __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
if (inx >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)
return NULL;
 
-   *doorbell_off = amdgpu_doorbell_index_on_bar(kfd->adev, kfd->doorbells, 
inx);
+   *doorbell_off = amdgpu_doorbell_index_on_bar(kfd->adev,
+kfd->doorbells,
+inx,
+
kfd->device_info.doorbell_size);
inx *= 2;
 
pr_debug("Get kernel queue doorbell\n"
@@ -233,6 +236,7 @@ phys_addr_t kfd_get_process_doorbells(struct 
kfd_process_device *pdd)
 {
struct amdgpu_device *adev = pdd->dev->adev;
uint32_t first_db_index;
+   uint32_t doorbell_size;
 
if (!pdd->qpd.proc_doorbells) {
if (kfd_alloc_process_doorbells(pdd->dev->kfd, pdd))
@@ -240,7 +244,12 @@ phys_addr_t kfd_get_process_doorbells(struct 
kfd_process_device *pdd)
return 0;
}
 
-   first_db_index = amdgpu_doorbell_index_on_bar(adev, 
pdd->qpd.proc_doorbells, 0);
+   doorbell_size = pdd->dev->kfd->device_info.doorbell_size;
+
+   first_db_index = amdgpu_doorbell_index_on_bar(adev,
+ pdd->qpd.proc_doorbells,
+ 0,
+ doorbell_size);
return adev->doorbell.base + first_db_index * sizeof(uint32_t);
 }
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index adb5e4bdc0b2..010cd8e8e6a1 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -375,9 +375,11 @@ int pqm_create_queue(struct process_queue_manager *pqm,
 * relative doorbell index = Absolute doorbell index -
 * absolute index of first doorbell in the page.
 */
+   uint32_t doorbell_size = 
pdd->dev->kfd->device_info.doorbell_size;
uint32_t first_db_index = 
amdgpu_doorbell_index_on_bar(pdd->dev->adev,
   
pdd->qpd.proc_doorbells,
-  0);
+  0,
+  
doorbell_size);
 
*p_doorbell_offset_in_process = (q->properties.doorbell_off
- first_db_index) * 
sizeof(uint32_t);
-- 
2.34.1



[PATCH v3 1/2] drm/amdgpu: Adding db_size to get doorbell absolute offset

2023-10-04 Thread Arvind Yadav
Here, passing db_size in byte to find the doorbell's
absolute offset for both 32-bit and 64-bit doorbell sizes.
So that doorbell offset will be aligned based on the doorbell
size.

v3:
- Adding db_size as parameter to get db absolute offset.

Cc: Christian Koenig 
Cc: Alex Deucher 
Signed-off-by: Shashank Sharma 
Signed-off-by: Arvind Yadav 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h |  5 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c | 13 +
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
index 09f6727e7c73..4a8b33f55f6b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
@@ -357,8 +357,9 @@ int amdgpu_doorbell_init(struct amdgpu_device *adev);
 void amdgpu_doorbell_fini(struct amdgpu_device *adev);
 int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev);
 uint32_t amdgpu_doorbell_index_on_bar(struct amdgpu_device *adev,
-  struct amdgpu_bo *db_bo,
-  uint32_t doorbell_index);
+ struct amdgpu_bo *db_bo,
+ uint32_t doorbell_index,
+ uint32_t db_size);
 
 #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
 #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
index da4be0bbb446..6690f5a72f4d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
@@ -114,19 +114,24 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, 
u32 index, u64 v)
  * @adev: amdgpu_device pointer
  * @db_bo: doorbell object's bo
  * @db_index: doorbell relative index in this doorbell object
+ * @db_size: doorbell size is in byte
  *
  * returns doorbell's absolute index in BAR
  */
 uint32_t amdgpu_doorbell_index_on_bar(struct amdgpu_device *adev,
-  struct amdgpu_bo *db_bo,
-  uint32_t doorbell_index)
+ struct amdgpu_bo *db_bo,
+ uint32_t doorbell_index,
+ uint32_t db_size)
 {
int db_bo_offset;
 
db_bo_offset = amdgpu_bo_gpu_offset_no_check(db_bo);
 
-   /* doorbell index is 32 bit but doorbell's size is 64-bit, so *2 */
-   return db_bo_offset / sizeof(u32) + doorbell_index * 2;
+   /* doorbell index is 32 bit but doorbell's size can be 32 bit
+* or 64 bit, so *db_size(in byte)/4 for alignment.
+*/
+   return db_bo_offset / sizeof(u32) + doorbell_index *
+  DIV_ROUND_UP(db_size, 4);
 }
 
 /**
-- 
2.34.1



[PATCH v3 0/2] drm/amdkfd: Fix unaligned doorbell absolute offset for gfx8

2023-10-04 Thread Arvind Yadav
On older chips, the absolute doorbell offset within
the doorbell page is based on the queue ID.
KFD is using queue ID and doorbell size to get an
absolute doorbell offset in userspace.

Here, adding db_size in byte to find the doorbell's
absolute offset for both 32-bit and 64-bit doorbell sizes.
So that doorbell offset will be aligned based on the doorbell
size.

v2:
- Addressed the review comment from Felix.

v3:
- Adding doorbell_size as parameter to get db absolute offset. 

Arvind Yadav (2):
  drm/amdgpu: Adding db_size to get doorbell absolute offset
  drm/amdkfd: get doorbell's absolute offset based on the db size

 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h|  5 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c| 13 +
 .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c   |  6 +-
 drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c   | 13 +++--
 .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c  |  4 +++-
 5 files changed, 31 insertions(+), 10 deletions(-)

-- 
2.34.1



Re: [PATCH v4] drm/i915/display/lspcon: Increase LSPCON mode settle timeout

2023-10-04 Thread Jani Nikula
On Mon, 02 Oct 2023, Niko Tsirakis  wrote:
> This is to eliminate all cases of "*ERROR* LSPCON mode hasn't settled",
> followed by link training errors. Intel engineers recommended increasing
> this timeout and that does resolve the issue.
>
> On some CometLake-based device designs the Parade PS175 takes more than
> 400ms to settle in PCON mode. 100 reboot trials on one device resulted
> in a median settle time of 440ms and a maximum of 444ms. Even after
> increasing the timeout to 500ms, 2% of devices still had this error. So
> this increases the timeout to 800ms.
>
> Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/9443
> Signed-off-by: Pablo Ceballos 
> Signed-off-by: Niko Tsirakis 

Thanks for the patch, pushed to drm-intel-next.

BR,
Jani.

> ---
>  drivers/gpu/drm/i915/display/intel_lspcon.c | 15 ++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c 
> b/drivers/gpu/drm/i915/display/intel_lspcon.c
> index dc1b35559afd..92536482e657 100644
> --- a/drivers/gpu/drm/i915/display/intel_lspcon.c
> +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c
> @@ -116,6 +116,18 @@ static enum drm_lspcon_mode 
> lspcon_get_current_mode(struct intel_lspcon *lspcon)
>   return current_mode;
>  }
>  
> +static int lspcon_get_mode_settle_timeout(struct intel_lspcon *lspcon)
> +{
> + /*
> +  * On some CometLake-based device designs the Parade PS175 takes more
> +  * than 400ms to settle in PCON mode. 100 reboot trials on one device
> +  * resulted in a median settle time of 440ms and a maximum of 444ms.
> +  * Even after increasing the timeout to 500ms, 2% of devices still had
> +  * this error. So this sets the timeout to 800ms.
> +  */
> + return lspcon->vendor == LSPCON_VENDOR_PARADE ? 800 : 400;
> +}
> +
>  static enum drm_lspcon_mode lspcon_wait_mode(struct intel_lspcon *lspcon,
>enum drm_lspcon_mode mode)
>  {
> @@ -128,7 +140,8 @@ static enum drm_lspcon_mode lspcon_wait_mode(struct 
> intel_lspcon *lspcon,
>   DRM_DEBUG_KMS("Waiting for LSPCON mode %s to settle\n",
> lspcon_mode_name(mode));
>  
> - wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode, 400);
> + wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode,
> + lspcon_get_mode_settle_timeout(lspcon));
>   if (current_mode != mode)
>   DRM_ERROR("LSPCON mode hasn't settled\n");

-- 
Jani Nikula, Intel


Re: [PATCH drm-misc-next v5 4/6] drm/gpuvm: track/lock/validate external/evicted objects

2023-10-04 Thread Thomas Hellström


On Wed, 2023-10-04 at 14:57 +0200, Danilo Krummrich wrote:
> On 10/3/23 11:11, Thomas Hellström wrote:
> 
> 
> 
> > > > +
> > > > +/**
> > > > + * drm_gpuvm_bo_evict() - add / remove a &drm_gpuvm_bo to /
> > > > from the &drm_gpuvms
> > > > + * evicted list
> > > > + * @vm_bo: the &drm_gpuvm_bo to add or remove
> > > > + * @evict: indicates whether the object is evicted
> > > > + *
> > > > + * Adds a &drm_gpuvm_bo to or removes it from the &drm_gpuvms
> > > > evicted list.
> > > > + */
> > > > +void
> > > > +drm_gpuvm_bo_evict(struct drm_gpuvm_bo *vm_bo, bool evict)
> > > > +{
> > > > +    struct drm_gem_object *obj = vm_bo->obj;
> > > > +
> > > > +    dma_resv_assert_held(obj->resv);
> > > > +
> > > > +    /* Always lock list transactions, even if
> > > > DRM_GPUVM_RESV_PROTECTED is
> > > > + * set. This is required to protect multiple concurrent
> > > > calls to
> > > > + * drm_gpuvm_bo_evict() with BOs with different dma_resv.
> > > > + */
> > > 
> > > This doesn't work. The RESV_PROTECTED case requires the evicted
> > > flag we discussed before. The list is either protected by the
> > > spinlock or the resv. Otherwise a list add could race with a list
> > > removal elsewhere.
> 
> I think it does unless I miss something, but it might be a bit subtle
> though.
> 
> Concurrent drm_gpuvm_bo_evict() are protected by the spinlock.
> Additionally, when
> drm_gpuvm_bo_evict() is called we hold the dma-resv of the
> corresponding GEM object.
> 
> In drm_gpuvm_validate() I assert that we hold *all* dma-resv, which
> implies that no
> one can call drm_gpuvm_bo_evict() on any of the VM's objects and no
> one can add a new
> one and directly call drm_gpuvm_bo_evict() on it either.

But translated into how the data (the list in this case) is protected
it becomes

"Either the spinlock and the bo resv of a single list item OR the bo
resvs of all bos that can potentially be on the list",

while this is certainly possible to assert, any new / future code that
manipulates the evict list will probably get this wrong and as a result
the code becomes pretty fragile. I think drm_gpuvm_bo_destroy() already
gets it wrong in that it, while holding a single resv, doesn't take the
spinlock.

So I think that needs fixing, and if keeping that protection I think it
needs to be documented with the list member and ideally an assert. But
also note that lockdep_assert_held will typically give false true for
dma_resv locks; as long as the first dma_resv lock locked in a drm_exec
sequence  remains locked, lockdep thinks *all* dma_resv locks are held.
(or something along those lines), so the resv lockdep asserts are
currently pretty useless. 

/Thomas



> 
> > > 
> > > Thanks,
> > > 
> > > Thomas
> > > 
> > > 
> > 
> 



Re: [PATCH 1/5] drm/bridge: samsung-dsim: add more mipi-dsi device debug information

2023-10-04 Thread Michael Tretter
On Wed, 27 Sep 2023 07:47:53 -0500, Adam Ford wrote:
> On Sun, Sep 3, 2023 at 8:05 PM Inki Dae  wrote:
> >
> > 2023년 8월 29일 (화) 오전 7:38, Adam Ford 님이 작성:
> > >
> > > On Mon, Aug 28, 2023 at 10:59 AM Michael Tretter
> > >  wrote:
> > > >
> > > > From: Marco Felsch 
> > > >
> > > > Since the MIPI configuration can be changed on demand it is very useful
> > > > to print more MIPI settings during the MIPI device attach step.
> > > >
> > > > Signed-off-by: Marco Felsch 
> > > > Signed-off-by: Michael Tretter 
> > >
> > > Reviewed-by: Adam Ford   #imx8mm-beacon
> > > Tested-by: Adam Ford   #imx8mm-beacon
> >
> > Reviewed-by: Inki Dae 
> > Acked-by: Inki Dae 
> 
> What needs to be done in order to get this accepted?  This series is a
> very nice improvement in i.MX8M Mini / Nano.

I think it is my turn to send a v2 that addresses the review comments. I'll
try to find time this week.

Michael

> 
> adam
> >
> > >
> > > > ---
> > > >  drivers/gpu/drm/bridge/samsung-dsim.c | 5 -
> > > >  1 file changed, 4 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
> > > > b/drivers/gpu/drm/bridge/samsung-dsim.c
> > > > index 73ec60757dbc..6778f1751faa 100644
> > > > --- a/drivers/gpu/drm/bridge/samsung-dsim.c
> > > > +++ b/drivers/gpu/drm/bridge/samsung-dsim.c
> > > > @@ -1711,7 +1711,10 @@ static int samsung_dsim_host_attach(struct 
> > > > mipi_dsi_host *host,
> > > > return ret;
> > > > }
> > > >
> > > > -   DRM_DEV_INFO(dev, "Attached %s device\n", device->name);
> > > > +   DRM_DEV_INFO(dev, "Attached %s device (lanes:%d bpp:%d 
> > > > mode-flags:0x%lx)\n",
> > > > +device->name, device->lanes,
> > > > +mipi_dsi_pixel_format_to_bpp(device->format),
> > > > +device->mode_flags);
> > > >
> > > > drm_bridge_add(&dsi->bridge);
> > > >
> > > >
> > > > --
> > > > 2.39.2
> > > >
> 


RE: [PATCH v3 1/2] dt-bindings: backlight: Add MPS MP3309C

2023-10-04 Thread Flavio Suligoi
Hi Daniel,
...
> ...
> > > > > +required:
> > > > > +  - compatible
> > > > > +  - reg
> > > > > +  - max-brightness
> > > >
> > > > Why is this mandatory?
> > > >
> > > > There's no point in setting max-brightness when running in I2C
> > > > mode
> > > > (max- brightness should default to 31 in that case).
> > > >
> > > >
> > > > > +  - default-brightness
> > > >
> > > > Again. I'm not clear why this needs to be mandatory.
> > > >
> > > >
> > >
> > > Ok, you are right, I'll remove max-brightness and default-brightness
> > > from required properties list. I think to change these properties,
> > > for the pwm dimming, into a clearer:
> > >
> > > - brightness-levels (uint32)
> > > - default-brightness-levels (uint32).
> > >
> > > For example:
> > >
> > >   brightness-levels:
> > > description:
> > >   Number of brightness levels. The actual brightness
> > >   level (PWM duty cycle) will be interpolated from 0 to this value.
> > >   0 means a  0% duty cycle (darkest/off), while the
> > > brightness-levels
> > represents
> > >   a 100% duty cycle (brightest).
> > > $ref: /schemas/types.yaml#/definitions/uint32
> > >
> > >   default-brightness-level:
> > > description:
> > >   The default brightness level (from 0 to brightness-levels)
> > > $ref: /schemas/types.yaml#/definitions/uint32
> > >
> > > Example:
> > > brightness-levels = <10>;
> > > default-brightness-level = <6>;
> > >
> > > What do you think about this solution?
> >
> > If you want to introduce a brightness-levels property then I would
> > expect it to be defined with the same meaning as pwm-backlight (it's
> > not relevant to the bindings but ideally it would be implemented by
> > refactoring and reusing the code from pwm_bl.c).
> 
> ok, I'll use the brightness-levels property as used in pwm-backlight
> 
> >
> > Same with default-brightness-level although I'm not sure why one
> > wouldn't just use default-brightness for new bindings (doesn't
> > default-brightness-level simply do exactly the same thing as default-
> brightness).
> 
> ok for default-brightness instead of default-brightness-level

Just a question: default-brightness-level is the index into the 
brightness-levels array.
But, if I use default-brightness instead of default-brightness-level,  
should I consider default-brightness also as an index into brightness-levels 
array?
Or, in this case, have the default-brightness to be equal to one of the values 
inside the
brightness-levels array?

> 
> >
> >
> > Daniel.
> 
> Thanks an best regards,
> Flavio

Thanks,

Flavio


Re: [Intel-gfx] [PATCH v2] drm/i915: Reduce MCR lock surface

2023-10-04 Thread Rodrigo Vivi
On Wed, Oct 04, 2023 at 03:54:59PM +0200, Nirmoy Das wrote:
> Hi Rodrigo,
> 
> On 10/4/2023 2:44 PM, Rodrigo Vivi wrote:
> > On Wed, Oct 04, 2023 at 02:04:07PM +0200, Nirmoy Das wrote:
> > > Take the mcr lock only when driver needs to write into a mcr based
> > > tlb based registers.
> > > 
> > > To prevent GT reset interference, employ gt->reset.mutex instead, since
> > > intel_gt_mcr_multicast_write relies on gt->uncore->lock not being held.
> > This looks a lot like protecting code and not protecting data [1]
> > 
> > But to be really honest I'm afraid we were already doing this before
> > this patch but with 2 other locks instead.
> 
> I haven't thought about that but yes, the issue was there already.
> 
> 
> > 
> > [1] - https://blog.ffwll.ch/2022/07/locking-engineering.html
> > 
> > > v2: remove unused var, flags.
> > > 
> > > Signed-off-by: Nirmoy Das 
> > > ---
> > >   drivers/gpu/drm/i915/gt/intel_tlb.c | 13 +
> > >   1 file changed, 5 insertions(+), 8 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/gt/intel_tlb.c 
> > > b/drivers/gpu/drm/i915/gt/intel_tlb.c
> > > index 139608c30d97..0ad905df4a98 100644
> > > --- a/drivers/gpu/drm/i915/gt/intel_tlb.c
> > > +++ b/drivers/gpu/drm/i915/gt/intel_tlb.c
> > > @@ -52,15 +52,13 @@ static void mmio_invalidate_full(struct intel_gt *gt)
> > >   struct intel_engine_cs *engine;
> > >   intel_engine_mask_t awake, tmp;
> > >   enum intel_engine_id id;
> > > - unsigned long flags;
> > >   if (GRAPHICS_VER(i915) < 8)
> > >   return;
> > >   intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
> > > - intel_gt_mcr_lock(gt, &flags);
> > > - spin_lock(&uncore->lock); /* serialise invalidate with GT reset */
> > > + mutex_lock(>->reset.mutex);/* serialise invalidate with GT reset */
> > I'm still looking at this and the commit message above and trying to 
> > understand
> > why we are doing this and changing the previous 2 by this other one. why?
> 
> 
> We need the MCR lock only for intel_gt_mcr_multicast_*() so I am not
> replacing the two locks here but moving the mcr lock down
> 
> where we were doing intel_gt_mcr_multicast_write_fw()
> 
> 
> why s/spin_lock(&uncore->lock)/mutex_lock(>->reset.mutex):
> 
> intel_gt_mcr_multicast_*() expects gt->uncore->lock to be not held

is there any lockdep assert or primitive that we could/should do
that to avoid this same issue in the future?
anyway, this is also another thing that it is important for the
commit message.

and why is that? what I have in mind goes along with the comment
above intel_de_read_fw():
"""
Access to registers should
 * therefore generally be serialised, by either the dev_priv->uncore.lock or
"""

> and to
> achieve this, I could do something like:
> 
> if (engine->tlb_inv.mcr) {
> 
>      spin_unlock(&uncore->lock);
> 
>  intel_gt_mcr_lock(gt, &flags);
> 
>  intel_gt_mcr_multicast_write_fw
> 
>  intel_gt_mcr_unlock(gt, flags);
> 
>     spin_lock(&uncore->lock);
> 
> }
> 
> Or take gt->reset.mutex instead which should block any concurrent gt reset.
> 
> If this is not acceptable then I can pick the above 1st option but I am not
> sure how safe is it do release uncore->lock and then take it back again.

hmm... probably the gt_reset one is better than releasing and grabbing it
again.

> 
> > 
> > >   awake = 0;
> > >   for_each_engine(engine, gt, id) {
> > > @@ -68,9 +66,9 @@ static void mmio_invalidate_full(struct intel_gt *gt)
> > >   continue;
> > >   if (engine->tlb_inv.mcr)
> > > - intel_gt_mcr_multicast_write_fw(gt,
> > > - 
> > > engine->tlb_inv.reg.mcr_reg,
> > > - 
> > > engine->tlb_inv.request);
> > > + intel_gt_mcr_multicast_write(gt,
> > > +  
> > > engine->tlb_inv.reg.mcr_reg,
> > > +  engine->tlb_inv.request);
> > you are already taking the forcewake_all domain above, so you wouldn't
> > need to convert this to the variant that grabs the forcewake underneath.
> > 
> > Also this is not mentioned in the commit message above.
> 
> intel_gt_mcr_multicast_write() takes the mcr lock for us, helps replacing 
> multiple lines into one.
> Will there be any side-effects for that ?

hmm... I can't forsee side-effects here... but I'm asking myself why on the non
MCR ones we are using the global forcewake_all and the _fw to start with.
Maybe there was a reason for that? Because in general we should prefer the non 
_fw
variants to start with. Maybe we should dig into the history there to understand
why the line below started with the intel_uncore_write_fw below?

> 
> I should've added that the commit message.

I'm even wondering if this should be 2 separated patches?!

> 
> Regards,
> Nirmoy
> 
> 
> > 
> > >   else
> > >

[PATCH] drm/tegra: dpaux: Fix PM disable depth imbalance in tegra_dpaux_probe

2023-10-04 Thread Zhang Shurong
The pm_runtime_enable function increases the power disable depth,
which means that we must perform a matching decrement on the error
handling path to maintain balance within the given context.
Additionally, we need to address the same issue for pm_runtime_get_sync.
We fix this by invoking pm_runtime_disable and pm_runtime_put_sync
when error returns.

Fixes: 82b81b3ec1a7 ("drm/tegra: dpaux: Implement runtime PM")
Signed-off-by: Zhang Shurong 
---
 drivers/gpu/drm/tegra/dpaux.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index ef02d530f78d..ae12d001a04b 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -522,7 +522,7 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
if (err < 0) {
dev_err(dpaux->dev, "failed to request IRQ#%u: %d\n",
dpaux->irq, err);
-   return err;
+   goto err_pm_disable;
}
 
disable_irq(dpaux->irq);
@@ -542,7 +542,7 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
 */
err = tegra_dpaux_pad_config(dpaux, DPAUX_PADCTL_FUNC_I2C);
if (err < 0)
-   return err;
+   goto err_pm_disable;
 
 #ifdef CONFIG_GENERIC_PINCONF
dpaux->desc.name = dev_name(&pdev->dev);
@@ -555,7 +555,8 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
dpaux->pinctrl = devm_pinctrl_register(&pdev->dev, &dpaux->desc, dpaux);
if (IS_ERR(dpaux->pinctrl)) {
dev_err(&pdev->dev, "failed to register pincontrol\n");
-   return PTR_ERR(dpaux->pinctrl);
+   err = PTR_ERR(dpaux->pinctrl);
+   goto err_pm_disable;
}
 #endif
/* enable and clear all interrupts */
@@ -571,10 +572,15 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
err = devm_of_dp_aux_populate_ep_devices(&dpaux->aux);
if (err < 0) {
dev_err(dpaux->dev, "failed to populate AUX bus: %d\n", err);
-   return err;
+   goto err_pm_disable;
}
 
return 0;
+
+err_pm_disable:
+   pm_runtime_put_sync(&pdev->dev);
+   pm_runtime_disable(&pdev->dev);
+   return err;
 }
 
 static void tegra_dpaux_remove(struct platform_device *pdev)
-- 
2.30.2



Re: [PATCH] dma-buf: Deny copy-on-writes mmaps

2023-10-04 Thread Christian König

Am 04.10.23 um 01:03 schrieb Andi Shyti:

From: Chris Wilson 

Enforce that an mmap of a dmabuf is always using MAP_SHARED so that all
access (both read and writes) using the device memory and not a local
copy-on-write page in system memory.


As much as I would like to do this I fear that this won't work.

First of all interesting approach to do this in .get_unmapped_area. The 
standard handling is to have the check like "if 
(is_cow_mapping(vma->vm_flags)) return -EINVAL;", see TTM for example.


Then IIRC we already tried this and had to revert it because it breaks 
the UAPI. Some broken applications actually use shared mappings (but not 
really cow) and we would like to keep them working.


Regards,
Christian.



Signed-off-by: Chris Wilson 
Signed-off-by: Andi Shyti 
---
  drivers/dma-buf/dma-buf.c | 15 +++
  1 file changed, 15 insertions(+)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 21916bba77d5..1ec297241842 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -25,6 +25,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  
@@ -128,6 +129,19 @@ static struct file_system_type dma_buf_fs_type = {

.kill_sb = kill_anon_super,
  };
  
+static unsigned long

+dma_buf_get_unmapped_area(struct file *file,
+ unsigned long addr,
+ unsigned long len,
+ unsigned long pgoff,
+ unsigned long flags)
+{
+   if ((flags & MAP_TYPE) == MAP_PRIVATE)
+   return -EINVAL;
+
+   return current->mm->get_unmapped_area(file, addr, len, pgoff, flags);
+}
+
  static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct 
*vma)
  {
struct dma_buf *dmabuf;
@@ -508,6 +522,7 @@ static void dma_buf_show_fdinfo(struct seq_file *m, struct 
file *file)
  
  static const struct file_operations dma_buf_fops = {

.release= dma_buf_file_release,
+   .get_unmapped_area = dma_buf_get_unmapped_area,
.mmap   = dma_buf_mmap_internal,
.llseek = dma_buf_llseek,
.poll   = dma_buf_poll,




Re: [Intel-gfx] [RFC PATCH] drm/i915/gt: Do not treat MCR locking timeouts as errors

2023-10-04 Thread Andi Shyti
Hi Tvrtko,

> > The MCR steering semaphore is a shared lock entry between i915
> > and various firmware components.
> > 
> > Getting the lock might sinchronize on some shared resources.
> > Sometimes though, it might happen that the firmware forgets to
> > unlock causing unnecessary noise in the driver which keeps doing
> > what was supposed to do, ignoring the problem.
> > 
> > Do not consider this failure as an error, but just print a debug
> > message stating that the MCR locking has been skipped.
> > 
> > On the driver side we still have spinlocks that make sure that
> > the access to the resources is serialized.
> > 
> > Signed-off-by: Andi Shyti 
> > Cc: Jonathan Cavitt 
> > Cc: Matt Roper 
> > Cc: Nirmoy Das 
> > ---
> >   drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 6 ++
> >   1 file changed, 2 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
> > b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > index 326c2ed1d99b..51eb693df39b 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> > @@ -395,10 +395,8 @@ void intel_gt_mcr_lock(struct intel_gt *gt, unsigned 
> > long *flags)
> >  * would indicate some hardware/firmware is misbehaving and not
> >  * releasing it properly.
> >  */
> > -   if (err == -ETIMEDOUT) {
> > -   gt_err_ratelimited(gt, "hardware MCR steering semaphore timed 
> > out");
> > -   add_taint_for_CI(gt->i915, TAINT_WARN);  /* CI is now 
> > unreliable */
> > -   }
> > +   if (err == -ETIMEDOUT)
> > +   gt_dbg(gt, "hardware MCR steering semaphore timed out");
> >   }
> >   /**
> 
> Are we sure this does not warrant a level higher than dbg, such as
> notice/warn?

We might make it a warn, but this doesn't change much the economy
of the driver as we will keep doing what we were supposed to do.

> Because how can we be sure the two entities will not stomp on
> each other toes if we failed to obtain lock?

So far, in all the research I've done, no one looks like using
MCR lock, but yet someone is stuck in it.

> (How can we be sure about
> "forgot to unlock" vs "in prolonged active use"?

There is a patch from Jonathan that is testing a different
timeout.

> Or if we can be sure, can
> we force unlock and take the lock for the driver explicitly?)

I sent a patch with this solution and Matt turned it down.

Andi


Re: [PATCH v2] drm/i915: Reduce MCR lock surface

2023-10-04 Thread Nirmoy Das

Hi Rodrigo,

On 10/4/2023 2:44 PM, Rodrigo Vivi wrote:

On Wed, Oct 04, 2023 at 02:04:07PM +0200, Nirmoy Das wrote:

Take the mcr lock only when driver needs to write into a mcr based
tlb based registers.

To prevent GT reset interference, employ gt->reset.mutex instead, since
intel_gt_mcr_multicast_write relies on gt->uncore->lock not being held.

This looks a lot like protecting code and not protecting data [1]

But to be really honest I'm afraid we were already doing this before
this patch but with 2 other locks instead.


I haven't thought about that but yes, the issue was there already.




[1] - https://blog.ffwll.ch/2022/07/locking-engineering.html


v2: remove unused var, flags.

Signed-off-by: Nirmoy Das 
---
  drivers/gpu/drm/i915/gt/intel_tlb.c | 13 +
  1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_tlb.c 
b/drivers/gpu/drm/i915/gt/intel_tlb.c
index 139608c30d97..0ad905df4a98 100644
--- a/drivers/gpu/drm/i915/gt/intel_tlb.c
+++ b/drivers/gpu/drm/i915/gt/intel_tlb.c
@@ -52,15 +52,13 @@ static void mmio_invalidate_full(struct intel_gt *gt)
struct intel_engine_cs *engine;
intel_engine_mask_t awake, tmp;
enum intel_engine_id id;
-   unsigned long flags;
  
  	if (GRAPHICS_VER(i915) < 8)

return;
  
  	intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
  
-	intel_gt_mcr_lock(gt, &flags);

-   spin_lock(&uncore->lock); /* serialise invalidate with GT reset */
+   mutex_lock(>->reset.mutex);/* serialise invalidate with GT reset */

I'm still looking at this and the commit message above and trying to understand
why we are doing this and changing the previous 2 by this other one. why?



We need the MCR lock only for intel_gt_mcr_multicast_*() so I am not 
replacing the two locks here but moving the mcr lock down


where we were doing intel_gt_mcr_multicast_write_fw()


why s/spin_lock(&uncore->lock)/mutex_lock(>->reset.mutex):

intel_gt_mcr_multicast_*() expects gt->uncore->lock to be not held and 
to achieve this, I could do something like:


if (engine->tlb_inv.mcr) {

     spin_unlock(&uncore->lock);

 intel_gt_mcr_lock(gt, &flags);

 intel_gt_mcr_multicast_write_fw

 intel_gt_mcr_unlock(gt, flags);

    spin_lock(&uncore->lock);

}

Or take gt->reset.mutex instead which should block any concurrent gt reset.

If this is not acceptable then I can pick the above 1st option but I am 
not sure how safe is it do release uncore->lock and then take it back again.




  
  	awake = 0;

for_each_engine(engine, gt, id) {
@@ -68,9 +66,9 @@ static void mmio_invalidate_full(struct intel_gt *gt)
continue;
  
  		if (engine->tlb_inv.mcr)

-   intel_gt_mcr_multicast_write_fw(gt,
-   
engine->tlb_inv.reg.mcr_reg,
-   
engine->tlb_inv.request);
+   intel_gt_mcr_multicast_write(gt,
+
engine->tlb_inv.reg.mcr_reg,
+engine->tlb_inv.request);

you are already taking the forcewake_all domain above, so you wouldn't
need to convert this to the variant that grabs the forcewake underneath.

Also this is not mentioned in the commit message above.


intel_gt_mcr_multicast_write() takes the mcr lock for us, helps replacing 
multiple lines into one.
Will there be any side-effects for that ?

I should've added that the commit message.

Regards,
Nirmoy





else
intel_uncore_write_fw(uncore,
  engine->tlb_inv.reg.reg,
@@ -90,8 +88,7 @@ static void mmio_invalidate_full(struct intel_gt *gt)
 IS_ALDERLAKE_P(i915)))
intel_uncore_write_fw(uncore, GEN12_OA_TLB_INV_CR, 1);
  
-	spin_unlock(&uncore->lock);

-   intel_gt_mcr_unlock(gt, flags);
+   mutex_unlock(>->reset.mutex);
  
  	for_each_engine_masked(engine, gt, awake, tmp) {

if (wait_for_invalidate(engine))
--
2.41.0



Re: [PATCH drm-misc-next v5 4/6] drm/gpuvm: track/lock/validate external/evicted objects

2023-10-04 Thread Danilo Krummrich

On 10/3/23 19:37, Thomas Hellström wrote:

Hi, Danilo

On Tue, 2023-10-03 at 18:55 +0200, Danilo Krummrich wrote:

It seems like we're mostly aligned on this series, except for the key
controversy we're discussing for a few versions now: locking of the
internal
lists. Hence, let's just re-iterate the options we have to get this
out of the
way.

(1) The spinlock dance. This basically works for every use case,
updating the VA
     space from the IOCTL, from the fence signaling path or anywhere
else.
     However, it has the downside of requiring spin_lock() /
spin_unlock() for
     *each* list element when locking all external objects and
validating all
     evicted objects. Typically, the amount of extobjs and evicted
objects
     shouldn't be excessive, but there might be exceptions, e.g. Xe.

(2) The dma-resv lock dance. This is convinient for drivers updating
the VA
     space from a VM_BIND ioctl() and is especially efficient if such
drivers
     have a huge amount of external and/or evicted objects to manage.
However,
     the downsides are that it requires a few tricks in drivers
updating the VA
     space from the fence signaling path (e.g. job_run()). Design
wise, I'm still
     skeptical that it is a good idea to protect internal data
structures with
     external locks in a way that it's not clear to callers that a
certain
     function would access one of those resources and hence needs
protection.
     E.g. it is counter intuitive that drm_gpuvm_bo_put() would
require both the
     dma-resv lock of the corresponding object and the VM's dma-resv
lock held.
     (Additionally, there were some concerns from amdgpu regarding
flexibility in
     terms of using GPUVM for non-VM_BIND uAPIs and compute, however,
AFAICS
     those discussions did not complete and to me it's still unclear
why it
     wouldn't work.)

(3) Simply use an internal mutex per list. This adds a tiny (IMHO
negligible)
     overhead for drivers updating the VA space from a VM_BIND
ioctl(), namely
     a *single* mutex_lock()/mutex_unlock() when locking all external
objects
     and validating all evicted objects. And it still requires some
tricks for
     drivers updating the VA space from the fence signaling path.
However, it's
     as simple as it can be and hence way less error prone as well as
     self-contained and hence easy to use. Additionally, it's flexible
in a way
     that we don't have any expections on drivers to already hold
certain locks
     that the driver in some situation might not be able to acquire in
the first
     place.


Such an overhead is fully OK IMO, But didn't we conclude at some point
that using a mutex in this way isn't possible due to the fact that
validate() needs to be able to lock dma_resv, and then we have
dma_resv()->mutex->dma_resv()?


Oh, yes. I already forgot about it. I think it would work for protecting the
evicted list. But it breaks with the external object list, because we'd hold
the mutex while acquiring the dma-resv locks. Hence, there'd be a potential
lock inversion when drm_gpuvm_bo_put() is called with the corrsponding
dma-resv lock held. Then this option is indeed gone as well, unfortunately.






(4) Arbitrary combinations of the above. For instance, the current V5
implements
     both (1) and (2) (as either one or the other). But also (1) and
(3) (as in
     (1) additionally to (3)) would be an option, where a driver could
opt-in for
     the spinlock dance in case it updates the VA space from the fence
signaling
     path.

I also considered a few other options as well, however, they don't
seem to be
flexible enough. For instance, as by now we could use SRCU for the
external
object list. However, this falls apart once a driver wants to remove
and re-add
extobjs for the same VM_BO instance. (For the same reason it wouldn't
work for
evicted objects.)

Personally, after seeing the weird implications of (1), (2) and a
combination of
both, I tend to go with (3). Optionally, with an opt-in for (1). The
reason for
the latter is that with (3) the weirdness of (1) by its own mostly
disappears.

Please let me know what you think, and, of course, other ideas than
the
mentioned ones above are still welcome.


Personally, after converting xe to version 5, I think it's pretty
convenient for the driver, (although had to add the evict trick), so I


With evict trick you mean a field drm_gpuvm_bo::evicted? I think we don't
need it necessarily (see my previous reply). But I agree it'd be a bit
cleaner locking wise.

My only concern with that is that it would restrict the context in which
the evict list is useful, because it implies that in order to even see the
actual state of the evict list all external objects must be locked first.

What if a driver wants to only lock and validate only a certain range of
the VA space? Surely, it can just call validate() for each drm_gpuva's BO,
but depending on the size of the range we might still want to accelerate
it using the evicted list.

Honestly, 

Re: [PATCH drm-misc-next v5 4/6] drm/gpuvm: track/lock/validate external/evicted objects

2023-10-04 Thread Danilo Krummrich

On 10/3/23 11:11, Thomas Hellström wrote:




+
+/**
+ * drm_gpuvm_bo_evict() - add / remove a &drm_gpuvm_bo to / from the 
&drm_gpuvms
+ * evicted list
+ * @vm_bo: the &drm_gpuvm_bo to add or remove
+ * @evict: indicates whether the object is evicted
+ *
+ * Adds a &drm_gpuvm_bo to or removes it from the &drm_gpuvms evicted list.
+ */
+void
+drm_gpuvm_bo_evict(struct drm_gpuvm_bo *vm_bo, bool evict)
+{
+    struct drm_gem_object *obj = vm_bo->obj;
+
+    dma_resv_assert_held(obj->resv);
+
+    /* Always lock list transactions, even if DRM_GPUVM_RESV_PROTECTED is
+ * set. This is required to protect multiple concurrent calls to
+ * drm_gpuvm_bo_evict() with BOs with different dma_resv.
+ */


This doesn't work. The RESV_PROTECTED case requires the evicted flag we 
discussed before. The list is either protected by the spinlock or the resv. 
Otherwise a list add could race with a list removal elsewhere.


I think it does unless I miss something, but it might be a bit subtle though.

Concurrent drm_gpuvm_bo_evict() are protected by the spinlock. Additionally, 
when
drm_gpuvm_bo_evict() is called we hold the dma-resv of the corresponding GEM 
object.

In drm_gpuvm_validate() I assert that we hold *all* dma-resv, which implies 
that no
one can call drm_gpuvm_bo_evict() on any of the VM's objects and no one can add 
a new
one and directly call drm_gpuvm_bo_evict() on it either.



Thanks,

Thomas








Re: [PATCH] drm/edid/firmware: drop drm_kms_helper.edid_firmware backward compat

2023-10-04 Thread Jani Nikula
On Thu, 21 Sep 2023, Jani Nikula  wrote:
> Since the edid_firmware module parameter was moved from
> drm_kms_helper.ko to drm.ko in v4.15, we've had a backwards
> compatibility helper in place, with a DRM_NOTE() suggesting to migrate
> to drm.edid_firmware. This was added in commit ac6c35a4d8c7 ("drm: add
> backwards compatibility support for drm_kms_helper.edid_firmware").
>
> More than five years and 30+ kernel releases later, see if we could drop
> the backward compatibility. Leave some warnings in place for a while
> longer.

Dave, Daniel, thoughts?

BR,
Jani.

>
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/drm_edid_load.c | 16 
>  drivers/gpu/drm/drm_kms_helper_common.c | 11 ++-
>  include/drm/drm_edid.h  |  5 -
>  3 files changed, 6 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c
> index 5d9ef267ebb3..60fcb80bce61 100644
> --- a/drivers/gpu/drm/drm_edid_load.c
> +++ b/drivers/gpu/drm/drm_edid_load.c
> @@ -23,22 +23,6 @@ module_param_string(edid_firmware, edid_firmware, 
> sizeof(edid_firmware), 0644);
>  MODULE_PARM_DESC(edid_firmware, "Do not probe monitor, use specified EDID 
> blob "
>   "from built-in data or /lib/firmware instead. ");
>  
> -/* Use only for backward compatibility with drm_kms_helper.edid_firmware */
> -int __drm_set_edid_firmware_path(const char *path)
> -{
> - scnprintf(edid_firmware, sizeof(edid_firmware), "%s", path);
> -
> - return 0;
> -}
> -EXPORT_SYMBOL(__drm_set_edid_firmware_path);
> -
> -/* Use only for backward compatibility with drm_kms_helper.edid_firmware */
> -int __drm_get_edid_firmware_path(char *buf, size_t bufsize)
> -{
> - return scnprintf(buf, bufsize, "%s", edid_firmware);
> -}
> -EXPORT_SYMBOL(__drm_get_edid_firmware_path);
> -
>  #define GENERIC_EDIDS 6
>  static const char * const generic_edid_name[GENERIC_EDIDS] = {
>   "edid/800x600.bin",
> diff --git a/drivers/gpu/drm/drm_kms_helper_common.c 
> b/drivers/gpu/drm/drm_kms_helper_common.c
> index 0bf0fc1abf54..924e0f7bd5b7 100644
> --- a/drivers/gpu/drm/drm_kms_helper_common.c
> +++ b/drivers/gpu/drm/drm_kms_helper_common.c
> @@ -38,17 +38,18 @@ MODULE_LICENSE("GPL and additional rights");
>  
>  #if IS_ENABLED(CONFIG_DRM_LOAD_EDID_FIRMWARE)
>  
> -/* Backward compatibility for drm_kms_helper.edid_firmware */
>  static int edid_firmware_set(const char *val, const struct kernel_param *kp)
>  {
> - DRM_NOTE("drm_kms_helper.edid_firmware is deprecated, please use 
> drm.edid_firmware instead.\n");
> + pr_warn("drm_kms_helper.edid_firmware has been removed, please use 
> drm.edid_firmware instead.\n");
>  
> - return __drm_set_edid_firmware_path(val);
> + return -ENOENT;
>  }
>  
>  static int edid_firmware_get(char *buffer, const struct kernel_param *kp)
>  {
> - return __drm_get_edid_firmware_path(buffer, PAGE_SIZE);
> + pr_warn("drm_kms_helper.edid_firmware has been removed, please use 
> drm.edid_firmware instead.\n");
> +
> + return -ENOENT;
>  }
>  
>  static const struct kernel_param_ops edid_firmware_ops = {
> @@ -59,6 +60,6 @@ static const struct kernel_param_ops edid_firmware_ops = {
>  module_param_cb(edid_firmware, &edid_firmware_ops, NULL, 0644);
>  __MODULE_PARM_TYPE(edid_firmware, "charp");
>  MODULE_PARM_DESC(edid_firmware,
> -  "DEPRECATED. Use drm.edid_firmware module parameter instead.");
> +  "REMOVED. Use drm.edid_firmware module parameter instead.");
>  
>  #endif
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 882d2638708e..00f0a778ab62 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -387,11 +387,6 @@ int drm_edid_to_speaker_allocation(const struct edid 
> *edid, u8 **sadb);
>  int drm_av_sync_delay(struct drm_connector *connector,
> const struct drm_display_mode *mode);
>  
> -#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
> -int __drm_set_edid_firmware_path(const char *path);
> -int __drm_get_edid_firmware_path(char *buf, size_t bufsize);
> -#endif
> -
>  bool drm_edid_are_equal(const struct edid *edid1, const struct edid *edid2);
>  
>  int

-- 
Jani Nikula, Intel


Re: [PATCH v2 12/16] platform/x86/amd/pmf: Add PMF-AMDGPU get interface

2023-10-04 Thread Ilpo Järvinen
On Sat, 30 Sep 2023, Shyam Sundar S K wrote:

> In order to provide GPU inputs to TA for the Smart PC solution to work, we
> need to have interface between the PMF driver and the AMDGPU driver.
> 
> Add the initial code path for get interface from AMDGPU.
> 
> Co-developed-by: Mario Limonciello 
> Signed-off-by: Mario Limonciello 
> Signed-off-by: Shyam Sundar S K 

> @@ -355,6 +356,21 @@ static int amd_pmf_get_bios_buffer(struct amd_pmf_dev 
> *dev)
>   return amd_pmf_start_policy_engine(dev);
>  }
>  
> +static int amd_pmf_get_gpu_handle(struct pci_dev *pdev, void *data)
> +{
> + struct amd_pmf_dev *dev = data;
> +
> + if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->devfn == 0) {
> + /* get the amdgpu handle from the pci root after walking 
> through the pci bus */

I can see from the code that you assign to amdgpu handle so this comment 
added no information.

It doesn't really answer at all why you're doing this second step. Based 
on the give parameters to pci_get_device(), it looks as if you're asking 
for the same device you already have in pdev to be searched to you.

> + dev->gfx_data.gpu_dev = pci_get_device(pdev->vendor, 
> pdev->device, NULL);
> + if (dev->gfx_data.gpu_dev) {
> + pci_dev_put(pdev);
> + return 1; /* stop walking */
> + }
> + }
> + return 0; /* continue walking */
> +}
> +
>  static int amd_pmf_amdtee_ta_match(struct tee_ioctl_version_data *ver, const 
> void *data)
>  {
>   return ver->impl_id == TEE_IMPL_ID_AMDTEE;
> @@ -451,6 +467,15 @@ int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev)
>   INIT_DELAYED_WORK(&dev->pb_work, amd_pmf_invoke_cmd);
>   amd_pmf_set_dram_addr(dev);
>   amd_pmf_get_bios_buffer(dev);
> +
> + /* get amdgpu handle */
> + pci_walk_bus(dev->root->bus, amd_pmf_get_gpu_handle, dev);
> + if (!dev->gfx_data.gpu_dev)
> + dev_err(dev->dev, "GPU handle not found!\n");
> +
> + if (!amd_pmf_gpu_init(&dev->gfx_data))
> + dev->gfx_data.gpu_dev_en = true;
> +


-- 
 i.



Re: [PATCH v2] drm/i915: Reduce MCR lock surface

2023-10-04 Thread Rodrigo Vivi
On Wed, Oct 04, 2023 at 02:04:07PM +0200, Nirmoy Das wrote:
> Take the mcr lock only when driver needs to write into a mcr based
> tlb based registers.
> 
> To prevent GT reset interference, employ gt->reset.mutex instead, since
> intel_gt_mcr_multicast_write relies on gt->uncore->lock not being held.

This looks a lot like protecting code and not protecting data [1]

But to be really honest I'm afraid we were already doing this before
this patch but with 2 other locks instead.

[1] - https://blog.ffwll.ch/2022/07/locking-engineering.html

> 
> v2: remove unused var, flags.
> 
> Signed-off-by: Nirmoy Das 
> ---
>  drivers/gpu/drm/i915/gt/intel_tlb.c | 13 +
>  1 file changed, 5 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_tlb.c 
> b/drivers/gpu/drm/i915/gt/intel_tlb.c
> index 139608c30d97..0ad905df4a98 100644
> --- a/drivers/gpu/drm/i915/gt/intel_tlb.c
> +++ b/drivers/gpu/drm/i915/gt/intel_tlb.c
> @@ -52,15 +52,13 @@ static void mmio_invalidate_full(struct intel_gt *gt)
>   struct intel_engine_cs *engine;
>   intel_engine_mask_t awake, tmp;
>   enum intel_engine_id id;
> - unsigned long flags;
>  
>   if (GRAPHICS_VER(i915) < 8)
>   return;
>  
>   intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
>  
> - intel_gt_mcr_lock(gt, &flags);
> - spin_lock(&uncore->lock); /* serialise invalidate with GT reset */
> + mutex_lock(>->reset.mutex);/* serialise invalidate with GT reset */

I'm still looking at this and the commit message above and trying to understand
why we are doing this and changing the previous 2 by this other one. why?

>  
>   awake = 0;
>   for_each_engine(engine, gt, id) {
> @@ -68,9 +66,9 @@ static void mmio_invalidate_full(struct intel_gt *gt)
>   continue;
>  
>   if (engine->tlb_inv.mcr)
> - intel_gt_mcr_multicast_write_fw(gt,
> - 
> engine->tlb_inv.reg.mcr_reg,
> - 
> engine->tlb_inv.request);
> + intel_gt_mcr_multicast_write(gt,
> +  
> engine->tlb_inv.reg.mcr_reg,
> +  engine->tlb_inv.request);

you are already taking the forcewake_all domain above, so you wouldn't
need to convert this to the variant that grabs the forcewake underneath.

Also this is not mentioned in the commit message above.

>   else
>   intel_uncore_write_fw(uncore,
> engine->tlb_inv.reg.reg,
> @@ -90,8 +88,7 @@ static void mmio_invalidate_full(struct intel_gt *gt)
>IS_ALDERLAKE_P(i915)))
>   intel_uncore_write_fw(uncore, GEN12_OA_TLB_INV_CR, 1);
>  
> - spin_unlock(&uncore->lock);
> - intel_gt_mcr_unlock(gt, flags);
> + mutex_unlock(>->reset.mutex);
>  
>   for_each_engine_masked(engine, gt, awake, tmp) {
>   if (wait_for_invalidate(engine))
> -- 
> 2.41.0
> 


Re: [PATCH 0/5] drm/amd/display: Remove migrate-disable and move memory allocation.

2023-10-04 Thread Harry Wentland



On 2023-10-03 15:54, Harry Wentland wrote:
> On 2023-10-02 06:58, Sebastian Andrzej Siewior wrote:
>> On 2023-09-22 07:33:26 [+0200], Christian König wrote:
>>> Am 21.09.23 um 16:15 schrieb Sebastian Andrzej Siewior:
 Hi,

 I stumbled uppon the amdgpu driver via a bugzilla report. The actual fix
 is #4 + #5 and the rest was made while looking at the code.
>>>
>>> Oh, yes please :)
>>>
>>> Rodrigo and I have been trying to sort those things out previously, but
>>> that's Sisyphean work.
>>>
>>> In general the DC team needs to judge, but of hand it looks good to me.
>>
>> Any way to get this merged? There was no reply from the DC team… No
>> reply from the person breaking it either. The bugzilla reporter stated
>> that it solves his trouble. He didn't report anything new ;)
>>
> 
> Apologies for the slow progress. We're feeding it through our CI and
> will let you know the verdict soon.
> 
> Do you happen to have the bugzilla link that this is fixing? It would
> be helpful to include that as a link in the patches as well, to give
> them context.
> 

CI passed.

Series is
Acked-by: Harry Wentland 

Harry

> Harry
> 
>>> Christian.
>>
>> Sebastian
> 



Re: bulk_move in ttm_resource manager

2023-10-04 Thread Christian König

Am 04.10.23 um 09:17 schrieb Thomas Hellström:

On Wed, 2023-10-04 at 03:52 +, Zeng, Oak wrote:

Hi Christian,
  
As a follow up to this thread:

https://www.spinics.net/lists/dri-devel/msg410740.html, I started the
work of moving the lru out of ttm_resource_manager and make it a
common library for both ttm and svm. While look into the details of
the bulk_move in ttm resource manager, I found a potential problem:
  
For simplicity, let’s say we only have one memory type and one

priority, so ttm resource manager only maintains one global lru list.
Let’s say this list has 10 nodes, node1 to node10.
  
But the lru_bulk_move is per vm. Let’s say vm1 has a bulk_move

covering node range [node4, node7] and vm2 has a bulk_move covering
node range [node6, node9]. Notice those two range has an overlap.
Since two vm can simultaneously add nodes to lru, I think this
scenario can happen.


That can't happen. See what ttm_resource_move_to_lru_tail() does when 
the BO has a bulk move associated with it.


  
Now if we perform a bulk move for vm1, moving [node4, node7] to the

tail of the lru list. The lru after this bulk move will be: node1,
node2, node3,node8,node9, node10, node4, node5, node6, node7. Now
notice that for vm2’s bulk_move, the first pointer  (pointing to
node6) is actually after the last pointer (pointing to node9), which
doesn’t make sense.
  
Is this a real problem? As I understand it, with this issue, we only

mess up the lru list order, but there won’t be any functional
problem. If it is a real problem, should we make the bulk_move global
instead of per vm based?
  
Thanks,

Oak
  

FWIW I have a patch set that converts the TTM bulk move code to using
sublists; a list item is either a resource or a sublist, and when
performing a bulk move essentially the sublist is moved. Bumping
resource LRU within a VM would touch only the sublist.


That sounds like my very first attempt at bulk moves which we abandoned 
for various reasons.


That's easily >5years ago, but the history of that should still be on 
the mailing list if I'm not completely mistaken.


Regards,
Christian.



Currently functionality and TTM API is essentially the same but when
experimenting with LRU traversal for exhaustive WW-locking eviction
this concept was easier to use. Also hopefully this would reduce
fragility and improve understanding since a scenario like the above
could really never happen...

Let me know if I should send it out as an RFC.

Code is here:
https://gitlab.freedesktop.org/drm/xe/kernel/-/merge_requests/351/commits

/Thomas









Re: [PATCH v2 11/16] platform/x86/amd/pmf: dump policy binary data

2023-10-04 Thread Ilpo Järvinen
On Sat, 30 Sep 2023, Shyam Sundar S K wrote:

> Sometimes policy binary retrieved from the BIOS maybe incorrect that can
> end up in failing to enable the Smart PC solution feature.
> 
> Use print_hex_dump_debug() to dump the policy binary in hex, so that we
> debug the issues related to the binary even before sending that to TA.
> 
> Signed-off-by: Shyam Sundar S K 
> ---
>  drivers/platform/x86/amd/pmf/tee-if.c | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
> b/drivers/platform/x86/amd/pmf/tee-if.c
> index 01f974b55a6a..d16bdecfd43a 100644
> --- a/drivers/platform/x86/amd/pmf/tee-if.c
> +++ b/drivers/platform/x86/amd/pmf/tee-if.c
> @@ -290,6 +290,9 @@ static ssize_t amd_pmf_get_pb_data(struct file *filp, 
> const char __user *buf,
>   if (copy_from_user(dev->policy_buf, buf, dev->policy_sz))
>   return -EFAULT;
>  
> + print_hex_dump_debug("(pb):  ", DUMP_PREFIX_OFFSET, 16, 1, 
> dev->policy_buf,
> +  dev->policy_sz, false);
> +
>   ret = amd_pmf_start_policy_engine(dev);
>   if (ret)
>   return -EINVAL;
> @@ -341,6 +344,10 @@ static int amd_pmf_get_bios_buffer(struct amd_pmf_dev 
> *dev)
>   return -ENOMEM;
>  
>   memcpy(dev->policy_buf, dev->policy_base, dev->policy_sz);
> +#ifdef CONFIG_AMD_PMF_DEBUG
> + print_hex_dump_debug("(pb):  ", DUMP_PREFIX_OFFSET, 16, 1, 
> dev->policy_buf,
> +  dev->policy_sz, false);
> +#endif

Create a wrapper for print_hex_dump_debug into #ifdef and #else blocks for 
this too so you don't need the ifdef here.

-- 
 i.



Re: [PATCH v2 09/16] platform/x86/amd/pmf: Add facility to dump TA inputs

2023-10-04 Thread Ilpo Järvinen
On Sat, 30 Sep 2023, Shyam Sundar S K wrote:

> PMF driver sends constant inputs to TA which its gets via the other
> subsystems in the kernel. To debug certain TA issues knowing what inputs
> being sent to TA becomes critical. Add debug facility to the driver which
> can isolate Smart PC and TA related issues.
> 
> Also, make source_as_str() as non-static function as this helper is
> required outside of sps.c file.
> 
> Reviewed-by: Mario Limonciello 
> Signed-off-by: Shyam Sundar S K 
> ---
>  drivers/platform/x86/amd/pmf/pmf.h|  3 +++
>  drivers/platform/x86/amd/pmf/spc.c| 37 +++
>  drivers/platform/x86/amd/pmf/sps.c|  2 +-
>  drivers/platform/x86/amd/pmf/tee-if.c |  1 +
>  4 files changed, 42 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
> b/drivers/platform/x86/amd/pmf/pmf.h
> index 34778192432e..2ad5ece47601 100644
> --- a/drivers/platform/x86/amd/pmf/pmf.h
> +++ b/drivers/platform/x86/amd/pmf/pmf.h
> @@ -595,6 +595,7 @@ int apmf_get_static_slider_granular(struct amd_pmf_dev 
> *pdev,
>  bool is_pprof_balanced(struct amd_pmf_dev *pmf);
>  int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev);
>  
> +const char *source_as_str(unsigned int state);

Too generic name, add prefix to the name.

-- 
 i.

>  int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx);
>  int amd_pmf_set_sps_power_limits(struct amd_pmf_dev *pmf);
> @@ -625,4 +626,6 @@ int apmf_check_smart_pc(struct amd_pmf_dev *pmf_dev);
>  
>  /* Smart PC - TA interfaces */
>  void amd_pmf_populate_ta_inputs(struct amd_pmf_dev *dev, struct 
> ta_pmf_enact_table *in);
> +void amd_pmf_dump_ta_inputs(struct amd_pmf_dev *dev, struct 
> ta_pmf_enact_table *in);
> +
>  #endif /* PMF_H */
> diff --git a/drivers/platform/x86/amd/pmf/spc.c 
> b/drivers/platform/x86/amd/pmf/spc.c
> index 3113bde051d9..3aee78629cce 100644
> --- a/drivers/platform/x86/amd/pmf/spc.c
> +++ b/drivers/platform/x86/amd/pmf/spc.c
> @@ -14,6 +14,43 @@
>  #include 
>  #include "pmf.h"
>  
> +#ifdef CONFIG_AMD_PMF_DEBUG
> +static const char *ta_slider_as_str(unsigned int state)
> +{
> + switch (state) {
> + case TA_BEST_PERFORMANCE:
> + return "PERFORMANCE";
> + case TA_BETTER_PERFORMANCE:
> + return "BALANCED";
> + case TA_BEST_BATTERY:
> + return "POWER_SAVER";
> + default:
> + return "Unknown TA Slider State";
> + }
> +}
> +
> +void amd_pmf_dump_ta_inputs(struct amd_pmf_dev *dev, struct 
> ta_pmf_enact_table *in)
> +{
> + dev_dbg(dev->dev, " TA inputs START \n");
> + dev_dbg(dev->dev, "Slider State : %s\n", 
> ta_slider_as_str(in->ev_info.power_slider));
> + dev_dbg(dev->dev, "Power Source : %s\n", 
> source_as_str(in->ev_info.power_source));
> + dev_dbg(dev->dev, "Battery Percentage : %u\n", 
> in->ev_info.bat_percentage);
> + dev_dbg(dev->dev, "Designed Battery Capacity : %u\n", 
> in->ev_info.bat_design);
> + dev_dbg(dev->dev, "Fully Charged Capacity : %u\n", 
> in->ev_info.full_charge_capacity);
> + dev_dbg(dev->dev, "Drain Rate : %d\n", in->ev_info.drain_rate);
> + dev_dbg(dev->dev, "Socket Power : %u\n", in->ev_info.socket_power);
> + dev_dbg(dev->dev, "Skin Temperature : %u\n", 
> in->ev_info.skin_temperature);
> + dev_dbg(dev->dev, "Avg C0 Residency : %u\n", 
> in->ev_info.avg_c0residency);
> + dev_dbg(dev->dev, "Max C0 Residency : %u\n", 
> in->ev_info.max_c0residency);
> + dev_dbg(dev->dev, "GFX Busy : %u\n", in->ev_info.gfx_busy);
> + dev_dbg(dev->dev, "Connected Display Count : %u\n", 
> in->ev_info.monitor_count);
> + dev_dbg(dev->dev, "LID State : %s\n", in->ev_info.lid_state ? "Close" : 
> "Open");
> + dev_dbg(dev->dev, " TA inputs END \n");
> +}
> +#else
> +void amd_pmf_dump_ta_inputs(struct amd_pmf_dev *dev, struct 
> ta_pmf_enact_table *in) {}
> +#endif
> +
>  static void amd_pmf_get_smu_info(struct amd_pmf_dev *dev, struct 
> ta_pmf_enact_table *in)
>  {
>   u16 max, avg = 0;
> diff --git a/drivers/platform/x86/amd/pmf/sps.c 
> b/drivers/platform/x86/amd/pmf/sps.c
> index a70e67749be3..13e36b52dfe8 100644
> --- a/drivers/platform/x86/amd/pmf/sps.c
> +++ b/drivers/platform/x86/amd/pmf/sps.c
> @@ -27,7 +27,7 @@ static const char *slider_as_str(unsigned int state)
>   }
>  }
>  
> -static const char *source_as_str(unsigned int state)
> +const char *source_as_str(unsigned int state)
>  {
>   switch (state) {
>   case POWER_SOURCE_AC:
> diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
> b/drivers/platform/x86/amd/pmf/tee-if.c
> index 961011530c1b..b0711b2f8c8f 100644
> --- a/drivers/platform/x86/amd/pmf/tee-if.c
> +++ b/drivers/platform/x86/amd/pmf/tee-if.c
> @@ -187,6 +187,7 @@ static int amd_pmf_invoke_cmd_enact(struct amd_pmf_dev 
> *dev)
>   }
>  
>   if (ta_sm->pmf_result == TA_PMF_TYPE_SUCCESS && out->actions_count) {
> + amd_pmf_dump_ta_inputs(dev, in);
>   dev_dbg(de

Re: [PATCH v2 08/16] platform/x86/amd/pmf: Add support to update system state

2023-10-04 Thread Ilpo Järvinen
On Sat, 30 Sep 2023, Shyam Sundar S K wrote:

> PMF driver based on the output actions from the TA can request to update
> the system states like entering s0i3, lock screen etc. by generating
> an uevent. Based on the udev rules set in the userspace the event id
> matching the uevent shall get updated accordingly using the systemctl.
> 
> Sample udev rules under Documentation/admin-guide/pmf.rst.
> 
> Reported-by: kernel test robot 
> Closes: 
> https://lore.kernel.org/oe-kbuild-all/202309260515.5xbr6n0g-...@intel.com/

Please don't put lkp tags for patches that are still under development 
(even if the email you get misleadingly instructs you to). Only use them 
when you fix code that's already in tree based on LKP's report.

> Signed-off-by: Shyam Sundar S K 
> ---
>  Documentation/admin-guide/index.rst   |  1 +
>  Documentation/admin-guide/pmf.rst | 25 
>  drivers/platform/x86/amd/pmf/pmf.h|  9 ++
>  drivers/platform/x86/amd/pmf/tee-if.c | 41 ++-
>  4 files changed, 75 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/admin-guide/pmf.rst
> 
> diff --git a/Documentation/admin-guide/index.rst 
> b/Documentation/admin-guide/index.rst
> index 43ea35613dfc..fb40a1f6f79e 100644
> --- a/Documentation/admin-guide/index.rst
> +++ b/Documentation/admin-guide/index.rst
> @@ -119,6 +119,7 @@ configure specific aspects of kernel behavior to your 
> liking.
> parport
> perf-security
> pm/index
> +   pmf
> pnp
> rapidio
> ras
> diff --git a/Documentation/admin-guide/pmf.rst 
> b/Documentation/admin-guide/pmf.rst
> new file mode 100644
> index ..90072add511e
> --- /dev/null
> +++ b/Documentation/admin-guide/pmf.rst
> @@ -0,0 +1,25 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +Set udev rules for PMF Smart PC Builder
> +---
> +
> +AMD PMF(Platform Management Framework) Smart PC Solution builder has to set 
> the system states
> +like S0i3, Screen lock, hibernate etc, based on the output actions provided 
> by the PMF
> +TA (Trusted Application).
> +
> +In order for this to work the PMF driver generates a uevent for userspace to 
> react to. Below are
> +sample udev rules that can facilitate this experience when a machine has PMF 
> Smart PC solution builder
> +enabled.
> +
> +Please add the following line(s) to
> +``/etc/udev/rules.d/99-local.rules``::
> +
> +DRIVERS=="amd-pmf", ACTION=="change", ENV{EVENT_ID}=="1", 
> RUN+="/usr/bin/systemctl suspend"
> +DRIVERS=="amd-pmf", ACTION=="change", ENV{EVENT_ID}=="2", 
> RUN+="/usr/bin/systemctl hibernate"
> +DRIVERS=="amd-pmf", ACTION=="change", ENV{EVENT_ID}=="3", 
> RUN+="/bin/loginctl lock-sessions"
> +
> +EVENT_ID values:
> +1= Put the system to S0i3/S2Idle
> +2= Put the system to hibernate
> +3= Lock the screen
> +
> diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
> b/drivers/platform/x86/amd/pmf/pmf.h
> index d5e410c41e81..34778192432e 100644
> --- a/drivers/platform/x86/amd/pmf/pmf.h
> +++ b/drivers/platform/x86/amd/pmf/pmf.h
> @@ -73,6 +73,7 @@
>  #define PMF_POLICY_STT_MIN   6
>  #define PMF_POLICY_STT_SKINTEMP_APU  7
>  #define PMF_POLICY_STT_SKINTEMP_HS2  8
> +#define PMF_POLICY_SYSTEM_STATE  9
>  #define PMF_POLICY_P3T   38
>  
>  /* TA macros */
> @@ -439,6 +440,13 @@ struct apmf_dyn_slider_output {
>  } __packed;
>  
>  /* Smart PC - TA internals */
> +enum system_state {
> + SYSTEM_STATE__S0i3 = 1,
> + SYSTEM_STATE__S4,
> + SYSTEM_STATE__SCREEN_LOCK,
> + SYSTEM_STATE__MAX
> +};
> +
>  enum ta_slider {
>   TA_BEST_BATTERY, /* Best Battery */
>   TA_BETTER_BATTERY, /* Better Battery */
> @@ -470,6 +478,7 @@ enum ta_pmf_error_type {
>  };
>  
>  struct pmf_action_table {
> + enum system_state system_state;
>   unsigned long spl; /* in mW */
>   unsigned long sppt; /* in mW */
>   unsigned long sppt_apuonly; /* in mW */
> diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
> b/drivers/platform/x86/amd/pmf/tee-if.c
> index 315e3d2eacdf..961011530c1b 100644
> --- a/drivers/platform/x86/amd/pmf/tee-if.c
> +++ b/drivers/platform/x86/amd/pmf/tee-if.c
> @@ -24,6 +24,20 @@ MODULE_PARM_DESC(pb_actions_ms, "Policy binary actions 
> sampling frequency (defau
>  static const uuid_t amd_pmf_ta_uuid = UUID_INIT(0x6fd93b77, 0x3fb8, 0x524d,
>   0xb1, 0x2d, 0xc5, 0x29, 0xb1, 
> 0x3d, 0x85, 0x43);
>  
> +static const char *amd_pmf_uevent_as_str(unsigned int state)
> +{
> + switch (state) {
> + case SYSTEM_STATE__S0i3:
> + return "S0i3";
> + case SYSTEM_STATE__S4:
> + return "S4";
> + case SYSTEM_STATE__SCREEN_LOCK:
> + return "SCREEN_LOCK";
> + default:
> + return "Unknown Smart PC event";
> + }
> +}
> +
>  

Re: [PATCH v2 06/16] platform/x86/amd/pmf: Add support to get inputs from other subsystems

2023-10-04 Thread Ilpo Järvinen
On Sat, 30 Sep 2023, Shyam Sundar S K wrote:

> PMF driver sends changing inputs from each subystem to TA for evaluating
> the conditions in the policy binary.
> 
> Add initial support of plumbing in the PMF driver for Smart PC to get
> information from other subsystems in the kernel.
> 
> Signed-off-by: Shyam Sundar S K 
> ---
>  drivers/platform/x86/amd/pmf/Makefile |   2 +-
>  drivers/platform/x86/amd/pmf/pmf.h|  18 
>  drivers/platform/x86/amd/pmf/spc.c| 119 ++
>  drivers/platform/x86/amd/pmf/tee-if.c |   3 +
>  4 files changed, 141 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/platform/x86/amd/pmf/spc.c
> 
> diff --git a/drivers/platform/x86/amd/pmf/Makefile 
> b/drivers/platform/x86/amd/pmf/Makefile
> index d2746ee7369f..6b26e48ce8ad 100644
> --- a/drivers/platform/x86/amd/pmf/Makefile
> +++ b/drivers/platform/x86/amd/pmf/Makefile
> @@ -7,4 +7,4 @@
>  obj-$(CONFIG_AMD_PMF) += amd-pmf.o
>  amd-pmf-objs := core.o acpi.o sps.o \
>   auto-mode.o cnqf.o \
> - tee-if.o
> + tee-if.o spc.o
> diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
> b/drivers/platform/x86/amd/pmf/pmf.h
> index 6f4b6f4ecee4..60b11455dadf 100644
> --- a/drivers/platform/x86/amd/pmf/pmf.h
> +++ b/drivers/platform/x86/amd/pmf/pmf.h
> @@ -149,6 +149,21 @@ struct smu_pmf_metrics {
>   u16 infra_gfx_maxfreq; /* in MHz */
>   u16 skin_temp; /* in centi-Celsius */
>   u16 device_state;
> + u16 curtemp; /* in centi-Celsius */
> + u16 filter_alpha_value;
> + u16 avg_gfx_clkfrequency;
> + u16 avg_fclk_frequency;
> + u16 avg_gfx_activity;
> + u16 avg_socclk_frequency;
> + u16 avg_vclk_frequency;
> + u16 avg_vcn_activity;
> + u16 avg_dram_reads;
> + u16 avg_dram_writes;
> + u16 avg_socket_power;
> + u16 avg_core_power[2];
> + u16 avg_core_c0residency[16];
> + u16 spare1;
> + u32 metrics_counter;
>  } __packed;
>  
>  enum amd_stt_skin_temp {
> @@ -595,4 +610,7 @@ extern const struct attribute_group 
> cnqf_feature_attribute_group;
>  int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev);
>  void amd_pmf_deinit_smart_pc(struct amd_pmf_dev *dev);
>  int apmf_check_smart_pc(struct amd_pmf_dev *pmf_dev);
> +
> +/* Smart PC - TA interfaces */
> +void amd_pmf_populate_ta_inputs(struct amd_pmf_dev *dev, struct 
> ta_pmf_enact_table *in);
>  #endif /* PMF_H */
> diff --git a/drivers/platform/x86/amd/pmf/spc.c 
> b/drivers/platform/x86/amd/pmf/spc.c
> new file mode 100644
> index ..3113bde051d9
> --- /dev/null
> +++ b/drivers/platform/x86/amd/pmf/spc.c
> @@ -0,0 +1,119 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * AMD Platform Management Framework Driver - Smart PC Capabilities
> + *
> + * Copyright (c) 2023, Advanced Micro Devices, Inc.
> + * All Rights Reserved.
> + *
> + * Authors: Shyam Sundar S K 
> + *  Patil Rajesh Reddy 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include "pmf.h"
> +
> +static void amd_pmf_get_smu_info(struct amd_pmf_dev *dev, struct 
> ta_pmf_enact_table *in)
> +{
> + u16 max, avg = 0;
> + int i;
> +
> + memset(dev->buf, 0, sizeof(dev->m_table));
> + amd_pmf_send_cmd(dev, SET_TRANSFER_TABLE, 0, 7, NULL);
> + memcpy(&dev->m_table, dev->buf, sizeof(dev->m_table));
> +
> + in->ev_info.socket_power = dev->m_table.apu_power + 
> dev->m_table.dgpu_power;
> + in->ev_info.skin_temperature = dev->m_table.skin_temp;
> +
> + /* get the avg C0 residency of all the cores */
> + for (i = 0; i < ARRAY_SIZE(dev->m_table.avg_core_c0residency); i++)
> + avg += dev->m_table.avg_core_c0residency[i];
> +
> + /* get the max C0 residency of all the cores */
> + max = dev->m_table.avg_core_c0residency[0];
> + for (i = 1; i < ARRAY_SIZE(dev->m_table.avg_core_c0residency); i++) {
> + if (dev->m_table.avg_core_c0residency[i] > max)
> + max = dev->m_table.avg_core_c0residency[i];
> + }

My comments weren't either answered adequately or changes made here.
Please check the v1 comments. I hope it's not because you feel hurry to 
get the next version out...

I'm still unsure if the u16 thing can overflow because I don't know what's 
the max value for avg_core_c0residency[i].

> +
> + in->ev_info.avg_c0residency = avg / 
> ARRAY_SIZE(dev->m_table.avg_core_c0residency);
> + in->ev_info.max_c0residency = max;
> + in->ev_info.gfx_busy = dev->m_table.avg_gfx_activity;
> +}
> +
> +static const char * const pmf_battery_supply_name[] = {
> + "BATT",
> + "BAT0",
> +};
> +
> +static int get_battery_prop(enum power_supply_property prop)
> +{
> + union power_supply_propval value;
> + struct power_supply *psy;
> + int i, ret = -EINVAL;
> +
> + for (i = 0; i < ARRAY_SIZE(pmf_battery_supply_name); i++) {
> + psy = power_supply_get_by_name(pmf_battery_supply_name[i]);
> + if (!psy)
> + continue;
> +
> + 

Re: [PATCH 1/5] drm/amd/display: Remove migrate_en/dis from dc_fpu_begin().

2023-10-04 Thread Hamza Mahfooz

On 10/3/23 15:53, Harry Wentland wrote:

On 2023-09-21 10:15, Sebastian Andrzej Siewior wrote:

This is a revert of the commit mentioned below while it is not wrong, as
in the kernel will explode, having migrate_disable() here it is
complete waste of resources.

Additionally commit message is plain wrong the review tag does not make


Not sure I follow what's unhelpful about the review tag with
0c316556d1249 ("drm/amd/display: Disable migration to ensure consistency of per-CPU 
variable")

I do wish the original patch showed the splat it's attempting
to fix. It apparently made a difference for something, whether
inadvertently or not. I wish I knew what that "something" was.


I did some digging, and it seems like the intention of that patch was to
fix the following splat:

WARNING: CPU: 5 PID: 1062 at 
drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/dc_fpu.c:71 
dc_assert_fp_enabled+0x1a/0x30 [amdgpu]

[...]
CPU: 5 PID: 1062 Comm: Xorg Tainted: G   OE 
5.15.0-56-generic #62-Ubuntu
Hardware name: ASUS System Product Name/ROG STRIX Z590-F GAMING WIFI, 
BIOS 1202 10/27/2021

RIP: 0010:dc_assert_fp_enabled+0x1a/0x30 [amdgpu]
Code: ff 45 31 f6 0f 0b e9 ca fe ff ff e8 90 1c 1f f7 48 c7 c0 00 30 03 
00 65 48 03 05 b1 aa 86 3f 8b 00 85 c0 7e 05 c3 cc cc cc cc <0f> 0b c3 
cc cc cc cc 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00

RSP: :b89b82a8f118 EFLAGS: 00010246
RAX:  RBX: 8c271cd0 RCX: 
RDX: 8c2708025000 RSI: 8c270e8c RDI: 8c271cd0
RBP: b89b82a8f1d0 R08:  R09: 7f6a
R10: b89b82a8f240 R11:  R12: 0002
R13: 8c271cd0 R14: 8c270e8c R15: 8c2708025000
FS:  7f0570019a80() GS:8c2e3fb4() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 5594858a0058 CR3: 00010e204001 CR4: 00770ee0
PKRU: 5554
Call Trace:
 
 ? dcn20_populate_dml_pipes_from_context+0x47/0x1730 [amdgpu]
 ? __kmalloc_node+0x2cb/0x3a0
 dcn32_populate_dml_pipes_from_context+0x2b/0x450 [amdgpu]
 dcn32_internal_validate_bw+0x15f9/0x2670 [amdgpu]
 dcn32_find_dummy_latency_index_for_fw_based_mclk_switch+0xd0/0x310 
[amdgpu]

 dcn32_calculate_wm_and_dlg_fpu+0xe6/0x1e50 [amdgpu]
 dcn32_calculate_wm_and_dlg+0x46/0x70 [amdgpu]
 dcn32_validate_bandwidth+0x1b7/0x3e0 [amdgpu]
 dc_validate_global_state+0x32c/0x560 [amdgpu]
 dc_validate_with_context+0x6e6/0xd80 [amdgpu]
 dc_commit_streams+0x21b/0x500 [amdgpu]
 dc_commit_state+0xf3/0x150 [amdgpu]
 amdgpu_dm_atomic_commit_tail+0x60d/0x3120 [amdgpu]
 ? dcn32_internal_validate_bw+0xcf8/0x2670 [amdgpu]
 ? fill_plane_buffer_attributes+0x1e5/0x560 [amdgpu]
 ? dcn32_validate_bandwidth+0x1e0/0x3e0 [amdgpu]
 ? kfree+0x1f7/0x250
 ? dcn32_validate_bandwidth+0x1e0/0x3e0 [amdgpu]
 ? dc_validate_global_state+0x32c/0x560 [amdgpu]
 ? __cond_resched+0x1a/0x50
 ? __wait_for_common+0x3e/0x150
 ? fill_plane_buffer_attributes+0x1e5/0x560 [amdgpu]
 ? usleep_range_state+0x90/0x90
 ? wait_for_completion_timeout+0x1d/0x30
 commit_tail+0xc2/0x170 [drm_kms_helper]
 ? drm_atomic_helper_swap_state+0x20f/0x370 [drm_kms_helper]
 drm_atomic_helper_commit+0x12b/0x150 [drm_kms_helper]
 amdgpu_dm_atomic_commit+0x11/0x20 [amdgpu]
 drm_atomic_commit+0x47/0x60 [drm]
 drm_mode_obj_set_property_ioctl+0x16b/0x420 [drm]
 ? mutex_lock+0x13/0x50
 ? drm_mode_createblob_ioctl+0xf6/0x130 [drm]
 ? drm_mode_obj_find_prop_id+0x90/0x90 [drm]
 drm_ioctl_kernel+0xb0/0x100 [drm]
 drm_ioctl+0x268/0x4b0 [drm]
 ? drm_mode_obj_find_prop_id+0x90/0x90 [drm]
 ? ktime_get_mono_fast_ns+0x4a/0xa0
 amdgpu_drm_ioctl+0x4e/0x90 [amdgpu]
 __x64_sys_ioctl+0x92/0xd0
 do_syscall_64+0x59/0xc0
 ? do_user_addr_fault+0x1e7/0x670
 ? do_syscall_64+0x69/0xc0
 ? exit_to_user_mode_prepare+0x37/0xb0
 ? irqentry_exit_to_user_mode+0x9/0x20
 ? irqentry_exit+0x1d/0x30
 ? exc_page_fault+0x89/0x170
 entry_SYSCALL_64_after_hwframe+0x61/0xcb
RIP: 0033:0x7f05704a2aff
Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 
44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <41> 89 c0 
3d 00 f0 ff ff 77 1f 48 8b 44 24 18 64 48 2b 04 25 28 00

RSP: 002b:7ffc8c45a3f0 EFLAGS: 0246 ORIG_RAX: 0010
RAX: ffda RBX: 7ffc8c45a480 RCX: 7f05704a2aff
RDX: 7ffc8c45a480 RSI: c01864ba RDI: 000e
RBP: c01864ba R08: 0077 R09: 
R10: 7f05705a22f0 R11: 0246 R12: 0004
R13: 000e R14: 000f R15: 7ffc8c45a8a8
 
---[ end trace 4deab30bb69df00f ]---



Harry


it any better. The migrate_disable() interface has a fat comment
describing it and it includes the word "undesired" in the headline which
should tickle people to read it before using it.
Initially I assumed it is worded too harsh but now I beg to differ.

The reviewer of the original commit, even not understanding what
migrate_disable() does should ask the following:

- migrate_disable()

[PATCH v2] drm/i915: Reduce MCR lock surface

2023-10-04 Thread Nirmoy Das
Take the mcr lock only when driver needs to write into a mcr based
tlb based registers.

To prevent GT reset interference, employ gt->reset.mutex instead, since
intel_gt_mcr_multicast_write relies on gt->uncore->lock not being held.

v2: remove unused var, flags.

Signed-off-by: Nirmoy Das 
---
 drivers/gpu/drm/i915/gt/intel_tlb.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_tlb.c 
b/drivers/gpu/drm/i915/gt/intel_tlb.c
index 139608c30d97..0ad905df4a98 100644
--- a/drivers/gpu/drm/i915/gt/intel_tlb.c
+++ b/drivers/gpu/drm/i915/gt/intel_tlb.c
@@ -52,15 +52,13 @@ static void mmio_invalidate_full(struct intel_gt *gt)
struct intel_engine_cs *engine;
intel_engine_mask_t awake, tmp;
enum intel_engine_id id;
-   unsigned long flags;
 
if (GRAPHICS_VER(i915) < 8)
return;
 
intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
 
-   intel_gt_mcr_lock(gt, &flags);
-   spin_lock(&uncore->lock); /* serialise invalidate with GT reset */
+   mutex_lock(>->reset.mutex);/* serialise invalidate with GT reset */
 
awake = 0;
for_each_engine(engine, gt, id) {
@@ -68,9 +66,9 @@ static void mmio_invalidate_full(struct intel_gt *gt)
continue;
 
if (engine->tlb_inv.mcr)
-   intel_gt_mcr_multicast_write_fw(gt,
-   
engine->tlb_inv.reg.mcr_reg,
-   
engine->tlb_inv.request);
+   intel_gt_mcr_multicast_write(gt,
+
engine->tlb_inv.reg.mcr_reg,
+engine->tlb_inv.request);
else
intel_uncore_write_fw(uncore,
  engine->tlb_inv.reg.reg,
@@ -90,8 +88,7 @@ static void mmio_invalidate_full(struct intel_gt *gt)
 IS_ALDERLAKE_P(i915)))
intel_uncore_write_fw(uncore, GEN12_OA_TLB_INV_CR, 1);
 
-   spin_unlock(&uncore->lock);
-   intel_gt_mcr_unlock(gt, flags);
+   mutex_unlock(>->reset.mutex);
 
for_each_engine_masked(engine, gt, awake, tmp) {
if (wait_for_invalidate(engine))
-- 
2.41.0



Re: [PATCH v2 02/16] platform/x86/amd/pmf: Add support PMF-TA interaction

2023-10-04 Thread Ilpo Järvinen
On Sat, 30 Sep 2023, Shyam Sundar S K wrote:

> PMF TA (Trusted Application) loads via the TEE environment into the
> AMD ASP.
> 
> PMF-TA supports two commands:
> 1) Init: Initialize the TA with the PMF Smart PC policy binary and
> start the policy engine. A policy is a combination of inputs and
> outputs, where;
>  - the inputs are the changing dynamics of the system like the user
>behaviour, system heuristics etc.
>  - the outputs, which are the actions to be set on the system which
>lead to better power management and enhanced user experience.
> 
> PMF driver acts as a central manager in this case to supply the
> inputs required to the TA (either by getting the information from
> the other kernel subsystems or from userland)
> 
> 2) Enact: Enact the output actions from the TA. The action could be
> applying a new thermal limit to boost/throttle the power limits or
> change system behavior.
> 
> Reviewed-by: Mario Limonciello 
> Signed-off-by: Shyam Sundar S K 
> ---
>  drivers/platform/x86/amd/pmf/pmf.h| 10 +++
>  drivers/platform/x86/amd/pmf/tee-if.c | 97 ++-
>  2 files changed, 106 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
> b/drivers/platform/x86/amd/pmf/pmf.h
> index 02460c2a31ea..e0837799f521 100644
> --- a/drivers/platform/x86/amd/pmf/pmf.h
> +++ b/drivers/platform/x86/amd/pmf/pmf.h
> @@ -59,6 +59,9 @@
>  #define ARG_NONE 0
>  #define AVG_SAMPLE_SIZE 3
>  
> +/* TA macros */
> +#define PMF_TA_IF_VERSION_MAJOR  1
> +
>  /* AMD PMF BIOS interfaces */
>  struct apmf_verify_interface {
>   u16 size;
> @@ -184,6 +187,7 @@ struct amd_pmf_dev {
>   struct tee_shm *fw_shm_pool;
>   u32 session_id;
>   void *shbuf;
> + struct delayed_work pb_work;
>   bool smart_pc_enabled;
>  };
>  
> @@ -395,6 +399,12 @@ struct apmf_dyn_slider_output {
>   struct apmf_cnqf_power_set ps[APMF_CNQF_MAX];
>  } __packed;
>  
> +/* cmd ids for TA communication */
> +enum ta_pmf_command {
> + TA_PMF_COMMAND_POLICY_BUILDER_INITIALIZE,
> + TA_PMF_COMMAND_POLICY_BUILDER_ENACT_POLICIES,
> +};
> +
>  struct ta_pmf_shared_memory {
>   int command_id;
>   int resp_id;
> diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
> b/drivers/platform/x86/amd/pmf/tee-if.c
> index 4db80ca59a11..1b3985cd7c08 100644
> --- a/drivers/platform/x86/amd/pmf/tee-if.c
> +++ b/drivers/platform/x86/amd/pmf/tee-if.c
> @@ -13,9 +13,96 @@
>  #include "pmf.h"
>  
>  #define MAX_TEE_PARAM4
> +
> +/* Policy binary actions sampling frequency (in ms) */
> +static int pb_actions_ms = 1000;

MSEC_PER_SEC (from #include , don't include the vdso one).

> +#ifdef CONFIG_AMD_PMF_DEBUG
> +module_param(pb_actions_ms, int, 0644);
> +MODULE_PARM_DESC(pb_actions_ms, "Policy binary actions sampling frequency 
> (default = 1000ms)");
> +#endif

-- 
 i.



Re: [PATCH v2 04/16] platform/x86/amd/pmf: Add support for PMF Policy Binary

2023-10-04 Thread Ilpo Järvinen
On Sat, 30 Sep 2023, Shyam Sundar S K wrote:

> PMF Policy binary is a encrypted and signed binary that will be part
> of the BIOS. PMF driver via the ACPI interface checks the existence
> of Smart PC bit. If the advertised bit is found, PMF driver walks
> the acpi namespace to find out the policy binary size and the address
> which has to be passed to the TA during the TA init sequence.
> 
> The policy binary is comprised of inputs (or the events) and outputs
> (or the actions). With the PMF ecosystem, OEMs generate the policy
> binary (or could be multiple binaries) that contains a supported set
> of inputs and outputs which could be specifically carved out for each
> usage segment (or for each user also) that could influence the system
> behavior either by enriching the user experience or/and boost/throttle
> power limits.
> 
> Once the TA init command succeeds, the PMF driver sends the changing
> events in the current environment to the TA for a constant sampling
> frequency time (the event here could be a lid close or open) and
> if the policy binary has corresponding action built within it, the
> TA sends the action for it in the subsequent enact command.
> 
> If the inputs sent to the TA has no output defined in the policy
> binary generated by OEMs, there will be no action to be performed
> by the PMF driver.
> 
> Example policies:
> 
> 1) if slider is performance ; set the SPL to 40W
> Here PMF driver registers with the platform profile interface and
> when the slider position is changed, PMF driver lets the TA know
> about this. TA sends back an action to update the Sustained
> Power Limit (SPL). PMF driver updates this limit via the PMFW mailbox.
> 
> 2) if user_away ; then lock the system
> Here PMF driver hooks to the AMD SFH driver to know the user presence
> and send the inputs to TA and if the condition is met, the TA sends
> the action of locking the system. PMF driver generates a uevent and
> based on the udev rule in the userland the system gets locked with
> systemctl.
> 
> The intent here is to provide the OEM's to make a policy to lock the
> system when the user is away ; but the userland can make a choice to
> ignore it.
> 
> and so on.
> 
> The OEMs will have an utility to create numerous such policies and
> the policies shall be reviewed by AMD before signing and encrypting
> them. Policies are shared between operating systems to have seemless user
> experience.
> 
> Since all this action has to happen via the "amdtee" driver, currently
> there is no caller for it in the kernel which can load the amdtee driver.
> Without amdtee driver loading onto the system the "tee" calls shall fail
> from the PMF driver. Hence an explicit "request_module" has been added
> to address this.
> 
> Signed-off-by: Shyam Sundar S K 
> ---
>  drivers/platform/x86/amd/pmf/Kconfig  |   1 +
>  drivers/platform/x86/amd/pmf/acpi.c   |  37 +++
>  drivers/platform/x86/amd/pmf/core.c   |  12 +++
>  drivers/platform/x86/amd/pmf/pmf.h| 135 
>  drivers/platform/x86/amd/pmf/tee-if.c | 141 +-
>  5 files changed, 324 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/platform/x86/amd/pmf/Kconfig 
> b/drivers/platform/x86/amd/pmf/Kconfig
> index 3064bc8ea167..437b78c6d1c5 100644
> --- a/drivers/platform/x86/amd/pmf/Kconfig
> +++ b/drivers/platform/x86/amd/pmf/Kconfig
> @@ -9,6 +9,7 @@ config AMD_PMF
>   depends on POWER_SUPPLY
>   depends on AMD_NB
>   select ACPI_PLATFORM_PROFILE
> + depends on AMDTEE
>   help
> This driver provides support for the AMD Platform Management 
> Framework.
> The goal is to enhance end user experience by making AMD PCs smarter,
> diff --git a/drivers/platform/x86/amd/pmf/acpi.c 
> b/drivers/platform/x86/amd/pmf/acpi.c
> index 3fc5e4547d9f..d0512af2cd42 100644
> --- a/drivers/platform/x86/amd/pmf/acpi.c
> +++ b/drivers/platform/x86/amd/pmf/acpi.c
> @@ -286,6 +286,43 @@ int apmf_install_handler(struct amd_pmf_dev *pmf_dev)
>   return 0;
>  }
>  
> +static acpi_status apmf_walk_resources(struct acpi_resource *res, void *data)
> +{
> + struct amd_pmf_dev *dev = data;
> +
> + switch (res->type) {
> + case ACPI_RESOURCE_TYPE_ADDRESS64:
> + dev->policy_addr = res->data.address64.address.minimum;
> + dev->policy_sz = res->data.address64.address.address_length;
> + break;
> + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
> + dev->policy_addr = res->data.fixed_memory32.address;
> + dev->policy_sz = res->data.fixed_memory32.address_length;
> + break;
> + }
> +
> + if (!dev->policy_addr || dev->policy_sz > POLICY_BUF_MAX_SZ || 
> dev->policy_sz == 0) {
> + pr_err("Incorrect Policy params, possibly a SBIOS bug\n");
> + return AE_ERROR;
> + }
> +
> + return AE_OK;
> +}
> +
> +int apmf_check_smart_pc(struct amd_pmf_dev *pmf_dev)
> +{
> + acpi_handle ahandle = ACPI_HANDLE(pmf_dev->

[PATCH] drm/i915: Reduce MCR lock surface

2023-10-04 Thread Nirmoy Das
Take the mcr lock only when driver needs to write into a mcr based
tlb based registers.

To prevent GT reset interference, employ gt->reset.mutex instead, since
intel_gt_mcr_multicast_write relies on gt->uncore->lock not being held.

Signed-off-by: Nirmoy Das 
---
 drivers/gpu/drm/i915/gt/intel_tlb.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_tlb.c 
b/drivers/gpu/drm/i915/gt/intel_tlb.c
index 139608c30d97..7b2d9549e595 100644
--- a/drivers/gpu/drm/i915/gt/intel_tlb.c
+++ b/drivers/gpu/drm/i915/gt/intel_tlb.c
@@ -59,8 +59,7 @@ static void mmio_invalidate_full(struct intel_gt *gt)
 
intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
 
-   intel_gt_mcr_lock(gt, &flags);
-   spin_lock(&uncore->lock); /* serialise invalidate with GT reset */
+   mutex_lock(>->reset.mutex);/* serialise invalidate with GT reset */
 
awake = 0;
for_each_engine(engine, gt, id) {
@@ -68,9 +67,9 @@ static void mmio_invalidate_full(struct intel_gt *gt)
continue;
 
if (engine->tlb_inv.mcr)
-   intel_gt_mcr_multicast_write_fw(gt,
-   
engine->tlb_inv.reg.mcr_reg,
-   
engine->tlb_inv.request);
+   intel_gt_mcr_multicast_write(gt,
+
engine->tlb_inv.reg.mcr_reg,
+engine->tlb_inv.request);
else
intel_uncore_write_fw(uncore,
  engine->tlb_inv.reg.reg,
@@ -90,8 +89,7 @@ static void mmio_invalidate_full(struct intel_gt *gt)
 IS_ALDERLAKE_P(i915)))
intel_uncore_write_fw(uncore, GEN12_OA_TLB_INV_CR, 1);
 
-   spin_unlock(&uncore->lock);
-   intel_gt_mcr_unlock(gt, flags);
+   mutex_unlock(>->reset.mutex);
 
for_each_engine_masked(engine, gt, awake, tmp) {
if (wait_for_invalidate(engine))
-- 
2.41.0



Re: [PATCH v2 01/16] platform/x86/amd/pmf: Add PMF TEE interface

2023-10-04 Thread Ilpo Järvinen
On Sat, 30 Sep 2023, Shyam Sundar S K wrote:

> AMD PMF driver loads the PMF TA (Trusted Application) into the AMD
> ASP's (AMD Security Processor) TEE (Trusted Execution Environment).
> 
> PMF Trusted Application is a secured firmware placed under
> /lib/firmware/amdtee gets loaded only when the TEE environment is
> initialized. Add the initial code path to build these pipes.
> 
> Reviewed-by: Mario Limonciello 
> Signed-off-by: Shyam Sundar S K 
> ---
>  drivers/platform/x86/amd/pmf/Makefile |   3 +-
>  drivers/platform/x86/amd/pmf/core.c   |  11 ++-
>  drivers/platform/x86/amd/pmf/pmf.h|  16 
>  drivers/platform/x86/amd/pmf/tee-if.c | 112 ++
>  4 files changed, 138 insertions(+), 4 deletions(-)
>  create mode 100644 drivers/platform/x86/amd/pmf/tee-if.c
> 
> diff --git a/drivers/platform/x86/amd/pmf/Makefile 
> b/drivers/platform/x86/amd/pmf/Makefile
> index fdededf54392..d2746ee7369f 100644
> --- a/drivers/platform/x86/amd/pmf/Makefile
> +++ b/drivers/platform/x86/amd/pmf/Makefile
> @@ -6,4 +6,5 @@
>  
>  obj-$(CONFIG_AMD_PMF) += amd-pmf.o
>  amd-pmf-objs := core.o acpi.o sps.o \
> - auto-mode.o cnqf.o
> + auto-mode.o cnqf.o \
> + tee-if.o
> diff --git a/drivers/platform/x86/amd/pmf/core.c 
> b/drivers/platform/x86/amd/pmf/core.c
> index 78ed3ee22555..68f1389dda3e 100644
> --- a/drivers/platform/x86/amd/pmf/core.c
> +++ b/drivers/platform/x86/amd/pmf/core.c
> @@ -309,8 +309,11 @@ static void amd_pmf_init_features(struct amd_pmf_dev 
> *dev)
>   dev_dbg(dev->dev, "SPS enabled and Platform Profiles 
> registered\n");
>   }
>  
> - /* Enable Auto Mode */
> - if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
> + if (amd_pmf_init_smart_pc(dev)) {
> + /* Enable Smart PC Solution builder */
> + dev_dbg(dev->dev, "Smart PC Solution Enabled\n");
> + } else if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
> + /* Enable Auto Mode */
>   amd_pmf_init_auto_mode(dev);
>   dev_dbg(dev->dev, "Auto Mode Init done\n");
>   } else if (is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_AC) ||
> @@ -330,7 +333,9 @@ static void amd_pmf_deinit_features(struct amd_pmf_dev 
> *dev)
>   amd_pmf_deinit_sps(dev);
>   }
>  
> - if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
> + if (dev->smart_pc_enabled) {
> + amd_pmf_deinit_smart_pc(dev);
> + } else if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
>   amd_pmf_deinit_auto_mode(dev);
>   } else if (is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_AC) ||
> is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_DC)) 
> {
> diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
> b/drivers/platform/x86/amd/pmf/pmf.h
> index deba88e6e4c8..02460c2a31ea 100644
> --- a/drivers/platform/x86/amd/pmf/pmf.h
> +++ b/drivers/platform/x86/amd/pmf/pmf.h
> @@ -179,6 +179,12 @@ struct amd_pmf_dev {
>   bool cnqf_enabled;
>   bool cnqf_supported;
>   struct notifier_block pwr_src_notifier;
> + /* Smart PC solution builder */
> + struct tee_context *tee_ctx;
> + struct tee_shm *fw_shm_pool;
> + u32 session_id;
> + void *shbuf;
> + bool smart_pc_enabled;
>  };
>  
>  struct apmf_sps_prop_granular {
> @@ -389,6 +395,13 @@ struct apmf_dyn_slider_output {
>   struct apmf_cnqf_power_set ps[APMF_CNQF_MAX];
>  } __packed;
>  
> +struct ta_pmf_shared_memory {
> + int command_id;
> + int resp_id;
> + u32 pmf_result;
> + u32 if_version;
> +};
> +
>  /* Core Layer */
>  int apmf_acpi_init(struct amd_pmf_dev *pmf_dev);
>  void apmf_acpi_deinit(struct amd_pmf_dev *pmf_dev);
> @@ -433,4 +446,7 @@ void amd_pmf_deinit_cnqf(struct amd_pmf_dev *dev);
>  int amd_pmf_trans_cnqf(struct amd_pmf_dev *dev, int socket_power, ktime_t 
> time_lapsed_ms);
>  extern const struct attribute_group cnqf_feature_attribute_group;
>  
> +/* Smart PC builder Layer*/
> +int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev);
> +void amd_pmf_deinit_smart_pc(struct amd_pmf_dev *dev);
>  #endif /* PMF_H */
> diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
> b/drivers/platform/x86/amd/pmf/tee-if.c
> new file mode 100644
> index ..4db80ca59a11
> --- /dev/null
> +++ b/drivers/platform/x86/amd/pmf/tee-if.c
> @@ -0,0 +1,112 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * AMD Platform Management Framework Driver - TEE Interface
> + *
> + * Copyright (c) 2023, Advanced Micro Devices, Inc.
> + * All Rights Reserved.
> + *
> + * Author: Shyam Sundar S K 
> + */
> +
> +#include 
> +#include 
> +#include "pmf.h"
> +
> +#define MAX_TEE_PARAM4
> +static const uuid_t amd_pmf_ta_uuid = UUID_INIT(0x6fd93b77, 0x3fb8, 0x524d,
> + 0xb1, 0x2d, 0xc5, 0x29, 0xb1, 
> 0x3d, 0x85, 0x43);
> +
> +static int amd_pmf_amdtee_ta_match(struct tee_ioctl_version_data *ver, const 
> void *data)
> 

Re: [PATCH v8 0/5] Add fdinfo support to Panfrost

2023-10-04 Thread Boris Brezillon
On Fri, 29 Sep 2023 19:14:26 +0100
Adrián Larumbe  wrote:

> This patch series adds fdinfo support to the Panfrost DRM driver. It will
> display a series of key:value pairs under /proc/pid/fdinfo/fd for render
> processes that open the Panfrost DRM file.
> 
> The pairs contain basic drm gpu engine and memory region information that
> can either be cat by a privileged user or accessed with IGT's gputop
> utility.
> 
> Changelog:
> 
> v1: 
> https://lore.kernel.org/lkml/bb52b872-e41b-3894-285e-b52cfc849...@arm.com/T/
> 
> v2: https://lore.kernel.org/lkml/20230901084457.5bc1a...@collabora.com/T/
>  - Changed the way gpu cycles and engine time are calculated, using GPU
>registers and taking into account potential resets.
>  - Split render engine values into fragment and vertex/tiler ones.
>  - Added more fine-grained calculation of RSS size for BO's.
>  - Implemente selection of drm-memory region size units.
>  - Removed locking of shrinker's mutex in GEM obj status function.
> 
> v3: 
> https://lore.kernel.org/lkml/20230905184533.959171-1-adrian.laru...@collabora.com/
>  - Changed fdinfo engine names to something more descriptive.;
>  - Mentioned GPU cycle counts aren't an exact measure.
>  - Handled the case when job->priv might be NULL.
>  - Handled 32 bit overflow of cycle register.
>  - Kept fdinfo drm memory stats size unit display within 10k times the
>previous multiplier for more accurate BO size numbers.
>  - Removed special handling of Prime imported BO RSS.
>  - Use rss_size only for heap objects.
>  - Use bo->base.madv instead of specific purgeable flag.
>  - Fixed kernel test robot warnings.
> 
> v4: 
> https://lore.kernel.org/lkml/20230912084044.955864-1-adrian.laru...@collabora.com/
>  - Move cycle counter get and put to panfrost_job_hw_submit and
>panfrost_job_handle_{err,done} for more accuracy.
>  - Make sure cycle counter refs are released in reset path
>  - Drop the model param for toggling cycle counting and do
>leave it down to the debugfs file.
>  - Don't disable cycle counter when togglint debugfs file,
>let refcounting logic handle it instead.
>  - Remove fdinfo data nested structure definion and 'names' field
>  - When incrementing BO RSS size in GPU MMU page fault IRQ handler, assume
>granuality of 2MiB for every successful mapping.
>  - drm-file picks an fdinfo memory object size unit that doesn't lose 
> precision.
> 
> v5: 
> https://lore.kernel.org/lkml/20230914223928.2374933-1-adrian.laru...@collabora.com/
>  - Removed explicit initialisation of atomic variable for profiling mode,
>as it's allocated with kzalloc.
>  - Pass engine utilisation structure to jobs rather than the file context, to 
> avoid
>future misusage of the latter.
>  - Remove double reading of cycle counter register and ktime in job deqeueue 
> function,
>as the scheduler will make sure these values are read over in case of 
> requeuing.
>  - Moved putting of cycle counting refcnt into panfrost job dequeue.
>function to avoid repetition.
> 
> v6: 
> https://lore.kernel.org/lkml/c73ad42b-a8db-23c2-86c7-1a2939dba...@linux.intel.com/T/
>  - Fix wrong swapped-round engine time and cycle values in fdinfo
>drm print statements.
> 
> v7: 
> https://lore.kernel.org/lkml/20230927213133.1651169-6-adrian.laru...@collabora.com/T/
>  - Make sure an object's actual RSS size is added to the overall fdinfo's 
> purgeable
>and active size tally when it's both resident and purgeable or active.
>  - Create a drm/panfrost.rst documentation file with meaning of fdinfo 
> strings.
>  - BUILD_BUG_ON checking the engine name array size for fdinfo.
>  - Added copyright notices for Amazon in Panfrost's new debugfs files.
>  - Discarded fdinfo memory stats unit size selection patch.
> 
> v8:
>  - Style improvements and addressing nitpicks. 
> 
> Adrián Larumbe (5):
>   drm/panfrost: Add cycle count GPU register definitions
>   drm/panfrost: Add fdinfo support GPU load metrics
>   drm/panfrost: Add fdinfo support for memory stats
>   drm/drm_file: Add DRM obj's RSS reporting function for fdinfo
>   drm/panfrost: Implement generic DRM object RSS reporting function

Queued to drm-misc-next.

Thanks!

Boris

> 
>  Documentation/gpu/drm-usage-stats.rst   |  1 +
>  Documentation/gpu/panfrost.rst  | 38 +
>  drivers/gpu/drm/drm_file.c  |  8 +--
>  drivers/gpu/drm/panfrost/Makefile   |  2 +
>  drivers/gpu/drm/panfrost/panfrost_debugfs.c | 21 
>  drivers/gpu/drm/panfrost/panfrost_debugfs.h | 14 +
>  drivers/gpu/drm/panfrost/panfrost_devfreq.c |  8 +++
>  drivers/gpu/drm/panfrost/panfrost_devfreq.h |  3 ++
>  drivers/gpu/drm/panfrost/panfrost_device.c  |  2 +
>  drivers/gpu/drm/panfrost/panfrost_device.h  | 13 +
>  drivers/gpu/drm/panfrost/panfrost_drv.c | 60 -
>  drivers/gpu/drm/panfrost/panfrost_gem.c | 30 +++
>  drivers/gpu/drm/panfrost/panfrost_gem.h |  5 ++
>  drivers/gpu/drm/panfro

Re: [PATCH v2 03/16] platform/x86/amd/pmf: Change return type of amd_pmf_set_dram_addr()

2023-10-04 Thread Ilpo Järvinen
On Sat, 30 Sep 2023, Shyam Sundar S K wrote:

> In the current code, the metrics table information was required only
> for auto-mode or CnQF at a given time. Hence keeping the return type
> of amd_pmf_set_dram_addr() as static made sense.
> 
> But with the addition of Smart PC builder feature, the metrics table
> information has to be shared by the Smart PC also and this feature
> resides outside of core.c.
> 
> To make amd_pmf_set_dram_addr() visible outside of core.c make it
> as a non-static function and move the allocation of memory for
> metrics table from amd_pmf_init_metrics_table() to amd_pmf_set_dram_addr()
> as amd_pmf_set_dram_addr() is the common function to set the DRAM
> address.
> 
> Reviewed-by: Mario Limonciello 
> Signed-off-by: Shyam Sundar S K 
> ---
>  drivers/platform/x86/amd/pmf/core.c | 26 ++
>  drivers/platform/x86/amd/pmf/pmf.h  |  1 +
>  2 files changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/platform/x86/amd/pmf/core.c 
> b/drivers/platform/x86/amd/pmf/core.c
> index 68f1389dda3e..678dce4fea08 100644
> --- a/drivers/platform/x86/amd/pmf/core.c
> +++ b/drivers/platform/x86/amd/pmf/core.c
> @@ -251,29 +251,35 @@ static const struct pci_device_id pmf_pci_ids[] = {
>   { }
>  };
>  
> -static void amd_pmf_set_dram_addr(struct amd_pmf_dev *dev)
> +int amd_pmf_set_dram_addr(struct amd_pmf_dev *dev)
>  {
>   u64 phys_addr;
>   u32 hi, low;
>  
> + /* Get Metrics Table Address */
> + dev->buf = kzalloc(sizeof(dev->m_table), GFP_KERNEL);
> + if (!dev->buf)
> + return -ENOMEM;
> +
>   phys_addr = virt_to_phys(dev->buf);
>   hi = phys_addr >> 32;
>   low = phys_addr & GENMASK(31, 0);
>  
>   amd_pmf_send_cmd(dev, SET_DRAM_ADDR_HIGH, 0, hi, NULL);
>   amd_pmf_send_cmd(dev, SET_DRAM_ADDR_LOW, 0, low, NULL);
> +
> + return 0;
>  }
>  
>  int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev)
>  {
> - /* Get Metrics Table Address */
> - dev->buf = kzalloc(sizeof(dev->m_table), GFP_KERNEL);
> - if (!dev->buf)
> - return -ENOMEM;
> + int ret;
>  
>   INIT_DELAYED_WORK(&dev->work_buffer, amd_pmf_get_metrics);
>  
> - amd_pmf_set_dram_addr(dev);
> + ret = amd_pmf_set_dram_addr(dev);
> + if (ret)
> + return ret;
>  
>   /*
>* Start collecting the metrics data after a small delay
> @@ -287,9 +293,13 @@ int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev)
>  static int amd_pmf_resume_handler(struct device *dev)
>  {
>   struct amd_pmf_dev *pdev = dev_get_drvdata(dev);
> + int ret;
>  
> - if (pdev->buf)
> - amd_pmf_set_dram_addr(pdev);
> + if (pdev->buf) {
> + ret = amd_pmf_set_dram_addr(pdev);

Won't this now leak the previous ->buf?

> + if (ret)
> + return ret;
> + }
>  
>   return 0;
>  }
> diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
> b/drivers/platform/x86/amd/pmf/pmf.h
> index e0837799f521..3930b8ed8333 100644
> --- a/drivers/platform/x86/amd/pmf/pmf.h
> +++ b/drivers/platform/x86/amd/pmf/pmf.h
> @@ -421,6 +421,7 @@ int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev);
>  int amd_pmf_get_power_source(void);
>  int apmf_install_handler(struct amd_pmf_dev *pmf_dev);
>  int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag);
> +int amd_pmf_set_dram_addr(struct amd_pmf_dev *dev);
>  
>  /* SPS Layer */
>  int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf);
> 

-- 
 i.



Re: [PATCH v2 02/16] platform/x86/amd/pmf: Add support PMF-TA interaction

2023-10-04 Thread Ilpo Järvinen
On Sat, 30 Sep 2023, Shyam Sundar S K wrote:

> PMF TA (Trusted Application) loads via the TEE environment into the
> AMD ASP.
> 
> PMF-TA supports two commands:
> 1) Init: Initialize the TA with the PMF Smart PC policy binary and
> start the policy engine. A policy is a combination of inputs and
> outputs, where;
>  - the inputs are the changing dynamics of the system like the user
>behaviour, system heuristics etc.
>  - the outputs, which are the actions to be set on the system which
>lead to better power management and enhanced user experience.
> 
> PMF driver acts as a central manager in this case to supply the
> inputs required to the TA (either by getting the information from
> the other kernel subsystems or from userland)
> 
> 2) Enact: Enact the output actions from the TA. The action could be
> applying a new thermal limit to boost/throttle the power limits or
> change system behavior.
> 
> Reviewed-by: Mario Limonciello 
> Signed-off-by: Shyam Sundar S K 
> ---
>  drivers/platform/x86/amd/pmf/pmf.h| 10 +++
>  drivers/platform/x86/amd/pmf/tee-if.c | 97 ++-
>  2 files changed, 106 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
> b/drivers/platform/x86/amd/pmf/pmf.h
> index 02460c2a31ea..e0837799f521 100644
> --- a/drivers/platform/x86/amd/pmf/pmf.h
> +++ b/drivers/platform/x86/amd/pmf/pmf.h
> @@ -59,6 +59,9 @@
>  #define ARG_NONE 0
>  #define AVG_SAMPLE_SIZE 3
>  
> +/* TA macros */
> +#define PMF_TA_IF_VERSION_MAJOR  1
> +
>  /* AMD PMF BIOS interfaces */
>  struct apmf_verify_interface {
>   u16 size;
> @@ -184,6 +187,7 @@ struct amd_pmf_dev {
>   struct tee_shm *fw_shm_pool;
>   u32 session_id;
>   void *shbuf;
> + struct delayed_work pb_work;
>   bool smart_pc_enabled;
>  };
>  
> @@ -395,6 +399,12 @@ struct apmf_dyn_slider_output {
>   struct apmf_cnqf_power_set ps[APMF_CNQF_MAX];
>  } __packed;
>  
> +/* cmd ids for TA communication */
> +enum ta_pmf_command {
> + TA_PMF_COMMAND_POLICY_BUILDER_INITIALIZE,
> + TA_PMF_COMMAND_POLICY_BUILDER_ENACT_POLICIES,
> +};
> +
>  struct ta_pmf_shared_memory {
>   int command_id;
>   int resp_id;
> diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
> b/drivers/platform/x86/amd/pmf/tee-if.c
> index 4db80ca59a11..1b3985cd7c08 100644
> --- a/drivers/platform/x86/amd/pmf/tee-if.c
> +++ b/drivers/platform/x86/amd/pmf/tee-if.c
> @@ -13,9 +13,96 @@
>  #include "pmf.h"
>  
>  #define MAX_TEE_PARAM4
> +
> +/* Policy binary actions sampling frequency (in ms) */
> +static int pb_actions_ms = 1000;
> +#ifdef CONFIG_AMD_PMF_DEBUG
> +module_param(pb_actions_ms, int, 0644);
> +MODULE_PARM_DESC(pb_actions_ms, "Policy binary actions sampling frequency 
> (default = 1000ms)");
> +#endif
> +
>  static const uuid_t amd_pmf_ta_uuid = UUID_INIT(0x6fd93b77, 0x3fb8, 0x524d,
>   0xb1, 0x2d, 0xc5, 0x29, 0xb1, 
> 0x3d, 0x85, 0x43);
>  
> +static void amd_pmf_prepare_args(struct amd_pmf_dev *dev, int cmd,
> +  struct tee_ioctl_invoke_arg *arg,
> +  struct tee_param *param)
> +{
> + memset(arg, 0, sizeof(*arg));
> + memset(param, 0, MAX_TEE_PARAM * sizeof(*param));
> +
> + arg->func = cmd;
> + arg->session = dev->session_id;
> + arg->num_params = MAX_TEE_PARAM;
> +
> + /* Fill invoke cmd params */
> + param[0].u.memref.size = sizeof(struct ta_pmf_shared_memory);
> + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT;
> + param[0].u.memref.shm = dev->fw_shm_pool;
> + param[0].u.memref.shm_offs = 0;
> +}
> +
> +static int amd_pmf_invoke_cmd_enact(struct amd_pmf_dev *dev)
> +{
> + struct ta_pmf_shared_memory *ta_sm = NULL;
> + struct tee_param param[MAX_TEE_PARAM];
> + struct tee_ioctl_invoke_arg arg;
> + int ret = 0;
> +
> + if (!dev->tee_ctx)
> + return -ENODEV;
> +
> + ta_sm = (struct ta_pmf_shared_memory *)dev->shbuf;

Don't cast from void * to a typed pointer, it's unnecessary as compiler 
will handle that for you.

> + memset(ta_sm, 0, sizeof(struct ta_pmf_shared_memory));

sizeof(*ta_sm) to be on the safer side of things.

> + ta_sm->command_id = TA_PMF_COMMAND_POLICY_BUILDER_ENACT_POLICIES;
> + ta_sm->if_version = PMF_TA_IF_VERSION_MAJOR;
> +
> + amd_pmf_prepare_args(dev, TA_PMF_COMMAND_POLICY_BUILDER_ENACT_POLICIES, 
> &arg, param);
> +
> + ret = tee_client_invoke_func(dev->tee_ctx, &arg, param);
> + if (ret < 0 || arg.ret != 0) {
> + dev_err(dev->dev, "TEE enact cmd failed. err: %x, ret:%x\n", 
> arg.ret, ret);

-Exx code should be printed as %x

> + return -EINVAL;

This overrides the original error code if ret < 0.

> + }
> +
> + return 0;
> +}
> +
> +static int amd_pmf_invoke_cmd_init(struct amd_pmf_dev *dev)
> +{
> + struct ta_pmf_shared_memory *ta_sm = NULL;
> + struct tee_param param

Re: [PATCH v2 01/16] platform/x86/amd/pmf: Add PMF TEE interface

2023-10-04 Thread Ilpo Järvinen
On Sat, 30 Sep 2023, Shyam Sundar S K wrote:

> AMD PMF driver loads the PMF TA (Trusted Application) into the AMD
> ASP's (AMD Security Processor) TEE (Trusted Execution Environment).
> 
> PMF Trusted Application is a secured firmware placed under
> /lib/firmware/amdtee gets loaded only when the TEE environment is
> initialized. Add the initial code path to build these pipes.
> 
> Reviewed-by: Mario Limonciello 
> Signed-off-by: Shyam Sundar S K 
> ---
>  drivers/platform/x86/amd/pmf/Makefile |   3 +-
>  drivers/platform/x86/amd/pmf/core.c   |  11 ++-
>  drivers/platform/x86/amd/pmf/pmf.h|  16 
>  drivers/platform/x86/amd/pmf/tee-if.c | 112 ++
>  4 files changed, 138 insertions(+), 4 deletions(-)
>  create mode 100644 drivers/platform/x86/amd/pmf/tee-if.c
> 
> diff --git a/drivers/platform/x86/amd/pmf/Makefile 
> b/drivers/platform/x86/amd/pmf/Makefile
> index fdededf54392..d2746ee7369f 100644
> --- a/drivers/platform/x86/amd/pmf/Makefile
> +++ b/drivers/platform/x86/amd/pmf/Makefile
> @@ -6,4 +6,5 @@
>  
>  obj-$(CONFIG_AMD_PMF) += amd-pmf.o
>  amd-pmf-objs := core.o acpi.o sps.o \
> - auto-mode.o cnqf.o
> + auto-mode.o cnqf.o \
> + tee-if.o
> diff --git a/drivers/platform/x86/amd/pmf/core.c 
> b/drivers/platform/x86/amd/pmf/core.c
> index 78ed3ee22555..68f1389dda3e 100644
> --- a/drivers/platform/x86/amd/pmf/core.c
> +++ b/drivers/platform/x86/amd/pmf/core.c
> @@ -309,8 +309,11 @@ static void amd_pmf_init_features(struct amd_pmf_dev 
> *dev)
>   dev_dbg(dev->dev, "SPS enabled and Platform Profiles 
> registered\n");
>   }
>  
> - /* Enable Auto Mode */
> - if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
> + if (amd_pmf_init_smart_pc(dev)) {
> + /* Enable Smart PC Solution builder */
> + dev_dbg(dev->dev, "Smart PC Solution Enabled\n");
> + } else if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
> + /* Enable Auto Mode */

I'm pretty certain neither of these two comments add any information to 
what's readily visible from the code itself so they can be dropped.

>   amd_pmf_init_auto_mode(dev);
>   dev_dbg(dev->dev, "Auto Mode Init done\n");
>   } else if (is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_AC) ||
> @@ -330,7 +333,9 @@ static void amd_pmf_deinit_features(struct amd_pmf_dev 
> *dev)
>   amd_pmf_deinit_sps(dev);
>   }
>  
> - if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
> + if (dev->smart_pc_enabled) {
> + amd_pmf_deinit_smart_pc(dev);
> + } else if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
>   amd_pmf_deinit_auto_mode(dev);
>   } else if (is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_AC) ||
> is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_DC)) 
> {
> diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
> b/drivers/platform/x86/amd/pmf/pmf.h
> index deba88e6e4c8..02460c2a31ea 100644
> --- a/drivers/platform/x86/amd/pmf/pmf.h
> +++ b/drivers/platform/x86/amd/pmf/pmf.h
> @@ -179,6 +179,12 @@ struct amd_pmf_dev {
>   bool cnqf_enabled;
>   bool cnqf_supported;
>   struct notifier_block pwr_src_notifier;
> + /* Smart PC solution builder */
> + struct tee_context *tee_ctx;
> + struct tee_shm *fw_shm_pool;
> + u32 session_id;
> + void *shbuf;
> + bool smart_pc_enabled;
>  };
>  
>  struct apmf_sps_prop_granular {
> @@ -389,6 +395,13 @@ struct apmf_dyn_slider_output {
>   struct apmf_cnqf_power_set ps[APMF_CNQF_MAX];
>  } __packed;
>  
> +struct ta_pmf_shared_memory {
> + int command_id;
> + int resp_id;
> + u32 pmf_result;
> + u32 if_version;
> +};
> +
>  /* Core Layer */
>  int apmf_acpi_init(struct amd_pmf_dev *pmf_dev);
>  void apmf_acpi_deinit(struct amd_pmf_dev *pmf_dev);
> @@ -433,4 +446,7 @@ void amd_pmf_deinit_cnqf(struct amd_pmf_dev *dev);
>  int amd_pmf_trans_cnqf(struct amd_pmf_dev *dev, int socket_power, ktime_t 
> time_lapsed_ms);
>  extern const struct attribute_group cnqf_feature_attribute_group;
>  
> +/* Smart PC builder Layer*/

Missing space.

> +int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev);
> +void amd_pmf_deinit_smart_pc(struct amd_pmf_dev *dev);
>  #endif /* PMF_H */
> diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
> b/drivers/platform/x86/amd/pmf/tee-if.c
> new file mode 100644
> index ..4db80ca59a11
> --- /dev/null
> +++ b/drivers/platform/x86/amd/pmf/tee-if.c
> @@ -0,0 +1,112 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * AMD Platform Management Framework Driver - TEE Interface
> + *
> + * Copyright (c) 2023, Advanced Micro Devices, Inc.
> + * All Rights Reserved.
> + *
> + * Author: Shyam Sundar S K 
> + */
> +
> +#include 
> +#include 
> +#include "pmf.h"
> +
> +#define MAX_TEE_PARAM4
> +static const uuid_t amd_pmf_ta_uuid = UUID_INIT(0x6fd93b77, 0x3fb8, 0x524d,
> +  

Re: [Intel-gfx] [RFC PATCH] drm/i915/gt: Do not treat MCR locking timeouts as errors

2023-10-04 Thread Tvrtko Ursulin



On 04/10/2023 10:43, Andi Shyti wrote:

The MCR steering semaphore is a shared lock entry between i915
and various firmware components.

Getting the lock might sinchronize on some shared resources.
Sometimes though, it might happen that the firmware forgets to
unlock causing unnecessary noise in the driver which keeps doing
what was supposed to do, ignoring the problem.

Do not consider this failure as an error, but just print a debug
message stating that the MCR locking has been skipped.

On the driver side we still have spinlocks that make sure that
the access to the resources is serialized.

Signed-off-by: Andi Shyti 
Cc: Jonathan Cavitt 
Cc: Matt Roper 
Cc: Nirmoy Das 
---
  drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 6 ++
  1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
index 326c2ed1d99b..51eb693df39b 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
@@ -395,10 +395,8 @@ void intel_gt_mcr_lock(struct intel_gt *gt, unsigned long 
*flags)
 * would indicate some hardware/firmware is misbehaving and not
 * releasing it properly.
 */
-   if (err == -ETIMEDOUT) {
-   gt_err_ratelimited(gt, "hardware MCR steering semaphore timed 
out");
-   add_taint_for_CI(gt->i915, TAINT_WARN);  /* CI is now 
unreliable */
-   }
+   if (err == -ETIMEDOUT)
+   gt_dbg(gt, "hardware MCR steering semaphore timed out");
  }
  
  /**


Are we sure this does not warrant a level higher than dbg, such as 
notice/warn? Because how can we be sure the two entities will not stomp 
on each other toes if we failed to obtain lock? (How can we be sure 
about "forgot to unlock" vs "in prolonged active use"? Or if we can be 
sure, can we force unlock and take the lock for the driver explicitly?)


Regards,

Tvrtko


RE: [PATCH v6 3/6] drm/i915/panelreplay: Initializaton and compute config for panel replay

2023-10-04 Thread Murthy, Arun R


> -Original Message-
> From: Manna, Animesh 
> Sent: Thursday, September 21, 2023 11:44 AM
> To: intel-...@lists.freedesktop.org
> Cc: dri-devel@lists.freedesktop.org; Nikula, Jani ;
> Hogander, Jouni ; Murthy, Arun R
> ; Manna, Animesh 
> Subject: [PATCH v6 3/6] drm/i915/panelreplay: Initializaton and compute config
> for panel replay
> 
> Modify existing PSR implementation to enable panel replay feature of DP 2.0
> which is similar to PSR feature of EDP panel. There is different DPCD address 
> to
> check panel capability compare to PSR and vsc sdp header is different.
> 
> v1: Initial version.
> v2:
> - Set source_panel_replay_support flag under HAS_PANEL_REPLAY() condition
> check. [Jouni]
> - Code restructured around intel_panel_replay_init and renamed to
> intel_panel_replay_init_dpcd. [Jouni]
> - Remove the initial code modification around has_psr2 flag. [Jouni]
> - Add CAN_PANEL_REPLAY() in intel_encoder_can_psr which is used to enable in
> intel_psr_post_plane_update. [Jouni]
> v3:
> - Initialize both psr and panel-replay. [Jouni]
> - Initialize both panel replay and psr if detected. [Jouni]
> - Refactoring psr function by introducing _psr_compute_config(). [Jouni]
> - Add check for !is_edp while deriving source_panel_replay_support. [Jouni]
> - Enable panel replay dpcd initialization in a separate patch. [Jouni]
> 
> v4:
> - HAS_PANEL_REPLAY() check not needed during sink capability check. [Jouni]
> - Set either panel replay source support or psr. [Jouni]
> 
> v5:
> - HAS_PANEL_REPLAY() removed and use HAS_DP20() instead. [Jouni]
> - Move psr related code to intel_psr.c. [Jani]
> - Reset sink_panel_replay_support flag during disconnection. [Jani]
> 
> v6: return statement restored which is removed by misatke. [Jouni]
> 
> Cc: Jouni Högander 
> Signed-off-by: Animesh Manna 
> ---
>  .../drm/i915/display/intel_display_types.h| 14 +--
>  drivers/gpu/drm/i915/display/intel_dp.c   | 50 --
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |  3 +
>  drivers/gpu/drm/i915/display/intel_psr.c  | 95 ++-
>  drivers/gpu/drm/i915/display/intel_psr.h  |  7 ++
>  5 files changed, 123 insertions(+), 46 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 2213ad6c00da..3eadd8e12f63 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1203,6 +1203,7 @@ struct intel_crtc_state {
>   bool has_psr2;
>   bool enable_psr2_sel_fetch;
>   bool req_psr2_sdp_prior_scanline;
> + bool has_panel_replay;
>   bool wm_level_disabled;
>   u32 dc3co_exitline;
>   u16 su_y_granularity;
> @@ -1695,6 +1696,8 @@ struct intel_psr {
>   bool irq_aux_error;
>   u16 su_w_granularity;
>   u16 su_y_granularity;
> + bool source_panel_replay_support;
> + bool sink_panel_replay_support;
>   u32 dc3co_exitline;
>   u32 dc3co_exit_delay;
>   struct delayed_work dc3co_work;
> @@ -1982,17 +1985,6 @@ dp_to_lspcon(struct intel_dp *intel_dp)
> 
>  #define dp_to_i915(__intel_dp) to_i915(dp_to_dig_port(__intel_dp)-
> >base.base.dev)
> 
> -#define CAN_PSR(intel_dp) ((intel_dp)->psr.sink_support && \
> -(intel_dp)->psr.source_support)
> -
> -static inline bool intel_encoder_can_psr(struct intel_encoder *encoder) -{
> - if (!intel_encoder_is_dp(encoder))
> - return false;
> -
> - return CAN_PSR(enc_to_intel_dp(encoder));
> -}
> -
>  static inline struct intel_digital_port *  hdmi_to_dig_port(struct intel_hdmi
> *intel_hdmi)  { diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index f16d9fa88fe1..1c7d9b14fd1c 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2338,12 +2338,22 @@ static void
> intel_dp_compute_vsc_colorimetry(const struct intel_crtc_state *crtc
>   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>   struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> 
> - /*
> -  * Prepare VSC Header for SU as per DP 1.4 spec, Table 2-118
> -  * VSC SDP supporting 3D stereo, PSR2, and Pixel Encoding/
> -  * Colorimetry Format indication.
> -  */
> - vsc->revision = 0x5;
> + if (crtc_state->has_panel_replay) {
> + /*
> +  * Prepare VSC Header for SU as per DP 2.0 spec, Table 2-223
> +  * VSC SDP supporting 3D stereo, Panel Replay, and Pixel
> +  * Encoding/Colorimetry Format indication.
> +  */
> + vsc->revision = 0x7;
> + } else {
> + /*
> +  * Prepare VSC Header for SU as per DP 1.4 spec, Table 2-118
> +  * VSC SDP supporting 3D stereo, PSR2, and Pixel Encoding/
> +  * Colorimetry Format indication.
> +  */
> + vsc->revision = 0

RE: [PATCH v6 6/6] drm/i915/panelreplay: Debugfs support for panel replay

2023-10-04 Thread Murthy, Arun R


> -Original Message-
> From: Manna, Animesh 
> Sent: Thursday, September 21, 2023 11:44 AM
> To: intel-...@lists.freedesktop.org
> Cc: dri-devel@lists.freedesktop.org; Nikula, Jani ;
> Hogander, Jouni ; Murthy, Arun R
> ; Manna, Animesh 
> Subject: [PATCH v6 6/6] drm/i915/panelreplay: Debugfs support for panel
> replay
> 
> Add debugfs support which will print source and sink status per connector
> basis.
> 
> Cc: Jouni Högander 
> Signed-off-by: Animesh Manna 

Reviewed-by: Arun R Murthy 

Thanks and Regards,
Arun R Murthy
---
> ---
>  drivers/gpu/drm/i915/display/intel_psr.c | 132 +--
>  1 file changed, 97 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index 67337b4a421b..65f22e4ff3b2 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -2834,6 +2834,25 @@ static int psr_get_status_and_error_status(struct
> intel_dp *intel_dp,
>   return 0;
>  }
> 
> +static int panel_replay_get_status_and_error_status(struct intel_dp 
> *intel_dp,
> + u8 *status, u8
> *error_status) {
> + struct drm_dp_aux *aux = &intel_dp->aux;
> + int ret;
> +
> + ret = drm_dp_dpcd_readb(aux,
> DP_SINK_DEVICE_PR_AND_FRAME_LOCK_STATUS, status);
> + if (ret != 1)
> + return ret;
> +
> + ret = drm_dp_dpcd_readb(aux, DP_PANEL_REPLAY_ERROR_STATUS,
> error_status);
> + if (ret != 1)
> + return ret;
> +
> + *status = *status & DP_PSR_SINK_STATE_MASK;
> +
> + return 0;
> +}
> +
>  static void psr_alpm_check(struct intel_dp *intel_dp)  {
>   struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -
> 3046,7 +3065,7 @@ psr_source_status(struct intel_dp *intel_dp, struct seq_file
> *m)
>   status = live_status[status_val];
>   }
> 
> - seq_printf(m, "Source PSR status: %s [0x%08x]\n", status, val);
> + seq_printf(m, "Source PSR/PanelReplay status: %s [0x%08x]\n", status,
> +val);
>  }
> 
>  static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp) 
> @@ -
> 3059,18 +3078,23 @@ static int intel_psr_status(struct seq_file *m, struct
> intel_dp *intel_dp)
>   bool enabled;
>   u32 val;
> 
> - seq_printf(m, "Sink support: %s", str_yes_no(psr->sink_support));
> - if (psr->sink_support)
> + seq_printf(m, "Sink support: PSR = %s, Panel Replay = %s",
> +str_yes_no(psr->sink_support),
> +str_yes_no(psr->sink_panel_replay_support));
> +
> + if (psr->sink_support || psr->sink_panel_replay_support)
>   seq_printf(m, " [0x%02x]", intel_dp->psr_dpcd[0]);
>   seq_puts(m, "\n");
> 
> - if (!psr->sink_support)
> + if (!(psr->sink_support || psr->sink_panel_replay_support))
>   return 0;
> 
>   wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
>   mutex_lock(&psr->lock);
> 
> - if (psr->enabled)
> + if (psr->panel_replay_enabled)
> + status = "Panel Replay Enabled";
> + else if (psr->enabled)
>   status = psr->psr2_enabled ? "PSR2 enabled" : "PSR1 enabled";
>   else
>   status = "disabled";
> @@ -3083,14 +3107,17 @@ static int intel_psr_status(struct seq_file *m,
> struct intel_dp *intel_dp)
>   goto unlock;
>   }
> 
> - if (psr->psr2_enabled) {
> + if (psr->panel_replay_enabled) {
> + val = intel_de_read(dev_priv,
> TRANS_DP2_CTL(cpu_transcoder));
> + enabled = val & TRANS_DP2_PANEL_REPLAY_ENABLE;
> + } else if (psr->psr2_enabled) {
>   val = intel_de_read(dev_priv, EDP_PSR2_CTL(cpu_transcoder));
>   enabled = val & EDP_PSR2_ENABLE;
>   } else {
>   val = intel_de_read(dev_priv, psr_ctl_reg(dev_priv,
> cpu_transcoder));
>   enabled = val & EDP_PSR_ENABLE;
>   }
> - seq_printf(m, "Source PSR ctl: %s [0x%08x]\n",
> + seq_printf(m, "Source PSR/PanelReplay ctl: %s [0x%08x]\n",
>  str_enabled_disabled(enabled), val);
>   psr_source_status(intel_dp, m);
>   seq_printf(m, "Busy frontbuffer bits: 0x%08x\n", @@ -3232,6 +3259,7
> @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)  {
>   struct intel_connector *connector = m->private;
>   struct intel_dp *intel_dp = intel_attached_dp(connector);
> + struct intel_psr *psr = &intel_dp->psr;
>   static const char * const sink_status[] = {
>   "inactive",
>   "transition to active, capture and display", @@ -3242,45
> +3270,82 @@ static int i915_psr_sink_status_show(struct seq_file *m, void
> *data)
>   "reserved",
>   "sink internal error",
>   };
> + static const char * const panel_replay_status[] = {
> + "Sink device frame is locked to the Source device",
> + "Sink d

RE: [PATCH v6 5/6] drm/i915/panelreplay: enable/disable panel replay

2023-10-04 Thread Murthy, Arun R


> -Original Message-
> From: Manna, Animesh 
> Sent: Thursday, September 21, 2023 11:44 AM
> To: intel-...@lists.freedesktop.org
> Cc: dri-devel@lists.freedesktop.org; Nikula, Jani ;
> Hogander, Jouni ; Murthy, Arun R
> ; Manna, Animesh 
> Subject: [PATCH v6 5/6] drm/i915/panelreplay: enable/disable panel replay
> 
> TRANS_DP2_CTL register is programmed to enable panel replay from source
> and sink is enabled through panel replay dpcd configuration address.
> 
> Bspec: 1407940617
> 
> v1: Initial version.
> v2:
> - Use pr_* flags instead psr_* flags. [Jouni]
> - Remove intel_dp_is_edp check as edp1.5 also has panel replay. [Jouni]
> 
> v3: Cover letter updated and selective fetch condition check is added before
> updating its bit in PSR2_MAN_TRK_CTL register. [Jouni]
> 
> v4: Selective fetch related PSR2_MAN_TRK_CTL programmming dropped.
> [Jouni]
> 
> v5: Added PSR2_MAN_TRK_CTL programming as needed for Continuous Full
> Frame (CFF) update.
> 
> Note: Initial plan is to enable panel replay in  full-screen live active frame
> update mode. In a incremental approach panel replay will be enabled in 
> selctive
> update mode if there is any gap in curent implementation.
> 
> Cc: Jouni Högander 
> Signed-off-by: Animesh Manna 
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c  |  7 +-
>  .../drm/i915/display/intel_display_types.h|  1 +
>  drivers/gpu/drm/i915/display/intel_psr.c  | 65 ++-
>  3 files changed, 56 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 4668de45d6fe..203c56c5e208 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -2717,10 +2717,15 @@ static void intel_ddi_pre_enable_dp(struct
> intel_atomic_state *state,
>   const struct drm_connector_state
> *conn_state)  {
>   struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> + struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> 
> - if (HAS_DP20(dev_priv))
> + if (HAS_DP20(dev_priv)) {
>   intel_dp_128b132b_sdp_crc16(enc_to_intel_dp(encoder),
>   crtc_state);
> + if (crtc_state->has_panel_replay)
> + drm_dp_dpcd_writeb(&intel_dp->aux,
> PANEL_REPLAY_CONFIG,
> +DP_PANEL_REPLAY_ENABLE);
> + }
> 
>   if (DISPLAY_VER(dev_priv) >= 14)
>   mtl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 3eadd8e12f63..1cf302e9deed 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1698,6 +1698,7 @@ struct intel_psr {
>   u16 su_y_granularity;
>   bool source_panel_replay_support;
>   bool sink_panel_replay_support;
> + bool panel_replay_enabled;
>   u32 dc3co_exitline;
>   u32 dc3co_exit_delay;
>   struct delayed_work dc3co_work;
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index a59f13c29c3d..67337b4a421b 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -607,8 +607,11 @@ static void intel_psr_enable_sink(struct intel_dp
> *intel_dp)
>   struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>   u8 dpcd_val = DP_PSR_ENABLE;
> 
> - /* Enable ALPM at sink for psr2 */
> + if (intel_dp->psr.panel_replay_enabled)
> + return;
> +
>   if (intel_dp->psr.psr2_enabled) {
> + /* Enable ALPM at sink for psr2 */
>   drm_dp_dpcd_writeb(&intel_dp->aux,
> DP_RECEIVER_ALPM_CONFIG,
>  DP_ALPM_ENABLE |
>  DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE);
> @@ -758,6 +761,17 @@ static int psr2_block_count(struct intel_dp *intel_dp)
>   return psr2_block_count_lines(intel_dp) / 4;  }
> 
> +static void dg2_activate_panel_replay(struct intel_dp *intel_dp) {
Is this specific to DG2?
If not can dg2 be replaces with intel ?

> + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> +
> + intel_de_rmw(dev_priv, PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder),
> +  0,
> ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME);
> +
> + intel_de_rmw(dev_priv, TRANS_DP2_CTL(intel_dp->psr.transcoder), 0,
> +  TRANS_DP2_PANEL_REPLAY_ENABLE);
> +}
> +
>  static void hsw_activate_psr2(struct intel_dp *intel_dp)  {
>   struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -
> 1322,18 +1336,23 @@ void intel_psr_get_config(struct intel_encoder
> *encoder,
>   return;
> 
>   intel_dp = &dig_port->dp;
> - if (!CAN_PSR(intel_dp))
> + if (!(CAN_PSR(intel_dp) || CAN_PANEL_REPLAY(

[RFC PATCH] drm/i915/gt: Do not treat MCR locking timeouts as errors

2023-10-04 Thread Andi Shyti
The MCR steering semaphore is a shared lock entry between i915
and various firmware components.

Getting the lock might sinchronize on some shared resources.
Sometimes though, it might happen that the firmware forgets to
unlock causing unnecessary noise in the driver which keeps doing
what was supposed to do, ignoring the problem.

Do not consider this failure as an error, but just print a debug
message stating that the MCR locking has been skipped.

On the driver side we still have spinlocks that make sure that
the access to the resources is serialized.

Signed-off-by: Andi Shyti 
Cc: Jonathan Cavitt 
Cc: Matt Roper 
Cc: Nirmoy Das 
---
 drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
index 326c2ed1d99b..51eb693df39b 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
@@ -395,10 +395,8 @@ void intel_gt_mcr_lock(struct intel_gt *gt, unsigned long 
*flags)
 * would indicate some hardware/firmware is misbehaving and not
 * releasing it properly.
 */
-   if (err == -ETIMEDOUT) {
-   gt_err_ratelimited(gt, "hardware MCR steering semaphore timed 
out");
-   add_taint_for_CI(gt->i915, TAINT_WARN);  /* CI is now 
unreliable */
-   }
+   if (err == -ETIMEDOUT)
+   gt_dbg(gt, "hardware MCR steering semaphore timed out");
 }
 
 /**
-- 
2.40.1



Re: [PATCH 1/5] drm/amd/display: Remove migrate_en/dis from dc_fpu_begin().

2023-10-04 Thread Sebastian Andrzej Siewior
On 2023-10-03 15:53:41 [-0400], Harry Wentland wrote:
> On 2023-09-21 10:15, Sebastian Andrzej Siewior wrote:
> > This is a revert of the commit mentioned below while it is not wrong, as
> > in the kernel will explode, having migrate_disable() here it is
> > complete waste of resources.
> > 
> > Additionally commit message is plain wrong the review tag does not make
> 
> Not sure I follow what's unhelpful about the review tag with
> 0c316556d1249 ("drm/amd/display: Disable migration to ensure consistency of 
> per-CPU variable")

I explained it below with two points what the reviewer should have
noticed why reading the commit message even if he does not know what
migrate_disable() itself does.

> I do wish the original patch showed the splat it's attempting
> to fix. It apparently made a difference for something, whether
> inadvertently or not. I wish I knew what that "something" was.

As far as I can tell the patch does make a difference.

> Harry

Sebastian


RE: [PATCH v6 2/6] drm/i915/psr: Move psr specific dpcd init into own function

2023-10-04 Thread Murthy, Arun R


> -Original Message-
> From: Manna, Animesh 
> Sent: Thursday, September 21, 2023 11:44 AM
> To: intel-...@lists.freedesktop.org
> Cc: dri-devel@lists.freedesktop.org; Nikula, Jani ;
> Hogander, Jouni ; Murthy, Arun R
> 
> Subject: [PATCH v6 2/6] drm/i915/psr: Move psr specific dpcd init into own
> function
> 
> From: Jouni Högander 
> 
> This patch is preparing adding panel replay specific dpcd init.
> 
> Signed-off-by: Jouni Högander 
> ---
Reviewed-by: Arun R Murthy 

Thanks and Regards,
Arun R Murthy


>  drivers/gpu/drm/i915/display/intel_psr.c | 41 +---
>  1 file changed, 23 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index 850b11f20285..71fe2e4aca85 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -474,27 +474,22 @@ static void intel_dp_get_su_granularity(struct
> intel_dp *intel_dp)
>   intel_dp->psr.su_y_granularity = y;
>  }
> 
> -void intel_psr_init_dpcd(struct intel_dp *intel_dp)
> +static void _psr_init_dpcd(struct intel_dp *intel_dp)
>  {
> - struct drm_i915_private *dev_priv =
> + struct drm_i915_private *i915 =
>   to_i915(dp_to_dig_port(intel_dp)->base.base.dev);
> 
> - drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp-
> >psr_dpcd,
> -  sizeof(intel_dp->psr_dpcd));
> -
> - if (!intel_dp->psr_dpcd[0])
> - return;
> - drm_dbg_kms(&dev_priv->drm, "eDP panel supports PSR version
> %x\n",
> + drm_dbg_kms(&i915->drm, "eDP panel supports PSR version %x\n",
>   intel_dp->psr_dpcd[0]);
> 
>   if (drm_dp_has_quirk(&intel_dp->desc, DP_DPCD_QUIRK_NO_PSR)) {
> - drm_dbg_kms(&dev_priv->drm,
> + drm_dbg_kms(&i915->drm,
>   "PSR support not currently available for this
> panel\n");
>   return;
>   }
> 
>   if (!(intel_dp->edp_dpcd[1] & DP_EDP_SET_POWER_CAP)) {
> - drm_dbg_kms(&dev_priv->drm,
> + drm_dbg_kms(&i915->drm,
>   "Panel lacks power state control, PSR cannot be
> enabled\n");
>   return;
>   }
> @@ -503,8 +498,8 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
>   intel_dp->psr.sink_sync_latency =
>   intel_dp_get_sink_sync_latency(intel_dp);
> 
> - if (DISPLAY_VER(dev_priv) >= 9 &&
> - (intel_dp->psr_dpcd[0] ==
> DP_PSR2_WITH_Y_COORD_IS_SUPPORTED)) {
> + if (DISPLAY_VER(i915) >= 9 &&
> + intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_IS_SUPPORTED)
> {
>   bool y_req = intel_dp->psr_dpcd[1] &
>DP_PSR2_SU_Y_COORDINATE_REQUIRED;
>   bool alpm = intel_dp_get_alpm_status(intel_dp);
> @@ -521,14 +516,24 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
>* GTC first.
>*/
>   intel_dp->psr.sink_psr2_support = y_req && alpm;
> - drm_dbg_kms(&dev_priv->drm, "PSR2 %ssupported\n",
> + drm_dbg_kms(&i915->drm, "PSR2 %ssupported\n",
>   intel_dp->psr.sink_psr2_support ? "" : "not ");
> + }
> +}
> 
> - if (intel_dp->psr.sink_psr2_support) {
> - intel_dp->psr.colorimetry_support =
> - intel_dp_get_colorimetry_status(intel_dp);
> - intel_dp_get_su_granularity(intel_dp);
> - }
> +void intel_psr_init_dpcd(struct intel_dp *intel_dp) {
> + drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp-
> >psr_dpcd,
> +  sizeof(intel_dp->psr_dpcd));
> +
> + if (intel_dp->psr_dpcd[0])
> + _psr_init_dpcd(intel_dp);
> + /* TODO: Add PR case here */
> +
> + if (intel_dp->psr.sink_psr2_support) {
> + intel_dp->psr.colorimetry_support =
> + intel_dp_get_colorimetry_status(intel_dp);
> + intel_dp_get_su_granularity(intel_dp);
>   }
>  }
> 
> --
> 2.29.0



Re: [PATCH 0/5] drm/amd/display: Remove migrate-disable and move memory allocation.

2023-10-04 Thread Sebastian Andrzej Siewior
On 2023-10-03 15:54:58 [-0400], Harry Wentland wrote:
> On 2023-10-02 06:58, Sebastian Andrzej Siewior wrote:
> > On 2023-09-22 07:33:26 [+0200], Christian König wrote:
> >> Am 21.09.23 um 16:15 schrieb Sebastian Andrzej Siewior:
> >>> Hi,
> >>>
> >>> I stumbled uppon the amdgpu driver via a bugzilla report. The actual fix
> >>> is #4 + #5 and the rest was made while looking at the code.
> >>
> >> Oh, yes please :)
> >>
> >> Rodrigo and I have been trying to sort those things out previously, but
> >> that's Sisyphean work.
> >>
> >> In general the DC team needs to judge, but of hand it looks good to me.
> > 
> > Any way to get this merged? There was no reply from the DC team… No
> > reply from the person breaking it either. The bugzilla reporter stated
> > that it solves his trouble. He didn't report anything new ;)
> > 
> 
> Apologies for the slow progress. We're feeding it through our CI and
> will let you know the verdict soon.
> 
> Do you happen to have the bugzilla link that this is fixing? It would
> be helpful to include that as a link in the patches as well, to give
> them context.
The bugzilla report is at
  https://bugzilla.kernel.org/show_bug.cgi?id=217928

but the patches explain the situation, too. Even more verbose than the
report…

> Harry

Sebastian


RE: [PATCH v6 1/6] drm/panelreplay: dpcd register definition for panelreplay

2023-10-04 Thread Murthy, Arun R


> -Original Message-
> From: Manna, Animesh 
> Sent: Thursday, September 21, 2023 11:44 AM
> To: intel-...@lists.freedesktop.org
> Cc: dri-devel@lists.freedesktop.org; Nikula, Jani ;
> Hogander, Jouni ; Murthy, Arun R
> ; Manna, Animesh 
> Subject: [PATCH v6 1/6] drm/panelreplay: dpcd register definition for
> panelreplay
> 
> Add DPCD register definition for discovering, enabling and checking status of
> panel replay of the sink.
> 
> Cc: Jouni Högander 
> Signed-off-by: Animesh Manna 

Reviewed-by: Arun R Murthy 

Thanks and Regards,
Arun R Murthy
---
> ---
>  include/drm/display/drm_dp.h | 23 +++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
> index e69cece404b3..fc42b622ef32 100644
> --- a/include/drm/display/drm_dp.h
> +++ b/include/drm/display/drm_dp.h
> @@ -543,6 +543,10 @@
>  /* DFP Capability Extension */
>  #define DP_DFP_CAPABILITY_EXTENSION_SUPPORT  0x0a3   /* 2.0 */
> 
> +#define DP_PANEL_REPLAY_CAP 0x0b0  /* DP 2.0 */
> +# define DP_PANEL_REPLAY_SUPPORT(1 << 0)
> +# define DP_PANEL_REPLAY_SU_SUPPORT (1 << 1)
> +
>  /* Link Configuration */
>  #define  DP_LINK_BW_SET  0x100
>  # define DP_LINK_RATE_TABLE  0x00/* eDP 1.4 */
> @@ -716,6 +720,13 @@
>  #define DP_BRANCH_DEVICE_CTRL0x1a1
>  # define DP_BRANCH_DEVICE_IRQ_HPD(1 << 0)
> 
> +#define PANEL_REPLAY_CONFIG 0x1b0  /* DP 2.0 */
> +# define DP_PANEL_REPLAY_ENABLE (1 << 0)
> +# define DP_PANEL_REPLAY_UNRECOVERABLE_ERROR_EN (1 << 3)
> +# define DP_PANEL_REPLAY_RFB_STORAGE_ERROR_EN   (1 << 4)
> +# define DP_PANEL_REPLAY_ACTIVE_FRAME_CRC_ERROR_EN  (1 << 5)
> +# define DP_PANEL_REPLAY_SU_ENABLE  (1 << 6)
> +
>  #define DP_PAYLOAD_ALLOCATE_SET  0x1c0
>  #define DP_PAYLOAD_ALLOCATE_START_TIME_SLOT 0x1c1  #define
> DP_PAYLOAD_ALLOCATE_TIME_SLOT_COUNT 0x1c2 @@ -1105,6 +1116,18
> @@
>  #define DP_LANE_ALIGN_STATUS_UPDATED_ESI   0x200e /* status same as
> 0x204 */
>  #define DP_SINK_STATUS_ESI 0x200f /* status same as 
> 0x205 */
> 
> +#define DP_PANEL_REPLAY_ERROR_STATUS   0x2020  /* DP 2.1*/
> +# define DP_PANEL_REPLAY_LINK_CRC_ERROR(1 << 0)
> +# define DP_PANEL_REPLAY_RFB_STORAGE_ERROR (1 << 1)
> +# define DP_PANEL_REPLAY_VSC_SDP_UNCORRECTABLE_ERROR   (1 << 2)
> +
> +#define DP_SINK_DEVICE_PR_AND_FRAME_LOCK_STATUS0x2022  /* DP
> 2.1 */
> +# define DP_SINK_DEVICE_PANEL_REPLAY_STATUS_MASK   (7 << 0)
> +# define DP_SINK_FRAME_LOCKED_SHIFT3
> +# define DP_SINK_FRAME_LOCKED_MASK (3 << 3)
> +# define DP_SINK_FRAME_LOCKED_STATUS_VALID_SHIFT   5
> +# define DP_SINK_FRAME_LOCKED_STATUS_VALID_MASK(1 << 5)
> +
>  /* Extended Receiver Capability: See DP_DPCD_REV for definitions */
>  #define DP_DP13_DPCD_REV0x2200
> 
> --
> 2.29.0



Re: [PATCH v2] drm/mediatek: Correctly free sg_table in gem prime vmap

2023-10-04 Thread Chen-Yu Tsai
On Wed, Oct 4, 2023 at 4:32 PM Chen-Yu Tsai  wrote:
>
> The MediaTek DRM driver implements GEM PRIME vmap by fetching the
> sg_table for the object, iterating through the pages, and then
> vmapping them. In essence, unlike the GEM DMA helpers which vmap
> when the object is first created or imported, the MediaTek version
> does it on request.
>
> Unfortunately, the code never correctly frees the sg_table contents.
> This results in a kernel memory leak. On a Hayato device with a text
> console on the internal display, this results in the system running
> out of memory in a few days from all the console screen cursor updates.
>
> Add sg_free_table() to correctly free the contents of the sg_table. This
> was missing despite explicitly required by mtk_gem_prime_get_sg_table().
>
> Also move the "out" shortcut label to after the kfree() call for the
> sg_table. Having sg_free_table() together with kfree() makes more sense.
> The shortcut is only used when the object already has a kernel address,
> in which case the pointer is NULL and kfree() does nothing. Hence this
> change causes no functional change.
>
> Fixes: 3df64d7b0a4f ("drm/mediatek: Implement gem prime vmap/vunmap function")
> Cc: 
> Signed-off-by: Chen-Yu Tsai 
> ---

Changes since v1:
- Move "out" shortcut label to after sg_free_table() and kfree()

> Please merge for v6.6 fixes.
>
> Also, I was wondering why the MediaTek DRM driver implements a lot of
> the GEM functionality itself, instead of using the GEM DMA helpers.
> From what I could tell, the code closely follows the DMA helpers, except
> that it vmaps the buffers only upon request.
>
>  drivers/gpu/drm/mediatek/mtk_drm_gem.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c 
> b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
> index 9f364df52478..0e0a41b2f57f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
> @@ -239,6 +239,7 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, 
> struct iosys_map *map)
> npages = obj->size >> PAGE_SHIFT;
> mtk_gem->pages = kcalloc(npages, sizeof(*mtk_gem->pages), GFP_KERNEL);
> if (!mtk_gem->pages) {
> +   sg_free_table(sgt);
> kfree(sgt);
> return -ENOMEM;
> }
> @@ -248,12 +249,15 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, 
> struct iosys_map *map)
> mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP,
>pgprot_writecombine(PAGE_KERNEL));
> if (!mtk_gem->kvaddr) {
> +   sg_free_table(sgt);
> kfree(sgt);
> kfree(mtk_gem->pages);
> return -ENOMEM;
> }
> -out:
> +   sg_free_table(sgt);
> kfree(sgt);
> +
> +out:
> iosys_map_set_vaddr(map, mtk_gem->kvaddr);
>
> return 0;
> --
> 2.42.0.582.g8ccd20d70d-goog
>


[PATCH v2] drm/mediatek: Correctly free sg_table in gem prime vmap

2023-10-04 Thread Chen-Yu Tsai
The MediaTek DRM driver implements GEM PRIME vmap by fetching the
sg_table for the object, iterating through the pages, and then
vmapping them. In essence, unlike the GEM DMA helpers which vmap
when the object is first created or imported, the MediaTek version
does it on request.

Unfortunately, the code never correctly frees the sg_table contents.
This results in a kernel memory leak. On a Hayato device with a text
console on the internal display, this results in the system running
out of memory in a few days from all the console screen cursor updates.

Add sg_free_table() to correctly free the contents of the sg_table. This
was missing despite explicitly required by mtk_gem_prime_get_sg_table().

Also move the "out" shortcut label to after the kfree() call for the
sg_table. Having sg_free_table() together with kfree() makes more sense.
The shortcut is only used when the object already has a kernel address,
in which case the pointer is NULL and kfree() does nothing. Hence this
change causes no functional change.

Fixes: 3df64d7b0a4f ("drm/mediatek: Implement gem prime vmap/vunmap function")
Cc: 
Signed-off-by: Chen-Yu Tsai 
---
Please merge for v6.6 fixes.

Also, I was wondering why the MediaTek DRM driver implements a lot of
the GEM functionality itself, instead of using the GEM DMA helpers.
>From what I could tell, the code closely follows the DMA helpers, except
that it vmaps the buffers only upon request.

 drivers/gpu/drm/mediatek/mtk_drm_gem.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c 
b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
index 9f364df52478..0e0a41b2f57f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
@@ -239,6 +239,7 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, 
struct iosys_map *map)
npages = obj->size >> PAGE_SHIFT;
mtk_gem->pages = kcalloc(npages, sizeof(*mtk_gem->pages), GFP_KERNEL);
if (!mtk_gem->pages) {
+   sg_free_table(sgt);
kfree(sgt);
return -ENOMEM;
}
@@ -248,12 +249,15 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, 
struct iosys_map *map)
mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP,
   pgprot_writecombine(PAGE_KERNEL));
if (!mtk_gem->kvaddr) {
+   sg_free_table(sgt);
kfree(sgt);
kfree(mtk_gem->pages);
return -ENOMEM;
}
-out:
+   sg_free_table(sgt);
kfree(sgt);
+
+out:
iosys_map_set_vaddr(map, mtk_gem->kvaddr);
 
return 0;
-- 
2.42.0.582.g8ccd20d70d-goog



  1   2   >