Re: [PATCH 4/8] drm/bridge: it66121: Add a helper function to get the next bridge

2023-11-22 Thread Dmitry Baryshkov
On Thu, 23 Nov 2023 at 07:25, Sui Jingfeng  wrote:
>
> Hi,
>
>
> On 2023/11/15 00:05, Dmitry Baryshkov wrote:
> > On Tue, 14 Nov 2023 at 17:09, Sui Jingfeng  wrote:
> >> From: Sui Jingfeng 
> >>
> >> Group the code lines(which with the same functional) into one dedicated
> >> function, which reduce the weight of it66121_probe() function. Just trivial
> >> cleanuo, no functional change.
> >>
> >> Signed-off-by: Sui Jingfeng 
> >> ---
> >>   drivers/gpu/drm/bridge/ite-it66121.c | 53 ++--
> >>   1 file changed, 34 insertions(+), 19 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
> >> b/drivers/gpu/drm/bridge/ite-it66121.c
> >> index 0f78737adc83..7e473beefc79 100644
> >> --- a/drivers/gpu/drm/bridge/ite-it66121.c
> >> +++ b/drivers/gpu/drm/bridge/ite-it66121.c
> >> @@ -340,6 +340,37 @@ static int it66121_of_read_bus_width(struct device 
> >> *dev, u32 *bus_width)
> >>  return 0;
> >>   }
> >>
> >> +static int it66121_of_get_next_bridge(struct device *dev,
> >> + struct drm_bridge **next_bridge)
> > it already exists and it is called drm_of_find_panel_or_bridge(),
> > could you please use it instead?
>
> That function is too fat and tangled, and should be untangled.
> it66121 can not connect with a panel, this is a prior knowledge
> and is known at compile time. So this prior knowledge shouldn't
> be dropped.

This prior knowledge is kept by passing NULL as a panel. We already
have a helper. It covers your use case. There is no need to write your
own boilerplate code for it.

