Re: [PATCH 3/5] drm/ttm: replace busy placement with flags v6

2024-01-17 Thread Thomas Zimmermann



Am 12.01.24 um 13:51 schrieb Christian König:

From: Somalapuram Amaranath 

Instead of a list of separate busy placement add flags which indicate
that a placement should only be used when there is room or if we need to
evict.

v2: add missing TTM_PL_FLAG_IDLE for i915
v3: fix auto build test ERROR on drm-tip/drm-tip
v4: fix some typos pointed out by checkpatch
v5: cleanup some rebase problems with VMWGFX
v6: implement some missing VMWGFX functionality pointed out by Zack,
 rename the flags as suggested by Michel, rebase on drm-tip and
 adjust XE as well

Signed-off-by: Christian König 
Signed-off-by: Somalapuram Amaranath 


For the VRAM helpers:

Reviewed-by: Thomas Zimmermann 


---
  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c |  6 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c| 11 +---
  drivers/gpu/drm/drm_gem_vram_helper.c  |  2 -
  drivers/gpu/drm/i915/gem/i915_gem_ttm.c| 37 +--
  drivers/gpu/drm/loongson/lsdc_ttm.c|  2 -
  drivers/gpu/drm/nouveau/nouveau_bo.c   | 59 +++--
  drivers/gpu/drm/nouveau/nouveau_bo.h   |  1 -
  drivers/gpu/drm/qxl/qxl_object.c   |  2 -
  drivers/gpu/drm/qxl/qxl_ttm.c  |  2 -
  drivers/gpu/drm/radeon/radeon_object.c |  2 -
  drivers/gpu/drm/radeon/radeon_ttm.c|  8 +--
  drivers/gpu/drm/radeon/radeon_uvd.c|  1 -
  drivers/gpu/drm/ttm/ttm_bo.c   | 21 ---
  drivers/gpu/drm/ttm/ttm_resource.c | 73 +-
  drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 33 +++---
  drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c |  4 --
  drivers/gpu/drm/xe/xe_bo.c | 33 +-
  include/drm/ttm/ttm_placement.h| 10 +--
  include/drm/ttm/ttm_resource.h |  8 +--
  19 files changed, 118 insertions(+), 197 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 425cebcc5cbf..b671b0665492 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -220,9 +220,6 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, 
u32 domain)
  
  	placement->num_placement = c;

placement->placement = places;
-
-   placement->num_busy_placement = c;
-   placement->busy_placement = places;
  }
  
  /**

@@ -1397,8 +1394,7 @@ vm_fault_t amdgpu_bo_fault_reserve_notify(struct 
ttm_buffer_object *bo)
AMDGPU_GEM_DOMAIN_GTT);
  
  	/* Avoid costly evictions; only set GTT as a busy placement */

-   abo->placement.num_busy_placement = 1;
-   abo->placement.busy_placement = &abo->placements[1];
+   abo->placements[0].flags |= TTM_PL_FLAG_DESIRED;
  
  	r = ttm_bo_validate(bo, &abo->placement, &ctx);

if (unlikely(r == -EBUSY || r == -ERESTARTSYS))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 75c9fd2c6c2a..8722beba494e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -102,23 +102,19 @@ static void amdgpu_evict_flags(struct ttm_buffer_object 
*bo,
/* Don't handle scatter gather BOs */
if (bo->type == ttm_bo_type_sg) {
placement->num_placement = 0;
-   placement->num_busy_placement = 0;
return;
}
  
  	/* Object isn't an AMDGPU object so ignore */

if (!amdgpu_bo_is_amdgpu_bo(bo)) {
placement->placement = &placements;
-   placement->busy_placement = &placements;
placement->num_placement = 1;
-   placement->num_busy_placement = 1;
return;
}
  
  	abo = ttm_to_amdgpu_bo(bo);

if (abo->flags & AMDGPU_GEM_CREATE_DISCARDABLE) {
placement->num_placement = 0;
-   placement->num_busy_placement = 0;
return;
}
  
@@ -128,13 +124,13 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,

case AMDGPU_PL_OA:
case AMDGPU_PL_DOORBELL:
placement->num_placement = 0;
-   placement->num_busy_placement = 0;
return;
  
  	case TTM_PL_VRAM:

if (!adev->mman.buffer_funcs_enabled) {
/* Move to system memory */
amdgpu_bo_placement_from_domain(abo, 
AMDGPU_GEM_DOMAIN_CPU);
+
} else if (!amdgpu_gmc_vram_full_visible(&adev->gmc) &&
   !(abo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) 
&&
   amdgpu_bo_in_cpu_visible_vram(abo)) {
@@ -149,8 +145,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
AMDGPU_GEM_DOMAIN_CPU);
abo->placements[0].fpfn = adev->gmc.visible_vram_size 
>> PAGE_SHIFT;
abo->placements[0].lpfn = 0;
-   abo->placement.

Re: [PATCH v2 1/1] drm/ttm: allocate dummy_read_page without DMA32 on fail

2024-01-17 Thread Christian König

Am 16.01.24 um 19:50 schrieb Yangyu Chen:

Some platforms may not have any memory in ZONE_DMA32 and use IOMMU to allow
32-bit-DMA-only device to work. Forcing GFP_DMA32 on dummy_read_page will
fail on such platforms. Retry after fail will get this works on such
platforms.

Signed-off-by: Yangyu Chen 


Reviewed and pushed to drm-misc-fixes. That patch should show up in the 
next rc and stable kernels next week or so.


Thanks,
Christian.



---
  drivers/gpu/drm/ttm/ttm_device.c | 12 +---
  1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
index d48b39132b32..c9fa8561f71f 100644
--- a/drivers/gpu/drm/ttm/ttm_device.c
+++ b/drivers/gpu/drm/ttm/ttm_device.c
@@ -95,11 +95,17 @@ static int ttm_global_init(void)
ttm_pool_mgr_init(num_pages);
ttm_tt_mgr_init(num_pages, num_dma32);
  
-	glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32);

+   glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32 |
+  __GFP_NOWARN);
  
+	/* Retry without GFP_DMA32 for platforms DMA32 is not available */

if (unlikely(glob->dummy_read_page == NULL)) {
-   ret = -ENOMEM;
-   goto out;
+   glob->dummy_read_page = alloc_page(__GFP_ZERO);
+   if (unlikely(glob->dummy_read_page == NULL)) {
+   ret = -ENOMEM;
+   goto out;
+   }
+   pr_warn("Using GFP_DMA32 fallback for dummy_read_page\n");
}
  
  	INIT_LIST_HEAD(&glob->device_list);




Re: [PATCH 01/10] pci: add new set of devres functions

2024-01-17 Thread Philipp Stanner
On Tue, 2024-01-16 at 12:44 -0600, Bjorn Helgaas wrote:
> On Mon, Jan 15, 2024 at 03:46:12PM +0100, Philipp Stanner wrote:
> > PCI's devres API is not extensible to ranged mappings and has
> > bug-provoking features. Improve that by providing better
> > alternatives.
> 
> I guess "ranged mappings" means a mapping that doesn't cover an
> entire
> BAR?  Maybe there's a way to clarify?

That's what it's supposed to mean, yes.
We could give it the longer title "mappings smaller than the whole BAR"
or something, I guess.


> 
> > When the original devres API for PCI was implemented, priority was
> > given
> > to the creation of a set of "pural functions" such as
> > pcim_request_regions(). These functions have bit masks as
> > parameters to
> > specify which BARs shall get mapped. Most users, however, only use
> > those
> > to mapp 1-3 BARs.
> > A complete set of "singular functions" does not exist.
> 
> s/mapp/map/
> 
> Rewrap to fill 75 columns or add blank lines between paragraphs. 
> Also
> below.
> 
> > As functions mapping / requesting multiple BARs at once have
> > (almost) no
> > mechanism in C to return the resources to the caller of the plural
> > function, the devres API utilizes the iomap-table administrated by
> > the
> > function pcim_iomap_table().
> > 
> > The entire PCI devres implementation was strongly tied to that
> > table
> > which only allows for mapping whole, complete BARs, as the BAR's
> > index
> > is used as table index. Consequently, it's not possible to, e.g.,
> > have a
> > pcim_iomap_range() function with that mechanism.
> > 
> > An additional problem is that pci-devres has been ipmlemented in a
> > sort
> > of "hybrid-mode": Some unmanaged functions have managed
> > counterparts
> > (e.g.: pci_iomap() <-> pcim_iomap()), making their managed nature
> > obvious to the programmer. However, the region-request functions in
> > pci.c, prefixed with pci_, behave either managed or unmanaged,
> > depending
> > on whether pci_enable_device() or pcim_enable_device() has been
> > called
> > in advance.
> 
> s/ipmlemented/implemented/
> 
> > This hybrid API is confusing and should be more cleanly separated
> > by
> > providing always-managed functions prefixed with pcim_.
> > 
> > Thus, the existing devres API is not desirable because:
> > a) The vast majority of the users of the plural functions
> > only
> >    ever sets a single bit in the bit mask, consequently
> > making
> >    them singular functions anyways.
> > b) There is no mechanism to request / iomap only part of a
> > BAR.
> > c) The iomap-table mechanism is over-engineered,
> > complicated and
> >    can by definition not perform bounds checks, thus,
> > provoking
> >    memory faults: pcim_iomap_table(pdev)[42]
> 
> Not sure what "pcim_iomap_table(pdev)[42]" means.

That function currently is implemented with this prototype:
void __iomem * const *pcim_iomap_table(struct pci_dev *pdev);

And apparently, it's intended to index directly over the function. And
that's how at least part of the users use it indeed.

Here in drivers/crypto/inside-secure/safexcel.c, L.1919 for example:

priv->base = pcim_iomap_table(pdev)[0];

I've never seen something that wonderful in C ever before, so it's not
surprising that you weren't sure what I mean

pcim_iomap_table() can not and does not perform any bounds check. If
you do

void __iomem *mappy_map_mapface = pcim_iomap_table(pdev)[42];

then it will just return random garbage, or it faults. No -EINVAL or
anything. You won't even get NULL.

That's why this function must die.


> 
> > d) region-request functions being sometimes managed and
> >    sometimes not is bug-provoking.
> 
> Indent with spaces (not tabs) so it still looks good when "git log"
> adds spaces to indent.
> 
> > + * Legacy struct storing addresses to whole mapped bars.
> 
> s/bar/BAR/ (several places).
> 
> > +   /* A region spaning an entire bar. */
> > +   PCIM_ADDR_DEVRES_TYPE_REGION,
> > +
> > +   /* A region spaning an entire bar, and a mapping for that
> > whole bar. */
> > +   PCIM_ADDR_DEVRES_TYPE_REGION_MAPPING,
> > +
> > +   /*
> > +    * A mapping within a bar, either spaning the whole bar or
> > just a range.
> > +    * Without a requested region.
> 
> s/spaning/spanning/ (several places).
> 
> > +   if (start == 0 || len == 0) /* that's an unused BAR. */
> 
> s/that/That/
> 
> > +   /*
> > +    * Ranged mappings don't get added to the legacy-table,
> > since the table
> > +    * only ever keeps track of whole BARs.
> > +    */
> > +
> 
> Spurious blank line.


I'll take care of the grammar and spelling stuff in v2.

Thanks,
P.

> 
> > +   devres_add(&pdev->dev, res);
> > +   return mapping;
> > +}
> > +EXPORT_SYMBOL(pcim_iomap_range);
> 
> Bjorn
> 



Re: [PATCH 0/2] drm/atomic: Allow drivers to write their own plane check for async

2024-01-17 Thread Pekka Paalanen
On Tue, 16 Jan 2024 17:10:18 +0100
Xaver Hugl  wrote:

> My plan is to require support for IN_FENCE_FD at least. If the driver
> doesn't
> allow tearing with that, then tearing just doesn't happen.

That's an excellent point. I think this is important enough in its own
right, that it should be called out in the patch series.

Is it important enough to be special-cased, e.g. to be always allowed
with async commits?

Now that I think of it, if userspace needs to wait for the in-fence
itself before kicking KMS async, that would defeat much of the async's
point, right? And cases where in-fence is not necessary are so rare
they might not even exist?

So if driver/hardware cannot do IN_FENCE_FD with async, is there any
use of supporting async to begin with?

> For overlay planes though, it depends on how the compositor prioritizes
> things.
> If the compositor prioritizes overlay planes and would like to do tearing
> if possible,
> then this patch works.

Ok, I can see that.

> If the compositor prioritizes tearing and would like to do overlay planes
> if possible,
> it would have to know that switching to synchronous commits for a single
> frame,
> setting up the overlay planes and then switching back to async commits
> works, and
> that can't be figured out with TEST_ONLY commits.

I had to ponder a bit why. So I guess the synchronous commit in between
is because driver/hardware may not be able to enable/disable extra
planes in async, so you need a synchronous commit to set them up, but
afterwards updates can tear.

The comment about Intel needing one more synchronous commit when
switching from sync to async updates comes to mind as well, would that
be a problem?

> So I think having a CAP or immutable plane property to signal that async
> commits
> with overlay and/or cursor planes is supported would be useful.

Async cursor planes a good point, particularly moving them around. I'm
not too informed about the prior/on-going efforts to allow cursor
movement more often than refresh rate, I recall something about
amending atomic commits? How would these interact?

I suppose the kernel still prevents any new async commit while a
previous commit is not finished, so amending commits would still be
necessary for cursor plane motion? Or would it, if you time "big
commits" to finish quickly and then spam async "cursor commits" in the
mean time?


Thanks,
pq

> Am Di., 16. Jan. 2024 um 14:35 Uhr schrieb André Almeida <
> andrealm...@igalia.com>:  
> 
> > + Joshua
> >
> > Em 16/01/2024 10:14, Pekka Paalanen escreveu:  
> > > On Tue, 16 Jan 2024 08:50:59 -0300
> > > André Almeida  wrote:
> > >  
> > >> Hi Pekka,
> > >>
> > >> Em 16/01/2024 06:45, Pekka Paalanen escreveu:  
> > >>> On Tue, 16 Jan 2024 01:51:57 -0300
> > >>> André Almeida  wrote:
> > >>>  
> >  Hi,
> > 
> >  AMD hardware can do more on the async flip path than just the primary  
> > plane, so  
> >  to lift up the current restrictions, this patchset allows drivers to  
> > write their  
> >  own check for planes for async flips.  
> > >>>
> > >>> Hi,
> > >>>
> > >>> what's the userspace story for this, how could userspace know it could  
> > do more?  
> > >>> What kind of userspace would take advantage of this and in what  
> > situations?  
> > >>>
> > >>> Or is this not meant for generic userspace?  
> > >>
> > >> Sorry, I forgot to document this. So the idea is that userspace will
> > >> query what they can do here with DRM_MODE_ATOMIC_TEST_ONLY calls,
> > >> instead of having capabilities for each prop.  
> > >
> > > That's the theory, but do you have a practical example?
> > >
> > > What other planes and props would one want change in some specific use
> > > case?
> > >
> > > Is it just "all or nothing", or would there be room to choose and pick
> > > which props you change and which you don't based on what the driver
> > > supports? If the latter, then relying on TEST_ONLY might be yet another
> > > combinatorial explosion to iterate through.
> > >  
> >
> > That's a good question, maybe Simon, Xaver or Joshua can share how they
> > were planning to use this on Gamescope or Kwin.
> >  
> > >
> > > Thanks,
> > > pq
> > >  
> >  I'm not sure if adding something new to drm_plane_funcs is the right  
> > way to do,  
> >  because if we want to expand the other object types (crtc, connector)  
> > we would  
> >  need to add their own drm_XXX_funcs, so feedbacks are welcome!
> > 
> > André
> > 
> >  André Almeida (2):
> >  drm/atomic: Allow drivers to write their own plane check for async
> >    flips
> >  drm/amdgpu: Implement check_async_props for planes
> > 
> > .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 30 +
> > drivers/gpu/drm/drm_atomic_uapi.c | 62  
> > ++-  
> > include/drm/drm_atomic_uapi.h | 12 
> > include/drm/drm_plane.h   |  5 ++
> > 4 files cha

Re: [PATCH 06/10] pci: move pinned status bit to pci_dev struct

2024-01-17 Thread Philipp Stanner
On Tue, 2024-01-16 at 23:34 +0200, andy.shevche...@gmail.com wrote:
> Mon, Jan 15, 2024 at 03:46:17PM +0100, Philipp Stanner kirjoitti:
> > The bit describing whether the PCI device is currently pinned is
> > stored
> > in the PCI devres struct. To clean up and simplify the pci-devres
> > API,
> 
> "PCI devres", 'pci-devres', ...
> Shouldn't these (and across entire series) be consistent terms?
> E.g., "PCI devres API".

Yes, we should agree on a canonical term probably.
Probably "PCI devres" is good.

> 
> > it's better if this information is stored in the pci_dev struct,
> > because
> 
> pci_dev struct --> struct pci_dev
> 
> > it allows for checking that device's pinned-status directly through
> > the
> > device struct.
> > This will later permit simplifying  pcim_enable_device().
> 
> > Move the 'pinned' boolean bit to struct pci_dev.
> 
> ...
> 
> > u8  pm_cap; /* PM capability offset */
> > unsigned intenabled:1;  /* Whether this dev is
> > enabled */
> > +   unsigned intpinned:1;   /* Whether this dev is
> > pinned */
> > unsigned intimm_ready:1;/* Supports Immediate
> > Readiness */
> > unsigned intpme_support:5;  /* Bitmask of states from
> > which PME#
> >    can be generated */
> 
> First of all, I think it's better to group PM stuff, like

ACK

> 
> u8  pm_cap; /* PM capability offset */
> unsigned intpme_support:5;  /* Bitmask of states from
> which PME#
>    can be generated */
> unsigned intimm_ready:1;/* Supports Immediate
> Readiness */
> unsigned intenabled:1;  /* Whether this dev is
> enabled */
> unsigned intpinned:1;   /* Whether this dev is pinned
> */
> 
> Second, does this layout anyhow related to the HW layout? (For
> example,
> PME bits and their location in some HW register vs. these bitfields)
> If so, but not sure, it might be good to preserve (to some extent)
> the
> order.

As far as I know, one of the greatest weaknesses of C is that neither
Ritchie nor the standard ever said anything about the fields' order.
Hence, every field-order is purely implementation-defined and in no way
portable.
So I can't imagine a bitfield will ever directly mapp to a HW-layout?

The fields order is purely aesthetic / for the human reader.


P.

> 



Re: [PATCH 01/10] pci: add new set of devres functions

2024-01-17 Thread Philipp Stanner
On Tue, 2024-01-16 at 23:15 +0200, andy.shevche...@gmail.com wrote:
> Mon, Jan 15, 2024 at 03:46:12PM +0100, Philipp Stanner kirjoitti:
> > PCI's devres API is not extensible to ranged mappings and has
> > bug-provoking features. Improve that by providing better
> > alternatives.
> > 
> > When the original devres API for PCI was implemented, priority was
> > given
> > to the creation of a set of "pural functions" such as
> > pcim_request_regions(). These functions have bit masks as
> > parameters to
> > specify which BARs shall get mapped. Most users, however, only use
> > those
> > to mapp 1-3 BARs.
> > A complete set of "singular functions" does not exist.
> > 
> > As functions mapping / requesting multiple BARs at once have
> > (almost) no
> > mechanism in C to return the resources to the caller of the plural
> > function, the devres API utilizes the iomap-table administrated by
> > the
> > function pcim_iomap_table().
> > 
> > The entire PCI devres implementation was strongly tied to that
> > table
> > which only allows for mapping whole, complete BARs, as the BAR's
> > index
> > is used as table index. Consequently, it's not possible to, e.g.,
> > have a
> > pcim_iomap_range() function with that mechanism.
> > 
> > An additional problem is that pci-devres has been ipmlemented in a
> > sort
> > of "hybrid-mode": Some unmanaged functions have managed
> > counterparts
> > (e.g.: pci_iomap() <-> pcim_iomap()), making their managed nature
> > obvious to the programmer. However, the region-request functions in
> > pci.c, prefixed with pci_, behave either managed or unmanaged,
> > depending
> > on whether pci_enable_device() or pcim_enable_device() has been
> > called
> > in advance.
> > 
> > This hybrid API is confusing and should be more cleanly separated
> > by
> > providing always-managed functions prefixed with pcim_.
> > 
> > Thus, the existing devres API is not desirable because:
> > a) The vast majority of the users of the plural functions
> > only
> >    ever sets a single bit in the bit mask, consequently
> > making
> >    them singular functions anyways.
> > b) There is no mechanism to request / iomap only part of a
> > BAR.
> > c) The iomap-table mechanism is over-engineered,
> > complicated and
> >    can by definition not perform bounds checks, thus,
> > provoking
> >    memory faults: pcim_iomap_table(pdev)[42]
> > d) region-request functions being sometimes managed and
> >    sometimes not is bug-provoking.
> > 
> > Implement a set of singular pcim_ functions that use devres
> > directly
> > and bypass the legacy iomap table mechanism.
> > Add devres.c to driver-api documentation.
> 
> ...
> 
> > +struct pcim_addr_devres {
> > +   enum pcim_addr_devres_type type;
> > +   void __iomem *baseaddr;
> > +   unsigned long offset;
> > +   unsigned long len;
> > +   short bar;
> > +};
> > +
> > +static inline void pcim_addr_devres_clear(struct pcim_addr_devres
> > *res)
> > +{
> > +   res->type = PCIM_ADDR_DEVRES_TYPE_INVALID;
> > +   res->bar = -1;
> > +   res->baseaddr = NULL;
> > +   res->offset = 0;
> > +   res->len = 0;
> 
> More robust (in case the data type gets extended) is memset() +
> individual
> (non-0) sets.

ACK

> 
> > +}
> 
> ...
> 
> > +static int __pcim_request_region_range(struct pci_dev *pdev, int
> > bar,
> > +   unsigned long offset, unsigned long maxlen,
> > +   const char *name, int exclusive)
> > +{
> > +   resource_size_t start = pci_resource_start(pdev, bar);
> > +   resource_size_t len = pci_resource_len(pdev, bar);
> > +   unsigned long flags = pci_resource_flags(pdev, bar);
> > +
> > +   if (start == 0 || len == 0) /* that's an unused BAR. */
> > +   return 0;
> > +   if (len <= offset)
> > +   return  -EINVAL;
> > +
> > +   start += offset;
> > +   len -= offset;
> 
> > +   if (len > maxlen && maxlen != 0)
> > +   len = maxlen;
> 
> if (maxlen && ...)
> 
> ?

I very much dislike this style, although I'm aware it's used in many
(but not all) regions of the kernel.

It makes your style inconsistent, because sometimes you do indeed check
for something larger or smaller than 0.

Plus, by checking for a number, everyone immediately sees that this is
an integer, not a pointer, which improves readability at 0 cost.

> 
> > +   if (flags & IORESOURCE_IO) {
> > +   if (!request_region(start, len, name))
> > +   return -EBUSY;
> > +   } else if (flags & IORESOURCE_MEM) {
> > +   if (!__request_mem_region(start, len, name,
> > exclusive))
> > +   return -EBUSY;
> > +   } else {
> > +   /* That's not a device we can request anything on.
> > */
> > +   return -ENODEV;
> > +   }
> 
> Hmm... Not sure, but the switch-case against type might be
> considered:
> 
> switc

Re: [PATCH v2 2/4] drm/uAPI: Add "force color format" drm property as setting for userspace

2024-01-17 Thread Pekka Paalanen
On Tue, 16 Jan 2024 14:11:43 +
Andri Yngvason  wrote:

> þri., 16. jan. 2024 kl. 13:29 skrifaði Sebastian Wick
> :
> >
> > On Tue, Jan 16, 2024 at 01:13:13PM +, Andri Yngvason wrote:  
> [...]
> > > şri., 16. jan. 2024 kl. 11:42 skrifaği Sebastian Wick
> > > :  
> > > >
> > > > On Mon, Jan 15, 2024 at 04:05:52PM +, Andri Yngvason wrote:  
> > > > > From: Werner Sembach 
> > > > >
> > > > > Add a new general drm property "force color format" which can be used
> > > > > by userspace to tell the graphics driver which color format to use.  
> > > >
> > > > I don't like the "force" in the name. This just selects the color
> > > > format, let's just call it "color format" then.
> > > >  
> > >
> > > In previous revisions, this was "preferred color format" and "actual
> > > color format", of which the latter has been dropped. I recommend
> > > reading the discussion for previous revisions.  
> >
> > Please don't imply that I didn't read the thread I'm answering to.

FYI, I have not read this thread.

> >  
> > > There are arguments for adding "actual color format" later and if it
> > > is added later, we'd end up with "color format" and "actual color
> > > format", which might be confusing, and it is why I chose to call it
> > > "force color format" because it clearly communicates intent and
> > > disambiguates it from "actual color format".  
> >
> > There is no such thing as "actual color format" in upstream though.
> > Basing your naming on discarded ideas is not useful. The thing that sets
> > the color space for example is called "Colorspace", not "force
> > colorspace".
> >  
> 
> Sure, I'm happy with calling it whatever people want. Maybe we can
> have a vote on it?

It would sound strange to say "force color format" = "auto". Just drop
the "force" of it.

If and when we need the feedback counterpart, it could be an immutable
prop called "active color format" where "auto" is not a valid value, or
something in the new "output properties" design Sima has been thinking
of.

> > > [...]  
> > > > > @@ -1396,6 +1404,15 @@ static const u32 dp_colorspaces =
> > > > >   *   drm_connector_attach_max_bpc_property() to create and attach the
> > > > >   *   property to the connector during initialization.
> > > > >   *
> > > > > + * force color format:
> > > > > + *   This property is used by userspace to change the used color 
> > > > > format. When
> > > > > + *   used the driver will use the selected format if valid for the 
> > > > > hardware,  
> > > >
> > > > All properties are always "used", they just can have different values.
> > > > You probably want to talk about the auto mode here.  
> > >
> > > Maybe we can say something like: If userspace does not set the
> > > property or if it is explicitly set to zero, the driver will select
> > > the appropriate color format based on other constraints.  
> >
> > The property can be in any state without involvement from user space.
> > Don't talk about setting it, talk about the state it is in:
> >
> >   When the color format is auto, the driver will select a format.
> >  
> 
> Ok.
> 
> > > >  
> > > > > + *   sink, and current resolution and refresh rate combination. 
> > > > > Drivers to  
> > > >
> > > > If valid? So when a value is not actually supported user space can still
> > > > set it? What happens then? How should user space figure out if the
> > > > driver and the sink support the format?  
> > >
> > > The kernel does not expose this property unless it's implemented in the 
> > > driver.  
> >
> > If the driver simply doesn't support *one format*, the enum value for
> > that format should not be exposed, period. This isn't about the property
> > on its own.  
> 
> Right, understood. You mean that enum should only contain values that
> are supported by the driver.

Yes. When a driver installs a property, it can choose which of the enum
entries are exposed. That cannot be changed later though, so the list
cannot live by the currently connected sink, only by what the driver
and display controlled could ever do.

> > > This was originally "preferred color format". Perhaps the
> > > documentation should better reflect that it is now a mandatory
> > > constraint which fails the modeset if not satisfied.  
> >
> > That would definitely help.
> >  
> > > >
> > > > For the Colorspace prop, the kernel just exposes all formats it supports
> > > > (independent of the sink) and then makes it the job of user space to
> > > > figure out if the sink supports it.
> > > >
> > > > The same could be done here. Property value is exposed if the driver
> > > > supports it in general, commits can fail if the driver can't support it
> > > > for a specific commit because e.g. the resolution or refresh rate. User
> > > > space must look at the EDID/DisplayID/mode to figure out the supported
> > > > format for the sink.  
> > >
> > > Yes, we can make it possible for userspace to discover which modes are
> > > supported by the monitor, but there are other constraints that n

Re: [PATCH RFC 0/4] Support for Simulated Panels

2024-01-17 Thread Maxime Ripard
Hi,

On Tue, Jan 16, 2024 at 02:22:03PM -0800, Jessica Zhang wrote:
> This series introduces a simulated MIPI DSI panel.
> 
> Currently, the only way to validate DSI connectors is with a physical
> panel. Since obtaining physical panels for all possible DSI configurations
> is logistically infeasible, introduce a way for DSI drivers to simulate a
> panel.
> 
> This will be helpful in catching DSI misconfiguration bugs and catching
> performance issues for high FPS panels that might not be easily
> obtainable.
> 
> For now, the simulated panel driver only supports setting customized
> modes via the panel_simlation.mode modparam. Eventually, we would like
> to add more customizations (such as configuring DSC, dual DSI, etc.).

I think that it's more complicated than it needs to be.

Why do we need to support (and switch to) both the actual and
"simulated" panel?

Wouldn't it be simpler if we had a vkms-like panel that we could either
configure from DT or from debugfs that would just be registered the
usual way and would be the only panel we register?

Maxime


signature.asc
Description: PGP signature


Re: (subset) [PATCH] drm/tests: mm: Call drm_mm_print in drm_test_mm_debug

2024-01-17 Thread Maxime Ripard
On Tue, 16 Jan 2024 18:46:02 +0100, Michał Winiarski wrote:
> The original intent behind the test was to sanity check whether calling
> the debug iterator (drm_mm_print) doesn't cause any problems.
> Unfortunately - this call got accidentally removed during KUnit
> transition. Restore it.
> 
> 

Applied to drm/drm-misc (drm-misc-fixes).

Thanks!
Maxime



Re: [PATCH v4 1/1] drm/tests: Add KUnit tests for drm_mode_create_dvi_i_properties()

2024-01-17 Thread Maxime Ripard
Hi,

On Sun, Jan 14, 2024 at 04:23:38PM +0530, Dipam Turkar wrote:
> Introduce unit tests for the drm_mode_create_dvi_i_properties() function to 
> ensure
> the proper creation of DVI-I specific connector properties and success if 
> called 
> multiple times.
> 
> Signed-off-by: Dipam Turkar 
> ---
>  drivers/gpu/drm/tests/drm_connector_test.c | 58 ++
>  1 file changed, 58 insertions(+)
> 
> diff --git a/drivers/gpu/drm/tests/drm_connector_test.c 
> b/drivers/gpu/drm/tests/drm_connector_test.c
> index c66aa2dc8d9d..217c0988171e 100644
> --- a/drivers/gpu/drm/tests/drm_connector_test.c
> +++ b/drivers/gpu/drm/tests/drm_connector_test.c
> @@ -4,6 +4,9 @@
>   */
>  
>  #include 
> +#include 
> +#include 
> +#include 
>  
>  #include 
>  
> @@ -70,7 +73,62 @@ static struct kunit_suite 
> drm_get_tv_mode_from_name_test_suite = {
>   .test_cases = drm_get_tv_mode_from_name_tests,
>  };
>  
> +/*
> + * Test that drm_mode_create_dvi_i_properties() succeeds and
> + * DVI-I subconnector and select subconectors properties have
> + * been created.
> + */
> +static void drm_test_mode_create_dvi_i_properties(struct kunit *test)
> +{
> + struct drm_device *drm;
> + struct device *dev;
> +
> + dev = drm_kunit_helper_alloc_device(test);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
> +
> + drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0, 
> DRIVER_MODESET);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
> +
> + KUNIT_EXPECT_EQ(test, drm_mode_create_dvi_i_properties(drm), 0);
> + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 
> drm->mode_config.dvi_i_select_subconnector_property);
> + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 
> drm->mode_config.dvi_i_subconnector_property);
> +}
> +
> +/*
> + * Test that drm_mode_create_dvi_i_properties() doesn't fail if called twice.
> + */
> +static void drm_test_mode_create_dvi_i_properties_repeated(struct kunit 
> *test)
> +{
> + struct drm_device *drm;
> + struct device *dev;
> +
> + dev = drm_kunit_helper_alloc_device(test);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
> +
> + drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0, 
> DRIVER_MODESET);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
> +
> + KUNIT_EXPECT_EQ(test, drm_mode_create_dvi_i_properties(drm), 0);
> + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 
> drm->mode_config.dvi_i_select_subconnector_property);
> + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 
> drm->mode_config.dvi_i_subconnector_property);
> +
> + /* Expect the function to return 0 if called twice. */
> + KUNIT_EXPECT_EQ(test, drm_mode_create_dvi_i_properties(drm), 0);
> +}
> +
> +static struct kunit_case drm_mode_create_dvi_i_properties_tests[] = {
> + KUNIT_CASE(drm_test_mode_create_dvi_i_properties),
> + KUNIT_CASE(drm_test_mode_create_dvi_i_properties_repeated),
> + { }
> +};
> +
> +static struct kunit_suite drm_mode_create_dvi_i_properties_test_suite = {
> + .name = "drm_mode_create_dvi_i_properties",
> + .test_cases = drm_mode_create_dvi_i_properties_tests,
> +};
> +
>  kunit_test_suite(drm_get_tv_mode_from_name_test_suite);
> +kunit_test_suite(drm_mode_create_dvi_i_properties_test_suite);

You should use kunit_test_suites here

Maxime


signature.asc
Description: PGP signature


Re: [PATCH 02/10] pci: deprecate iomap-table functions

2024-01-17 Thread Philipp Stanner
On Tue, 2024-01-16 at 23:27 +0200, andy.shevche...@gmail.com wrote:
> Mon, Jan 15, 2024 at 03:46:13PM +0100, Philipp Stanner kirjoitti:
> > The old plural devres functions tie PCI's devres implementation to
> > the
> > iomap-table mechanism which unfortunately is not extensible.
> > 
> > As the purlal functions are almost never used with more than one
> > bit set
> > in their bit-mask, deprecating them and encouraging users to use
> > the new
> > singular functions instead is reasonable.
> > 
> > Furthermore, to make the implementation more consistent and
> > extensible,
> > the plural functions should use the singular functions.
> > 
> > Add new wrapper to request / release all BARs.
> > Make the plural functions call into the singular functions.
> > Mark the plural functions as deprecated.
> > Remove as much of the iomap-table-mechanism as possible.
> > Add comments describing the path towards a cleaned-up API.
> 
> ...
> 
> >  static void pcim_iomap_release(struct device *gendev, void *res)
> >  {
> > -   struct pci_dev *dev = to_pci_dev(gendev);
> > -   struct pcim_iomap_devres *this = res;
> > -   int i;
> > -
> > -   for (i = 0; i < PCIM_IOMAP_MAX; i++)
> > -   if (this->table[i])
> > -   pci_iounmap(dev, this->table[i]);
> > +   /*
> > +    * Do nothing. This is legacy code.
> > +    *
> > +    * Cleanup of the mappings is now done directly through the
> > callbacks
> > +    * registered when creating them.
> > +    */
> >  }
> 
> How many users we have? Can't we simply kill it for good?
> 
> ...

There are 126 users in the kernel.

When I began with all of this I indeed checked whether we might burn it
completely.
Indeed the majority of driver users are wise enough to do something
like

driver->map0 = pcim_iomap_table(pdev)[0];
driver->map1 = pcim_iomap_table(pdev)[1];

So we could just easily replace it with

+ drivers->map0 = pcim_iomap_region(pdev, 0, "driver");
+ if (IS_ERR(drivers->map0))


Buut.. certain people, such as the crypto folks, do indeed not
store the mapping-address in their own driver-struct but call
pcim_iomap_table() to get the address whenever they need it.


That's where I gave up. It's too much work for and would take forever,
even if the code were sane, until you get it all merged.
We want that new API for DRM, that's why I'm working on it in the first
place.

That's why this API should have never been merged back in 2006/7. But
no one dared to touch it for 16 years, so here we are.

> 
> > + * This function is DEPRECATED. Do not use it in new code.
> 
> We have __deprecated IIRC, can it be used?

It seems the Boss has deprecated __deprecated a few years ago :D

/*
 * Don't. Just don't. See commit 771c035372a0 ("deprecate the '__deprecated'
 * attribute warnings entirely and for good") for more information.
 *
 *   gcc: 
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-deprecated-function-attribute
 *   gcc: 
https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-deprecated-type-attribute
 *   gcc: 
https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-deprecated-variable-attribute
 *   gcc: 
https://gcc.gnu.org/onlinedocs/gcc/Enumerator-Attributes.html#index-deprecated-enumerator-attribute
 * clang: https://clang.llvm.org/docs/AttributeReference.html#deprecated
 */
