Re: [PATCH 1/2] Enable buddy memory manager support

2021-09-21 Thread Christian König

Am 20.09.21 um 21:20 schrieb Arunpravin:

Port Intel buddy system manager to drm root folder
Add CPU mappable/non-mappable region support to the drm buddy manager


And where is the patch to switch i915 and remove the Intel copy of this?

In general I think that every public function here needs a kerneldoc 
description what it is all about.


Regards,
Christian.



Signed-off-by: Arunpravin 
---
  drivers/gpu/drm/Makefile|   2 +-
  drivers/gpu/drm/drm_buddy.c | 465 
  include/drm/drm_buddy.h | 154 
  3 files changed, 620 insertions(+), 1 deletion(-)
  create mode 100644 drivers/gpu/drm/drm_buddy.c
  create mode 100644 include/drm/drm_buddy.h

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index a118692a6df7..fe1a2fc09675 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -18,7 +18,7 @@ drm-y   :=drm_aperture.o drm_auth.o drm_cache.o \
drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o \
-   drm_managed.o drm_vblank_work.o
+   drm_managed.o drm_vblank_work.o drm_buddy.o
  
  drm-$(CONFIG_DRM_LEGACY) += drm_agpsupport.o drm_bufs.o drm_context.o drm_dma.o \

drm_legacy_misc.o drm_lock.o drm_memory.o 
drm_scatter.o \
diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c
new file mode 100644
index ..f07919a004b6
--- /dev/null
+++ b/drivers/gpu/drm/drm_buddy.c
@@ -0,0 +1,465 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright � 2021 Intel Corporation
+ */
+
+#include 
+#include 
+
+static struct drm_buddy_block *drm_block_alloc(struct drm_buddy_mm *mm,
+   struct drm_buddy_block *parent, unsigned int order,
+   u64 offset)
+{
+   struct drm_buddy_block *block;
+
+   BUG_ON(order > DRM_BUDDY_MAX_ORDER);
+
+   block = kmem_cache_zalloc(mm->slab_blocks, GFP_KERNEL);
+   if (!block)
+   return NULL;
+
+   block->header = offset;
+   block->header |= order;
+   block->parent = parent;
+   block->start = offset >> PAGE_SHIFT;
+   block->size = (mm->chunk_size << order) >> PAGE_SHIFT;
+
+   BUG_ON(block->header & DRM_BUDDY_HEADER_UNUSED);
+   return block;
+}
+
+static void drm_block_free(struct drm_buddy_mm *mm, struct drm_buddy_block 
*block)
+{
+   kmem_cache_free(mm->slab_blocks, block);
+}
+
+static void add_ordered(struct drm_buddy_mm *mm, struct drm_buddy_block *block)
+{
+   struct drm_buddy_block *node;
+
+   if (list_empty(&mm->free_list[drm_buddy_block_order(block)])) {
+   list_add(&block->link,
+   &mm->free_list[drm_buddy_block_order(block)]);
+   return;
+   }
+
+   list_for_each_entry(node, &mm->free_list[drm_buddy_block_order(block)], 
link)
+   if (block->start > node->start)
+   break;
+
+   __list_add(&block->link, node->link.prev, &node->link);
+}
+
+static void mark_allocated(struct drm_buddy_block *block)
+{
+   block->header &= ~DRM_BUDDY_HEADER_STATE;
+   block->header |= DRM_BUDDY_ALLOCATED;
+
+   list_del(&block->link);
+}
+
+static void mark_free(struct drm_buddy_mm *mm,
+ struct drm_buddy_block *block)
+{
+   block->header &= ~DRM_BUDDY_HEADER_STATE;
+   block->header |= DRM_BUDDY_FREE;
+
+   add_ordered(mm, block);
+}
+
+static void mark_split(struct drm_buddy_block *block)
+{
+   block->header &= ~DRM_BUDDY_HEADER_STATE;
+   block->header |= DRM_BUDDY_SPLIT;
+
+   list_del(&block->link);
+}
+
+int drm_buddy_init(struct drm_buddy_mm *mm, u64 size, u64 chunk_size)
+{
+   unsigned int i;
+   u64 offset;
+
+   if (size < chunk_size)
+   return -EINVAL;
+
+   if (chunk_size < PAGE_SIZE)
+   return -EINVAL;
+
+   if (!is_power_of_2(chunk_size))
+   return -EINVAL;
+
+   size = round_down(size, chunk_size);
+
+   mm->size = size;
+   mm->chunk_size = chunk_size;
+   mm->max_order = ilog2(size) - ilog2(chunk_size);
+
+   BUG_ON(mm->max_order > DRM_BUDDY_MAX_ORDER);
+
+   mm->slab_blocks = KMEM_CACHE(drm_buddy_block, SLAB_HWCACHE_ALIGN);
+
+   if (!mm->slab_blocks)
+   return -ENOMEM;
+
+   mm->free_list = kmalloc_array(mm->max_order + 1,
+ sizeof(struct list_head),
+ GFP_KERNEL);
+   if (!mm->free_list)
+   goto out_destroy_slab;
+
+   for (i = 0; i <= mm->max_order; ++i)
+   INIT_LIST_HEAD(&mm->free_list[i]);
+
+   mm->n_roots = hweight64(size);
+
+   mm->roots = kmalloc_array(mm->n_roots,
+ sizeof(struct drm_buddy_block *),
+ GF

Re: [PATCH 2/2] Add drm buddy manager support to amdgpu driver

2021-09-21 Thread Christian König

Am 21.09.21 um 17:51 schrieb Paneer Selvam, Arunpravin:

[AMD Public Use]

Hi Christian,
Please find my comments.


A better mail client might be helpful for mailing list communication. I 
use Thunderbird, but Outlook with appropriate setting should do as well.




Thanks,
Arun
-Original Message-
From: Koenig, Christian 
Sent: Tuesday, September 21, 2021 2:34 PM
To: Paneer Selvam, Arunpravin ; 
dri-devel@lists.freedesktop.org; intel-...@lists.freedesktop.org; 
amd-...@lists.freedesktop.org; matthew.a...@intel.com; dan...@ffwll.ch; Deucher, Alexander 

Subject: Re: [PATCH 2/2] Add drm buddy manager support to amdgpu driver

Am 20.09.21 um 21:21 schrieb Arunpravin:
[SNIP]

+   struct list_head blocks;
+};
+
+static inline struct amdgpu_vram_mgr_node *
+to_amdgpu_vram_mgr_node(struct ttm_resource *res) {
+   return container_of(container_of(res, struct ttm_range_mgr_node, base),
+   struct amdgpu_vram_mgr_node, tnode); }
+

Maybe stuff that in a separate amdgpu_vram_mgr.h file together with all the 
other defines for the vram manager.

Arun - I thought about it, will create a new header file for vram manager


Maybe make that a separate patch before this one here.


+   if (mode == DRM_BUDDY_ALLOC_RANGE) {
+   r = drm_buddy_alloc_range(mm, &vnode->blocks,
+   (uint64_t)place->fpfn << PAGE_SHIFT, pages << 
PAGE_SHIFT);

That handling won't work. It's possible that you need contiguous memory in a 
specific range.

Arun - the existing default backend range handler allocates contiguous nodes in 
power of 2 finding the MSB's of
the any given size. We get linked nodes (depends on the requested size) in 
continuous range of address.
Example, for the size 768 pages request, we get 512 + 256 range of continuous 
address in 2 nodes.

It works by passing the fpfn and the requested size, the backend handler 
calculates the lpfn by adding fpfn + size = lpfn.
The drawback here are we are not handling the specific lpfn value (as of now it 
is calculated using the fpfn + requested size)
and not following the pages_per_node rule.

Please let me know if this won't work for all specific fpfn / lpfn cases


From your description that sounds like it won't work at all for any cases.

See the fpfn/lpfn specifies the range of allocation. For the most common 
case that's either 0..visible_vram or 0..start_of_some_hw_limitation.


When you always try to allocate the range from 0 you will quickly find 
that you clash with existing allocations.


What you need to do in general is to have a drm_buddy_alloc() which is 
able to limit the returned page to the desired range fpfn..lpfn.



+
+   do {
+   unsigned int order;
+
+   order = fls(n_pages) - 1;
+   BUG_ON(order > mm->max_order);
+
+   spin_lock(&mgr->lock);
+   block = drm_buddy_alloc(mm, order, 
bar_limit_enabled,
+   
visible_pfn, mode);

That doesn't seem to make much sense either. The backend allocator should not 
care about the BAR size nor the visible_pfn.

Arun - we are sending the BAR limit enable information (in case of APU or large 
BAR, we take different approach) and visible_pfn
Information.

In case of bar_limit_enabled is true, I thought visible_pfn required for the 
backend allocator to compare with the block start address
and find the desired blocks for the TOP-DOWN and BOTTOM-UP approach (TOP-DOWN - 
return blocks higher than the visible_pfn limit,
BOTTOM-UP - return blocks lower than the visible_pfn limit).

In case of bar_limit_enabled is false, we just return the top ordered blocks 
and bottom most blocks for the TOP-DOWN and BOTTOM-UP
respectively (suitable for APU and Large BAR case).

Please let me know if we have other way to fix this problem


That is the completely wrong approach. The backend must not care about 
the BAR configuration and visibility of the VRAM.


What it should do instead is to take the fpfn..lpfn range into account 
and make sure that all allocated pages are in the desired range.


BOTTOM-UP vs. TOP-DOWN then just optimizes the algorithm because we 
insert all freed up TOP-DOWN pages at the end and all BOTTOM-UP pages at 
the front and on new allocations walk the lest of free pages from the 
front or back depending on the flag.





+   spin_unlock(&mgr->lock);
   
-		vis_usage += amdgpu_vram_mgr_vis_size(adev, &node->mm_nodes[i]);

-   amdgpu_vram_mgr_virt_start(&node->base, &node->mm_nodes[i]);
-   pages_left -= pages;
-   ++i;
+   if (IS_ERR(block)) {
+   r = -ENOSPC;
+   goto error_free_blocks;
+   }
   
-		if (pages > pages_left)

- 

Re: [RESEND] [PATCH v2 1/2] dt-bindings: display: bridge: Add binding for R-Car MIPI DSI/CSI-2 TX

2021-09-21 Thread Geert Uytterhoeven
Hi Laurent,

On Wed, Sep 22, 2021 at 3:27 AM Laurent Pinchart
 wrote:
> On Tue, Sep 21, 2021 at 05:53:52PM +0200, Geert Uytterhoeven wrote:
> > On Wed, Jul 28, 2021 at 6:26 PM Laurent Pinchart wrote:
> > > The R-Car MIPI DSI/CSI-2 TX is embedded in the Renesas R-Car V3U SoC. It
> > > can operate in either DSI or CSI-2 mode, with up to four data lanes.
> > >
> > > Signed-off-by: Laurent Pinchart 
> > > 
> > > Reviewed-by: Kieran Bingham 
> >
> > Thanks for your patch!
> >
> > > --- /dev/null
> > > +++ 
> > > b/Documentation/devicetree/bindings/display/bridge/renesas,dsi-csi2-tx.yaml
> > > @@ -0,0 +1,118 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: 
> > > http://devicetree.org/schemas/display/bridge/renesas,dsi-csi2-tx.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Renesas R-Car MIPI DSI/CSI-2 Encoder
> > > +
> > > +maintainers:
> > > +  - Laurent Pinchart 
> > > +
> > > +description: |
> > > +  This binding describes the MIPI DSI/CSI-2 encoder embedded in the 
> > > Renesas
> > > +  R-Car V3U SoC. The encoder can operate in either DSI or CSI-2 mode, 
> > > with up
> > > +  to four data lanes.
> > > +
> > > +properties:
> > > +  compatible:
> > > +enum:
> > > +  - renesas,r8a779a0-dsi-csi2-tx# for V3U
> > > +
> > > +  reg:
> > > +maxItems: 1
> > > +
> > > +  clocks:
> > > +items:
> > > +  - description: Functional clock
> > > +  - description: DSI (and CSI-2) functional clock
> > > +  - description: PLL reference clock
> > > +
> > > +  clock-names:
> > > +items:
> > > +  - const: fck
> > > +  - const: dsi
> > > +  - const: pll
> >
> > No interrupts?
> > The hardware manual says there are 9 interrupts.
>
> Who comes up with such insanely high numbers of interrupts ? :-)
>
> What the hardware manual doesn't document is how interrupts are mapped.
> There's indeed 9 of them, and there are 9 interrupt sources, but that's
> all we know. I can easily add a
>
>   interrupts:
> maxItems: 9
>
> but I can add interrupt names without additional information. It may be
> possible to deduce some of the interrupt mappings from experiments, but
> not all of them. What do you think would be a good way forward ? Leave
> the interrupts out for now as we don't have the information ? Only list
> the interrupts but not their names ? Something else ?

I think what we did in the past is not list the interrupts at all.
They can be added once we receive more documentation.

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 v1] drm/i915/bdb: Fix version check

2021-09-21 Thread Radosław Biernacki
- dropping stable

...

> > diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h 
> > b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
> > index 330077c2e588..fff456bf8783 100644
> > --- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
> > +++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
> > @@ -814,6 +814,11 @@ struct lfp_brightness_level {
> >   u16 reserved;
> >  } __packed;
> >
> > +/*
> > + * Changing struct bdb_lfp_backlight_data might affect its
> > + * size comparation to the value hold in BDB.
> > + * (e.g. in parse_lfp_backlight())
> > + */
>
> This is true for all the blocks so I don't think we need this comment.

Lack of such comment was probable cause of this overlook.
As this is an example of the consequence (bricking platforms dependent
on mentioned conditions) IMO we need some comment here, or this will
probably happen again.


>
> >  struct bdb_lfp_backlight_data {
> >   u8 entry_size;
> >   struct lfp_backlight_data_entry data[16];
>


[PATCH] drm/bridge: cdns-dsi: Make sure to to create proper aliases for dt

2021-09-21 Thread Nishanth Menon
Add MODULE_DEVICE_TABLE to the device tree table to create required
aliases needed for module to be loaded with device tree based platform.

Fixes: e19233955d9e ("drm/bridge: Add Cadence DSI driver")
Signed-off-by: Nishanth Menon 
---
 drivers/gpu/drm/bridge/cdns-dsi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c 
b/drivers/gpu/drm/bridge/cdns-dsi.c
index d8a15c459b42..829e1a144656 100644
--- a/drivers/gpu/drm/bridge/cdns-dsi.c
+++ b/drivers/gpu/drm/bridge/cdns-dsi.c
@@ -1284,6 +1284,7 @@ static const struct of_device_id cdns_dsi_of_match[] = {
{ .compatible = "cdns,dsi" },
{ },
 };
+MODULE_DEVICE_TABLE(of, cdns_dsi_of_match);
 
 static struct platform_driver cdns_dsi_platform_driver = {
.probe  = cdns_dsi_drm_probe,
-- 
2.32.0



[PATCH v6 9/9] HAX: drm/i915/gem: Fix the __i915_gem_is_lmem() function

2021-09-21 Thread Thomas Hellström
Signed-off-by: Thomas Hellström 
---
 drivers/gpu/drm/i915/gem/i915_gem_lmem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
index d659239fcbcc..444f8268b9c5 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
@@ -67,7 +67,7 @@ bool __i915_gem_object_is_lmem(struct drm_i915_gem_object 
*obj)
 
 #ifdef CONFIG_LOCKDEP
GEM_WARN_ON(dma_resv_test_signaled(obj->base.resv, true) &&
-   !i915_gem_object_evictable(obj));
+   i915_gem_object_evictable(obj));
 #endif
return mr && (mr->type == INTEL_MEMORY_LOCAL ||
  mr->type == INTEL_MEMORY_STOLEN_LOCAL);
-- 
2.31.1



[PATCH v6 8/9] HAX: component: do not leave master devres group open after bind

2021-09-21 Thread Thomas Hellström
From: Kai Vehmanen 

In current code, the devres group for aggregate master is left open
after call to component_master_add_*(). This leads to problems when the
master does further managed allocations on its own. When any
participating driver calls component_del(), this leads to immediate
release of resources.

This came up when investigating a page fault occurring with i915 DRM
driver unbind with 5.15-rc1 kernel. The following sequence occurs:

 i915_pci_remove()
   -> intel_display_driver_unregister()
 -> i915_audio_component_cleanup()
   -> component_del()
 -> component.c:take_down_master()
   -> hdac_component_master_unbind() [via master->ops->unbind()]
   -> devres_release_group(master->parent, NULL)

With older kernels this has not caused issues, but with audio driver
moving to use managed interfaces for more of its allocations, this no
longer works. Devres log shows following to occur:

component_master_add_with_match()
[  126.886032] snd_hda_intel :00:1f.3: DEVRES ADD 323ccdc5 
devm_component_match_release (24 bytes)
[  126.886045] snd_hda_intel :00:1f.3: DEVRES ADD 865cdb29 grp< (0 
bytes)
[  126.886049] snd_hda_intel :00:1f.3: DEVRES ADD 1b480725 grp< (0 
bytes)

audio driver completes its PCI probe()
[  126.892238] snd_hda_intel :00:1f.3: DEVRES ADD 1b480725 
pcim_iomap_release (48 bytes)

component_del() called() at DRM/i915 unbind()
[  137.579422] i915 :00:02.0: DEVRES REL ef44c293 grp< (0 bytes)
[  137.579445] snd_hda_intel :00:1f.3: DEVRES REL 865cdb29 grp< (0 
bytes)
[  137.579458] snd_hda_intel :00:1f.3: DEVRES REL 1b480725 
pcim_iomap_release (48 bytes)

So the "devres_release_group(master->parent, NULL)" ends up freeing the
pcim_iomap allocation. Upon next runtime resume, the audio driver will
cause a page fault as the iomap alloc was released without the driver
knowing about it.

Fix this issue by using the "struct master" pointer as identifier for
the devres group, and by closing the devres group after the master->ops->bind()
call is done. This allows devres allocations done by the driver acting as
master to be isolated from the binding state of the aggregate driver. This
modifies the logic originally introduced in commit 9e1ccb4a7700
("drivers/base: fix devres handling for master device").

BugLink: https://gitlab.freedesktop.org/drm/intel/-/issues/4136
Signed-off-by: Kai Vehmanen 
Acked-by: Imre Deak 
Acked-by: Russell King (Oracle) 
---
 drivers/base/component.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index 5e79299f6c3f..870485cbbb87 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -246,7 +246,7 @@ static int try_to_bring_up_master(struct master *master,
return 0;
}
 
-   if (!devres_open_group(master->parent, NULL, GFP_KERNEL))
+   if (!devres_open_group(master->parent, master, GFP_KERNEL))
return -ENOMEM;
 
/* Found all components */
@@ -258,6 +258,7 @@ static int try_to_bring_up_master(struct master *master,
return ret;
}
 
+   devres_close_group(master->parent, NULL);
master->bound = true;
return 1;
 }
@@ -282,7 +283,7 @@ static void take_down_master(struct master *master)
 {
if (master->bound) {
master->ops->unbind(master->parent);
-   devres_release_group(master->parent, NULL);
+   devres_release_group(master->parent, master);
master->bound = false;
}
 }
-- 
2.31.1



[PATCH v6 5/9] drm/i915/gt: Register the migrate contexts with their engines

2021-09-21 Thread Thomas Hellström
Pinned contexts, like the migrate contexts need reset after resume
since their context image may have been lost. Also the GuC needs to
register pinned contexts.

Add a list to struct intel_engine_cs where we add all pinned contexts on
creation, and traverse that list at resume time to reset the pinned
contexts.

This fixes the kms_pipe_crc_basic@suspend-read-crc-pipe-a selftest for now,
but proper LMEM backup / restore is needed for full suspend functionality.
However, note that even with full LMEM backup / restore it may be
desirable to keep the reset since backing up the migrate context images
must happen using memcpy() after the migrate context has become inactive,
and for performance- and other reasons we want to avoid memcpy() from
LMEM.

Also traverse the list at guc_init_lrc_mapping() calling
guc_kernel_context_pin() for the pinned contexts, like is already done
for the kernel context.

v2:
- Don't reset the contexts on each __engine_unpark() but rather at
  resume time (Chris Wilson).
v3:
- Reset contexts in the engine sanitize callback. (Chris Wilson)

Cc: Tvrtko Ursulin 
Cc: Matthew Auld 
Cc: Maarten Lankhorst 
Cc: Brost Matthew 
Cc: Chris Wilson 
Signed-off-by: Thomas Hellström 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gt/intel_context_types.h |  8 +++
 drivers/gpu/drm/i915/gt/intel_engine_cs.c |  4 
 drivers/gpu/drm/i915/gt/intel_engine_pm.c | 23 +++
 drivers/gpu/drm/i915/gt/intel_engine_pm.h |  2 ++
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  7 ++
 .../drm/i915/gt/intel_execlists_submission.c  |  2 ++
 .../gpu/drm/i915/gt/intel_ring_submission.c   |  3 +++
 drivers/gpu/drm/i915/gt/mock_engine.c |  2 ++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 12 +++---
 9 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 930569a1a01f..12252c411159 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -153,6 +153,14 @@ struct intel_context {
/** sseu: Control eu/slice partitioning */
struct intel_sseu sseu;
 
+   /**
+* pinned_contexts_link: List link for the engine's pinned contexts.
+* This is only used if this is a perma-pinned kernel context and
+* the list is assumed to only be manipulated during driver load
+* or unload time so no mutex protection currently.
+*/
+   struct list_head pinned_contexts_link;
+
u8 wa_bb_page; /* if set, page num reserved for context workarounds */
 
struct {
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 06dfe7f38953..2ae57e4656a3 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -320,6 +320,7 @@ static int intel_engine_setup(struct intel_gt *gt, enum 
intel_engine_id id)
 
BUILD_BUG_ON(BITS_PER_TYPE(engine->mask) < I915_NUM_ENGINES);
 
+   INIT_LIST_HEAD(&engine->pinned_contexts_list);
engine->id = id;
engine->legacy_idx = INVALID_ENGINE;
engine->mask = BIT(id);
@@ -890,6 +891,8 @@ intel_engine_create_pinned_context(struct intel_engine_cs 
*engine,
return ERR_PTR(err);
}
 
+   list_add_tail(&ce->pinned_contexts_link, &engine->pinned_contexts_list);
+
/*
 * Give our perma-pinned kernel timelines a separate lockdep class,
 * so that we can use them from within the normal user timelines
@@ -912,6 +915,7 @@ void intel_engine_destroy_pinned_context(struct 
intel_context *ce)
list_del(&ce->timeline->engine_link);
mutex_unlock(&hwsp->vm->mutex);
 
+   list_del(&ce->pinned_contexts_link);
intel_context_unpin(ce);
intel_context_put(ce);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c 
b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index 1f07ac4e0672..dacd62773735 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -298,6 +298,29 @@ void intel_engine_init__pm(struct intel_engine_cs *engine)
intel_engine_init_heartbeat(engine);
 }
 
+/**
+ * intel_engine_reset_pinned_contexts - Reset the pinned contexts of
+ * an engine.
+ * @engine: The engine whose pinned contexts we want to reset.
+ *
+ * Typically the pinned context LMEM images lose or get their content
+ * corrupted on suspend. This function resets their images.
+ */
+void intel_engine_reset_pinned_contexts(struct intel_engine_cs *engine)
+{
+   struct intel_context *ce;
+
+   list_for_each_entry(ce, &engine->pinned_contexts_list,
+   pinned_contexts_link) {
+   /* kernel context gets reset at __engine_unpark() */
+   if (ce == engine->kernel_context)
+   continue;
+
+   dbg_poison_ce(ce);
+   ce->ops->rese

[PATCH v6 3/9] drm/i915/gt: Increase suspend timeout

2021-09-21 Thread Thomas Hellström
With GuC submission on DG1, the execution of the requests times out
for the gem_exec_suspend igt test case after executing around 800-900
of 1000 submitted requests.

Given the time we allow elsewhere for fences to signal (in the order of
seconds), increase the timeout before we mark the gt wedged and proceed.

Signed-off-by: Thomas Hellström 
---
 drivers/gpu/drm/i915/gt/intel_gt_pm.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c 
b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index dea8e2479897..f84f2bfe2de0 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -19,6 +19,8 @@
 #include "intel_rps.h"
 #include "intel_wakeref.h"
 
+#define I915_GT_SUSPEND_IDLE_TIMEOUT (HZ / 2)
+
 static void user_forcewake(struct intel_gt *gt, bool suspend)
 {
int count = atomic_read(>->user_wakeref);
@@ -279,7 +281,7 @@ static void wait_for_suspend(struct intel_gt *gt)
if (!intel_gt_pm_is_awake(gt))
return;
 
-   if (intel_gt_wait_for_idle(gt, I915_GEM_IDLE_TIMEOUT) == -ETIME) {
+   if (intel_gt_wait_for_idle(gt, I915_GT_SUSPEND_IDLE_TIMEOUT) == -ETIME) 
{
/*
 * Forcibly cancel outstanding work and leave
 * the gpu quiet.
-- 
2.31.1



[PATCH v6 7/9] drm/i915: Reduce the number of objects subject to memcpy recover

2021-09-21 Thread Thomas Hellström
We really only need memcpy restore for objects that affect the
operability of the migrate context. That is, primarily the page-table
objects of the migrate VM.

Add an object flag, I915_BO_ALLOC_PM_EARLY for objects that need early
restores using memcpy and a way to assign LMEM page-table object flags
to be used by the vms.

Restore objects without this flag with the gpu blitter and only objects
carrying the flag using TTM memcpy.

Initially mark the migrate, gt, gtt and vgpu vms to use this flag, and
defer for a later audit which vms actually need it. Most importantly, user-
allocated vms with pinned page-table objects can be restored using the
blitter.

Performance-wise memcpy restore is probably as fast as gpu restore if not
faster, but using gpu restore will help tackling future restrictions in
mappable LMEM size.

v4:
- Don't mark the aliasing ppgtt page table flags for early resume, but
  rather the ggtt page table flags as intended. (Matthew Auld)
- The check for user buffer objects during early resume is pointless, since
  they are never marked I915_BO_ALLOC_PM_EARLY. (Matthew Auld)
v5:
- Mark GuC LMEM objects with I915_BO_ALLOC_PM_EARLY to have them restored
  before we fire up the migrate context.

Cc: Matthew Brost 
Signed-off-by: Thomas Hellström 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c  |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_object_types.h |  9 ++---
 drivers/gpu/drm/i915/gem/i915_gem_pm.c   |  6 +-
 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c   |  5 +++--
 drivers/gpu/drm/i915/gem/selftests/huge_pages.c  |  2 +-
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c |  2 +-
 drivers/gpu/drm/i915/gt/gen8_ppgtt.c |  5 +++--
 drivers/gpu/drm/i915/gt/gen8_ppgtt.h |  4 +++-
 drivers/gpu/drm/i915/gt/intel_ggtt.c |  3 ++-
 drivers/gpu/drm/i915/gt/intel_gt.c   |  2 +-
 drivers/gpu/drm/i915/gt/intel_gtt.c  |  3 ++-
 drivers/gpu/drm/i915/gt/intel_gtt.h  |  9 +++--
 drivers/gpu/drm/i915/gt/intel_migrate.c  |  2 +-
 drivers/gpu/drm/i915/gt/intel_ppgtt.c| 13 -
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c |  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc.c   |  3 ++-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c |  7 +--
 drivers/gpu/drm/i915/gvt/scheduler.c |  2 +-
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c|  4 ++--
 19 files changed, 56 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index c2ab0e22db0a..8208fd5b72c3 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -1287,7 +1287,7 @@ i915_gem_create_context(struct drm_i915_private *i915,
} else if (HAS_FULL_PPGTT(i915)) {
struct i915_ppgtt *ppgtt;
 
-   ppgtt = i915_ppgtt_create(&i915->gt);
+   ppgtt = i915_ppgtt_create(&i915->gt, 0);
if (IS_ERR(ppgtt)) {
drm_dbg(&i915->drm, "PPGTT setup failed (%ld)\n",
PTR_ERR(ppgtt));
@@ -1465,7 +1465,7 @@ int i915_gem_vm_create_ioctl(struct drm_device *dev, void 
*data,
if (args->flags)
return -EINVAL;
 
-   ppgtt = i915_ppgtt_create(&i915->gt);
+   ppgtt = i915_ppgtt_create(&i915->gt, 0);
if (IS_ERR(ppgtt))
return PTR_ERR(ppgtt);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 118691ce81d7..fa2ba9e2a4d0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -294,13 +294,16 @@ struct drm_i915_gem_object {
 #define I915_BO_ALLOC_USERBIT(3)
 /* Object is allowed to lose its contents on suspend / resume, even if pinned 
*/
 #define I915_BO_ALLOC_PM_VOLATILE BIT(4)
+/* Object needs to be restored early using memcpy during resume */
+#define I915_BO_ALLOC_PM_EARLYBIT(5)
 #define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \
 I915_BO_ALLOC_VOLATILE | \
 I915_BO_ALLOC_CPU_CLEAR | \
 I915_BO_ALLOC_USER | \
-I915_BO_ALLOC_PM_VOLATILE)
-#define I915_BO_READONLY  BIT(5)
-#define I915_TILING_QUIRK_BIT 6 /* unknown swizzling; do not release! */
+I915_BO_ALLOC_PM_VOLATILE | \
+I915_BO_ALLOC_PM_EARLY)
+#define I915_BO_READONLY  BIT(6)
+#define I915_TILING_QUIRK_BIT 7 /* unknown swizzling; do not release! */
 
/**
 * @mem_flags - Mutable placement-related flags
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
index 12b37b4c1192..726b40e1fbb0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pm.c
+++ b/drivers/gpu/drm

[PATCH v6 6/9] drm/i915: Don't back up pinned LMEM context images and rings during suspend

2021-09-21 Thread Thomas Hellström
Pinned context images are now reset during resume. Don't back them up,
and assuming that rings can be assumed empty at suspend, don't back them
up either.

Introduce a new object flag, I915_BO_ALLOC_PM_VOLATILE meaning that an
object is allowed to lose its content on suspend.

v3:
- Slight documentation clarification (Matthew Auld)

Signed-off-by: Thomas Hellström 
Reviewed-by: Matthew Auld 
---
 .../gpu/drm/i915/gem/i915_gem_object_types.h| 17 ++---
 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c  |  3 +++
 drivers/gpu/drm/i915/gt/intel_lrc.c |  3 ++-
 drivers/gpu/drm/i915/gt/intel_ring.c|  3 ++-
 4 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 734cc8e16481..118691ce81d7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -288,16 +288,19 @@ struct drm_i915_gem_object {
I915_SELFTEST_DECLARE(struct list_head st_link);
 
unsigned long flags;
-#define I915_BO_ALLOC_CONTIGUOUS BIT(0)
-#define I915_BO_ALLOC_VOLATILE   BIT(1)
-#define I915_BO_ALLOC_CPU_CLEAR  BIT(2)
-#define I915_BO_ALLOC_USER   BIT(3)
+#define I915_BO_ALLOC_CONTIGUOUS  BIT(0)
+#define I915_BO_ALLOC_VOLATILEBIT(1)
+#define I915_BO_ALLOC_CPU_CLEAR   BIT(2)
+#define I915_BO_ALLOC_USERBIT(3)
+/* Object is allowed to lose its contents on suspend / resume, even if pinned 
*/
+#define I915_BO_ALLOC_PM_VOLATILE BIT(4)
 #define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \
 I915_BO_ALLOC_VOLATILE | \
 I915_BO_ALLOC_CPU_CLEAR | \
-I915_BO_ALLOC_USER)
-#define I915_BO_READONLY BIT(4)
-#define I915_TILING_QUIRK_BIT5 /* unknown swizzling; do not release! */
+I915_BO_ALLOC_USER | \
+I915_BO_ALLOC_PM_VOLATILE)
+#define I915_BO_READONLY  BIT(5)
+#define I915_TILING_QUIRK_BIT 6 /* unknown swizzling; do not release! */
 
/**
 * @mem_flags - Mutable placement-related flags
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
index cb1c46724f70..03a00d193f40 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
@@ -60,6 +60,9 @@ static int i915_ttm_backup(struct i915_gem_apply_to_region 
*apply,
if (!pm_apply->backup_pinned)
return 0;
 
+   if (obj->flags & I915_BO_ALLOC_PM_VOLATILE)
+   return 0;
+
backup = i915_gem_object_create_shmem(i915, obj->base.size);
if (IS_ERR(backup))
return PTR_ERR(backup);
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 6ba8daea2f56..3ef9eaf8c50e 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -942,7 +942,8 @@ __lrc_alloc_state(struct intel_context *ce, struct 
intel_engine_cs *engine)
context_size += PAGE_SIZE;
}
 
-   obj = i915_gem_object_create_lmem(engine->i915, context_size, 0);
+   obj = i915_gem_object_create_lmem(engine->i915, context_size,
+ I915_BO_ALLOC_PM_VOLATILE);
if (IS_ERR(obj))
obj = i915_gem_object_create_shmem(engine->i915, context_size);
if (IS_ERR(obj))
diff --git a/drivers/gpu/drm/i915/gt/intel_ring.c 
b/drivers/gpu/drm/i915/gt/intel_ring.c
index 7c4d5158e03b..2fdd52b62092 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring.c
@@ -112,7 +112,8 @@ static struct i915_vma *create_ring_vma(struct i915_ggtt 
*ggtt, int size)
struct drm_i915_gem_object *obj;
struct i915_vma *vma;
 
-   obj = i915_gem_object_create_lmem(i915, size, I915_BO_ALLOC_VOLATILE);
+   obj = i915_gem_object_create_lmem(i915, size, I915_BO_ALLOC_VOLATILE |
+ I915_BO_ALLOC_PM_VOLATILE);
if (IS_ERR(obj) && i915_ggtt_has_aperture(ggtt))
obj = i915_gem_object_create_stolen(i915, size);
if (IS_ERR(obj))
-- 
2.31.1



[PATCH v6 4/9] drm/i915 Implement LMEM backup and restore for suspend / resume

2021-09-21 Thread Thomas Hellström
Just evict unpinned objects to system. For pinned LMEM objects,
make a backup system object and blit the contents to that.

Backup is performed in three steps,
1: Opportunistically evict evictable objects using the gpu blitter.
2: After gt idle, evict evictable objects using the gpu blitter. This will
be modified in an upcoming patch to backup pinned objects that are not used
by the blitter itself.
3: Backup remaining pinned objects using memcpy.

Also move uC suspend to after 2) to make sure we have a functional GuC
during 2) if using GuC submission.

v2:
- Major refactor to make sure gem_exec_suspend@hang-SX subtests work, and
  suspend / resume works with a slightly modified GuC submission enabling
  patch series.

v3:
- Fix a potential use-after-free (Matthew Auld)
- Use i915_gem_object_create_shmem() instead of
  i915_gem_object_create_region (Matthew Auld)
- Minor simplifications (Matthew Auld)
- Fix up kerneldoc for i195_ttm_restore_region().
- Final lmem_suspend() call moved to i915_gem_backup_suspend from
  i915_gem_suspend_late, since the latter gets called at driver unload
  and we don't unnecessarily want to run it at that time.

v4:
- Interface change of ttm- & lmem suspend / resume functions to use
  flags rather than bools. (Matthew Auld)
- Completely drop the i915_gem_backup_suspend change (Matthew Auld)

Signed-off-by: Thomas Hellström 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/Makefile |   1 +
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |   1 +
 drivers/gpu/drm/i915/gem/i915_gem_pm.c|  87 
 drivers/gpu/drm/i915/gem/i915_gem_pm.h|   1 +
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c   |  30 ++-
 drivers/gpu/drm/i915/gem/i915_gem_ttm.h   |  10 +
 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c| 202 ++
 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.h|  26 +++
 drivers/gpu/drm/i915/gt/intel_gt_pm.c |   4 +-
 drivers/gpu/drm/i915/i915_drv.c   |   4 +-
 10 files changed, 353 insertions(+), 13 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 335a8c668848..5c8e022a7383 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -154,6 +154,7 @@ gem-y += \
gem/i915_gem_throttle.o \
gem/i915_gem_tiling.o \
gem/i915_gem_ttm.o \
+   gem/i915_gem_ttm_pm.o \
gem/i915_gem_userptr.o \
gem/i915_gem_wait.o \
gem/i915_gemfs.o
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 2471f36aaff3..734cc8e16481 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -534,6 +534,7 @@ struct drm_i915_gem_object {
struct {
struct sg_table *cached_io_st;
struct i915_gem_object_page_iter get_io_page;
+   struct drm_i915_gem_object *backup;
bool created:1;
} ttm;
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
index 8b9d7d14c4bd..12b37b4c1192 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
@@ -5,6 +5,7 @@
  */
 
 #include "gem/i915_gem_pm.h"
+#include "gem/i915_gem_ttm_pm.h"
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_pm.h"
 #include "gt/intel_gt_requests.h"
@@ -39,6 +40,84 @@ void i915_gem_suspend(struct drm_i915_private *i915)
i915_gem_drain_freed_objects(i915);
 }
 
+static int lmem_restore(struct drm_i915_private *i915, u32 flags)
+{
+   struct intel_memory_region *mr;
+   int ret = 0, id;
+
+   for_each_memory_region(mr, i915, id) {
+   if (mr->type == INTEL_MEMORY_LOCAL) {
+   ret = i915_ttm_restore_region(mr, flags);
+   if (ret)
+   break;
+   }
+   }
+
+   return ret;
+}
+
+static int lmem_suspend(struct drm_i915_private *i915, u32 flags)
+{
+   struct intel_memory_region *mr;
+   int ret = 0, id;
+
+   for_each_memory_region(mr, i915, id) {
+   if (mr->type == INTEL_MEMORY_LOCAL) {
+   ret = i915_ttm_backup_region(mr, flags);
+   if (ret)
+   break;
+   }
+   }
+
+   return ret;
+}
+
+static void lmem_recover(struct drm_i915_private *i915)
+{
+   struct intel_memory_region *mr;
+   int id;
+
+   for_each_memory_region(mr, i915, id)
+   if (mr->type == INTEL_MEMORY_LOCAL)
+   i915_ttm_recover_region(mr);
+}
+
+int i915_gem_backup_suspend(struct drm_i915_private *i915)
+{
+   int ret;
+
+   /* Opportunistically try to evict unpinned objects */
+   ret = lmem_suspend(i915, I915_TTM_BACKUP_ALLOW_GPU

[PATCH v6 2/9] drm/i915/gem: Implement a function to process all gem objects of a region

2021-09-21 Thread Thomas Hellström
An upcoming common pattern is to traverse the region object list and
perform certain actions on all objects in a region. It's a little tricky
to get the list locking right, in particular since a gem object may
change region unless it's pinned or the object lock is held.

Define a function that does this for us and that takes an argument that
defines the action to be performed on each object.

v3:
- Improve structure documentation a bit (Matthew Auld)

Signed-off-by: Thomas Hellström 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_region.c | 70 ++
 drivers/gpu/drm/i915/gem/i915_gem_region.h | 37 
 2 files changed, 107 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c 
b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index 1f557b2178ed..a016ccec36f3 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -80,3 +80,73 @@ i915_gem_object_create_region(struct intel_memory_region 
*mem,
i915_gem_object_free(obj);
return ERR_PTR(err);
 }
+
+/**
+ * i915_gem_process_region - Iterate over all objects of a region using ops
+ * to process and optionally skip objects
+ * @mr: The memory region
+ * @apply: ops and private data
+ *
+ * This function can be used to iterate over the regions object list,
+ * checking whether to skip objects, and, if not, lock the objects and
+ * process them using the supplied ops. Note that this function temporarily
+ * removes objects from the region list while iterating, so that if run
+ * concurrently with itself may not iterate over all objects.
+ *
+ * Return: 0 if successful, negative error code on failure.
+ */
+int i915_gem_process_region(struct intel_memory_region *mr,
+   struct i915_gem_apply_to_region *apply)
+{
+   const struct i915_gem_apply_to_region_ops *ops = apply->ops;
+   struct drm_i915_gem_object *obj;
+   struct list_head still_in_list;
+   int ret = 0;
+
+   /*
+* In the future, a non-NULL apply->ww could mean the caller is
+* already in a locking transaction and provides its own context.
+*/
+   GEM_WARN_ON(apply->ww);
+
+   INIT_LIST_HEAD(&still_in_list);
+   mutex_lock(&mr->objects.lock);
+   for (;;) {
+   struct i915_gem_ww_ctx ww;
+
+   obj = list_first_entry_or_null(&mr->objects.list, typeof(*obj),
+  mm.region_link);
+   if (!obj)
+   break;
+
+   list_move_tail(&obj->mm.region_link, &still_in_list);
+   if (!kref_get_unless_zero(&obj->base.refcount))
+   continue;
+
+   /*
+* Note: Someone else might be migrating the object at this
+* point. The object's region is not stable until we lock
+* the object.
+*/
+   mutex_unlock(&mr->objects.lock);
+   apply->ww = &ww;
+   for_i915_gem_ww(&ww, ret, apply->interruptible) {
+   ret = i915_gem_object_lock(obj, apply->ww);
+   if (ret)
+   continue;
+
+   if (obj->mm.region == mr)
+   ret = ops->process_obj(apply, obj);
+   /* Implicit object unlock */
+   }
+
+   i915_gem_object_put(obj);
+   mutex_lock(&mr->objects.lock);
+   if (ret)
+   break;
+   }
+   list_splice_tail(&still_in_list, &mr->objects.list);
+   mutex_unlock(&mr->objects.lock);
+
+   return ret;
+}
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.h 
b/drivers/gpu/drm/i915/gem/i915_gem_region.h
index 1008e580a89a..fcaa12d657d4 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.h
@@ -12,6 +12,41 @@ struct intel_memory_region;
 struct drm_i915_gem_object;
 struct sg_table;
 
+struct i915_gem_apply_to_region;
+
+/**
+ * struct i915_gem_apply_to_region_ops - ops to use when iterating over all
+ * region objects.
+ */
+struct i915_gem_apply_to_region_ops {
+   /**
+* process_obj - Process the current object
+* @apply: Embed this for private data.
+* @obj: The current object.
+*
+* Note that if this function is part of a ww transaction, and
+* if returns -EDEADLK for one of the objects, it may be
+* rerun for that same object in the same pass.
+*/
+   int (*process_obj)(struct i915_gem_apply_to_region *apply,
+  struct drm_i915_gem_object *obj);
+};
+
+/**
+ * struct i915_gem_apply_to_region - Argument to the struct
+ * i915_gem_apply_to_region_ops functions.
+ * @ops: The ops for the operation.
+ * @ww: Locking context used for the transaction.
+ * @interruptible: Whether to perform object locking interruptible.
+ *
+ * 

[PATCH v6 1/9] drm/i915/ttm: Implement a function to copy the contents of two TTM-based objects

2021-09-21 Thread Thomas Hellström
When backing up or restoring contents of pinned objects at suspend /
resume time we need to allocate a new object as the backup. Add a function
to facilitate copies between the two. Some data needs to be copied before
the migration context is ready for operation, so make sure we can
disable accelerated copies.

v2:
- Fix a missing return value check (Matthew Auld)

Signed-off-by: Thomas Hellström 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 69 +
 drivers/gpu/drm/i915/gem/i915_gem_ttm.h |  4 ++
 2 files changed, 64 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
index 2f672f06b169..22d59510d0c3 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -428,6 +428,7 @@ i915_ttm_resource_get_st(struct drm_i915_gem_object *obj,
 static int i915_ttm_accel_move(struct ttm_buffer_object *bo,
   bool clear,
   struct ttm_resource *dst_mem,
+  struct ttm_tt *dst_ttm,
   struct sg_table *dst_st)
 {
struct drm_i915_private *i915 = container_of(bo->bdev, typeof(*i915),
@@ -437,14 +438,14 @@ static int i915_ttm_accel_move(struct ttm_buffer_object 
*bo,
struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
struct sg_table *src_st;
struct i915_request *rq;
-   struct ttm_tt *ttm = bo->ttm;
+   struct ttm_tt *src_ttm = bo->ttm;
enum i915_cache_level src_level, dst_level;
int ret;
 
if (!i915->gt.migrate.context)
return -EINVAL;
 
-   dst_level = i915_ttm_cache_level(i915, dst_mem, ttm);
+   dst_level = i915_ttm_cache_level(i915, dst_mem, dst_ttm);
if (clear) {
if (bo->type == ttm_bo_type_kernel)
return -EINVAL;
@@ -461,10 +462,10 @@ static int i915_ttm_accel_move(struct ttm_buffer_object 
*bo,
}
intel_engine_pm_put(i915->gt.migrate.context->engine);
} else {
-   src_st = src_man->use_tt ? i915_ttm_tt_get_st(ttm) :
+   src_st = src_man->use_tt ? i915_ttm_tt_get_st(src_ttm) :
obj->ttm.cached_io_st;
 
-   src_level = i915_ttm_cache_level(i915, bo->resource, ttm);
+   src_level = i915_ttm_cache_level(i915, bo->resource, src_ttm);
intel_engine_pm_get(i915->gt.migrate.context->engine);
ret = intel_context_migrate_copy(i915->gt.migrate.context,
 NULL, src_st->sgl, src_level,
@@ -484,11 +485,14 @@ static int i915_ttm_accel_move(struct ttm_buffer_object 
*bo,
 
 static void __i915_ttm_move(struct ttm_buffer_object *bo, bool clear,
struct ttm_resource *dst_mem,
-   struct sg_table *dst_st)
+   struct ttm_tt *dst_ttm,
+   struct sg_table *dst_st,
+   bool allow_accel)
 {
-   int ret;
+   int ret = -EINVAL;
 
-   ret = i915_ttm_accel_move(bo, clear, dst_mem, dst_st);
+   if (allow_accel)
+   ret = i915_ttm_accel_move(bo, clear, dst_mem, dst_ttm, dst_st);
if (ret) {
struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
struct intel_memory_region *dst_reg, *src_reg;
@@ -503,7 +507,7 @@ static void __i915_ttm_move(struct ttm_buffer_object *bo, 
bool clear,
GEM_BUG_ON(!dst_reg || !src_reg);
 
dst_iter = !cpu_maps_iomem(dst_mem) ?
-   ttm_kmap_iter_tt_init(&_dst_iter.tt, bo->ttm) :
+   ttm_kmap_iter_tt_init(&_dst_iter.tt, dst_ttm) :
ttm_kmap_iter_iomap_init(&_dst_iter.io, &dst_reg->iomap,
 dst_st, dst_reg->region.start);
 
@@ -558,7 +562,7 @@ static int i915_ttm_move(struct ttm_buffer_object *bo, bool 
evict,
 
clear = !cpu_maps_iomem(bo->resource) && (!ttm || 
!ttm_tt_is_populated(ttm));
if (!(clear && ttm && !(ttm->page_flags & TTM_PAGE_FLAG_ZERO_ALLOC)))
-   __i915_ttm_move(bo, clear, dst_mem, dst_st);
+   __i915_ttm_move(bo, clear, dst_mem, bo->ttm, dst_st, true);
 
ttm_bo_move_sync_cleanup(bo, dst_mem);
i915_ttm_adjust_domains_after_move(obj);
@@ -973,3 +977,50 @@ i915_gem_ttm_system_setup(struct drm_i915_private *i915,
intel_memory_region_set_name(mr, "system-ttm");
return mr;
 }
+
+/**
+ * i915_gem_obj_copy_ttm - Copy the contents of one ttm-based gem object to
+ * another
+ * @dst: The destination object
+ * @src: The source object
+ * @allow_accel: Allow using the blitter. Otherwise TTM memcpy is used.
+ * @intr: Whether to perform waits interruptible:
+ *
+ * Note: The caller is responsible for assuring that the underlyin

[PATCH v6 0/9] drm/i915: Suspend / resume backup- and restore of LMEM.

2021-09-21 Thread Thomas Hellström
Implement backup and restore of LMEM during suspend / resume.
What complicates things a bit is handling of pinned LMEM memory during
suspend and the fact that we might be dealing with unmappable LMEM in
the future, which makes us want to restrict the number of pinned objects that
need memcpy resume.

The first two patches are prereq patches implementing object content copy
and a generic means of iterating through all objects in a region.
The third patch adds the backup / recover / restore functions and the
two last patches deal with restricting the number of objects we need to
use memcpy for.

v2:
- Some polishing of patch 4/6, see patch commit message for details (Chris
  Wilson)
- Rework of patch 3/6.

v3:
- Comment changes in patch 2/6 (Matthew Auld)
- A number of changes to patch 3/6, see commit message.
- Slightly reword comment in patch 5/6. (Matthew Auld).

v4:
- Various cleanups, among other things reworking the ttm / lmem backup-
  and resume interfaces somewhat.

v5:
- GuC adaptations. Mark GuC LMEM objects for early resume and increase
  the suspend idle timeout.

v6:
- Add two HAX patches to make broken CI happy.

Kai Vehmanen (1):
  HAX: component: do not leave master devres group open after bind

Thomas Hellström (8):
  drm/i915/ttm: Implement a function to copy the contents of two
TTM-based objects
  drm/i915/gem: Implement a function to process all gem objects of a
region
  drm/i915/gt: Increase suspend timeout
  drm/i915 Implement LMEM backup and restore for suspend / resume
  drm/i915/gt: Register the migrate contexts with their engines
  drm/i915: Don't back up pinned LMEM context images and rings during
suspend
  drm/i915: Reduce the number of objects subject to memcpy recover
  HAX: drm/i915/gem: Fix the __i915_gem_is_lmem() function

 drivers/base/component.c  |   5 +-
 drivers/gpu/drm/i915/Makefile |   1 +
 drivers/gpu/drm/i915/gem/i915_gem_context.c   |   4 +-
 drivers/gpu/drm/i915/gem/i915_gem_lmem.c  |   2 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  21 +-
 drivers/gpu/drm/i915/gem/i915_gem_pm.c|  91 
 drivers/gpu/drm/i915/gem/i915_gem_pm.h|   1 +
 drivers/gpu/drm/i915/gem/i915_gem_region.c|  70 ++
 drivers/gpu/drm/i915/gem/i915_gem_region.h|  37 
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c   |  99 +++--
 drivers/gpu/drm/i915/gem/i915_gem_ttm.h   |  14 ++
 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c| 206 ++
 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.h|  26 +++
 .../gpu/drm/i915/gem/selftests/huge_pages.c   |   2 +-
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c  |   2 +-
 drivers/gpu/drm/i915/gt/gen8_ppgtt.c  |   5 +-
 drivers/gpu/drm/i915/gt/gen8_ppgtt.h  |   4 +-
 drivers/gpu/drm/i915/gt/intel_context_types.h |   8 +
 drivers/gpu/drm/i915/gt/intel_engine_cs.c |   4 +
 drivers/gpu/drm/i915/gt/intel_engine_pm.c |  23 ++
 drivers/gpu/drm/i915/gt/intel_engine_pm.h |   2 +
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |   7 +
 .../drm/i915/gt/intel_execlists_submission.c  |   2 +
 drivers/gpu/drm/i915/gt/intel_ggtt.c  |   3 +-
 drivers/gpu/drm/i915/gt/intel_gt.c|   2 +-
 drivers/gpu/drm/i915/gt/intel_gt_pm.c |   8 +-
 drivers/gpu/drm/i915/gt/intel_gtt.c   |   3 +-
 drivers/gpu/drm/i915/gt/intel_gtt.h   |   9 +-
 drivers/gpu/drm/i915/gt/intel_lrc.c   |   3 +-
 drivers/gpu/drm/i915/gt/intel_migrate.c   |   2 +-
 drivers/gpu/drm/i915/gt/intel_ppgtt.c |  13 +-
 drivers/gpu/drm/i915/gt/intel_ring.c  |   3 +-
 .../gpu/drm/i915/gt/intel_ring_submission.c   |   3 +
 drivers/gpu/drm/i915/gt/mock_engine.c |   2 +
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c  |   2 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|   3 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  12 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  |   7 +-
 drivers/gpu/drm/i915/gvt/scheduler.c  |   2 +-
 drivers/gpu/drm/i915/i915_drv.c   |   4 +-
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |   4 +-
 41 files changed, 658 insertions(+), 63 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.h

-- 
2.31.1



Re: [PATCH v3 4/9] drm/scheduler: Add fence deadline support

2021-09-21 Thread Rob Clark
On Tue, Sep 21, 2021 at 7:18 PM Andrey Grodzovsky
 wrote:
>
>
> On 2021-09-21 4:47 p.m., Rob Clark wrote:
> > On Tue, Sep 21, 2021 at 1:09 PM Andrey Grodzovsky
> >  wrote:
> >> On 2021-09-03 2:47 p.m., Rob Clark wrote:
> >>
> >>> From: Rob Clark 
> >>>
> >>> As the finished fence is the one that is exposed to userspace, and
> >>> therefore the one that other operations, like atomic update, would
> >>> block on, we need to propagate the deadline from from the finished
> >>> fence to the actual hw fence.
> >>>
> >>> v2: Split into drm_sched_fence_set_parent() (ckoenig)
> >>>
> >>> Signed-off-by: Rob Clark 
> >>> ---
> >>>drivers/gpu/drm/scheduler/sched_fence.c | 34 +
> >>>drivers/gpu/drm/scheduler/sched_main.c  |  2 +-
> >>>include/drm/gpu_scheduler.h |  8 ++
> >>>3 files changed, 43 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/scheduler/sched_fence.c 
> >>> b/drivers/gpu/drm/scheduler/sched_fence.c
> >>> index bcea035cf4c6..4fc41a71d1c7 100644
> >>> --- a/drivers/gpu/drm/scheduler/sched_fence.c
> >>> +++ b/drivers/gpu/drm/scheduler/sched_fence.c
> >>> @@ -128,6 +128,30 @@ static void drm_sched_fence_release_finished(struct 
> >>> dma_fence *f)
> >>>dma_fence_put(&fence->scheduled);
> >>>}
> >>>
> >>> +static void drm_sched_fence_set_deadline_finished(struct dma_fence *f,
> >>> +   ktime_t deadline)
> >>> +{
> >>> + struct drm_sched_fence *fence = to_drm_sched_fence(f);
> >>> + unsigned long flags;
> >>> +
> >>> + spin_lock_irqsave(&fence->lock, flags);
> >>> +
> >>> + /* If we already have an earlier deadline, keep it: */
> >>> + if (test_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT, &f->flags) &&
> >>> + ktime_before(fence->deadline, deadline)) {
> >>> + spin_unlock_irqrestore(&fence->lock, flags);
> >>> + return;
> >>> + }
> >>> +
> >>> + fence->deadline = deadline;
> >>> + set_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT, &f->flags);
> >>> +
> >>> + spin_unlock_irqrestore(&fence->lock, flags);
> >>> +
> >>> + if (fence->parent)
> >>> + dma_fence_set_deadline(fence->parent, deadline);
> >>> +}
> >>> +
> >>>static const struct dma_fence_ops drm_sched_fence_ops_scheduled = {
> >>>.get_driver_name = drm_sched_fence_get_driver_name,
> >>>.get_timeline_name = drm_sched_fence_get_timeline_name,
> >>> @@ -138,6 +162,7 @@ static const struct dma_fence_ops 
> >>> drm_sched_fence_ops_finished = {
> >>>.get_driver_name = drm_sched_fence_get_driver_name,
> >>>.get_timeline_name = drm_sched_fence_get_timeline_name,
> >>>.release = drm_sched_fence_release_finished,
> >>> + .set_deadline = drm_sched_fence_set_deadline_finished,
> >>>};
> >>>
> >>>struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f)
> >>> @@ -152,6 +177,15 @@ struct drm_sched_fence *to_drm_sched_fence(struct 
> >>> dma_fence *f)
> >>>}
> >>>EXPORT_SYMBOL(to_drm_sched_fence);
> >>>
> >>> +void drm_sched_fence_set_parent(struct drm_sched_fence *s_fence,
> >>> + struct dma_fence *fence)
> >>> +{
> >>> + s_fence->parent = dma_fence_get(fence);
> >>> + if (test_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT,
> >>> +  &s_fence->finished.flags))
> >>> + dma_fence_set_deadline(fence, s_fence->deadline);
> >>
> >> I believe above you should pass be s_fence->finished to
> >> dma_fence_set_deadline
> >> instead it fence which is the HW fence itself.
> > Hmm, unless this has changed recently with some patches I don't have,
> > s_fence->parent is the one signalled by hw, so it is the one we want
> > to set the deadline on
> >
> > BR,
> > -R
>
>
> No it didn't change. But then when exactly will
> drm_sched_fence_set_deadline_finished
> execute such that fence->parent != NULL ? In other words, I am not clear
> how propagation
> happens otherwise - if dma_fence_set_deadline is called with the HW
> fence then the assumption
> here is that driver provided driver specific
> dma_fence_ops.dma_fence_set_deadline callback executes
> but I was under impression that drm_sched_fence_set_deadline_finished is
> the one that propagates
> the deadline to the HW fence's callback and for it to execute
> dma_fence_set_deadline needs to be called
> with s_fence->finished.

Assuming I didn't screw up drm/msm conversion to scheduler,
&s_fence->finished is the one that will be returned to userspace.. and
later passed back to kernel for atomic commit (or to the compositor).
So it is the one that fence->set_deadline() will be called on.  But
s_fence->parent is the actual hw fence that needs to know about the
deadline.  Depending on whether or not the job has been written into
hw ringbuffer or not, there are two cases:

1) not scheduled yet, s_fence will store the deadline and propagate it
later once s_fence->parent is known
2) already scheduled, in which case s_fence