>
> >> +{
> >> +   struct device_node *np;
> >> +   struct drm_bridge *bridge;
> >> +
> >> +   np = of_graph_get_remote_node(dev->of_node, 1, -1);
> >> +   if (!np) {
> >> +   dev_err(dev, "The endpoint is unconnected\n");
> >> +   return -EINVAL;
> >> +   }
> >> +
> >> +   if (!of_device_is_available(np)) {
> >> +   of_node_put(np);
> >> +   dev_err(dev, "The remote device is disabled\n");
> >> +   return -ENODEV;
> >> +   }
> >> +
> >> +   bridge = of_drm_find_bridge(np);
> >> +   of_node_put(np);
> >> +
> >> +   if (!bridge) {
> >> +   dev_dbg(dev, "Next bridge not found, deferring probe\n");
> >> +   return -EPROBE_DEFER;
> >> +   }
> >> +
> >> +   *next_bridge = bridge;
> >> +
> >> +   return 0;
> >> +}
> >> +
> >>   static const struct regmap_range_cfg it66121_regmap_banks[] = {
> >>  {
> >>  .name = "it66121",
> >> @@ -1531,7 +1562,6 @@ static const char * const it66121_supplies[] = {
> >>   static int it66121_probe(struct i2c_client *client)
> >>   {
> >>  u32 revision_id, vendor_ids[2] = { 0 }, device_ids[2] = { 0 };
> >> -   struct device_node *ep;
> >>  int ret;
> >>  struct it66121_ctx *ctx;
> >>  struct device *dev = >dev;
> >> @@ -1553,24 +1583,9 @@ static int it66121_probe(struct i2c_client *client)
> >>  if (ret)
> >>  return ret;
> >>
> >> -   ep = of_graph_get_remote_node(dev->of_node, 1, -1);
> >> -   if (!ep) {
> >> -   dev_err(dev, "The endpoint is unconnected\n");
> >> -   return -EINVAL;
> >> -   }
> >> -
> >> -   if (!of_device_is_available(ep)) {
> >> -   of_node_put(ep);
> >> -   dev_err(dev, "The remote device is disabled\n");
> >> -   return -ENODEV;
> >> -   }
> >> -
> >> -   ctx->next_bridge = of_drm_find_bridge(ep);
> >> -   of_node_put(ep);
> >> -   if (!ctx->next_bridge) {
> >> -   dev_dbg(dev, "Next bridge not found, deferring probe\n");
> >> -   return -EPROBE_DEFER;
> >> -   }
> >> +   ret = it66121_of_get_next_bridge(dev, >next_bridge);
> >> +   if (ret)
> >> +   return ret;
> >>
> >>  i2c_set_clientdata(client, ctx);
> >>  mutex_init(>lock);
> >> --
> >> 2.34.1
> >>
> >



-- 
With best wishes
Dmitry


Re: [PATCH 5/8] drm/bridge: it66121: Add a helper function to read chip id

2023-11-22 Thread Dmitry Baryshkov
On Thu, 23 Nov 2023 at 07:37, Sui Jingfeng  wrote:
>
> Hi,
>
>
> On 2023/11/16 21:00, Dmitry Baryshkov wrote:
> > On Thu, 16 Nov 2023 at 14:18, Sui Jingfeng  wrote:
> >> Hi,
> >>
> >>
> >> On 2023/11/15 00:06, Dmitry Baryshkov wrote:
> >>> On Tue, 14 Nov 2023 at 17:09, Sui Jingfeng  wrote:
>  From: Sui Jingfeng 
> 
>  Read the required chip id data back by calling regmap_bulk_read() once,
>  reduce the number of local variables needed in it66121_probe() function.
>  And store its values into struct it66121_ctx, as it will be used latter.
> 
>  Signed-off-by: Sui Jingfeng 
>  ---
> drivers/gpu/drm/bridge/ite-it66121.c | 47 
> 1 file changed, 34 insertions(+), 13 deletions(-)
> 
>  diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
>  b/drivers/gpu/drm/bridge/ite-it66121.c
>  index 7e473beefc79..f36d05331f25 100644
>  --- a/drivers/gpu/drm/bridge/ite-it66121.c
>  +++ b/drivers/gpu/drm/bridge/ite-it66121.c
>  @@ -313,6 +313,9 @@ struct it66121_ctx {
>    bool auto_cts;
>    } audio;
>    const struct it66121_chip_info *info;
>  +   u16 vender_id;
>  +   u16 device_id;
>  +   u8 revision;
> >>> There is no need to store them, they are not used by the driver anywhere.
> >>>
> };
> 
> static inline struct it66121_ctx *bridge_to_it66121(struct drm_bridge 
>  *bridge)
>  @@ -399,6 +402,30 @@ static void it66121_hw_reset(struct it66121_ctx 
>  *ctx)
>    gpiod_set_value(ctx->gpio_reset, 0);
> }
> 
>  +static int it66121_read_chip_id(struct it66121_ctx *ctx, bool verbose)
>  +{
>  +   u8 id[4];
>  +   int ret;
>  +
>  +   ret = regmap_bulk_read(ctx->regmap, IT66121_VENDOR_ID0_REG, id, 
>  4);
>  +   if (ret < 0) {
>  +   dev_err(ctx->dev, "Failed to read chip ID: %d\n", ret);
>  +   return ret;
>  +   }
>  +
>  +   ctx->vender_id = (u16)id[1] << 8 | id[0];
>  +   ctx->device_id = ((u16)(id[3] & IT66121_DEVICE_ID1_MASK) << 8 | 
>  id[2]);
>  +   /* Revision is shared with DEVICE_ID1 */
>  +   ctx->revision = FIELD_GET(IT66121_REVISION_MASK, id[3]);
>  +
>  +   if (verbose) {
>  +   dev_info(ctx->dev, "Found ITE66121: 0x%x%x, revision: 
>  %u\n",
>  +ctx->vender_id, ctx->device_id, ctx->revision);
>  +   }
>  +
>  +   return 0;
>  +}
>  +
> static inline int it66121_preamble_ddc(struct it66121_ctx *ctx)
> {
>    return regmap_write(ctx->regmap, IT66121_MASTER_SEL_REG, 
>  IT66121_MASTER_SEL_HOST);
>  @@ -1561,7 +1588,6 @@ static const char * const it66121_supplies[] = {
> 
> static int it66121_probe(struct i2c_client *client)
> {
>  -   u32 revision_id, vendor_ids[2] = { 0 }, device_ids[2] = { 0 };
>    int ret;
>    struct it66121_ctx *ctx;
>    struct device *dev = >dev;
>  @@ -1603,19 +1629,13 @@ static int it66121_probe(struct i2c_client 
>  *client)
>    if (IS_ERR(ctx->regmap))
>    return PTR_ERR(ctx->regmap);
> 
>  -   regmap_read(ctx->regmap, IT66121_VENDOR_ID0_REG, _ids[0]);
>  -   regmap_read(ctx->regmap, IT66121_VENDOR_ID1_REG, _ids[1]);
>  -   regmap_read(ctx->regmap, IT66121_DEVICE_ID0_REG, _ids[0]);
>  -   regmap_read(ctx->regmap, IT66121_DEVICE_ID1_REG, _ids[1]);
>  -
>  -   /* Revision is shared with DEVICE_ID1 */
>  -   revision_id = FIELD_GET(IT66121_REVISION_MASK, device_ids[1]);
>  -   device_ids[1] &= IT66121_DEVICE_ID1_MASK;
>  +   ret = it66121_read_chip_id(ctx, false);
>  +   if (ret)
>  +   return ret;
> 
>  -   if ((vendor_ids[1] << 8 | vendor_ids[0]) != ctx->info->vid ||
>  -   (device_ids[1] << 8 | device_ids[0]) != ctx->info->pid) {
>  +   if (ctx->vender_id != ctx->info->vid ||
>  +   ctx->device_id != ctx->info->pid)
> >> Q: There is no need to store them, they are not used by the driver 
> >> anywhere.
> >>
> >> A: Here it is used, it is also used by the 0007-patch to get the 
> >> entity(instance)-specific data.
> > And the patch 7 will be changed once you have proper i2c client struct
> > registered.
> >
> >>
> >> Since it6610 was introduced, this is used for chip identifying.
> >> It can also be used with in debugfs context, to show who I am.
> > I'd say, there is little point in whoami debugfs files. Debugfs is for
> > the useful information.
>
> Sinceit6610 was introduced, how do you know what the device it66121 driver is
> binding? Printing model specific information is common practice for a
> large driver. Especially if you can only able to debug remotely where
> only 

Re: [PATCH v4 00/20] remove I2C_CLASS_DDC support

2023-11-22 Thread Heiner Kallweit
On 23.11.2023 07:56, Thomas Zimmermann wrote:
> Hi
> 
> Am 20.11.23 um 22:46 schrieb Heiner Kallweit:
>> After removal of the legacy EEPROM driver and I2C_CLASS_DDC support in
>> olpc_dcon there's no i2c client driver left supporting I2C_CLASS_DDC.
>> Class-based device auto-detection is a legacy mechanism and shouldn't
>> be used in new code. So we can remove this class completely now.
>>
>> Preferably this series should be applied via the i2c tree.
>>
>> v2:
>> - change tag in commit subject of patch 03
>> - add ack tags
>> v3:
>> - fix a compile error in patch 5
>> v4:
>> - more ack and review tags
>>
>> Signed-off-by: Heiner Kallweit 
> 
> Acked-by: Thomas Zimmermann 
> 
> for the patches that don't already have my r-b.
> 
This refers to which patches of the series?
Patches 8, 16, 18 are the remaining ones w/o A-b or R-b.

> Best regards
> Thomas
> 
Thanks, Heiner

>>
>> ---
>>
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c   |    1 -
>>   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |    1 -
>>   drivers/gpu/drm/ast/ast_i2c.c |    1 -
>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi.c |    1 -
>>   drivers/gpu/drm/display/drm_dp_helper.c   |    1 -
>>   drivers/gpu/drm/display/drm_dp_mst_topology.c |    1 -
>>   drivers/gpu/drm/gma500/cdv_intel_dp.c |    1 -
>>   drivers/gpu/drm/gma500/intel_gmbus.c  |    1 -
>>   drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c    |    1 -
>>   drivers/gpu/drm/gma500/psb_intel_sdvo.c   |    1 -
>>   drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c   |    1 -
>>   drivers/gpu/drm/i915/display/intel_gmbus.c    |    1 -
>>   drivers/gpu/drm/i915/display/intel_sdvo.c |    1 -
>>   drivers/gpu/drm/loongson/lsdc_i2c.c   |    1 -
>>   drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c   |    1 -
>>   drivers/gpu/drm/mgag200/mgag200_i2c.c |    1 -
>>   drivers/gpu/drm/msm/hdmi/hdmi_i2c.c   |    1 -
>>   drivers/gpu/drm/radeon/radeon_i2c.c   |    1 -
>>   drivers/gpu/drm/rockchip/inno_hdmi.c  |    1 -
>>   drivers/gpu/drm/rockchip/rk3066_hdmi.c    |    1 -
>>   drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c    |    1 -
>>   drivers/video/fbdev/core/fb_ddc.c |    1 -
>>   drivers/video/fbdev/cyber2000fb.c |    1 -
>>   drivers/video/fbdev/i740fb.c  |    1 -
>>   drivers/video/fbdev/intelfb/intelfb_i2c.c |   15 +--
>>   drivers/video/fbdev/matrox/i2c-matroxfb.c |   12 
>>   drivers/video/fbdev/s3fb.c    |    1 -
>>   drivers/video/fbdev/tdfxfb.c  |    1 -
>>   drivers/video/fbdev/tridentfb.c   |    1 -
>>   drivers/video/fbdev/via/via_i2c.c |    1 -
>>   include/linux/i2c.h   |    1 -
>>   31 files changed, 9 insertions(+), 47 deletions(-)
> 



[PATCH v5 3/5] mm/gup: Introduce pin_user_pages_fd() for pinning shmem/hugetlbfs file pages (v5)

2023-11-22 Thread Vivek Kasireddy
For drivers that would like to longterm-pin the pages associated
with a file, the pin_user_pages_fd() API provides an option to
not only pin the pages via FOLL_PIN but also to check and migrate
them if they reside in movable zone or CMA block. This API
currently works with files that belong to either shmem or hugetlbfs.
Files belonging to other filesystems are rejected for now.

The pages need to be located first before pinning them via FOLL_PIN.
If they are found in the page cache, they can be immediately pinned.
Otherwise, they need to be allocated using the filesystem specific
APIs and then pinned.

v2:
- Drop gup_flags and improve comments and commit message (David)
- Allocate a page if we cannot find in page cache for the hugetlbfs
  case as well (David)
- Don't unpin pages if there is a migration related failure (David)
- Drop the unnecessary nr_pages <= 0 check (Jason)
- Have the caller of the API pass in file * instead of fd (Jason)

v3: (David)
- Enclose the huge page allocation code with #ifdef CONFIG_HUGETLB_PAGE
  (Build error reported by kernel test robot )
- Don't forget memalloc_pin_restore() on non-migration related errors
- Improve the readability of the cleanup code associated with
  non-migration related errors
- Augment the comments by describing FOLL_LONGTERM like behavior
- Include the R-b tag from Jason

v4:
- Remove the local variable "page" and instead use 3 return statements
  in alloc_file_page() (David)
- Add the R-b tag from David

v5: (David)
- For hugetlb case, ensure that we only obtain head pages from the
  mapping by using __filemap_get_folio() instead of find_get_page_flags()
- Handle -EEXIST when two or more potential users try to simultaneously
  add a huge page to the mapping by forcing them to retry on failure

Cc: David Hildenbrand 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 
Suggested-by: Jason Gunthorpe 
Reviewed-by: Jason Gunthorpe  (v2)
Reviewed-by: David Hildenbrand  (v3)
Signed-off-by: Vivek Kasireddy 
---
 include/linux/mm.h |   2 +
 mm/gup.c   | 114 +
 2 files changed, 116 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 418d26608ece..1b675fa35059 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2472,6 +2472,8 @@ long get_user_pages_unlocked(unsigned long start, 
unsigned long nr_pages,
struct page **pages, unsigned int gup_flags);
 long pin_user_pages_unlocked(unsigned long start, unsigned long nr_pages,
struct page **pages, unsigned int gup_flags);
+long pin_user_pages_fd(struct file *file, pgoff_t start,
+  unsigned long nr_pages, struct page **pages);
 
 int get_user_pages_fast(unsigned long start, int nr_pages,
unsigned int gup_flags, struct page **pages);
diff --git a/mm/gup.c b/mm/gup.c
index 231711efa390..ab1056b3e75b 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -3410,3 +3410,117 @@ long pin_user_pages_unlocked(unsigned long start, 
unsigned long nr_pages,
 , gup_flags);
 }
 EXPORT_SYMBOL(pin_user_pages_unlocked);
+
+static struct page *alloc_file_page(struct file *file, pgoff_t idx)
+{
+#ifdef CONFIG_HUGETLB_PAGE
+   struct folio *folio;
+   int err;
+
+   if (is_file_hugepages(file)) {
+   folio = alloc_hugetlb_folio_nodemask(hstate_file(file),
+NUMA_NO_NODE,
+NULL,
+GFP_USER);
+   if (folio && folio_try_get(folio)) {
+   err = hugetlb_add_to_page_cache(folio,
+   file->f_mapping,
+   idx);
+   if (err) {
+   folio_put(folio);
+   free_huge_folio(folio);
+   return ERR_PTR(err);
+   }
+   return >page;
+   }
+   return ERR_PTR(-ENOMEM);
+   }
+#endif
+   return shmem_read_mapping_page(file->f_mapping, idx);
+}
+
+/**
+ * pin_user_pages_fd() - pin user pages associated with a file
+ * @file:   the file whose pages are to be pinned
+ * @start:  starting file offset
+ * @nr_pages:   number of pages from start to pin
+ * @pages:  array that receives pointers to the pages pinned.
+ *  Should be at-least nr_pages long.
+ *
+ * Attempt to pin pages associated with a file that belongs to either shmem
+ * or hugetlb. The pages are either found in the page cache or allocated if
+ * necessary. Once the pages are located, they are all pinned via FOLL_PIN.
+ * And, these pinned pages need to be released either using unpin_user_pages()
+ * or unpin_user_page().
+ *
+ * It must 

[PATCH v5 4/5] udmabuf: Pin the pages using pin_user_pages_fd() API (v3)

2023-11-22 Thread Vivek Kasireddy
Using pin_user_pages_fd() will ensure that the pages are pinned
correctly using FOLL_PIN. And, this also ensures that we don't
accidentally break features such as memory hotunplug as it would
not allow pinning pages in the movable zone.

Using this new API also simplifies the code as we no longer have
to deal with extracting individual pages from their mappings. As
a result, we can drop some of the local variables such as page,
hpage, mapping, etc.

v2:
- Adjust to the change in signature of pin_user_pages_fd() by
  passing in file * instead of fd.

v3:
- Limit the changes in this patch only to those that are required
  for using pin_user_pages_fd()
- Slightly improve the commit message

Cc: David Hildenbrand 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Jason Gunthorpe 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 
Signed-off-by: Vivek Kasireddy 
---
 drivers/dma-buf/udmabuf.c | 61 ++-
 1 file changed, 22 insertions(+), 39 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index d77d119f4048..883bd97e4076 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -156,7 +156,8 @@ static void release_udmabuf(struct dma_buf *buf)
put_sg_table(dev, ubuf->sg, DMA_BIDIRECTIONAL);
 
for (pg = 0; pg < ubuf->pagecount; pg++)
-   put_page(ubuf->pages[pg]);
+   unpin_user_page(ubuf->pages[pg]);
+
kfree(ubuf->subpgoff);
kfree(ubuf->pages);
kfree(ubuf);
@@ -217,15 +218,13 @@ static long udmabuf_create(struct miscdevice *device,
 {
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
struct file *memfd = NULL;
-   struct address_space *mapping = NULL;
struct udmabuf *ubuf;
struct dma_buf *buf;
-   pgoff_t pgoff, pgcnt, pgidx, pgbuf = 0, pglimit;
-   struct page *page, *hpage = NULL;
-   struct folio *folio;
+   pgoff_t pgcnt, pgbuf = 0, pglimit, nr_pages;
pgoff_t mapidx, chunkoff, maxchunks;
struct hstate *hpstate;
-   int seals, ret = -EINVAL;
+   long ret = -EINVAL;
+   int seals;
u32 i, flags;
 
ubuf = kzalloc(sizeof(*ubuf), GFP_KERNEL);
@@ -259,8 +258,7 @@ static long udmabuf_create(struct miscdevice *device,
memfd = fget(list[i].memfd);
if (!memfd)
goto err;
-   mapping = memfd->f_mapping;
-   if (!shmem_mapping(mapping) && !is_file_hugepages(memfd))
+   if (!shmem_file(memfd) && !is_file_hugepages(memfd))
goto err;
seals = memfd_fcntl(memfd, F_GET_SEALS, 0);
if (seals == -EINVAL)
@@ -269,7 +267,7 @@ static long udmabuf_create(struct miscdevice *device,
if ((seals & SEALS_WANTED) != SEALS_WANTED ||
(seals & SEALS_DENIED) != 0)
goto err;
-   pgoff = list[i].offset >> PAGE_SHIFT;
+   mapidx = list[i].offset >> PAGE_SHIFT;
pgcnt = list[i].size   >> PAGE_SHIFT;
if (is_file_hugepages(memfd)) {
if (!ubuf->subpgoff) {
@@ -287,42 +285,26 @@ static long udmabuf_create(struct miscdevice *device,
~huge_page_mask(hpstate)) >> PAGE_SHIFT;
maxchunks = huge_page_size(hpstate) >> PAGE_SHIFT;
}
-   for (pgidx = 0; pgidx < pgcnt; pgidx++) {
+
+   do {
+   nr_pages = shmem_file(memfd) ? pgcnt : 1;
+   ret = pin_user_pages_fd(memfd, mapidx, nr_pages,
+   ubuf->pages + pgbuf);
+   if (ret < 0)
+   goto err;
+
if (is_file_hugepages(memfd)) {
-   if (!hpage) {
-   folio = __filemap_get_folio(mapping, 
mapidx,
-   
FGP_ACCESSED, 0);
-   hpage = IS_ERR(folio) ? NULL: 
>page;
-   if (!hpage) {
-   ret = -EINVAL;
-   goto err;
-   }
-   }
-   get_page(hpage);
-   ubuf->pages[pgbuf] = hpage;
-   ubuf->subpgoff[pgbuf++] = chunkoff << 
PAGE_SHIFT;
+   ubuf->subpgoff[pgbuf] = chunkoff << PAGE_SHIFT;
if (++chunkoff == maxchunks) {
-   put_page(hpage);
-   hpage = NULL;
chunkoff = 0;
mapidx++;
 

[PATCH v5 2/5] udmabuf: Add back support for mapping hugetlb pages (v4)

2023-11-22 Thread Vivek Kasireddy
A user or admin can configure a VMM (Qemu) Guest's memory to be
backed by hugetlb pages for various reasons. However, a Guest OS
would still allocate (and pin) buffers that are backed by regular
4k sized pages. In order to map these buffers and create dma-bufs
for them on the Host, we first need to find the hugetlb pages where
the buffer allocations are located and then determine the offsets
of individual chunks (within those pages) and use this information
to eventually populate a scatterlist.

Testcase: default_hugepagesz=2M hugepagesz=2M hugepages=2500 options
were passed to the Host kernel and Qemu was launched with these
relevant options: qemu-system-x86_64 -m 4096m
-device virtio-gpu-pci,max_outputs=1,blob=true,xres=1920,yres=1080
-display gtk,gl=on
-object memory-backend-memfd,hugetlb=on,id=mem1,size=4096M
-machine memory-backend=mem1

Replacing -display gtk,gl=on with -display gtk,gl=off above would
exercise the mmap handler.

v2: Updated get_sg_table() to manually populate the scatterlist for
both huge page and non-huge-page cases.

v3: s/offsets/subpgoff/g
s/hpoff/mapidx/g

v4: Replaced find_get_page_flags() with __filemap_get_folio() to
ensure that we only obtain head pages from the mapping

Cc: David Hildenbrand 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Jason Gunthorpe 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 
Acked-by: Mike Kravetz  (v2)
Signed-off-by: Vivek Kasireddy 
---
 drivers/dma-buf/udmabuf.c | 87 +--
 1 file changed, 74 insertions(+), 13 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 820c993c8659..d77d119f4048 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -28,6 +29,7 @@ struct udmabuf {
struct page **pages;
struct sg_table *sg;
struct miscdevice *device;
+   pgoff_t *subpgoff;
 };
 
 static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
@@ -41,6 +43,10 @@ static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
return VM_FAULT_SIGBUS;
 
pfn = page_to_pfn(ubuf->pages[pgoff]);
+   if (ubuf->subpgoff) {
+   pfn += ubuf->subpgoff[pgoff] >> PAGE_SHIFT;
+   }
+
return vmf_insert_pfn(vma, vmf->address, pfn);
 }
 
@@ -90,23 +96,31 @@ static struct sg_table *get_sg_table(struct device *dev, 
struct dma_buf *buf,
 {
struct udmabuf *ubuf = buf->priv;
struct sg_table *sg;
+   struct scatterlist *sgl;
+   pgoff_t offset;
+   unsigned long i = 0;
int ret;
 
sg = kzalloc(sizeof(*sg), GFP_KERNEL);
if (!sg)
return ERR_PTR(-ENOMEM);
-   ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->pagecount,
-   0, ubuf->pagecount << PAGE_SHIFT,
-   GFP_KERNEL);
+
+   ret = sg_alloc_table(sg, ubuf->pagecount, GFP_KERNEL);
if (ret < 0)
-   goto err;
+   goto err_alloc;
+
+   for_each_sg(sg->sgl, sgl, ubuf->pagecount, i) {
+   offset = ubuf->subpgoff ? ubuf->subpgoff[i] : 0;
+   sg_set_page(sgl, ubuf->pages[i], PAGE_SIZE, offset);
+   }
ret = dma_map_sgtable(dev, sg, direction, 0);
if (ret < 0)
-   goto err;
+   goto err_map;
return sg;
 
-err:
+err_map:
sg_free_table(sg);
+err_alloc:
kfree(sg);
return ERR_PTR(ret);
 }
@@ -143,6 +157,7 @@ static void release_udmabuf(struct dma_buf *buf)
 
for (pg = 0; pg < ubuf->pagecount; pg++)
put_page(ubuf->pages[pg]);
+   kfree(ubuf->subpgoff);
kfree(ubuf->pages);
kfree(ubuf);
 }
@@ -206,7 +221,10 @@ static long udmabuf_create(struct miscdevice *device,
struct udmabuf *ubuf;
struct dma_buf *buf;
pgoff_t pgoff, pgcnt, pgidx, pgbuf = 0, pglimit;
-   struct page *page;
+   struct page *page, *hpage = NULL;
+   struct folio *folio;
+   pgoff_t mapidx, chunkoff, maxchunks;
+   struct hstate *hpstate;
int seals, ret = -EINVAL;
u32 i, flags;
 
@@ -242,7 +260,7 @@ static long udmabuf_create(struct miscdevice *device,
if (!memfd)
goto err;
mapping = memfd->f_mapping;
-   if (!shmem_mapping(mapping))
+   if (!shmem_mapping(mapping) && !is_file_hugepages(memfd))
goto err;
seals = memfd_fcntl(memfd, F_GET_SEALS, 0);
if (seals == -EINVAL)
@@ -253,16 +271,58 @@ static long udmabuf_create(struct miscdevice *device,
goto err;
pgoff = list[i].offset >> PAGE_SHIFT;
pgcnt = list[i].size   >> PAGE_SHIFT;
+   if (is_file_hugepages(memfd)) {
+   if 

[PATCH v5 1/5] udmabuf: Use vmf_insert_pfn and VM_PFNMAP for handling mmap

2023-11-22 Thread Vivek Kasireddy
Add VM_PFNMAP to vm_flags in the mmap handler to ensure that
the mappings would be managed without using struct page.

And, in the vm_fault handler, use vmf_insert_pfn to share the
page's pfn to userspace instead of directly sharing the page
(via struct page *).

Cc: David Hildenbrand 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Jason Gunthorpe 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 
Suggested-by: David Hildenbrand 
Acked-by: David Hildenbrand 
Signed-off-by: Vivek Kasireddy 
---
 drivers/dma-buf/udmabuf.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index c40645999648..820c993c8659 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -35,12 +35,13 @@ static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
struct vm_area_struct *vma = vmf->vma;
struct udmabuf *ubuf = vma->vm_private_data;
pgoff_t pgoff = vmf->pgoff;
+   unsigned long pfn;
 
if (pgoff >= ubuf->pagecount)
return VM_FAULT_SIGBUS;
-   vmf->page = ubuf->pages[pgoff];
-   get_page(vmf->page);
-   return 0;
+
+   pfn = page_to_pfn(ubuf->pages[pgoff]);
+   return vmf_insert_pfn(vma, vmf->address, pfn);
 }
 
 static const struct vm_operations_struct udmabuf_vm_ops = {
@@ -56,6 +57,7 @@ static int mmap_udmabuf(struct dma_buf *buf, struct 
vm_area_struct *vma)
 
vma->vm_ops = _vm_ops;
vma->vm_private_data = ubuf;
+   vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
return 0;
 }
 
-- 
2.39.2



[PATCH v5 5/5] selftests/dma-buf/udmabuf: Add tests to verify data after page migration

2023-11-22 Thread Vivek Kasireddy
Since the memfd pages associated with a udmabuf may be migrated
as part of udmabuf create, we need to verify the data coherency
after successful migration. The new tests added in this patch try
to do just that using 4k sized pages and also 2 MB sized huge
pages for the memfd.

Successful completion of the tests would mean that there is no
disconnect between the memfd pages and the ones associated with
a udmabuf. And, these tests can also be augmented in the future
to test newer udmabuf features (such as handling memfd hole punch).

Cc: Shuah Khan 
Cc: David Hildenbrand 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Jason Gunthorpe 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 
Based-on-patch-by: Mike Kravetz 
Signed-off-by: Vivek Kasireddy 
---
 .../selftests/drivers/dma-buf/udmabuf.c   | 151 +-
 1 file changed, 147 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/drivers/dma-buf/udmabuf.c 
b/tools/testing/selftests/drivers/dma-buf/udmabuf.c
index c812080e304e..d76c813fe652 100644
--- a/tools/testing/selftests/drivers/dma-buf/udmabuf.c
+++ b/tools/testing/selftests/drivers/dma-buf/udmabuf.c
@@ -9,26 +9,132 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
 #define TEST_PREFIX"drivers/dma-buf/udmabuf"
 #define NUM_PAGES   4
+#define NUM_ENTRIES 4
+#define MEMFD_SIZE  1024 /* in pages */
 
-static int memfd_create(const char *name, unsigned int flags)
+static unsigned int page_size;
+
+static int create_memfd_with_seals(off64_t size, bool hpage)
+{
+   int memfd, ret;
+   unsigned int flags = MFD_ALLOW_SEALING;
+
+   if (hpage)
+   flags |= MFD_HUGETLB;
+
+   memfd = memfd_create("udmabuf-test", flags);
+   if (memfd < 0) {
+   printf("%s: [skip,no-memfd]\n", TEST_PREFIX);
+   exit(77);
+   }
+
+   ret = fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK);
+   if (ret < 0) {
+   printf("%s: [skip,fcntl-add-seals]\n", TEST_PREFIX);
+   exit(77);
+   }
+
+   ret = ftruncate(memfd, size);
+   if (ret == -1) {
+   printf("%s: [FAIL,memfd-truncate]\n", TEST_PREFIX);
+   exit(1);
+   }
+
+   return memfd;
+}
+
+static int create_udmabuf_list(int devfd, int memfd, off64_t memfd_size)
+{
+   struct udmabuf_create_list *list;
+   int ubuf_fd, i;
+
+   list = malloc(sizeof(struct udmabuf_create_list) +
+ sizeof(struct udmabuf_create_item) * NUM_ENTRIES);
+   if (!list) {
+   printf("%s: [FAIL, udmabuf-malloc]\n", TEST_PREFIX);
+   exit(1);
+   }
+
+   for (i = 0; i < NUM_ENTRIES; i++) {
+   list->list[i].memfd  = memfd;
+   list->list[i].offset = i * (memfd_size / NUM_ENTRIES);
+   list->list[i].size   = getpagesize() * NUM_PAGES;
+   }
+
+   list->count = NUM_ENTRIES;
+   list->flags = UDMABUF_FLAGS_CLOEXEC;
+   ubuf_fd = ioctl(devfd, UDMABUF_CREATE_LIST, list);
+   free(list);
+   if (ubuf_fd < 0) {
+   printf("%s: [FAIL, udmabuf-create]\n", TEST_PREFIX);
+   exit(1);
+   }
+
+   return ubuf_fd;
+}
+
+static void write_to_memfd(void *addr, off64_t size, char chr)
+{
+   int i;
+
+   for (i = 0; i < size / page_size; i++) {
+   *((char *)addr + (i * page_size)) = chr;
+   }
+}
+
+static void *mmap_fd(int fd, off64_t size)
 {
-   return syscall(__NR_memfd_create, name, flags);
+   void *addr;
+
+   addr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+   if (addr == MAP_FAILED) {
+   printf("%s: ubuf_fd mmap fail\n", TEST_PREFIX);
+   exit(1);
+   }
+
+   return addr;
+}
+
+static int compare_chunks(void *addr1, void *addr2, off64_t memfd_size)
+{
+   off64_t off;
+   int i = 0, j, k = 0, ret = 0;
+   char char1, char2;
+
+   while (i < NUM_ENTRIES) {
+   off = i * (memfd_size / NUM_ENTRIES);
+   for (j = 0; j < NUM_PAGES; j++, k++) {
+   char1 = *((char *)addr1 + off + (j * getpagesize()));
+   char2 = *((char *)addr2 + (k * getpagesize()));
+   if (char1 != char2) {
+   ret = -1;
+   goto err;
+   }
+   }
+   i++;
+   }
+err:
+   munmap(addr1, memfd_size);
+   munmap(addr2, NUM_ENTRIES * NUM_PAGES * getpagesize());
+   return ret;
 }
 
 int main(int argc, char *argv[])
 {
struct udmabuf_create create;
int devfd, memfd, buf, ret;
-   off_t size;
-   void *mem;
+   off64_t size;
+   void *addr1, *addr2;
 
devfd = open("/dev/udmabuf", O_RDWR);
if (devfd < 0) {
@@ -90,6 +196,9 @@ int main(int argc, char *argv[])
}
 
/* should work */
+   

[PATCH v5 0/5] mm/gup: Introduce pin_user_pages_fd() for pinning shmem/hugetlbfs file pages (v5)

2023-11-22 Thread Vivek Kasireddy
The first two patches were previously reviewed but not yet merged.
These ones need to be merged first as the fourth patch depends on
the changes introduced in them and they also fix bugs seen in
very specific scenarios (running Qemu with hugetlb=on, blob=true
and rebooting guest VM).

The third patch introduces pin_user_pages_fd() API and the fourth
patch shows how the udmabuf driver can make use of it to
longterm-pin the the pages. The last patch adds two new udmabuf
selftests to verify data coherency after potential page migration.

v2:
- Updated the first patch to include review feedback from David and
  Jason. The main change in this series is the allocation of page
  in the case of hugetlbfs if it is not found in the page cache.

v3:
- Made changes to include review feedback from David to improve the
  comments and readability of code
- Enclosed the hugepage alloc code with #ifdef CONFIG_HUGETLB_PAGE

v4:
- Augmented the commit message of the udmabuf patch that uses
  pin_user_pages_fd()
- Added previously reviewed but unmerged udmabuf patches to this
  series

v5:
- Updated the patch that adds pin_user_pages_fd() to include feedback
  from David to handle simultaneous users trying to add a huge page
  to the mapping
- Replaced find_get_page_flags() with __filemap_get_folio() in the
  second and third patches to ensure that we only obtain head pages
  from the mapping

Cc: David Hildenbrand 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Jason Gunthorpe 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 

Vivek Kasireddy (5):
  udmabuf: Use vmf_insert_pfn and VM_PFNMAP for handling mmap
  udmabuf: Add back support for mapping hugetlb pages (v4)
  mm/gup: Introduce pin_user_pages_fd() for pinning shmem/hugetlbfs file
pages (v5)
  udmabuf: Pin the pages using pin_user_pages_fd() API (v3)
  selftests/dma-buf/udmabuf: Add tests to verify data after page
migration

 drivers/dma-buf/udmabuf.c |  96 ---
 include/linux/mm.h|   2 +
 mm/gup.c  | 114 +
 .../selftests/drivers/dma-buf/udmabuf.c   | 151 +-
 4 files changed, 334 insertions(+), 29 deletions(-)

-- 
2.39.2



RE: [PATCH] drm/i915/psr: Fix unsigned expression compared with zero

2023-11-22 Thread Kahola, Mika
> -Original Message-
> From: Jani Nikula 
> Sent: Wednesday, November 22, 2023 11:15 AM
> To: Jiapeng Chong 
> Cc: joonas.lahti...@linux.intel.com; Vivi, Rodrigo ; 
> tvrtko.ursu...@linux.intel.com; airl...@gmail.com;
> dan...@ffwll.ch; intel-...@lists.freedesktop.org; 
> dri-devel@lists.freedesktop.org; linux-ker...@vger.kernel.org; Jiapeng Chong
> ; Abaci Robot ; 
> Kahola, Mika 
> Subject: Re: [PATCH] drm/i915/psr: Fix unsigned expression compared with zero
> 
> On Wed, 22 Nov 2023, Jiapeng Chong  wrote:
> > The entry_setup_frames is defined as u8 type, else(entry_setup_frames
> > < 0) is invalid. At the same time, the return value of function
> > intel_psr_entry_setup_frames is also of type int. so modified its type
> > to int.
> >
> > ./drivers/gpu/drm/i915/display/intel_psr.c:1336:5-23: WARNING: Unsigned 
> > expression compared with zero:
> entry_setup_frames >= 0.
> >
> > Reported-by: Abaci Robot 
> > Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=7610
> > Signed-off-by: Jiapeng Chong 
> 
> There's already a patch. Mika, please follow up with it.
> 
> https://patchwork.freedesktop.org/patch/msgid/20231116090512.480373-1-mika.kah...@intel.com

The patch is now merged. Thanks for the review.

-Mika-
> 
> > ---
> >  drivers/gpu/drm/i915/display/intel_psr.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> > b/drivers/gpu/drm/i915/display/intel_psr.c
> > index 8d180132a74b..204da50e3f28 100644
> > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > @@ -1319,7 +1319,7 @@ static bool _psr_compute_config(struct intel_dp
> > *intel_dp,  {
> > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > const struct drm_display_mode *adjusted_mode = 
> > _state->hw.adjusted_mode;
> > -   u8 entry_setup_frames;
> > +   int entry_setup_frames;
> >
> > /*
> >  * Current PSR panels don't work reliably with VRR enabled
> 
> --
> Jani Nikula, Intel


Re: [PATCH v4 00/20] remove I2C_CLASS_DDC support

2023-11-22 Thread Thomas Zimmermann

Hi

Am 20.11.23 um 22:46 schrieb Heiner Kallweit:

After removal of the legacy EEPROM driver and I2C_CLASS_DDC support in
olpc_dcon there's no i2c client driver left supporting I2C_CLASS_DDC.
Class-based device auto-detection is a legacy mechanism and shouldn't
be used in new code. So we can remove this class completely now.

Preferably this series should be applied via the i2c tree.

v2:
- change tag in commit subject of patch 03
- add ack tags
v3:
- fix a compile error in patch 5
v4:
- more ack and review tags

Signed-off-by: Heiner Kallweit 


Acked-by: Thomas Zimmermann 

for the patches that don't already have my r-b.

Best regards
Thomas



---

  drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c   |1 -
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |1 -
  drivers/gpu/drm/ast/ast_i2c.c |1 -
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c |1 -
  drivers/gpu/drm/display/drm_dp_helper.c   |1 -
  drivers/gpu/drm/display/drm_dp_mst_topology.c |1 -
  drivers/gpu/drm/gma500/cdv_intel_dp.c |1 -
  drivers/gpu/drm/gma500/intel_gmbus.c  |1 -
  drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c|1 -
  drivers/gpu/drm/gma500/psb_intel_sdvo.c   |1 -
  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c   |1 -
  drivers/gpu/drm/i915/display/intel_gmbus.c|1 -
  drivers/gpu/drm/i915/display/intel_sdvo.c |1 -
  drivers/gpu/drm/loongson/lsdc_i2c.c   |1 -
  drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c   |1 -
  drivers/gpu/drm/mgag200/mgag200_i2c.c |1 -
  drivers/gpu/drm/msm/hdmi/hdmi_i2c.c   |1 -
  drivers/gpu/drm/radeon/radeon_i2c.c   |1 -
  drivers/gpu/drm/rockchip/inno_hdmi.c  |1 -
  drivers/gpu/drm/rockchip/rk3066_hdmi.c|1 -
  drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c|1 -
  drivers/video/fbdev/core/fb_ddc.c |1 -
  drivers/video/fbdev/cyber2000fb.c |1 -
  drivers/video/fbdev/i740fb.c  |1 -
  drivers/video/fbdev/intelfb/intelfb_i2c.c |   15 +--
  drivers/video/fbdev/matrox/i2c-matroxfb.c |   12 
  drivers/video/fbdev/s3fb.c|1 -
  drivers/video/fbdev/tdfxfb.c  |1 -
  drivers/video/fbdev/tridentfb.c   |1 -
  drivers/video/fbdev/via/via_i2c.c |1 -
  include/linux/i2c.h   |1 -
  31 files changed, 9 insertions(+), 47 deletions(-)


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


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH 5/8] drm/bridge: it66121: Add a helper function to read chip id

2023-11-22 Thread Sui Jingfeng

Hi,


On 2023/11/16 21:00, Dmitry Baryshkov wrote:

On Thu, 16 Nov 2023 at 14:18, Sui Jingfeng  wrote:

Hi,


On 2023/11/15 00:06, Dmitry Baryshkov wrote:

On Tue, 14 Nov 2023 at 17:09, Sui Jingfeng  wrote:

From: Sui Jingfeng 

Read the required chip id data back by calling regmap_bulk_read() once,
reduce the number of local variables needed in it66121_probe() function.
And store its values into struct it66121_ctx, as it will be used latter.

Signed-off-by: Sui Jingfeng 
---
   drivers/gpu/drm/bridge/ite-it66121.c | 47 
   1 file changed, 34 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
b/drivers/gpu/drm/bridge/ite-it66121.c
index 7e473beefc79..f36d05331f25 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -313,6 +313,9 @@ struct it66121_ctx {
  bool auto_cts;
  } audio;
  const struct it66121_chip_info *info;
+   u16 vender_id;
+   u16 device_id;
+   u8 revision;

There is no need to store them, they are not used by the driver anywhere.


   };

   static inline struct it66121_ctx *bridge_to_it66121(struct drm_bridge 
*bridge)
@@ -399,6 +402,30 @@ static void it66121_hw_reset(struct it66121_ctx *ctx)
  gpiod_set_value(ctx->gpio_reset, 0);
   }

+static int it66121_read_chip_id(struct it66121_ctx *ctx, bool verbose)
+{
+   u8 id[4];
+   int ret;
+
+   ret = regmap_bulk_read(ctx->regmap, IT66121_VENDOR_ID0_REG, id, 4);
+   if (ret < 0) {
+   dev_err(ctx->dev, "Failed to read chip ID: %d\n", ret);
+   return ret;
+   }
+
+   ctx->vender_id = (u16)id[1] << 8 | id[0];
+   ctx->device_id = ((u16)(id[3] & IT66121_DEVICE_ID1_MASK) << 8 | id[2]);
+   /* Revision is shared with DEVICE_ID1 */
+   ctx->revision = FIELD_GET(IT66121_REVISION_MASK, id[3]);
+
+   if (verbose) {
+   dev_info(ctx->dev, "Found ITE66121: 0x%x%x, revision: %u\n",
+ctx->vender_id, ctx->device_id, ctx->revision);
+   }
+
+   return 0;
+}
+
   static inline int it66121_preamble_ddc(struct it66121_ctx *ctx)
   {
  return regmap_write(ctx->regmap, IT66121_MASTER_SEL_REG, 
IT66121_MASTER_SEL_HOST);
@@ -1561,7 +1588,6 @@ static const char * const it66121_supplies[] = {

   static int it66121_probe(struct i2c_client *client)
   {
-   u32 revision_id, vendor_ids[2] = { 0 }, device_ids[2] = { 0 };
  int ret;
  struct it66121_ctx *ctx;
  struct device *dev = >dev;
@@ -1603,19 +1629,13 @@ static int it66121_probe(struct i2c_client *client)
  if (IS_ERR(ctx->regmap))
  return PTR_ERR(ctx->regmap);

-   regmap_read(ctx->regmap, IT66121_VENDOR_ID0_REG, _ids[0]);
-   regmap_read(ctx->regmap, IT66121_VENDOR_ID1_REG, _ids[1]);
-   regmap_read(ctx->regmap, IT66121_DEVICE_ID0_REG, _ids[0]);
-   regmap_read(ctx->regmap, IT66121_DEVICE_ID1_REG, _ids[1]);
-
-   /* Revision is shared with DEVICE_ID1 */
-   revision_id = FIELD_GET(IT66121_REVISION_MASK, device_ids[1]);
-   device_ids[1] &= IT66121_DEVICE_ID1_MASK;
+   ret = it66121_read_chip_id(ctx, false);
+   if (ret)
+   return ret;

-   if ((vendor_ids[1] << 8 | vendor_ids[0]) != ctx->info->vid ||
-   (device_ids[1] << 8 | device_ids[0]) != ctx->info->pid) {
+   if (ctx->vender_id != ctx->info->vid ||
+   ctx->device_id != ctx->info->pid)

Q: There is no need to store them, they are not used by the driver anywhere.

A: Here it is used, it is also used by the 0007-patch to get the 
entity(instance)-specific data.

And the patch 7 will be changed once you have proper i2c client struct
registered.



Since it6610 was introduced, this is used for chip identifying.
It can also be used with in debugfs context, to show who I am.

I'd say, there is little point in whoami debugfs files. Debugfs is for
the useful information.


Sinceit6610 was introduced, how do you know what the device it66121 driver is 
binding? Printing model specific information is common practice for a 
large driver. Especially if you can only able to debug remotely where 
only a SSH is given. You could see debugfs of drm/etnaviv for a 
reference. It is common to testing a large driver running on 20+ 
machines with various hardware model.






  return -ENODEV;
-   }

  ctx->bridge.funcs = _bridge_funcs;
  ctx->bridge.of_node = dev->of_node;
@@ -1633,7 +1653,8 @@ static int it66121_probe(struct i2c_client *client)

  drm_bridge_add(>bridge);

-   dev_info(dev, "IT66121 revision %d probed\n", revision_id);
+   dev_info(dev, "IT66121 probed, chip id: 0x%x:0x%x, revision: %u\n",
+ctx->vender_id, ctx->device_id, ctx->revision);

  return 0;
   }
--
2.34.1






Re: [PATCH 4/8] drm/bridge: it66121: Add a helper function to get the next bridge

2023-11-22 Thread Sui Jingfeng

Hi,


On 2023/11/15 00:05, Dmitry Baryshkov wrote:

On Tue, 14 Nov 2023 at 17:09, Sui Jingfeng  wrote:

From: Sui Jingfeng 

Group the code lines(which with the same functional) into one dedicated
function, which reduce the weight of it66121_probe() function. Just trivial
cleanuo, no functional change.

Signed-off-by: Sui Jingfeng 
---
  drivers/gpu/drm/bridge/ite-it66121.c | 53 ++--
  1 file changed, 34 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
b/drivers/gpu/drm/bridge/ite-it66121.c
index 0f78737adc83..7e473beefc79 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -340,6 +340,37 @@ static int it66121_of_read_bus_width(struct device *dev, 
u32 *bus_width)
 return 0;
  }

+static int it66121_of_get_next_bridge(struct device *dev,
+ struct drm_bridge **next_bridge)

it already exists and it is called drm_of_find_panel_or_bridge(),
could you please use it instead?


That function is too fat and tangled, and should be untangled.
it66121 can not connect with a panel, this is a prior knowledge
and is known at compile time. So this prior knowledge shouldn't
be dropped.


+{
+   struct device_node *np;
+   struct drm_bridge *bridge;
+
+   np = of_graph_get_remote_node(dev->of_node, 1, -1);
+   if (!np) {
+   dev_err(dev, "The endpoint is unconnected\n");
+   return -EINVAL;
+   }
+
+   if (!of_device_is_available(np)) {
+   of_node_put(np);
+   dev_err(dev, "The remote device is disabled\n");
+   return -ENODEV;
+   }
+
+   bridge = of_drm_find_bridge(np);
+   of_node_put(np);
+
+   if (!bridge) {
+   dev_dbg(dev, "Next bridge not found, deferring probe\n");
+   return -EPROBE_DEFER;
+   }
+
+   *next_bridge = bridge;
+
+   return 0;
+}
+
  static const struct regmap_range_cfg it66121_regmap_banks[] = {
 {
 .name = "it66121",
@@ -1531,7 +1562,6 @@ static const char * const it66121_supplies[] = {
  static int it66121_probe(struct i2c_client *client)
  {
 u32 revision_id, vendor_ids[2] = { 0 }, device_ids[2] = { 0 };
-   struct device_node *ep;
 int ret;
 struct it66121_ctx *ctx;
 struct device *dev = >dev;
@@ -1553,24 +1583,9 @@ static int it66121_probe(struct i2c_client *client)
 if (ret)
 return ret;

-   ep = of_graph_get_remote_node(dev->of_node, 1, -1);
-   if (!ep) {
-   dev_err(dev, "The endpoint is unconnected\n");
-   return -EINVAL;
-   }
-
-   if (!of_device_is_available(ep)) {
-   of_node_put(ep);
-   dev_err(dev, "The remote device is disabled\n");
-   return -ENODEV;
-   }
-
-   ctx->next_bridge = of_drm_find_bridge(ep);
-   of_node_put(ep);
-   if (!ctx->next_bridge) {
-   dev_dbg(dev, "Next bridge not found, deferring probe\n");
-   return -EPROBE_DEFER;
-   }
+   ret = it66121_of_get_next_bridge(dev, >next_bridge);
+   if (ret)
+   return ret;

 i2c_set_clientdata(client, ctx);
 mutex_init(>lock);
--
2.34.1





[PATCH v2] drm/bridge: imx93-mipi-dsi: Fix a couple of building warnings

2023-11-22 Thread Liu Ying
Fix a couple of building warnings on used uninitialized 'best_m' and
'best_n' local variables by initializing 'best_m' to zero and 'best_n'
to UINT_MAX.  This makes compiler happy only.  No functional change.

Fixes: ce62f8ea7e3f ("drm/bridge: imx: Add i.MX93 MIPI DSI support")
Reported-by: kernel test robot 
Closes: 
https://lore.kernel.org/oe-kbuild-all/202311151746.f7u7dzbz-...@intel.com/
Signed-off-by: Liu Ying 
---
v2:
* Initialize 'best_n' to UINT_MAX instead of zero. (Maxime)

 drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c 
b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c
index 3ff30ce80c5b..2347f8dd632f 100644
--- a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c
@@ -226,8 +226,8 @@ dphy_pll_get_configure_from_opts(struct imx93_dsi *dsi,
unsigned long fout;
unsigned long best_fout = 0;
unsigned int fvco_div;
-   unsigned int min_n, max_n, n, best_n;
-   unsigned long m, best_m;
+   unsigned int min_n, max_n, n, best_n = UINT_MAX;
+   unsigned long m, best_m = 0;
unsigned long min_delta = ULONG_MAX;
unsigned long delta;
u64 tmp;
-- 
2.37.1



Re: [PATCH 8/8] drm/bridge: it66121: Allow link this driver as a lib

2023-11-22 Thread Sui Jingfeng

Hi,


On 2023/11/16 19:19, Dmitry Baryshkov wrote:

On Thu, 16 Nov 2023 at 12:13, Sui Jingfeng  wrote:

Hi,


On 2023/11/16 17:30, Dmitry Baryshkov wrote:

On Thu, 16 Nov 2023 at 11:14, Sui Jingfeng  wrote:

Hi,

Thanks a lot for reviewing!


On 2023/11/15 00:30, Dmitry Baryshkov wrote:

On Tue, 14 Nov 2023 at 17:09, Sui Jingfeng  wrote:

From: Sui Jingfeng 

The it66121_create_bridge() and it66121_destroy_bridge() are added to
export the core functionalities. Create a connector manually by using
bridge connector helpers when link as a lib.

Signed-off-by: Sui Jingfeng 
---
drivers/gpu/drm/bridge/ite-it66121.c | 134 +++
include/drm/bridge/ite-it66121.h |  17 
2 files changed, 113 insertions(+), 38 deletions(-)
create mode 100644 include/drm/bridge/ite-it66121.h

diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
b/drivers/gpu/drm/bridge/ite-it66121.c
index 8971414a2a60..f5968b679c5d 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -22,6 +22,7 @@

#include 
#include 
+#include 
#include 
#include 
#include 
@@ -703,14 +704,32 @@ static int it66121_bridge_attach(struct drm_bridge 
*bridge,
enum drm_bridge_attach_flags flags)
{
   struct it66121_ctx *ctx = bridge_to_it66121(bridge);
+   struct drm_bridge *next_bridge = ctx->next_bridge;
+   struct drm_encoder *encoder = bridge->encoder;
   int ret;

-   if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
-   return -EINVAL;
+   if (next_bridge) {
+   if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+   WARN_ON(1);

Why? At least use WARN() instead

Originally I want to





+   flags |= DRM_BRIDGE_ATTACH_NO_CONNECTOR;
+   }
+   ret = drm_bridge_attach(encoder, next_bridge, bridge, flags);
+   if (ret)
+   return ret;
+   } else {
+   struct drm_connector *connector;

-   ret = drm_bridge_attach(bridge->encoder, ctx->next_bridge, bridge, 
flags);
-   if (ret)
-   return ret;
+   if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
+   WARN_ON(1);

No. It is perfectly fine to create attach a bridge with no next_bridge
and with the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag.


The document say when DRM_BRIDGE_ATTACH_NO_CONNECTOR flag is set
the bridge shall not create a drm_connector. So I think if a display
bridge driver don't have a next bridge attached (Currently, this is
told by the DT), it says that this is a non-DT environment. On such
a case, this display bridge driver(it66121.ko) should behavior like
a *agent*. Because the upstream port of it66121 is the DVO port of
the display controller, the downstream port of it66121 is the HDMI
connector. it66121 is on the middle. So I think the it66121.ko should
handle all of troubles on behalf of the display controller drivers.

No. Don't make decisions for the other drivers. They might have different needs.

[...]



Therefore (when in non-DT use case), the display controller drivers
side should not set DRM_BRIDGE_ATTACH_NO_CONNECTOR flag anymore.
Which is to hint that the it66121 should totally in charge of those
tasks (either by using bridge connector helper or create a connector
manually). I don't understand on such a case, why bother display
controller drivers anymore.

This is the reason why we had introduced this flag. It allows the
driver to customise the connector. It even allows the driver to
implement a connector on its own, completely ignoring the
drm_bridge_connector.


I know what you said is right in the sense of the universe cases,
but I think the most frequent(majority) use case is that there is
only one display bridge on the middle. Therefore, I don't want to
movethe connector things into device driver if there is only one display
bridge(say it66121) in the middle. After all, there is no *direct
physical connection* from the perspective of the hardware. I means that
there is no hardware wires connectthe HDMI connector and the DVO port. So 
display controller drivers
should not interact with anything related with the connector on a
perfect abstract on the software side. Especially for such a simple use
case. It probably make senses to make a  decision for themost frequently use 
case, please also note
that this patch didn't introduce any-restriction for the more advance
uses cases(multiple bridges in the middle).

So, for the sake of not having the connector in the display driver,
you want to add boilerplate code basically to each and every bridge
driver. In the end, they should all behave in the same way.

Moreover, there is no way this implementation can work without a
warning if there are two bridges in a chain and the it66121 is the
second (the last) one. The host can not specify the
DRM_BRIDGE_ATTACH_NO_CONNECTOR)

+   

[PATCH] drm/msm/gpu: Fix null-pointer dereference in zap_shader_load_mdt

2023-11-22 Thread Kunwu Chan
kasprintf() returns a pointer to dynamically allocated memory
which can be NULL upon failure. Ensure the allocation was successful
by checking the pointer validity.

Fixes: a9e2559c931d ("drm/msm/gpu: Move zap shader loading to adreno")
Signed-off-by: Kunwu Chan 
---
 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 3fe9fd240cc7..0ebf86ffd57b 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -144,6 +144,10 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, const 
char *fwname,
char *newname;
 
newname = kasprintf(GFP_KERNEL, "qcom/%s", fwname);
+   if (!newname) {
+   ret = -ENOMEM;
+   goto out;
+   }
 
ret = qcom_mdt_load(dev, fw, newname, pasid,
mem_region, mem_phys, mem_size, NULL);
-- 
2.34.1



[PATCH] drm/bridge: panel: Check device dependency before managing device link

2023-11-22 Thread Liu Ying
Some panel devices already depend on DRM device, like the panel in
arch/arm/boot/dts/st/ste-ux500-samsung-skomer.dts, because DRM device is
the ancestor of those panel devices.  device_link_add() would fail by
returning a NULL pointer for those panel devices because of the existing
dependency.  So, check the dependency by calling device_is_dependent()
before adding or deleting device link between panel device and DRM device
so that the link is managed only for independent panel devices.

Fixes: 887878014534 ("drm/bridge: panel: Fix device link for 
DRM_BRIDGE_ATTACH_NO_CONNECTOR")
Fixes: 199cf07ebd2b ("drm/bridge: panel: Add a device link between drm device 
and panel device")
Reported-by: Linus Walleij 
Closes: 
https://lore.kernel.org/lkml/cacrpkdagzxd6hbix7mvunjajtmepg00pp6+nj1p0jrfj-ar...@mail.gmail.com/T/
Tested-by: Linus Walleij 
Signed-off-by: Liu Ying 
---
 drivers/gpu/drm/bridge/panel.c | 27 ++-
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index e48823a4f1ed..5e8980023407 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -23,6 +23,7 @@ struct panel_bridge {
struct drm_panel *panel;
struct device_link *link;
u32 connector_type;
+   bool is_independent;
 };
 
 static inline struct panel_bridge *
@@ -67,12 +68,17 @@ static int panel_bridge_attach(struct drm_bridge *bridge,
struct drm_device *drm_dev = bridge->dev;
int ret;
 
-   panel_bridge->link = device_link_add(drm_dev->dev, panel->dev,
-DL_FLAG_STATELESS);
-   if (!panel_bridge->link) {
-   DRM_ERROR("Failed to add device link between %s and %s\n",
- dev_name(drm_dev->dev), dev_name(panel->dev));
-   return -EINVAL;
+   panel_bridge->is_independent = !device_is_dependent(drm_dev->dev,
+   panel->dev);
+
+   if (panel_bridge->is_independent) {
+   panel_bridge->link = device_link_add(drm_dev->dev, panel->dev,
+DL_FLAG_STATELESS);
+   if (!panel_bridge->link) {
+   DRM_ERROR("Failed to add device link between %s and 
%s\n",
+ dev_name(drm_dev->dev), dev_name(panel->dev));
+   return -EINVAL;
+   }
}
 
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
@@ -80,7 +86,8 @@ static int panel_bridge_attach(struct drm_bridge *bridge,
 
if (!bridge->encoder) {
DRM_ERROR("Missing encoder\n");
-   device_link_del(panel_bridge->link);
+   if (panel_bridge->is_independent)
+   device_link_del(panel_bridge->link);
return -ENODEV;
}
 
@@ -92,7 +99,8 @@ static int panel_bridge_attach(struct drm_bridge *bridge,
 panel_bridge->connector_type);
if (ret) {
DRM_ERROR("Failed to initialize connector\n");
-   device_link_del(panel_bridge->link);
+   if (panel_bridge->is_independent)
+   device_link_del(panel_bridge->link);
return ret;
}
 
@@ -115,7 +123,8 @@ static void panel_bridge_detach(struct drm_bridge *bridge)
struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
struct drm_connector *connector = _bridge->connector;
 
-   device_link_del(panel_bridge->link);
+   if (panel_bridge->is_independent)
+   device_link_del(panel_bridge->link);
 
/*
 * Cleanup the connector if we know it was initialized.
-- 
2.37.1



RE: [PATCH v3] drm/bridge: panel: Add a device link between drm device and panel device

2023-11-22 Thread Ying Liu
On Wednesday, November 22, 2023 9:59 PM, Linus Walleij 
 wrote:
> Hi Ying,

Hi Linus,

> 
> On Mon, Nov 20, 2023 at 11:08 AM Ying Liu  wrote:
> 
> [Me]
> > > > v2->v3:
> > > > * Improve commit message s/swapped/reversed/.
> > >
> > > This patch causes a regression in the Ux500 MCDE
> > > drivers/gpu/drm/mcde/* driver with the nt35510 panel
> > > drivers/gpu/drm/panel/panel-novatek-nt35510.c
> > > my dmesg looks like this:
> (...)
> > Sorry for the breakage and a bit late response(I'm a bit busy with internal
> > things).
> >
> > I think device_link_add() fails because a0351000.dsi.0 already depends
> > on a035.mcde.  Can you confirm that device_link_add() returns NULL
> > right after it calls device_is_dependent()?
> >
> > Does this patch fix the issue?
> 
> Yep it works!
> 
> You missed one device_link_del() instance on the errorpath.

Will add it.

> 
> Tested-by: Linus Walleij 

Thanks for the test.

> 
> Can you send it as a proper patch?

Will do.

Regards,
Liu Ying


Re: [PATCH 1/3] riscv: Add support for kernel-mode FPU

2023-11-22 Thread kernel test robot
Hi Samuel,

kernel test robot noticed the following build errors:

[auto build test ERROR on drm-misc/drm-misc-next]
[also build test ERROR on linus/master v6.7-rc2 next-20231122]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Samuel-Holland/riscv-Add-support-for-kernel-mode-FPU/20231122-111015
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:
https://lore.kernel.org/r/20231122030621.3759313-2-samuel.holland%40sifive.com
patch subject: [PATCH 1/3] riscv: Add support for kernel-mode FPU
config: riscv-randconfig-r111-20231123 
(https://download.01.org/0day-ci/archive/20231123/202311230628.tkl31mjj-...@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 13.2.0
reproduce: 
(https://download.01.org/0day-ci/archive/20231123/202311230628.tkl31mjj-...@intel.com/reproduce)

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

All errors (new ones prefixed by >>):

   In file included from include/linux/linkage.h:7,
from include/linux/printk.h:8,
from include/asm-generic/bug.h:22,
from arch/riscv/include/asm/bug.h:83,
from include/linux/bug.h:5,
from arch/riscv/include/asm/current.h:13,
from include/linux/sched.h:12,
from include/linux/ratelimit.h:6,
from include/linux/dev_printk.h:16,
from include/linux/device.h:15,
from include/linux/node.h:18,
from include/linux/cpu.h:17,
from arch/riscv/kernel/process.c:10:
>> arch/riscv/kernel/process.c:229:19: error: '__fstate_save' undeclared here 
>> (not in a function); did you mean 'fstate_save'?
 229 | EXPORT_SYMBOL_GPL(__fstate_save);
 |   ^
   include/linux/export.h:74:23: note: in definition of macro '__EXPORT_SYMBOL'
  74 | extern typeof(sym) sym; \
 |   ^~~
   include/linux/export.h:87:41: note: in expansion of macro '_EXPORT_SYMBOL'
  87 | #define EXPORT_SYMBOL_GPL(sym)  _EXPORT_SYMBOL(sym, "GPL")
 | ^~
   arch/riscv/kernel/process.c:229:1: note: in expansion of macro 
'EXPORT_SYMBOL_GPL'
 229 | EXPORT_SYMBOL_GPL(__fstate_save);
 | ^
>> arch/riscv/kernel/process.c:230:19: error: '__fstate_restore' undeclared 
>> here (not in a function); did you mean 'fstate_restore'?
 230 | EXPORT_SYMBOL_GPL(__fstate_restore);
 |   ^~~~
   include/linux/export.h:74:23: note: in definition of macro '__EXPORT_SYMBOL'
  74 | extern typeof(sym) sym; \
 |   ^~~
   include/linux/export.h:87:41: note: in expansion of macro '_EXPORT_SYMBOL'
  87 | #define EXPORT_SYMBOL_GPL(sym)  _EXPORT_SYMBOL(sym, "GPL")
 | ^~
   arch/riscv/kernel/process.c:230:1: note: in expansion of macro 
'EXPORT_SYMBOL_GPL'
 230 | EXPORT_SYMBOL_GPL(__fstate_restore);
 | ^


vim +229 arch/riscv/kernel/process.c

   228  
 > 229  EXPORT_SYMBOL_GPL(__fstate_save);
 > 230  EXPORT_SYMBOL_GPL(__fstate_restore);

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


Re: Radeon regression in 6.6 kernel

2023-11-22 Thread Luben Tuikov
On 2023-11-21 17:05, Phillip Susi wrote:
> Alex Deucher  writes:
> 
>> Does reverting 56e449603f0ac580700621a356d35d5716a62ce5 alone fix it?
>> Can you also attach your full dmesg log for the failed suspend?
> 
> No, it doesn't.  Here is the full syslog from the boot with only that
> revert:
> 

Thank you Phillip for verifying this.

BTW, luben.tui...@amd.com should absolutely bounce for everyone sending emails 
to it. Not sure why it is still active.
My new email is the one this email is coming from.
-- 
Regards,
Luben


OpenPGP_0x4C15479431A334AF.asc
Description: OpenPGP public key


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH] drm/rockchip: rk3066_hdmi: include drm/drm_atomic.h

2023-11-22 Thread Heiko Stuebner
On Wed, 22 Nov 2023 23:18:29 +0100, Arnd Bergmann wrote:
> From: Arnd Bergmann 
> 
> Without this header, the newly added code fails to build:
> 
> drivers/gpu/drm/rockchip/rk3066_hdmi.c: In function 
> 'rk3066_hdmi_encoder_enable':
> drivers/gpu/drm/rockchip/rk3066_hdmi.c:397:22: error: implicit declaration of 
> function 'drm_atomic_get_new_connector_state'; did you mean 
> 'drm_atomic_helper_connector_reset'? [-Werror=implicit-function-declaration]
>   397 | conn_state = drm_atomic_get_new_connector_state(state, 
> >connector);
>   |  ^~
>   |  drm_atomic_helper_connector_reset
> drivers/gpu/drm/rockchip/rk3066_hdmi.c:397:20: error: assignment to 'struct 
> drm_connector_state *' from 'int' makes pointer from integer without a cast 
> [-Werror=int-conversion]
>   397 | conn_state = drm_atomic_get_new_connector_state(state, 
> >connector);
>   |^
> drivers/gpu/drm/rockchip/rk3066_hdmi.c:401:22: error: implicit declaration of 
> function 'drm_atomic_get_new_crtc_state'; did you mean 
> 'drm_atomic_helper_swap_state'? [-Werror=implicit-function-declaration]
>   401 | crtc_state = drm_atomic_get_new_crtc_state(state, 
> conn_state->crtc);
>   |  ^
>   |  drm_atomic_helper_swap_state
> drivers/gpu/drm/rockchip/rk3066_hdmi.c:401:20: error: assignment to 'struct 
> drm_crtc_state *' from 'int' makes pointer from integer without a cast 
> [-Werror=int-conversion]
>   401 | crtc_state = drm_atomic_get_new_crtc_state(state, 
> conn_state->crtc);
>   |^
> 
> [...]

Applied, thanks!

[1/1] drm/rockchip: rk3066_hdmi: include drm/drm_atomic.h
  commit: f4814c20d14ca168382e8887c768f290e4a2a861

Very puzzling, I did testbuild with the atomic conversion in place
and also re-did it again to before applying this patch and didn't get
the mentioned error - not sure what I might have done differently to
create a dufferent reszkt,

In any case, I applied the fix.


Best regards,
-- 
Heiko Stuebner 


[PATCH v2] drm/amdgpu: Fix cat debugfs amdgpu_regs_didt causes kernel null pointer

2023-11-22 Thread Lu Yao
For 'AMDGPU_FAMILY_SI' family cards, in 'si_common_early_init' func, init
'didt_rreg' and 'didt_wreg' to 'NULL'. But in func
'amdgpu_debugfs_regs_didt_read/write', using 'RREG32_DIDT' 'WREG32_DIDT'
lacks of relevant judgment. And other 'amdgpu_ip_block_version' that use
these two definitions won't be added for 'AMDGPU_FAMILY_SI'.

So, add null pointer judgment before calling.

Signed-off-by: Lu Yao 
---
Changes in v2:
  1. Drop dev_err message.
  2. Change error code from 'EPERM' to 'EOPNOTSUPP'
Link to v1: https://lore.kernel.org/all/20231122093509.34302-1-ya...@kylinos.cn/
Thanks Christian for his comments.
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
index a53f436fa9f1..e098cd66fa2a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -638,6 +638,9 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file 
*f, char __user *buf,
if (size & 0x3 || *pos & 0x3)
return -EINVAL;
 
+   if (adev->didt_rreg == NULL)
+   return -EOPNOTSUPP;
+
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
@@ -694,6 +697,9 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file 
*f, const char __user
if (size & 0x3 || *pos & 0x3)
return -EINVAL;
 
+   if (adev->didt_wreg == NULL)
+   return -EOPNOTSUPP;
+
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
-- 
2.25.1



Re: [PATCH v2 1/1] drm/msm/adreno: Add support for SM7150 SoC machine

2023-11-22 Thread Danila Tikhonov

sc7180/sm7125 (atoll) expects speedbins from atoll.dtsi:
And has a parameter: /delete-property/ qcom,gpu-speed-bin;
107 for 504Mhz max freq, pwrlevel 4
130 for 610Mhz max freq, pwrlevel 3
159 for 750Mhz max freq, pwrlevel 5
169 for 800Mhz max freq, pwrlevel 2
174 for 825Mhz max freq, pwrlevel 1 (Downstream says 172, but thats 
probably typo)

For rest of the speed bins, speed-bin value is calulated as
FMAX/4.8MHz + 2 round up to zero decimal places.

sm7150 (sdmmagpie) expects speedbins from sdmmagpie-gpu.dtsi:
128 for 610Mhz max freq, pwrlevel 3
146 for 700Mhz max freq, pwrlevel 2
167 for 800Mhz max freq, pwrlevel 4
172 for 504Mhz max freq, pwrlevel 1
For rest of the speed bins, speed-bin value is calulated as
FMAX/4.8 MHz round up to zero decimal places.

Creating a new entry does not make much sense.
I can suggest expanding the standard entry:

.speedbins = ADRENO_SPEEDBINS(
    { 0, 0 },
    /* sc7180/sm7125 */
    { 107, 3 },
    { 130, 4 },
    { 159, 5 },
    { 168, 1 }, has already
    { 174, 2 }, has already
    /* sm7150 */
    { 128, 1 },
    { 146, 2 },
    { 167, 3 },
    { 172, 4 }, ),

All the best,
Danila

On 11/22/23 23:28, Konrad Dybcio wrote:



On 10/16/23 16:32, Dmitry Baryshkov wrote:

On 26/09/2023 23:03, Konrad Dybcio wrote:

On 26.09.2023 21:10, Danila Tikhonov wrote:


I think you mean by name downstream dt - sdmmagpie-gpu.dtsi

You can see the forked version of the mainline here:
https://github.com/sm7150-mainline/linux/blob/next/arch/arm64/boot/dts/qcom/sm7150.dtsi 



All fdt that we got here, if it is useful for you:
https://github.com/sm7150-mainline/downstream-fdt

Best wishes, Danila

Taking a look at downstream, atoll.dtsi (SC7180) includes
sdmmagpie-gpu.dtsi.

Bottom line is, they share the speed bins, so it should be
fine to just extend the existing entry.


But then atoll.dtsi rewrites speed bins and pwrlevel bins. So they 
are not shared.

+Akhil

could you please check internally?

Konrad




Re: [PATCH v2 1/4] i915: make inject_virtual_interrupt() void

2023-11-22 Thread Zhenyu Wang
On 2023.11.22 13:48:22 +0100, Christian Brauner wrote:
> The single caller of inject_virtual_interrupt() ignores the return value
> anyway. This allows us to simplify eventfd_signal() in follow-up
> patches.
> 
> Signed-off-by: Christian Brauner 
> ---
>  drivers/gpu/drm/i915/gvt/interrupt.c | 14 +++---
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gvt/interrupt.c 
> b/drivers/gpu/drm/i915/gvt/interrupt.c
> index de3f5903d1a7..9665876b4b13 100644
> --- a/drivers/gpu/drm/i915/gvt/interrupt.c
> +++ b/drivers/gpu/drm/i915/gvt/interrupt.c
> @@ -422,7 +422,7 @@ static void init_irq_map(struct intel_gvt_irq *irq)
>  #define MSI_CAP_DATA(offset) (offset + 8)
>  #define MSI_CAP_EN 0x1
>  
> -static int inject_virtual_interrupt(struct intel_vgpu *vgpu)
> +static void inject_virtual_interrupt(struct intel_vgpu *vgpu)
>  {
>   unsigned long offset = vgpu->gvt->device_info.msi_cap_offset;
>   u16 control, data;
> @@ -434,10 +434,10 @@ static int inject_virtual_interrupt(struct intel_vgpu 
> *vgpu)
>  
>   /* Do not generate MSI if MSIEN is disabled */
>   if (!(control & MSI_CAP_EN))
> - return 0;
> + return;
>  
>   if (WARN(control & GENMASK(15, 1), "only support one MSI format\n"))
> - return -EINVAL;
> + return;
>  
>   trace_inject_msi(vgpu->id, addr, data);
>  
> @@ -451,10 +451,10 @@ static int inject_virtual_interrupt(struct intel_vgpu 
> *vgpu)
>* returned and don't inject interrupt into guest.
>*/
>   if (!test_bit(INTEL_VGPU_STATUS_ATTACHED, vgpu->status))
> - return -ESRCH;
> - if (vgpu->msi_trigger && eventfd_signal(vgpu->msi_trigger, 1) != 1)
> - return -EFAULT;
> - return 0;
> + return;
> + if (!vgpu->msi_trigger)
> + return;
> + eventfd_signal(vgpu->msi_trigger, 1);
>  }

I think it's a little simpler to write as
if (vgpu->msi_trigger)
eventfd_signal(vgpu->msi_trigger, 1);

Looks fine with me.

Reviewed-by: Zhenyu Wang 

Thanks!

>  
>  static void propagate_event(struct intel_gvt_irq *irq,
> 
> -- 
> 2.42.0
> 


signature.asc
Description: PGP signature


[PATCH 6/6] x86/vmware: Add TDX hypercall support

2023-11-22 Thread Alexey Makhalov
VMware hypercalls use I/O port, VMCALL or VMMCALL instructions.
Add __tdx_hypercall path to support TDX guests.

No change in high bandwidth hypercalls, as only low bandwidth
ones are supported for TDX guests.

Co-developed-by: Tim Merrifield 
Signed-off-by: Tim Merrifield 
Signed-off-by: Alexey Makhalov 
---
 arch/x86/include/asm/vmware.h | 72 +++
 arch/x86/kernel/cpu/vmware.c  |  9 +
 2 files changed, 81 insertions(+)

diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index 17091eba68cb..cd58ff8ef1af 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -40,6 +40,54 @@
 
 extern u8 vmware_hypercall_mode;
 
+#define VMWARE_TDX_VENDOR_LEAF 0x1AF7E4909ULL
+#define VMWARE_TDX_HCALL_FUNC  1
+
+extern void vmware_tdx_hypercall_args(struct tdx_module_args *args);
+
+/*
+ * TDCALL[TDG.VP.VMCALL] uses rax (arg0) and rcx (arg2), while the use of
+ * rbp (arg6) is discouraged by the TDX specification. Therefore, we
+ * remap those registers to r12, r13 and r14, respectively.
+ */
+static inline
+unsigned long vmware_tdx_hypercall(unsigned long cmd, unsigned long in1,
+  unsigned long in3, unsigned long in4,
+  unsigned long in5, unsigned long in6,
+  uint32_t *out1, uint32_t *out2,
+  uint32_t *out3, uint32_t *out4,
+  uint32_t *out5, uint32_t *out6)
+{
+   struct tdx_module_args args = {
+   .r10 = VMWARE_TDX_VENDOR_LEAF,
+   .r11 = VMWARE_TDX_HCALL_FUNC,
+   .r12 = VMWARE_HYPERVISOR_MAGIC,
+   .r13 = cmd,
+   .rbx = in1,
+   .rdx = in3,
+   .rsi = in4,
+   .rdi = in5,
+   .r14 = in6,
+   };
+
+   vmware_tdx_hypercall_args();
+
+   if (out1)
+   *out1 = args.rbx;
+   if (out2)
+   *out2 = args.r13;
+   if (out3)
+   *out3 = args.rdx;
+   if (out4)
+   *out4 = args.rsi;
+   if (out5)
+   *out5 = args.rdi;
+   if (out6)
+   *out6 = args.r14;
+
+   return args.r12;
+}
+
 /*
  * The low bandwidth call. The low word of edx is presumed to have OUT bit
  * set. The high word of edx may contain input data from the caller.
@@ -67,6 +115,10 @@ unsigned long vmware_hypercall1(unsigned long cmd, unsigned 
long in1)
 {
unsigned long out0;
 
+   if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+   return vmware_tdx_hypercall(cmd, in1, 0, 0, 0, 0, NULL, NULL,
+   NULL, NULL, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -85,6 +137,10 @@ unsigned long vmware_hypercall3(unsigned long cmd, unsigned 
long in1,
 {
unsigned long out0;
 
+   if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+   return vmware_tdx_hypercall(cmd, in1, 0, 0, 0, 0, out1, out2,
+   NULL, NULL, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=b" (*out1), "=c" (*out2)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -104,6 +160,10 @@ unsigned long vmware_hypercall4(unsigned long cmd, 
unsigned long in1,
 {
unsigned long out0;
 
+   if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+   return vmware_tdx_hypercall(cmd, in1, 0, 0, 0, 0, out1, out2,
+   out3, NULL, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -123,6 +183,10 @@ unsigned long vmware_hypercall5(unsigned long cmd, 
unsigned long in1,
 {
unsigned long out0;
 
+   if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+   return vmware_tdx_hypercall(cmd, in1, in3, in4, in5, 0, NULL,
+   out2, NULL, NULL, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=c" (*out2)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -145,6 +209,10 @@ unsigned long vmware_hypercall6(unsigned long cmd, 
unsigned long in1,
 {
unsigned long out0;
 
+   if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+   return vmware_tdx_hypercall(cmd, in1, in3, 0, 0, 0, NULL, out2,
+   out3, out4, out5, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=c" (*out2), "=d" (*out3), "=S" (*out4),
  "=D" (*out5)
@@ -166,6 +234,10 @@ unsigned long vmware_hypercall7(unsigned long cmd, 
unsigned long in1,
 {
unsigned long out0;
 
+   if 

[PATCH 5/6] drm/vmwgfx: Use vmware_hypercall API

2023-11-22 Thread Alexey Makhalov
Switch from VMWARE_HYPERCALL macro to vmware_hypercall API.
Eliminate arch specific code.

drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h: implement arm64 variant of
vmware_hypercall here. To be moved to arch/arm64/include/asm/vmware.h
later.

Signed-off-by: Alexey Makhalov 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_msg.c   | 173 +++
 drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h | 197 +++---
 drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h   | 185 
 3 files changed, 197 insertions(+), 358 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
index 2651fe0ef518..1f15990d3934 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
@@ -48,8 +48,6 @@
 
 #define RETRIES 3
 
-#define VMW_HYPERVISOR_MAGIC0x564D5868
-
 #define VMW_PORT_CMD_MSG30
 #define VMW_PORT_CMD_HB_MSG 0
 #define VMW_PORT_CMD_OPEN_CHANNEL  (MSG_TYPE_OPEN << 16 | VMW_PORT_CMD_MSG)
@@ -104,20 +102,18 @@ static const char* const 
mksstat_kern_name_desc[MKSSTAT_KERN_COUNT][2] =
  */
 static int vmw_open_channel(struct rpc_channel *channel, unsigned int protocol)
 {
-   unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
+   u32 ecx, edx, esi, edi;
 
-   VMW_PORT(VMW_PORT_CMD_OPEN_CHANNEL,
-   (protocol | GUESTMSG_FLAG_COOKIE), si, di,
-   0,
-   VMW_HYPERVISOR_MAGIC,
-   eax, ebx, ecx, edx, si, di);
+   vmware_hypercall6(VMW_PORT_CMD_OPEN_CHANNEL,
+ (protocol | GUESTMSG_FLAG_COOKIE), 0,
+ , , , );
 
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
return -EINVAL;
 
channel->channel_id  = HIGH_WORD(edx);
-   channel->cookie_high = si;
-   channel->cookie_low  = di;
+   channel->cookie_high = esi;
+   channel->cookie_low  = edi;
 
return 0;
 }
@@ -133,17 +129,13 @@ static int vmw_open_channel(struct rpc_channel *channel, 
unsigned int protocol)
  */
 static int vmw_close_channel(struct rpc_channel *channel)
 {
-   unsigned long eax, ebx, ecx, edx, si, di;
-
-   /* Set up additional parameters */
-   si  = channel->cookie_high;
-   di  = channel->cookie_low;
+   u32 ecx;
 
-   VMW_PORT(VMW_PORT_CMD_CLOSE_CHANNEL,
-   0, si, di,
-   channel->channel_id << 16,
-   VMW_HYPERVISOR_MAGIC,
-   eax, ebx, ecx, edx, si, di);
+   vmware_hypercall5(VMW_PORT_CMD_CLOSE_CHANNEL,
+ 0, channel->channel_id << 16,
+ channel->cookie_high,
+ channel->cookie_low,
+ );
 
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
return -EINVAL;
@@ -163,24 +155,18 @@ static int vmw_close_channel(struct rpc_channel *channel)
 static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
 const char *msg, bool hb)
 {
-   unsigned long si, di, eax, ebx, ecx, edx;
+   u32 ebx, ecx;
unsigned long msg_len = strlen(msg);
 
/* HB port can't access encrypted memory. */
if (hb && !cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
-   unsigned long bp = channel->cookie_high;
-   u32 channel_id = (channel->channel_id << 16);
-
-   si = (uintptr_t) msg;
-   di = channel->cookie_low;
-
-   VMW_PORT_HB_OUT(
+   vmware_hypercall_hb_out(
(MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
-   msg_len, si, di,
-   VMWARE_HYPERVISOR_HB | channel_id |
-   VMWARE_HYPERVISOR_OUT,
-   VMW_HYPERVISOR_MAGIC, bp,
-   eax, ebx, ecx, edx, si, di);
+   msg_len,
+   channel->channel_id << 16,
+   (uintptr_t) msg, channel->cookie_low,
+   channel->cookie_high,
+   );
 
return ebx;
}
@@ -194,14 +180,13 @@ static unsigned long vmw_port_hb_out(struct rpc_channel 
*channel,
memcpy(, msg, bytes);
msg_len -= bytes;
msg += bytes;
-   si = channel->cookie_high;
-   di = channel->cookie_low;
-
-   VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_SENDPAYLOAD << 16),
-word, si, di,
-channel->channel_id << 16,
-VMW_HYPERVISOR_MAGIC,
-eax, ebx, ecx, edx, si, di);
+
+   vmware_hypercall5(VMW_PORT_CMD_MSG |
+ (MSG_TYPE_SENDPAYLOAD << 16),
+ word, channel->channel_id << 16,
+ channel->cookie_high,
+ channel->cookie_low,
+ 

[PATCH 3/6] ptp/vmware: Use vmware_hypercall API

2023-11-22 Thread Alexey Makhalov
Switch from VMWARE_HYPERCALL macro to vmware_hypercall API.
Eliminate arch specific code. No functional changes intended.

Signed-off-by: Alexey Makhalov 
---
 drivers/ptp/ptp_vmw.c | 12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/ptp/ptp_vmw.c b/drivers/ptp/ptp_vmw.c
index 27c5547aa8a9..e5bb521b9b82 100644
--- a/drivers/ptp/ptp_vmw.c
+++ b/drivers/ptp/ptp_vmw.c
@@ -14,7 +14,6 @@
 #include 
 #include 
 
-#define VMWARE_MAGIC 0x564D5868
 #define VMWARE_CMD_PCLK(nr) ((nr << 16) | 97)
 #define VMWARE_CMD_PCLK_GETTIME VMWARE_CMD_PCLK(0)
 
@@ -24,15 +23,10 @@ static struct ptp_clock *ptp_vmw_clock;
 
 static int ptp_vmw_pclk_read(u64 *ns)
 {
-   u32 ret, nsec_hi, nsec_lo, unused1, unused2, unused3;
-
-   asm volatile (VMWARE_HYPERCALL :
-   "=a"(ret), "=b"(nsec_hi), "=c"(nsec_lo), "=d"(unused1),
-   "=S"(unused2), "=D"(unused3) :
-   "a"(VMWARE_MAGIC), "b"(0),
-   "c"(VMWARE_CMD_PCLK_GETTIME), "d"(0) :
-   "memory");
+   u32 ret, nsec_hi, nsec_lo;
 
+   ret = vmware_hypercall3(VMWARE_CMD_PCLK_GETTIME, 0,
+   _hi, _lo);
if (ret == 0)
*ns = ((u64)nsec_hi << 32) | nsec_lo;
return ret;
-- 
2.39.0



[PATCH 1/6] x86/vmware: Move common macros to vmware.h

2023-11-22 Thread Alexey Makhalov
Move VMware hypercall macros to vmware.h as a preparation step
for the next commit. No functional changes besides exporting
vmware_hypercall_mode symbol.

Signed-off-by: Alexey Makhalov 
---
 arch/x86/include/asm/vmware.h | 69 ++-
 arch/x86/kernel/cpu/vmware.c  | 57 +++--
 2 files changed, 66 insertions(+), 60 deletions(-)

diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index ac9fc51e2b18..8cabf4a577bf 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -8,25 +8,37 @@
 
 /*
  * The hypercall definitions differ in the low word of the %edx argument
- * in the following way: the old port base interface uses the port
- * number to distinguish between high- and low bandwidth versions.
+ * in the following way: the old I/O port based interface uses the port
+ * number to distinguish between high- and low bandwidth versions, and
+ * uses IN/OUT instructions to define transfer direction.
  *
  * The new vmcall interface instead uses a set of flags to select
  * bandwidth mode and transfer direction. The flags should be loaded
  * into %dx by any user and are automatically replaced by the port
- * number if the VMWARE_HYPERVISOR_PORT method is used.
+ * number if the I/O port method is used.
  *
  * In short, new driver code should strictly use the new definition of
  * %dx content.
  */
 
-/* Old port-based version */
-#define VMWARE_HYPERVISOR_PORT0x5658
-#define VMWARE_HYPERVISOR_PORT_HB 0x5659
+#define VMWARE_HYPERVISOR_HB   BIT(0)
+#define VMWARE_HYPERVISOR_OUT  BIT(1)
 
-/* Current vmcall / vmmcall version */
-#define VMWARE_HYPERVISOR_HB   BIT(0)
-#define VMWARE_HYPERVISOR_OUT  BIT(1)
+#define VMWARE_HYPERVISOR_PORT 0x5658
+#define VMWARE_HYPERVISOR_PORT_HB  (VMWARE_HYPERVISOR_PORT | \
+VMWARE_HYPERVISOR_HB)
+
+#define VMWARE_HYPERVISOR_MAGIC0x564D5868U
+
+#define VMWARE_CMD_GETVERSION  10
+#define VMWARE_CMD_GETHZ   45
+#define VMWARE_CMD_GETVCPU_INFO68
+#define VMWARE_CMD_STEALCLOCK  91
+
+#define CPUID_VMWARE_FEATURES_ECX_VMMCALL  BIT(0)
+#define CPUID_VMWARE_FEATURES_ECX_VMCALL   BIT(1)
+
+extern u8 vmware_hypercall_mode;
 
 /* The low bandwidth call. The low word of edx is presumed clear. */
 #define VMWARE_HYPERCALL   \
@@ -54,4 +66,43 @@
  "rep insb",   \
  "vmcall", X86_FEATURE_VMCALL, \
  "vmmcall", X86_FEATURE_VMW_VMMCALL)
+
+#define VMWARE_PORT(cmd, eax, ebx, ecx, edx)   \
+   __asm__("inl (%%dx), %%eax" :   \
+   "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :\
+   "a"(VMWARE_HYPERVISOR_MAGIC),   \
+   "c"(VMWARE_CMD_##cmd),  \
+   "d"(VMWARE_HYPERVISOR_PORT), "b"(UINT_MAX) :\
+   "memory")
+
+#define VMWARE_VMCALL(cmd, eax, ebx, ecx, edx) \
+   __asm__("vmcall" :  \
+   "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :\
+   "a"(VMWARE_HYPERVISOR_MAGIC),   \
+   "c"(VMWARE_CMD_##cmd),  \
+   "d"(0), "b"(UINT_MAX) : \
+   "memory")
+
+#define VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx)
\
+   __asm__("vmmcall" : \
+   "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :\
+   "a"(VMWARE_HYPERVISOR_MAGIC),   \
+   "c"(VMWARE_CMD_##cmd),  \
+   "d"(0), "b"(UINT_MAX) : \
+   "memory")
+
+#define VMWARE_CMD(cmd, eax, ebx, ecx, edx) do {   \
+   switch (vmware_hypercall_mode) {\
+   case CPUID_VMWARE_FEATURES_ECX_VMCALL:  \
+   VMWARE_VMCALL(cmd, eax, ebx, ecx, edx); \
+   break;  \
+   case CPUID_VMWARE_FEATURES_ECX_VMMCALL: \
+   VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx);\
+   break;  \
+   default:\
+   VMWARE_PORT(cmd, eax, ebx, ecx, edx);   \
+   break;  \
+   }   \
+   } while (0)
+
 #endif
diff --git a/arch/x86/kernel/cpu/vmware.c 

[PATCH 0/6] VMware hypercalls enhancements

2023-11-22 Thread Alexey Makhalov
VMware hypercalls invocations were all spread out across the kernel
implementing same ABI as in-place asm-inline. With encrypted memory
and confidential computing it became harder to maintain every changes
in these hypercall implementations.

Intention of this patchset is to introduce arch independent VMware
hypercall API layer other subsystems such as device drivers can call
to, while hiding architecture specific implementation behind.

Second patch introduces the vmware_hypercall low and high bandwidth
families of functions, with little enhancements there.
Sixth patch adds tdx hypercall support

arm64 implementation of vmware_hypercalls is in drivers/gpu/drm/
vmwgfx/vmwgfx_msg_arm64.h and going to be moved to arch/arm64 with
a separate patchset with the introduction of VMware Linux guest
support for arm64.

No functional changes in drivers/input/mouse/vmmouse.c and
drivers/ptp/ptp_vmw.c

Alexey Makhalov (6):
  x86/vmware: Move common macros to vmware.h
  x86/vmware: Introduce vmware_hypercall API
  ptp/vmware: Use vmware_hypercall API
  input/vmmouse: Use vmware_hypercall API
  drm/vmwgfx: Use vmware_hypercall API
  x86/vmware: Add TDX hypercall support

 arch/x86/include/asm/vmware.h | 327 --
 arch/x86/kernel/cpu/vmware.c  | 101 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_msg.c   | 173 
 drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h | 197 +
 drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h   | 185 
 drivers/input/mouse/vmmouse.c |  76 ++---
 drivers/ptp/ptp_vmw.c |  12 +-
 7 files changed, 551 insertions(+), 520 deletions(-)

-- 
2.39.0



[PATCH 6/6] x86/vmware: Add TDX hypercall support

2023-11-22 Thread Alexey Makhalov
VMware hypercalls use I/O port, VMCALL or VMMCALL instructions.
Add __tdx_hypercall path to support TDX guests.

No change in high bandwidth hypercalls, as only low bandwidth
ones are supported for TDX guests.

Co-developed-by: Tim Merrifield 
Signed-off-by: Tim Merrifield 
Signed-off-by: Alexey Makhalov 
---
 arch/x86/include/asm/vmware.h | 72 +++
 arch/x86/kernel/cpu/vmware.c  |  9 +
 2 files changed, 81 insertions(+)

diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index 17091eba68cb..cd58ff8ef1af 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -40,6 +40,54 @@
 
 extern u8 vmware_hypercall_mode;
 
+#define VMWARE_TDX_VENDOR_LEAF 0x1AF7E4909ULL
+#define VMWARE_TDX_HCALL_FUNC  1
+
+extern void vmware_tdx_hypercall_args(struct tdx_module_args *args);
+
+/*
+ * TDCALL[TDG.VP.VMCALL] uses rax (arg0) and rcx (arg2), while the use of
+ * rbp (arg6) is discouraged by the TDX specification. Therefore, we
+ * remap those registers to r12, r13 and r14, respectively.
+ */
+static inline
+unsigned long vmware_tdx_hypercall(unsigned long cmd, unsigned long in1,
+  unsigned long in3, unsigned long in4,
+  unsigned long in5, unsigned long in6,
+  uint32_t *out1, uint32_t *out2,
+  uint32_t *out3, uint32_t *out4,
+  uint32_t *out5, uint32_t *out6)
+{
+   struct tdx_module_args args = {
+   .r10 = VMWARE_TDX_VENDOR_LEAF,
+   .r11 = VMWARE_TDX_HCALL_FUNC,
+   .r12 = VMWARE_HYPERVISOR_MAGIC,
+   .r13 = cmd,
+   .rbx = in1,
+   .rdx = in3,
+   .rsi = in4,
+   .rdi = in5,
+   .r14 = in6,
+   };
+
+   vmware_tdx_hypercall_args();
+
+   if (out1)
+   *out1 = args.rbx;
+   if (out2)
+   *out2 = args.r13;
+   if (out3)
+   *out3 = args.rdx;
+   if (out4)
+   *out4 = args.rsi;
+   if (out5)
+   *out5 = args.rdi;
+   if (out6)
+   *out6 = args.r14;
+
+   return args.r12;
+}
+
 /*
  * The low bandwidth call. The low word of edx is presumed to have OUT bit
  * set. The high word of edx may contain input data from the caller.
@@ -67,6 +115,10 @@ unsigned long vmware_hypercall1(unsigned long cmd, unsigned 
long in1)
 {
unsigned long out0;
 
+   if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+   return vmware_tdx_hypercall(cmd, in1, 0, 0, 0, 0, NULL, NULL,
+   NULL, NULL, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -85,6 +137,10 @@ unsigned long vmware_hypercall3(unsigned long cmd, unsigned 
long in1,
 {
unsigned long out0;
 
+   if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+   return vmware_tdx_hypercall(cmd, in1, 0, 0, 0, 0, out1, out2,
+   NULL, NULL, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=b" (*out1), "=c" (*out2)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -104,6 +160,10 @@ unsigned long vmware_hypercall4(unsigned long cmd, 
unsigned long in1,
 {
unsigned long out0;
 
+   if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+   return vmware_tdx_hypercall(cmd, in1, 0, 0, 0, 0, out1, out2,
+   out3, NULL, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -123,6 +183,10 @@ unsigned long vmware_hypercall5(unsigned long cmd, 
unsigned long in1,
 {
unsigned long out0;
 
+   if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+   return vmware_tdx_hypercall(cmd, in1, in3, in4, in5, 0, NULL,
+   out2, NULL, NULL, NULL, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=c" (*out2)
: [port] "i" (VMWARE_HYPERVISOR_PORT),
@@ -145,6 +209,10 @@ unsigned long vmware_hypercall6(unsigned long cmd, 
unsigned long in1,
 {
unsigned long out0;
 
+   if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+   return vmware_tdx_hypercall(cmd, in1, in3, 0, 0, 0, NULL, out2,
+   out3, out4, out5, NULL);
+
asm_inline volatile (VMWARE_HYPERCALL
: "=a" (out0), "=c" (*out2), "=d" (*out3), "=S" (*out4),
  "=D" (*out5)
@@ -166,6 +234,10 @@ unsigned long vmware_hypercall7(unsigned long cmd, 
unsigned long in1,
 {
unsigned long out0;
 
+   if 

[PATCH 2/6] x86/vmware: Introduce vmware_hypercall API

2023-11-22 Thread Alexey Makhalov
Introducing vmware_hypercall family of functions as a common
implementation to be used by the VMware guest code and virtual
device drivers in arhitecture independent manner.

By analogy with KVM hypercall API, vmware_hypercallX and
vmware_hypercall_hb_{out,in} set of functions was added to
achieve that. Architecture specific implementation should be
hidden inside.

It will simplify future enhancements in VMware hypercalls such
as SEV-ES and TDX related changes without needs to modify a
caller in device drivers code.

Current implementation extends an idea from commit bac7b4e84323
("x86/vmware: Update platform detection code for VMCALL/VMMCALL
hypercalls") to have a slow, but safe path in VMWARE_HYPERCALL
when alternatives are not yet applied. This logic was inherited
from VMWARE_CMD from the commit mentioned above. Default
alternative code was optimized by size to reduse excessive nop
alignment once alternatives are applied. Total default code size
is 26 bytes, in worse case (3 bytes alternative) remaining 23
bytes will be aligned by only 3 long NOP instructions.

Signed-off-by: Alexey Makhalov 
---
 arch/x86/include/asm/vmware.h | 262 ++
 arch/x86/kernel/cpu/vmware.c  |  35 ++---
 2 files changed, 220 insertions(+), 77 deletions(-)

diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index 8cabf4a577bf..17091eba68cb 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -40,69 +40,219 @@
 
 extern u8 vmware_hypercall_mode;
 
-/* The low bandwidth call. The low word of edx is presumed clear. */
-#define VMWARE_HYPERCALL   \
-   ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT) ", %%dx; " \
- "inl (%%dx), %%eax",  \
- "vmcall", X86_FEATURE_VMCALL, \
- "vmmcall", X86_FEATURE_VMW_VMMCALL)
-
 /*
- * The high bandwidth out call. The low word of edx is presumed to have the
- * HB and OUT bits set.
+ * The low bandwidth call. The low word of edx is presumed to have OUT bit
+ * set. The high word of edx may contain input data from the caller.
  */
-#define VMWARE_HYPERCALL_HB_OUT
\
-   ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; 
" \
- "rep outsb",  \
+#define VMWARE_HYPERCALL   \
+   ALTERNATIVE_3("cmpb $"  \
+   __stringify(CPUID_VMWARE_FEATURES_ECX_VMMCALL)  \
+   ", %[mode]\n\t" \
+ "jg 2f\n\t"   \
+ "je 1f\n\t"   \
+ "movw %[port], %%dx\n\t"  \
+ "inl (%%dx), %%eax\n\t"   \
+ "jmp 3f\n\t"  \
+ "1: vmmcall\n\t"  \
+ "jmp 3f\n\t"  \
+ "2: vmcall\n\t"   \
+ "3:\n\t", \
+ "movw %[port], %%dx\n\t"  \
+ "inl (%%dx), %%eax", X86_FEATURE_HYPERVISOR,  \
  "vmcall", X86_FEATURE_VMCALL, \
  "vmmcall", X86_FEATURE_VMW_VMMCALL)
 
+static inline
+unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)
+{
+   unsigned long out0;
+
+   asm_inline volatile (VMWARE_HYPERCALL
+   : "=a" (out0)
+   : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ [mode] "m" (vmware_hypercall_mode),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (0)
+   : "cc", "memory");
+   return out0;
+}
+
+static inline
+unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1,
+   uint32_t *out1, uint32_t *out2)
+{
+   unsigned long out0;
+
+   asm_inline volatile (VMWARE_HYPERCALL
+   : "=a" (out0), "=b" (*out1), "=c" (*out2)
+   : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ [mode] "m" (vmware_hypercall_mode),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (0)
+   : "cc", "memory");
+   return out0;
+}
+
+static inline
+unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1,
+   uint32_t *out1, uint32_t *out2,
+   uint32_t *out3)
+{
+   

[PATCH 1/6] x86/vmware: Move common macros to vmware.h

2023-11-22 Thread Alexey Makhalov
Move VMware hypercall macros to vmware.h as a preparation step
for the next commit. No functional changes besides exporting
vmware_hypercall_mode symbol.

Signed-off-by: Alexey Makhalov 
---
 arch/x86/include/asm/vmware.h | 69 ++-
 arch/x86/kernel/cpu/vmware.c  | 57 +++--
 2 files changed, 66 insertions(+), 60 deletions(-)

diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index ac9fc51e2b18..8cabf4a577bf 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -8,25 +8,37 @@
 
 /*
  * The hypercall definitions differ in the low word of the %edx argument
- * in the following way: the old port base interface uses the port
- * number to distinguish between high- and low bandwidth versions.
+ * in the following way: the old I/O port based interface uses the port
+ * number to distinguish between high- and low bandwidth versions, and
+ * uses IN/OUT instructions to define transfer direction.
  *
  * The new vmcall interface instead uses a set of flags to select
  * bandwidth mode and transfer direction. The flags should be loaded
  * into %dx by any user and are automatically replaced by the port
- * number if the VMWARE_HYPERVISOR_PORT method is used.
+ * number if the I/O port method is used.
  *
  * In short, new driver code should strictly use the new definition of
  * %dx content.
  */
 
-/* Old port-based version */
-#define VMWARE_HYPERVISOR_PORT0x5658
-#define VMWARE_HYPERVISOR_PORT_HB 0x5659
+#define VMWARE_HYPERVISOR_HB   BIT(0)
+#define VMWARE_HYPERVISOR_OUT  BIT(1)
 
-/* Current vmcall / vmmcall version */
-#define VMWARE_HYPERVISOR_HB   BIT(0)
-#define VMWARE_HYPERVISOR_OUT  BIT(1)
+#define VMWARE_HYPERVISOR_PORT 0x5658
+#define VMWARE_HYPERVISOR_PORT_HB  (VMWARE_HYPERVISOR_PORT | \
+VMWARE_HYPERVISOR_HB)
+
+#define VMWARE_HYPERVISOR_MAGIC0x564D5868U
+
+#define VMWARE_CMD_GETVERSION  10
+#define VMWARE_CMD_GETHZ   45
+#define VMWARE_CMD_GETVCPU_INFO68
+#define VMWARE_CMD_STEALCLOCK  91
+
+#define CPUID_VMWARE_FEATURES_ECX_VMMCALL  BIT(0)
+#define CPUID_VMWARE_FEATURES_ECX_VMCALL   BIT(1)
+
+extern u8 vmware_hypercall_mode;
 
 /* The low bandwidth call. The low word of edx is presumed clear. */
 #define VMWARE_HYPERCALL   \
@@ -54,4 +66,43 @@
  "rep insb",   \
  "vmcall", X86_FEATURE_VMCALL, \
  "vmmcall", X86_FEATURE_VMW_VMMCALL)
+
+#define VMWARE_PORT(cmd, eax, ebx, ecx, edx)   \
+   __asm__("inl (%%dx), %%eax" :   \
+   "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :\
+   "a"(VMWARE_HYPERVISOR_MAGIC),   \
+   "c"(VMWARE_CMD_##cmd),  \
+   "d"(VMWARE_HYPERVISOR_PORT), "b"(UINT_MAX) :\
+   "memory")
+
+#define VMWARE_VMCALL(cmd, eax, ebx, ecx, edx) \
+   __asm__("vmcall" :  \
+   "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :\
+   "a"(VMWARE_HYPERVISOR_MAGIC),   \
+   "c"(VMWARE_CMD_##cmd),  \
+   "d"(0), "b"(UINT_MAX) : \
+   "memory")
+
+#define VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx)
\
+   __asm__("vmmcall" : \
+   "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :\
+   "a"(VMWARE_HYPERVISOR_MAGIC),   \
+   "c"(VMWARE_CMD_##cmd),  \
+   "d"(0), "b"(UINT_MAX) : \
+   "memory")
+
+#define VMWARE_CMD(cmd, eax, ebx, ecx, edx) do {   \
+   switch (vmware_hypercall_mode) {\
+   case CPUID_VMWARE_FEATURES_ECX_VMCALL:  \
+   VMWARE_VMCALL(cmd, eax, ebx, ecx, edx); \
+   break;  \
+   case CPUID_VMWARE_FEATURES_ECX_VMMCALL: \
+   VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx);\
+   break;  \
+   default:\
+   VMWARE_PORT(cmd, eax, ebx, ecx, edx);   \
+   break;  \
+   }   \
+   } while (0)
+
 #endif
diff --git a/arch/x86/kernel/cpu/vmware.c 

[PATCH 4/6] input/vmmouse: Use vmware_hypercall API

2023-11-22 Thread Alexey Makhalov
Switch from VMWARE_HYPERCALL macro to vmware_hypercall API.
Eliminate arch specific code. No functional changes intended.

Signed-off-by: Alexey Makhalov 
---
 drivers/input/mouse/vmmouse.c | 76 ++-
 1 file changed, 22 insertions(+), 54 deletions(-)

diff --git a/drivers/input/mouse/vmmouse.c b/drivers/input/mouse/vmmouse.c
index ea9eff7c8099..fb1d986a6895 100644
--- a/drivers/input/mouse/vmmouse.c
+++ b/drivers/input/mouse/vmmouse.c
@@ -21,19 +21,16 @@
 #include "psmouse.h"
 #include "vmmouse.h"
 
-#define VMMOUSE_PROTO_MAGIC0x564D5868U
-
 /*
  * Main commands supported by the vmmouse hypervisor port.
  */
-#define VMMOUSE_PROTO_CMD_GETVERSION   10
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_DATA  39
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS40
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND   41
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_RESTRICT   86
+#define VMWARE_CMD_ABSPOINTER_DATA 39
+#define VMWARE_CMD_ABSPOINTER_STATUS   40
+#define VMWARE_CMD_ABSPOINTER_COMMAND  41
+#define VMWARE_CMD_ABSPOINTER_RESTRICT 86
 
 /*
- * Subcommands for VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND
+ * Subcommands for VMWARE_CMD_ABSPOINTER_COMMAND
  */
 #define VMMOUSE_CMD_ENABLE 0x45414552U
 #define VMMOUSE_CMD_DISABLE0x00f5U
@@ -76,28 +73,6 @@ struct vmmouse_data {
char dev_name[128];
 };
 
-/*
- * Hypervisor-specific bi-directional communication channel
- * implementing the vmmouse protocol. Should never execute on
- * bare metal hardware.
- */
-#define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4)  \
-({ \
-   unsigned long __dummy1, __dummy2;   \
-   __asm__ __volatile__ (VMWARE_HYPERCALL :\
-   "=a"(out1), \
-   "=b"(out2), \
-   "=c"(out3), \
-   "=d"(out4), \
-   "=S"(__dummy1), \
-   "=D"(__dummy2) :\
-   "a"(VMMOUSE_PROTO_MAGIC),   \
-   "b"(in1),   \
-   "c"(VMMOUSE_PROTO_CMD_##cmd),   \
-   "d"(0) :\
-   "memory");  \
-})
-
 /**
  * vmmouse_report_button - report button state on the correct input device
  *
@@ -145,14 +120,12 @@ static psmouse_ret_t vmmouse_report_events(struct psmouse 
*psmouse)
struct input_dev *abs_dev = priv->abs_dev;
struct input_dev *pref_dev;
u32 status, x, y, z;
-   u32 dummy1, dummy2, dummy3;
unsigned int queue_length;
unsigned int count = 255;
 
while (count--) {
/* See if we have motion data. */
-   VMMOUSE_CMD(ABSPOINTER_STATUS, 0,
-   status, dummy1, dummy2, dummy3);
+   status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0);
if ((status & VMMOUSE_ERROR) == VMMOUSE_ERROR) {
psmouse_err(psmouse, "failed to fetch status data\n");
/*
@@ -172,7 +145,8 @@ static psmouse_ret_t vmmouse_report_events(struct psmouse 
*psmouse)
}
 
/* Now get it */
-   VMMOUSE_CMD(ABSPOINTER_DATA, 4, status, x, y, z);
+   status = vmware_hypercall4(VMWARE_CMD_ABSPOINTER_DATA, 4,
+  , , );
 
/*
 * And report what we've got. Prefer to report button
@@ -247,14 +221,10 @@ static psmouse_ret_t vmmouse_process_byte(struct psmouse 
*psmouse)
 static void vmmouse_disable(struct psmouse *psmouse)
 {
u32 status;
-   u32 dummy1, dummy2, dummy3, dummy4;
-
-   VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE,
-   dummy1, dummy2, dummy3, dummy4);
 
-   VMMOUSE_CMD(ABSPOINTER_STATUS, 0,
-   status, dummy1, dummy2, dummy3);
+   vmware_hypercall1(VMWARE_CMD_ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE);
 
+   status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0);
if ((status & VMMOUSE_ERROR) != VMMOUSE_ERROR)
psmouse_warn(psmouse, "failed to disable vmmouse device\n");
 }
@@ -271,26 +241,24 @@ static void vmmouse_disable(struct psmouse *psmouse)
 static int vmmouse_enable(struct psmouse *psmouse)
 {
u32 status, version;
-   u32 dummy1, dummy2, dummy3, dummy4;
 
/*
 * Try enabling the device. If successful, we should be able to
 * read valid version ID back from it.
 */
-   VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_ENABLE,
-   dummy1, dummy2, dummy3, dummy4);
+   vmware_hypercall1(VMWARE_CMD_ABSPOINTER_COMMAND, VMMOUSE_CMD_ENABLE);
 
/*
 * See if version ID can be 

[PATCH 4/6] input/vmmouse: Use vmware_hypercall API

2023-11-22 Thread Alexey Makhalov
Switch from VMWARE_HYPERCALL macro to vmware_hypercall API.
Eliminate arch specific code. No functional changes intended.

Signed-off-by: Alexey Makhalov 
---
 drivers/input/mouse/vmmouse.c | 76 ++-
 1 file changed, 22 insertions(+), 54 deletions(-)

diff --git a/drivers/input/mouse/vmmouse.c b/drivers/input/mouse/vmmouse.c
index ea9eff7c8099..fb1d986a6895 100644
--- a/drivers/input/mouse/vmmouse.c
+++ b/drivers/input/mouse/vmmouse.c
@@ -21,19 +21,16 @@
 #include "psmouse.h"
 #include "vmmouse.h"
 
-#define VMMOUSE_PROTO_MAGIC0x564D5868U
-
 /*
  * Main commands supported by the vmmouse hypervisor port.
  */
-#define VMMOUSE_PROTO_CMD_GETVERSION   10
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_DATA  39
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS40
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND   41
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_RESTRICT   86
+#define VMWARE_CMD_ABSPOINTER_DATA 39
+#define VMWARE_CMD_ABSPOINTER_STATUS   40
+#define VMWARE_CMD_ABSPOINTER_COMMAND  41
+#define VMWARE_CMD_ABSPOINTER_RESTRICT 86
 
 /*
- * Subcommands for VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND
+ * Subcommands for VMWARE_CMD_ABSPOINTER_COMMAND
  */
 #define VMMOUSE_CMD_ENABLE 0x45414552U
 #define VMMOUSE_CMD_DISABLE0x00f5U
@@ -76,28 +73,6 @@ struct vmmouse_data {
char dev_name[128];
 };
 
-/*
- * Hypervisor-specific bi-directional communication channel
- * implementing the vmmouse protocol. Should never execute on
- * bare metal hardware.
- */
-#define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4)  \
-({ \
-   unsigned long __dummy1, __dummy2;   \
-   __asm__ __volatile__ (VMWARE_HYPERCALL :\
-   "=a"(out1), \
-   "=b"(out2), \
-   "=c"(out3), \
-   "=d"(out4), \
-   "=S"(__dummy1), \
-   "=D"(__dummy2) :\
-   "a"(VMMOUSE_PROTO_MAGIC),   \
-   "b"(in1),   \
-   "c"(VMMOUSE_PROTO_CMD_##cmd),   \
-   "d"(0) :\
-   "memory");  \
-})
-
 /**
  * vmmouse_report_button - report button state on the correct input device
  *
@@ -145,14 +120,12 @@ static psmouse_ret_t vmmouse_report_events(struct psmouse 
*psmouse)
struct input_dev *abs_dev = priv->abs_dev;
struct input_dev *pref_dev;
u32 status, x, y, z;
-   u32 dummy1, dummy2, dummy3;
unsigned int queue_length;
unsigned int count = 255;
 
while (count--) {
/* See if we have motion data. */
-   VMMOUSE_CMD(ABSPOINTER_STATUS, 0,
-   status, dummy1, dummy2, dummy3);
+   status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0);
if ((status & VMMOUSE_ERROR) == VMMOUSE_ERROR) {
psmouse_err(psmouse, "failed to fetch status data\n");
/*
@@ -172,7 +145,8 @@ static psmouse_ret_t vmmouse_report_events(struct psmouse 
*psmouse)
}
 
/* Now get it */
-   VMMOUSE_CMD(ABSPOINTER_DATA, 4, status, x, y, z);
+   status = vmware_hypercall4(VMWARE_CMD_ABSPOINTER_DATA, 4,
+  , , );
 
/*
 * And report what we've got. Prefer to report button
@@ -247,14 +221,10 @@ static psmouse_ret_t vmmouse_process_byte(struct psmouse 
*psmouse)
 static void vmmouse_disable(struct psmouse *psmouse)
 {
u32 status;
-   u32 dummy1, dummy2, dummy3, dummy4;
-
-   VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE,
-   dummy1, dummy2, dummy3, dummy4);
 
-   VMMOUSE_CMD(ABSPOINTER_STATUS, 0,
-   status, dummy1, dummy2, dummy3);
+   vmware_hypercall1(VMWARE_CMD_ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE);
 
+   status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0);
if ((status & VMMOUSE_ERROR) != VMMOUSE_ERROR)
psmouse_warn(psmouse, "failed to disable vmmouse device\n");
 }
@@ -271,26 +241,24 @@ static void vmmouse_disable(struct psmouse *psmouse)
 static int vmmouse_enable(struct psmouse *psmouse)
 {
u32 status, version;
-   u32 dummy1, dummy2, dummy3, dummy4;
 
/*
 * Try enabling the device. If successful, we should be able to
 * read valid version ID back from it.
 */
-   VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_ENABLE,
-   dummy1, dummy2, dummy3, dummy4);
+   vmware_hypercall1(VMWARE_CMD_ABSPOINTER_COMMAND, VMMOUSE_CMD_ENABLE);
 
/*
 * See if version ID can be 

[PATCH 2/6] x86/vmware: Introduce vmware_hypercall API

2023-11-22 Thread Alexey Makhalov
Introducing vmware_hypercall family of functions as a common
implementation to be used by the VMware guest code and virtual
device drivers in arhitecture independent manner.

By analogy with KVM hypercall API, vmware_hypercallX and
vmware_hypercall_hb_{out,in} set of functions was added to
achieve that. Architecture specific implementation should be
hidden inside.

It will simplify future enhancements in VMware hypercalls such
as SEV-ES and TDX related changes without needs to modify a
caller in device drivers code.

Current implementation extends an idea from commit bac7b4e84323
("x86/vmware: Update platform detection code for VMCALL/VMMCALL
hypercalls") to have a slow, but safe path in VMWARE_HYPERCALL
when alternatives are not yet applied. This logic was inherited
from VMWARE_CMD from the commit mentioned above. Default
alternative code was optimized by size to reduse excessive nop
alignment once alternatives are applied. Total default code size
is 26 bytes, in worse case (3 bytes alternative) remaining 23
bytes will be aligned by only 3 long NOP instructions.

Signed-off-by: Alexey Makhalov 
---
 arch/x86/include/asm/vmware.h | 262 ++
 arch/x86/kernel/cpu/vmware.c  |  35 ++---
 2 files changed, 220 insertions(+), 77 deletions(-)

diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index 8cabf4a577bf..17091eba68cb 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -40,69 +40,219 @@
 
 extern u8 vmware_hypercall_mode;
 
-/* The low bandwidth call. The low word of edx is presumed clear. */
-#define VMWARE_HYPERCALL   \
-   ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT) ", %%dx; " \
- "inl (%%dx), %%eax",  \
- "vmcall", X86_FEATURE_VMCALL, \
- "vmmcall", X86_FEATURE_VMW_VMMCALL)
-
 /*
- * The high bandwidth out call. The low word of edx is presumed to have the
- * HB and OUT bits set.
+ * The low bandwidth call. The low word of edx is presumed to have OUT bit
+ * set. The high word of edx may contain input data from the caller.
  */
-#define VMWARE_HYPERCALL_HB_OUT
\
-   ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; 
" \
- "rep outsb",  \
+#define VMWARE_HYPERCALL   \
+   ALTERNATIVE_3("cmpb $"  \
+   __stringify(CPUID_VMWARE_FEATURES_ECX_VMMCALL)  \
+   ", %[mode]\n\t" \
+ "jg 2f\n\t"   \
+ "je 1f\n\t"   \
+ "movw %[port], %%dx\n\t"  \
+ "inl (%%dx), %%eax\n\t"   \
+ "jmp 3f\n\t"  \
+ "1: vmmcall\n\t"  \
+ "jmp 3f\n\t"  \
+ "2: vmcall\n\t"   \
+ "3:\n\t", \
+ "movw %[port], %%dx\n\t"  \
+ "inl (%%dx), %%eax", X86_FEATURE_HYPERVISOR,  \
  "vmcall", X86_FEATURE_VMCALL, \
  "vmmcall", X86_FEATURE_VMW_VMMCALL)
 
+static inline
+unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)
+{
+   unsigned long out0;
+
+   asm_inline volatile (VMWARE_HYPERCALL
+   : "=a" (out0)
+   : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ [mode] "m" (vmware_hypercall_mode),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (0)
+   : "cc", "memory");
+   return out0;
+}
+
+static inline
+unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1,
+   uint32_t *out1, uint32_t *out2)
+{
+   unsigned long out0;
+
+   asm_inline volatile (VMWARE_HYPERCALL
+   : "=a" (out0), "=b" (*out1), "=c" (*out2)
+   : [port] "i" (VMWARE_HYPERVISOR_PORT),
+ [mode] "m" (vmware_hypercall_mode),
+ "a" (VMWARE_HYPERVISOR_MAGIC),
+ "b" (in1),
+ "c" (cmd),
+ "d" (0)
+   : "cc", "memory");
+   return out0;
+}
+
+static inline
+unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1,
+   uint32_t *out1, uint32_t *out2,
+   uint32_t *out3)
+{
+   

[PATCH 5/6] drm/vmwgfx: Use vmware_hypercall API

2023-11-22 Thread Alexey Makhalov
Switch from VMWARE_HYPERCALL macro to vmware_hypercall API.
Eliminate arch specific code.

drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h: implement arm64 variant of
vmware_hypercall here. To be moved to arch/arm64/include/asm/vmware.h
later.

Signed-off-by: Alexey Makhalov 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_msg.c   | 173 +++
 drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h | 197 +++---
 drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h   | 185 
 3 files changed, 197 insertions(+), 358 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
index 2651fe0ef518..1f15990d3934 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
@@ -48,8 +48,6 @@
 
 #define RETRIES 3
 
-#define VMW_HYPERVISOR_MAGIC0x564D5868
-
 #define VMW_PORT_CMD_MSG30
 #define VMW_PORT_CMD_HB_MSG 0
 #define VMW_PORT_CMD_OPEN_CHANNEL  (MSG_TYPE_OPEN << 16 | VMW_PORT_CMD_MSG)
@@ -104,20 +102,18 @@ static const char* const 
mksstat_kern_name_desc[MKSSTAT_KERN_COUNT][2] =
  */
 static int vmw_open_channel(struct rpc_channel *channel, unsigned int protocol)
 {
-   unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
+   u32 ecx, edx, esi, edi;
 
-   VMW_PORT(VMW_PORT_CMD_OPEN_CHANNEL,
-   (protocol | GUESTMSG_FLAG_COOKIE), si, di,
-   0,
-   VMW_HYPERVISOR_MAGIC,
-   eax, ebx, ecx, edx, si, di);
+   vmware_hypercall6(VMW_PORT_CMD_OPEN_CHANNEL,
+ (protocol | GUESTMSG_FLAG_COOKIE), 0,
+ , , , );
 
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
return -EINVAL;
 
channel->channel_id  = HIGH_WORD(edx);
-   channel->cookie_high = si;
-   channel->cookie_low  = di;
+   channel->cookie_high = esi;
+   channel->cookie_low  = edi;
 
return 0;
 }
@@ -133,17 +129,13 @@ static int vmw_open_channel(struct rpc_channel *channel, 
unsigned int protocol)
  */
 static int vmw_close_channel(struct rpc_channel *channel)
 {
-   unsigned long eax, ebx, ecx, edx, si, di;
-
-   /* Set up additional parameters */
-   si  = channel->cookie_high;
-   di  = channel->cookie_low;
+   u32 ecx;
 
-   VMW_PORT(VMW_PORT_CMD_CLOSE_CHANNEL,
-   0, si, di,
-   channel->channel_id << 16,
-   VMW_HYPERVISOR_MAGIC,
-   eax, ebx, ecx, edx, si, di);
+   vmware_hypercall5(VMW_PORT_CMD_CLOSE_CHANNEL,
+ 0, channel->channel_id << 16,
+ channel->cookie_high,
+ channel->cookie_low,
+ );
 
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
return -EINVAL;
@@ -163,24 +155,18 @@ static int vmw_close_channel(struct rpc_channel *channel)
 static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
 const char *msg, bool hb)
 {
-   unsigned long si, di, eax, ebx, ecx, edx;
+   u32 ebx, ecx;
unsigned long msg_len = strlen(msg);
 
/* HB port can't access encrypted memory. */
if (hb && !cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
-   unsigned long bp = channel->cookie_high;
-   u32 channel_id = (channel->channel_id << 16);
-
-   si = (uintptr_t) msg;
-   di = channel->cookie_low;
-
-   VMW_PORT_HB_OUT(
+   vmware_hypercall_hb_out(
(MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
-   msg_len, si, di,
-   VMWARE_HYPERVISOR_HB | channel_id |
-   VMWARE_HYPERVISOR_OUT,
-   VMW_HYPERVISOR_MAGIC, bp,
-   eax, ebx, ecx, edx, si, di);
+   msg_len,
+   channel->channel_id << 16,
+   (uintptr_t) msg, channel->cookie_low,
+   channel->cookie_high,
+   );
 
return ebx;
}
@@ -194,14 +180,13 @@ static unsigned long vmw_port_hb_out(struct rpc_channel 
*channel,
memcpy(, msg, bytes);
msg_len -= bytes;
msg += bytes;
-   si = channel->cookie_high;
-   di = channel->cookie_low;
-
-   VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_SENDPAYLOAD << 16),
-word, si, di,
-channel->channel_id << 16,
-VMW_HYPERVISOR_MAGIC,
-eax, ebx, ecx, edx, si, di);
+
+   vmware_hypercall5(VMW_PORT_CMD_MSG |
+ (MSG_TYPE_SENDPAYLOAD << 16),
+ word, channel->channel_id << 16,
+ channel->cookie_high,
+ channel->cookie_low,
+ 

[PATCH 0/6] VMware hypercalls enhancements

2023-11-22 Thread Alexey Makhalov
VMware hypercalls invocations were all spread out across the kernel
implementing same ABI as in-place asm-inline. With encrypted memory
and confidential computing it became harder to maintain every changes
in these hypercall implementations.

Intention of this patchset is to introduce arch independent VMware
hypercall API layer other subsystems such as device drivers can call
to, while hiding architecture specific implementation behind.

Second patch introduces the vmware_hypercall low and high bandwidth
families of functions, with little enhancements there.
Sixth patch adds tdx hypercall support

arm64 implementation of vmware_hypercalls is in drivers/gpu/drm/
vmwgfx/vmwgfx_msg_arm64.h and going to be moved to arch/arm64 with
a separate patchset with the introduction of VMware Linux guest
support for arm64.

No functional changes in drivers/input/mouse/vmmouse.c and
drivers/ptp/ptp_vmw.c

Alexey Makhalov (6):
  x86/vmware: Move common macros to vmware.h
  x86/vmware: Introduce vmware_hypercall API
  ptp/vmware: Use vmware_hypercall API
  input/vmmouse: Use vmware_hypercall API
  drm/vmwgfx: Use vmware_hypercall API
  x86/vmware: Add TDX hypercall support

 arch/x86/include/asm/vmware.h | 327 --
 arch/x86/kernel/cpu/vmware.c  | 101 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_msg.c   | 173 
 drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h | 197 +
 drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h   | 185 
 drivers/input/mouse/vmmouse.c |  76 ++---
 drivers/ptp/ptp_vmw.c |  12 +-
 7 files changed, 551 insertions(+), 520 deletions(-)

-- 
2.39.0




[PATCH 3/6] ptp/vmware: Use vmware_hypercall API

2023-11-22 Thread Alexey Makhalov
Switch from VMWARE_HYPERCALL macro to vmware_hypercall API.
Eliminate arch specific code. No functional changes intended.

Signed-off-by: Alexey Makhalov 
---
 drivers/ptp/ptp_vmw.c | 12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/ptp/ptp_vmw.c b/drivers/ptp/ptp_vmw.c
index 27c5547aa8a9..e5bb521b9b82 100644
--- a/drivers/ptp/ptp_vmw.c
+++ b/drivers/ptp/ptp_vmw.c
@@ -14,7 +14,6 @@
 #include 
 #include 
 
-#define VMWARE_MAGIC 0x564D5868
 #define VMWARE_CMD_PCLK(nr) ((nr << 16) | 97)
 #define VMWARE_CMD_PCLK_GETTIME VMWARE_CMD_PCLK(0)
 
@@ -24,15 +23,10 @@ static struct ptp_clock *ptp_vmw_clock;
 
 static int ptp_vmw_pclk_read(u64 *ns)
 {
-   u32 ret, nsec_hi, nsec_lo, unused1, unused2, unused3;
-
-   asm volatile (VMWARE_HYPERCALL :
-   "=a"(ret), "=b"(nsec_hi), "=c"(nsec_lo), "=d"(unused1),
-   "=S"(unused2), "=D"(unused3) :
-   "a"(VMWARE_MAGIC), "b"(0),
-   "c"(VMWARE_CMD_PCLK_GETTIME), "d"(0) :
-   "memory");
+   u32 ret, nsec_hi, nsec_lo;
 
+   ret = vmware_hypercall3(VMWARE_CMD_PCLK_GETTIME, 0,
+   _hi, _lo);
if (ret == 0)
*ns = ((u64)nsec_hi << 32) | nsec_lo;
return ret;
-- 
2.39.0



Re: drm scheduler redesign causes deadlocks [extended repost]

2023-11-22 Thread Luben Tuikov
On 2023-11-21 04:00, Bert Karwatzki wrote:
> Since linux-next-20231115 my linux system (debian sid on msi alpha 15 laptop)
> suffers from random deadlocks which can occur after  30 - 180min of usage. 
> These
> deadlocks can be actively provoked by creating high system load (usually by
> compiling a kernel with make -j NRCPUS) and the opening instances of 
> libreoffice
> --writer until the system GUI locks (the mouse cursor can still be moved but 
> the
> screen is frozen). In this state ssh'ing into the machine is still possible 
> and
> at least sometimes log messages about hung tasks appear in /var/log/kern.log.
> 
> More info can be found here:
> https://gitlab.freedesktop.org/drm/amd/-/issues/2994
> 
> Using the method described to trigger the bug I bisected the problem in the
> linux-next and drm-misc trees to give commit f3123c2590005 as the problem.
> As this simple patch fixes the problem
> 
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c
> b/drivers/gpu/drm/scheduler/sched_main.c
> index 044a8c4875ba..25b97db1b623 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -1029,9 +1029,8 @@ EXPORT_SYMBOL(drm_sched_job_cleanup);
>  void drm_sched_wakeup(struct drm_gpu_scheduler *sched,
>   struct drm_sched_entity *entity)
>  {
> -   if (drm_sched_entity_is_ready(entity))
> -   if (drm_sched_can_queue(sched, entity))
> -   drm_sched_run_job_queue(sched);
> +   if (drm_sched_can_queue(sched, entity))
> +   drm_sched_run_job_queue(sched);
>  }
>  
>  /**
> 
> there might be in the entity->dependency branch of drm_sched_entity_is_ready
> (some kind of circular dependencies ...).
> 
> To see if the change to drm_sched_wakeup is the actual cause of the problem or
> if this problem has been cause by the redesign of the drm scheduler in linux
> next-20231115+, I created the following patch for linux-6.6.0:
> 
> diff --git a/drivers/gpu/drm/scheduler/sched_entity.c
> b/drivers/gpu/drm/scheduler/sched_entity.c
> index a42763e1429d..dc2abd299aeb 100644
> --- a/drivers/gpu/drm/scheduler/sched_entity.c
> +++ b/drivers/gpu/drm/scheduler/sched_entity.c
> @@ -358,7 +358,7 @@ static void drm_sched_entity_wakeup(struct dma_fence *f,
>  container_of(cb, struct drm_sched_entity, cb);
> 
>  drm_sched_entity_clear_dep(f, cb);
> - drm_sched_wakeup_if_can_queue(entity->rq->sched);
> + drm_sched_wakeup_if_can_queue(entity->rq->sched, entity);
>  }
> 
>  /**
> @@ -590,7 +590,7 @@ void drm_sched_entity_push_job(struct drm_sched_job
> *sched_job)
>  if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
>  drm_sched_rq_update_fifo(entity, submit_ts);
> 
> - drm_sched_wakeup_if_can_queue(entity->rq->sched);
> + drm_sched_wakeup_if_can_queue(entity->rq->sched, entity);
>  }
>  }
>  EXPORT_SYMBOL(drm_sched_entity_push_job);
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c
> b/drivers/gpu/drm/scheduler/sched_main.c
> index 5a3a622fc672..bbe06403b33d 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -865,10 +865,11 @@ static bool drm_sched_can_queue(struct drm_gpu_scheduler
> *sched)
>   *
>   * Wake up the scheduler if we can queue jobs.
>   */
> -void drm_sched_wakeup_if_can_queue(struct drm_gpu_scheduler *sched)
> +void drm_sched_wakeup_if_can_queue(struct drm_gpu_scheduler *sched, struct
> drm_sched_entity *entity)
>  {
> - if (drm_sched_can_queue(sched))
> - wake_up_interruptible(>wake_up_worker);
> + if(drm_sched_entity_is_ready(entity))
> + if (drm_sched_can_queue(sched))
> + wake_up_interruptible(>wake_up_worker);
>  }
> 
>  /**
> diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
> index ac65f0626cfc..6cfe3d193e69 100644
> --- a/include/drm/gpu_scheduler.h
> +++ b/include/drm/gpu_scheduler.h
> @@ -548,7 +548,7 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity
> *entity,
> unsigned int num_sched_list);
> 
>  void drm_sched_job_cleanup(struct drm_sched_job *job);
> -void drm_sched_wakeup_if_can_queue(struct drm_gpu_scheduler *sched);
> +void drm_sched_wakeup_if_can_queue(struct drm_gpu_scheduler *sched, struct
> drm_sched_entity *entity);
>  void drm_sched_stop(struct drm_gpu_scheduler *sched, struct drm_sched_job
> *bad);
>  void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery);
>  void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched);
> 
> This brings the extra check to the old scheduler and has so far not caused any
> trouble (using the same stress test described above), so chances are that the
> error is somewhere else in redesigned scheduler.
> 
> 
> Bert Karwatzki

Hi Bert,

Thanks for looking into this.

As an afterthought, removing the "entity_is_ready()" qualifier in wake-up, makes
the scheduling more opportunistic, and I agree that that is the more correct 
approach.
Commit f3123c2590005, basically made the code as close to the way it 

Re: [PATCH v3] drm/i915/vma: Fix VMA UAF on destroy against deactivate race

2023-11-22 Thread Andi Shyti
Hi Janusz,

this patch is conflicting now with:

  5e4e06e4087e ("drm/i915: Track gt pm wakerefs")

from Andrzej. I have fixed the conflict and if you want I can
send it. But I thought you might want to check it yourself,
first.

Andi

On Thu, Nov 16, 2023 at 03:07:20PM +0100, Janusz Krzysztofik wrote:
> Object debugging tools were sporadically reporting illegal attempts to
> free a still active i915 VMA object from when parking a GPU tile believed
> to be idle.
> 
> [161.359441] ODEBUG: free active (active state 0) object: 88811643b958 
> object type: i915_active hint: __i915_vma_active+0x0/0x50 [i915]
> [161.360082] WARNING: CPU: 5 PID: 276 at lib/debugobjects.c:514 
> debug_print_object+0x80/0xb0
> ...
> [161.360304] CPU: 5 PID: 276 Comm: kworker/5:2 Not tainted 
> 6.5.0-rc1-CI_DRM_13375-g003f860e5577+ #1
> [161.360314] Hardware name: Intel Corporation Rocket Lake Client 
> Platform/RocketLake S UDIMM 6L RVP, BIOS RKLSFWI1.R00.3173.A03.2204210138 
> 04/21/2022
> [161.360322] Workqueue: i915-unordered __intel_wakeref_put_work [i915]
> [161.360592] RIP: 0010:debug_print_object+0x80/0xb0
> ...
> [161.361347] debug_object_free+0xeb/0x110
> [161.361362] i915_active_fini+0x14/0x130 [i915]
> [161.361866] release_references+0xfe/0x1f0 [i915]
> [161.362543] i915_vma_parked+0x1db/0x380 [i915]
> [161.363129] __gt_park+0x121/0x230 [i915]
> [161.363515] intel_wakeref_put_last+0x1f/0x70 [i915]
> 
> That has been tracked down to be happening when another thread is
> deactivating the VMA inside __active_retire() helper, after the VMA's
> active counter has been already decremented to 0, but before deactivation
> of the VMA's object is reported to the object debugging tool.
> 
> We could prevent from that race by serializing i915_active_fini() with
> __active_retire() via ref->tree_lock, but that wouldn't stop the VMA from
> being used, e.g. from __i915_vma_retire() called at the end of
> __active_retire(), after that VMA has been already freed by a concurrent
> i915_vma_destroy() on return from the i915_active_fini().  Then, we should
> rather fix the issue at the VMA level, not in i915_active.
> 
> Since __i915_vma_parked() is called from __gt_park() on last put of the
> GT's wakeref, the issue could be addressed by holding the GT wakeref long
> enough for __active_retire() to complete before that wakeref is released
> and the GT parked.
> 
> A VMA associated with a request doesn't acquire a GT wakeref by itself.
> Instead, it depends on a wakeref held directly by the request's active
> intel_context for a GT associated with its VM, and indirectly on that
> intel_context's engine wakeref if the engine belongs to the same GT as the
> VMA's VM.  In case of single-tile platforms, at least one of those
> wakerefs is usually held long enough for the request's VMA to be
> deactivated on time, before it is destroyed on last put of its VM GT
> wakeref.  However, on multi-tile platforms, a request may use a VMA from a
> tile other than the one that hosts the request's engine, then it is
> protected only with the intel_context's VM GT wakeref.
> 
> There was an attempt to fix this issue on 2-tile Meteor Lake by acquiring
> an extra wakeref for a Primary GT from i915_gem_do_execbuffer() -- see
> commit f56fe3e91787 ("drm/i915: Fix a VMA UAF for multi-gt platform").
> However, it occurred insufficient -- the issue was still reported by CI.
> That wakeref was released on exit from i915_gem_do_execbuffer(), then
> potentially before completion of the request and deactivation of its
> associated VMAs.
> 
> OTOH, CI reports indicate that single-tile platforms also suffer
> sporadically from the same race.
> 
> I believe the issue was introduced by commit d93939730347 ("drm/i915:
> Remove the vma refcount") which moved a call to i915_active_fini() from
> a dropped i915_vma_release(), called on last put of the removed VMA kref,
> to i915_vma_parked() processing path called on last put of a GT wakeref.
> However, its visibility to the object debugging tool was suppressed by a
> bug in i915_active that was fixed two weeks later with commit e92eb246feb9
> ("drm/i915/active: Fix missing debug object activation").
> 
> Fix the issue by getting a wakeref for the VMA's tile when activating it,
> and putting that wakeref only after the VMA is deactivated.  However,
> exclude global GTT from that processing path, otherwise the GPU never goes
> idle.  Since __i915_vma_retire() may be called from atomic contexts, use
> async variant of wakeref put.
> 
> Having that fixed, stop explicitly acquiring the extra GT0 wakeref from
> inside i915_gem_do_execbuffer(), and also drop an extra call to
> i915_active_wait(), introduced by commit 7a2280e8dcd2 ("drm/i915: Wait for
> active retire before i915_active_fini()") as another insufficient fix for
> this UAF race.
> 
> v3: Identify root cause more precisely, and a commit to blame,
>   - identify and drop former workarounds,
>   - update commit message and description.
> v2: Get the wakeref before 

Re: linux-next: Signed-off-by missing for commit in the drm-misc tree

2023-11-22 Thread Luben Tuikov
On 2023-11-22 07:00, Maxime Ripard wrote:
> Hi Luben,
> 
> On Thu, Nov 16, 2023 at 09:27:58AM +0100, Daniel Vetter wrote:
>> On Thu, Nov 16, 2023 at 09:11:43AM +0100, Maxime Ripard wrote:
>>> On Tue, Nov 14, 2023 at 06:46:21PM -0500, Luben Tuikov wrote:
 On 2023-11-13 22:08, Stephen Rothwell wrote:
> BTW, cherry picking commits does not avoid conflicts - in fact it can
> cause conflicts if there are further changes to the files affected by
> the cherry picked commit in either the tree/branch the commit was
> cheery picked from or the destination tree/branch (I have to deal with
> these all the time when merging the drm trees in linux-next).  Much
> better is to cross merge the branches so that the patch only appears
> once or have a shared branches that are merged by any other branch that
> needs the changes.
>
> I understand that things are not done like this in the drm trees :-(

 Hi Stephen,

 Thank you for the clarification--understood. I'll be more careful in the 
 future.
 Thanks again! :-)
>>>
>>> In this case, the best thing to do would indeed have been to ask the
>>> drm-misc maintainers to merge drm-misc-fixes into drm-misc-next.
>>>
>>> We're doing that all the time, but we're not ubiquitous so you need to
>>> ask us :)
>>>
>>> Also, dim should have caught that when you pushed the branch. Did you
>>> use it?
>>
>> Yeah dim must be used, exactly to avoid these issues. Both for applying
>> patches (so not git am directly, or cherry-picking from your own
>> development branch), and for pushing. The latter is even checked for by
>> the server (dim sets a special push flag which is very long and contains a
>> very clear warning if you bypass it).
>>
>> If dim was used, this would be a bug in the dim script that we need to
>> fix.
> 
> It would be very useful for you to explain what happened here so we
> improve the tooling or doc and can try to make sure it doesn't happen
> again
> 
> Maxime

There is no problem with the tooling--I just forced the commit in.
-- 
Regards,
Luben


OpenPGP_0x4C15479431A334AF.asc
Description: OpenPGP public key


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH v18 24/26] drm/virtio: Attach shmem BOs dynamically

2023-11-22 Thread Dmitry Osipenko
On 11/23/23 01:37, Dmitry Osipenko wrote:
> On 11/13/23 12:57, Boris Brezillon wrote:
>> On Mon, 30 Oct 2023 02:02:03 +0300
>> Dmitry Osipenko  wrote:
>>
>>> Prepare for addition of memory shrinker support by attaching shmem pages
>>> to host dynamically on first use. Previously the attachment vq command
>>> wasn't fenced and there was no vq kick made in the BO creation code path,
>>> hence the attachment already was happening dynamically, but implicitly.
>>> Making attachment explicitly dynamic will allow to simplify and reuse more
>>> code when shrinker will be added. The virtio_gpu_object_shmem_init() now
>>> works under the held reservation lock, which will be important to have for
>>> shrinker to avoid moving pages while they are in active use by the driver.
>> Ah, this commit might actually help getting rid of the workaround
>> introduced in "drm/shmem-helper: Add common memory shrinker".
> 
> Not really. The virtio_gpu_free_object() is unchanged, it's only
> allocation that is being deferred and it's only done for a one BO type
> (virtio-gpu has multiple BO types).

s/allocation/attachment/

Pages are still allocated by virtio_gpu_object_create().

-- 
Best regards,
Dmitry



Re: [PATCH v18 24/26] drm/virtio: Attach shmem BOs dynamically

2023-11-22 Thread Dmitry Osipenko
On 11/13/23 12:57, Boris Brezillon wrote:
> On Mon, 30 Oct 2023 02:02:03 +0300
> Dmitry Osipenko  wrote:
> 
>> Prepare for addition of memory shrinker support by attaching shmem pages
>> to host dynamically on first use. Previously the attachment vq command
>> wasn't fenced and there was no vq kick made in the BO creation code path,
>> hence the attachment already was happening dynamically, but implicitly.
>> Making attachment explicitly dynamic will allow to simplify and reuse more
>> code when shrinker will be added. The virtio_gpu_object_shmem_init() now
>> works under the held reservation lock, which will be important to have for
>> shrinker to avoid moving pages while they are in active use by the driver.
> Ah, this commit might actually help getting rid of the workaround
> introduced in "drm/shmem-helper: Add common memory shrinker".

Not really. The virtio_gpu_free_object() is unchanged, it's only
allocation that is being deferred and it's only done for a one BO type
(virtio-gpu has multiple BO types).

-- 
Best regards,
Dmitry



Re: [PATCH] drm/rockchip: rk3066_hdmi: include drm/drm_atomic.h

2023-11-22 Thread Randy Dunlap



On 11/22/23 14:18, Arnd Bergmann wrote:
> From: Arnd Bergmann 
> 
> Without this header, the newly added code fails to build:
> 
> drivers/gpu/drm/rockchip/rk3066_hdmi.c: In function 
> 'rk3066_hdmi_encoder_enable':
> drivers/gpu/drm/rockchip/rk3066_hdmi.c:397:22: error: implicit declaration of 
> function 'drm_atomic_get_new_connector_state'; did you mean 
> 'drm_atomic_helper_connector_reset'? [-Werror=implicit-function-declaration]
>   397 | conn_state = drm_atomic_get_new_connector_state(state, 
> >connector);
>   |  ^~
>   |  drm_atomic_helper_connector_reset
> drivers/gpu/drm/rockchip/rk3066_hdmi.c:397:20: error: assignment to 'struct 
> drm_connector_state *' from 'int' makes pointer from integer without a cast 
> [-Werror=int-conversion]
>   397 | conn_state = drm_atomic_get_new_connector_state(state, 
> >connector);
>   |^
> drivers/gpu/drm/rockchip/rk3066_hdmi.c:401:22: error: implicit declaration of 
> function 'drm_atomic_get_new_crtc_state'; did you mean 
> 'drm_atomic_helper_swap_state'? [-Werror=implicit-function-declaration]
>   401 | crtc_state = drm_atomic_get_new_crtc_state(state, 
> conn_state->crtc);
>   |  ^
>   |  drm_atomic_helper_swap_state
> drivers/gpu/drm/rockchip/rk3066_hdmi.c:401:20: error: assignment to 'struct 
> drm_crtc_state *' from 'int' makes pointer from integer without a cast 
> [-Werror=int-conversion]
>   401 | crtc_state = drm_atomic_get_new_crtc_state(state, 
> conn_state->crtc);
>   |^
> 
> Fixes: ae3436a5e7c2 ("drm/rockchip: rk3066_hdmi: Switch encoder hooks to 
> atomic")
> Signed-off-by: Arnd Bergmann 

Acked-by: Randy Dunlap 
Tested-by: Randy Dunlap  # build-tested

Thanks.

> ---
>  drivers/gpu/drm/rockchip/rk3066_hdmi.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c 
> b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
> index 0e7aae341960..7d561c5a650f 100644
> --- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c
> +++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
> @@ -4,6 +4,7 @@
>   *Zheng Yang 
>   */
>  
> +#include 
>  #include 
>  #include 
>  #include 

-- 
~Randy


Re: [PATCH v18 22/26] drm/shmem-helper: Don't free refcounted GEM

2023-11-22 Thread Dmitry Osipenko
On 11/13/23 12:54, Boris Brezillon wrote:
> On Mon, 30 Oct 2023 02:02:01 +0300
> Dmitry Osipenko  wrote:
> 
>> Don't free refcounted shmem object to prevent use-after-free bug that
>> is worse than a memory leak.
>>
>> Signed-off-by: Dmitry Osipenko 
>> ---
>>  drivers/gpu/drm/drm_gem_shmem_helper.c | 7 ---
>>  1 file changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
>> b/drivers/gpu/drm/drm_gem_shmem_helper.c
>> index 6dd087f19ea3..4253c367dc07 100644
>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>> @@ -203,9 +203,10 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object 
>> *shmem)
>>  if (obj->import_attach)
>>  drm_prime_gem_destroy(obj, shmem->sgt);
>>  
>> -drm_WARN_ON(obj->dev, refcount_read(>vmap_use_count));
>> -drm_WARN_ON(obj->dev, refcount_read(>pages_use_count));
>> -drm_WARN_ON(obj->dev, refcount_read(>pages_pin_count));
>> +if (drm_WARN_ON(obj->dev, refcount_read(>vmap_use_count)) ||
>> +drm_WARN_ON(obj->dev, refcount_read(>pages_use_count)) ||
>> +drm_WARN_ON(obj->dev, refcount_read(>pages_pin_count)))
>> +return;
> 
> I guess you're worried about ->sgt being referenced by the driver after
> the GEM is destroyed. If we assume drivers don't cache the sgt and
> always call get_pages_sgt() when they need it that shouldn't be an
> issue. What we really don't want to release is the pages themselves,
> but the GPU MMU might still have active mappings pointing to these
> pages.
> 
> In any case, I'm not against leaking the GEM object when any of these
> counters are not zero, but can we at least have a comment in the
> code explaining why we're doing that, so people don't have to go look
> at the git history to figure it out.

This patch is a minor improvement, it doesn't address any specific
issue. This should be a common pattern in kernel. If you're giving a
warning and know about the inevitable catastrophe, then avoid it if you can.

Actually, there are other similar cases in drm-shmem that can be improved.

-- 
Best regards,
Dmitry




[PATCH] drm/rockchip: rk3066_hdmi: include drm/drm_atomic.h

2023-11-22 Thread Arnd Bergmann
From: Arnd Bergmann 

Without this header, the newly added code fails to build:

drivers/gpu/drm/rockchip/rk3066_hdmi.c: In function 
'rk3066_hdmi_encoder_enable':
drivers/gpu/drm/rockchip/rk3066_hdmi.c:397:22: error: implicit declaration of 
function 'drm_atomic_get_new_connector_state'; did you mean 
'drm_atomic_helper_connector_reset'? [-Werror=implicit-function-declaration]
  397 | conn_state = drm_atomic_get_new_connector_state(state, 
>connector);
  |  ^~
  |  drm_atomic_helper_connector_reset
drivers/gpu/drm/rockchip/rk3066_hdmi.c:397:20: error: assignment to 'struct 
drm_connector_state *' from 'int' makes pointer from integer without a cast 
[-Werror=int-conversion]
  397 | conn_state = drm_atomic_get_new_connector_state(state, 
>connector);
  |^
drivers/gpu/drm/rockchip/rk3066_hdmi.c:401:22: error: implicit declaration of 
function 'drm_atomic_get_new_crtc_state'; did you mean 
'drm_atomic_helper_swap_state'? [-Werror=implicit-function-declaration]
  401 | crtc_state = drm_atomic_get_new_crtc_state(state, 
conn_state->crtc);
  |  ^
  |  drm_atomic_helper_swap_state
drivers/gpu/drm/rockchip/rk3066_hdmi.c:401:20: error: assignment to 'struct 
drm_crtc_state *' from 'int' makes pointer from integer without a cast 
[-Werror=int-conversion]
  401 | crtc_state = drm_atomic_get_new_crtc_state(state, 
conn_state->crtc);
  |^

Fixes: ae3436a5e7c2 ("drm/rockchip: rk3066_hdmi: Switch encoder hooks to 
atomic")
Signed-off-by: Arnd Bergmann 
---
 drivers/gpu/drm/rockchip/rk3066_hdmi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c 
b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
index 0e7aae341960..7d561c5a650f 100644
--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c
+++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
@@ -4,6 +4,7 @@
  *Zheng Yang 
  */
 
+#include 
 #include 
 #include 
 #include 
-- 
2.39.2



[PATCH] drm/amd/display: avoid stringop-overflow warnings for dp_decide_lane_settings()

2023-11-22 Thread Arnd Bergmann
From: Arnd Bergmann 

gcc prints a warning about a possible array overflow for a couple of
callers of dp_decide_lane_settings() after commit 1b56c90018f0 ("Makefile:
Enable -Wstringop-overflow globally"):

drivers/gpu/drm/amd/amdgpu/../display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c:
 In function 'dp_perform_fixed_vs_pe_training_sequence_legacy':
drivers/gpu/drm/amd/amdgpu/../display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c:426:25:
 error: 'dp_decide_lane_settings' accessing 4 bytes in a region of size 1 
[-Werror=stringop-overflow=]
  426 | dp_decide_lane_settings(lt_settings, 
dpcd_lane_adjust,
  | 
^~
  427 | lt_settings->hw_lane_settings, 
lt_settings->dpcd_lane_settings);
  | 
~~~
drivers/gpu/drm/amd/amdgpu/../display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c:426:25:
 note: referencing argument 4 of type 'union dpcd_training_lane[4]'

I'm not entirely sure what caused this, but changing the prototype to expect
a pointer instead of an array avoids the warnings.

Fixes: 7727e7b60f82 ("drm/amd/display: Improve robustness of FIXED_VS link 
training at DP1 rates")
Signed-off-by: Arnd Bergmann 
---
 .../gpu/drm/amd/display/dc/link/protocols/link_dp_training.c| 2 +-
 .../gpu/drm/amd/display/dc/link/protocols/link_dp_training.h| 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c
index 90339c2dfd84..5a0b04518956 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c
@@ -807,7 +807,7 @@ void dp_decide_lane_settings(
const struct link_training_settings *lt_settings,
const union lane_adjust ln_adjust[LANE_COUNT_DP_MAX],
struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX],
-   union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX])
+   union dpcd_training_lane *dpcd_lane_settings)
 {
uint32_t lane;
 
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h
index 7d027bac8255..851bd17317a0 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h
@@ -111,7 +111,7 @@ void dp_decide_lane_settings(
const struct link_training_settings *lt_settings,
const union lane_adjust ln_adjust[LANE_COUNT_DP_MAX],
struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX],
-   union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]);
+   union dpcd_training_lane *dpcd_lane_settings);
 
 enum dc_dp_training_pattern decide_cr_training_pattern(
const struct dc_link_settings *link_settings);
-- 
2.39.2



Re: [PATCH v18 15/26] drm/panfrost: Explicitly get and put drm-shmem pages

2023-11-22 Thread Dmitry Osipenko
On 11/10/23 13:53, Boris Brezillon wrote:
> Hm, there was no drm_gem_shmem_get_pages_sgt() call here, why should we
> add a drm_gem_shmem_get_pages()? What we should do instead is add a
> drm_gem_shmem_get_pages() for each drm_gem_shmem_get_pages_sgt() we
> have in the driver (in panfrost_mmu_map()), and add
> drm_gem_shmem_put_pages() calls where they are missing
> (panfrost_mmu_unmap()).
> 
>> +if (err)
>> +goto err_free;
>> +}
>> +
>>  return bo;
>> +
>> +err_free:
>> +drm_gem_shmem_free(>base);
>> +
>> +return ERR_PTR(err);
>>  }
>>  
>>  struct drm_gem_object *
>> diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c 
>> b/drivers/gpu/drm/panfrost/panfrost_mmu.c
>> index 770dab1942c2..ac145a98377b 100644
>> --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
>> +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
>> @@ -504,7 +504,7 @@ static int panfrost_mmu_map_fault_addr(struct 
>> panfrost_device *pfdev, int as,
>>  if (IS_ERR(pages[i])) {
>>  ret = PTR_ERR(pages[i]);
>>  pages[i] = NULL;
>> -goto err_pages;
>> +goto err_unlock;
>>  }
>>  }
>>  
>> @@ -512,7 +512,7 @@ static int panfrost_mmu_map_fault_addr(struct 
>> panfrost_device *pfdev, int as,
>>  ret = sg_alloc_table_from_pages(sgt, pages + page_offset,
>>  NUM_FAULT_PAGES, 0, SZ_2M, GFP_KERNEL);
>>  if (ret)
>> -goto err_pages;
>> +goto err_unlock;
> Feels like the panfrost_gem_mapping object should hold a ref on the BO
> pages, not the BO itself, because, ultimately, the user of the BO is
> the GPU. This matches what I was saying about moving get/put_pages() to
> panfrost_mmu_map/unmap(): everytime a panfrost_gem_mapping becomes
> active, to want to take a pages ref, every time it becomes inactive,
> you should release the pages ref.

The panfrost_mmu_unmap() is also used by shrinker when BO is purged. I'm
unhappy with how icky it all becomes if unmap is made to put pages.

Previously map() was implicitly allocating pages with get_sgt() and then
pages were implicitly released by drm_gem_shmem_free(). A non-heap BO is
mapped when it's created by Panfrost, hence the actual lifetime of pages
is kept unchanged by this patch. The implicit allocation is turned into
explicit one, i.e. pages are explicitly allocated before BO is mapped.

-- 
Best regards,
Dmitry



[PATCH v2 1/1] drm/i915/pxp: Add missing tag for Wa_14019159160

2023-11-22 Thread Alan Previn
Add missing tag for "Wa_14019159160 - Case 2" (for existing
PXP code that ensures run alone mode bit is set to allow
PxP-decryption.

 v2: - Fix WA id number (John Harrison).
 - Improve comments and code to be specific
   for the targetted platforms (John Harrison)

Signed-off-by: Alan Previn 
---
 drivers/gpu/drm/i915/gt/intel_lrc.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 7c367ba8d9dc..2959dfed2aa0 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -863,11 +863,13 @@ static bool ctx_needs_runalone(const struct intel_context 
*ce)
bool ctx_is_protected = false;
 
/*
-* On MTL and newer platforms, protected contexts require setting
-* the LRC run-alone bit or else the encryption will not happen.
+* Wa_14019159160 - Case 2: mtl
+* On some platforms, protected contexts require setting
+* the LRC run-alone bit or else the encryption/decryption will not 
happen.
+* NOTE: Case 2 only applies to PXP use-case of said workaround.
 */
-   if (GRAPHICS_VER_FULL(ce->engine->i915) >= IP_VER(12, 70) &&
-   (ce->engine->class == COMPUTE_CLASS || ce->engine->class == 
RENDER_CLASS)) {
+   if (IS_METEORLAKE(ce->engine->i915) && (ce->engine->class == 
COMPUTE_CLASS ||
+   ce->engine->class == 
RENDER_CLASS)) {
rcu_read_lock();
gem_ctx = rcu_dereference(ce->gem_context);
if (gem_ctx)

base-commit: 5429d55de723544dfc0630cf39d96392052b27a1
-- 
2.39.0



Re: [PATCH v9 0/4] drm: Add support for atomic async page-flip

2023-11-22 Thread André Almeida

Hi Hamza,

Em 22/11/2023 17:23, Hamza Mahfooz escreveu:

Hi André,
On 11/22/23 11:19, André Almeida wrote:

Hi,

This work from me and Simon adds support for DRM_MODE_PAGE_FLIP_ASYNC 
through
the atomic API. This feature is already available via the legacy API. 
The use

case is to be able to present a new frame immediately (or as soon as
possible), even if after missing a vblank. This might result in 
tearing, but

it's useful when a high framerate is desired, such as for gaming.

Differently from earlier versions, this one refuses to flip if any 
prop changes
for async flips. The idea is that the fast path of immediate page 
flips doesn't

play well with modeset changes, so only the fb_id can be changed.

Tested with:
  - Intel TigerLake-LP GT2
  - AMD VanGogh


Have you had a chance to test this with VRR enabled? Since, I suspect
this series might break that feature.



Someone asked this question in an earlier version of this patch, and the 
result is that VRR still works as expected. You can follow the thread at 
this link:


https://lore.kernel.org/lkml/b48bd1fc-fcb0-481b-8413-9210d44d7...@igalia.com/

I should have included this note at my cover letter, my bad.

Thanks,
André


Re: [PATCH v2 1/1] drm/msm/adreno: Add support for SM7150 SoC machine

2023-11-22 Thread Konrad Dybcio




On 10/16/23 16:32, Dmitry Baryshkov wrote:

On 26/09/2023 23:03, Konrad Dybcio wrote:

On 26.09.2023 21:10, Danila Tikhonov wrote:


I think you mean by name downstream dt - sdmmagpie-gpu.dtsi

You can see the forked version of the mainline here:
https://github.com/sm7150-mainline/linux/blob/next/arch/arm64/boot/dts/qcom/sm7150.dtsi

All fdt that we got here, if it is useful for you:
https://github.com/sm7150-mainline/downstream-fdt

Best wishes, Danila

Taking a look at downstream, atoll.dtsi (SC7180) includes
sdmmagpie-gpu.dtsi.

Bottom line is, they share the speed bins, so it should be
fine to just extend the existing entry.


But then atoll.dtsi rewrites speed bins and pwrlevel bins. So they are not 
shared.

+Akhil

could you please check internally?

Konrad


Re: [PATCH 1/3] riscv: Add support for kernel-mode FPU

2023-11-22 Thread kernel test robot
Hi Samuel,

kernel test robot noticed the following build errors:

[auto build test ERROR on drm-misc/drm-misc-next]
[also build test ERROR on linus/master v6.7-rc2 next-20231122]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Samuel-Holland/riscv-Add-support-for-kernel-mode-FPU/20231122-111015
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:
https://lore.kernel.org/r/20231122030621.3759313-2-samuel.holland%40sifive.com
patch subject: [PATCH 1/3] riscv: Add support for kernel-mode FPU
config: riscv-allnoconfig 
(https://download.01.org/0day-ci/archive/20231123/202311230215.dbfywpqb-...@intel.com/config)
compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project.git 
4a5ac14ee968ff0ad5d2cc1ffa0299048db4c88a)
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20231123/202311230215.dbfywpqb-...@intel.com/reproduce)

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

All errors (new ones prefixed by >>):

>> arch/riscv/kernel/process.c:229:19: error: use of undeclared identifier 
>> '__fstate_save'
 229 | EXPORT_SYMBOL_GPL(__fstate_save);
 |   ^
>> arch/riscv/kernel/process.c:230:19: error: use of undeclared identifier 
>> '__fstate_restore'
 230 | EXPORT_SYMBOL_GPL(__fstate_restore);
 |   ^
   2 errors generated.


vim +/__fstate_save +229 arch/riscv/kernel/process.c

   228  
 > 229  EXPORT_SYMBOL_GPL(__fstate_save);
 > 230  EXPORT_SYMBOL_GPL(__fstate_restore);

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


Re: [PATCH v9 0/4] drm: Add support for atomic async page-flip

2023-11-22 Thread Hamza Mahfooz

Hi André,
On 11/22/23 11:19, André Almeida wrote:

Hi,

This work from me and Simon adds support for DRM_MODE_PAGE_FLIP_ASYNC through
the atomic API. This feature is already available via the legacy API. The use
case is to be able to present a new frame immediately (or as soon as
possible), even if after missing a vblank. This might result in tearing, but
it's useful when a high framerate is desired, such as for gaming.

Differently from earlier versions, this one refuses to flip if any prop changes
for async flips. The idea is that the fast path of immediate page flips doesn't
play well with modeset changes, so only the fb_id can be changed.

Tested with:
  - Intel TigerLake-LP GT2
  - AMD VanGogh


Have you had a chance to test this with VRR enabled? Since, I suspect
this series might break that feature.



Thanks,
André

- User-space patch: https://github.com/Plagman/gamescope/pull/595
- IGT tests: 
https://lore.kernel.org/all/20231110163811.24158-1-andrealm...@igalia.com/

Changes from v8:
- Dropped atomic_async_page_flip_not_supported, giving that current design works
with any driver that support atomic and async at the same time.
- Dropped the patch that disabled atomic_async_page_flip_not_supported for AMD.
- Reordered commits
v8: https://lore.kernel.org/all/20231025005318.293690-1-andrealm...@igalia.com/

Changes from v7:
- Only accept flips to primary planes. If a driver support flips in different
planes, support will be added  later.
v7: 
https://lore.kernel.org/dri-devel/20231017092837.32428-1-andrealm...@igalia.com/

Changes from v6:
- Dropped the exception to allow MODE_ID changes (Simon)
- Clarify what happens when flipping with the same FB_ID (Pekka)

v6: 
https://lore.kernel.org/dri-devel/20230815185710.159779-1-andrealm...@igalia.com/

Changes from v5:
- Add note in the docs that not every redundant attribute will result in no-op,
   some might cause oversynchronization issues.

v5: 
https://lore.kernel.org/dri-devel/20230707224059.305474-1-andrealm...@igalia.com/

Changes from v4:
  - Documentation rewrote by Pekka Paalanen

v4: 
https://lore.kernel.org/dri-devel/20230701020917.143394-1-andrealm...@igalia.com/

Changes from v3:
  - Add new patch to reject prop changes
  - Add a documentation clarifying the KMS atomic state set

v3: 
https://lore.kernel.org/dri-devel/20220929184307.258331-1-cont...@emersion.fr/

André Almeida (1):
   drm: Refuse to async flip with atomic prop changes

Pekka Paalanen (1):
   drm/doc: Define KMS atomic state set

Simon Ser (2):
   drm: allow DRM_MODE_PAGE_FLIP_ASYNC for atomic commits
   drm: introduce DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP

  Documentation/gpu/drm-uapi.rst  | 47 ++
  drivers/gpu/drm/drm_atomic_uapi.c   | 77 ++---
  drivers/gpu/drm/drm_crtc_internal.h |  2 +-
  drivers/gpu/drm/drm_ioctl.c |  4 ++
  drivers/gpu/drm/drm_mode_object.c   |  2 +-
  include/uapi/drm/drm.h  | 10 +++-
  include/uapi/drm/drm_mode.h |  9 
  7 files changed, 142 insertions(+), 9 deletions(-)


--
Hamza



Re: [PATCH -next] drm/nouveau/fifo: Remove duplicated include in chan.c

2023-11-22 Thread Lyude Paul
Reviewed-by: Lyude Paul 

Will push upstream in a moment

On Wed, 2023-11-22 at 08:49 +0800, Yang Li wrote:
> ./drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c: chid.h is included more 
> than once.
> 
> Reported-by: Abaci Robot 
> Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=7603
> Signed-off-by: Yang Li 
> ---
>  drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c 
> b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c
> index 87a62d4ff4bd..7d4716dcd512 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c
> @@ -24,7 +24,6 @@
>  #include "chan.h"
>  #include "chid.h"
>  #include "cgrp.h"
> -#include "chid.h"
>  #include "runl.h"
>  #include "priv.h"
>  

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



Re: [PATCH v9 00/20] Imagination Technologies PowerVR DRM driver

2023-11-22 Thread Maxime Ripard
Hi,

On Wed, Nov 22, 2023 at 04:34:21PM +, Donald Robson wrote:
> This patch series adds the initial DRM driver for Imagination Technologies 
> PowerVR
> GPUs, starting with those based on our Rogue architecture. It's worth pointing
> out that this is a new driver, written from the ground up, rather than a
> refactored version of our existing downstream driver (pvrsrvkm).
> 
> This new DRM driver supports:
> - GEM shmem allocations
> - dma-buf / PRIME
> - Per-context userspace managed virtual address space
> - DRM sync objects (binary and timeline)
> - Power management suspend / resume
> - GPU job submission (geometry, fragment, compute, transfer)
> - META firmware processor
> - MIPS firmware processor
> - GPU hang detection and recovery
> 
> Currently our main focus is on the AXE-1-16M GPU. Testing so far has been done
> using a TI SK-AM62 board (AXE-1-16M GPU). The driver has also been confirmed 
> to
> work on the BeaglePlay board. Firmware for the AXE-1-16M can be found here:
> https://gitlab.freedesktop.org/frankbinns/linux-firmware/-/tree/powervr
> 
> A Vulkan driver that works with our downstream kernel driver has already been
> merged into Mesa [1][2]. Support for this new DRM driver is being maintained 
> in
> a merge request [3], with the branch located here:
> https://gitlab.freedesktop.org/frankbinns/mesa/-/tree/powervr-winsys
> 
> Vulkan driver links referred to above:
> [1] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15243
> [2] 
> https://gitlab.freedesktop.org/mesa/mesa/-/tree/main/src/imagination/vulkan
> [3] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15507
> 
> Job stream formats are documented at:
> https://gitlab.freedesktop.org/mesa/mesa/-/blob/f8d2b42ae65c2f16f36a43e0ae39d288431e4263/src/imagination/csbgen/rogue_kmd_stream.xml
> 
> The Vulkan driver is progressing towards Vulkan 1.0. The current combination 
> of this
> kernel driver with the Mesa Vulkan driver (powervr-mesa-next branch) 
> successfully
> completes Vulkan CTS 1.3.4.1 in our local runs. The driver is expected to 
> pass the
> Khronos Conformance Process once the submission is made.
> 
> The code in this patch series, along with the needed dts changes can be found 
> here:
> https://gitlab.freedesktop.org/frankbinns/powervr/-/tree/dev/v9_dts
> The full development history can be found here:
> https://gitlab.freedesktop.org/frankbinns/powervr/-/tree/powervr-next

I just merged all the patches to drm-misc-next.

Congrats :)

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v2 2/4] drm/prime: Helper to export dmabuf without fd

2023-11-22 Thread Felix Kuehling



On 2023-11-22 05:32, Thomas Zimmermann wrote:

Hi,

my apologies if this sounds picky or annoying. This change appears to be
going in the wrong direction. The goal of the refactoring is to be able
to use drm_driver.gem_prime_import and drm_gem_object_funcs.export for
the additional import/export code; and hence keep the GEM object code in
a single place. Keeping the prime_fd file descriptor within amdkfd will
likely help with that.

Here's my suggestion:

   1) Please keep the internal interfaces drm_gem_prime_handle_to_fd()
and drm_gem_prime_fd_to_handle(). They should be called from the _ioctl
entry functions as is. That could be stream-lined in a later patch set.

   2) From drm_gem_prime_handle_to_fd() and drm_gem_prime_fd_to_handle(),
create drm_gem_prime_handle_to_dmabuf() and
drm_gem_prime_dmabuf_to_handle().


Do you mean duplicate the code, or call drm_gem_prime_handle_to_dmabuf 
from drm_gem_prime_handle_to_fd?




  They should be exported. You can then
keep the file-descriptor code in amdkfd and out of the PRIME helpers.

   3) Patches 1 and 2 should be squashed into one.

   4) And if I'm not mistaken, the additional import/export code can then
go into drm_driver.gem_prime_import and drm_gem_object_funcs.export,
which are being called from within the PRIME helpers.


I'm not sure what you mean by "additional import/export code" that would 
move into those driver callbacks.





That's admittedly quite a bit of refactoring. OR simply go back to v1 of
this patch set, which was consistent at least.


I think I'd prefer that because I don't really understand what you're 
trying to achieve.


Thanks,
  Felix




Best regards
Thomas


Am 22.11.23 um 00:11 schrieb Felix Kuehling:

Change drm_gem_prime_handle_to_fd to drm_gem_prime_handle_to_dmabuf to
export a dmabuf without creating an FD as a user mode handle. This is
more useful for users in kernel mode.

Suggested-by: Thomas Zimmermann 
Signed-off-by: Felix Kuehling 
---
   drivers/gpu/drm/drm_prime.c | 63 ++---
   include/drm/drm_prime.h |  6 ++--
   2 files changed, 33 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 834a5e28abbe..d491b5f73eea 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -410,26 +410,25 @@ static struct dma_buf *export_and_register_object(struct 
drm_device *dev,
   }
   
   /**

- * drm_gem_prime_handle_to_fd - PRIME export function for GEM drivers
+ * drm_gem_prime_handle_to_dmabuf - PRIME export function for GEM drivers
* @dev: dev to export the buffer from
* @file_priv: drm file-private structure
* @handle: buffer handle to export
* @flags: flags like DRM_CLOEXEC
- * @prime_fd: pointer to storage for the fd id of the create dma-buf
+ * @dma_buf: pointer to storage for the dma-buf reference
*
* This is the PRIME export function which must be used mandatorily by GEM
* drivers to ensure correct lifetime management of the underlying GEM 
object.
* The actual exporting from GEM object to a dma-buf is done through the
* _gem_object_funcs.export callback.
*/
-int drm_gem_prime_handle_to_fd(struct drm_device *dev,
-  struct drm_file *file_priv, uint32_t handle,
-  uint32_t flags,
-  int *prime_fd)
+struct dma_buf *drm_gem_prime_handle_to_dmabuf(struct drm_device *dev,
+  struct drm_file *file_priv,
+  uint32_t handle, uint32_t flags)
   {
struct drm_gem_object *obj;
int ret = 0;
-   struct dma_buf *dmabuf;
+   struct dma_buf *dmabuf = NULL;
   
   	mutex_lock(_priv->prime.lock);

obj = drm_gem_object_lookup(file_priv, handle);
@@ -441,7 +440,7 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev,
dmabuf = drm_prime_lookup_buf_by_handle(_priv->prime, handle);
if (dmabuf) {
get_dma_buf(dmabuf);
-   goto out_have_handle;
+   goto out;
}
   
   	mutex_lock(>object_name_lock);

@@ -479,40 +478,22 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev,
   dmabuf, handle);
mutex_unlock(>object_name_lock);
if (ret)
-   goto fail_put_dmabuf;
-
-out_have_handle:
-   ret = dma_buf_fd(dmabuf, flags);
-   /*
-* We must _not_ remove the buffer from the handle cache since the newly
-* created dma buf is already linked in the global obj->dma_buf pointer,
-* and that is invariant as long as a userspace gem handle exists.
-* Closing the handle will clean out the cache anyway, so we don't leak.
-*/
-   if (ret < 0) {
-   goto fail_put_dmabuf;
-   } else {
-   *prime_fd = ret;
-   ret = 0;
-   }
-
-   goto out;
-
-fail_put_dmabuf:
-   

[PATCH v5] drm/i915/pxp: Add drm_dbgs for critical PXP events.

2023-11-22 Thread Alan Previn
Debugging PXP issues can't even begin without understanding precedding
sequence of important events. Add drm_dbg into the most important PXP
events.

 v5 : - rebase.
 v4 : - rebase.
 v3 : - move gt_dbg to after mutex block in function
i915_gsc_proxy_component_bind. (Vivaik)
 v2 : - remove __func__ since drm_dbg covers that (Jani).
  - add timeout dbg of the restart from front-end (Alan).

Signed-off-by: Alan Previn 
Reviewed-by: Vivaik Balasubrawmanian 
---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c |  2 ++
 drivers/gpu/drm/i915/pxp/intel_pxp.c | 15 ---
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c |  5 +++--
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c |  6 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h   |  1 +
 5 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
index 5f138de3c14f..40817ebcca71 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
@@ -322,6 +322,7 @@ static int i915_gsc_proxy_component_bind(struct device 
*i915_kdev,
gsc->proxy.component = data;
gsc->proxy.component->mei_dev = mei_kdev;
mutex_unlock(>proxy.mutex);
+   gt_dbg(gt, "GSC proxy mei component bound\n");
 
return 0;
 }
@@ -342,6 +343,7 @@ static void i915_gsc_proxy_component_unbind(struct device 
*i915_kdev,
with_intel_runtime_pm(>runtime_pm, wakeref)
intel_uncore_rmw(gt->uncore, HECI_H_CSR(MTL_GSC_HECI2_BASE),
 HECI_H_CSR_IE | HECI_H_CSR_RST, 0);
+   gt_dbg(gt, "GSC proxy mei component unbound\n");
 }
 
 static const struct component_ops i915_gsc_proxy_component_ops = {
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index dc327cf40b5a..e11f562b1876 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -303,6 +303,8 @@ static int __pxp_global_teardown_final(struct intel_pxp 
*pxp)
 
if (!pxp->arb_is_valid)
return 0;
+
+   drm_dbg(>ctrl_gt->i915->drm, "PXP: teardown for suspend/fini");
/*
 * To ensure synchronous and coherent session teardown completion
 * in response to suspend or shutdown triggers, don't use a worker.
@@ -324,6 +326,8 @@ static int __pxp_global_teardown_restart(struct intel_pxp 
*pxp)
 
if (pxp->arb_is_valid)
return 0;
+
+   drm_dbg(>ctrl_gt->i915->drm, "PXP: teardown for restart");
/*
 * The arb-session is currently inactive and we are doing a reset and 
restart
 * due to a runtime event. Use the worker that was designed for this.
@@ -332,8 +336,11 @@ static int __pxp_global_teardown_restart(struct intel_pxp 
*pxp)
 
timeout = intel_pxp_get_backend_timeout_ms(pxp);
 
-   if (!wait_for_completion_timeout(>termination, 
msecs_to_jiffies(timeout)))
+   if (!wait_for_completion_timeout(>termination, 
msecs_to_jiffies(timeout))) {
+   drm_dbg(>ctrl_gt->i915->drm, "PXP: restart backend timed 
out (%d ms)",
+   timeout);
return -ETIMEDOUT;
+   }
 
return 0;
 }
@@ -414,10 +421,12 @@ int intel_pxp_start(struct intel_pxp *pxp)
int ret = 0;
 
ret = intel_pxp_get_readiness_status(pxp, PXP_READINESS_TIMEOUT);
-   if (ret < 0)
+   if (ret < 0) {
+   drm_dbg(>ctrl_gt->i915->drm, "PXP: tried but not-avail 
(%d)", ret);
return ret;
-   else if (ret > 1)
+   } else if (ret > 1) {
return -EIO; /* per UAPI spec, user may retry later */
+   }
 
mutex_lock(>arb_mutex);
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
index 91e9622c07d0..d81750b9bdda 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
@@ -40,11 +40,12 @@ void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
   GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT)) {
/* immediately mark PXP as inactive on termination */
intel_pxp_mark_termination_in_progress(pxp);
-   pxp->session_events |= PXP_TERMINATION_REQUEST | 
PXP_INVAL_REQUIRED;
+   pxp->session_events |= PXP_TERMINATION_REQUEST | 
PXP_INVAL_REQUIRED |
+  PXP_EVENT_TYPE_IRQ;
}
 
if (iir & GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
-   pxp->session_events |= PXP_TERMINATION_COMPLETE;
+   pxp->session_events |= PXP_TERMINATION_COMPLETE | 
PXP_EVENT_TYPE_IRQ;
 
if (pxp->session_events)
queue_work(system_unbound_wq, >session_work);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index 0a3e66b0265e..091c86e03d1a 100644
--- 

Re: [PATCH v2 09/12] dt-bindings: soc: vop2: Add more endpoint definition

2023-11-22 Thread Krzysztof Kozlowski
On 22/11/2023 13:55, Andy Yan wrote:
> From: Andy Yan 
> 
> There are 2 HDMI, 2 DP, 2 eDP on rk3588, so add
> corresponding endpoint definition for it.

Please wrap commit message according to Linux coding style / submission
process (neither too early nor over the limit):
https://elixir.bootlin.com/linux/v6.4-rc1/source/Documentation/process/submitting-patches.rst#L597

Subject:

dt-bindings: soc: rockchip,vop2:
or
dt-bindings: rockchip,vop2:


Acked-by: Krzysztof Kozlowski 


---

This is an automated instruction, just in case, because many review tags
are being ignored. If you know the process, you can skip it (please do
not feel offended by me posting it here - no bad intentions intended).
If you do not know the process, here is a short explanation:

Please add Acked-by/Reviewed-by/Tested-by tags when posting new
versions, under or above your Signed-off-by tag. Tag is "received", when
provided in a message replied to you on the mailing list. Tools like b4
can help here. However, there's no need to repost patches *only* to add
the tags. The upstream maintainer will do that for tags received on the
version they apply.

https://elixir.bootlin.com/linux/v6.5-rc3/source/Documentation/process/submitting-patches.rst#L577

Best regards,
Krzysztof



Re: [PATCH v2 08/12] dt-bindings: display: vop2: Add rk3588 support

2023-11-22 Thread Krzysztof Kozlowski
On 22/11/2023 13:55, Andy Yan wrote:
> From: Andy Yan 
> 
> The vop2 on rk3588 is similar to which on rk356x
> but with 4 video ports and need to reference
> more grf modules.
> 
> Signed-off-by: Andy Yan 
> 
> ---
> 
> Changes in v2:
> - fix errors when running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> 
>  .../display/rockchip/rockchip-vop2.yaml   | 27 +++
>  1 file changed, 27 insertions(+)
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml 
> b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
> index b60b90472d42..24148d9b3b14 100644
> --- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
> +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
> @@ -20,6 +20,7 @@ properties:
>  enum:
>- rockchip,rk3566-vop
>- rockchip,rk3568-vop
> +  - rockchip,rk3588-vop
>  
>reg:
>  items:
> @@ -42,26 +43,47 @@ properties:
>frame start (VSYNC), line flag and other status interrupts.
>  
>clocks:
> +minItems: 3
>  items:
>- description: Clock for ddr buffer transfer.
>- description: Clock for the ahb bus to R/W the phy regs.
>- description: Pixel clock for video port 0.
>- description: Pixel clock for video port 1.
>- description: Pixel clock for video port 2.
> +  - description: Pixel clock for video port 4.
> +  - description: Peripheral clock for vop on rk3588.
>  
>clock-names:
> +minItems: 3

You relax requirements for all existing variants here which is not
explained in commit msg. I assume this was not intentional, so you need
to re-constrain them in allOf:if:then.

See for example:
https://elixir.bootlin.com/linux/v5.19-rc6/source/Documentation/devicetree/bindings/clock/samsung,exynos7-clock.yaml#L57
for some ideas.

>  items:
>- const: aclk
>- const: hclk
>- const: dclk_vp0
>- const: dclk_vp1
>- const: dclk_vp2
> +  - const: dclk_vp3
> +  - const: pclk_vop
>  
>rockchip,grf:
>  $ref: /schemas/types.yaml#/definitions/phandle
>  description:
>Phandle to GRF regs used for misc control
>  
> +  rockchip,vo-grf:
> +$ref: /schemas/types.yaml#/definitions/phandle
> +description:
> +  Phandle to VO GRF regs used for misc control, required for rk3588

Drop last sentence, instead add it to required in allOf:if:then.

Is this valid for other variants? If not, should be disallowed in
allOf:if:then: for them.

> +
> +  rockchip,vop-grf:
> +$ref: /schemas/types.yaml#/definitions/phandle
> +description:
> +  Phandle to VOP GRF regs used for misc control, required for rk3588
> +
> +  rockchip,pmu:
> +$ref: /schemas/types.yaml#/definitions/phandle
> +description:
> +  Phandle to PMU regs used for misc control, required for rk3588

For all these three: what is "misc control"? Way too vague. Everything
is a misc and everything can be control. You must be here specific and
much more descriptive.

> +
>ports:
>  $ref: /schemas/graph.yaml#/properties/ports
>  
> @@ -81,6 +103,11 @@ properties:
>  description:
>Output endpoint of VP2
>  
> +  port@3:
> +$ref: /schemas/graph.yaml#/properties/port
> +description:
> +  Output endpoint of VP3

Valid for other variants?

Best regards,
Krzysztof



Re: [PATCH] dma-buf: Correct the documentation of name and exp_name symbols

2023-11-22 Thread Christian König

Am 22.11.23 um 17:05 schrieb Ramesh Errabolu:

Fix the documentation of struct dma_buf members name and exp_name
as to how these members are to be used and accessed.

Signed-off-by: Ramesh Errabolu 


Reviewed-by: Christian König 


---
  include/linux/dma-buf.h | 11 +++
  1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index 3f31baa3293f..8ff4add71f88 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -343,16 +343,19 @@ struct dma_buf {
/**
 * @exp_name:
 *
-* Name of the exporter; useful for debugging. See the
-* DMA_BUF_SET_NAME IOCTL.
+* Name of the exporter; useful for debugging. Must not be NULL
 */
const char *exp_name;
  
  	/**

 * @name:
 *
-* Userspace-provided name; useful for accounting and debugging,
-* protected by dma_resv_lock() on @resv and @name_lock for read access.
+* Userspace-provided name. Default value is NULL. If not NULL,
+* length cannot be longer than DMA_BUF_NAME_LEN, including NIL
+* char. Useful for accounting and debugging. Read/Write accesses
+* are protected by @name_lock
+*
+* See the IOCTLs DMA_BUF_SET_NAME or DMA_BUF_SET_NAME_A/B
 */
const char *name;
  




Re: Implement per-key keyboard backlight as auxdisplay?

2023-11-22 Thread Hans de Goede
Hi Werner,

On 11/21/23 14:29, Werner Sembach wrote:
> 
> Am 21.11.23 um 13:20 schrieb Hans de Goede:
>> Hi Werner,
>>
>> On 11/21/23 12:33, Werner Sembach wrote:
>>> Hi,
>>>
>>> Am 20.11.23 um 21:52 schrieb Pavel Machek:
 Hi!

>>> So... a bit of rationale. The keyboard does not really fit into the
>>> LED subsystem; LEDs are expected to be independent ("hdd led") and not
>>> a matrix of them.
>> Makes sense.
>>
>>> We do see various strange displays these days -- they commonly have
>>> rounded corners and holes in them. I'm not sure how that's currently
>>> supported, but I believe it is reasonable to view keyboard as a
>>> display with slightly weird placing of pixels.
>>>
>>> Plus, I'd really like to play tetris on one of those :-).
>>>
>>> So, would presenting them as auxdisplay be acceptable? Or are there
>>> better options?
>> It sounds like a fair use case -- auxdisplay are typically simple
>> character-based or small graphical displays, e.g. 128x64, that may not
>> be a "main" / usual screen as typically understood, but the concept is
>> a bit fuzzy and we are a bit of a catch-all.
>>
>> And "keyboard backlight display with a pixel/color per-key" does not
>> sound like a "main" screen, and having some cute effects displayed
>> there are the kind of thing that one could do in the usual small
>> graphical ones too. :)
>>
>> But if somebody prefers to create new categories (or subcategories
>> within auxdisplay) to hold these, that could be nice too (in the
>> latter case, I would perhaps suggest reorganizing all of the existing
>> ones while at it).
> One could also reasonably make the argument that controlling the
> individual keyboard key backlights should be part of the input
> subsystem. It's not a display per se. (Unless you actually have small
> displays on the keycaps, and I think that's a thing too.)
 While it would not be completely crazy to do that... I believe the
 backlight is more of a display and less of a keyboard. Plus input
 subystem is very far away from supporting this, and we had no input
 from input people here.

 I don't think LED subsystem is right place for this, and I believe
 auxdisplay makes slightly more sense than input.

 Unless someone steps up, I'd suggest Werner tries to implement this as
 an auxdisplay. [And yes, this will not be simple task. RGB on LED is
 different from RGB on display. But there are other LED displays, so
 auxdisplay should handle this. Plus pixels are really funnily
 shaped. But displays with missing pixels -- aka holes for camera --
 are common in phones, and I believe we'll get variable pixel densities
 -- less dense over camera -- too. So displays will have to deal with
 these in the end.]
>>> Another idea I want to throw in the mix:
>>>
>>> Maybe the kernel is not the right place to implement this at all. RGB stuff 
>>> is not at all standardized and every vendor is doing completely different 
>>> interfaces, which does not fit the kernel userpsace apis desire to be 
>>> uniformal and fixed. e.g. Auxdisplay might fit static setting of RGB 
>>> values, but it does not fit the snake-effect mode, or the raindrops mode, 
>>> or the 4-different-colors-in-the-edges-breathing-and-color-cycling mode.
>>>
>>> So my current idea: Implement these keyboards as a single zone RGB 
>>> kbd_backlight in the leds interface to have something functional out of the 
>>> box, but make it runtime disable-able if something like 
>>> https://gitlab.com/CalcProgrammer1/OpenRGB wants to take over more fine 
>>> granular control from userspace via hidraw.
>> That sounds like a good approach to me. We are seeing the same with game 
>> controllers where steam and wine/proton also sometimes use hidraw mode to 
>> get access to all the crazy^W interesting features.
>>
>> That would mean that all we need to standardize and the kernel <-> userspace 
>> API level is adding a standard way to disable the single zone RGB 
>> kbd_backlight support in the kernel.
> 
> I would suggest a simple "enable" entry. Default is 1. When set to 0 the 
> kernel driver no longer does anything.

I'm not in favor of using "enable" as sysfs attribute for this,
I would like to see a more descriptive name, how about:

"disable_kernel_kbd_backlight_support"

And then maybe also have the driver actually unregister
the LED class device ?

Or just make the support inactive when writing 1 to
this and allow re-enabling it by writing 0?

> Questions:
> 
> - Should the driver try to reset the settings to boot default? Or just leave 
> the device in the current state? With the former I could see issues that they 
> keyboard is flashing when changing from kernelspace control to userspace 
> control. With the later the burden on bringing the device to a know state 
> lies with the userspace driver.

My vote would 

Re: [PATCH v6 0/6] drm: simplify support for transparent DRM bridges

2023-11-22 Thread Dmitry Baryshkov
On Wed, 22 Nov 2023 at 18:03, Sui Jingfeng  wrote:
>
> Hi,
>
>
> On 2023/11/4 07:03, Dmitry Baryshkov wrote:
> > Supporting DP/USB-C can result in a chain of several transparent
> > bridges (PHY, redrivers, mux, etc). All attempts to implement DP support
> > in a different way resulted either in series of hacks or in device tree
> > not reflecting the actual hardware design. This results in drivers
> > having similar boilerplate code for such bridges.
>
> Please improve the written,  "resulted" -> "yield" ?
>
> > Next, these drivers are susceptible to -EPROBE_DEFER loops: the next
> > bridge can either be probed from the bridge->attach callback, when it is
> > too late to return -EPROBE_DEFER, or from the probe() callback, when the
> > next bridge might not yet be available, because it depends on the
> > resources provided by the probing device. Device links can not fully
> > solve this problem since there are mutual dependencies between adjancent
> > devices.
> >
> > Last, but not least, this results in the the internal knowledge of DRM
>
> There is a duplicated "the" word in this sentence.
>
> As far as I can understand, nearly all of those troubles are because the 
> display bridges
> drivers are designed as a kernel module(.ko) instead of making them as static 
> link-able
> helpers. I means that a display bridge device can not work standalone, as it 
> have to be
> used with a display controller. So a display bridge is just a slave device or 
> a auxiliary
> device. My question is: if it can't works by itself, we probably shouldn't 
> design them as
> kernel modules style. Am I correct?

No. This has nothing to do with the driver being a kernel module or built-in.

>
> > subsystem slowly diffusing into other subsystems, like PHY or USB/TYPEC.
>
> Yeah, this indeed a problem.
>
> > To solve all these issues, define a separate DRM helper, which creates
> > separate aux device just for the bridge.
>
> I'm supporting you if want to solve all these problems, this is fine and 
> thanks a lot.
> But I want to ask a question, now that you are solving these problems by 
> creating separate
> devices, does this manner match the hardware design perfectly? which is the 
> hardware units
> you newly created device is corresponding to?

Aux devices do not always follow the actual hardware internals. For
example, see the TI sn65dsi86 driver, which also uses aux devices to
split dependency and probing chains.

> > During probe such aux device
> > doesn't result in the EPROBE_DEFER loops. Instead it allows the device
> > drivers to probe properly, according to the actual resource
> > dependencies. The bridge auxdevs are then probed when the next bridge
> > becomes available, sparing drivers from drm_bridge_attach() returning
> > -EPROBE_DEFER.
>
> OK, as far as I can understand,  in order to solve the mentioned problem
> you are also retire the defer probe mechanism.

No, I'm not retiring the probe deferral mechanism. Instead I'm
splitting it into two chains. One going from the controller to the
usb-c connector for the signal flow, another going from the connector
back to the drm_encoder for the drm_bridge dependencies.

>
>
> > Changes since v5:
> >   - Removed extra semicolon in !DRM_AUX_HPD_BRIDGE stubs definition.
> >
> > Changes since v4:
> >   - Added documentation for new API (Sima)
> >   - Added generic code to handle "last mile" DP bridges implementing just
> > the HPD functionality.
> >   - Rebased on top of linux-next to be able to drop #ifdef's around
> > drm_bridge->of_node
> >
> > Changes since v3:
> >   - Moved bridge driver to gpu/drm/bridge (Neil Armstrong)
> >   - Renamed it to aux-bridge (since there is already a simple_bridge driver)
> >   - Made CONFIG_OF mandatory for this driver (Neil Armstrong)
> >   - Added missing kfree and ida_free (Dan Carpenter)
> >
> > Changes since v2:
> >   - ifdef'ed bridge->of_node access (LKP)
> >
> > Changes since v1:
> >   - Added EXPORT_SYMBOL_GPL / MODULE_LICENSE / etc. to drm_simple_bridge
> >
> > Dmitry Baryshkov (6):
> >drm/bridge: add transparent bridge helper
> >phy: qcom: qmp-combo: switch to DRM_AUX_BRIDGE
> >usb: typec: nb7vpq904m: switch to DRM_AUX_BRIDGE
> >drm/bridge: implement generic DP HPD bridge
> >soc: qcom: pmic-glink: switch to DRM_AUX_HPD_BRIDGE
> >usb: typec: qcom-pmic-typec: switch to DRM_AUX_HPD_BRIDGE
> >
> >   drivers/gpu/drm/bridge/Kconfig|  17 ++
> >   drivers/gpu/drm/bridge/Makefile   |   2 +
> >   drivers/gpu/drm/bridge/aux-bridge.c   | 140 +++
> >   drivers/gpu/drm/bridge/aux-hpd-bridge.c   | 164 ++
> >   drivers/phy/qualcomm/Kconfig  |   2 +-
> >   drivers/phy/qualcomm/phy-qcom-qmp-combo.c |  44 +
> >   drivers/soc/qcom/Kconfig  |   1 +
> >   drivers/soc/qcom/pmic_glink_altmode.c |  33 +---
> >   drivers/usb/typec/mux/Kconfig |   2 +-
> >   

Re: [PATCH 04/14] drm/i915: Include

2023-11-22 Thread Jani Nikula
On Wed, 22 Nov 2023, Thomas Zimmermann  wrote:
> One of the source files includes  via ,
> which will be removed. Include drm_auth.h directly.
>
> Signed-off-by: Thomas Zimmermann 
> Cc: Jani Nikula 
> Cc: Joonas Lahtinen 
> Cc: Rodrigo Vivi 
> Cc: Tvrtko Ursulin 
> Cc: intel-...@lists.freedesktop.org

Acked-by: Jani Nikula 

> ---
>  drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> index b1aa62dfb155d..81a57dd52dfda 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> @@ -9,6 +9,7 @@
>  #include 
>  #include 
>  
> +#include 
>  #include 
>  
>  #include "display/intel_frontbuffer.h"

-- 
Jani Nikula, Intel


Re: [v6,1/6] drm/bridge: add transparent bridge helper

2023-11-22 Thread Sui Jingfeng

Hi,


On 2023/11/4 07:03, Dmitry Baryshkov wrote:

Define a helper for creating simple transparent bridges which serve the
only purpose of linking devices into the bridge chain up to the last
bridge representing the connector.


As far as I can tell, traditionally, transparent display bridges are
used to refer to the hardware encoders which transform the video signals.
Such as ADV7123/ADV7125(RGB888 to VGA), TFP410 (RGB888 to DVI) etc.
Which can be used without the need of software configuration. TFP410
is a little bit special, it can be configured by I2C interface, but
TFP410 don't support read edid for the monitor. But at the least,
there do has a corresponding *hardware entity* working in the chains.
It is just that it don't need a driver to configure.

Does the "simple transparent bridges" you created has a corresponding
hardware entity? Are you trying to solve software side problems by
abusing the device-driver model?

I'm afraid that the written "simple transparent bridges" is not a
accurate description if you don't really has a hardware entity to
corresponding with. Because all of the classic drm display bridges
are able to transform transfer/consume video(and/or audio) data.
Well, the device you create just can't. Probably, you should call
it as "simple auxiliary device".



This is especially useful for
DP/USB-C bridge chains, which can span across several devices, but do
not require any additional functionality from the intermediate bridges.

Signed-off-by: Dmitry Baryshkov 
Reviewed-by: Neil Armstrong 
---
  drivers/gpu/drm/bridge/Kconfig  |   9 ++
  drivers/gpu/drm/bridge/Makefile |   1 +
  drivers/gpu/drm/bridge/aux-bridge.c | 140 
  include/drm/bridge/aux-bridge.h |  19 
  4 files changed, 169 insertions(+)
  create mode 100644 drivers/gpu/drm/bridge/aux-bridge.c
  create mode 100644 include/drm/bridge/aux-bridge.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index ba82a1142adf..f12eab62799f 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -12,6 +12,15 @@ config DRM_PANEL_BRIDGE
help
  DRM bridge wrapper of DRM panels
  
+config DRM_AUX_BRIDGE

+   tristate
+   depends on DRM_BRIDGE && OF
+   select AUXILIARY_BUS
+   select DRM_PANEL_BRIDGE
+   help
+ Simple transparent bridge that is used by several non-DRM drivers to
+ build bridges chain.
+
  menu "Display Interface Bridges"
depends on DRM && DRM_BRIDGE
  
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile

index 2b892b7ed59e..918e3bfff079 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,4 +1,5 @@
  # SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
  obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
  obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
  obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
diff --git a/drivers/gpu/drm/bridge/aux-bridge.c 
b/drivers/gpu/drm/bridge/aux-bridge.c
new file mode 100644
index ..6245976b8fef
--- /dev/null
+++ b/drivers/gpu/drm/bridge/aux-bridge.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Linaro Ltd.
+ *
+ * Author: Dmitry Baryshkov 
+ */
+#include 
+#include 
+
+#include 
+#include 
+
+static DEFINE_IDA(drm_aux_bridge_ida);
+
+static void drm_aux_bridge_release(struct device *dev)
+{
+   struct auxiliary_device *adev = to_auxiliary_dev(dev);
+
+   ida_free(_aux_bridge_ida, adev->id);
+
+   kfree(adev);
+}
+
+static void drm_aux_bridge_unregister_adev(void *_adev)
+{
+   struct auxiliary_device *adev = _adev;


It seems that the single underscore(prefix) at here is a little bit
not good in looking, please replace it with 'void *data'.



+
+   auxiliary_device_delete(adev);
+   auxiliary_device_uninit(adev);
+}
+
+/**
+ * drm_aux_bridge_register - Create a simple bridge device to link the chain
+ * @parent: device instance providing this bridge
+ *
+ * Creates a simple DRM bridge that doesn't implement any drm_bridge
+ * operations. Such bridges merely fill a place in the bridge chain linking
+ * surrounding DRM bridges.
+ *
+ * Return: zero on success, negative error code on failure
+ */
+int drm_aux_bridge_register(struct device *parent)
+{
+   struct auxiliary_device *adev;
+   int ret;
+
+   adev = kzalloc(sizeof(*adev), GFP_KERNEL);
+   if (!adev)
+   return -ENOMEM;
+
+   ret = ida_alloc(_aux_bridge_ida, GFP_KERNEL);
+   if (ret < 0) {
+   kfree(adev);
+   return ret;
+   }
+
+   adev->id = ret;
+   adev->name = "aux_bridge";
+   adev->dev.parent = parent;
+   adev->dev.of_node = parent->of_node;
+   adev->dev.release = drm_aux_bridge_release;
+
+   ret = auxiliary_device_init(adev);
+   if (ret) {
+   ida_free(_aux_bridge_ida, 

[PATCH v9 20/20] drm/imagination: Add driver documentation

2023-11-22 Thread Donald Robson
From: Sarah Walker 

Add documentation for the UAPI.

Changes since v5:
- Remove obsolete VM documentation

Co-developed-by: Matt Coster 
Signed-off-by: Matt Coster 
Co-developed-by: Donald Robson 
Signed-off-by: Donald Robson 
Signed-off-by: Sarah Walker 
Reviewed-by: Maxime Ripard 
---
 Documentation/gpu/drivers.rst   |   2 +
 Documentation/gpu/imagination/index.rst |  13 ++
 Documentation/gpu/imagination/uapi.rst  | 174 
 MAINTAINERS |   1 +
 4 files changed, 190 insertions(+)
 create mode 100644 Documentation/gpu/imagination/index.rst
 create mode 100644 Documentation/gpu/imagination/uapi.rst

diff --git a/Documentation/gpu/drivers.rst b/Documentation/gpu/drivers.rst
index 45a12e552091..cc6535f5f28c 100644
--- a/Documentation/gpu/drivers.rst
+++ b/Documentation/gpu/drivers.rst
@@ -3,9 +3,11 @@ GPU Driver Documentation
 
 
 .. toctree::
+   :maxdepth: 3
 
amdgpu/index
i915
+   imagination/index
mcde
meson
pl111
diff --git a/Documentation/gpu/imagination/index.rst 
b/Documentation/gpu/imagination/index.rst
new file mode 100644
index ..dc9579e758c3
--- /dev/null
+++ b/Documentation/gpu/imagination/index.rst
@@ -0,0 +1,13 @@
+===
+drm/imagination PowerVR Graphics Driver
+===
+
+.. kernel-doc:: drivers/gpu/drm/imagination/pvr_drv.c
+   :doc: PowerVR Graphics Driver
+
+Contents
+
+.. toctree::
+   :maxdepth: 2
+
+   uapi
diff --git a/Documentation/gpu/imagination/uapi.rst 
b/Documentation/gpu/imagination/uapi.rst
new file mode 100644
index ..2227ea7e6222
--- /dev/null
+++ b/Documentation/gpu/imagination/uapi.rst
@@ -0,0 +1,174 @@
+
+UAPI
+
+The sources associated with this section can be found in ``pvr_drm.h``.
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR UAPI
+
+OBJECT ARRAYS
+=
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_obj_array
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: DRM_PVR_OBJ_ARRAY
+
+IOCTLS
+==
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR IOCTL interface
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: PVR_IOCTL
+
+DEV_QUERY
+-
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR IOCTL DEV_QUERY interface
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_dev_query
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_ioctl_dev_query_args
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_dev_query_gpu_info
+ drm_pvr_dev_query_runtime_info
+ drm_pvr_dev_query_hwrt_info
+ drm_pvr_dev_query_quirks
+ drm_pvr_dev_query_enhancements
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_heap_id
+ drm_pvr_heap
+ drm_pvr_dev_query_heap_info
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: Flags for DRM_PVR_DEV_QUERY_HEAP_INFO_GET.
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_static_data_area_usage
+ drm_pvr_static_data_area
+ drm_pvr_dev_query_static_data_areas
+
+CREATE_BO
+-
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR IOCTL CREATE_BO interface
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_ioctl_create_bo_args
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: Flags for CREATE_BO
+
+GET_BO_MMAP_OFFSET
+--
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR IOCTL GET_BO_MMAP_OFFSET interface
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_ioctl_get_bo_mmap_offset_args
+
+CREATE_VM_CONTEXT and DESTROY_VM_CONTEXT
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR IOCTL CREATE_VM_CONTEXT and DESTROY_VM_CONTEXT interfaces
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_ioctl_create_vm_context_args
+ drm_pvr_ioctl_destroy_vm_context_args
+
+VM_MAP and VM_UNMAP
+---
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR IOCTL VM_MAP and VM_UNMAP interfaces
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_ioctl_vm_map_args
+ drm_pvr_ioctl_vm_unmap_args
+
+CREATE_CONTEXT and DESTROY_CONTEXT
+--
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :doc: PowerVR IOCTL CREATE_CONTEXT and DESTROY_CONTEXT interfaces
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_ioctl_create_context_args
+
+.. kernel-doc:: include/uapi/drm/pvr_drm.h
+   :identifiers: drm_pvr_ctx_priority
+ drm_pvr_ctx_type
+ drm_pvr_static_render_context_state
+ drm_pvr_static_render_context_state_format
+  

[PATCH v9 19/20] drm/imagination: Add firmware trace to debugfs

2023-11-22 Thread Donald Robson
From: Sarah Walker 

Firmware trace is exposed at /sys/debug/dri//pvr_fw/trace_0.
Trace is enabled via the group mask at
/sys/debug/dri//pvr_params/fw_trace_mask.

Changes since v8:
- Corrected license identifiers

Changes since v3:
- Use drm_dev_{enter,exit}

Co-developed-by: Matt Coster 
Signed-off-by: Matt Coster 
Signed-off-by: Sarah Walker 
Signed-off-by: Donald Robson 
---
 drivers/gpu/drm/imagination/Makefile   |   4 +
 drivers/gpu/drm/imagination/pvr_debugfs.c  |  53 +++
 drivers/gpu/drm/imagination/pvr_debugfs.h  |  29 ++
 drivers/gpu/drm/imagination/pvr_device.c   |   9 +
 drivers/gpu/drm/imagination/pvr_device.h   |  10 +
 drivers/gpu/drm/imagination/pvr_drv.c  |   4 +
 drivers/gpu/drm/imagination/pvr_fw_trace.c | 395 +
 drivers/gpu/drm/imagination/pvr_params.c   | 147 
 drivers/gpu/drm/imagination/pvr_params.h   |  72 
 9 files changed, 723 insertions(+)
 create mode 100644 drivers/gpu/drm/imagination/pvr_debugfs.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_debugfs.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_params.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_params.h

diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index 7e3515c99caa..ec6db8e9b403 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -20,6 +20,7 @@ powervr-y := \
pvr_hwrt.o \
pvr_job.o \
pvr_mmu.o \
+   pvr_params.o \
pvr_power.o \
pvr_queue.o \
pvr_stream.o \
@@ -28,4 +29,7 @@ powervr-y := \
pvr_vm.o \
pvr_vm_mips.o
 
+powervr-$(CONFIG_DEBUG_FS) += \
+   pvr_debugfs.o
+
 obj-$(CONFIG_DRM_POWERVR) += powervr.o
diff --git a/drivers/gpu/drm/imagination/pvr_debugfs.c 
b/drivers/gpu/drm/imagination/pvr_debugfs.c
new file mode 100644
index ..6b77c9b4bde8
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_debugfs.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#include "pvr_debugfs.h"
+
+#include "pvr_device.h"
+#include "pvr_fw_trace.h"
+#include "pvr_params.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+static const struct pvr_debugfs_entry pvr_debugfs_entries[] = {
+   {"pvr_params", pvr_params_debugfs_init},
+   {"pvr_fw", pvr_fw_trace_debugfs_init},
+};
+
+void
+pvr_debugfs_init(struct drm_minor *minor)
+{
+   struct drm_device *drm_dev = minor->dev;
+   struct pvr_device *pvr_dev = to_pvr_device(drm_dev);
+   struct dentry *root = minor->debugfs_root;
+   size_t i;
+
+   for (i = 0; i < ARRAY_SIZE(pvr_debugfs_entries); ++i) {
+   const struct pvr_debugfs_entry *entry = _debugfs_entries[i];
+   struct dentry *dir;
+
+   dir = debugfs_create_dir(entry->name, root);
+   if (IS_ERR(dir)) {
+   drm_warn(drm_dev,
+"failed to create debugfs dir '%s' (err=%d)",
+entry->name, (int)PTR_ERR(dir));
+   continue;
+   }
+
+   entry->init(pvr_dev, dir);
+   }
+}
+
+/*
+ * Since all entries are created under _minor->debugfs_root, there's no
+ * need for a pvr_debugfs_fini() as DRM will clean up everything under its root
+ * automatically.
+ */
diff --git a/drivers/gpu/drm/imagination/pvr_debugfs.h 
b/drivers/gpu/drm/imagination/pvr_debugfs.h
new file mode 100644
index ..ebacbd13b84a
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_debugfs.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#ifndef PVR_DEBUGFS_H
+#define PVR_DEBUGFS_H
+
+/* Forward declaration from . */
+struct drm_minor;
+
+#if defined(CONFIG_DEBUG_FS)
+/* Forward declaration from "pvr_device.h". */
+struct pvr_device;
+
+/* Forward declaration from . */
+struct dentry;
+
+struct pvr_debugfs_entry {
+   const char *name;
+   void (*init)(struct pvr_device *pvr_dev, struct dentry *dir);
+};
+
+void pvr_debugfs_init(struct drm_minor *minor);
+#else /* defined(CONFIG_DEBUG_FS) */
+#include 
+
+static __always_inline void pvr_debugfs_init(struct drm_minor *minor) {}
+#endif /* defined(CONFIG_DEBUG_FS) */
+
+#endif /* PVR_DEBUGFS_H */
diff --git a/drivers/gpu/drm/imagination/pvr_device.c 
b/drivers/gpu/drm/imagination/pvr_device.c
index 199f812d1ee7..8499becf4fbb 100644
--- a/drivers/gpu/drm/imagination/pvr_device.c
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -5,6 +5,7 @@
 #include "pvr_device_info.h"
 
 #include "pvr_fw.h"
+#include "pvr_params.h"
 #include "pvr_power.h"
 #include "pvr_queue.h"
 #include "pvr_rogue_cr_defs.h"
@@ -495,6 +496,14 @@ pvr_device_init(struct pvr_device *pvr_dev)
struct device *dev = drm_dev->dev;
int err;
 
+   /*
+* Setup device parameters. We do this 

[PATCH v9 18/20] drm/imagination: Add firmware trace header

2023-11-22 Thread Donald Robson
From: Sarah Walker 

Changes since v8:
- Corrected license identifiers

Changes since v5:
- Split up header commit due to size

Signed-off-by: Sarah Walker 
Signed-off-by: Donald Robson 
---
 .../gpu/drm/imagination/pvr_rogue_fwif_sf.h   | 1648 +
 1 file changed, 1648 insertions(+)
 create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_fwif_sf.h

diff --git a/drivers/gpu/drm/imagination/pvr_rogue_fwif_sf.h 
b/drivers/gpu/drm/imagination/pvr_rogue_fwif_sf.h
new file mode 100644
index ..571954182f33
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_rogue_fwif_sf.h
@@ -0,0 +1,1648 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#ifndef PVR_ROGUE_FWIF_SF_H
+#define PVR_ROGUE_FWIF_SF_H
+
+/*
+ **
+ * *DO*NOT* rearrange or delete lines in rogue_fw_log_sfgroups or stid_fmts
+ *   WILL BREAK fw tracing message compatibility with previous
+ *   fw versions. Only add new ones, if so required.
+ **
+ */
+
+/* Available log groups. */
+enum rogue_fw_log_sfgroups {
+   ROGUE_FW_GROUP_NULL,
+   ROGUE_FW_GROUP_MAIN,
+   ROGUE_FW_GROUP_CLEANUP,
+   ROGUE_FW_GROUP_CSW,
+   ROGUE_FW_GROUP_PM,
+   ROGUE_FW_GROUP_RTD,
+   ROGUE_FW_GROUP_SPM,
+   ROGUE_FW_GROUP_MTS,
+   ROGUE_FW_GROUP_BIF,
+   ROGUE_FW_GROUP_MISC,
+   ROGUE_FW_GROUP_POW,
+   ROGUE_FW_GROUP_HWR,
+   ROGUE_FW_GROUP_HWP,
+   ROGUE_FW_GROUP_RPM,
+   ROGUE_FW_GROUP_DMA,
+   ROGUE_FW_GROUP_DBG,
+};
+
+#define PVR_SF_STRING_MAX_SIZE 256U
+
+/* pair of string format id and string formats */
+struct rogue_fw_stid_fmt {
+   u32 id;
+   char name[PVR_SF_STRING_MAX_SIZE];
+};
+
+/*
+ *  The symbolic names found in the table above are assigned an u32 value of
+ *  the following format:
+ *  31 30 28 27   20   19  1615  12  110   bits
+ *  -   ---         
+ * 0-11: id number
+ *12-15: group id number
+ *16-19: number of parameters
+ *20-27: unused
+ *28-30: active: identify SF packet, otherwise regular int32
+ *   31: reserved for signed/unsigned compatibility
+ *
+ *   The following macro assigns those values to the enum generated SF ids 
list.
+ */
+#define ROGUE_FW_LOG_IDMARKER (0x7000U)
+#define ROGUE_FW_LOG_CREATESFID(a, b, e) ((u32)(a) | ((u32)(b) << 12) | 
((u32)(e) << 16) | \
+ ROGUE_FW_LOG_IDMARKER)
+
+#define ROGUE_FW_LOG_IDMASK (0xFFF0)
+#define ROGUE_FW_LOG_VALIDID(I) (((I) & ROGUE_FW_LOG_IDMASK) == 
ROGUE_FW_LOG_IDMARKER)
+
+/* Return the group id that the given (enum generated) id belongs to */
+#define ROGUE_FW_SF_GID(x) (((u32)(x) >> 12) & 0xfU)
+/* Returns how many arguments the SF(string format) for the given (enum 
generated) id requires */
+#define ROGUE_FW_SF_PARAMNUM(x) (((u32)(x) >> 16) & 0xfU)
+
+/* pair of string format id and string formats */
+struct rogue_km_stid_fmt {
+   u32 id;
+   const char *name;
+};
+
+static const struct rogue_km_stid_fmt stid_fmts[] = {
+   { ROGUE_FW_LOG_CREATESFID(0, ROGUE_FW_GROUP_NULL, 0),
+ "You should not use this string" },
+
+   { ROGUE_FW_LOG_CREATESFID(1, ROGUE_FW_GROUP_MAIN, 6),
+ "Kick 3D: FWCtx 0x%08.8x @ %d, RTD 0x%08x. Partial render:%d, CSW 
resume:%d, prio:%d" },
+   { ROGUE_FW_LOG_CREATESFID(2, ROGUE_FW_GROUP_MAIN, 2),
+ "3D finished, HWRTData0State=%x, HWRTData1State=%x" },
+   { ROGUE_FW_LOG_CREATESFID(3, ROGUE_FW_GROUP_MAIN, 4),
+ "Kick 3D TQ: FWCtx 0x%08.8x @ %d, CSW resume:%d, prio: %d" },
+   { ROGUE_FW_LOG_CREATESFID(4, ROGUE_FW_GROUP_MAIN, 0),
+ "3D Transfer finished" },
+   { ROGUE_FW_LOG_CREATESFID(5, ROGUE_FW_GROUP_MAIN, 3),
+ "Kick Compute: FWCtx 0x%08.8x @ %d, prio: %d" },
+   { ROGUE_FW_LOG_CREATESFID(6, ROGUE_FW_GROUP_MAIN, 0),
+ "Compute finished" },
+   { ROGUE_FW_LOG_CREATESFID(7, ROGUE_FW_GROUP_MAIN, 7),
+ "Kick TA: FWCtx 0x%08.8x @ %d, RTD 0x%08x. First kick:%d, Last 
kick:%d, CSW resume:%d, prio:%d" },
+   { ROGUE_FW_LOG_CREATESFID(8, ROGUE_FW_GROUP_MAIN, 0),
+ "TA finished" },
+   { ROGUE_FW_LOG_CREATESFID(9, ROGUE_FW_GROUP_MAIN, 0),
+ "Restart TA after partial render" },
+   { ROGUE_FW_LOG_CREATESFID(10, ROGUE_FW_GROUP_MAIN, 0),
+ "Resume TA without partial render" },
+   { ROGUE_FW_LOG_CREATESFID(11, ROGUE_FW_GROUP_MAIN, 2),
+ "Out of memory! Context 0x%08x, HWRTData 0x%x" },
+   { ROGUE_FW_LOG_CREATESFID(12, ROGUE_FW_GROUP_MAIN, 3),
+ "Kick TLA: FWCtx 0x%08.8x @ %d, prio:%d" },
+   { ROGUE_FW_LOG_CREATESFID(13, ROGUE_FW_GROUP_MAIN, 0),
+ "TLA finished" },
+   { ROGUE_FW_LOG_CREATESFID(14, ROGUE_FW_GROUP_MAIN, 3),
+ "cCCB 

[PATCH v9 03/20] dt-bindings: gpu: Add Imagination Technologies PowerVR/IMG GPU

2023-11-22 Thread Donald Robson
From: Sarah Walker 

Add the device tree binding documentation for the IMG AXE GPU used in
TI AM62 SoCs.

Co-developed-by: Frank Binns 
Signed-off-by: Frank Binns 
Signed-off-by: Sarah Walker 
Signed-off-by: Donald Robson 
Reviewed-by: Maxime Ripard 
Reviewed-by: Linus Walleij 
Reviewed-by: Conor Dooley 
---
Changes since v8:
- Updated maintainer

Changes since v7:
- Updated maintainer

Changes since v6:
- Remove unused gpu label from example
- Updated maintainer

Changes since v5:
- Update compatible string & description to match marketing name
- Remove unnecessary clock-names definition in ti,am62-gpu constraints
- Document that GPU revision is discoverable

Changes since v4:
- Add clocks constraint for ti,am62-gpu
- Remove excess address and size cells in example
- Remove interrupt name and add maxItems
- Make property order consistent between dts and bindings doc
- Update example to match dts

Changes since v3:
- Remove oneOf in compatible property
- Remove power-supply (not used on AM62)

Changes since v2:
- Add commit message description
- Remove mt8173-gpu support (not currently supported)
- Drop quotes from $id and $schema
- Remove reg: minItems
- Drop _clk suffixes from clock-names
- Remove operating-points-v2 property and cooling-cells (not currently
  used)
- Add additionalProperties: false
- Remove stray blank line at the end of file

 .../devicetree/bindings/gpu/img,powervr.yaml  | 73 +++
 MAINTAINERS   |  7 ++
 2 files changed, 80 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpu/img,powervr.yaml

diff --git a/Documentation/devicetree/bindings/gpu/img,powervr.yaml 
b/Documentation/devicetree/bindings/gpu/img,powervr.yaml
new file mode 100644
index ..a13298f1a182
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpu/img,powervr.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (c) 2023 Imagination Technologies Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpu/img,powervr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Imagination Technologies PowerVR and IMG GPU
+
+maintainers:
+  - Frank Binns 
+
+properties:
+  compatible:
+items:
+  - enum:
+  - ti,am62-gpu
+  - const: img,img-axe # IMG AXE GPU model/revision is fully discoverable
+
+  reg:
+maxItems: 1
+
+  clocks:
+minItems: 1
+maxItems: 3
+
+  clock-names:
+items:
+  - const: core
+  - const: mem
+  - const: sys
+minItems: 1
+
+  interrupts:
+maxItems: 1
+
+  power-domains:
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+
+additionalProperties: false
+
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+const: ti,am62-gpu
+then:
+  properties:
+clocks:
+  maxItems: 1
+
+examples:
+  - |
+#include 
+#include 
+#include 
+
+gpu@fd0 {
+compatible = "ti,am62-gpu", "img,img-axe";
+reg = <0x0fd0 0x2>;
+clocks = <_clks 187 0>;
+clock-names = "core";
+interrupts = ;
+power-domains = <_pds 187 TI_SCI_PD_EXCLUSIVE>;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 8a70be8f08ee..59c60abf341e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10392,6 +10392,13 @@ IMGTEC IR DECODER DRIVER
 S: Orphan
 F: drivers/media/rc/img-ir/
 
+IMGTEC POWERVR DRM DRIVER
+M: Frank Binns 
+M: Donald Robson 
+M: Matt Coster 
+S: Supported
+F: Documentation/devicetree/bindings/gpu/img,powervr.yaml
+
 IMON SOUNDGRAPH USB IR RECEIVER
 M: Sean Young 
 L: linux-me...@vger.kernel.org
-- 
2.25.1



[PATCH v9 05/20] drm/imagination: Add skeleton PowerVR driver

2023-11-22 Thread Donald Robson
From: Sarah Walker 

This adds the basic skeleton of the driver. The driver registers
itself with DRM on probe. Ioctl handlers are currently implemented
as stubs.

Changes since v8:
- Corrected license identifiers

Changes since v5:
- Update compatible string & description to match marketing name
- Checkpatch fixes in to/from_pvr_device/file macros

Changes since v3:
- Clarify supported GPU generations in driver description
- Use drm_dev_unplug() when removing device
- Change from_* and to_* functions to macros
- Fix IS_PTR/PTR_ERR confusion in pvr_probe()
- Remove err_out labels in favour of direct returning
- Remove specific am62 compatible match string
- Drop MODULE_FIRMWARE()

Co-developed-by: Frank Binns 
Signed-off-by: Frank Binns 
Co-developed-by: Matt Coster 
Signed-off-by: Matt Coster 
Signed-off-by: Sarah Walker 
Signed-off-by: Donald Robson 
Reviewed-by: Maxime Ripard 
---
 MAINTAINERS  |   1 +
 drivers/gpu/drm/Kconfig  |   2 +
 drivers/gpu/drm/Makefile |   1 +
 drivers/gpu/drm/imagination/Kconfig  |  15 +
 drivers/gpu/drm/imagination/Makefile |   9 +
 drivers/gpu/drm/imagination/pvr_device.h | 153 +++
 drivers/gpu/drm/imagination/pvr_drv.c| 509 +++
 drivers/gpu/drm/imagination/pvr_drv.h|  22 +
 8 files changed, 712 insertions(+)
 create mode 100644 drivers/gpu/drm/imagination/Kconfig
 create mode 100644 drivers/gpu/drm/imagination/Makefile
 create mode 100644 drivers/gpu/drm/imagination/pvr_device.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_drv.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_drv.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 37642011c319..debbc1956b8e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10398,6 +10398,7 @@ M:  Donald Robson 
 M: Matt Coster 
 S: Supported
 F: Documentation/devicetree/bindings/gpu/img,powervr.yaml
+F: drivers/gpu/drm/imagination/
 F: include/uapi/drm/pvr_drm.h
 
 IMON SOUNDGRAPH USB IR RECEIVER
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index cdbc56e07649..740c1c0bd068 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -394,6 +394,8 @@ source "drivers/gpu/drm/solomon/Kconfig"
 
 source "drivers/gpu/drm/sprd/Kconfig"
 
+source "drivers/gpu/drm/imagination/Kconfig"
+
 config DRM_HYPERV
tristate "DRM Support for Hyper-V synthetic video device"
depends on DRM && PCI && MMU && HYPERV
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index cdbe91ac0bfc..b4cb0835620a 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -199,3 +199,4 @@ obj-$(CONFIG_DRM_HYPERV) += hyperv/
 obj-y  += solomon/
 obj-$(CONFIG_DRM_SPRD) += sprd/
 obj-$(CONFIG_DRM_LOONGSON) += loongson/
+obj-$(CONFIG_DRM_POWERVR) += imagination/
diff --git a/drivers/gpu/drm/imagination/Kconfig 
b/drivers/gpu/drm/imagination/Kconfig
new file mode 100644
index ..03d0a5031f5c
--- /dev/null
+++ b/drivers/gpu/drm/imagination/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-only OR MIT
+# Copyright (c) 2023 Imagination Technologies Ltd.
+
+config DRM_POWERVR
+   tristate "Imagination Technologies PowerVR (Series 6 and later) & IMG 
Graphics"
+   depends on ARM64
+   depends on DRM
+   select DRM_GEM_SHMEM_HELPER
+   select DRM_SCHED
+   select FW_LOADER
+   help
+ Choose this option if you have a system that has an Imagination
+ Technologies PowerVR (Series 6 or later) or IMG GPU.
+
+ If "M" is selected, the module will be called powervr.
diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
new file mode 100644
index ..f12a06ada9ec
--- /dev/null
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-only OR MIT
+# Copyright (c) 2023 Imagination Technologies Ltd.
+
+subdir-ccflags-y := -I$(srctree)/$(src)
+
+powervr-y := \
+   pvr_drv.o \
+
+obj-$(CONFIG_DRM_POWERVR) += powervr.o
diff --git a/drivers/gpu/drm/imagination/pvr_device.h 
b/drivers/gpu/drm/imagination/pvr_device.h
new file mode 100644
index ..d3629164a629
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_device.h
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#ifndef PVR_DEVICE_H
+#define PVR_DEVICE_H
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * struct pvr_device - powervr-specific wrapper for  drm_device
+ */
+struct pvr_device {
+   /**
+* @base: The underlying  drm_device.
+*
+* Do not access this member directly, instead call
+* from_pvr_device().
+*/
+   struct drm_device base;
+};
+
+/**
+ * struct pvr_file - powervr-specific data to be assigned to 
+ * drm_file.driver_priv
+ */
+struct pvr_file {
+   /**
+* 

[PATCH v9 04/20] drm/imagination/uapi: Add PowerVR driver UAPI

2023-11-22 Thread Donald Robson
From: Sarah Walker 

Add the UAPI implementation for the PowerVR driver.

Changes from v8:
- Fixed documentation for unmapping, which previously suggested the
  size was not used
- Corrected license identifier

Changes from v7:
- Remove prefixes from DRM_PVR_BO_* flags
- Improve struct drm_pvr_ioctl_create_hwrt_dataset_args documentation
- Remove references to static area carveouts
- CREATE_BO ioctl now returns an error if provided size isn't page aligned
- Clarify documentation for DRM_PVR_STATIC_DATA_AREA_EOT

Changes from v6:
- Add padding to struct drm_pvr_dev_query_gpu_info
- Improve BYPASS_CACHE flag documentation
- Add SUBMIT_JOB_FRAG_CMD_DISABLE_PIXELMERGE flag

Changes from v4:
- Remove CREATE_ZEROED flag for BO creation (all buffers are now zeroed)

Co-developed-by: Frank Binns 
Signed-off-by: Frank Binns 
Co-developed-by: Boris Brezillon 
Signed-off-by: Boris Brezillon 
Co-developed-by: Matt Coster 
Signed-off-by: Matt Coster 
Co-developed-by: Donald Robson 
Signed-off-by: Donald Robson 
Signed-off-by: Sarah Walker 
Reviewed-by: Faith Ekstrand 
---
 MAINTAINERS|1 +
 include/uapi/drm/pvr_drm.h | 1297 
 2 files changed, 1298 insertions(+)
 create mode 100644 include/uapi/drm/pvr_drm.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 59c60abf341e..37642011c319 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10398,6 +10398,7 @@ M:  Donald Robson 
 M: Matt Coster 
 S: Supported
 F: Documentation/devicetree/bindings/gpu/img,powervr.yaml
+F: include/uapi/drm/pvr_drm.h
 
 IMON SOUNDGRAPH USB IR RECEIVER
 M: Sean Young 
diff --git a/include/uapi/drm/pvr_drm.h b/include/uapi/drm/pvr_drm.h
new file mode 100644
index ..1834375390c4
--- /dev/null
+++ b/include/uapi/drm/pvr_drm.h
@@ -0,0 +1,1297 @@
+/* SPDX-License-Identifier: (GPL-2.0-only WITH Linux-syscall-note) OR MIT */
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#ifndef PVR_DRM_UAPI_H
+#define PVR_DRM_UAPI_H
+
+#include "drm.h"
+
+#include 
+#include 
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/**
+ * DOC: PowerVR UAPI
+ *
+ * The PowerVR IOCTL argument structs have a few limitations in place, in
+ * addition to the standard kernel restrictions:
+ *
+ *  - All members must be type-aligned.
+ *  - The overall struct must be padded to 64-bit alignment.
+ *  - Explicit padding is almost always required. This takes the form of
+ *``_padding_[x]`` members of sufficient size to pad to the next 
power-of-two
+ *alignment, where [x] is the offset into the struct in hexadecimal. Arrays
+ *are never used for alignment. Padding fields must be zeroed; this is
+ *always checked.
+ *  - Unions may only appear as the last member of a struct.
+ *  - Individual union members may grow in the future. The space between the
+ *end of a union member and the end of its containing union is considered
+ *"implicit padding" and must be zeroed. This is always checked.
+ *
+ * In addition to the IOCTL argument structs, the PowerVR UAPI makes use of
+ * DEV_QUERY argument structs. These are used to fetch information about the
+ * device and runtime. These structs are subject to the same rules set out
+ * above.
+ */
+
+/**
+ * struct drm_pvr_obj_array - Container used to pass arrays of objects
+ *
+ * It is not unusual to have to extend objects to pass new parameters, and the 
DRM
+ * ioctl infrastructure is supporting that by padding ioctl arguments with 
zeros
+ * when the data passed by userspace is smaller than the struct defined in the
+ * drm_ioctl_desc, thus keeping things backward compatible. This type is just
+ * applying the same concepts to indirect objects passed through arrays 
referenced
+ * from the main ioctl arguments structure: the stride basically defines the 
size
+ * of the object passed by userspace, which allows the kernel driver to pad 
with
+ * zeros when it's smaller than the size of the object it expects.
+ *
+ * Use ``DRM_PVR_OBJ_ARRAY()`` to fill object array fields, unless you
+ * have a very good reason not to.
+ */
+struct drm_pvr_obj_array {
+   /** @stride: Stride of object struct. Used for versioning. */
+   __u32 stride;
+
+   /** @count: Number of objects in the array. */
+   __u32 count;
+
+   /** @array: User pointer to an array of objects. */
+   __u64 array;
+};
+
+/**
+ * DRM_PVR_OBJ_ARRAY() - Helper macro for filling  drm_pvr_obj_array.
+ * @cnt: Number of elements pointed to py @ptr.
+ * @ptr: Pointer to start of a C array.
+ *
+ * Return: Literal of type  drm_pvr_obj_array.
+ */
+#define DRM_PVR_OBJ_ARRAY(cnt, ptr) \
+   { .stride = sizeof((ptr)[0]), .count = (cnt), .array = 
(__u64)(uintptr_t)(ptr) }
+
+/**
+ * DOC: PowerVR IOCTL interface
+ */
+
+/**
+ * PVR_IOCTL() - Build a PowerVR IOCTL number
+ * @_ioctl: An incrementing id for this IOCTL. Added to %DRM_COMMAND_BASE.
+ * @_mode: Must be one of %DRM_IOR, %DRM_IOW or %DRM_IOWR.
+ * @_data: The type of the args struct 

[PATCH v9 17/20] drm/imagination: Implement job submission and scheduling

2023-11-22 Thread Donald Robson
From: Sarah Walker 

Implement job submission ioctl. Job scheduling is implemented using
drm_sched.

Jobs are submitted in a stream format. This is intended to allow the UAPI
data format to be independent of the actual FWIF structures in use, which
vary depending on the GPU in use.

The stream formats are documented at:
https://gitlab.freedesktop.org/mesa/mesa/-/blob/f8d2b42ae65c2f16f36a43e0ae39d288431e4263/src/imagination/csbgen/rogue_kmd_stream.xml

Changes since v8:
- Updated for upstreamed DRM scheduler changes
- Removed workaround code for the pending_list previously being updated
  after run_job() returned
- Fixed null deref in pvr_queue_cleanup_fw_context() for bad stream ptr
  given to create_context ioctl
- Corrected license identifiers

Changes since v7:
- Updated for v8 "DRM scheduler changes for XE" patchset

Changes since v6:
- Fix fence handling in pvr_sync_signal_array_add()
- Add handling for SUBMIT_JOB_FRAG_CMD_DISABLE_PIXELMERGE flag
- Fix missing dma_resv locking in job submit path

Changes since v5:
- Fix leak in job creation error path

Changes since v4:
- Use a regular workqueue for job scheduling

Changes since v3:
- Support partial render jobs
- Add job timeout handler
- Split sync handling out of job code
- Use drm_dev_{enter,exit}

Changes since v2:
- Use drm_sched for job scheduling

Co-developed-by: Boris Brezillon 
Signed-off-by: Boris Brezillon 
Co-developed-by: Donald Robson 
Signed-off-by: Donald Robson 
Signed-off-by: Sarah Walker 
---
 drivers/gpu/drm/imagination/Kconfig   |1 +
 drivers/gpu/drm/imagination/Makefile  |3 +
 drivers/gpu/drm/imagination/pvr_context.c |  125 +-
 drivers/gpu/drm/imagination/pvr_context.h |   44 +
 drivers/gpu/drm/imagination/pvr_device.c  |   31 +
 drivers/gpu/drm/imagination/pvr_device.h  |   21 +
 drivers/gpu/drm/imagination/pvr_drv.c |   40 +-
 drivers/gpu/drm/imagination/pvr_job.c |  788 +
 drivers/gpu/drm/imagination/pvr_job.h |  161 ++
 drivers/gpu/drm/imagination/pvr_power.c   |   28 +
 drivers/gpu/drm/imagination/pvr_queue.c   | 1432 +
 drivers/gpu/drm/imagination/pvr_queue.h   |  169 ++
 drivers/gpu/drm/imagination/pvr_stream_defs.c |  226 +++
 drivers/gpu/drm/imagination/pvr_sync.c|  289 
 drivers/gpu/drm/imagination/pvr_sync.h|   84 +
 15 files changed, 3438 insertions(+), 4 deletions(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_job.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_job.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_queue.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_queue.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_sync.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_sync.h

diff --git a/drivers/gpu/drm/imagination/Kconfig 
b/drivers/gpu/drm/imagination/Kconfig
index 0abd1b9bf3be..3bfa2ac212dc 100644
--- a/drivers/gpu/drm/imagination/Kconfig
+++ b/drivers/gpu/drm/imagination/Kconfig
@@ -6,6 +6,7 @@ config DRM_POWERVR
depends on ARM64
depends on DRM
depends on PM
+   select DRM_EXEC
select DRM_GEM_SHMEM_HELPER
select DRM_SCHED
select DRM_GPUVM
diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index 7f7bea8c60c4..7e3515c99caa 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -18,10 +18,13 @@ powervr-y := \
pvr_fw_trace.o \
pvr_gem.o \
pvr_hwrt.o \
+   pvr_job.o \
pvr_mmu.o \
pvr_power.o \
+   pvr_queue.o \
pvr_stream.o \
pvr_stream_defs.o \
+   pvr_sync.o \
pvr_vm.o \
pvr_vm_mips.o
 
diff --git a/drivers/gpu/drm/imagination/pvr_context.c 
b/drivers/gpu/drm/imagination/pvr_context.c
index 6cec5aa5a759..eded5e955cc0 100644
--- a/drivers/gpu/drm/imagination/pvr_context.c
+++ b/drivers/gpu/drm/imagination/pvr_context.c
@@ -6,10 +6,12 @@
 #include "pvr_device.h"
 #include "pvr_drv.h"
 #include "pvr_gem.h"
+#include "pvr_job.h"
 #include "pvr_power.h"
 #include "pvr_rogue_fwif.h"
 #include "pvr_rogue_fwif_common.h"
 #include "pvr_rogue_fwif_resetframework.h"
+#include "pvr_stream.h"
 #include "pvr_stream_defs.h"
 #include "pvr_vm.h"
 
@@ -164,6 +166,116 @@ ctx_fw_data_init(void *cpu_ptr, void *priv)
memcpy(cpu_ptr, ctx->data, ctx->data_size);
 }
 
+/**
+ * pvr_context_destroy_queues() - Destroy all queues attached to a context.
+ * @ctx: Context to destroy queues on.
+ *
+ * Should be called when the last reference to a context object is dropped.
+ * It releases all resources attached to the queues bound to this context.
+ */
+static void pvr_context_destroy_queues(struct pvr_context *ctx)
+{
+   switch (ctx->type) {
+   case DRM_PVR_CTX_TYPE_RENDER:
+   pvr_queue_destroy(ctx->queues.fragment);
+   pvr_queue_destroy(ctx->queues.geometry);
+   break;
+   case DRM_PVR_CTX_TYPE_COMPUTE:
+  

[PATCH v9 06/20] drm/imagination: Get GPU resources

2023-11-22 Thread Donald Robson
From: Sarah Walker 

Acquire clock and register resources, and enable/map as appropriate.

Changes since v8:
- Corrected license identifiers

Changes since v3:
- Remove regulator resource (not used on supported platform)
- Use devm helpers
- Use devm_clk_get_optional() for optional clocks
- Don't prepare clocks on resource acquisition
- Drop pvr_device_clk_core_get_freq() helper
- Drop pvr_device_reg_fini()
- Drop NULLing of clocks in pvr_device_clk_init()
- Use dev_err_probe() on clock acquisition failure
- Remove PVR_CR_READ/WRITE helper macros
- Improve documentation for GPU clocks
- Remove regs resource (not used in this commit)

Co-developed-by: Frank Binns 
Signed-off-by: Frank Binns 
Co-developed-by: Matt Coster 
Signed-off-by: Matt Coster 
Signed-off-by: Sarah Walker 
Signed-off-by: Donald Robson 
Reviewed-by: Maxime Ripard 
---
 drivers/gpu/drm/imagination/Makefile |   1 +
 drivers/gpu/drm/imagination/pvr_device.c | 147 ++
 drivers/gpu/drm/imagination/pvr_device.h | 152 +++
 drivers/gpu/drm/imagination/pvr_drv.c|  18 ++-
 4 files changed, 317 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_device.c

diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index f12a06ada9ec..d36007f2825c 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -4,6 +4,7 @@
 subdir-ccflags-y := -I$(srctree)/$(src)
 
 powervr-y := \
+   pvr_device.o \
pvr_drv.o \
 
 obj-$(CONFIG_DRM_POWERVR) += powervr.o
diff --git a/drivers/gpu/drm/imagination/pvr_device.c 
b/drivers/gpu/drm/imagination/pvr_device.c
new file mode 100644
index ..abcdf733f57b
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#include "pvr_device.h"
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * pvr_device_reg_init() - Initialize kernel access to a PowerVR device's
+ * control registers.
+ * @pvr_dev: Target PowerVR device.
+ *
+ * Sets struct pvr_device->regs.
+ *
+ * This method of mapping the device control registers into memory ensures that
+ * they are unmapped when the driver is detached (i.e. no explicit cleanup is
+ * required).
+ *
+ * Return:
+ *  * 0 on success, or
+ *  * Any error returned by devm_platform_ioremap_resource().
+ */
+static int
+pvr_device_reg_init(struct pvr_device *pvr_dev)
+{
+   struct drm_device *drm_dev = from_pvr_device(pvr_dev);
+   struct platform_device *plat_dev = to_platform_device(drm_dev->dev);
+   void __iomem *regs;
+
+   pvr_dev->regs = NULL;
+
+   regs = devm_platform_ioremap_resource(plat_dev, 0);
+   if (IS_ERR(regs))
+   return dev_err_probe(drm_dev->dev, PTR_ERR(regs),
+"failed to ioremap gpu registers\n");
+
+   pvr_dev->regs = regs;
+
+   return 0;
+}
+
+/**
+ * pvr_device_clk_init() - Initialize clocks required by a PowerVR device
+ * @pvr_dev: Target PowerVR device.
+ *
+ * Sets struct pvr_device->core_clk, struct pvr_device->sys_clk and
+ * struct pvr_device->mem_clk.
+ *
+ * Three clocks are required by the PowerVR device: core, sys and mem. On
+ * return, this function guarantees that the clocks are in one of the following
+ * states:
+ *
+ *  * All successfully initialized,
+ *  * Core errored, sys and mem uninitialized,
+ *  * Core deinitialized, sys errored, mem uninitialized, or
+ *  * Core and sys deinitialized, mem errored.
+ *
+ * Return:
+ *  * 0 on success,
+ *  * Any error returned by devm_clk_get(), or
+ *  * Any error returned by devm_clk_get_optional().
+ */
+static int pvr_device_clk_init(struct pvr_device *pvr_dev)
+{
+   struct drm_device *drm_dev = from_pvr_device(pvr_dev);
+   struct clk *core_clk;
+   struct clk *sys_clk;
+   struct clk *mem_clk;
+
+   core_clk = devm_clk_get(drm_dev->dev, "core");
+   if (IS_ERR(core_clk))
+   return dev_err_probe(drm_dev->dev, PTR_ERR(core_clk),
+"failed to get core clock\n");
+
+   sys_clk = devm_clk_get_optional(drm_dev->dev, "sys");
+   if (IS_ERR(sys_clk))
+   return dev_err_probe(drm_dev->dev, PTR_ERR(core_clk),
+"failed to get sys clock\n");
+
+   mem_clk = devm_clk_get_optional(drm_dev->dev, "mem");
+   if (IS_ERR(mem_clk))
+   return dev_err_probe(drm_dev->dev, PTR_ERR(core_clk),
+"failed to get mem clock\n");
+
+   pvr_dev->core_clk = core_clk;
+   pvr_dev->sys_clk = sys_clk;
+   pvr_dev->mem_clk = mem_clk;
+
+   return 0;
+}
+
+/**
+ * pvr_device_init() - Initialize a PowerVR device
+ * @pvr_dev: Target PowerVR device.
+ *
+ * If this function returns 

[PATCH v9 14/20] drm/imagination: Implement MIPS firmware processor and MMU support

2023-11-22 Thread Donald Robson
From: Sarah Walker 

Add support for the MIPS firmware processor, used in the Series AXE GPU.
The MIPS firmware processor uses a separate MMU to the rest of the GPU, so
this patch adds support for that as well.

Changes since v8:
- Corrected license identifiers

Changes since v6:
- Fix integer overflow in VM map error path

Changes since v5:
- Use alloc_page() when allocating MIPS pagetable

Changes since v3:
- Get regs resource (removed from GPU resources commit)

Signed-off-by: Sarah Walker 
Signed-off-by: Donald Robson 
---
 drivers/gpu/drm/imagination/Makefile  |   4 +-
 drivers/gpu/drm/imagination/pvr_device.c  |   5 +-
 drivers/gpu/drm/imagination/pvr_device.h  |   3 +
 drivers/gpu/drm/imagination/pvr_fw.c  |   2 +
 drivers/gpu/drm/imagination/pvr_fw_mips.c | 252 ++
 drivers/gpu/drm/imagination/pvr_fw_mips.h |  48 +
 drivers/gpu/drm/imagination/pvr_vm_mips.c | 238 
 drivers/gpu/drm/imagination/pvr_vm_mips.h |  22 ++
 8 files changed, 572 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_mips.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_mips.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_vm_mips.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_vm_mips.h

diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index 5c1c918af7a3..71dc36cc6b9d 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -10,11 +10,13 @@ powervr-y := \
pvr_drv.o \
pvr_fw.o \
pvr_fw_meta.o \
+   pvr_fw_mips.o \
pvr_fw_startstop.o \
pvr_fw_trace.o \
pvr_gem.o \
pvr_mmu.o \
pvr_power.o \
-   pvr_vm.o
+   pvr_vm.o \
+   pvr_vm_mips.o
 
 obj-$(CONFIG_DRM_POWERVR) += powervr.o
diff --git a/drivers/gpu/drm/imagination/pvr_device.c 
b/drivers/gpu/drm/imagination/pvr_device.c
index 1be14cdbdace..2d6db4715f85 100644
--- a/drivers/gpu/drm/imagination/pvr_device.c
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -50,16 +50,19 @@ pvr_device_reg_init(struct pvr_device *pvr_dev)
 {
struct drm_device *drm_dev = from_pvr_device(pvr_dev);
struct platform_device *plat_dev = to_platform_device(drm_dev->dev);
+   struct resource *regs_resource;
void __iomem *regs;
 
+   pvr_dev->regs_resource = NULL;
pvr_dev->regs = NULL;
 
-   regs = devm_platform_ioremap_resource(plat_dev, 0);
+   regs = devm_platform_get_and_ioremap_resource(plat_dev, 0, 
_resource);
if (IS_ERR(regs))
return dev_err_probe(drm_dev->dev, PTR_ERR(regs),
 "failed to ioremap gpu registers\n");
 
pvr_dev->regs = regs;
+   pvr_dev->regs_resource = regs_resource;
 
return 0;
 }
diff --git a/drivers/gpu/drm/imagination/pvr_device.h 
b/drivers/gpu/drm/imagination/pvr_device.h
index 39347595c6f0..8853249f4884 100644
--- a/drivers/gpu/drm/imagination/pvr_device.h
+++ b/drivers/gpu/drm/imagination/pvr_device.h
@@ -93,6 +93,9 @@ struct pvr_device {
/** @fw_version: Firmware version detected at runtime. */
struct pvr_fw_version fw_version;
 
+   /** @regs_resource: Resource representing device control registers. */
+   struct resource *regs_resource;
+
/**
 * @regs: Device control registers.
 *
diff --git a/drivers/gpu/drm/imagination/pvr_fw.c 
b/drivers/gpu/drm/imagination/pvr_fw.c
index f8ed981f1807..3debc9870a82 100644
--- a/drivers/gpu/drm/imagination/pvr_fw.c
+++ b/drivers/gpu/drm/imagination/pvr_fw.c
@@ -933,6 +933,8 @@ pvr_fw_init(struct pvr_device *pvr_dev)
 
if (fw_dev->processor_type == PVR_FW_PROCESSOR_TYPE_META)
fw_dev->defs = _fw_defs_meta;
+   else if (fw_dev->processor_type == PVR_FW_PROCESSOR_TYPE_MIPS)
+   fw_dev->defs = _fw_defs_mips;
else
return -EINVAL;
 
diff --git a/drivers/gpu/drm/imagination/pvr_fw_mips.c 
b/drivers/gpu/drm/imagination/pvr_fw_mips.c
new file mode 100644
index ..0bed0257e2ab
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_fw_mips.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#include "pvr_device.h"
+#include "pvr_fw.h"
+#include "pvr_fw_mips.h"
+#include "pvr_gem.h"
+#include "pvr_rogue_mips.h"
+#include "pvr_vm_mips.h"
+
+#include 
+#include 
+#include 
+
+#define ROGUE_FW_HEAP_MIPS_BASE 0xC000
+#define ROGUE_FW_HEAP_MIPS_SHIFT 24 /* 16 MB */
+#define ROGUE_FW_HEAP_MIPS_RESERVED_SIZE SZ_1M
+
+/**
+ * process_elf_command_stream() - Process ELF firmware image and populate
+ *firmware sections
+ * @pvr_dev: Device pointer.
+ * @fw: Pointer to firmware image.
+ * @fw_code_ptr: Pointer to FW code section.
+ * @fw_data_ptr: Pointer to FW data section.
+ * @fw_core_code_ptr: Pointer to FW coremem code section.
+ * 

[PATCH v9 01/20] sizes.h: Add entries between SZ_32G and SZ_64T

2023-11-22 Thread Donald Robson
From: Matt Coster 

sizes.h has a gap in defines between SZ_32G and SZ_64T. Add the missing
defines so they can be used in drivers.

Signed-off-by: Matt Coster 
Signed-off-by: Sarah Walker 
Signed-off-by: Donald Robson 
Reviewed-by: Linus Walleij 
---
 include/linux/sizes.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/linux/sizes.h b/include/linux/sizes.h
index 84aa448d8bb3..c3a00b967d18 100644
--- a/include/linux/sizes.h
+++ b/include/linux/sizes.h
@@ -47,8 +47,17 @@
 #define SZ_8G  _AC(0x2, ULL)
 #define SZ_16G _AC(0x4, ULL)
 #define SZ_32G _AC(0x8, ULL)
+#define SZ_64G _AC(0x10, ULL)
+#define SZ_128G_AC(0x20, ULL)
+#define SZ_256G_AC(0x40, ULL)
+#define SZ_512G_AC(0x80, ULL)
 
 #define SZ_1T  _AC(0x100, ULL)
+#define SZ_2T  _AC(0x200, ULL)
+#define SZ_4T  _AC(0x400, ULL)
+#define SZ_8T  _AC(0x800, ULL)
+#define SZ_16T _AC(0x1000, ULL)
+#define SZ_32T _AC(0x2000, ULL)
 #define SZ_64T _AC(0x4000, ULL)
 
 #endif /* __LINUX_SIZES_H__ */
-- 
2.25.1



Re: [PATCH v2 0/8] dma-buf: heaps: Add secure heap

2023-11-22 Thread Pratyush Brahma

Hi

We have sent a patch series at [1] using this series to add support for 
Qualcomm secure heaps.

Instead of TEE calls, it uses qcom_scm_assign_mem() to secure the memory.

Thanks,
Pratyush

[1] 
https://lore.kernel.org/lkml/cover.1700544802.git.quic_vji...@quicinc.com/




[PATCH v9 13/20] drm/imagination: Implement firmware infrastructure and META FW support

2023-11-22 Thread Donald Robson
From: Sarah Walker 

The infrastructure includes parsing of the firmware image, initialising
FW-side structures, handling the kernel and firmware command
ringbuffers and starting & stopping the firmware processor.

This patch also adds the necessary support code for the META firmware
processor.

Changes since v8:
- Fix documentation for pvr_fwccb_process()
- Corrected license identifiers

Changes since v6:
- Add a minimum retry count to pvr_kccb_reserve_slot_sync()

Changes since v5:
- Add workaround for BRN 71242
- Attempt to recover GPU on MMU flush command failure

Changes since v4:
- Remove use of drm_gem_shmem_get_pages()
- Remove interrupt resource name

Changes since v3:
- Hard reset FW processor on watchdog timeout
- Switch to threaded IRQ
- Rework FW object creation/initialisation to aid hard reset
- Added MODULE_FIRMWARE()
- Use drm_dev_{enter,exit}

Signed-off-by: Sarah Walker 
Signed-off-by: Donald Robson 
---
 drivers/gpu/drm/imagination/Makefile  |4 +
 drivers/gpu/drm/imagination/pvr_ccb.c |  635 
 drivers/gpu/drm/imagination/pvr_ccb.h |   71 +
 drivers/gpu/drm/imagination/pvr_device.c  |  103 ++
 drivers/gpu/drm/imagination/pvr_device.h  |   60 +
 drivers/gpu/drm/imagination/pvr_drv.c |1 +
 drivers/gpu/drm/imagination/pvr_fw.c  | 1342 +
 drivers/gpu/drm/imagination/pvr_fw.h  |  474 ++
 drivers/gpu/drm/imagination/pvr_fw_meta.c |  554 +++
 drivers/gpu/drm/imagination/pvr_fw_meta.h |   14 +
 .../gpu/drm/imagination/pvr_fw_startstop.c|  306 
 .../gpu/drm/imagination/pvr_fw_startstop.h|   13 +
 drivers/gpu/drm/imagination/pvr_fw_trace.c|  120 ++
 drivers/gpu/drm/imagination/pvr_fw_trace.h|   78 +
 drivers/gpu/drm/imagination/pvr_mmu.c |   70 +-
 drivers/gpu/drm/imagination/pvr_power.c   |  166 +-
 drivers/gpu/drm/imagination/pvr_power.h   |2 +
 drivers/gpu/drm/imagination/pvr_vm.c  |   26 +-
 18 files changed, 4015 insertions(+), 24 deletions(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_ccb.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_ccb.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_meta.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_meta.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_startstop.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_startstop.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_trace.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_trace.h

diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index d9e00a0db6b2..5c1c918af7a3 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -4,10 +4,14 @@
 subdir-ccflags-y := -I$(srctree)/$(src)
 
 powervr-y := \
+   pvr_ccb.o \
pvr_device.o \
pvr_device_info.o \
pvr_drv.o \
pvr_fw.o \
+   pvr_fw_meta.o \
+   pvr_fw_startstop.o \
+   pvr_fw_trace.o \
pvr_gem.o \
pvr_mmu.o \
pvr_power.o \
diff --git a/drivers/gpu/drm/imagination/pvr_ccb.c 
b/drivers/gpu/drm/imagination/pvr_ccb.c
new file mode 100644
index ..48f06f58f3f1
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_ccb.c
@@ -0,0 +1,635 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#include "pvr_ccb.h"
+#include "pvr_device.h"
+#include "pvr_drv.h"
+#include "pvr_fw.h"
+#include "pvr_gem.h"
+#include "pvr_power.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RESERVE_SLOT_TIMEOUT (1 * HZ) /* 1s */
+#define RESERVE_SLOT_MIN_RETRIES 10
+
+static void
+ccb_ctrl_init(void *cpu_ptr, void *priv)
+{
+   struct rogue_fwif_ccb_ctl *ctrl = cpu_ptr;
+   struct pvr_ccb *pvr_ccb = priv;
+
+   ctrl->write_offset = 0;
+   ctrl->read_offset = 0;
+   ctrl->wrap_mask = pvr_ccb->num_cmds - 1;
+   ctrl->cmd_size = pvr_ccb->cmd_size;
+}
+
+/**
+ * pvr_ccb_init() - Initialise a CCB
+ * @pvr_dev: Device pointer.
+ * @pvr_ccb: Pointer to CCB structure to initialise.
+ * @num_cmds_log2: Log2 of number of commands in this CCB.
+ * @cmd_size: Command size for this CCB.
+ *
+ * Return:
+ *  * Zero on success, or
+ *  * Any error code returned by pvr_fw_object_create_and_map().
+ */
+static int
+pvr_ccb_init(struct pvr_device *pvr_dev, struct pvr_ccb *pvr_ccb,
+u32 num_cmds_log2, size_t cmd_size)
+{
+   u32 num_cmds = 1 << num_cmds_log2;
+   u32 ccb_size = num_cmds * cmd_size;
+   int err;
+
+   pvr_ccb->num_cmds = num_cmds;
+   pvr_ccb->cmd_size = cmd_size;
+
+   err = drmm_mutex_init(from_pvr_device(pvr_dev), _ccb->lock);
+   if (err)
+   return err;
+
+   /*
+* Map CCB and control structure as uncached, so we don't have to flush
+* CPU cache repeatedly when polling for space.
+*/
+   pvr_ccb->ctrl = 

[PATCH v9 15/20] drm/imagination: Implement free list and HWRT create and destroy ioctls

2023-11-22 Thread Donald Robson
From: Sarah Walker 

Implement ioctls to create and destroy free lists and HWRT datasets. Free
lists are used for GPU-side memory allocation during geometry processing.
HWRT datasets are the FW-side structures representing render targets.

Changes since v8:
- Corrected license identifiers

Changes since v6:
- Fix out-of-bounds shift in get_cr_multisamplectl_val()

Changes since v4:
- Remove use of drm_gem_shmem_get_pages()

Changes since v3:
- Support free list grow requests from FW
- Use drm_dev_{enter,exit}

Co-developed-by: Boris Brezillon 
Signed-off-by: Boris Brezillon 
Co-developed-by: Donald Robson 
Signed-off-by: Donald Robson 
Signed-off-by: Sarah Walker 
---
 drivers/gpu/drm/imagination/Makefile|   2 +
 drivers/gpu/drm/imagination/pvr_ccb.c   |  10 +
 drivers/gpu/drm/imagination/pvr_device.h|  24 +
 drivers/gpu/drm/imagination/pvr_drv.c   | 112 +++-
 drivers/gpu/drm/imagination/pvr_free_list.c | 625 
 drivers/gpu/drm/imagination/pvr_free_list.h | 195 ++
 drivers/gpu/drm/imagination/pvr_hwrt.c  | 549 +
 drivers/gpu/drm/imagination/pvr_hwrt.h  | 165 ++
 8 files changed, 1678 insertions(+), 4 deletions(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_free_list.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_free_list.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_hwrt.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_hwrt.h

diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index 71dc36cc6b9d..2bd501018d5d 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -8,12 +8,14 @@ powervr-y := \
pvr_device.o \
pvr_device_info.o \
pvr_drv.o \
+   pvr_free_list.o \
pvr_fw.o \
pvr_fw_meta.o \
pvr_fw_mips.o \
pvr_fw_startstop.o \
pvr_fw_trace.o \
pvr_gem.o \
+   pvr_hwrt.o \
pvr_mmu.o \
pvr_power.o \
pvr_vm.o \
diff --git a/drivers/gpu/drm/imagination/pvr_ccb.c 
b/drivers/gpu/drm/imagination/pvr_ccb.c
index 48f06f58f3f1..4deeac7ed40a 100644
--- a/drivers/gpu/drm/imagination/pvr_ccb.c
+++ b/drivers/gpu/drm/imagination/pvr_ccb.c
@@ -4,6 +4,7 @@
 #include "pvr_ccb.h"
 #include "pvr_device.h"
 #include "pvr_drv.h"
+#include "pvr_free_list.h"
 #include "pvr_fw.h"
 #include "pvr_gem.h"
 #include "pvr_power.h"
@@ -139,6 +140,15 @@ process_fwccb_command(struct pvr_device *pvr_dev, struct 
rogue_fwif_fwccb_cmd *c
pvr_power_reset(pvr_dev, false);
break;
 
+   case ROGUE_FWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION:
+   pvr_free_list_process_reconstruct_req(pvr_dev,
+ 
>cmd_data.cmd_freelists_reconstruction);
+   break;
+
+   case ROGUE_FWIF_FWCCB_CMD_FREELIST_GROW:
+   pvr_free_list_process_grow_req(pvr_dev, 
>cmd_data.cmd_free_list_gs);
+   break;
+
default:
drm_info(from_pvr_device(pvr_dev), "Received unknown FWCCB 
command %x\n",
 cmd->cmd_type);
diff --git a/drivers/gpu/drm/imagination/pvr_device.h 
b/drivers/gpu/drm/imagination/pvr_device.h
index 8853249f4884..f5b82b793566 100644
--- a/drivers/gpu/drm/imagination/pvr_device.h
+++ b/drivers/gpu/drm/imagination/pvr_device.h
@@ -152,6 +152,14 @@ struct pvr_device {
 */
atomic_t mmu_flush_cache_flags;
 
+   /**
+* @free_list_ids: Array of free lists belonging to this device. Array 
members
+* are of type "struct pvr_free_list *".
+*
+* This array is used to allocate IDs used by the firmware.
+*/
+   struct xarray free_list_ids;
+
struct {
/** @work: Work item for watchdog callback. */
struct delayed_work work;
@@ -247,6 +255,22 @@ struct pvr_file {
 */
struct pvr_device *pvr_dev;
 
+   /**
+* @free_list_handles: Array of free lists belonging to this file. Array
+* members are of type "struct pvr_free_list *".
+*
+* This array is used to allocate handles returned to userspace.
+*/
+   struct xarray free_list_handles;
+
+   /**
+* @hwrt_handles: Array of HWRT datasets belonging to this file. Array
+* members are of type "struct pvr_hwrt_dataset *".
+*
+* This array is used to allocate handles returned to userspace.
+*/
+   struct xarray hwrt_handles;
+
/**
 * @vm_ctx_handles: Array of VM contexts belonging to this file. Array
 * members are of type "struct pvr_vm_context *".
diff --git a/drivers/gpu/drm/imagination/pvr_drv.c 
b/drivers/gpu/drm/imagination/pvr_drv.c
index 33b38c0d79c8..f485e2cc60f9 100644
--- a/drivers/gpu/drm/imagination/pvr_drv.c
+++ b/drivers/gpu/drm/imagination/pvr_drv.c
@@ -3,7 +3,9 @@
 
 #include "pvr_device.h"
 #include "pvr_drv.h"
+#include 

[PATCH v9 10/20] drm/imagination: Add GPU ID parsing and firmware loading

2023-11-22 Thread Donald Robson
From: Sarah Walker 

Read the GPU ID register at probe time and select the correct
features/quirks/enhancements. Use the GPU ID to form the firmware
file name and load the firmware.

The features/quirks/enhancements arrays are currently hardcoded in
the driver for the supported GPUs. We are looking at moving this
information to the firmware image.

Changes since v8:
- Corrected license identifiers

Changes since v7:
- Fix kerneldoc for pvr_device_info_set_enhancements()

Changes since v5:
- Add BRN 71242 to device info

Changes since v4:
- Retrieve device information from firmware header
- Pull forward firmware header parsing from FW infrastructure patch
- Use devm_add_action_or_reset to release firmware

Changes since v3:
- Use drm_dev_{enter,exit}

Co-developed-by: Frank Binns 
Signed-off-by: Frank Binns 
Co-developed-by: Matt Coster 
Signed-off-by: Matt Coster 
Co-developed-by: Donald Robson 
Signed-off-by: Donald Robson 
Signed-off-by: Sarah Walker 
---
 drivers/gpu/drm/imagination/Makefile  |   2 +
 drivers/gpu/drm/imagination/pvr_device.c  | 323 ++-
 drivers/gpu/drm/imagination/pvr_device.h  | 220 
 drivers/gpu/drm/imagination/pvr_device_info.c | 254 +
 drivers/gpu/drm/imagination/pvr_device_info.h | 186 +++
 drivers/gpu/drm/imagination/pvr_drv.c | 521 +-
 drivers/gpu/drm/imagination/pvr_drv.h | 107 
 drivers/gpu/drm/imagination/pvr_fw.c  | 145 +
 drivers/gpu/drm/imagination/pvr_fw.h  |  34 ++
 drivers/gpu/drm/imagination/pvr_fw_info.h | 135 +
 10 files changed, 1925 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_device_info.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_device_info.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_fw_info.h

diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index d36007f2825c..0b863e9f51b8 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -5,6 +5,8 @@ subdir-ccflags-y := -I$(srctree)/$(src)
 
 powervr-y := \
pvr_device.o \
+   pvr_device_info.o \
pvr_drv.o \
+   pvr_fw.o
 
 obj-$(CONFIG_DRM_POWERVR) += powervr.o
diff --git a/drivers/gpu/drm/imagination/pvr_device.c 
b/drivers/gpu/drm/imagination/pvr_device.c
index abcdf733f57b..05e382cacb27 100644
--- a/drivers/gpu/drm/imagination/pvr_device.c
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -2,19 +2,31 @@
 /* Copyright (c) 2023 Imagination Technologies Ltd. */
 
 #include "pvr_device.h"
+#include "pvr_device_info.h"
+
+#include "pvr_fw.h"
+#include "pvr_rogue_cr_defs.h"
 
 #include 
 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
+
+/* Major number for the supported version of the firmware. */
+#define PVR_FW_VERSION_MAJOR 1
 
 /**
  * pvr_device_reg_init() - Initialize kernel access to a PowerVR device's
@@ -100,6 +112,209 @@ static int pvr_device_clk_init(struct pvr_device *pvr_dev)
return 0;
 }
 
+/**
+ * pvr_build_firmware_filename() - Construct a PowerVR firmware filename
+ * @pvr_dev: Target PowerVR device.
+ * @base: First part of the filename.
+ * @major: Major version number.
+ *
+ * A PowerVR firmware filename consists of three parts separated by underscores
+ * (``'_'``) along with a '.fw' file suffix. The first part is the exact value
+ * of @base, the second part is the hardware version string derived from 
@pvr_fw
+ * and the final part is the firmware version number constructed from @major 
with
+ * a 'v' prefix, e.g. powervr/rogue_4.40.2.51_v1.fw.
+ *
+ * The returned string will have been slab allocated and must be freed with
+ * kfree().
+ *
+ * Return:
+ *  * The constructed filename on success, or
+ *  * Any error returned by kasprintf().
+ */
+static char *
+pvr_build_firmware_filename(struct pvr_device *pvr_dev, const char *base,
+   u8 major)
+{
+   struct pvr_gpu_id *gpu_id = _dev->gpu_id;
+
+   return kasprintf(GFP_KERNEL, "%s_%d.%d.%d.%d_v%d.fw", base, gpu_id->b,
+gpu_id->v, gpu_id->n, gpu_id->c, major);
+}
+
+static void
+pvr_release_firmware(void *data)
+{
+   struct pvr_device *pvr_dev = data;
+
+   release_firmware(pvr_dev->fw_dev.firmware);
+}
+
+/**
+ * pvr_request_firmware() - Load firmware for a PowerVR device
+ * @pvr_dev: Target PowerVR device.
+ *
+ * See pvr_build_firmware_filename() for details on firmware file naming.
+ *
+ * Return:
+ *  * 0 on success,
+ *  * Any error returned by pvr_build_firmware_filename(), or
+ *  * Any error returned by request_firmware().
+ */
+static int
+pvr_request_firmware(struct pvr_device *pvr_dev)
+{
+   struct drm_device *drm_dev = _dev->base;
+   char *filename;
+   

[PATCH v9 16/20] drm/imagination: Implement context creation/destruction ioctls

2023-11-22 Thread Donald Robson
From: Sarah Walker 

Implement ioctls for the creation and destruction of contexts. Contexts are
used for job submission and each is associated with a particular job type.

Changes since v8:
- Fixed one error path in pvr_stream_process_1()
- Corrected license identifiers

Changes since v5:
- Fix context release in final error path in pvr_context_create()

Changes since v3:
- Use drm_dev_{enter,exit}

Co-developed-by: Boris Brezillon 
Signed-off-by: Boris Brezillon 
Signed-off-by: Sarah Walker 
Signed-off-by: Donald Robson 
---
 drivers/gpu/drm/imagination/Makefile  |   4 +
 drivers/gpu/drm/imagination/pvr_cccb.c| 267 ++
 drivers/gpu/drm/imagination/pvr_cccb.h| 109 ++
 drivers/gpu/drm/imagination/pvr_context.c | 341 ++
 drivers/gpu/drm/imagination/pvr_context.h | 161 +
 drivers/gpu/drm/imagination/pvr_device.h  |  21 ++
 drivers/gpu/drm/imagination/pvr_drv.c |  29 +-
 drivers/gpu/drm/imagination/pvr_stream.c  | 285 +++
 drivers/gpu/drm/imagination/pvr_stream.h  |  75 
 drivers/gpu/drm/imagination/pvr_stream_defs.c | 125 +++
 drivers/gpu/drm/imagination/pvr_stream_defs.h |  16 +
 11 files changed, 1431 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_cccb.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_cccb.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_context.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_context.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_stream.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_stream.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_stream_defs.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_stream_defs.h

diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index 2bd501018d5d..7f7bea8c60c4 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -5,6 +5,8 @@ subdir-ccflags-y := -I$(srctree)/$(src)
 
 powervr-y := \
pvr_ccb.o \
+   pvr_cccb.o \
+   pvr_context.o \
pvr_device.o \
pvr_device_info.o \
pvr_drv.o \
@@ -18,6 +20,8 @@ powervr-y := \
pvr_hwrt.o \
pvr_mmu.o \
pvr_power.o \
+   pvr_stream.o \
+   pvr_stream_defs.o \
pvr_vm.o \
pvr_vm_mips.o
 
diff --git a/drivers/gpu/drm/imagination/pvr_cccb.c 
b/drivers/gpu/drm/imagination/pvr_cccb.c
new file mode 100644
index ..4fabab41bea7
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_cccb.c
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#include "pvr_ccb.h"
+#include "pvr_cccb.h"
+#include "pvr_device.h"
+#include "pvr_gem.h"
+#include "pvr_hwrt.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static __always_inline u32
+get_ccb_space(u32 w_off, u32 r_off, u32 ccb_size)
+{
+   return (((r_off) - (w_off)) + ((ccb_size) - 1)) & ((ccb_size) - 1);
+}
+
+static void
+cccb_ctrl_init(void *cpu_ptr, void *priv)
+{
+   struct rogue_fwif_cccb_ctl *ctrl = cpu_ptr;
+   struct pvr_cccb *pvr_cccb = priv;
+
+   WRITE_ONCE(ctrl->write_offset, 0);
+   WRITE_ONCE(ctrl->read_offset, 0);
+   WRITE_ONCE(ctrl->dep_offset, 0);
+   WRITE_ONCE(ctrl->wrap_mask, pvr_cccb->wrap_mask);
+}
+
+/**
+ * pvr_cccb_init() - Initialise a Client CCB
+ * @pvr_dev: Device pointer.
+ * @pvr_cccb: Pointer to Client CCB structure to initialise.
+ * @size_log2: Log2 size of Client CCB in bytes.
+ * @name: Name of owner of Client CCB. Used for fence context.
+ *
+ * Return:
+ *  * Zero on success, or
+ *  * Any error code returned by pvr_fw_object_create_and_map().
+ */
+int
+pvr_cccb_init(struct pvr_device *pvr_dev, struct pvr_cccb *pvr_cccb,
+ u32 size_log2, const char *name)
+{
+   size_t size = 1 << size_log2;
+   int err;
+
+   pvr_cccb->size = size;
+   pvr_cccb->write_offset = 0;
+   pvr_cccb->wrap_mask = size - 1;
+
+   /*
+* Map CCCB and control structure as uncached, so we don't have to flush
+* CPU cache repeatedly when polling for space.
+*/
+   pvr_cccb->ctrl = pvr_fw_object_create_and_map(pvr_dev, 
sizeof(*pvr_cccb->ctrl),
+ 
PVR_BO_FW_FLAGS_DEVICE_UNCACHED,
+ cccb_ctrl_init, pvr_cccb,
+ _cccb->ctrl_obj);
+   if (IS_ERR(pvr_cccb->ctrl))
+   return PTR_ERR(pvr_cccb->ctrl);
+
+   pvr_cccb->cccb = pvr_fw_object_create_and_map(pvr_dev, size,
+ 
PVR_BO_FW_FLAGS_DEVICE_UNCACHED,
+ NULL, NULL, 
_cccb->cccb_obj);
+   if (IS_ERR(pvr_cccb->cccb)) {
+   err = PTR_ERR(pvr_cccb->cccb);
+   goto err_free_ctrl;
+   }
+

[PATCH v9 12/20] drm/imagination: Implement power management

2023-11-22 Thread Donald Robson
From: Sarah Walker 

Add power management to the driver, using runtime pm. The power off
sequence depends on firmware commands which are not implemented in this
patch.

Changes since v8:
- Corrected license identifiers

Changes since v5:
- Use RUNTIME_PM_OPS() to declare PM callbacks
- Add Kconfig dependency on CONFIG_PM

Changes since v4:
- Suspend runtime PM before unplugging device on rmmod

Changes since v3:
- Don't power device when calling pvr_device_gpu_fini()
- Documentation for pvr_dev->lost has been improved
- pvr_power_init() renamed to pvr_watchdog_init()
- Use drm_dev_{enter,exit}

Changes since v2:
- Use runtime PM
- Implement watchdog

Signed-off-by: Sarah Walker 
Signed-off-by: Donald Robson 
Reviewed-by: Maxime Ripard 
---
 drivers/gpu/drm/imagination/Kconfig  |   1 +
 drivers/gpu/drm/imagination/Makefile |   1 +
 drivers/gpu/drm/imagination/pvr_device.c |  23 +-
 drivers/gpu/drm/imagination/pvr_device.h |  22 ++
 drivers/gpu/drm/imagination/pvr_drv.c|  20 +-
 drivers/gpu/drm/imagination/pvr_power.c  | 271 +++
 drivers/gpu/drm/imagination/pvr_power.h  |  39 
 7 files changed, 374 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/imagination/pvr_power.c
 create mode 100644 drivers/gpu/drm/imagination/pvr_power.h

diff --git a/drivers/gpu/drm/imagination/Kconfig 
b/drivers/gpu/drm/imagination/Kconfig
index 6f82edf89144..0abd1b9bf3be 100644
--- a/drivers/gpu/drm/imagination/Kconfig
+++ b/drivers/gpu/drm/imagination/Kconfig
@@ -5,6 +5,7 @@ config DRM_POWERVR
tristate "Imagination Technologies PowerVR (Series 6 and later) & IMG 
Graphics"
depends on ARM64
depends on DRM
+   depends on PM
select DRM_GEM_SHMEM_HELPER
select DRM_SCHED
select DRM_GPUVM
diff --git a/drivers/gpu/drm/imagination/Makefile 
b/drivers/gpu/drm/imagination/Makefile
index 678c3dbb4326..d9e00a0db6b2 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -10,6 +10,7 @@ powervr-y := \
pvr_fw.o \
pvr_gem.o \
pvr_mmu.o \
+   pvr_power.o \
pvr_vm.o
 
 obj-$(CONFIG_DRM_POWERVR) += powervr.o
diff --git a/drivers/gpu/drm/imagination/pvr_device.c 
b/drivers/gpu/drm/imagination/pvr_device.c
index 201ae780494f..e16282325178 100644
--- a/drivers/gpu/drm/imagination/pvr_device.c
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -5,6 +5,7 @@
 #include "pvr_device_info.h"
 
 #include "pvr_fw.h"
+#include "pvr_power.h"
 #include "pvr_rogue_cr_defs.h"
 #include "pvr_vm.h"
 
@@ -361,6 +362,8 @@ pvr_device_gpu_fini(struct pvr_device *pvr_dev)
 int
 pvr_device_init(struct pvr_device *pvr_dev)
 {
+   struct drm_device *drm_dev = from_pvr_device(pvr_dev);
+   struct device *dev = drm_dev->dev;
int err;
 
/* Enable and initialize clocks required for the device to operate. */
@@ -368,13 +371,29 @@ pvr_device_init(struct pvr_device *pvr_dev)
if (err)
return err;
 
+   /* Explicitly power the GPU so we can access control registers before 
the FW is booted. */
+   err = pm_runtime_resume_and_get(dev);
+   if (err)
+   return err;
+
/* Map the control registers into memory. */
err = pvr_device_reg_init(pvr_dev);
if (err)
-   return err;
+   goto err_pm_runtime_put;
 
/* Perform GPU-specific initialization steps. */
-   return pvr_device_gpu_init(pvr_dev);
+   err = pvr_device_gpu_init(pvr_dev);
+   if (err)
+   goto err_pm_runtime_put;
+
+   pm_runtime_put(dev);
+
+   return 0;
+
+err_pm_runtime_put:
+   pm_runtime_put_sync_suspend(dev);
+
+   return err;
 }
 
 /**
diff --git a/drivers/gpu/drm/imagination/pvr_device.h 
b/drivers/gpu/drm/imagination/pvr_device.h
index bfc853ffd58f..771ba879f02d 100644
--- a/drivers/gpu/drm/imagination/pvr_device.h
+++ b/drivers/gpu/drm/imagination/pvr_device.h
@@ -141,6 +141,28 @@ struct pvr_device {
 * before submitting the next job.
 */
atomic_t mmu_flush_cache_flags;
+
+   struct {
+   /** @work: Work item for watchdog callback. */
+   struct delayed_work work;
+
+   /** @old_kccb_cmds_executed: KCCB command execution count at 
last watchdog poll. */
+   u32 old_kccb_cmds_executed;
+
+   /** @kccb_stall_count: Number of watchdog polls KCCB has been 
stalled for. */
+   u32 kccb_stall_count;
+   } watchdog;
+
+   /**
+* @lost: %true if the device has been lost.
+*
+* This variable is set if the device has become irretrievably 
unavailable, e.g. if the
+* firmware processor has stopped responding and can not be revived via 
a hard reset.
+*/
+   bool lost;
+
+   /** @sched_wq: Workqueue for schedulers. */
+   struct workqueue_struct *sched_wq;
 };
 
 /**
diff --git a/drivers/gpu/drm/imagination/pvr_drv.c 

[PATCH v9 08/20] drm/imagination: Add firmware and MMU related headers

2023-11-22 Thread Donald Robson
From: Sarah Walker 

Changes since v8:
- Corrected license identifiers

Changes since v5:
- Split up header commit due to size

Signed-off-by: Sarah Walker 
Signed-off-by: Donald Robson 
Acked-by: Maxime Ripard 
---
 .../drm/imagination/pvr_rogue_heap_config.h   | 113 ++
 drivers/gpu/drm/imagination/pvr_rogue_meta.h  | 356 ++
 drivers/gpu/drm/imagination/pvr_rogue_mips.h  | 335 
 .../drm/imagination/pvr_rogue_mips_check.h|  58 +++
 .../gpu/drm/imagination/pvr_rogue_mmu_defs.h  | 136 +++
 5 files changed, 998 insertions(+)
 create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_heap_config.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_meta.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_mips.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_mips_check.h
 create mode 100644 drivers/gpu/drm/imagination/pvr_rogue_mmu_defs.h

diff --git a/drivers/gpu/drm/imagination/pvr_rogue_heap_config.h 
b/drivers/gpu/drm/imagination/pvr_rogue_heap_config.h
new file mode 100644
index ..684766006703
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_rogue_heap_config.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/* Copyright (c) 2023 Imagination Technologies Ltd. */
+
+#ifndef PVR_ROGUE_HEAP_CONFIG_H
+#define PVR_ROGUE_HEAP_CONFIG_H
+
+#include 
+
+/*
+ * ROGUE Device Virtual Address Space Definitions
+ *
+ * This file defines the ROGUE virtual address heaps that are used in
+ * application memory contexts. It also shows where the Firmware memory heap
+ * fits into this, but the firmware heap is only ever created in the
+ * kernel driver and never exposed to userspace.
+ *
+ * ROGUE_PDSCODEDATA_HEAP_BASE and ROGUE_USCCODE_HEAP_BASE will be programmed,
+ * on a global basis, into ROGUE_CR_PDS_EXEC_BASE and ROGUE_CR_USC_CODE_BASE_*
+ * respectively. Therefore if client drivers use multiple configs they must
+ * still be consistent with their definitions for these heaps.
+ *
+ * Base addresses have to be a multiple of 4MiB.
+ * Heaps must not start at 0x00, as this is reserved for internal
+ * use within the driver.
+ * Range comments, those starting in column 0 below are a section heading of
+ * sorts and are above the heaps in that range. Often this is the reserved
+ * size of the heap within the range.
+ */
+
+/* 0x00__ /
+
+/* 0x00__ - 0x00_0040_ */
+/* 0 MiB to 4 MiB, size of 4 MiB : RESERVED */
+
+/* 0x00_0040_ - 0x7F_FFC0_ **/
+/* 4 MiB to 512 GiB, size of 512 GiB less 4 MiB : RESERVED **/
+
+/* 0x80__ /
+
+/* 0x80__ - 0x9F__ **/
+/* 512 GiB to 640 GiB, size of 128 GiB : GENERAL_HEAP **/
+#define ROGUE_GENERAL_HEAP_BASE 0x80ull
+#define ROGUE_GENERAL_HEAP_SIZE SZ_128G
+
+/* 0xA0__ - 0xAF__ */
+/* 640 GiB to 704 GiB, size of 64 GiB : FREE */
+
+/* B0__ - 0xB7__ */
+/* 704 GiB to 736 GiB, size of 32 GiB : FREE */
+
+/* 0xB8__ - 0xBF__ */
+/* 736 GiB to 768 GiB, size of 32 GiB : RESERVED */
+
+/* 0xC0__ /
+
+/* 0xC0__ - 0xD9__ */
+/* 768 GiB to 872 GiB, size of 104 GiB : FREE */
+
+/* 0xDA__ - 0xDA__ */
+/* 872 GiB to 876 GiB, size of 4 GiB : PDSCODEDATA_HEAP */
+#define ROGUE_PDSCODEDATA_HEAP_BASE 0xDAull
+#define ROGUE_PDSCODEDATA_HEAP_SIZE SZ_4G
+
+/* 0xDB__ - 0xDB__ */
+/* 876 GiB to 880 GiB, size of 256 MiB (reserved 4GiB) : BRN **/
+/*
+ * The BRN63142 quirk workaround requires Region Header memory to be at the top
+ * of a 16GiB aligned range. This is so when masked with 0x03 the
+ * address will avoid aliasing PB addresses. Start at 879.75GiB. Size of 
256MiB.
+ */
+#define ROGUE_RGNHDR_HEAP_BASE 0xDBF000ull
+#define ROGUE_RGNHDR_HEAP_SIZE SZ_256M
+
+/* 0xDC__ - 0xDF__ */
+/* 880 GiB to 896 GiB, size of 16 GiB : FREE */
+
+/* 0xE0__ - 0xE0__ */
+/* 896 GiB to 900 GiB, size of 4 GiB : USCCODE_HEAP */
+#define ROGUE_USCCODE_HEAP_BASE 0xE0ull
+#define ROGUE_USCCODE_HEAP_SIZE SZ_4G
+
+/* 0xE1__ - 0xE1_BFFF_ */
+/* 900 GiB to 903 GiB, size of 3 GiB : RESERVED */
+
+/* 0xE1_C000_000 - 0xE1__ */
+/* 903 GiB to 904 GiB, reserved 1 GiB, : FIRMWARE_HEAP */
+#define ROGUE_FW_HEAP_BASE 0xE1C000ull
+
+/* 0xE2__ - 0xE3__ */
+/* 904 GiB to 912 GiB, size of 8 GiB : FREE */
+
+/* 0xE4__ - 0xE7__ */
+/* 912 GiB to 968 GiB, size of 16 GiB : TRANSFER_FRAG */
+#define ROGUE_TRANSFER_FRAG_HEAP_BASE 0xE4ull
+#define ROGUE_TRANSFER_FRAG_HEAP_SIZE SZ_16G
+
+/* 0xE8__ - 0xF1__ */
+/* 928 GiB to 968 GiB, size of 40 GiB : RESERVED */
+
+/* 0xF2__ - 0xF2_001F_ **/
+/* 968 GiB to 969 GiB, size of 2 MiB : VISTEST_HEAP */
+#define 

[PATCH v9 02/20] drm/gpuvm: Helper to get range of unmap from a remap op.

2023-11-22 Thread Donald Robson
Determining the start and range of the unmap stage of a remap op is a
common piece of code currently implemented by multiple drivers. Add a
helper for this.

Changes since v7:
- Renamed helper to drm_gpuva_op_remap_to_unmap_range()
- Improved documentation

Changes since v6:
- Remove use of __always_inline

Signed-off-by: Donald Robson 
Signed-off-by: Sarah Walker 
Reviewed-by: Danilo Krummrich 
---
 include/drm/drm_gpuvm.h | 28 
 1 file changed, 28 insertions(+)

diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h
index 8ca10461d8ac..f94fec9a8517 100644
--- a/include/drm/drm_gpuvm.h
+++ b/include/drm/drm_gpuvm.h
@@ -1213,4 +1213,32 @@ void drm_gpuva_remap(struct drm_gpuva *prev,
 
 void drm_gpuva_unmap(struct drm_gpuva_op_unmap *op);
 
+/**
+ * drm_gpuva_op_remap_to_unmap_range() - Helper to get the start and range of
+ * the unmap stage of a remap op.
+ * @op: Remap op.
+ * @start_addr: Output pointer for the start of the required unmap.
+ * @range: Output pointer for the length of the required unmap.
+ *
+ * The given start address and range will be set such that they represent the
+ * range of the address space that was previously covered by the mapping being
+ * re-mapped, but is now empty.
+ */
+static inline void
+drm_gpuva_op_remap_to_unmap_range(const struct drm_gpuva_op_remap *op,
+ u64 *start_addr, u64 *range)
+{
+   const u64 va_start = op->prev ?
+op->prev->va.addr + op->prev->va.range :
+op->unmap->va->va.addr;
+   const u64 va_end = op->next ?
+  op->next->va.addr :
+  op->unmap->va->va.addr + op->unmap->va->va.range;
+
+   if (start_addr)
+   *start_addr = va_start;
+   if (range)
+   *range = va_end - va_start;
+}
+
 #endif /* __DRM_GPUVM_H__ */
-- 
2.25.1



[PATCH v9 00/20] Imagination Technologies PowerVR DRM driver

2023-11-22 Thread Donald Robson
This patch series adds the initial DRM driver for Imagination Technologies 
PowerVR
GPUs, starting with those based on our Rogue architecture. It's worth pointing
out that this is a new driver, written from the ground up, rather than a
refactored version of our existing downstream driver (pvrsrvkm).

This new DRM driver supports:
- GEM shmem allocations
- dma-buf / PRIME
- Per-context userspace managed virtual address space
- DRM sync objects (binary and timeline)
- Power management suspend / resume
- GPU job submission (geometry, fragment, compute, transfer)
- META firmware processor
- MIPS firmware processor
- GPU hang detection and recovery

Currently our main focus is on the AXE-1-16M GPU. Testing so far has been done
using a TI SK-AM62 board (AXE-1-16M GPU). The driver has also been confirmed to
work on the BeaglePlay board. Firmware for the AXE-1-16M can be found here:
https://gitlab.freedesktop.org/frankbinns/linux-firmware/-/tree/powervr

A Vulkan driver that works with our downstream kernel driver has already been
merged into Mesa [1][2]. Support for this new DRM driver is being maintained in
a merge request [3], with the branch located here:
https://gitlab.freedesktop.org/frankbinns/mesa/-/tree/powervr-winsys

Vulkan driver links referred to above:
[1] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15243
[2] https://gitlab.freedesktop.org/mesa/mesa/-/tree/main/src/imagination/vulkan
[3] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15507

Job stream formats are documented at:
https://gitlab.freedesktop.org/mesa/mesa/-/blob/f8d2b42ae65c2f16f36a43e0ae39d288431e4263/src/imagination/csbgen/rogue_kmd_stream.xml

The Vulkan driver is progressing towards Vulkan 1.0. The current combination of 
this
kernel driver with the Mesa Vulkan driver (powervr-mesa-next branch) 
successfully
completes Vulkan CTS 1.3.4.1 in our local runs. The driver is expected to pass 
the
Khronos Conformance Process once the submission is made.

The code in this patch series, along with the needed dts changes can be found 
here:
https://gitlab.freedesktop.org/frankbinns/powervr/-/tree/dev/v9_dts
The full development history can be found here:
https://gitlab.freedesktop.org/frankbinns/powervr/-/tree/powervr-next

High level summary of changes:
v9:
* Bug fixes related to rebasing on latest drm_sched changes
* Updated for recent changes to drm_gpuvm
* Switch to dma_resv locking in pvr_vm
* Corrected license identifiers 

v8:
* Documentation clarifications/fixes for UAPI
* CREATE_BO ioctl now returns an error if provided size isn't page aligned
* Optimisations to MMU flush operations
* FWIF change to support CPU cached FW allocations/mappings

v7:
* Fix fence handling in pvr_sync_signal_array_add()
* Add a minimum retry count to pvr_kccb_reserve_slot_sync()
* Don't initialise kernel_vm_ctx when using MIPS firmware processor
* Remove unused gpu label from dt bindings example
* Improve UAPI BYPASS_CACHE documentation
* Add DRM_PVR_SUBMIT_JOB_FRAG_CMD_DISABLE_PIXELMERGE flag to UAPI
* Rename gpuva_manager usage to gpuvm
* Sync GEM objects to device on creation
* Fix out-of-bounds shift bug
* Fix integer overflow in MIPS MMU map error path
* Add missing commit messages

v6:
* Fix a number of error paths
* Attempt to recover GPU on MMU flush command failure
* Defer freeing/releasing page table backing pages until after TLB flush
* Add memory barriers and use WRITE_ONCE() when writing to page tables
* Add Kconfig dependency on CONFIG_PM
* Fix a few issues with GPU VA manager usage
* Split up header commit due to size
* Update compatible string and driver description to match marketing name
* Use alloc_page() to allocate MIPS pagetable
* Remove obsolete documentation

v5:
* Retrieve GPU device information from firmware image header
* Address issues with DT binding and example DTS
* Update VM code for upstream GPU VA manager
* BOs are always zeroed on allocation
* Update copyright

v4:
* Implemented hang recovery via firmware hard reset
* Add support for partial render jobs
* Move to a threaded IRQ
* Remove unnecessary read/write and clock helpers
* Remove device tree elements not relevant to AXE-1-16M
* Clean up resource acquisition
* Remove unused DT binding attributes

v3:
* Use drm_sched for scheduling
* Use GPU VA manager
* Use runtime PM
* Use drm_gem_shmem
* GPU watchdog and device loss handling
* DT binding changes: remove unused attributes, add additionProperties:false

v2:
* Redesigned and simplified UAPI based on RFC feedback from XDC 2022
* Support for transfer and partial render jobs
* Support for timeline sync objects

RFC v1: 
https://lore.kernel.org/dri-devel/20220815165156.118212-1-sarah.wal...@imgtec.com/

RFC v2: 
https://lore.kernel.org/dri-devel/20230413103419.293493-1-sarah.wal...@imgtec.com/

v3: 
https://lore.kernel.org/dri-devel/20230613144800.52657-1-sarah.wal...@imgtec.com/

v4: 
https://lore.kernel.org/dri-devel/20230714142355.111382-1-sarah.wal...@imgtec.com/

v5: 

[PATCH v9 4/4] drm/doc: Define KMS atomic state set

2023-11-22 Thread André Almeida
From: Pekka Paalanen 

Specify how the atomic state is maintained between userspace and
kernel, plus the special case for async flips.

Signed-off-by: Pekka Paalanen 
Signed-off-by: André Almeida 
---
v9:
- no changes
v8:
- no changes
v7:
- add a note that drivers can make exceptions for ad-hoc prop changes
- add a note about flipping the same FB_ID as a no-op
---
---
 Documentation/gpu/drm-uapi.rst | 47 ++
 1 file changed, 47 insertions(+)

diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst
index 370d820be248..d0693f902a5c 100644
--- a/Documentation/gpu/drm-uapi.rst
+++ b/Documentation/gpu/drm-uapi.rst
@@ -570,3 +570,50 @@ dma-buf interoperability
 
 Please see Documentation/userspace-api/dma-buf-alloc-exchange.rst for
 information on how dma-buf is integrated and exposed within DRM.
+
+KMS atomic state
+
+
+An atomic commit can change multiple KMS properties in an atomic fashion,
+without ever applying intermediate or partial state changes.  Either the whole
+commit succeeds or fails, and it will never be applied partially. This is the
+fundamental improvement of the atomic API over the older non-atomic API which 
is
+referred to as the "legacy API".  Applying intermediate state could 
unexpectedly
+fail, cause visible glitches, or delay reaching the final state.
+
+An atomic commit can be flagged with DRM_MODE_ATOMIC_TEST_ONLY, which means the
+complete state change is validated but not applied.  Userspace should use this
+flag to validate any state change before asking to apply it. If validation 
fails
+for any reason, userspace should attempt to fall back to another, perhaps
+simpler, final state.  This allows userspace to probe for various 
configurations
+without causing visible glitches on screen and without the need to undo a
+probing change.
+
+The changes recorded in an atomic commit apply on top the current KMS state in
+the kernel. Hence, the complete new KMS state is the complete old KMS state 
with
+the committed property settings done on top. The kernel will try to avoid
+no-operation changes, so it is safe for userspace to send redundant property
+settings.  However, not every situation allows for no-op changes, due to the
+need to acquire locks for some attributes. Userspace needs to be aware that 
some
+redundant information might result in oversynchronization issues.  No-operation
+changes do not count towards actually needed changes, e.g.  setting MODE_ID to 
a
+different blob with identical contents as the current KMS state shall not be a
+modeset on its own. As a special exception for VRR needs, explicitly setting
+FB_ID to its current value is not a no-op.
+
+A "modeset" is a change in KMS state that might enable, disable, or temporarily
+disrupt the emitted video signal, possibly causing visible glitches on screen. 
A
+modeset may also take considerably more time to complete than other kinds of
+changes, and the video sink might also need time to adapt to the new signal
+properties. Therefore a modeset must be explicitly allowed with the flag
+DRM_MODE_ATOMIC_ALLOW_MODESET.  This in combination with
+DRM_MODE_ATOMIC_TEST_ONLY allows userspace to determine if a state change is
+likely to cause visible disruption on screen and avoid such changes when end
+users do not expect them.
+
+An atomic commit with the flag DRM_MODE_PAGE_FLIP_ASYNC is allowed to
+effectively change only the FB_ID property on any planes. No-operation changes
+are ignored as always. Changing any other property will cause the commit to be
+rejected. Each driver may relax this restriction if they have guarantees that
+such property change doesn't cause modesets. Userspace can use TEST_ONLY 
commits
+to query the driver about this.
-- 
2.42.1



[PATCH v9 3/4] drm: introduce DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP

2023-11-22 Thread André Almeida
From: Simon Ser 

This new kernel capability indicates whether async page-flips are
supported via the atomic uAPI. DRM clients can use it to check
for support before feeding DRM_MODE_PAGE_FLIP_ASYNC to the kernel.

Make it clear that DRM_CAP_ASYNC_PAGE_FLIP is for legacy uAPI only.

Signed-off-by: Simon Ser 
Reviewed-by: André Almeida 
Reviewed-by: Alex Deucher 
Signed-off-by: André Almeida 
---
v9: no changes
---
---
 drivers/gpu/drm/drm_ioctl.c |  4 
 include/uapi/drm/drm.h  | 10 +-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 44fda68c28ae..f461ed862480 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -301,6 +301,10 @@ static int drm_getcap(struct drm_device *dev, void *data, 
struct drm_file *file_
case DRM_CAP_CRTC_IN_VBLANK_EVENT:
req->value = 1;
break;
+   case DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP:
+   req->value = drm_core_check_feature(dev, DRIVER_ATOMIC) &&
+dev->mode_config.async_page_flip;
+   break;
default:
return -EINVAL;
}
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 8662b5aeea0c..796de831f4a0 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -713,7 +713,8 @@ struct drm_gem_open {
 /**
  * DRM_CAP_ASYNC_PAGE_FLIP
  *
- * If set to 1, the driver supports _MODE_PAGE_FLIP_ASYNC.
+ * If set to 1, the driver supports _MODE_PAGE_FLIP_ASYNC for legacy
+ * page-flips.
  */
 #define DRM_CAP_ASYNC_PAGE_FLIP0x7
 /**
@@ -773,6 +774,13 @@ struct drm_gem_open {
  * :ref:`drm_sync_objects`.
  */
 #define DRM_CAP_SYNCOBJ_TIMELINE   0x14
+/**
+ * DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP
+ *
+ * If set to 1, the driver supports _MODE_PAGE_FLIP_ASYNC for atomic
+ * commits.
+ */
+#define DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP 0x15
 
 /* DRM_IOCTL_GET_CAP ioctl argument type */
 struct drm_get_cap {
-- 
2.42.1



[PATCH v9 2/4] drm: allow DRM_MODE_PAGE_FLIP_ASYNC for atomic commits

2023-11-22 Thread André Almeida
From: Simon Ser 

If the driver supports it, allow user-space to supply the
DRM_MODE_PAGE_FLIP_ASYNC flag to request an async page-flip.
Set drm_crtc_state.async_flip accordingly.

Document that drivers will reject atomic commits if an async
flip isn't possible. This allows user-space to fall back to
something else. For instance, Xorg falls back to a blit.
Another option is to wait as close to the next vblank as
possible before performing the page-flip to reduce latency.

Signed-off-by: Simon Ser 
Reviewed-by: Alex Deucher 
Co-developed-by: André Almeida 
Signed-off-by: André Almeida 
---
v9: dropped atomic_async_page_flip_not_supported
---
 drivers/gpu/drm/drm_atomic_uapi.c | 25 ++---
 include/uapi/drm/drm_mode.h   |  9 +
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index ed46133a2dd7..de4265423ddc 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -1368,6 +1368,18 @@ static void complete_signaling(struct drm_device *dev,
kfree(fence_state);
 }
 
+static void
+set_async_flip(struct drm_atomic_state *state)
+{
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *crtc_state;
+   int i;
+
+   for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
+   crtc_state->async_flip = true;
+   }
+}
+
 int drm_mode_atomic_ioctl(struct drm_device *dev,
  void *data, struct drm_file *file_priv)
 {
@@ -1409,9 +1421,13 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
}
 
if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) {
-   drm_dbg_atomic(dev,
-  "commit failed: invalid flag 
DRM_MODE_PAGE_FLIP_ASYNC\n");
-   return -EINVAL;
+   if (!dev->mode_config.async_page_flip) {
+   drm_dbg_atomic(dev,
+  "commit failed: DRM_MODE_PAGE_FLIP_ASYNC 
not supported\n");
+   return -EINVAL;
+   }
+
+   async_flip = true;
}
 
/* can't test and expect an event at the same time. */
@@ -1514,6 +1530,9 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
if (ret)
goto out;
 
+   if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC)
+   set_async_flip(state);
+
if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) {
ret = drm_atomic_check_only(state);
} else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 09e7a471ee30..95630f170110 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -957,6 +957,15 @@ struct hdr_output_metadata {
  * Request that the page-flip is performed as soon as possible, ie. with no
  * delay due to waiting for vblank. This may cause tearing to be visible on
  * the screen.
+ *
+ * When used with atomic uAPI, the driver will return an error if the hardware
+ * doesn't support performing an asynchronous page-flip for this update.
+ * User-space should handle this, e.g. by falling back to a regular page-flip.
+ *
+ * Note, some hardware might need to perform one last synchronous page-flip
+ * before being able to switch to asynchronous page-flips. As an exception,
+ * the driver will return success even though that first page-flip is not
+ * asynchronous.
  */
 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02
 #define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
-- 
2.42.1



[PATCH v9 1/4] drm: Refuse to async flip with atomic prop changes

2023-11-22 Thread André Almeida
Given that prop changes may lead to modesetting, which would defeat the
fast path of the async flip, refuse any atomic prop change for async
flips in atomic API. The only exception is the framebuffer ID to flip
to. Currently the only plane type supported is the primary one.

Signed-off-by: André Almeida 
Reviewed-by: Simon Ser 
---
v9: no changes
v8: add a check for plane type, we can only flip primary planes
v7: drop the mode_id exception for prop changes
---
 drivers/gpu/drm/drm_atomic_uapi.c   | 52 +++--
 drivers/gpu/drm/drm_crtc_internal.h |  2 +-
 drivers/gpu/drm/drm_mode_object.c   |  2 +-
 3 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index 98d3b10c08ae..ed46133a2dd7 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -1006,13 +1006,28 @@ int drm_atomic_connector_commit_dpms(struct 
drm_atomic_state *state,
return ret;
 }
 
+static int drm_atomic_check_prop_changes(int ret, uint64_t old_val, uint64_t 
prop_value,
+struct drm_property *prop)
+{
+   if (ret != 0 || old_val != prop_value) {
+   drm_dbg_atomic(prop->dev,
+  "[PROP:%d:%s] No prop can be changed during 
async flip\n",
+  prop->base.id, prop->name);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 int drm_atomic_set_property(struct drm_atomic_state *state,
struct drm_file *file_priv,
struct drm_mode_object *obj,
struct drm_property *prop,
-   uint64_t prop_value)
+   uint64_t prop_value,
+   bool async_flip)
 {
struct drm_mode_object *ref;
+   uint64_t old_val;
int ret;
 
if (!drm_property_change_valid_get(prop, prop_value, ))
@@ -1029,6 +1044,13 @@ int drm_atomic_set_property(struct drm_atomic_state 
*state,
break;
}
 
+   if (async_flip) {
+   ret = drm_atomic_connector_get_property(connector, 
connector_state,
+   prop, _val);
+   ret = drm_atomic_check_prop_changes(ret, old_val, 
prop_value, prop);
+   break;
+   }
+
ret = drm_atomic_connector_set_property(connector,
connector_state, file_priv,
prop, prop_value);
@@ -1044,6 +1066,13 @@ int drm_atomic_set_property(struct drm_atomic_state 
*state,
break;
}
 
+   if (async_flip) {
+   ret = drm_atomic_crtc_get_property(crtc, crtc_state,
+  prop, _val);
+   ret = drm_atomic_check_prop_changes(ret, old_val, 
prop_value, prop);
+   break;
+   }
+
ret = drm_atomic_crtc_set_property(crtc,
crtc_state, prop, prop_value);
break;
@@ -1051,6 +1080,7 @@ int drm_atomic_set_property(struct drm_atomic_state 
*state,
case DRM_MODE_OBJECT_PLANE: {
struct drm_plane *plane = obj_to_plane(obj);
struct drm_plane_state *plane_state;
+   struct drm_mode_config *config = >dev->mode_config;
 
plane_state = drm_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state)) {
@@ -1058,6 +1088,21 @@ int drm_atomic_set_property(struct drm_atomic_state 
*state,
break;
}
 
+   if (async_flip && prop != config->prop_fb_id) {
+   ret = drm_atomic_plane_get_property(plane, plane_state,
+   prop, _val);
+   ret = drm_atomic_check_prop_changes(ret, old_val, 
prop_value, prop);
+   break;
+   }
+
+   if (async_flip && plane_state->plane->type != 
DRM_PLANE_TYPE_PRIMARY) {
+   drm_dbg_atomic(prop->dev,
+   "[OBJECT:%d] Only primary planes can be changed 
during async flip\n",
+   obj->id);
+   ret = -EINVAL;
+   break;
+   }
+
ret = drm_atomic_plane_set_property(plane,
plane_state, file_priv,
prop, prop_value);
@@ -1337,6 +1382,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
struct drm_out_fence_state *fence_state;
int ret = 0;
unsigned int i, j, num_fences;
+   bool async_flip = false;
 
/* disallow for drivers not supporting atomic: */
   

[PATCH v9 0/4] drm: Add support for atomic async page-flip

2023-11-22 Thread André Almeida
Hi,

This work from me and Simon adds support for DRM_MODE_PAGE_FLIP_ASYNC through
the atomic API. This feature is already available via the legacy API. The use
case is to be able to present a new frame immediately (or as soon as
possible), even if after missing a vblank. This might result in tearing, but
it's useful when a high framerate is desired, such as for gaming.

Differently from earlier versions, this one refuses to flip if any prop changes
for async flips. The idea is that the fast path of immediate page flips doesn't
play well with modeset changes, so only the fb_id can be changed.

Tested with:
 - Intel TigerLake-LP GT2
 - AMD VanGogh

Thanks,
André

- User-space patch: https://github.com/Plagman/gamescope/pull/595
- IGT tests: 
https://lore.kernel.org/all/20231110163811.24158-1-andrealm...@igalia.com/

Changes from v8:
- Dropped atomic_async_page_flip_not_supported, giving that current design works
with any driver that support atomic and async at the same time.
- Dropped the patch that disabled atomic_async_page_flip_not_supported for AMD.
- Reordered commits
v8: https://lore.kernel.org/all/20231025005318.293690-1-andrealm...@igalia.com/

Changes from v7:
- Only accept flips to primary planes. If a driver support flips in different
planes, support will be added  later.
v7: 
https://lore.kernel.org/dri-devel/20231017092837.32428-1-andrealm...@igalia.com/

Changes from v6:
- Dropped the exception to allow MODE_ID changes (Simon)
- Clarify what happens when flipping with the same FB_ID (Pekka)

v6: 
https://lore.kernel.org/dri-devel/20230815185710.159779-1-andrealm...@igalia.com/

Changes from v5:
- Add note in the docs that not every redundant attribute will result in no-op,
  some might cause oversynchronization issues.

v5: 
https://lore.kernel.org/dri-devel/20230707224059.305474-1-andrealm...@igalia.com/

Changes from v4:
 - Documentation rewrote by Pekka Paalanen

v4: 
https://lore.kernel.org/dri-devel/20230701020917.143394-1-andrealm...@igalia.com/

Changes from v3:
 - Add new patch to reject prop changes
 - Add a documentation clarifying the KMS atomic state set

v3: 
https://lore.kernel.org/dri-devel/20220929184307.258331-1-cont...@emersion.fr/

André Almeida (1):
  drm: Refuse to async flip with atomic prop changes

Pekka Paalanen (1):
  drm/doc: Define KMS atomic state set

Simon Ser (2):
  drm: allow DRM_MODE_PAGE_FLIP_ASYNC for atomic commits
  drm: introduce DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP

 Documentation/gpu/drm-uapi.rst  | 47 ++
 drivers/gpu/drm/drm_atomic_uapi.c   | 77 ++---
 drivers/gpu/drm/drm_crtc_internal.h |  2 +-
 drivers/gpu/drm/drm_ioctl.c |  4 ++
 drivers/gpu/drm/drm_mode_object.c   |  2 +-
 include/uapi/drm/drm.h  | 10 +++-
 include/uapi/drm/drm_mode.h |  9 
 7 files changed, 142 insertions(+), 9 deletions(-)

-- 
2.42.1



Re: [PATCH] drm/msm/a690: Fix reg values for a690

2023-11-22 Thread Konrad Dybcio




On 11/21/23 17:21, Rob Clark wrote:

From: Danylo Piliaiev 

KGSL doesn't support a690 so all reg values were the same as
on a660. Now we know the values and they are different from the
windows driver.

This fixes hangs on D3D12 games and some CTS tests.

Signed-off-by: Danylo Piliaiev 
Signed-off-by: Rob Clark 
---

Very interesting.. did you document how to get these on windows?

Konrad


[PATCH] dma-buf: Correct the documentation of name and exp_name symbols

2023-11-22 Thread Ramesh Errabolu
Fix the documentation of struct dma_buf members name and exp_name
as to how these members are to be used and accessed.

Signed-off-by: Ramesh Errabolu 
---
 include/linux/dma-buf.h | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index 3f31baa3293f..8ff4add71f88 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -343,16 +343,19 @@ struct dma_buf {
/**
 * @exp_name:
 *
-* Name of the exporter; useful for debugging. See the
-* DMA_BUF_SET_NAME IOCTL.
+* Name of the exporter; useful for debugging. Must not be NULL
 */
const char *exp_name;
 
/**
 * @name:
 *
-* Userspace-provided name; useful for accounting and debugging,
-* protected by dma_resv_lock() on @resv and @name_lock for read access.
+* Userspace-provided name. Default value is NULL. If not NULL,
+* length cannot be longer than DMA_BUF_NAME_LEN, including NIL
+* char. Useful for accounting and debugging. Read/Write accesses
+* are protected by @name_lock
+*
+* See the IOCTLs DMA_BUF_SET_NAME or DMA_BUF_SET_NAME_A/B
 */
const char *name;
 
-- 
2.34.1



Re: [PATCH v6 0/6] drm: simplify support for transparent DRM bridges

2023-11-22 Thread Sui Jingfeng

Hi,


On 2023/11/4 07:03, Dmitry Baryshkov wrote:

Supporting DP/USB-C can result in a chain of several transparent
bridges (PHY, redrivers, mux, etc). All attempts to implement DP support
in a different way resulted either in series of hacks or in device tree
not reflecting the actual hardware design. This results in drivers
having similar boilerplate code for such bridges.


Please improve the written,  "resulted" -> "yield" ?


Next, these drivers are susceptible to -EPROBE_DEFER loops: the next
bridge can either be probed from the bridge->attach callback, when it is
too late to return -EPROBE_DEFER, or from the probe() callback, when the
next bridge might not yet be available, because it depends on the
resources provided by the probing device. Device links can not fully
solve this problem since there are mutual dependencies between adjancent
devices.

Last, but not least, this results in the the internal knowledge of DRM


There is a duplicated "the" word in this sentence.

As far as I can understand, nearly all of those troubles are because the 
display bridges
drivers are designed as a kernel module(.ko) instead of making them as static 
link-able
helpers. I means that a display bridge device can not work standalone, as it 
have to be
used with a display controller. So a display bridge is just a slave device or a 
auxiliary
device. My question is: if it can't works by itself, we probably shouldn't 
design them as
kernel modules style. Am I correct?


subsystem slowly diffusing into other subsystems, like PHY or USB/TYPEC.


Yeah, this indeed a problem.


To solve all these issues, define a separate DRM helper, which creates
separate aux device just for the bridge.


I'm supporting you if want to solve all these problems, this is fine and thanks 
a lot.
But I want to ask a question, now that you are solving these problems by 
creating separate
devices, does this manner match the hardware design perfectly? which is the 
hardware units
you newly created device is corresponding to?



During probe such aux device
doesn't result in the EPROBE_DEFER loops. Instead it allows the device
drivers to probe properly, according to the actual resource
dependencies. The bridge auxdevs are then probed when the next bridge
becomes available, sparing drivers from drm_bridge_attach() returning
-EPROBE_DEFER.


OK, as far as I can understand,  in order to solve the mentioned problem
you are also retire the defer probe mechanism.



Changes since v5:
  - Removed extra semicolon in !DRM_AUX_HPD_BRIDGE stubs definition.

Changes since v4:
  - Added documentation for new API (Sima)
  - Added generic code to handle "last mile" DP bridges implementing just
the HPD functionality.
  - Rebased on top of linux-next to be able to drop #ifdef's around
drm_bridge->of_node

Changes since v3:
  - Moved bridge driver to gpu/drm/bridge (Neil Armstrong)
  - Renamed it to aux-bridge (since there is already a simple_bridge driver)
  - Made CONFIG_OF mandatory for this driver (Neil Armstrong)
  - Added missing kfree and ida_free (Dan Carpenter)

Changes since v2:
  - ifdef'ed bridge->of_node access (LKP)

Changes since v1:
  - Added EXPORT_SYMBOL_GPL / MODULE_LICENSE / etc. to drm_simple_bridge

Dmitry Baryshkov (6):
   drm/bridge: add transparent bridge helper
   phy: qcom: qmp-combo: switch to DRM_AUX_BRIDGE
   usb: typec: nb7vpq904m: switch to DRM_AUX_BRIDGE
   drm/bridge: implement generic DP HPD bridge
   soc: qcom: pmic-glink: switch to DRM_AUX_HPD_BRIDGE
   usb: typec: qcom-pmic-typec: switch to DRM_AUX_HPD_BRIDGE

  drivers/gpu/drm/bridge/Kconfig|  17 ++
  drivers/gpu/drm/bridge/Makefile   |   2 +
  drivers/gpu/drm/bridge/aux-bridge.c   | 140 +++
  drivers/gpu/drm/bridge/aux-hpd-bridge.c   | 164 ++
  drivers/phy/qualcomm/Kconfig  |   2 +-
  drivers/phy/qualcomm/phy-qcom-qmp-combo.c |  44 +
  drivers/soc/qcom/Kconfig  |   1 +
  drivers/soc/qcom/pmic_glink_altmode.c |  33 +---
  drivers/usb/typec/mux/Kconfig |   2 +-
  drivers/usb/typec/mux/nb7vpq904m.c|  44 +
  drivers/usb/typec/tcpm/Kconfig|   1 +
  drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c |  41 +
  include/drm/bridge/aux-bridge.h   |  37 
  13 files changed, 383 insertions(+), 145 deletions(-)
  create mode 100644 drivers/gpu/drm/bridge/aux-bridge.c
  create mode 100644 drivers/gpu/drm/bridge/aux-hpd-bridge.c
  create mode 100644 include/drm/bridge/aux-bridge.h



[drm-intel:for-linux-next-gt 1/6] drivers/gpu/drm/i915/i915_drm_client.h:81:1: error: non-void function does not return a value

2023-11-22 Thread kernel test robot
tree:   git://anongit.freedesktop.org/drm-intel for-linux-next-gt
head:   5032c607e886e0c40749a05d37b835c1757d38ff
commit: e4ae85e364fc652ea15d85b0f3a6da304c9b5ce7 [1/6] drm/i915: Add ability 
for tracking buffer objects per client
config: x86_64-buildonly-randconfig-006-20231122 
(https://download.01.org/0day-ci/archive/20231122/202311222102.lhbe6kcx-...@intel.com/config)
compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git 
ae42196bc493ffe877a7e3dff8be32035dea4d07)
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20231122/202311222102.lhbe6kcx-...@intel.com/reproduce)

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

Note: the drm-intel/for-linux-next-gt HEAD 
5032c607e886e0c40749a05d37b835c1757d38ff builds fine.
  It only hurts bisectability.

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/i915/selftests/igt_spinner.c:12:
   In file included from drivers/gpu/drm/i915/selftests/igt_spinner.h:10:
   In file included from drivers/gpu/drm/i915/gem/i915_gem_context.h:12:
   In file included from drivers/gpu/drm/i915/gt/intel_context.h:14:
   In file included from drivers/gpu/drm/i915/i915_drv.h:54:
>> drivers/gpu/drm/i915/i915_drm_client.h:81:1: error: non-void function does 
>> not return a value [-Werror,-Wreturn-type]
   }
   ^
   1 error generated.


vim +81 drivers/gpu/drm/i915/i915_drm_client.h

78  
79  static inline bool i915_drm_client_remove_object(struct 
drm_i915_gem_object *obj)
80  {
  > 81  }
82  #endif
83  

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


[PATCH AUTOSEL 4.14 3/3] drm/amdgpu: correct chunk_ptr to a pointer to chunk.

2023-11-22 Thread Sasha Levin
From: YuanShang 

[ Upstream commit 50d51374b498457c4dea26779d32ccfed12ddaff ]

The variable "chunk_ptr" should be a pointer pointing
to a struct drm_amdgpu_cs_chunk instead of to a pointer
of that.

Signed-off-by: YuanShang 
Reviewed-by: Christian König 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 7bad519aaae08..d24ef103471b9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -113,7 +113,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser 
*p, void *data)
}
 
for (i = 0; i < p->nchunks; i++) {
-   struct drm_amdgpu_cs_chunk __user **chunk_ptr = NULL;
+   struct drm_amdgpu_cs_chunk __user *chunk_ptr = NULL;
struct drm_amdgpu_cs_chunk user_chunk;
uint32_t __user *cdata;
 
-- 
2.42.0



[PATCH AUTOSEL 4.19 6/6] drm/amdgpu: correct chunk_ptr to a pointer to chunk.

2023-11-22 Thread Sasha Levin
From: YuanShang 

[ Upstream commit 50d51374b498457c4dea26779d32ccfed12ddaff ]

The variable "chunk_ptr" should be a pointer pointing
to a struct drm_amdgpu_cs_chunk instead of to a pointer
of that.

Signed-off-by: YuanShang 
Reviewed-by: Christian König 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 70e446c2acf82..94b06c918e80d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -147,7 +147,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser 
*p, union drm_amdgpu_cs
}
 
for (i = 0; i < p->nchunks; i++) {
-   struct drm_amdgpu_cs_chunk __user **chunk_ptr = NULL;
+   struct drm_amdgpu_cs_chunk __user *chunk_ptr = NULL;
struct drm_amdgpu_cs_chunk user_chunk;
uint32_t __user *cdata;
 
-- 
2.42.0



[PATCH AUTOSEL 5.4 6/6] drm/amdgpu: correct chunk_ptr to a pointer to chunk.

2023-11-22 Thread Sasha Levin
From: YuanShang 

[ Upstream commit 50d51374b498457c4dea26779d32ccfed12ddaff ]

The variable "chunk_ptr" should be a pointer pointing
to a struct drm_amdgpu_cs_chunk instead of to a pointer
of that.

Signed-off-by: YuanShang 
Reviewed-by: Christian König 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 1a83055211762..f9c725a8991b7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -141,7 +141,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser 
*p, union drm_amdgpu_cs
}
 
for (i = 0; i < p->nchunks; i++) {
-   struct drm_amdgpu_cs_chunk __user **chunk_ptr = NULL;
+   struct drm_amdgpu_cs_chunk __user *chunk_ptr = NULL;
struct drm_amdgpu_cs_chunk user_chunk;
uint32_t __user *cdata;
 
-- 
2.42.0



[PATCH AUTOSEL 5.10 7/7] drm/amdgpu: correct chunk_ptr to a pointer to chunk.

2023-11-22 Thread Sasha Levin
From: YuanShang 

[ Upstream commit 50d51374b498457c4dea26779d32ccfed12ddaff ]

The variable "chunk_ptr" should be a pointer pointing
to a struct drm_amdgpu_cs_chunk instead of to a pointer
of that.

Signed-off-by: YuanShang 
Reviewed-by: Christian König 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 7f2adac82e3a6..addeda42339fa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -143,7 +143,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser 
*p, union drm_amdgpu_cs
}
 
for (i = 0; i < p->nchunks; i++) {
-   struct drm_amdgpu_cs_chunk __user **chunk_ptr = NULL;
+   struct drm_amdgpu_cs_chunk __user *chunk_ptr = NULL;
struct drm_amdgpu_cs_chunk user_chunk;
uint32_t __user *cdata;
 
-- 
2.42.0



[PATCH AUTOSEL 5.15 7/7] drm/amdgpu: correct chunk_ptr to a pointer to chunk.

2023-11-22 Thread Sasha Levin
From: YuanShang 

[ Upstream commit 50d51374b498457c4dea26779d32ccfed12ddaff ]

The variable "chunk_ptr" should be a pointer pointing
to a struct drm_amdgpu_cs_chunk instead of to a pointer
of that.

Signed-off-by: YuanShang 
Reviewed-by: Christian König 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 2d8f71dde9803..f293d0dfec613 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -142,7 +142,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser 
*p, union drm_amdgpu_cs
}
 
for (i = 0; i < p->nchunks; i++) {
-   struct drm_amdgpu_cs_chunk __user **chunk_ptr = NULL;
+   struct drm_amdgpu_cs_chunk __user *chunk_ptr = NULL;
struct drm_amdgpu_cs_chunk user_chunk;
uint32_t __user *cdata;
 
-- 
2.42.0



[PATCH AUTOSEL 6.1 9/9] drm/amdgpu: correct chunk_ptr to a pointer to chunk.

2023-11-22 Thread Sasha Levin
From: YuanShang 

[ Upstream commit 50d51374b498457c4dea26779d32ccfed12ddaff ]

The variable "chunk_ptr" should be a pointer pointing
to a struct drm_amdgpu_cs_chunk instead of to a pointer
of that.

Signed-off-by: YuanShang 
Reviewed-by: Christian König 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 4624160315648..26b55cca27680 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -201,7 +201,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
}
 
for (i = 0; i < p->nchunks; i++) {
-   struct drm_amdgpu_cs_chunk __user **chunk_ptr = NULL;
+   struct drm_amdgpu_cs_chunk __user *chunk_ptr = NULL;
struct drm_amdgpu_cs_chunk user_chunk;
uint32_t __user *cdata;
 
-- 
2.42.0



[PATCH AUTOSEL 6.5 14/15] drm/amdgpu: correct chunk_ptr to a pointer to chunk.

2023-11-22 Thread Sasha Levin
From: YuanShang 

[ Upstream commit 50d51374b498457c4dea26779d32ccfed12ddaff ]

The variable "chunk_ptr" should be a pointer pointing
to a struct drm_amdgpu_cs_chunk instead of to a pointer
of that.

Signed-off-by: YuanShang 
Reviewed-by: Christian König 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 946d031d2520e..c66719a92e9ba 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -208,7 +208,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
}
 
for (i = 0; i < p->nchunks; i++) {
-   struct drm_amdgpu_cs_chunk __user **chunk_ptr = NULL;
+   struct drm_amdgpu_cs_chunk __user *chunk_ptr = NULL;
struct drm_amdgpu_cs_chunk user_chunk;
uint32_t __user *cdata;
 
-- 
2.42.0



[PATCH AUTOSEL 6.5 13/15] drm/amdgpu: finalizing mem_partitions at the end of GMC v9 sw_fini

2023-11-22 Thread Sasha Levin
From: Le Ma 

[ Upstream commit bdb72185d310fc8049c7ea95221d640e9e7165e5 ]

The valid num_mem_partitions is required during ttm pool fini,
thus move the cleanup at the end of the function.

Signed-off-by: Le Ma 
Reviewed-by: Hawking Zhang 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index 67e669e0141cc..00c719b93c76e 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -2211,8 +2211,6 @@ static int gmc_v9_0_sw_fini(void *handle)
 
if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 3))
amdgpu_gmc_sysfs_fini(adev);
-   adev->gmc.num_mem_partitions = 0;
-   kfree(adev->gmc.mem_partitions);
 
amdgpu_gmc_ras_fini(adev);
amdgpu_gem_force_release(adev);
@@ -2226,6 +2224,9 @@ static int gmc_v9_0_sw_fini(void *handle)
amdgpu_bo_free_kernel(>gmc.pdb0_bo, NULL, >gmc.ptr_pdb0);
amdgpu_bo_fini(adev);
 
+   adev->gmc.num_mem_partitions = 0;
+   kfree(adev->gmc.mem_partitions);
+
return 0;
 }
 
-- 
2.42.0



  1   2   >