#define __deprecated


> 
> ...
> 
> > +   if (pcim_add_mapping_to_legacy_table(pdev, mapping, bar) !=
> > 0)
> 
> Redundant ' != 0' part.
> 
> > +   goto err_table;
> 
> ...
> 
> > +static inline bool mask_contains_bar(int mask, int bar)
> > +{
> > +   return mask & (1 << bar);
> 
> BIT() ?

Yo, we could use it

> 
> > +}
> 
> But I believe this function is not needed (see below).
> 
> ...
> 
> >  /**
> > - * pcim_iomap_regions - Request and iomap PCI BARs
> > + * pcim_iomap_regions - Request and iomap PCI BARs (DEPRECATED)
> >   * @pdev: PCI device to map IO resources for
> >   * @mask: Mask of BARs to request and iomap
> >   * @name: Name associated with the requests
> >   *
> > + * Returns 0 on success, negative error code on failure.
> 
> Validate the kernel-doc.
> 
> >   * Request and iomap regions specified by @mask.
> > + *
> > + * This function is DEPRECATED. Don't use it in new code.
> > + * Use pcim_iomap_region() instead.
> >   */
> 
> ...
> 
> > +   for (bar = 0; bar < DEVICE_COUNT_RESOURCE; bar++) {
> > +   if (!mask_contains_bar(mask, bar))
> > +   continue;
> 
> NIH for_each_set_bit().

But wouldn't that iterate too frequently?
It would check all bits, whereas this for-loop (that I inherited from
the existing implementation, I just tried to keep the functionality
identical) loops until DEVICE_COUNT_RESOURCE, which might be !=
sizeof(int).

> 
> ...
> 
> > +   ret = pcim_add_mapping_to_legacy_table(pdev,
> > mapping, bar);
> > +   if (ret != 0)
> 
> if (ret)
> 
> > +   

Re: [DO NOT MERGE v6 17/37] dt-bindings: interrupt-controller: renesas, sh7751-intc: Add json-schema

2024-01-17 Thread Yoshinori Sato
On Tue, 09 Jan 2024 21:30:34 +0900,
Linus Walleij wrote:
> 
> Hi Yoshinori,
> 
> thanks for your patch!
> 
> On Tue, Jan 9, 2024 at 9:24 AM Yoshinori Sato
>  wrote:
> 
> > +  renesas,icr-irlm:
> > +$ref: /schemas/types.yaml#/definitions/flag
> > +description: If true four independent interrupt requests mode 
> > (ICR.IRLM is 1).
> > +
> > +  renesas,ipr-map:
> > +$ref: /schemas/types.yaml#/definitions/uint32-array
> > +description: |
> > +  IRQ to IPR mapping definition.
> > +  1st - INTEVT code
> > +  2nd - Register
> > +  3rd - bit index
> 
> (...)
> 
> > +renesas,ipr-map = <0x240 IPRD IPR_B12>, /* IRL0 */
> > +  <0x2a0 IPRD IPR_B8>,  /* IRL1 */
> > +  <0x300 IPRD IPR_B4>,  /* IRL2 */
> > +  <0x360 IPRD IPR_B0>,  /* IRL3 */
> (...)
> 
> Is it really necessary to have all this in the device tree?
> 
> You know from the compatible that this is "renesas,sh7751-intc"
> and I bet this table will be the same for any sh7751 right?
> 
> Then just put it in a table in the driver instead and skip this from
> the device tree and bindings. If more interrupt controllers need
> to be supported by the driver, you can simply look up the table from
> the compatible string.

The SH interrupt controller has the same structure, only this part is different 
for each SoC.
Currently, we are targeting only the 7751, but in the future we plan to handle 
all SoCs.
Is it better to differentiate SoC only by compatible?

> Yours,
> Linus Walleij
> 

-- 
Yosinori Sato


Re: [PATCH v12 4/7] drm: bridge: Cadence: Add MHDP8501 DP/HDMI driver

2024-01-17 Thread Alexander Stein
Hi Sandor,

thanks for the update.

Am Mittwoch, 10. Januar 2024, 02:08:45 CET schrieb Sandor Yu:
> Add a new DRM DisplayPort and HDMI bridge driver for Candence MHDP8501
> used in i.MX8MQ SOC. MHDP8501 could support HDMI or DisplayPort
> standards according embedded Firmware running in the uCPU.
> 
> For iMX8MQ SOC, the DisplayPort/HDMI FW was loaded and activated by
> SOC's ROM code. Bootload binary included respective specific firmware
> is required.
> 
> Driver will check display connector type and
> then load the corresponding driver.
> 
> Signed-off-by: Sandor Yu 
> Tested-by: Alexander Stein 
> ---
> v11->v12:
> - Replace DRM_INFO with dev_info or dev_warn.
> - Replace DRM_ERROR with dev_err.
> - Return ret when cdns_mhdp_dpcd_read failed in function
> cdns_dp_aux_transferi(). - Remove unused parmeter in function
> cdns_dp_get_msa_misc
>   and use two separate variables for color space and bpc.
> - Add year 2024 to copyright.
> 
>  drivers/gpu/drm/bridge/cadence/Kconfig|  16 +
>  drivers/gpu/drm/bridge/cadence/Makefile   |   2 +
>  .../drm/bridge/cadence/cdns-mhdp8501-core.c   | 315 
>  .../drm/bridge/cadence/cdns-mhdp8501-core.h   | 365 +
>  .../gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c | 699 ++
>  .../drm/bridge/cadence/cdns-mhdp8501-hdmi.c   | 678 +
>  6 files changed, 2075 insertions(+)
>  create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
>  create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.h
>  create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
>  create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-hdmi.c
> 
> diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig
> b/drivers/gpu/drm/bridge/cadence/Kconfig index e0973339e9e33..45848e741f5f4
> 100644
> --- a/drivers/gpu/drm/bridge/cadence/Kconfig
> +++ b/drivers/gpu/drm/bridge/cadence/Kconfig
> @@ -51,3 +51,19 @@ config DRM_CDNS_MHDP8546_J721E
> initializes the J721E Display Port and sets up the
> clock and data muxes.
>  endif
> +
> +config DRM_CDNS_MHDP8501
> + tristate "Cadence MHDP8501 DP/HDMI bridge"
> + select DRM_KMS_HELPER
> + select DRM_PANEL_BRIDGE
> + select DRM_DISPLAY_DP_HELPER
> + select DRM_DISPLAY_HELPER
> + select CDNS_MHDP_HELPER
> + select DRM_CDNS_AUDIO
> + depends on OF
> + help
> +   Support Cadence MHDP8501 DisplayPort/HDMI bridge.
> +   Cadence MHDP8501 support one or more protocols,
> +   including DisplayPort and HDMI.
> +   To use the DP and HDMI drivers, their respective
> +   specific firmware is required.
> diff --git a/drivers/gpu/drm/bridge/cadence/Makefile
> b/drivers/gpu/drm/bridge/cadence/Makefile index
> 087dc074820d7..02c1a9f3cf6fc 100644
> --- a/drivers/gpu/drm/bridge/cadence/Makefile
> +++ b/drivers/gpu/drm/bridge/cadence/Makefile
> @@ -6,3 +6,5 @@ obj-$(CONFIG_CDNS_MHDP_HELPER) += cdns-mhdp-helper.o
>  obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
>  cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o
>  cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o
> +obj-$(CONFIG_DRM_CDNS_MHDP8501) += cdns-mhdp8501.o
> +cdns-mhdp8501-y := cdns-mhdp8501-core.o cdns-mhdp8501-dp.o
> cdns-mhdp8501-hdmi.o diff --git
> a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
> b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c new file mode 100644
> index 0..3080c7507a012
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-core.c
> @@ -0,0 +1,315 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Cadence Display Port Interface (DP) driver
> + *
> + * Copyright (C) 2023, 2024 NXP Semiconductor, Inc.
> + *
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 

Since commit d57d584ef69de ("of: Stop circularly including of_device.h and 
of_platform.h") you to explicitly include linux/platform_device.h here. Please 
compile against next tree.

> +#include 
> +
> +#include "cdns-mhdp8501-core.h"
> +
> [snip]
> diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
> b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c new file mode 100644
> index 0..6963c7143a3b0
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8501-dp.c
> @@ -0,0 +1,699 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Cadence MHDP8501 DisplayPort(DP) bridge driver
> + *
> + * Copyright (C) 2019-2024 NXP Semiconductor, Inc.
> + *
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "cdns-mhdp8501-core.h"
> +
> +#define LINK_TRAINING_TIMEOUT_MS 500
> +#define LINK_TRAINING_RETRY_MS   20
> +
> +ssize_t cdns_dp_aux_transfer(struct drm_dp_aux *aux,
> +  struct drm_dp_aux_msg *msg)
> +{
> + struct cdns_mhdp8501_device *mhdp = dev_get_drvdata(aux->dev);
> + bool native = msg->request & (DP_AUX_NATIVE_WRITE & 
DP_AUX_NATIVE_READ);
> + int ret

Re: [PATCH v12 7/7] phy: freescale: Add HDMI PHY driver for i.MX8MQ

2024-01-17 Thread Alexander Stein
Hi Sandor,

thanks for the update.

Am Mittwoch, 10. Januar 2024, 02:08:48 CET schrieb Sandor Yu:
> Add Cadence HDP-TX HDMI PHY driver for i.MX8MQ.
> 
> Cadence HDP-TX PHY could be put in either DP mode or
> HDMI mode base on the configuration chosen.
> HDMI PHY mode is configurated in the driver.
> 
> Signed-off-by: Sandor Yu 
> Tested-by: Alexander Stein 
> ---
> v11->v12:
> - Adjust clk disable order.
> - Return error code to replace -1 for function wait_for_ack().
> - Use bool for variable pclk_in.
> - Add year 2024 to copyright.
> 
>  drivers/phy/freescale/Kconfig   |  10 +
>  drivers/phy/freescale/Makefile  |   1 +
>  drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c | 959 
>  3 files changed, 970 insertions(+)
>  create mode 100644 drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
> 
> diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
> index c39709fd700ac..14f47b7cc77ab 100644
> --- a/drivers/phy/freescale/Kconfig
> +++ b/drivers/phy/freescale/Kconfig
> @@ -45,6 +45,16 @@ config PHY_FSL_IMX8MQ_DP
> Enable this to support the Cadence HDPTX DP PHY driver
> on i.MX8MQ SOC.
> 
> +config PHY_FSL_IMX8MQ_HDMI
> + tristate "Freescale i.MX8MQ HDMI PHY support"
> + depends on OF && HAS_IOMEM
> + depends on COMMON_CLK
> + select GENERIC_PHY
> + select CDNS_MHDP_HELPER
> + help
> +   Enable this to support the Cadence HDPTX HDMI PHY driver
> +   on i.MX8MQ SOC.
> +
>  endif
> 
>  config PHY_FSL_LYNX_28G
> diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
> index 47e5285209fa8..1380ac31c2ead 100644
> --- a/drivers/phy/freescale/Makefile
> +++ b/drivers/phy/freescale/Makefile
> @@ -1,5 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  obj-$(CONFIG_PHY_FSL_IMX8MQ_DP)  += phy-fsl-imx8mq-dp.o
> +obj-$(CONFIG_PHY_FSL_IMX8MQ_HDMI)+= phy-fsl-imx8mq-hdmi.o
>  obj-$(CONFIG_PHY_FSL_IMX8MQ_USB) += phy-fsl-imx8mq-usb.o
>  obj-$(CONFIG_PHY_MIXEL_LVDS_PHY) += phy-fsl-imx8qm-lvds-phy.o
>  obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY)+= phy-fsl-imx8-mipi-dphy.o
> diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
> b/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c new file mode 100644
> index 0..9e03c726f290c
> --- /dev/null
> +++ b/drivers/phy/freescale/phy-fsl-imx8mq-hdmi.c
> @@ -0,0 +1,959 @@
> [snip]
> +int cdns_hdptx_hdmi_phy_valid(struct phy *phy, enum phy_mode mode, int
> submode, +  union phy_configure_opts *opts)

This function can be made static.

Thanks and best regards,
Alexander

> +{
> + u32 rate = opts->hdmi.pixel_clk_rate;
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(pixel_clk_output_ctrl_table); i++)
> + if (rate == 
pixel_clk_output_ctrl_table[i].pixel_clk_freq_min)
> + return 0;
> +
> + return -EINVAL;
> +}
> +
> +static int cdns_hdptx_hdmi_phy_init(struct phy *phy)
> +{
> + return 0;
> +}
> +
> +static int cdns_hdptx_hdmi_configure(struct phy *phy,
> +  union phy_configure_opts *opts)
> +{
> + struct cdns_hdptx_hdmi_phy *cdns_phy = phy_get_drvdata(phy);
> + int ret;
> +
> + cdns_phy->pixel_clk_rate = opts->hdmi.pixel_clk_rate;
> + cdns_phy->color_space = opts->hdmi.color_space;
> + cdns_phy->bpc = opts->hdmi.bpc;
> +
> + /* Check HDMI FW alive before HDMI PHY init */
> + ret = hdptx_phy_check_alive(cdns_phy);
> + if (!ret) {
> + dev_err(cdns_phy->dev, "NO HDMI FW running\n");
> + return -ENXIO;
> + }
> +
> + /* Configure PHY */
> + if (hdptx_hdmi_phy_cfg(cdns_phy, cdns_phy->pixel_clk_rate) < 0) {
> + dev_err(cdns_phy->dev, "failed to set phy pclock\n");
> + return -EINVAL;
> + }
> +
> + ret = hdptx_hdmi_phy_power_up(cdns_phy);
> + if (ret < 0)
> + return ret;
> +
> + hdptx_hdmi_phy_set_vswing(cdns_phy);
> +
> + return 0;
> +}
> +
> +static const struct phy_ops cdns_hdptx_hdmi_phy_ops = {
> + .init = cdns_hdptx_hdmi_phy_init,
> + .configure = cdns_hdptx_hdmi_configure,
> + .power_on = cdns_hdptx_hdmi_phy_on,
> + .power_off = cdns_hdptx_hdmi_phy_off,
> + .validate = cdns_hdptx_hdmi_phy_valid,
> + .owner = THIS_MODULE,
> +};
> +
> +static int cdns_hdptx_hdmi_phy_probe(struct platform_device *pdev)
> +{
> + struct cdns_hdptx_hdmi_phy *cdns_phy;
> + struct device *dev = &pdev->dev;
> + struct device_node *node = dev->of_node;
> + struct phy_provider *phy_provider;
> + struct resource *res;
> + struct phy *phy;
> + int ret;
> +
> + cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL);
> + if (!cdns_phy)
> + return -ENOMEM;
> +
> + dev_set_drvdata(dev, cdns_phy);
> + cdns_phy->dev = dev;
> + mutex_init(&cdns_phy->mbox_mutex);
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!res)
> + return -E

Re: (subset) [PATCH v5 3/5] drm/tests: managed: Add comments about test intent

2024-01-17 Thread Maxime Ripard
On Mon, 15 Jan 2024 18:13:49 +0100, Michał Winiarski wrote:
> Add comments explaining the intention behind the test and certain
> implementation details related to device lifetime.
> 
> 

Applied to drm/drm-misc (drm-misc-next).

Thanks!
Maxime



Re: (subset) [PATCH v5 5/5] drm/tests: managed: Add a simple test for drmm_managed_release

2024-01-17 Thread Maxime Ripard
On Mon, 15 Jan 2024 18:13:51 +0100, Michał Winiarski wrote:
> Add a simple test that checks whether the action is called when
> drmm_managed_release is called.
> 
> 

Applied to drm/drm-misc (drm-misc-next).

Thanks!
Maxime



Re: (subset) [PATCH] drm/rockchip: inno_hdmi: Explicitly include drm_atomic.h

2024-01-17 Thread Maxime Ripard
On Mon, 15 Jan 2024 10:24:35 +0100, Alex Bee wrote:
> Commit d3e040f450ec ("drm/rockchip: inno_hdmi: Get rid of mode_set")
> started using drm_atomic_get_new_connector_state and
> drm_atomic_get_new_crtc_state which are defined in drm_atomic.h
> Building does currently only work if CONFIG_OF and CONFIG_DRM_PANEL_BRIDGE
> are enabled since this will include drm_atomic.h via drm_bridge.h (see
> drm_of.h).
> 
> [...]

Applied to drm/drm-misc (drm-misc-next).

Thanks!
Maxime



Re: (subset) [PATCH v5 1/5] drm/managed: Add drmm_release_action

2024-01-17 Thread Maxime Ripard
On Mon, 15 Jan 2024 18:13:47 +0100, Michał Winiarski wrote:
> Similar to devres equivalent, it allows to call the "release" action
> directly and remove the resource from the managed resources list.
> 
> 

Applied to drm/drm-misc (drm-misc-next).

Thanks!
Maxime



Re: (subset) [PATCH v5 2/5] drm/tests: managed: Rename the suite name to match other DRM tests

2024-01-17 Thread Maxime Ripard
On Mon, 15 Jan 2024 18:13:48 +0100, Michał Winiarski wrote:
> DRM tests use "_" rather than "-" as word separator. Rename the test
> suite to match other tests.
> 
> 

Applied to drm/drm-misc (drm-misc-next).

Thanks!
Maxime



Re: (subset) [PATCH v5 4/5] drm/tests: managed: Extract device initialization into test init

2024-01-17 Thread Maxime Ripard
On Mon, 15 Jan 2024 18:13:50 +0100, Michał Winiarski wrote:
> It simplifies the process of extending the test suite with additional
> test cases without unnecessary duplication.
> 
> 

Applied to drm/drm-misc (drm-misc-next).

Thanks!
Maxime



Re: (subset) [PATCH] drm/rockchip: inno_hdmi: Explicitly include drm_atomic.h

2024-01-17 Thread Heiko Stübner
Hi Maxime,

Am Mittwoch, 17. Januar 2024, 10:46:57 CET schrieb Maxime Ripard:
> On Mon, 15 Jan 2024 10:24:35 +0100, Alex Bee wrote:
> > Commit d3e040f450ec ("drm/rockchip: inno_hdmi: Get rid of mode_set")
> > started using drm_atomic_get_new_connector_state and
> > drm_atomic_get_new_crtc_state which are defined in drm_atomic.h
> > Building does currently only work if CONFIG_OF and CONFIG_DRM_PANEL_BRIDGE
> > are enabled since this will include drm_atomic.h via drm_bridge.h (see
> > drm_of.h).
> > 
> > [...]
> 
> Applied to drm/drm-misc (drm-misc-next).

wouldn't have drm-misc-next-fixes been more appropriate?
Because I _think_ the change causing the issue made it in during the
current merge-window?

Heiko




Re: [PATCH 00/10] Make PCI's devres API more consistent

2024-01-17 Thread Philipp Stanner
On Tue, 2024-01-16 at 23:17 +0200, andy.shevche...@gmail.com wrote:
> Mon, Jan 15, 2024 at 03:46:11PM +0100, Philipp Stanner kirjoitti:
> > ¡Hola!
> 
> i? Vim user? :-)

The Dark Side of the Force is the path to many abilities, that some
consider to be... unnatural
https://www.neo-layout.org/

> 
> > PCI's devres API suffers several weaknesses:
> > 
> > 1. There are functions prefixed with pcim_. Those are always
> > managed
> >    counterparts to never-managed functions prefixed with pci_ – or
> > so one
> >    would like to think. There are some apparently unmanaged
> > functions
> >    (all region-request / release functions, and pci_intx()) which
> >    suddenly become managed once the user has initialized the device
> > with
> >    pcim_enable_device() instead of pci_enable_device(). This
> > "sometimes
> >    yes, sometimes no" nature of those functions is confusing and
> >    therefore bug-provoking. In fact, it has already caused a bug in
> > DRM.
> >    The last patch in this series fixes that bug.
> > 2. iomappings: Instead of giving each mapping its own callback, the
> >    existing API uses a statically allocated struct tracking one
> > mapping
> >    per bar. This is not extensible. Especially, you can't create
> >    _ranged_ managed mappings that way, which many drivers want.
> > 3. Managed request functions only exist as "plural versions" with a
> >    bit-mask as a parameter. That's quite over-engineered
> > considering
> >    that each user only ever mapps one, maybe two bars.
> > 
> > This series:
> > - add a set of new "singular" devres functions that use devres the
> > way
> >   its intended, with one callback per resource.
> > - deprecates the existing iomap-table mechanism.
> > - deprecates the hybrid nature of pci_ functions.
> > - preserves backwards compatibility so that drivers using the
> > existing
> >   API won't notice any changes.
> > - adds documentation, especially some warning users about the
> >   complicated nature of PCI's devres.
> 
> Instead of adding pcim_intx(), please provide proper one for
> pci_alloc_irq_vectors(). Ideally it would be nice to deprecate
> old IRQ management functions in PCI core and delete them in the
> future.
> 

In order to deprecate the intermingling with half-managed hyprid devres
in pci.c, you need to have pci_intx() be backwards compatible. Unless
you can remove it at once.
And the least broken way to do that I thought would be pcim_intx(),
because that's consistent with how I make pci_request_region() & Co.
call into their managed counterparts.

There are 25 users of pci_intx().
We'd have to look how many of them call pcim_enable_device() and how
easy they would be to port to... pci_alloc_irq_vectors() you say? I
haven't used that before. Would have to look into it and see how we
could do that.


P.



Re: [DO NOT MERGE v6 17/37] dt-bindings: interrupt-controller: renesas,sh7751-intc: Add json-schema

2024-01-17 Thread Geert Uytterhoeven
Hi Sato-san,

On Wed, Jan 17, 2024 at 10:46 AM Yoshinori Sato
 wrote:
> On Tue, 09 Jan 2024 21:30:34 +0900,
> Linus Walleij wrote:
> > On Tue, Jan 9, 2024 at 9:24 AM Yoshinori Sato
> >  wrote:
> >
> > > +  renesas,icr-irlm:
> > > +$ref: /schemas/types.yaml#/definitions/flag
> > > +description: If true four independent interrupt requests mode 
> > > (ICR.IRLM is 1).
> > > +
> > > +  renesas,ipr-map:
> > > +$ref: /schemas/types.yaml#/definitions/uint32-array
> > > +description: |
> > > +  IRQ to IPR mapping definition.
> > > +  1st - INTEVT code
> > > +  2nd - Register
> > > +  3rd - bit index
> >
> > (...)
> >
> > > +renesas,ipr-map = <0x240 IPRD IPR_B12>, /* IRL0 */
> > > +  <0x2a0 IPRD IPR_B8>,  /* IRL1 */
> > > +  <0x300 IPRD IPR_B4>,  /* IRL2 */
> > > +  <0x360 IPRD IPR_B0>,  /* IRL3 */
> > (...)
> >
> > Is it really necessary to have all this in the device tree?
> >
> > You know from the compatible that this is "renesas,sh7751-intc"
> > and I bet this table will be the same for any sh7751 right?
> >
> > Then just put it in a table in the driver instead and skip this from
> > the device tree and bindings. If more interrupt controllers need
> > to be supported by the driver, you can simply look up the table from
> > the compatible string.
>
> The SH interrupt controller has the same structure, only this part is 
> different for each SoC.
> Currently, we are targeting only the 7751, but in the future we plan to 
> handle all SoCs.
> Is it better to differentiate SoC only by compatible?

Yes, it is better to differentiate SoC only by compatible value.

When you describe all differences explicitly using properties, you
might discover later that you missed something important, causing
backwards compatibility issues with old DTBs.
DT is a stable ABI, while you can always update a driver when needed.

Gr{oetje,eeting}s,

Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds


Re: [PATCH RFC 0/4] Support for Simulated Panels

2024-01-17 Thread Jani Nikula
On Wed, 17 Jan 2024, Maxime Ripard  wrote:
> Hi,
>
> On Tue, Jan 16, 2024 at 02:22:03PM -0800, Jessica Zhang wrote:
>> This series introduces a simulated MIPI DSI panel.
>> 
>> Currently, the only way to validate DSI connectors is with a physical
>> panel. Since obtaining physical panels for all possible DSI configurations
>> is logistically infeasible, introduce a way for DSI drivers to simulate a
>> panel.
>> 
>> This will be helpful in catching DSI misconfiguration bugs and catching
>> performance issues for high FPS panels that might not be easily
>> obtainable.
>> 
>> For now, the simulated panel driver only supports setting customized
>> modes via the panel_simlation.mode modparam. Eventually, we would like
>> to add more customizations (such as configuring DSC, dual DSI, etc.).
>
> I think that it's more complicated than it needs to be.

Both too complicated and not complicated enough! :p

> Why do we need to support (and switch to) both the actual and
> "simulated" panel?
>
> Wouldn't it be simpler if we had a vkms-like panel that we could either
> configure from DT or from debugfs that would just be registered the
> usual way and would be the only panel we register?

I get the idea of trying to test DSI code without panels, and looking at
the goals above, I think your vkms suggestion is going to fall short of
those goals.

However, my gut feeling is that creating a simulated panel to catch DSI
misconfiguration etc. is going to be insanely complicated, and this
series doesn't even scratch the surface.

I guess my questions are, what's the scope here really, are those goals
realistic, does more code already exist beyond this skeleton?

BR,
Jani.



-- 
Jani Nikula, Intel


Re: [PATCH 2/5] drm/ttm: return ENOSPC from ttm_bo_mem_space

2024-01-17 Thread Thomas Hellström

Hi,

On 1/12/24 13:51, Christian König wrote:

Only convert it to ENOMEM in ttm_bo_validate.

This allows ttm_bo_validate to distinct between an out of memory

NIT: s/distinct/distinguish/

situation and just out of space in a placement domain.


In fact it would be nice if this could be propagated back to drivers as 
well at some point, but then perhaps guarded with a flag in the 
operation context.


In any case

Reviewed-by: Thomas Hellström 



Signed-off-by: Christian König 
---
  drivers/gpu/drm/ttm/ttm_bo.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index edf10618fe2b..8c1eaa74fa21 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -830,7 +830,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
goto error;
}
  
-	ret = -ENOMEM;

+   ret = -ENOSPC;
if (!type_found) {
pr_err(TTM_PFX "No compatible memory type found\n");
ret = -EINVAL;
@@ -916,6 +916,9 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
return -EINVAL;
  
  	ret = ttm_bo_move_buffer(bo, placement, ctx);

+   /* For backward compatibility with userspace */
+   if (ret == -ENOSPC)
+   return -ENOMEM;
if (ret)
return ret;
  


[PATCH] drm: apple: mark local functions static

2024-01-17 Thread Arnd Bergmann
From: Arnd Bergmann 

With linux-6.8, the kernel warns about functions that have no
extern declaration, so mark both of these static.

Fixes: 2d782b0d007d ("gpu: drm: apple: Add sound mode parsing")
Signed-off-by: Arnd Bergmann 
---
This is for the bits/200-dcp branch in https://github.com/AsahiLinux/linux,
the code is not yet upstream.
---
 drivers/gpu/drm/apple/parser.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/apple/parser.c b/drivers/gpu/drm/apple/parser.c
index 44aad9a64f9a..ea9f40bb7de2 100644
--- a/drivers/gpu/drm/apple/parser.c
+++ b/drivers/gpu/drm/apple/parser.c
@@ -694,7 +694,7 @@ int parse_epic_service_init(struct dcp_parse_ctx *handle, 
const char **name,
return ret;
 }
 
-int parse_sample_rate_bit(struct dcp_parse_ctx *handle, unsigned int *ratebit)
+static int parse_sample_rate_bit(struct dcp_parse_ctx *handle, unsigned int 
*ratebit)
 {
s64 rate;
int ret = parse_int(handle, &rate);
@@ -715,7 +715,7 @@ int parse_sample_rate_bit(struct dcp_parse_ctx *handle, 
unsigned int *ratebit)
return 0;
 }
 
-int parse_sample_fmtbit(struct dcp_parse_ctx *handle, u64 *fmtbit)
+static int parse_sample_fmtbit(struct dcp_parse_ctx *handle, u64 *fmtbit)
 {
s64 sample_size;
int ret = parse_int(handle, &sample_size);
-- 
2.39.2



Re: [PATCH 3/5] drm/ttm: replace busy placement with flags v6

2024-01-17 Thread Thomas Hellström

Hi, Christian

Xe changes look good. Will send the series to xe ci to check for 
regressions.


/Thomas


On 1/12/24 13:51, Christian König wrote:

From: Somalapuram Amaranath 

Instead of a list of separate busy placement add flags which indicate
that a placement should only be used when there is room or if we need to
evict.

v2: add missing TTM_PL_FLAG_IDLE for i915
v3: fix auto build test ERROR on drm-tip/drm-tip
v4: fix some typos pointed out by checkpatch
v5: cleanup some rebase problems with VMWGFX
v6: implement some missing VMWGFX functionality pointed out by Zack,
 rename the flags as suggested by Michel, rebase on drm-tip and
 adjust XE as well

Signed-off-by: Christian König 
Signed-off-by: Somalapuram Amaranath 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c |  6 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c| 11 +---
  drivers/gpu/drm/drm_gem_vram_helper.c  |  2 -
  drivers/gpu/drm/i915/gem/i915_gem_ttm.c| 37 +--
  drivers/gpu/drm/loongson/lsdc_ttm.c|  2 -
  drivers/gpu/drm/nouveau/nouveau_bo.c   | 59 +++--
  drivers/gpu/drm/nouveau/nouveau_bo.h   |  1 -
  drivers/gpu/drm/qxl/qxl_object.c   |  2 -
  drivers/gpu/drm/qxl/qxl_ttm.c  |  2 -
  drivers/gpu/drm/radeon/radeon_object.c |  2 -
  drivers/gpu/drm/radeon/radeon_ttm.c|  8 +--
  drivers/gpu/drm/radeon/radeon_uvd.c|  1 -
  drivers/gpu/drm/ttm/ttm_bo.c   | 21 ---
  drivers/gpu/drm/ttm/ttm_resource.c | 73 +-
  drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 33 +++---
  drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c |  4 --
  drivers/gpu/drm/xe/xe_bo.c | 33 +-
  include/drm/ttm/ttm_placement.h| 10 +--
  include/drm/ttm/ttm_resource.h |  8 +--
  19 files changed, 118 insertions(+), 197 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 425cebcc5cbf..b671b0665492 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -220,9 +220,6 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, 
u32 domain)
  
  	placement->num_placement = c;

placement->placement = places;
-
-   placement->num_busy_placement = c;
-   placement->busy_placement = places;
  }
  
  /**

@@ -1397,8 +1394,7 @@ vm_fault_t amdgpu_bo_fault_reserve_notify(struct 
ttm_buffer_object *bo)
AMDGPU_GEM_DOMAIN_GTT);
  
  	/* Avoid costly evictions; only set GTT as a busy placement */

-   abo->placement.num_busy_placement = 1;
-   abo->placement.busy_placement = &abo->placements[1];
+   abo->placements[0].flags |= TTM_PL_FLAG_DESIRED;
  
  	r = ttm_bo_validate(bo, &abo->placement, &ctx);