Re: [Freedreno] [PATCH v2 00/13] drm/hdcp: Pull HDCP auth/exchange/check into helpers

2021-09-21 Thread abhinavk

Hi Sean

On 2021-09-15 13:38, Sean Paul wrote:

From: Sean Paul 

Hello again,
This is the second version of the HDCP helper patchset. See version 1
here: https://patchwork.freedesktop.org/series/94623/

In this second version, I've fixed up the oopsies exposed by 0-day and
yamllint and incorporated early review feedback from the dt/dts 
reviews.


Please take a look,

Sean


One question overall on the series:

1) Regarding validation, did you run any secure video to check the 
transitions?

2) Is running HDCP 1x compliance also part of the validation efforts?

Thanks

Abhinav



Sean Paul (13):
  drm/hdcp: Add drm_hdcp_atomic_check()
  drm/hdcp: Avoid changing crtc state in hdcp atomic check
  drm/hdcp: Update property value on content type and user changes
  drm/hdcp: Expand HDCP helper library for enable/disable/check
  drm/i915/hdcp: Consolidate HDCP setup/state cache
  drm/i915/hdcp: Retain hdcp_capable return codes
  drm/i915/hdcp: Use HDCP helpers for i915
  drm/msm/dpu_kms: Re-order dpu includes
  drm/msm/dpu: Remove useless checks in dpu_encoder
  drm/msm/dpu: Remove encoder->enable() hack
  drm/msm/dp: Re-order dp_audio_put in deinit_sub_modules
  dt-bindings: msm/dp: Add bindings for HDCP registers
  drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

 .../bindings/display/msm/dp-controller.yaml   |7 +-
 arch/arm64/boot/dts/qcom/sc7180.dtsi  |4 +-
 drivers/gpu/drm/drm_hdcp.c| 1197 -
 drivers/gpu/drm/i915/display/intel_atomic.c   |7 +-
 drivers/gpu/drm/i915/display/intel_ddi.c  |   29 +-
 .../drm/i915/display/intel_display_debugfs.c  |   11 +-
 .../drm/i915/display/intel_display_types.h|   58 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  |  345 ++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   17 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 1011 +++---
 drivers/gpu/drm/i915/display/intel_hdcp.h |   35 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c |  256 ++--
 drivers/gpu/drm/msm/Makefile  |1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |   17 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |   30 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |2 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h |4 -
 drivers/gpu/drm/msm/dp/dp_debug.c |   49 +-
 drivers/gpu/drm/msm/dp/dp_debug.h |6 +-
 drivers/gpu/drm/msm/dp/dp_display.c   |   47 +-
 drivers/gpu/drm/msm/dp/dp_display.h   |5 +
 drivers/gpu/drm/msm/dp/dp_drm.c   |   68 +-
 drivers/gpu/drm/msm/dp/dp_drm.h   |5 +
 drivers/gpu/drm/msm/dp/dp_hdcp.c  |  433 ++
 drivers/gpu/drm/msm/dp/dp_hdcp.h  |   27 +
 drivers/gpu/drm/msm/dp/dp_parser.c|   22 +-
 drivers/gpu/drm/msm/dp/dp_parser.h|4 +
 drivers/gpu/drm/msm/dp/dp_reg.h   |   44 +-
 drivers/gpu/drm/msm/msm_atomic.c  |   15 +
 include/drm/drm_hdcp.h|  194 +++
 30 files changed, 2561 insertions(+), 1389 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h


Re: [PATCH v3] mdacon: fix redefinition of 'scr_memsetw'

2021-09-21 Thread Jackie Liu

ping, would anyone take this patch?

在 2021/9/15 上午9:13, Jackie Liu 写道:

From: Jackie Liu 

CONFIG_VGA_CONSOLE=n and CONFIG_MDA_CONSOLE=n will cause vt_buffer.h not
include .

But if we set CONFIG_MDA_CONSOLE=m, mdacon.c include 
is in front of include . VT_BUF_HAVE_MEMSETW is not defined,
so vt_buffer.h will define a scr_memsetw, after that, vga.h also define
a scr_memsetw, so the repeated definition of scr_memsetw appears, builds
error.

We only need to make vt_buffer.h also contain vga.h when
CONFIG_MDA_CONSOLE=m. This problem can be fixed.

BTW, mdacon.c no need to include vga.h forcibly, let vt_buffer.h do it.

Cc: linux-fb...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Fixes: ac036f9570a2 ("vga: optimise console scrolling")
Reviewed-by: Greg Kroah-Hartman 
Signed-off-by: Jackie Liu 
---
  drivers/video/console/mdacon.c | 1 -
  include/linux/vt_buffer.h  | 2 +-
  2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index ef29b321967f..5898d01bc492 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -42,7 +42,6 @@
  #include 
  
  #include 

-#include 
  
  static DEFINE_SPINLOCK(mda_lock);
  
diff --git a/include/linux/vt_buffer.h b/include/linux/vt_buffer.h

index 848db1b1569f..3a79cc27a33b 100644
--- a/include/linux/vt_buffer.h
+++ b/include/linux/vt_buffer.h
@@ -16,7 +16,7 @@
  
  #include 
  
-#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE)

+#if defined(CONFIG_VGA_CONSOLE) || IS_ENABLED(CONFIG_MDA_CONSOLE)
  #include 
  #endif
  



Re: [PATCH v2 2/2] drm/panel: Add Sony Tulip Truly NT35521 driver

2021-09-21 Thread Shawn Guo
On Tue, Aug 24, 2021 at 09:59:04PM +0200, Sam Ravnborg wrote:
> On Tue, Aug 24, 2021 at 10:58:31AM +0800, Shawn Guo wrote:
> > On Mon, Aug 09, 2021 at 01:10:08PM +0800, Shawn Guo wrote:
> > > It adds a DRM panel driver for Sony Tulip Truly NT35521 5.24" 1280x720
> > > DSI panel, which can be found on Sony Xperia M4 Aqua phone.  The panel
> > > backlight is managed through DSI link.
> > > 
> > > The driver is built using linux-mdss-dsi-panel-driver-generator[1], and
> > > additionally modeling the 5V control GPIOs with regulators and adding
> > > Backlight GPIO support.
> > > 
> > > [1] 
> > > https://github.com/msm8916-mainline/linux-mdss-dsi-panel-driver-generator
> > > 
> > > Signed-off-by: Shawn Guo 
> > 
> > Sam, Stephan,
> > 
> > Thank you for the review comments on v1!  How does v2 look to you?
> 
> I will not have time until next week - sorry.
> Please ping me if you have no feedback i one week from now.

Sam,

Could you help handle this patch now?  Thanks!

Shawn


Re: [Freedreno] [PATCH v2 08/13] drm/msm/dpu_kms: Re-order dpu includes

2021-09-21 Thread abhinavk

On 2021-09-15 13:38, Sean Paul wrote:

From: Sean Paul 

Make includes alphabetical in dpu_kms.c

Signed-off-by: Sean Paul 

Reviewed-by: Abhinav Kumar 

Link:
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-9-s...@poorly.run
#v1

Changes in v2:
-None
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index ae48f41821cf..fb0d9f781c66 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -21,14 +21,14 @@
 #include "msm_gem.h"
 #include "disp/msm_disp_snapshot.h"

-#include "dpu_kms.h"
 #include "dpu_core_irq.h"
+#include "dpu_crtc.h"
+#include "dpu_encoder.h"
 #include "dpu_formats.h"
 #include "dpu_hw_vbif.h"
-#include "dpu_vbif.h"
-#include "dpu_encoder.h"
+#include "dpu_kms.h"
 #include "dpu_plane.h"
-#include "dpu_crtc.h"
+#include "dpu_vbif.h"

 #define CREATE_TRACE_POINTS
 #include "dpu_trace.h"


Re: [Freedreno] [PATCH v2 13/13] drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

2021-09-21 Thread abhinavk

On 2021-09-15 13:38, Sean Paul wrote:

From: Sean Paul 

This patch adds HDCP 1.x support to msm DP connectors using the new 
HDCP

helpers.

Cc: Stephen Boyd 
Signed-off-by: Sean Paul 
Link:
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-15-s...@poorly.run
#v1

Changes in v2:
-Squash [1] into this patch with the following changes (Stephen)
  -Update the sc7180 dtsi file
  -Remove resource names and just use index (Stephen)





[1]
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-14-s...@poorly.run
---
 arch/arm64/boot/dts/qcom/sc7180.dtsi |   4 +-
 drivers/gpu/drm/msm/Makefile |   1 +
 drivers/gpu/drm/msm/dp/dp_debug.c|  49 ++-
 drivers/gpu/drm/msm/dp/dp_debug.h|   6 +-
 drivers/gpu/drm/msm/dp/dp_display.c  |  45 ++-
 drivers/gpu/drm/msm/dp/dp_display.h  |   5 +
 drivers/gpu/drm/msm/dp/dp_drm.c  |  68 -
 drivers/gpu/drm/msm/dp/dp_drm.h  |   5 +
 drivers/gpu/drm/msm/dp/dp_hdcp.c | 433 +++
 drivers/gpu/drm/msm/dp/dp_hdcp.h |  27 ++
 drivers/gpu/drm/msm/dp/dp_parser.c   |  22 +-
 drivers/gpu/drm/msm/dp/dp_parser.h   |   4 +
 drivers/gpu/drm/msm/dp/dp_reg.h  |  44 ++-
 drivers/gpu/drm/msm/msm_atomic.c |  15 +
 14 files changed, 709 insertions(+), 19 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi
b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index c8921e2d6480..3ae6fc7a2c01 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -3088,7 +3088,9 @@ mdss_dp: displayport-controller@ae9 {
compatible = "qcom,sc7180-dp";
status = "disabled";

-   reg = <0 0x0ae9 0 0x1400>;
+   reg = <0 0x0ae9 0 0x1400>,
+ <0 0x0aed1000 0 0x174>,
+ <0 0x0aee1000 0 0x2c>;

interrupt-parent = <&mdss>;
interrupts = <12>;
diff --git a/drivers/gpu/drm/msm/Makefile 
b/drivers/gpu/drm/msm/Makefile

index 904535eda0c4..98731fd262d6 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -109,6 +109,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
dp/dp_ctrl.o \
dp/dp_display.o \
dp/dp_drm.o \
+   dp/dp_hdcp.o \
dp/dp_hpd.o \
dp/dp_link.o \
dp/dp_panel.o \
diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c
b/drivers/gpu/drm/msm/dp/dp_debug.c
index 2f6247e80e9d..de16fca8782a 100644
--- a/drivers/gpu/drm/msm/dp/dp_debug.c
+++ b/drivers/gpu/drm/msm/dp/dp_debug.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "dp_parser.h"
 #include "dp_catalog.h"
@@ -15,6 +16,7 @@
 #include "dp_ctrl.h"
 #include "dp_debug.h"
 #include "dp_display.h"
+#include "dp_hdcp.h"

 #define DEBUG_NAME "msm_dp"

@@ -24,6 +26,7 @@ struct dp_debug_private {
struct dp_usbpd *usbpd;
struct dp_link *link;
struct dp_panel *panel;
+   struct dp_hdcp *hdcp;
struct drm_connector **connector;
struct device *dev;
struct drm_device *drm_dev;
@@ -349,6 +352,38 @@ static int dp_test_active_open(struct inode 
*inode,

inode->i_private);
 }

+static ssize_t dp_hdcp_key_write(struct file *file, const char __user 
*ubuf,

+size_t len, loff_t *offp)
+{
+   char *input_buffer;
+   int ret = 0;
+   struct dp_debug_private *debug = file->private_data;
+   struct drm_device *dev;
+
+   dev = debug->drm_dev;
+
+   if (len != (DRM_HDCP_KSV_LEN + DP_HDCP_NUM_KEYS * DP_HDCP_KEY_LEN))
+   return -EINVAL;
+
+   if (!debug->hdcp)
+   return -ENOENT;
+
+   input_buffer = memdup_user_nul(ubuf, len);
+   if (IS_ERR(input_buffer))
+   return PTR_ERR(input_buffer);
+
+   ret = dp_hdcp_ingest_key(debug->hdcp, input_buffer, len);
+
+   kfree(input_buffer);
+   if (ret < 0) {
+   DRM_ERROR("Could not ingest HDCP key, ret=%d\n", ret);
+   return ret;
+   }
+
+   *offp += len;
+   return len;
+}


It seems like the HDCP keys written using debugfs, just for my 
understanding,
are you storing this in some secure partition and the usermode reads 
from it

and writes them here?


+
 static const struct file_operations dp_debug_fops = {
.open = simple_open,
.read = dp_debug_read_info,
@@ -363,6 +398,12 @@ static const struct file_operations 
test_active_fops = {

.write = dp_test_active_write
 };

+static const struct file_operations dp_hdcp_key_fops = {
+   .owner = THIS_MODULE,
+   .open = simple_open,
+   .write = dp_hdcp_key_write,
+};
+
 static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor 
*minor)

 {
int rc = 0;
@@

Re: [PATCH v3 4/9] drm/scheduler: Add fence deadline support

2021-09-21 Thread Andrey Grodzovsky



On 2021-09-21 4:47 p.m., Rob Clark wrote:

On Tue, Sep 21, 2021 at 1:09 PM Andrey Grodzovsky
 wrote:

On 2021-09-03 2:47 p.m., Rob Clark wrote:


From: Rob Clark 

As the finished fence is the one that is exposed to userspace, and
therefore the one that other operations, like atomic update, would
block on, we need to propagate the deadline from from the finished
fence to the actual hw fence.

v2: Split into drm_sched_fence_set_parent() (ckoenig)

Signed-off-by: Rob Clark 
---
   drivers/gpu/drm/scheduler/sched_fence.c | 34 +
   drivers/gpu/drm/scheduler/sched_main.c  |  2 +-
   include/drm/gpu_scheduler.h |  8 ++
   3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/scheduler/sched_fence.c 
b/drivers/gpu/drm/scheduler/sched_fence.c
index bcea035cf4c6..4fc41a71d1c7 100644
--- a/drivers/gpu/drm/scheduler/sched_fence.c
+++ b/drivers/gpu/drm/scheduler/sched_fence.c
@@ -128,6 +128,30 @@ static void drm_sched_fence_release_finished(struct 
dma_fence *f)
   dma_fence_put(&fence->scheduled);
   }

+static void drm_sched_fence_set_deadline_finished(struct dma_fence *f,
+   ktime_t deadline)
+{
+ struct drm_sched_fence *fence = to_drm_sched_fence(f);
+ unsigned long flags;
+
+ spin_lock_irqsave(&fence->lock, flags);
+
+ /* If we already have an earlier deadline, keep it: */
+ if (test_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT, &f->flags) &&
+ ktime_before(fence->deadline, deadline)) {
+ spin_unlock_irqrestore(&fence->lock, flags);
+ return;
+ }
+
+ fence->deadline = deadline;
+ set_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT, &f->flags);
+
+ spin_unlock_irqrestore(&fence->lock, flags);
+
+ if (fence->parent)
+ dma_fence_set_deadline(fence->parent, deadline);
+}
+
   static const struct dma_fence_ops drm_sched_fence_ops_scheduled = {
   .get_driver_name = drm_sched_fence_get_driver_name,
   .get_timeline_name = drm_sched_fence_get_timeline_name,
@@ -138,6 +162,7 @@ static const struct dma_fence_ops 
drm_sched_fence_ops_finished = {
   .get_driver_name = drm_sched_fence_get_driver_name,
   .get_timeline_name = drm_sched_fence_get_timeline_name,
   .release = drm_sched_fence_release_finished,
+ .set_deadline = drm_sched_fence_set_deadline_finished,
   };

   struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f)
@@ -152,6 +177,15 @@ struct drm_sched_fence *to_drm_sched_fence(struct 
dma_fence *f)
   }
   EXPORT_SYMBOL(to_drm_sched_fence);

+void drm_sched_fence_set_parent(struct drm_sched_fence *s_fence,
+ struct dma_fence *fence)
+{
+ s_fence->parent = dma_fence_get(fence);
+ if (test_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT,
+  &s_fence->finished.flags))
+ dma_fence_set_deadline(fence, s_fence->deadline);


I believe above you should pass be s_fence->finished to
dma_fence_set_deadline
instead it fence which is the HW fence itself.

Hmm, unless this has changed recently with some patches I don't have,
s_fence->parent is the one signalled by hw, so it is the one we want
to set the deadline on

BR,
-R



No it didn't change. But then when exactly will 
drm_sched_fence_set_deadline_finished
execute such that fence->parent != NULL ? In other words, I am not clear 
how propagation
happens otherwise - if dma_fence_set_deadline is called with the HW 
fence then the assumption
here is that driver provided driver specific 
dma_fence_ops.dma_fence_set_deadline callback executes
but I was under impression that drm_sched_fence_set_deadline_finished is 
the one that propagates
the deadline to the HW fence's callback and for it to execute 
dma_fence_set_deadline needs to be called

with s_fence->finished.

Andrey






Andrey