if (unlikely(r == -EBUSY || r == -ERESTARTSYS))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 75c9fd2c6c2a..8722beba494e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -102,23 +102,19 @@ static void amdgpu_evict_flags(struct ttm_buffer_object 
*bo,
/* Don't handle scatter gather BOs */
if (bo->type == ttm_bo_type_sg) {
placement->num_placement = 0;
-   placement->num_busy_placement = 0;
return;
}
  
  	/* Object isn't an AMDGPU object so ignore */

if (!amdgpu_bo_is_amdgpu_bo(bo)) {
placement->placement = &placements;
-   placement->busy_placement = &placements;
placement->num_placement = 1;
-   placement->num_busy_placement = 1;
return;
}
  
  	abo = ttm_to_amdgpu_bo(bo);

if (abo->flags & AMDGPU_GEM_CREATE_DISCARDABLE) {
placement->num_placement = 0;
-   placement->num_busy_placement = 0;
return;
}
  
@@ -128,13 +124,13 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,

case AMDGPU_PL_OA:
case AMDGPU_PL_DOORBELL:
placement->num_placement = 0;
-   placement->num_busy_placement = 0;
return;
  
  	case TTM_PL_VRAM:

if (!adev->mman.buffer_funcs_enabled) {
/* Move to system memory */
amdgpu_bo_placement_from_domain(abo, 
AMDGPU_GEM_DOMAIN_CPU);
+
} else if (!amdgpu_gmc_vram_full_visible(&adev->gmc) &&
   !(abo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) 
&&
   amdgpu_bo_in_cpu_visible_vram(abo)) {
@@ -149,8 +145,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
AMDGPU_GEM_DOMAIN_CPU);
abo->placements[0].fpfn = adev->gmc.visible_vram_size 
>> PAGE_SHIFT;
abo->placements[0].lpfn = 0;

Re: [PATCH v1 0/8] drm/ci: Add support for GPU and display testing

2024-01-17 Thread Vignesh Raman

Hi Daniel,

On 11/01/24 23:41, Daniel Stone wrote:

Hi Vignesh,

On Wed, 10 Jan 2024 at 10:47, Vignesh Raman  wrote:

On 09/01/24 19:08, Daniel Stone wrote:

A better sequencing would be something like:
1. add ANX7625 config
2. refactor _existing_ MTK display jobs to use YAML includes, change
the existing job name, and rename the existing xfail set, remove
IGT_FORCE_DRIVER from the script since it's now set by the job
3. add MTK Panfrost+PVR GPU jobs with new xfails, add xfail entry to
MAINTAINERS
4+5: same as 2+3 but for Amlogic
6+7: same as 2+3 but for Rockchip

Then the separate rename/update xfail commits just disappear, as does
the removal of IGT_FORCE_DRIVER, because it's just done incrementally
as part of the commits which change the related functionality. It's
extremely important that every change can work standalone, instead of
introducing intermediate breakage which is only fixed in later commits
in the series.


Thank you for reviewing the patches. I agree, will follow this sequence
and send a v2 version.


Alongside Rob's patch to add msm-specific tests to the runlist, we'd
need to add the Panfrost-specific tests. Whilst we're here, we might
as well add the vc4/v3d/etnaviv/lima tests so they can use it in
future.

Panfrost should also skip kms_.* tests - since it's not a KMS driver,
it can't run the KMS tests, so there's no point in trying.


I will add these tests and update skips file. Sorry missed this before 
sending v2. I'm rechecking the xfails for the v2 series and will send

v3 with these changes. Thanks.

Regards,
Vignesh


Re: [PATCH v3 4/4] Documentation: usb: Document FunctionFS DMABUF API

2024-01-17 Thread Paul Cercueil
Hi Vegard,

Le mardi 09 janvier 2024 à 14:08 +0100, Vegard Nossum a écrit :
> On 08/01/2024 13:00, Paul Cercueil wrote:
> > Add documentation for the three ioctls used to attach or detach
> > externally-created DMABUFs, and to request transfers from/to
> > previously
> > attached DMABUFs.
> > 
> > Signed-off-by: Paul Cercueil 
> > 
> > ---
> > v3: New patch
> > ---
> >   Documentation/usb/functionfs.rst | 36
> > 
> >   1 file changed, 36 insertions(+)
> 
> Hi,
> 
> I'd like to point out that this file (usb/functionfs.rst) is
> currently
> included by Documentation/subsystem-apis.rst, the top-level file for
> the
> "Kernel subsystem documentation" set of books, which describe
> internal
> APIs: "These books get into the details of how specific kernel
> subsystems work from the point of view of a kernel developer".
> 
> However, functionfs.rst (and especially your new additions) are
> documenting a userspace API, so it really belongs somewhere in
> Documentation/userspace-api/ -- that's where /proc, /sys, /dev and
> ioctl
> descriptions for userspace programmers belong.

Agreed. Even the original content prior to my additions describe a
userspace API.

> 
> I'm not NAKing the patch -- I just want to draw attention to this
> discrepancy. Maybe we can separate the kernel-implementation details
> (stuff about __init sections and stuff) from the new ioctl() info?
> 
> Looking at  I see that there are many
> other adjacent documents that are also not really documenting kernel
> implementation details, rough categorization as follows:
> 
> USB support
> ---
> 
> - Linux ACM driver v0.16 ==> admin/user info
> - Authorizing (or not) your USB devices to connect to the system ==> 
> admin/user info
> - ChipIdea Highspeed Dual Role Controller Driver => admin/user info
> - DWC3 driver ==> driver TODOs (can be moved into source code?)
> - EHCI driver ==> technical info + driver details
> - How FunctionFS works
> - Linux USB gadget configured through configfs ==> userspace API + 
> implementation
> - Linux USB HID gadget driver ==> implementation + userspace API
> - Multifunction Composite Gadget ==> technical + user info
> - Linux USB Printer Gadget Driver ==> userspace API
> - Linux Gadget Serial Driver v2.0 ==> user/admin + userspace API
> - Linux UVC Gadget Driver ==> user/admin + userspace API
> - Gadget Testing ==> user/admin + userspace API
> - Infinity Usb Unlimited Readme ==> user/admin
> - Mass Storage Gadget (MSG) ==> user/admin
> - USB 7-Segment Numeric Display ==> user/admin
> - mtouchusb driver ==> user/admin
> - OHCI ==> technical info
> - USB Raw Gadget ==> userspace API
> - USB/IP protocol ==> technical info
> - usbmon ==> user/admin + userspace API
> - USB serial ==> user/admin + technical info
> - USB references
> - Linux CDC ACM inf
> - Linux inf
> - USB devfs drop permissions source
> - Credits
> 
> By "admin/user info", I mean things that a user would have to do or
> run
> (e.g. modprobe + flags) to make use of a driver; "technical info" is
> more like device specifications (transfer speeds, modes of operation,
> etc.); "userspace API" is stuff like configfs and ioctls; "driver
> details" is really implementation details and internal
> considerations.
> 
> The last ones I don't even really know how to categorize.
> 
> I'm guessing nobody is really enthralled by the idea of splitting
> Documentation/usb/ up like this?
> 
>    Documentation/admin-guide/usb/
>    Documentation/driver-api/usb/ (this one actually exists already)
>    Documentation/userspace-api/usb/
> 
> For the stuff that is _actually_ internal to a specific driver (so
> not
> useful for end users, not useful for admins, not generic USB info,
> and
> not useful for userspace programmers), I would honestly propose to
> just
> move it directly into the driver's source code, or, if the text is
> obsolete, just get rid of it completely.
> 
> The distinction between user/admin and userspace API is pretty clear
> (one is for end users, the other is for userspace _programmers_), but
> it
> can sometimes be hard to determine whether something falls in one or
> the
> other category.
> 
> In any case -- it looks like almost all of the usb/ directory does
> not
> document "how specific kernel subsystems work from the point of view
> of
> a kernel developer" so maybe we should just move the include to
> userspace-api/ for now as an obvious improvement (if still not 100%
> correct):
> 
> diff --git a/Documentation/subsystem-apis.rst 
> b/Documentation/subsystem-apis.rst
> index 2d353fb8ea26..fe972f57bf4c 100644
> --- a/Documentation/subsystem-apis.rst
> +++ b/Documentation/subsystem-apis.rst
> @@ -81,7 +81,6 @@ Storage interfaces
>  security/index
>  crypto/index
>  bpf/index
> -   usb/index
>  PCI/index
>  misc-devices/index
>  peci/index
> diff --git a/Documentation/userspace-api/index.rst 
> b/Documentation/userspace-api/index.rst
> index 82f9dbd228f5..e6

Re: [PATCH] [v2] drm/lima: fix a memleak in lima_heap_alloc

2024-01-17 Thread Qiang Yu
Reviewed-by: Qiang Yu 

On Wed, Jan 17, 2024 at 3:14 PM Zhipeng Lu  wrote:
>
> When lima_vm_map_bo fails, the resources need to be deallocated, or
> there will be memleaks.
>
> Fixes: 6aebc51d7aef ("drm/lima: support heap buffer creation")
> Signed-off-by: Zhipeng Lu 
> ---
> Changelog:
>
> v2: rearrange the error-handling to ladder tags.
> ---
>  drivers/gpu/drm/lima/lima_gem.c | 23 +++
>  1 file changed, 15 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
> index 4f9736e5f929..d3d82ee7fb4c 100644
> --- a/drivers/gpu/drm/lima/lima_gem.c
> +++ b/drivers/gpu/drm/lima/lima_gem.c
> @@ -75,29 +75,36 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm 
> *vm)
> } else {
> bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL);
> if (!bo->base.sgt) {
> -   sg_free_table(&sgt);
> -   return -ENOMEM;
> +   ret = -ENOMEM;
> +   goto err_out0;
> }
> }
>
> ret = dma_map_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0);
> if (ret) {
> -   sg_free_table(&sgt);
> -   kfree(bo->base.sgt);
> -   bo->base.sgt = NULL;
> -   return ret;
> +   goto err_out1;
> }
>
> *bo->base.sgt = sgt;
>
> if (vm) {
> ret = lima_vm_map_bo(vm, bo, old_size >> PAGE_SHIFT);
> -   if (ret)
> -   return ret;
> +   if (ret) {
> +   goto err_out2;
> +   }
> }
>
> bo->heap_size = new_size;
> return 0;
> +
> +err_out2:
> +   dma_unmap_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0);
> +err_out1:
> +   kfree(bo->base.sgt);
> +   bo->base.sgt = NULL;
> +err_out0:
> +   sg_free_table(&sgt);
> +   return ret;
>  }
>
>  int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file,
> --
> 2.34.1
>


Re: [PATCH v3 1/2] drm/imx/dcss: request memory region

2024-01-17 Thread Laurentiu Palcu
Hi Philipp,

On Thu, Jan 11, 2024 at 11:13:46AM +0100, Philipp Stanner wrote:
> The driver's memory regions are currently just ioremap()ed, but not
> reserved through a request. That's not a bug, but having the request is
> a little more robust.
> 
> Implement the region-request through the corresponding managed
> devres-function.
> 
> Signed-off-by: Philipp Stanner 

Reviewed-by: Laurentiu Palcu 

Thanks,
Laurentiu

> ---
>  drivers/gpu/drm/imx/dcss/dcss-dev.c | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-dev.c 
> b/drivers/gpu/drm/imx/dcss/dcss-dev.c
> index 4f3af0dfb344..d448bf1c205e 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-dev.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-dev.c
> @@ -170,6 +170,7 @@ struct dcss_dev *dcss_dev_create(struct device *dev, bool 
> hdmi_output)
>   struct resource *res;
>   struct dcss_dev *dcss;
>   const struct dcss_type_data *devtype;
> + resource_size_t res_len;
>  
>   devtype = of_device_get_match_data(dev);
>   if (!devtype) {
> @@ -183,6 +184,12 @@ struct dcss_dev *dcss_dev_create(struct device *dev, 
> bool hdmi_output)
>   return ERR_PTR(-EINVAL);
>   }
>  
> + res_len = res->end - res->start;
> + if (!devm_request_mem_region(dev, res->start, res_len, "dcss")) {
> + dev_err(dev, "cannot request memory region\n");
> + return ERR_PTR(-EBUSY);
> + }
> +
>   dcss = kzalloc(sizeof(*dcss), GFP_KERNEL);
>   if (!dcss)
>   return ERR_PTR(-ENOMEM);
> -- 
> 2.43.0
> 


[PATCH v4 0/4] usb: gadget: functionfs: DMABUF import interface

2024-01-17 Thread Paul Cercueil
Hi,

This is the v4 of my patchset that adds a new DMABUF import interface to
FunctionFS. It addresses the points that Daniel raised on the v3 - see
changelog below.

This interface is being used at Analog Devices, to transfer data from
high-speed transceivers to USB in a zero-copy fashion, using also the
DMABUF import interface to the IIO subsystem which is being upstreamed
in parallel [1]. The two are used by the Libiio software [2].

On a ZCU102 board with a FMComms3 daughter board, using the combination
of these two new interfaces yields a drastic improvement of the
throughput, from about 127 MiB/s using IIO's buffer read/write interface
+ read/write to the FunctionFS endpoints, to about 274 MiB/s when
passing around DMABUFs, for a lower CPU usage (0.85 load avg. before,
vs. 0.65 after).

Right now, *technically* there are no users of this interface, as
Analog Devices wants to wait until both interfaces are accepted upstream
to merge the DMABUF code in Libiio into the main branch, and Jonathan
wants to wait and see if this patchset is accepted to greenlight the
DMABUF interface in IIO as well. I think this isn't really a problem;
once everybody is happy with its part of the cake, we can merge them all
at once.

This is obviously for 5.9, and based on next-20240117.

Changelog:

- [3/4]:
  - Protect the dmabufs list with a mutex
  - Use incremental sequence number for the dma_fences
  - Unref attachments and DMABUFs in workers
  - Remove dead code in ffs_dma_resv_lock()
  - Fix non-block actually blocking
  - Use dma_fence_begin/end_signalling()
  - Add comment about cache-management and dma_buf_unmap_attachment()
  - Make sure dma_buf_map_attachment() is called with the dma-resv locked

Cheers,
-Paul

[1] 
https://lore.kernel.org/linux-iio/219abc43b4fdd4a13b307ed2efaa0e6869e68e3f.ca...@gmail.com/T/
[2] https://github.com/analogdevicesinc/libiio/tree/pcercuei/dev-new-dmabuf-api

Paul Cercueil (4):
  usb: gadget: Support already-mapped DMA SGs
  usb: gadget: functionfs: Factorize wait-for-endpoint code
  usb: gadget: functionfs: Add DMABUF import interface
  Documentation: usb: Document FunctionFS DMABUF API

 Documentation/usb/functionfs.rst|  36 ++
 drivers/usb/gadget/function/f_fs.c  | 500 ++--
 drivers/usb/gadget/udc/core.c   |   7 +-
 include/linux/usb/gadget.h  |   2 +
 include/uapi/linux/usb/functionfs.h |  41 +++
 5 files changed, 565 insertions(+), 21 deletions(-)

-- 
2.43.0



[PATCH v4 1/4] usb: gadget: Support already-mapped DMA SGs

2024-01-17 Thread Paul Cercueil
Add a new 'sg_was_mapped' field to the struct usb_request. This field
can be used to indicate that the scatterlist associated to the USB
transfer has already been mapped into the DMA space, and it does not
have to be done internally.