+}
+
   struct drm_sched_fence *drm_sched_fence_alloc(struct drm_sched_entity 
*entity,
 void *owner)
   {
diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index 595e47ff7d06..27bf0ac0625f 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -978,7 +978,7 @@ static int drm_sched_main(void *param)
   drm_sched_fence_scheduled(s_fence);

   if (!IS_ERR_OR_NULL(fence)) {
- s_fence->parent = dma_fence_get(fence);
+ drm_sched_fence_set_parent(s_fence, fence);
   r = dma_fence_add_callback(fence, &sched_job->cb,
  drm_sched_job_done_cb);
   if (r == -ENOENT)
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index 7f77a455722c..158ddd662469 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -238,6 +238,12 @@ struct drm_sched_fence {
*/
   struct dma_fencefinished;

+ /**
+ 

[PATCH] drm/i915: Drop stealing of bits from i915_sw_fence function pointer

2021-09-21 Thread Matthew Brost
Rather than stealing bits from i915_sw_fence function pointer use
seperate fields for function pointer and flags. If using two different
fields, the 4 byte alignment for the i915_sw_fence function pointer can
also be dropped.

Signed-off-by: Matthew Brost 
---
 drivers/gpu/drm/i915/display/intel_display.c  |  2 +-
 drivers/gpu/drm/i915/gem/i915_gem_context.c   |  2 +-
 drivers/gpu/drm/i915/i915_request.c   |  4 ++--
 drivers/gpu/drm/i915/i915_sw_fence.c  |  9 +++-
 drivers/gpu/drm/i915/i915_sw_fence.h  | 21 +--
 drivers/gpu/drm/i915/i915_sw_fence_work.c |  2 +-
 .../gpu/drm/i915/selftests/i915_sw_fence.c|  2 +-
 drivers/gpu/drm/i915/selftests/lib_sw_fence.c |  4 ++--
 8 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index a7ca38613f89..6d5bb55ffc82 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -10323,7 +10323,7 @@ static void intel_atomic_commit_work(struct work_struct 
*work)
intel_atomic_commit_tail(state);
 }
 
-static int __i915_sw_fence_call
+static int
 intel_atomic_commit_ready(struct i915_sw_fence *fence,
  enum i915_sw_fence_notify notify)
 {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index c2ab0e22db0a..df5fec5c3da8 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -800,7 +800,7 @@ static void free_engines_rcu(struct rcu_head *rcu)
free_engines(engines);
 }
 
-static int __i915_sw_fence_call
+static int
 engines_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
 {
struct i915_gem_engines *engines =
diff --git a/drivers/gpu/drm/i915/i915_request.c 
b/drivers/gpu/drm/i915/i915_request.c
index ce446716d092..945d3025a0b6 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -719,7 +719,7 @@ void i915_request_cancel(struct i915_request *rq, int error)
intel_context_cancel_request(rq->context, rq);
 }
 
-static int __i915_sw_fence_call
+static int
 submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
 {
struct i915_request *request =
@@ -755,7 +755,7 @@ submit_notify(struct i915_sw_fence *fence, enum 
i915_sw_fence_notify state)
return NOTIFY_DONE;
 }
 
-static int __i915_sw_fence_call
+static int
 semaphore_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
 {
struct i915_request *rq = container_of(fence, typeof(*rq), semaphore);
diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c 
b/drivers/gpu/drm/i915/i915_sw_fence.c
index c589a681da77..5cf101cf06d2 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence.c
+++ b/drivers/gpu/drm/i915/i915_sw_fence.c
@@ -34,7 +34,7 @@ enum {
 
 static void *i915_sw_fence_debug_hint(void *addr)
 {
-   return (void *)(((struct i915_sw_fence *)addr)->flags & 
I915_SW_FENCE_MASK);
+   return (void *)(((struct i915_sw_fence *)addr)->fn);
 }
 
 #ifdef CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS
@@ -126,10 +126,7 @@ static inline void debug_fence_assert(struct i915_sw_fence 
*fence)
 static int __i915_sw_fence_notify(struct i915_sw_fence *fence,
  enum i915_sw_fence_notify state)
 {
-   i915_sw_fence_notify_t fn;
-
-   fn = (i915_sw_fence_notify_t)(fence->flags & I915_SW_FENCE_MASK);
-   return fn(fence, state);
+   return fence->fn(fence, state);
 }
 
 #ifdef CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS
@@ -242,7 +239,7 @@ void __i915_sw_fence_init(struct i915_sw_fence *fence,
  const char *name,
  struct lock_class_key *key)
 {
-   BUG_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK);
+   BUG_ON(!fn);
 
__init_waitqueue_head(&fence->wait, name, key);
fence->flags = (unsigned long)fn;
diff --git a/drivers/gpu/drm/i915/i915_sw_fence.h 
b/drivers/gpu/drm/i915/i915_sw_fence.h
index 30a863353ee6..70ba1789aa89 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence.h
+++ b/drivers/gpu/drm/i915/i915_sw_fence.h
@@ -17,26 +17,25 @@
 
 struct completion;
 struct dma_resv;
+struct i915_sw_fence;
+
+enum i915_sw_fence_notify {
+   FENCE_COMPLETE,
+   FENCE_FREE
+};
+
+typedef int (*i915_sw_fence_notify_t)(struct i915_sw_fence *,
+ enum i915_sw_fence_notify state);
 
 struct i915_sw_fence {
wait_queue_head_t wait;
+   i915_sw_fence_notify_t fn;
unsigned long flags;
atomic_t pending;
int error;
 };
 
 #define I915_SW_FENCE_CHECKED_BIT  0 /* used internally for DAG checking */
-#define I915_SW_FENCE_PRIVATE_BIT  1 /* available for use by owner */
-#define I915_SW_FENCE_MASK (~3)
-
-enum i915_sw_fence_notify {
-   FENCE_COMPLETE,
-   FENCE_FREE
-};
-
-typedef int (

[PATCH] drm/i915: fix blank screen booting crashes

2021-09-21 Thread Matthew Brost
From: Hugh Dickins 

5.15-rc1 crashes with blank screen when booting up on two ThinkPads
using i915.  Bisections converge convincingly, but arrive at different
and surprising "culprits", none of them the actual culprit.

netconsole (with init_netconsole() hacked to call i915_init() when
logging has started, instead of by module_init()) tells the story:

kernel BUG at drivers/gpu/drm/i915/i915_sw_fence.c:245!
with RSI: 814d408b pointing to sw_fence_dummy_notify().
I've been building with CONFIG_CC_OPTIMIZE_FOR_SIZE=y, and that
function needs to be 4-byte aligned.

v2:
 (Jani Nikula)
  - Change BUG_ON to WARN_ON
v3:
 (Jani / Tvrtko)
  - Short circuit __i915_sw_fence_init on WARN_ON
v4:
 (Lucas)
  - Break WARN_ON changes out in a different patch

Fixes: 62eaf0ae217d ("drm/i915/guc: Support request cancellation")
Signed-off-by: Hugh Dickins 
Signed-off-by: Matthew Brost 
Reviewed-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/intel_context.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index ff637147b1a9..e7f78bc7ebfc 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -362,8 +362,8 @@ static int __intel_context_active(struct i915_active 
*active)
return 0;
 }
 
-static int sw_fence_dummy_notify(struct i915_sw_fence *sf,
-enum i915_sw_fence_notify state)
+static int __i915_sw_fence_call
+sw_fence_dummy_notify(struct i915_sw_fence *sf, enum i915_sw_fence_notify 
state)
 {
return NOTIFY_DONE;
 }
-- 
2.32.0



Re: [Intel-gfx] [PATCH] drm/i915: fix blank screen booting crashes

2021-09-21 Thread Matthew Brost
On Tue, Sep 21, 2021 at 04:29:31PM -0700, Lucas De Marchi wrote:
> On Tue, Sep 21, 2021 at 03:55:15PM -0700, Matthew Brost wrote:
> > On Tue, Sep 21, 2021 at 11:46:37AM -0700, Lucas De Marchi wrote:
> > > On Tue, Sep 21, 2021 at 10:43:32AM -0700, Matthew Brost wrote:
> > > > From: Hugh Dickins 
> > > >
> > > > 5.15-rc1 crashes with blank screen when booting up on two ThinkPads
> > > > using i915.  Bisections converge convincingly, but arrive at different
> > > > and surprising "culprits", none of them the actual culprit.
> > > >
> > > > netconsole (with init_netconsole() hacked to call i915_init() when
> > > > logging has started, instead of by module_init()) tells the story:
> > > >
> > > > kernel BUG at drivers/gpu/drm/i915/i915_sw_fence.c:245!
> > > > with RSI: 814d408b pointing to sw_fence_dummy_notify().
> > > > I've been building with CONFIG_CC_OPTIMIZE_FOR_SIZE=y, and that
> > > > function needs to be 4-byte aligned.
> > > >
> > > > v2:
> > > > (Jani Nikula)
> > > >  - Change BUG_ON to WARN_ON
> > > > v3:
> > > > (Jani / Tvrtko)
> > > >  - Short circuit __i915_sw_fence_init on WARN_ON
> > > >
> > > > Fixes: 62eaf0ae217d ("drm/i915/guc: Support request cancellation")
> > > > Signed-off-by: Hugh Dickins 
> > > > Signed-off-by: Matthew Brost 
> > > > Reviewed-by: Matthew Brost 
> > > > ---
> > > > drivers/gpu/drm/i915/gt/intel_context.c |  4 ++--
> > > > drivers/gpu/drm/i915/i915_sw_fence.c| 17 ++---
> > > > 2 files changed, 12 insertions(+), 9 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
> > > > b/drivers/gpu/drm/i915/gt/intel_context.c
> > > > index ff637147b1a9..e7f78bc7ebfc 100644
> > > > --- a/drivers/gpu/drm/i915/gt/intel_context.c
> > > > +++ b/drivers/gpu/drm/i915/gt/intel_context.c
> > > > @@ -362,8 +362,8 @@ static int __intel_context_active(struct 
> > > > i915_active *active)
> > > > return 0;
> > > > }
> > > >
> > > 
> > > > -static int sw_fence_dummy_notify(struct i915_sw_fence *sf,
> > > > -enum i915_sw_fence_notify state)
> > > > +static int __i915_sw_fence_call
> > > > +sw_fence_dummy_notify(struct i915_sw_fence *sf, enum 
> > > > i915_sw_fence_notify state)
> > > > {
> > > > return NOTIFY_DONE;
> > > > }
> > > > diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c 
> > > > b/drivers/gpu/drm/i915/i915_sw_fence.c
> > > > index c589a681da77..08cea73264e7 100644
> > > > --- a/drivers/gpu/drm/i915/i915_sw_fence.c
> > > > +++ b/drivers/gpu/drm/i915/i915_sw_fence.c
> > > > @@ -13,9 +13,9 @@
> > > > #include "i915_selftest.h"
> > > >
> > > > #if IS_ENABLED(CONFIG_DRM_I915_DEBUG)
> > > > -#define I915_SW_FENCE_BUG_ON(expr) BUG_ON(expr)
> > > > +#define I915_SW_FENCE_WARN_ON(expr) WARN_ON(expr)
> > > > #else
> > > > -#define I915_SW_FENCE_BUG_ON(expr) BUILD_BUG_ON_INVALID(expr)
> > > > +#define I915_SW_FENCE_WARN_ON(expr) BUILD_BUG_ON_INVALID(expr)
> > > > #endif
> > > >
> > > > static DEFINE_SPINLOCK(i915_sw_fence_lock);
> > > > @@ -129,7 +129,10 @@ static int __i915_sw_fence_notify(struct 
> > > > i915_sw_fence *fence,
> > > > i915_sw_fence_notify_t fn;
> > > >
> > > > fn = (i915_sw_fence_notify_t)(fence->flags & 
> > > > I915_SW_FENCE_MASK);
> > > > -   return fn(fence, state);
> > > > +   if (likely(fn))
> > > > +   return fn(fence, state);
> > > > +   else
> > > > +   return 0;
> > > 
> > > since the knowledge for these being NULL (or with the wrong alignment)
> > > are in the init/reinit functions,  wouldn't it be better to just add a
> > > fence_nop() and assign it there instead this likely() here?
> > > 
> > 
> > Maybe? I prefer the way it is.
> > 
> > > > }
> > > >
> > > > #ifdef CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS
> > > > @@ -242,9 +245,9 @@ void __i915_sw_fence_init(struct i915_sw_fence 
> > > > *fence,
> > > >   const char *name,
> > > >   struct lock_class_key *key)
> > > > {
> > > > -   BUG_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK);
> > > > -
> > > > __init_waitqueue_head(&fence->wait, name, key);
> > > > +   if (WARN_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK))
> > > > +   return;
> > > 
> > > like:
> > >   if (WARN_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK))
> > >   fence->flags = (unsigned long)sw_fence_dummy_notify;
> > >   else
> > >   fence->flags = (unsigned long)fn;
> > > 
> > > 
> > > f you return here instead of calling i915_sw_fence_reinit(), aren't you
> > > just going to use uninitialized memory later? At least in the selftests,
> > > which allocate it with kmalloc()... I didn't check others.
> > > 
> > 
> > I don't think so, maybe the fence won't work but it won't blow up
> > either.
> > 
> > > 
> > > For the bug fix we could just add the __aligned(4) and leave the rest to a
> > > separate patch.
> > > 
> > 
> > The bug was sw_fence_dummy_notify in gt/intel_context.c was not 4 byte
> > align wh

Re: [PATCH v2 2/2] drm: rcar-du: Add R-Car DSI driver

2021-09-21 Thread Laurent Pinchart
Hi Andrzej,

On Tue, Sep 21, 2021 at 09:42:11PM +0200, Andrzej Hajda wrote:
> W dniu 23.06.2021 o 15:56, Laurent Pinchart pisze:
> > From: LUU HOAI 
> >
> > The driver supports the MIPI DSI/CSI-2 TX encoder found in the R-Car V3U
> > SoC. It currently supports DSI mode only.
> >
> > Signed-off-by: LUU HOAI 
> > Signed-off-by: Laurent Pinchart 
> > Reviewed-by: Kieran Bingham 
> > Tested-by: Kieran Bingham 
> > ---
> >   drivers/gpu/drm/rcar-du/Kconfig  |   6 +
> >   drivers/gpu/drm/rcar-du/Makefile |   1 +
> >   drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c  | 827 +++
> >   drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h | 172 
> >   4 files changed, 1006 insertions(+)
> >   create mode 100644 drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> >   create mode 100644 drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h
> >
> > diff --git a/drivers/gpu/drm/rcar-du/Kconfig 
> > b/drivers/gpu/drm/rcar-du/Kconfig
> > index b47e74421e34..8cb94fe90639 100644
> > --- a/drivers/gpu/drm/rcar-du/Kconfig
> > +++ b/drivers/gpu/drm/rcar-du/Kconfig
> > @@ -38,6 +38,12 @@ config DRM_RCAR_LVDS
> > help
> >   Enable support for the R-Car Display Unit embedded LVDS encoders.
> >   
> > +config DRM_RCAR_MIPI_DSI
> > +   tristate "R-Car DU MIPI DSI Encoder Support"
> > +   depends on DRM && DRM_BRIDGE && OF
> > +   help
> > + Enable support for the R-Car Display Unit embedded MIPI DSI encoders.
> > +
> >   config DRM_RCAR_VSP
> > bool "R-Car DU VSP Compositor Support" if ARM
> > default y if ARM64
> > diff --git a/drivers/gpu/drm/rcar-du/Makefile 
> > b/drivers/gpu/drm/rcar-du/Makefile
> > index 4d1187ccc3e5..adc1b49d02cf 100644
> > --- a/drivers/gpu/drm/rcar-du/Makefile
> > +++ b/drivers/gpu/drm/rcar-du/Makefile
> > @@ -19,6 +19,7 @@ obj-$(CONFIG_DRM_RCAR_CMM)+= rcar_cmm.o
> >   obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o
> >   obj-$(CONFIG_DRM_RCAR_DW_HDMI)+= rcar_dw_hdmi.o
> >   obj-$(CONFIG_DRM_RCAR_LVDS)   += rcar_lvds.o
> > +obj-$(CONFIG_DRM_RCAR_MIPI_DSI)+= rcar_mipi_dsi.o
> >   
> >   # 'remote-endpoint' is fixed up at run-time
> >   DTC_FLAGS_rcar_du_of_lvds_r8a7790 += -Wno-graph_endpoint
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c 
> > b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> > new file mode 100644
> > index ..e94245029f95
> > --- /dev/null
> > +++ b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> > @@ -0,0 +1,827 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * rcar_mipi_dsi.c  --  R-Car MIPI DSI Encoder
> > + *
> > + * Copyright (C) 2020 Renesas Electronics Corporation
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "rcar_mipi_dsi_regs.h"
> > +
> > +struct rcar_mipi_dsi {
> > +   struct device *dev;
> > +   const struct rcar_mipi_dsi_device_info *info;
> > +   struct reset_control *rstc;
> > +
> > +   struct mipi_dsi_host host;
> > +   struct drm_bridge bridge;
> > +   struct drm_bridge *next_bridge;
> > +   struct drm_connector connector;
> > +
> > +   void __iomem *mmio;
> > +   struct {
> > +   struct clk *mod;
> > +   struct clk *pll;
> > +   struct clk *dsi;
> > +   } clocks;
> > +
> > +   struct drm_display_mode display_mode;
> > +   enum mipi_dsi_pixel_format format;
> > +   unsigned int num_data_lanes;
> > +   unsigned int lanes;
> > +};
> > +
> > +static inline struct rcar_mipi_dsi *
> > +bridge_to_rcar_mipi_dsi(struct drm_bridge *bridge)
> > +{
> > +   return container_of(bridge, struct rcar_mipi_dsi, bridge);
> > +}
> > +
> > +static inline struct rcar_mipi_dsi *
> > +host_to_rcar_mipi_dsi(struct mipi_dsi_host *host)
> > +{
> > +   return container_of(host, struct rcar_mipi_dsi, host);
> > +}
> > +
> > +static const u32 phtw[] = {
> > +   0x01020114, 0x01600115, /* General testing */
> > +   0x01030116, 0x0102011d, /* General testing */
> > +   0x011101a4, 0x018601a4, /* 1Gbps testing */
> > +   0x014201a0, 0x010001a3, /* 1Gbps testing */
> > +   0x0101011f, /* 1Gbps testing */
> > +};
> > +
> > +static const u32 phtw2[] = {
> > +   0x010c0130, 0x010c0140, /* General testing */
> > +   0x010c0150, 0x010c0180, /* General testing */
> > +   0x010c0190,
> > +   0x010a0160, 0x010a0170,
> > +   0x01800164, 0x01800174, /* 1Gbps testing */
> > +};
> > +
> > +static const u32 hsfreqrange_table[][2] = {
> > +   { 8000,   0x00 }, { 9000,   0x10 }, { 1,  0x20 },
> > +   { 11000,  0x30 }, { 12000,  0x01 }, { 13000,  0x11 },
> > +   { 14000,  0x21 }, { 15000,  0x31 }, { 16000,  0x02 },
> > +   { 17000,  0x12 }, { 18000,  0x22 }, { 19000,  0x32 },
> > +   { 20500,  0x03 }, { 22000,  0x13 }, { 23500,  0x23 },
> > +   { 25000,  0x33 }, 

Re: [RESEND] [PATCH v2 1/2] dt-bindings: display: bridge: Add binding for R-Car MIPI DSI/CSI-2 TX

2021-09-21 Thread Laurent Pinchart
Hi Geert,

On Tue, Sep 21, 2021 at 05:53:52PM +0200, Geert Uytterhoeven wrote:
> On Wed, Jul 28, 2021 at 6:26 PM Laurent Pinchart wrote:
> > The R-Car MIPI DSI/CSI-2 TX is embedded in the Renesas R-Car V3U SoC. It
> > can operate in either DSI or CSI-2 mode, with up to four data lanes.
> >
> > Signed-off-by: Laurent Pinchart 
> > Reviewed-by: Kieran Bingham 
> 
> Thanks for your patch!
> 
> > --- /dev/null
> > +++ 
> > b/Documentation/devicetree/bindings/display/bridge/renesas,dsi-csi2-tx.yaml
> > @@ -0,0 +1,118 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/display/bridge/renesas,dsi-csi2-tx.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Renesas R-Car MIPI DSI/CSI-2 Encoder
> > +
> > +maintainers:
> > +  - Laurent Pinchart 
> > +
> > +description: |
> > +  This binding describes the MIPI DSI/CSI-2 encoder embedded in the Renesas
> > +  R-Car V3U SoC. The encoder can operate in either DSI or CSI-2 mode, with 
> > up
> > +  to four data lanes.
> > +
> > +properties:
> > +  compatible:
> > +enum:
> > +  - renesas,r8a779a0-dsi-csi2-tx# for V3U
> > +
> > +  reg:
> > +maxItems: 1
> > +
> > +  clocks:
> > +items:
> > +  - description: Functional clock
> > +  - description: DSI (and CSI-2) functional clock
> > +  - description: PLL reference clock
> > +
> > +  clock-names:
> > +items:
> > +  - const: fck
> > +  - const: dsi
> > +  - const: pll
> 
> No interrupts?
> The hardware manual says there are 9 interrupts.

Who comes up with such insanely high numbers of interrupts ? :-)

What the hardware manual doesn't document is how interrupts are mapped.
There's indeed 9 of them, and there are 9 interrupt sources, but that's
all we know. I can easily add a

  interrupts:
maxItems: 9

but I can add interrupt names without additional information. It may be
possible to deduce some of the interrupt mappings from experiments, but
not all of them. What do you think would be a good way forward ? Leave
the interrupts out for now as we don't have the information ? Only list
the interrupts but not their names ? Something else ?

-- 
Regards,

Laurent Pinchart


Re: [Intel-gfx] [PATCH v3 03/13] drm/dp: add LTTPR DP 2.0 DPCD addresses

2021-09-21 Thread Stephen Rothwell
Hi Nathan,