Signed-off-by: Paul Cercueil 
---
 drivers/usb/gadget/udc/core.c | 7 ++-
 include/linux/usb/gadget.h| 2 ++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index d59f94464b87..9d4150124fdb 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -903,6 +903,11 @@ int usb_gadget_map_request_by_dev(struct device *dev,
if (req->length == 0)
return 0;
 
+   if (req->sg_was_mapped) {
+   req->num_mapped_sgs = req->num_sgs;
+   return 0;
+   }
+
if (req->num_sgs) {
int mapped;
 
@@ -948,7 +953,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_map_request);
 void usb_gadget_unmap_request_by_dev(struct device *dev,
struct usb_request *req, int is_in)
 {
-   if (req->length == 0)
+   if (req->length == 0 || req->sg_was_mapped)
return;
 
if (req->num_mapped_sgs) {
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index a771ccc038ac..c529e4e06997 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -52,6 +52,7 @@ struct usb_ep;
  * @short_not_ok: When reading data, makes short packets be
  * treated as errors (queue stops advancing till cleanup).
  * @dma_mapped: Indicates if request has been mapped to DMA (internal)
+ * @sg_was_mapped: Set if the scatterlist has been mapped before the request
  * @complete: Function called when request completes, so this request and
  * its buffer may be re-used.  The function will always be called with
  * interrupts disabled, and it must not sleep.
@@ -111,6 +112,7 @@ struct usb_request {
unsignedzero:1;
unsignedshort_not_ok:1;
unsigneddma_mapped:1;
+   unsignedsg_was_mapped:1;
 
void(*complete)(struct usb_ep *ep,
struct usb_request *req);
-- 
2.43.0



[PATCH v4 2/4] usb: gadget: functionfs: Factorize wait-for-endpoint code

2024-01-17 Thread Paul Cercueil
This exact same code was duplicated in two different places.

Signed-off-by: Paul Cercueil 
---
 drivers/usb/gadget/function/f_fs.c | 48 +-
 1 file changed, 27 insertions(+), 21 deletions(-)

diff --git a/drivers/usb/gadget/function/f_fs.c 
b/drivers/usb/gadget/function/f_fs.c
index 6bff6cb93789..ed2a6d5fcef7 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -934,31 +934,44 @@ static ssize_t __ffs_epfile_read_data(struct ffs_epfile 
*epfile,
return ret;
 }
 
-static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
+static struct ffs_ep *ffs_epfile_wait_ep(struct file *file)
 {
struct ffs_epfile *epfile = file->private_data;
-   struct usb_request *req;
struct ffs_ep *ep;
-   char *data = NULL;
-   ssize_t ret, data_len = -EINVAL;
-   int halt;
-
-   /* Are we still active? */
-   if (WARN_ON(epfile->ffs->state != FFS_ACTIVE))
-   return -ENODEV;
+   int ret;
 
/* Wait for endpoint to be enabled */
ep = epfile->ep;
if (!ep) {
if (file->f_flags & O_NONBLOCK)
-   return -EAGAIN;
+   return ERR_PTR(-EAGAIN);
 
ret = wait_event_interruptible(
epfile->ffs->wait, (ep = epfile->ep));
if (ret)
-   return -EINTR;
+   return ERR_PTR(-EINTR);
}
 
+   return ep;
+}
+
+static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
+{
+   struct ffs_epfile *epfile = file->private_data;
+   struct usb_request *req;
+   struct ffs_ep *ep;
+   char *data = NULL;
+   ssize_t ret, data_len = -EINVAL;
+   int halt;
+
+   /* Are we still active? */
+   if (WARN_ON(epfile->ffs->state != FFS_ACTIVE))
+   return -ENODEV;
+
+   ep = ffs_epfile_wait_ep(file);
+   if (IS_ERR(ep))
+   return PTR_ERR(ep);
+
/* Do we halt? */
halt = (!io_data->read == !epfile->in);
if (halt && epfile->isoc)
@@ -1280,16 +1293,9 @@ static long ffs_epfile_ioctl(struct file *file, unsigned 
code,
return -ENODEV;
 
/* Wait for endpoint to be enabled */
-   ep = epfile->ep;
-   if (!ep) {
-   if (file->f_flags & O_NONBLOCK)
-   return -EAGAIN;
-
-   ret = wait_event_interruptible(
-   epfile->ffs->wait, (ep = epfile->ep));
-   if (ret)
-   return -EINTR;
-   }
+   ep = ffs_epfile_wait_ep(file);
+   if (IS_ERR(ep))
+   return PTR_ERR(ep);
 
spin_lock_irq(&epfile->ffs->eps_lock);
 
-- 
2.43.0



[PATCH v4 3/4] usb: gadget: functionfs: Add DMABUF import interface

2024-01-17 Thread Paul Cercueil
This patch introduces three new ioctls. They all should be called on a
data endpoint (ie. not ep0). They are:

- FUNCTIONFS_DMABUF_ATTACH, which takes the file descriptor of a DMABUF
  object to attach to the endpoint.

- FUNCTIONFS_DMABUF_DETACH, which takes the file descriptor of the
  DMABUF to detach from the endpoint. Note that closing the endpoint's
  file descriptor will automatically detach all attached DMABUFs.

- FUNCTIONFS_DMABUF_TRANSFER, which requests a data transfer from / to
  the given DMABUF. Its argument is a structure that packs the DMABUF's
  file descriptor, the size in bytes to transfer (which should generally
  be set to the size of the DMABUF), and a 'flags' field which is unused
  for now.
  Before this ioctl can be used, the related DMABUF must be attached
  with FUNCTIONFS_DMABUF_ATTACH.

These three ioctls enable the FunctionFS code to transfer data between
the USB stack and a DMABUF object, which can be provided by a driver
from a completely different subsystem, in a zero-copy fashion.

Signed-off-by: Paul Cercueil 
Acked-by: Daniel Vetter 

---
v2:
- Make ffs_dma_resv_lock() static
- Add MODULE_IMPORT_NS(DMA_BUF);
- The attach/detach functions are now performed without locking the
  eps_lock spinlock. The transfer function starts with the spinlock
  unlocked, then locks it before allocating and queueing the USB
  transfer.

v3:
- Inline to_ffs_dma_fence() which was called only once.
- Simplify ffs_dma_resv_lock()
- Add comment explaining why we unref twice in ffs_dmabuf_detach()
- Document uapi struct usb_ffs_dmabuf_transfer_req and IOCTLs

v4:
- Protect the dmabufs list with a mutex
- Use incremental sequence number for the dma_fences
- Unref attachments and DMABUFs in workers
- Remove dead code in ffs_dma_resv_lock()
- Fix non-block actually blocking
- Use dma_fence_begin/end_signalling()
- Add comment about cache-management and dma_buf_unmap_attachment()
- Make sure dma_buf_map_attachment() is called with the dma-resv locked
---
 drivers/usb/gadget/function/f_fs.c  | 454 
 include/uapi/linux/usb/functionfs.h |  41 +++
 2 files changed, 495 insertions(+)

diff --git a/drivers/usb/gadget/function/f_fs.c 
b/drivers/usb/gadget/function/f_fs.c
index ed2a6d5fcef7..64dfd084c857 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -15,6 +15,9 @@
 /* #define VERBOSE_DEBUG */
 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -43,6 +46,8 @@
 
 #define FUNCTIONFS_MAGIC   0xa647361 /* Chosen by a honest dice roll ;) */
 
+MODULE_IMPORT_NS(DMA_BUF);
+
 /* Reference counter handling */
 static void ffs_data_get(struct ffs_data *ffs);
 static void ffs_data_put(struct ffs_data *ffs);
@@ -124,6 +129,23 @@ struct ffs_ep {
u8  num;
 };
 
+struct ffs_dmabuf_priv {
+   struct list_head entry;
+   struct kref ref;
+   struct ffs_data *ffs;
+   struct dma_buf_attachment *attach;
+   spinlock_t lock;
+   u64 context;
+};
+
+struct ffs_dma_fence {
+   struct dma_fence base;
+   struct ffs_dmabuf_priv *priv;
+   struct sg_table *sgt;
+   enum dma_data_direction dir;
+   struct work_struct work;
+};
+
 struct ffs_epfile {
/* Protects ep->ep and ep->req. */
struct mutexmutex;
@@ -197,6 +219,11 @@ struct ffs_epfile {
unsigned char   isoc;   /* P: ffs->eps_lock */
 
unsigned char   _pad;
+
+   /* Protects dmabufs */
+   struct mutexdmabufs_mutex;
+   struct list_headdmabufs; /* P: dmabufs_mutex */
+   atomic_tseqno;
 };
 
 struct ffs_buffer {
@@ -1271,10 +1298,47 @@ static ssize_t ffs_epfile_read_iter(struct kiocb 
*kiocb, struct iov_iter *to)
return res;
 }
 
+static void ffs_dmabuf_release(struct kref *ref)
+{
+   struct ffs_dmabuf_priv *priv = container_of(ref, struct 
ffs_dmabuf_priv, ref);
+   struct dma_buf_attachment *attach = priv->attach;
+   struct dma_buf *dmabuf = attach->dmabuf;
+
+   pr_debug("FFS DMABUF release\n");
+   dma_buf_detach(attach->dmabuf, attach);
+   dma_buf_put(dmabuf);
+   kfree(priv);
+}
+
+static void ffs_dmabuf_get(struct dma_buf_attachment *attach)
+{
+   struct ffs_dmabuf_priv *priv = attach->importer_priv;
+
+   kref_get(&priv->ref);
+}
+
+static void ffs_dmabuf_put(struct dma_buf_attachment *attach)
+{
+   struct ffs_dmabuf_priv *priv = attach->importer_priv;
+
+   kref_put(&priv->ref, ffs_dmabuf_release);
+}
+
 static int
 ffs_epfile_release(struct inode *inode, struct file *file)
 {
struct ffs_epfile *epfile = inode->i_private;
+   struct ffs_dmabuf_priv *priv, *tmp;
+
+   mutex_lock(&epfile->dmabufs_mutex);
+
+   /* Close all attached DMABUFs */
+   list_for_each_entry_safe(priv, tmp, &epfile->dmabufs, entry) {
+   list_del(&priv->entry);
+ 

[PATCH v4 4/4] Documentation: usb: Document FunctionFS DMABUF API

2024-01-17 Thread Paul Cercueil
Add documentation for the three ioctls used to attach or detach
externally-created DMABUFs, and to request transfers from/to previously
attached DMABUFs.

Signed-off-by: Paul Cercueil 

---
v3: New patch
---
 Documentation/usb/functionfs.rst | 36 
 1 file changed, 36 insertions(+)

diff --git a/Documentation/usb/functionfs.rst b/Documentation/usb/functionfs.rst
index a3054bea38f3..d05a775bc45b 100644
--- a/Documentation/usb/functionfs.rst
+++ b/Documentation/usb/functionfs.rst
@@ -2,6 +2,9 @@
 How FunctionFS works
 
 
+Overview
+
+
 From kernel point of view it is just a composite function with some
 unique behaviour.  It may be added to an USB configuration only after
 the user space driver has registered by writing descriptors and
@@ -66,3 +69,36 @@ have been written to their ep0's.
 
 Conversely, the gadget is unregistered after the first USB function
 closes its endpoints.
+
+DMABUF interface
+
+
+FunctionFS additionally supports a DMABUF based interface, where the
+userspace can attach DMABUF objects (externally created) to an endpoint,
+and subsequently use them for data transfers.
+
+A userspace application can then use this interface to share DMABUF
+objects between several interfaces, allowing it to transfer data in a
+zero-copy fashion, for instance between IIO and the USB stack.
+
+As part of this interface, three new IOCTLs have been added. These three
+IOCTLs have to be performed on a data endpoint (ie. not ep0). They are:
+
+  ``FUNCTIONFS_DMABUF_ATTACH(int)``
+Attach the DMABUF object, identified by its file descriptor, to the
+data endpoint. Returns zero on success, and a negative errno value
+on error.
+
+  ``FUNCTIONFS_DMABUF_DETACH(int)``
+Detach the given DMABUF object, identified by its file descriptor,
+from the data endpoint. Returns zero on success, and a negative
+errno value on error. Note that closing the endpoint's file
+descriptor will automatically detach all attached DMABUFs.
+
+  ``FUNCTIONFS_DMABUF_TRANSFER(struct usb_ffs_dmabuf_transfer_req *)``
+Enqueue the previously attached DMABUF to the transfer queue.
+The argument is a structure that packs the DMABUF's file descriptor,
+the size in bytes to transfer (which should generally correspond to
+the size of the DMABUF), and a 'flags' field which is unused
+for now. Returns zero on success, and a negative errno value on
+error.
-- 
2.43.0



Re: [PATCH v3 2/2] drm/imx/dcss: have all init functions use devres

2024-01-17 Thread Laurentiu Palcu
Hi Philipp,

Several minor comments below.

On Thu, Jan 11, 2024 at 11:13:47AM +0100, Philipp Stanner wrote:
> dcss currently allocates and ioremaps quite a few resources in its probe
> function's call graph. Devres now provides convenient functions which
> perform the same task but do the cleanup automatically.
> 
> Port all memory allocations and ioremap() calls to the devres
> counterparts.
> 
> Signed-off-by: Philipp Stanner 
> ---
>  drivers/gpu/drm/imx/dcss/dcss-blkctl.c | 14 +++---
>  drivers/gpu/drm/imx/dcss/dcss-ctxld.c  | 15 ---
>  drivers/gpu/drm/imx/dcss/dcss-dev.c| 12 ++--
>  drivers/gpu/drm/imx/dcss/dcss-dev.h|  1 -
>  drivers/gpu/drm/imx/dcss/dcss-dpr.c| 25 ++---
>  drivers/gpu/drm/imx/dcss/dcss-drv.c| 12 +++-
>  drivers/gpu/drm/imx/dcss/dcss-dtg.c| 23 ---
>  drivers/gpu/drm/imx/dcss/dcss-scaler.c | 24 +---
>  drivers/gpu/drm/imx/dcss/dcss-ss.c | 11 +++
>  9 files changed, 30 insertions(+), 107 deletions(-)
> 
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-blkctl.c 
> b/drivers/gpu/drm/imx/dcss/dcss-blkctl.c
> index c9b54bb2692d..58e12ec65f80 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-blkctl.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-blkctl.c
> @@ -41,15 +41,15 @@ void dcss_blkctl_cfg(struct dcss_blkctl *blkctl)
>  int dcss_blkctl_init(struct dcss_dev *dcss, unsigned long blkctl_base)
>  {
>   struct dcss_blkctl *blkctl;
> + struct device *dev = dcss->dev;
>  
> - blkctl = kzalloc(sizeof(*blkctl), GFP_KERNEL);
> + blkctl = devm_kzalloc(dev, sizeof(*blkctl), GFP_KERNEL);
>   if (!blkctl)
>   return -ENOMEM;
>  
> - blkctl->base_reg = ioremap(blkctl_base, SZ_4K);
> + blkctl->base_reg = devm_ioremap(dev, blkctl_base, SZ_4K);
>   if (!blkctl->base_reg) {
>   dev_err(dcss->dev, "unable to remap BLK CTRL base\n");
> - kfree(blkctl);
>   return -ENOMEM;
>   }
>  
> @@ -60,11 +60,3 @@ int dcss_blkctl_init(struct dcss_dev *dcss, unsigned long 
> blkctl_base)
>  
>   return 0;
>  }
> -
> -void dcss_blkctl_exit(struct dcss_blkctl *blkctl)
> -{
> - if (blkctl->base_reg)
> - iounmap(blkctl->base_reg);
> -
> - kfree(blkctl);
> -}
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-ctxld.c 
> b/drivers/gpu/drm/imx/dcss/dcss-ctxld.c
> index 3a84cb3209c4..444511d0f382 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-ctxld.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-ctxld.c
> @@ -199,10 +199,11 @@ static int dcss_ctxld_alloc_ctx(struct dcss_ctxld 
> *ctxld)
>  
>  int dcss_ctxld_init(struct dcss_dev *dcss, unsigned long ctxld_base)
>  {
> + struct device *dev = dcss->dev;
>   struct dcss_ctxld *ctxld;
>   int ret;
>  
> - ctxld = kzalloc(sizeof(*ctxld), GFP_KERNEL);
> + ctxld = devm_kzalloc(dev, sizeof(*ctxld), GFP_KERNEL);
>   if (!ctxld)
>   return -ENOMEM;
>  
> @@ -217,7 +218,7 @@ int dcss_ctxld_init(struct dcss_dev *dcss, unsigned long 
> ctxld_base)
>   goto err;
>   }
>  
> - ctxld->ctxld_reg = ioremap(ctxld_base, SZ_4K);
> + ctxld->ctxld_reg = devm_ioremap(dev, ctxld_base, SZ_4K);
>   if (!ctxld->ctxld_reg) {
>   dev_err(dcss->dev, "ctxld: unable to remap ctxld base\n");
>   ret = -ENOMEM;
> @@ -226,18 +227,14 @@ int dcss_ctxld_init(struct dcss_dev *dcss, unsigned 
> long ctxld_base)
>  
>   ret = dcss_ctxld_irq_config(ctxld, to_platform_device(dcss->dev));
>   if (ret)
> - goto err_irq;
> + goto err;
>  
>   dcss_ctxld_hw_cfg(ctxld);
>  
>   return 0;
>  
> -err_irq:
> - iounmap(ctxld->ctxld_reg);
> -
>  err:
>   dcss_ctxld_free_ctx(ctxld);
> - kfree(ctxld);
>  
>   return ret;
>  }
> @@ -246,11 +243,7 @@ void dcss_ctxld_exit(struct dcss_ctxld *ctxld)
>  {
>   free_irq(ctxld->irq, ctxld);
>  
> - if (ctxld->ctxld_reg)
> - iounmap(ctxld->ctxld_reg);
> -
>   dcss_ctxld_free_ctx(ctxld);
> - kfree(ctxld);
>  }
>  
>  static int dcss_ctxld_enable_locked(struct dcss_ctxld *ctxld)
> diff --git a/drivers/gpu/drm/imx/dcss/dcss-dev.c 
> b/drivers/gpu/drm/imx/dcss/dcss-dev.c
> index d448bf1c205e..597e9b7bd4bf 100644
> --- a/drivers/gpu/drm/imx/dcss/dcss-dev.c
> +++ b/drivers/gpu/drm/imx/dcss/dcss-dev.c
> @@ -109,8 +109,6 @@ static int dcss_submodules_init(struct dcss_dev *dcss)
>   dcss_ctxld_exit(dcss->ctxld);
>  
>  ctxld_err:
> - dcss_blkctl_exit(dcss->blkctl);
> -
>   dcss_clocks_disable(dcss);
>  
>   return ret;
> @@ -124,7 +122,6 @@ static void dcss_submodules_stop(struct dcss_dev *dcss)
>   dcss_ss_exit(dcss->ss);
>   dcss_dtg_exit(dcss->dtg);
>   dcss_ctxld_exit(dcss->ctxld);
> - dcss_blkctl_exit(dcss->blkctl);
>   dcss_clocks_disable(dcss);
>  }
>  
> @@ -190,7 +187,7 @@ struct dcss_dev *dcss_dev_create(struct device *dev, bool 
> hdmi_output)
>   return ERR_PTR(-EBUSY);

Re: [PATCH 3/5] drm/ttm: replace busy placement with flags v6

2024-01-17 Thread Thomas Hellström



On 1/17/24 11:47, Thomas Hellström wrote:

Hi, Christian

Xe changes look good. Will send the series to xe ci to check for 
regressions.


Hmm, there are some checkpatch warnings about author / SOB email mismatch,

But worserthere are some regressions in the dma-buf ktest (it tests 
evicting of a dynamic dma-buf),


https://patchwork.freedesktop.org/series/128873/

I'll take a look later today or tomorrow.

/Thomas





/Thomas


On 1/12/24 13:51, Christian König wrote:

From: Somalapuram Amaranath 

Instead of a list of separate busy placement add flags which indicate
that a placement should only be used when there is room or if we need to
evict.

v2: add missing TTM_PL_FLAG_IDLE for i915
v3: fix auto build test ERROR on drm-tip/drm-tip
v4: fix some typos pointed out by checkpatch
v5: cleanup some rebase problems with VMWGFX
v6: implement some missing VMWGFX functionality pointed out by Zack,
 rename the flags as suggested by Michel, rebase on drm-tip and
 adjust XE as well

Signed-off-by: Christian König 
Signed-off-by: Somalapuram Amaranath 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c |  6 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    | 11 +---
  drivers/gpu/drm/drm_gem_vram_helper.c  |  2 -
  drivers/gpu/drm/i915/gem/i915_gem_ttm.c    | 37 +--
  drivers/gpu/drm/loongson/lsdc_ttm.c    |  2 -
  drivers/gpu/drm/nouveau/nouveau_bo.c   | 59 +++--
  drivers/gpu/drm/nouveau/nouveau_bo.h   |  1 -
  drivers/gpu/drm/qxl/qxl_object.c   |  2 -
  drivers/gpu/drm/qxl/qxl_ttm.c  |  2 -
  drivers/gpu/drm/radeon/radeon_object.c |  2 -
  drivers/gpu/drm/radeon/radeon_ttm.c    |  8 +--
  drivers/gpu/drm/radeon/radeon_uvd.c    |  1 -
  drivers/gpu/drm/ttm/ttm_bo.c   | 21 ---
  drivers/gpu/drm/ttm/ttm_resource.c | 73 +-
  drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 33 +++---
  drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c |  4 --
  drivers/gpu/drm/xe/xe_bo.c | 33 +-
  include/drm/ttm/ttm_placement.h    | 10 +--
  include/drm/ttm/ttm_resource.h |  8 +--
  19 files changed, 118 insertions(+), 197 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c

index 425cebcc5cbf..b671b0665492 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -220,9 +220,6 @@ void amdgpu_bo_placement_from_domain(struct 
amdgpu_bo *abo, u32 domain)

    placement->num_placement = c;
  placement->placement = places;
-
-    placement->num_busy_placement = c;
-    placement->busy_placement = places;
  }
    /**
@@ -1397,8 +1394,7 @@ vm_fault_t 
amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)

  AMDGPU_GEM_DOMAIN_GTT);
    /* Avoid costly evictions; only set GTT as a busy placement */
-    abo->placement.num_busy_placement = 1;
-    abo->placement.busy_placement = &abo->placements[1];
+    abo->placements[0].flags |= TTM_PL_FLAG_DESIRED;
    r = ttm_bo_validate(bo, &abo->placement, &ctx);
  if (unlikely(r == -EBUSY || r == -ERESTARTSYS))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c

index 75c9fd2c6c2a..8722beba494e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -102,23 +102,19 @@ static void amdgpu_evict_flags(struct 
ttm_buffer_object *bo,

  /* Don't handle scatter gather BOs */
  if (bo->type == ttm_bo_type_sg) {
  placement->num_placement = 0;
-    placement->num_busy_placement = 0;
  return;
  }
    /* Object isn't an AMDGPU object so ignore */
  if (!amdgpu_bo_is_amdgpu_bo(bo)) {
  placement->placement = &placements;
-    placement->busy_placement = &placements;
  placement->num_placement = 1;
-    placement->num_busy_placement = 1;
  return;
  }
    abo = ttm_to_amdgpu_bo(bo);
  if (abo->flags & AMDGPU_GEM_CREATE_DISCARDABLE) {
  placement->num_placement = 0;
-    placement->num_busy_placement = 0;
  return;
  }
  @@ -128,13 +124,13 @@ static void amdgpu_evict_flags(struct 
ttm_buffer_object *bo,

  case AMDGPU_PL_OA:
  case AMDGPU_PL_DOORBELL:
  placement->num_placement = 0;
-    placement->num_busy_placement = 0;
  return;
    case TTM_PL_VRAM:
  if (!adev->mman.buffer_funcs_enabled) {
  /* Move to system memory */
  amdgpu_bo_placement_from_domain(abo, 
AMDGPU_GEM_DOMAIN_CPU);

+
  } else if (!amdgpu_gmc_vram_full_visible(&adev->gmc) &&
 !(abo->flags & 
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) &&

 amdgpu_bo_in_cpu_visible_vram(abo)) {
@@ -149,8 +145,7 @@ static void amdgpu_evict_flags(struct 
ttm_buffer_object *bo,

  AMDGPU_GEM_DOMAIN_CPU);
  abo->placem

[PATCH 3/8] firmware/sysfb: Set firmware-framebuffer parent device

2024-01-17 Thread Thomas Zimmermann
Set the firmware framebuffer's parent device, which usually is the
graphics hardware's physical device. Integrates the framebuffer in
the Linux device hierarchy and lets Linux handle dependencies among
devices. For example, the graphics hardware won't be suspended while
the firmware device is still active.

Signed-off-by: Thomas Zimmermann 
---
 drivers/firmware/sysfb.c  | 11 ++-
 drivers/firmware/sysfb_simplefb.c |  5 -
 include/linux/sysfb.h |  3 ++-
 3 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c
index 19706bd2642a..8a42da3f67a9 100644
--- a/drivers/firmware/sysfb.c
+++ b/drivers/firmware/sysfb.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -72,6 +73,8 @@ EXPORT_SYMBOL_GPL(sysfb_disable);
 static __init int sysfb_init(void)
 {
const struct screen_info *si = &screen_info;
+   struct device *parent = NULL;
+   struct pci_dev *pparent;
struct simplefb_platform_data mode;
const char *name;
bool compatible;
@@ -83,10 +86,14 @@ static __init int sysfb_init(void)
 
sysfb_apply_efi_quirks();
 
+   pparent = screen_info_pci_dev(si);
+   if (pparent)
+   parent = &pparent->dev;
+
/* try to create a simple-framebuffer device */
compatible = sysfb_parse_mode(si, &mode);
if (compatible) {
-   pd = sysfb_create_simplefb(si, &mode);
+   pd = sysfb_create_simplefb(si, &mode, parent);
if (!IS_ERR(pd))
goto unlock_mutex;
}
@@ -109,6 +116,8 @@ static __init int sysfb_init(void)
goto unlock_mutex;
}
 
+   pd->dev.parent = parent;
+
sysfb_set_efifb_fwnode(pd);
 
ret = platform_device_add_data(pd, si, sizeof(*si));
diff --git a/drivers/firmware/sysfb_simplefb.c 
b/drivers/firmware/sysfb_simplefb.c
index 74363ed7501f..75a186bf8f8e 100644
--- a/drivers/firmware/sysfb_simplefb.c
+++ b/drivers/firmware/sysfb_simplefb.c
@@ -91,7 +91,8 @@ __init bool sysfb_parse_mode(const struct screen_info *si,
 }
 
 __init struct platform_device *sysfb_create_simplefb(const struct screen_info 
*si,
-const struct 
simplefb_platform_data *mode)
+const struct 
simplefb_platform_data *mode,
+struct device *parent)
 {
struct platform_device *pd;
struct resource res;
@@ -143,6 +144,8 @@ __init struct platform_device *sysfb_create_simplefb(const 
struct screen_info *s
if (!pd)
return ERR_PTR(-ENOMEM);
 
+   pd->dev.parent = parent;
+
sysfb_set_efifb_fwnode(pd);
 
ret = platform_device_add_resources(pd, &res, 1);
diff --git a/include/linux/sysfb.h b/include/linux/sysfb.h
index 19cb803dd5ec..6ee3ade3f8b0 100644
--- a/include/linux/sysfb.h
+++ b/include/linux/sysfb.h
@@ -91,7 +91,8 @@ static inline void sysfb_set_efifb_fwnode(struct 
platform_device *pd)
 bool sysfb_parse_mode(const struct screen_info *si,
  struct simplefb_platform_data *mode);
 struct platform_device *sysfb_create_simplefb(const struct screen_info *si,
- const struct 
simplefb_platform_data *mode);
+ const struct 
simplefb_platform_data *mode,
+ struct device *parent);
 
 #else /* CONFIG_SYSFB_SIMPLE */
 
-- 
2.43.0



[PATCH 0/8] firmware/sysfb: Track parent device for screen_info

2024-01-17 Thread Thomas Zimmermann
Detect the firmware framebuffer's parent device from the global
screen_info state and set up the framebuffer's device accordingly.
Remove the equivalent functionality from efifb. Other drivers for
firmware framebuffers, such as simpledrm or vesafb, now add these
new features.

Patches 1 and 2 provide a set of helper functions to avoid parsing
the screen_info values manually. Decoding screen_info is fragile and
many drivers get it wrong. We should later adopt these helpers in
existing drivers, such as efifb, vesafb, as well.

Patches 3 and 4 set the firmware framebuffer's parent device. There
is code in efifb to do something similar for power management. That
is now obsolete and being cleaned up. Setting the parent device makes
Linux track the power management correctly.

Patches 5 and 6 track the parent device's enable state. We don't
create framebuffer devices if the underlying hardware device has been
disabled. Remove the functionality from efifb.

Patches 7 and 8 track the parent device's PCI BAR location. It can
happen on aarch64 that the firmware framebuffer moves its location
during the kernel's boot. We now fix up the screen_info state to
point to the correct location. Again remove such functionality from
efifb.

Thomas Zimmermann (8):
  video: Add helpers for decoding screen_info
  video: Provide screen_info_get_pci_dev() to find screen_info's PCI
device
  firmware/sysfb: Set firmware-framebuffer parent device
  fbdev/efifb: Remove PM for parent device
  firmware/sysfb: Create firmware device only for enabled PCI devices
  fbdev/efifb: Do not track parent device status
  firmware/sysfb: Update screen_info for relocated EFI framebuffers
  fbdev/efifb: Remove framebuffer relocation tracking

 drivers/firmware/Kconfig|   1 +
 drivers/firmware/sysfb.c|  37 ++-
 drivers/firmware/sysfb_simplefb.c   |   5 +-
 drivers/video/Kconfig   |   4 +
 drivers/video/Makefile  |   4 +
 drivers/video/fbdev/efifb.c |  97 +-
 drivers/video/screen_info_generic.c | 148 
 drivers/video/screen_info_pci.c | 142 ++
 include/linux/screen_info.h | 126 +++
 include/linux/sysfb.h   |   3 +-
 10 files changed, 472 insertions(+), 95 deletions(-)
 create mode 100644 drivers/video/screen_info_generic.c
 create mode 100644 drivers/video/screen_info_pci.c

-- 
2.43.0



[PATCH 1/8] video: Add helpers for decoding screen_info

2024-01-17 Thread Thomas Zimmermann
The plain values as stored in struct screen_info need to be decoded
before being used. Add helpers that decode the type of video output
and the framebuffer I/O aperture.

Old or non-x86 systems may not set the type of video directly, but
only indicate the presence by storing 0x01 in orig_video_isVGA. The
decoding logic in screen_info_video_type() takes this into account.
It then follows similar code in vgacon's vgacon_startup() to detect
the video type from the given values.

A call to screen_info_resources() returns all known resources of the
given screen_info. The resources' values have been taken from existing
code in vgacon and vga16fb. These drivers can later be converted to
use the new interfaces.

Signed-off-by: Thomas Zimmermann 
---
 drivers/firmware/Kconfig|   1 +
 drivers/video/Kconfig   |   4 +
 drivers/video/Makefile  |   3 +
 drivers/video/screen_info_generic.c | 148 
 include/linux/screen_info.h | 100 +++
 5 files changed, 256 insertions(+)
 create mode 100644 drivers/video/screen_info_generic.c

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 4a98a859d44d..deba323178cc 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -191,6 +191,7 @@ config MTK_ADSP_IPC
 config SYSFB
bool
select BOOT_VESA_SUPPORT
+   select SCREEN_INFO
 
 config SYSFB_SIMPLEFB
bool "Mark VGA/VBE/EFI FB as generic system framebuffer"
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index b694d7669d32..1eb755a94940 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -11,6 +11,10 @@ config APERTURE_HELPERS
  Support tracking and hand-over of aperture ownership. Required
  by graphics drivers for firmware-provided framebuffers.
 
+config SCREEN_INFO
+   bool
+   default n
+
 config STI_CORE
bool
depends on PARISC
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 6bbc03950899..b929b664d52c 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -1,12 +1,15 @@
 # SPDX-License-Identifier: GPL-2.0
 
 obj-$(CONFIG_APERTURE_HELPERS)+= aperture.o
+obj-$(CONFIG_SCREEN_INFO) += screen_info.o
 obj-$(CONFIG_STI_CORE)+= sticore.o
 obj-$(CONFIG_VGASTATE)+= vgastate.o
 obj-$(CONFIG_VIDEO_CMDLINE)   += cmdline.o
 obj-$(CONFIG_VIDEO_NOMODESET) += nomodeset.o
 obj-$(CONFIG_HDMI)+= hdmi.o
 
+screen_info-y:= screen_info_generic.o
+
 obj-$(CONFIG_VT) += console/
 obj-$(CONFIG_FB_STI) += console/
 obj-$(CONFIG_LOGO)   += logo/
diff --git a/drivers/video/screen_info_generic.c 
b/drivers/video/screen_info_generic.c
new file mode 100644
index ..4be26941b2d9
--- /dev/null
+++ b/drivers/video/screen_info_generic.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+#include 
+#include 
+
+static void resource_init_named(struct resource *r,
+   resource_size_t start, resource_size_t size,
+   const char *name, unsigned int flags)
+{
+   memset(r, 0, sizeof(*r));
+
+   r->start = start;
+   r->end = start + size - 1;
+   r->name = name;
+   r->flags = flags;
+}
+
+static void resource_init_io_named(struct resource *r,
+  resource_size_t start, resource_size_t size,
+  const char *name)
+{
+   resource_init_named(r, start, size, name, IORESOURCE_IO);
+}
+
+static void resource_init_mem_named(struct resource *r,
+  resource_size_t start, resource_size_t size,
+  const char *name)
+{
+   resource_init_named(r, start, size, name, IORESOURCE_MEM);
+}
+
+static inline bool __screen_info_has_ega_gfx(unsigned int mode)
+{
+   switch (mode) {
+   case 0x0d:  /* 320x200-4 */
+   case 0x0e:  /* 640x200-4 */
+   case 0x0f:  /* 640x350-1 */
+   case 0x10:  /* 640x350-4 */
+   return true;
+   default:
+   return false;
+   }
+}
+
+static inline bool __screen_info_has_vga_gfx(unsigned int mode)
+{
+   switch (mode) {
+   case 0x10:  /* 640x480-1 */
+   case 0x12:  /* 640x480-4 */
+   case 0x13:  /* 320-200-8 */
+   case 0x6a:  /* 800x600-4 (VESA) */
+   return true;
+   default:
+   return __screen_info_has_ega_gfx(mode);
+   }
+}
+
+/**
+ * screen_info_resources() - Get resources from screen_info structure
+ * @si: the screen_info
+ * @r: pointer to an array of resource structures
+ * @num: number of elements in @r:
+ *
+ * Returns:
+ * The number of resources stored in @r on success, or a negative errno code 
otherwise.
+ *
+ * A call to screen_info_resources() returns the resources consumed by the
+ * screen_info's de

[PATCH 4/8] fbdev/efifb: Remove PM for parent device

2024-01-17 Thread Thomas Zimmermann
The EFI device has the correct parent device set. This allows Linux
to handle the power management internally. Hence, remove the manual
PM management for the parent device from efifb.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/efifb.c | 16 +++-
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index 10fc14ad5d12..e66ef35fa6b6 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -17,7 +17,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include  /* For drm_get_panel_orientation_quirk */
@@ -258,9 +257,6 @@ static void efifb_destroy(struct fb_info *info)
 {
struct efifb_par *par = info->par;
 
-   if (efifb_pci_dev)
-   pm_runtime_put(&efifb_pci_dev->dev);
-
if (info->screen_base) {
if (mem_flags & (EFI_MEMORY_UC | EFI_MEMORY_WC))
iounmap(info->screen_base);
@@ -598,26 +594,20 @@ static int efifb_probe(struct platform_device *dev)
goto err_groups;
}
 
-   if (efifb_pci_dev)
-   WARN_ON(pm_runtime_get_sync(&efifb_pci_dev->dev) < 0);
-
err = devm_aperture_acquire_for_platform_device(dev, par->base, 
par->size);
if (err) {
pr_err("efifb: cannot acquire aperture\n");
-   goto err_put_rpm_ref;
+   goto err_fb_dealloc_cmap;
}
err = register_framebuffer(info);
if (err < 0) {
pr_err("efifb: cannot register framebuffer\n");
-   goto err_put_rpm_ref;
+   goto err_fb_dealloc_cmap;
}
fb_info(info, "%s frame buffer device\n", info->fix.id);
return 0;
 
-err_put_rpm_ref:
-   if (efifb_pci_dev)
-   pm_runtime_put(&efifb_pci_dev->dev);
-
+err_fb_dealloc_cmap:
fb_dealloc_cmap(&info->cmap);
 err_groups:
sysfs_remove_groups(&dev->dev.kobj, efifb_groups);
-- 
2.43.0



[PATCH 7/8] firmware/sysfb: Update screen_info for relocated EFI framebuffers

2024-01-17 Thread Thomas Zimmermann
On ARM PCI systems, the PCI hierarchy might be reconfigured during
boot and the firmware framebuffer might move as a result of that.
The values in screen_info will then be invalid.

Work around this problem by tracking the framebuffer's initial
location before it get relocated; then fix the screen_info state
between reloaction and creating the firmware framebuffer's device.

This functionality has been lifted from efifb. See the commit message
of commit 55d728a40d36 ("efi/fb: Avoid reconfiguration of BAR that
covers the framebuffer") for more information.

Signed-off-by: Thomas Zimmermann 
---
 drivers/firmware/sysfb.c|  2 +
 drivers/video/screen_info_pci.c | 88 +
 include/linux/screen_info.h | 16 ++
 3 files changed, 106 insertions(+)

diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c
index 48a550bd1a93..5791f9dc47df 100644
--- a/drivers/firmware/sysfb.c
+++ b/drivers/firmware/sysfb.c
@@ -101,6 +101,8 @@ static __init int sysfb_init(void)
bool compatible;
int ret = 0;
 
+   screen_info_apply_fixups();
+
mutex_lock(&disable_lock);
if (disabled)
goto unlock_mutex;
diff --git a/drivers/video/screen_info_pci.c b/drivers/video/screen_info_pci.c
index 16fe4afa3377..a546681b2d15 100644
--- a/drivers/video/screen_info_pci.c
+++ b/drivers/video/screen_info_pci.c
@@ -1,7 +1,95 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include 
+#include 
 #include 
+#include 
+
+static struct pci_dev *screen_info_lfb_pdev;
+static size_t screen_info_lfb_bar;
+static resource_size_t screen_info_lfb_offset;
+static struct resource screen_info_lfb_res = DEFINE_RES_MEM(0, 0);
+
+static bool __screen_info_relocation_is_valid(const struct screen_info *si, 
struct resource *pr)
+{
+   u64 size = __screen_info_lfb_size(si, screen_info_video_type(si));
+
+   if (screen_info_lfb_offset > resource_size(pr))
+   return false;
+   if (size > resource_size(pr))
+   return false;
+   if (resource_size(pr) - size < screen_info_lfb_offset)
+   return false;
+
+   return true;
+}
+
+void screen_info_apply_fixups(void)
+{
+   struct screen_info *si = &screen_info;
+
+   if (screen_info_lfb_pdev) {
+   struct resource *pr = 
&screen_info_lfb_pdev->resource[screen_info_lfb_bar];
+
+   if (pr->start != screen_info_lfb_res.start) {
+   if (__screen_info_relocation_is_valid(si, pr)) {
+   /*
+* Only update base if we have an actual
+* relocation to a valid I/O range.
+*/
+   __screen_info_set_lfb_base(si, pr->start + 
screen_info_lfb_offset);
+   pr_info("Relocating firmware framebuffer to 
offset %pa[d] within %pr\n",
+   &screen_info_lfb_offset, pr);
+   } else {
+   pr_warn("Invalid relocating, disabling firmware 
framebuffer\n");
+   }
+   }
+   }
+}
+
+static void screen_info_fixup_lfb(struct pci_dev *pdev)
+{
+   unsigned int type;
+   struct resource res[SCREEN_INFO_MAX_RESOURCES];
+   size_t i, numres;
+   int ret;
+   const struct screen_info *si = &screen_info;
+
+   if (screen_info_lfb_pdev)
+   return; // already found
+
+   type = screen_info_video_type(si);
+   if (type != VIDEO_TYPE_EFI)
+   return; // only applies to EFI
+
+   ret = screen_info_resources(si, res, ARRAY_SIZE(res));
+   if (ret < 0)
+   return;
+   numres = ret;
+
+   for (i = 0; i < numres; ++i) {
+   struct resource *r = &res[i];
+   const struct resource *pr;
+
+   if (!(r->flags & IORESOURCE_MEM))
+   continue;
+   pr = pci_find_resource(pdev, r);
+   if (!pr)
+   continue;
+
+   /*
+* We've found a PCI device with the framebuffer
+* resource. Store away the parameters to track
+* relocation of the framebuffer aperture.
+*/
+   screen_info_lfb_pdev = pdev;
+   screen_info_lfb_bar = pr - pdev->resource;
+   screen_info_lfb_offset = r->start - pr->start;
+   memcpy(&screen_info_lfb_res, r, sizeof(screen_info_lfb_res));
+   }
+}
+DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY, 
16,
+  screen_info_fixup_lfb);
 
 static struct pci_dev *__screen_info_pci_dev(struct resource *res)
 {
diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
index 746645b8ee83..80b348137492 100644
--- a/include/linux/screen_info.h
+++ b/include/linux/screen_info.h
@@ -4,6 +4,8 @@
 
 #include 
 
+#include

[PATCH 2/8] video: Provide screen_info_get_pci_dev() to find screen_info's PCI device

2024-01-17 Thread Thomas Zimmermann
Add screen_info_get_pci_dev() to find the PCI device of an instance
of screen_info. Does nothing on systems without PCI bus.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/Makefile  |  1 +
 drivers/video/screen_info_pci.c | 54 +
 include/linux/screen_info.h | 10 ++
 3 files changed, 65 insertions(+)
 create mode 100644 drivers/video/screen_info_pci.c

diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index b929b664d52c..6bbf87c1b579 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_VIDEO_NOMODESET) += nomodeset.o
 obj-$(CONFIG_HDMI)+= hdmi.o
 
 screen_info-y:= screen_info_generic.o
+screen_info-$(CONFIG_PCI) += screen_info_pci.o
 
 obj-$(CONFIG_VT) += console/
 obj-$(CONFIG_FB_STI) += console/
diff --git a/drivers/video/screen_info_pci.c b/drivers/video/screen_info_pci.c
new file mode 100644
index ..16fe4afa3377
--- /dev/null
+++ b/drivers/video/screen_info_pci.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+
+static struct pci_dev *__screen_info_pci_dev(struct resource *res)
+{
+   struct pci_dev *pdev;
+
+   if (!(res->flags & IORESOURCE_MEM))
+   return NULL;
+
+   for_each_pci_dev(pdev) {
+   const struct resource *r;
+
+   if ((pdev->class >> 16) != PCI_BASE_CLASS_DISPLAY)
+   continue;
+
+   r = pci_find_resource(pdev, res);
+   if (r)
+   return pdev;
+   }
+
+   return NULL;
+}
+
+/**
+ * screen_info_pci_dev() - Return PCI parent device that contains 
screen_info's framebuffer
+ * @si: the screen_info
+ *
+ * Returns:
+ * The screen_info's parent device on success, or NULL otherwise.
+ */
+struct pci_dev *screen_info_pci_dev(const struct screen_info *si)
+{
+   struct resource res[SCREEN_INFO_MAX_RESOURCES];
+   size_t i, numres;
+   int ret;
+
+   ret = screen_info_resources(si, res, ARRAY_SIZE(res));
+   if (ret < 0)
+   return ERR_PTR(ret);
+   numres = ret;
+
+   for (i = 0; i < numres; ++i) {
+   struct pci_dev *pdev = __screen_info_pci_dev(&res[i]);
+
+   if (pdev)
+   return pdev;
+   }
+
+   return NULL;
+}
+EXPORT_SYMBOL(screen_info_pci_dev);
diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
index d4d45395df19..746645b8ee83 100644
--- a/include/linux/screen_info.h
+++ b/include/linux/screen_info.h
@@ -9,6 +9,7 @@
  */
 #define SCREEN_INFO_MAX_RESOURCES  3
 
+struct pci_dev;
 struct resource;
 
 static inline bool __screen_info_has_lfb(unsigned int type)
@@ -104,6 +105,15 @@ static inline unsigned int screen_info_video_type(const 
struct screen_info *si)
 
 int screen_info_resources(const struct screen_info *si, struct resource *r, 
size_t num);
 
+#if defined(CONFIG_PCI)
+struct pci_dev *screen_info_pci_dev(const struct screen_info *si);
+#else
+static inline struct pci_dev *screen_info_pci_dev(const struct screen_info *si)
+{
+   return NULL;
+}
+#endif
+
 extern struct screen_info screen_info;
 
 #endif /* _SCREEN_INFO_H */
-- 
2.43.0



[PATCH 6/8] fbdev/efifb: Do not track parent device status

2024-01-17 Thread Thomas Zimmermann
There will be no EFI framebuffer device for disabled parent devices
and thus we never probe efifb in that case. Hence remove the tracking
code from efifb.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/efifb.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index e66ef35fa6b6..f76b7ae00751 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -348,8 +348,6 @@ static struct attribute *efifb_attrs[] = {
 };
 ATTRIBUTE_GROUPS(efifb);
 
-static bool pci_dev_disabled;  /* FB base matches BAR of a disabled device */
-
 static struct resource *bar_resource;
 static u64 bar_offset;
 
@@ -377,7 +375,7 @@ static int efifb_probe(struct platform_device *dev)
if (!si)
return -ENOMEM;
 
-   if (si->orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
+   if (si->orig_video_isVGA != VIDEO_TYPE_EFI)
return -ENODEV;
 
if (fb_get_options("efifb", &option))
@@ -653,7 +651,6 @@ static void record_efifb_bar_resource(struct pci_dev *dev, 
int idx, u64 offset)
 
pci_read_config_word(dev, PCI_COMMAND, &word);
if (!(word & PCI_COMMAND_MEMORY)) {
-   pci_dev_disabled = true;
dev_err(&dev->dev,
"BAR %d: assigned to efifb but device is disabled!\n",
idx);
-- 
2.43.0



[PATCH 5/8] firmware/sysfb: Create firmware device only for enabled PCI devices

2024-01-17 Thread Thomas Zimmermann
Test if the firmware framebuffer's parent PCI device, if any, has
been enabled. If not, the firmware framebuffer is most likely not
working. Hence, do not create a device for the firmware framebuffer
on disabled PCI devices.

So far, efifb tracked the status of the PCI parent device internally
and did not bind if it was disabled. This patch implements the
functionality for all firmware framebuffers.

Signed-off-by: Thomas Zimmermann 
---
 drivers/firmware/sysfb.c | 26 +-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c
index 8a42da3f67a9..48a550bd1a93 100644
--- a/drivers/firmware/sysfb.c
+++ b/drivers/firmware/sysfb.c
@@ -70,6 +70,27 @@ void sysfb_disable(void)
 }
 EXPORT_SYMBOL_GPL(sysfb_disable);
 
+static __init bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
+{
+#if defined(CONFIG_PCI)
+   /*
+* TODO: Try to integrate this code into the PCI subsystem
+*/
+   int ret;
+   u16 command;
+
+   ret = pci_read_config_word(pdev, PCI_COMMAND, &command);
+   if (ret != PCIBIOS_SUCCESSFUL)
+   return false;
+   if (!(command & PCI_COMMAND_MEMORY))
+   return false;
+   return true;
+#else
+   // Getting here without PCI support is probably a bug.
+   return false;
+#endif
+}
+
 static __init int sysfb_init(void)
 {
const struct screen_info *si = &screen_info;
@@ -87,8 +108,11 @@ static __init int sysfb_init(void)
sysfb_apply_efi_quirks();
 
pparent = screen_info_pci_dev(si);
-   if (pparent)
+   if (pparent) {
+   if (!sysfb_pci_dev_is_enabled(pparent))
+   goto unlock_mutex;
parent = &pparent->dev;
+   }
 
/* try to create a simple-framebuffer device */
compatible = sysfb_parse_mode(si, &mode);
-- 
2.43.0



[PATCH 8/8] fbdev/efifb: Remove framebuffer relocation tracking

2024-01-17 Thread Thomas Zimmermann
If the firmware framebuffer has been reloacted, the sysfb code
fixes the screen_info state before it creates the framebuffer's
platform device. Efifb will automatically receive a screen_info
with updated values. Hence remove the tracking from efifb.

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/efifb.c | 76 +
 1 file changed, 1 insertion(+), 75 deletions(-)

diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index f76b7ae00751..8dd82afb3452 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -13,7 +13,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -47,8 +46,6 @@ static bool use_bgrt = true;
 static bool request_mem_succeeded = false;
 static u64 mem_flags = EFI_MEMORY_WC | EFI_MEMORY_UC;
 
-static struct pci_dev *efifb_pci_dev;  /* dev with BAR covering the efifb */
-
 struct efifb_par {
u32 pseudo_palette[16];
resource_size_t base;
@@ -348,9 +345,6 @@ static struct attribute *efifb_attrs[] = {
 };
 ATTRIBUTE_GROUPS(efifb);
 
-static struct resource *bar_resource;
-static u64 bar_offset;
-
 static int efifb_probe(struct platform_device *dev)
 {
struct screen_info *si;
@@ -411,21 +405,7 @@ static int efifb_probe(struct platform_device *dev)
si->rsvd_pos = 24;
}
 
-   efifb_fix.smem_start = si->lfb_base;
-
-   if (si->capabilities & VIDEO_CAPABILITY_64BIT_BASE) {
-   u64 ext_lfb_base;
-
-   ext_lfb_base = (u64)(unsigned long)si->ext_lfb_base << 32;
-   efifb_fix.smem_start |= ext_lfb_base;
-   }
-
-   if (bar_resource &&
-   bar_resource->start + bar_offset != efifb_fix.smem_start) {
-   dev_info(&efifb_pci_dev->dev,
-"BAR has moved, updating efifb address\n");
-   efifb_fix.smem_start = bar_resource->start + bar_offset;
-   }
+   efifb_fix.smem_start = __screen_info_lfb_base(si);
 
efifb_defined.bits_per_pixel = si->lfb_depth;
efifb_defined.xres = si->lfb_width;
@@ -640,57 +620,3 @@ static struct platform_driver efifb_driver = {
 };
 
 builtin_platform_driver(efifb_driver);
-
-#if defined(CONFIG_PCI)
-
-static void record_efifb_bar_resource(struct pci_dev *dev, int idx, u64 offset)
-{
-   u16 word;
-
-   efifb_pci_dev = dev;
-
-   pci_read_config_word(dev, PCI_COMMAND, &word);
-   if (!(word & PCI_COMMAND_MEMORY)) {
-   dev_err(&dev->dev,
-   "BAR %d: assigned to efifb but device is disabled!\n",
-   idx);
-   return;
-   }
-
-   bar_resource = &dev->resource[idx];
-   bar_offset = offset;
-
-   dev_info(&dev->dev, "BAR %d: assigned to efifb\n", idx);
-}
-
-static void efifb_fixup_resources(struct pci_dev *dev)
-{
-   u64 base = screen_info.lfb_base;
-   u64 size = screen_info.lfb_size;
-   int i;
-
-   if (efifb_pci_dev || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
-   return;
-
-   if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
-   base |= (u64)screen_info.ext_lfb_base << 32;
-
-   if (!base)
-   return;
-
-   for (i = 0; i < PCI_STD_NUM_BARS; i++) {
-   struct resource *res = &dev->resource[i];
-
-   if (!(res->flags & IORESOURCE_MEM))
-   continue;
-
-   if (res->start <= base && res->end >= base + size - 1) {
-   record_efifb_bar_resource(dev, i, base - res->start);
-   break;
-   }
-   }
-}
-DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY,
-  16, efifb_fixup_resources);
-
-#endif
-- 
2.43.0



Re: [PATCH 0/2] drm/atomic: Allow drivers to write their own plane check for async

2024-01-17 Thread Xaver Hugl
Am Mi., 17. Jan. 2024 um 09:55 Uhr schrieb Pekka Paalanen :
> Is it important enough to be special-cased, e.g. to be always allowed
> with async commits?

I thought so, and sent a patch to dri-devel to make it happen, but
there are some
concerns about untested driver paths.
https://lists.freedesktop.org/archives/dri-devel/2024-January/437511.html

> Now that I think of it, if userspace needs to wait for the in-fence
> itself before kicking KMS async, that would defeat much of the async's
> point, right? And cases where in-fence is not necessary are so rare
> they might not even exist?
>
> So if driver/hardware cannot do IN_FENCE_FD with async, is there any
> use of supporting async to begin with?

KWin never commits a buffer where IN_FENCE_FD would actually delay the
pageflip; it's really only used to disable implicit sync, as there's some edge
cases where it can wrongly delay the pageflip. The waiting for buffers to become
readable on the compositor side isn't really significant in terms of latency.

If hardware doesn't support IN_FENCE_FD with async commits, checking if the
fence is already signaled at commit time would thus still make things work, at
least for KWin.

> > If the compositor prioritizes tearing and would like to do overlay planes
> > if possible,
> > it would have to know that switching to synchronous commits for a single
> > frame,
> > setting up the overlay planes and then switching back to async commits
> > works, and
> > that can't be figured out with TEST_ONLY commits.
>
> I had to ponder a bit why. So I guess the synchronous commit in between
> is because driver/hardware may not be able to enable/disable extra
> planes in async, so you need a synchronous commit to set them up, but
> afterwards updates can tear.

The hardware could be a factor, yes, but I've been thinking more about the API.
With this patchset, the compositor is still only allowed to change a
limited set of
plane properties - but it needs to set at least SRC_X, SRC_Y, CRTC_X etc on
the overlay plane(s) to the correct values before it can only change the allowed
properties again.

> The comment about Intel needing one more synchronous commit when
> switching from sync to async updates comes to mind as well, would that
> be a problem?

With only one synchronous update, the compositor could theoretically mask the
issue by committing it right before vblank; with that one
implicitly-sync "async"
commit though, you'd definitely get one frame without async commits. Having a
flag for a sync-but-then-async-again commit could solve that issue.

In practice I don't think anyone will notice one or two frames without
async commits.
It should be a pretty rare occurance, usually when the game or match
starts or an
overlay gets opened, so I doubt it's worth putting effort in to fix that.

> > So I think having a CAP or immutable plane property to signal that async
> > commits
> > with overlay and/or cursor planes is supported would be useful.
>
> Async cursor planes a good point, particularly moving them around. I'm
> not too informed about the prior/on-going efforts to allow cursor
> movement more often than refresh rate, I recall something about
> amending atomic commits? How would these interact?
>
> I suppose the kernel still prevents any new async commit while a
> previous commit is not finished, so amending commits would still be
> necessary for cursor plane motion? Or would it, if you time "big
> commits" to finish quickly and then spam async "cursor commits" in the
> mean time?

With async commits for cursor planes I'm really only talking about
getting to use
the cursor plane while doing async commits on the primary plane.

FWIW I personally consider the amend stuff mostly solved - KWin does that
internally since a few months ago now, with a separate thread to amend and
even reorder commits in a queue, and only actually commit immediately
before vblank.

>
> Thanks,
> pq
>
> > Am Di., 16. Jan. 2024 um 14:35 Uhr schrieb André Almeida <
> > andrealm...@igalia.com>:
> >
> > > + Joshua
> > >
> > > Em 16/01/2024 10:14, Pekka Paalanen escreveu:
> > > > On Tue, 16 Jan 2024 08:50:59 -0300
> > > > André Almeida  wrote:
> > > >
> > > >> Hi Pekka,
> > > >>
> > > >> Em 16/01/2024 06:45, Pekka Paalanen escreveu:
> > > >>> On Tue, 16 Jan 2024 01:51:57 -0300
> > > >>> André Almeida  wrote:
> > > >>>
> > >  Hi,
> > > 
> > >  AMD hardware can do more on the async flip path than just the primary
> > > plane, so
> > >  to lift up the current restrictions, this patchset allows drivers to
> > > write their
> > >  own check for planes for async flips.
> > > >>>
> > > >>> Hi,
> > > >>>
> > > >>> what's the userspace story for this, how could userspace know it could
> > > do more?
> > > >>> What kind of userspace would take advantage of this and in what
> > > situations?
> > > >>>
> > > >>> Or is this not meant for generic userspace?
> > > >>
> > > >> Sorry, I forgot to document this. So the idea is that userspace will
> > > >> q

Re: [PATCH v2 2/4] drm/uAPI: Add "force color format" drm property as setting for userspace

2024-01-17 Thread Andri Yngvason
mið., 17. jan. 2024 kl. 09:21 skrifaði Pekka Paalanen :
>
> On Tue, 16 Jan 2024 14:11:43 +
> Andri Yngvason  wrote:
>
> > þri., 16. jan. 2024 kl. 13:29 skrifaði Sebastian Wick
> > :
> > >
> > > On Tue, Jan 16, 2024 at 01:13:13PM +, Andri Yngvason wrote:
> > [...]
> > > > şri., 16. jan. 2024 kl. 11:42 skrifaği Sebastian Wick
> > > > :
> > > > >
> > > > > On Mon, Jan 15, 2024 at 04:05:52PM +, Andri Yngvason wrote:
> > > > > > From: Werner Sembach 
> > > > > >
> > > > > > Add a new general drm property "force color format" which can be 
> > > > > > used
> > > > > > by userspace to tell the graphics driver which color format to use.
> > > > >
> > > > > I don't like the "force" in the name. This just selects the color
> > > > > format, let's just call it "color format" then.
> > > > >
> > > >
> > > > In previous revisions, this was "preferred color format" and "actual
> > > > color format", of which the latter has been dropped. I recommend
> > > > reading the discussion for previous revisions.
> > >
> > > Please don't imply that I didn't read the thread I'm answering to.
>
> FYI, I have not read this thread.
>

pq, You did not read this summary?
https://lore.kernel.org/dri-devel/cafnqbqwjejax6b4oewpgasmud5_nxzymxufdog294ctvgbt...@mail.gmail.com/

You partook in the discussion on IRC. Please read it and tell me if I
misunderstood anything.

Sebastian, I apologise. You clearly read it as you even replied to it!

> > >
> > > > There are arguments for adding "actual color format" later and if it
> > > > is added later, we'd end up with "color format" and "actual color
> > > > format", which might be confusing, and it is why I chose to call it
> > > > "force color format" because it clearly communicates intent and
> > > > disambiguates it from "actual color format".
> > >
> > > There is no such thing as "actual color format" in upstream though.
> > > Basing your naming on discarded ideas is not useful. The thing that sets
> > > the color space for example is called "Colorspace", not "force
> > > colorspace".
> > >
> >
> > Sure, I'm happy with calling it whatever people want. Maybe we can
> > have a vote on it?
>
> It would sound strange to say "force color format" = "auto". Just drop
> the "force" of it.
>
> If and when we need the feedback counterpart, it could be an immutable
> prop called "active color format" where "auto" is not a valid value, or
> something in the new "output properties" design Sima has been thinking
> of.

There seems to be consensus for calling it "color format"

>
> > > > [...]
> > > > > > @@ -1396,6 +1404,15 @@ static const u32 dp_colorspaces =
> > > > > >   *   drm_connector_attach_max_bpc_property() to create and attach 
> > > > > > the
> > > > > >   *   property to the connector during initialization.
> > > > > >   *
> > > > > > + * force color format:
> > > > > > + *   This property is used by userspace to change the used color 
> > > > > > format. When
> > > > > > + *   used the driver will use the selected format if valid for the 
> > > > > > hardware,
> > > > >
> > > > > All properties are always "used", they just can have different values.
> > > > > You probably want to talk about the auto mode here.
> > > >
> > > > Maybe we can say something like: If userspace does not set the
> > > > property or if it is explicitly set to zero, the driver will select
> > > > the appropriate color format based on other constraints.
> > >
> > > The property can be in any state without involvement from user space.
> > > Don't talk about setting it, talk about the state it is in:
> > >
> > >   When the color format is auto, the driver will select a format.
> > >
> >
> > Ok.
> >
> > > > >
> > > > > > + *   sink, and current resolution and refresh rate combination. 
> > > > > > Drivers to
> > > > >
> > > > > If valid? So when a value is not actually supported user space can 
> > > > > still
> > > > > set it? What happens then? How should user space figure out if the
> > > > > driver and the sink support the format?
> > > >
> > > > The kernel does not expose this property unless it's implemented in the 
> > > > driver.
> > >
> > > If the driver simply doesn't support *one format*, the enum value for
> > > that format should not be exposed, period. This isn't about the property
> > > on its own.
> >
> > Right, understood. You mean that enum should only contain values that
> > are supported by the driver.
>
> Yes. When a driver installs a property, it can choose which of the enum
> entries are exposed. That cannot be changed later though, so the list
> cannot live by the currently connected sink, only by what the driver
> and display controlled could ever do.

Yes, and I think that basing it also on the connected sink's
capabilities would just add complexity for very little gain. In fact,
I think that limiting it based on the driver's capabilities is also
over-engineering, but I don't mind adding it if that's what people
really want.

>
> > > > This was originally "preferred color format". Perh

Re: [PATCH v4 3/4] usb: gadget: functionfs: Add DMABUF import interface

2024-01-17 Thread Christian König

Am 17.01.24 um 13:26 schrieb Paul Cercueil:

This patch introduces three new ioctls. They all should be called on a
data endpoint (ie. not ep0). They are:

- FUNCTIONFS_DMABUF_ATTACH, which takes the file descriptor of a DMABUF
   object to attach to the endpoint.

- FUNCTIONFS_DMABUF_DETACH, which takes the file descriptor of the
   DMABUF to detach from the endpoint. Note that closing the endpoint's
   file descriptor will automatically detach all attached DMABUFs.

- FUNCTIONFS_DMABUF_TRANSFER, which requests a data transfer from / to
   the given DMABUF. Its argument is a structure that packs the DMABUF's
   file descriptor, the size in bytes to transfer (which should generally
   be set to the size of the DMABUF), and a 'flags' field which is unused
   for now.
   Before this ioctl can be used, the related DMABUF must be attached
   with FUNCTIONFS_DMABUF_ATTACH.

These three ioctls enable the FunctionFS code to transfer data between
the USB stack and a DMABUF object, which can be provided by a driver
from a completely different subsystem, in a zero-copy fashion.

Signed-off-by: Paul Cercueil 
Acked-by: Daniel Vetter 


I only looked at it from the DMA-buf maintainer point of view and 
especially the fence signaling (which people often get wrong) looks 
correct to me.


Can't judge if the USB side will work or not, so I can only give my 
Acked-by for this as well.


Regards,
Christian.



---
v2:
- Make ffs_dma_resv_lock() static
- Add MODULE_IMPORT_NS(DMA_BUF);
- The attach/detach functions are now performed without locking the
   eps_lock spinlock. The transfer function starts with the spinlock
   unlocked, then locks it before allocating and queueing the USB
   transfer.

v3:
- Inline to_ffs_dma_fence() which was called only once.
- Simplify ffs_dma_resv_lock()
- Add comment explaining why we unref twice in ffs_dmabuf_detach()
- Document uapi struct usb_ffs_dmabuf_transfer_req and IOCTLs

v4:
- Protect the dmabufs list with a mutex
- Use incremental sequence number for the dma_fences
- Unref attachments and DMABUFs in workers
- Remove dead code in ffs_dma_resv_lock()
- Fix non-block actually blocking
- Use dma_fence_begin/end_signalling()
- Add comment about cache-management and dma_buf_unmap_attachment()
- Make sure dma_buf_map_attachment() is called with the dma-resv locked
---
  drivers/usb/gadget/function/f_fs.c  | 454 
  include/uapi/linux/usb/functionfs.h |  41 +++
  2 files changed, 495 insertions(+)

diff --git a/drivers/usb/gadget/function/f_fs.c 
b/drivers/usb/gadget/function/f_fs.c
index ed2a6d5fcef7..64dfd084c857 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -15,6 +15,9 @@
  /* #define VERBOSE_DEBUG */
  
  #include 

+#include 
+#include 
+#include 
  #include 
  #include 
  #include 
@@ -43,6 +46,8 @@
  
  #define FUNCTIONFS_MAGIC	0xa647361 /* Chosen by a honest dice roll ;) */
  
+MODULE_IMPORT_NS(DMA_BUF);

+
  /* Reference counter handling */
  static void ffs_data_get(struct ffs_data *ffs);
  static void ffs_data_put(struct ffs_data *ffs);
@@ -124,6 +129,23 @@ struct ffs_ep {
u8  num;
  };
  
+struct ffs_dmabuf_priv {

+   struct list_head entry;
+   struct kref ref;
+   struct ffs_data *ffs;
+   struct dma_buf_attachment *attach;
+   spinlock_t lock;
+   u64 context;
+};
+
+struct ffs_dma_fence {
+   struct dma_fence base;
+   struct ffs_dmabuf_priv *priv;
+   struct sg_table *sgt;
+   enum dma_data_direction dir;
+   struct work_struct work;
+};
+
  struct ffs_epfile {
/* Protects ep->ep and ep->req. */
struct mutexmutex;
@@ -197,6 +219,11 @@ struct ffs_epfile {
unsigned char   isoc;   /* P: ffs->eps_lock */
  
  	unsigned char			_pad;

+
+   /* Protects dmabufs */
+   struct mutexdmabufs_mutex;
+   struct list_headdmabufs; /* P: dmabufs_mutex */
+   atomic_tseqno;
  };
  
  struct ffs_buffer {

@@ -1271,10 +1298,47 @@ static ssize_t ffs_epfile_read_iter(struct kiocb 
*kiocb, struct iov_iter *to)
return res;
  }
  
+static void ffs_dmabuf_release(struct kref *ref)

+{
+   struct ffs_dmabuf_priv *priv = container_of(ref, struct 
ffs_dmabuf_priv, ref);
+   struct dma_buf_attachment *attach = priv->attach;
+   struct dma_buf *dmabuf = attach->dmabuf;
+
+   pr_debug("FFS DMABUF release\n");
+   dma_buf_detach(attach->dmabuf, attach);
+   dma_buf_put(dmabuf);
+   kfree(priv);
+}
+
+static void ffs_dmabuf_get(struct dma_buf_attachment *attach)
+{
+   struct ffs_dmabuf_priv *priv = attach->importer_priv;
+
+   kref_get(&priv->ref);
+}
+
+static void ffs_dmabuf_put(struct dma_buf_attachment *attach)
+{
+   struct ffs_dmabuf_priv *priv = attach->importer_priv;
+
+   kref_put(&priv->ref, ffs_dmabuf_release);
+}
+
  static int
  ffs_epfile_release(struc

Re: Re: (subset) [PATCH] drm/rockchip: inno_hdmi: Explicitly include drm_atomic.h

2024-01-17 Thread Maxime Ripard
On Wed, Jan 17, 2024 at 10:52:04AM +0100, Heiko Stübner wrote:
> Hi Maxime,
> 
> Am Mittwoch, 17. Januar 2024, 10:46:57 CET schrieb Maxime Ripard:
> > On Mon, 15 Jan 2024 10:24:35 +0100, Alex Bee wrote:
> > > Commit d3e040f450ec ("drm/rockchip: inno_hdmi: Get rid of mode_set")
> > > started using drm_atomic_get_new_connector_state and
> > > drm_atomic_get_new_crtc_state which are defined in drm_atomic.h
> > > Building does currently only work if CONFIG_OF and CONFIG_DRM_PANEL_BRIDGE
> > > are enabled since this will include drm_atomic.h via drm_bridge.h (see
> > > drm_of.h).
> > > 
> > > [...]
> > 
> > Applied to drm/drm-misc (drm-misc-next).
> 
> wouldn't have drm-misc-next-fixes been more appropriate?
> Because I _think_ the change causing the issue made it in during the
> current merge-window?

AFAIK, the offending commit is in drm-misc-next only

Maxime


signature.asc
Description: PGP signature


Re: [PATCH 09/10] pci: devres: remove legacy pcim_release()

2024-01-17 Thread Philipp Stanner
On Tue, 2024-01-16 at 23:40 +0200, andy.shevche...@gmail.com wrote:
> Mon, Jan 15, 2024 at 03:46:20PM +0100, Philipp Stanner kirjoitti:
> > Thanks to preceding cleanup steps, pcim_release() is now not needed
> > anymore and can be replaced by pcim_disable_device(), which is the
> > exact
> > counterpart to pcim_enable_device().
> > This permits removing further parts of the old devres API.
> > 
> > Replace pcim_release() with pcim_disable_device().
> > Remove the now surplus get_dr() function.
> 
> ...
> 
> > +   devm_add_action(&pdev->dev, pcim_disable_device, pdev);
> 
> No error check?
> 
> > +   return pci_enable_device(pdev);
> 
> Maybe
> 
> ret = pci_enable_device(...);
> if (ret)
> return ret;
> 
> return devm_add_action_or_reset(...)?
> 
> I could think of side effects of this, so perhaps the commit message
> and/or
> code needs a comment on why the above proposal can _not_ be used?
> 

That proposal can be used, so this was simply a bug.

P.



Re: [PATCH 1/4] drm: xlnx: zynqmp_dpsub: Make drm bridge discoverable

2024-01-17 Thread Tomi Valkeinen

On 13/01/2024 01:42, Anatoliy Klymenko wrote:

Assign device of node to bridge prior registering it. This will
make said bridge discoverable by separate crtc driver.


I think a few words on why this is needed (and why it wasn't needed 
before) would be nice.


Other than that:

Reviewed-by: Tomi Valkeinen 

 Tomi


Signed-off-by: Anatoliy Klymenko 
---
  drivers/gpu/drm/xlnx/zynqmp_dp.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
index a0606fab0e22..d60b7431603f 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
@@ -1721,6 +1721,7 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub)
bridge->ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
| DRM_BRIDGE_OP_HPD;
bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
+   bridge->of_node = dp->dev->of_node;
dpsub->bridge = bridge;
  
  	/*




Re: [PATCH 2/4] drm: xlnx: zynqmp_dpsub: Fix timing for live mode

2024-01-17 Thread Tomi Valkeinen

On 13/01/2024 01:42, Anatoliy Klymenko wrote:

Expect external video timing in live video input mode, program
DPSUB accordingly.

Signed-off-by: Anatoliy Klymenko 
---
  drivers/gpu/drm/xlnx/zynqmp_disp.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c 
b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index 407bc07cec69..8a39b3accce5 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -1166,7 +1166,7 @@ void zynqmp_disp_enable(struct zynqmp_disp *disp)
/* Choose clock source based on the DT clock handle. */
zynqmp_disp_avbuf_set_clocks_sources(disp, disp->dpsub->vid_clk_from_ps,
 disp->dpsub->aud_clk_from_ps,
-true);
+disp->dpsub->vid_clk_from_ps);
zynqmp_disp_avbuf_enable_channels(disp);
zynqmp_disp_avbuf_enable_audio(disp);
  


Reviewed-by: Tomi Valkeinen 

 Tomi



Re: [PATCH 0/2] drm/atomic: Allow drivers to write their own plane check for async

2024-01-17 Thread Michel Dänzer
On 2024-01-17 13:57, Xaver Hugl wrote:
> Am Mi., 17. Jan. 2024 um 09:55 Uhr schrieb Pekka Paalanen 
> :
>> Is it important enough to be special-cased, e.g. to be always allowed
>> with async commits?
> 
> I thought so, and sent a patch to dri-devel to make it happen, but
> there are some
> concerns about untested driver paths.
> https://lists.freedesktop.org/archives/dri-devel/2024-January/437511.html
> 
>> Now that I think of it, if userspace needs to wait for the in-fence
>> itself before kicking KMS async, that would defeat much of the async's
>> point, right? And cases where in-fence is not necessary are so rare
>> they might not even exist?
>>
>> So if driver/hardware cannot do IN_FENCE_FD with async, is there any
>> use of supporting async to begin with?
> 
> KWin never commits a buffer where IN_FENCE_FD would actually delay the
> pageflip; it's really only used to disable implicit sync, as there's some edge
> cases where it can wrongly delay the pageflip. The waiting for buffers to 
> become
> readable on the compositor side isn't really significant in terms of latency.
> 
> If hardware doesn't support IN_FENCE_FD with async commits, checking if the
> fence is already signaled at commit time would thus still make things work, at
> least for KWin.

That's how IN_FENCE_FD (and implicit sync) is handled anyway, in common code: 
It waits for all fences to signal before calling into the driver to commit the 
atomic commit.

I can't see why this wouldn't work with async commits, the same as with 
synchronous ones, with any driver.


-- 
Earthling Michel Dänzer|  https://redhat.com
Libre software enthusiast  | Mesa and Xwayland developer



Re: [PATCH 3/4] drm: xlnx: zynqmp_dpsub: Don't generate vblank in live mode

2024-01-17 Thread Tomi Valkeinen

On 13/01/2024 01:42, Anatoliy Klymenko wrote:

Filter out status register against interrupts' mask.
Some events are being reported via DP status register, even if
corresponding interrupts have been disabled. Avoid processing
of such events in interrupt handler context.


The subject talks about vblank and live mode, the the description 
doesn't. Can you elaborate in the desc a bit about when this is an issue 
and why it wasn't before?



Signed-off-by: Anatoliy Klymenko 
---
  drivers/gpu/drm/xlnx/zynqmp_dp.c | 11 +--
  1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
index d60b7431603f..571c5dbc97e5 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
@@ -1624,8 +1624,16 @@ static irqreturn_t zynqmp_dp_irq_handler(int irq, void 
*data)
u32 status, mask;
  
  	status = zynqmp_dp_read(dp, ZYNQMP_DP_INT_STATUS);

+   zynqmp_dp_write(dp, ZYNQMP_DP_INT_STATUS, status);
mask = zynqmp_dp_read(dp, ZYNQMP_DP_INT_MASK);
-   if (!(status & ~mask))
+
+   /*
+* Status register may report some events, which corresponding 
interrupts
+* have been disabled. Filter out those events against interrupts' mask.
+*/
+   status &= ~mask;
+
+   if (!status)
return IRQ_NONE;
  
  	/* dbg for diagnostic, but not much that the driver can do */

@@ -1634,7 +1642,6 @@ static irqreturn_t zynqmp_dp_irq_handler(int irq, void 
*data)
if (status & ZYNQMP_DP_INT_CHBUF_OVERFLW_MASK)
dev_dbg_ratelimited(dp->dev, "overflow interrupt\n");
  
-	zynqmp_dp_write(dp, ZYNQMP_DP_INT_STATUS, status);
  
  	if (status & ZYNQMP_DP_INT_VBLANK_START)

zynqmp_dpsub_drm_handle_vblank(dp->dpsub);


Moving the zynqmp_dp_write() is not related to this fix, is it? I think 
it should be in a separate patch.


 Tomi



Re: (subset) [PATCH] drm/rockchip: inno_hdmi: Explicitly include drm_atomic.h

2024-01-17 Thread Heiko Stübner
Am Mittwoch, 17. Januar 2024, 14:47:48 CET schrieb Maxime Ripard:
> On Wed, Jan 17, 2024 at 10:52:04AM +0100, Heiko Stübner wrote:
> > Hi Maxime,
> > 
> > Am Mittwoch, 17. Januar 2024, 10:46:57 CET schrieb Maxime Ripard:
> > > On Mon, 15 Jan 2024 10:24:35 +0100, Alex Bee wrote:
> > > > Commit d3e040f450ec ("drm/rockchip: inno_hdmi: Get rid of mode_set")
> > > > started using drm_atomic_get_new_connector_state and
> > > > drm_atomic_get_new_crtc_state which are defined in drm_atomic.h
> > > > Building does currently only work if CONFIG_OF and 
> > > > CONFIG_DRM_PANEL_BRIDGE
> > > > are enabled since this will include drm_atomic.h via drm_bridge.h (see
> > > > drm_of.h).
> > > > 
> > > > [...]
> > > 
> > > Applied to drm/drm-misc (drm-misc-next).
> > 
> > wouldn't have drm-misc-next-fixes been more appropriate?
> > Because I _think_ the change causing the issue made it in during the
> > current merge-window?
> 
> AFAIK, the offending commit is in drm-misc-next only

ah, you're of course right. Mistook that for the one in the rk3066_hdmi
but that was fixed back in november already.

So all is well.

Heiko




Re: [PATCH 0/4] Fixing live video input in ZynqMP DPSUB

2024-01-17 Thread Laurent Pinchart
On Mon, Jan 15, 2024 at 09:28:39AM +0100, Maxime Ripard wrote:
> On Fri, Jan 12, 2024 at 03:42:18PM -0800, Anatoliy Klymenko wrote:
> > Patches 1/4,2/4,3/4 are minor fixes.
> > 
> > DPSUB requires input live video format to be configured.
> > Patch 4/4: The DP Subsystem requires the input live video format to be
> > configured. In this patch we are assuming that the CRTC's bus format is 
> > fixed
> > and comes from the device tree. This is a proposed solution, as there are 
> > no api
> > to query CRTC output bus format.
> > 
> > Is this a good approach to go with?
> 
> I guess you would need to expand a bit on what "live video input" is? Is
> it some kind of mechanism to bypass memory and take your pixels straight
> from a FIFO from another device, or something else?

Yes and no.

The DPSUB integrates DMA engines, a blending engine (two planes), and a
DP encoder. The dpsub driver supports all of this, and creates a DRM
device. The DP encoder hardware always takes its input data from the
output of the blending engine.

The blending engine can optionally take input data from a bus connected
to the FPGA fabric, instead of taking it from the DPSUB internal DMA
engines. When operating in that mode, the dpsub driver exposes the DP
encoder as a bridge, and internally programs the blending engine to
disable blending. Typically, the FPGA fabric will then contain a CRTC of
some sort, with a driver that will acquire the DP encoder bridge as
usually done.

In this mode of operation, it is typical for the IP cores in FPGA fabric
to be synthesized with a fixed format (as that saves resources), while
the DPSUB supports multiple input formats. Bridge drivers in the
upstream kernel work the other way around, with the bridge hardware
supporting a limited set of formats, and the CRTC then being programmed
with whatever the bridges chain needs. Here, the negotiation needs to go
the other way around, as the CRTC is the limiting factor, not the
bridge.

Is this explanation clear ?

-- 
Regards,

Laurent Pinchart


Re: [PATCH 1/4] drm: xlnx: zynqmp_dpsub: Make drm bridge discoverable

2024-01-17 Thread Laurent Pinchart
On Wed, Jan 17, 2024 at 04:06:31PM +0200, Tomi Valkeinen wrote:
> On 13/01/2024 01:42, Anatoliy Klymenko wrote:
> > Assign device of node to bridge prior registering it. This will
> > make said bridge discoverable by separate crtc driver.
> 
> I think a few words on why this is needed (and why it wasn't needed 
> before) would be nice.
> 
> Other than that:
> 
> Reviewed-by: Tomi Valkeinen 

Agreed. With a better commit message,

Reviewed-by: Laurent Pinchart 

> > Signed-off-by: Anatoliy Klymenko 
> > ---
> >   drivers/gpu/drm/xlnx/zynqmp_dp.c | 1 +
> >   1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c 
> > b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> > index a0606fab0e22..d60b7431603f 100644
> > --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> > +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> > @@ -1721,6 +1721,7 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub)
> > bridge->ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
> > | DRM_BRIDGE_OP_HPD;
> > bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
> > +   bridge->of_node = dp->dev->of_node;
> > dpsub->bridge = bridge;
> >   
> > /*

-- 
Regards,

Laurent Pinchart


Re: [PATCH v7 5/9] drm/fb_dma: Add generic get_scanout_buffer() for drm_panic

2024-01-17 Thread Jocelyn Falempe




On 12/01/2024 14:41, Daniel Vetter wrote:

On Thu, Jan 04, 2024 at 05:00:49PM +0100, Jocelyn Falempe wrote:

This was initialy done for imx6, but should work on most drivers
using drm_fb_dma_helper.

Signed-off-by: Jocelyn Falempe 
---
  drivers/gpu/drm/drm_fb_dma_helper.c | 55 +
  include/drm/drm_fb_dma_helper.h |  4 +++
  2 files changed, 59 insertions(+)

diff --git a/drivers/gpu/drm/drm_fb_dma_helper.c 
b/drivers/gpu/drm/drm_fb_dma_helper.c
index 3b535ad1b07c..caed2935df4f 100644
--- a/drivers/gpu/drm/drm_fb_dma_helper.c
+++ b/drivers/gpu/drm/drm_fb_dma_helper.c
@@ -15,6 +15,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -148,3 +149,57 @@ void drm_fb_dma_sync_non_coherent(struct drm_device *drm,
}
  }
  EXPORT_SYMBOL_GPL(drm_fb_dma_sync_non_coherent);
+
+#if defined(CONFIG_DRM_PANIC)
+/**
+ * @dev: DRM device
+ * @drm_scanout_buffer: scanout buffer for the panic handler
+ * Returns: 0 or negative error code
+ *
+ * Generic get_scanout_buffer() implementation, for drivers that uses the
+ * drm_fb_dma_helper.
+ */
+int drm_panic_gem_get_scanout_buffer(struct drm_device *dev,
+struct drm_scanout_buffer *sb)
+{
+   struct drm_plane *plane;
+   struct drm_gem_dma_object *dma_obj;
+   struct drm_framebuffer *fb;
+
+   drm_for_each_primary_visible_plane(plane, dev) {


Ok that's not enough locking by far. You can't just hope that nothing
disappears while you're in a panic handler. We've been there and ended up
reliably oopsing in the panic handler itself. So you _have_ to follow the
full set of locking rules for all drm structures, or things will just get
worse at the worst possible moment.

But also, you're not allowed to do anything else than trylock, because a
panic handler might run from nmi context, and so you cannot even acquire
irq-safe spinlocks reliably.

Which means:

- You need to be safe against concurrent drm_dev_unregister. Using the
   atomic panic notifier directly for each device should take care of that
   (but maybe that stuff is still not nmi safe, not sure).

- You _have_ to use all the locks. Luckily iterating over the plane list
   doesn't need one, but you have to trylock the plane's modeset lock.
   Which means your nice iterator macro is already toast, because that
   already looks at state it's not allowed to look at without a lock. Or
   well, the plane->state pointer is no-go already.


mutex_trylock() shouldn't be called from interrupt context, and as the 
panic may occurs in irq, I can't use that.


But the panic context should guarantee that only one CPU is still running:
https://elixir.bootlin.com/linux/latest/source/kernel/panic.c#L310

So I think using mutex_is_locked() should be safe: 
https://elixir.bootlin.com/linux/latest/source/include/linux/mutex.h#L128


This will only check if the lock is not taken, but as it's not possible 
for another task to run at the same time, I think that should be good 
enough ?


The drawback, is if we want to test without crashing the kernel, then we 
need to take the locks with trylock(), (and it's safe this time), but 
the code path would be slightly different.


--

Jocelyn




Given the locking issues I'm not sure whether the
drm_for_each_primary_visible_plane iterator is going to work, you'd need
something like iter_init/next/end we have for walking the connector list.
Plus it would be very panic specific due to the trylock, so maybe

drm_for_each_visible_plane_in_panic_handler()

or something like that.

One thing I was wondering is whether we should lift this iteration over
all planes into the shared code, and move the ->get_scanout_buffer
function to the drm_plane_funcs structure instead?


+   fb = plane->state->fb;
+   /* Only support linear modifier */
+   if (fb->modifier != DRM_FORMAT_MOD_LINEAR)
+   continue;
+
+   /* Check if color format is supported */
+   if (!drm_panic_is_format_supported(fb->format->format))
+   continue;
+
+   dma_obj = drm_fb_dma_get_gem_obj(fb, 0);
+
+   /* Buffer should be accessible from the CPU */
+   if (dma_obj->base.import_attach)


This might be a bit too restrictive, since some drivers import dma-buf
including a vmap. So just checking for ->vaddr might be better. But can be
changed later on.


+   continue;
+
+   /* Buffer should be already mapped to CPU */


I'd clarify this comment to state that vaddr is invariant over the
lifetime of the buffer and therefore needs no locking. Correct locking
that a) takes all the locks b) never ever stalls for one is absolutely
crucial for a panic handler that won't make the situation worse.


+   if (!dma_obj->vaddr)




+   continue;
+
+   iosys_map_set_vaddr(&sb->map, dma_obj->vaddr);
+   sb->form

[PATCH] drm/radeon: remove dead code in ni_mc_load_microcode()

2024-01-17 Thread Nikita Zhandarovich
Inside the if block with (running == 0), the checks for 'running'
possibly being non-zero are redundant. Remove them altogether.

This change is similar to the one authored by Heinrich Schuchardt
 in commit
ddbbd3be9679 ("drm/radeon: remove dead code, si_mc_load_microcode (v2)")

Found by Linux Verification Center (linuxtesting.org) with static
analysis tool Svace.

Fixes: 0af62b016804 ("drm/radeon/kms: add ucode loader for NI")
Signed-off-by: Nikita Zhandarovich 
---
 drivers/gpu/drm/radeon/ni.c | 10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 927e5f42e97d..8eac8c090433 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -624,7 +624,7 @@ static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] 
= {
 int ni_mc_load_microcode(struct radeon_device *rdev)
 {
const __be32 *fw_data;
-   u32 mem_type, running, blackout = 0;
+   u32 mem_type, running;
u32 *io_mc_regs;
int i, ucode_size, regs_size;
 
@@ -659,11 +659,6 @@ int ni_mc_load_microcode(struct radeon_device *rdev)
running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
 
if ((mem_type == MC_SEQ_MISC0_GDDR5_VALUE) && (running == 0)) {
-   if (running) {
-   blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
-   WREG32(MC_SHARED_BLACKOUT_CNTL, 1);
-   }
-
/* reset the engine and set to writable */
WREG32(MC_SEQ_SUP_CNTL, 0x0008);
WREG32(MC_SEQ_SUP_CNTL, 0x0010);
@@ -689,9 +684,6 @@ int ni_mc_load_microcode(struct radeon_device *rdev)
break;
udelay(1);
}
-
-   if (running)
-   WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
}
 
return 0;


[PATCH] drm/radeon/ni_dpm: remove redundant NULL check

2024-01-17 Thread Nikita Zhandarovich
'leakage_table' will always be successfully initialized as a pointer
to '&rdev->pm.dpm.dyn_state.cac_leakage_table'.

Remove unnecessary check if only to silence static checkers.

Found by Linux Verification Center (linuxtesting.org) with static
analysis tool Svace.

Fixes: 69e0b57a91ad ("drm/radeon/kms: add dpm support for cayman (v5)")
Signed-off-by: Nikita Zhandarovich 
---
 drivers/gpu/drm/radeon/ni_dpm.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
index 3e1c1a392fb7..e08559c44a5c 100644
--- a/drivers/gpu/drm/radeon/ni_dpm.c
+++ b/drivers/gpu/drm/radeon/ni_dpm.c
@@ -3103,9 +3103,6 @@ static int ni_init_simplified_leakage_table(struct 
radeon_device *rdev,
u32 smc_leakage, max_leakage = 0;
u32 scaling_factor;
 
-   if (!leakage_table)
-   return -EINVAL;
-
table_size = leakage_table->count;
 
if (eg_pi->vddc_voltage_table.count != table_size)


Re: [PATCH v7 1/9] drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill

2024-01-17 Thread Thomas Zimmermann

Hi

Am 04.01.24 um 17:00 schrieb Jocelyn Falempe:

This is needed for drm_panic, to draw the font, and fill
the background color, in multiple color format.


TBH, I don't like this patch at all. It looks like you're reimplementing 
existing functionality for a single use case; specifically drm_fb_blit().


What's wrong with the existing interfaces?

Best regards
Thomas



v5:
  * Change the drawing API, use drm_fb_blit_from_r1() to draw the font.
  * Also add drm_fb_fill() to fill area with background color.
v6:
  * fix __le32 conversion warning found by the kernel test bot

Signed-off-by: Jocelyn Falempe 
---
  drivers/gpu/drm/drm_format_helper.c | 432 ++--
  include/drm/drm_format_helper.h |   9 +
  2 files changed, 360 insertions(+), 81 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index b1be458ed4dd..8cbc2d747cff 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -111,6 +111,153 @@ void drm_format_conv_state_release(struct 
drm_format_conv_state *state)
  }
  EXPORT_SYMBOL(drm_format_conv_state_release);
  
+static inline __le16 drm_format_xrgb_to_rgb565(__le32 val32)

+{
+   u16 val16;
+   u32 pix;
+
+   pix = le32_to_cpu(val32);
+   val16 = ((pix & 0x00F8) >> 8) |
+   ((pix & 0xFC00) >> 5) |
+   ((pix & 0x00F8) >> 3);
+   return cpu_to_le16(val16);
+}
+
+static inline __le16 drm_format_xrgb_to_rgba5551(__le32 val32)
+{
+   u16 val16;
+   u32 pix;
+
+   pix = le32_to_cpu(val32);
+   val16 = ((pix & 0x00f8) >> 8) |
+   ((pix & 0xf800) >> 5) |
+   ((pix & 0x00f8) >> 2) |
+   BIT(0); /* set alpha bit */
+   return cpu_to_le16(val16);
+}
+
+static inline __le16 drm_format_xrgb_to_xrgb1555(__le32 val32)
+{
+   u16 val16;
+   u32 pix;
+
+   pix = le32_to_cpu(val32);
+   val16 = ((pix & 0x00f8) >> 9) |
+   ((pix & 0xf800) >> 6) |
+   ((pix & 0x00f8) >> 3);
+   return cpu_to_le16(val16);
+}
+
+static inline __le16 drm_format_xrgb_to_argb1555(__le32 val32)
+{
+   u16 val16;
+   u32 pix;
+
+   pix = le32_to_cpu(val32);
+   val16 = BIT(15) | /* set alpha bit */
+   ((pix & 0x00f8) >> 9) |
+   ((pix & 0xf800) >> 6) |
+   ((pix & 0x00f8) >> 3);
+   return cpu_to_le16(val16);
+}
+
+static inline __le32 drm_format_xrgb_to_argb(__le32 pix)
+{
+   u32 val32;
+
+   val32 = le32_to_cpu(pix);
+   val32 |= GENMASK(31, 24); /* fill alpha bits */
+   return cpu_to_le32(val32);
+}
+
+static inline __le32 drm_format_xrgb_to_xbgr(__le32 pix)
+{
+   u32 val32;
+
+   val32 = le32_to_cpu(pix);
+   val32 = ((val32 & 0x00ff) >> 16) <<  0 |
+   ((val32 & 0xff00) >>  8) <<  8 |
+   ((val32 & 0x00ff) >>  0) << 16 |
+   ((val32 & 0xff00) >> 24) << 24;
+   return cpu_to_le32(val32);
+}
+
+static inline __le32 drm_format_xrgb_to_abgr(__le32 pix)
+{
+   u32 val32;
+
+   val32 = le32_to_cpu(pix);
+   val32 = ((val32 & 0x00ff) >> 16) <<  0 |
+   ((val32 & 0xff00) >>  8) <<  8 |
+   ((val32 & 0x00ff) >>  0) << 16 |
+   GENMASK(31, 24); /* fill alpha bits */
+   return cpu_to_le32(val32);
+}
+
+static inline __le32 drm_format_xrgb_to_xrgb2101010(__le32 pix)
+{
+   u32 val32;
+
+   val32 = le32_to_cpu(pix);
+   val32 = ((val32 & 0x00FF) << 2) |
+   ((val32 & 0xFF00) << 4) |
+   ((val32 & 0x00FF) << 6);
+   return cpu_to_le32(val32 | ((val32 >> 8) & 0x00300C03));
+}
+
+static inline __le32 drm_format_xrgb_to_argb2101010(__le32 pix)
+{
+   u32 val32;
+
+   val32 = le32_to_cpu(pix);
+   val32 = ((val32 & 0x00FF) << 2) |
+   ((val32 & 0xFF00) << 4) |
+   ((val32 & 0x00FF) << 6);
+   val32 = GENMASK(31, 30) | /* set alpha bits */
+ val32 | ((val32 >> 8) & 0x00300c03);
+   return cpu_to_le32(val32);
+}
+
+/**
+ * drm_fb_convert_from_xrgb - convert one pixel from xrgb to the 
desired format
+ * @color: input color, in xrgb format
+ * @format: output format
+ *
+ * Returns:
+ * Color in the format specified, casted to u32.
+ * Or 0 if the format is unknown.
+ */
+u32 drm_fb_convert_from_xrgb(u32 color, u32 format)
+{
+   __le32 pix = cpu_to_le32(color);
+
+   switch (format) {
+   case DRM_FORMAT_RGB565:
+   return le16_to_cpu(drm_format_xrgb_to_rgb565(pix));
+   case DRM_FORMAT_RGBA5551:
+   return le16_to_cpu(drm_format_xrgb_to_rgba5551(pix));
+   case DRM_FORMAT_XRGB1555:
+   return le16_to_cpu(drm_format_xrgb_to_xrgb1555(pix));
+   case DRM_FORMAT_ARGB1555:
+   return le

Re: [PATCH v7 7/9] drm/mgag200: Add drm_panic support

2024-01-17 Thread Thomas Zimmermann

Hi

Am 04.01.24 um 17:00 schrieb Jocelyn Falempe:

Add support for the drm_panic module, which displays a message to
the screen when a kernel panic occurs.

v5:
  * Also check that the plane is visible and primary. (Thomas Zimmermann)

v7:
  * use drm_for_each_primary_visible_plane()

Signed-off-by: Jocelyn Falempe 
---
  drivers/gpu/drm/mgag200/mgag200_drv.c | 22 ++
  1 file changed, 22 insertions(+)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c 
b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 2fb18b782b05..2bf5918eadc5 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -13,10 +13,12 @@
  #include 
  #include 
  #include 
+#include 


Needs to go below drm_file.h

With that fixed:

Reviewed-by: Thomas Zimmermann 


  #include 
  #include 
  #include 
  #include 
+#include 
  #include 
  
  #include "mgag200_drv.h"

@@ -84,6 +86,25 @@ resource_size_t mgag200_probe_vram(void __iomem *mem, 
resource_size_t size)
return offset - 65536;
  }
  
+static int mgag200_get_scanout_buffer(struct drm_device *dev,

+ struct drm_scanout_buffer *sb)
+{
+   struct drm_plane *plane;
+   struct mga_device *mdev = to_mga_device(dev);
+   struct iosys_map map = IOSYS_MAP_INIT_VADDR_IOMEM(mdev->vram);
+
+   /* find the primary and visible plane */
+   drm_for_each_primary_visible_plane(plane, dev) {
+   sb->format = plane->state->fb->format;
+   sb->width = plane->state->fb->width;
+   sb->height = plane->state->fb->height;
+   sb->pitch = plane->state->fb->pitches[0];
+   sb->map = map;
+   return 0;
+   }
+   return -ENODEV;
+}
+
  /*
   * DRM driver
   */
@@ -99,6 +120,7 @@ static const struct drm_driver mgag200_driver = {
.major = DRIVER_MAJOR,
.minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL,
+   .get_scanout_buffer = mgag200_get_scanout_buffer,
DRM_GEM_SHMEM_DRIVER_OPS,
  };
  


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH v7 8/9] drm/ast: Add drm_panic support

2024-01-17 Thread Thomas Zimmermann

Hi

Am 04.01.24 um 17:00 schrieb Jocelyn Falempe:

Add support for the drm_panic module, which displays a message to
the screen when a kernel panic occurs.

v7
  * Use drm_for_each_primary_visible_plane()

Signed-off-by: Jocelyn Falempe 


Reviewed-by: Thomas Zimmermann 


---
  drivers/gpu/drm/ast/ast_drv.c | 26 --
  1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index 90bcb1eb9cd9..8ddce3d7fda9 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -35,6 +35,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  
  #include "ast_drv.h"

@@ -48,6 +49,27 @@ module_param_named(modeset, ast_modeset, int, 0400);
   * DRM driver
   */
  
+static int ast_get_scanout_buffer(struct drm_device *dev,

+ struct drm_scanout_buffer *sb)
+{
+   struct drm_plane *plane;
+   struct ast_plane *ast_plane;
+
+   drm_for_each_primary_visible_plane(plane, dev) {
+   ast_plane = to_ast_plane(plane);
+   if (!ast_plane->vaddr)
+   continue;
+
+   sb->format = plane->state->fb->format;
+   sb->width = plane->state->fb->width;
+   sb->height = plane->state->fb->height;
+   sb->pitch = plane->state->fb->pitches[0];
+   iosys_map_set_vaddr_iomem(&sb->map, ast_plane->vaddr);
+   return 0;
+   }
+   return -ENODEV;
+}
+
  DEFINE_DRM_GEM_FOPS(ast_fops);
  
  static const struct drm_driver ast_driver = {

@@ -62,8 +84,8 @@ static const struct drm_driver ast_driver = {
.major = DRIVER_MAJOR,
.minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL,
-
-   DRM_GEM_SHMEM_DRIVER_OPS
+   .get_scanout_buffer = ast_get_scanout_buffer,
+   DRM_GEM_SHMEM_DRIVER_OPS,
  };
  
  /*


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH v7 6/9] drm/simpledrm: Add drm_panic support

2024-01-17 Thread Thomas Zimmermann



Am 04.01.24 um 17:00 schrieb Jocelyn Falempe:

Add support for the drm_panic module, which displays a user-friendly
message to the screen when a kernel panic occurs.

Signed-off-by: Jocelyn Falempe 


Reviewed-by: Thomas Zimmermann 


---
  drivers/gpu/drm/tiny/simpledrm.c | 15 +++
  1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index 7ce1c4617675..6dd2afee84d4 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -25,6 +25,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  
  #define DRIVER_NAME	"simpledrm"

@@ -985,6 +986,19 @@ static struct simpledrm_device 
*simpledrm_device_create(struct drm_driver *drv,
return sdev;
  }
  
+static int simpledrm_get_scanout_buffer(struct drm_device *dev,

+   struct drm_scanout_buffer *sb)
+{
+   struct simpledrm_device *sdev = simpledrm_device_of_dev(dev);
+
+   sb->width = sdev->mode.hdisplay;
+   sb->height = sdev->mode.vdisplay;
+   sb->pitch = sdev->pitch;
+   sb->format = sdev->format;
+   sb->map = sdev->screen_base;
+   return 0;
+}
+
  /*
   * DRM driver
   */
@@ -1000,6 +1014,7 @@ static struct drm_driver simpledrm_driver = {
.minor  = DRIVER_MINOR,
.driver_features= DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
.fops   = &simpledrm_fops,
+   .get_scanout_buffer = simpledrm_get_scanout_buffer,
  };
  
  /*


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH v7 6/9] drm/simpledrm: Add drm_panic support

2024-01-17 Thread Thomas Zimmermann

Hi

Am 12.01.24 um 14:58 schrieb Maxime Ripard:

On Fri, Jan 12, 2024 at 02:44:57PM +0100, Daniel Vetter wrote:

On Thu, Jan 04, 2024 at 05:00:50PM +0100, Jocelyn Falempe wrote:

Add support for the drm_panic module, which displays a user-friendly
message to the screen when a kernel panic occurs.

Signed-off-by: Jocelyn Falempe 
---
  drivers/gpu/drm/tiny/simpledrm.c | 15 +++
  1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index 7ce1c4617675..6dd2afee84d4 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -25,6 +25,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  
  #define DRIVER_NAME	"simpledrm"

@@ -985,6 +986,19 @@ static struct simpledrm_device 
*simpledrm_device_create(struct drm_driver *drv,
return sdev;
  }
  
+static int simpledrm_get_scanout_buffer(struct drm_device *dev,

+   struct drm_scanout_buffer *sb)
+{
+   struct simpledrm_device *sdev = simpledrm_device_of_dev(dev);


So I guess simpledrm is the reason why the get_scanout_buffer hook is at
the device level and not at the plane level. Even from the few drivers you
have in your series it seems very much the exception, so I'm not sure
whether that's the best design.

I guess we'll know when we see the plane iterator code with the right
locking, whether it's ok to have that in driver hooks or it's better to
pull it out into shared code.


Wouldn't the CRTC level be better than the planes?


What's in favor of the CRTC level?

I'd put a hook at the plane level and do the 
drm_for_each_primary_visible_plane() in the panic handler. Simpledrm 
would fit into this pattern nicely.


But it's not like I have strong feeling about this. The current 
callbacks are simple enough.


Best regards
Thomas



Maxime


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH v7 1/9] drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill

2024-01-17 Thread Jani Nikula
On Thu, 04 Jan 2024, Jocelyn Falempe  wrote:
> This is needed for drm_panic, to draw the font, and fill
> the background color, in multiple color format.
>
> v5:
>  * Change the drawing API, use drm_fb_blit_from_r1() to draw the font.
>  * Also add drm_fb_fill() to fill area with background color.
> v6:
>  * fix __le32 conversion warning found by the kernel test bot
>
> Signed-off-by: Jocelyn Falempe 
> ---
>  drivers/gpu/drm/drm_format_helper.c | 432 ++--
>  include/drm/drm_format_helper.h |   9 +
>  2 files changed, 360 insertions(+), 81 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_format_helper.c 
> b/drivers/gpu/drm/drm_format_helper.c
> index b1be458ed4dd..8cbc2d747cff 100644
> --- a/drivers/gpu/drm/drm_format_helper.c
> +++ b/drivers/gpu/drm/drm_format_helper.c
> @@ -111,6 +111,153 @@ void drm_format_conv_state_release(struct 
> drm_format_conv_state *state)
>  }
>  EXPORT_SYMBOL(drm_format_conv_state_release);
>  
> +static inline __le16 drm_format_xrgb_to_rgb565(__le32 val32)

Please don't use inline in C files. Just let the compiler do its job.

BR,
Jani.

> +{
> + u16 val16;
> + u32 pix;
> +
> + pix = le32_to_cpu(val32);
> + val16 = ((pix & 0x00F8) >> 8) |
> + ((pix & 0xFC00) >> 5) |
> + ((pix & 0x00F8) >> 3);
> + return cpu_to_le16(val16);
> +}
> +
> +static inline __le16 drm_format_xrgb_to_rgba5551(__le32 val32)
> +{
> + u16 val16;
> + u32 pix;
> +
> + pix = le32_to_cpu(val32);
> + val16 = ((pix & 0x00f8) >> 8) |
> + ((pix & 0xf800) >> 5) |
> + ((pix & 0x00f8) >> 2) |
> + BIT(0); /* set alpha bit */
> + return cpu_to_le16(val16);
> +}
> +
> +static inline __le16 drm_format_xrgb_to_xrgb1555(__le32 val32)
> +{
> + u16 val16;
> + u32 pix;
> +
> + pix = le32_to_cpu(val32);
> + val16 = ((pix & 0x00f8) >> 9) |
> + ((pix & 0xf800) >> 6) |
> + ((pix & 0x00f8) >> 3);
> + return cpu_to_le16(val16);
> +}
> +
> +static inline __le16 drm_format_xrgb_to_argb1555(__le32 val32)
> +{
> + u16 val16;
> + u32 pix;
> +
> + pix = le32_to_cpu(val32);
> + val16 = BIT(15) | /* set alpha bit */
> + ((pix & 0x00f8) >> 9) |
> + ((pix & 0xf800) >> 6) |
> + ((pix & 0x00f8) >> 3);
> + return cpu_to_le16(val16);
> +}
> +
> +static inline __le32 drm_format_xrgb_to_argb(__le32 pix)
> +{
> + u32 val32;
> +
> + val32 = le32_to_cpu(pix);
> + val32 |= GENMASK(31, 24); /* fill alpha bits */
> + return cpu_to_le32(val32);
> +}
> +
> +static inline __le32 drm_format_xrgb_to_xbgr(__le32 pix)
> +{
> + u32 val32;
> +
> + val32 = le32_to_cpu(pix);
> + val32 = ((val32 & 0x00ff) >> 16) <<  0 |
> + ((val32 & 0xff00) >>  8) <<  8 |
> + ((val32 & 0x00ff) >>  0) << 16 |
> + ((val32 & 0xff00) >> 24) << 24;
> + return cpu_to_le32(val32);
> +}
> +
> +static inline __le32 drm_format_xrgb_to_abgr(__le32 pix)
> +{
> + u32 val32;
> +
> + val32 = le32_to_cpu(pix);
> + val32 = ((val32 & 0x00ff) >> 16) <<  0 |
> + ((val32 & 0xff00) >>  8) <<  8 |
> + ((val32 & 0x00ff) >>  0) << 16 |
> + GENMASK(31, 24); /* fill alpha bits */
> + return cpu_to_le32(val32);
> +}
> +
> +static inline __le32 drm_format_xrgb_to_xrgb2101010(__le32 pix)
> +{
> + u32 val32;
> +
> + val32 = le32_to_cpu(pix);
> + val32 = ((val32 & 0x00FF) << 2) |
> + ((val32 & 0xFF00) << 4) |
> + ((val32 & 0x00FF) << 6);
> + return cpu_to_le32(val32 | ((val32 >> 8) & 0x00300C03));
> +}
> +
> +static inline __le32 drm_format_xrgb_to_argb2101010(__le32 pix)
> +{
> + u32 val32;
> +
> + val32 = le32_to_cpu(pix);
> + val32 = ((val32 & 0x00FF) << 2) |
> + ((val32 & 0xFF00) << 4) |
> + ((val32 & 0x00FF) << 6);
> + val32 = GENMASK(31, 30) | /* set alpha bits */
> +   val32 | ((val32 >> 8) & 0x00300c03);
> + return cpu_to_le32(val32);
> +}
> +
> +/**
> + * drm_fb_convert_from_xrgb - convert one pixel from xrgb to the 
> desired format
> + * @color: input color, in xrgb format
> + * @format: output format
> + *
> + * Returns:
> + * Color in the format specified, casted to u32.
> + * Or 0 if the format is unknown.
> + */
> +u32 drm_fb_convert_from_xrgb(u32 color, u32 format)
> +{
> + __le32 pix = cpu_to_le32(color);
> +
> + switch (format) {
> + case DRM_FORMAT_RGB565:
> + return le16_to_cpu(drm_format_xrgb_to_rgb565(pix));
> + case DRM_FORMAT_RGBA5551:
> + return le16_to_cpu(drm_format_xrgb_to_rgba5551(pix));
> + case DRM_FORMAT_XRGB1555:
> + return le16_to_cpu(drm_format_xrgb_to_xrgb1555(pix));
> + case DRM_FORMAT_ARGB1555:
> +   

Re: Implement per-key keyboard backlight as auxdisplay?

2024-01-17 Thread Hans de Goede
Hi Werner,

Once again, sorry for the very slow response here.

On 11/27/23 11:59, Werner Sembach wrote:
> Hi Hans,
> 
> Am 22.11.23 um 19:34 schrieb Hans de Goede:
>> Hi Werner,
> [snip]
> Another idea I want to throw in the mix:
>
> Maybe the kernel is not the right place to implement this at all. RGB 
> stuff is not at all standardized and every vendor is doing completely 
> different interfaces, which does not fit the kernel userpsace apis desire 
> to be uniformal and fixed. e.g. Auxdisplay might fit static setting of 
> RGB values, but it does not fit the snake-effect mode, or the raindrops 
> mode, or the 4-different-colors-in-the-edges-breathing-and-color-cycling 
> mode.
>
> So my current idea: Implement these keyboards as a single zone RGB 
> kbd_backlight in the leds interface to have something functional out of 
> the box, but make it runtime disable-able if something like 
> https://gitlab.com/CalcProgrammer1/OpenRGB wants to take over more fine 
> granular control from userspace via hidraw.
 That sounds like a good approach to me. We are seeing the same with game 
 controllers where steam and wine/proton also sometimes use hidraw mode to 
 get access to all the crazy^W interesting features.

 That would mean that all we need to standardize and the kernel <-> 
 userspace API level is adding a standard way to disable the single zone 
 RGB kbd_backlight support in the kernel.
>>> I would suggest a simple "enable" entry. Default is 1. When set to 0 the 
>>> kernel driver no longer does anything.
>> I'm not in favor of using "enable" as sysfs attribute for this,
>> I would like to see a more descriptive name, how about:
>>
>> "disable_kernel_kbd_backlight_support"
>>
>> And then maybe also have the driver actually unregister
>> the LED class device ?
>>
>> Or just make the support inactive when writing 1 to
>> this and allow re-enabling it by writing 0?
> 
> Unregistering would mean that it can't be reenabled without module 
> reload/reboot?

Yes.

> I would prefer that the userspace driver could easily give back control to 
> the leds interface.

Hmm, the problem here is that leaving a non-working LED class device
behind may confuse things like upower.

So maybe the disable_kbd_backlight_support sysfs attr should
not sit under /sys/class/leds/foobar::kbd_backlight, but rather
it should sit under the sysfs dir of the parent-device ?

So if we are talking [USB|I2C]-HID keyboards and userspace
using hidraw to takeover kbd_backlight control through,
then have "disable_kbd_backlight_support" sit under
/sys/bus/hid/devices/0003::./disable_kbd_backlight_support

and then re-register the LED class device for the keyboard
when 0 gets written to disable_kbd_backlight_support ?

That seems better to me then leaving a non-working LED
class device behind and this will not require any changes
to the LED subsystem.


>>> Questions:
>>>
>>> - Should the driver try to reset the settings to boot default? Or just 
>>> leave the device in the current state? With the former I could see issues 
>>> that they keyboard is flashing when changing from kernelspace control to 
>>> userspace control. With the later the burden on bringing the device to a 
>>> know state lies with the userspace driver.
>> My vote would go to leave the state as is. Even if the hw
>> does not support state readback, then the userspace code
>> can readback the state before writing 1 to
>> "disable_kernel_kbd_backlight_support"
> ack
>>
>>> - Should this be a optional entry that only shows up on drivers supporting 
>>> it, or could this implemented in a generic way affecting all current led 
>>> entries?
>> IMHO this should be optional. If we go with the variant
>> where writing 1 to "disable_kernel_kbd_backlight_support"
>> just disables support and 0 re-enables it then I guess
>> we could have support for this in the LED-core, enabled
>> by a flag set by the driver.
>>
>> If we go with unregistering the led class device,
>> then this needs to be mostly handled in the driver.
>>
>> Either way the kernel driver should know about this even
>> if it is mostly handled in the LED core so that e.g.
>> it does not try to restore settings on resume from suspend.
> 
> So a generic implementation would still require all current led drivers to be 
> touched?
> 
> For the sake of simplicity I would then prefer the optional variant.

See above, I think we need to put the sysfs-attr to disable
the kernel's builtin kbd-backlight support in the parents
sysfs-dir and then actually unregister the LED class device,
this way we don't need any LED subsytem changes at all.

>>> - I guess UPower integration for the userspace driver could be archived 
>>> with https://www.kernel.org/doc/html/latest/leds/uleds.html however this 
>>> limited to brightness atm, so when accent colors actually come to UPower 
>>> this would also need some expansion to be able to pass a preferr

Re: [PATCH 4/4] drm: xlnx: zynqmp_dpsub: Set live video in format

2024-01-17 Thread Tomi Valkeinen

Hi Anatoliy,

On 13/01/2024 01:42, Anatoliy Klymenko wrote:

Live video input format is expected to be set as
"bus-format" property in connected remote endpoint.
Program live video input format DPSUB registers.
Set display layer mode in layer creation context.


Some comments inline below. But one thing to improve is the commit desc.

I think this needs more explanation on what's the issue here. So 
basically something like what's the feature in question, why it's not 
working or what's missing, and what does this patch do to get it working.


And while often it's reasonable to expect some level of understanding of 
the HW in question, it doesn't hurt to give some clarifications on the 
names used (here the "live video input").



Signed-off-by: Anatoliy Klymenko 
---
  drivers/gpu/drm/xlnx/zynqmp_disp.c  | 109 ++--
  drivers/gpu/drm/xlnx/zynqmp_disp.h  |   3 +-
  drivers/gpu/drm/xlnx/zynqmp_disp_regs.h |   8 +-
  drivers/gpu/drm/xlnx/zynqmp_dp.c|   2 +-
  drivers/gpu/drm/xlnx/zynqmp_kms.c   |   2 +-
  5 files changed, 107 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c 
b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index 8a39b3accce5..83af3ad9cdb5 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -20,8 +20,10 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
+#include 


Alphabetical order, please.


  #include "zynqmp_disp.h"
  #include "zynqmp_disp_regs.h"
@@ -67,12 +69,16 @@
  /**
   * struct zynqmp_disp_format - Display subsystem format information
   * @drm_fmt: DRM format (4CC)
+ * @bus_fmt: Live video media bus format
   * @buf_fmt: AV buffer format
   * @swap: Flag to swap R & B for RGB formats, and U & V for YUV formats
   * @sf: Scaling factors for color components
   */
  struct zynqmp_disp_format {
-   u32 drm_fmt;
+   union {
+   u32 drm_fmt;
+   u32 bus_fmt;
+   };
u32 buf_fmt;
bool swap;
const u32 *sf;
@@ -354,6 +360,16 @@ static const struct zynqmp_disp_format avbuf_gfx_fmts[] = {
},
  };
  
+/* TODO: add support for different formats */

+static const struct zynqmp_disp_format avbuf_live_vid_fmts[] = {
+   {
+   .bus_fmt= MEDIA_BUS_FMT_UYVY8_1X16,
+   .buf_fmt= ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_8 |
+ ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV422,
+   .sf = scaling_factors_888,
+   }
+};
+
  static u32 zynqmp_disp_avbuf_read(struct zynqmp_disp *disp, int reg)
  {
return readl(disp->avbuf.base + reg);
@@ -369,6 +385,34 @@ static bool zynqmp_disp_layer_is_video(const struct 
zynqmp_disp_layer *layer)
return layer->id == ZYNQMP_DPSUB_LAYER_VID;
  }
  
+/**

+ * zynqmp_disp_avbuf_set_live_format - Set live input format for a layer
+ * @disp: Display controller
+ * @layer: The layer
+ * @fmt: The format information
+ *
+ * Set the live video input format for @layer to @fmt.
+ */
+static void zynqmp_disp_avbuf_set_live_format(struct zynqmp_disp *disp,
+ struct zynqmp_disp_layer *layer,
+ const struct zynqmp_disp_format 
*fmt)
+{
+   u32 reg, i;
+
+   reg = zynqmp_disp_layer_is_video(layer)
+   ? ZYNQMP_DISP_AV_BUF_LIVE_VID_CONFIG
+   : ZYNQMP_DISP_AV_BUF_LIVE_GFX_CONFIG;
+   zynqmp_disp_avbuf_write(disp, reg, fmt->buf_fmt);
+
+   for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_SF; ++i) {
+   reg = zynqmp_disp_layer_is_video(layer)
+   ? ZYNQMP_DISP_AV_BUF_LIVD_VID_COMP_SF(i)
+   : ZYNQMP_DISP_AV_BUF_LIVD_GFX_COMP_SF(i);
+   zynqmp_disp_avbuf_write(disp, reg, fmt->sf[i]);
+   }
+   layer->disp_fmt = fmt;
+}
+
  /**
   * zynqmp_disp_avbuf_set_format - Set the input format for a layer
   * @disp: Display controller
@@ -902,15 +946,12 @@ u32 *zynqmp_disp_layer_drm_formats(struct 
zynqmp_disp_layer *layer,
  /**
   * zynqmp_disp_layer_enable - Enable a layer
   * @layer: The layer
- * @mode: Operating mode of layer
   *
   * Enable the @layer in the audio/video buffer manager and the blender. DMA
   * channels are started separately by zynqmp_disp_layer_update().
   */
-void zynqmp_disp_layer_enable(struct zynqmp_disp_layer *layer,
- enum zynqmp_dpsub_layer_mode mode)
+void zynqmp_disp_layer_enable(struct zynqmp_disp_layer *layer)
  {
-   layer->mode = mode;
zynqmp_disp_avbuf_enable_video(layer->disp, layer);
zynqmp_disp_blend_layer_enable(layer->disp, layer);
  }
@@ -950,11 +991,12 @@ void zynqmp_disp_layer_set_format(struct 
zynqmp_disp_layer *layer,
layer->disp_fmt = zynqmp_disp_layer_find_format(layer, info->format);
layer->drm_fmt = info;
  
-	zynqmp_disp_avbuf_set_format(layer->disp, layer, layer->disp_fmt);

-
-   if (!layer->disp->dpsub->dma_ena

Re: [PATCH v2 2/3] dt-bindings: atmel, hlcdc: convert pwm bindings to json-schema

2024-01-17 Thread Conor Dooley
On Wed, Jan 17, 2024 at 02:43:00AM +, dharm...@microchip.com wrote:
> On 17/01/24 1:40 am, Alexandre Belloni wrote:
> > EXTERNAL EMAIL: Do not click links or open attachments unless you know the 
> > content is safe
> > 
> > On 16/01/2024 18:03:19+, Conor Dooley wrote:
> >> On Tue, Jan 16, 2024 at 05:07:59PM +0530, Dharma Balasubiramani wrote:
> >>> Convert device tree bindings for Atmel's HLCDC PWM controller to YAML
> >>> format.
> >>>
> >>> Signed-off-by: Dharma Balasubiramani 
> >>> ---
> >>> changelog
> >>> v1 -> v2
> >>> - Remove the explicit copyrights.
> >>> - Modify title (not include words like binding/driver).
> >>> - Modify description actually describing the hardware and not the driver.
> >>> - Remove pinctrl properties which aren't required.
> >>> - Drop parent node and it's other sub-device node which are not related 
> >>> here.
> >>> ---
> >>>   .../bindings/pwm/atmel,hlcdc-pwm.yaml | 47 +++
> >>>   .../bindings/pwm/atmel-hlcdc-pwm.txt  | 29 
> >>>   2 files changed, 47 insertions(+), 29 deletions(-)
> >>>   create mode 100644 
> >>> Documentation/devicetree/bindings/pwm/atmel,hlcdc-pwm.yaml
> >>>   delete mode 100644 
> >>> Documentation/devicetree/bindings/pwm/atmel-hlcdc-pwm.txt
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/pwm/atmel,hlcdc-pwm.yaml 
> >>> b/Documentation/devicetree/bindings/pwm/atmel,hlcdc-pwm.yaml
> >>> new file mode 100644
> >>> index ..751122309fa9
> >>> --- /dev/null
> >>> +++ b/Documentation/devicetree/bindings/pwm/atmel,hlcdc-pwm.yaml
> >>> @@ -0,0 +1,47 @@
> >>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> >>
> >> The original file has no license, but was originally written by a
> >> free-electrons employee, so the relicensing here is fine.
> >>
> > 
> > I confirm relicensing is fine, even assigning the copyright to
> > Microchip (note that Bootlin is legally the same entity as
> > free-electrons)
> Thanks Conor and Alexandre.
> I will add the copyrights back in v3.

Just to note, in case you misunderstood my original comment here:
What I said had nothing to do with adding a Microchip copyright assignment
to the file, but rather about the fact that your patch relicenses the
binding from GPL v2 to GPL v2 OR BSD 2 Clause.


signature.asc
Description: PGP signature


Re: [PATCH v7 2/9] drm/panic: Add a drm panic handler

2024-01-17 Thread Thomas Zimmermann

Hi

Am 04.01.24 um 17:00 schrieb Jocelyn Falempe:
[...]
  
+	/**

+* @get_scanout_buffer:
+*
+* Get the current scanout buffer, to display a panic message with 
drm_panic.
+* The driver should do the minimum changes to provide a linear buffer, 
that
+* can be used to display the panic screen.
+* It is called from a panic callback, and must follow its restrictions.
+* (no locks, no memory allocation, no sleep, no thread/workqueue, ...)
+* It's a best effort mode, so it's expected that in some complex cases 
the
+* panic screen won't be displayed.
+* Some hardware cannot provide a linear buffer, so there is a 
draw_pixel_xy()
+* callback in the struct drm_scanout_buffer that can be used in this 
case.
+*
+* Returns:
+*
+* Zero on success, negative errno on failure.
+*/
+   int (*get_scanout_buffer)(struct drm_device *dev,
+ struct drm_scanout_buffer *sb);
+


After reading through Sima's comments on (try-)locking, I'd like to 
propose a different interface: instead of having the panic handler 
search for the scanout buffer, let each driver explicitly set the 
scanout buffer after each page flip. The algorithm for mode programming 
then looks like this:


 1) Maybe clear the panic handler's buffer at the beginning of 
atomic_commit_tail, if necessary

 2) Do the mode setting as usual
 3) In the driver's atomic_flush or atomic_update, call something like

void drm_panic_set_scanout_buffer(dev, scanout_buffer)

to set the panic handler's new output.

This avoids all the locking and the second guessing about the pipeline 
status.


I don't see an easy way of reliably showing a panic screen during a 
modeset. But during a modeset, the old scanout buffer should 
(theoretically) not disappear until the new scanout buffer is in place. 
So if the panic happens, it would blit to the old address at worst. 
Well, that assumption needs to be verified per driver.


Best regards
Thomas



/** @major: driver major number */
int major;
/** @minor: driver minor number */
diff --git a/include/drm/drm_panic.h b/include/drm/drm_panic.h
new file mode 100644
index ..bcf392b6fa1b
--- /dev/null
+++ b/include/drm/drm_panic.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: GPL-2.0 or MIT */
+#ifndef __DRM_PANIC_H__
+#define __DRM_PANIC_H__
+
+/*
+ * Copyright (c) 2023 Red Hat.
+ * Author: Jocelyn Falempe 
+ */
+
+#include 
+#include 
+#include 
+
+struct drm_device;
+
+/**
+ * struct drm_scanout_buffer - DRM scanout buffer
+ *
+ * This structure holds the information necessary for drm_panic to draw the
+ * panic screen, and display it.
+ * If the driver can't provide a linear buffer, it must clear @map with
+ * iosys_map_clear() and provide a draw_pixel_xy() function.
+ */
+struct drm_scanout_buffer {
+   /**
+* @format:
+*
+* drm format of the scanout buffer.
+*/
+   const struct drm_format_info *format;
+   /**
+* @map:
+*
+* Virtual address of the scanout buffer, either in memory or iomem.
+* The scanout buffer should be in linear format, and can be directly
+* sent to the display hardware. Tearing is not an issue for the panic
+* screen.
+*/
+   struct iosys_map map;
+   /**
+* @width: Width of the scanout buffer, in pixels.
+*/
+   unsigned int width;
+   /**
+* @height: Height of the scanout buffer, in pixels.
+*/
+   unsigned int height;
+   /**
+* @pitch: Length in bytes between the start of two consecutive lines.
+*/
+   unsigned int pitch;
+   /**
+* @private:
+*
+* In case the driver can't provide a linear buffer, this is a pointer 
to
+* some private data, that will be passed when calling @draw_pixel_xy()
+* and @flush()
+*/
+   void *private;
+   /**
+* @draw_pixel_xy:
+*
+* In case the driver can't provide a linear buffer, this is a function
+* that drm_panic will call for each pixel to draw.
+* Color will be converted to the format specified by @format.
+*/
+   void (*draw_pixel_xy)(unsigned int x, unsigned int y, u32 color, void 
*private);
+   /**
+* @flush:
+*
+* This function is called after the panic screen is drawn, either using
+* the iosys_map or the draw_pixel_xy path. In this function, the driver
+* can send additional commands to the hardware, to make the buffer
+* visible.
+*/
+   void (*flush)(void *private);
+};
+
+#ifdef CONFIG_DRM_PANIC
+
+void drm_panic_init(void);
+void drm_panic_exit(void);
+
+void drm_panic_register(struct drm_device *dev);
+void drm_panic_unregister(struct drm_device *dev);
+
+#else
+
+static inline void drm_panic_init(void) {}
+stati

Re: [PATCH 08/11] ARM: dts: DRA7xx: Add device tree entry for SGX GPU

2024-01-17 Thread Andrew Davis

On 1/10/24 2:29 AM, Tony Lindgren wrote:

* Andrew Davis  [240109 17:20]:

--- a/arch/arm/boot/dts/ti/omap/dra7.dtsi
+++ b/arch/arm/boot/dts/ti/omap/dra7.dtsi
@@ -850,12 +850,19 @@ target-module@5600 {
;
ti,sysc-sidle = ,
,
-   ;
+   ,
+   ;


You probably checked this already.. But just in case, can you please
confirm this is intentional. The documentation lists the smart wakeup
capability bit as reserved for dra7, maybe the documentation is wrong.



It was an intentional change, although I'm not sure it is correct :)

This is how we had it in our "evil vendor tree" for years (back when it
was hwmod based), so when converting these nodes to use "ti,sysc" I noticed
this bit was set, but as you point out the documentation disagrees.

I'd rather go with what has worked before, but it doesn't seem to
break anything either way, so we could also break this change out into
its own patch if you would prefer.

Andrew


Regards,

Tony



Re: [PATCH v7 1/9] drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill

2024-01-17 Thread Jocelyn Falempe




On 17/01/2024 16:06, Thomas Zimmermann wrote:

Hi

Am 04.01.24 um 17:00 schrieb Jocelyn Falempe:

This is needed for drm_panic, to draw the font, and fill
the background color, in multiple color format.


TBH, I don't like this patch at all. It looks like you're reimplementing 
existing functionality for a single use case; specifically drm_fb_blit().


What's wrong with the existing interfaces?


drm_fb_blit() is good to copy a framebuffer to another, but is clearly 
unoptimal to draw font.
It handles xrgb to any rgb format, and I need monochrome to any rgb 
format.
I need to convert foreground and background color to the destination 
format, but using drm_fb_blit() to convert 1 pixel is tedious.


It also requires an additional memory buffer, and do an additional 
memory copy that we don't need at all.


It also has no way to fill a region with the background color.

The last thing, is if I plan to add YUV support, with this 
implementation, I only need to write one function that convert one 
pixel. Otherwise I would need to add the drm_fb_r1_to_yuvxxx_line() and 
drm_fb_r1_to_yuv() boilerplate.


Best regards,

--

Jocelyn



Best regards
Thomas



v5:
  * Change the drawing API, use drm_fb_blit_from_r1() to draw the font.
  * Also add drm_fb_fill() to fill area with background color.
v6:
  * fix __le32 conversion warning found by the kernel test bot

Signed-off-by: Jocelyn Falempe 
---
  drivers/gpu/drm/drm_format_helper.c | 432 ++--
  include/drm/drm_format_helper.h |   9 +
  2 files changed, 360 insertions(+), 81 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c

index b1be458ed4dd..8cbc2d747cff 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -111,6 +111,153 @@ void drm_format_conv_state_release(struct 
drm_format_conv_state *state)

  }
  EXPORT_SYMBOL(drm_format_conv_state_release);
+static inline __le16 drm_format_xrgb_to_rgb565(__le32 val32)
+{
+    u16 val16;
+    u32 pix;
+
+    pix = le32_to_cpu(val32);
+    val16 = ((pix & 0x00F8) >> 8) |
+    ((pix & 0xFC00) >> 5) |
+    ((pix & 0x00F8) >> 3);
+    return cpu_to_le16(val16);
+}
+
+static inline __le16 drm_format_xrgb_to_rgba5551(__le32 val32)
+{
+    u16 val16;
+    u32 pix;
+
+    pix = le32_to_cpu(val32);
+    val16 = ((pix & 0x00f8) >> 8) |
+    ((pix & 0xf800) >> 5) |
+    ((pix & 0x00f8) >> 2) |
+    BIT(0); /* set alpha bit */
+    return cpu_to_le16(val16);
+}
+
+static inline __le16 drm_format_xrgb_to_xrgb1555(__le32 val32)
+{
+    u16 val16;
+    u32 pix;
+
+    pix = le32_to_cpu(val32);
+    val16 = ((pix & 0x00f8) >> 9) |
+    ((pix & 0xf800) >> 6) |
+    ((pix & 0x00f8) >> 3);
+    return cpu_to_le16(val16);
+}
+
+static inline __le16 drm_format_xrgb_to_argb1555(__le32 val32)
+{
+    u16 val16;
+    u32 pix;
+
+    pix = le32_to_cpu(val32);
+    val16 = BIT(15) | /* set alpha bit */
+    ((pix & 0x00f8) >> 9) |
+    ((pix & 0xf800) >> 6) |
+    ((pix & 0x00f8) >> 3);
+    return cpu_to_le16(val16);
+}
+
+static inline __le32 drm_format_xrgb_to_argb(__le32 pix)
+{
+    u32 val32;
+
+    val32 = le32_to_cpu(pix);
+    val32 |= GENMASK(31, 24); /* fill alpha bits */
+    return cpu_to_le32(val32);
+}
+
+static inline __le32 drm_format_xrgb_to_xbgr(__le32 pix)
+{
+    u32 val32;
+
+    val32 = le32_to_cpu(pix);
+    val32 = ((val32 & 0x00ff) >> 16) <<  0 |
+    ((val32 & 0xff00) >>  8) <<  8 |
+    ((val32 & 0x00ff) >>  0) << 16 |
+    ((val32 & 0xff00) >> 24) << 24;
+    return cpu_to_le32(val32);
+}
+
+static inline __le32 drm_format_xrgb_to_abgr(__le32 pix)
+{
+    u32 val32;
+
+    val32 = le32_to_cpu(pix);
+    val32 = ((val32 & 0x00ff) >> 16) <<  0 |
+    ((val32 & 0xff00) >>  8) <<  8 |
+    ((val32 & 0x00ff) >>  0) << 16 |
+    GENMASK(31, 24); /* fill alpha bits */
+    return cpu_to_le32(val32);
+}
+
+static inline __le32 drm_format_xrgb_to_xrgb2101010(__le32 pix)
+{
+    u32 val32;
+
+    val32 = le32_to_cpu(pix);
+    val32 = ((val32 & 0x00FF) << 2) |
+    ((val32 & 0xFF00) << 4) |
+    ((val32 & 0x00FF) << 6);
+    return cpu_to_le32(val32 | ((val32 >> 8) & 0x00300C03));
+}
+
+static inline __le32 drm_format_xrgb_to_argb2101010(__le32 pix)
+{
+    u32 val32;
+
+    val32 = le32_to_cpu(pix);
+    val32 = ((val32 & 0x00FF) << 2) |
+    ((val32 & 0xFF00) << 4) |
+    ((val32 & 0x00FF) << 6);
+    val32 = GENMASK(31, 30) | /* set alpha bits */
+  val32 | ((val32 >> 8) & 0x00300c03);
+    return cpu_to_le32(val32);
+}
+
+/**
+ * drm_fb_convert_from_xrgb - convert one pixel from xrgb to 
the desired format

+ * @color: input color, in xrgb format
+ * @format: output format
+ *
+ * Returns:
+ * Color in the format specified, casted to u32.
+ * Or 0 i

Re: [PATCH v7 1/9] drm/format-helper: Add drm_fb_blit_from_r1 and drm_fb_fill

2024-01-17 Thread Jocelyn Falempe




On 17/01/2024 16:26, Jani Nikula wrote:

On Thu, 04 Jan 2024, Jocelyn Falempe  wrote:

This is needed for drm_panic, to draw the font, and fill
the background color, in multiple color format.

v5:
  * Change the drawing API, use drm_fb_blit_from_r1() to draw the font.
  * Also add drm_fb_fill() to fill area with background color.
v6:
  * fix __le32 conversion warning found by the kernel test bot

Signed-off-by: Jocelyn Falempe 
---
  drivers/gpu/drm/drm_format_helper.c | 432 ++--
  include/drm/drm_format_helper.h |   9 +
  2 files changed, 360 insertions(+), 81 deletions(-)

diff --git a/drivers/gpu/drm/drm_format_helper.c 
b/drivers/gpu/drm/drm_format_helper.c
index b1be458ed4dd..8cbc2d747cff 100644
--- a/drivers/gpu/drm/drm_format_helper.c
+++ b/drivers/gpu/drm/drm_format_helper.c
@@ -111,6 +111,153 @@ void drm_format_conv_state_release(struct 
drm_format_conv_state *state)
  }
  EXPORT_SYMBOL(drm_format_conv_state_release);
  
+static inline __le16 drm_format_xrgb_to_rgb565(__le32 val32)


Please don't use inline in C files. Just let the compiler do its job.


Sure, I will remove those inline in next version.

Thanks,

--

Jocelyn



BR,
Jani.


+{
+   u16 val16;
+   u32 pix;
+
+   pix = le32_to_cpu(val32);
+   val16 = ((pix & 0x00F8) >> 8) |
+   ((pix & 0xFC00) >> 5) |
+   ((pix & 0x00F8) >> 3);
+   return cpu_to_le16(val16);
+}
+
+static inline __le16 drm_format_xrgb_to_rgba5551(__le32 val32)
+{
+   u16 val16;
+   u32 pix;
+
+   pix = le32_to_cpu(val32);
+   val16 = ((pix & 0x00f8) >> 8) |
+   ((pix & 0xf800) >> 5) |
+   ((pix & 0x00f8) >> 2) |
+   BIT(0); /* set alpha bit */
+   return cpu_to_le16(val16);
+}
+
+static inline __le16 drm_format_xrgb_to_xrgb1555(__le32 val32)
+{
+   u16 val16;
+   u32 pix;
+
+   pix = le32_to_cpu(val32);
+   val16 = ((pix & 0x00f8) >> 9) |
+   ((pix & 0xf800) >> 6) |
+   ((pix & 0x00f8) >> 3);
+   return cpu_to_le16(val16);
+}
+
+static inline __le16 drm_format_xrgb_to_argb1555(__le32 val32)
+{
+   u16 val16;
+   u32 pix;
+
+   pix = le32_to_cpu(val32);
+   val16 = BIT(15) | /* set alpha bit */
+   ((pix & 0x00f8) >> 9) |
+   ((pix & 0xf800) >> 6) |
+   ((pix & 0x00f8) >> 3);
+   return cpu_to_le16(val16);
+}
+
+static inline __le32 drm_format_xrgb_to_argb(__le32 pix)
+{
+   u32 val32;
+
+   val32 = le32_to_cpu(pix);
+   val32 |= GENMASK(31, 24); /* fill alpha bits */
+   return cpu_to_le32(val32);
+}
+
+static inline __le32 drm_format_xrgb_to_xbgr(__le32 pix)
+{
+   u32 val32;
+
+   val32 = le32_to_cpu(pix);
+   val32 = ((val32 & 0x00ff) >> 16) <<  0 |
+   ((val32 & 0xff00) >>  8) <<  8 |
+   ((val32 & 0x00ff) >>  0) << 16 |
+   ((val32 & 0xff00) >> 24) << 24;
+   return cpu_to_le32(val32);
+}
+
+static inline __le32 drm_format_xrgb_to_abgr(__le32 pix)
+{
+   u32 val32;
+
+   val32 = le32_to_cpu(pix);
+   val32 = ((val32 & 0x00ff) >> 16) <<  0 |
+   ((val32 & 0xff00) >>  8) <<  8 |
+   ((val32 & 0x00ff) >>  0) << 16 |
+   GENMASK(31, 24); /* fill alpha bits */
+   return cpu_to_le32(val32);
+}
+
+static inline __le32 drm_format_xrgb_to_xrgb2101010(__le32 pix)
+{
+   u32 val32;
+
+   val32 = le32_to_cpu(pix);
+   val32 = ((val32 & 0x00FF) << 2) |
+   ((val32 & 0xFF00) << 4) |
+   ((val32 & 0x00FF) << 6);
+   return cpu_to_le32(val32 | ((val32 >> 8) & 0x00300C03));
+}
+
+static inline __le32 drm_format_xrgb_to_argb2101010(__le32 pix)
+{
+   u32 val32;
+
+   val32 = le32_to_cpu(pix);
+   val32 = ((val32 & 0x00FF) << 2) |
+   ((val32 & 0xFF00) << 4) |
+   ((val32 & 0x00FF) << 6);
+   val32 = GENMASK(31, 30) | /* set alpha bits */
+ val32 | ((val32 >> 8) & 0x00300c03);
+   return cpu_to_le32(val32);
+}
+
+/**
+ * drm_fb_convert_from_xrgb - convert one pixel from xrgb to the 
desired format
+ * @color: input color, in xrgb format
+ * @format: output format
+ *
+ * Returns:
+ * Color in the format specified, casted to u32.
+ * Or 0 if the format is unknown.
+ */
+u32 drm_fb_convert_from_xrgb(u32 color, u32 format)
+{
+   __le32 pix = cpu_to_le32(color);
+
+   switch (format) {
+   case DRM_FORMAT_RGB565:
+   return le16_to_cpu(drm_format_xrgb_to_rgb565(pix));
+   case DRM_FORMAT_RGBA5551:
+   return le16_to_cpu(drm_format_xrgb_to_rgba5551(pix));
+   case DRM_FORMAT_XRGB1555:
+   return le16_to_cpu(drm_format_xrgb_to_xrgb1555(pix));
+   case DRM_FORMAT_ARGB1555:
+   return le16_to_cpu(drm_forma

Re: Userspace API for per key backlight for non HID (no hidraw) keyboards

2024-01-17 Thread Hans de Goede
Hi All,

On 11/27/23 11:59, Werner Sembach wrote:



> I also stumbled across a new Problem:
> 
> We have an upcoming device that has a per-key keyboard backlight, but does 
> the control completely via a wmi/acpi interface. So no usable hidraw here for 
> a potential userspace driver implementation ...
> 
> So a quick summary for the ideas floating in this thread so far:
> 
> 1. Expand leds interface allowing arbitrary modes with semi arbitrary 
> optional attributes:
> 
>     - Pro:
> 
>         - Still offers all default attributes for use with UPower
> 
>         - Fairly simple to implement from the preexisting codebase
> 
>         - Could be implemented for all (to me) known internal keyboard 
> backlights
> 
>     - Con:
> 
>         - Violates the simplicity paradigm of the leds interface (e.g. with 
> this one leds entry controls possible multiple leds)

So what you are suggesting here is having some way (a-z + other sysfs attr?)
to use a single LED class device and then extend that to allow setting all
keys ?

This does not seem like a good idea to me and this will also cause issues
when doing animations in software, since this API will likely be slow.

And if the API is not slow, then it will likely involve some sort
of binary sysfs file for setting multiple keys rather then 1
file per key which would break the normal 1 file per setting sysfs
paradigm.

> 2. Implement per-key keyboards as auxdisplay
> 
>     - Pro:
> 
>         - Already has a concept for led positions

With a "concept" you mean simple x,y positioning or is
there something more advanced here that I'm aware of ?

>         - Is conceptually closer to "multiple leds forming a singular entity"
> 
>     - Con:
> 
>         - No preexisting UPower support
> 
>         - No concept for special hardware lightning modes
> 
>         - No support for arbitrary led outlines yet (e.g. ISO style enter-key)

Hmm, so there is very little documentation on this and what
docs there is: Documentation/admin-guide/auxdisplay/cfag12864b.rst
as well as the example program how to uses this suggests that
this is using the old /dev/fb# interface which we are sorta
trying to retire.


> 3. Implement in input subsystem
> 
>     - Pro:
> 
>         - Preexisting concept for keys and key purpose
> 
>     - Con:
> 
>         - Not in scope for subsystem
> 
>         - No other preexisting light infrastructure

Dmitry actually recently nacked the addition of
a LED_MIC_MUTE define to include/uapi/linux/input-event-codes.h
which was intended to be able to allow the input LED support
with standard HID mic-mute leds (spk-mute is already supported
this way).

Dmitry was very clear that no new LEDs must be added and
that any new LED support should be done through the LED
subsytem, so I do not think that something like this
is going to fly.


> 4. Implement a simple leds driver only supporting a small subset of the 
> capabilities and make it disable-able for a userspace driver to take over
> 
>     - Pro:
> 
>         - Most simple to implement basic support
> 
>         - In scope for led subsystem simplicity paradigm
> 
>     - Con:
> 
>         - Not all built in keyboard backlights can be implemented in a 
> userspace only driver

Right, so this is basically what we have been discussing in the other
part of the thread with the:

/sys/bus/hid/devices/0003::./disable_kbd_backlight_support

proposal to unregister the kernel's LED class device and then
allow userspace to do whatever it wants through /dev/hidraw
without the kernel also trying to access the backlight
functionality at the same time.

AFAIK there already is a bunch of userspace support for
per key addressable kbd RGB backlights using hidraw support,
so this way we can use the momentum / code of these existing
projects, at least for existing hidraw keyboards and adding
support for:

/sys/bus/hid/devices/0003::./disable_kbd_backlight_support

to these existing projects should be simple.

Yet this will not work for your mentioned "control completely
via a wmi/acpi interface". Still I think we should go the same
route for those adding a misc-char device or something like
that to allow making WMI calls from userspace (like Windows
can do). Maybe with an allow list per GUID to only allow
specific calls, so that we can avoid possible dangerous calls.

Armin Wolf recently became the WMI bus maintainer.

Armin, we are discussing how to deal with (laptop) keyboards
which have a separate RGB LED per key and how to control
those LEDs.

So far per key addressable keyboard backlighting has always
been HID based, so any existing support is just userspace
based using /dev/hidraw. In my experience the problem with
supporting gaming peripherals is that there is interest in it,
but not really enough interest to keep a sustained momentum
behind projects, especially not when it comes to taking code
from a fun weekend hack to upstreaming them into bigger
projects like the kernel.

So I would like to

Re: [PATCH v2] drm/bridge: parade-ps8640: Ensure bridge is suspended in .post_disable()

2024-01-17 Thread Doug Anderson
Hi,

On Tue, Jan 9, 2024 at 8:52 AM Doug Anderson  wrote:
>
> Hi,
>
> On Tue, Jan 9, 2024 at 4:05 AM Pin-yen Lin  wrote:
> >
> > The ps8640 bridge seems to expect everything to be power cycled at the
> > disable process, but sometimes ps8640_aux_transfer() holds the runtime
> > PM reference and prevents the bridge from suspend.
> >
> > Prevent that by introducing a mutex lock between ps8640_aux_transfer()
> > and .post_disable() to make sure the bridge is really powered off.
> >
> > Fixes: 826cff3f7ebb ("drm/bridge: parade-ps8640: Enable runtime power 
> > management")
> > Signed-off-by: Pin-yen Lin 
> > ---
> >
> > Changes in v2:
> > - Use mutex instead of the completion and autosuspend hack
> >
> >  drivers/gpu/drm/bridge/parade-ps8640.c | 16 
> >  1 file changed, 16 insertions(+)
>
> This looks OK to me now.
>
> Reviewed-by: Douglas Anderson 
>
> I'll let it stew on the mailing list for ~1 week and then land it in
> drm-misc-fixes unless there are additional comments.

Pushed to drm-misc-fixes:

26db46bc9c67 drm/bridge: parade-ps8640: Ensure bridge is suspended in
.post_disable()


Re: [PATCH RFC 0/4] Support for Simulated Panels

2024-01-17 Thread Abhinav Kumar

Hi Jani and Maxime

On 1/17/2024 2:16 AM, Jani Nikula wrote:

On Wed, 17 Jan 2024, Maxime Ripard  wrote:

Hi,

On Tue, Jan 16, 2024 at 02:22:03PM -0800, Jessica Zhang wrote:

This series introduces a simulated MIPI DSI panel.

Currently, the only way to validate DSI connectors is with a physical
panel. Since obtaining physical panels for all possible DSI configurations
is logistically infeasible, introduce a way for DSI drivers to simulate a
panel.

This will be helpful in catching DSI misconfiguration bugs and catching
performance issues for high FPS panels that might not be easily
obtainable.

For now, the simulated panel driver only supports setting customized
modes via the panel_simlation.mode modparam. Eventually, we would like
to add more customizations (such as configuring DSC, dual DSI, etc.).


I think that it's more complicated than it needs to be.


Both too complicated and not complicated enough! :p



The end goal is to have a framework to be able to validate the display 
pipeline with MIPI panels of any resolution , DSC/non-DSC, different 
MIPI flags etc.


Historically, QC has been having an in-house framework to validate the 
panels in a simulated way as its logistically not possible to procure 
every panel from every vendor. This has been working pretty well but its 
not upstream yet. So we would like to work with the community to work on 
a model which works for everyone and this RFC was initiated with that in 
mind.


There is simulation infrastructure in place in upstream for HDMI/DP in 
the form of chamelium based testing in IGT but no such fwk exists for 
DSI displays.


Different MIPI panels and resolutions test out not only the DSI 
controller but the entire display pipeline as based on resolution, 
compression and MIPI mode flags different parts of the pipeline can get 
exercised.



Why do we need to support (and switch to) both the actual and
"simulated" panel?



As per my discussion on IRC with the panel/bridge maintainers and DT 
maintainers, a simulation panel does not qualify for its own devicetree 
as its not a real hardware so we needed to come up with a way to have a 
module which can be attached to the encoder without its own bindings and 
devicetree. Thats what led to this RFC.



Wouldn't it be simpler if we had a vkms-like panel that we could either
configure from DT or from debugfs that would just be registered the
usual way and would be the only panel we register?




No, we need to have validate actual hardware pipeline with the simulated 
panel. With vkms, actual display pipeline will not be validated. With 
incorrect display pipeline misconfigurations arising from different 
panel combinations, this can easily be caught with any existing IGT CRC 
testing. In addition, all performance related bugs can also be easily 
caught by simulating high resolution displays.



I get the idea of trying to test DSI code without panels, and looking at
the goals above, I think your vkms suggestion is going to fall short of
those goals.

However, my gut feeling is that creating a simulated panel to catch DSI
misconfiguration etc. is going to be insanely complicated, and this
series doesn't even scratch the surface.

I guess my questions are, what's the scope here really, are those goals
realistic, does more code already exist beyond this skeleton?




This series is only a starting RFC to be able to validate any display 
mode. This would have to be extended to be able to customize different 
pieces of the panel. Lets talk about the customizable pieces:


1) Display resolution with timings (drm_display_mode)
2) Compression/non-compression
3) Command mode/Video mode
4) MIPI mode flags
5) DCS commands for panel enable/disable and other panel sequences
6) Power-up/Power-down sequence for the panel

Without a physical panel, yes its hard to validate if anything is wrong 
with (4) OR (5), the display might not come up at all visually. But from 
our experience, thats only a small portion and the real benefit of this 
framework will actually be from the validation failures we will catch 
from (1) to (4).


This RFC only provides a way to customize (1) at the moment as we wanted 
to get some feedback from the community about the best way which will 
work for everyone to customize all these parameters.


We are willing to expand this series based on the generic way we agree 
on to customize other params.


Yes, debugfs is an option too. But typically MIPI displays need some 
parameters configured to attach the panel to the encoder. So perhaps we 
can boot the simulation panel with a default resolution passed through 
command line and then across a modeset switch (1) to (4).


Thanks

Abhinav

BR,
Jani.





[PATCH v2] drm/msm/dp: correct configure Colorimetry Indicator Field at MISC0

2024-01-17 Thread Kuogee Hsieh
MSA MISC0 bit 1 to 7 contains Colorimetry Indicator Field. At
current implementation, at DP_TEST_DYNAMIC_RANGE_CEA case the
Colorimetry Indicator Field is mistakenly left shifted one extra
bit. This patch return correct value of colorimetry at
dp_link_get_colorimetry_config() to fix this problem.

Changes in V2:
-- drop retrieving colorimetry from colorspace
-- drop dr = link->dp_link.test_video.test_dyn_range assignment

Fixes: c943b4948b58 ("drm/msm/dp: add displayPort driver support")
Signed-off-by: Kuogee Hsieh 
---
 drivers/gpu/drm/msm/dp/dp_link.c | 11 ++-
 drivers/gpu/drm/msm/dp/dp_link.h |  3 +++
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c
index 98427d4..2e1bdaf 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.c
+++ b/drivers/gpu/drm/msm/dp/dp_link.c
@@ -1082,7 +1082,7 @@ int dp_link_process_request(struct dp_link *dp_link)
 
 int dp_link_get_colorimetry_config(struct dp_link *dp_link)
 {
-   u32 cc;
+   u32 cc = DP_MISC0_LEGACY_RGB;
struct dp_link_private *link;
 
if (!dp_link) {
@@ -1096,10 +1096,11 @@ int dp_link_get_colorimetry_config(struct dp_link 
*dp_link)
 * Unless a video pattern CTS test is ongoing, use RGB_VESA
 * Only RGB_VESA and RGB_CEA supported for now
 */
-   if (dp_link_is_video_pattern_requested(link))
-   cc = link->dp_link.test_video.test_dyn_range;
-   else
-   cc = DP_TEST_DYNAMIC_RANGE_VESA;
+   if (dp_link_is_video_pattern_requested(link)) {
+   if (link->dp_link.test_video.test_dyn_range &
+   DP_TEST_DYNAMIC_RANGE_CEA)
+   cc = DP_MISC0_CEA_RGB;
+   }
 
return cc;
 }
diff --git a/drivers/gpu/drm/msm/dp/dp_link.h b/drivers/gpu/drm/msm/dp/dp_link.h
index 9dd4dd9..fe8f716 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.h
+++ b/drivers/gpu/drm/msm/dp/dp_link.h
@@ -12,6 +12,9 @@
 #define DP_TEST_BIT_DEPTH_UNKNOWN 0x
 #define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0)
 
+#define DP_MISC0_LEGACY_RGB0
+#define DP_MISC0_CEA_RGB   0x04
+
 struct dp_link_info {
unsigned char revision;
unsigned int rate;
-- 
2.7.4



[PATCH] dma-buf: heaps: Don't track CMA dma-buf pages under RssFile

2024-01-17 Thread T.J. Mercier
DMA buffers allocated from the CMA dma-buf heap get counted under
RssFile for processes that map them and trigger page faults. In
addition to the incorrect accounting reported to userspace, reclaim
behavior was influenced by the MM_FILEPAGES counter until linux 6.8, but
this memory is not reclaimable. [1] Change the CMA dma-buf heap to set
VM_PFNMAP on the VMA so MM does not poke at the memory managed by this
dma-buf heap, and use vmf_insert_pfn to correct the RSS accounting.

The system dma-buf heap does not suffer from this issue since
remap_pfn_range is used during the mmap of the buffer, which also sets
VM_PFNMAP on the VMA.

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/mm/vmscan.c?id=fb46e22a9e3863e08aef8815df9f17d0f4b9aede

Fixes: b61614ec318a ("dma-buf: heaps: Add CMA heap to dmabuf heaps")
Signed-off-by: T.J. Mercier 
---
 drivers/dma-buf/heaps/cma_heap.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
index ee899f8e6721..4a63567e93ba 100644
--- a/drivers/dma-buf/heaps/cma_heap.c
+++ b/drivers/dma-buf/heaps/cma_heap.c
@@ -168,10 +168,7 @@ static vm_fault_t cma_heap_vm_fault(struct vm_fault *vmf)
if (vmf->pgoff > buffer->pagecount)
return VM_FAULT_SIGBUS;
 
-   vmf->page = buffer->pages[vmf->pgoff];
-   get_page(vmf->page);
-
-   return 0;
+   return vmf_insert_pfn(vma, vmf->address, 
page_to_pfn(buffer->pages[vmf->pgoff]));
 }
 
 static const struct vm_operations_struct dma_heap_vm_ops = {
@@ -185,6 +182,8 @@ static int cma_heap_mmap(struct dma_buf *dmabuf, struct 
vm_area_struct *vma)
if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
return -EINVAL;
 
+   vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
+
vma->vm_ops = &dma_heap_vm_ops;
vma->vm_private_data = buffer;
 
-- 
2.43.0.381.gb435a96ce8-goog



Re: [PATCH v2] drm/msm/dp: correct configure Colorimetry Indicator Field at MISC0

2024-01-17 Thread Dmitry Baryshkov
On Wed, 17 Jan 2024 at 19:54, Kuogee Hsieh  wrote:
>
> MSA MISC0 bit 1 to 7 contains Colorimetry Indicator Field. At
> current implementation, at DP_TEST_DYNAMIC_RANGE_CEA case the

In the current implementation, in the ... case

> Colorimetry Indicator Field is mistakenly left shifted one extra
> bit.

This doesn't make sense. You say that the value is mistakenly shifted,
but the shift is still in place in dp_catalog_ctrl_config_misc().

> This patch return correct value of colorimetry at
> dp_link_get_colorimetry_config() to fix this problem.

See Documentation/process/submitting-patches.rst#_describe_changes

>
> Changes in V2:
> -- drop retrieving colorimetry from colorspace
> -- drop dr = link->dp_link.test_video.test_dyn_range assignment
>
> Fixes: c943b4948b58 ("drm/msm/dp: add displayPort driver support")
> Signed-off-by: Kuogee Hsieh 
> ---
>  drivers/gpu/drm/msm/dp/dp_link.c | 11 ++-
>  drivers/gpu/drm/msm/dp/dp_link.h |  3 +++
>  2 files changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_link.c 
> b/drivers/gpu/drm/msm/dp/dp_link.c
> index 98427d4..2e1bdaf 100644
> --- a/drivers/gpu/drm/msm/dp/dp_link.c
> +++ b/drivers/gpu/drm/msm/dp/dp_link.c
> @@ -1082,7 +1082,7 @@ int dp_link_process_request(struct dp_link *dp_link)
>
>  int dp_link_get_colorimetry_config(struct dp_link *dp_link)
>  {
> -   u32 cc;
> +   u32 cc = DP_MISC0_LEGACY_RGB;
> struct dp_link_private *link;
>
> if (!dp_link) {
> @@ -1096,10 +1096,11 @@ int dp_link_get_colorimetry_config(struct dp_link 
> *dp_link)
>  * Unless a video pattern CTS test is ongoing, use RGB_VESA
>  * Only RGB_VESA and RGB_CEA supported for now
>  */
> -   if (dp_link_is_video_pattern_requested(link))
> -   cc = link->dp_link.test_video.test_dyn_range;
> -   else
> -   cc = DP_TEST_DYNAMIC_RANGE_VESA;
> +   if (dp_link_is_video_pattern_requested(link)) {
> +   if (link->dp_link.test_video.test_dyn_range &
> +   DP_TEST_DYNAMIC_RANGE_CEA)
> +   cc = DP_MISC0_CEA_RGB;
> +   }
>
> return cc;
>  }
> diff --git a/drivers/gpu/drm/msm/dp/dp_link.h 
> b/drivers/gpu/drm/msm/dp/dp_link.h
> index 9dd4dd9..fe8f716 100644
> --- a/drivers/gpu/drm/msm/dp/dp_link.h
> +++ b/drivers/gpu/drm/msm/dp/dp_link.h
> @@ -12,6 +12,9 @@
>  #define DP_TEST_BIT_DEPTH_UNKNOWN 0x
>  #define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0)
>
> +#define DP_MISC0_LEGACY_RGB0
> +#define DP_MISC0_CEA_RGB   0x04

These should go to dp_reg.h and should start with DP_MISC0_COLORIMETRY_CFG

> +
>  struct dp_link_info {
> unsigned char revision;
> unsigned int rate;
> --
> 2.7.4
>


-- 
With best wishes
Dmitry


Re: [PATCH v1 1/6] drm/lima: fix devfreq refcount imbalance for job timeouts

2024-01-17 Thread Vasily Khoruzhick
On Tue, Jan 16, 2024 at 7:12 PM Erico Nunes  wrote:
>
> In case a task manages to complete but it took just long enough to also
> trigger the timeout handler, the current code results in a refcount
> imbalance on lima_pm_idle.
>
> While this can be a rare occurrence, when it happens it may fill user
> logs with stack traces such as:
>
> [10136.669170] WARNING: CPU: 0 PID: 0 at 
> drivers/gpu/drm/lima/lima_devfreq.c:205 lima_devfreq_record_idle+0xa0/0xb0
> ...
> [10136.669459] pc : lima_devfreq_record_idle+0xa0/0xb0
> ...
> [10136.669628] Call trace:
> [10136.669634]  lima_devfreq_record_idle+0xa0/0xb0
> [10136.669646]  lima_sched_pipe_task_done+0x5c/0xb0
> [10136.669656]  lima_gp_irq_handler+0xa8/0x120
> [10136.669666]  __handle_irq_event_percpu+0x48/0x160
> [10136.669679]  handle_irq_event+0x4c/0xc0
>
> The imbalance happens because lima_sched_pipe_task_done() already calls
> lima_pm_idle for this case if there was no error.
> Check the error flag in the timeout handler to ensure we can never run
> into this case.
>
> Signed-off-by: Erico Nunes 
Reviewed-by: Vasily Khoruzhick 

> ---
>  drivers/gpu/drm/lima/lima_sched.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/lima/lima_sched.c 
> b/drivers/gpu/drm/lima/lima_sched.c
> index c3bf8cda8498..66317296d831 100644
> --- a/drivers/gpu/drm/lima/lima_sched.c
> +++ b/drivers/gpu/drm/lima/lima_sched.c
> @@ -427,7 +427,8 @@ static enum drm_gpu_sched_stat 
> lima_sched_timedout_job(struct drm_sched_job *job
> pipe->current_vm = NULL;
> pipe->current_task = NULL;
>
> -   lima_pm_idle(ldev);
> +   if (pipe->error)
> +   lima_pm_idle(ldev);
>
> drm_sched_resubmit_jobs(&pipe->base);
> drm_sched_start(&pipe->base, true);
> --
> 2.43.0
>


Re: [PATCH v1 2/6] drm/lima: reset async_reset on pp hard reset

2024-01-17 Thread Vasily Khoruzhick
On Tue, Jan 16, 2024 at 7:12 PM Erico Nunes  wrote:
>
> Lima pp jobs use an async reset to avoid having to wait for the soft
> reset right after a job. The soft reset is done at the end of a job and
> a reset_complete flag is expected to be set at the next job.
> However, in case the user runs into a job timeout from any application,
> a hard reset is issued to the hardware. This hard reset clears the
> reset_complete flag, which causes an error message to show up before the
> next job.
> This is probably harmless for the execution but can be very confusing to
> debug, as it blames a reset timeout on the next application to submit a
> job.
> Reset the async_reset flag when doing the hard reset so that we don't
> get that message.
>
> Signed-off-by: Erico Nunes 
Reviewed-by: Vasily Khoruzhick 

> ---
>  drivers/gpu/drm/lima/lima_pp.c | 7 +++
>  1 file changed, 7 insertions(+)
>
> diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c
> index a5c95bed08c0..a8f8f63b8295 100644
> --- a/drivers/gpu/drm/lima/lima_pp.c
> +++ b/drivers/gpu/drm/lima/lima_pp.c
> @@ -191,6 +191,13 @@ static int lima_pp_hard_reset(struct lima_ip *ip)
> pp_write(LIMA_PP_PERF_CNT_0_LIMIT, 0);
> pp_write(LIMA_PP_INT_CLEAR, LIMA_PP_IRQ_MASK_ALL);
> pp_write(LIMA_PP_INT_MASK, LIMA_PP_IRQ_MASK_USED);
> +
> +   /*
> +* if there was an async soft reset queued,
> +* don't wait for it in the next job
> +*/
> +   ip->data.async_reset = false;
> +
> return 0;
>  }
>
> --
> 2.43.0
>


Re: [PATCH v1 3/6] drm/lima: set bus_stop bit before hard reset

2024-01-17 Thread Vasily Khoruzhick
On Tue, Jan 16, 2024 at 7:12 PM Erico Nunes  wrote:
>
> This is required for reliable hard resets. Otherwise, doing a hard reset
> while a task is still running (such as a task which is being stopped by
> the drm_sched timeout handler) may result in random mmu write timeouts
> or lockups which cause the entire gpu to hang.

It looks like Mali driver is doing the same, so it totally makes sense.

> Signed-off-by: Erico Nunes 
Reviewed-by: Vasily Khoruzhick 

> ---
>  drivers/gpu/drm/lima/lima_pp.c | 13 +
>  1 file changed, 13 insertions(+)
>
> diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c
> index a8f8f63b8295..ac097dd75072 100644
> --- a/drivers/gpu/drm/lima/lima_pp.c
> +++ b/drivers/gpu/drm/lima/lima_pp.c
> @@ -168,6 +168,11 @@ static void lima_pp_write_frame(struct lima_ip *ip, u32 
> *frame, u32 *wb)
> }
>  }
>
> +static int lima_pp_bus_stop_poll(struct lima_ip *ip)
> +{
> +   return !!(pp_read(LIMA_PP_STATUS) & LIMA_PP_STATUS_BUS_STOPPED);
> +}
> +
>  static int lima_pp_hard_reset_poll(struct lima_ip *ip)
>  {
> pp_write(LIMA_PP_PERF_CNT_0_LIMIT, 0xC01A);
> @@ -181,6 +186,14 @@ static int lima_pp_hard_reset(struct lima_ip *ip)
>
> pp_write(LIMA_PP_PERF_CNT_0_LIMIT, 0xC0FFE000);
> pp_write(LIMA_PP_INT_MASK, 0);
> +
> +   pp_write(LIMA_PP_CTRL, LIMA_PP_CTRL_STOP_BUS);
> +   ret = lima_poll_timeout(ip, lima_pp_bus_stop_poll, 10, 100);
> +   if (ret) {
> +   dev_err(dev->dev, "pp %s bus stop timeout\n", 
> lima_ip_name(ip));
> +   return ret;
> +   }
> +
> pp_write(LIMA_PP_CTRL, LIMA_PP_CTRL_FORCE_RESET);
> ret = lima_poll_timeout(ip, lima_pp_hard_reset_poll, 10, 100);
> if (ret) {
> --
> 2.43.0
>


Re: [PATCH v1 4/6] drm/lima: handle spurious timeouts due to high irq latency

2024-01-17 Thread Vasily Khoruzhick
On Tue, Jan 16, 2024 at 7:12 PM Erico Nunes  wrote:
>
> There are several unexplained and unreproduced cases of rendering
> timeouts with lima, for which one theory is high IRQ latency coming from
> somewhere else in the system.
> This kind of occurrence may cause applications to trigger unnecessary
> resets of the GPU or even applications to hang if it hits an issue in
> the recovery path.
> Panfrost already does some special handling to account for such
> "spurious timeouts", it makes sense to have this in lima too to reduce
> the chance that it hit users.
>
> Signed-off-by: Erico Nunes 
Reviewed-by: Vasily Khoruzhick 

> ---
>  drivers/gpu/drm/lima/lima_sched.c | 32 ++-
>  drivers/gpu/drm/lima/lima_sched.h |  2 ++
>  2 files changed, 29 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/lima/lima_sched.c 
> b/drivers/gpu/drm/lima/lima_sched.c
> index 66317296d831..9449b81bcd5b 100644
> --- a/drivers/gpu/drm/lima/lima_sched.c
> +++ b/drivers/gpu/drm/lima/lima_sched.c
> @@ -1,6 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0 OR MIT
>  /* Copyright 2017-2019 Qiang Yu  */
>
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -223,10 +224,7 @@ static struct dma_fence *lima_sched_run_job(struct 
> drm_sched_job *job)
>
> task->fence = &fence->base;
>
> -   /* for caller usage of the fence, otherwise irq handler
> -* may consume the fence before caller use it
> -*/
> -   dma_fence_get(task->fence);
> +   task->done_fence = dma_fence_get(task->fence);
>
> pipe->current_task = task;
>
> @@ -401,9 +399,33 @@ static enum drm_gpu_sched_stat 
> lima_sched_timedout_job(struct drm_sched_job *job
> struct lima_sched_pipe *pipe = to_lima_pipe(job->sched);
> struct lima_sched_task *task = to_lima_task(job);
> struct lima_device *ldev = pipe->ldev;
> +   struct lima_ip *ip = pipe->processor[0];
> +
> +   /*
> +* If the GPU managed to complete this jobs fence, the timeout is
> +* spurious. Bail out.
> +*/
> +   if (dma_fence_is_signaled(task->done_fence)) {
> +   DRM_WARN("%s spurious timeout\n", lima_ip_name(ip));
> +   return DRM_GPU_SCHED_STAT_NOMINAL;
> +   }
> +
> +   /*
> +* Lima IRQ handler may take a long time to process an interrupt
> +* if there is another IRQ handler hogging the processing.
> +* In order to catch such cases and not report spurious Lima job
> +* timeouts, synchronize the IRQ handler and re-check the fence
> +* status.
> +*/
> +   synchronize_irq(ip->irq);
> +
> +   if (dma_fence_is_signaled(task->done_fence)) {
> +   DRM_WARN("%s unexpectedly high interrupt latency\n", 
> lima_ip_name(ip));
> +   return DRM_GPU_SCHED_STAT_NOMINAL;
> +   }
>
> if (!pipe->error)
> -   DRM_ERROR("lima job timeout\n");
> +   DRM_ERROR("%s lima job timeout\n", lima_ip_name(ip));
>
> drm_sched_stop(&pipe->base, &task->base);
>
> diff --git a/drivers/gpu/drm/lima/lima_sched.h 
> b/drivers/gpu/drm/lima/lima_sched.h
> index 6a11764d87b3..34050facb110 100644
> --- a/drivers/gpu/drm/lima/lima_sched.h
> +++ b/drivers/gpu/drm/lima/lima_sched.h
> @@ -29,6 +29,8 @@ struct lima_sched_task {
> bool recoverable;
> struct lima_bo *heap;
>
> +   struct dma_fence *done_fence;
> +
> /* pipe fence */
> struct dma_fence *fence;
>  };
> --
> 2.43.0
>


Re: [PATCH v2] drm/msm/dp: correct configure Colorimetry Indicator Field at MISC0

2024-01-17 Thread Kuogee Hsieh



On 1/17/2024 10:12 AM, Dmitry Baryshkov wrote:

On Wed, 17 Jan 2024 at 19:54, Kuogee Hsieh  wrote:

MSA MISC0 bit 1 to 7 contains Colorimetry Indicator Field. At
current implementation, at DP_TEST_DYNAMIC_RANGE_CEA case the

In the current implementation, in the ... case


Colorimetry Indicator Field is mistakenly left shifted one extra
bit.

This doesn't make sense. You say that the value is mistakenly shifted,
but the shift is still in place in dp_catalog_ctrl_config_misc().


The problem is at

 link->dp_link.test_video.test_dyn_range =   (bp & 
DP_TEST_DYNAMIC_RANGE_CEA);   <== this from reading dpcd directly where 
==> DP_TEST_DYNAMIC_RANGE_CEA  is   (1 << 3)


within dp_catalog_ctrl_config_misc(), cc will be left shift one more bit.
so that cc is totally is left shifted 4 bits (bit 4).

at misc0, it should be bit 3 set only for CEA_RGB.




This patch return correct value of colorimetry at
dp_link_get_colorimetry_config() to fix this problem.

See Documentation/process/submitting-patches.rst#_describe_changes


Changes in V2:
-- drop retrieving colorimetry from colorspace
-- drop dr = link->dp_link.test_video.test_dyn_range assignment

Fixes: c943b4948b58 ("drm/msm/dp: add displayPort driver support")
Signed-off-by: Kuogee Hsieh 
---
  drivers/gpu/drm/msm/dp/dp_link.c | 11 ++-
  drivers/gpu/drm/msm/dp/dp_link.h |  3 +++
  2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c
index 98427d4..2e1bdaf 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.c
+++ b/drivers/gpu/drm/msm/dp/dp_link.c
@@ -1082,7 +1082,7 @@ int dp_link_process_request(struct dp_link *dp_link)

  int dp_link_get_colorimetry_config(struct dp_link *dp_link)
  {
-   u32 cc;
+   u32 cc = DP_MISC0_LEGACY_RGB;
 struct dp_link_private *link;

 if (!dp_link) {
@@ -1096,10 +1096,11 @@ int dp_link_get_colorimetry_config(struct dp_link 
*dp_link)
  * Unless a video pattern CTS test is ongoing, use RGB_VESA
  * Only RGB_VESA and RGB_CEA supported for now
  */
-   if (dp_link_is_video_pattern_requested(link))
-   cc = link->dp_link.test_video.test_dyn_range;
-   else
-   cc = DP_TEST_DYNAMIC_RANGE_VESA;
+   if (dp_link_is_video_pattern_requested(link)) {
+   if (link->dp_link.test_video.test_dyn_range &
+   DP_TEST_DYNAMIC_RANGE_CEA)
+   cc = DP_MISC0_CEA_RGB;
+   }

 return cc;
  }
diff --git a/drivers/gpu/drm/msm/dp/dp_link.h b/drivers/gpu/drm/msm/dp/dp_link.h
index 9dd4dd9..fe8f716 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.h
+++ b/drivers/gpu/drm/msm/dp/dp_link.h
@@ -12,6 +12,9 @@
  #define DP_TEST_BIT_DEPTH_UNKNOWN 0x
  #define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0)

+#define DP_MISC0_LEGACY_RGB0
+#define DP_MISC0_CEA_RGB   0x04

These should go to dp_reg.h and should start with DP_MISC0_COLORIMETRY_CFG


+
  struct dp_link_info {
 unsigned char revision;
 unsigned int rate;
--
2.7.4





Re: [PATCH v1 5/6] drm/lima: remove guilty drm_sched context handling

2024-01-17 Thread Vasily Khoruzhick
On Tue, Jan 16, 2024 at 7:12 PM Erico Nunes  wrote:
>
> Marking the context as guilty currently only makes the application which
> hits a single timeout problem to stop its rendering context entirely.
> All jobs submitted later are dropped from the guilty context.
>
> Lima runs on fairly underpowered hardware for modern standards and it is
> not entirely unreasonable that a rendering job may time out occasionally
> due to high system load or too demanding application stack. In this case
> it would be generally preferred to report the error but try to keep the
> application going.
>
> Other similar embedded GPU drivers don't make use of the guilty context
> flag. Now that there are reliability improvements to the lima timeout
> recovery handling, drop the guilty contexts to let the application keep
> running in this case.
>
> Signed-off-by: Erico Nunes 
Reviewed-by: Vasily Khoruzhick 

> ---
>  drivers/gpu/drm/lima/lima_ctx.c   | 2 +-
>  drivers/gpu/drm/lima/lima_ctx.h   | 1 -
>  drivers/gpu/drm/lima/lima_sched.c | 5 ++---
>  drivers/gpu/drm/lima/lima_sched.h | 3 +--
>  4 files changed, 4 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/lima/lima_ctx.c b/drivers/gpu/drm/lima/lima_ctx.c
> index 8389f2d7d021..0e668fc1e0f9 100644
> --- a/drivers/gpu/drm/lima/lima_ctx.c
> +++ b/drivers/gpu/drm/lima/lima_ctx.c
> @@ -19,7 +19,7 @@ int lima_ctx_create(struct lima_device *dev, struct 
> lima_ctx_mgr *mgr, u32 *id)
> kref_init(&ctx->refcnt);
>
> for (i = 0; i < lima_pipe_num; i++) {
> -   err = lima_sched_context_init(dev->pipe + i, ctx->context + 
> i, &ctx->guilty);
> +   err = lima_sched_context_init(dev->pipe + i, ctx->context + 
> i);
> if (err)
> goto err_out0;
> }
> diff --git a/drivers/gpu/drm/lima/lima_ctx.h b/drivers/gpu/drm/lima/lima_ctx.h
> index 74e2be09090f..5b1063ce968b 100644
> --- a/drivers/gpu/drm/lima/lima_ctx.h
> +++ b/drivers/gpu/drm/lima/lima_ctx.h
> @@ -13,7 +13,6 @@ struct lima_ctx {
> struct kref refcnt;
> struct lima_device *dev;
> struct lima_sched_context context[lima_pipe_num];
> -   atomic_t guilty;
>
> /* debug info */
> char pname[TASK_COMM_LEN];
> diff --git a/drivers/gpu/drm/lima/lima_sched.c 
> b/drivers/gpu/drm/lima/lima_sched.c
> index 9449b81bcd5b..496c79713fe8 100644
> --- a/drivers/gpu/drm/lima/lima_sched.c
> +++ b/drivers/gpu/drm/lima/lima_sched.c
> @@ -154,13 +154,12 @@ void lima_sched_task_fini(struct lima_sched_task *task)
>  }
>
>  int lima_sched_context_init(struct lima_sched_pipe *pipe,
> -   struct lima_sched_context *context,
> -   atomic_t *guilty)
> +   struct lima_sched_context *context)
>  {
> struct drm_gpu_scheduler *sched = &pipe->base;
>
> return drm_sched_entity_init(&context->base, 
> DRM_SCHED_PRIORITY_NORMAL,
> -&sched, 1, guilty);
> +&sched, 1, NULL);
>  }
>
>  void lima_sched_context_fini(struct lima_sched_pipe *pipe,
> diff --git a/drivers/gpu/drm/lima/lima_sched.h 
> b/drivers/gpu/drm/lima/lima_sched.h
> index 34050facb110..677e908b53f8 100644
> --- a/drivers/gpu/drm/lima/lima_sched.h
> +++ b/drivers/gpu/drm/lima/lima_sched.h
> @@ -93,8 +93,7 @@ int lima_sched_task_init(struct lima_sched_task *task,
>  void lima_sched_task_fini(struct lima_sched_task *task);
>
>  int lima_sched_context_init(struct lima_sched_pipe *pipe,
> -   struct lima_sched_context *context,
> -   atomic_t *guilty);
> +   struct lima_sched_context *context);
>  void lima_sched_context_fini(struct lima_sched_pipe *pipe,
>  struct lima_sched_context *context);
>  struct dma_fence *lima_sched_context_queue_task(struct lima_sched_task 
> *task);
> --
> 2.43.0
>


Re: [PATCH v1 6/6] drm/lima: improve some pp debug messages

2024-01-17 Thread Vasily Khoruzhick
On Tue, Jan 16, 2024 at 7:12 PM Erico Nunes  wrote:
>
> Make the messages more consistent by showing the pp name.
>
> Signed-off-by: Erico Nunes 
Reviewed-by: Vasily Khoruzhick 

> ---
>  drivers/gpu/drm/lima/lima_pp.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c
> index ac097dd75072..d9e178d6645d 100644
> --- a/drivers/gpu/drm/lima/lima_pp.c
> +++ b/drivers/gpu/drm/lima/lima_pp.c
> @@ -197,7 +197,7 @@ static int lima_pp_hard_reset(struct lima_ip *ip)
> pp_write(LIMA_PP_CTRL, LIMA_PP_CTRL_FORCE_RESET);
> ret = lima_poll_timeout(ip, lima_pp_hard_reset_poll, 10, 100);
> if (ret) {
> -   dev_err(dev->dev, "pp hard reset timeout\n");
> +   dev_err(dev->dev, "pp %s hard reset timeout\n", 
> lima_ip_name(ip));
> return ret;
> }
>
> @@ -423,8 +423,8 @@ static void lima_pp_task_error(struct lima_sched_pipe 
> *pipe)
> for (i = 0; i < pipe->num_processor; i++) {
> struct lima_ip *ip = pipe->processor[i];
>
> -   dev_err(ip->dev->dev, "pp task error %d int_state=%x 
> status=%x\n",
> -   i, pp_read(LIMA_PP_INT_STATUS), 
> pp_read(LIMA_PP_STATUS));
> +   dev_err(ip->dev->dev, "pp %s task error int_state=%x 
> status=%x\n",
> +   lima_ip_name(ip), pp_read(LIMA_PP_INT_STATUS), 
> pp_read(LIMA_PP_STATUS));
>
> lima_pp_hard_reset(ip);
> }
> --
> 2.43.0
>


[PATCH] drm/bridge: parade-ps8640: Make sure we drop the AUX mutex in the error case

2024-01-17 Thread Douglas Anderson
After commit 26db46bc9c67 ("drm/bridge: parade-ps8640: Ensure bridge
is suspended in .post_disable()"), if we hit the error case in
ps8640_aux_transfer() then we return without dropping the mutex. Fix
this oversight.

Fixes: 26db46bc9c67 ("drm/bridge: parade-ps8640: Ensure bridge is suspended in 
.post_disable()")
Signed-off-by: Douglas Anderson 
---
Sorry for missing this in my review! :( Given that this is really
simple and I'd rather the buggy commit not be there for long, if I can
get a quick Reviewed-by tag on this patch I'll land it without the
typical stewing period.

 drivers/gpu/drm/bridge/parade-ps8640.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c 
b/drivers/gpu/drm/bridge/parade-ps8640.c
index 166bfc725ef4..14d4dcf239da 100644
--- a/drivers/gpu/drm/bridge/parade-ps8640.c
+++ b/drivers/gpu/drm/bridge/parade-ps8640.c
@@ -351,11 +351,13 @@ static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux,
ret = _ps8640_wait_hpd_asserted(ps_bridge, 200 * 1000);
if (ret) {
pm_runtime_put_sync_suspend(dev);
-   return ret;
+   goto exit;
}
ret = ps8640_aux_transfer_msg(aux, msg);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
+
+exit:
mutex_unlock(&ps_bridge->aux_lock);
 
return ret;
-- 
2.43.0.381.gb435a96ce8-goog



Re: [PATCH v2] drm/bridge: parade-ps8640: Ensure bridge is suspended in .post_disable()

2024-01-17 Thread Doug Anderson
Hi,

On Wed, Jan 17, 2024 at 9:34 AM Doug Anderson  wrote:
>
> Hi,
>
> On Tue, Jan 9, 2024 at 8:52 AM Doug Anderson  wrote:
> >
> > Hi,
> >
> > On Tue, Jan 9, 2024 at 4:05 AM Pin-yen Lin  wrote:
> > >
> > > The ps8640 bridge seems to expect everything to be power cycled at the
> > > disable process, but sometimes ps8640_aux_transfer() holds the runtime
> > > PM reference and prevents the bridge from suspend.
> > >
> > > Prevent that by introducing a mutex lock between ps8640_aux_transfer()
> > > and .post_disable() to make sure the bridge is really powered off.
> > >
> > > Fixes: 826cff3f7ebb ("drm/bridge: parade-ps8640: Enable runtime power 
> > > management")
> > > Signed-off-by: Pin-yen Lin 
> > > ---
> > >
> > > Changes in v2:
> > > - Use mutex instead of the completion and autosuspend hack
> > >
> > >  drivers/gpu/drm/bridge/parade-ps8640.c | 16 
> > >  1 file changed, 16 insertions(+)
> >
> > This looks OK to me now.
> >
> > Reviewed-by: Douglas Anderson 
> >
> > I'll let it stew on the mailing list for ~1 week and then land it in
> > drm-misc-fixes unless there are additional comments.
>
> Pushed to drm-misc-fixes:
>
> 26db46bc9c67 drm/bridge: parade-ps8640: Ensure bridge is suspended in
> .post_disable()

Crud. I landed this and then almost immediately hit a bug with it. :(
I've posted up the fix:

https://lore.kernel.org/r/20240117103502.1.Ib726a0184913925efc7e99c4d4fc801982e1bc24@changeid

-Doug


Re: [PATCH v2] drm/msm/dp: correct configure Colorimetry Indicator Field at MISC0

2024-01-17 Thread Dmitry Baryshkov
On Wed, 17 Jan 2024 at 20:29, Kuogee Hsieh  wrote:
>
>
> On 1/17/2024 10:12 AM, Dmitry Baryshkov wrote:
> > On Wed, 17 Jan 2024 at 19:54, Kuogee Hsieh  wrote:
> >> MSA MISC0 bit 1 to 7 contains Colorimetry Indicator Field. At
> >> current implementation, at DP_TEST_DYNAMIC_RANGE_CEA case the
> > In the current implementation, in the ... case
> >
> >> Colorimetry Indicator Field is mistakenly left shifted one extra
> >> bit.
> > This doesn't make sense. You say that the value is mistakenly shifted,
> > but the shift is still in place in dp_catalog_ctrl_config_misc().
>
> The problem is at
>
>   link->dp_link.test_video.test_dyn_range =   (bp &
> DP_TEST_DYNAMIC_RANGE_CEA);   <== this from reading dpcd directly where
> ==> DP_TEST_DYNAMIC_RANGE_CEA  is   (1 << 3)
>
> within dp_catalog_ctrl_config_misc(), cc will be left shift one more bit.
> so that cc is totally is left shifted 4 bits (bit 4).
>
> at misc0, it should be bit 3 set only for CEA_RGB.

Yes. But your patch doesn't fix the shift (which is correct). You
patch fixes the value being written to that field.

>
> >
> >> This patch return correct value of colorimetry at
> >> dp_link_get_colorimetry_config() to fix this problem.
> > See Documentation/process/submitting-patches.rst#_describe_changes
> >
> >> Changes in V2:
> >> -- drop retrieving colorimetry from colorspace
> >> -- drop dr = link->dp_link.test_video.test_dyn_range assignment
> >>
> >> Fixes: c943b4948b58 ("drm/msm/dp: add displayPort driver support")
> >> Signed-off-by: Kuogee Hsieh 
> >> ---
> >>   drivers/gpu/drm/msm/dp/dp_link.c | 11 ++-
> >>   drivers/gpu/drm/msm/dp/dp_link.h |  3 +++
> >>   2 files changed, 9 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/msm/dp/dp_link.c 
> >> b/drivers/gpu/drm/msm/dp/dp_link.c
> >> index 98427d4..2e1bdaf 100644
> >> --- a/drivers/gpu/drm/msm/dp/dp_link.c
> >> +++ b/drivers/gpu/drm/msm/dp/dp_link.c
> >> @@ -1082,7 +1082,7 @@ int dp_link_process_request(struct dp_link *dp_link)
> >>
> >>   int dp_link_get_colorimetry_config(struct dp_link *dp_link)
> >>   {
> >> -   u32 cc;
> >> +   u32 cc = DP_MISC0_LEGACY_RGB;
> >>  struct dp_link_private *link;
> >>
> >>  if (!dp_link) {
> >> @@ -1096,10 +1096,11 @@ int dp_link_get_colorimetry_config(struct dp_link 
> >> *dp_link)
> >>   * Unless a video pattern CTS test is ongoing, use RGB_VESA
> >>   * Only RGB_VESA and RGB_CEA supported for now
> >>   */
> >> -   if (dp_link_is_video_pattern_requested(link))
> >> -   cc = link->dp_link.test_video.test_dyn_range;
> >> -   else
> >> -   cc = DP_TEST_DYNAMIC_RANGE_VESA;
> >> +   if (dp_link_is_video_pattern_requested(link)) {
> >> +   if (link->dp_link.test_video.test_dyn_range &
> >> +   DP_TEST_DYNAMIC_RANGE_CEA)
> >> +   cc = DP_MISC0_CEA_RGB;
> >> +   }
> >>
> >>  return cc;
> >>   }
> >> diff --git a/drivers/gpu/drm/msm/dp/dp_link.h 
> >> b/drivers/gpu/drm/msm/dp/dp_link.h
> >> index 9dd4dd9..fe8f716 100644
> >> --- a/drivers/gpu/drm/msm/dp/dp_link.h
> >> +++ b/drivers/gpu/drm/msm/dp/dp_link.h
> >> @@ -12,6 +12,9 @@
> >>   #define DP_TEST_BIT_DEPTH_UNKNOWN 0x
> >>   #define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0)
> >>
> >> +#define DP_MISC0_LEGACY_RGB0
> >> +#define DP_MISC0_CEA_RGB   0x04
> > These should go to dp_reg.h and should start with DP_MISC0_COLORIMETRY_CFG
> >
> >> +
> >>   struct dp_link_info {
> >>  unsigned char revision;
> >>  unsigned int rate;
> >> --
> >> 2.7.4
> >>
> >



-- 
With best wishes
Dmitry


[PATCH 1/2] tracing, dma-buf: add a trace_dma_fence_sync_to event

2024-01-17 Thread Pierre-Eric Pelloux-Prayer
This new event can be used to trace where a given dma_fence is added
as a dependency of some other work.

I plan to use it in amdgpu.

Signed-off-by: Pierre-Eric Pelloux-Prayer 
---
 drivers/dma-buf/dma-fence.c  |  1 +
 include/trace/events/dma_fence.h | 34 
 2 files changed, 35 insertions(+)

diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index e0fd99e61a2d..671a499a5ccd 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -23,6 +23,7 @@
 EXPORT_TRACEPOINT_SYMBOL(dma_fence_emit);
 EXPORT_TRACEPOINT_SYMBOL(dma_fence_enable_signal);
 EXPORT_TRACEPOINT_SYMBOL(dma_fence_signaled);
+EXPORT_TRACEPOINT_SYMBOL(dma_fence_sync_to);
 
 static DEFINE_SPINLOCK(dma_fence_stub_lock);
 static struct dma_fence dma_fence_stub;
diff --git a/include/trace/events/dma_fence.h b/include/trace/events/dma_fence.h
index 3963e79ca7b4..9b3875f7aa79 100644
--- a/include/trace/events/dma_fence.h
+++ b/include/trace/events/dma_fence.h
@@ -83,6 +83,40 @@ DEFINE_EVENT(dma_fence, dma_fence_wait_end,
TP_ARGS(fence)
 );
 
+DECLARE_EVENT_CLASS(dma_fence_from,
+
+   TP_PROTO(struct dma_fence *fence, const char *reason),
+
+   TP_ARGS(fence, reason),
+
+   TP_STRUCT__entry(
+   __string(driver, fence->ops->get_driver_name(fence))
+   __string(timeline, fence->ops->get_timeline_name(fence))
+   __field(unsigned int, context)
+   __field(unsigned int, seqno)
+   __string(reason, reason)
+   ),
+
+   TP_fast_assign(
+   __assign_str(driver, fence->ops->get_driver_name(fence));
+   __assign_str(timeline, fence->ops->get_timeline_name(fence));
+   __entry->context = fence->context;
+   __entry->seqno = fence->seqno;
+   __assign_str(reason, reason);
+   ),
+
+   TP_printk("driver=%s timeline=%s context=%u seqno=%u reason=%s",
+ __get_str(driver), __get_str(timeline), __entry->context,
+ __entry->seqno, __get_str(reason))
+);
+
+DEFINE_EVENT(dma_fence_from, dma_fence_sync_to,
+
+   TP_PROTO(struct dma_fence *fence, const char *reason),
+
+   TP_ARGS(fence, reason)
+);
+
 #endif /*  _TRACE_DMA_FENCE_H */
 
 /* This part must be outside protection */
-- 
2.40.1



[PATCH 2/2] amdgpu: use trace_dma_fence_sync_to in amdgpu_fence_sync

2024-01-17 Thread Pierre-Eric Pelloux-Prayer
This makes it possible to understand the dependencies between jobs.
Possible usage of this trace:
* stuttering issues like Mesa !9189
* incorrect synchronization: I don't have a link for this one, but having
  these events was very useful to debug a virtio-gpu / native-context /
  radeonsi sync issue

I have prototype code using this in UMR, as can be see here:
   https://gitlab.freedesktop.org/tomstdenis/umr/-/merge_requests/37

The 'reason' param currently uses __func__ but I didn't add a macro for
this because it'd be interesting to use more descriptive names for each
use of amdgpu_fence_sync.

Signed-off-by: Pierre-Eric Pelloux-Prayer 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c |  8 
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c   | 14 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c  |  8 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c  |  4 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 11 ---
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h |  3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c |  4 ++--
 7 files changed, 28 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index d17b2452cb1f..fde98e48c84b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -491,7 +491,7 @@ static int vm_update_pds(struct amdgpu_vm *vm, struct 
amdgpu_sync *sync)
if (ret)
return ret;
 
-   return amdgpu_sync_fence(sync, vm->last_update);
+   return amdgpu_sync_fence(sync, vm->last_update, __func__);
 }
 
 static uint64_t get_pte_flags(struct amdgpu_device *adev, struct kgd_mem *mem)
@@ -1251,7 +1251,7 @@ static void unmap_bo_from_gpuvm(struct kgd_mem *mem,
 
amdgpu_vm_clear_freed(adev, vm, &bo_va->last_pt_update);
 
-   amdgpu_sync_fence(sync, bo_va->last_pt_update);
+   amdgpu_sync_fence(sync, bo_va->last_pt_update, __func__);
 }
 
 static int update_gpuvm_pte(struct kgd_mem *mem,
@@ -1273,7 +1273,7 @@ static int update_gpuvm_pte(struct kgd_mem *mem,
return ret;
}
 
-   return amdgpu_sync_fence(sync, bo_va->last_pt_update);
+   return amdgpu_sync_fence(sync, bo_va->last_pt_update, __func__);
 }
 
 static int map_bo_to_gpuvm(struct kgd_mem *mem,
@@ -2910,7 +2910,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, 
struct dma_fence **ef)
}
dma_resv_for_each_fence(&cursor, bo->tbo.base.resv,
DMA_RESV_USAGE_KERNEL, fence) {
-   ret = amdgpu_sync_fence(&sync_obj, fence);
+   ret = amdgpu_sync_fence(&sync_obj, fence, __func__);
if (ret) {
pr_debug("Memory eviction: Sync BO fence 
failed. Try again\n");
goto validate_map_fail;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 6adeddfb3d56..6830892383c3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -423,7 +423,7 @@ static int amdgpu_cs_p2_dependencies(struct 
amdgpu_cs_parser *p,
dma_fence_put(old);
}
 
-   r = amdgpu_sync_fence(&p->sync, fence);
+   r = amdgpu_sync_fence(&p->sync, fence, __func__);
dma_fence_put(fence);
if (r)
return r;
@@ -445,7 +445,7 @@ static int amdgpu_syncobj_lookup_and_add(struct 
amdgpu_cs_parser *p,
return r;
}
 
-   r = amdgpu_sync_fence(&p->sync, fence);
+   r = amdgpu_sync_fence(&p->sync, fence, __func__);
dma_fence_put(fence);
return r;
 }
@@ -1101,7 +1101,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser 
*p)
if (r)
return r;
 
-   r = amdgpu_sync_fence(&p->sync, fpriv->prt_va->last_pt_update);
+   r = amdgpu_sync_fence(&p->sync, fpriv->prt_va->last_pt_update, 
__func__);
if (r)
return r;
 
@@ -1112,7 +1112,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser 
*p)
if (r)
return r;
 
-   r = amdgpu_sync_fence(&p->sync, bo_va->last_pt_update);
+   r = amdgpu_sync_fence(&p->sync, bo_va->last_pt_update, 
__func__);
if (r)
return r;
}
@@ -1131,7 +1131,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser 
*p)
if (r)
return r;
 
-   r = amdgpu_sync_fence(&p->sync, bo_va->last_pt_update);
+   r = amdgpu_sync_fence(&p->sync, bo_va->last_pt_update, 
__func__);
if (r)
return r;
}
@@ -1144,7 +1144,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser 
*p)
   

Re: [PATCH v2] drm/msm/dp: correct configure Colorimetry Indicator Field at MISC0

2024-01-17 Thread Kuogee Hsieh



On 1/17/2024 10:40 AM, Dmitry Baryshkov wrote:

On Wed, 17 Jan 2024 at 20:29, Kuogee Hsieh  wrote:


On 1/17/2024 10:12 AM, Dmitry Baryshkov wrote:

On Wed, 17 Jan 2024 at 19:54, Kuogee Hsieh  wrote:

MSA MISC0 bit 1 to 7 contains Colorimetry Indicator Field. At
current implementation, at DP_TEST_DYNAMIC_RANGE_CEA case the

In the current implementation, in the ... case


Colorimetry Indicator Field is mistakenly left shifted one extra
bit.

This doesn't make sense. You say that the value is mistakenly shifted,
but the shift is still in place in dp_catalog_ctrl_config_misc().

The problem is at

   link->dp_link.test_video.test_dyn_range =   (bp &
DP_TEST_DYNAMIC_RANGE_CEA);   <== this from reading dpcd directly where
==> DP_TEST_DYNAMIC_RANGE_CEA  is   (1 << 3)

within dp_catalog_ctrl_config_misc(), cc will be left shift one more bit.
so that cc is totally is left shifted 4 bits (bit 4).

at misc0, it should be bit 3 set only for CEA_RGB.

Yes. But your patch doesn't fix the shift (which is correct). You
patch fixes the value being written to that field.

ok, i will rewording the commit test



This patch return correct value of colorimetry at
dp_link_get_colorimetry_config() to fix this problem.

See Documentation/process/submitting-patches.rst#_describe_changes


Changes in V2:
-- drop retrieving colorimetry from colorspace
-- drop dr = link->dp_link.test_video.test_dyn_range assignment

Fixes: c943b4948b58 ("drm/msm/dp: add displayPort driver support")
Signed-off-by: Kuogee Hsieh 
---
   drivers/gpu/drm/msm/dp/dp_link.c | 11 ++-
   drivers/gpu/drm/msm/dp/dp_link.h |  3 +++
   2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c
index 98427d4..2e1bdaf 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.c
+++ b/drivers/gpu/drm/msm/dp/dp_link.c
@@ -1082,7 +1082,7 @@ int dp_link_process_request(struct dp_link *dp_link)

   int dp_link_get_colorimetry_config(struct dp_link *dp_link)
   {
-   u32 cc;
+   u32 cc = DP_MISC0_LEGACY_RGB;
  struct dp_link_private *link;

  if (!dp_link) {
@@ -1096,10 +1096,11 @@ int dp_link_get_colorimetry_config(struct dp_link 
*dp_link)
   * Unless a video pattern CTS test is ongoing, use RGB_VESA
   * Only RGB_VESA and RGB_CEA supported for now
   */
-   if (dp_link_is_video_pattern_requested(link))
-   cc = link->dp_link.test_video.test_dyn_range;
-   else
-   cc = DP_TEST_DYNAMIC_RANGE_VESA;
+   if (dp_link_is_video_pattern_requested(link)) {
+   if (link->dp_link.test_video.test_dyn_range &
+   DP_TEST_DYNAMIC_RANGE_CEA)
+   cc = DP_MISC0_CEA_RGB;
+   }

  return cc;
   }
diff --git a/drivers/gpu/drm/msm/dp/dp_link.h b/drivers/gpu/drm/msm/dp/dp_link.h
index 9dd4dd9..fe8f716 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.h
+++ b/drivers/gpu/drm/msm/dp/dp_link.h
@@ -12,6 +12,9 @@
   #define DP_TEST_BIT_DEPTH_UNKNOWN 0x
   #define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0)

+#define DP_MISC0_LEGACY_RGB0
+#define DP_MISC0_CEA_RGB   0x04

These should go to dp_reg.h and should start with DP_MISC0_COLORIMETRY_CFG


+
   struct dp_link_info {
  unsigned char revision;
  unsigned int rate;
--
2.7.4






Re: [PATCH] drm/msm/adreno: Add a null pointer check in zap_shader_load_mdt()

2024-01-17 Thread Markus Elfring
> kasprintf() returns a pointer to dynamically allocated memory
> which can be NULL upon failure. Ensure the allocation was successful
> by checking the pointer validity.
…
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> @@ -144,6 +144,10 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, 
> const char *fwname,
>   char *newname;
>
>   newname = kasprintf(GFP_KERNEL, "qcom/%s", fwname);
> + if (!newname) {
> + ret = -ENOMEM;
> + goto out;
> + }
…

How do you think about to avoid the repetition of the pointer check
for the variable “mem_region”?
Can the usage of other labels become more appropriate?

Regards,
Markus


Re: [PATCH] drm/bridge: parade-ps8640: Make sure we drop the AUX mutex in the error case

2024-01-17 Thread Hsin-Yi Wang
On Wed, Jan 17, 2024 at 10:35 AM Douglas Anderson  wrote:
>
> After commit 26db46bc9c67 ("drm/bridge: parade-ps8640: Ensure bridge
> is suspended in .post_disable()"), if we hit the error case in
> ps8640_aux_transfer() then we return without dropping the mutex. Fix
> this oversight.
>
> Fixes: 26db46bc9c67 ("drm/bridge: parade-ps8640: Ensure bridge is suspended 
> in .post_disable()")
> Signed-off-by: Douglas Anderson 
> ---
> Sorry for missing this in my review! :( Given that this is really
> simple and I'd rather the buggy commit not be there for long, if I can
> get a quick Reviewed-by tag on this patch I'll land it without the
> typical stewing period.
>

Reviewed-by: Hsin-Yi Wang 

>  drivers/gpu/drm/bridge/parade-ps8640.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c 
> b/drivers/gpu/drm/bridge/parade-ps8640.c
> index 166bfc725ef4..14d4dcf239da 100644
> --- a/drivers/gpu/drm/bridge/parade-ps8640.c
> +++ b/drivers/gpu/drm/bridge/parade-ps8640.c
> @@ -351,11 +351,13 @@ static ssize_t ps8640_aux_transfer(struct drm_dp_aux 
> *aux,
> ret = _ps8640_wait_hpd_asserted(ps_bridge, 200 * 1000);
> if (ret) {
> pm_runtime_put_sync_suspend(dev);
> -   return ret;
> +   goto exit;
> }
> ret = ps8640_aux_transfer_msg(aux, msg);
> pm_runtime_mark_last_busy(dev);
> pm_runtime_put_autosuspend(dev);
> +
> +exit:
> mutex_unlock(&ps_bridge->aux_lock);
>
> return ret;
> --
> 2.43.0.381.gb435a96ce8-goog
>


[PATCH] drm/msm/dpu: check for valid hw_pp in dpu_encoder_helper_phys_cleanup

2024-01-17 Thread Abhinav Kumar
The commit 8b45a26f2ba9 ("drm/msm/dpu: reserve cdm blocks for writeback
in case of YUV output") introduced a smatch warning about another
conditional block in dpu_encoder_helper_phys_cleanup() which had assumed
hw_pp will always be valid which may not necessarily be true.

Lets fix the other conditional block by making sure hw_pp is valid
before dereferencing it.

Reported-by: Dan Carpenter 
Fixes: ae4d721ce100 ("drm/msm/dpu: add an API to reset the encoder related hw 
blocks")
Signed-off-by: Abhinav Kumar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 83380bc92a00..282d84c872f2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2072,7 +2072,7 @@ void dpu_encoder_helper_phys_cleanup(struct 
dpu_encoder_phys *phys_enc)
}
 
/* reset the merge 3D HW block */
-   if (phys_enc->hw_pp->merge_3d) {
+   if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) {

phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
BLEND_3D_NONE);
if (phys_enc->hw_ctl->ops.update_pending_flush_merge_3d)
@@ -2103,7 +2103,7 @@ void dpu_encoder_helper_phys_cleanup(struct 
dpu_encoder_phys *phys_enc)
if (phys_enc->hw_wb)
intf_cfg.wb = phys_enc->hw_wb->idx;
 
-   if (phys_enc->hw_pp->merge_3d)
+   if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d)
intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
 
if (ctl->ops.reset_intf_cfg)
-- 
2.40.1



Re: [PATCH v3,04/21] v4l: add documentation for secure memory flag

2024-01-17 Thread Nicolas Dufresne
Hi,

Le mercredi 06 décembre 2023 à 16:15 +0800, Yunfei Dong a écrit :
> From: Jeffrey Kardatzke 
> 
> Adds documentation for V4L2_MEMORY_FLAG_SECURE.

As I noticed from DMA Heap discussions, shall this also be renamed SECURE ->
RESTRICTED ?

regards,
Nicolas

> 
> Signed-off-by: Jeffrey Kardatzke 
> Signed-off-by: Yunfei Dong 
> ---
>  Documentation/userspace-api/media/v4l/buffer.rst | 8 +++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/userspace-api/media/v4l/buffer.rst 
> b/Documentation/userspace-api/media/v4l/buffer.rst
> index 52bbee81c080..a5a7d1c72d53 100644
> --- a/Documentation/userspace-api/media/v4l/buffer.rst
> +++ b/Documentation/userspace-api/media/v4l/buffer.rst
> @@ -696,7 +696,7 @@ enum v4l2_memory
>  
>  .. _memory-flags:
>  
> -Memory Consistency Flags
> +Memory Flags
>  
>  
>  .. raw:: latex
> @@ -728,6 +728,12 @@ Memory Consistency Flags
>   only if the buffer is used for :ref:`memory mapping ` I/O and the
>   queue reports the :ref:`V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS
>   ` capability.
> +* .. _`V4L2-MEMORY-FLAG-SECURE`:
> +
> +  - ``V4L2_MEMORY_FLAG_SECURE``
> +  - 0x0002
> +  - DMA bufs passed into the queue will be validated to ensure they were
> + allocated from a secure dma-heap.
>  
>  .. raw:: latex
>  



Re: [PATCH] drm/bridge: parade-ps8640: Make sure we drop the AUX mutex in the error case

2024-01-17 Thread Doug Anderson
Hi,

On Wed, Jan 17, 2024 at 11:39 AM Hsin-Yi Wang  wrote:
>
> On Wed, Jan 17, 2024 at 10:35 AM Douglas Anderson  
> wrote:
> >
> > After commit 26db46bc9c67 ("drm/bridge: parade-ps8640: Ensure bridge
> > is suspended in .post_disable()"), if we hit the error case in
> > ps8640_aux_transfer() then we return without dropping the mutex. Fix
> > this oversight.
> >
> > Fixes: 26db46bc9c67 ("drm/bridge: parade-ps8640: Ensure bridge is suspended 
> > in .post_disable()")
> > Signed-off-by: Douglas Anderson 
> > ---
> > Sorry for missing this in my review! :( Given that this is really
> > simple and I'd rather the buggy commit not be there for long, if I can
> > get a quick Reviewed-by tag on this patch I'll land it without the
> > typical stewing period.
> >
>
> Reviewed-by: Hsin-Yi Wang 

Thanks! I've pushed this to avoid the breakage. If any additional
follow up comes up I'm happy to post additional patches.

a20f1b02bafc drm/bridge: parade-ps8640: Make sure we drop the AUX
mutex in the error case


-Doug


Re: [RFC PATCH 1/3] dt-bindings: display: ti,am65x-dss: Add support for display sharing mode

2024-01-17 Thread Rob Herring
On Tue, Jan 16, 2024 at 07:11:40PM +0530, Devarsh Thakkar wrote:
> Add support for using TI Keystone DSS hardware present in display
> sharing mode.
> 
> TI Keystone DSS hardware supports partitioning of resources between
> multiple hosts as it provides separate register space and unique
> interrupt line to each host.
> 
> The DSS hardware can be used in shared mode in such a way that one or
> more of video planes can be owned by Linux wherease other planes can be
> owned by remote cores.
> 
> One or more of the video ports can be dedicated exclusively to a
> processing core, wherease some of the video ports can be shared between
> two hosts too with only one of them having write access.
> 
> Signed-off-by: Devarsh Thakkar 
> ---
>  .../bindings/display/ti/ti,am65x-dss.yaml | 82 +++
>  1 file changed, 82 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml 
> b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> index 55e3e490d0e6..d9bc69fbf1fb 100644
> --- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> +++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> @@ -112,6 +112,86 @@ properties:
>Input memory (from main memory to dispc) bandwidth limit in
>bytes per second
>  
> +  ti,dss-shared-mode:
> +type: boolean
> +description:
> +  TI DSS7 supports sharing of display between multiple hosts
> +  as it provides separate register space for display configuration and
> +  unique interrupt line to each host.

If you care about line breaks, you need '|'. 

> +  One of the host is provided access to the global display
> +  configuration labelled as "common" region of DSS allows that host
> +  exclusive access to global registers of DSS while other host can
> +  configure the display for it's usage using a separate register
> +  space labelled as "common1".
> +  The DSS resources can be partitioned in such a way that one or more
> +  of the video planes are owned by Linux whereas other video planes

Your h/w can only run Linux?

What if you want to use this same binding to define the configuration to 
the 'remote processor'? You can easily s/Linux/the OS/, but it all 
should be reworded to describe things in terms of the local processor.

> +  can be owned by a remote core.
> +  The video port controlling these planes acts as a shared video port
> +  and it can be configured with write access either by Linux or the
> +  remote core in which case Linux only has read-only access to that
> +  video port.

What is the purpose of this property when all the other properties are 
required?

> +
> +  ti,dss-shared-mode-planes:
> +description:
> +  The video layer that is owned by processing core running Linux.
> +  The display driver running from Linux has exclusive write access to
> +  this video layer.
> +$ref: /schemas/types.yaml#/definitions/string
> +enum: [vidl, vid]
> +
> +  ti,dss-shared-mode-vp:
> +description:
> +  The video port that is being used in context of processing core
> +  running Linux with display susbsytem being used in shared mode.
> +  This can be owned either by the processing core running Linux in
> +  which case Linux has the write access and the responsibility to
> +  configure this video port and the associated overlay manager or
> +  it can be shared between core running Linux and a remote core
> +  with remote core provided with write access to this video port and
> +  associated overlay managers and remote core configures and drives
> +  this video port also feeding data from one or more of the
> +  video planes owned by Linux, with Linux only having read-only access
> +  to this video port and associated overlay managers.
> +
> +$ref: /schemas/types.yaml#/definitions/string
> +enum: [vp1, vp2]
> +
> +  ti,dss-shared-mode-common:
> +description:
> +  The DSS register region owned by processing core running Linux.
> +$ref: /schemas/types.yaml#/definitions/string
> +enum: [common, common1]
> +
> +  ti,dss-shared-mode-vp-owned:
> +description:
> +  This tells whether processing core running Linux has write access to
> +  the video ports enlisted in ti,dss-shared-mode-vps.
> +$ref: /schemas/types.yaml#/definitions/uint32
> +enum: [0, 1]

This can be boolean. Do writes abort or just get ignored? The latter can 
be probed and doesn't need a property.

> +
> +  ti,dss-shared-mode-plane-zorder:
> +description:
> +  The zorder of the planes owned by Linux.
> +  For the scenario where Linux is not having write access to associated
> +  video port, this field is just for
> +  informational purpose to enumerate the zorder configuration
> +  being used by remote core.
> +
> +$ref: /schemas/types.yaml#/definitions/uint32
> +enum: [0, 1]

I don't understand how 0 or 1

  1   2   >