On Tue, 21 Sep 2021 15:58:23 -0700 Nathan Chancellor  wrote:
>
> On Thu, Sep 09, 2021 at 03:51:55PM +0300, Jani Nikula wrote:
> > DP 2.0 brings some new DPCD addresses for PHY repeaters.
> > 
> > Cc: dri-devel@lists.freedesktop.org
> > Reviewed-by: Manasi Navare 
> > Signed-off-by: Jani Nikula 
> > ---
> >  include/drm/drm_dp_helper.h | 4 
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> > index 1d5b3dbb6e56..f3a61341011d 100644
> > --- a/include/drm/drm_dp_helper.h
> > +++ b/include/drm/drm_dp_helper.h
> > @@ -1319,6 +1319,10 @@ struct drm_panel;
> >  #define DP_MAX_LANE_COUNT_PHY_REPEATER 0xf0004 /* 
> > 1.4a */
> >  #define DP_Repeater_FEC_CAPABILITY 0xf0004 /* 1.4 */
> >  #define DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT  0xf0005 /* 
> > 1.4a */
> > +#define DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER   0xf0006 /* 2.0 */
> > +# define DP_PHY_REPEATER_128B132B_SUPPORTED(1 << 0)
> > +/* See DP_128B132B_SUPPORTED_LINK_RATES for values */
> > +#define DP_PHY_REPEATER_128B132B_RATES 0xf0007 /* 
> > 2.0 */
> >  
> >  enum drm_dp_phy {
> > DP_PHY_DPRX,
> > -- 
> > 2.30.2
> > 
> >   
> 
> This patch causes a build failure in -next when combined with the AMD
> tree:
> 
> In file included from drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c:33:
> In file included from ./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgpu.h:70:
> In file included from ./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgpu_mode.h:36:
> ./include/drm/drm_dp_helper.h:1322:9: error: 
> 'DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER' macro redefined 
> [-Werror,-Wmacro-redefined]
> #define DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER0xf0006 /* 2.0 */
> ^
> ./drivers/gpu/drm/amd/amdgpu/../display/dc/dc_dp_types.h:881:9: note: 
> previous definition is here
> #define DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER0xF0006
> ^
> 1 error generated.
> 
> Perhaps something like this should be applied during the merge of the
> second tree or maybe this patch should be in a branch that could be
> shared between the Intel and AMD trees so that this diff could be
> applied to the AMD tree directly? Not sure what the standard procedure
> for this is.
> 
> Cheers,
> Nathan
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c 
> b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> index 234dfbea926a..279863b5c650 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
> @@ -4590,7 +4590,7 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
>   
> DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
>  
>   link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.raw =
> - lttpr_dpcd_data[DP_PHY_REPEATER_128b_132b_RATES 
> -
> + lttpr_dpcd_data[DP_PHY_REPEATER_128B132B_RATES -
>   
> DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
>  #endif
>  
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h 
> b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
> index a5e798b5da79..8caf9af5ffa2 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
> @@ -878,8 +878,6 @@ struct psr_caps {
>  # define DP_DSC_DECODER_COUNT_MASK   (0b111 << 5)
>  # define DP_DSC_DECODER_COUNT_SHIFT  5
>  #define DP_MAIN_LINK_CHANNEL_CODING_SET  0x108
> -#define DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER 0xF0006
> -#define DP_PHY_REPEATER_128b_132b_RATES  0xF0007
>  #define DP_128b_132b_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1  0xF0022
>  #define DP_INTRA_HOP_AUX_REPLY_INDICATION(1 << 3)
>  /* TODO - Use DRM header to replace above once available */

Thanks for the heads up.  I have applied the above as a merge fix patch
until something else happens.

-- 
Cheers,
Stephen Rothwell


pgp4olpvKtbqD.pgp
Description: OpenPGP digital signature


Re: [PATCH v6 2/2] drm/bridge: parade-ps8640: Add support for AUX channel

2021-09-21 Thread Stephen Boyd
Quoting Philip Chen (2021-09-21 11:06:17)
> Implement the first version of AUX support, which will be useful as
> we expand the driver to support varied use cases.
>
> Reviewed-by: Sam Ravnborg 
> Signed-off-by: Philip Chen 
> ---

Reviewed-by: Stephen Boyd 


Re: [PATCH v6 1/2] drm/bridge: parade-ps8640: Use regmap APIs

2021-09-21 Thread Stephen Boyd
Quoting Philip Chen (2021-09-21 11:06:16)
> Replace the direct i2c access (i2c_smbus_* functions) with regmap APIs,
> which will simplify the future update on ps8640 driver.
>
> Reviewed-by: Douglas Anderson 
> Acked-by: Sam Ravnborg 
> Signed-off-by: Philip Chen 
> ---

Reviewed-by: Stephen Boyd 


[PATCH v11 00/17] drm/i915: Introduce Intel PXP

2021-09-21 Thread Alan Previn
PXP (Protected Xe Path) is an i915 component, available on
GEN12 and newer platforms, that helps to establish the hardware
protected session and manage the status of the alive software session,
as well as its life cycle.

changes from v10:
- Added v10 delta into history of patches that changed in v10
- Fixed checkpatch errors.

Tested with: https://patchwork.freedesktop.org/series/87570/

Cc: Gaurav Kumar 
Cc: Chris Wilson 
Cc: Rodrigo Vivi 
Cc: Joonas Lahtinen 
Cc: Juston Li 
Cc: Alan Previn 
Cc: Lionel Landwerlin 
Cc: Jason Ekstrand 
Cc: Daniel Vetter 

Anshuman Gupta (2):
  drm/i915/pxp: Add plane decryption support
  drm/i915/pxp: black pixels on pxp disabled

Daniele Ceraolo Spurio (9):
  drm/i915/pxp: Define PXP component interface
  drm/i915/pxp: define PXP device flag and kconfig
  drm/i915/pxp: allocate a vcs context for pxp usage
  drm/i915/pxp: set KCR reg init
  drm/i915/pxp: interfaces for using protected objects
  drm/i915/pxp: start the arb session on demand
  drm/i915/pxp: add pxp debugfs
  drm/i915/pxp: add PXP documentation
  drm/i915/pxp: enable PXP for integrated Gen12

Huang, Sean Z (5):
  drm/i915/pxp: Implement funcs to create the TEE channel
  drm/i915/pxp: Create the arbitrary session after boot
  drm/i915/pxp: Implement arb session teardown
  drm/i915/pxp: Implement PXP irq handler
  drm/i915/pxp: Enable PXP power management

Vitaly Lubart (1):
  mei: pxp: export pavp client to me client bus

 Documentation/gpu/i915.rst|   8 +
 drivers/gpu/drm/i915/Kconfig  |  11 +
 drivers/gpu/drm/i915/Makefile |  10 +
 drivers/gpu/drm/i915/display/intel_display.c  |  34 ++
 .../drm/i915/display/intel_display_types.h|   6 +
 .../drm/i915/display/skl_universal_plane.c|  49 ++-
 drivers/gpu/drm/i915/gem/i915_gem_context.c   |  96 +-
 drivers/gpu/drm/i915/gem/i915_gem_context.h   |   6 +
 .../gpu/drm/i915/gem/i915_gem_context_types.h |  28 ++
 drivers/gpu/drm/i915/gem/i915_gem_create.c|  72 +++--
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c|  18 ++
 drivers/gpu/drm/i915/gem/i915_gem_object.c|   1 +
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   6 +
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |   8 +
 .../gpu/drm/i915/gem/selftests/mock_context.c |   4 +-
 drivers/gpu/drm/i915/gt/intel_engine.h|   2 +
 drivers/gpu/drm/i915/gt/intel_gpu_commands.h  |  22 +-
 drivers/gpu/drm/i915/gt/intel_gt.c|   5 +
 drivers/gpu/drm/i915/gt/intel_gt_debugfs.c|   2 +
 drivers/gpu/drm/i915/gt/intel_gt_irq.c|   7 +
 drivers/gpu/drm/i915/gt/intel_gt_pm.c |  15 +-
 drivers/gpu/drm/i915/gt/intel_gt_types.h  |   3 +
 drivers/gpu/drm/i915/i915_drv.c   |   2 +
 drivers/gpu/drm/i915/i915_drv.h   |   3 +
 drivers/gpu/drm/i915/i915_pci.c   |   2 +
 drivers/gpu/drm/i915/i915_reg.h   |  48 +++
 drivers/gpu/drm/i915/intel_device_info.h  |   1 +
 drivers/gpu/drm/i915/pxp/intel_pxp.c  | 298 ++
 drivers/gpu/drm/i915/pxp/intel_pxp.h  |  64 
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c  | 141 +
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h  |  15 +
 drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c  |  78 +
 drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.h  |  21 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c  | 101 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h  |  32 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c   |  46 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h   |  24 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  | 175 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h  |  15 +
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c  | 172 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h  |  17 +
 .../drm/i915/pxp/intel_pxp_tee_interface.h|  36 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h|  83 +
 drivers/misc/mei/Kconfig  |   2 +
 drivers/misc/mei/Makefile |   1 +
 drivers/misc/mei/pxp/Kconfig  |  13 +
 drivers/misc/mei/pxp/Makefile |   7 +
 drivers/misc/mei/pxp/mei_pxp.c| 229 ++
 drivers/misc/mei/pxp/mei_pxp.h|  18 ++
 include/drm/i915_component.h  |   1 +
 include/drm/i915_pxp_tee_interface.h  |  42 +++
 include/uapi/drm/i915_drm.h   |  99 +-
 52 files changed, 2157 insertions(+), 42 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
 create mode 100644 drivers/gpu/drm/i915/pxp/int

Re: [PATCH v5 13/16] drm/mediatek: add ETHDR support for MT8195

2021-09-21 Thread Chun-Kuang Hu
Hi, Nancy:

Nancy.Lin  於 2021年9月6日 週一 下午3:15寫道:
>
> ETHDR is a part of ovl_adaptor.
> ETHDR is designed for HDR video and graphics conversion in the external
> display path. It handles multiple HDR input types and performs tone
> mapping, color space/color format conversion, and then combine
> different layers, output the required HDR or SDR signal to the
> subsequent display path.
>
> Signed-off-by: Nancy.Lin 
> ---
>  drivers/gpu/drm/mediatek/Makefile|   1 +
>  drivers/gpu/drm/mediatek/mtk_ethdr.c | 424 +++
>  drivers/gpu/drm/mediatek/mtk_ethdr.h |  25 ++
>  3 files changed, 450 insertions(+)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.h

[snip]

> +
> +void mtk_ethdr_disable_vblank(struct device *dev)
> +{
> +   struct mtk_ethdr *priv = dev_get_drvdata(dev);
> +   unsigned long flags;
> +
> +   spin_lock_irqsave(&priv->lock, flags);
> +   priv->vblank_cb = NULL;
> +   priv->vblank_cb_data = NULL;
> +   spin_unlock_irqrestore(&priv->lock, flags);
> +
> +   writel(0x0, priv->ethdr_comp[ETHDR_MIXER].regs + MIX_INTEN);
> +}
> +
> +static irqreturn_t mtk_ethdr_irq_handler(int irq, void *dev_id)
> +{
> +   struct mtk_ethdr *priv = dev_id;
> +   unsigned long flags;
> +
> +   writel(0x0, priv->ethdr_comp[ETHDR_MIXER].regs + MIX_INTSTA);
> +
> +   spin_lock_irqsave(&priv->lock, flags);
> +   if (!priv->vblank_cb) {
> +   spin_unlock_irqrestore(&priv->lock, flags);
> +   return IRQ_NONE;
> +   }
> +
> +   priv->vblank_cb(priv->vblank_cb_data);
> +   spin_unlock_irqrestore(&priv->lock, flags);
> +
> +   return IRQ_HANDLED;
> +}
> +
> +void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
> +   struct mtk_plane_state *state,
> +   struct cmdq_pkt *cmdq_pkt)
> +{
> +   struct mtk_ethdr *priv = dev_get_drvdata(dev);
> +   struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
> +   struct mtk_plane_pending_state *pending = &state->pending;
> +   unsigned int offset = (pending->y << 16) | pending->x;

unsigned int offset = (pending->x & 1) << 31 |  pending->y << 16 | pending->x;

So you don't need x_offset_odd.

> +   unsigned int mixer_pad_mode = MIXER_INx_MODE_BYPASS;
> +   unsigned int alpha_con = 0;
> +   unsigned int fmt = 0;
> +   bool x_offset_odd = false;
> +
> +   dev_dbg(dev, "%s+ idx:%d", __func__, idx);
> +
> +   if (idx >= 4)
> +   return;
> +
> +   if (!pending->enable) {
> +   mtk_ddp_write(cmdq_pkt, 0, &mixer->cmdq_base, mixer->regs, 
> MIX_L_SRC_SIZE(idx));
> +   mtk_mmsys_ddp_config(priv->mmsys_dev, 
> MMSYS_CONFIG_MIXER_IN_MODE,
> +idx + 1, MIXER_INx_MODE_BYPASS, 
> cmdq_pkt);
> +   mtk_mmsys_ddp_config(priv->mmsys_dev, 
> MMSYS_CONFIG_MIXER_IN_BIWIDTH,
> +idx + 1, 0, cmdq_pkt);
> +   return;
> +   }
> +
> +   if (pending->x % 2) {
> +   x_offset_odd = true;
> +   mixer_pad_mode = MIXER_INx_MODE_EVEN_EXTEND;
> +   }
> +   mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_MODE,
> +idx + 1, mixer_pad_mode, cmdq_pkt);
> +   mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_BIWIDTH,
> +idx + 1, pending->width / 2 - 1, cmdq_pkt);
> +
> +   if (state->base.fb && state->base.fb->format->has_alpha) {
> +   alpha_con = MIXER_ALPHA_AEN | MIXER_ALPHA;
> +   mtk_mmsys_ddp_config(priv->mmsys_dev, 
> MMSYS_CONFIG_HDR_ALPHA_SEL,
> +idx + 1, 0, cmdq_pkt);
> +   } else {
> +   mtk_mmsys_ddp_config(priv->mmsys_dev, 
> MMSYS_CONFIG_HDR_ALPHA_SEL,
> +idx + 1, 1, cmdq_pkt);
> +   }
> +   mtk_mmsys_ddp_config(priv->mmsys_dev, 
> MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, idx + 1,
> +DEFAULT_9BIT_ALPHA, cmdq_pkt);
> +   mtk_mmsys_ddp_config(priv->mmsys_dev, 
> MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, idx + 1,
> +DEFAULT_9BIT_ALPHA, cmdq_pkt);
> +
> +   mtk_ddp_write(cmdq_pkt, (pending->height << 16) | pending->width, 
> &mixer->cmdq_base,

mtk_ddp_write(cmdq_pkt, pending->height << 16 | pending->width,
&mixer->cmdq_base,

> + mixer->regs, MIX_L_SRC_SIZE(idx));
> +   mtk_ddp_write(cmdq_pkt, (x_offset_odd << 31) | offset, 
> &mixer->cmdq_base,
> + mixer->regs, MIX_L_SRC_OFFSET(idx));
> +   mtk_ddp_write_mask(cmdq_pkt, alpha_con, &mixer->cmdq_base, 
> mixer->regs, MIX_L_SRC_CON(idx),
> +  0x1ff);
> +   mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &mixer->cmdq_base, 
> mixer->regs, MIX_SRC_CON,
> +  BIT(idx));
> +}
> +
> +v

Re: [Freedreno] [PATCH v2 04/13] drm/hdcp: Expand HDCP helper library for enable/disable/check

2021-09-21 Thread abhinavk

On 2021-09-15 13:38, Sean Paul wrote:

From: Sean Paul 

This patch expands upon the HDCP helper library to manage HDCP
enable, disable, and check.

Previous to this patch, the majority of the state management and sink
interaction is tucked inside the Intel driver with the understanding
that once a new platform supported HDCP we could make good decisions
about what should be centralized. With the addition of HDCP support
for Qualcomm, it's time to migrate the protocol-specific bits of HDCP
authentication, key exchange, and link checks to the HDCP helper.

In terms of functionality, this migration is 1:1 with the Intel driver,
however things are laid out a bit differently than with intel_hdcp.c,
which is why this is a separate patch from the i915 transition to the
helper. On i915, the "shim" vtable is used to account for HDMI vs. DP
vs. DP-MST differences whereas the helper library uses a LUT to
account for the register offsets and a remote read function to route
the messages. On i915, storing the sink information in the source is
done inline whereas now we use the new drm_hdcp_helper_funcs vtable
to store and fetch information to/from source hw. Finally, instead of
calling enable/disable directly from the driver, we'll leave that
decision to the helper and by calling drm_hdcp_helper_atomic_commit()
from the driver. All told, this will centralize the protocol and state
handling in the helper, ensuring we collect all of our bugs^Wlogic
in one place.

Signed-off-by: Sean Paul 
Link:
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-5-s...@poorly.run
#v1

Changes in v2:
-Fixed set-but-unused variable identified by 0-day
---
 drivers/gpu/drm/drm_hdcp.c | 1103 
 include/drm/drm_hdcp.h |  191 +++
 2 files changed, 1294 insertions(+)

diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index 742313ce8f6f..47c6e6923a76 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -6,15 +6,20 @@
  * Ramalingam C 
  */

+#include 
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
+#include 

 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -513,3 +518,1101 @@ bool drm_hdcp_atomic_check(struct drm_connector
*connector,
return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_atomic_check);
+
+struct drm_hdcp_helper_data {
+   struct mutex mutex;
+   struct mutex *driver_mutex;
+
+   struct drm_connector *connector;
+   const struct drm_hdcp_helper_funcs *funcs;
+
+   u64 value;
+   unsigned int enabled_type;
+
+   struct delayed_work check_work;
+   struct work_struct prop_work;
+
+   struct drm_dp_aux *aux;
+   const struct drm_hdcp_hdcp1_receiver_reg_lut *hdcp1_lut;
+};
+
+struct drm_hdcp_hdcp1_receiver_reg_lut {
+   unsigned int bksv;
+   unsigned int ri;
+   unsigned int aksv;
+   unsigned int an;
+   unsigned int ainfo;
+   unsigned int v[5];
+   unsigned int bcaps;
+   unsigned int bcaps_mask_repeater_present;
+   unsigned int bstatus;
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut 
drm_hdcp_hdcp1_ddc_lut = {

+   .bksv = DRM_HDCP_DDC_BKSV,
+   .ri = DRM_HDCP_DDC_RI_PRIME,
+   .aksv = DRM_HDCP_DDC_AKSV,
+   .an = DRM_HDCP_DDC_AN,
+   .ainfo = DRM_HDCP_DDC_AINFO,
+   .v = { DRM_HDCP_DDC_V_PRIME(0), DRM_HDCP_DDC_V_PRIME(1),
+  DRM_HDCP_DDC_V_PRIME(2), DRM_HDCP_DDC_V_PRIME(3),
+  DRM_HDCP_DDC_V_PRIME(4) },
+   .bcaps = DRM_HDCP_DDC_BCAPS,
+   .bcaps_mask_repeater_present = DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT,
+   .bstatus = DRM_HDCP_DDC_BSTATUS,
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut 
drm_hdcp_hdcp1_dpcd_lut = {

+   .bksv = DP_AUX_HDCP_BKSV,
+   .ri = DP_AUX_HDCP_RI_PRIME,
+   .aksv = DP_AUX_HDCP_AKSV,
+   .an = DP_AUX_HDCP_AN,
+   .ainfo = DP_AUX_HDCP_AINFO,
+   .v = { DP_AUX_HDCP_V_PRIME(0), DP_AUX_HDCP_V_PRIME(1),
+  DP_AUX_HDCP_V_PRIME(2), DP_AUX_HDCP_V_PRIME(3),
+  DP_AUX_HDCP_V_PRIME(4) },
+   .bcaps = DP_AUX_HDCP_BCAPS,
+   .bcaps_mask_repeater_present = DP_BCAPS_REPEATER_PRESENT,
+
+   /*
+* For some reason the HDMI and DP HDCP specs call this register
+	 * definition by different names. In the HDMI spec, it's called 
BSTATUS,

+* but in DP it's called BINFO.
+*/
+   .bstatus = DP_AUX_HDCP_BINFO,
+};
+
+static int drm_hdcp_remote_ddc_read(struct i2c_adapter *i2c,
+   unsigned int offset, u8 *value, size_t len)
+{
+   int ret;
+   u8 start = offset & 0xff;
+   struct i2c_msg msgs[] = {
+   {
+   .addr = DRM_HDCP_DDC_ADDR,
+   .flags = 0,
+   .len = 1,
+   .buf = &start,
+   },
+   {
+   .addr = DRM_HDCP_DDC_ADDR,
+  

Re: [Intel-gfx] [PATCH] drm/i915: fix blank screen booting crashes

2021-09-21 Thread Lucas De Marchi

On Tue, Sep 21, 2021 at 03:55:15PM -0700, Matthew Brost wrote:

On Tue, Sep 21, 2021 at 11:46:37AM -0700, Lucas De Marchi wrote:

On Tue, Sep 21, 2021 at 10:43:32AM -0700, Matthew Brost wrote:
> From: Hugh Dickins 
>
> 5.15-rc1 crashes with blank screen when booting up on two ThinkPads
> using i915.  Bisections converge convincingly, but arrive at different
> and surprising "culprits", none of them the actual culprit.
>
> netconsole (with init_netconsole() hacked to call i915_init() when
> logging has started, instead of by module_init()) tells the story:
>
> kernel BUG at drivers/gpu/drm/i915/i915_sw_fence.c:245!
> with RSI: 814d408b pointing to sw_fence_dummy_notify().
> I've been building with CONFIG_CC_OPTIMIZE_FOR_SIZE=y, and that
> function needs to be 4-byte aligned.
>
> v2:
> (Jani Nikula)
>  - Change BUG_ON to WARN_ON
> v3:
> (Jani / Tvrtko)
>  - Short circuit __i915_sw_fence_init on WARN_ON
>
> Fixes: 62eaf0ae217d ("drm/i915/guc: Support request cancellation")
> Signed-off-by: Hugh Dickins 
> Signed-off-by: Matthew Brost 
> Reviewed-by: Matthew Brost 
> ---
> drivers/gpu/drm/i915/gt/intel_context.c |  4 ++--
> drivers/gpu/drm/i915/i915_sw_fence.c| 17 ++---
> 2 files changed, 12 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
> index ff637147b1a9..e7f78bc7ebfc 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context.c
> +++ b/drivers/gpu/drm/i915/gt/intel_context.c
> @@ -362,8 +362,8 @@ static int __intel_context_active(struct i915_active 
*active)
>return 0;
> }
>

> -static int sw_fence_dummy_notify(struct i915_sw_fence *sf,
> -   enum i915_sw_fence_notify state)
> +static int __i915_sw_fence_call
> +sw_fence_dummy_notify(struct i915_sw_fence *sf, enum i915_sw_fence_notify 
state)
> {
>return NOTIFY_DONE;
> }
> diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c 
b/drivers/gpu/drm/i915/i915_sw_fence.c
> index c589a681da77..08cea73264e7 100644
> --- a/drivers/gpu/drm/i915/i915_sw_fence.c
> +++ b/drivers/gpu/drm/i915/i915_sw_fence.c
> @@ -13,9 +13,9 @@
> #include "i915_selftest.h"
>
> #if IS_ENABLED(CONFIG_DRM_I915_DEBUG)
> -#define I915_SW_FENCE_BUG_ON(expr) BUG_ON(expr)
> +#define I915_SW_FENCE_WARN_ON(expr) WARN_ON(expr)
> #else
> -#define I915_SW_FENCE_BUG_ON(expr) BUILD_BUG_ON_INVALID(expr)
> +#define I915_SW_FENCE_WARN_ON(expr) BUILD_BUG_ON_INVALID(expr)
> #endif
>
> static DEFINE_SPINLOCK(i915_sw_fence_lock);
> @@ -129,7 +129,10 @@ static int __i915_sw_fence_notify(struct i915_sw_fence 
*fence,
>i915_sw_fence_notify_t fn;
>
>fn = (i915_sw_fence_notify_t)(fence->flags & I915_SW_FENCE_MASK);
> -  return fn(fence, state);
> +  if (likely(fn))
> +  return fn(fence, state);
> +  else
> +  return 0;

since the knowledge for these being NULL (or with the wrong alignment)
are in the init/reinit functions,  wouldn't it be better to just add a
fence_nop() and assign it there instead this likely() here?



Maybe? I prefer the way it is.


> }
>
> #ifdef CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS
> @@ -242,9 +245,9 @@ void __i915_sw_fence_init(struct i915_sw_fence *fence,
>  const char *name,
>  struct lock_class_key *key)
> {
> -  BUG_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK);
> -
>__init_waitqueue_head(&fence->wait, name, key);
> +  if (WARN_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK))
> +  return;

like:
if (WARN_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK))
fence->flags = (unsigned long)sw_fence_dummy_notify;
else
fence->flags = (unsigned long)fn;


f you return here instead of calling i915_sw_fence_reinit(), aren't you
just going to use uninitialized memory later? At least in the selftests,
which allocate it with kmalloc()... I didn't check others.



I don't think so, maybe the fence won't work but it won't blow up
either.



For the bug fix we could just add the __aligned(4) and leave the rest to a
separate patch.



The bug was sw_fence_dummy_notify in gt/intel_context.c was not 4 byte
align which triggered a BUG_ON during boot which blank screened a
laptop. Jani / Tvrtko suggested that we make the BUG_ON to WARN_ONs so
if someone makes this mistake in the future kernel should boot albiet
with a WARNING.


yes, I understood. But afaics with WARN_ON you are allowing it to
continue and may be using uninitialized memory later, just causing other
problems down the line, which may be equally difficult to debug.

what I suggested is that there is the easy fix to apply to the current
rcX kernel, adding __aligned(4) to sw_fence_dummy_notify() (patch 1).
And there is the additional protection being added here (patch 2) which
is subject to the debate.



The long term fix is just pull out the I915_SW_FENCE_MASK (stealing bits
from a poitner) and we don't have to worry any of this.


Patch 2 may not even be needed if you're going that 

[PATCH v3 10/12] drm/virtio: implement context init: handle VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK

2021-09-21 Thread Gurchetan Singh
For the Sommelier guest Wayland proxy, it's desirable for the
DRM fd to be pollable in response to an host compositor event.
This can also be used by the 3D driver to poll events on a CPU
timeline.

This enables the DRM fd associated with a particular 3D context
to be polled independent of KMS events.  The parameter
VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK specifies the pollable
rings.

Signed-off-by: Gurchetan Singh 
Acked-by: Nicholas Verne 
---
 drivers/gpu/drm/virtio/virtgpu_drv.h   |  1 +
 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 22 +-
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index cca9ab505deb..cb60d52c2bd1 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -266,6 +266,7 @@ struct virtio_gpu_fpriv {
bool context_created;
uint32_t num_rings;
uint64_t base_fence_ctx;
+   uint64_t ring_idx_mask;
struct mutex context_lock;
 };
 
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c 
b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 262f79210283..be7b22a03884 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -694,6 +694,7 @@ static int virtio_gpu_context_init_ioctl(struct drm_device 
*dev,
 {
int ret = 0;
uint32_t num_params, i, param, value;
+   uint64_t valid_ring_mask;
size_t len;
struct drm_virtgpu_context_set_param *ctx_set_params = NULL;
struct virtio_gpu_device *vgdev = dev->dev_private;
@@ -707,7 +708,7 @@ static int virtio_gpu_context_init_ioctl(struct drm_device 
*dev,
return -EINVAL;
 
/* Number of unique parameters supported at this time. */
-   if (num_params > 2)
+   if (num_params > 3)
return -EINVAL;
 
ctx_set_params = memdup_user(u64_to_user_ptr(args->ctx_set_params),
@@ -761,12 +762,31 @@ static int virtio_gpu_context_init_ioctl(struct 
drm_device *dev,
vfpriv->base_fence_ctx = dma_fence_context_alloc(value);
vfpriv->num_rings = value;
break;
+   case VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK:
+   if (vfpriv->ring_idx_mask) {
+   ret = -EINVAL;
+   goto out_unlock;
+   }
+
+   vfpriv->ring_idx_mask = value;
+   break;
default:
ret = -EINVAL;
goto out_unlock;
}
}
 
+   if (vfpriv->ring_idx_mask) {
+   valid_ring_mask = 0;
+   for (i = 0; i < vfpriv->num_rings; i++)
+   valid_ring_mask |= 1 << i;
+
+   if (~valid_ring_mask & vfpriv->ring_idx_mask) {
+   ret = -EINVAL;
+   goto out_unlock;
+   }
+   }
+
virtio_gpu_create_context_locked(vgdev, vfpriv);
virtio_gpu_notify(vgdev);
 
-- 
2.33.0.464.g1972c5931b-goog



[PATCH v3 07/12] drm/virtio: implement context init: plumb {base_fence_ctx, ring_idx} to virtio_gpu_fence_alloc

2021-09-21 Thread Gurchetan Singh
These were defined in the previous commit. We'll need these
parameters when allocating a dma_fence.  The use case for this
is multiple synchronizations timelines.

The maximum number of timelines per 3D instance will be 32. Usually,
only 2 are needed -- one for CPU commands, and another for GPU
commands.

As such, we'll need to specify these parameters when allocating a
dma_fence.

vgdev->fence_drv.context is the "default" fence context for 2D mode
and old userspace.

Signed-off-by: Gurchetan Singh 
Acked-by: Lingfeng Yang 
---
 drivers/gpu/drm/virtio/virtgpu_drv.h   | 5 +++--
 drivers/gpu/drm/virtio/virtgpu_fence.c | 4 +++-
 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 9 +
 drivers/gpu/drm/virtio/virtgpu_plane.c | 3 ++-
 4 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 401aec1a5efb..a5142d60c2fa 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -426,8 +426,9 @@ struct drm_plane *virtio_gpu_plane_init(struct 
virtio_gpu_device *vgdev,
int index);
 
 /* virtgpu_fence.c */
-struct virtio_gpu_fence *virtio_gpu_fence_alloc(
-   struct virtio_gpu_device *vgdev);
+struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device 
*vgdev,
+   uint64_t base_fence_ctx,
+   uint32_t ring_idx);
 void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev,
  struct virtio_gpu_ctrl_hdr *cmd_hdr,
  struct virtio_gpu_fence *fence);
diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c 
b/drivers/gpu/drm/virtio/virtgpu_fence.c
index d28e25e8409b..24c728b65d21 100644
--- a/drivers/gpu/drm/virtio/virtgpu_fence.c
+++ b/drivers/gpu/drm/virtio/virtgpu_fence.c
@@ -71,7 +71,9 @@ static const struct dma_fence_ops virtio_gpu_fence_ops = {
.timeline_value_str  = virtio_gpu_timeline_value_str,
 };
 
-struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device 
*vgdev)
+struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device 
*vgdev,
+   uint64_t base_fence_ctx,
+   uint32_t ring_idx)
 {
struct virtio_gpu_fence_driver *drv = &vgdev->fence_drv;
struct virtio_gpu_fence *fence = kzalloc(sizeof(struct 
virtio_gpu_fence),
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c 
b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index f5281d1e30e1..f51f3393a194 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -173,7 +173,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device 
*dev, void *data,
goto out_memdup;
}
 
-   out_fence = virtio_gpu_fence_alloc(vgdev);
+   out_fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0);
if(!out_fence) {
ret = -ENOMEM;
goto out_unresv;
@@ -288,7 +288,7 @@ static int virtio_gpu_resource_create_ioctl(struct 
drm_device *dev, void *data,
if (params.size == 0)
params.size = PAGE_SIZE;
 
-   fence = virtio_gpu_fence_alloc(vgdev);
+   fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0);
if (!fence)
return -ENOMEM;
ret = virtio_gpu_object_create(vgdev, ¶ms, &qobj, fence);
@@ -367,7 +367,7 @@ static int virtio_gpu_transfer_from_host_ioctl(struct 
drm_device *dev,
if (ret != 0)
goto err_put_free;
 
-   fence = virtio_gpu_fence_alloc(vgdev);
+   fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0);
if (!fence) {
ret = -ENOMEM;
goto err_unlock;
@@ -427,7 +427,8 @@ static int virtio_gpu_transfer_to_host_ioctl(struct 
drm_device *dev, void *data,
goto err_put_free;
 
ret = -ENOMEM;
-   fence = virtio_gpu_fence_alloc(vgdev);
+   fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context,
+  0);
if (!fence)
goto err_unlock;
 
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c 
b/drivers/gpu/drm/virtio/virtgpu_plane.c
index a49fd9480381..6d3cc9e238a4 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -256,7 +256,8 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane 
*plane,
return 0;
 
if (bo->dumb && (plane->state->fb != new_state->fb)) {
-   vgfb->fence = virtio_gpu_fence_alloc(vgdev);
+   vgfb->fence = virtio_gpu_fence_alloc(vgdev, 
vgdev->fence_drv.context,
+0);
if (!vgfb->fence)
return -ENOMEM;
}
-- 
2.33

[PATCH v3 06/12] drm/virtio: implement context init: track {ring_idx, emit_fence_info} in virtio_gpu_fence

2021-09-21 Thread Gurchetan Singh
Each fence should be associated with a [fence ID, fence_context,
seqno].  The seqno number is just the fence id.

To get the fence context, we add the ring_idx to the 3D context's
base_fence_ctx.  The ring_idx is between 0 and 31, inclusive.

Each 3D context will have it's own base_fence_ctx. The ring_idx will
be emitted to host userspace, when emit_fence_info is true.

Signed-off-by: Gurchetan Singh 
Acked-by: Lingfeng Yang 
---
 drivers/gpu/drm/virtio/virtgpu_drv.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 9996abf60e3a..401aec1a5efb 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -139,7 +139,9 @@ struct virtio_gpu_fence_driver {
 
 struct virtio_gpu_fence {
struct dma_fence f;
+   uint32_t ring_idx;
uint64_t fence_id;
+   bool emit_fence_info;
struct virtio_gpu_fence_driver *drv;
struct list_head node;
 };
-- 
2.33.0.464.g1972c5931b-goog



[PATCH v3 08/12] drm/virtio: implement context init: stop using drv->context when creating fence

2021-09-21 Thread Gurchetan Singh
The plumbing is all here to do this.  Since we always use the
default fence context when allocating a fence, this makes no
functional difference.

We can't process just the largest fence id anymore, since it's
it's associated with different timelines.  It's fine for fence_id
260 to signal before 259.  As such, process each fence_id
individually.

Signed-off-by: Gurchetan Singh 
Acked-by: Lingfeng Yang 
---
 drivers/gpu/drm/virtio/virtgpu_fence.c | 16 ++--
 drivers/gpu/drm/virtio/virtgpu_vq.c| 15 +++
 2 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c 
b/drivers/gpu/drm/virtio/virtgpu_fence.c
index 24c728b65d21..98a00c1e654d 100644
--- a/drivers/gpu/drm/virtio/virtgpu_fence.c
+++ b/drivers/gpu/drm/virtio/virtgpu_fence.c
@@ -75,20 +75,25 @@ struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct 
virtio_gpu_device *vgdev,
uint64_t base_fence_ctx,
uint32_t ring_idx)
 {
+   uint64_t fence_context = base_fence_ctx + ring_idx;
struct virtio_gpu_fence_driver *drv = &vgdev->fence_drv;
struct virtio_gpu_fence *fence = kzalloc(sizeof(struct 
virtio_gpu_fence),
GFP_KERNEL);
+
if (!fence)
return fence;
 
fence->drv = drv;
+   fence->ring_idx = ring_idx;
+   fence->emit_fence_info = !(base_fence_ctx == drv->context);
 
/* This only partially initializes the fence because the seqno is
 * unknown yet.  The fence must not be used outside of the driver
 * until virtio_gpu_fence_emit is called.
 */
-   dma_fence_init(&fence->f, &virtio_gpu_fence_ops, &drv->lock, 
drv->context,
-  0);
+
+   dma_fence_init(&fence->f, &virtio_gpu_fence_ops, &drv->lock,
+  fence_context, 0);
 
return fence;
 }
@@ -110,6 +115,13 @@ void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev,
 
cmd_hdr->flags |= cpu_to_le32(VIRTIO_GPU_FLAG_FENCE);
cmd_hdr->fence_id = cpu_to_le64(fence->fence_id);
+
+   /* Only currently defined fence param. */
+   if (fence->emit_fence_info) {
+   cmd_hdr->flags |=
+   cpu_to_le32(VIRTIO_GPU_FLAG_INFO_RING_IDX);
+   cmd_hdr->ring_idx = (u8)fence->ring_idx;
+   }
 }
 
 void virtio_gpu_fence_event_process(struct virtio_gpu_device *vgdev,
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c 
b/drivers/gpu/drm/virtio/virtgpu_vq.c
index db7741549ab0..7c052efe8836 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -199,7 +199,7 @@ void virtio_gpu_dequeue_ctrl_func(struct work_struct *work)
struct list_head reclaim_list;
struct virtio_gpu_vbuffer *entry, *tmp;
struct virtio_gpu_ctrl_hdr *resp;
-   u64 fence_id = 0;
+   u64 fence_id;
 
INIT_LIST_HEAD(&reclaim_list);
spin_lock(&vgdev->ctrlq.qlock);
@@ -226,23 +226,14 @@ void virtio_gpu_dequeue_ctrl_func(struct work_struct 
*work)
DRM_DEBUG("response 0x%x\n", 
le32_to_cpu(resp->type));
}
if (resp->flags & cpu_to_le32(VIRTIO_GPU_FLAG_FENCE)) {
-   u64 f = le64_to_cpu(resp->fence_id);
-
-   if (fence_id > f) {
-   DRM_ERROR("%s: Oops: fence %llx -> %llx\n",
- __func__, fence_id, f);
-   } else {
-   fence_id = f;
-   }
+   fence_id = le64_to_cpu(resp->fence_id);
+   virtio_gpu_fence_event_process(vgdev, fence_id);
}
if (entry->resp_cb)
entry->resp_cb(vgdev, entry);
}
wake_up(&vgdev->ctrlq.ack_queue);
 
-   if (fence_id)
-   virtio_gpu_fence_event_process(vgdev, fence_id);
-
list_for_each_entry_safe(entry, tmp, &reclaim_list, list) {
if (entry->objs)
virtio_gpu_array_put_free_delayed(vgdev, entry->objs);
-- 
2.33.0.464.g1972c5931b-goog



[PATCH v3 12/12] drm/virtio: implement context init: advertise feature to userspace

2021-09-21 Thread Gurchetan Singh
This advertises the context init feature to userspace, along with
a mask of supported capabilities.

Signed-off-by: Gurchetan Singh 
Acked-by: Lingfeng Yang 
---
 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c 
b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index fdaa7f3d9eeb..5618a1d5879c 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -286,6 +286,12 @@ static int virtio_gpu_getparam_ioctl(struct drm_device 
*dev, void *data,
case VIRTGPU_PARAM_CROSS_DEVICE:
value = vgdev->has_resource_assign_uuid ? 1 : 0;
break;
+   case VIRTGPU_PARAM_CONTEXT_INIT:
+   value = vgdev->has_context_init ? 1 : 0;
+   break;
+   case VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs:
+   value = vgdev->capset_id_mask;
+   break;
default:
return -EINVAL;
}
-- 
2.33.0.464.g1972c5931b-goog



[PATCH v3 11/12] drm/virtio: implement context init: add virtio_gpu_fence_event

2021-09-21 Thread Gurchetan Singh
Similar to DRM_VMW_EVENT_FENCE_SIGNALED.  Sends a pollable event
to the DRM file descriptor when a fence on a specific ring is
signaled.

One difference is the event is not exposed via the UAPI -- this is
because host responses are on a shared memory buffer of type
BLOB_MEM_GUEST [this is the common way to receive responses with
virtgpu].  As such, there is no context specific read(..)
implementation either -- just a poll(..) implementation.

Signed-off-by: Gurchetan Singh 
Acked-by: Nicholas Verne 
---
 drivers/gpu/drm/virtio/virtgpu_drv.c   | 43 +-
 drivers/gpu/drm/virtio/virtgpu_drv.h   |  7 +
 drivers/gpu/drm/virtio/virtgpu_fence.c | 10 ++
 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 34 
 4 files changed, 93 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c 
b/drivers/gpu/drm/virtio/virtgpu_drv.c
index 9d963f1fda8f..749db18dcfa2 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -29,6 +29,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -155,6 +157,35 @@ static void virtio_gpu_config_changed(struct virtio_device 
*vdev)
schedule_work(&vgdev->config_changed_work);
 }
 
+static __poll_t virtio_gpu_poll(struct file *filp,
+   struct poll_table_struct *wait)
+{
+   struct drm_file *drm_file = filp->private_data;
+   struct virtio_gpu_fpriv *vfpriv = drm_file->driver_priv;
+   struct drm_device *dev = drm_file->minor->dev;
+   struct drm_pending_event *e = NULL;
+   __poll_t mask = 0;
+
+   if (!vfpriv->ring_idx_mask)
+   return drm_poll(filp, wait);
+
+   poll_wait(filp, &drm_file->event_wait, wait);
+
+   if (!list_empty(&drm_file->event_list)) {
+   spin_lock_irq(&dev->event_lock);
+   e = list_first_entry(&drm_file->event_list,
+struct drm_pending_event, link);
+   drm_file->event_space += e->event->length;
+   list_del(&e->link);
+   spin_unlock_irq(&dev->event_lock);
+
+   kfree(e);
+   mask |= EPOLLIN | EPOLLRDNORM;
+   }
+
+   return mask;
+}
+
 static struct virtio_device_id id_table[] = {
{ VIRTIO_ID_GPU, VIRTIO_DEV_ANY_ID },
{ 0 },
@@ -194,7 +225,17 @@ MODULE_AUTHOR("Dave Airlie ");
 MODULE_AUTHOR("Gerd Hoffmann ");
 MODULE_AUTHOR("Alon Levy");
 
-DEFINE_DRM_GEM_FOPS(virtio_gpu_driver_fops);
+static const struct file_operations virtio_gpu_driver_fops = {
+   .owner  = THIS_MODULE,
+   .open   = drm_open,
+   .release= drm_release,
+   .unlocked_ioctl = drm_ioctl,
+   .compat_ioctl   = drm_compat_ioctl,
+   .poll   = virtio_gpu_poll,
+   .read   = drm_read,
+   .llseek = noop_llseek,
+   .mmap   = drm_gem_mmap
+};
 
 static const struct drm_driver driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_RENDER | 
DRIVER_ATOMIC,
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index cb60d52c2bd1..e0265fe74aa5 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -138,11 +138,18 @@ struct virtio_gpu_fence_driver {
spinlock_t   lock;
 };
 
+#define VIRTGPU_EVENT_FENCE_SIGNALED_INTERNAL 0x1000
+struct virtio_gpu_fence_event {
+   struct drm_pending_event base;
+   struct drm_event event;
+};
+
 struct virtio_gpu_fence {
struct dma_fence f;
uint32_t ring_idx;
uint64_t fence_id;
bool emit_fence_info;
+   struct virtio_gpu_fence_event *e;
struct virtio_gpu_fence_driver *drv;
struct list_head node;
 };
diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c 
b/drivers/gpu/drm/virtio/virtgpu_fence.c
index 98a00c1e654d..f28357dbde35 100644
--- a/drivers/gpu/drm/virtio/virtgpu_fence.c
+++ b/drivers/gpu/drm/virtio/virtgpu_fence.c
@@ -152,11 +152,21 @@ void virtio_gpu_fence_event_process(struct 
virtio_gpu_device *vgdev,
continue;
 
dma_fence_signal_locked(&curr->f);
+   if (curr->e) {
+   drm_send_event(vgdev->ddev, &curr->e->base);
+   curr->e = NULL;
+   }
+
list_del(&curr->node);
dma_fence_put(&curr->f);
}
 
dma_fence_signal_locked(&signaled->f);
+   if (signaled->e) {
+   drm_send_event(vgdev->ddev, &signaled->e->base);
+   signaled->e = NULL;
+   }
+
list_del(&signaled->node);
dma_fence_put(&signaled->f);
break;
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c 
b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index be7b22a03884..fdaa

[PATCH v3 05/12] drm/virtio: implement context init: support init ioctl

2021-09-21 Thread Gurchetan Singh
From: Anthoine Bourgeois 

This implements the context initialization ioctl.  A list of params
is passed in by userspace, and kernel driver validates them.  The
only currently supported param is VIRTGPU_CONTEXT_PARAM_CAPSET_ID.

If the context has already been initialized, -EEXIST is returned.
This happens after Linux userspace does dumb_create + followed by
opening the Mesa virgl driver with the same virtgpu instance.

However, for most applications, 3D contexts will be explicitly
initialized when the feature is available.

Signed-off-by: Anthoine Bourgeois 
Acked-by: Lingfeng Yang 
---
 drivers/gpu/drm/virtio/virtgpu_drv.h   |  6 +-
 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 96 --
 drivers/gpu/drm/virtio/virtgpu_vq.c|  4 +-
 3 files changed, 98 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 5e1958a522ff..9996abf60e3a 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -259,12 +259,13 @@ struct virtio_gpu_device {
 
 struct virtio_gpu_fpriv {
uint32_t ctx_id;
+   uint32_t context_init;
bool context_created;
struct mutex context_lock;
 };
 
 /* virtgpu_ioctl.c */
-#define DRM_VIRTIO_NUM_IOCTLS 11
+#define DRM_VIRTIO_NUM_IOCTLS 12
 extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS];
 void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file);
 
@@ -342,7 +343,8 @@ int virtio_gpu_cmd_get_capset(struct virtio_gpu_device 
*vgdev,
  struct virtio_gpu_drv_cap_cache **cache_p);
 int virtio_gpu_cmd_get_edids(struct virtio_gpu_device *vgdev);
 void virtio_gpu_cmd_context_create(struct virtio_gpu_device *vgdev, uint32_t 
id,
-  uint32_t nlen, const char *name);
+  uint32_t context_init, uint32_t nlen,
+  const char *name);
 void virtio_gpu_cmd_context_destroy(struct virtio_gpu_device *vgdev,
uint32_t id);
 void virtio_gpu_cmd_context_attach_resource(struct virtio_gpu_device *vgdev,
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c 
b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 5c1ad1596889..f5281d1e30e1 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -38,20 +38,30 @@
VIRTGPU_BLOB_FLAG_USE_SHAREABLE | \
VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE)
 
+/* Must be called with &virtio_gpu_fpriv.struct_mutex held. */
+static void virtio_gpu_create_context_locked(struct virtio_gpu_device *vgdev,
+struct virtio_gpu_fpriv *vfpriv)
+{
+   char dbgname[TASK_COMM_LEN];
+
+   get_task_comm(dbgname, current);
+   virtio_gpu_cmd_context_create(vgdev, vfpriv->ctx_id,
+ vfpriv->context_init, strlen(dbgname),
+ dbgname);
+
+   vfpriv->context_created = true;
+}
+
 void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file)
 {
struct virtio_gpu_device *vgdev = dev->dev_private;
struct virtio_gpu_fpriv *vfpriv = file->driver_priv;
-   char dbgname[TASK_COMM_LEN];
 
mutex_lock(&vfpriv->context_lock);
if (vfpriv->context_created)
goto out_unlock;
 
-   get_task_comm(dbgname, current);
-   virtio_gpu_cmd_context_create(vgdev, vfpriv->ctx_id,
- strlen(dbgname), dbgname);
-   vfpriv->context_created = true;
+   virtio_gpu_create_context_locked(vgdev, vfpriv);
 
 out_unlock:
mutex_unlock(&vfpriv->context_lock);
@@ -662,6 +672,79 @@ static int virtio_gpu_resource_create_blob_ioctl(struct 
drm_device *dev,
return 0;
 }
 
+static int virtio_gpu_context_init_ioctl(struct drm_device *dev,
+void *data, struct drm_file *file)
+{
+   int ret = 0;
+   uint32_t num_params, i, param, value;
+   size_t len;
+   struct drm_virtgpu_context_set_param *ctx_set_params = NULL;
+   struct virtio_gpu_device *vgdev = dev->dev_private;
+   struct virtio_gpu_fpriv *vfpriv = file->driver_priv;
+   struct drm_virtgpu_context_init *args = data;
+
+   num_params = args->num_params;
+   len = num_params * sizeof(struct drm_virtgpu_context_set_param);
+
+   if (!vgdev->has_context_init || !vgdev->has_virgl_3d)
+   return -EINVAL;
+
+   /* Number of unique parameters supported at this time. */
+   if (num_params > 1)
+   return -EINVAL;
+
+   ctx_set_params = memdup_user(u64_to_user_ptr(args->ctx_set_params),
+len);
+
+   if (IS_ERR(ctx_set_params))
+   return PTR_ERR(ctx_set_params);
+
+   mutex_lock(&vfpriv->context_lock);
+   if (vfpriv->context

[PATCH v3 09/12] drm/virtio: implement context init: allocate an array of fence contexts

2021-09-21 Thread Gurchetan Singh
We don't want fences from different 3D contexts (virgl, gfxstream,
venus) to be on the same timeline.  With explicit context creation,
we can specify the number of ring each context wants.

Execbuffer can specify which ring to use.

Signed-off-by: Gurchetan Singh 
Acked-by: Lingfeng Yang 
---
 drivers/gpu/drm/virtio/virtgpu_drv.h   |  3 +++
 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 34 --
 2 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index a5142d60c2fa..cca9ab505deb 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -56,6 +56,7 @@
 #define STATE_ERR 2
 
 #define MAX_CAPSET_ID 63
+#define MAX_RINGS 64
 
 struct virtio_gpu_object_params {
unsigned long size;
@@ -263,6 +264,8 @@ struct virtio_gpu_fpriv {
uint32_t ctx_id;
uint32_t context_init;
bool context_created;
+   uint32_t num_rings;
+   uint64_t base_fence_ctx;
struct mutex context_lock;
 };
 
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c 
b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index f51f3393a194..262f79210283 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -99,6 +99,11 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device 
*dev, void *data,
int in_fence_fd = exbuf->fence_fd;
int out_fence_fd = -1;
void *buf;
+   uint64_t fence_ctx;
+   uint32_t ring_idx;
+
+   fence_ctx = vgdev->fence_drv.context;
+   ring_idx = 0;
 
if (vgdev->has_virgl_3d == false)
return -ENOSYS;
@@ -106,6 +111,17 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device 
*dev, void *data,
if ((exbuf->flags & ~VIRTGPU_EXECBUF_FLAGS))
return -EINVAL;
 
+   if ((exbuf->flags & VIRTGPU_EXECBUF_RING_IDX)) {
+   if (exbuf->ring_idx >= vfpriv->num_rings)
+   return -EINVAL;
+
+   if (!vfpriv->base_fence_ctx)
+   return -EINVAL;
+
+   fence_ctx = vfpriv->base_fence_ctx;
+   ring_idx = exbuf->ring_idx;
+   }
+
exbuf->fence_fd = -1;
 
virtio_gpu_create_context(dev, file);
@@ -173,7 +189,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device 
*dev, void *data,
goto out_memdup;
}
 
-   out_fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context, 0);
+   out_fence = virtio_gpu_fence_alloc(vgdev, fence_ctx, ring_idx);
if(!out_fence) {
ret = -ENOMEM;
goto out_unresv;
@@ -691,7 +707,7 @@ static int virtio_gpu_context_init_ioctl(struct drm_device 
*dev,
return -EINVAL;
 
/* Number of unique parameters supported at this time. */
-   if (num_params > 1)
+   if (num_params > 2)
return -EINVAL;
 
ctx_set_params = memdup_user(u64_to_user_ptr(args->ctx_set_params),
@@ -731,6 +747,20 @@ static int virtio_gpu_context_init_ioctl(struct drm_device 
*dev,
 
vfpriv->context_init |= value;
break;
+   case VIRTGPU_CONTEXT_PARAM_NUM_RINGS:
+   if (vfpriv->base_fence_ctx) {
+   ret = -EINVAL;
+   goto out_unlock;
+   }
+
+   if (value > MAX_RINGS) {
+   ret = -EINVAL;
+   goto out_unlock;
+   }
+
+   vfpriv->base_fence_ctx = dma_fence_context_alloc(value);
+   vfpriv->num_rings = value;
+   break;
default:
ret = -EINVAL;
goto out_unlock;
-- 
2.33.0.464.g1972c5931b-goog



[PATCH v3 03/12] drm/virtio: implement context init: track valid capabilities in a mask

2021-09-21 Thread Gurchetan Singh
The valid capability IDs are between 1 to 63, and defined in the
virtio gpu spec.  This is used for error checking the subsequent
patches.  We're currently only using 2 capability IDs, so this
should be plenty for the immediate future.

Signed-off-by: Gurchetan Singh 
Acked-by: Lingfeng Yang 
---
 drivers/gpu/drm/virtio/virtgpu_drv.h |  3 +++
 drivers/gpu/drm/virtio/virtgpu_kms.c | 18 +-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 0c4810982530..3023e16be0d6 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -55,6 +55,8 @@
 #define STATE_OK 1
 #define STATE_ERR 2
 
+#define MAX_CAPSET_ID 63
+
 struct virtio_gpu_object_params {
unsigned long size;
bool dumb;
@@ -245,6 +247,7 @@ struct virtio_gpu_device {
 
struct virtio_gpu_drv_capset *capsets;
uint32_t num_capsets;
+   uint64_t capset_id_mask;
struct list_head cap_cache;
 
/* protects uuid state when exporting */
diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c 
b/drivers/gpu/drm/virtio/virtgpu_kms.c
index f3379059f324..58a65121c200 100644
--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
+++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
@@ -65,6 +65,7 @@ static void virtio_gpu_get_capsets(struct virtio_gpu_device 
*vgdev,
   int num_capsets)
 {
int i, ret;
+   bool invalid_capset_id = false;
 
vgdev->capsets = kcalloc(num_capsets,
 sizeof(struct virtio_gpu_drv_capset),
@@ -78,19 +79,34 @@ static void virtio_gpu_get_capsets(struct virtio_gpu_device 
*vgdev,
virtio_gpu_notify(vgdev);
ret = wait_event_timeout(vgdev->resp_wq,
 vgdev->capsets[i].id > 0, 5 * HZ);
-   if (ret == 0) {
+   /*
+* Capability ids are defined in the virtio-gpu spec and are
+* between 1 to 63, inclusive.
+*/
+   if (!vgdev->capsets[i].id ||
+   vgdev->capsets[i].id > MAX_CAPSET_ID)
+   invalid_capset_id = true;
+
+   if (ret == 0)
DRM_ERROR("timed out waiting for cap set %d\n", i);
+   else if (invalid_capset_id)
+   DRM_ERROR("invalid capset id %u", vgdev->capsets[i].id);
+
+   if (ret == 0 || invalid_capset_id) {
spin_lock(&vgdev->display_info_lock);
kfree(vgdev->capsets);
vgdev->capsets = NULL;
spin_unlock(&vgdev->display_info_lock);
return;
}
+
+   vgdev->capset_id_mask |= 1 << vgdev->capsets[i].id;
DRM_INFO("cap set %d: id %d, max-version %d, max-size %d\n",
 i, vgdev->capsets[i].id,
 vgdev->capsets[i].max_version,
 vgdev->capsets[i].max_size);
}
+
vgdev->num_capsets = num_capsets;
 }
 
-- 
2.33.0.464.g1972c5931b-goog



[PATCH v3 04/12] drm/virtio: implement context init: probe for feature

2021-09-21 Thread Gurchetan Singh
From: Anthoine Bourgeois 

Let's probe for VIRTIO_GPU_F_CONTEXT_INIT.

Create a new DRM_INFO(..) line since the current one is getting
too long.

Signed-off-by: Anthoine Bourgeois 
Acked-by: Lingfeng Yang 
---
 drivers/gpu/drm/virtio/virtgpu_debugfs.c | 1 +
 drivers/gpu/drm/virtio/virtgpu_drv.c | 1 +
 drivers/gpu/drm/virtio/virtgpu_drv.h | 1 +
 drivers/gpu/drm/virtio/virtgpu_kms.c | 8 +++-
 4 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_debugfs.c 
b/drivers/gpu/drm/virtio/virtgpu_debugfs.c
index c2b20e0ee030..b6954e2f75e6 100644
--- a/drivers/gpu/drm/virtio/virtgpu_debugfs.c
+++ b/drivers/gpu/drm/virtio/virtgpu_debugfs.c
@@ -52,6 +52,7 @@ static int virtio_gpu_features(struct seq_file *m, void *data)
vgdev->has_resource_assign_uuid);
 
virtio_gpu_add_bool(m, "blob resources", vgdev->has_resource_blob);
+   virtio_gpu_add_bool(m, "context init", vgdev->has_context_init);
virtio_gpu_add_int(m, "cap sets", vgdev->num_capsets);
virtio_gpu_add_int(m, "scanouts", vgdev->num_scanouts);
if (vgdev->host_visible_region.len) {
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c 
b/drivers/gpu/drm/virtio/virtgpu_drv.c
index ed85a7863256..9d963f1fda8f 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -172,6 +172,7 @@ static unsigned int features[] = {
VIRTIO_GPU_F_EDID,
VIRTIO_GPU_F_RESOURCE_UUID,
VIRTIO_GPU_F_RESOURCE_BLOB,
+   VIRTIO_GPU_F_CONTEXT_INIT,
 };
 static struct virtio_driver virtio_gpu_driver = {
.feature_table = features,
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 3023e16be0d6..5e1958a522ff 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -236,6 +236,7 @@ struct virtio_gpu_device {
bool has_resource_assign_uuid;
bool has_resource_blob;
bool has_host_visible;
+   bool has_context_init;
struct virtio_shm_region host_visible_region;
struct drm_mm host_visible_mm;
 
diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c 
b/drivers/gpu/drm/virtio/virtgpu_kms.c
index 58a65121c200..21f410901694 100644
--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
+++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
@@ -191,13 +191,19 @@ int virtio_gpu_init(struct drm_device *dev)
(unsigned long)vgdev->host_visible_region.addr,
(unsigned long)vgdev->host_visible_region.len);
}
+   if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_CONTEXT_INIT)) {
+   vgdev->has_context_init = true;
+   }
 
-   DRM_INFO("features: %cvirgl %cedid %cresource_blob %chost_visible\n",
+   DRM_INFO("features: %cvirgl %cedid %cresource_blob %chost_visible",
 vgdev->has_virgl_3d? '+' : '-',
 vgdev->has_edid? '+' : '-',
 vgdev->has_resource_blob ? '+' : '-',
 vgdev->has_host_visible ? '+' : '-');
 
+   DRM_INFO("features: %ccontext_init\n",
+vgdev->has_context_init ? '+' : '-');
+
ret = virtio_find_vqs(vgdev->vdev, 2, vqs, callbacks, names, NULL);
if (ret) {
DRM_ERROR("failed to find virt queues\n");
-- 
2.33.0.464.g1972c5931b-goog



[PATCH v3 02/12] drm/virtgpu api: create context init feature

2021-09-21 Thread Gurchetan Singh
This change allows creating contexts of depending on set of
context parameters.  The meaning of each of the parameters
is listed below:

1) VIRTGPU_CONTEXT_PARAM_CAPSET_ID

This determines the type of a context based on the capability set
ID.  For example, the current capsets:

VIRTIO_GPU_CAPSET_VIRGL
VIRTIO_GPU_CAPSET_VIRGL2

define a Gallium, TGSI based "virgl" context.  We only need 1 capset
ID per context type, though virgl has two due a bug that has since
been fixed.

The use case is the "gfxstream" rendering library and "venus"
renderer.

gfxstream doesn't do Gallium/TGSI translation and mostly relies on
auto-generated API streaming.  Certain users prefer gfxstream over
virgl for GLES on GLES emulation.  {gfxstream vk}/{venus} are also
required for Vulkan emulation.  The maximum capset ID is 63.

The goal is for guest userspace to choose the optimal context type
depending on the situation/hardware.

2) VIRTGPU_CONTEXT_PARAM_NUM_RINGS

This tells the number of independent command rings that the context
will use.  This value may be zero and is inferred to be zero if
VIRTGPU_CONTEXT_PARAM_NUM_RINGS is not passed in.  This is for backwards
compatibility for virgl, which has one big giant command ring for all
commands.

The maxiumum number of rings is 64.  In practice, multi-queue or
multi-ring submission is used for powerful dGPUs and virtio-gpu
may not be the best option in that case (see PCI passthrough or
rendernode forwarding).

3) VIRTGPU_CONTEXT_PARAM_POLL_RING_IDX_MASK

This is a mask of ring indices for which the DRM fd is pollable.
For example, if VIRTGPU_CONTEXT_PARAM_NUM_RINGS is 2, then the mask
may be:

[ring idx]  |  [1 << ring_idx] | final mask
---
0  11
1  23

The "Sommelier" guest Wayland proxy uses this to poll for events
from the host compositor.

Signed-off-by: Gurchetan Singh 
Acked-by: Lingfeng Yang 
Acked-by: Nicholas Verne 
---
 include/uapi/drm/virtgpu_drm.h | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/include/uapi/drm/virtgpu_drm.h b/include/uapi/drm/virtgpu_drm.h
index b9ec26e9c646..a13e20cc66b4 100644
--- a/include/uapi/drm/virtgpu_drm.h
+++ b/include/uapi/drm/virtgpu_drm.h
@@ -47,12 +47,15 @@ extern "C" {
 #define DRM_VIRTGPU_WAIT 0x08
 #define DRM_VIRTGPU_GET_CAPS  0x09
 #define DRM_VIRTGPU_RESOURCE_CREATE_BLOB 0x0a
+#define DRM_VIRTGPU_CONTEXT_INIT 0x0b
 
 #define VIRTGPU_EXECBUF_FENCE_FD_IN0x01
 #define VIRTGPU_EXECBUF_FENCE_FD_OUT   0x02
+#define VIRTGPU_EXECBUF_RING_IDX   0x04
 #define VIRTGPU_EXECBUF_FLAGS  (\
VIRTGPU_EXECBUF_FENCE_FD_IN |\
VIRTGPU_EXECBUF_FENCE_FD_OUT |\
+   VIRTGPU_EXECBUF_RING_IDX |\
0)
 
 struct drm_virtgpu_map {
@@ -68,6 +71,8 @@ struct drm_virtgpu_execbuffer {
__u64 bo_handles;
__u32 num_bo_handles;
__s32 fence_fd; /* in/out fence fd (see 
VIRTGPU_EXECBUF_FENCE_FD_IN/OUT) */
+   __u32 ring_idx; /* command ring index (see VIRTGPU_EXECBUF_RING_IDX) */
+   __u32 pad;
 };
 
 #define VIRTGPU_PARAM_3D_FEATURES 1 /* do we have 3D features in the hw */
@@ -75,6 +80,8 @@ struct drm_virtgpu_execbuffer {
 #define VIRTGPU_PARAM_RESOURCE_BLOB 3 /* DRM_VIRTGPU_RESOURCE_CREATE_BLOB */
 #define VIRTGPU_PARAM_HOST_VISIBLE 4 /* Host blob resources are mappable */
 #define VIRTGPU_PARAM_CROSS_DEVICE 5 /* Cross virtio-device resource sharing  
*/
+#define VIRTGPU_PARAM_CONTEXT_INIT 6 /* DRM_VIRTGPU_CONTEXT_INIT */
+#define VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs 7 /* Bitmask of supported 
capability set ids */
 
 struct drm_virtgpu_getparam {
__u64 param;
@@ -173,6 +180,22 @@ struct drm_virtgpu_resource_create_blob {
__u64 blob_id;
 };
 
+#define VIRTGPU_CONTEXT_PARAM_CAPSET_ID   0x0001
+#define VIRTGPU_CONTEXT_PARAM_NUM_RINGS   0x0002
+#define VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK 0x0003
+struct drm_virtgpu_context_set_param {
+   __u64 param;
+   __u64 value;
+};
+
+struct drm_virtgpu_context_init {
+   __u32 num_params;
+   __u32 pad;
+
+   /* pointer to drm_virtgpu_context_set_param array */
+   __u64 ctx_set_params;
+};
+
 #define DRM_IOCTL_VIRTGPU_MAP \
DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_MAP, struct drm_virtgpu_map)
 
@@ -212,6 +235,10 @@ struct drm_virtgpu_resource_create_blob {
DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_CREATE_BLOB,   \
struct drm_virtgpu_resource_create_blob)
 
+#define DRM_IOCTL_VIRTGPU_CONTEXT_INIT \
+   DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_CONTEXT_INIT,   \
+   struct drm_virtgpu_context_init)
+
 #if defined(__cplusplus)
 }
 #endif
-- 
2.33.0.464.g1972c5931b-goog



[PATCH v3 01/12] virtio-gpu api: multiple context types with explicit initialization

2021-09-21 Thread Gurchetan Singh
This feature allows for each virtio-gpu 3D context to be created
with a "context_init" variable.  This variable can specify:

 - the type of protocol used by the context via the capset id.
   This is useful for differentiating virgl, gfxstream, and venus
   protocols by host userspace.

 - other things in the future, such as the version of the context.

In addition, each different context needs one or more timelines, so
for example a virgl context's waiting can be independent on a
gfxstream context's waiting.

VIRTIO_GPU_FLAG_INFO_RING_IDX is introduced to specific to tell the
host which per-context command ring (or "hardware queue", distinct
from the virtio-queue) the fence should be associated with.

The new capability sets (gfxstream, venus etc.) are only defined in
the virtio-gpu spec and not defined in the header.

Signed-off-by: Gurchetan Singh 
Acked-by: Lingfeng Yang 
---
 include/uapi/linux/virtio_gpu.h | 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h
index 97523a95781d..f556fde07b76 100644
--- a/include/uapi/linux/virtio_gpu.h
+++ b/include/uapi/linux/virtio_gpu.h
@@ -59,6 +59,11 @@
  * VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB
  */
 #define VIRTIO_GPU_F_RESOURCE_BLOB   3
+/*
+ * VIRTIO_GPU_CMD_CREATE_CONTEXT with
+ * context_init and multiple timelines
+ */
+#define VIRTIO_GPU_F_CONTEXT_INIT4
 
 enum virtio_gpu_ctrl_type {
VIRTIO_GPU_UNDEFINED = 0,
@@ -122,14 +127,20 @@ enum virtio_gpu_shm_id {
VIRTIO_GPU_SHM_ID_HOST_VISIBLE = 1
 };
 
-#define VIRTIO_GPU_FLAG_FENCE (1 << 0)
+#define VIRTIO_GPU_FLAG_FENCE (1 << 0)
+/*
+ * If the following flag is set, then ring_idx contains the index
+ * of the command ring that needs to used when creating the fence
+ */
+#define VIRTIO_GPU_FLAG_INFO_RING_IDX (1 << 1)
 
 struct virtio_gpu_ctrl_hdr {
__le32 type;
__le32 flags;
__le64 fence_id;
__le32 ctx_id;
-   __le32 padding;
+   __u8 ring_idx;
+   __u8 padding[3];
 };
 
 /* data passed in the cursor vq */
@@ -269,10 +280,11 @@ struct virtio_gpu_resource_create_3d {
 };
 
 /* VIRTIO_GPU_CMD_CTX_CREATE */
+#define VIRTIO_GPU_CONTEXT_INIT_CAPSET_ID_MASK 0x00ff
 struct virtio_gpu_ctx_create {
struct virtio_gpu_ctrl_hdr hdr;
__le32 nlen;
-   __le32 padding;
+   __le32 context_init;
char debug_name[64];
 };
 
-- 
2.33.0.464.g1972c5931b-goog



[PATCH v3 00/12] Context types, v3

2021-09-21 Thread Gurchetan Singh
Version 2 of context types:

https://lists.oasis-open.org/archives/virtio-dev/202108/msg00141.html

Changes since RFC:
   * le32 info --> {u8 ring_idx + u8 padding[3]).
   * Max rings is now 64.

Changes since v1:
   * Document plan regarding context types + display combinations that
 need implicit sync in patch 9.

Changes since v2:
   * u8 ring_idx --> __u8 ring_idx to fix buildbot issues

Anthoine Bourgeois (2):
  drm/virtio: implement context init: probe for feature
  drm/virtio: implement context init: support init ioctl

Gurchetan Singh (10):
  virtio-gpu api: multiple context types with explicit initialization
  drm/virtgpu api: create context init feature
  drm/virtio: implement context init: track valid capabilities in a mask
  drm/virtio: implement context init: track {ring_idx, emit_fence_info}
in virtio_gpu_fence
  drm/virtio: implement context init: plumb {base_fence_ctx, ring_idx}
to virtio_gpu_fence_alloc
  drm/virtio: implement context init: stop using drv->context when
creating fence
  drm/virtio: implement context init: allocate an array of fence
contexts
  drm/virtio: implement context init: handle
VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK
  drm/virtio: implement context init: add virtio_gpu_fence_event
  drm/virtio: implement context init: advertise feature to userspace

 drivers/gpu/drm/virtio/virtgpu_debugfs.c |   1 +
 drivers/gpu/drm/virtio/virtgpu_drv.c |  44 -
 drivers/gpu/drm/virtio/virtgpu_drv.h |  28 +++-
 drivers/gpu/drm/virtio/virtgpu_fence.c   |  30 +++-
 drivers/gpu/drm/virtio/virtgpu_ioctl.c   | 195 +--
 drivers/gpu/drm/virtio/virtgpu_kms.c |  26 ++-
 drivers/gpu/drm/virtio/virtgpu_plane.c   |   3 +-
 drivers/gpu/drm/virtio/virtgpu_vq.c  |  19 +--
 include/uapi/drm/virtgpu_drm.h   |  27 
 include/uapi/linux/virtio_gpu.h  |  18 ++-
 10 files changed, 355 insertions(+), 36 deletions(-)

-- 
2.33.0.464.g1972c5931b-goog



Re: [Intel-gfx] [PATCH] drm/i915: fix blank screen booting crashes

2021-09-21 Thread Matthew Brost
On Tue, Sep 21, 2021 at 11:46:37AM -0700, Lucas De Marchi wrote:
> On Tue, Sep 21, 2021 at 10:43:32AM -0700, Matthew Brost wrote:
> > From: Hugh Dickins 
> > 
> > 5.15-rc1 crashes with blank screen when booting up on two ThinkPads
> > using i915.  Bisections converge convincingly, but arrive at different
> > and surprising "culprits", none of them the actual culprit.
> > 
> > netconsole (with init_netconsole() hacked to call i915_init() when
> > logging has started, instead of by module_init()) tells the story:
> > 
> > kernel BUG at drivers/gpu/drm/i915/i915_sw_fence.c:245!
> > with RSI: 814d408b pointing to sw_fence_dummy_notify().
> > I've been building with CONFIG_CC_OPTIMIZE_FOR_SIZE=y, and that
> > function needs to be 4-byte aligned.
> > 
> > v2:
> > (Jani Nikula)
> >  - Change BUG_ON to WARN_ON
> > v3:
> > (Jani / Tvrtko)
> >  - Short circuit __i915_sw_fence_init on WARN_ON
> > 
> > Fixes: 62eaf0ae217d ("drm/i915/guc: Support request cancellation")
> > Signed-off-by: Hugh Dickins 
> > Signed-off-by: Matthew Brost 
> > Reviewed-by: Matthew Brost 
> > ---
> > drivers/gpu/drm/i915/gt/intel_context.c |  4 ++--
> > drivers/gpu/drm/i915/i915_sw_fence.c| 17 ++---
> > 2 files changed, 12 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
> > b/drivers/gpu/drm/i915/gt/intel_context.c
> > index ff637147b1a9..e7f78bc7ebfc 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_context.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_context.c
> > @@ -362,8 +362,8 @@ static int __intel_context_active(struct i915_active 
> > *active)
> > return 0;
> > }
> > 
> 
> > -static int sw_fence_dummy_notify(struct i915_sw_fence *sf,
> > -enum i915_sw_fence_notify state)
> > +static int __i915_sw_fence_call
> > +sw_fence_dummy_notify(struct i915_sw_fence *sf, enum i915_sw_fence_notify 
> > state)
> > {
> > return NOTIFY_DONE;
> > }
> > diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c 
> > b/drivers/gpu/drm/i915/i915_sw_fence.c
> > index c589a681da77..08cea73264e7 100644
> > --- a/drivers/gpu/drm/i915/i915_sw_fence.c
> > +++ b/drivers/gpu/drm/i915/i915_sw_fence.c
> > @@ -13,9 +13,9 @@
> > #include "i915_selftest.h"
> > 
> > #if IS_ENABLED(CONFIG_DRM_I915_DEBUG)
> > -#define I915_SW_FENCE_BUG_ON(expr) BUG_ON(expr)
> > +#define I915_SW_FENCE_WARN_ON(expr) WARN_ON(expr)
> > #else
> > -#define I915_SW_FENCE_BUG_ON(expr) BUILD_BUG_ON_INVALID(expr)
> > +#define I915_SW_FENCE_WARN_ON(expr) BUILD_BUG_ON_INVALID(expr)
> > #endif
> > 
> > static DEFINE_SPINLOCK(i915_sw_fence_lock);
> > @@ -129,7 +129,10 @@ static int __i915_sw_fence_notify(struct i915_sw_fence 
> > *fence,
> > i915_sw_fence_notify_t fn;
> > 
> > fn = (i915_sw_fence_notify_t)(fence->flags & I915_SW_FENCE_MASK);
> > -   return fn(fence, state);
> > +   if (likely(fn))
> > +   return fn(fence, state);
> > +   else
> > +   return 0;
> 
> since the knowledge for these being NULL (or with the wrong alignment)
> are in the init/reinit functions,  wouldn't it be better to just add a
> fence_nop() and assign it there instead this likely() here?
> 

Maybe? I prefer the way it is.

> > }
> > 
> > #ifdef CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS
> > @@ -242,9 +245,9 @@ void __i915_sw_fence_init(struct i915_sw_fence *fence,
> >   const char *name,
> >   struct lock_class_key *key)
> > {
> > -   BUG_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK);
> > -
> > __init_waitqueue_head(&fence->wait, name, key);
> > +   if (WARN_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK))
> > +   return;
> 
> like:
>   if (WARN_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK))
>   fence->flags = (unsigned long)sw_fence_dummy_notify;
>   else
>   fence->flags = (unsigned long)fn;
> 
> 
> f you return here instead of calling i915_sw_fence_reinit(), aren't you
> just going to use uninitialized memory later? At least in the selftests,
> which allocate it with kmalloc()... I didn't check others.
> 

I don't think so, maybe the fence won't work but it won't blow up
either.

> 
> For the bug fix we could just add the __aligned(4) and leave the rest to a
> separate patch.
> 

The bug was sw_fence_dummy_notify in gt/intel_context.c was not 4 byte
align which triggered a BUG_ON during boot which blank screened a
laptop. Jani / Tvrtko suggested that we make the BUG_ON to WARN_ONs so
if someone makes this mistake in the future kernel should boot albiet
with a WARNING.

The long term fix is just pull out the I915_SW_FENCE_MASK (stealing bits
from a poitner) and we don't have to worry any of this.

Matt

> 
> Lucas De Marchi
> 
> > fence->flags = (unsigned long)fn;
> > 
> > i915_sw_fence_reinit(fence);
> > @@ -257,8 +260,8 @@ void i915_sw_fence_reinit(struct i915_sw_fence *fence)
> > atomic_set(&fence->pending, 1);
> > fence->error = 0;
> > 
> > -   I915_SW_FENCE_BUG_ON(!fence->flags);
> > -   I915_S

Re: [Intel-gfx] [PATCH v3 03/13] drm/dp: add LTTPR DP 2.0 DPCD addresses

2021-09-21 Thread Nathan Chancellor
On Thu, Sep 09, 2021 at 03:51:55PM +0300, Jani Nikula wrote:
> DP 2.0 brings some new DPCD addresses for PHY repeaters.
> 
> Cc: dri-devel@lists.freedesktop.org
> Reviewed-by: Manasi Navare 
> Signed-off-by: Jani Nikula 
> ---
>  include/drm/drm_dp_helper.h | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index 1d5b3dbb6e56..f3a61341011d 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -1319,6 +1319,10 @@ struct drm_panel;
>  #define DP_MAX_LANE_COUNT_PHY_REPEATER   0xf0004 /* 
> 1.4a */
>  #define DP_Repeater_FEC_CAPABILITY   0xf0004 /* 1.4 */
>  #define DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT0xf0005 /* 
> 1.4a */
> +#define DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER 0xf0006 /* 2.0 */
> +# define DP_PHY_REPEATER_128B132B_SUPPORTED  (1 << 0)
> +/* See DP_128B132B_SUPPORTED_LINK_RATES for values */
> +#define DP_PHY_REPEATER_128B132B_RATES   0xf0007 /* 
> 2.0 */
>  
>  enum drm_dp_phy {
>   DP_PHY_DPRX,
> -- 
> 2.30.2
> 
> 

This patch causes a build failure in -next when combined with the AMD
tree:

In file included from drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c:33:
In file included from ./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgpu.h:70:
In file included from ./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgpu_mode.h:36:
./include/drm/drm_dp_helper.h:1322:9: error: 
'DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER' macro redefined 
[-Werror,-Wmacro-redefined]
#define DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER0xf0006 /* 2.0 */
^
./drivers/gpu/drm/amd/amdgpu/../display/dc/dc_dp_types.h:881:9: note: previous 
definition is here
#define DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER0xF0006
^
1 error generated.

Perhaps something like this should be applied during the merge of the
second tree or maybe this patch should be in a branch that could be
shared between the Intel and AMD trees so that this diff could be
applied to the AMD tree directly? Not sure what the standard procedure
for this is.

Cheers,
Nathan

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 234dfbea926a..279863b5c650 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -4590,7 +4590,7 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)

DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
 
link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.raw =
-   lttpr_dpcd_data[DP_PHY_REPEATER_128b_132b_RATES 
-
+   lttpr_dpcd_data[DP_PHY_REPEATER_128B132B_RATES -

DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
 #endif
 
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h 
b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
index a5e798b5da79..8caf9af5ffa2 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
@@ -878,8 +878,6 @@ struct psr_caps {
 # define DP_DSC_DECODER_COUNT_MASK (0b111 << 5)
 # define DP_DSC_DECODER_COUNT_SHIFT5
 #define DP_MAIN_LINK_CHANNEL_CODING_SET0x108
-#define DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER   0xF0006
-#define DP_PHY_REPEATER_128b_132b_RATES0xF0007
 #define DP_128b_132b_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER10xF0022
 #define DP_INTRA_HOP_AUX_REPLY_INDICATION  (1 << 3)
 /* TODO - Use DRM header to replace above once available */


Re: [PATCH v2 3/3] drm/bridge: ti-sn65dsi86: Add NO_CONNECTOR support

2021-09-21 Thread Rob Clark
On Tue, Sep 21, 2021 at 3:20 PM Doug Anderson  wrote:
>
> Hi,
>
> On Mon, Sep 20, 2021 at 3:53 PM Rob Clark  wrote:
> >
> > From: Rob Clark 
> >
> > Slightly awkward to fish out the display_info when we aren't creating
> > own connector.  But I don't see an obvious better way.
> >
> > v2: Remove error return with NO_CONNECTOR flag
> >
> > Signed-off-by: Rob Clark 
> > ---
> >  drivers/gpu/drm/bridge/ti-sn65dsi86.c | 39 ---
> >  1 file changed, 29 insertions(+), 10 deletions(-)
>
> This seems fine to me:
>
> Reviewed-by: Douglas Anderson 
>
> ...if you would like me to apply patch #2 / #3 to drm-misc-next then
> please yell.

Thanks.. I think we can give it a few days for Laurent to have a look.

This will conflict some with Maxime's bridge vs dsi-host ordering
series.. not sure how close that one is to the finish line, but I can
rebase either patch on top of the other depending on which order they
are applied

BR,
-R


Re: [PATCH v2 6/6] drm/i915/dg2: Add DG2-specific shadow register table

2021-09-21 Thread Lucas De Marchi

On Fri, Sep 10, 2021 at 01:10:30PM -0700, Matt Roper wrote:

We thought the DG2 table of shadowed registers would be the same as the
gen12/xehp table, but it turns out that there are a few minor
differences that require us to define a new DG2-specific table:
* One register is removed (0xC4D4)
* One register is added (0xC4E0)

Signed-off-by: Matt Roper 


I did the conversion from the table to this array and arrived at the
same result.


Reviewed-by: Lucas De Marchi 

Lucas De Marchi


Re: [PATCH v2 3/3] drm/bridge: ti-sn65dsi86: Add NO_CONNECTOR support

2021-09-21 Thread Doug Anderson
Hi,

On Mon, Sep 20, 2021 at 3:53 PM Rob Clark  wrote:
>
> From: Rob Clark 
>
> Slightly awkward to fish out the display_info when we aren't creating
> own connector.  But I don't see an obvious better way.
>
> v2: Remove error return with NO_CONNECTOR flag
>
> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/bridge/ti-sn65dsi86.c | 39 ---
>  1 file changed, 29 insertions(+), 10 deletions(-)

This seems fine to me:

Reviewed-by: Douglas Anderson 

...if you would like me to apply patch #2 / #3 to drm-misc-next then
please yell.

-Doug


Re: [PATCH v3 5/8] x86/sme: Replace occurrences of sme_active() with cc_platform_has()

2021-09-21 Thread Kirill A. Shutemov
On Tue, Sep 21, 2021 at 04:43:59PM -0500, Tom Lendacky wrote:
> On 9/21/21 4:34 PM, Kirill A. Shutemov wrote:
> > On Tue, Sep 21, 2021 at 11:27:17PM +0200, Borislav Petkov wrote:
> > > On Wed, Sep 22, 2021 at 12:20:59AM +0300, Kirill A. Shutemov wrote:
> > > > I still believe calling cc_platform_has() from __startup_64() is totally
> > > > broken as it lacks proper wrapping while accessing global variables.
> > > 
> > > Well, one of the issues on the AMD side was using boot_cpu_data too
> > > early and the Intel side uses it too. Can you replace those checks with
> > > is_tdx_guest() or whatever was the helper's name which would check
> > > whether the the kernel is running as a TDX guest, and see if that helps?
> > 
> > There's no need in Intel check this early. Only AMD need it. Maybe just
> > opencode them?
> 
> Any way you can put a gzipped/bzipped copy of your vmlinux file somewhere I
> can grab it from and take a look at it?

You can find broken vmlinux and bzImage here:

https://drive.google.com/drive/folders/1n74vUQHOGebnF70Im32qLFY8iS3wvjIs?usp=sharing

Let me know when I can remove it.

-- 
 Kirill A. Shutemov


Re: [RFC PATCH] component: do not leave master devres group open after bind

2021-09-21 Thread Russell King (Oracle)
On Tue, Sep 21, 2021 at 02:18:10PM +0300, Kai Vehmanen wrote:
> In current code, the devres group for aggregate master is left open
> after call to component_master_add_*(). This leads to problems when the
> master does further managed allocations on its own. When any
> participating driver calls component_del(), this leads to immediate
> release of resources.
> 
> This came up when investigating a page fault occurring with i915 DRM
> driver unbind with 5.15-rc1 kernel. The following sequence occurs:
> 
>  i915_pci_remove()
>-> intel_display_driver_unregister()
>  -> i915_audio_component_cleanup()
>-> component_del()
>  -> component.c:take_down_master()
>-> hdac_component_master_unbind() [via master->ops->unbind()]
>-> devres_release_group(master->parent, NULL)
> 
> With older kernels this has not caused issues, but with audio driver
> moving to use managed interfaces for more of its allocations, this no
> longer works. Devres log shows following to occur:
> 
> component_master_add_with_match()
> [  126.886032] snd_hda_intel :00:1f.3: DEVRES ADD 323ccdc5 
> devm_component_match_release (24 bytes)
> [  126.886045] snd_hda_intel :00:1f.3: DEVRES ADD 865cdb29 grp< 
> (0 bytes)
> [  126.886049] snd_hda_intel :00:1f.3: DEVRES ADD 1b480725 grp< 
> (0 bytes)
> 
> audio driver completes its PCI probe()
> [  126.892238] snd_hda_intel :00:1f.3: DEVRES ADD 1b480725 
> pcim_iomap_release (48 bytes)
> 
> component_del() called() at DRM/i915 unbind()
> [  137.579422] i915 :00:02.0: DEVRES REL ef44c293 grp< (0 bytes)
> [  137.579445] snd_hda_intel :00:1f.3: DEVRES REL 865cdb29 grp< 
> (0 bytes)
> [  137.579458] snd_hda_intel :00:1f.3: DEVRES REL 1b480725 
> pcim_iomap_release (48 bytes)
> 
> So the "devres_release_group(master->parent, NULL)" ends up freeing the
> pcim_iomap allocation. Upon next runtime resume, the audio driver will
> cause a page fault as the iomap alloc was released without the driver
> knowing about it.
> 
> Fix this issue by using the "struct master" pointer as identifier for
> the devres group, and by closing the devres group after the 
> master->ops->bind()
> call is done. This allows devres allocations done by the driver acting as
> master to be isolated from the binding state of the aggregate driver. This
> modifies the logic originally introduced in commit 9e1ccb4a7700
> ("drivers/base: fix devres handling for master device").

Yes, this is the right fix - I did not expect people to be claiming
resources after adding the component master, since that is the point
at which the master can become active. Hence all resources that may
be used should either already be claimed, or (preferred) be claimed
when the master gets the bind call.

However, I think the i915 bits are more complex than that simple view,
so putting the component stuff inside its own devres group and closing
it at the end of try_to_bring_up_master() makes sense.

Acked-by: Russell King (Oracle) 

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


Re: [PATCH v3 5/8] x86/sme: Replace occurrences of sme_active() with cc_platform_has()

2021-09-21 Thread Tom Lendacky

On 9/21/21 4:34 PM, Kirill A. Shutemov wrote:

On Tue, Sep 21, 2021 at 11:27:17PM +0200, Borislav Petkov wrote:

On Wed, Sep 22, 2021 at 12:20:59AM +0300, Kirill A. Shutemov wrote:

I still believe calling cc_platform_has() from __startup_64() is totally
broken as it lacks proper wrapping while accessing global variables.


Well, one of the issues on the AMD side was using boot_cpu_data too
early and the Intel side uses it too. Can you replace those checks with
is_tdx_guest() or whatever was the helper's name which would check
whether the the kernel is running as a TDX guest, and see if that helps?


There's no need in Intel check this early. Only AMD need it. Maybe just
opencode them?


Any way you can put a gzipped/bzipped copy of your vmlinux file somewhere 
I can grab it from and take a look at it?


Thanks,
Tom





Re: [PATCH v3 5/8] x86/sme: Replace occurrences of sme_active() with cc_platform_has()

2021-09-21 Thread Kirill A. Shutemov
On Tue, Sep 21, 2021 at 11:27:17PM +0200, Borislav Petkov wrote:
> On Wed, Sep 22, 2021 at 12:20:59AM +0300, Kirill A. Shutemov wrote:
> > I still believe calling cc_platform_has() from __startup_64() is totally
> > broken as it lacks proper wrapping while accessing global variables.
> 
> Well, one of the issues on the AMD side was using boot_cpu_data too
> early and the Intel side uses it too. Can you replace those checks with
> is_tdx_guest() or whatever was the helper's name which would check
> whether the the kernel is running as a TDX guest, and see if that helps?

There's no need in Intel check this early. Only AMD need it. Maybe just
opencode them?

-- 
 Kirill A. Shutemov


Re: [PATCH v3 5/8] x86/sme: Replace occurrences of sme_active() with cc_platform_has()

2021-09-21 Thread Borislav Petkov
On Wed, Sep 22, 2021 at 12:20:59AM +0300, Kirill A. Shutemov wrote:
> I still believe calling cc_platform_has() from __startup_64() is totally
> broken as it lacks proper wrapping while accessing global variables.

Well, one of the issues on the AMD side was using boot_cpu_data too
early and the Intel side uses it too. Can you replace those checks with
is_tdx_guest() or whatever was the helper's name which would check
whether the the kernel is running as a TDX guest, and see if that helps?

Thx.

-- 
Regards/Gruss,
Boris.



[PATCH] video: fbdev: gbefb: Only instantiate device when built for IP32

2021-09-21 Thread Mark Brown
The gbefb driver not only registers a driver but also the device for that
driver. This is all well and good when run on the IP32 machines that are
supported by the driver but since the driver supports building with
COMPILE_TEST we might also be building on other platforms which do not have
this hardware and will crash instantiating the driver. Add an IS_ENABLED()
check so we compile out the device registration if we don't have the Kconfig
option for the machine enabled.

Fixes: 552ccf6b259d290c0c ("video: fbdev: gbefb: add COMPILE_TEST support")
Signed-off-by: Mark Brown 
Cc: Bartlomiej Zolnierkiewicz 
---
 drivers/video/fbdev/gbefb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/gbefb.c b/drivers/video/fbdev/gbefb.c
index c5b99a4861e8..6b4d5a7f3e15 100644
--- a/drivers/video/fbdev/gbefb.c
+++ b/drivers/video/fbdev/gbefb.c
@@ -1267,7 +1267,7 @@ static struct platform_device *gbefb_device;
 static int __init gbefb_init(void)
 {
int ret = platform_driver_register(&gbefb_driver);
-   if (!ret) {
+   if (IS_ENABLED(CONFIG_SGI_IP32) && !ret) {
gbefb_device = platform_device_alloc("gbefb", 0);
if (gbefb_device) {
ret = platform_device_add(gbefb_device);
-- 
2.20.1



Re: [PATCH v3 5/8] x86/sme: Replace occurrences of sme_active() with cc_platform_has()

2021-09-21 Thread Kirill A. Shutemov
On Tue, Sep 21, 2021 at 07:47:15PM +0200, Borislav Petkov wrote:
> On Tue, Sep 21, 2021 at 12:04:58PM -0500, Tom Lendacky wrote:
> > Looks like instrumentation during early boot. I worked with Boris offline to
> > exclude arch/x86/kernel/cc_platform.c from some of the instrumentation and
> > that allowed an allyesconfig to boot.
> 
> And here's the lineup I have so far, I'd appreciate it if ppc and s390 folks
> could run it too:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git/log/?h=rc2-cc

Still broken for me with allyesconfig.

gcc version 11.2.0 (Gentoo 11.2.0 p1)
GNU ld (Gentoo 2.37_p1 p0) 2.37

I still believe calling cc_platform_has() from __startup_64() is totally
broken as it lacks proper wrapping while accessing global variables.

I think sme_get_me_mask() has the same problem. I just happened to work
(until next compiler update).

This hack makes kernel boot again:

diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index f98c76a1d16c..e9110a44bf1b 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -285,7 +285,7 @@ unsigned long __head __startup_64(unsigned long physaddr,
 * there is no need to zero it after changing the memory encryption
 * attribute.
 */
-   if (cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
+   if (0 && cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
vaddr = (unsigned long)__start_bss_decrypted;
vaddr_end = (unsigned long)__end_bss_decrypted;
for (; vaddr < vaddr_end; vaddr += PMD_SIZE) {
diff --git a/arch/x86/mm/mem_encrypt_identity.c 
b/arch/x86/mm/mem_encrypt_identity.c
index eff4d19f9cb4..91638ed0b1db 100644
--- a/arch/x86/mm/mem_encrypt_identity.c
+++ b/arch/x86/mm/mem_encrypt_identity.c
@@ -288,7 +288,7 @@ void __init sme_encrypt_kernel(struct boot_params *bp)
unsigned long pgtable_area_len;
unsigned long decrypted_base;
 
-   if (!cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
+   if (1 || !cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
return;
 
/*
-- 
 Kirill A. Shutemov


Re: [Freedreno] [PATCH] drm/msm/dsi: do not install irq handler before power up the host

2021-09-21 Thread abhinavk

On 2021-09-21 10:47, Dmitry Baryshkov wrote:

Hi,

On Tue, 21 Sept 2021 at 20:01,  wrote:


On 2021-09-21 09:22, Dmitry Baryshkov wrote:
> The DSI host might be left in some state by the bootloader. If this
> state generates an IRQ, it might hang the system by holding the
> interrupt line before the driver sets up the DSI host to the known
> state.
>
> Move the request/free_irq calls into msm_dsi_host_power_on/_off calls,
> so that we can be sure that the interrupt is delivered when the host is
> in the known state.
>
> Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support")
> Signed-off-by: Dmitry Baryshkov 

This is a valid change and we have seen interrupt storms in downstream
happening
when like you said the bootloader leaves the DSI host in unknown 
state.

Just one question below.

> ---
>  drivers/gpu/drm/msm/dsi/dsi_host.c | 21 -
>  1 file changed, 12 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
> b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index e269df285136..cd842347a6b1 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -1951,15 +1951,6 @@ int msm_dsi_host_modeset_init(struct
> mipi_dsi_host *host,
>   return ret;
>   }
>
> - ret = devm_request_irq(&pdev->dev, msm_host->irq,
> - dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> - "dsi_isr", msm_host);
> - if (ret < 0) {
> - DRM_DEV_ERROR(&pdev->dev, "failed to request IRQ%u: %d\n",
> - msm_host->irq, ret);
> - return ret;
> - }
> -
>   msm_host->dev = dev;
>   ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
>   if (ret) {
> @@ -2413,6 +2404,16 @@ int msm_dsi_host_power_on(struct mipi_dsi_host
> *host,
>   if (msm_host->disp_en_gpio)
>   gpiod_set_value(msm_host->disp_en_gpio, 1);
>
> + ret = devm_request_irq(&msm_host->pdev->dev, msm_host->irq,
> + dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> + "dsi_isr", msm_host);
> + if (ret < 0) {
> + DRM_DEV_ERROR(&msm_host->pdev->dev, "failed to request IRQ%u: 
%d\n",
> + msm_host->irq, ret);
> + return ret;
> + }
> +
> +

Do you want to move this to msm_dsi_host_enable()?
So without the controller being enabled it is still in unknown state?


msm_dsi_host_power_on() reconfigures the host registers, so the state
is known at the end of the power_on().


Also do you want to do this after dsi0 and dsi1 are initialized to
account for
dual dsi cases?


I don't think this should matter. The host won't generate 'extra'
interrupts in such case, will it?

We have seen cases where misconfiguration has caused interrupts to storm 
only
on one DSI in some cases. So yes, I would prefer this is done after both 
are

configured.



>   msm_host->power_on = true;
>   mutex_unlock(&msm_host->dev_mutex);
>
> @@ -2439,6 +2440,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host
> *host)
>   goto unlock_ret;
>   }
>
> + devm_free_irq(&msm_host->pdev->dev, msm_host->irq, msm_host);
> +
>   dsi_ctrl_config(msm_host, false, NULL, NULL);
>
>   if (msm_host->disp_en_gpio)


Re: [PATCH v3 4/9] drm/scheduler: Add fence deadline support

2021-09-21 Thread Rob Clark
On Tue, Sep 21, 2021 at 1:09 PM Andrey Grodzovsky
 wrote:
>
> On 2021-09-03 2:47 p.m., Rob Clark wrote:
>
> > From: Rob Clark 
> >
> > As the finished fence is the one that is exposed to userspace, and
> > therefore the one that other operations, like atomic update, would
> > block on, we need to propagate the deadline from from the finished
> > fence to the actual hw fence.
> >
> > v2: Split into drm_sched_fence_set_parent() (ckoenig)
> >
> > Signed-off-by: Rob Clark 
> > ---
> >   drivers/gpu/drm/scheduler/sched_fence.c | 34 +
> >   drivers/gpu/drm/scheduler/sched_main.c  |  2 +-
> >   include/drm/gpu_scheduler.h |  8 ++
> >   3 files changed, 43 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/scheduler/sched_fence.c 
> > b/drivers/gpu/drm/scheduler/sched_fence.c
> > index bcea035cf4c6..4fc41a71d1c7 100644
> > --- a/drivers/gpu/drm/scheduler/sched_fence.c
> > +++ b/drivers/gpu/drm/scheduler/sched_fence.c
> > @@ -128,6 +128,30 @@ static void drm_sched_fence_release_finished(struct 
> > dma_fence *f)
> >   dma_fence_put(&fence->scheduled);
> >   }
> >
> > +static void drm_sched_fence_set_deadline_finished(struct dma_fence *f,
> > +   ktime_t deadline)
> > +{
> > + struct drm_sched_fence *fence = to_drm_sched_fence(f);
> > + unsigned long flags;
> > +
> > + spin_lock_irqsave(&fence->lock, flags);
> > +
> > + /* If we already have an earlier deadline, keep it: */
> > + if (test_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT, &f->flags) &&
> > + ktime_before(fence->deadline, deadline)) {
> > + spin_unlock_irqrestore(&fence->lock, flags);
> > + return;
> > + }
> > +
> > + fence->deadline = deadline;
> > + set_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT, &f->flags);
> > +
> > + spin_unlock_irqrestore(&fence->lock, flags);
> > +
> > + if (fence->parent)
> > + dma_fence_set_deadline(fence->parent, deadline);
> > +}
> > +
> >   static const struct dma_fence_ops drm_sched_fence_ops_scheduled = {
> >   .get_driver_name = drm_sched_fence_get_driver_name,
> >   .get_timeline_name = drm_sched_fence_get_timeline_name,
> > @@ -138,6 +162,7 @@ static const struct dma_fence_ops 
> > drm_sched_fence_ops_finished = {
> >   .get_driver_name = drm_sched_fence_get_driver_name,
> >   .get_timeline_name = drm_sched_fence_get_timeline_name,
> >   .release = drm_sched_fence_release_finished,
> > + .set_deadline = drm_sched_fence_set_deadline_finished,
> >   };
> >
> >   struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f)
> > @@ -152,6 +177,15 @@ struct drm_sched_fence *to_drm_sched_fence(struct 
> > dma_fence *f)
> >   }
> >   EXPORT_SYMBOL(to_drm_sched_fence);
> >
> > +void drm_sched_fence_set_parent(struct drm_sched_fence *s_fence,
> > + struct dma_fence *fence)
> > +{
> > + s_fence->parent = dma_fence_get(fence);
> > + if (test_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT,
> > +  &s_fence->finished.flags))
> > + dma_fence_set_deadline(fence, s_fence->deadline);
>
>
> I believe above you should pass be s_fence->finished to
> dma_fence_set_deadline
> instead it fence which is the HW fence itself.

Hmm, unless this has changed recently with some patches I don't have,
s_fence->parent is the one signalled by hw, so it is the one we want
to set the deadline on

BR,
-R

> Andrey
>
>
> > +}
> > +
> >   struct drm_sched_fence *drm_sched_fence_alloc(struct drm_sched_entity 
> > *entity,
> > void *owner)
> >   {
> > diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
> > b/drivers/gpu/drm/scheduler/sched_main.c
> > index 595e47ff7d06..27bf0ac0625f 100644
> > --- a/drivers/gpu/drm/scheduler/sched_main.c
> > +++ b/drivers/gpu/drm/scheduler/sched_main.c
> > @@ -978,7 +978,7 @@ static int drm_sched_main(void *param)
> >   drm_sched_fence_scheduled(s_fence);
> >
> >   if (!IS_ERR_OR_NULL(fence)) {
> > - s_fence->parent = dma_fence_get(fence);
> > + drm_sched_fence_set_parent(s_fence, fence);
> >   r = dma_fence_add_callback(fence, &sched_job->cb,
> >  drm_sched_job_done_cb);
> >   if (r == -ENOENT)
> > diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
> > index 7f77a455722c..158ddd662469 100644
> > --- a/include/drm/gpu_scheduler.h
> > +++ b/include/drm/gpu_scheduler.h
> > @@ -238,6 +238,12 @@ struct drm_sched_fence {
> >*/
> >   struct dma_fencefinished;
> >
> > + /**
> > +  * @deadline: deadline set on &drm_sched_fence.finished which
> > +  * potentially needs to be propagated to &drm_sched_fence.parent
> > +  */
> > + ktime_t deadline;
> > +
> >   /**
> >* @parent: the fence r

[PATCH v2] drm/msm/dsi: do not enable irq handler before powering up the host

2021-09-21 Thread Dmitry Baryshkov
The DSI host might be left in some state by the bootloader. If this
state generates an IRQ, it might hang the system by holding the
interrupt line before the driver sets up the DSI host to the known
state.

Move the request_irq into msm_dsi_host_init and pass IRQF_NO_AUTOEN to
it. Call enable/disable_irq from msm_dsi_host_power_on/_off() functions,
so that we can be sure that the interrupt is delivered when the host is
in the known state.

Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support")
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 38 +-
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index e269df285136..b47708305f5c 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1898,6 +1898,23 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
return ret;
}
 
+   msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+   if (msm_host->irq < 0) {
+   ret = msm_host->irq;
+   dev_err(&pdev->dev, "failed to get irq: %d\n", ret);
+   return ret;
+   }
+
+   /* do not autoenable, will be enabled later, in msm_dsi_host_power_on */
+   ret = devm_request_irq(&pdev->dev, msm_host->irq, dsi_host_irq,
+   IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN,
+   "dsi_isr", msm_host);
+   if (ret < 0) {
+   dev_err(&pdev->dev, "failed to request IRQ%u: %d\n",
+   msm_host->irq, ret);
+   return ret;
+   }
+
init_completion(&msm_host->dma_comp);
init_completion(&msm_host->video_comp);
mutex_init(&msm_host->dev_mutex);
@@ -1941,25 +1958,8 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
 {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
-   struct platform_device *pdev = msm_host->pdev;
int ret;
 
-   msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
-   if (msm_host->irq < 0) {
-   ret = msm_host->irq;
-   DRM_DEV_ERROR(dev->dev, "failed to get irq: %d\n", ret);
-   return ret;
-   }
-
-   ret = devm_request_irq(&pdev->dev, msm_host->irq,
-   dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
-   "dsi_isr", msm_host);
-   if (ret < 0) {
-   DRM_DEV_ERROR(&pdev->dev, "failed to request IRQ%u: %d\n",
-   msm_host->irq, ret);
-   return ret;
-   }
-
msm_host->dev = dev;
ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
if (ret) {
@@ -2413,6 +2413,8 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
if (msm_host->disp_en_gpio)
gpiod_set_value(msm_host->disp_en_gpio, 1);
 
+   enable_irq(msm_host->irq);
+
msm_host->power_on = true;
mutex_unlock(&msm_host->dev_mutex);
 
@@ -2439,6 +2441,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host)
goto unlock_ret;
}
 
+   disable_irq(msm_host->irq);
+
dsi_ctrl_config(msm_host, false, NULL, NULL);
 
if (msm_host->disp_en_gpio)
-- 
2.30.2



Re: [PATCH v3 4/9] drm/scheduler: Add fence deadline support

2021-09-21 Thread Andrey Grodzovsky

On 2021-09-03 2:47 p.m., Rob Clark wrote:


From: Rob Clark 

As the finished fence is the one that is exposed to userspace, and
therefore the one that other operations, like atomic update, would
block on, we need to propagate the deadline from from the finished
fence to the actual hw fence.

v2: Split into drm_sched_fence_set_parent() (ckoenig)

Signed-off-by: Rob Clark 
---
  drivers/gpu/drm/scheduler/sched_fence.c | 34 +
  drivers/gpu/drm/scheduler/sched_main.c  |  2 +-
  include/drm/gpu_scheduler.h |  8 ++
  3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/scheduler/sched_fence.c 
b/drivers/gpu/drm/scheduler/sched_fence.c
index bcea035cf4c6..4fc41a71d1c7 100644
--- a/drivers/gpu/drm/scheduler/sched_fence.c
+++ b/drivers/gpu/drm/scheduler/sched_fence.c
@@ -128,6 +128,30 @@ static void drm_sched_fence_release_finished(struct 
dma_fence *f)
dma_fence_put(&fence->scheduled);
  }
  
+static void drm_sched_fence_set_deadline_finished(struct dma_fence *f,

+ ktime_t deadline)
+{
+   struct drm_sched_fence *fence = to_drm_sched_fence(f);
+   unsigned long flags;
+
+   spin_lock_irqsave(&fence->lock, flags);
+
+   /* If we already have an earlier deadline, keep it: */
+   if (test_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT, &f->flags) &&
+   ktime_before(fence->deadline, deadline)) {
+   spin_unlock_irqrestore(&fence->lock, flags);
+   return;
+   }
+
+   fence->deadline = deadline;
+   set_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT, &f->flags);
+
+   spin_unlock_irqrestore(&fence->lock, flags);
+
+   if (fence->parent)
+   dma_fence_set_deadline(fence->parent, deadline);
+}
+
  static const struct dma_fence_ops drm_sched_fence_ops_scheduled = {
.get_driver_name = drm_sched_fence_get_driver_name,
.get_timeline_name = drm_sched_fence_get_timeline_name,
@@ -138,6 +162,7 @@ static const struct dma_fence_ops 
drm_sched_fence_ops_finished = {
.get_driver_name = drm_sched_fence_get_driver_name,
.get_timeline_name = drm_sched_fence_get_timeline_name,
.release = drm_sched_fence_release_finished,
+   .set_deadline = drm_sched_fence_set_deadline_finished,
  };
  
  struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f)

@@ -152,6 +177,15 @@ struct drm_sched_fence *to_drm_sched_fence(struct 
dma_fence *f)
  }
  EXPORT_SYMBOL(to_drm_sched_fence);
  
+void drm_sched_fence_set_parent(struct drm_sched_fence *s_fence,

+   struct dma_fence *fence)
+{
+   s_fence->parent = dma_fence_get(fence);
+   if (test_bit(DMA_FENCE_FLAG_HAS_DEADLINE_BIT,
+&s_fence->finished.flags))
+   dma_fence_set_deadline(fence, s_fence->deadline);



I believe above you should pass be s_fence->finished to 
dma_fence_set_deadline

instead it fence which is the HW fence itself.

Andrey



+}
+
  struct drm_sched_fence *drm_sched_fence_alloc(struct drm_sched_entity *entity,
  void *owner)
  {
diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
b/drivers/gpu/drm/scheduler/sched_main.c
index 595e47ff7d06..27bf0ac0625f 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -978,7 +978,7 @@ static int drm_sched_main(void *param)
drm_sched_fence_scheduled(s_fence);
  
  		if (!IS_ERR_OR_NULL(fence)) {

-   s_fence->parent = dma_fence_get(fence);
+   drm_sched_fence_set_parent(s_fence, fence);
r = dma_fence_add_callback(fence, &sched_job->cb,
   drm_sched_job_done_cb);
if (r == -ENOENT)
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index 7f77a455722c..158ddd662469 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -238,6 +238,12 @@ struct drm_sched_fence {
   */
struct dma_fencefinished;
  
+	/**

+* @deadline: deadline set on &drm_sched_fence.finished which
+* potentially needs to be propagated to &drm_sched_fence.parent
+*/
+   ktime_t deadline;
+
  /**
   * @parent: the fence returned by &drm_sched_backend_ops.run_job
   * when scheduling the job on hardware. We signal the
@@ -505,6 +511,8 @@ void drm_sched_entity_set_priority(struct drm_sched_entity 
*entity,
   enum drm_sched_priority priority);
  bool drm_sched_entity_is_ready(struct drm_sched_entity *entity);
  
+void drm_sched_fence_set_parent(struct drm_sched_fence *s_fence,

+   struct dma_fence *fence);
  struct drm_sched_fence *drm_sched_fence_alloc(
struct drm_sched_entity *s_entity, void *owner);
  void drm_sched_fence_init

Re: [PATCH v2 2/2] drm: rcar-du: Add R-Car DSI driver

2021-09-21 Thread Andrzej Hajda


W dniu 23.06.2021 o 15:56, Laurent Pinchart pisze:
> From: LUU HOAI 
>
> The driver supports the MIPI DSI/CSI-2 TX encoder found in the R-Car V3U
> SoC. It currently supports DSI mode only.
>
> Signed-off-by: LUU HOAI 
> Signed-off-by: Laurent Pinchart 
> Reviewed-by: Kieran Bingham 
> Tested-by: Kieran Bingham 
> ---
>   drivers/gpu/drm/rcar-du/Kconfig  |   6 +
>   drivers/gpu/drm/rcar-du/Makefile |   1 +
>   drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c  | 827 +++
>   drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h | 172 
>   4 files changed, 1006 insertions(+)
>   create mode 100644 drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
>   create mode 100644 drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h
>
> diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig
> index b47e74421e34..8cb94fe90639 100644
> --- a/drivers/gpu/drm/rcar-du/Kconfig
> +++ b/drivers/gpu/drm/rcar-du/Kconfig
> @@ -38,6 +38,12 @@ config DRM_RCAR_LVDS
>   help
> Enable support for the R-Car Display Unit embedded LVDS encoders.
>   
> +config DRM_RCAR_MIPI_DSI
> + tristate "R-Car DU MIPI DSI Encoder Support"
> + depends on DRM && DRM_BRIDGE && OF
> + help
> +   Enable support for the R-Car Display Unit embedded MIPI DSI encoders.
> +
>   config DRM_RCAR_VSP
>   bool "R-Car DU VSP Compositor Support" if ARM
>   default y if ARM64
> diff --git a/drivers/gpu/drm/rcar-du/Makefile 
> b/drivers/gpu/drm/rcar-du/Makefile
> index 4d1187ccc3e5..adc1b49d02cf 100644
> --- a/drivers/gpu/drm/rcar-du/Makefile
> +++ b/drivers/gpu/drm/rcar-du/Makefile
> @@ -19,6 +19,7 @@ obj-$(CONFIG_DRM_RCAR_CMM)  += rcar_cmm.o
>   obj-$(CONFIG_DRM_RCAR_DU)   += rcar-du-drm.o
>   obj-$(CONFIG_DRM_RCAR_DW_HDMI)  += rcar_dw_hdmi.o
>   obj-$(CONFIG_DRM_RCAR_LVDS) += rcar_lvds.o
> +obj-$(CONFIG_DRM_RCAR_MIPI_DSI)  += rcar_mipi_dsi.o
>   
>   # 'remote-endpoint' is fixed up at run-time
>   DTC_FLAGS_rcar_du_of_lvds_r8a7790 += -Wno-graph_endpoint
> diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c 
> b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> new file mode 100644
> index ..e94245029f95
> --- /dev/null
> +++ b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> @@ -0,0 +1,827 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * rcar_mipi_dsi.c  --  R-Car MIPI DSI Encoder
> + *
> + * Copyright (C) 2020 Renesas Electronics Corporation
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "rcar_mipi_dsi_regs.h"
> +
> +struct rcar_mipi_dsi {
> + struct device *dev;
> + const struct rcar_mipi_dsi_device_info *info;
> + struct reset_control *rstc;
> +
> + struct mipi_dsi_host host;
> + struct drm_bridge bridge;
> + struct drm_bridge *next_bridge;
> + struct drm_connector connector;
> +
> + void __iomem *mmio;
> + struct {
> + struct clk *mod;
> + struct clk *pll;
> + struct clk *dsi;
> + } clocks;
> +
> + struct drm_display_mode display_mode;
> + enum mipi_dsi_pixel_format format;
> + unsigned int num_data_lanes;
> + unsigned int lanes;
> +};
> +
> +static inline struct rcar_mipi_dsi *
> +bridge_to_rcar_mipi_dsi(struct drm_bridge *bridge)
> +{
> + return container_of(bridge, struct rcar_mipi_dsi, bridge);
> +}
> +
> +static inline struct rcar_mipi_dsi *
> +host_to_rcar_mipi_dsi(struct mipi_dsi_host *host)
> +{
> + return container_of(host, struct rcar_mipi_dsi, host);
> +}
> +
> +static const u32 phtw[] = {
> + 0x01020114, 0x01600115, /* General testing */
> + 0x01030116, 0x0102011d, /* General testing */
> + 0x011101a4, 0x018601a4, /* 1Gbps testing */
> + 0x014201a0, 0x010001a3, /* 1Gbps testing */
> + 0x0101011f, /* 1Gbps testing */
> +};
> +
> +static const u32 phtw2[] = {
> + 0x010c0130, 0x010c0140, /* General testing */
> + 0x010c0150, 0x010c0180, /* General testing */
> + 0x010c0190,
> + 0x010a0160, 0x010a0170,
> + 0x01800164, 0x01800174, /* 1Gbps testing */
> +};
> +
> +static const u32 hsfreqrange_table[][2] = {
> + { 8000,   0x00 }, { 9000,   0x10 }, { 1,  0x20 },
> + { 11000,  0x30 }, { 12000,  0x01 }, { 13000,  0x11 },
> + { 14000,  0x21 }, { 15000,  0x31 }, { 16000,  0x02 },
> + { 17000,  0x12 }, { 18000,  0x22 }, { 19000,  0x32 },
> + { 20500,  0x03 }, { 22000,  0x13 }, { 23500,  0x23 },
> + { 25000,  0x33 }, { 27500,  0x04 }, { 3,  0x14 },
> + { 32500,  0x25 }, { 35000,  0x35 }, { 4,  0x05 },
> + { 45000,  0x16 }, { 5,  0x26 }, { 55000,  0x37 },
> + { 6,  0x07 }, { 65000,  0x18 }, { 7,  0x28 },
> + { 75000

Re: [Intel-gfx] [PATCH 19/27] drm/i915: Fix bug in user proto-context creation that leaked contexts

2021-09-21 Thread Matthew Brost
On Tue, Sep 21, 2021 at 03:49:53PM +0100, Tvrtko Ursulin wrote:
> 
> On 20/09/2021 23:57, John Harrison wrote:
> > On 8/20/2021 15:44, Matthew Brost wrote:
> > > Set number of engines before attempting to create contexts so the
> > > function free_engines can clean up properly.
> > > 
> > > Fixes: d4433c7600f7 ("drm/i915/gem: Use the proto-context to handle
> > > create parameters (v5)")
> > > Signed-off-by: Matthew Brost 
> > > Cc: 
> > > ---
> > >   drivers/gpu/drm/i915/gem/i915_gem_context.c | 2 +-
> > >   1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > index dbaeb924a437..bcaaf514876b 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > @@ -944,6 +944,7 @@ static struct i915_gem_engines
> > > *user_engines(struct i915_gem_context *ctx,
> > >   unsigned int n;
> > >   e = alloc_engines(num_engines);
> > This can return null when out of memory. There needs to be an early exit
> > check before dereferencing a null pointer. Not sure if that is a worse
> > bug or not than leaking memory! Either way, it would be good to fix that
> > too.
> 
> Pull out from the series and send a fix standalone ASAP? Also suggest adding

Sure, will do.

Matt

> author and reviewer to cc for typically quicker turnaround time.
> 
> Regards,
> 
> Tvrtko
> 
> 
> > John.
> > 
> > > +    e->num_engines = num_engines;
> > >   for (n = 0; n < num_engines; n++) {
> > >   struct intel_context *ce;
> > >   int ret;
> > > @@ -977,7 +978,6 @@ static struct i915_gem_engines
> > > *user_engines(struct i915_gem_context *ctx,
> > >   goto free_engines;
> > >   }
> > >   }
> > > -    e->num_engines = num_engines;
> > >   return e;
> > 


Re: [Intel-gfx] [PATCH 19/27] drm/i915: Fix bug in user proto-context creation that leaked contexts

2021-09-21 Thread Matthew Brost
On Mon, Sep 20, 2021 at 03:57:06PM -0700, John Harrison wrote:
> On 8/20/2021 15:44, Matthew Brost wrote:
> > Set number of engines before attempting to create contexts so the
> > function free_engines can clean up properly.
> > 
> > Fixes: d4433c7600f7 ("drm/i915/gem: Use the proto-context to handle create 
> > parameters (v5)")
> > Signed-off-by: Matthew Brost 
> > Cc: 
> > ---
> >   drivers/gpu/drm/i915/gem/i915_gem_context.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
> > b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > index dbaeb924a437..bcaaf514876b 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > @@ -944,6 +944,7 @@ static struct i915_gem_engines *user_engines(struct 
> > i915_gem_context *ctx,
> > unsigned int n;
> > e = alloc_engines(num_engines);
> This can return null when out of memory. There needs to be an early exit
> check before dereferencing a null pointer. Not sure if that is a worse bug
> or not than leaking memory! Either way, it would be good to fix that too.
> 

Indeed there is another bug. Will fix that one too.

Matt

> John.
> 
> > +   e->num_engines = num_engines;
> > for (n = 0; n < num_engines; n++) {
> > struct intel_context *ce;
> > int ret;
> > @@ -977,7 +978,6 @@ static struct i915_gem_engines *user_engines(struct 
> > i915_gem_context *ctx,
> > goto free_engines;
> > }
> > }
> > -   e->num_engines = num_engines;
> > return e;
> 


Re: [PATCH v2] drm/rockchip: cdn-dp-core: Fix cdn_dp_resume unused warning

2021-09-21 Thread Heiko Stübner
Hi,

Am Dienstag, 21. September 2021, 17:04:10 CEST schrieb Palmer Dabbelt:
> On Tue, 21 Sep 2021 02:12:17 PDT (-0700), he...@sntech.de wrote:
> > On Fri, 10 Sep 2021 20:43:18 -0700, Palmer Dabbelt wrote:
> >> cdn_dp_resume is only used under PM_SLEEP, and now that it's static an
> >> unused function warning is triggered undner !PM_SLEEP.  This marks the
> >> function as possibly unused, to avoid triggering compiler warnings.
> >
> > Applied, thanks!
> >
> > [1/1] drm/rockchip: cdn-dp-core: Fix cdn_dp_resume unused warning
> >   commit: f7c57a4566115657c16fd6603b6ef8a21bae5194
> 
> I'm not quite sure where that lives, but is it applied on top of 
> something or is it merged from the tag?  Like I said a bit below this in 
> the original patch, this has started to break the build for me and I'd 
> like to pull it in as soon as possible.

The patch now lives here:
https://cgit.freedesktop.org/drm/drm-misc/commit/?h=drm-misc-fixes&id=f7c57a4566115657c16fd6603b6ef8a21bae5194

This is the drm-misc tree, with the patch living in the drm-misc-fixes
branch, which targets the current rc-kernels.

drm-misc-* moves into the core drm tree and from there on to Linus.


Hope that helps
Heiko





BoF at LPC: Documenting the Heterogeneous Memory Model Architecture

2021-09-21 Thread Felix Kuehling
As the programming models for GPU-based high-performance computing 
applications are evolving, HMM is helping us integrate the GPU memory 
management more closely with the kernel's virtual memory management. As 
a result we can provide a shared virtual address space with 
demand-paging and page-based migrations of anonymous pages to/from 
device memory. A patch series by AMD [1, 2] to add support for 
cache-coherent, CPU-accessible device memory has brought up some fairly 
fundamental questions about HMM and its interaction with virtual memory 
management, page cache and file systems. We'd like to use the chance of 
getting together for a BoF [3] at LPC to raise awareness for HMM outside 
the GPU driver code, identify gaps in the architectural documentation 
and clarify our priorities for future development.


Thank you, Daniel, for suggesting the BoF and getting it scheduled. It's 
set for Friday, 10am Pacific, 1pm Eastern, 5pm UTC.


I am registered at LPC. Daniel got a speaker's pass. We're still trying 
to work something out for Alex.


I hope to see many of you on Friday.

Best regards,
  Felix


[1] https://patchwork.freedesktop.org/series/94611/
[2] https://patchwork.freedesktop.org/series/90706/
[3] https://linuxplumbersconf.org/event/11/contributions/1123/

--
F e l i x   K u e h l i n g
PMTS Software Development Engineer | Linux Compute Kernel
1 Commerce Valley Dr. East, Markham, ON L3T 7X6 Canada
(O) +1(289)695-1597
_ _   _   _   _
   / \   | \ / | |  _  \  \ _  |
  / A \  | \M/ | | |D) )  /|_| |
 /_/ \_\ |_| |_| |_/ |__/ \|   facebook.com/AMD | amd.com



Re: [Intel-gfx] [PATCH 18/27] drm/i915/guc: Update debugfs for GuC multi-lrc

2021-09-21 Thread Matthew Brost
On Mon, Sep 20, 2021 at 03:48:59PM -0700, John Harrison wrote:
> 
> 
> On 8/20/2021 15:44, Matthew Brost wrote:
> > Display the workqueue status in debugfs for GuC contexts that are in
> > parent-child relationship.
> > 
> > Signed-off-by: Matthew Brost 
> > ---
> >   .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 51 ++-
> >   1 file changed, 37 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
> > b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > index e34e0ea9136a..07eee9a399c8 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > @@ -3673,6 +3673,26 @@ static void guc_log_context_priority(struct 
> > drm_printer *p,
> > drm_printf(p, "\n");
> >   }
> > +
> > +static inline void guc_log_context(struct drm_printer *p,
> > +  struct intel_context *ce)
> > +{
> > +   drm_printf(p, "GuC lrc descriptor %u:\n", ce->guc_id.id);
> > +   drm_printf(p, "\tHW Context Desc: 0x%08x\n", ce->lrc.lrca);
> > +   drm_printf(p, "\t\tLRC Head: Internal %u, Memory %u\n",
> > +  ce->ring->head,
> > +  ce->lrc_reg_state[CTX_RING_HEAD]);
> > +   drm_printf(p, "\t\tLRC Tail: Internal %u, Memory %u\n",
> > +  ce->ring->tail,
> > +  ce->lrc_reg_state[CTX_RING_TAIL]);
> > +   drm_printf(p, "\t\tContext Pin Count: %u\n",
> > +  atomic_read(&ce->pin_count));
> > +   drm_printf(p, "\t\tGuC ID Ref Count: %u\n",
> > +  atomic_read(&ce->guc_id.ref));
> > +   drm_printf(p, "\t\tSchedule State: 0x%x\n\n",
> > +  ce->guc_state.sched_state);
> > +}
> > +
> >   void intel_guc_submission_print_context_info(struct intel_guc *guc,
> >  struct drm_printer *p)
> >   {
> > @@ -3682,22 +3702,25 @@ void intel_guc_submission_print_context_info(struct 
> > intel_guc *guc,
> > xa_lock_irqsave(&guc->context_lookup, flags);
> > xa_for_each(&guc->context_lookup, index, ce) {
> > -   drm_printf(p, "GuC lrc descriptor %u:\n", ce->guc_id.id);
> > -   drm_printf(p, "\tHW Context Desc: 0x%08x\n", ce->lrc.lrca);
> > -   drm_printf(p, "\t\tLRC Head: Internal %u, Memory %u\n",
> > -  ce->ring->head,
> > -  ce->lrc_reg_state[CTX_RING_HEAD]);
> > -   drm_printf(p, "\t\tLRC Tail: Internal %u, Memory %u\n",
> > -  ce->ring->tail,
> > -  ce->lrc_reg_state[CTX_RING_TAIL]);
> > -   drm_printf(p, "\t\tContext Pin Count: %u\n",
> > -  atomic_read(&ce->pin_count));
> > -   drm_printf(p, "\t\tGuC ID Ref Count: %u\n",
> > -  atomic_read(&ce->guc_id.ref));
> > -   drm_printf(p, "\t\tSchedule State: 0x%x\n\n",
> > -  ce->guc_state.sched_state);
> > +   GEM_BUG_ON(intel_context_is_child(ce));
> > +   guc_log_context(p, ce);
> > guc_log_context_priority(p, ce);
> > +
> > +   if (intel_context_is_parent(ce)) {
> > +   struct guc_process_desc *desc = __get_process_desc(ce);
> > +   struct intel_context *child;
> > +
> > +   drm_printf(p, "\t\tWQI Head: %u\n",
> > +  READ_ONCE(desc->head));
> > +   drm_printf(p, "\t\tWQI Tail: %u\n",
> > +  READ_ONCE(desc->tail));
> > +   drm_printf(p, "\t\tWQI Status: %u\n\n",
> > +  READ_ONCE(desc->wq_status));
> > +
> > +   for_each_child(ce, child)
> > +   guc_log_context(p, child);
> There should be some indication that this is a child context and/or how many
> children there are. Otherwise how does the reader differentiation between
> the list of child contexts and the next parent/single context?
> 

We don't log the priority info or work queue info for child contexts so
it is actually pretty easy to parse. That being said, I'll output the
number of children if the context is a parent.

Matt

> John.
> 
> > +   }
> > }
> > xa_unlock_irqrestore(&guc->context_lookup, flags);
> >   }
> 


Re: [PATCH v6 2/2] drm/bridge: parade-ps8640: Add support for AUX channel

2021-09-21 Thread Doug Anderson
Hi,

On Tue, Sep 21, 2021 at 11:06 AM Philip Chen  wrote:
>
> Implement the first version of AUX support, which will be useful as
> we expand the driver to support varied use cases.
>
> Reviewed-by: Sam Ravnborg 
> Signed-off-by: Philip Chen 

Reviewed-by: Douglas Anderson 

Snoozing for 2 days and will plan to apply to drm-misc-next unless
there are objections.

-Doug


Re: [Intel-gfx] [PATCH] drm/i915: fix blank screen booting crashes

2021-09-21 Thread Lucas De Marchi

On Tue, Sep 21, 2021 at 10:43:32AM -0700, Matthew Brost wrote:

From: Hugh Dickins 

5.15-rc1 crashes with blank screen when booting up on two ThinkPads
using i915.  Bisections converge convincingly, but arrive at different
and surprising "culprits", none of them the actual culprit.

netconsole (with init_netconsole() hacked to call i915_init() when
logging has started, instead of by module_init()) tells the story:

kernel BUG at drivers/gpu/drm/i915/i915_sw_fence.c:245!
with RSI: 814d408b pointing to sw_fence_dummy_notify().
I've been building with CONFIG_CC_OPTIMIZE_FOR_SIZE=y, and that
function needs to be 4-byte aligned.

v2:
(Jani Nikula)
 - Change BUG_ON to WARN_ON
v3:
(Jani / Tvrtko)
 - Short circuit __i915_sw_fence_init on WARN_ON

Fixes: 62eaf0ae217d ("drm/i915/guc: Support request cancellation")
Signed-off-by: Hugh Dickins 
Signed-off-by: Matthew Brost 
Reviewed-by: Matthew Brost 
---
drivers/gpu/drm/i915/gt/intel_context.c |  4 ++--
drivers/gpu/drm/i915/i915_sw_fence.c| 17 ++---
2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index ff637147b1a9..e7f78bc7ebfc 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -362,8 +362,8 @@ static int __intel_context_active(struct i915_active 
*active)
return 0;
}




-static int sw_fence_dummy_notify(struct i915_sw_fence *sf,
-enum i915_sw_fence_notify state)
+static int __i915_sw_fence_call
+sw_fence_dummy_notify(struct i915_sw_fence *sf, enum i915_sw_fence_notify 
state)
{
return NOTIFY_DONE;
}
diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c 
b/drivers/gpu/drm/i915/i915_sw_fence.c
index c589a681da77..08cea73264e7 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence.c
+++ b/drivers/gpu/drm/i915/i915_sw_fence.c
@@ -13,9 +13,9 @@
#include "i915_selftest.h"

#if IS_ENABLED(CONFIG_DRM_I915_DEBUG)
-#define I915_SW_FENCE_BUG_ON(expr) BUG_ON(expr)
+#define I915_SW_FENCE_WARN_ON(expr) WARN_ON(expr)
#else
-#define I915_SW_FENCE_BUG_ON(expr) BUILD_BUG_ON_INVALID(expr)
+#define I915_SW_FENCE_WARN_ON(expr) BUILD_BUG_ON_INVALID(expr)
#endif

static DEFINE_SPINLOCK(i915_sw_fence_lock);
@@ -129,7 +129,10 @@ static int __i915_sw_fence_notify(struct i915_sw_fence 
*fence,
i915_sw_fence_notify_t fn;

fn = (i915_sw_fence_notify_t)(fence->flags & I915_SW_FENCE_MASK);
-   return fn(fence, state);
+   if (likely(fn))
+   return fn(fence, state);
+   else
+   return 0;


since the knowledge for these being NULL (or with the wrong alignment)
are in the init/reinit functions,  wouldn't it be better to just add a
fence_nop() and assign it there instead this likely() here?


}

#ifdef CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS
@@ -242,9 +245,9 @@ void __i915_sw_fence_init(struct i915_sw_fence *fence,
  const char *name,
  struct lock_class_key *key)
{
-   BUG_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK);
-
__init_waitqueue_head(&fence->wait, name, key);
+   if (WARN_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK))
+   return;


like:
if (WARN_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK))
fence->flags = (unsigned long)sw_fence_dummy_notify;
else
fence->flags = (unsigned long)fn;


f you return here instead of calling i915_sw_fence_reinit(), aren't you
just going to use uninitialized memory later? At least in the selftests,
which allocate it with kmalloc()... I didn't check others.


For the bug fix we could just add the __aligned(4) and leave the rest to a
separate patch.


Lucas De Marchi


fence->flags = (unsigned long)fn;

i915_sw_fence_reinit(fence);
@@ -257,8 +260,8 @@ void i915_sw_fence_reinit(struct i915_sw_fence *fence)
atomic_set(&fence->pending, 1);
fence->error = 0;

-   I915_SW_FENCE_BUG_ON(!fence->flags);
-   I915_SW_FENCE_BUG_ON(!list_empty(&fence->wait.head));
+   I915_SW_FENCE_WARN_ON(!fence->flags);
+   I915_SW_FENCE_WARN_ON(!list_empty(&fence->wait.head));
}

void i915_sw_fence_commit(struct i915_sw_fence *fence)
--
2.32.0



[Bug 211277] sometimes crash at s2ram-wake (Ryzen 3500U): amdgpu, drm, commit_tail, amdgpu_dm_atomic_commit_tail

2021-09-21 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=211277

--- Comment #71 from youling...@gmail.com ---
(In reply to James Zhu from comment #70)
> My mistaake. Can you try add pci=noats in boot parameters?

no help, still resume failed.

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

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

Re: [PATCH] drm/msm/dsi: do not install irq handler before power up the host

2021-09-21 Thread Andrzej Hajda
W dniu 21.09.2021 o 18:22, Dmitry Baryshkov pisze:
> The DSI host might be left in some state by the bootloader. If this
> state generates an IRQ, it might hang the system by holding the
> interrupt line before the driver sets up the DSI host to the known
> state.
>
> Move the request/free_irq calls into msm_dsi_host_power_on/_off calls,
> so that we can be sure that the interrupt is delivered when the host is
> in the known state.


The established practice is to request IRQ in probe, to avoid 
auto-enabling use IRQF_NO_AUTOEN flag.

Then you can call enable_irq in power-on.


Regards

Andrzej



>
> Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support")
> Signed-off-by: Dmitry Baryshkov 
> ---
>   drivers/gpu/drm/msm/dsi/dsi_host.c | 21 -
>   1 file changed, 12 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
> b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index e269df285136..cd842347a6b1 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -1951,15 +1951,6 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host 
> *host,
>   return ret;
>   }
>   
> - ret = devm_request_irq(&pdev->dev, msm_host->irq,
> - dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> - "dsi_isr", msm_host);
> - if (ret < 0) {
> - DRM_DEV_ERROR(&pdev->dev, "failed to request IRQ%u: %d\n",
> - msm_host->irq, ret);
> - return ret;
> - }
> -
>   msm_host->dev = dev;
>   ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
>   if (ret) {
> @@ -2413,6 +2404,16 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
>   if (msm_host->disp_en_gpio)
>   gpiod_set_value(msm_host->disp_en_gpio, 1);
>   
> + ret = devm_request_irq(&msm_host->pdev->dev, msm_host->irq,
> + dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> + "dsi_isr", msm_host);
> + if (ret < 0) {
> + DRM_DEV_ERROR(&msm_host->pdev->dev, "failed to request IRQ%u: 
> %d\n",
> + msm_host->irq, ret);
> + return ret;
> + }
> +
> +
>   msm_host->power_on = true;
>   mutex_unlock(&msm_host->dev_mutex);
>   
> @@ -2439,6 +2440,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host)
>   goto unlock_ret;
>   }
>   
> + devm_free_irq(&msm_host->pdev->dev, msm_host->irq, msm_host);
> +
>   dsi_ctrl_config(msm_host, false, NULL, NULL);
>   
>   if (msm_host->disp_en_gpio)


Re: [PATCH] MAINTAINERS: fix typo in DRM DRIVER FOR SAMSUNG S6D27A1 PANELS

2021-09-21 Thread Linus Walleij
On Tue, Sep 21, 2021 at 2:22 PM Lukas Bulwahn  wrote:

> Commit ebd8cbf1fb96 ("drm/panel: s6d27a1: Add driver for Samsung S6D27A1
> display panel") introduces a new section DRM DRIVER FOR SAMSUNG S6D27A1
> PANELS with a minor typo in one of its file entries.
>
> Hence, ./scripts/get_maintainer.pl --self-test=patterns complains:
>
>   warning: no file matches  F:  driver/gpu/drm/panel/panel-samsung-s6d27a1.c
>
> So, repair the entry and make get_maintainer.pl happy.
>
> Signed-off-by: Lukas Bulwahn 
> ---
> applies cleanly on next-20210920
>
> Linus, please pick this minor quick clean-up patch on drm-misc-next
> (on top of the commit mentioned above).

Patch applied!

Yours,
Linus Walleij


Re: [PATCH v5 2/2] drm/bridge: parade-ps8640: Add support for AUX channel

2021-09-21 Thread Philip Chen
Hi

On Tue, Sep 21, 2021 at 9:02 AM Doug Anderson  wrote:
>
> Hi,
>
> On Sat, Sep 18, 2021 at 10:21 AM Philip Chen  wrote:
> >
> > +static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux,
> > +  struct drm_dp_aux_msg *msg)
> > +{
> > +   struct ps8640 *ps_bridge = aux_to_ps8640(aux);
> > +   struct regmap *map = ps_bridge->regmap[PAGE0_DP_CNTL];
> > +   struct device *dev = &ps_bridge->page[PAGE0_DP_CNTL]->dev;
> > +
> > +   unsigned int len = msg->size;
>
> nit: usually no blank lines in the variable definition section.
Fixed in v6.
PTAL.

>
>
> > +   base = PAGE0_SWAUX_ADDR_7_0;
> > +   addr_len[PAGE0_SWAUX_ADDR_7_0 - base] = msg->address;
> > +   addr_len[PAGE0_SWAUX_ADDR_15_8 - base] = msg->address >> 8;
> > +   addr_len[PAGE0_SWAUX_ADDR_23_16 - base] = (msg->address >> 16) &
> > + SWAUX_ADDR_19_16_MASK;
> > +   addr_len[PAGE0_SWAUX_ADDR_23_16 - base] |= (msg->request << 4) &
> > +  SWAUX_CMD_MASK;
>
> optional nit: Probably you could get rid of the mask for the request.
> After all, you're storing it to a thing that's a byte (so bits above
> bit 7 will implicitly be masked) and you're left shifting by 4 (so
> bits 0-3 will implicitly be masked) so this just makes it uglier. ;-)
>
Fixed in v6.
PTAL.
> optional nit: In theory you could also get rid of the
> SWAUX_ADDR_19_16_MASK and if you really wanted to you could error
> check that the address wasn't bigger than 20-bits since giving an
> error for an invalid address would actually be better than silently
> masking it anyway...
>
Fixed in v6.
PTAL.
>
> > +   if (len && (request == DP_AUX_NATIVE_READ ||
> > +   request == DP_AUX_I2C_READ)) {
> > +   /* Read from the internal FIFO buffer */
> > +   for (i = 0; i < len; i++) {
> > +   ret = regmap_read(map, PAGE0_SWAUX_RDATA,
> > + (unsigned int *)(buf + i));
>
> The cast to "unsigned int *" looks wrong to me. You can't just cast
> like this for a number of reasons. Go back to reading into a local
> variable and copy the byte into your buffer.
>
Previously I was not 100% sure about this change either.
Now I'm sure it is bad after some experiments.
In v6, I reverted to how this was handled in v3.
PTAL.

>
> Other than the regmap_read() this looks fine to me. If you send a v6
> with that fixed I'll plan to wait a day or two and then apply it with
> Sam's tags.
>
> -Doug


[PATCH v6 2/2] drm/bridge: parade-ps8640: Add support for AUX channel

2021-09-21 Thread Philip Chen
Implement the first version of AUX support, which will be useful as
we expand the driver to support varied use cases.

Reviewed-by: Sam Ravnborg 
Signed-off-by: Philip Chen 
---

Changes in v6:
- Error check the aux address is no greater than 20 bits
- Read RDATA into a u32 variable and then copy the byte to the u8 buf
- Fix a few nits from v5 review

Changes in v5:
- Add a couple of syntax fixes accidentally uncommited in v4

Changes in v4:
- Fix aux_transfer function:
  - Replace dev_err with DRM_DEV_ERROR
  - Reorg the bit manipulation around address/len/request registers
  - Make SWAUX_STATUS_I2C_NACK fall through to SWAUX_STATUS_ACKM and
store the number of read bytes to `len` w/o returning immediately

Changes in v3:
- Verify with HW and thus remove WARNING from the patch description
- Fix the reg names to better match the manual
- Fix aux_transfer function:
  - Fix the switch statement which handles aux request
  - Write the original (unstripped) aux request code to the register
  - Replace DRM_ERROR with dev_err
  - Remove goto and just return ret
  - Fix the switch statement which handles aux status
  - When reading returned data, read from RDATA instead of WDATA
- Fix attach function:
  - Call mipi_dsi_detach() when aux_register fails

Changes in v2:
- Handle the case where an AUX transaction has no payload
- Add a reg polling for p0.0x83 to confirm AUX cmd is issued and
  read data is returned
- Replace regmap_noinc_read/write with looped regmap_read/write,
  as regmap_noinc_read/write doesn't read one byte at a time unless
  max_raw_read/write is set to 1.
- Register/Unregister the AUX device explicitly when the bridge is
  attached/detached
- Remove the use of runtime PM
- Program AUX addr/cmd/len in a single regmap_bulk_write()
- Add newlines for DRM_ERROR messages

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

diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c 
b/drivers/gpu/drm/bridge/parade-ps8640.c
index 18328e75bf90..56a206967e3d 100644
--- a/drivers/gpu/drm/bridge/parade-ps8640.c
+++ b/drivers/gpu/drm/bridge/parade-ps8640.c
@@ -13,11 +13,36 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 
+#define PAGE0_AUXCH_CFG3   0x76
+#define  AUXCH_CFG3_RESET  0xff
+#define PAGE0_SWAUX_ADDR_7_0   0x7d
+#define PAGE0_SWAUX_ADDR_15_8  0x7e
+#define PAGE0_SWAUX_ADDR_23_16 0x7f
+#define  SWAUX_ADDR_MASK   GENMASK(19, 0)
+#define PAGE0_SWAUX_LENGTH 0x80
+#define  SWAUX_LENGTH_MASK GENMASK(3, 0)
+#define  SWAUX_NO_PAYLOAD  BIT(7)
+#define PAGE0_SWAUX_WDATA  0x81
+#define PAGE0_SWAUX_RDATA  0x82
+#define PAGE0_SWAUX_CTRL   0x83
+#define  SWAUX_SENDBIT(0)
+#define PAGE0_SWAUX_STATUS 0x84
+#define  SWAUX_M_MASK  GENMASK(4, 0)
+#define  SWAUX_STATUS_MASK GENMASK(7, 5)
+#define  SWAUX_STATUS_NACK (0x1 << 5)
+#define  SWAUX_STATUS_DEFER(0x2 << 5)
+#define  SWAUX_STATUS_ACKM (0x3 << 5)
+#define  SWAUX_STATUS_INVALID  (0x4 << 5)
+#define  SWAUX_STATUS_I2C_NACK (0x5 << 5)
+#define  SWAUX_STATUS_I2C_DEFER(0x6 << 5)
+#define  SWAUX_STATUS_TIMEOUT  (0x7 << 5)
+
 #define PAGE2_GPIO_H   0xa7
 #define  PS_GPIO9  BIT(1)
 #define PAGE2_I2C_BYPASS   0xea
@@ -68,6 +93,7 @@ enum ps8640_vdo_control {
 struct ps8640 {
struct drm_bridge bridge;
struct drm_bridge *panel_bridge;
+   struct drm_dp_aux aux;
struct mipi_dsi_device *dsi;
struct i2c_client *page[MAX_DEVS];
struct regmap   *regmap[MAX_DEVS];
@@ -117,6 +143,137 @@ static inline struct ps8640 *bridge_to_ps8640(struct 
drm_bridge *e)
return container_of(e, struct ps8640, bridge);
 }
 
+static inline struct ps8640 *aux_to_ps8640(struct drm_dp_aux *aux)
+{
+   return container_of(aux, struct ps8640, aux);
+}
+
+static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux,
+  struct drm_dp_aux_msg *msg)
+{
+   struct ps8640 *ps_bridge = aux_to_ps8640(aux);
+   struct regmap *map = ps_bridge->regmap[PAGE0_DP_CNTL];
+   struct device *dev = &ps_bridge->page[PAGE0_DP_CNTL]->dev;
+   unsigned int len = msg->size;
+   unsigned int data;
+   unsigned int base;
+   int ret;
+   u8 request = msg->request &
+~(DP_AUX_I2C_MOT | DP_AUX_I2C_WRITE_STATUS_UPDATE);
+   u8 *buf = msg->buffer;
+   u8 addr_len[PAGE0_SWAUX_LENGTH + 1 - PAGE0_SWAUX_ADDR_7_0];
+   u8 i;
+   bool is_native_aux = false;
+
+   if (len > DP_AUX_MAX_PAYLOAD_BYTES)
+   return -EINVAL;
+
+   if (msg->address & ~SWAUX_ADDR_MASK)
+   return -EINVAL;
+
+   switch (request) {
+   case DP_AUX_NATIVE_WRITE:
+   case DP_AUX_NATIVE_READ:
+   is_native_aux = true;
+   fallthrough;
+   case DP_AUX_I2C_WRITE:
+   case DP_AUX_I2C_READ:
+   break;
+   default:
+

[PATCH v6 1/2] drm/bridge: parade-ps8640: Use regmap APIs

2021-09-21 Thread Philip Chen
Replace the direct i2c access (i2c_smbus_* functions) with regmap APIs,
which will simplify the future update on ps8640 driver.

Reviewed-by: Douglas Anderson 
Acked-by: Sam Ravnborg 
Signed-off-by: Philip Chen 
---

(no changes since v4)

Changes in v4:
- Remove excessive error logging from the probe function

Changes in v3:
- Fix the nits from v2 review

Changes in v2:
- Add separate reg map config per page

 drivers/gpu/drm/bridge/parade-ps8640.c | 94 ++
 1 file changed, 64 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c 
b/drivers/gpu/drm/bridge/parade-ps8640.c
index 685e9c38b2db..18328e75bf90 100644
--- a/drivers/gpu/drm/bridge/parade-ps8640.c
+++ b/drivers/gpu/drm/bridge/parade-ps8640.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -31,6 +32,11 @@
 
 #define NUM_MIPI_LANES 4
 
+#define COMMON_PS8640_REGMAP_CONFIG \
+   .reg_bits = 8, \
+   .val_bits = 8, \
+   .cache_type = REGCACHE_NONE
+
 /*
  * PS8640 uses multiple addresses:
  * page[0]: for DP control
@@ -64,12 +70,48 @@ struct ps8640 {
struct drm_bridge *panel_bridge;
struct mipi_dsi_device *dsi;
struct i2c_client *page[MAX_DEVS];
+   struct regmap   *regmap[MAX_DEVS];
struct regulator_bulk_data supplies[2];
struct gpio_desc *gpio_reset;
struct gpio_desc *gpio_powerdown;
bool powered;
 };
 
+static const struct regmap_config ps8640_regmap_config[] = {
+   [PAGE0_DP_CNTL] = {
+   COMMON_PS8640_REGMAP_CONFIG,
+   .max_register = 0xbf,
+   },
+   [PAGE1_VDO_BDG] = {
+   COMMON_PS8640_REGMAP_CONFIG,
+   .max_register = 0xff,
+   },
+   [PAGE2_TOP_CNTL] = {
+   COMMON_PS8640_REGMAP_CONFIG,
+   .max_register = 0xff,
+   },
+   [PAGE3_DSI_CNTL1] = {
+   COMMON_PS8640_REGMAP_CONFIG,
+   .max_register = 0xff,
+   },
+   [PAGE4_MIPI_PHY] = {
+   COMMON_PS8640_REGMAP_CONFIG,
+   .max_register = 0xff,
+   },
+   [PAGE5_VPLL] = {
+   COMMON_PS8640_REGMAP_CONFIG,
+   .max_register = 0x7f,
+   },
+   [PAGE6_DSI_CNTL2] = {
+   COMMON_PS8640_REGMAP_CONFIG,
+   .max_register = 0xff,
+   },
+   [PAGE7_SPI_CNTL] = {
+   COMMON_PS8640_REGMAP_CONFIG,
+   .max_register = 0xff,
+   },
+};
+
 static inline struct ps8640 *bridge_to_ps8640(struct drm_bridge *e)
 {
return container_of(e, struct ps8640, bridge);
@@ -78,13 +120,13 @@ static inline struct ps8640 *bridge_to_ps8640(struct 
drm_bridge *e)
 static int ps8640_bridge_vdo_control(struct ps8640 *ps_bridge,
 const enum ps8640_vdo_control ctrl)
 {
-   struct i2c_client *client = ps_bridge->page[PAGE3_DSI_CNTL1];
+   struct regmap *map = ps_bridge->regmap[PAGE3_DSI_CNTL1];
u8 vdo_ctrl_buf[] = { VDO_CTL_ADD, ctrl };
int ret;
 
-   ret = i2c_smbus_write_i2c_block_data(client, PAGE3_SET_ADD,
-sizeof(vdo_ctrl_buf),
-vdo_ctrl_buf);
+   ret = regmap_bulk_write(map, PAGE3_SET_ADD,
+   vdo_ctrl_buf, sizeof(vdo_ctrl_buf));
+
if (ret < 0) {
DRM_ERROR("failed to %sable VDO: %d\n",
  ctrl == ENABLE ? "en" : "dis", ret);
@@ -96,8 +138,7 @@ static int ps8640_bridge_vdo_control(struct ps8640 
*ps_bridge,
 
 static void ps8640_bridge_poweron(struct ps8640 *ps_bridge)
 {
-   struct i2c_client *client = ps_bridge->page[PAGE2_TOP_CNTL];
-   unsigned long timeout;
+   struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL];
int ret, status;
 
if (ps_bridge->powered)
@@ -121,18 +162,12 @@ static void ps8640_bridge_poweron(struct ps8640 
*ps_bridge)
 */
msleep(200);
 
-   timeout = jiffies + msecs_to_jiffies(200) + 1;
-
-   while (time_is_after_jiffies(timeout)) {
-   status = i2c_smbus_read_byte_data(client, PAGE2_GPIO_H);
-   if (status < 0) {
-   DRM_ERROR("failed read PAGE2_GPIO_H: %d\n", status);
-   goto err_regulators_disable;
-   }
-   if ((status & PS_GPIO9) == PS_GPIO9)
-   break;
+   ret = regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
+   status & PS_GPIO9, 20 * 1000, 200 * 1000);
 
-   msleep(20);
+   if (ret < 0) {
+   DRM_ERROR("failed read PAGE2_GPIO_H: %d\n", ret);
+   goto err_regulators_disable;
}
 
msleep(50);
@@ -144,22 +179,15 @@ static void ps8640_bridge_poweron(struct ps8640 
*ps_bridge)
 * disabled by the manufacturer. Once disabled, all MCS commands are
 * ignored by the display interface.
  

Re: [RFC PATCH v3 1/6] drm/doc: Color Management and HDR10 RFC

2021-09-21 Thread Harry Wentland



On 2021-09-21 09:31, Pekka Paalanen wrote:
> On Mon, 20 Sep 2021 20:14:50 -0400
> Harry Wentland  wrote:
> 
>> On 2021-09-15 10:01, Pekka Paalanen wrote:> On Fri, 30 Jul 2021 16:41:29 
>> -0400
>>> Harry Wentland  wrote:
>>>   
 Use the new DRM RFC doc section to capture the RFC previously only
 described in the cover letter at
 https://patchwork.freedesktop.org/series/89506/

 v3:
  * Add sections on single-plane and multi-plane HDR
  * Describe approach to define HW details vs approach to define SW 
 intentions
  * Link Jeremy Cline's excellent HDR summaries
  * Outline intention behind overly verbose doc
  * Describe FP16 use-case
  * Clean up links

 v2: create this doc

 v1: n/a

 Signed-off-by: Harry Wentland   
> 
> Hi Harry!
> 
> ...
> 
 ---
  Documentation/gpu/rfc/color_intentions.drawio |   1 +
  Documentation/gpu/rfc/color_intentions.svg|   3 +
  Documentation/gpu/rfc/colorpipe   |   1 +
  Documentation/gpu/rfc/colorpipe.svg   |   3 +
  Documentation/gpu/rfc/hdr-wide-gamut.rst  | 580 ++
  Documentation/gpu/rfc/index.rst   |   1 +
  6 files changed, 589 insertions(+)
  create mode 100644 Documentation/gpu/rfc/color_intentions.drawio
  create mode 100644 Documentation/gpu/rfc/color_intentions.svg
  create mode 100644 Documentation/gpu/rfc/colorpipe
  create mode 100644 Documentation/gpu/rfc/colorpipe.svg
  create mode 100644 Documentation/gpu/rfc/hdr-wide-gamut.rst  
> 
> ...
> 
 +
 +Here are some examples of real-life objects and their approximate
 +luminance values:
 +
 +
 +.. _PQ (perceptual quantizer) function: 
 https://en.wikipedia.org/wiki/High-dynamic-range_video#Perceptual_Quantizer
 +
 +.. flat-table::
 +   :header-rows: 1
 +
 +   * - Object
 + - Luminance in nits
 +
 +   *  - Fluorescent light
 +  - 10,000
 +
 +   *  - Highlights
 +  - 1,000 - sunlight  
>>>
>>> Did fluorescent and highlights get swapped here?
>>>   
>> No, though at first glance it can look like that. This is pulled
>> from an internal doc I didn't write, but I think the intention is
>> to show that fluorescent lights can be up to 10,000 nits and
>> highlights are usually 1,000+ nits.
>>
>> I'll clarify this in v4.
>>
>> A quick google search seems to show that there are even fluorescent
>> lights with 46,000 nits. I guess these numbers provide a ballpark
>> view more than anything.
> 
> Those seem quite extreme fluorescent lights, far beyond what one might
> find in offices I suppose?
> 
> I mean, I can totally stare straight at my office fluorescent lights
> without any discomfort.
> 
> Highlights OTOH of course depend on which highlights we're talking
> about, and your 1000 - sunlight range I can totally agree with.
> 
> If you look at a sea or a lake on a sunny day, the reflections of Sun
> on the water surface are much much brighter than anything else in
> nature aside from Sun itself. I happened to see this myself when
> playing with a camera: the rest of the image can be black while the
> water highlights still shoot way beyond the captured dynamic range.
> 
 +
 +   *  - White Objects
 +  - 250 - 1,000
 +
 +   *  - Typical Objects
 +  - 1 - 250
 +
 +   *  - Shadows
 +  - 0.01 - 1
 +
 +   *  - Ultra Blacks
 +  - 0 - 0.0005
 +
 +
 +Transfer functions
 +--
 +
 +Traditionally we used the terms gamma and de-gamma to describe the
 +encoding of a pixel's luminance value and the operation to transfer from
 +a linear luminance space to the non-linear space used to encode the
 +pixels. Since some newer encodings don't use a gamma curve I suggest
 +we refer to non-linear encodings using the terms `EOTF, and OETF`_, or
 +simply as transfer function in general.  
>>>
>>> Yeah, gamma could mean lots of things. If you have e.g. OETF gamma
>>> 1/2.2 and EOTF gamma 2.4, the result is OOTF gamma 1.09.
>>>
>>> OETF, EOTF and OOTF are not unambiguous either, since there is always
>>> the question of whose function is it.
>>>   
>> Yeah, I think both gamma and EO/OE/OO/EETF are all somewhat problematic.
> 
> We can use them, but we have to explain which functions we are
> referring to. In particular, if you have a specific EOTF, then the
> inverse of it should be called EOTF^-1 and not OETF, to follow what I
> have understood of specs like BT.2100.
> 

I should probably add a paragraph about OOTF. The apple talk you
linked below uses OOTF to refer to tone-mapping.

> Personally I'd take things further and talk about encoding and decoding
> functions when the intent is to translate between pixel values and
> light-linear color values rather than characterising a piece of
> equipment.
> 
>> I tend to think about these more in terms of input and ou

Re: [PATCH v3 8/9] dma-buf/sync_file: Add SET_DEADLINE ioctl

2021-09-21 Thread Rob Clark
On Wed, Sep 8, 2021 at 2:10 PM Daniel Vetter  wrote:
>
> On Wed, Sep 8, 2021 at 9:36 PM Rob Clark  wrote:
> > On Wed, Sep 8, 2021 at 11:49 AM Daniel Vetter  wrote:
> > > On Wed, Sep 08, 2021 at 11:23:42AM -0700, Rob Clark wrote:
> > > > On Wed, Sep 8, 2021 at 10:50 AM Daniel Vetter  wrote:
> > > > >
> > > > > On Fri, Sep 03, 2021 at 11:47:59AM -0700, Rob Clark wrote:
> > > > > > From: Rob Clark 
> > > > > >
> > > > > > The initial purpose is for igt tests, but this would also be useful 
> > > > > > for
> > > > > > compositors that wait until close to vblank deadline to make 
> > > > > > decisions
> > > > > > about which frame to show.
> > > > > >
> > > > > > Signed-off-by: Rob Clark 
> > > > >
> > > > > Needs userspace and I think ideally also some igts to make sure it 
> > > > > works
> > > > > and doesn't go boom.
> > > >
> > > > See cover-letter.. there are igt tests, although currently that is the
> > > > only user.
> > >
> > > Ah sorry missed that. It would be good to record that in the commit too
> > > that adds the uapi. git blame doesn't find cover letters at all, unlike on
> > > gitlab where you get the MR request with everything.
> > >
> > > Ok there is the Link: thing, but since that only points at the last
> > > version all the interesting discussion is still usually lost, so I tend to
> > > not bother looking there.
> > >
> > > > I'd be ok to otherwise initially restrict this and the sw_sync UABI
> > > > (CAP_SYS_ADMIN?  Or??) until there is a non-igt user, but they are
> > > > both needed by the igt tests
> > >
> > > Hm really awkward, uapi for igts in cross vendor stuff like this isn't
> > > great. I think hiding it in vgem is semi-ok (we have fences there
> > > already). But it's all a bit silly ...
> > >
> > > For the tests, should we instead have a selftest/Kunit thing to exercise
> > > this stuff? igt probably not quite the right thing. Or combine with a page
> > > flip if you want to test msm.
> >
> > Hmm, IIRC we have used CONFIG_BROKEN or something along those lines
> > for UABI in other places where we weren't willing to commit to yet?
> >
> > I suppose if we had to I could make this a sw_sync ioctl instead.  But
> > OTOH there are kind of a limited # of ways this ioctl could look.  And
> > we already know that at least some wayland compositors are going to
> > want this.
>
> Hm I was trying to think up a few ways this could work, but didn't
> come up with anything reasonable. Forcing the compositor to boost the
> entire chain (for gl composited primary plane fallback) is something
> the kernel can easily do too. Also only makes sense for priority
> boost, not so much for clock boosting, since clock boosting only
> really needs the final element to be boosted.

So, I think the compositor, much like
drm_atomic_helper_wait_for_fences(), really just sees one fence per
surface, it doesn't really know (or care) that under-the-hood it is a
fence-chain or fence-array.  There isn't really much for the
compositor to do but inform "if possible, I'd like this fence to be
signaled by time T".

Say you have multiple updated frames, which have a fence-array
composed of fences from multiple different rings.  It is up to the
fence provider to keep track of the latest fence and the earliest
deadline.

The drm/msm implementation doesn't try to be too clever and track
multiple deadlines, Ie. fenceA wanted by time1 and fenceB wanted by
time2.  It just keeps track of the nearest deadline and the last
fence.  That is probably sufficient, eventually the utilization based
gpu freq governor will settle into the appropriate steady-state
framerate.

(Although, I did realize that the WAIT_FENCE ioctl should also be
setting a deadline.. I forgot to add that)

> > I guess I can look at non-igt options.  But the igt test is already a
> > pretty convenient way to contrive situations (like loops, which is a
> > thing I need to add)
>
> Yeah it's definitely very useful for testing ... One option could be a
> hacky debugfs interface, where you write a fd number and deadline and
> the debugfs read function does the deadline setting. Horribly, but
> since it's debugfs no one ever cares. That's at least where we're
> hiding all the i915 hacks that igts need.

ugg :-)

BR,
-R

> -Daniel
>
> > BR,
> > -R
> >
> >
> > > -Daniel
> > >
> > > >
> > > > BR,
> > > > -R
> > > >
> > > > > -Daniel
> > > > >
> > > > > > ---
> > > > > >  drivers/dma-buf/sync_file.c| 19 +++
> > > > > >  include/uapi/linux/sync_file.h | 20 
> > > > > >  2 files changed, 39 insertions(+)
> > > > > >
> > > > > > diff --git a/drivers/dma-buf/sync_file.c 
> > > > > > b/drivers/dma-buf/sync_file.c
> > > > > > index 394e6e1e9686..f295772d5169 100644
> > > > > > --- a/drivers/dma-buf/sync_file.c
> > > > > > +++ b/drivers/dma-buf/sync_file.c
> > > > > > @@ -459,6 +459,22 @@ static long sync_file_ioctl_fence_info(struct 
> > > > > > sync_file *sync_file,
> > > > > >   return ret;
> > > > > >  }
> > > > > >
> > > > > > 

[Bug 211277] sometimes crash at s2ram-wake (Ryzen 3500U): amdgpu, drm, commit_tail, amdgpu_dm_atomic_commit_tail

2021-09-21 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=211277

--- Comment #70 from James Zhu (jam...@amd.com) ---
My mistaake. Can you try add pci=noats in boot parameters?

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

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

[PATCH v5 5/7] drm/i915/gt: Register the migrate contexts with their engines

2021-09-21 Thread Thomas Hellström
Pinned contexts, like the migrate contexts need reset after resume
since their context image may have been lost. Also the GuC needs to
register pinned contexts.

Add a list to struct intel_engine_cs where we add all pinned contexts on
creation, and traverse that list at resume time to reset the pinned
contexts.

This fixes the kms_pipe_crc_basic@suspend-read-crc-pipe-a selftest for now,
but proper LMEM backup / restore is needed for full suspend functionality.
However, note that even with full LMEM backup / restore it may be
desirable to keep the reset since backing up the migrate context images
must happen using memcpy() after the migrate context has become inactive,
and for performance- and other reasons we want to avoid memcpy() from
LMEM.

Also traverse the list at guc_init_lrc_mapping() calling
guc_kernel_context_pin() for the pinned contexts, like is already done
for the kernel context.

v2:
- Don't reset the contexts on each __engine_unpark() but rather at
  resume time (Chris Wilson).
v3:
- Reset contexts in the engine sanitize callback. (Chris Wilson)

Cc: Tvrtko Ursulin 
Cc: Matthew Auld 
Cc: Maarten Lankhorst 
Cc: Brost Matthew 
Cc: Chris Wilson 
Signed-off-by: Thomas Hellström 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gt/intel_context_types.h |  8 +++
 drivers/gpu/drm/i915/gt/intel_engine_cs.c |  4 
 drivers/gpu/drm/i915/gt/intel_engine_pm.c | 23 +++
 drivers/gpu/drm/i915/gt/intel_engine_pm.h |  2 ++
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  7 ++
 .../drm/i915/gt/intel_execlists_submission.c  |  2 ++
 .../gpu/drm/i915/gt/intel_ring_submission.c   |  3 +++
 drivers/gpu/drm/i915/gt/mock_engine.c |  2 ++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 12 +++---
 9 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 930569a1a01f..12252c411159 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -153,6 +153,14 @@ struct intel_context {
/** sseu: Control eu/slice partitioning */
struct intel_sseu sseu;
 
+   /**
+* pinned_contexts_link: List link for the engine's pinned contexts.
+* This is only used if this is a perma-pinned kernel context and
+* the list is assumed to only be manipulated during driver load
+* or unload time so no mutex protection currently.
+*/
+   struct list_head pinned_contexts_link;
+
u8 wa_bb_page; /* if set, page num reserved for context workarounds */
 
struct {
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 06dfe7f38953..2ae57e4656a3 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -320,6 +320,7 @@ static int intel_engine_setup(struct intel_gt *gt, enum 
intel_engine_id id)
 
BUILD_BUG_ON(BITS_PER_TYPE(engine->mask) < I915_NUM_ENGINES);
 
+   INIT_LIST_HEAD(&engine->pinned_contexts_list);
engine->id = id;
engine->legacy_idx = INVALID_ENGINE;
engine->mask = BIT(id);
@@ -890,6 +891,8 @@ intel_engine_create_pinned_context(struct intel_engine_cs 
*engine,
return ERR_PTR(err);
}
 
+   list_add_tail(&ce->pinned_contexts_link, &engine->pinned_contexts_list);
+
/*
 * Give our perma-pinned kernel timelines a separate lockdep class,
 * so that we can use them from within the normal user timelines
@@ -912,6 +915,7 @@ void intel_engine_destroy_pinned_context(struct 
intel_context *ce)
list_del(&ce->timeline->engine_link);
mutex_unlock(&hwsp->vm->mutex);
 
+   list_del(&ce->pinned_contexts_link);
intel_context_unpin(ce);
intel_context_put(ce);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c 
b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index 1f07ac4e0672..dacd62773735 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -298,6 +298,29 @@ void intel_engine_init__pm(struct intel_engine_cs *engine)
intel_engine_init_heartbeat(engine);
 }
 
+/**
+ * intel_engine_reset_pinned_contexts - Reset the pinned contexts of
+ * an engine.
+ * @engine: The engine whose pinned contexts we want to reset.
+ *
+ * Typically the pinned context LMEM images lose or get their content
+ * corrupted on suspend. This function resets their images.
+ */
+void intel_engine_reset_pinned_contexts(struct intel_engine_cs *engine)
+{
+   struct intel_context *ce;
+
+   list_for_each_entry(ce, &engine->pinned_contexts_list,
+   pinned_contexts_link) {
+   /* kernel context gets reset at __engine_unpark() */
+   if (ce == engine->kernel_context)
+   continue;
+
+   dbg_poison_ce(ce);
+   ce->ops->rese

[PATCH v5 7/7] drm/i915: Reduce the number of objects subject to memcpy recover

2021-09-21 Thread Thomas Hellström
We really only need memcpy restore for objects that affect the
operability of the migrate context. That is, primarily the page-table
objects of the migrate VM.

Add an object flag, I915_BO_ALLOC_PM_EARLY for objects that need early
restores using memcpy and a way to assign LMEM page-table object flags
to be used by the vms.

Restore objects without this flag with the gpu blitter and only objects
carrying the flag using TTM memcpy.

Initially mark the migrate, gt, gtt and vgpu vms to use this flag, and
defer for a later audit which vms actually need it. Most importantly, user-
allocated vms with pinned page-table objects can be restored using the
blitter.

Performance-wise memcpy restore is probably as fast as gpu restore if not
faster, but using gpu restore will help tackling future restrictions in
mappable LMEM size.

v4:
- Don't mark the aliasing ppgtt page table flags for early resume, but
  rather the ggtt page table flags as intended. (Matthew Auld)
- The check for user buffer objects during early resume is pointless, since
  they are never marked I915_BO_ALLOC_PM_EARLY. (Matthew Auld)
v5:
- Mark GuC LMEM objects with I915_BO_ALLOC_PM_EARLY to have them restored
  before we fire up the migrate context.

Cc: Matthew Brost 
Signed-off-by: Thomas Hellström 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c  |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_object_types.h |  9 ++---
 drivers/gpu/drm/i915/gem/i915_gem_pm.c   |  6 +-
 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c   |  5 +++--
 drivers/gpu/drm/i915/gem/selftests/huge_pages.c  |  2 +-
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c |  2 +-
 drivers/gpu/drm/i915/gt/gen8_ppgtt.c |  5 +++--
 drivers/gpu/drm/i915/gt/gen8_ppgtt.h |  4 +++-
 drivers/gpu/drm/i915/gt/intel_ggtt.c |  3 ++-
 drivers/gpu/drm/i915/gt/intel_gt.c   |  2 +-
 drivers/gpu/drm/i915/gt/intel_gtt.c  |  3 ++-
 drivers/gpu/drm/i915/gt/intel_gtt.h  |  9 +++--
 drivers/gpu/drm/i915/gt/intel_migrate.c  |  2 +-
 drivers/gpu/drm/i915/gt/intel_ppgtt.c| 13 -
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c |  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc.c   |  3 ++-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c |  7 +--
 drivers/gpu/drm/i915/gvt/scheduler.c |  2 +-
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c|  4 ++--
 19 files changed, 56 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index c2ab0e22db0a..8208fd5b72c3 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -1287,7 +1287,7 @@ i915_gem_create_context(struct drm_i915_private *i915,
} else if (HAS_FULL_PPGTT(i915)) {
struct i915_ppgtt *ppgtt;
 
-   ppgtt = i915_ppgtt_create(&i915->gt);
+   ppgtt = i915_ppgtt_create(&i915->gt, 0);
if (IS_ERR(ppgtt)) {
drm_dbg(&i915->drm, "PPGTT setup failed (%ld)\n",
PTR_ERR(ppgtt));
@@ -1465,7 +1465,7 @@ int i915_gem_vm_create_ioctl(struct drm_device *dev, void 
*data,
if (args->flags)
return -EINVAL;
 
-   ppgtt = i915_ppgtt_create(&i915->gt);
+   ppgtt = i915_ppgtt_create(&i915->gt, 0);
if (IS_ERR(ppgtt))
return PTR_ERR(ppgtt);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 118691ce81d7..fa2ba9e2a4d0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -294,13 +294,16 @@ struct drm_i915_gem_object {
 #define I915_BO_ALLOC_USERBIT(3)
 /* Object is allowed to lose its contents on suspend / resume, even if pinned 
*/
 #define I915_BO_ALLOC_PM_VOLATILE BIT(4)
+/* Object needs to be restored early using memcpy during resume */
+#define I915_BO_ALLOC_PM_EARLYBIT(5)
 #define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \
 I915_BO_ALLOC_VOLATILE | \
 I915_BO_ALLOC_CPU_CLEAR | \
 I915_BO_ALLOC_USER | \
-I915_BO_ALLOC_PM_VOLATILE)
-#define I915_BO_READONLY  BIT(5)
-#define I915_TILING_QUIRK_BIT 6 /* unknown swizzling; do not release! */
+I915_BO_ALLOC_PM_VOLATILE | \
+I915_BO_ALLOC_PM_EARLY)
+#define I915_BO_READONLY  BIT(6)
+#define I915_TILING_QUIRK_BIT 7 /* unknown swizzling; do not release! */
 
/**
 * @mem_flags - Mutable placement-related flags
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
index 12b37b4c1192..726b40e1fbb0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pm.c
+++ b/drivers/gpu/drm

[PATCH v5 6/7] drm/i915: Don't back up pinned LMEM context images and rings during suspend

2021-09-21 Thread Thomas Hellström
Pinned context images are now reset during resume. Don't back them up,
and assuming that rings can be assumed empty at suspend, don't back them
up either.

Introduce a new object flag, I915_BO_ALLOC_PM_VOLATILE meaning that an
object is allowed to lose its content on suspend.

v3:
- Slight documentation clarification (Matthew Auld)

Signed-off-by: Thomas Hellström 
Reviewed-by: Matthew Auld 
---
 .../gpu/drm/i915/gem/i915_gem_object_types.h| 17 ++---
 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c  |  3 +++
 drivers/gpu/drm/i915/gt/intel_lrc.c |  3 ++-
 drivers/gpu/drm/i915/gt/intel_ring.c|  3 ++-
 4 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 734cc8e16481..118691ce81d7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -288,16 +288,19 @@ struct drm_i915_gem_object {
I915_SELFTEST_DECLARE(struct list_head st_link);
 
unsigned long flags;
-#define I915_BO_ALLOC_CONTIGUOUS BIT(0)
-#define I915_BO_ALLOC_VOLATILE   BIT(1)
-#define I915_BO_ALLOC_CPU_CLEAR  BIT(2)
-#define I915_BO_ALLOC_USER   BIT(3)
+#define I915_BO_ALLOC_CONTIGUOUS  BIT(0)
+#define I915_BO_ALLOC_VOLATILEBIT(1)
+#define I915_BO_ALLOC_CPU_CLEAR   BIT(2)
+#define I915_BO_ALLOC_USERBIT(3)
+/* Object is allowed to lose its contents on suspend / resume, even if pinned 
*/
+#define I915_BO_ALLOC_PM_VOLATILE BIT(4)
 #define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \
 I915_BO_ALLOC_VOLATILE | \
 I915_BO_ALLOC_CPU_CLEAR | \
-I915_BO_ALLOC_USER)
-#define I915_BO_READONLY BIT(4)
-#define I915_TILING_QUIRK_BIT5 /* unknown swizzling; do not release! */
+I915_BO_ALLOC_USER | \
+I915_BO_ALLOC_PM_VOLATILE)
+#define I915_BO_READONLY  BIT(5)
+#define I915_TILING_QUIRK_BIT 6 /* unknown swizzling; do not release! */
 
/**
 * @mem_flags - Mutable placement-related flags
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
index cb1c46724f70..03a00d193f40 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
@@ -60,6 +60,9 @@ static int i915_ttm_backup(struct i915_gem_apply_to_region 
*apply,
if (!pm_apply->backup_pinned)
return 0;
 
+   if (obj->flags & I915_BO_ALLOC_PM_VOLATILE)
+   return 0;
+
backup = i915_gem_object_create_shmem(i915, obj->base.size);
if (IS_ERR(backup))
return PTR_ERR(backup);
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 6ba8daea2f56..3ef9eaf8c50e 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -942,7 +942,8 @@ __lrc_alloc_state(struct intel_context *ce, struct 
intel_engine_cs *engine)
context_size += PAGE_SIZE;
}
 
-   obj = i915_gem_object_create_lmem(engine->i915, context_size, 0);
+   obj = i915_gem_object_create_lmem(engine->i915, context_size,
+ I915_BO_ALLOC_PM_VOLATILE);
if (IS_ERR(obj))
obj = i915_gem_object_create_shmem(engine->i915, context_size);
if (IS_ERR(obj))
diff --git a/drivers/gpu/drm/i915/gt/intel_ring.c 
b/drivers/gpu/drm/i915/gt/intel_ring.c
index 7c4d5158e03b..2fdd52b62092 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring.c
@@ -112,7 +112,8 @@ static struct i915_vma *create_ring_vma(struct i915_ggtt 
*ggtt, int size)
struct drm_i915_gem_object *obj;
struct i915_vma *vma;
 
-   obj = i915_gem_object_create_lmem(i915, size, I915_BO_ALLOC_VOLATILE);
+   obj = i915_gem_object_create_lmem(i915, size, I915_BO_ALLOC_VOLATILE |
+ I915_BO_ALLOC_PM_VOLATILE);
if (IS_ERR(obj) && i915_ggtt_has_aperture(ggtt))
obj = i915_gem_object_create_stolen(i915, size);
if (IS_ERR(obj))
-- 
2.31.1



[PATCH v5 3/7] drm/i915/gt: Increase suspend timeout

2021-09-21 Thread Thomas Hellström
With GuC submission on DG1, the execution of the requests times out
for the gem_exec_suspend igt test case after executing around 800-900
of 1000 submitted requests.

Given the time we allow elsewhere for fences to signal (in the order of
seconds), increase the timeout before we mark the gt wedged and proceed.

Signed-off-by: Thomas Hellström 
---
 drivers/gpu/drm/i915/gt/intel_gt_pm.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c 
b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index dea8e2479897..f84f2bfe2de0 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -19,6 +19,8 @@
 #include "intel_rps.h"
 #include "intel_wakeref.h"
 
+#define I915_GT_SUSPEND_IDLE_TIMEOUT (HZ / 2)
+
 static void user_forcewake(struct intel_gt *gt, bool suspend)
 {
int count = atomic_read(>->user_wakeref);
@@ -279,7 +281,7 @@ static void wait_for_suspend(struct intel_gt *gt)
if (!intel_gt_pm_is_awake(gt))
return;
 
-   if (intel_gt_wait_for_idle(gt, I915_GEM_IDLE_TIMEOUT) == -ETIME) {
+   if (intel_gt_wait_for_idle(gt, I915_GT_SUSPEND_IDLE_TIMEOUT) == -ETIME) 
{
/*
 * Forcibly cancel outstanding work and leave
 * the gpu quiet.
-- 
2.31.1



[PATCH v5 2/7] drm/i915/gem: Implement a function to process all gem objects of a region

2021-09-21 Thread Thomas Hellström
An upcoming common pattern is to traverse the region object list and
perform certain actions on all objects in a region. It's a little tricky
to get the list locking right, in particular since a gem object may
change region unless it's pinned or the object lock is held.

Define a function that does this for us and that takes an argument that
defines the action to be performed on each object.

v3:
- Improve structure documentation a bit (Matthew Auld)

Signed-off-by: Thomas Hellström 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_region.c | 70 ++
 drivers/gpu/drm/i915/gem/i915_gem_region.h | 37 
 2 files changed, 107 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c 
b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index 1f557b2178ed..a016ccec36f3 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -80,3 +80,73 @@ i915_gem_object_create_region(struct intel_memory_region 
*mem,
i915_gem_object_free(obj);
return ERR_PTR(err);
 }
+
+/**
+ * i915_gem_process_region - Iterate over all objects of a region using ops
+ * to process and optionally skip objects
+ * @mr: The memory region
+ * @apply: ops and private data
+ *
+ * This function can be used to iterate over the regions object list,
+ * checking whether to skip objects, and, if not, lock the objects and
+ * process them using the supplied ops. Note that this function temporarily
+ * removes objects from the region list while iterating, so that if run
+ * concurrently with itself may not iterate over all objects.
+ *
+ * Return: 0 if successful, negative error code on failure.
+ */
+int i915_gem_process_region(struct intel_memory_region *mr,
+   struct i915_gem_apply_to_region *apply)
+{
+   const struct i915_gem_apply_to_region_ops *ops = apply->ops;
+   struct drm_i915_gem_object *obj;
+   struct list_head still_in_list;
+   int ret = 0;
+
+   /*
+* In the future, a non-NULL apply->ww could mean the caller is
+* already in a locking transaction and provides its own context.
+*/
+   GEM_WARN_ON(apply->ww);
+
+   INIT_LIST_HEAD(&still_in_list);
+   mutex_lock(&mr->objects.lock);
+   for (;;) {
+   struct i915_gem_ww_ctx ww;
+
+   obj = list_first_entry_or_null(&mr->objects.list, typeof(*obj),
+  mm.region_link);
+   if (!obj)
+   break;
+
+   list_move_tail(&obj->mm.region_link, &still_in_list);
+   if (!kref_get_unless_zero(&obj->base.refcount))
+   continue;
+
+   /*
+* Note: Someone else might be migrating the object at this
+* point. The object's region is not stable until we lock
+* the object.
+*/
+   mutex_unlock(&mr->objects.lock);
+   apply->ww = &ww;
+   for_i915_gem_ww(&ww, ret, apply->interruptible) {
+   ret = i915_gem_object_lock(obj, apply->ww);
+   if (ret)
+   continue;
+
+   if (obj->mm.region == mr)
+   ret = ops->process_obj(apply, obj);
+   /* Implicit object unlock */
+   }
+
+   i915_gem_object_put(obj);
+   mutex_lock(&mr->objects.lock);
+   if (ret)
+   break;
+   }
+   list_splice_tail(&still_in_list, &mr->objects.list);
+   mutex_unlock(&mr->objects.lock);
+
+   return ret;
+}
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.h 
b/drivers/gpu/drm/i915/gem/i915_gem_region.h
index 1008e580a89a..fcaa12d657d4 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.h
@@ -12,6 +12,41 @@ struct intel_memory_region;
 struct drm_i915_gem_object;
 struct sg_table;
 
+struct i915_gem_apply_to_region;
+
+/**
+ * struct i915_gem_apply_to_region_ops - ops to use when iterating over all
+ * region objects.
+ */
+struct i915_gem_apply_to_region_ops {
+   /**
+* process_obj - Process the current object
+* @apply: Embed this for private data.
+* @obj: The current object.
+*
+* Note that if this function is part of a ww transaction, and
+* if returns -EDEADLK for one of the objects, it may be
+* rerun for that same object in the same pass.
+*/
+   int (*process_obj)(struct i915_gem_apply_to_region *apply,
+  struct drm_i915_gem_object *obj);
+};
+
+/**
+ * struct i915_gem_apply_to_region - Argument to the struct
+ * i915_gem_apply_to_region_ops functions.
+ * @ops: The ops for the operation.
+ * @ww: Locking context used for the transaction.
+ * @interruptible: Whether to perform object locking interruptible.
+ *
+ * 

[PATCH v5 4/7] drm/i915 Implement LMEM backup and restore for suspend / resume

2021-09-21 Thread Thomas Hellström
Just evict unpinned objects to system. For pinned LMEM objects,
make a backup system object and blit the contents to that.

Backup is performed in three steps,
1: Opportunistically evict evictable objects using the gpu blitter.
2: After gt idle, evict evictable objects using the gpu blitter. This will
be modified in an upcoming patch to backup pinned objects that are not used
by the blitter itself.
3: Backup remaining pinned objects using memcpy.

Also move uC suspend to after 2) to make sure we have a functional GuC
during 2) if using GuC submission.

v2:
- Major refactor to make sure gem_exec_suspend@hang-SX subtests work, and
  suspend / resume works with a slightly modified GuC submission enabling
  patch series.

v3:
- Fix a potential use-after-free (Matthew Auld)
- Use i915_gem_object_create_shmem() instead of
  i915_gem_object_create_region (Matthew Auld)
- Minor simplifications (Matthew Auld)
- Fix up kerneldoc for i195_ttm_restore_region().
- Final lmem_suspend() call moved to i915_gem_backup_suspend from
  i915_gem_suspend_late, since the latter gets called at driver unload
  and we don't unnecessarily want to run it at that time.

v4:
- Interface change of ttm- & lmem suspend / resume functions to use
  flags rather than bools. (Matthew Auld)
- Completely drop the i915_gem_backup_suspend change (Matthew Auld)

Signed-off-by: Thomas Hellström 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/Makefile |   1 +
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |   1 +
 drivers/gpu/drm/i915/gem/i915_gem_pm.c|  87 
 drivers/gpu/drm/i915/gem/i915_gem_pm.h|   1 +
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c   |  30 ++-
 drivers/gpu/drm/i915/gem/i915_gem_ttm.h   |  10 +
 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c| 202 ++
 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.h|  26 +++
 drivers/gpu/drm/i915/gt/intel_gt_pm.c |   4 +-
 drivers/gpu/drm/i915/i915_drv.c   |   4 +-
 10 files changed, 353 insertions(+), 13 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 335a8c668848..5c8e022a7383 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -154,6 +154,7 @@ gem-y += \
gem/i915_gem_throttle.o \
gem/i915_gem_tiling.o \
gem/i915_gem_ttm.o \
+   gem/i915_gem_ttm_pm.o \
gem/i915_gem_userptr.o \
gem/i915_gem_wait.o \
gem/i915_gemfs.o
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 2471f36aaff3..734cc8e16481 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -534,6 +534,7 @@ struct drm_i915_gem_object {
struct {
struct sg_table *cached_io_st;
struct i915_gem_object_page_iter get_io_page;
+   struct drm_i915_gem_object *backup;
bool created:1;
} ttm;
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
index 8b9d7d14c4bd..12b37b4c1192 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
@@ -5,6 +5,7 @@
  */
 
 #include "gem/i915_gem_pm.h"
+#include "gem/i915_gem_ttm_pm.h"
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_pm.h"
 #include "gt/intel_gt_requests.h"
@@ -39,6 +40,84 @@ void i915_gem_suspend(struct drm_i915_private *i915)
i915_gem_drain_freed_objects(i915);
 }
 
+static int lmem_restore(struct drm_i915_private *i915, u32 flags)
+{
+   struct intel_memory_region *mr;
+   int ret = 0, id;
+
+   for_each_memory_region(mr, i915, id) {
+   if (mr->type == INTEL_MEMORY_LOCAL) {
+   ret = i915_ttm_restore_region(mr, flags);
+   if (ret)
+   break;
+   }
+   }
+
+   return ret;
+}
+
+static int lmem_suspend(struct drm_i915_private *i915, u32 flags)
+{
+   struct intel_memory_region *mr;
+   int ret = 0, id;
+
+   for_each_memory_region(mr, i915, id) {
+   if (mr->type == INTEL_MEMORY_LOCAL) {
+   ret = i915_ttm_backup_region(mr, flags);
+   if (ret)
+   break;
+   }
+   }
+
+   return ret;
+}
+
+static void lmem_recover(struct drm_i915_private *i915)
+{
+   struct intel_memory_region *mr;
+   int id;
+
+   for_each_memory_region(mr, i915, id)
+   if (mr->type == INTEL_MEMORY_LOCAL)
+   i915_ttm_recover_region(mr);
+}
+
+int i915_gem_backup_suspend(struct drm_i915_private *i915)
+{
+   int ret;
+
+   /* Opportunistically try to evict unpinned objects */
+   ret = lmem_suspend(i915, I915_TTM_BACKUP_ALLOW_GPU

[PATCH v5 1/7] drm/i915/ttm: Implement a function to copy the contents of two TTM-based objects

2021-09-21 Thread Thomas Hellström
When backing up or restoring contents of pinned objects at suspend /
resume time we need to allocate a new object as the backup. Add a function
to facilitate copies between the two. Some data needs to be copied before
the migration context is ready for operation, so make sure we can
disable accelerated copies.

v2:
- Fix a missing return value check (Matthew Auld)

Signed-off-by: Thomas Hellström 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 69 +
 drivers/gpu/drm/i915/gem/i915_gem_ttm.h |  4 ++
 2 files changed, 64 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
index 2f672f06b169..22d59510d0c3 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -428,6 +428,7 @@ i915_ttm_resource_get_st(struct drm_i915_gem_object *obj,
 static int i915_ttm_accel_move(struct ttm_buffer_object *bo,
   bool clear,
   struct ttm_resource *dst_mem,
+  struct ttm_tt *dst_ttm,
   struct sg_table *dst_st)
 {
struct drm_i915_private *i915 = container_of(bo->bdev, typeof(*i915),
@@ -437,14 +438,14 @@ static int i915_ttm_accel_move(struct ttm_buffer_object 
*bo,
struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
struct sg_table *src_st;
struct i915_request *rq;
-   struct ttm_tt *ttm = bo->ttm;
+   struct ttm_tt *src_ttm = bo->ttm;
enum i915_cache_level src_level, dst_level;
int ret;
 
if (!i915->gt.migrate.context)
return -EINVAL;
 
-   dst_level = i915_ttm_cache_level(i915, dst_mem, ttm);
+   dst_level = i915_ttm_cache_level(i915, dst_mem, dst_ttm);
if (clear) {
if (bo->type == ttm_bo_type_kernel)
return -EINVAL;
@@ -461,10 +462,10 @@ static int i915_ttm_accel_move(struct ttm_buffer_object 
*bo,
}
intel_engine_pm_put(i915->gt.migrate.context->engine);
} else {
-   src_st = src_man->use_tt ? i915_ttm_tt_get_st(ttm) :
+   src_st = src_man->use_tt ? i915_ttm_tt_get_st(src_ttm) :
obj->ttm.cached_io_st;
 
-   src_level = i915_ttm_cache_level(i915, bo->resource, ttm);
+   src_level = i915_ttm_cache_level(i915, bo->resource, src_ttm);
intel_engine_pm_get(i915->gt.migrate.context->engine);
ret = intel_context_migrate_copy(i915->gt.migrate.context,
 NULL, src_st->sgl, src_level,
@@ -484,11 +485,14 @@ static int i915_ttm_accel_move(struct ttm_buffer_object 
*bo,
 
 static void __i915_ttm_move(struct ttm_buffer_object *bo, bool clear,
struct ttm_resource *dst_mem,
-   struct sg_table *dst_st)
+   struct ttm_tt *dst_ttm,
+   struct sg_table *dst_st,
+   bool allow_accel)
 {
-   int ret;
+   int ret = -EINVAL;
 
-   ret = i915_ttm_accel_move(bo, clear, dst_mem, dst_st);
+   if (allow_accel)
+   ret = i915_ttm_accel_move(bo, clear, dst_mem, dst_ttm, dst_st);
if (ret) {
struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
struct intel_memory_region *dst_reg, *src_reg;
@@ -503,7 +507,7 @@ static void __i915_ttm_move(struct ttm_buffer_object *bo, 
bool clear,
GEM_BUG_ON(!dst_reg || !src_reg);
 
dst_iter = !cpu_maps_iomem(dst_mem) ?
-   ttm_kmap_iter_tt_init(&_dst_iter.tt, bo->ttm) :
+   ttm_kmap_iter_tt_init(&_dst_iter.tt, dst_ttm) :
ttm_kmap_iter_iomap_init(&_dst_iter.io, &dst_reg->iomap,
 dst_st, dst_reg->region.start);
 
@@ -558,7 +562,7 @@ static int i915_ttm_move(struct ttm_buffer_object *bo, bool 
evict,
 
clear = !cpu_maps_iomem(bo->resource) && (!ttm || 
!ttm_tt_is_populated(ttm));
if (!(clear && ttm && !(ttm->page_flags & TTM_PAGE_FLAG_ZERO_ALLOC)))
-   __i915_ttm_move(bo, clear, dst_mem, dst_st);
+   __i915_ttm_move(bo, clear, dst_mem, bo->ttm, dst_st, true);
 
ttm_bo_move_sync_cleanup(bo, dst_mem);
i915_ttm_adjust_domains_after_move(obj);
@@ -973,3 +977,50 @@ i915_gem_ttm_system_setup(struct drm_i915_private *i915,
intel_memory_region_set_name(mr, "system-ttm");
return mr;
 }
+
+/**
+ * i915_gem_obj_copy_ttm - Copy the contents of one ttm-based gem object to
+ * another
+ * @dst: The destination object
+ * @src: The source object
+ * @allow_accel: Allow using the blitter. Otherwise TTM memcpy is used.
+ * @intr: Whether to perform waits interruptible:
+ *
+ * Note: The caller is responsible for assuring that the underlyin

[PATCH v5 0/7] drm/i915: Suspend / resume backup- and restore of LMEM.

2021-09-21 Thread Thomas Hellström
Implement backup and restore of LMEM during suspend / resume.
What complicates things a bit is handling of pinned LMEM memory during
suspend and the fact that we might be dealing with unmappable LMEM in
the future, which makes us want to restrict the number of pinned objects that
need memcpy resume.

The first two patches are prereq patches implementing object content copy
and a generic means of iterating through all objects in a region.
The third patch adds the backup / recover / restore functions and the
two last patches deal with restricting the number of objects we need to
use memcpy for.

v2:
- Some polishing of patch 4/6, see patch commit message for details (Chris
  Wilson)
- Rework of patch 3/6.

v3:
- Comment changes in patch 2/6 (Matthew Auld)
- A number of changes to patch 3/6, see commit message.
- Slightly reword comment in patch 5/6. (Matthew Auld).

v4:
- Various cleanups, among other things reworking the ttm / lmem backup-
  and resume interfaces somewhat.

v5:
- GuC adaptations. Mark GuC LMEM objects for early resume and increase
  the suspend idle timeout.

Thomas Hellström (7):
  drm/i915/ttm: Implement a function to copy the contents of two
TTM-based objects
  drm/i915/gem: Implement a function to process all gem objects of a
region
  drm/i915/gt: Increase suspend timeout
  drm/i915 Implement LMEM backup and restore for suspend / resume
  drm/i915/gt: Register the migrate contexts with their engines
  drm/i915: Don't back up pinned LMEM context images and rings during
suspend
  drm/i915: Reduce the number of objects subject to memcpy recover

 drivers/gpu/drm/i915/Makefile |   1 +
 drivers/gpu/drm/i915/gem/i915_gem_context.c   |   4 +-
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  21 +-
 drivers/gpu/drm/i915/gem/i915_gem_pm.c|  91 
 drivers/gpu/drm/i915/gem/i915_gem_pm.h|   1 +
 drivers/gpu/drm/i915/gem/i915_gem_region.c|  70 ++
 drivers/gpu/drm/i915/gem/i915_gem_region.h|  37 
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c   |  99 +++--
 drivers/gpu/drm/i915/gem/i915_gem_ttm.h   |  14 ++
 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c| 206 ++
 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.h|  26 +++
 .../gpu/drm/i915/gem/selftests/huge_pages.c   |   2 +-
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c  |   2 +-
 drivers/gpu/drm/i915/gt/gen8_ppgtt.c  |   5 +-
 drivers/gpu/drm/i915/gt/gen8_ppgtt.h  |   4 +-
 drivers/gpu/drm/i915/gt/intel_context_types.h |   8 +
 drivers/gpu/drm/i915/gt/intel_engine_cs.c |   4 +
 drivers/gpu/drm/i915/gt/intel_engine_pm.c |  23 ++
 drivers/gpu/drm/i915/gt/intel_engine_pm.h |   2 +
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |   7 +
 .../drm/i915/gt/intel_execlists_submission.c  |   2 +
 drivers/gpu/drm/i915/gt/intel_ggtt.c  |   3 +-
 drivers/gpu/drm/i915/gt/intel_gt.c|   2 +-
 drivers/gpu/drm/i915/gt/intel_gt_pm.c |   8 +-
 drivers/gpu/drm/i915/gt/intel_gtt.c   |   3 +-
 drivers/gpu/drm/i915/gt/intel_gtt.h   |   9 +-
 drivers/gpu/drm/i915/gt/intel_lrc.c   |   3 +-
 drivers/gpu/drm/i915/gt/intel_migrate.c   |   2 +-
 drivers/gpu/drm/i915/gt/intel_ppgtt.c |  13 +-
 drivers/gpu/drm/i915/gt/intel_ring.c  |   3 +-
 .../gpu/drm/i915/gt/intel_ring_submission.c   |   3 +
 drivers/gpu/drm/i915/gt/mock_engine.c |   2 +
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c  |   2 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|   3 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  12 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  |   7 +-
 drivers/gpu/drm/i915/gvt/scheduler.c  |   2 +-
 drivers/gpu/drm/i915/i915_drv.c   |   4 +-
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |   4 +-
 39 files changed, 654 insertions(+), 60 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.h

-- 
2.31.1



[PATCH] drm/i915: fix blank screen booting crashes

2021-09-21 Thread Matthew Brost
From: Hugh Dickins 

5.15-rc1 crashes with blank screen when booting up on two ThinkPads
using i915.  Bisections converge convincingly, but arrive at different
and surprising "culprits", none of them the actual culprit.

netconsole (with init_netconsole() hacked to call i915_init() when
logging has started, instead of by module_init()) tells the story:

kernel BUG at drivers/gpu/drm/i915/i915_sw_fence.c:245!
with RSI: 814d408b pointing to sw_fence_dummy_notify().
I've been building with CONFIG_CC_OPTIMIZE_FOR_SIZE=y, and that
function needs to be 4-byte aligned.

v2:
 (Jani Nikula)
  - Change BUG_ON to WARN_ON
v3:
 (Jani / Tvrtko)
  - Short circuit __i915_sw_fence_init on WARN_ON

Fixes: 62eaf0ae217d ("drm/i915/guc: Support request cancellation")
Signed-off-by: Hugh Dickins 
Signed-off-by: Matthew Brost 
Reviewed-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/intel_context.c |  4 ++--
 drivers/gpu/drm/i915/i915_sw_fence.c| 17 ++---
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index ff637147b1a9..e7f78bc7ebfc 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -362,8 +362,8 @@ static int __intel_context_active(struct i915_active 
*active)
return 0;
 }
 
-static int sw_fence_dummy_notify(struct i915_sw_fence *sf,
-enum i915_sw_fence_notify state)
+static int __i915_sw_fence_call
+sw_fence_dummy_notify(struct i915_sw_fence *sf, enum i915_sw_fence_notify 
state)
 {
return NOTIFY_DONE;
 }
diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c 
b/drivers/gpu/drm/i915/i915_sw_fence.c
index c589a681da77..08cea73264e7 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence.c
+++ b/drivers/gpu/drm/i915/i915_sw_fence.c
@@ -13,9 +13,9 @@
 #include "i915_selftest.h"
 
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG)
-#define I915_SW_FENCE_BUG_ON(expr) BUG_ON(expr)
+#define I915_SW_FENCE_WARN_ON(expr) WARN_ON(expr)
 #else
-#define I915_SW_FENCE_BUG_ON(expr) BUILD_BUG_ON_INVALID(expr)
+#define I915_SW_FENCE_WARN_ON(expr) BUILD_BUG_ON_INVALID(expr)
 #endif
 
 static DEFINE_SPINLOCK(i915_sw_fence_lock);
@@ -129,7 +129,10 @@ static int __i915_sw_fence_notify(struct i915_sw_fence 
*fence,
i915_sw_fence_notify_t fn;
 
fn = (i915_sw_fence_notify_t)(fence->flags & I915_SW_FENCE_MASK);
-   return fn(fence, state);
+   if (likely(fn))
+   return fn(fence, state);
+   else
+   return 0;
 }
 
 #ifdef CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS
@@ -242,9 +245,9 @@ void __i915_sw_fence_init(struct i915_sw_fence *fence,
  const char *name,
  struct lock_class_key *key)
 {
-   BUG_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK);
-
__init_waitqueue_head(&fence->wait, name, key);
+   if (WARN_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK))
+   return;
fence->flags = (unsigned long)fn;
 
i915_sw_fence_reinit(fence);
@@ -257,8 +260,8 @@ void i915_sw_fence_reinit(struct i915_sw_fence *fence)
atomic_set(&fence->pending, 1);
fence->error = 0;
 
-   I915_SW_FENCE_BUG_ON(!fence->flags);
-   I915_SW_FENCE_BUG_ON(!list_empty(&fence->wait.head));
+   I915_SW_FENCE_WARN_ON(!fence->flags);
+   I915_SW_FENCE_WARN_ON(!list_empty(&fence->wait.head));
 }
 
 void i915_sw_fence_commit(struct i915_sw_fence *fence)
-- 
2.32.0



Re: [PATCH v3 5/8] x86/sme: Replace occurrences of sme_active() with cc_platform_has()

2021-09-21 Thread Borislav Petkov
On Tue, Sep 21, 2021 at 12:04:58PM -0500, Tom Lendacky wrote:
> Looks like instrumentation during early boot. I worked with Boris offline to
> exclude arch/x86/kernel/cc_platform.c from some of the instrumentation and
> that allowed an allyesconfig to boot.

And here's the lineup I have so far, I'd appreciate it if ppc and s390 folks
could run it too:

https://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git/log/?h=rc2-cc

Thx.

-- 
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette


Re: [Freedreno] [PATCH] drm/msm/dsi: do not install irq handler before power up the host

2021-09-21 Thread Dmitry Baryshkov
Hi,

On Tue, 21 Sept 2021 at 20:01,  wrote:
>
> On 2021-09-21 09:22, Dmitry Baryshkov wrote:
> > The DSI host might be left in some state by the bootloader. If this
> > state generates an IRQ, it might hang the system by holding the
> > interrupt line before the driver sets up the DSI host to the known
> > state.
> >
> > Move the request/free_irq calls into msm_dsi_host_power_on/_off calls,
> > so that we can be sure that the interrupt is delivered when the host is
> > in the known state.
> >
> > Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support")
> > Signed-off-by: Dmitry Baryshkov 
>
> This is a valid change and we have seen interrupt storms in downstream
> happening
> when like you said the bootloader leaves the DSI host in unknown state.
> Just one question below.
>
> > ---
> >  drivers/gpu/drm/msm/dsi/dsi_host.c | 21 -
> >  1 file changed, 12 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
> > b/drivers/gpu/drm/msm/dsi/dsi_host.c
> > index e269df285136..cd842347a6b1 100644
> > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> > @@ -1951,15 +1951,6 @@ int msm_dsi_host_modeset_init(struct
> > mipi_dsi_host *host,
> >   return ret;
> >   }
> >
> > - ret = devm_request_irq(&pdev->dev, msm_host->irq,
> > - dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> > - "dsi_isr", msm_host);
> > - if (ret < 0) {
> > - DRM_DEV_ERROR(&pdev->dev, "failed to request IRQ%u: %d\n",
> > - msm_host->irq, ret);
> > - return ret;
> > - }
> > -
> >   msm_host->dev = dev;
> >   ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
> >   if (ret) {
> > @@ -2413,6 +2404,16 @@ int msm_dsi_host_power_on(struct mipi_dsi_host
> > *host,
> >   if (msm_host->disp_en_gpio)
> >   gpiod_set_value(msm_host->disp_en_gpio, 1);
> >
> > + ret = devm_request_irq(&msm_host->pdev->dev, msm_host->irq,
> > + dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> > + "dsi_isr", msm_host);
> > + if (ret < 0) {
> > + DRM_DEV_ERROR(&msm_host->pdev->dev, "failed to request IRQ%u: 
> > %d\n",
> > + msm_host->irq, ret);
> > + return ret;
> > + }
> > +
> > +
>
> Do you want to move this to msm_dsi_host_enable()?
> So without the controller being enabled it is still in unknown state?

msm_dsi_host_power_on() reconfigures the host registers, so the state
is known at the end of the power_on().

> Also do you want to do this after dsi0 and dsi1 are initialized to
> account for
> dual dsi cases?

I don't think this should matter. The host won't generate 'extra'
interrupts in such case, will it?

>
> >   msm_host->power_on = true;
> >   mutex_unlock(&msm_host->dev_mutex);
> >
> > @@ -2439,6 +2440,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host
> > *host)
> >   goto unlock_ret;
> >   }
> >
> > + devm_free_irq(&msm_host->pdev->dev, msm_host->irq, msm_host);
> > +
> >   dsi_ctrl_config(msm_host, false, NULL, NULL);
> >
> >   if (msm_host->disp_en_gpio)



-- 
With best wishes
Dmitry


Re: [RFC PATCH] component: do not leave master devres group open after bind

2021-09-21 Thread Imre Deak
On Tue, Sep 21, 2021 at 02:18:10PM +0300, Kai Vehmanen wrote:
> In current code, the devres group for aggregate master is left open
> after call to component_master_add_*(). This leads to problems when the
> master does further managed allocations on its own. When any
> participating driver calls component_del(), this leads to immediate
> release of resources.
> 
> This came up when investigating a page fault occurring with i915 DRM
> driver unbind with 5.15-rc1 kernel. The following sequence occurs:
> 
>  i915_pci_remove()
>-> intel_display_driver_unregister()
>  -> i915_audio_component_cleanup()
>-> component_del()
>  -> component.c:take_down_master()
>-> hdac_component_master_unbind() [via master->ops->unbind()]
>-> devres_release_group(master->parent, NULL)
> 
> With older kernels this has not caused issues, but with audio driver
> moving to use managed interfaces for more of its allocations, this no
> longer works. Devres log shows following to occur:
> 
> component_master_add_with_match()
> [  126.886032] snd_hda_intel :00:1f.3: DEVRES ADD 323ccdc5 
> devm_component_match_release (24 bytes)
> [  126.886045] snd_hda_intel :00:1f.3: DEVRES ADD 865cdb29 grp< 
> (0 bytes)
> [  126.886049] snd_hda_intel :00:1f.3: DEVRES ADD 1b480725 grp< 
> (0 bytes)
> 
> audio driver completes its PCI probe()
> [  126.892238] snd_hda_intel :00:1f.3: DEVRES ADD 1b480725 
> pcim_iomap_release (48 bytes)
> 
> component_del() called() at DRM/i915 unbind()
> [  137.579422] i915 :00:02.0: DEVRES REL ef44c293 grp< (0 bytes)
> [  137.579445] snd_hda_intel :00:1f.3: DEVRES REL 865cdb29 grp< 
> (0 bytes)
> [  137.579458] snd_hda_intel :00:1f.3: DEVRES REL 1b480725 
> pcim_iomap_release (48 bytes)
> 
> So the "devres_release_group(master->parent, NULL)" ends up freeing the
> pcim_iomap allocation. Upon next runtime resume, the audio driver will
> cause a page fault as the iomap alloc was released without the driver
> knowing about it.
> 
> Fix this issue by using the "struct master" pointer as identifier for
> the devres group, and by closing the devres group after the 
> master->ops->bind()
> call is done. This allows devres allocations done by the driver acting as
> master to be isolated from the binding state of the aggregate driver. This
> modifies the logic originally introduced in commit 9e1ccb4a7700
> ("drivers/base: fix devres handling for master device").
> 
> BugLink: https://gitlab.freedesktop.org/drm/intel/-/issues/4136
> Signed-off-by: Kai Vehmanen 

This makes sense to me and also seems to match the devres logic for
component binding (component_bind()), where the only resources freed at
unbind (or at bind failure) are those that were allocated in the
components' bind hook. Any resource allocated later by the components
are not affected by the unbinding:

Acked-by: Imre Deak 

If for some reason the current behaviour was intentional, one
alternative I can think of would be for audio to register itself with the
component framework using a dedicated kdev object.

Imo the component framework's devres semantics would need to be
documented as well.

> ---
>  drivers/base/component.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> Hi,
> I'm sending this as RFC as I'm not sure of the implications of
> not leaving the devres group open might have to other users
> of the component framework.
> 
> For audio, the current behaviour seems very problematic. The display
> codec is usually just one of many audio codecs attached to the controller,
> and unbind of the display codec (and the aggregate driver created with
> DRM), should not bring down the whole audio card.
> 
> However, now all allocations audio driver does after call to
> component_master_add_with_match(), will be freed when display
> driver calls component_del().
> 
> Closing the devres group at end of component_master_add_*() would
> seem the cleanest option. Looking for feedback whether this approach
> is feasible. One alternative would be for the audio driver to
> close the "last opened" group after its call to component_master_add(),
> but this seems messy (audio would make assumptions on component.c
> internals).
> 
> diff --git a/drivers/base/component.c b/drivers/base/component.c
> index 5e79299f6c3f..870485cbbb87 100644
> --- a/drivers/base/component.c
> +++ b/drivers/base/component.c
> @@ -246,7 +246,7 @@ static int try_to_bring_up_master(struct master *master,
>   return 0;
>   }
>  
> - if (!devres_open_group(master->parent, NULL, GFP_KERNEL))
> + if (!devres_open_group(master->parent, master, GFP_KERNEL))
>   return -ENOMEM;
>  
>   /* Found all components */
> @@ -258,6 +258,7 @@ static int try_to_bring_up_master(struct master *master,
>   return ret;
>   }
>  
> + devres_close_group(master->parent, NULL);
>   master->bound = true;
>   return 

[Bug 211277] sometimes crash at s2ram-wake (Ryzen 3500U): amdgpu, drm, commit_tail, amdgpu_dm_atomic_commit_tail

2021-09-21 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=211277

--- Comment #69 from youling...@gmail.com ---
(In reply to James Zhu from comment #67)
> (In reply to youling257 from comment #66)
> > resume failed record video,
> > https://drive.google.com/drive/folders/1bWMC4ByGvudC9zBk-9Xgamz-
> > shir0pqX?usp=sharing
> 
> Can you try apply this patch: 
> https://lore.kernel.org/all/20210920163922.313113...@linuxfoundation.org/?

linux kernel 5.15rc1 is good, suspend to disk resume success.
linux kernel 5.15rc2 is bad, suspend to disk failed.
revert "drm/amdgpu: move iommu_resume before ip init/resume" can suspend to
disk resume success.

linux kernel 5.15rc2 has "drm/amdkfd: separate kfd_iommu_resume from
kfd_resume", why you suggest me apply the patch

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

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

[Bug 211277] sometimes crash at s2ram-wake (Ryzen 3500U): amdgpu, drm, commit_tail, amdgpu_dm_atomic_commit_tail

2021-09-21 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=211277

--- Comment #68 from youling...@gmail.com ---
(In reply to James Zhu from comment #67)
> (In reply to youling257 from comment #66)
> > resume failed record video,
> > https://drive.google.com/drive/folders/1bWMC4ByGvudC9zBk-9Xgamz-
> > shir0pqX?usp=sharing
> 
> Can you try apply this patch: 
> https://lore.kernel.org/all/20210920163922.313113...@linuxfoundation.org/?

linux kernel 5.15rc1 is good, suspend to disk resume success.
linux kernel 5.15rc2 is bad, suspend to disk failed.
revert "drm/amdgpu: move iommu_resume before ip init/resume" can suspend to
disk resume success.

linux kernel 5.15rc2 has "drm/amdkfd: separate kfd_iommu_resume from
kfd_resume", why you suggest me apply the patch

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

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

Re: [PATCH v2 2/2] dt-bindings: display: Add binding for LG.Philips SW43101

2021-09-21 Thread Rob Herring
On Thu, 09 Sep 2021 04:40:27 +, Yassine Oudjana wrote:
> Add a device tree binding for LG.Philips SW43101.
> 
> Signed-off-by: Yassine Oudjana 
> ---
> Changes since v1:
>  - Add regulator support.
>  - Add MAINTAINERS entry.
>  - Dual-license DT binding.
> 
>  .../display/panel/lgphilips,sw43101.yaml  | 75 +++
>  MAINTAINERS   |  1 +
>  2 files changed, 76 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/panel/lgphilips,sw43101.yaml
> 

Reviewed-by: Rob Herring 


Re: [PATCH v2 5/6] drm/i915/uncore: Drop gen11 mmio read handlers

2021-09-21 Thread Lucas De Marchi

On Fri, Sep 10, 2021 at 01:10:29PM -0700, Matt Roper wrote:

Consolidate down to just a single 'fwtable' implementation.  For reads
we don't need to worry about shadow tables.  Also, the
NEEDS_FORCE_WAKE() check we previously had in the fwtable implementation
can be dropped --- if a register is outside that range on one of the old
platforms, then it won't belong to any forcewake range and 0 will be
returned anyway.

v2:
- Restore NEEDS_FORCE_WAKE() check.  (Chris, Tvrtko)

Cc: Chris Wilson 
Cc: Tvrtko Ursulin 
Signed-off-by: Matt Roper 
---
drivers/gpu/drm/i915/intel_uncore.c | 40 -
1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
b/drivers/gpu/drm/i915/intel_uncore.c
index bfb2a6337f9d..10f124297e7c 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -935,9 +935,6 @@ static const struct intel_forcewake_range __vlv_fw_ranges[] 
= {
__fwd; \
})

-#define __gen11_fwtable_reg_read_fw_domains(uncore, offset) \
-   find_fw_domain(uncore, offset)
-
/* *Must* be sorted by offset! See intel_shadow_table_check(). */
static const struct i915_range gen8_shadowed_regs[] = {
{ .start =  0x2030, .end =  0x2030 },
@@ -1570,33 +1567,30 @@ static inline void __force_wake_auto(struct 
intel_uncore *uncore,
___force_wake_auto(uncore, fw_domains);
}

-#define __gen_read(func, x) \
+#define __gen_fwtable_read(x) \
static u##x \
-func##_read##x(struct intel_uncore *uncore, i915_reg_t reg, bool trace) { \
+fwtable_read##x(struct intel_uncore *uncore, i915_reg_t reg, bool trace) \
+{ \
enum forcewake_domains fw_engine; \
GEN6_READ_HEADER(x); \
-   fw_engine = __##func##_reg_read_fw_domains(uncore, offset); \
+   fw_engine = __fwtable_reg_read_fw_domains(uncore, offset); \
if (fw_engine) \
__force_wake_auto(uncore, fw_engine); \
val = __raw_uncore_read##x(uncore, reg); \
GEN6_READ_FOOTER; \
}

-#define __gen_reg_read_funcs(func) \
-static enum forcewake_domains \
-func##_reg_read_fw_domains(struct intel_uncore *uncore, i915_reg_t reg) { \
-   return __##func##_reg_read_fw_domains(uncore, 
i915_mmio_reg_offset(reg)); \
-} \
-\
-__gen_read(func, 8) \
-__gen_read(func, 16) \
-__gen_read(func, 32) \
-__gen_read(func, 64)
+static enum forcewake_domains
+fwtable_reg_read_fw_domains(struct intel_uncore *uncore, i915_reg_t reg) {
+   return __fwtable_reg_read_fw_domains(uncore, i915_mmio_reg_offset(reg));
+}

-__gen_reg_read_funcs(gen11_fwtable);
-__gen_reg_read_funcs(fwtable);
+__gen_fwtable_read(8)
+__gen_fwtable_read(16)
+__gen_fwtable_read(32)
+__gen_fwtable_read(64)

-#undef __gen_reg_read_funcs
+#undef __gen_fwtable_read
#undef GEN6_READ_FOOTER
#undef GEN6_READ_HEADER

@@ -2062,22 +2056,22 @@ static int uncore_forcewake_init(struct intel_uncore 
*uncore)
ASSIGN_FW_DOMAINS_TABLE(uncore, __dg2_fw_ranges);
ASSIGN_SHADOW_TABLE(uncore, gen12_shadowed_regs);
ASSIGN_WRITE_MMIO_VFUNCS(uncore, fwtable);
-   ASSIGN_READ_MMIO_VFUNCS(uncore, gen11_fwtable);
+   ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable);
} else if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50)) {
ASSIGN_FW_DOMAINS_TABLE(uncore, __xehp_fw_ranges);
ASSIGN_SHADOW_TABLE(uncore, gen12_shadowed_regs);
ASSIGN_WRITE_MMIO_VFUNCS(uncore, fwtable);
-   ASSIGN_READ_MMIO_VFUNCS(uncore, gen11_fwtable);
+   ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable);
} else if (GRAPHICS_VER(i915) >= 12) {
ASSIGN_FW_DOMAINS_TABLE(uncore, __gen12_fw_ranges);
ASSIGN_SHADOW_TABLE(uncore, gen12_shadowed_regs);
ASSIGN_WRITE_MMIO_VFUNCS(uncore, fwtable);
-   ASSIGN_READ_MMIO_VFUNCS(uncore, gen11_fwtable);
+   ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable);
} else if (GRAPHICS_VER(i915) == 11) {
ASSIGN_FW_DOMAINS_TABLE(uncore, __gen11_fw_ranges);
ASSIGN_SHADOW_TABLE(uncore, gen11_shadowed_regs);
ASSIGN_WRITE_MMIO_VFUNCS(uncore, fwtable);
-   ASSIGN_READ_MMIO_VFUNCS(uncore, gen11_fwtable);
+   ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable);


these together with patch 1 make the fwtable variant be the only one
used for reads so, should we pull these assignments out of if/else
chain? gen < 6 don't have forcewake so afaics we cover all the
platforms.

this can be done as a separate patch though.


Reviewed-by: Lucas De Marchi 

Lucas De Marchi


} else if (IS_GRAPHICS_VER(i915, 9, 10)) {
ASSIGN_FW_DOMAINS_TABLE(uncore, __gen9_fw_ranges);
ASSIGN_SHADOW_TABLE(uncore, gen8_shadowed_regs);
--
2.25.4



[PATCH 23/26] drm/nouveau: use the new interator in nv50_wndw_prepare_fb

2021-09-21 Thread Christian König
Makes the handling a bit more complex, but avoids the use of
dma_resv_get_excl_unlocked().

Signed-off-by: Christian König 
---
 drivers/gpu/drm/nouveau/dispnv50/wndw.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c 
b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
index 8d048bacd6f0..30712a681e2a 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
@@ -539,6 +539,8 @@ nv50_wndw_prepare_fb(struct drm_plane *plane, struct 
drm_plane_state *state)
struct nouveau_bo *nvbo;
struct nv50_head_atom *asyh;
struct nv50_wndw_ctxdma *ctxdma;
+   struct dma_resv_iter cursor;
+   struct dma_fence *fence;
int ret;
 
NV_ATOMIC(drm, "%s prepare: %p\n", plane->name, fb);
@@ -561,7 +563,13 @@ nv50_wndw_prepare_fb(struct drm_plane *plane, struct 
drm_plane_state *state)
asyw->image.handle[0] = ctxdma->object.handle;
}
 
-   asyw->state.fence = dma_resv_get_excl_unlocked(nvbo->bo.base.resv);
+   dma_resv_iter_begin(&cursor, nvbo->bo.base.resv, false);
+   dma_resv_for_each_fence_unlocked(&cursor, fence) {
+   /* TODO: We only use the first writer here */
+   asyw->state.fence = dma_fence_get(fence);
+   break;
+   }
+   dma_resv_iter_end(&cursor);
asyw->image.offset[0] = nvbo->offset;
 
if (wndw->func->prepare) {
-- 
2.25.1



[PATCH 22/26] drm/nouveau: use the new iterator in nouveau_fence_sync

2021-09-21 Thread Christian König
Simplifying the code a bit.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/nouveau/nouveau_fence.c | 48 +++--
 1 file changed, 12 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c 
b/drivers/gpu/drm/nouveau/nouveau_fence.c
index 05d0b3eb3690..26f9299df881 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -339,14 +339,15 @@ nouveau_fence_wait(struct nouveau_fence *fence, bool 
lazy, bool intr)
 }
 
 int
-nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan, bool 
exclusive, bool intr)
+nouveau_fence_sync(struct nouveau_bo *nvbo, struct nouveau_channel *chan,
+  bool exclusive, bool intr)
 {
struct nouveau_fence_chan *fctx = chan->fence;
-   struct dma_fence *fence;
struct dma_resv *resv = nvbo->bo.base.resv;
-   struct dma_resv_list *fobj;
+   struct dma_resv_iter cursor;
+   struct dma_fence *fence;
struct nouveau_fence *f;
-   int ret = 0, i;
+   int ret;
 
if (!exclusive) {
ret = dma_resv_reserve_shared(resv, 1);
@@ -355,10 +356,7 @@ nouveau_fence_sync(struct nouveau_bo *nvbo, struct 
nouveau_channel *chan, bool e
return ret;
}
 
-   fobj = dma_resv_shared_list(resv);
-   fence = dma_resv_excl_fence(resv);
-
-   if (fence) {
+   dma_resv_for_each_fence(&cursor, resv, exclusive, fence) {
struct nouveau_channel *prev = NULL;
bool must_wait = true;
 
@@ -366,41 +364,19 @@ nouveau_fence_sync(struct nouveau_bo *nvbo, struct 
nouveau_channel *chan, bool e
if (f) {
rcu_read_lock();
prev = rcu_dereference(f->channel);
-   if (prev && (prev == chan || fctx->sync(f, prev, chan) 
== 0))
+   if (prev && (prev == chan ||
+fctx->sync(f, prev, chan) == 0))
must_wait = false;
rcu_read_unlock();
}
 
-   if (must_wait)
+   if (must_wait) {
ret = dma_fence_wait(fence, intr);
-
-   return ret;
-   }
-
-   if (!exclusive || !fobj)
-   return ret;
-
-   for (i = 0; i < fobj->shared_count && !ret; ++i) {
-   struct nouveau_channel *prev = NULL;
-   bool must_wait = true;
-
-   fence = rcu_dereference_protected(fobj->shared[i],
-   dma_resv_held(resv));
-
-   f = nouveau_local_fence(fence, chan->drm);
-   if (f) {
-   rcu_read_lock();
-   prev = rcu_dereference(f->channel);
-   if (prev && (prev == chan || fctx->sync(f, prev, chan) 
== 0))
-   must_wait = false;
-   rcu_read_unlock();
+   if (ret)
+   return ret;
}
-
-   if (must_wait)
-   ret = dma_fence_wait(fence, intr);
}
-
-   return ret;
+   return 0;
 }
 
 void
-- 
2.25.1



[PATCH 25/26] drm/etnaviv: replace dma_resv_get_excl_unlocked

2021-09-21 Thread Christian König
We certainly hold the reservation lock here, no need for the RCU dance.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c 
b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
index 4dd7d9d541c0..7e17bc2b5df1 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
@@ -195,7 +195,7 @@ static int submit_fence_sync(struct etnaviv_gem_submit 
*submit)
if (ret)
return ret;
} else {
-   bo->excl = dma_resv_get_excl_unlocked(robj);
+   bo->excl = dma_fence_get(dma_resv_excl_fence(robj));
}
 
}
-- 
2.25.1



[PATCH 18/26] drm/i915: use new iterator in i915_gem_object_last_write_engine

2021-09-21 Thread Christian König
This is maybe even a fix since the RCU usage here looks incorrect.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/i915/gem/i915_gem_object.h | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 48112b9d76df..e20efffce3a9 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -507,16 +507,16 @@ static inline struct intel_engine_cs *
 i915_gem_object_last_write_engine(struct drm_i915_gem_object *obj)
 {
struct intel_engine_cs *engine = NULL;
+   struct dma_resv_iter cursor;
struct dma_fence *fence;
 
-   rcu_read_lock();
-   fence = dma_resv_get_excl_unlocked(obj->base.resv);
-   rcu_read_unlock();
-
-   if (fence && dma_fence_is_i915(fence) && !dma_fence_is_signaled(fence))
-   engine = to_request(fence)->engine;
-   dma_fence_put(fence);
-
+   dma_resv_iter_begin(&cursor, obj->base.resv, false);
+   dma_resv_for_each_fence_unlocked(&cursor, fence) {
+   if (fence && dma_fence_is_i915(fence) &&
+   !dma_fence_is_signaled(fence))
+   engine = to_request(fence)->engine;
+   }
+   dma_resv_iter_end(&cursor);
return engine;
 }
 
-- 
2.25.1



  1   2   3   >