Re: [PATCH v4 3/3] drm/panel-simple: allow LVDS format override

2023-08-18 Thread Johannes Zink

Hi Dan,

do you have any input on this for me?

Best regards
Johannes

On 7/28/23 16:16, Johannes Zink wrote:

Some panels support multiple LVDS data mapping formats, which can be
used e.g. run displays on jeida-18 format when only 3 LVDS lanes are
available.

Add parsing of an optional data-mapping devicetree property, which also
touches up the bits per color to match the bus format.

Signed-off-by: Johannes Zink 

---

Changes:

   v3 -> v4: - worked in Dan's feedback (thanks for reviewing my work):
 - return with a proper error in case the call to
  panel_simple_override_nondefault_lvds_datamapping()
  fails
 - drop the unneeded and ambiguous ret variable

   v2 -> v3: - worked in Laurent's review findings (thanks for reviewing
   my work):
- extract fixing up the bus format to separate
  function
- only call function on LVDS panels
- fix typos found by Laurent
- simplified error handling

   v1 -> v2: - fix missing unwind goto found by test robot
   Reported-by: kernel test robot 
   Reported-by: Dan Carpenter 
   Link: 
https://lore.kernel.org/r/202304160359.4lhmfolu-...@intel.com/
---
  drivers/gpu/drm/panel/panel-simple.c | 53 
  1 file changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index 4badda6570d5..3a164931093e 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -40,6 +40,7 @@
  #include 
  #include 
  #include 
+#include 
  
  /**

   * struct panel_desc - Describes a simple panel.
@@ -549,6 +550,51 @@ static void panel_simple_parse_panel_timing_node(struct 
device *dev,
dev_err(dev, "Reject override mode: No display_timing found\n");
  }
  
+static int panel_simple_override_nondefault_lvds_datamapping(struct device *dev,

+struct 
panel_simple *panel)
+{
+   int ret, bpc;
+
+   ret = drm_of_lvds_get_data_mapping(dev->of_node);
+   if (ret < 0) {
+   if (ret == -EINVAL)
+   dev_warn(dev, "Ignore invalid data-mapping property\n");
+
+   /*
+* Ignore non-existing or malformatted property, fallback to
+* default data-mapping, and return 0.
+*/
+   return 0;
+   }
+
+   switch (ret) {
+   default:
+   WARN_ON(1);
+   fallthrough;
+   case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
+   fallthrough;
+   case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
+   bpc = 8;
+   break;
+   case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
+   bpc = 6;
+   }
+
+   if (panel->desc->bpc != bpc || panel->desc->bus_format != ret) {
+   struct panel_desc *override_desc;
+
+   override_desc = devm_kmemdup(dev, panel->desc, 
sizeof(*panel->desc), GFP_KERNEL);
+   if (!override_desc)
+   return -ENOMEM;
+
+   override_desc->bus_format = ret;
+   override_desc->bpc = bpc;
+   panel->desc = override_desc;
+   }
+
+   return 0;
+}
+
  static int panel_simple_probe(struct device *dev, const struct panel_desc 
*desc)
  {
struct panel_simple *panel;
@@ -601,6 +647,13 @@ static int panel_simple_probe(struct device *dev, const 
struct panel_desc *desc)
panel_simple_parse_panel_timing_node(dev, panel, &dt);
}
  
+	if (desc->connector_type == DRM_MODE_CONNECTOR_LVDS) {

+   /* Optional data-mapping property for overriding bus format */
+   err = panel_simple_override_nondefault_lvds_datamapping(dev, 
panel);
+   if (err)
+   goto free_ddc;
+   }
+
connector_type = desc->connector_type;
/* Catch common mistakes for panels. */
switch (connector_type) {



--
Pengutronix e.K.| Johannes Zink  |
Steuerwalder Str. 21| https://www.pengutronix.de/|
31137 Hildesheim, Germany   | Phone: +49-5121-206917-0   |
Amtsgericht Hildesheim, HRA 2686| Fax:   +49-5121-206917-|



Re: [PATCH 03/13] scatterlist: Add sg_set_folio()

2023-08-18 Thread Zhu Yanjun



在 2023/7/31 5:42, Matthew Wilcox 写道:

On Sun, Jul 30, 2023 at 09:57:06PM +0800, Zhu Yanjun wrote:

在 2023/7/30 19:18, Matthew Wilcox 写道:

On Sun, Jul 30, 2023 at 07:01:26PM +0800, Zhu Yanjun wrote:

Does the following function have folio version?

"
int sg_alloc_append_table_from_pages(struct sg_append_table *sgt_append,
struct page **pages, unsigned int n_pages, unsigned int offset,
unsigned long size, unsigned int max_segment,
unsigned int left_pages, gfp_t gfp_mask)
"

No -- I haven't needed to convert anything that uses
sg_alloc_append_table_from_pages() yet.  It doesn't look like it should
be _too_ hard to add a folio version.

In many places, this function is used. So this function needs the folio
version.

It's not used in very many places.  But the first one that I see it used
(drivers/infiniband/core/umem.c), you can't do a straightforward folio
conversion:

 pinned = pin_user_pages_fast(cur_base,
   min_t(unsigned long, npages,
 PAGE_SIZE /
 sizeof(struct page *)),
   gup_flags, page_list);
...
 ret = sg_alloc_append_table_from_pages(
 &umem->sgt_append, page_list, pinned, 0,
 pinned << PAGE_SHIFT, ib_dma_max_seg_size(device),
 npages, GFP_KERNEL);

That can't be converted to folios.  The GUP might start in the middle of
the folio, and we have no way to communicate that.

This particular usage really needs the phyr work that Jason is doing so
we can efficiently communicate physically contiguous ranges from GUP
to sg.


Hi, Matthew

Thanks. To the following function, it seems that no folio function 
replace vmalloc_to_page.


vmalloc_to_page calls virt_to_page to get page. Finally the followings 
will be called.


"
(mem_map + ((pfn) - ARCH_PFN_OFFSET))

"

And I do not find the related folio functions with vmalloc_to_page.

And no folio function replaces dma_map_page.

dma_map_page will call dma_map_page_attrs.

Or these 2 function should not be replaced with folio functions?

int irdma_map_vm_page_list(struct irdma_hw *hw, void *va, dma_addr_t 
*pg_dma,


   u32 pg_cnt)
{
    struct page *vm_page;
    int i;
    u8 *addr;

    addr = (u8 *)(uintptr_t)va;
    for (i = 0; i < pg_cnt; i++) {
    vm_page = vmalloc_to_page(addr);
    if (!vm_page)
    goto err;

    pg_dma[i] = dma_map_page(hw->device, vm_page, 0, PAGE_SIZE,
 DMA_BIDIRECTIONAL);
    if (dma_mapping_error(hw->device, pg_dma[i]))
    goto err;

    addr += PAGE_SIZE;
    }

    return 0;

err:
    irdma_unmap_vm_page_list(hw, pg_dma, i);
    return -ENOMEM;

}

Thanks,

Zhu Yanjun



Another problem, after folio is used, I want to know the performance after
folio is implemented.

How to make tests to get the performance?

You know what you're working on ... I wouldn't know how best to test
your code.


Re: [PATCH drm-misc-next] drm/ttm/tests: Require MMU when testing

2023-08-18 Thread Karolina Stolarek

Hi Thomas,

On 17.08.2023 15:11, Thomas Zimmermann wrote:

Hi

I've cherry-picked the patch into drm-misc-next-fixes, so it will show 
up in upstream soon.


Many thanks for your help. I'm sorry this one slipped through.



Am 11.08.23 um 13:36 schrieb Karolina Stolarek:

Satisfy MMU dependency when testing TTM with KUnit. This fixes
compilation errors on platforms that don't select this option
by default.

Signed-off-by: Karolina Stolarek 
Cc: Christian König 
Reported-by: kernel test robot 
Closes: 
https://lore.kernel.org/oe-kbuild-all/202308110133.f0lhfwmv-...@intel.com/
Closes: 
https://lore.kernel.org/oe-kbuild-all/202308111032.enu8iisr-...@intel.com/


This should have also mentioned

Fixes: e3912d09bf8d ("drm/ttm: Introduce KUnit test")


I wasn't sure if for the "Fixes" tag I can refer to drm-misc-next 
commits, so I left it out.


All the best,
Karolina



Best regards
Thomas


---
  drivers/gpu/drm/Kconfig | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 9d1f0e04fd56..ab9ef1c20349 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -198,7 +198,7 @@ config DRM_TTM
  config DRM_TTM_KUNIT_TEST
  tristate "KUnit tests for TTM" if !KUNIT_ALL_TESTS
  default n
-    depends on DRM && KUNIT
+    depends on DRM && KUNIT && MMU
  select DRM_TTM
  select DRM_EXPORT_FOR_TESTS if m
  select DRM_KUNIT_TEST_HELPERS




Adds support for ConfigFS to VKMS!

2023-08-18 Thread Brandon Pollack
Since Jim is busy with other work and I'm working on some things that
rely on this, I've taken up the task of doing the iterations.  I've
addressed the comments as best I can (those replies are to each
individual change) and here is the patch set to go with those.

I added my own signoff to each commit, but I've left jshargo@ as the
author of all the commits he wrote.  I'm sure there is still more to
address and the ICT tests that were writtein parallel to this may also
need some additions, but I'm hoping we're in a good enough state to get
this in and iterate from there soon.

Since V3:
I've added hotplug support in the latest patch.  This has been reviewed some
and the notes from that review are addressed here as well.

Original Message:

Usage
=

After installing these patches, you can create a VKMS device with two
displays and a movable overlay like so (this is documented in the
patches):

  $ modprobe vkms enable_overlay=1 enable_cursor=1 enable_writeback=1
  $ mkdir -p /config/
  $ mount -t configfs none /config

  $ export DRM_PLANE_TYPE_PRIMARY=1
  $ export DRM_PLANE_TYPE_CURSOR=2
  $ export DRM_PLANE_TYPE_OVERLAY=0

  $ mkdir /config/vkms/test

  $ mkdir /config/vkms/test/planes/primary
  $ echo $DRM_PLANE_TYPE_PRIMARY > /config/vkms/test/planes/primary/type

  $ mkdir /config/vkms/test/planes/other_primary
  $ echo $DRM_PLANE_TYPE_PRIMARY > /config/vkms/test/planes/other_primary/type

  $ mkdir /config/vkms/test/planes/cursor
  $ echo $DRM_PLANE_TYPE_CURSOR > /config/vkms/test/planes/cursor/type

  $ mkdir /config/vkms/test/planes/overlay
  $ echo $DRM_PLANE_TYPE_OVERLAY > /config/vkms/test/planes/overlay/type

  $ mkdir /config/vkms/test/crtcs/crtc
  $ mkdir /config/vkms/test/crtcs/crtc_other
  $ mkdir /config/vkms/test/encoders/encoder
  $ mkdir /config/vkms/test/connectors/connector

  $ ln -s /config/vkms/test/encoders/encoder 
/config/vkms/test/connectors/connector/possible_encoders
  $ ln -s /config/vkms/test/crtcs/crtc 
/config/vkms/test/encoders/encoder/possible_crtcs/
  $ ln -s /config/vkms/test/crtcs/crtc 
/config/vkms/test/planes/primary/possible_crtcs/
  $ ln -s /config/vkms/test/crtcs/crtc 
/config/vkms/test/planes/cursor/possible_crtcs/
  $ ln -s /config/vkms/test/crtcs/crtc 
/config/vkms/test/planes/overlay/possible_crtcs/
  $ ln -s /config/vkms/test/crtcs/crtc_other 
/config/vkms/test/planes/overlay/possible_crtcs/
  $ ln -s /config/vkms/test/crtcs/crtc_other 
/config/vkms/test/planes/other_primary/possible_crtcs/

  $ echo 1 > /config/vkms/test/enabled

Changes within core VKMS


This introduces a few important changes to the overall structure of
VKMS:

  - Devices are now memory managed!
  - Support for multiple CRTCs and other objects has been added

Since v1


  - Added DRMM memory management to automatically clean up resources
  - Added a param to disable the default device
  - Renamed "cards" to "devices" to improve legibility
  - Added a lock for the configfs setup handler
  - Moved all the new docs into the relevant .c file
  - Addressed as many of s...@poorly.run as possible

Testing
===

  - New IGT tests (see
gitlab.freedesktop.org/jshargo/igt-gpu-tools/-/merge_requests/1)
  - Existing IGT tests (excluding .*suspend.*, including .*kms_flip.*
.*kms_writeback.* .*kms_cursor_crc.*, .*kms_plane.*)

Outro
=

I'm excited to share these changes, it's my still my first kernel patch
and I've been putting a lot of love into these.




[PATCH v3 1/7] drm/vkms: Back VKMS with DRM memory management instead of static objects

2023-08-18 Thread Brandon Pollack
From: Jim Shargo 

This is a small refactor to make ConfigFS support easier. Once we
support ConfigFS, there can be multiple devices instantiated by the
driver, and so moving everything into managed memory makes things much
easier.

This should be a no-op refactor.

Signed-off-by: Jim Shargo 
Signed-off-by: Brandon Pollack 
---
 drivers/gpu/drm/vkms/vkms_drv.c| 128 +++--
 drivers/gpu/drm/vkms/vkms_drv.h|   4 +-
 drivers/gpu/drm/vkms/vkms_output.c |   6 +-
 3 files changed, 71 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index dd0af086e7fa..387c832f5dc9 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -9,10 +9,12 @@
  * the GPU in DRM API tests.
  */
 
+#include 
 #include 
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -37,8 +39,6 @@
 #define DRIVER_MAJOR   1
 #define DRIVER_MINOR   0
 
-static struct vkms_config *default_config;
-
 static bool enable_cursor = true;
 module_param_named(enable_cursor, enable_cursor, bool, 0444);
 MODULE_PARM_DESC(enable_cursor, "Enable/Disable cursor support");
@@ -96,9 +96,9 @@ static int vkms_config_show(struct seq_file *m, void *data)
struct drm_device *dev = entry->dev;
struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev);
 
-   seq_printf(m, "writeback=%d\n", vkmsdev->config->writeback);
-   seq_printf(m, "cursor=%d\n", vkmsdev->config->cursor);
-   seq_printf(m, "overlay=%d\n", vkmsdev->config->overlay);
+   seq_printf(m, "writeback=%d\n", vkmsdev->config.writeback);
+   seq_printf(m, "cursor=%d\n", vkmsdev->config.cursor);
+   seq_printf(m, "overlay=%d\n", vkmsdev->config.overlay);
 
return 0;
 }
@@ -166,121 +166,127 @@ static int vkms_modeset_init(struct vkms_device 
*vkmsdev)
dev->mode_config.cursor_height = 512;
/* FIXME: There's a confusion between bpp and depth between this and
 * fbdev helpers. We have to go with 0, meaning "pick the default",
-* which ix XRGB in all cases. */
+* which ix XRGB in all cases.
+*/
dev->mode_config.preferred_depth = 0;
dev->mode_config.helper_private = &vkms_mode_config_helpers;
 
return vkms_output_init(vkmsdev, 0);
 }
 
-static int vkms_create(struct vkms_config *config)
+static int vkms_platform_probe(struct platform_device *pdev)
 {
int ret;
-   struct platform_device *pdev;
struct vkms_device *vkms_device;
+   void *grp;
 
-   pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
-   if (IS_ERR(pdev))
-   return PTR_ERR(pdev);
-
-   if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) {
-   ret = -ENOMEM;
-   goto out_unregister;
-   }
+   grp = devres_open_group(&pdev->dev, NULL, GFP_KERNEL);
+   if (!grp)
+   return -ENOMEM;
 
vkms_device = devm_drm_dev_alloc(&pdev->dev, &vkms_driver,
 struct vkms_device, drm);
if (IS_ERR(vkms_device)) {
ret = PTR_ERR(vkms_device);
-   goto out_devres;
+   goto out_release_group;
}
+
vkms_device->platform = pdev;
-   vkms_device->config = config;
-   config->dev = vkms_device;
+   vkms_device->config.cursor = enable_cursor;
+   vkms_device->config.writeback = enable_writeback;
+   vkms_device->config.overlay = enable_overlay;
 
ret = dma_coerce_mask_and_coherent(vkms_device->drm.dev,
   DMA_BIT_MASK(64));
-
if (ret) {
DRM_ERROR("Could not initialize DMA support\n");
-   goto out_devres;
+   goto out_release_group;
}
 
ret = drm_vblank_init(&vkms_device->drm, 1);
if (ret) {
DRM_ERROR("Failed to vblank\n");
-   goto out_devres;
+   goto out_release_group;
}
 
ret = vkms_modeset_init(vkms_device);
-   if (ret)
-   goto out_devres;
+   if (ret) {
+   DRM_ERROR("Unable to initialize modesetting\n");
+   goto out_release_group;
+   }
 
drm_debugfs_add_files(&vkms_device->drm, vkms_config_debugfs_list,
  ARRAY_SIZE(vkms_config_debugfs_list));
 
ret = drm_dev_register(&vkms_device->drm, 0);
-   if (ret)
-   goto out_devres;
+   if (ret) {
+   DRM_ERROR("Unable to register device with id %d\n", pdev->id);
+   goto out_release_group;
+   }
 
drm_fbdev_generic_setup(&vkms_device->drm, 0);
+   platform_set_drvdata(pdev, vkms_device);
+   devres_close_group(&pdev->dev, grp);
 
return 0;
 
-out_devres:
-   devres_release_group(&pdev->dev, NULL);
-out_unregister:
-   platform_device_unregister(pdev);
+out_release_group:
+   devres_rele

[PATCH v3 2/7] drm/vkms: Support multiple DRM objects (crtcs, etc.) per VKMS device

2023-08-18 Thread Brandon Pollack
From: Jim Shargo 

This change supports multiple CRTCs, encoders, connectors instead of one
of each per device.

Since ConfigFS-based devices will support multiple crtcs, it's useful to
move all of the writeback/composition data from being per-"output" to
being per-CRTC.

Since there's still only ever one CRTC, this should be a no-op refactor.

Signed-off-by: Jim Shargo 
Signed-off-by: Brandon Pollack 
---
 drivers/gpu/drm/vkms/vkms_composer.c  |  30 +++
 drivers/gpu/drm/vkms/vkms_crtc.c  | 101 -
 drivers/gpu/drm/vkms/vkms_drv.c   |  12 +--
 drivers/gpu/drm/vkms/vkms_drv.h   |  70 +--
 drivers/gpu/drm/vkms/vkms_output.c| 122 ++
 drivers/gpu/drm/vkms/vkms_plane.c |  38 ++--
 drivers/gpu/drm/vkms/vkms_writeback.c |  33 +++
 7 files changed, 259 insertions(+), 147 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
b/drivers/gpu/drm/vkms/vkms_composer.c
index d5d4f642d367..a59eb75a21c4 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -300,13 +300,13 @@ void vkms_composer_worker(struct work_struct *work)
composer_work);
struct drm_crtc *crtc = crtc_state->base.crtc;
struct vkms_writeback_job *active_wb = crtc_state->active_writeback;
-   struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
+   struct vkms_crtc *vkms_crtc = drm_crtc_to_vkms_crtc(crtc);
bool crc_pending, wb_pending;
u64 frame_start, frame_end;
u32 crc32 = 0;
int ret;
 
-   spin_lock_irq(&out->composer_lock);
+   spin_lock_irq(&vkms_crtc->composer_lock);
frame_start = crtc_state->frame_start;
frame_end = crtc_state->frame_end;
crc_pending = crtc_state->crc_pending;
@@ -330,7 +330,7 @@ void vkms_composer_worker(struct work_struct *work)
crtc_state->gamma_lut.base = NULL;
}
 
-   spin_unlock_irq(&out->composer_lock);
+   spin_unlock_irq(&vkms_crtc->composer_lock);
 
/*
 * We raced with the vblank hrtimer and previous work already computed
@@ -348,10 +348,10 @@ void vkms_composer_worker(struct work_struct *work)
return;
 
if (wb_pending) {
-   drm_writeback_signal_completion(&out->wb_connector, 0);
-   spin_lock_irq(&out->composer_lock);
+   drm_writeback_signal_completion(&vkms_crtc->wb_connector, 0);
+   spin_lock_irq(&vkms_crtc->composer_lock);
crtc_state->wb_pending = false;
-   spin_unlock_irq(&out->composer_lock);
+   spin_unlock_irq(&vkms_crtc->composer_lock);
}
 
/*
@@ -401,30 +401,30 @@ int vkms_verify_crc_source(struct drm_crtc *crtc, const 
char *src_name,
return 0;
 }
 
-void vkms_set_composer(struct vkms_output *out, bool enabled)
+void vkms_set_composer(struct vkms_crtc *vkms_crtc, bool enabled)
 {
bool old_enabled;
 
if (enabled)
-   drm_crtc_vblank_get(&out->crtc);
+   drm_crtc_vblank_get(&vkms_crtc->base);
 
-   mutex_lock(&out->enabled_lock);
-   old_enabled = out->composer_enabled;
-   out->composer_enabled = enabled;
+   mutex_lock(&vkms_crtc->enabled_lock);
+   old_enabled = vkms_crtc->composer_enabled;
+   vkms_crtc->composer_enabled = enabled;
 
/* the composition wasn't enabled, so unlock the lock to make sure the 
lock
 * will be balanced even if we have a failed commit
 */
-   if (!out->composer_enabled)
-   mutex_unlock(&out->enabled_lock);
+   if (!vkms_crtc->composer_enabled)
+   mutex_unlock(&vkms_crtc->enabled_lock);
 
if (old_enabled)
-   drm_crtc_vblank_put(&out->crtc);
+   drm_crtc_vblank_put(&vkms_crtc->base);
 }
 
 int vkms_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 {
-   struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
+   struct vkms_crtc *out = drm_crtc_to_vkms_crtc(crtc);
bool enabled = false;
int ret = 0;
 
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index 3c5ebf106b66..f10a5ec8111d 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 
+#include "linux/mutex.h"
 #include 
 
 #include 
@@ -11,27 +12,27 @@
 
 static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
 {
-   struct vkms_output *output = container_of(timer, struct vkms_output,
- vblank_hrtimer);
-   struct drm_crtc *crtc = &output->crtc;
+   struct vkms_crtc *vkms_crtc = timer_to_vkms_crtc(timer);
+   struct drm_crtc *crtc = &vkms_crtc->base;
struct vkms_crtc_state *state;
u64 ret_overrun;
bool ret, fence_cookie, composer_enabled;
 
fence_cookie = dma_fence

[PATCH v3 3/7] drm/vkms: Provide platform data when creating VKMS devices

2023-08-18 Thread Brandon Pollack
From: Jim Shargo 

This is a small refactor to make ConfigFS support easier. This should be
a no-op refactor.

Signed-off-by: Jim Shargo 
Signed-off-by: Brandon Pollack 
---
 drivers/gpu/drm/vkms/vkms_drv.c| 14 --
 drivers/gpu/drm/vkms/vkms_drv.h|  9 ++---
 drivers/gpu/drm/vkms/vkms_output.c |  2 +-
 3 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index 65b1e2c52106..6c94c2b5d529 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -9,6 +9,7 @@
  * the GPU in DRM API tests.
  */
 
+#include "asm-generic/errno-base.h"
 #include 
 #include 
 #include 
@@ -171,12 +172,14 @@ static int vkms_modeset_init(struct vkms_device *vkmsdev)
dev->mode_config.preferred_depth = 0;
dev->mode_config.helper_private = &vkms_mode_config_helpers;
 
-   return vkms_output_init(vkmsdev, 0);
+   return vkmsdev->is_default ? vkms_output_init_default(vkmsdev) :
+-EINVAL;
 }
 
 static int vkms_platform_probe(struct platform_device *pdev)
 {
int ret;
+   struct vkms_device_setup *vkms_device_setup = pdev->dev.platform_data;
struct vkms_device *vkms_device;
void *grp;
 
@@ -195,6 +198,7 @@ static int vkms_platform_probe(struct platform_device *pdev)
vkms_device->config.cursor = enable_cursor;
vkms_device->config.writeback = enable_writeback;
vkms_device->config.overlay = enable_overlay;
+   vkms_device->is_default = vkms_device_setup->is_default;
 
ret = dma_coerce_mask_and_coherent(vkms_device->drm.dev,
   DMA_BIT_MASK(64));
@@ -258,6 +262,9 @@ static int __init vkms_init(void)
 {
int ret;
struct platform_device *pdev;
+   struct vkms_device_setup vkms_device_setup = {
+   .is_default = true,
+   };
 
ret = platform_driver_register(&vkms_platform_driver);
if (ret) {
@@ -265,8 +272,11 @@ static int __init vkms_init(void)
return ret;
}
 
-   pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
+   pdev = platform_device_register_data(NULL, DRIVER_NAME, 0,
+&vkms_device_setup,
+sizeof(vkms_device_setup));
if (IS_ERR(pdev)) {
+   DRM_ERROR("Unable to register default vkms device\n");
platform_driver_unregister(&vkms_platform_driver);
return PTR_ERR(pdev);
}
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 761cd809617e..4262dcffd7e1 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -132,17 +132,20 @@ struct vkms_output {
struct vkms_plane planes[VKMS_MAX_PLANES];
 };
 
-struct vkms_device;
-
 struct vkms_config {
bool writeback;
bool cursor;
bool overlay;
 };
 
+struct vkms_device_setup {
+   bool is_default;
+};
+
 struct vkms_device {
struct drm_device drm;
struct platform_device *platform;
+   bool is_default;
struct vkms_output output;
struct vkms_config config;
 };
@@ -166,7 +169,7 @@ struct vkms_crtc *vkms_crtc_init(struct vkms_device 
*vkmsdev,
 struct drm_plane *primary,
 struct drm_plane *cursor);
 
-int vkms_output_init(struct vkms_device *vkmsdev, int index);
+int vkms_output_init_default(struct vkms_device *vkmsdev);
 
 struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
   enum drm_plane_type type);
diff --git a/drivers/gpu/drm/vkms/vkms_output.c 
b/drivers/gpu/drm/vkms/vkms_output.c
index 86faf94f7408..bfc2e2362c6d 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -80,7 +80,7 @@ static struct drm_encoder *vkms_encoder_init(struct 
vkms_device *vkms_device)
return encoder;
 }
 
-int vkms_output_init(struct vkms_device *vkmsdev, int index)
+int vkms_output_init_default(struct vkms_device *vkmsdev)
 {
struct vkms_output *output = &vkmsdev->output;
struct drm_device *dev = &vkmsdev->drm;
-- 
2.42.0.rc1.204.g551eb34607-goog



[PATCH v3 4/7] drm/vkms: Add ConfigFS scaffolding to VKMS

2023-08-18 Thread Brandon Pollack
From: Jim Shargo 

This change adds the basic scaffolding for ConfigFS, including setting
up the default directories. It does not allow for the registration of
configfs-backed devices, which is complex and provided in a follow-up
commit.

This CL includes docs about using ConfigFS with VKMS, but I'll summarize
in brief here as well (assuming ConfigFS is mounted at /config/):

To create a new device, you can do so via `mkdir
/config/vkms/my-device`.

This will create a number of directories and files automatically:

/config
`-- vkms
`-- my-device
|-- connectors
|-- crtcs
|-- encoders
|-- planes
`-- enabled

You can then configure objects by mkdir'ing in each of the directories.

When you're satisfied, you can `echo 1 > /config/vkms/my-device/enabled`.
This will create a new device according to your configuration.

For now, this will fail, but the next change will add support for it.

Signed-off-by: Jim Shargo 
Signed-off-by: Brandon Pollack 
---
 Documentation/gpu/vkms.rst   |  18 +-
 drivers/gpu/drm/Kconfig  |   1 +
 drivers/gpu/drm/vkms/Makefile|   1 +
 drivers/gpu/drm/vkms/vkms_configfs.c | 651 +++
 drivers/gpu/drm/vkms/vkms_drv.c  |  56 ++-
 drivers/gpu/drm/vkms/vkms_drv.h  |  92 +++-
 drivers/gpu/drm/vkms/vkms_output.c   |   5 +
 7 files changed, 807 insertions(+), 17 deletions(-)
 create mode 100644 drivers/gpu/drm/vkms/vkms_configfs.c

diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index ba04ac7c2167..c3875bf66dba 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -51,6 +51,12 @@ To disable the driver, use ::
 
   sudo modprobe -r vkms
 
+Configuration With ConfigFS
+===
+
+.. kernel-doc:: drivers/gpu/drm/vkms/vkms_configfs.c
+   :doc: ConfigFS Support for VKMS
+
 Testing With IGT
 
 
@@ -135,22 +141,16 @@ project.
 Runtime Configuration
 -
 
-We want to be able to reconfigure vkms instance without having to reload the
-module. Use/Test-cases:
+We want to be able to manipulate vkms instances without having to reload the
+module. Such configuration can be added as extensions to vkms's ConfigFS
+support. Use-cases:
 
 - Hotplug/hotremove connectors on the fly (to be able to test DP MST handling
   of compositors).
 
-- Configure planes/crtcs/connectors (we'd need some code to have more than 1 of
-  them first).
-
 - Change output configuration: Plug/unplug screens, change EDID, allow changing
   the refresh rate.
 
-The currently proposed solution is to expose vkms configuration through
-configfs. All existing module options should be supported through configfs
-too.
-
 Writeback support
 -
 
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index ab9ef1c20349..e39ee0e8ca06 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -284,6 +284,7 @@ config DRM_VKMS
depends on DRM && MMU
select DRM_KMS_HELPER
select DRM_GEM_SHMEM_HELPER
+   select CONFIGFS_FS
select CRC32
default n
help
diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile
index 1b28a6a32948..6b83907ad554 100644
--- a/drivers/gpu/drm/vkms/Makefile
+++ b/drivers/gpu/drm/vkms/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 vkms-y := \
+   vkms_configfs.o \
vkms_drv.o \
vkms_plane.o \
vkms_output.o \
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c 
b/drivers/gpu/drm/vkms/vkms_configfs.c
new file mode 100644
index ..72723427a1ac
--- /dev/null
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -0,0 +1,651 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "vkms_drv.h"
+
+/**
+ * DOC: ConfigFS Support for VKMS
+ *
+ * VKMS is instrumented with support for configuration via :doc:`ConfigFS
+ * <../filesystems/configfs>`.
+ *
+ * With VKMS installed, you can mount ConfigFS at ``/config/`` like so::
+ *
+ *   mkdir -p /config/
+ *   sudo mount -t configfs none /config
+ *
+ * This allows you to configure multiple virtual devices. Note
+ * that the default device which can be enabled in the module params with::
+ *
+ *  modprobe vkms default_device=1
+ *
+ * is immutable because we cannot pre-populate ConfigFS directories with normal
+ * files.
+ *
+ * To set up a new device, create a new directory under the VKMS configfs
+ * directory::
+ *
+ *   mkdir /config/vkms/test
+ *
+ * With your device created you'll find an new directory ready to be
+ * configured::
+ *
+ *   /config
+ *   `-- vkms
+ *   `-- test
+ *   |-- connectors
+ *   |-- crtcs
+ *   |-- encoders
+ *   |-- planes
+ *   `-- enabled
+ *
+ * Each directory you add within the connectors, crtcs, encoders, and planes
+ * directories will let you conf

[PATCH v3 5/7] drm/vkms: Support enabling ConfigFS devices

2023-08-18 Thread Brandon Pollack
From: Jim Shargo 

VKMS now supports creating and using virtual devices!

In addition to the enabling logic, this commit also prevents users from
adding new objects once a card is registered.

Signed-off-by: Jim Shargo 
Signed-off-by: Brandon Pollack 
---
 drivers/gpu/drm/vkms/vkms_configfs.c |  37 +++--
 drivers/gpu/drm/vkms/vkms_crtc.c |   4 +-
 drivers/gpu/drm/vkms/vkms_drv.c  |   1 +
 drivers/gpu/drm/vkms/vkms_drv.h  |   2 +-
 drivers/gpu/drm/vkms/vkms_output.c   | 208 ++-
 5 files changed, 204 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c 
b/drivers/gpu/drm/vkms/vkms_configfs.c
index 72723427a1ac..d9c48ab3d760 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -509,29 +509,40 @@ static ssize_t device_enabled_store(struct config_item 
*item, const char *buf,
 {
struct vkms_configfs *configfs = item_to_configfs(item);
struct vkms_device *device;
-   int value, ret;
+   int enabled, ret;
 
-   ret = kstrtoint(buf, 0, &value);
+   ret = kstrtoint(buf, 0, &enabled);
if (ret)
return ret;
 
-   if (value != 1)
-   return -EINVAL;
-
-   mutex_lock(&configfs->lock);
-
-   if (configfs->vkms_device) {
+   if (enabled == 0) {
+   mutex_lock(&configfs->lock);
+   if (configfs->vkms_device) {
+   vkms_remove_device(configfs->vkms_device);
+   configfs->vkms_device = NULL;
+   }
mutex_unlock(&configfs->lock);
+
return len;
}
 
-   device = vkms_add_device(configfs);
-   mutex_unlock(&configfs->lock);
+   if (enabled == 1) {
+   mutex_lock(&configfs->lock);
+   if (!configfs->vkms_device) {
+   device = vkms_add_device(configfs);
+   if (IS_ERR(device)) {
+   mutex_unlock(&configfs->lock);
+   return -PTR_ERR(device);
+   }
+
+   configfs->vkms_device = device;
+   }
+   mutex_unlock(&configfs->lock);
 
-   if (IS_ERR(device))
-   return -PTR_ERR(device);
+   return len;
+   }
 
-   return len;
+   return -EINVAL;
 }
 
 CONFIGFS_ATTR(device_, enabled);
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index f10a5ec8111d..a9ed02eea1e4 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -280,7 +280,7 @@ static const struct drm_crtc_helper_funcs 
vkms_crtc_helper_funcs = {
 
 struct vkms_crtc *vkms_crtc_init(struct vkms_device *vkmsdev,
 struct drm_plane *primary,
-struct drm_plane *cursor)
+struct drm_plane *cursor, const char *name)
 {
struct drm_device *dev = &vkmsdev->drm;
struct vkms_crtc *vkms_crtc;
@@ -292,7 +292,7 @@ struct vkms_crtc *vkms_crtc_init(struct vkms_device 
*vkmsdev,
vkms_crtc = &vkmsdev->output.crtcs[vkmsdev->output.num_crtcs++];
 
ret = drmm_crtc_init_with_planes(dev, &vkms_crtc->base, primary, cursor,
-&vkms_crtc_funcs, NULL);
+&vkms_crtc_funcs, name);
if (ret) {
DRM_ERROR("Failed to init CRTC\n");
goto out_error;
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index 819e880a8cf7..6e7f20681890 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -275,6 +275,7 @@ struct vkms_device *vkms_add_device(struct vkms_configfs 
*configfs)
dev, &vkms_platform_driver.driver))) {
pdev = to_platform_device(dev);
max_id = max(max_id, pdev->id);
+   put_device(dev);
}
 
pdev = platform_device_register_data(NULL, DRIVER_NAME, max_id + 1,
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 8cdd7949f661..9f1465b06055 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -250,7 +250,7 @@ void vkms_remove_device(struct vkms_device *vkms_device);
 /* CRTC */
 struct vkms_crtc *vkms_crtc_init(struct vkms_device *vkmsdev,
 struct drm_plane *primary,
-struct drm_plane *cursor);
+struct drm_plane *cursor, const char *name);
 
 int vkms_output_init(struct vkms_device *vkmsdev);
 int vkms_output_init_default(struct vkms_device *vkmsdev);
diff --git a/drivers/gpu/drm/vkms/vkms_output.c 
b/drivers/gpu/drm/vkms/vkms_output.c
index dc69959c5e1d..512f147d41b8 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -2,8 +2,10 @@
 
 #includ

[PATCH v3 6/7] drm/vkms: Add a module param to enable/disable the default device

2023-08-18 Thread Brandon Pollack
From: Jim Shargo 

In many testing circumstances, we will want to just create a new device
and test against that. If we create a default device, it can be annoying
to have to manually select the new device instead of choosing the only
one that exists.

The param, enable_default, is defaulted to true to maintain backwards
compatibility.

Signed-off-by: Jim Shargo 
Signed-off-by: Brandon Pollack 
---
 drivers/gpu/drm/vkms/vkms_drv.c | 45 ++---
 1 file changed, 30 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index 6e7f20681890..293bebf8e8ce 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -42,17 +42,26 @@
 #define DRIVER_MAJOR   1
 #define DRIVER_MINOR   0
 
+static bool enable_default_device = true;
+module_param_named(enable_default_device, enable_default_device, bool, 0444);
+MODULE_PARM_DESC(enable_default_device,
+"Enable/Disable creating the default device");
+
 static bool enable_cursor = true;
 module_param_named(enable_cursor, enable_cursor, bool, 0444);
-MODULE_PARM_DESC(enable_cursor, "Enable/Disable cursor support");
+MODULE_PARM_DESC(enable_cursor,
+"Enable/Disable cursor support for the default device");
 
 static bool enable_writeback = true;
 module_param_named(enable_writeback, enable_writeback, bool, 0444);
-MODULE_PARM_DESC(enable_writeback, "Enable/Disable writeback connector 
support");
+MODULE_PARM_DESC(
+   enable_writeback,
+   "Enable/Disable writeback connector support for the default device");
 
 static bool enable_overlay;
 module_param_named(enable_overlay, enable_overlay, bool, 0444);
-MODULE_PARM_DESC(enable_overlay, "Enable/Disable overlay support");
+MODULE_PARM_DESC(enable_overlay,
+"Enable/Disable overlay support for the default device");
 
 DEFINE_DRM_GEM_FOPS(vkms_driver_fops);
 
@@ -99,6 +108,7 @@ static int vkms_config_show(struct seq_file *m, void *data)
struct drm_device *dev = entry->dev;
struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev);
 
+   seq_printf(m, "default_device=%d\n", enable_default_device);
seq_printf(m, "writeback=%d\n", vkmsdev->config.writeback);
seq_printf(m, "cursor=%d\n", vkmsdev->config.cursor);
seq_printf(m, "overlay=%d\n", vkmsdev->config.overlay);
@@ -297,10 +307,7 @@ void vkms_remove_device(struct vkms_device *vkms_device)
 static int __init vkms_init(void)
 {
int ret;
-   struct platform_device *pdev;
-   struct vkms_device_setup vkms_device_setup = {
-   .configfs = NULL,
-   };
+   struct platform_device *default_pdev = NULL;
 
ret = platform_driver_register(&vkms_platform_driver);
if (ret) {
@@ -308,19 +315,27 @@ static int __init vkms_init(void)
return ret;
}
 
-   pdev = platform_device_register_data(NULL, DRIVER_NAME, 0,
-&vkms_device_setup,
-sizeof(vkms_device_setup));
-   if (IS_ERR(pdev)) {
-   DRM_ERROR("Unable to register default vkms device\n");
-   platform_driver_unregister(&vkms_platform_driver);
-   return PTR_ERR(pdev);
+   if (enable_default_device) {
+   struct vkms_device_setup vkms_device_setup = {
+   .configfs = NULL,
+   };
+
+   default_pdev = platform_device_register_data(
+   NULL, DRIVER_NAME, 0, &vkms_device_setup,
+   sizeof(vkms_device_setup));
+   if (IS_ERR(default_pdev)) {
+   DRM_ERROR("Unable to register default vkms device\n");
+   platform_driver_unregister(&vkms_platform_driver);
+   return PTR_ERR(default_pdev);
+   }
}
 
ret = vkms_init_configfs();
if (ret) {
DRM_ERROR("Unable to initialize configfs\n");
-   platform_device_unregister(pdev);
+   if (default_pdev)
+   platform_device_unregister(default_pdev);
+
platform_driver_unregister(&vkms_platform_driver);
}
 
-- 
2.42.0.rc1.204.g551eb34607-goog



[PATCH v3 7/7] drm/vkms Add hotplug support via configfs to VKMS.

2023-08-18 Thread Brandon Pollack
This change adds the ability to read or write a "1" or a "0" to the
newly added "connected" attribute of a connector in the vkms entry in
configfs.

A write will trigger a call to drm_kms_helper_hotplug_event, causing a
hotplug uevent.

With this we can write virtualized multidisplay tests that involve
hotplugging displays (eg recompositing windows when a monitor is turned
off).

Signed-off-by: Brandon Pollack 
---
 Documentation/gpu/vkms.rst   |  2 +-
 drivers/gpu/drm/vkms/vkms_configfs.c | 68 ++--
 drivers/gpu/drm/vkms/vkms_drv.h  | 11 +
 drivers/gpu/drm/vkms/vkms_output.c   | 47 ++-
 4 files changed, 123 insertions(+), 5 deletions(-)

diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index c3875bf66dba..7f715097539c 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -145,7 +145,7 @@ We want to be able to manipulate vkms instances without 
having to reload the
 module. Such configuration can be added as extensions to vkms's ConfigFS
 support. Use-cases:
 
-- Hotplug/hotremove connectors on the fly (to be able to test DP MST handling
+- Hotremove connectors on the fly (to be able to test DP MST handling
   of compositors).
 
 - Change output configuration: Plug/unplug screens, change EDID, allow changing
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c 
b/drivers/gpu/drm/vkms/vkms_configfs.c
index d9c48ab3d760..94a78780af09 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 
+#include "drm/drm_probe_helper.h"
 #include 
 #include 
 #include 
@@ -40,6 +41,7 @@
  *   `-- vkms
  *   `-- test
  *   |-- connectors
+ *`-- connected
  *   |-- crtcs
  *   |-- encoders
  *   |-- planes
@@ -92,6 +94,14 @@
  *
  *   echo 1 > /config/vkms/test/enabled
  *
+ * By default no display is "connected" so to connect a connector you'll also
+ * have to write 1 to a connectors "connected" attribute::
+ *
+ *   echo 1 > /config/vkms/test/connectors/connector/connected
+ *
+ * One can verify that this is worked using the `modetest` utility or the
+ * equivalent for your platform.
+ *
  * When you're done with the virtual device, you can clean up the device like
  * so::
  *
@@ -237,7 +247,58 @@ static void add_possible_encoders(struct config_group 
*parent,
 
 /*  Connector item, e.g. /config/vkms/device/connectors/ID */
 
+static ssize_t connector_connected_show(struct config_item *item, char *buf)
+{
+   struct vkms_config_connector *connector =
+   item_to_config_connector(item);
+   struct vkms_configfs *configfs = connector_item_to_configfs(item);
+   bool connected = false;
+
+   mutex_lock(&configfs->lock);
+   connected = connector->connected;
+   mutex_unlock(&configfs->lock);
+
+   return sprintf(buf, "%d\n", connected);
+}
+
+static ssize_t connector_connected_store(struct config_item *item,
+const char *buf, size_t len)
+{
+   struct vkms_config_connector *connector =
+   item_to_config_connector(item);
+   struct vkms_configfs *configfs = connector_item_to_configfs(item);
+   int val, ret;
+
+   ret = kstrtouint(buf, 10, &val);
+   if (ret)
+   return ret;
+
+   if (val != 1 && val != 0)
+   return -EINVAL;
+
+   mutex_lock(&configfs->lock);
+   connector->connected = val;
+   if (!connector->connector) {
+   pr_info("VKMS Device %s is not yet enabled, connector will be 
enabled on start",
+   configfs->device_group.cg_item.ci_name);
+   }
+   mutex_unlock(&configfs->lock);
+
+   if (connector->connector)
+   drm_kms_helper_hotplug_event(connector->connector->dev);
+
+   return len;
+}
+
+CONFIGFS_ATTR(connector_, connected);
+
+static struct configfs_attribute *connector_attrs[] = {
+   &connector_attr_connected,
+   NULL,
+};
+
 static struct config_item_type connector_type = {
+   .ct_attrs = connector_attrs,
.ct_owner = THIS_MODULE,
 };
 
@@ -265,7 +326,7 @@ static ssize_t plane_type_show(struct config_item *item, 
char *buf)
plane_type = plane->type;
mutex_unlock(&configfs->lock);
 
-   return sprintf(buf, "%u", plane_type);
+   return sprintf(buf, "%u\n", plane_type);
 }
 
 static ssize_t plane_type_store(struct config_item *item, const char *buf,
@@ -320,6 +381,7 @@ static struct config_group *connectors_group_make(struct 
config_group *group,
&connector_type);
add_possible_encoders(&connector->config_group,
  &connector->possible_encoders.group);
+   connector->connected = false;
 
return &connector->config_group;
 }
@@ -501,7 +563,7 @@ static ssize_t device_enabled_show(struct config_item 
*item, char *buf)
is_enabled =

Re: Implement svm without BO concept in xe driver

2023-08-18 Thread Thomas Hellström



On 8/17/23 04:12, Zeng, Oak wrote:

-Original Message-
From: Dave Airlie 
Sent: August 16, 2023 6:52 PM
To: Felix Kuehling 
Cc: Zeng, Oak ; Christian König
; Thomas Hellström
; Brost, Matthew
; maarten.lankho...@linux.intel.com;
Vishwanathapura, Niranjana ; Welty,
Brian ; Philip Yang ; intel-
x...@lists.freedesktop.org; dri-devel@lists.freedesktop.org
Subject: Re: Implement svm without BO concept in xe driver

On Thu, 17 Aug 2023 at 08:15, Felix Kuehling  wrote:

On 2023-08-16 13:30, Zeng, Oak wrote:

I spoke with Thomas. We discussed two approaches:

1) make ttm_resource a central place for vram management functions such as

eviction, cgroup memory accounting. Both the BO-based driver and BO-less SVM
codes call into ttm_resource_alloc/free functions for vram allocation/free.

  *This way BO driver and SVM driver shares the eviction/cgroup logic, no

need to reimplment LRU eviction list in SVM driver. Cgroup logic should be in
ttm_resource layer. +Maarten.

  *ttm_resource is not a perfect match for SVM to allocate vram. It is 
still a

big overhead. The *bo* member of ttm_resource is not needed for SVM - this
might end up with invasive changes to ttm...need to look into more details

Overhead is a problem. We'd want to be able to allocate, free and evict
memory at a similar granularity as our preferred migration and page
fault granularity, which defaults to 2MB in our SVM implementation.



2) svm code allocate memory directly from drm-buddy allocator, and expose

memory eviction functions from both ttm and svm so they can evict memory
from each other. For example, expose the ttm_mem_evict_first function from
ttm side so hmm/svm code can call it; expose a similar function from svm side so
ttm can evict hmm memory.

I like this option. One thing that needs some thought with this is how
to get some semblance of fairness between the two types of clients.
Basically how to choose what to evict. And what share of the available
memory does each side get to use on average. E.g. an idle client may get
all its memory evicted while a busy client may get a bigger share of the
available memory.

I'd also like to suggest we try to write any management/generic code
in driver agnostic way as much as possible here. I don't really see
much hw difference should be influencing it.

I do worry about having effectively 2 LRUs here, you can't really have
two "leasts".

Like if we hit the shrinker paths who goes first? do we shrink one
object from each side in turn?

One way to solve this fairness problem is to create a driver agnostic 
drm_vram_mgr. Maintain a single LRU in drm_vram_mgr. Move the memory 
eviction/cgroups memory accounting logic from ttm_resource manager to 
drm_vram_mgr. Both BO-based driver and SVM driver calls to drm_vram_mgr to 
allocate/free memory.

I am not sure whether this meets the 2M allocate/free/evict granularity 
requirement Felix mentioned above. SVM can allocate 2M size blocks. But BO 
driver should be able to allocate any arbitrary sized blocks - So the eviction 
is also arbitrary size.


This is not far from what a TTM resource manager does with TTM 
resources, only made generic at the drm level, and making the "resource" 
as lean as possible. With 2M granularity this seems plausible.





Also will we have systems where we can expose system SVM but userspace
may choose to not use the fine grained SVM and use one of the older
modes, will that path get emulated on top of SVM or use the BO paths?


If by "older modes" you meant the gem_bo_create (such as xe_gem_create or 
amdgpu_gem_create), then today both amd and intel implement those interfaces using BO 
path. We don't have a plan to emulate that old mode on tope of SVM, afaict.


I think we might end up emulating "older modes" on top of SVM at some 
point, not to far out, although what immediately comes to mind would be 
eviction based on something looking like NUMA- and CGROUP aware 
shrinkers for integrated bo drivers if that turns out to be sufficient 
from a memory usage starvation POW. This is IMHO indeed something to 
start thinking about, but for the current situation trying to solve a 
mutual SVM-TTM fair eviction problem would be a reasonable scope.


Thanks,

Thomas




Thanks,
Oak


Dave.


[PATCH v3 0/7] Adds support for ConfigFS to VKMS!

2023-08-18 Thread Brandon Pollack
Since Jim is busy with other work and I'm working on some things that
rely on this, I've taken up the task of doing the iterations.  I've
addressed the comments as best I can (those replies are to each
individual change) and here is the patch set to go with those.

I added my own signoff to each commit, but I've left jshargo@ as the
author of all the commits he wrote.  I'm sure there is still more to
address and the ICT tests that were writtein parallel to this may also
need some additions, but I'm hoping we're in a good enough state to get
this in and iterate from there soon.

Since V3:

I've added hotplug support in the latest patch.  This has been reviewed some
and the notes from that review are addressed here as well.

Relevant/Utilizing work:
===
I've built a while test framework based on this as proof it functions (though
I'm sure there may be lingering bugs!).  You can check that out on
crrev.com if you are interested and need to get started yourself (but be
aware of any licensing that may differ from the kernel itself!  Make
sure you understand the license:

https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/tast-tests/LICENSE

That said, you can see the changes in review on the crrev gerrit:

https://chromium-review.googlesource.com/c/chromiumos/platform/tast-tests/+/469

Outro:
=
I really appreciate everyone's input and tolerance in getting these
changes in.  Jim's first patch series was this, and other than some
small cleanups and documentation, taking over it is also mine.

Thank you everyone :)

Original Message:
>Usage
>=
>
>After installing these patches, you can create a VKMS device with two
>displays and a movable overlay like so (this is documented in the
>patches):
>
>  $ modprobe vkms enable_overlay=1 enable_cursor=1 enable_writeback=1
>  $ mkdir -p /config/
>  $ mount -t configfs none /config
>
>  $ export DRM_PLANE_TYPE_PRIMARY=1
>  $ export DRM_PLANE_TYPE_CURSOR=2
>  $ export DRM_PLANE_TYPE_OVERLAY=0
>
>  $ mkdir /config/vkms/test
>
>  $ mkdir /config/vkms/test/planes/primary
>  $ echo $DRM_PLANE_TYPE_PRIMARY > /config/vkms/test/planes/primary/type
>
>  $ mkdir /config/vkms/test/planes/other_primary
>  $ echo $DRM_PLANE_TYPE_PRIMARY > /config/vkms/test/planes/other_primary/type
>
>  $ mkdir /config/vkms/test/planes/cursor
>  $ echo $DRM_PLANE_TYPE_CURSOR > /config/vkms/test/planes/cursor/type
>
>  $ mkdir /config/vkms/test/planes/overlay
>  $ echo $DRM_PLANE_TYPE_OVERLAY > /config/vkms/test/planes/overlay/type
>
>  $ mkdir /config/vkms/test/crtcs/crtc
>  $ mkdir /config/vkms/test/crtcs/crtc_other
>  $ mkdir /config/vkms/test/encoders/encoder
>  $ mkdir /config/vkms/test/connectors/connector
>
>  $ ln -s /config/vkms/test/encoders/encoder 
> /config/vkms/test/connectors/connector/possible_encoders
>  $ ln -s /config/vkms/test/crtcs/crtc 
> /config/vkms/test/encoders/encoder/possible_crtcs/
>  $ ln -s /config/vkms/test/crtcs/crtc 
> /config/vkms/test/planes/primary/possible_crtcs/
>  $ ln -s /config/vkms/test/crtcs/crtc 
> /config/vkms/test/planes/cursor/possible_crtcs/
>  $ ln -s /config/vkms/test/crtcs/crtc 
> /config/vkms/test/planes/overlay/possible_crtcs/
>  $ ln -s /config/vkms/test/crtcs/crtc_other 
> /config/vkms/test/planes/overlay/possible_crtcs/
>  $ ln -s /config/vkms/test/crtcs/crtc_other 
> /config/vkms/test/planes/other_primary/possible_crtcs/
>
>  $ echo 1 > /config/vkms/test/enabled
>
>Changes within core VKMS
>
>
>This introduces a few important changes to the overall structure of
>VKMS:
>
>  - Devices are now memory managed!
>  - Support for multiple CRTCs and other objects has been added
>
>Since v1
>
>
>  - Added DRMM memory management to automatically clean up resources
>  - Added a param to disable the default device
>  - Renamed "cards" to "devices" to improve legibility
>  - Added a lock for the configfs setup handler
>  - Moved all the new docs into the relevant .c file
>  - Addressed as many of s...@poorly.run as possible
>
>Testing
>===
>
>  - New IGT tests (see
>gitlab.freedesktop.org/jshargo/igt-gpu-tools/-/merge_requests/1)
>  - Existing IGT tests (excluding .*suspend.*, including .*kms_flip.*
>.*kms_writeback.* .*kms_cursor_crc.*, .*kms_plane.*)
>
>Outro
>=
>
>I'm excited to share these changes, it's my still my first kernel patch
>and I've been putting a lot of love into these.

Brandon Pollack (1):
  drm/vkms Add hotplug support via configfs to VKMS.

Jim Shargo (6):
  drm/vkms: Back VKMS with DRM memory management instead of static
objects
  drm/vkms: Support multiple DRM objects (crtcs, etc.) per VKMS device
  drm/vkms: Provide platform data when creating VKMS devices
  drm/vkms: Add ConfigFS scaffolding to VKMS
  drm/vkms: Support enabling ConfigFS devices
  drm/vkms: Add a module param to enable/disable the default device

 Documentation/gpu/vkms.rst|  20 +-
 drivers/gpu/drm/Kconfig   |   1 +
 drivers/gpu

[PATCH v3 1/7] drm/vkms: Back VKMS with DRM memory management instead of static objects

2023-08-18 Thread Brandon Pollack
From: Jim Shargo 

This is a small refactor to make ConfigFS support easier. Once we
support ConfigFS, there can be multiple devices instantiated by the
driver, and so moving everything into managed memory makes things much
easier.

This should be a no-op refactor.

Signed-off-by: Jim Shargo 
Signed-off-by: Brandon Pollack 
---
 drivers/gpu/drm/vkms/vkms_drv.c| 128 +++--
 drivers/gpu/drm/vkms/vkms_drv.h|   4 +-
 drivers/gpu/drm/vkms/vkms_output.c |   6 +-
 3 files changed, 71 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index dd0af086e7fa..387c832f5dc9 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -9,10 +9,12 @@
  * the GPU in DRM API tests.
  */
 
+#include 
 #include 
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -37,8 +39,6 @@
 #define DRIVER_MAJOR   1
 #define DRIVER_MINOR   0
 
-static struct vkms_config *default_config;
-
 static bool enable_cursor = true;
 module_param_named(enable_cursor, enable_cursor, bool, 0444);
 MODULE_PARM_DESC(enable_cursor, "Enable/Disable cursor support");
@@ -96,9 +96,9 @@ static int vkms_config_show(struct seq_file *m, void *data)
struct drm_device *dev = entry->dev;
struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev);
 
-   seq_printf(m, "writeback=%d\n", vkmsdev->config->writeback);
-   seq_printf(m, "cursor=%d\n", vkmsdev->config->cursor);
-   seq_printf(m, "overlay=%d\n", vkmsdev->config->overlay);
+   seq_printf(m, "writeback=%d\n", vkmsdev->config.writeback);
+   seq_printf(m, "cursor=%d\n", vkmsdev->config.cursor);
+   seq_printf(m, "overlay=%d\n", vkmsdev->config.overlay);
 
return 0;
 }
@@ -166,121 +166,127 @@ static int vkms_modeset_init(struct vkms_device 
*vkmsdev)
dev->mode_config.cursor_height = 512;
/* FIXME: There's a confusion between bpp and depth between this and
 * fbdev helpers. We have to go with 0, meaning "pick the default",
-* which ix XRGB in all cases. */
+* which ix XRGB in all cases.
+*/
dev->mode_config.preferred_depth = 0;
dev->mode_config.helper_private = &vkms_mode_config_helpers;
 
return vkms_output_init(vkmsdev, 0);
 }
 
-static int vkms_create(struct vkms_config *config)
+static int vkms_platform_probe(struct platform_device *pdev)
 {
int ret;
-   struct platform_device *pdev;
struct vkms_device *vkms_device;
+   void *grp;
 
-   pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
-   if (IS_ERR(pdev))
-   return PTR_ERR(pdev);
-
-   if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) {
-   ret = -ENOMEM;
-   goto out_unregister;
-   }
+   grp = devres_open_group(&pdev->dev, NULL, GFP_KERNEL);
+   if (!grp)
+   return -ENOMEM;
 
vkms_device = devm_drm_dev_alloc(&pdev->dev, &vkms_driver,
 struct vkms_device, drm);
if (IS_ERR(vkms_device)) {
ret = PTR_ERR(vkms_device);
-   goto out_devres;
+   goto out_release_group;
}
+
vkms_device->platform = pdev;
-   vkms_device->config = config;
-   config->dev = vkms_device;
+   vkms_device->config.cursor = enable_cursor;
+   vkms_device->config.writeback = enable_writeback;
+   vkms_device->config.overlay = enable_overlay;
 
ret = dma_coerce_mask_and_coherent(vkms_device->drm.dev,
   DMA_BIT_MASK(64));
-
if (ret) {
DRM_ERROR("Could not initialize DMA support\n");
-   goto out_devres;
+   goto out_release_group;
}
 
ret = drm_vblank_init(&vkms_device->drm, 1);
if (ret) {
DRM_ERROR("Failed to vblank\n");
-   goto out_devres;
+   goto out_release_group;
}
 
ret = vkms_modeset_init(vkms_device);
-   if (ret)
-   goto out_devres;
+   if (ret) {
+   DRM_ERROR("Unable to initialize modesetting\n");
+   goto out_release_group;
+   }
 
drm_debugfs_add_files(&vkms_device->drm, vkms_config_debugfs_list,
  ARRAY_SIZE(vkms_config_debugfs_list));
 
ret = drm_dev_register(&vkms_device->drm, 0);
-   if (ret)
-   goto out_devres;
+   if (ret) {
+   DRM_ERROR("Unable to register device with id %d\n", pdev->id);
+   goto out_release_group;
+   }
 
drm_fbdev_generic_setup(&vkms_device->drm, 0);
+   platform_set_drvdata(pdev, vkms_device);
+   devres_close_group(&pdev->dev, grp);
 
return 0;
 
-out_devres:
-   devres_release_group(&pdev->dev, NULL);
-out_unregister:
-   platform_device_unregister(pdev);
+out_release_group:
+   devres_rele

[PATCH v3 2/7] drm/vkms: Support multiple DRM objects (crtcs, etc.) per VKMS device

2023-08-18 Thread Brandon Pollack
From: Jim Shargo 

This change supports multiple CRTCs, encoders, connectors instead of one
of each per device.

Since ConfigFS-based devices will support multiple crtcs, it's useful to
move all of the writeback/composition data from being per-"output" to
being per-CRTC.

Since there's still only ever one CRTC, this should be a no-op refactor.

Signed-off-by: Jim Shargo 
Signed-off-by: Brandon Pollack 
---
 drivers/gpu/drm/vkms/vkms_composer.c  |  30 +++
 drivers/gpu/drm/vkms/vkms_crtc.c  | 101 -
 drivers/gpu/drm/vkms/vkms_drv.c   |  12 +--
 drivers/gpu/drm/vkms/vkms_drv.h   |  70 +--
 drivers/gpu/drm/vkms/vkms_output.c| 122 ++
 drivers/gpu/drm/vkms/vkms_plane.c |  38 ++--
 drivers/gpu/drm/vkms/vkms_writeback.c |  33 +++
 7 files changed, 259 insertions(+), 147 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
b/drivers/gpu/drm/vkms/vkms_composer.c
index d5d4f642d367..a59eb75a21c4 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -300,13 +300,13 @@ void vkms_composer_worker(struct work_struct *work)
composer_work);
struct drm_crtc *crtc = crtc_state->base.crtc;
struct vkms_writeback_job *active_wb = crtc_state->active_writeback;
-   struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
+   struct vkms_crtc *vkms_crtc = drm_crtc_to_vkms_crtc(crtc);
bool crc_pending, wb_pending;
u64 frame_start, frame_end;
u32 crc32 = 0;
int ret;
 
-   spin_lock_irq(&out->composer_lock);
+   spin_lock_irq(&vkms_crtc->composer_lock);
frame_start = crtc_state->frame_start;
frame_end = crtc_state->frame_end;
crc_pending = crtc_state->crc_pending;
@@ -330,7 +330,7 @@ void vkms_composer_worker(struct work_struct *work)
crtc_state->gamma_lut.base = NULL;
}
 
-   spin_unlock_irq(&out->composer_lock);
+   spin_unlock_irq(&vkms_crtc->composer_lock);
 
/*
 * We raced with the vblank hrtimer and previous work already computed
@@ -348,10 +348,10 @@ void vkms_composer_worker(struct work_struct *work)
return;
 
if (wb_pending) {
-   drm_writeback_signal_completion(&out->wb_connector, 0);
-   spin_lock_irq(&out->composer_lock);
+   drm_writeback_signal_completion(&vkms_crtc->wb_connector, 0);
+   spin_lock_irq(&vkms_crtc->composer_lock);
crtc_state->wb_pending = false;
-   spin_unlock_irq(&out->composer_lock);
+   spin_unlock_irq(&vkms_crtc->composer_lock);
}
 
/*
@@ -401,30 +401,30 @@ int vkms_verify_crc_source(struct drm_crtc *crtc, const 
char *src_name,
return 0;
 }
 
-void vkms_set_composer(struct vkms_output *out, bool enabled)
+void vkms_set_composer(struct vkms_crtc *vkms_crtc, bool enabled)
 {
bool old_enabled;
 
if (enabled)
-   drm_crtc_vblank_get(&out->crtc);
+   drm_crtc_vblank_get(&vkms_crtc->base);
 
-   mutex_lock(&out->enabled_lock);
-   old_enabled = out->composer_enabled;
-   out->composer_enabled = enabled;
+   mutex_lock(&vkms_crtc->enabled_lock);
+   old_enabled = vkms_crtc->composer_enabled;
+   vkms_crtc->composer_enabled = enabled;
 
/* the composition wasn't enabled, so unlock the lock to make sure the 
lock
 * will be balanced even if we have a failed commit
 */
-   if (!out->composer_enabled)
-   mutex_unlock(&out->enabled_lock);
+   if (!vkms_crtc->composer_enabled)
+   mutex_unlock(&vkms_crtc->enabled_lock);
 
if (old_enabled)
-   drm_crtc_vblank_put(&out->crtc);
+   drm_crtc_vblank_put(&vkms_crtc->base);
 }
 
 int vkms_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 {
-   struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
+   struct vkms_crtc *out = drm_crtc_to_vkms_crtc(crtc);
bool enabled = false;
int ret = 0;
 
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index 3c5ebf106b66..f10a5ec8111d 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 
+#include "linux/mutex.h"
 #include 
 
 #include 
@@ -11,27 +12,27 @@
 
 static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
 {
-   struct vkms_output *output = container_of(timer, struct vkms_output,
- vblank_hrtimer);
-   struct drm_crtc *crtc = &output->crtc;
+   struct vkms_crtc *vkms_crtc = timer_to_vkms_crtc(timer);
+   struct drm_crtc *crtc = &vkms_crtc->base;
struct vkms_crtc_state *state;
u64 ret_overrun;
bool ret, fence_cookie, composer_enabled;
 
fence_cookie = dma_fence

[PATCH v3 7/7] drm/vkms Add hotplug support via configfs to VKMS.

2023-08-18 Thread Brandon Pollack
This change adds the ability to read or write a "1" or a "0" to the
newly added "connected" attribute of a connector in the vkms entry in
configfs.

A write will trigger a call to drm_kms_helper_hotplug_event, causing a
hotplug uevent.

With this we can write virtualized multidisplay tests that involve
hotplugging displays (eg recompositing windows when a monitor is turned
off).

Signed-off-by: Brandon Pollack 
---
 Documentation/gpu/vkms.rst   |  2 +-
 drivers/gpu/drm/vkms/vkms_configfs.c | 68 ++--
 drivers/gpu/drm/vkms/vkms_drv.h  | 11 +
 drivers/gpu/drm/vkms/vkms_output.c   | 47 ++-
 4 files changed, 123 insertions(+), 5 deletions(-)

diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index c3875bf66dba..7f715097539c 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -145,7 +145,7 @@ We want to be able to manipulate vkms instances without 
having to reload the
 module. Such configuration can be added as extensions to vkms's ConfigFS
 support. Use-cases:
 
-- Hotplug/hotremove connectors on the fly (to be able to test DP MST handling
+- Hotremove connectors on the fly (to be able to test DP MST handling
   of compositors).
 
 - Change output configuration: Plug/unplug screens, change EDID, allow changing
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c 
b/drivers/gpu/drm/vkms/vkms_configfs.c
index d9c48ab3d760..94a78780af09 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 
+#include "drm/drm_probe_helper.h"
 #include 
 #include 
 #include 
@@ -40,6 +41,7 @@
  *   `-- vkms
  *   `-- test
  *   |-- connectors
+ *`-- connected
  *   |-- crtcs
  *   |-- encoders
  *   |-- planes
@@ -92,6 +94,14 @@
  *
  *   echo 1 > /config/vkms/test/enabled
  *
+ * By default no display is "connected" so to connect a connector you'll also
+ * have to write 1 to a connectors "connected" attribute::
+ *
+ *   echo 1 > /config/vkms/test/connectors/connector/connected
+ *
+ * One can verify that this is worked using the `modetest` utility or the
+ * equivalent for your platform.
+ *
  * When you're done with the virtual device, you can clean up the device like
  * so::
  *
@@ -237,7 +247,58 @@ static void add_possible_encoders(struct config_group 
*parent,
 
 /*  Connector item, e.g. /config/vkms/device/connectors/ID */
 
+static ssize_t connector_connected_show(struct config_item *item, char *buf)
+{
+   struct vkms_config_connector *connector =
+   item_to_config_connector(item);
+   struct vkms_configfs *configfs = connector_item_to_configfs(item);
+   bool connected = false;
+
+   mutex_lock(&configfs->lock);
+   connected = connector->connected;
+   mutex_unlock(&configfs->lock);
+
+   return sprintf(buf, "%d\n", connected);
+}
+
+static ssize_t connector_connected_store(struct config_item *item,
+const char *buf, size_t len)
+{
+   struct vkms_config_connector *connector =
+   item_to_config_connector(item);
+   struct vkms_configfs *configfs = connector_item_to_configfs(item);
+   int val, ret;
+
+   ret = kstrtouint(buf, 10, &val);
+   if (ret)
+   return ret;
+
+   if (val != 1 && val != 0)
+   return -EINVAL;
+
+   mutex_lock(&configfs->lock);
+   connector->connected = val;
+   if (!connector->connector) {
+   pr_info("VKMS Device %s is not yet enabled, connector will be 
enabled on start",
+   configfs->device_group.cg_item.ci_name);
+   }
+   mutex_unlock(&configfs->lock);
+
+   if (connector->connector)
+   drm_kms_helper_hotplug_event(connector->connector->dev);
+
+   return len;
+}
+
+CONFIGFS_ATTR(connector_, connected);
+
+static struct configfs_attribute *connector_attrs[] = {
+   &connector_attr_connected,
+   NULL,
+};
+
 static struct config_item_type connector_type = {
+   .ct_attrs = connector_attrs,
.ct_owner = THIS_MODULE,
 };
 
@@ -265,7 +326,7 @@ static ssize_t plane_type_show(struct config_item *item, 
char *buf)
plane_type = plane->type;
mutex_unlock(&configfs->lock);
 
-   return sprintf(buf, "%u", plane_type);
+   return sprintf(buf, "%u\n", plane_type);
 }
 
 static ssize_t plane_type_store(struct config_item *item, const char *buf,
@@ -320,6 +381,7 @@ static struct config_group *connectors_group_make(struct 
config_group *group,
&connector_type);
add_possible_encoders(&connector->config_group,
  &connector->possible_encoders.group);
+   connector->connected = false;
 
return &connector->config_group;
 }
@@ -501,7 +563,7 @@ static ssize_t device_enabled_show(struct config_item 
*item, char *buf)
is_enabled =

[PATCH v3 3/7] drm/vkms: Provide platform data when creating VKMS devices

2023-08-18 Thread Brandon Pollack
From: Jim Shargo 

This is a small refactor to make ConfigFS support easier. This should be
a no-op refactor.

Signed-off-by: Jim Shargo 
Signed-off-by: Brandon Pollack 
---
 drivers/gpu/drm/vkms/vkms_drv.c| 14 --
 drivers/gpu/drm/vkms/vkms_drv.h|  9 ++---
 drivers/gpu/drm/vkms/vkms_output.c |  2 +-
 3 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index 65b1e2c52106..6c94c2b5d529 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -9,6 +9,7 @@
  * the GPU in DRM API tests.
  */
 
+#include "asm-generic/errno-base.h"
 #include 
 #include 
 #include 
@@ -171,12 +172,14 @@ static int vkms_modeset_init(struct vkms_device *vkmsdev)
dev->mode_config.preferred_depth = 0;
dev->mode_config.helper_private = &vkms_mode_config_helpers;
 
-   return vkms_output_init(vkmsdev, 0);
+   return vkmsdev->is_default ? vkms_output_init_default(vkmsdev) :
+-EINVAL;
 }
 
 static int vkms_platform_probe(struct platform_device *pdev)
 {
int ret;
+   struct vkms_device_setup *vkms_device_setup = pdev->dev.platform_data;
struct vkms_device *vkms_device;
void *grp;
 
@@ -195,6 +198,7 @@ static int vkms_platform_probe(struct platform_device *pdev)
vkms_device->config.cursor = enable_cursor;
vkms_device->config.writeback = enable_writeback;
vkms_device->config.overlay = enable_overlay;
+   vkms_device->is_default = vkms_device_setup->is_default;
 
ret = dma_coerce_mask_and_coherent(vkms_device->drm.dev,
   DMA_BIT_MASK(64));
@@ -258,6 +262,9 @@ static int __init vkms_init(void)
 {
int ret;
struct platform_device *pdev;
+   struct vkms_device_setup vkms_device_setup = {
+   .is_default = true,
+   };
 
ret = platform_driver_register(&vkms_platform_driver);
if (ret) {
@@ -265,8 +272,11 @@ static int __init vkms_init(void)
return ret;
}
 
-   pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
+   pdev = platform_device_register_data(NULL, DRIVER_NAME, 0,
+&vkms_device_setup,
+sizeof(vkms_device_setup));
if (IS_ERR(pdev)) {
+   DRM_ERROR("Unable to register default vkms device\n");
platform_driver_unregister(&vkms_platform_driver);
return PTR_ERR(pdev);
}
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 761cd809617e..4262dcffd7e1 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -132,17 +132,20 @@ struct vkms_output {
struct vkms_plane planes[VKMS_MAX_PLANES];
 };
 
-struct vkms_device;
-
 struct vkms_config {
bool writeback;
bool cursor;
bool overlay;
 };
 
+struct vkms_device_setup {
+   bool is_default;
+};
+
 struct vkms_device {
struct drm_device drm;
struct platform_device *platform;
+   bool is_default;
struct vkms_output output;
struct vkms_config config;
 };
@@ -166,7 +169,7 @@ struct vkms_crtc *vkms_crtc_init(struct vkms_device 
*vkmsdev,
 struct drm_plane *primary,
 struct drm_plane *cursor);
 
-int vkms_output_init(struct vkms_device *vkmsdev, int index);
+int vkms_output_init_default(struct vkms_device *vkmsdev);
 
 struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
   enum drm_plane_type type);
diff --git a/drivers/gpu/drm/vkms/vkms_output.c 
b/drivers/gpu/drm/vkms/vkms_output.c
index 86faf94f7408..bfc2e2362c6d 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -80,7 +80,7 @@ static struct drm_encoder *vkms_encoder_init(struct 
vkms_device *vkms_device)
return encoder;
 }
 
-int vkms_output_init(struct vkms_device *vkmsdev, int index)
+int vkms_output_init_default(struct vkms_device *vkmsdev)
 {
struct vkms_output *output = &vkmsdev->output;
struct drm_device *dev = &vkmsdev->drm;
-- 
2.42.0.rc1.204.g551eb34607-goog



[PATCH v3 5/7] drm/vkms: Support enabling ConfigFS devices

2023-08-18 Thread Brandon Pollack
From: Jim Shargo 

VKMS now supports creating and using virtual devices!

In addition to the enabling logic, this commit also prevents users from
adding new objects once a card is registered.

Signed-off-by: Jim Shargo 
Signed-off-by: Brandon Pollack 
---
 drivers/gpu/drm/vkms/vkms_configfs.c |  37 +++--
 drivers/gpu/drm/vkms/vkms_crtc.c |   4 +-
 drivers/gpu/drm/vkms/vkms_drv.c  |   1 +
 drivers/gpu/drm/vkms/vkms_drv.h  |   2 +-
 drivers/gpu/drm/vkms/vkms_output.c   | 208 ++-
 5 files changed, 204 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c 
b/drivers/gpu/drm/vkms/vkms_configfs.c
index 72723427a1ac..d9c48ab3d760 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -509,29 +509,40 @@ static ssize_t device_enabled_store(struct config_item 
*item, const char *buf,
 {
struct vkms_configfs *configfs = item_to_configfs(item);
struct vkms_device *device;
-   int value, ret;
+   int enabled, ret;
 
-   ret = kstrtoint(buf, 0, &value);
+   ret = kstrtoint(buf, 0, &enabled);
if (ret)
return ret;
 
-   if (value != 1)
-   return -EINVAL;
-
-   mutex_lock(&configfs->lock);
-
-   if (configfs->vkms_device) {
+   if (enabled == 0) {
+   mutex_lock(&configfs->lock);
+   if (configfs->vkms_device) {
+   vkms_remove_device(configfs->vkms_device);
+   configfs->vkms_device = NULL;
+   }
mutex_unlock(&configfs->lock);
+
return len;
}
 
-   device = vkms_add_device(configfs);
-   mutex_unlock(&configfs->lock);
+   if (enabled == 1) {
+   mutex_lock(&configfs->lock);
+   if (!configfs->vkms_device) {
+   device = vkms_add_device(configfs);
+   if (IS_ERR(device)) {
+   mutex_unlock(&configfs->lock);
+   return -PTR_ERR(device);
+   }
+
+   configfs->vkms_device = device;
+   }
+   mutex_unlock(&configfs->lock);
 
-   if (IS_ERR(device))
-   return -PTR_ERR(device);
+   return len;
+   }
 
-   return len;
+   return -EINVAL;
 }
 
 CONFIGFS_ATTR(device_, enabled);
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index f10a5ec8111d..a9ed02eea1e4 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -280,7 +280,7 @@ static const struct drm_crtc_helper_funcs 
vkms_crtc_helper_funcs = {
 
 struct vkms_crtc *vkms_crtc_init(struct vkms_device *vkmsdev,
 struct drm_plane *primary,
-struct drm_plane *cursor)
+struct drm_plane *cursor, const char *name)
 {
struct drm_device *dev = &vkmsdev->drm;
struct vkms_crtc *vkms_crtc;
@@ -292,7 +292,7 @@ struct vkms_crtc *vkms_crtc_init(struct vkms_device 
*vkmsdev,
vkms_crtc = &vkmsdev->output.crtcs[vkmsdev->output.num_crtcs++];
 
ret = drmm_crtc_init_with_planes(dev, &vkms_crtc->base, primary, cursor,
-&vkms_crtc_funcs, NULL);
+&vkms_crtc_funcs, name);
if (ret) {
DRM_ERROR("Failed to init CRTC\n");
goto out_error;
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index 819e880a8cf7..6e7f20681890 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -275,6 +275,7 @@ struct vkms_device *vkms_add_device(struct vkms_configfs 
*configfs)
dev, &vkms_platform_driver.driver))) {
pdev = to_platform_device(dev);
max_id = max(max_id, pdev->id);
+   put_device(dev);
}
 
pdev = platform_device_register_data(NULL, DRIVER_NAME, max_id + 1,
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 8cdd7949f661..9f1465b06055 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -250,7 +250,7 @@ void vkms_remove_device(struct vkms_device *vkms_device);
 /* CRTC */
 struct vkms_crtc *vkms_crtc_init(struct vkms_device *vkmsdev,
 struct drm_plane *primary,
-struct drm_plane *cursor);
+struct drm_plane *cursor, const char *name);
 
 int vkms_output_init(struct vkms_device *vkmsdev);
 int vkms_output_init_default(struct vkms_device *vkmsdev);
diff --git a/drivers/gpu/drm/vkms/vkms_output.c 
b/drivers/gpu/drm/vkms/vkms_output.c
index dc69959c5e1d..512f147d41b8 100644
--- a/drivers/gpu/drm/vkms/vkms_output.c
+++ b/drivers/gpu/drm/vkms/vkms_output.c
@@ -2,8 +2,10 @@
 
 #includ

[PATCH v3 4/7] drm/vkms: Add ConfigFS scaffolding to VKMS

2023-08-18 Thread Brandon Pollack
From: Jim Shargo 

This change adds the basic scaffolding for ConfigFS, including setting
up the default directories. It does not allow for the registration of
configfs-backed devices, which is complex and provided in a follow-up
commit.

This CL includes docs about using ConfigFS with VKMS, but I'll summarize
in brief here as well (assuming ConfigFS is mounted at /config/):

To create a new device, you can do so via `mkdir
/config/vkms/my-device`.

This will create a number of directories and files automatically:

/config
`-- vkms
`-- my-device
|-- connectors
|-- crtcs
|-- encoders
|-- planes
`-- enabled

You can then configure objects by mkdir'ing in each of the directories.

When you're satisfied, you can `echo 1 > /config/vkms/my-device/enabled`.
This will create a new device according to your configuration.

For now, this will fail, but the next change will add support for it.

Signed-off-by: Jim Shargo 
Signed-off-by: Brandon Pollack 
---
 Documentation/gpu/vkms.rst   |  18 +-
 drivers/gpu/drm/Kconfig  |   1 +
 drivers/gpu/drm/vkms/Makefile|   1 +
 drivers/gpu/drm/vkms/vkms_configfs.c | 651 +++
 drivers/gpu/drm/vkms/vkms_drv.c  |  56 ++-
 drivers/gpu/drm/vkms/vkms_drv.h  |  92 +++-
 drivers/gpu/drm/vkms/vkms_output.c   |   5 +
 7 files changed, 807 insertions(+), 17 deletions(-)
 create mode 100644 drivers/gpu/drm/vkms/vkms_configfs.c

diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index ba04ac7c2167..c3875bf66dba 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -51,6 +51,12 @@ To disable the driver, use ::
 
   sudo modprobe -r vkms
 
+Configuration With ConfigFS
+===
+
+.. kernel-doc:: drivers/gpu/drm/vkms/vkms_configfs.c
+   :doc: ConfigFS Support for VKMS
+
 Testing With IGT
 
 
@@ -135,22 +141,16 @@ project.
 Runtime Configuration
 -
 
-We want to be able to reconfigure vkms instance without having to reload the
-module. Use/Test-cases:
+We want to be able to manipulate vkms instances without having to reload the
+module. Such configuration can be added as extensions to vkms's ConfigFS
+support. Use-cases:
 
 - Hotplug/hotremove connectors on the fly (to be able to test DP MST handling
   of compositors).
 
-- Configure planes/crtcs/connectors (we'd need some code to have more than 1 of
-  them first).
-
 - Change output configuration: Plug/unplug screens, change EDID, allow changing
   the refresh rate.
 
-The currently proposed solution is to expose vkms configuration through
-configfs. All existing module options should be supported through configfs
-too.
-
 Writeback support
 -
 
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index ab9ef1c20349..e39ee0e8ca06 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -284,6 +284,7 @@ config DRM_VKMS
depends on DRM && MMU
select DRM_KMS_HELPER
select DRM_GEM_SHMEM_HELPER
+   select CONFIGFS_FS
select CRC32
default n
help
diff --git a/drivers/gpu/drm/vkms/Makefile b/drivers/gpu/drm/vkms/Makefile
index 1b28a6a32948..6b83907ad554 100644
--- a/drivers/gpu/drm/vkms/Makefile
+++ b/drivers/gpu/drm/vkms/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 vkms-y := \
+   vkms_configfs.o \
vkms_drv.o \
vkms_plane.o \
vkms_output.o \
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c 
b/drivers/gpu/drm/vkms/vkms_configfs.c
new file mode 100644
index ..72723427a1ac
--- /dev/null
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -0,0 +1,651 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "vkms_drv.h"
+
+/**
+ * DOC: ConfigFS Support for VKMS
+ *
+ * VKMS is instrumented with support for configuration via :doc:`ConfigFS
+ * <../filesystems/configfs>`.
+ *
+ * With VKMS installed, you can mount ConfigFS at ``/config/`` like so::
+ *
+ *   mkdir -p /config/
+ *   sudo mount -t configfs none /config
+ *
+ * This allows you to configure multiple virtual devices. Note
+ * that the default device which can be enabled in the module params with::
+ *
+ *  modprobe vkms default_device=1
+ *
+ * is immutable because we cannot pre-populate ConfigFS directories with normal
+ * files.
+ *
+ * To set up a new device, create a new directory under the VKMS configfs
+ * directory::
+ *
+ *   mkdir /config/vkms/test
+ *
+ * With your device created you'll find an new directory ready to be
+ * configured::
+ *
+ *   /config
+ *   `-- vkms
+ *   `-- test
+ *   |-- connectors
+ *   |-- crtcs
+ *   |-- encoders
+ *   |-- planes
+ *   `-- enabled
+ *
+ * Each directory you add within the connectors, crtcs, encoders, and planes
+ * directories will let you conf

[PATCH v3 6/7] drm/vkms: Add a module param to enable/disable the default device

2023-08-18 Thread Brandon Pollack
From: Jim Shargo 

In many testing circumstances, we will want to just create a new device
and test against that. If we create a default device, it can be annoying
to have to manually select the new device instead of choosing the only
one that exists.

The param, enable_default, is defaulted to true to maintain backwards
compatibility.

Signed-off-by: Jim Shargo 
Signed-off-by: Brandon Pollack 
---
 drivers/gpu/drm/vkms/vkms_drv.c | 45 ++---
 1 file changed, 30 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index 6e7f20681890..293bebf8e8ce 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -42,17 +42,26 @@
 #define DRIVER_MAJOR   1
 #define DRIVER_MINOR   0
 
+static bool enable_default_device = true;
+module_param_named(enable_default_device, enable_default_device, bool, 0444);
+MODULE_PARM_DESC(enable_default_device,
+"Enable/Disable creating the default device");
+
 static bool enable_cursor = true;
 module_param_named(enable_cursor, enable_cursor, bool, 0444);
-MODULE_PARM_DESC(enable_cursor, "Enable/Disable cursor support");
+MODULE_PARM_DESC(enable_cursor,
+"Enable/Disable cursor support for the default device");
 
 static bool enable_writeback = true;
 module_param_named(enable_writeback, enable_writeback, bool, 0444);
-MODULE_PARM_DESC(enable_writeback, "Enable/Disable writeback connector 
support");
+MODULE_PARM_DESC(
+   enable_writeback,
+   "Enable/Disable writeback connector support for the default device");
 
 static bool enable_overlay;
 module_param_named(enable_overlay, enable_overlay, bool, 0444);
-MODULE_PARM_DESC(enable_overlay, "Enable/Disable overlay support");
+MODULE_PARM_DESC(enable_overlay,
+"Enable/Disable overlay support for the default device");
 
 DEFINE_DRM_GEM_FOPS(vkms_driver_fops);
 
@@ -99,6 +108,7 @@ static int vkms_config_show(struct seq_file *m, void *data)
struct drm_device *dev = entry->dev;
struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev);
 
+   seq_printf(m, "default_device=%d\n", enable_default_device);
seq_printf(m, "writeback=%d\n", vkmsdev->config.writeback);
seq_printf(m, "cursor=%d\n", vkmsdev->config.cursor);
seq_printf(m, "overlay=%d\n", vkmsdev->config.overlay);
@@ -297,10 +307,7 @@ void vkms_remove_device(struct vkms_device *vkms_device)
 static int __init vkms_init(void)
 {
int ret;
-   struct platform_device *pdev;
-   struct vkms_device_setup vkms_device_setup = {
-   .configfs = NULL,
-   };
+   struct platform_device *default_pdev = NULL;
 
ret = platform_driver_register(&vkms_platform_driver);
if (ret) {
@@ -308,19 +315,27 @@ static int __init vkms_init(void)
return ret;
}
 
-   pdev = platform_device_register_data(NULL, DRIVER_NAME, 0,
-&vkms_device_setup,
-sizeof(vkms_device_setup));
-   if (IS_ERR(pdev)) {
-   DRM_ERROR("Unable to register default vkms device\n");
-   platform_driver_unregister(&vkms_platform_driver);
-   return PTR_ERR(pdev);
+   if (enable_default_device) {
+   struct vkms_device_setup vkms_device_setup = {
+   .configfs = NULL,
+   };
+
+   default_pdev = platform_device_register_data(
+   NULL, DRIVER_NAME, 0, &vkms_device_setup,
+   sizeof(vkms_device_setup));
+   if (IS_ERR(default_pdev)) {
+   DRM_ERROR("Unable to register default vkms device\n");
+   platform_driver_unregister(&vkms_platform_driver);
+   return PTR_ERR(default_pdev);
+   }
}
 
ret = vkms_init_configfs();
if (ret) {
DRM_ERROR("Unable to initialize configfs\n");
-   platform_device_unregister(pdev);
+   if (default_pdev)
+   platform_device_unregister(default_pdev);
+
platform_driver_unregister(&vkms_platform_driver);
}
 
-- 
2.42.0.rc1.204.g551eb34607-goog



Re: [PATCH] drm/panel: Add prepare_prev_first flag to Visionox VTDR6130

2023-08-18 Thread neil . armstrong

Hi Dmitry,

On 17/08/2023 20:35, Dmitry Baryshkov wrote:

On 16/08/2023 10:51, neil.armstr...@linaro.org wrote:

Hi Abhinav,

On 14/08/2023 20:02, Abhinav Kumar wrote:






Sending HS commands will always work on any controller, it's all about LP 
commands.
The Samsung panels you listed only send HS commands so they can use 
prepare_prev_first
and work on any controllers.


I think there is some misunderstanding there, supported by the description of 
the flag.

If I remember correctly, some hosts (sunxi) can not send DCS commands after 
enabling video stream and switching to HS mode, see [1]. Thus, as you know, 
most of the drivers have all DSI panel setup commands in 
drm_panel_funcs::prepare() / drm_bridge_funcs::pre_enable() callbacks, not 
paying attention whether these commands are to be sent in LP or in HS mode.

Previously DSI source drivers could power on the DSI link either in mode_set() 
or in pre_enable() callbacks, with mode_set() being the hack to make 
panel/bridge drivers to be able to send commands from their prepare() / 
pre_enable() callbacks.

With the prev_first flags being introduced, we have established that DSI link 
should be enabled in DSI host's pre_enable() callback and switched to HS mode 
(be it command or video) in the enable() callback.

So far so good.


It seems coherent, I would like first to have a state of all DSI host drivers 
and make this would actually work first before adding the prev_first flag to 
all the required panels.



Unfortunately this change is not fully backwards-compatible. This requires that all DSI 
panels sending commands from prepare() should have the prepare_prev_first flag. In some 
sense, all such patches might have Fixes: 5ea6b1702781 ("drm/panel: Add 
prepare_prev_first flag to drm_panel").


This kind of migration should be done *before* any possible regression, not the 
other way round.

If all panels sending commands from prepare() should have the 
prepare_prev_first flag, then it should be first, check for regressions then 
continue.





I understand, but this patch doesn't qualify as a fix for 9e15123eca79 and is 
too late to be merged in drm-misc-next for v6.6,
and since 9e15123eca79 actually breaks some support it should be reverted (+ 
deps) since we are late in the rc cycles.


If we go this way, we can never reapply these patches. There will be no 
guarantee that all panel drivers are completely converted. We already have a 
story without an observable end - DRM_BRIDGE_ATTACH_NO_CONNECTOR.


I don't understand this point, who would block re-applying the patches ?

The migration to DRM_BRIDGE_ATTACH_NO_CONNECTOR was done over multiple Linux 
version and went smoothly because we reverted
regressing patches and restarted when needed, I don't understand why we can't 
do this here aswell.



I'd consider that the DSI driver is correct here and it is about the panel 
drivers that require fixes patches. If you care about the particular Fixes tag, 
I have provided one several lines above.


Unfortunately it should be done in the other way round, prepare for migration, 
then migrate,

I mean if it's a required migration, then it should be done and I'll support it 
from both bridge and panel PoV.

So, first this patch has the wrong Fixes tag, and I would like a better 
explanation on the commit message in any case.
Then I would like to have an ack from some drm-misc maintainers before applying 
it because it fixes a patch that
was sent via the msm tree thus per the drm-misc rules I cannot apply it via the 
drm-misc-next-fixes tree.

Neil





Re: [PATCH v2 1/2] drm/v3d: Implement show_fdinfo() callback for GPU usage stats

2023-08-18 Thread Melissa Wen
On 08/07, Maíra Canal wrote:
> This patch exposes the accumulated amount of active time per client
> through the fdinfo infrastructure. The amount of active time is exposed
> for each V3D queue: BIN, RENDER, CSD, TFU and CACHE_CLEAN.
> 
> In order to calculate the amount of active time per client, a CPU clock
> is used through the function local_clock(). The point where the jobs has
> started is marked and is finally compared with the time that the job had
> finished.
> 
> Moreover, the number of jobs submitted to each queue is also exposed on
> fdinfo through the identifier "v3d-jobs-".
> 
> Co-developed-by: Jose Maria Casanova Crespo 
> Signed-off-by: Jose Maria Casanova Crespo 
> Signed-off-by: Maíra Canal 
> ---
>  drivers/gpu/drm/v3d/v3d_drv.c   | 30 +-
>  drivers/gpu/drm/v3d/v3d_drv.h   | 23 +++
>  drivers/gpu/drm/v3d/v3d_gem.c   |  1 +
>  drivers/gpu/drm/v3d/v3d_irq.c   | 17 +
>  drivers/gpu/drm/v3d/v3d_sched.c | 24 
>  5 files changed, 94 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
> index ffbbe9d527d3..ca65c707da03 100644
> --- a/drivers/gpu/drm/v3d/v3d_drv.c
> +++ b/drivers/gpu/drm/v3d/v3d_drv.c
> @@ -19,6 +19,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  #include 
> @@ -111,6 +112,10 @@ v3d_open(struct drm_device *dev, struct drm_file *file)
>   v3d_priv->v3d = v3d;
>  
>   for (i = 0; i < V3D_MAX_QUEUES; i++) {
> + v3d_priv->enabled_ns[i] = 0;
> + v3d_priv->start_ns[i] = 0;
> + v3d_priv->jobs_sent[i] = 0;
> +
>   sched = &v3d->queue[i].sched;
>   drm_sched_entity_init(&v3d_priv->sched_entity[i],
> DRM_SCHED_PRIORITY_NORMAL, &sched,
> @@ -136,7 +141,29 @@ v3d_postclose(struct drm_device *dev, struct drm_file 
> *file)
>   kfree(v3d_priv);
>  }
>  
> -DEFINE_DRM_GEM_FOPS(v3d_drm_fops);
> +static void v3d_show_fdinfo(struct drm_printer *p, struct drm_file *file)
> +{
> + struct v3d_file_priv *file_priv = file->driver_priv;
> + u64 timestamp = local_clock();
> + enum v3d_queue queue;
> +
> + for (queue = 0; queue < V3D_MAX_QUEUES; queue++) {
> + drm_printf(p, "drm-engine-%s: \t%llu ns\n",
> +v3d_queue_to_string(queue),
> +file_priv->start_ns[queue] ? 
> file_priv->enabled_ns[queue]
> +   + timestamp - 
> file_priv->start_ns[queue]
> +   : 
> file_priv->enabled_ns[queue]);
> +
> + drm_printf(p, "v3d-jobs-%s: \t%llu jobs\n",
> +v3d_queue_to_string(queue), 
> file_priv->jobs_sent[queue]);
> + }
> +}
> +
> +static const struct file_operations v3d_drm_fops = {
> + .owner = THIS_MODULE,
> + DRM_GEM_FOPS,
> + .show_fdinfo = drm_show_fdinfo,
> +};

Dunno where, but could you document somewhere what is the expected
counting behavior in case of a GPU reset?

>  
>  /* DRM_AUTH is required on SUBMIT_CL for now, while we don't have GMP
>   * protection between clients.  Note that render nodes would be
> @@ -176,6 +203,7 @@ static const struct drm_driver v3d_drm_driver = {
>   .ioctls = v3d_drm_ioctls,
>   .num_ioctls = ARRAY_SIZE(v3d_drm_ioctls),
>   .fops = &v3d_drm_fops,
> + .show_fdinfo = v3d_show_fdinfo,
>  
>   .name = DRIVER_NAME,
>   .desc = DRIVER_DESC,
> diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h
> index 7f664a4b2a75..7f2897e5b2cb 100644
> --- a/drivers/gpu/drm/v3d/v3d_drv.h
> +++ b/drivers/gpu/drm/v3d/v3d_drv.h
> @@ -21,6 +21,18 @@ struct reset_control;
>  
>  #define V3D_MAX_QUEUES (V3D_CACHE_CLEAN + 1)
>  
> +static inline char *v3d_queue_to_string(enum v3d_queue queue)
> +{
> + switch (queue) {
> + case V3D_BIN: return "bin";
> + case V3D_RENDER: return "render";
> + case V3D_TFU: return "tfu";
> + case V3D_CSD: return "csd";
> + case V3D_CACHE_CLEAN: return "cache_clean";
> + }
> + return "UNKNOWN";
> +}
> +
>  struct v3d_queue_state {
>   struct drm_gpu_scheduler sched;
>  
> @@ -167,6 +179,12 @@ struct v3d_file_priv {
>   } perfmon;
>  
>   struct drm_sched_entity sched_entity[V3D_MAX_QUEUES];
> +
> + u64 start_ns[V3D_MAX_QUEUES];
> +
> + u64 enabled_ns[V3D_MAX_QUEUES];
> +
> + u64 jobs_sent[V3D_MAX_QUEUES];
>  };
>  
>  struct v3d_bo {
> @@ -238,6 +256,11 @@ struct v3d_job {
>*/
>   struct v3d_perfmon *perfmon;
>  
> + /* File descriptor of the process that submitted the job that could be 
> used
> +  * for collecting stats by process of GPU usage.
> +  */
> + struct drm_file *file;
> +
>   /* Callback for the freeing of the job on refcount going to 0. */
>   void (*free)(struct kref *ref);
>  };
> diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b

Re: [PATCH v2] drm: bridge: samsung-dsim: Fix init during host transfer

2023-08-18 Thread Neil Armstrong

On 24/07/2023 17:16, Frieder Schrempf wrote:

From: Frieder Schrempf 

In case the downstream bridge or panel uses DSI transfers before the
DSI host was actually initialized through samsung_dsim_atomic_enable()
which clears the stop state (LP11) mode, all transfers will fail.

This happens with downstream bridges that are controlled by DSI
commands such as the tc358762.

As documented in [1] DSI hosts are expected to allow transfers
outside the normal bridge enable/disable flow.

To fix this make sure that stop state is cleared in
samsung_dsim_host_transfer() which restores the previous
behavior.

We also factor out the common code to enable/disable stop state
to samsung_dsim_set_stop_state().

[1] https://docs.kernel.org/gpu/drm-kms-helpers.html#mipi-dsi-bridge-operation

Fixes: 0c14d3130654 ("drm: bridge: samsung-dsim: Fix i.MX8M enable flow to meet 
spec")
Reported-by: Tim Harvey 
Signed-off-by: Frieder Schrempf 
---
Changes for v2:
   * Fix reversed stop state enable/disable in samsung_dsim_set_stop_state()

Hi Tim, could you please give this patch a try and report back if
it fixes your problem? Thanks!
---
  drivers/gpu/drm/bridge/samsung-dsim.c | 27 +--
  1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
index 043b8109e64a..73ec60757dbc 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -1386,6 +1386,18 @@ static void samsung_dsim_disable_irq(struct samsung_dsim 
*dsi)
disable_irq(dsi->irq);
  }
  
+static void samsung_dsim_set_stop_state(struct samsung_dsim *dsi, bool enable)

+{
+   u32 reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);
+
+   if (enable)
+   reg |= DSIM_FORCE_STOP_STATE;
+   else
+   reg &= ~DSIM_FORCE_STOP_STATE;
+
+   samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg);
+}
+
  static int samsung_dsim_init(struct samsung_dsim *dsi)
  {
const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;
@@ -1445,15 +1457,12 @@ static void samsung_dsim_atomic_enable(struct 
drm_bridge *bridge,
   struct drm_bridge_state 
*old_bridge_state)
  {
struct samsung_dsim *dsi = bridge_to_dsi(bridge);
-   u32 reg;
  
  	if (samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) {

samsung_dsim_set_display_mode(dsi);
samsung_dsim_set_display_enable(dsi, true);
} else {
-   reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);
-   reg &= ~DSIM_FORCE_STOP_STATE;
-   samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg);
+   samsung_dsim_set_stop_state(dsi, false);
}
  
  	dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;

@@ -1463,16 +1472,12 @@ static void samsung_dsim_atomic_disable(struct 
drm_bridge *bridge,
struct drm_bridge_state 
*old_bridge_state)
  {
struct samsung_dsim *dsi = bridge_to_dsi(bridge);
-   u32 reg;
  
  	if (!(dsi->state & DSIM_STATE_ENABLED))

return;
  
-	if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) {

-   reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);
-   reg |= DSIM_FORCE_STOP_STATE;
-   samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg);
-   }
+   if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type))
+   samsung_dsim_set_stop_state(dsi, true);
  
  	dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;

  }
@@ -1775,6 +1780,8 @@ static ssize_t samsung_dsim_host_transfer(struct 
mipi_dsi_host *host,
if (ret)
return ret;
  
+	samsung_dsim_set_stop_state(dsi, false);

+
ret = mipi_dsi_create_packet(&xfer.packet, msg);
if (ret < 0)
return ret;


Reviewed-by: Neil Armstrong 


Re: [PATCH v2] drm: bridge: samsung-dsim: Fix init during host transfer

2023-08-18 Thread Neil Armstrong
Hi,

On Mon, 24 Jul 2023 17:16:32 +0200, Frieder Schrempf wrote:
> In case the downstream bridge or panel uses DSI transfers before the
> DSI host was actually initialized through samsung_dsim_atomic_enable()
> which clears the stop state (LP11) mode, all transfers will fail.
> 
> This happens with downstream bridges that are controlled by DSI
> commands such as the tc358762.
> 
> [...]

Thanks, Applied to https://anongit.freedesktop.org/git/drm/drm-misc.git 
(drm-misc-fixes)

[1/1] drm: bridge: samsung-dsim: Fix init during host transfer
  
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=20c827683de05a6c7e7ae7fae586899690693251

-- 
Neil



Re: [PATCH v2 2/2] drm/v3d: Expose the total GPU usage stats on sysfs

2023-08-18 Thread Melissa Wen
On 08/07, Maíra Canal wrote:
> The previous patch exposed the accumulated amount of active time per
> client for each V3D queue. But this doesn't provide a global notion of
> the GPU usage.
> 
> Therefore, provide the accumulated amount of active time for each V3D
> queue (BIN, RENDER, CSD, TFU and CACHE_CLEAN), considering all the jobs
> submitted to the queue, independent of the client.
> 
> This data is exposed through the sysfs interface, so that if the
> interface is queried at two different points of time the usage percentage
> of each of the queues can be calculated.
> 
> Co-developed-by: Jose Maria Casanova Crespo 
> Signed-off-by: Jose Maria Casanova Crespo 
> Signed-off-by: Maíra Canal 
> ---
>  drivers/gpu/drm/v3d/Makefile|   3 +-
>  drivers/gpu/drm/v3d/v3d_drv.c   |   9 +++
>  drivers/gpu/drm/v3d/v3d_drv.h   |   7 +++
>  drivers/gpu/drm/v3d/v3d_gem.c   |   5 +-
>  drivers/gpu/drm/v3d/v3d_irq.c   |  24 ++--
>  drivers/gpu/drm/v3d/v3d_sched.c |  13 +++-
>  drivers/gpu/drm/v3d/v3d_sysfs.c | 101 
>  7 files changed, 155 insertions(+), 7 deletions(-)
>  create mode 100644 drivers/gpu/drm/v3d/v3d_sysfs.c
> 
> diff --git a/drivers/gpu/drm/v3d/Makefile b/drivers/gpu/drm/v3d/Makefile
> index e8b314137020..4b21b20e4998 100644
> --- a/drivers/gpu/drm/v3d/Makefile
> +++ b/drivers/gpu/drm/v3d/Makefile
> @@ -11,7 +11,8 @@ v3d-y := \
>   v3d_mmu.o \
>   v3d_perfmon.o \
>   v3d_trace_points.o \
> - v3d_sched.o
> + v3d_sched.o \
> + v3d_sysfs.o
>  
>  v3d-$(CONFIG_DEBUG_FS) += v3d_debugfs.o
>  
> diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
> index ca65c707da03..7fc84a2525ca 100644
> --- a/drivers/gpu/drm/v3d/v3d_drv.c
> +++ b/drivers/gpu/drm/v3d/v3d_drv.c
> @@ -309,8 +309,14 @@ static int v3d_platform_drm_probe(struct platform_device 
> *pdev)
>   if (ret)
>   goto irq_disable;
>  
> + ret = v3d_sysfs_init(dev);
> + if (ret)
> + goto drm_unregister;
> +
>   return 0;
>  
> +drm_unregister:
> + drm_dev_unregister(drm);
>  irq_disable:
>   v3d_irq_disable(v3d);
>  gem_destroy:
> @@ -324,6 +330,9 @@ static void v3d_platform_drm_remove(struct 
> platform_device *pdev)
>  {
>   struct drm_device *drm = platform_get_drvdata(pdev);
>   struct v3d_dev *v3d = to_v3d_dev(drm);
> + struct device *dev = &pdev->dev;
> +
> + v3d_sysfs_destroy(dev);
>  
>   drm_dev_unregister(drm);
>  
> diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h
> index 7f2897e5b2cb..c8f95a91af46 100644
> --- a/drivers/gpu/drm/v3d/v3d_drv.h
> +++ b/drivers/gpu/drm/v3d/v3d_drv.h
> @@ -38,6 +38,9 @@ struct v3d_queue_state {
>  
>   u64 fence_context;
>   u64 emit_seqno;
> +
> + u64 start_ns;
> + u64 enabled_ns;
>  };
>  
>  /* Performance monitor object. The perform lifetime is controlled by 
> userspace
> @@ -441,3 +444,7 @@ int v3d_perfmon_destroy_ioctl(struct drm_device *dev, 
> void *data,
> struct drm_file *file_priv);
>  int v3d_perfmon_get_values_ioctl(struct drm_device *dev, void *data,
>struct drm_file *file_priv);
> +
> +/* v3d_sysfs.c */
> +int v3d_sysfs_init(struct device *dev);
> +void v3d_sysfs_destroy(struct device *dev);
> diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c
> index 40ed0c7c3fad..630ea2db8f8f 100644
> --- a/drivers/gpu/drm/v3d/v3d_gem.c
> +++ b/drivers/gpu/drm/v3d/v3d_gem.c
> @@ -1014,8 +1014,11 @@ v3d_gem_init(struct drm_device *dev)
>   u32 pt_size = 4096 * 1024;
>   int ret, i;
>  
> - for (i = 0; i < V3D_MAX_QUEUES; i++)
> + for (i = 0; i < V3D_MAX_QUEUES; i++) {
>   v3d->queue[i].fence_context = dma_fence_context_alloc(1);
> + v3d->queue[i].start_ns = 0;
> + v3d->queue[i].enabled_ns = 0;
> + }
>  
>   spin_lock_init(&v3d->mm_lock);
>   spin_lock_init(&v3d->job_lock);
> diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c
> index c898800ae9c2..be4ff7559309 100644
> --- a/drivers/gpu/drm/v3d/v3d_irq.c
> +++ b/drivers/gpu/drm/v3d/v3d_irq.c
> @@ -102,9 +102,13 @@ v3d_irq(int irq, void *arg)
>   struct v3d_fence *fence =
>   to_v3d_fence(v3d->bin_job->base.irq_fence);
>   struct v3d_file_priv *file = 
> v3d->bin_job->base.file->driver_priv;
> + u64 runtime = local_clock() - file->start_ns[V3D_BIN];
>  
> - file->enabled_ns[V3D_BIN] += local_clock() - 
> file->start_ns[V3D_BIN];
>   file->start_ns[V3D_BIN] = 0;
> + v3d->queue[V3D_BIN].start_ns = 0;
> +
> + file->enabled_ns[V3D_BIN] += runtime;
> + v3d->queue[V3D_BIN].enabled_ns += runtime;
>  
>   trace_v3d_bcl_irq(&v3d->drm, fence->seqno);
>   dma_fence_signal(&fence->base);
> @@ -115,9 +119,13 @@ v3d_irq(int irq, void *arg)
>   struct v3d_fence *fence =
> 

Re: [PATCH v2 0/2] drm/v3d: Expose GPU usage stats

2023-08-18 Thread Melissa Wen
On 08/07, Maíra Canal wrote:
> This patchset exposes GPU usages stats both globally and per-file
> descriptor.
> 
> The first patch exposes the accumulated amount of active time per client
> through the fdinfo infrastructure. The amount of active time is exposed
> for each V3D queue. Moreover, it exposes the number of jobs submitted to
> each queue.
> 
> The second patch exposes the accumulated amount of active time for each
> V3D queue, independent of the client. This data is exposed through the
> sysfs interface.
> 
> With these patches, it is possible to calculate the GPU usage percentage
> per queue globally and per-file descriptor.
> 
> * Example fdinfo output:
> 
> $ cat /proc/1140/fdinfo/4
> pos:0
> flags:  0242
> mnt_id: 24
> ino:209
> drm-driver: v3d
> drm-client-id:  44
> drm-engine-bin: 1661076898 ns
> v3d-jobs-bin:   19576 jobs
> drm-engine-render:  31469427170 ns
> v3d-jobs-render:19575 jobs
> drm-engine-tfu: 5002964 ns
> v3d-jobs-tfu:   13 jobs
> drm-engine-csd: 188038329691 ns
> v3d-jobs-csd:   250393 jobs
> drm-engine-cache_clean: 27736024038 ns
> v3d-jobs-cache_clean:   250392 job
> 
> * Example gputop output:
> 
> DRM minor 128
>  PID bin   render   tfucsd
> cache_clean NAME
> 1140 |▎||██▋   || 
> ||█▍   ||█▋   | computecloth
> 1158 |▍||▉ || ||  
>|| | gears
> 1002 |▏||█▎|| ||  
>|| | chromium-browse
> 

Hi Maíra,

Nice job!

Overall LGTM but I prefer to have an ack from Chema before applying it.

I left some comments regarding documentation for future users.
With this, you can add my r-b in the next version:
Reviewed-by: Melissa Wen 

Thanks,

Melissa

> Best Regards,
> - Maíra
> ---
> 
> v1 -> v2: 
> https://lore.kernel.org/dri-devel/20230727142929.1275149-1-mca...@igalia.com/T/
> 
> * Use sysfs to expose global GPU stats (Tvrtko Ursulin)
> 
> Maíra Canal (2):
>   drm/v3d: Implement show_fdinfo() callback for GPU usage stats
>   drm/v3d: Expose the total GPU usage stats on sysfs
> 
>  drivers/gpu/drm/v3d/Makefile|   3 +-
>  drivers/gpu/drm/v3d/v3d_drv.c   |  39 +++-
>  drivers/gpu/drm/v3d/v3d_drv.h   |  30 ++
>  drivers/gpu/drm/v3d/v3d_gem.c   |   6 +-
>  drivers/gpu/drm/v3d/v3d_irq.c   |  33 +++
>  drivers/gpu/drm/v3d/v3d_sched.c |  35 +++
>  drivers/gpu/drm/v3d/v3d_sysfs.c | 101 
>  7 files changed, 244 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/gpu/drm/v3d/v3d_sysfs.c
> 
> --
> 2.41.0
> 


signature.asc
Description: PGP signature


Re: [Linaro-mm-sig] [PATCH] dma-buf/sw_sync: Avoid recursive lock during fence signal

2023-08-18 Thread Christian König

Am 17.08.23 um 23:37 schrieb Rob Clark:

From: Rob Clark 

If a signal callback releases the sw_sync fence, that will trigger a
deadlock as the timeline_fence_release recurses onto the fence->lock
(used both for signaling and the the timeline tree).

To avoid that, temporarily hold an extra reference to the signalled
fences until after we drop the lock.

(This is an alternative implementation of 
https://patchwork.kernel.org/patch/11664717/
which avoids some potential UAF issues with the original patch.)

Reported-by: Bas Nieuwenhuizen 
Fixes: d3c6dd1fb30d ("dma-buf/sw_sync: Synchronize signal vs syncpt free")
Signed-off-by: Rob Clark 
---
  drivers/dma-buf/sw_sync.c | 10 ++
  1 file changed, 10 insertions(+)

diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 63f0aeb66db6..ceb6a0408624 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -191,6 +191,7 @@ static const struct dma_fence_ops timeline_fence_ops = {
   */
  static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
  {
+   LIST_HEAD(signalled);
struct sync_pt *pt, *next;
  
  	trace_sync_timeline(obj);

@@ -203,9 +204,13 @@ static void sync_timeline_signal(struct sync_timeline 
*obj, unsigned int inc)
if (!timeline_fence_signaled(&pt->base))
break;
  
+		dma_fence_get(&pt->base);


Question is why don't have the fences a reference on the list in the 
first place?



+
list_del_init(&pt->link);
rb_erase(&pt->node, &obj->pt_tree);
  
+		list_add_tail(&pt->link, &signalled);


Instead of list_del()/list_add_tail() you could also use 
list_move_tail() here.



+
/*
 * A signal callback may release the last reference to this
 * fence, causing it to be freed. That operation has to be
@@ -218,6 +223,11 @@ static void sync_timeline_signal(struct sync_timeline 
*obj, unsigned int inc)
}
  
  	spin_unlock_irq(&obj->lock);

+
+   list_for_each_entry_safe(pt, next, &signalled, link) {
+   list_del(&pt->link);


You must use list_del_init() here or otherwise the pt->link will keep 
pointing to the prev/next entries and the list_empty() check in 
timeline_fence_release() will fail and potentially corrupt things.


Regards,
Christian.


+   dma_fence_put(&pt->base);
+   }
  }
  
  /**




Re: [PATCH 1/5] drm/bridge: tc358762: Split register programming from pre-enable to enable

2023-08-18 Thread Dmitry Baryshkov

On 16/06/2023 22:02, Sam Ravnborg wrote:

Hi Marek,

On Thu, Jun 15, 2023 at 10:18:58PM +0200, Marek Vasut wrote:

Move the register programming part, which actually enables the bridge and
makes it push data out of its DPI side, into the enable callback. The DSI
host like DSIM may not be able to transmit commands in pre_enable, moving
the register programming into enable assures it can transmit commands.

Signed-off-by: Marek Vasut 


I was about to complain that the use of .enable is deprecated, but the
following patch fixes this.
So:
Reviewed-by: Sam Ravnborg 


Dear drm-misc / bridge maintainers. About two years ago nearly the same 
patch was rejected ([1]) on the grounds of some hosts (sunxi) being 
unable to send DCS commands in HS state. Later Dave created and landed 
patches that potentially enable all peripherals to send DSI commands 
from the pre_enable callback ([2]) and tc358762 picked up usage of these 
flags ([3]).


And then we land this patch, which contradicts all previous steps.
I think I fail to understand your actions.

[1] 
https://lore.kernel.org/linux-arm-msm/capy8ntbrhyamsradqjgutrsl6vjgxbamvon7xwev7e4qzv+...@mail.gmail.com/


[2] 
https://lore.kernel.org/r/20221205173328.1395350-5-dave.steven...@raspberrypi.com


[3] 
https://lore.kernel.org/dri-devel/20230131141756.RFT.v2.1.I723a3761d57ea60c5dd754c144aed6c3b2ea6f5a@changeid/






---
Cc: Andrzej Hajda 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jernej Skrabec 
Cc: Jonas Karlman 
Cc: Laurent Pinchart 
Cc: Neil Armstrong 
Cc: Robert Foss 
Cc: dri-devel@lists.freedesktop.org
---
  drivers/gpu/drm/bridge/tc358762.c | 11 +--
  1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358762.c 
b/drivers/gpu/drm/bridge/tc358762.c
index 5641395fd310e..df9703eacab1f 100644
--- a/drivers/gpu/drm/bridge/tc358762.c
+++ b/drivers/gpu/drm/bridge/tc358762.c
@@ -162,11 +162,17 @@ static void tc358762_pre_enable(struct drm_bridge *bridge)
usleep_range(5000, 1);
}
  
+	ctx->pre_enabled = true;

+}
+
+static void tc358762_enable(struct drm_bridge *bridge)
+{
+   struct tc358762 *ctx = bridge_to_tc358762(bridge);
+   int ret;
+
ret = tc358762_init(ctx);
if (ret < 0)
dev_err(ctx->dev, "error initializing bridge (%d)\n", ret);
-
-   ctx->pre_enabled = true;
  }
  
  static int tc358762_attach(struct drm_bridge *bridge,

@@ -181,6 +187,7 @@ static int tc358762_attach(struct drm_bridge *bridge,
  static const struct drm_bridge_funcs tc358762_bridge_funcs = {
.post_disable = tc358762_post_disable,
.pre_enable = tc358762_pre_enable,
+   .enable = tc358762_enable,
.attach = tc358762_attach,
  };
  
--

2.39.2


--
With best wishes
Dmitry



Re: [PATCH v4] PCI/VGA: Make the vga_is_firmware_default() less arch-dependent

2023-08-18 Thread suijingfeng

Hi,


On 2023/8/18 06:08, Bjorn Helgaas wrote:

This patch makes the vga_is_firmware_default() function works on whatever
arch that has UEFI GOP support. But we make it available only on platforms
where PCI resource relocation happens. if the provided method proves to be
effective and reliable, it can be expanded to other arch easily.

v2:
* Fix test robot warnnings and fix typos

v3:
* Fix linkage problems if the global screen_info is not exported

v4:
* Handle linkage problems by hiding behind of CONFIG_SYSFB,
* Drop side-effects and simplify.

The v2, v3, v4 changelog is nice, but we don't need it in the commit
log itself, where it will become part of the git history.  It should
go in a cover letter or after the "---" marker:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?id=v6.0#n678


Thanks for point it out, now I know. Will be fixed at the next version.



Re: [PATCH v5 02/17] dt-bindings: gpu: Add Imagination Technologies PowerVR GPU

2023-08-18 Thread Linus Walleij
Hi Sarah,

thanks for your patch!

Patches adding device tree bindings need to be CC:ed to
devicet...@vger.kernel.org
and the DT binding maintainers, I have added it for now.

On Wed, Aug 16, 2023 at 10:26 AM Sarah Walker  wrote:

> Add the device tree binding documentation for the Series AXE GPU used in
> TI AM62 SoCs.
>
> Co-developed-by: Frank Binns 
> Signed-off-by: Frank Binns 
> Signed-off-by: Sarah Walker 
(...)
> +properties:
> +  compatible:
> +items:
> +  - enum:
> +  - ti,am62-gpu
> +  - const: img,powervr-seriesaxe

Should there not at least be a dash there?

img,powervr-series-axe?

It is spelled in two words in the commit message,
Series AXE not SeriesAXE?

Moreover, if this pertains to the AXE-1-16 and AXE-2-16 it is kind of a wildcard
and we usually don't do that, I would use the exact version instead,
such as:
const: img,powervr-axe-1-16
any reason not to do this?

I asked about the relationship between these strings and the product
designations earlier I think :/

Yours,
Linus Walleij


Re: [RFC PATCH v2 00/11] Device Memory TCP

2023-08-18 Thread Pavel Begunkov

On 8/14/23 02:12, David Ahern wrote:

On 8/9/23 7:57 PM, Mina Almasry wrote:

Changes in RFC v2:
--

...

** Test Setup

Kernel: net-next with this RFC and memory provider API cherry-picked
locally.

Hardware: Google Cloud A3 VMs.

NIC: GVE with header split & RSS & flow steering support.


This set seems to depend on Jakub's memory provider patches and a netdev
driver change which is not included. For the testing mentioned here, you
must have a tree + branch with all of the patches. Is it publicly available?

It would be interesting to see how well (easy) this integrates with
io_uring. Besides avoiding all of the syscalls for receiving the iov and
releasing the buffers back to the pool, io_uring also brings in the
ability to seed a page_pool with registered buffers which provides a
means to get simpler Rx ZC for host memory.


The patchset sounds pretty interesting. I've been working with David Wei
(CC'ing) on io_uring zc rx (prototype polishing stage) all that is old
similar approaches based on allocating an rx queue. It targets host
memory and device memory as an extra feature, uapi is different, lifetimes
are managed/bound to io_uring. Completions/buffers are returned to user via
a separate queue instead of cmsg, and pushed back granularly to the kernel
via another queue. I'll leave it to David to elaborate

It sounds like we have space for collaboration here, if not merging then
reusing internals as much as we can, but we'd need to look into the
details deeper.


Overall I like the intent and possibilities for extensions, but a lot of
details are missing - perhaps some are answered by seeing an end-to-end
implementation.


--
Pavel Begunkov


Re: [PATCH v4] PCI/VGA: Make the vga_is_firmware_default() less arch-dependent

2023-08-18 Thread suijingfeng

Hi,


On 2023/8/18 06:08, Bjorn Helgaas wrote:

Please note that before apply this patch, vgaarb can not select the
right boot vga due to weird logic introduced with the commit
57fc7323a8e7c ("LoongArch: Add PCI controller support")

If we need this reference to 57fc7323a8e7c, we need more specifics
about what the "weird logic" is.  pci_fixup_vgadev() is the only
obvious VGA connection, so I suppose it's related to that.


Yes, you are right.

The pci_fixup_vgadev() function will set the last VGA device enumerated as the 
default boot device.
By "the last" VGA device, I mean that this device has the largest PCI bus, 
domain, and function triple.
Thus, it is added to vgaarb in the end of all VGA device.
So that logic expresses that the last one added will be the default.
This probably is not what we want.


On the LS3A5000+LS7A1000 platform, the last VGA device is a S3 graphics 
(08:00.0). This GPU has two cores. Say the log below:



$ lspci | grep VGA

 00:06.1 VGA compatible controller: Loongson Technology LLC DC (Display 
Controller) (rev 01)
 03:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] 
Caicos XT [Radeon HD 7470/8470 / R5 235/310 OEM]
 07:00.0 VGA compatible controller: S3 Graphics Ltd. Device 9070 (rev 01)
 08:00.0 VGA compatible controller: S3 Graphics Ltd. Device 9070 (rev 01)

[0.361781] vgaarb: loaded
[0.367838] pci :00:06.1: Overriding boot device as 1002:6778
[0.367841] pci :00:06.1: Overriding boot device as 5333:9070
[0.367843] pci :00:06.1: Overriding boot device as 5333:9070

1) The "weird" logic completely overrides whatever decision VGAARB ever made.

It seems to say that the decision ever made by VGAARB is useless.
Well, I think VGAARB shouldn't endure this; VGAARB has to be small.

 


2) The results it gives are not correct either.

In the first testing example in my commit message,
it overrides the S3 graphics as the default boot VGA instead of the AMD/ATI GPU.
Actually, the firmware chooses the AMD/ATI GPU as the "frimware default".

 


3) It tries to make the decision for the end user instead of the firmware.

Therefore, that function is always wrong. Again, it's a policy, not a mechanism.


Since that already have been merge, I'm fine.
Maybe Huacai is busy, he might don't has the time to carry on a deep thinking.
But I think we should correct the mistake ever made,
let's merge this patch to make vgaarb great again ?


Well, that commit is not a dependency, I don't mind delete the referencing
to that commit. After all, I think my patch will be effective on other 
architectures.
Is additional testing on ARM64 and X86 is needed, if so I have to find the 
machine to
carry on the testing.



Re: [PATCH] drm/panel: Add prepare_prev_first flag to Visionox VTDR6130

2023-08-18 Thread Dmitry Baryshkov

On 18/08/2023 11:25, neil.armstr...@linaro.org wrote:

Hi Dmitry,

On 17/08/2023 20:35, Dmitry Baryshkov wrote:

On 16/08/2023 10:51, neil.armstr...@linaro.org wrote:

Hi Abhinav,

On 14/08/2023 20:02, Abhinav Kumar wrote:






Sending HS commands will always work on any controller, it's all 
about LP commands.
The Samsung panels you listed only send HS commands so they can use 
prepare_prev_first

and work on any controllers.


I think there is some misunderstanding there, supported by the 
description of the flag.


If I remember correctly, some hosts (sunxi) can not send DCS commands 
after enabling video stream and switching to HS mode, see [1]. Thus, 
as you know, most of the drivers have all DSI panel setup commands in 
drm_panel_funcs::prepare() / drm_bridge_funcs::pre_enable() callbacks, 
not paying attention whether these commands are to be sent in LP or in 
HS mode.


Previously DSI source drivers could power on the DSI link either in 
mode_set() or in pre_enable() callbacks, with mode_set() being the 
hack to make panel/bridge drivers to be able to send commands from 
their prepare() / pre_enable() callbacks.


With the prev_first flags being introduced, we have established that 
DSI link should be enabled in DSI host's pre_enable() callback and 
switched to HS mode (be it command or video) in the enable() callback.


So far so good.


It seems coherent, I would like first to have a state of all DSI host 
drivers and make this would actually work first before adding the 
prev_first flag to all the required panels.




Unfortunately this change is not fully backwards-compatible. This 
requires that all DSI panels sending commands from prepare() should 
have the prepare_prev_first flag. In some sense, all such patches 
might have Fixes: 5ea6b1702781 ("drm/panel: Add prepare_prev_first 
flag to drm_panel").


This kind of migration should be done *before* any possible regression, 
not the other way round.


If all panels sending commands from prepare() should have the 
prepare_prev_first flag, then it should be first, check for regressions 
then continue.






I understand, but this patch doesn't qualify as a fix for 
9e15123eca79 and is too late to be merged in drm-misc-next for v6.6,
and since 9e15123eca79 actually breaks some support it should be 
reverted (+ deps) since we are late in the rc cycles.


If we go this way, we can never reapply these patches. There will be 
no guarantee that all panel drivers are completely converted. We 
already have a story without an observable end - 
DRM_BRIDGE_ATTACH_NO_CONNECTOR.


I don't understand this point, who would block re-applying the patches ?


Consider us reverting 9e15123eca79 now and then reapplying it next 
cycle. Then another panel / bridge that was not converted to use 
pre_enable_prev_first pops up. And suddently we have to revert them again.


The migration to DRM_BRIDGE_ATTACH_NO_CONNECTOR was done over multiple 
Linux version and went smoothly because we reverted
regressing patches and restarted when needed, I don't understand why we 
can't do this here aswell.


With DRM_BRIDGE_ATTACH_NO_CONNECTOR both host and peripheral drivers 
were involved. This way they share knowledge about the migration state.


With prev_first we do not have such shared knowledge. Host assumes that 
it can work according to the documentation: turn DSI link to LP-11 in 
pre_enable(), switch to HS in enable(). It can not check whether the 
next bridge did not set pre_enable_prev_first because of it not being 
required (like for the Parade bridge) or because next bridge is not 
converted yet (and thus DSI host should power up the link in 
atomic_mode_set).


Granted that there is no way for the DSI host driver to attune itself to 
the DSI peripheral driver requirements, I can only consider 
corresponding (requiring prev_first) panel drivers broken since 
5ea6b1702781 ("drm/panel: Add prepare_prev_first flag to drm_panel") and 
all bridge drivers with this issue broken since 4fb912e5e190 
("drm/bridge: Introduce pre_enable_prev_first to alter bridge init order").






I'd consider that the DSI driver is correct here and it is about the 
panel drivers that require fixes patches. If you care about the 
particular Fixes tag, I have provided one several lines above.


Unfortunately it should be done in the other way round, prepare for 
migration, then migrate,


I mean if it's a required migration, then it should be done and I'll 
support it from both bridge and panel PoV.


So, first this patch has the wrong Fixes tag, and I would like a better 
explanation on the commit message in any case.
Then I would like to have an ack from some drm-misc maintainers before 
applying it because it fixes a patch that
was sent via the msm tree thus per the drm-misc rules I cannot apply it 
via the drm-misc-next-fixes tree.


Neil





--
With best wishes
Dmitry



Re: [PATCH 3/4] drm/uapi: document the USB subconnector type

2023-08-18 Thread Dmitry Baryshkov

On 18/08/2023 09:24, Simon Ser wrote:

On Thursday, August 17th, 2023 at 21:33, Dmitry Baryshkov 
 wrote:


We have been looking for a way to document that the corresponding DP
port is represented by the USB connector on the device.

Consequently, I believe the best way to document it, would be to use
DisplayPort / USB, when there is no dongle connected, switching to
DisplayPort / HDMI, DisplayPort / VGA, DisplayPort / DisplayPort, etc.
when the actual dongle / display is connected and then switching back to
the DisplayPort / USB when it gets disconnected.

If this sounds good to all parties, I'll post v2, adding this
explanation to the cover letter.


But how can user-space discover that the port is USB-C when it's
connected? That information is lost at this point.


Yes, unfortunately.


(In addition, this clashes with the existing semantics of the
subconnector prop as discussed before: USB-C is not sub-, it's super-.)


Ok. How do we proceed then? Is it fine to add another property for DP 
case? Do you have any particular property name in mind? I will follow 
with addition of this property then.


--
With best wishes
Dmitry



Re: [PATCH v5 02/17] dt-bindings: gpu: Add Imagination Technologies PowerVR GPU

2023-08-18 Thread Krzysztof Kozlowski
On 16/08/2023 10:25, Sarah Walker wrote:
> Add the device tree binding documentation for the Series AXE GPU used in
> TI AM62 SoCs.
> 
> Co-developed-by: Frank Binns 
> Signed-off-by: Frank Binns 
> Signed-off-by: Sarah Walker 
> ---
> Changes since v4:
> - Add clocks constraint for ti,am62-gpu


Please use scripts/get_maintainers.pl to get a list of necessary people
and lists to CC. It might happen, that command when run on an older
kernel, gives you outdated entries. Therefore please be sure you base
your patches on recent Linux kernel.

You missed at least DT list (maybe more), so this won't be tested by
automated tooling. Performing review on untested code might be a waste
of time, thus I will skip this patch entirely till you follow the
process allowing the patch to be tested.

Please kindly resend and include all necessary To/Cc entries.


You already got this comment. I think more than once. Fix your
processes, so finally this is resolved.

Best regards,
Krzysztof



Re: [PATCH v5 02/17] dt-bindings: gpu: Add Imagination Technologies PowerVR GPU

2023-08-18 Thread Krzysztof Kozlowski
On 18/08/2023 11:36, Linus Walleij wrote:
> Hi Sarah,
> 
> thanks for your patch!
> 
> Patches adding device tree bindings need to be CC:ed to
> devicet...@vger.kernel.org
> and the DT binding maintainers, I have added it for now.
> 

This won't help, I think. Patch will not be tested.

I was already asking for using get_maintainers in the past... sigh...

Best regards,
Krzysztof



Re: [PATCH v5 17/17] arm64: dts: ti: k3-am62-main: Add GPU device node [DO NOT MERGE]

2023-08-18 Thread Krzysztof Kozlowski
On 16/08/2023 10:25, Sarah Walker wrote:
> Add the Series AXE GPU node to the AM62 device tree.
> 
> Changes since v4:
> - Remove interrupt name
> - Make property order consistent across dts and bindings doc
> - Fixed formatting (replaced spaces with tabs)
> 

Nope, DTS go via SoC tree. You skipped all lists and maybe also all
maintainers.

Really, start finally using the Linux tools - scripts/get_maintainers.pl


Best regards,
Krzysztof



Re: [PATCH RFC v5 02/10] drm: Introduce solid fill DRM plane property

2023-08-18 Thread Pekka Paalanen
On Fri, 4 Aug 2023 16:59:00 +0300
Dmitry Baryshkov  wrote:

> On Fri, 4 Aug 2023 at 16:44, Sebastian Wick  wrote:
> >
> > On Fri, Aug 4, 2023 at 3:27 PM Dmitry Baryshkov
> >  wrote:  
> > >
> > > On Fri, 28 Jul 2023 at 20:03, Jessica Zhang  
> > > wrote:  
> > > >
> > > > Document and add support for solid_fill property to drm_plane. In
> > > > addition, add support for setting and getting the values for solid_fill.
> > > >
> > > > To enable solid fill planes, userspace must assign a property blob to
> > > > the "solid_fill" plane property containing the following information:
> > > >
> > > > struct drm_mode_solid_fill {
> > > > u32 version;
> > > > u32 r, g, b;
> > > > };
> > > >
> > > > Signed-off-by: Jessica Zhang 
> > > > ---
> > > >  drivers/gpu/drm/drm_atomic_state_helper.c |  9 +
> > > >  drivers/gpu/drm/drm_atomic_uapi.c | 55 
> > > > +++
> > > >  drivers/gpu/drm/drm_blend.c   | 30 +
> > > >  include/drm/drm_blend.h   |  1 +
> > > >  include/drm/drm_plane.h   | 35 
> > > >  include/uapi/drm/drm_mode.h   | 24 ++
> > > >  6 files changed, 154 insertions(+)
> > > >  
> > >
> > > [skipped most of the patch]
> > >  
> > > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > > > index 43691058d28f..53c8efa5ad7f 100644
> > > > --- a/include/uapi/drm/drm_mode.h
> > > > +++ b/include/uapi/drm/drm_mode.h
> > > > @@ -259,6 +259,30 @@ struct drm_mode_modeinfo {
> > > > char name[DRM_DISPLAY_MODE_LEN];
> > > >  };
> > > >
> > > > +/**
> > > > + * struct drm_mode_solid_fill - User info for solid fill planes
> > > > + *
> > > > + * This is the userspace API solid fill information structure.
> > > > + *
> > > > + * Userspace can enable solid fill planes by assigning the plane 
> > > > "solid_fill"
> > > > + * property to a blob containing a single drm_mode_solid_fill struct 
> > > > populated with an RGB323232
> > > > + * color and setting the pixel source to "SOLID_FILL".
> > > > + *
> > > > + * For information on the plane property, see 
> > > > drm_plane_create_solid_fill_property()
> > > > + *
> > > > + * @version: Version of the blob. Currently, there is only support for 
> > > > version == 1
> > > > + * @r: Red color value of single pixel
> > > > + * @g: Green color value of single pixel
> > > > + * @b: Blue color value of single pixel
> > > > + */
> > > > +struct drm_mode_solid_fill {
> > > > +   __u32 version;
> > > > +   __u32 r;
> > > > +   __u32 g;
> > > > +   __u32 b;  
> > >
> > > Another thought about the drm_mode_solid_fill uABI. I still think we
> > > should add alpha here. The reason is the following:
> > >
> > > It is true that we have  drm_plane_state::alpha and the plane's
> > > "alpha" property. However it is documented as "the plane-wide opacity
> > > [...] It can be combined with pixel alpha. The pixel values in the
> > > framebuffers are expected to not be pre-multiplied by the global alpha
> > > associated to the plane.".
> > >
> > > I can imagine a use case, when a user might want to enable plane-wide
> > > opacity, set "pixel blend mode" to "Coverage" and then switch between
> > > partially opaque framebuffer and partially opaque solid-fill without
> > > touching the plane's alpha value.  
> >
> > The only reason I see against this is that there might be some
> > hardware which supports only RGB but not alpha on planes and they
> > could then not use this property.  
> 
> Fair enough.
> 
> > Maybe another COLOR_FILL enum value
> > with alpha might be better? Maybe just doing the alpha via the alpha
> > property is good enough.  
> 
> One of our customers has a use case for setting the opaque solid fill,
> while keeping the plane's alpha intact.

Could you explain more about why they must keep plane alpha intact
instead of reprogramming everything with atomic? Is there some
combination that just cannot reach the same end result via userspace
manipulation of the solid fill values with plane alpha?

Or is it a matter of userspace architecture where you have independent
components responsible for different KMS property values?


Thanks,
pq


pgp1FJotbdwQI.pgp
Description: OpenPGP digital signature


Re: [EXTERNAL] Re: [PATCH v5 13/17] drm/imagination: Implement context creation/destruction ioctls

2023-08-18 Thread Sarah Walker
On Fri, 2023-08-18 at 00:42 +0200, Jann Horn wrote:
> *** CAUTION: This email originates from a source not known to Imagination 
> Technologies. Think before you click a link or open an attachment ***
> 
> On Wed, Aug 16, 2023 at 10:25 AM Sarah Walker  wrote:
> > Implement ioctls for the creation and destruction of contexts. Contexts are
> > used for job submission and each is associated with a particular job type.
> [...]
> > +/**
> > + * pvr_context_create() - Create a context.
> > + * @pvr_file: File to attach the created context to.
> > + * @args: Context creation arguments.
> > + *
> > + * Return:
> > + *  * 0 on success, or
> > + *  * A negative error code on failure.
> > + */
> > +int pvr_context_create(struct pvr_file *pvr_file, struct 
> > drm_pvr_ioctl_create_context_args *args)
> > +{
> > +   struct pvr_device *pvr_dev = pvr_file->pvr_dev;
> > +   struct pvr_context *ctx;
> > +   int ctx_size;
> > +   int err;
> > +
> > +   /* Context creation flags are currently unused and must be zero. */
> > +   if (args->flags)
> > +   return -EINVAL;
> > +
> > +   ctx_size = get_fw_obj_size(args->type);
> > +   if (ctx_size < 0)
> > +   return ctx_size;
> > +
> > +   ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
> > +   if (!ctx)
> > +   return -ENOMEM;
> > +
> > +   ctx->data_size = ctx_size;
> > +   ctx->type = args->type;
> > +   ctx->flags = args->flags;
> > +   ctx->pvr_dev = pvr_dev;
> > +   kref_init(&ctx->ref_count);
> > +
> > +   err = remap_priority(pvr_file, args->priority, &ctx->priority);
> > +   if (err)
> > +   goto err_free_ctx;
> > +
> > +   ctx->vm_ctx = pvr_vm_context_lookup(pvr_file, 
> > args->vm_context_handle);
> > +   if (IS_ERR(ctx->vm_ctx)) {
> > +   err = PTR_ERR(ctx->vm_ctx);
> > +   goto err_free_ctx;
> > +   }
> > +
> > +   ctx->data = kzalloc(ctx_size, GFP_KERNEL);
> > +   if (!ctx->data) {
> > +   err = -ENOMEM;
> > +   goto err_put_vm;
> > +   }
> > +
> > +   err = init_fw_objs(ctx, args, ctx->data);
> > +   if (err)
> > +   goto err_free_ctx_data;
> > +
> > +   err = pvr_fw_object_create(pvr_dev, ctx_size, 
> > PVR_BO_FW_FLAGS_DEVICE_UNCACHED,
> > +  ctx_fw_data_init, ctx, &ctx->fw_obj);
> > +   if (err)
> > +   goto err_free_ctx_data;
> > +
> > +   err = xa_alloc(&pvr_dev->ctx_ids, &ctx->ctx_id, ctx, xa_limit_32b, 
> > GFP_KERNEL);
> > +   if (err)
> > +   goto err_destroy_fw_obj;
> > +
> > +   err = xa_alloc(&pvr_file->ctx_handles, &args->handle, ctx, 
> > xa_limit_32b, GFP_KERNEL);
> > +   if (err)
> > +   goto err_release_id;
> 
> This bailout looks a bit dodgy. We have already inserted ctx into
> &pvr_dev->ctx_ids, and now we just take it out again. If someone could
> concurrently call pvr_context_lookup_id() on the ID we just allocated
> (I don't understand enough about what's going on here at a high level
> to be able to tell if that's possible), I think they would be able to
> elevate the ctx->ref_count from 1 to 2, and then on the bailout path
> we'll just free the ctx without looking at the refcount.
> 
> If this can't happen, it might be a good idea to add a comment
> explaining why. If it can happen, I guess one way to fix it would be
> to replace this last bailout with a call to pvr_context_put()?

Yes, I think you're correct here. I don't think there's anything in the current
patch set that can actually trigger this, but it definitely needs fixing.

Thanks,
Sarah

> 
> 
> > +
> > +   return 0;
> > +
> > +err_release_id:
> > +   xa_erase(&pvr_dev->ctx_ids, ctx->ctx_id);
> > +
> > +err_destroy_fw_obj:
> > +   pvr_fw_object_destroy(ctx->fw_obj);
> > +
> > +err_free_ctx_data:
> > +   kfree(ctx->data);
> > +
> > +err_put_vm:
> > +   pvr_vm_context_put(ctx->vm_ctx);
> > +
> > +err_free_ctx:
> > +   kfree(ctx);
> > +   return err;
> > +}


Re: [PATCH RFC v5 02/10] drm: Introduce solid fill DRM plane property

2023-08-18 Thread Dmitry Baryshkov

On 18/08/2023 13:51, Pekka Paalanen wrote:

On Fri, 4 Aug 2023 16:59:00 +0300
Dmitry Baryshkov  wrote:


On Fri, 4 Aug 2023 at 16:44, Sebastian Wick  wrote:


On Fri, Aug 4, 2023 at 3:27 PM Dmitry Baryshkov
 wrote:


On Fri, 28 Jul 2023 at 20:03, Jessica Zhang  wrote:


Document and add support for solid_fill property to drm_plane. In
addition, add support for setting and getting the values for solid_fill.

To enable solid fill planes, userspace must assign a property blob to
the "solid_fill" plane property containing the following information:

struct drm_mode_solid_fill {
 u32 version;
 u32 r, g, b;
};

Signed-off-by: Jessica Zhang 
---
  drivers/gpu/drm/drm_atomic_state_helper.c |  9 +
  drivers/gpu/drm/drm_atomic_uapi.c | 55 +++
  drivers/gpu/drm/drm_blend.c   | 30 +
  include/drm/drm_blend.h   |  1 +
  include/drm/drm_plane.h   | 35 
  include/uapi/drm/drm_mode.h   | 24 ++
  6 files changed, 154 insertions(+)
  


[skipped most of the patch]
  

diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 43691058d28f..53c8efa5ad7f 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -259,6 +259,30 @@ struct drm_mode_modeinfo {
 char name[DRM_DISPLAY_MODE_LEN];
  };

+/**
+ * struct drm_mode_solid_fill - User info for solid fill planes
+ *
+ * This is the userspace API solid fill information structure.
+ *
+ * Userspace can enable solid fill planes by assigning the plane "solid_fill"
+ * property to a blob containing a single drm_mode_solid_fill struct populated 
with an RGB323232
+ * color and setting the pixel source to "SOLID_FILL".
+ *
+ * For information on the plane property, see 
drm_plane_create_solid_fill_property()
+ *
+ * @version: Version of the blob. Currently, there is only support for version 
== 1
+ * @r: Red color value of single pixel
+ * @g: Green color value of single pixel
+ * @b: Blue color value of single pixel
+ */
+struct drm_mode_solid_fill {
+   __u32 version;
+   __u32 r;
+   __u32 g;
+   __u32 b;


Another thought about the drm_mode_solid_fill uABI. I still think we
should add alpha here. The reason is the following:

It is true that we have  drm_plane_state::alpha and the plane's
"alpha" property. However it is documented as "the plane-wide opacity
[...] It can be combined with pixel alpha. The pixel values in the
framebuffers are expected to not be pre-multiplied by the global alpha
associated to the plane.".

I can imagine a use case, when a user might want to enable plane-wide
opacity, set "pixel blend mode" to "Coverage" and then switch between
partially opaque framebuffer and partially opaque solid-fill without
touching the plane's alpha value.


The only reason I see against this is that there might be some
hardware which supports only RGB but not alpha on planes and they
could then not use this property.


Fair enough.


Maybe another COLOR_FILL enum value
with alpha might be better? Maybe just doing the alpha via the alpha
property is good enough.


One of our customers has a use case for setting the opaque solid fill,
while keeping the plane's alpha intact.


Could you explain more about why they must keep plane alpha intact
instead of reprogramming everything with atomic? Is there some
combination that just cannot reach the same end result via userspace
manipulation of the solid fill values with plane alpha?

Or is it a matter of userspace architecture where you have independent
components responsible for different KMS property values?
The latter one. The goal is to be able to switch between pixel sources 
without touching any additional properties (including plane's alpha value).


--
With best wishes
Dmitry



Re: [Intel-gfx] [RESEND PATCH] drm/i915: constify pointers to hwmon_channel_info

2023-08-18 Thread Jani Nikula
On Thu, 25 May 2023, Jani Nikula  wrote:
> On Thu, 11 May 2023, Krzysztof Kozlowski  
> wrote:
>> Statically allocated array of pointers to hwmon_channel_info can be made
>> const for safety.
>
> Btw if you want to further make things const, the compound literals
> defined by HWMON_CHANNEL_INFO() still end up mutable, even if they're
> only referenced inline using a const pointer. If possible, would be nice
> to add const there too.

Krzysztof, can I persuade you to follow up on this one? ;)

With HWMON_CHANNEL_INFO defined like this:

#define HWMON_CHANNEL_INFO(stype, ...)  \
(&(struct hwmon_channel_info) { \
.type = hwmon_##stype,  \
.config = (u32 []) {\
__VA_ARGS__, 0  \
}   \
})

and initializers like this all over the kernel:

static const struct hwmon_channel_info * const hwm_info[] = {
HWMON_CHANNEL_INFO(in, HWMON_I_INPUT),
HWMON_CHANNEL_INFO(power, HWMON_P_MAX | HWMON_P_RATED_MAX | 
HWMON_P_CRIT),
HWMON_CHANNEL_INFO(energy, HWMON_E_INPUT),
HWMON_CHANNEL_INFO(curr, HWMON_C_CRIT),
NULL
};

You'll actually end up with *mutable non-const* struct
hwmon_channel_info's being allocated in .data sections, and having the
const pointers in the arrays point at the mutable stuff. Check with
readelf or objdump.

To put all of it in .rodata, you'd need to make the compound literals
const too:

 #define HWMON_CHANNEL_INFO(stype, ...) \
-   (&(struct hwmon_channel_info) { \
+   (&(const struct hwmon_channel_info) {   \
.type = hwmon_##stype,  \

But I'm not up for going throw all of the use sites to see if they can
all be const.


BR,
Jani.



>
> BR,
> Jani.
>
>>
>> Acked-by: Jani Nikula 
>> Signed-off-by: Krzysztof Kozlowski 
>> ---
>>  drivers/gpu/drm/i915/i915_hwmon.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_hwmon.c 
>> b/drivers/gpu/drm/i915/i915_hwmon.c
>> index 8e7dccc8d3a0..e99e8c97ef01 100644
>> --- a/drivers/gpu/drm/i915/i915_hwmon.c
>> +++ b/drivers/gpu/drm/i915/i915_hwmon.c
>> @@ -267,7 +267,7 @@ static const struct attribute_group *hwm_groups[] = {
>>  NULL
>>  };
>>  
>> -static const struct hwmon_channel_info *hwm_info[] = {
>> +static const struct hwmon_channel_info * const hwm_info[] = {
>>  HWMON_CHANNEL_INFO(in, HWMON_I_INPUT),
>>  HWMON_CHANNEL_INFO(power, HWMON_P_MAX | HWMON_P_RATED_MAX | 
>> HWMON_P_CRIT),
>>  HWMON_CHANNEL_INFO(energy, HWMON_E_INPUT),
>> @@ -275,7 +275,7 @@ static const struct hwmon_channel_info *hwm_info[] = {
>>  NULL
>>  };
>>  
>> -static const struct hwmon_channel_info *hwm_gt_info[] = {
>> +static const struct hwmon_channel_info * const hwm_gt_info[] = {
>>  HWMON_CHANNEL_INFO(energy, HWMON_E_INPUT),
>>  NULL
>>  };

-- 
Jani Nikula, Intel Open Source Graphics Center


Re: [PATCH -next] drm/msm/adreno: adreno_gpu: Switch to memdup_user_nul() helper

2023-08-18 Thread Dmitry Baryshkov

On 10/08/2023 15:04, Ruan Jinjie wrote:

Use memdup_user_nul() helper instead of open-coding to simplify the code.

Signed-off-by: Ruan Jinjie 
---
  drivers/gpu/drm/msm/adreno/adreno_gpu.c | 14 +++---
  1 file changed, 3 insertions(+), 11 deletions(-)


Reviewed-by: Dmitry Baryshkov 

--
With best wishes
Dmitry



Re: [PATCH] drm/vmwgfx: Fix possible invalid drm gem put calls

2023-08-18 Thread Martin Krastev (VMware)

From: Martin Krastev 


LGTM!

Reviewed-by: Martin Krastev 


Regards,

Martin


On 18 Aug 2023 04:13:14, Zack Rusin wrote:

>From: Zack Rusin 
>
>vmw_bo_unreference sets the input buffer to null on exit, resulting in
>null ptr deref's on the subsequent drm gem put calls.
>
>This went unnoticed because only very old userspace would be exercising
>those paths but it wouldn't be hard to hit on old distros with brand
>new kernels.
>
>Introduce a new function that abstracts unrefing of user bo's to make
>the code cleaner and more explicit.
>
>Signed-off-by: Zack Rusin 
>Reported-by: Ian Forbes 
>Fixes: 9ef8d83e8e25 ("drm/vmwgfx: Do not drop the reference to the 
handle too soon")

>Cc:  # v6.4+
>---
> drivers/gpu/drm/vmwgfx/vmwgfx_bo.c  | 6 ++
> drivers/gpu/drm/vmwgfx/vmwgfx_bo.h  | 8 
> drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 6 ++
> drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 6 ++
> drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | 3 +--
> drivers/gpu/drm/vmwgfx/vmwgfx_shader.c  | 3 +--
> 6 files changed, 16 insertions(+), 16 deletions(-)
>
>diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c

>index 82094c137855..c43853597776 100644
>--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
>+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
>@@ -497,10 +497,9 @@ static int vmw_user_bo_synccpu_release(struct 
drm_file *filp,

> if (!(flags & drm_vmw_synccpu_allow_cs)) {
> atomic_dec(&vmw_bo->cpu_writers);
> }
>-   ttm_bo_put(&vmw_bo->tbo);
>+   vmw_user_bo_unref(vmw_bo);
> }
>
>-   drm_gem_object_put(&vmw_bo->tbo.base);
> return ret;
> }
>
>@@ -540,8 +539,7 @@ int vmw_user_bo_synccpu_ioctl(struct drm_device 
*dev, void *data,

> return ret;
>
> ret = vmw_user_bo_synccpu_grab(vbo, arg->flags);
>-   vmw_bo_unreference(&vbo);
>-   drm_gem_object_put(&vbo->tbo.base);
>+   vmw_user_bo_unref(vbo);
> if (unlikely(ret != 0)) {
> if (ret == -ERESTARTSYS || ret == -EBUSY)
> return -EBUSY;
>diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h 
b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h

>index 50a836e70994..1d433fceed3d 100644
>--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
>+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
>@@ -195,6 +195,14 @@ static inline struct vmw_bo 
*vmw_bo_reference(struct vmw_bo *buf)

> return buf;
> }
>
>+static inline void vmw_user_bo_unref(struct vmw_bo *vbo)
>+{
>+   if (vbo) {
>+   ttm_bo_put(&vbo->tbo);
>+   drm_gem_object_put(&vbo->tbo.base);
>+   }
>+}
>+
> static inline struct vmw_bo *to_vmw_bo(struct drm_gem_object *gobj)
> {
> return container_of((gobj), struct vmw_bo, tbo.base);
>diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c

>index 6b9aa2b4ef54..25b96821df0f 100644
>--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
>+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
>@@ -1164,8 +1164,7 @@ static int vmw_translate_mob_ptr(struct 
vmw_private *dev_priv,

> }
> vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_MOB, 
VMW_BO_DOMAIN_MOB);

> ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo);
>-   ttm_bo_put(&vmw_bo->tbo);
>-   drm_gem_object_put(&vmw_bo->tbo.base);
>+   vmw_user_bo_unref(vmw_bo);
> if (unlikely(ret != 0))
> return ret;
>
>@@ -1221,8 +1220,7 @@ static int vmw_translate_guest_ptr(struct 
vmw_private *dev_priv,
> vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_GMR | 
VMW_BO_DOMAIN_VRAM,

>  VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM);
> ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo);
>-   ttm_bo_put(&vmw_bo->tbo);
>-   drm_gem_object_put(&vmw_bo->tbo.base);
>+   vmw_user_bo_unref(vmw_bo);
> if (unlikely(ret != 0))
> return ret;
>
>diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c

>index b62207be3363..1489ad73c103 100644
>--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
>+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
>@@ -1665,10 +1665,8 @@ static struct drm_framebuffer 
*vmw_kms_fb_create(struct drm_device *dev,

>
> err_out:
> /* vmw_user_lookup_handle takes one ref so does new_fb */
>-   if (bo) {
>-   vmw_bo_unreference(&bo);
>-   drm_gem_object_put(&bo->tbo.base);
>-   }
>+   if (bo)
>+   vmw_user_bo_unref(bo);
> if (surface)
> vmw_surface_unreference(&surface);
>
>diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c

>index 7e112319a23c..fb85f244c3d0 100644
>--- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
>+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
>@@ -451,8 +451,7 @@ int vmw_overlay_ioctl(struct drm_device *dev, void 
*data,

>
> ret = vmw_overlay_update_stream(dev_pri

Re: [PATCH 7/7] drm: adv7511: Add hpd_override_enable feature bit to struct adv7511_chip_info

2023-08-18 Thread Adam Ford
On Sun, Aug 13, 2023 at 1:06 PM Biju Das  wrote:
>
> As per spec, it is allowed to pulse the HPD signal to indicate that the
> EDID information has changed. Some monitors do this when they wake up
> from standby or are enabled. When the HPD goes low the adv7511 is
> reset and the outputs are disabled which might cause the monitor to
> go to standby again. To avoid this we ignore the HPD pin for the
> first few seconds after enabling the output. On the other hand,
> adv7535 require to enable HPD Override bit for proper HPD.
>
> Add hpd_override_enable feature bit to struct adv7511_chip_info to handle
> this scenario.
>
> While at it, drop the enum adv7511_type as it is unused.

It seems like dropping adv7511_type is unrelated to the rest of the
patch, and I think it should be split from this into its own patch

adam
>
> Signed-off-by: Biju Das 
> ---
>  drivers/gpu/drm/bridge/adv7511/adv7511.h |  8 +---
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 12 +---
>  2 files changed, 6 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
> b/drivers/gpu/drm/bridge/adv7511/adv7511.h
> index 627531f48f84..c523ac4c9bc8 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
> @@ -325,22 +325,16 @@ struct adv7511_video_config {
> struct hdmi_avi_infoframe avi_infoframe;
>  };
>
> -enum adv7511_type {
> -   ADV7511,
> -   ADV7533,
> -   ADV7535,
> -};
> -
>  #define ADV7511_MAX_ADDRS 3
>
>  struct adv7511_chip_info {
> -   enum adv7511_type type;
> unsigned long max_mode_clock;
> unsigned long max_lane_freq;
> const char * const *supply_names;
> unsigned int num_supplies;
> unsigned has_dsi:1;
> unsigned link_config:1;
> +   unsigned hpd_override_enable:1;
>  };
>
>  struct adv7511 {
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> index 6974c267b1d5..7b06a0a21685 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> @@ -354,7 +354,7 @@ static void __adv7511_power_on(struct adv7511 *adv7511)
>  * first few seconds after enabling the output. On the other hand
>  * adv7535 require to enable HPD Override bit for proper HPD.
>  */
> -   if (adv7511->info->type == ADV7535)
> +   if (adv7511->info->hpd_override_enable)
> regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
>ADV7535_REG_POWER2_HPD_OVERRIDE,
>ADV7535_REG_POWER2_HPD_OVERRIDE);
> @@ -381,7 +381,7 @@ static void adv7511_power_on(struct adv7511 *adv7511)
>  static void __adv7511_power_off(struct adv7511 *adv7511)
>  {
> /* TODO: setup additional power down modes */
> -   if (adv7511->info->type == ADV7535)
> +   if (adv7511->info->hpd_override_enable)
> regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
>ADV7535_REG_POWER2_HPD_OVERRIDE, 0);
>
> @@ -682,7 +682,7 @@ adv7511_detect(struct adv7511 *adv7511, struct 
> drm_connector *connector)
> status = connector_status_disconnected;
> } else {
> /* Renable HPD sensing */
> -   if (adv7511->info->type == ADV7535)
> +   if (adv7511->info->hpd_override_enable)
> regmap_update_bits(adv7511->regmap, 
> ADV7511_REG_POWER2,
>ADV7535_REG_POWER2_HPD_OVERRIDE,
>ADV7535_REG_POWER2_HPD_OVERRIDE);
> @@ -1360,14 +1360,12 @@ static void adv7511_remove(struct i2c_client *i2c)
>  }
>
>  static const struct adv7511_chip_info adv7511_chip_info = {
> -   .type = ADV7511,
> .supply_names = adv7511_supply_names,
> .num_supplies = ARRAY_SIZE(adv7511_supply_names),
> .link_config = 1
>  };
>
>  static const struct adv7511_chip_info adv7533_chip_info = {
> -   .type = ADV7533,
> .max_mode_clock = 8,
> .max_lane_freq = 80,
> .supply_names = adv7533_supply_names,
> @@ -1376,12 +1374,12 @@ static const struct adv7511_chip_info 
> adv7533_chip_info = {
>  };
>
>  static const struct adv7511_chip_info adv7535_chip_info = {
> -   .type = ADV7535,
> .max_mode_clock = 148500,
> .max_lane_freq = 891000,
> .supply_names = adv7533_supply_names,
> .num_supplies = ARRAY_SIZE(adv7533_supply_names),
> -   .has_dsi = 1
> +   .has_dsi = 1,
> +   .hpd_override_enable = 1
>  };
>
>  static const struct i2c_device_id adv7511_i2c_ids[] = {
> --
> 2.25.1
>


[PATCH -next] drm/scheduler: Remove unused declarations

2023-08-18 Thread Yue Haibing
Commit 06a2d7cc3f04 ("drm/amdgpu: revert "implement tdr advanced mode"")
removed drm_sched_reset_karma()/drm_sched_increase_karma_ext() but leave
the declarations.
Commit 2cf9886e2816 ("drm/scheduler: remove drm_sched_dependency_optimized")
removed drm_sched_dependency_optimized() but not its declaration.

Signed-off-by: Yue Haibing 
---
 include/drm/gpu_scheduler.h | 4 
 1 file changed, 4 deletions(-)

diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index f9544d9b670d..cd8ac90865fc 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -554,10 +554,6 @@ 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);
 void drm_sched_increase_karma(struct drm_sched_job *bad);
-void drm_sched_reset_karma(struct drm_sched_job *bad);
-void drm_sched_increase_karma_ext(struct drm_sched_job *bad, int type);
-bool drm_sched_dependency_optimized(struct dma_fence* fence,
-   struct drm_sched_entity *entity);
 void drm_sched_fault(struct drm_gpu_scheduler *sched);
 
 void drm_sched_rq_add_entity(struct drm_sched_rq *rq,
-- 
2.34.1



Re: [PATCH v2 1/9] drm/sched: Convert drm scheduler to use a work queue rather than kthread

2023-08-18 Thread Matthew Brost
On Fri, Aug 18, 2023 at 07:40:41AM +0200, Christian König wrote:
> Am 18.08.23 um 05:08 schrieb Matthew Brost:
> > On Thu, Aug 17, 2023 at 01:13:31PM +0200, Danilo Krummrich wrote:
> > > On 8/17/23 07:33, Christian König wrote:
> > > > Am 16.08.23 um 18:33 schrieb Danilo Krummrich:
> > > > > On 8/16/23 16:59, Christian König wrote:
> > > > > > Am 16.08.23 um 14:30 schrieb Danilo Krummrich:
> > > > > > > On 8/16/23 16:05, Christian König wrote:
> > > > > > > > Am 16.08.23 um 13:30 schrieb Danilo Krummrich:
> > > > > > > > > Hi Matt,
> > > > > > > > > 
> > > > > > > > > On 8/11/23 04:31, Matthew Brost wrote:
> > > > > > > > > > In XE, the new Intel GPU driver, a choice has made to have 
> > > > > > > > > > a 1 to 1
> > > > > > > > > > mapping between a drm_gpu_scheduler and
> > > > > > > > > > drm_sched_entity. At first this
> > > > > > > > > > seems a bit odd but let us explain the reasoning below.
> > > > > > > > > > 
> > > > > > > > > > 1. In XE the submission order from multiple 
> > > > > > > > > > drm_sched_entity is not
> > > > > > > > > > guaranteed to be the same completion even if
> > > > > > > > > > targeting the same hardware
> > > > > > > > > > engine. This is because in XE we have a firmware scheduler, 
> > > > > > > > > > the GuC,
> > > > > > > > > > which allowed to reorder, timeslice, and preempt
> > > > > > > > > > submissions. If a using
> > > > > > > > > > shared drm_gpu_scheduler across multiple
> > > > > > > > > > drm_sched_entity, the TDR falls
> > > > > > > > > > apart as the TDR expects submission order ==
> > > > > > > > > > completion order. Using a
> > > > > > > > > > dedicated drm_gpu_scheduler per drm_sched_entity solve this 
> > > > > > > > > > problem.
> > > > > > > > > > 
> > > > > > > > > > 2. In XE submissions are done via programming a
> > > > > > > > > > ring buffer (circular
> > > > > > > > > > buffer), a drm_gpu_scheduler provides a limit on
> > > > > > > > > > number of jobs, if the
> > > > > > > > > > limit of number jobs is set to RING_SIZE /
> > > > > > > > > > MAX_SIZE_PER_JOB we get flow
> > > > > > > > > > control on the ring for free.
> > > > > > > > > In XE, where does the limitation of MAX_SIZE_PER_JOB come 
> > > > > > > > > from?
> > > > > > > > > 
> > > > > > > > > In Nouveau we currently do have such a limitation as
> > > > > > > > > well, but it is derived from the RING_SIZE, hence
> > > > > > > > > RING_SIZE / MAX_SIZE_PER_JOB would always be 1.
> > > > > > > > > However, I think most jobs won't actually utilize
> > > > > > > > > the whole ring.
> > > > > > > > Well that should probably rather be RING_SIZE /
> > > > > > > > MAX_SIZE_PER_JOB = hw_submission_limit (or even
> > > > > > > > hw_submission_limit - 1 when the hw can't distinct full
> > > > > > > > vs empty ring buffer).
> > > > > > > Not sure if I get you right, let me try to clarify what I
> > > > > > > was trying to say: I wanted to say that in Nouveau
> > > > > > > MAX_SIZE_PER_JOB isn't really limited by anything other than
> > > > > > > the RING_SIZE and hence we'd never allow more than 1 active
> > > > > > > job.
> > > > > > But that lets the hw run dry between submissions. That is
> > > > > > usually a pretty horrible idea for performance.
> > > > > Correct, that's the reason why I said it seems to be more efficient
> > > > > to base ring flow control on the actual size of each incoming job
> > > > > rather than the maximum size of a job.
> > > > > 
> > > > > > > However, it seems to be more efficient to base ring flow
> > > > > > > control on the actual size of each incoming job rather than
> > > > > > > the worst case, namely the maximum size of a job.
> > > > > > That doesn't sounds like a good idea to me. See we don't limit
> > > > > > the number of submitted jobs based on the ring size, but rather
> > > > > > we calculate the ring size based on the number of submitted
> > > > > > jobs.
> > > > > > 
> > > > > My point isn't really about whether we derive the ring size from the
> > > > > job limit or the other way around. It's more about the job size (or
> > > > > its maximum size) being arbitrary.
> > > > > 
> > > > > As mentioned in my reply to Matt:
> > > > > 
> > > > > "In Nouveau, userspace can submit an arbitrary amount of addresses
> > > > > of indirect bufferes containing the ring instructions. The ring on
> > > > > the kernel side takes the addresses of the indirect buffers rather
> > > > > than the instructions themself. Hence, technically there isn't
> > > > > really a limit on the amount of IBs submitted by a job except for
> > > > > the ring size."
> > > > > 
> > > > > So, my point is that I don't really want to limit the job size
> > > > > artificially just to be able to fit multiple jobs into the ring even
> > > > > if they're submitted at their "artificial" maximum size, but rather
> > > > > track how much of the ring the submitted job actually occupies.
> > > > > 
> > > > > > In other words the hw_submission_limit defines the ring size,
> > > > > > not the other way a

Re: [PATCH v2 2/4] drm/bridge: imx: add bridge wrapper driver for i.MX8MP DWC HDMI

2023-08-18 Thread Luca Ceresoli
Hi Lucas,

On Fri, 16 Dec 2022 22:07:40 +0100
Lucas Stach  wrote:

> Add a simple wrapper driver for the DWC HDMI bridge driver that
> implements the few bits that are necessary to abstract the i.MX8MP
> SoC integration.
> 
> Signed-off-by: Lucas Stach 
> Reviewed-by: Laurent Pinchart 
> Tested-by: Marek Vasut 

I realized I had sent my Tested-by to v1 when v2 was already out. So,
in case you still need some encouragement for keeping on with this
series:

[Tested on a custom board using modetest on v6.5-rc6]
Tested-by: Luca Ceresoli 

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


Re: [PATCH v2 4/4] drm/bridge: imx: add driver for HDMI TX Parallel Video Interface

2023-08-18 Thread Luca Ceresoli
Hi Lucas,

On Fri, 16 Dec 2022 22:07:42 +0100
Lucas Stach  wrote:

> This IP block is found in the HDMI subsystem of the i.MX8MP SoC. It has a
> full timing generator and can switch between different video sources. On
> the i.MX8MP however the only supported source is the LCDIF. The block
> just needs to be powered up and told about the polarity of the video
> sync signals to act in bypass mode.
> 
> Signed-off-by: Lucas Stach 
> Tested-by: Marek Vasut 
> ---
>  drivers/gpu/drm/bridge/imx/Kconfig   |   7 +
>  drivers/gpu/drm/bridge/imx/Makefile  |   1 +
>  drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c | 202 +++
>  3 files changed, 210 insertions(+)
>  create mode 100644 drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
> 
> diff --git a/drivers/gpu/drm/bridge/imx/Kconfig 
> b/drivers/gpu/drm/bridge/imx/Kconfig
> index d828d8bfd893..e6cc4000bccd 100644
> --- a/drivers/gpu/drm/bridge/imx/Kconfig
> +++ b/drivers/gpu/drm/bridge/imx/Kconfig
> @@ -53,4 +53,11 @@ config DRM_IMX8MP_DW_HDMI_BRIDGE
> Choose this to enable support for the internal HDMI encoder found
> on the i.MX8MP SoC.
>  
> +config DRM_IMX8MP_HDMI_PVI
> + tristate "i.MX8MP HDMI PVI bridge support"
> + depends on OF
> + help
> +   Choose this to enable support for the internal HDMI TX Parallel
> +   Video Interface found on the i.MX8MP SoC.
> +
>  endif # ARCH_MXC || COMPILE_TEST
> diff --git a/drivers/gpu/drm/bridge/imx/Makefile 
> b/drivers/gpu/drm/bridge/imx/Makefile
> index 03b0074ae538..b0fd56550dad 100644
> --- a/drivers/gpu/drm/bridge/imx/Makefile
> +++ b/drivers/gpu/drm/bridge/imx/Makefile
> @@ -9,3 +9,4 @@ obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK) += imx8qxp-pixel-link.o
>  obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI) += imx8qxp-pxl2dpi.o
>  
>  obj-$(CONFIG_DRM_IMX8MP_DW_HDMI_BRIDGE) += imx8mp-hdmi.o
> +obj-$(CONFIG_DRM_IMX8MP_HDMI_PVI) += imx8mp-hdmi-pvi.o
> diff --git a/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c 
> b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
> new file mode 100644
> index ..30d40c21dabb
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c
> @@ -0,0 +1,202 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/*
> + * Copyright (C) 2022 Pengutronix, Lucas Stach 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define HTX_PVI_CTL  0x0

Personally I would s/CTL/CTRL/, to be consistent with the manual and
thus more search-friendly.

> +#define  PVI_CTL_OP_VSYNC_POLBIT(18)
> +#define  PVI_CTL_OP_HSYNC_POLBIT(17)
> +#define  PVI_CTL_OP_DE_POL   BIT(16)
> +#define  PVI_CTL_INP_VSYNC_POL   BIT(14)
> +#define  PVI_CTL_INP_HSYNC_POL   BIT(13)
> +#define  PVI_CTL_INP_DE_POL  BIT(12)
> +#define  PVI_CTL_INPUT_LCDIF BIT(2)

According to the reference manual there is actually a 2-bit field here:
HTX_PVI_MODE, using bits 2:1, and whose "LCDIF" value is 0b10. Thus
while it obviously won't change the resulting code, it seems more
correct to define this as (2 << 1).

> +static void imx8mp_hdmi_pvi_bridge_enable(struct drm_bridge *bridge,
> +   struct drm_bridge_state *bridge_state)
> +{
> + struct drm_atomic_state *state = bridge_state->base.state;
> + struct imx8mp_hdmi_pvi *pvi = to_imx8mp_hdmi_pvi(bridge);
> + struct drm_connector_state *conn_state;
> + const struct drm_display_mode *mode;
> + struct drm_crtc_state *crtc_state;
> + struct drm_connector *connector;
> + u32 bus_flags, val;
> +
> + connector = drm_atomic_get_new_connector_for_encoder(state, 
> bridge->encoder);
> + conn_state = drm_atomic_get_new_connector_state(state, connector);
> + crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
> +
> + if (WARN_ON(pm_runtime_resume_and_get(pvi->dev)))
> + return;
> +
> + mode = &crtc_state->adjusted_mode;
> +
> + val = PVI_CTL_INPUT_LCDIF;
> +
> + if (mode->flags & DRM_MODE_FLAG_PVSYNC)
> + val |= PVI_CTL_OP_VSYNC_POL | PVI_CTL_INP_VSYNC_POL;
> +
> + if (mode->flags & DRM_MODE_FLAG_PHSYNC)
> + val |= PVI_CTL_OP_HSYNC_POL | PVI_CTL_INP_HSYNC_POL;
> +
> + if (pvi->next_bridge->timings)
> + bus_flags = pvi->next_bridge->timings->input_bus_flags;
> + else if (bridge_state)
> + bus_flags = bridge_state->input_bus_cfg.flags;
> +
> + if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
> + val |= PVI_CTL_OP_DE_POL | PVI_CTL_INP_DE_POL;
> +
> + writel(val, pvi->regs + HTX_PVI_CTL);
> + val |= PVI_CTL_EN;
> + writel(val, pvi->regs + HTX_PVI_CTL);

I guess I'm missing something here: why can't one just write the
register once, with the enable bit set? I tried removing the first
writel() and everything seems to work just the same.

With these fixed:
Reviewed-by: Luca Ceresoli 

And definitely:
[Tested on a custom board using modetest on v6.5-rc6]
Tested-by: Luca Ceresoli 



-- 
Luca

Re: [PATCH v4] drm/sysfs: Link DRM connectors to corresponding Type-C connectors

2023-08-18 Thread Dmitry Baryshkov

On 11/11/2022 11:52, Daniel Vetter wrote:

On Thu, Nov 10, 2022 at 11:33:11AM -0800, Won Chung wrote:

Hi Daniel,

Thank you very much for a review.

On Wed, Nov 9, 2022 at 3:54 AM Daniel Vetter  wrote:


On Tue, Nov 08, 2022 at 06:50:04PM +, Won Chung wrote:

Create a symlink pointing to USB Type-C connector for DRM connectors
when they are created. The link will be created only if the firmware is
able to describe the connection beween the two connectors.


Generic question for this patch:

There can be several typec connectors and several DP connectors. Will 
this patch handle this correctly?


Moreover, if everything is bound through the fwnodes, it might be easier 
to set connector's device fwnode pointer to point to the corresponding 
connector's node. Then one can easily enumerate them without adding new 
uABI.





Currently, even if a display uses a USB Type-C port, there is no way for
the userspace to find which port is used for which display. With the
symlink, display information would be accessible from Type-C connectors
and port information would be accessible from DRM connectors.
Associating the two subsystems, userspace would have potential to expose
and utilize more complex information, such as bandwidth used for a
specific USB Type-C port.

Signed-off-by: Won Chung 
Acked-by: Heikki Krogerus 
---
Changes from v3:
- Append to the commit message on why this patch is needed

Changes from v2:
- Resend the patch to dri-devel list

Changes from v1:
- Fix multiple lines to single line


We seem to be spinning wheels a bit here (or at least I'm missing a lot of
important information from this series alone) with already at v4 but the
fundamentals not answered:

- where's the usb side of this, and anything we need to do in drivers?
   This should all be one series, or if that's too big, then a link in the
   cover letter for where to find all the other pieces


We already have a framework in typec port-mapper.c where it goes
through component devices and runs the bind functions for those with
matching _PLD (physical location of device).
https://elixir.bootlin.com/linux/v5.18.1/source/drivers/usb/typec/port-mapper.c

Currently, USB ports and USB4 ports are added as components to create
a symlink with Type C connector.
USB: 
https://lore.kernel.org/all/20211223082349.45616-1-heikki.kroge...@linux.intel.com/
USB4: https://lore.kernel.org/all/20220418175932.1809770-3-wonch...@google.com/

Since these are already submitted, do you think it would be a good
idea to add the links in the commit message?


Hm yeah explaining this in the commit message with links should be good
enough.

Another thing, will this hit the component nesting problem? With this
change we'll have drm drivers which are both aggregates and components at
the same time, and last time someone tried this it all deadlocked in
component.c.


drm/msm uses components already. It wouldn't be nice to break it in this 
way. Not to mention that it doesn't use ACPI and so port-mapper.c is not 
used on this platform.





- since I'm guessing this is for cros, will this also work on standard
   acpi x86 that are built for windows? arm with dt? Might be answered with
   the full picture


Yes this is for cros, but it should work on any ACPI x86 as long as
_PLD field for Type C connectors and DRM connectors are correctly
added to the firmware.

Since _PLD is ACPI specific, we do not have ARM with DT supported at the moment.
In the future, if we find something similar to _PLD in DT, I think we
can also use that in typec port-mapper for component matching.

Heikki@ Can you correct me if I am incorrect or missing something?


Ok sounds good, would be good to include this in the commit message, too.





- you say this helps userspace, but how? Best way here is to just point at
   the userspace change set that makes use of this link, code explains
   concepts much more precisely than lots of words, and it's also easier to
   review for corner cases that might be missed. That link also needs to be
   in the commit message/cover letter somewhere, so people can find it.


I do not have working code in the userspace yet since there is no
symlink created between Type C connector and DRM connector at the
moment.
If this patch is to go through, ChromeOS will parse the symlink in DRM
to find which Type C port got displays connected.


This isn't how new uapi works, we need to have the userspace together with
the kernel changes. Otherwise ... how can you test that things actually
work before we commit to the kernel change? Freezing down uapi on the
promise that userspace will show up and that we're crossing fingers that
it'll all work is not how we roll in drm.


First use case is metrics collection.
We would like to know which port at which location is most preferred
to be used for displays.
We also want to see how many users charge the system on the same Type
C port as displays.
To answer these types of questions, we need to know which specific
display uses 

Re: [PATCH v2 4/9] drm/sched: Split free_job into own work item

2023-08-18 Thread Matthew Brost
On Fri, Aug 18, 2023 at 07:27:33AM +0200, Christian König wrote:
> Am 17.08.23 um 19:54 schrieb Matthew Brost:
> > On Thu, Aug 17, 2023 at 03:39:40PM +0200, Christian König wrote:
> > > Am 11.08.23 um 04:31 schrieb Matthew Brost:
> > > > Rather than call free_job and run_job in same work item have a dedicated
> > > > work item for each. This aligns with the design and intended use of work
> > > > queues.
> > > I would rather say we should get completely rid of the free_job callback.
> > > 
> > Would we still have work item? e.g. Would we still want to call
> > drm_sched_get_cleanup_job which removes the job from the pending list
> > and adjusts the TDR? Trying to figure out out what this looks like. We
> > probably can't do all of this from an IRQ context.
> > 
> > > Essentially the job is just the container which carries the information
> > > which are necessary before you push it to the hw. The real representation 
> > > of
> > > the submission is actually the scheduler fence.
> > > 
> > Most of the free_jobs call plus drm_sched_job_cleanup + a put on job. In
> > Xe this cannot be called from an IRQ context either.
> > 
> > I'm just confused what exactly you are suggesting here.
> 
> To summarize on one sentence: Instead of the job we keep the scheduler and
> hardware fences around after pushing the job to the hw.
> 
> The free_job callback would then be replaced by dropping the reference on
> the scheduler and hw fence.
> 
> Would that work for you?
> 

I don't think so for a few reasons.

The job and hw fence are different structures (also different allocs too)
for a reason. The job referenced until it is complete (hw fence is
signaled) and the free_job is called. This reference is needed for the
TDR to work properly and also some reset flows too. Also in Xe some of
things done in free_job cannot be from an IRQ context, hence calling
this from the scheduler worker is rather helpful.

The HW fence can live for longer as it can be installed in dma-resv
slots, syncobjs, etc... If the job and hw fence are combined now we
holding on the memory for the longer and perhaps at the mercy of the
user. We also run the risk of the final put being done from an IRQ
context which again wont work in Xe as it is currently coded. Lastly 2
jobs from the same scheduler could do the final put in parallel, so
rather than having free_job serialized by the worker now multiple jobs
are freeing themselves at the same time. This might not be an issue but
adds another level of raceyness that needs to be accounted for. None of
this sounds desirable to me.

FWIW what you suggesting sounds like how the i915 did things
(i915_request and hw fence in 1 memory alloc) and that turned out to be
a huge mess. As rule of thumb I generally do the opposite of whatever
the i915 did.

Matt

> Christian.
> 
> > 
> > Matt
> > 
> > > All the lifetime issues we had came from ignoring this fact and I think we
> > > should push for fixing this design up again.
> > > 
> > > Regards,
> > > Christian.
> > > 
> > > > Signed-off-by: Matthew Brost 
> > > > ---
> > > >drivers/gpu/drm/scheduler/sched_main.c | 137 
> > > > ++---
> > > >include/drm/gpu_scheduler.h|   8 +-
> > > >2 files changed, 106 insertions(+), 39 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
> > > > b/drivers/gpu/drm/scheduler/sched_main.c
> > > > index cede47afc800..b67469eac179 100644
> > > > --- a/drivers/gpu/drm/scheduler/sched_main.c
> > > > +++ b/drivers/gpu/drm/scheduler/sched_main.c
> > > > @@ -213,11 +213,12 @@ void drm_sched_rq_remove_entity(struct 
> > > > drm_sched_rq *rq,
> > > > * drm_sched_rq_select_entity_rr - Select an entity which could 
> > > > provide a job to run
> > > > *
> > > > * @rq: scheduler run queue to check.
> > > > + * @dequeue: dequeue selected entity
> > > > *
> > > > * Try to find a ready entity, returns NULL if none found.
> > > > */
> > > >static struct drm_sched_entity *
> > > > -drm_sched_rq_select_entity_rr(struct drm_sched_rq *rq)
> > > > +drm_sched_rq_select_entity_rr(struct drm_sched_rq *rq, bool dequeue)
> > > >{
> > > > struct drm_sched_entity *entity;
> > > > @@ -227,8 +228,10 @@ drm_sched_rq_select_entity_rr(struct drm_sched_rq 
> > > > *rq)
> > > > if (entity) {
> > > > list_for_each_entry_continue(entity, &rq->entities, 
> > > > list) {
> > > > if (drm_sched_entity_is_ready(entity)) {
> > > > -   rq->current_entity = entity;
> > > > -   reinit_completion(&entity->entity_idle);
> > > > +   if (dequeue) {
> > > > +   rq->current_entity = entity;
> > > > +   
> > > > reinit_completion(&entity->entity_idle);
> > > > +   }
> > > > spin_unlock(&rq->lock);
> > > >  

[PATCH] drm/amd/display: fix mode scaling (RMX_.*)

2023-08-18 Thread Hamza Mahfooz
As made mention of in commit 4a2df0d1f28e ("drm/amd/display: Fixed
non-native modes not lighting up"), we shouldn't call
drm_mode_set_crtcinfo() once the crtc timings have been decided. Since,
it can cause settings to be unintentionally overwritten. So, since
dm_state is never NULL now, we can use old_stream to determine if we
should call drm_mode_set_crtcinfo() because we only need to set the crtc
timing parameters for entirely new streams.

Cc: Harry Wentland 
Cc: Rodrigo Siqueira 
Fixes: 712237a4a1b4 ("drm/amd/display: Always set crtcinfo from 
create_stream_for_sink")
Signed-off-by: Hamza Mahfooz 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 3b27b7742854..e9aff5014e39 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6035,7 +6035,7 @@ create_stream_for_sink(struct amdgpu_dm_connector 
*aconnector,
 
if (recalculate_timing)
drm_mode_set_crtcinfo(&saved_mode, 0);
-   else
+   else if (!old_stream)
drm_mode_set_crtcinfo(&mode, 0);
 
/*
-- 
2.41.0



[PATCH 2/2] drivers/tidss: Add support for AM62A7 DSS

2023-08-18 Thread Aradhya Bhatia
Add support for the DSS controller on TI's AM62A7 SoC in the tidss
driver.

This contrller has 2 video pipelines that can render 2 video planes on
over a screen, using the overlay managers. The output of the DSS comes
from video port 2 (VP2) in the form of RGB88 DPI signals, while the VP1
is tied off inside the SoC.

Signed-off-by: Aradhya Bhatia 
---
 drivers/gpu/drm/tidss/tidss_dispc.c | 53 +
 drivers/gpu/drm/tidss/tidss_dispc.h |  2 ++
 drivers/gpu/drm/tidss/tidss_drv.c   |  1 +
 3 files changed, 56 insertions(+)

diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c 
b/drivers/gpu/drm/tidss/tidss_dispc.c
index 9d9dee7abaef..0e2d55d9a0d7 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.c
+++ b/drivers/gpu/drm/tidss/tidss_dispc.c
@@ -322,6 +322,54 @@ const struct dispc_features dispc_am625_feats = {
.vid_order = { 1, 0 },
 };
 
+const struct dispc_features dispc_am62a7_feats = {
+   .max_pclk_khz = {
+   [DISPC_VP_DPI] = 165000,
+   },
+
+   .scaling = {
+   .in_width_max_5tap_rgb = 1280,
+   .in_width_max_3tap_rgb = 2560,
+   .in_width_max_5tap_yuv = 2560,
+   .in_width_max_3tap_yuv = 4096,
+   .upscale_limit = 16,
+   .downscale_limit_5tap = 4,
+   .downscale_limit_3tap = 2,
+   /*
+* The max supported pixel inc value is 255. The value
+* of pixel inc is calculated like this: 1+(xinc-1)*bpp.
+* The maximum bpp of all formats supported by the HW
+* is 8. So the maximum supported xinc value is 32,
+* because 1+(32-1)*8 < 255 < 1+(33-1)*4.
+*/
+   .xinc_max = 32,
+   },
+
+   .subrev = DISPC_AM62A7,
+
+   .common = "common",
+   .common_regs = tidss_am65x_common_regs,
+
+   .num_vps = 2,
+   .vp_name = { "vp1", "vp2" },
+   .ovr_name = { "ovr1", "ovr2" },
+   .vpclk_name =  { "vp1", "vp2" },
+   .vp_bus_type = { DISPC_VP_INTERNAL, DISPC_VP_DPI },
+
+   .vp_feat = { .color = {
+   .has_ctm = true,
+   .gamma_size = 256,
+   .gamma_type = TIDSS_GAMMA_8BIT,
+   },
+   },
+
+   .num_planes = 2,
+   /* note: vid is plane_id 0 and vidl1 is plane_id 1 */
+   .vid_name = { "vid", "vidl1" },
+   .vid_lite = { false, true, },
+   .vid_order = { 1, 0 },
+};
+
 static const u16 *dispc_common_regmap;
 
 struct dss_vp_data {
@@ -823,6 +871,7 @@ dispc_irq_t dispc_read_and_clear_irqstatus(struct 
dispc_device *dispc)
switch (dispc->feat->subrev) {
case DISPC_K2G:
return dispc_k2g_read_and_clear_irqstatus(dispc);
+   case DISPC_AM62A7:
case DISPC_AM625:
case DISPC_AM65X:
case DISPC_J721E:
@@ -839,6 +888,7 @@ void dispc_set_irqenable(struct dispc_device *dispc, 
dispc_irq_t mask)
case DISPC_K2G:
dispc_k2g_set_irqenable(dispc, mask);
break;
+   case DISPC_AM62A7:
case DISPC_AM625:
case DISPC_AM65X:
case DISPC_J721E:
@@ -1330,6 +1380,7 @@ void dispc_ovr_set_plane(struct dispc_device *dispc, u32 
hw_plane,
dispc_k2g_ovr_set_plane(dispc, hw_plane, hw_videoport,
x, y, layer);
break;
+   case DISPC_AM62A7:
case DISPC_AM625:
case DISPC_AM65X:
dispc_am65x_ovr_set_plane(dispc, hw_plane, hw_videoport,
@@ -2249,6 +2300,7 @@ static void dispc_plane_init(struct dispc_device *dispc)
case DISPC_K2G:
dispc_k2g_plane_init(dispc);
break;
+   case DISPC_AM62A7:
case DISPC_AM625:
case DISPC_AM65X:
case DISPC_J721E:
@@ -2356,6 +2408,7 @@ static void dispc_vp_write_gamma_table(struct 
dispc_device *dispc,
case DISPC_K2G:
dispc_k2g_vp_write_gamma_table(dispc, hw_videoport);
break;
+   case DISPC_AM62A7:
case DISPC_AM625:
case DISPC_AM65X:
dispc_am65x_vp_write_gamma_table(dispc, hw_videoport);
diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h 
b/drivers/gpu/drm/tidss/tidss_dispc.h
index 33ac5ad7a423..2aa1c814ea2a 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.h
+++ b/drivers/gpu/drm/tidss/tidss_dispc.h
@@ -59,6 +59,7 @@ enum dispc_vp_bus_type {
 
 enum dispc_dss_subrevision {
DISPC_K2G,
+   DISPC_AM62A7,
DISPC_AM625,
DISPC_AM65X,
DISPC_J721E,
@@ -88,6 +89,7 @@ struct dispc_features {
 
 extern const struct dispc_features dispc_k2g_feats;
 extern const struct dispc_features dispc_am625_feats;
+extern const struct dispc_features dispc_am62a7_feats;
 extern const struct dispc_features dispc_am65x_feats;
 extern const struct dispc_features dispc_j721e_feats;
 
diff --git a/drivers/gpu/drm/tidss/tidss_drv.c 
b/drivers/gpu/drm/tidss/tidss_drv.c
index 4d063eb9c

Re: [PATCH 1/1] drm/fourcc: Add documentation about software color conversion.

2023-08-18 Thread Pekka Paalanen
On Thu, 10 Aug 2023 09:45:27 +0200
Maxime Ripard  wrote:

> Hi
> 
> On Mon, Aug 07, 2023 at 03:45:15PM +0200, Jocelyn Falempe wrote:
> > After discussions on IRC, the consensus is that the DRM drivers should
> > not do software color conversion, and only advertise the supported formats.
> > Update the doc accordingly so that the rule and exceptions are clear for
> > everyone.
> > 
> > Signed-off-by: Jocelyn Falempe 
> > ---
> >  include/uapi/drm/drm_fourcc.h | 7 +++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
> > index 8db7fd3f743e..00a29152da9f 100644
> > --- a/include/uapi/drm/drm_fourcc.h
> > +++ b/include/uapi/drm/drm_fourcc.h
> > @@ -38,6 +38,13 @@ extern "C" {
> >   * fourcc code, a Format Modifier may optionally be provided, in order to
> >   * further describe the buffer's format - for example tiling or 
> > compression.
> >   *
> > + * DRM drivers should not do software color conversion, and only advertise 
> > the
> > + * format they support in hardware. But there are two exceptions:  
> 
> I would do a bullet list here:
> https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#lists-and-quote-like-blocks
> 
> > + * The first is to support XRGB if the hardware doesn't support it, 
> > because
> > + * it's the de facto standard for userspace applications.  
> 
> We can also provide a bit more context here, something like:
> 
> All drivers must support XRGB, even if the hardware cannot support
> it. This has become the de-facto standard and a lot of user-space assume
> it will be present.
> 
> > + * The second is to drop the unused bits when sending the data to the 
> > hardware,
> > + * to improve the bandwidth, like dropping the "X" in XRGB.  
> 
> I think it can be made a bit more generic, with something like:
> 
> Any driver is free to modify its internal representation of the format,
> as long as it doesn't alter the visible content in any way. An example
> would be to drop the padding component from a format to save some memory
> bandwidth.

Hi,

to my understanding and desire, the rule to not "fake" pixel format
support is strictly related to performance. When a KMS client does a
page flip, it usually does not expect a massive amount of CPU or GPU
work to occur just because of the flip. A name for such work is "copy",
referring to any kind of copying of large amounts of pixel data,
including a format conversion or not.

This is especially important with GPU rendering and hardware video
playback systems, where any such copy could destroy the usability of
the whole system. This is the main reason why KMS must not do any
expensive processing unexpectedly (as in, not documented in UAPI).
Doing any kind of copy could cause a vblank to be missed, ruining
display timings.

I believe the above is the spirit of the rule. Then there will be
exceptions. I'd like to think that everything below (except for
XRGB) can be derived from the above with common sense - that's what
I did.

XRGB support is the prime exception. I suspect it originates from
the legacy KMS UAPI, and the practise that XRGB has been widely
supported always. This makes it plausible for userspace to exist that
cannot produce any other format. Hence, it is good to support XRGB
through a conversion (copy) in the kernel for dumb buffers (that is,
for software rendered framebuffers). I would be very hesitant to extend
this exception to GPU rendered buffers, but OTOH if you have a GPU,
presumably you also have a display controller capable of scanning out
what the GPU renders, so you wouldn't even consider copying under the
hood.

DRM devices that cannot directly scan out buffers at all are a whole
category of exceptions. They include USB display adapters (literal USB,
not USB-C alt mode), perhaps networked and wireless displays, VKMS
which does everything in software, and so on. They simply have to
process the bulk pixel data with a CPU one way or another, and
hopefully they make use of damage rectangles to minimise the work.

Old-school special cursor planes may have been using special pixel
formats that may not be supported by userspace. Cursors are usually
small images and they can make a huge performance impact, so it makes
sense to support ARGB even with a CPU conversion.

Then we have display controllers without GPUs. Everything is
software-rendered. If it so happens that software rendering into sysram
and then copying (with conversion) into VRAM is more performant than
rendering into VRAM, then the copy is well justified.

Software-rendering into sysram and then copying into VRAM is actually
so commonly preferred, that KMS has a special flag to suggest userspace
does it: DRM_CAP_DUMB_PREFER_SHADOW [1]. A well-behaved
software-rendering KMS client checks this flag and honours it. If a
driver both sets the flag, and copies itself, then that's two copies
for each flip. The driver's copy is unexpected, but is the

[Bug 217664] Laptop doesnt wake up from suspend mode.

2023-08-18 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=217664

--- Comment #20 from Alex Deucher (alexdeuc...@gmail.com) ---
(In reply to popus_czy_to_ty from comment #18)
> banned all in grub ( GRUB_CMDLINE_LINUX_DEFAULT="quiet splash
> module_blacklist=nvidia,nvidia-current,nvidia_drm,nvidia_uvm,nvidia_modeset,
> nouveau" )
> still doesnt wake up

All GPU drivers, including amdgpu.  I'm trying to understand if this is a
general platform issue or something specific to one of the GPUs.

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

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

[PATCH 0/2] Add DSS support for TI AM62A7 SoC

2023-08-18 Thread Aradhya Bhatia
This patch series adds a new compatible for the Display SubSystem (DSS)
controller on TI's AM62A7 SoC. It further adds the required support, for
the same, in the tidss driver.

The DSS controller is similar to the recently added AM625 DSS, with the
key difference being the absence of VP1 output on the SoC. The VP1 in
AM62A7 DSS is tied off and cannot be used, unlike in AM625, where the
VP1 was connected to 2 OLDI TXes. The video pipeline that corresponds to
VP1 still exists and can be used to overlay planes on the VP2's primary
plane. This can be done using the overlay managers inside the SoC.
Moreover, DSS VP2 can output Full-HD RGB888 DPI video signals.

I have tested these patches on AM62A7 SK-EVM, which converts DPI signals
to HDMI on the platform using the Sil9022A HDMI transmitter. All the
patches, required to enable display on AM62A7-SK, can be found on my
github fork[0] in the branch "next_am62a".

Regards
Aradhya

[0]: https://github.com/aradhya07/linux-ab/tree/next_am62a


Aradhya Bhatia (2):
  dt-bindings: display: ti: Add support for am62a7 dss
  drivers/tidss: Add support for AM62A7 DSS

 .../bindings/display/ti/ti,am65x-dss.yaml | 14 +
 drivers/gpu/drm/tidss/tidss_dispc.c   | 53 +++
 drivers/gpu/drm/tidss/tidss_dispc.h   |  2 +
 drivers/gpu/drm/tidss/tidss_drv.c |  1 +
 4 files changed, 70 insertions(+)


base-commit: 47762f08697484cf0c2f2904b8c52375ed26c8cb
-- 
2.40.1



Re: [PATCH] drm/amd/display: fix mode scaling (RMX_.*)

2023-08-18 Thread Alex Deucher
On Fri, Aug 18, 2023 at 9:25 AM Hamza Mahfooz  wrote:
>
> As made mention of in commit 4a2df0d1f28e ("drm/amd/display: Fixed
> non-native modes not lighting up"), we shouldn't call
> drm_mode_set_crtcinfo() once the crtc timings have been decided. Since,
> it can cause settings to be unintentionally overwritten. So, since
> dm_state is never NULL now, we can use old_stream to determine if we
> should call drm_mode_set_crtcinfo() because we only need to set the crtc
> timing parameters for entirely new streams.
>
> Cc: Harry Wentland 
> Cc: Rodrigo Siqueira 
> Fixes: 712237a4a1b4 ("drm/amd/display: Always set crtcinfo from 
> create_stream_for_sink")
> Signed-off-by: Hamza Mahfooz 

Does this fix:
https://gitlab.freedesktop.org/drm/amd/-/issues/2783
If so, add a link tag for that.

Alex

> ---
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 3b27b7742854..e9aff5014e39 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -6035,7 +6035,7 @@ create_stream_for_sink(struct amdgpu_dm_connector 
> *aconnector,
>
> if (recalculate_timing)
> drm_mode_set_crtcinfo(&saved_mode, 0);
> -   else
> +   else if (!old_stream)
> drm_mode_set_crtcinfo(&mode, 0);
>
> /*
> --
> 2.41.0
>


Re: [PATCH v2 1/9] drm/sched: Convert drm scheduler to use a work queue rather than kthread

2023-08-18 Thread Danilo Krummrich

On 8/17/23 18:17, Christian König wrote:

Am 17.08.23 um 14:48 schrieb Danilo Krummrich:

On 8/17/23 15:35, Christian König wrote:

Am 17.08.23 um 13:13 schrieb Danilo Krummrich:

On 8/17/23 07:33, Christian König wrote:

[SNIP]
My proposal would be to just keep the hw_submission_limit (maybe 
rename it to submission_unit_limit) and add a submission_units 
field to struct drm_sched_job. By default a jobs submission_units 
field would be 0 and the scheduler would behave the exact same way 
as it does now.


Accordingly, jobs with submission_units > 1 would contribute more 
than one unit to the submission_unit_limit.


What do you think about that?


I think you are approaching this from the completely wrong side.


First of all, thanks for keeping up the discussion - I appreciate it. 
Some more comments / questions below.




See the UAPI needs to be stable, so you need a maximum job size 
otherwise it can happen that a combination of large and small 
submissions work while a different combination doesn't.


How is this related to the uAPI being stable? What do you mean by 
'stable' in this context?


Stable is in you don't get indifferent behavior, not stable is in the 
sense of backward compatibility. Sorry for the confusing wording :)




The Nouveau uAPI allows userspace to pass EXEC jobs by supplying the 
ring ID (channel), in-/out-syncs and a certain amount of indirect push 
buffers. The amount of IBs per job is limited by the amount of IBs 
fitting into the ring. Just to be clear, when I say 'job size' I mean 
the amount of IBs per job.


Well that more or less sounds identical to all other hardware I know of, 
e.g. AMD, Intel and the different ARM chips seem to all work like this. 
But on those drivers the job size limit is not the ring size, but rather 
a fixed value (at least as far as I know).




Maybe I should also mention that the rings we are talking about are 
software rings managed by a firmware scheduler. We can have an 
arbitrary amount of software rings and even multiple ones per FD.


Given a constant ring size I really don't see why I should limit the 
maximum amount of IBs userspace can push per job just to end up with a 
hw_submission_limit > 1.


For example, let's just assume the ring can take 128 IBs, why would I 
limit userspace to submit just e.g. 16 IBs at a time, such that the 
hw_submission_limit becomes 8?


Well the question is what happens when you have two submissions back to 
back which use more than halve of the ring buffer?


I only see two possible outcomes:
1. You return -EBUSY (or similar) error code indicating the the hw can't 
receive more commands.

2. Wait on previously pushed commands to be executed.
(3. Your driver crash because you accidentally overwrite stuff in the 
ring buffer which is still executed. I just assume that's prevented).


Resolution #1 with -EBUSY is actually something the UAPI should not do, 
because your UAPI then depends on the specific timing of submissions 
which is a really bad idea.


Resolution #2 is usually bad because it forces the hw to run dry between 
submission and so degrade performance.


I agree, that is a good reason for at least limiting the maximum job 
size to half of the ring size.


However, there could still be cases where two subsequent jobs are 
submitted with just a single IB, which as is would still block 
subsequent jobs to be pushed to the ring although there is still plenty 
of space. Depending on the (CPU) scheduler latency, such a case can let 
the HW run dry as well.


Surely, we could just continue decrease the maximum job size even 
further, but this would result in further overhead on user and kernel 
for larger IB counts. Tracking the actual job size seems to be the 
better solution for drivers where the job size can vary over a rather 
huge range.


- Danilo





What is the advantage of doing that, rather than letting userspace 
submit *up to* 128 IBs per job and just letting the scheduler push IBs 
to the ring as long as there's actually space left on the ring?


Predictable behavior I think. Basically you want organize things so that 
the hw is at least kept busy all the time without depending on actual 
timing.






So what you usually do, and this is driver independent because simply 
a requirement of the UAPI, is that you say here that's my maximum job 
size as well as the number of submission which should be pushed to 
the hw at the same time. And then get the resulting ring size by the 
product of the two.


Given the above, how is that a requirement of the uAPI?


The requirement of the UAPI is actually pretty simple: You should get 
consistent results, independent of the timing (at least as long as you 
don't do stuff in parallel).


Otherwise you can run into issues when on a certain configuration stuff 
suddenly runs faster or slower than expected. In other words you should 
not depend on that stuff finishes in a certain amount of time.






That the ring in this use case can't be fully ut

RE: [PATCH 7/7] drm: adv7511: Add hpd_override_enable feature bit to struct adv7511_chip_info

2023-08-18 Thread Biju Das
Hi Adam Ford,

Thanks for the feedback.

> Subject: Re: [PATCH 7/7] drm: adv7511: Add hpd_override_enable feature bit
> to struct adv7511_chip_info
> 
> On Sun, Aug 13, 2023 at 1:06 PM Biju Das 
> wrote:
> >
> > As per spec, it is allowed to pulse the HPD signal to indicate that
> > the EDID information has changed. Some monitors do this when they wake
> > up from standby or are enabled. When the HPD goes low the adv7511 is
> > reset and the outputs are disabled which might cause the monitor to go
> > to standby again. To avoid this we ignore the HPD pin for the first
> > few seconds after enabling the output. On the other hand,
> > adv7535 require to enable HPD Override bit for proper HPD.
> >
> > Add hpd_override_enable feature bit to struct adv7511_chip_info to
> > handle this scenario.
> >
> > While at it, drop the enum adv7511_type as it is unused.
> 
> It seems like dropping adv7511_type is unrelated to the rest of the patch,
> and I think it should be split from this into its own patch

With this patch, there is no user for adv7511_type that is the
reason it is added here. I thought that is the common practice.

Please correct me if that is not the case.

Cheers,
Biju

> 
> adam
> >
> > Signed-off-by: Biju Das 
> > ---
> >  drivers/gpu/drm/bridge/adv7511/adv7511.h |  8 +---
> >  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 12 +---
> >  2 files changed, 6 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> > b/drivers/gpu/drm/bridge/adv7511/adv7511.h
> > index 627531f48f84..c523ac4c9bc8 100644
> > --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
> > @@ -325,22 +325,16 @@ struct adv7511_video_config {
> > struct hdmi_avi_infoframe avi_infoframe;  };
> >
> > -enum adv7511_type {
> > -   ADV7511,
> > -   ADV7533,
> > -   ADV7535,
> > -};
> > -
> >  #define ADV7511_MAX_ADDRS 3
> >
> >  struct adv7511_chip_info {
> > -   enum adv7511_type type;
> > unsigned long max_mode_clock;
> > unsigned long max_lane_freq;
> > const char * const *supply_names;
> > unsigned int num_supplies;
> > unsigned has_dsi:1;
> > unsigned link_config:1;
> > +   unsigned hpd_override_enable:1;
> >  };
> >
> >  struct adv7511 {
> > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> > b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> > index 6974c267b1d5..7b06a0a21685 100644
> > --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> > @@ -354,7 +354,7 @@ static void __adv7511_power_on(struct adv7511
> *adv7511)
> >  * first few seconds after enabling the output. On the other hand
> >  * adv7535 require to enable HPD Override bit for proper HPD.
> >  */
> > -   if (adv7511->info->type == ADV7535)
> > +   if (adv7511->info->hpd_override_enable)
> > regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
> >ADV7535_REG_POWER2_HPD_OVERRIDE,
> >ADV7535_REG_POWER2_HPD_OVERRIDE);
> > @@ -381,7 +381,7 @@ static void adv7511_power_on(struct adv7511
> > *adv7511)  static void __adv7511_power_off(struct adv7511 *adv7511)  {
> > /* TODO: setup additional power down modes */
> > -   if (adv7511->info->type == ADV7535)
> > +   if (adv7511->info->hpd_override_enable)
> > regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
> >ADV7535_REG_POWER2_HPD_OVERRIDE,
> > 0);
> >
> > @@ -682,7 +682,7 @@ adv7511_detect(struct adv7511 *adv7511, struct
> drm_connector *connector)
> > status = connector_status_disconnected;
> > } else {
> > /* Renable HPD sensing */
> > -   if (adv7511->info->type == ADV7535)
> > +   if (adv7511->info->hpd_override_enable)
> > regmap_update_bits(adv7511->regmap,
> ADV7511_REG_POWER2,
> >
> ADV7535_REG_POWER2_HPD_OVERRIDE,
> >
> > ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -1360,14 +1360,12 @@ static void
> > adv7511_remove(struct i2c_client *i2c)  }
> >
> >  static const struct adv7511_chip_info adv7511_chip_info = {
> > -   .type = ADV7511,
> > .supply_names = adv7511_supply_names,
> > .num_supplies = ARRAY_SIZE(adv7511_supply_names),
> > .link_config = 1
> >  };
> >
> >  static const struct adv7511_chip_info adv7533_chip_info = {
> > -   .type = ADV7533,
> > .max_mode_clock = 8,
> > .max_lane_freq = 80,
> > .supply_names = adv7533_supply_names, @@ -1376,12 +1374,12 @@
> > static const struct adv7511_chip_info adv7533_chip_info = {  };
> >
> >  static const struct adv7511_chip_info adv7535_chip_info = {
> > -   .type = ADV7535,
> > .max_mode_clock = 148500,
> > .max_lane_freq = 891000,
> > .supply_names = adv7533_suppl

Re: [PATCH 7/7] drm: adv7511: Add hpd_override_enable feature bit to struct adv7511_chip_info

2023-08-18 Thread Adam Ford
On Fri, Aug 18, 2023 at 8:35 AM Biju Das  wrote:
>
> Hi Adam Ford,
>
> Thanks for the feedback.
>
> > Subject: Re: [PATCH 7/7] drm: adv7511: Add hpd_override_enable feature bit
> > to struct adv7511_chip_info
> >
> > On Sun, Aug 13, 2023 at 1:06 PM Biju Das 
> > wrote:
> > >
> > > As per spec, it is allowed to pulse the HPD signal to indicate that
> > > the EDID information has changed. Some monitors do this when they wake
> > > up from standby or are enabled. When the HPD goes low the adv7511 is
> > > reset and the outputs are disabled which might cause the monitor to go
> > > to standby again. To avoid this we ignore the HPD pin for the first
> > > few seconds after enabling the output. On the other hand,
> > > adv7535 require to enable HPD Override bit for proper HPD.
> > >
> > > Add hpd_override_enable feature bit to struct adv7511_chip_info to
> > > handle this scenario.
> > >
> > > While at it, drop the enum adv7511_type as it is unused.
> >
> > It seems like dropping adv7511_type is unrelated to the rest of the patch,
> > and I think it should be split from this into its own patch
>
> With this patch, there is no user for adv7511_type that is the
> reason it is added here. I thought that is the common practice.
>
I wasn't sure.

> Please correct me if that is not the case.

I'll defer to the maintainers.  In general I like the series because
it reduces the number of compare evaluations.  I'll try to run some
tests on a board that I have with a adv7535 this weekend.

adam
>
> Cheers,
> Biju
>
> >
> > adam
> > >
> > > Signed-off-by: Biju Das 
> > > ---
> > >  drivers/gpu/drm/bridge/adv7511/adv7511.h |  8 +---
> > >  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 12 +---
> > >  2 files changed, 6 insertions(+), 14 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> > > b/drivers/gpu/drm/bridge/adv7511/adv7511.h
> > > index 627531f48f84..c523ac4c9bc8 100644
> > > --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> > > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
> > > @@ -325,22 +325,16 @@ struct adv7511_video_config {
> > > struct hdmi_avi_infoframe avi_infoframe;  };
> > >
> > > -enum adv7511_type {
> > > -   ADV7511,
> > > -   ADV7533,
> > > -   ADV7535,
> > > -};
> > > -
> > >  #define ADV7511_MAX_ADDRS 3
> > >
> > >  struct adv7511_chip_info {
> > > -   enum adv7511_type type;
> > > unsigned long max_mode_clock;
> > > unsigned long max_lane_freq;
> > > const char * const *supply_names;
> > > unsigned int num_supplies;
> > > unsigned has_dsi:1;
> > > unsigned link_config:1;
> > > +   unsigned hpd_override_enable:1;
> > >  };
> > >
> > >  struct adv7511 {
> > > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> > > b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> > > index 6974c267b1d5..7b06a0a21685 100644
> > > --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> > > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> > > @@ -354,7 +354,7 @@ static void __adv7511_power_on(struct adv7511
> > *adv7511)
> > >  * first few seconds after enabling the output. On the other hand
> > >  * adv7535 require to enable HPD Override bit for proper HPD.
> > >  */
> > > -   if (adv7511->info->type == ADV7535)
> > > +   if (adv7511->info->hpd_override_enable)
> > > regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
> > >ADV7535_REG_POWER2_HPD_OVERRIDE,
> > >ADV7535_REG_POWER2_HPD_OVERRIDE);
> > > @@ -381,7 +381,7 @@ static void adv7511_power_on(struct adv7511
> > > *adv7511)  static void __adv7511_power_off(struct adv7511 *adv7511)  {
> > > /* TODO: setup additional power down modes */
> > > -   if (adv7511->info->type == ADV7535)
> > > +   if (adv7511->info->hpd_override_enable)
> > > regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
> > >ADV7535_REG_POWER2_HPD_OVERRIDE,
> > > 0);
> > >
> > > @@ -682,7 +682,7 @@ adv7511_detect(struct adv7511 *adv7511, struct
> > drm_connector *connector)
> > > status = connector_status_disconnected;
> > > } else {
> > > /* Renable HPD sensing */
> > > -   if (adv7511->info->type == ADV7535)
> > > +   if (adv7511->info->hpd_override_enable)
> > > regmap_update_bits(adv7511->regmap,
> > ADV7511_REG_POWER2,
> > >
> > ADV7535_REG_POWER2_HPD_OVERRIDE,
> > >
> > > ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -1360,14 +1360,12 @@ static void
> > > adv7511_remove(struct i2c_client *i2c)  }
> > >
> > >  static const struct adv7511_chip_info adv7511_chip_info = {
> > > -   .type = ADV7511,
> > > .supply_names = adv7511_supply_names,
> > > .num_supplies = ARRAY_SIZE(adv7511_supply_names),
> > > .link_config = 1
> > >  };
> > >
> > >  static const struct adv

Re: [PATCH v2 1/9] drm/sched: Convert drm scheduler to use a work queue rather than kthread

2023-08-18 Thread Danilo Krummrich

On 8/18/23 14:49, Matthew Brost wrote:

On Fri, Aug 18, 2023 at 07:40:41AM +0200, Christian König wrote:

Am 18.08.23 um 05:08 schrieb Matthew Brost:

On Thu, Aug 17, 2023 at 01:13:31PM +0200, Danilo Krummrich wrote:

On 8/17/23 07:33, Christian König wrote:

Am 16.08.23 um 18:33 schrieb Danilo Krummrich:

On 8/16/23 16:59, Christian König wrote:

Am 16.08.23 um 14:30 schrieb Danilo Krummrich:

On 8/16/23 16:05, Christian König wrote:

Am 16.08.23 um 13:30 schrieb Danilo Krummrich:

Hi Matt,

On 8/11/23 04:31, Matthew Brost wrote:

In XE, the new Intel GPU driver, a choice has made to have a 1 to 1
mapping between a drm_gpu_scheduler and
drm_sched_entity. At first this
seems a bit odd but let us explain the reasoning below.

1. In XE the submission order from multiple drm_sched_entity is not
guaranteed to be the same completion even if
targeting the same hardware
engine. This is because in XE we have a firmware scheduler, the GuC,
which allowed to reorder, timeslice, and preempt
submissions. If a using
shared drm_gpu_scheduler across multiple
drm_sched_entity, the TDR falls
apart as the TDR expects submission order ==
completion order. Using a
dedicated drm_gpu_scheduler per drm_sched_entity solve this problem.

2. In XE submissions are done via programming a
ring buffer (circular
buffer), a drm_gpu_scheduler provides a limit on
number of jobs, if the
limit of number jobs is set to RING_SIZE /
MAX_SIZE_PER_JOB we get flow
control on the ring for free.

In XE, where does the limitation of MAX_SIZE_PER_JOB come from?

In Nouveau we currently do have such a limitation as
well, but it is derived from the RING_SIZE, hence
RING_SIZE / MAX_SIZE_PER_JOB would always be 1.
However, I think most jobs won't actually utilize
the whole ring.

Well that should probably rather be RING_SIZE /
MAX_SIZE_PER_JOB = hw_submission_limit (or even
hw_submission_limit - 1 when the hw can't distinct full
vs empty ring buffer).

Not sure if I get you right, let me try to clarify what I
was trying to say: I wanted to say that in Nouveau
MAX_SIZE_PER_JOB isn't really limited by anything other than
the RING_SIZE and hence we'd never allow more than 1 active
job.

But that lets the hw run dry between submissions. That is
usually a pretty horrible idea for performance.

Correct, that's the reason why I said it seems to be more efficient
to base ring flow control on the actual size of each incoming job
rather than the maximum size of a job.


However, it seems to be more efficient to base ring flow
control on the actual size of each incoming job rather than
the worst case, namely the maximum size of a job.

That doesn't sounds like a good idea to me. See we don't limit
the number of submitted jobs based on the ring size, but rather
we calculate the ring size based on the number of submitted
jobs.


My point isn't really about whether we derive the ring size from the
job limit or the other way around. It's more about the job size (or
its maximum size) being arbitrary.

As mentioned in my reply to Matt:

"In Nouveau, userspace can submit an arbitrary amount of addresses
of indirect bufferes containing the ring instructions. The ring on
the kernel side takes the addresses of the indirect buffers rather
than the instructions themself. Hence, technically there isn't
really a limit on the amount of IBs submitted by a job except for
the ring size."

So, my point is that I don't really want to limit the job size
artificially just to be able to fit multiple jobs into the ring even
if they're submitted at their "artificial" maximum size, but rather
track how much of the ring the submitted job actually occupies.


In other words the hw_submission_limit defines the ring size,
not the other way around. And you usually want the
hw_submission_limit as low as possible for good scheduler
granularity and to avoid extra overhead.

I don't think you really mean "as low as possible", do you?

No, I do mean as low as possible or in other words as few as possible.

Ideally the scheduler would submit only the minimum amount of work to
the hardware to keep the hardware busy. >
The hardware seems to work mostly the same for all vendors, but you
somehow seem to think that filling the ring is somehow beneficial which
is really not the case as far as I can see.

I think that's a misunderstanding. I'm not trying to say that it is *always*
beneficial to fill up the ring as much as possible. But I think it is under
certain circumstances, exactly those circumstances I described for Nouveau.

As mentioned, in Nouveau the size of a job is only really limited by the
ring size, which means that one job can (but does not necessarily) fill up
the whole ring. We both agree that this is inefficient, because it
potentially results into the HW run dry due to hw_submission_limit == 1.

I recognize you said that one should define hw_submission_limit and adjust
the other parts of the equation accordingly, the options I see are:

(1) Increase the ring size while keeping the maximum j

Re: [PATCH 2/2] drivers/tidss: Add support for AM62A7 DSS

2023-08-18 Thread Aradhya Bhatia



On 18-Aug-23 18:47, Aradhya Bhatia wrote:
> Add support for the DSS controller on TI's AM62A7 SoC in the tidss
> driver.
> 
> This contrller has 2 video pipelines that can render 2 video planes on
> over a screen, using the overlay managers. The output of the DSS comes
> from video port 2 (VP2) in the form of RGB88 DPI signals, while the VP1
> is tied off inside the SoC.
> 
> Signed-off-by: Aradhya Bhatia 
> ---
>  drivers/gpu/drm/tidss/tidss_dispc.c | 53 +
>  drivers/gpu/drm/tidss/tidss_dispc.h |  2 ++
>  drivers/gpu/drm/tidss/tidss_drv.c   |  1 +
>  3 files changed, 56 insertions(+)
> 
> diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c 
> b/drivers/gpu/drm/tidss/tidss_dispc.c
> index 9d9dee7abaef..0e2d55d9a0d7 100644
> --- a/drivers/gpu/drm/tidss/tidss_dispc.c
> +++ b/drivers/gpu/drm/tidss/tidss_dispc.c
> @@ -322,6 +322,54 @@ const struct dispc_features dispc_am625_feats = {
>   .vid_order = { 1, 0 },
>  };
>  
> +const struct dispc_features dispc_am62a7_feats = {
> + .max_pclk_khz = {
> + [DISPC_VP_DPI] = 165000,
> + },
> +
> + .scaling = {
> + .in_width_max_5tap_rgb = 1280,
> + .in_width_max_3tap_rgb = 2560,
> + .in_width_max_5tap_yuv = 2560,
> + .in_width_max_3tap_yuv = 4096,
> + .upscale_limit = 16,
> + .downscale_limit_5tap = 4,
> + .downscale_limit_3tap = 2,
> + /*
> +  * The max supported pixel inc value is 255. The value
> +  * of pixel inc is calculated like this: 1+(xinc-1)*bpp.
> +  * The maximum bpp of all formats supported by the HW
> +  * is 8. So the maximum supported xinc value is 32,
> +  * because 1+(32-1)*8 < 255 < 1+(33-1)*4.
> +  */
> + .xinc_max = 32,
> + },
> +
> + .subrev = DISPC_AM62A7,
> +
> + .common = "common",
> + .common_regs = tidss_am65x_common_regs,
> +
> + .num_vps = 2,
> + .vp_name = { "vp1", "vp2" },
> + .ovr_name = { "ovr1", "ovr2" },
> + .vpclk_name =  { "vp1", "vp2" },
> + .vp_bus_type = { DISPC_VP_INTERNAL, DISPC_VP_DPI },
> +
> + .vp_feat = { .color = {
> + .has_ctm = true,
> + .gamma_size = 256,
> + .gamma_type = TIDSS_GAMMA_8BIT,
> + },
> + },
> +
> + .num_planes = 2,
> + /* note: vid is plane_id 0 and vidl1 is plane_id 1 */
> + .vid_name = { "vid", "vidl1" },
> + .vid_lite = { false, true, },
> + .vid_order = { 1, 0 },
> +};
> +
>  static const u16 *dispc_common_regmap;
>  
>  struct dss_vp_data {
> @@ -823,6 +871,7 @@ dispc_irq_t dispc_read_and_clear_irqstatus(struct 
> dispc_device *dispc)
>   switch (dispc->feat->subrev) {
>   case DISPC_K2G:
>   return dispc_k2g_read_and_clear_irqstatus(dispc);
> + case DISPC_AM62A7:
>   case DISPC_AM625:
>   case DISPC_AM65X:
>   case DISPC_J721E:
> @@ -839,6 +888,7 @@ void dispc_set_irqenable(struct dispc_device *dispc, 
> dispc_irq_t mask)
>   case DISPC_K2G:
>   dispc_k2g_set_irqenable(dispc, mask);
>   break;
> + case DISPC_AM62A7:
>   case DISPC_AM625:
>   case DISPC_AM65X:
>   case DISPC_J721E:
> @@ -1330,6 +1380,7 @@ void dispc_ovr_set_plane(struct dispc_device *dispc, 
> u32 hw_plane,
>   dispc_k2g_ovr_set_plane(dispc, hw_plane, hw_videoport,
>   x, y, layer);
>   break;
> + case DISPC_AM62A7:
>   case DISPC_AM625:
>   case DISPC_AM65X:
>   dispc_am65x_ovr_set_plane(dispc, hw_plane, hw_videoport,
> @@ -2249,6 +2300,7 @@ static void dispc_plane_init(struct dispc_device *dispc)
>   case DISPC_K2G:
>   dispc_k2g_plane_init(dispc);
>   break;
> + case DISPC_AM62A7:
>   case DISPC_AM625:
>   case DISPC_AM65X:
>   case DISPC_J721E:
> @@ -2356,6 +2408,7 @@ static void dispc_vp_write_gamma_table(struct 
> dispc_device *dispc,
>   case DISPC_K2G:
>   dispc_k2g_vp_write_gamma_table(dispc, hw_videoport);
>   break;
> + case DISPC_AM62A7:
>   case DISPC_AM625:
>   case DISPC_AM65X:
>   dispc_am65x_vp_write_gamma_table(dispc, hw_videoport);
> diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h 
> b/drivers/gpu/drm/tidss/tidss_dispc.h
> index 33ac5ad7a423..2aa1c814ea2a 100644
> --- a/drivers/gpu/drm/tidss/tidss_dispc.h
> +++ b/drivers/gpu/drm/tidss/tidss_dispc.h
> @@ -59,6 +59,7 @@ enum dispc_vp_bus_type {
>  
>  enum dispc_dss_subrevision {
>   DISPC_K2G,
> + DISPC_AM62A7,
>   DISPC_AM625,
>   DISPC_AM65X,
>   DISPC_J721E,
> @@ -88,6 +89,7 @@ struct dispc_features {

Made an oopsie and missed sorting 'DISPC_AM62A7' in above instances. It
should be under DISPC_AM625. Please ignore this patch / series. Will
send a v2. Apologies for the noise.

Regards
Aradhya

>  
>  extern const struct dis

Re: [BUG] KCSAN: data-race in drm_sched_entity_is_ready [gpu_sched] / drm_sched_entity_push_job [gpu_sched]

2023-08-18 Thread Mirsad Todorovac

On 8/17/23 21:54, Mirsad Todorovac wrote:

Hi,

This is your friendly bug reporter.

The environment is vanilla torvalds tree kernel on Ubuntu 22.04 LTS and a Ryzen 
7950X box.

Please find attached the complete dmesg output from the ring buffer and lshw 
output.

NOTE: The kernel reports tainted kernel, but to my knowledge there are no 
proprietary (G) modules,
   but this taint is turned on by the previous bugs.

dmesg excerpt:

[ 8791.864576] 
==
[ 8791.864648] BUG: KCSAN: data-race in drm_sched_entity_is_ready [gpu_sched] / 
drm_sched_entity_push_job [gpu_sched]

[ 8791.864776] write (marked) to 0x9b74491b7c40 of 8 bytes by task 3807 on 
cpu 18:
[ 8791.864788]  drm_sched_entity_push_job+0xf4/0x2a0 [gpu_sched]
[ 8791.864852]  amdgpu_cs_ioctl+0x3888/0x3de0 [amdgpu]
[ 8791.868731]  drm_ioctl_kernel+0x127/0x210 [drm]
[ 8791.869222]  drm_ioctl+0x38f/0x6f0 [drm]
[ 8791.869711]  amdgpu_drm_ioctl+0x7e/0xe0 [amdgpu]
[ 8791.873660]  __x64_sys_ioctl+0xd2/0x120
[ 8791.873676]  do_syscall_64+0x58/0x90
[ 8791.873688]  entry_SYSCALL_64_after_hwframe+0x73/0xdd

[ 8791.873710] read to 0x9b74491b7c40 of 8 bytes by task 1119 on cpu 27:
[ 8791.873722]  drm_sched_entity_is_ready+0x16/0x50 [gpu_sched]
[ 8791.873786]  drm_sched_select_entity+0x1c7/0x220 [gpu_sched]
[ 8791.873849]  drm_sched_main+0xd2/0x500 [gpu_sched]
[ 8791.873912]  kthread+0x18b/0x1d0
[ 8791.873924]  ret_from_fork+0x43/0x70
[ 8791.873939]  ret_from_fork_asm+0x1b/0x30

[ 8791.873955] value changed: 0x -> 0x9b750ebcfc00

[ 8791.873971] Reported by Kernel Concurrency Sanitizer on:
[ 8791.873980] CPU: 27 PID: 1119 Comm: gfx_0.0.0 Tainted: G L 
6.5.0-rc6-net-cfg-kcsan-00038-g16931859a650 #35
[ 8791.873994] Hardware name: ASRock X670E PG Lightning/X670E PG Lightning, 
BIOS 1.21 04/26/2023
[ 8791.874002] 
==


P.S.

According to Mr. Heo's instructions, I am adding the unwound trace here:

[ 1879.706518] 
==
[ 1879.706616] BUG: KCSAN: data-race in drm_sched_entity_is_ready [gpu_sched] / 
drm_sched_entity_push_job [gpu_sched]

[ 1879.706737] write (marked) to 0x8f3672748c40 of 8 bytes by task 4087 on 
cpu 10:
[ 1879.706748] drm_sched_entity_push_job (./include/drm/spsc_queue.h:74 
drivers/gpu/drm/scheduler/sched_entity.c:574) gpu_sched
[ 1879.706808] amdgpu_cs_ioctl (drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1375 
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1469) amdgpu
[ 1879.710589] drm_ioctl_kernel (drivers/gpu/drm/drm_ioctl.c:788) drm
[ 1879.711068] drm_ioctl (drivers/gpu/drm/drm_ioctl.c:892) drm
[ 1879.711551] amdgpu_drm_ioctl (drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c:2748) 
amdgpu
[ 1879.715319] __x64_sys_ioctl (fs/ioctl.c:51 fs/ioctl.c:870 fs/ioctl.c:856 
fs/ioctl.c:856)
[ 1879.715334] do_syscall_64 (arch/x86/entry/common.c:50 
arch/x86/entry/common.c:80)
[ 1879.715345] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120)

[ 1879.715365] read to 0x8f3672748c40 of 8 bytes by task 1098 on cpu 11:
[ 1879.715376] drm_sched_entity_is_ready 
(drivers/gpu/drm/scheduler/sched_entity.c:134) gpu_sched
[ 1879.715435] drm_sched_select_entity 
(drivers/gpu/drm/scheduler/sched_main.c:248 
drivers/gpu/drm/scheduler/sched_main.c:893) gpu_sched
[ 1879.715495] drm_sched_main (drivers/gpu/drm/scheduler/sched_main.c:1019) 
gpu_sched
[ 1879.715554] kthread (kernel/kthread.c:389)
[ 1879.715563] ret_from_fork (arch/x86/kernel/process.c:145)
[ 1879.715575] ret_from_fork_asm (arch/x86/entry/entry_64.S:312)

[ 1879.715590] value changed: 0x -> 0x8f360663dc00

[ 1879.715604] Reported by Kernel Concurrency Sanitizer on:
[ 1879.715612] CPU: 11 PID: 1098 Comm: gfx_0.0.0 Tainted: G L 
6.5.0-rc6+ #47
[ 1879.715624] Hardware name: ASRock X670E PG Lightning/X670E PG Lightning, 
BIOS 1.21 04/26/2023
[ 1879.715631] 
==

It seems that the line in question might be:

first = spsc_queue_push(&entity->job_queue, &sched_job->queue_node);

which expands to:

static inline bool spsc_queue_push(struct spsc_queue *queue, struct spsc_node 
*node)
{
struct spsc_node **tail;

node->next = NULL;

preempt_disable();

tail = (struct spsc_node **)atomic_long_xchg(&queue->tail, 
(long)&node->next);
WRITE_ONCE(*tail, node);
atomic_inc(&queue->job_count);

/*
 * In case of first element verify new node will be visible to the 
consumer
 * thread when we ping the kernel thread that there is new work to do.
 */
smp_wmb();

preempt_enable();

return tail == &queue->head;
}

According to the manual, preempt_disable() only guaranteed exclusion on a 
single CPU/core/thread, so
we might be plagued with the slow, old fashioned locking unless anyone had a 
better idea.

RE: [PATCH 7/7] drm: adv7511: Add hpd_override_enable feature bit to struct adv7511_chip_info

2023-08-18 Thread Biju Das
Hi Adam,

> Subject: Re: [PATCH 7/7] drm: adv7511: Add hpd_override_enable feature bit
> to struct adv7511_chip_info
> 
> On Fri, Aug 18, 2023 at 8:35 AM Biju Das 
> wrote:
> >
> > Hi Adam Ford,
> >
> > Thanks for the feedback.
> >
> > > Subject: Re: [PATCH 7/7] drm: adv7511: Add hpd_override_enable
> > > feature bit to struct adv7511_chip_info
> > >
> > > On Sun, Aug 13, 2023 at 1:06 PM Biju Das
> > > 
> > > wrote:
> > > >
> > > > As per spec, it is allowed to pulse the HPD signal to indicate
> > > > that the EDID information has changed. Some monitors do this when
> > > > they wake up from standby or are enabled. When the HPD goes low
> > > > the adv7511 is reset and the outputs are disabled which might
> > > > cause the monitor to go to standby again. To avoid this we ignore
> > > > the HPD pin for the first few seconds after enabling the output.
> > > > On the other hand,
> > > > adv7535 require to enable HPD Override bit for proper HPD.
> > > >
> > > > Add hpd_override_enable feature bit to struct adv7511_chip_info to
> > > > handle this scenario.
> > > >
> > > > While at it, drop the enum adv7511_type as it is unused.
> > >
> > > It seems like dropping adv7511_type is unrelated to the rest of the
> > > patch, and I think it should be split from this into its own patch
> >
> > With this patch, there is no user for adv7511_type that is the reason
> > it is added here. I thought that is the common practice.
> >
> I wasn't sure.
> 
> > Please correct me if that is not the case.
> 
> I'll defer to the maintainers.  In general I like the series because it
> reduces the number of compare evaluations.  I'll try to run some tests on a
> board that I have with a adv7535 this weekend.

Thank you,
Biju

> >
> > Cheers,
> > Biju
> >
> > >
> > > adam
> > > >
> > > > Signed-off-by: Biju Das 
> > > > ---
> > > >  drivers/gpu/drm/bridge/adv7511/adv7511.h |  8 +---
> > > >  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 12 +---
> > > >  2 files changed, 6 insertions(+), 14 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> > > > b/drivers/gpu/drm/bridge/adv7511/adv7511.h
> > > > index 627531f48f84..c523ac4c9bc8 100644
> > > > --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> > > > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
> > > > @@ -325,22 +325,16 @@ struct adv7511_video_config {
> > > > struct hdmi_avi_infoframe avi_infoframe;  };
> > > >
> > > > -enum adv7511_type {
> > > > -   ADV7511,
> > > > -   ADV7533,
> > > > -   ADV7535,
> > > > -};
> > > > -
> > > >  #define ADV7511_MAX_ADDRS 3
> > > >
> > > >  struct adv7511_chip_info {
> > > > -   enum adv7511_type type;
> > > > unsigned long max_mode_clock;
> > > > unsigned long max_lane_freq;
> > > > const char * const *supply_names;
> > > > unsigned int num_supplies;
> > > > unsigned has_dsi:1;
> > > > unsigned link_config:1;
> > > > +   unsigned hpd_override_enable:1;
> > > >  };
> > > >
> > > >  struct adv7511 {
> > > > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> > > > b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> > > > index 6974c267b1d5..7b06a0a21685 100644
> > > > --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> > > > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> > > > @@ -354,7 +354,7 @@ static void __adv7511_power_on(struct adv7511
> > > *adv7511)
> > > >  * first few seconds after enabling the output. On the other
> hand
> > > >  * adv7535 require to enable HPD Override bit for proper HPD.
> > > >  */
> > > > -   if (adv7511->info->type == ADV7535)
> > > > +   if (adv7511->info->hpd_override_enable)
> > > > regmap_update_bits(adv7511->regmap,
> ADV7511_REG_POWER2,
> > > >ADV7535_REG_POWER2_HPD_OVERRIDE,
> > > >
> > > > ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -381,7 +381,7 @@ static void
> > > > adv7511_power_on(struct adv7511
> > > > *adv7511)  static void __adv7511_power_off(struct adv7511 *adv7511)
> {
> > > > /* TODO: setup additional power down modes */
> > > > -   if (adv7511->info->type == ADV7535)
> > > > +   if (adv7511->info->hpd_override_enable)
> > > > regmap_update_bits(adv7511->regmap,
> ADV7511_REG_POWER2,
> > > >
> > > > ADV7535_REG_POWER2_HPD_OVERRIDE, 0);
> > > >
> > > > @@ -682,7 +682,7 @@ adv7511_detect(struct adv7511 *adv7511, struct
> > > drm_connector *connector)
> > > > status = connector_status_disconnected;
> > > > } else {
> > > > /* Renable HPD sensing */
> > > > -   if (adv7511->info->type == ADV7535)
> > > > +   if (adv7511->info->hpd_override_enable)
> > > > regmap_update_bits(adv7511->regmap,
> > > ADV7511_REG_POWER2,
> > > >
> > > ADV7535_REG_POWER2_HPD_OVERRIDE,
> > > >
> > > > ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -1360,14 +1360,12 @@ static
> > > > void adv7511_remo

[PATCH 1/2] dt-bindings: display: ti: Add support for am62a7 dss

2023-08-18 Thread Aradhya Bhatia
The DSS controller on TI's AM62A7 SoC is an update from that on TI's
AM625 SoC. Like the DSS in AM625, the DSS in this SoC has 2 video
pipelines, but unlike the former, the latter only has one output port on
VP2 to service DPI display sinks.

Add the new controller's compatible.

Signed-off-by: Aradhya Bhatia 
---
 .../bindings/display/ti/ti,am65x-dss.yaml  | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml 
b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
index ae09cd3cbce1..b6767ef0d24d 100644
--- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
+++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
@@ -23,6 +23,7 @@ properties:
   compatible:
 enum:
   - ti,am625-dss
+  - ti,am62a7,dss
   - ti,am65x-dss
 
   reg:
@@ -87,6 +88,7 @@ properties:
   For AM65x DSS, the OLDI output port node from video port 1.
   For AM625 DSS, the internal DPI output port node from video
   port 1.
+  For AM62A7 DSS, the port is tied off inside the SoC.
 
   port@1:
 $ref: /schemas/graph.yaml#/properties/port
@@ -108,6 +110,18 @@ properties:
   Input memory (from main memory to dispc) bandwidth limit in
   bytes per second
 
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+const: ti,am62a7-dss
+then:
+  properties:
+ports:
+  properties:
+port@0: false
+
 required:
   - compatible
   - reg
-- 
2.40.1



Re: [PATCH] drm/amd/display: fix mode scaling (RMX_.*)

2023-08-18 Thread Hamza Mahfooz



On 8/18/23 09:28, Alex Deucher wrote:

On Fri, Aug 18, 2023 at 9:25 AM Hamza Mahfooz  wrote:


As made mention of in commit 4a2df0d1f28e ("drm/amd/display: Fixed
non-native modes not lighting up"), we shouldn't call
drm_mode_set_crtcinfo() once the crtc timings have been decided. Since,
it can cause settings to be unintentionally overwritten. So, since
dm_state is never NULL now, we can use old_stream to determine if we
should call drm_mode_set_crtcinfo() because we only need to set the crtc
timing parameters for entirely new streams.

Cc: Harry Wentland 
Cc: Rodrigo Siqueira 
Fixes: 712237a4a1b4 ("drm/amd/display: Always set crtcinfo from 
create_stream_for_sink")
Signed-off-by: Hamza Mahfooz 


Does this fix:
https://gitlab.freedesktop.org/drm/amd/-/issues/2783
If so, add a link tag for that.


The issue I'm addressing is specific to the colorspace patches (which
weren't ported to 6.4.y to my knowledge). So, that's probably unrelated.



Alex


---
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 3b27b7742854..e9aff5014e39 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6035,7 +6035,7 @@ create_stream_for_sink(struct amdgpu_dm_connector 
*aconnector,

 if (recalculate_timing)
 drm_mode_set_crtcinfo(&saved_mode, 0);
-   else
+   else if (!old_stream)
 drm_mode_set_crtcinfo(&mode, 0);

 /*
--
2.41.0


--
Hamza



Re: [EXTERNAL] Re: [PATCH v5 03/17] drm/imagination/uapi: Add PowerVR driver UAPI

2023-08-18 Thread Sarah Walker
On Thu, 2023-08-17 at 19:43 -0500, Faith Ekstrand wrote:
> On Wed, Aug 16, 2023 at 3:26 AM Sarah Walker  wrote:
> > 
> > +/**
> > + * struct drm_pvr_dev_query_runtime_info - Container used to fetch 
> > information
> > + * about the graphics runtime.
> > + *
> > + * When fetching this type &struct drm_pvr_ioctl_dev_query_args.type must 
> > be set
> > + * to %DRM_PVR_DEV_QUERY_RUNTIME_INFO_GET.
> > + */
> > +struct drm_pvr_dev_query_runtime_info {
> > +   /**
> > +* @free_list_min_pages: Minimum allowed free list size,
> > +* in PM physical pages.
> > +*/
> > +   __u64 free_list_min_pages;
> > +
> > +   /**
> > +* @free_list_max_pages: Maximum allowed free list size,
> > +* in PM physical pages.
> > +*/
> > +   __u64 free_list_max_pages;
> > +
> > +   /**
> > +* @common_store_alloc_region_size: Size of the Allocation
> > +* Region within the Common Store used for coefficient and shared
> > +* registers, in dwords.
> > +*/
> > +   __u32 common_store_alloc_region_size;
> 
> Any reason why this is in dwords?  It's not really my place to have an 
> opinion but that seems like kind-of a funny unit for the size of an 
> allocation region. Why not just bytes?

This is a holdover from the closed source driver. It can be changed to bytes if
that is particularly desired?

> +/**
> > + * struct drm_pvr_dev_query_quirks - Container used to fetch information 
> > about
> > + * hardware fixes for which the device may require support in the user mode
> > + * driver.
> > + *
> > + * When fetching this type &struct drm_pvr_ioctl_dev_query_args.type must 
> > be set
> > + * to %DRM_PVR_DEV_QUERY_QUIRKS_GET.
> > + */
> > +struct drm_pvr_dev_query_quirks {
> > +   /**
> > +* @quirks: A userspace address for the hardware quirks __u32 array.
> > +*
> > +* The first @musthave_count items in the list are quirks that the
> > +* client must support for this device. If userspace does not 
> > support
> > +* all these quirks then functionality is not guaranteed and client
> > +* initialisation must fail.
> > +* The remaining quirks in the list affect userspace and the kernel 
> > or
> > +* firmware. They are disabled by default and require userspace to
> > +* opt-in. The opt-in mechanism depends on the quirk.
> > +*/
> > +   __u64 quirks;
> 
> Where are these quirk IDs defined and where do they come from? If they're 
> effectively coming from hardware, possibly via firmware, that's probably 
> okay.  The important thing is that quirks should only ever get removed for 
> any given piece of hardware otherwise you risk breaking userspace.

Quirks are defined in the firmware header. The actual IDs are from our issue
tracking system; they're shared with the closed source driver. We are aware of
the need to not remove quirks for a given GPU.

> > +/**
> > + * struct drm_pvr_dev_query_enhancements - Container used to fetch 
> > information
> > + * about optional enhancements supported by the device that require 
> > support in
> > + * the user mode driver.
> > + *
> > + * When fetching this type &struct drm_pvr_ioctl_dev_query_args.type must 
> > be set
> > + * to %DRM_PVR_DEV_ENHANCEMENTS_GET.
> > + */
> > +struct drm_pvr_dev_query_enhancements {
> > +   /**
> > +* @enhancements: A userspace address for the hardware enhancements
> > +* __u32 array.
> > +*
> > +* These enhancements affect userspace and the kernel or firmware. 
> > They
> > +* are disabled by default and require userspace to opt-in. The 
> > opt-in
> > +* mechanism depends on the quirk.
> > +*/
> > +   __u64 enhancements;
> 
> Can you provide some examples of "enhancements"? Not that you need to put it 
> in the docs. I'm just trying to understand what this API is doing so I can 
> better review. Again, where do these come from? Also, how is an enhancement 
> different from a quirk?

Enhancements are comparatively minor improvements in GPU subrevisions that don't
qualify as a full "product feature". A couple of examples would be 35421, which
improves compute thread barrier support, and 42064, which adds mask support for
the pixel backend. As with quirks, enhancements are defined in the firmware
header, with the IDs coming from our issue tracker.

Thanks,
Sarah



Re: [PATCH RFC v5 02/10] drm: Introduce solid fill DRM plane property

2023-08-18 Thread Pekka Paalanen
On Fri, 18 Aug 2023 14:03:14 +0300
Dmitry Baryshkov  wrote:

> On 18/08/2023 13:51, Pekka Paalanen wrote:
> > On Fri, 4 Aug 2023 16:59:00 +0300
> > Dmitry Baryshkov  wrote:
> >   
> >> On Fri, 4 Aug 2023 at 16:44, Sebastian Wick  
> >> wrote:  
> >>>
> >>> On Fri, Aug 4, 2023 at 3:27 PM Dmitry Baryshkov
> >>>  wrote:  
> 
>  On Fri, 28 Jul 2023 at 20:03, Jessica Zhang  
>  wrote:  
> >
> > Document and add support for solid_fill property to drm_plane. In
> > addition, add support for setting and getting the values for solid_fill.
> >
> > To enable solid fill planes, userspace must assign a property blob to
> > the "solid_fill" plane property containing the following information:
> >
> > struct drm_mode_solid_fill {
> >  u32 version;
> >  u32 r, g, b;
> > };
> >
> > Signed-off-by: Jessica Zhang 
> > ---
> >   drivers/gpu/drm/drm_atomic_state_helper.c |  9 +
> >   drivers/gpu/drm/drm_atomic_uapi.c | 55 
> > +++
> >   drivers/gpu/drm/drm_blend.c   | 30 +
> >   include/drm/drm_blend.h   |  1 +
> >   include/drm/drm_plane.h   | 35 
> >   include/uapi/drm/drm_mode.h   | 24 ++
> >   6 files changed, 154 insertions(+)
> > 
> 
>  [skipped most of the patch]

...

> >>> Maybe another COLOR_FILL enum value
> >>> with alpha might be better? Maybe just doing the alpha via the alpha
> >>> property is good enough.  
> >>
> >> One of our customers has a use case for setting the opaque solid fill,
> >> while keeping the plane's alpha intact.  
> > 
> > Could you explain more about why they must keep plane alpha intact
> > instead of reprogramming everything with atomic? Is there some
> > combination that just cannot reach the same end result via userspace
> > manipulation of the solid fill values with plane alpha?
> > 
> > Or is it a matter of userspace architecture where you have independent
> > components responsible for different KMS property values?  

> The latter one. The goal is to be able to switch between pixel sources 
> without touching any additional properties (including plane's alpha value).

Sorry, but that does not seem like a good justification for KMS UAPI
design.

It is even in conflict with how atomic KMS UAPI was designed to work:
collect all your changes into a single commit, and push it at once.
Here we are talking about separate components changing the different
properties of the same KMS plane even. If you want to change both plane
opacity and contents, does it mean you need two refresh cycles, one at
a time? Could the two components be even racing with each other,
stalling each other randomly?


Thanks,
pq


pgpmyDBWEeKaU.pgp
Description: OpenPGP digital signature


Re: [PATCH 0/7] ADV7511 driver enhancements

2023-08-18 Thread Fabio Estevam
Hi Biju,

On Sun, Aug 13, 2023 at 3:05 PM Biju Das  wrote:
>
> This patch series aims to improve ADV7511 driver by adding
> feature bits and data instead of comparing enum adv7511_type for
> various hardware differences between ADV7511, ADV7533 and ADV7535.
>
> This patch series tested with[1] on RZ/G2L SMARC EVK which embeds
> ADV7535.

I have successfully tested this series on a imx8mm-evk, which has an ADV7535:

Tested-by: Fabio Estevam 


Re: [06/12] arch: Declare screen_info in

2023-08-18 Thread suijingfeng

Hi,


Why this patch get dropped in the end?

Since the global screen_info is an arch-specific thing,
Whenever an arch-neutral module or subsystem references the global screen_info,
There are some complaints from either compile testing robot.
Well, a programmer may handle it by using the CONFIG_SYSFB guard,
but it is not as precise as what this patch provided.

Personally, I think this patch is still valuable.
I suggest either forcing all other architectures to export screen_info,
like the X86 and IA64 arch does, after all the screen_info is a good thing.
or provide the fine-control version like this patch does.


On 2023/6/29 19:45, Thomas Zimmermann wrote:

The variable screen_info does not exist on all architectures. Declare
it in . All architectures that do declare it
will provide it via .

Add the Kconfig token ARCH_HAS_SCREEN_INFO to guard against access on
architectures that don't provide screen_info.

Signed-off-by: Thomas Zimmermann 
Cc: Richard Henderson 
Cc: Ivan Kokshaysky 
Cc: Matt Turner 
Cc: Russell King 
Cc: Catalin Marinas 
Cc: Will Deacon 
Cc: Guo Ren 
Cc: Brian Cain 
Cc: Huacai Chen 
Cc: WANG Xuerui 
Cc: Thomas Bogendoerfer 
Cc: Dinh Nguyen 
Cc: Michael Ellerman 
Cc: Nicholas Piggin 
Cc: Christophe Leroy 
Cc: Paul Walmsley 
Cc: Palmer Dabbelt 
Cc: Albert Ou 
Cc: Yoshinori Sato 
Cc: Rich Felker 
Cc: John Paul Adrian Glaubitz 
Cc: "David S. Miller" 
Cc: Thomas Gleixner 
Cc: Ingo Molnar 
Cc: Borislav Petkov 
Cc: Dave Hansen 
Cc: x...@kernel.org
Cc: "H. Peter Anvin" 
Cc: Chris Zankel 
Cc: Max Filippov 
Cc: Helge Deller 
Cc: Arnd Bergmann 
Cc: Kees Cook 
Cc: "Paul E. McKenney" 
Cc: Peter Zijlstra 
Cc: Frederic Weisbecker 
Cc: Andrew Morton 
Cc: Ard Biesheuvel 
Cc: Sami Tolvanen 
Cc: Juerg Haefliger 
Cc: Geert Uytterhoeven 
Cc: Anshuman Khandual 
Cc: Niklas Schnelle 
Cc: "Russell King (Oracle)" 
Cc: Linus Walleij 
Cc: Sebastian Reichel 
Cc: "Mike Rapoport (IBM)" 
Cc: "Kirill A. Shutemov" 
Cc: Zi Yan 
Acked-by: WANG Xuerui  # loongarch
---
  arch/Kconfig  |  6 ++
  arch/alpha/Kconfig|  1 +
  arch/arm/Kconfig  |  1 +
  arch/arm64/Kconfig|  1 +
  arch/csky/Kconfig |  1 +
  arch/hexagon/Kconfig  |  1 +
  arch/ia64/Kconfig |  1 +
  arch/loongarch/Kconfig|  1 +
  arch/mips/Kconfig |  1 +
  arch/nios2/Kconfig|  1 +
  arch/powerpc/Kconfig  |  1 +
  arch/riscv/Kconfig|  1 +
  arch/sh/Kconfig   |  1 +
  arch/sparc/Kconfig|  1 +
  arch/x86/Kconfig  |  1 +
  arch/xtensa/Kconfig   |  1 +
  drivers/video/Kconfig |  3 +++
  include/asm-generic/Kbuild|  1 +
  include/asm-generic/screen_info.h | 12 
  include/linux/screen_info.h   |  2 +-
  20 files changed, 38 insertions(+), 1 deletion(-)
  create mode 100644 include/asm-generic/screen_info.h

diff --git a/arch/Kconfig b/arch/Kconfig
index 205fd23e0cada..2f58293fd7bcb 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1466,6 +1466,12 @@ config ARCH_HAS_NONLEAF_PMD_YOUNG
  address translations. Page table walkers that clear the accessed bit
  may use this capability to reduce their search space.
  
+config ARCH_HAS_SCREEN_INFO

+   bool
+   help
+ Selected by architectures that provide a global instance of
+ screen_info.
+
  source "kernel/gcov/Kconfig"
  
  source "scripts/gcc-plugins/Kconfig"

diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index a5c2b1aa46b02..d749011d88b14 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -4,6 +4,7 @@ config ALPHA
default y
select ARCH_32BIT_USTAT_F_TINODE
select ARCH_HAS_CURRENT_STACK_POINTER
+   select ARCH_HAS_SCREEN_INFO
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
select ARCH_NO_PREEMPT
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0fb4b218f6658..a9d01ee67a90e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -15,6 +15,7 @@ config ARM
select ARCH_HAS_MEMBARRIER_SYNC_CORE
select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
select ARCH_HAS_PTE_SPECIAL if ARM_LPAE
+   select ARCH_HAS_SCREEN_INFO
select ARCH_HAS_SETUP_DMA_OPS
select ARCH_HAS_SET_MEMORY
select ARCH_STACKWALK
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 343e1e1cae10a..21addc4715bb3 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -36,6 +36,7 @@ config ARM64
select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
select ARCH_HAS_PTE_DEVMAP
select ARCH_HAS_PTE_SPECIAL
+   select ARCH_HAS_SCREEN_INFO
select ARCH_HAS_SETUP_DMA_OPS
select ARCH_HAS_SET_DIRECT_MAP
select ARCH_HAS_SET_MEMORY
diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig
index 4df1f8c9d170b..28444e581fc1f 100644
--- a/arch/csky/Kconfig
+++ b/arch/csky/Kconfig
@@ -10

Re: [EXTERNAL] Re: [PATCH v5 08/17] drm/imagination: Add GEM and VM related code

2023-08-18 Thread Sarah Walker
On Fri, 2023-08-18 at 00:42 +0200, Jann Horn wrote:
> *** CAUTION: This email originates from a source not known to Imagination 
> Technologies. Think before you click a link or open an attachment ***
> 
> Hi!
> 
> Thanks, I think it's great that Imagination is writing an upstream
> driver for PowerVR. :)
> 
> On Wed, Aug 16, 2023 at 10:25 AM Sarah Walker  wrote:
> > +#define PVR_BO_CPU_CACHED BIT_ULL(63)
> > +
> > +#define PVR_BO_FW_NO_CLEAR_ON_RESET BIT_ULL(62)
> > +
> > +/* Bits 62..3 are undefined. */
> > +/* Bits 2..0 are defined in the UAPI. */
> > +
> > +/* Other utilities. */
> > +#define PVR_BO_UNDEFINED_MASK GENMASK_ULL(61, 3)
> > +#define PVR_BO_RESERVED_MASK (PVR_BO_UNDEFINED_MASK | GENMASK_ULL(63, 63))
> 
> In commit 1a9c568fb559 ("drm/imagination: Rework firmware object
> initialisation") in powervr-next, PVR_BO_FW_NO_CLEAR_ON_RESET (bit 62)
> was added in the kernel-only flags group, but the mask
> PVR_BO_RESERVED_MASK (which is used in pvr_ioctl_create_bo to detect
> kernel-only and reserved flags) looks like it wasn't changed to
> include bit 62. I think that means it becomes possible for userspace
> to pass this bit in via pvr_ioctl_create_bo()?

Yes, this is a bug. Will fix (and refactor a bit).

> > +/**
> > + * pvr_page_table_l2_entry_raw_set() - Write a valid entry into a raw 
> > level 2
> > + * page table.
> > + * @entry: Target raw level 2 page table entry.
> > + * @child_table_dma_addr: DMA address of the level 1 page table to be
> > + *associated with @entry.
> > + *
> > + * When calling this function, @child_table_dma_addr must be a valid DMA
> > + * address and a multiple of %ROGUE_MMUCTRL_PC_DATA_PD_BASE_ALIGNSIZE.
> > + */
> > +static void
> > +pvr_page_table_l2_entry_raw_set(struct pvr_page_table_l2_entry_raw *entry,
> > +   dma_addr_t child_table_dma_addr)
> > +{
> > +   child_table_dma_addr >>= ROGUE_MMUCTRL_PC_DATA_PD_BASE_ALIGNSHIFT;
> > +
> > +   entry->val =
> > +   PVR_PAGE_TABLE_FIELD_PREP(2, PC, VALID, true) |
> > +   PVR_PAGE_TABLE_FIELD_PREP(2, PC, ENTRY_PENDING, false) |
> > +   PVR_PAGE_TABLE_FIELD_PREP(2, PC, PD_BASE, 
> > child_table_dma_addr);
> > +}
> 
> For this function and others that manipulate page table entries,
> please use some kernel helper that ensures that the store can't tear
> (at least WRITE_ONCE() - that can still tear on 32-bit, but I see the
> driver depends on ARM64, so that's not a problem).

Will do.

> > +/**
> > + * pvr_page_table_l2_insert() - Insert an entry referring to a level 1 page
> > + * table into a level 2 page table.
> > + * @op_ctx: Target MMU op context pointing at the entry to insert the L1 
> > page
> > + * table into.
> > + * @child_table: Target level 1 page table to be referenced by the new 
> > entry.
> > + *
> > + * It is the caller's responsibility to ensure @op_ctx.curr_page points to 
> > a
> > + * valid L2 entry.
> > + */
> > +static void
> > +pvr_page_table_l2_insert(struct pvr_mmu_op_context *op_ctx,
> > +struct pvr_page_table_l1 *child_table)
> > +{
> > +   struct pvr_page_table_l2 *l2_table =
> > +   &op_ctx->mmu_ctx->page_table_l2;
> > +   struct pvr_page_table_l2_entry_raw *entry_raw =
> > +   pvr_page_table_l2_get_entry_raw(l2_table,
> > +   op_ctx->curr_page.l2_idx);
> > +
> > +   pvr_page_table_l2_entry_raw_set(entry_raw,
> > +   child_table->backing_page.dma_addr);
> 
> Can you maybe add comments in functions that set page table entries to
> document who is responsible for using a memory barrier (like wmb()) to
> ensure that the creation of a page table entry is ordered after the
> thing it points to is fully initialized, so that the GPU can't end up
> concurrently walking into a page table and observe its old contents
> from before it was zero-initialized?

Will do.

> > +static int
> > +pvr_page_table_l1_get_or_insert(struct pvr_mmu_op_context *op_ctx,
> > +   bool should_insert)
> > +{
> > +   struct pvr_page_table_l2 *l2_table =
> > +   &op_ctx->mmu_ctx->page_table_l2;
> > +   struct pvr_page_table_l1 *table;
> > +   int err;
> > +
> > +   if (pvr_page_table_l2_entry_is_valid(l2_table,
> > +op_ctx->curr_page.l2_idx)) {
> > +   op_ctx->curr_page.l1_table =
> > +   l2_table->entries[op_ctx->curr_page.l2_idx];
> > +   return 0;
> > +   }
> > +
> > +   if (!should_insert)
> > +   return -ENXIO;
> > +
> > +   /* Take a prealloced table. */
> > +   table = op_ctx->l1_free_tables;
> > +   if (!table)
> > +   return -ENOMEM;
> > +
> > +   err = pvr_page_table_l1_init(table, op_ctx->mmu_ctx->pvr_dev);
> 
> I think when we have a preallocated table here,

Re: [06/12] arch: Declare screen_info in

2023-08-18 Thread suijingfeng



On 2023/8/18 22:04, suijingfeng wrote:

Hi,


Why this patch get dropped in the end?

Since the global screen_info is an arch-specific thing,
Whenever an arch-neutral module or subsystem references the global 
screen_info,

There are some complaints from either compile testing robot.



There are some complaints from either compile testing robot or domain 
specific reviewers who doubt why you select the CONFIG_SYSFB not 
CONFIG_VT or CONFIG_EFI.




Well, a programmer may handle it by using the CONFIG_SYSFB guard,
but it is not as precise as what this patch provided.

Personally, I think this patch is still valuable.
I suggest either forcing all other architectures to export screen_info,
like the X86 and IA64 arch does, after all the screen_info is a good 
thing.

or provide the fine-control version like this patch does.



Because all of the three tokens(CONFIG_SYSFB not CONFIG_VT or CONFIG_EFI.)

have no direct relationship with the global screen_info if an arch is 
not mentioned first.





On 2023/6/29 19:45, Thomas Zimmermann wrote:

The variable screen_info does not exist on all architectures. Declare
it in . All architectures that do declare it
will provide it via .

Add the Kconfig token ARCH_HAS_SCREEN_INFO to guard against access on
architectures that don't provide screen_info.

Signed-off-by: Thomas Zimmermann 
Cc: Richard Henderson 
Cc: Ivan Kokshaysky 
Cc: Matt Turner 
Cc: Russell King 
Cc: Catalin Marinas 
Cc: Will Deacon 
Cc: Guo Ren 
Cc: Brian Cain 
Cc: Huacai Chen 
Cc: WANG Xuerui 
Cc: Thomas Bogendoerfer 
Cc: Dinh Nguyen 
Cc: Michael Ellerman 
Cc: Nicholas Piggin 
Cc: Christophe Leroy 
Cc: Paul Walmsley 
Cc: Palmer Dabbelt 
Cc: Albert Ou 
Cc: Yoshinori Sato 
Cc: Rich Felker 
Cc: John Paul Adrian Glaubitz 
Cc: "David S. Miller" 
Cc: Thomas Gleixner 
Cc: Ingo Molnar 
Cc: Borislav Petkov 
Cc: Dave Hansen 
Cc: x...@kernel.org
Cc: "H. Peter Anvin" 
Cc: Chris Zankel 
Cc: Max Filippov 
Cc: Helge Deller 
Cc: Arnd Bergmann 
Cc: Kees Cook 
Cc: "Paul E. McKenney" 
Cc: Peter Zijlstra 
Cc: Frederic Weisbecker 
Cc: Andrew Morton 
Cc: Ard Biesheuvel 
Cc: Sami Tolvanen 
Cc: Juerg Haefliger 
Cc: Geert Uytterhoeven 
Cc: Anshuman Khandual 
Cc: Niklas Schnelle 
Cc: "Russell King (Oracle)" 
Cc: Linus Walleij 
Cc: Sebastian Reichel 
Cc: "Mike Rapoport (IBM)" 
Cc: "Kirill A. Shutemov" 
Cc: Zi Yan 
Acked-by: WANG Xuerui  # loongarch
---
  arch/Kconfig  |  6 ++
  arch/alpha/Kconfig    |  1 +
  arch/arm/Kconfig  |  1 +
  arch/arm64/Kconfig    |  1 +
  arch/csky/Kconfig |  1 +
  arch/hexagon/Kconfig  |  1 +
  arch/ia64/Kconfig |  1 +
  arch/loongarch/Kconfig    |  1 +
  arch/mips/Kconfig |  1 +
  arch/nios2/Kconfig    |  1 +
  arch/powerpc/Kconfig  |  1 +
  arch/riscv/Kconfig    |  1 +
  arch/sh/Kconfig   |  1 +
  arch/sparc/Kconfig    |  1 +
  arch/x86/Kconfig  |  1 +
  arch/xtensa/Kconfig   |  1 +
  drivers/video/Kconfig |  3 +++
  include/asm-generic/Kbuild    |  1 +
  include/asm-generic/screen_info.h | 12 
  include/linux/screen_info.h   |  2 +-
  20 files changed, 38 insertions(+), 1 deletion(-)
  create mode 100644 include/asm-generic/screen_info.h

diff --git a/arch/Kconfig b/arch/Kconfig
index 205fd23e0cada..2f58293fd7bcb 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1466,6 +1466,12 @@ config ARCH_HAS_NONLEAF_PMD_YOUNG
    address translations. Page table walkers that clear the 
accessed bit

    may use this capability to reduce their search space.
  +config ARCH_HAS_SCREEN_INFO
+    bool
+    help
+  Selected by architectures that provide a global instance of
+  screen_info.
+
  source "kernel/gcov/Kconfig"
    source "scripts/gcc-plugins/Kconfig"
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index a5c2b1aa46b02..d749011d88b14 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -4,6 +4,7 @@ config ALPHA
  default y
  select ARCH_32BIT_USTAT_F_TINODE
  select ARCH_HAS_CURRENT_STACK_POINTER
+    select ARCH_HAS_SCREEN_INFO
  select ARCH_MIGHT_HAVE_PC_PARPORT
  select ARCH_MIGHT_HAVE_PC_SERIO
  select ARCH_NO_PREEMPT
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0fb4b218f6658..a9d01ee67a90e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -15,6 +15,7 @@ config ARM
  select ARCH_HAS_MEMBARRIER_SYNC_CORE
  select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
  select ARCH_HAS_PTE_SPECIAL if ARM_LPAE
+    select ARCH_HAS_SCREEN_INFO
  select ARCH_HAS_SETUP_DMA_OPS
  select ARCH_HAS_SET_MEMORY
  select ARCH_STACKWALK
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 343e1e1cae10a..21addc4715bb3 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -36,6 +36,7 @@ config ARM64
  select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
  select ARCH_HAS_PTE_D

[PATCH v2 0/2] Add DSS support for TI AM62A7 SoC

2023-08-18 Thread Aradhya Bhatia
This patch series adds a new compatible for the Display SubSystem (DSS)
controller on TI's AM62A7 SoC. It further adds the required support, for
the same, in the tidss driver.

The DSS controller is similar to the recently added AM625 DSS, with the
key difference being the absence of VP1 output on the SoC. The VP1 in
AM62A7 DSS is tied off and cannot be used, unlike in AM625, where the
VP1 was connected to 2 OLDI TXes. The video pipeline that corresponds to
VP1 still exists and can be used to overlay planes on the VP2's primary
plane. This can be done using the overlay managers inside the SoC.
Moreover, DSS VP2 can output Full-HD RGB888 DPI video signals.

I have tested these patches on AM62A7 SK-EVM, which converts DPI signals
to HDMI on the platform using the Sil9022A HDMI transmitter. All the
patches, required to enable display on AM62A7-SK, can be found on my
github fork[0] in the branch "next_am62a-v2".

Regards
Aradhya

[0]: https://github.com/aradhya07/linux-ab/tree/next_am62a-v2

Change Log:
V1 -> V2:
  - Correctly sort DISPC_AM62A7 macro after DISPC_AM625 in patch 2/2.

Previous Versions:
V1: https://lore.kernel.org/all/20230818131750.4779-1-a-bhat...@ti.com/

Aradhya Bhatia (2):
  dt-bindings: display: ti: Add support for am62a7 dss
  drivers/tidss: Add support for AM62A7 DSS

 .../bindings/display/ti/ti,am65x-dss.yaml | 14 +
 drivers/gpu/drm/tidss/tidss_dispc.c   | 53 +++
 drivers/gpu/drm/tidss/tidss_dispc.h   |  2 +
 drivers/gpu/drm/tidss/tidss_drv.c |  1 +
 4 files changed, 70 insertions(+)


base-commit: 47762f08697484cf0c2f2904b8c52375ed26c8cb
-- 
2.40.1



[PATCH v2 1/2] dt-bindings: display: ti: Add support for am62a7 dss

2023-08-18 Thread Aradhya Bhatia
The DSS controller on TI's AM62A7 SoC is an update from that on TI's
AM625 SoC. Like the DSS in AM625, the DSS in this SoC has 2 video
pipelines, but unlike the former, the latter only has one output port on
VP2 to service DPI display sinks.

Add the new controller's compatible.

Signed-off-by: Aradhya Bhatia 
---
Notes:
   Changes from V1:
   * No change from V1.

 .../bindings/display/ti/ti,am65x-dss.yaml  | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml 
b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
index ae09cd3cbce1..b6767ef0d24d 100644
--- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
+++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
@@ -23,6 +23,7 @@ properties:
   compatible:
 enum:
   - ti,am625-dss
+  - ti,am62a7,dss
   - ti,am65x-dss
 
   reg:
@@ -87,6 +88,7 @@ properties:
   For AM65x DSS, the OLDI output port node from video port 1.
   For AM625 DSS, the internal DPI output port node from video
   port 1.
+  For AM62A7 DSS, the port is tied off inside the SoC.
 
   port@1:
 $ref: /schemas/graph.yaml#/properties/port
@@ -108,6 +110,18 @@ properties:
   Input memory (from main memory to dispc) bandwidth limit in
   bytes per second
 
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+const: ti,am62a7-dss
+then:
+  properties:
+ports:
+  properties:
+port@0: false
+
 required:
   - compatible
   - reg
-- 
2.40.1



[PATCH v2 2/2] drivers/tidss: Add support for AM62A7 DSS

2023-08-18 Thread Aradhya Bhatia
Add support for the DSS controller on TI's AM62A7 SoC in the tidss
driver.

This contrller has 2 video pipelines that can render 2 video planes on
over a screen, using the overlay managers. The output of the DSS comes
from video port 2 (VP2) in the form of RGB88 DPI signals, while the VP1
is tied off inside the SoC.

Signed-off-by: Aradhya Bhatia 
---
Notes:
   Changes from V1:
   * Correctly sort DISPC_AM62A7 macro after DISPC_AM625.

 drivers/gpu/drm/tidss/tidss_dispc.c | 53 +
 drivers/gpu/drm/tidss/tidss_dispc.h |  2 ++
 drivers/gpu/drm/tidss/tidss_drv.c   |  1 +
 3 files changed, 56 insertions(+)

diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c 
b/drivers/gpu/drm/tidss/tidss_dispc.c
index 9d9dee7abaef..5539ddb7f338 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.c
+++ b/drivers/gpu/drm/tidss/tidss_dispc.c
@@ -322,6 +322,54 @@ const struct dispc_features dispc_am625_feats = {
.vid_order = { 1, 0 },
 };
 
+const struct dispc_features dispc_am62a7_feats = {
+   .max_pclk_khz = {
+   [DISPC_VP_DPI] = 165000,
+   },
+
+   .scaling = {
+   .in_width_max_5tap_rgb = 1280,
+   .in_width_max_3tap_rgb = 2560,
+   .in_width_max_5tap_yuv = 2560,
+   .in_width_max_3tap_yuv = 4096,
+   .upscale_limit = 16,
+   .downscale_limit_5tap = 4,
+   .downscale_limit_3tap = 2,
+   /*
+* The max supported pixel inc value is 255. The value
+* of pixel inc is calculated like this: 1+(xinc-1)*bpp.
+* The maximum bpp of all formats supported by the HW
+* is 8. So the maximum supported xinc value is 32,
+* because 1+(32-1)*8 < 255 < 1+(33-1)*4.
+*/
+   .xinc_max = 32,
+   },
+
+   .subrev = DISPC_AM62A7,
+
+   .common = "common",
+   .common_regs = tidss_am65x_common_regs,
+
+   .num_vps = 2,
+   .vp_name = { "vp1", "vp2" },
+   .ovr_name = { "ovr1", "ovr2" },
+   .vpclk_name =  { "vp1", "vp2" },
+   .vp_bus_type = { DISPC_VP_INTERNAL, DISPC_VP_DPI },
+
+   .vp_feat = { .color = {
+   .has_ctm = true,
+   .gamma_size = 256,
+   .gamma_type = TIDSS_GAMMA_8BIT,
+   },
+   },
+
+   .num_planes = 2,
+   /* note: vid is plane_id 0 and vidl1 is plane_id 1 */
+   .vid_name = { "vid", "vidl1" },
+   .vid_lite = { false, true, },
+   .vid_order = { 1, 0 },
+};
+
 static const u16 *dispc_common_regmap;
 
 struct dss_vp_data {
@@ -824,6 +872,7 @@ dispc_irq_t dispc_read_and_clear_irqstatus(struct 
dispc_device *dispc)
case DISPC_K2G:
return dispc_k2g_read_and_clear_irqstatus(dispc);
case DISPC_AM625:
+   case DISPC_AM62A7:
case DISPC_AM65X:
case DISPC_J721E:
return dispc_k3_read_and_clear_irqstatus(dispc);
@@ -840,6 +889,7 @@ void dispc_set_irqenable(struct dispc_device *dispc, 
dispc_irq_t mask)
dispc_k2g_set_irqenable(dispc, mask);
break;
case DISPC_AM625:
+   case DISPC_AM62A7:
case DISPC_AM65X:
case DISPC_J721E:
dispc_k3_set_irqenable(dispc, mask);
@@ -1331,6 +1381,7 @@ void dispc_ovr_set_plane(struct dispc_device *dispc, u32 
hw_plane,
x, y, layer);
break;
case DISPC_AM625:
+   case DISPC_AM62A7:
case DISPC_AM65X:
dispc_am65x_ovr_set_plane(dispc, hw_plane, hw_videoport,
  x, y, layer);
@@ -2250,6 +2301,7 @@ static void dispc_plane_init(struct dispc_device *dispc)
dispc_k2g_plane_init(dispc);
break;
case DISPC_AM625:
+   case DISPC_AM62A7:
case DISPC_AM65X:
case DISPC_J721E:
dispc_k3_plane_init(dispc);
@@ -2357,6 +2409,7 @@ static void dispc_vp_write_gamma_table(struct 
dispc_device *dispc,
dispc_k2g_vp_write_gamma_table(dispc, hw_videoport);
break;
case DISPC_AM625:
+   case DISPC_AM62A7:
case DISPC_AM65X:
dispc_am65x_vp_write_gamma_table(dispc, hw_videoport);
break;
diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h 
b/drivers/gpu/drm/tidss/tidss_dispc.h
index 33ac5ad7a423..7f203f83559b 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.h
+++ b/drivers/gpu/drm/tidss/tidss_dispc.h
@@ -60,6 +60,7 @@ enum dispc_vp_bus_type {
 enum dispc_dss_subrevision {
DISPC_K2G,
DISPC_AM625,
+   DISPC_AM62A7,
DISPC_AM65X,
DISPC_J721E,
 };
@@ -88,6 +89,7 @@ struct dispc_features {
 
 extern const struct dispc_features dispc_k2g_feats;
 extern const struct dispc_features dispc_am625_feats;
+extern const struct dispc_features dispc_am62a7_feats;
 extern const struct dispc_features dispc_am65x_feats;
 

Re: [PATCH v2 10/15] drm/panthor: Add the heap logical block

2023-08-18 Thread Steven Price
On 09/08/2023 17:53, Boris Brezillon wrote:
> Tiler heap growing requires some kernel driver involvement: when the
> tiler runs out of heap memory, it will raise an exception which is
> either directly handled by the firmware if some free heap chunks are
> available in the heap context, or passed back to the kernel otherwise.
> The heap helpers will be used by the scheduler logic to allocate more
> heap chunks to a heap context, when such a situation happens.
> 
> Heap context creation is explicitly requested by userspace (using
> the TILER_HEAP_CREATE ioctl), and the returned context is attached to a
> queue through some command stream instruction.
> 
> All the kernel does is keep the list of heap chunks allocated to a
> context, so they can be freed when TILER_HEAP_DESTROY is called, or
> extended when the FW requests a new chunk.
> 
> v2:
> - Rename the driver (pancsf -> panthor)
> - Split the driver addition commit
> - Document the code
> - Fix various bugs
> 
> Signed-off-by: Boris Brezillon 

Mostly looks good, but I think we might have issues with struct
panthor_heap_gpu_ctx potentially being smaller than a (GPU) cache line
(see below).

> ---
>  drivers/gpu/drm/panthor/panthor_heap.c | 550 +
>  drivers/gpu/drm/panthor/panthor_heap.h |  36 ++
>  2 files changed, 586 insertions(+)
>  create mode 100644 drivers/gpu/drm/panthor/panthor_heap.c
>  create mode 100644 drivers/gpu/drm/panthor/panthor_heap.h
> 
> diff --git a/drivers/gpu/drm/panthor/panthor_heap.c 
> b/drivers/gpu/drm/panthor/panthor_heap.c
> new file mode 100644
> index ..39244efc2eaa
> --- /dev/null
> +++ b/drivers/gpu/drm/panthor/panthor_heap.c
> @@ -0,0 +1,550 @@
> +// SPDX-License-Identifier: GPL-2.0 or MIT
> +/* Copyright 2023 Collabora ltd. */
> +
> +#include 
> +#include 
> +
> +#include 
> +
> +#include "panthor_device.h"
> +#include "panthor_gem.h"
> +#include "panthor_heap.h"
> +#include "panthor_mmu.h"
> +
> +/**
> + * struct panthor_heap_gpu_ctx - Heap context used by the GPU/FW.
> + */
> +struct panthor_heap_gpu_ctx {
> + /**
> +  * @first_heap_chunk: GPU VA of the first free heap chunk.
> +  *
> +  * This forms a single-link list, where each chunk points to the
> +  * next free chunk, and the last element points to NULL.
> +  *
> +  * Heap chunks get freed and returned to the heap context when fragment
> +  * jobs picking data from those heap chunks complete. When this happens
> +  * this field is updated to insert the heap chunks that were freed.
> +  *
> +  * When the tiler runs out of memory, it will first check if there
> +  * are free heap chunks in the heap context, and pick those if there 
> are.
> +  *
> +  * When there is no free heap chunks left, the FW will raise a TILER_OOM
> +  * interrupt, letting the kernel driver allocate more heap chunks.
> +  *
> +  * If the heap context reached its heap chunk limit, the FW will wait
> +  * for fragment jobs to consume some data and return chunks to the
> +  * context.
> +  *
> +  * As a last resort, if there is no in-flight fragment jobs, the FW
> +  * will try to execute the exception handler set on the command stream.
> +  * This exception handler is expected to issue fragment job to store
> +  * the partial rendering results, free up some heap chunks.
> +  */
> + u64 first_heap_chunk;
> +
> + /** @unused1: MBZ. */
> + u32 unused1[2];
> +
> + /**
> +  * @vt_started_count: Number of vertex/tiling operations started.
> +  *
> +  * This is marking the beginning of a render pass, and is explicity

s/explicity/explicitly/

> +  * flagged with a HEAP_OPERATION.vt_start instruction. If the render 
> pass
> +  * contains multiple vertex/tiler/IDVS jobs, this 
> HEAP_OPERATION.vt_start
> +  * is only called once.
> +  */
> + u32 vt_started_count;
> +
> + /**
> +  * @vt_completed_count: Number of completed vertex/tiler jobs.
> +  *
> +  * This is marking the end of the geometry processing part of a render
> +  * pass, and is explicity flagged by the user command stream with

s/explicity/explicitly/

> +  * a HEAP_OPERATION.vt_completed instruction. If the render pass 
> contains
> +  * multiple vertex/tiler/IDVS jobs, this HEAP_OPERATION.vt_end
> +  * instruction is only issued once.
> +  */
> + u32 vt_completed_count;
> +
> + /** @unused2: MBZ. */
> + u32 unused2;
> +
> + /**
> +  * @frag_completed_count: Number of completed fragment jobs.
> +  *
> +  * @vt_started_count - @frag_completed_count is the number of in-flight
> +  * render targets that's used by the driver to determine if it's worth
> +  * allocating new chunk or if we should instead wait for fragment jobs
> +  * to complete.
> +  *
> +  * Fragment completion is explicitly flagged by the user command stream
> +  * with a HEAP_OPERATION.frag_end or FINIS

Re: [Linaro-mm-sig] [PATCH] dma-buf/sw_sync: Avoid recursive lock during fence signal

2023-08-18 Thread Rob Clark
On Fri, Aug 18, 2023 at 2:09 AM Christian König
 wrote:
>
> Am 17.08.23 um 23:37 schrieb Rob Clark:
> > From: Rob Clark 
> >
> > If a signal callback releases the sw_sync fence, that will trigger a
> > deadlock as the timeline_fence_release recurses onto the fence->lock
> > (used both for signaling and the the timeline tree).
> >
> > To avoid that, temporarily hold an extra reference to the signalled
> > fences until after we drop the lock.
> >
> > (This is an alternative implementation of 
> > https://patchwork.kernel.org/patch/11664717/
> > which avoids some potential UAF issues with the original patch.)
> >
> > Reported-by: Bas Nieuwenhuizen 
> > Fixes: d3c6dd1fb30d ("dma-buf/sw_sync: Synchronize signal vs syncpt free")
> > Signed-off-by: Rob Clark 
> > ---
> >   drivers/dma-buf/sw_sync.c | 10 ++
> >   1 file changed, 10 insertions(+)
> >
> > diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
> > index 63f0aeb66db6..ceb6a0408624 100644
> > --- a/drivers/dma-buf/sw_sync.c
> > +++ b/drivers/dma-buf/sw_sync.c
> > @@ -191,6 +191,7 @@ static const struct dma_fence_ops timeline_fence_ops = {
> >*/
> >   static void sync_timeline_signal(struct sync_timeline *obj, unsigned int 
> > inc)
> >   {
> > + LIST_HEAD(signalled);
> >   struct sync_pt *pt, *next;
> >
> >   trace_sync_timeline(obj);
> > @@ -203,9 +204,13 @@ static void sync_timeline_signal(struct sync_timeline 
> > *obj, unsigned int inc)
> >   if (!timeline_fence_signaled(&pt->base))
> >   break;
> >
> > + dma_fence_get(&pt->base);
>
> Question is why don't have the fences a reference on the list in the
> first place?

As best I can tell, it is because the fences hold a reference to the
timeline, so a reference in the other direction would cause a loop.

BR,
-R

> > +
> >   list_del_init(&pt->link);
> >   rb_erase(&pt->node, &obj->pt_tree);
> >
> > + list_add_tail(&pt->link, &signalled);
>
> Instead of list_del()/list_add_tail() you could also use
> list_move_tail() here.
>
> > +
> >   /*
> >* A signal callback may release the last reference to this
> >* fence, causing it to be freed. That operation has to be
> > @@ -218,6 +223,11 @@ static void sync_timeline_signal(struct sync_timeline 
> > *obj, unsigned int inc)
> >   }
> >
> >   spin_unlock_irq(&obj->lock);
> > +
> > + list_for_each_entry_safe(pt, next, &signalled, link) {
> > + list_del(&pt->link);
>
> You must use list_del_init() here or otherwise the pt->link will keep
> pointing to the prev/next entries and the list_empty() check in
> timeline_fence_release() will fail and potentially corrupt things.
>
> Regards,
> Christian.
>
> > + dma_fence_put(&pt->base);
> > + }
> >   }
> >
> >   /**
>


Re: [PATCH 1/7] drm: adv7511: Add struct adv7511_chip_info and use i2c_get_match_data()

2023-08-18 Thread Adam Ford
On Sun, Aug 13, 2023 at 1:05 PM Biju Das  wrote:
>
> Add struct adv7511_chip_info to handle hw differences between various
> chips rather checking against the 'type' variable in various places.
> Replace 'adv->type'->'info->type' by moving variable 'type' from
> struct adv7511 to struct adv7511_chip_info.
>
> Replace of_device_get_match_data() and ID lookup for retrieving match data
> with i2c_get_match_data() by adding adv7511_chip_info as device data for
> both OF and ID tables.
>
> Signed-off-by: Biju Das 

Reviewed-by: Adam Ford 
> ---
>  drivers/gpu/drm/bridge/adv7511/adv7511.h |  6 +-
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 68 +++-
>  drivers/gpu/drm/bridge/adv7511/adv7533.c |  4 +-
>  3 files changed, 46 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
> b/drivers/gpu/drm/bridge/adv7511/adv7511.h
> index 17445800248d..59e8ef10d72e 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
> @@ -333,6 +333,10 @@ enum adv7511_type {
>
>  #define ADV7511_MAX_ADDRS 3
>
> +struct adv7511_chip_info {
> +   enum adv7511_type type;
> +};
> +
>  struct adv7511 {
> struct i2c_client *i2c_main;
> struct i2c_client *i2c_edid;
> @@ -377,7 +381,7 @@ struct adv7511 {
> u8 num_dsi_lanes;
> bool use_timing_gen;
>
> -   enum adv7511_type type;
> +   const struct adv7511_chip_info *info;
> struct platform_device *audio_pdev;
>
> struct cec_adapter *cec_adap;
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> index 2611afd2c1c1..013d8d640ef4 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> @@ -354,7 +354,7 @@ static void __adv7511_power_on(struct adv7511 *adv7511)
>  * first few seconds after enabling the output. On the other hand
>  * adv7535 require to enable HPD Override bit for proper HPD.
>  */
> -   if (adv7511->type == ADV7535)
> +   if (adv7511->info->type == ADV7535)
> regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
>ADV7535_REG_POWER2_HPD_OVERRIDE,
>ADV7535_REG_POWER2_HPD_OVERRIDE);
> @@ -373,7 +373,7 @@ static void adv7511_power_on(struct adv7511 *adv7511)
>  */
> regcache_sync(adv7511->regmap);
>
> -   if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
> +   if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535)
> adv7533_dsi_power_on(adv7511);
> adv7511->powered = true;
>  }
> @@ -381,7 +381,7 @@ static void adv7511_power_on(struct adv7511 *adv7511)
>  static void __adv7511_power_off(struct adv7511 *adv7511)
>  {
> /* TODO: setup additional power down modes */
> -   if (adv7511->type == ADV7535)
> +   if (adv7511->info->type == ADV7535)
> regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
>ADV7535_REG_POWER2_HPD_OVERRIDE, 0);
>
> @@ -397,7 +397,7 @@ static void __adv7511_power_off(struct adv7511 *adv7511)
>  static void adv7511_power_off(struct adv7511 *adv7511)
>  {
> __adv7511_power_off(adv7511);
> -   if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
> +   if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535)
> adv7533_dsi_power_off(adv7511);
> adv7511->powered = false;
>  }
> @@ -682,7 +682,7 @@ adv7511_detect(struct adv7511 *adv7511, struct 
> drm_connector *connector)
> status = connector_status_disconnected;
> } else {
> /* Renable HPD sensing */
> -   if (adv7511->type == ADV7535)
> +   if (adv7511->info->type == ADV7535)
> regmap_update_bits(adv7511->regmap, 
> ADV7511_REG_POWER2,
>ADV7535_REG_POWER2_HPD_OVERRIDE,
>ADV7535_REG_POWER2_HPD_OVERRIDE);
> @@ -786,7 +786,7 @@ static void adv7511_mode_set(struct adv7511 *adv7511,
> else
> low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE;
>
> -   if (adv7511->type == ADV7511)
> +   if (adv7511->info->type == ADV7511)
> regmap_update_bits(adv7511->regmap, 0xfb,
>0x6, low_refresh_rate << 1);
> else
> @@ -921,7 +921,7 @@ static enum drm_mode_status 
> adv7511_bridge_mode_valid(struct drm_bridge *bridge,
>  {
> struct adv7511 *adv = bridge_to_adv7511(bridge);
>
> -   if (adv->type == ADV7533 || adv->type == ADV7535)
> +   if (adv->info->type == ADV7533 || adv->info->type == ADV7535)
> return adv7533_mode_valid(adv, mode);
> else
> return adv7511_mode_valid(adv, mode);
> @@ -1009,7 +1009,7 @@ static int 

[PATCH v2] dma-buf/sw_sync: Avoid recursive lock during fence signal

2023-08-18 Thread Rob Clark
From: Rob Clark 

If a signal callback releases the sw_sync fence, that will trigger a
deadlock as the timeline_fence_release recurses onto the fence->lock
(used both for signaling and the the timeline tree).

To avoid that, temporarily hold an extra reference to the signalled
fences until after we drop the lock.

(This is an alternative implementation of 
https://patchwork.kernel.org/patch/11664717/
which avoids some potential UAF issues with the original patch.)

v2: Remove now obsolete comment, use list_move_tail() and
list_del_init()

Reported-by: Bas Nieuwenhuizen 
Fixes: d3c6dd1fb30d ("dma-buf/sw_sync: Synchronize signal vs syncpt free")
Signed-off-by: Rob Clark 
---
 drivers/dma-buf/sw_sync.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 63f0aeb66db6..f0a35277fd84 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -191,6 +191,7 @@ static const struct dma_fence_ops timeline_fence_ops = {
  */
 static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
 {
+   LIST_HEAD(signalled);
struct sync_pt *pt, *next;
 
trace_sync_timeline(obj);
@@ -203,21 +204,20 @@ static void sync_timeline_signal(struct sync_timeline 
*obj, unsigned int inc)
if (!timeline_fence_signaled(&pt->base))
break;
 
-   list_del_init(&pt->link);
+   dma_fence_get(&pt->base);
+
+   list_move_tail(&pt->link, &signalled);
rb_erase(&pt->node, &obj->pt_tree);
 
-   /*
-* A signal callback may release the last reference to this
-* fence, causing it to be freed. That operation has to be
-* last to avoid a use after free inside this loop, and must
-* be after we remove the fence from the timeline in order to
-* prevent deadlocking on timeline->lock inside
-* timeline_fence_release().
-*/
dma_fence_signal_locked(&pt->base);
}
 
spin_unlock_irq(&obj->lock);
+
+   list_for_each_entry_safe(pt, next, &signalled, link) {
+   list_del_init(&pt->link);
+   dma_fence_put(&pt->base);
+   }
 }
 
 /**
-- 
2.41.0



Re: [PATCH] drm/amd/display: fix mode scaling (RMX_.*)

2023-08-18 Thread Harry Wentland



On 2023-08-18 09:17, Hamza Mahfooz wrote:
> As made mention of in commit 4a2df0d1f28e ("drm/amd/display: Fixed
> non-native modes not lighting up"), we shouldn't call
> drm_mode_set_crtcinfo() once the crtc timings have been decided. Since,
> it can cause settings to be unintentionally overwritten. So, since
> dm_state is never NULL now, we can use old_stream to determine if we
> should call drm_mode_set_crtcinfo() because we only need to set the crtc
> timing parameters for entirely new streams.
> 
> Cc: Harry Wentland 
> Cc: Rodrigo Siqueira 
> Fixes: 712237a4a1b4 ("drm/amd/display: Always set crtcinfo from 
> create_stream_for_sink")
> Signed-off-by: Hamza Mahfooz 

Reviewed-by: Harry Wentland 

Harry

> ---
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 3b27b7742854..e9aff5014e39 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -6035,7 +6035,7 @@ create_stream_for_sink(struct amdgpu_dm_connector 
> *aconnector,
>  
>   if (recalculate_timing)
>   drm_mode_set_crtcinfo(&saved_mode, 0);
> - else
> + else if (!old_stream)
>   drm_mode_set_crtcinfo(&mode, 0);
>  
>   /*



[PATCH 0/4] drm/xe: Support optional pinning of userptr pages

2023-08-18 Thread Thomas Hellström
This series add a flag at VM_BIND time to pin the memory backing a VMA.
Initially this is needed for long-running workloads on hardware that
neither support mid-thread preemption nor pagefaults, since without it
the userptr MMU notifier will wait for preemption until preemption times
out.

Moving forward this could be supported also for bo-backed VMAs given
a proper accounting takes place. A sysadmin could then optionally configure
a system to be optimized for dealing with a single GPU application
at a time.

The series will be followed up with an igt series to exercise the uAPI.

Thomas Hellström (4):
  drm/xe/vm: Use onion unwind for xe_vma_userptr_pin_pages()
  drm/xe/vm: Implement userptr page pinning
  drm/xe/vm: Perform accounting of userptr pinned pages
  drm/xe/uapi: Support pinning of userptr vmas

 drivers/gpu/drm/xe/xe_vm.c   | 181 +++
 drivers/gpu/drm/xe/xe_vm.h   |   9 ++
 drivers/gpu/drm/xe/xe_vm_types.h |  14 +++
 include/uapi/drm/xe_drm.h|  18 +++
 4 files changed, 176 insertions(+), 46 deletions(-)

-- 
2.41.0



[PATCH 1/4] drm/xe/vm: Use onion unwind for xe_vma_userptr_pin_pages()

2023-08-18 Thread Thomas Hellström
Use onion error unwind since that makes the function easier to read
and extend. No functional change.

Signed-off-by: Thomas Hellström 
---
 drivers/gpu/drm/xe/xe_vm.c | 37 +++--
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 2e99f865d7ec..8bf7f62e6548 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -116,19 +116,17 @@ int xe_vma_userptr_pin_pages(struct xe_vma *vma)
kthread_unuse_mm(vma->userptr.notifier.mm);
mmput(vma->userptr.notifier.mm);
}
-mm_closed:
if (ret)
-   goto out;
+   goto out_release_pages;
 
ret = sg_alloc_table_from_pages_segment(&vma->userptr.sgt, pages,
pinned, 0,
(u64)pinned << PAGE_SHIFT,
xe_sg_segment_size(xe->drm.dev),
GFP_KERNEL);
-   if (ret) {
-   vma->userptr.sg = NULL;
-   goto out;
-   }
+   if (ret)
+   goto out_release_pages;
+
vma->userptr.sg = &vma->userptr.sgt;
 
ret = dma_map_sgtable(xe->drm.dev, vma->userptr.sg,
@@ -136,11 +134,8 @@ int xe_vma_userptr_pin_pages(struct xe_vma *vma)
  DMA_BIDIRECTIONAL,
  DMA_ATTR_SKIP_CPU_SYNC |
  DMA_ATTR_NO_KERNEL_MAPPING);
-   if (ret) {
-   sg_free_table(vma->userptr.sg);
-   vma->userptr.sg = NULL;
-   goto out;
-   }
+   if (ret)
+   goto out_free_sg;
 
for (i = 0; i < pinned; ++i) {
if (!read_only) {
@@ -152,17 +147,23 @@ int xe_vma_userptr_pin_pages(struct xe_vma *vma)
mark_page_accessed(pages[i]);
}
 
-out:
release_pages(pages, pinned);
kvfree(pages);
 
-   if (!(ret < 0)) {
-   vma->userptr.notifier_seq = notifier_seq;
-   if (xe_vma_userptr_check_repin(vma) == -EAGAIN)
-   goto retry;
-   }
+   vma->userptr.notifier_seq = notifier_seq;
+   if (xe_vma_userptr_check_repin(vma) == -EAGAIN)
+   goto retry;
+
+   return 0;
 
-   return ret < 0 ? ret : 0;
+out_free_sg:
+   sg_free_table(vma->userptr.sg);
+   vma->userptr.sg = NULL;
+out_release_pages:
+   release_pages(pages, pinned);
+mm_closed:
+   kvfree(pages);
+   return ret;
 }
 
 static bool preempt_fences_waiting(struct xe_vm *vm)
-- 
2.41.0



[PATCH 2/4] drm/xe/vm: Implement userptr page pinning

2023-08-18 Thread Thomas Hellström
Implement pinning of userptrs between VM_BIND and VM_UNBIND, which will
facilitate avoiding long hangs on non-preemptible workloads. But don't
hook it up to userspace just yet.

Signed-off-by: Thomas Hellström 
---
 drivers/gpu/drm/xe/xe_vm.c   | 76 ++--
 drivers/gpu/drm/xe/xe_vm.h   |  9 
 drivers/gpu/drm/xe/xe_vm_types.h | 12 +
 3 files changed, 74 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 8bf7f62e6548..ecbcad696b60 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -74,10 +74,6 @@ int xe_vma_userptr_pin_pages(struct xe_vma *vma)
if (notifier_seq == vma->userptr.notifier_seq)
return 0;
 
-   pages = kvmalloc_array(num_pages, sizeof(*pages), GFP_KERNEL);
-   if (!pages)
-   return -ENOMEM;
-
if (vma->userptr.sg) {
dma_unmap_sgtable(xe->drm.dev,
  vma->userptr.sg,
@@ -87,6 +83,17 @@ int xe_vma_userptr_pin_pages(struct xe_vma *vma)
vma->userptr.sg = NULL;
}
 
+   if (vma->userptr.pinned_pages) {
+   unpin_user_pages_dirty_lock(vma->userptr.pinned_pages,
+   vma->userptr.num_pinned,
+   !read_only);
+   pages = vma->userptr.pinned_pages;
+   } else {
+   pages = kvmalloc_array(num_pages, sizeof(*pages), GFP_KERNEL);
+   if (!pages)
+   return -ENOMEM;
+   }
+
pinned = ret = 0;
if (in_kthread) {
if (!mmget_not_zero(vma->userptr.notifier.mm)) {
@@ -97,11 +104,18 @@ int xe_vma_userptr_pin_pages(struct xe_vma *vma)
}
 
while (pinned < num_pages) {
-   ret = get_user_pages_fast(xe_vma_userptr(vma) +
- pinned * PAGE_SIZE,
- num_pages - pinned,
- read_only ? 0 : FOLL_WRITE,
- &pages[pinned]);
+   if (xe_vma_is_pinned(vma))
+   ret = pin_user_pages_fast(xe_vma_userptr(vma) +
+ pinned * PAGE_SIZE,
+ num_pages - pinned,
+ read_only ? 0 : FOLL_WRITE,
+ &pages[pinned]);
+   else
+   ret = get_user_pages_fast(xe_vma_userptr(vma) +
+ pinned * PAGE_SIZE,
+ num_pages - pinned,
+ read_only ? 0 : FOLL_WRITE,
+ &pages[pinned]);
if (ret < 0) {
if (in_kthread)
ret = 0;
@@ -137,19 +151,24 @@ int xe_vma_userptr_pin_pages(struct xe_vma *vma)
if (ret)
goto out_free_sg;
 
-   for (i = 0; i < pinned; ++i) {
-   if (!read_only) {
-   lock_page(pages[i]);
-   set_page_dirty(pages[i]);
-   unlock_page(pages[i]);
+   if (!xe_vma_is_pinned(vma)) {
+   for (i = 0; i < pinned; ++i) {
+   if (!read_only) {
+   lock_page(pages[i]);
+   set_page_dirty(pages[i]);
+   unlock_page(pages[i]);
+   }
+
+   mark_page_accessed(pages[i]);
}
 
-   mark_page_accessed(pages[i]);
+   release_pages(pages, pinned);
+   kvfree(pages);
+   } else {
+   vma->userptr.pinned_pages = pages;
+   vma->userptr.num_pinned = pinned;
}
 
-   release_pages(pages, pinned);
-   kvfree(pages);
-
vma->userptr.notifier_seq = notifier_seq;
if (xe_vma_userptr_check_repin(vma) == -EAGAIN)
goto retry;
@@ -160,9 +179,14 @@ int xe_vma_userptr_pin_pages(struct xe_vma *vma)
sg_free_table(vma->userptr.sg);
vma->userptr.sg = NULL;
 out_release_pages:
-   release_pages(pages, pinned);
+   if (!xe_vma_is_pinned(vma))
+   release_pages(pages, pinned);
+   else
+   unpin_user_pages(pages, pinned);
+   vma->userptr.num_pinned = 0;
 mm_closed:
kvfree(pages);
+   vma->userptr.pinned_pages = NULL;
return ret;
 }
 
@@ -721,7 +745,7 @@ static bool vma_userptr_invalidate(struct 
mmu_interval_notifier *mni,
mmu_interval_set_seq(mni, cur_seq);
 
/* No need to stop gpu access if the userptr is not yet bound. */
-   if (!vma->userptr.initial_bind) {
+   if (xe_vma_is_pinned(vma) || !vma-

[PATCH 3/4] drm/xe/vm: Perform accounting of userptr pinned pages

2023-08-18 Thread Thomas Hellström
Account these pages against RLIMIT_MEMLOCK following how RDMA does this
with CAP_IPC_LOCK bypassing the limit.

Signed-off-by: Thomas Hellström 
---
 drivers/gpu/drm/xe/xe_vm.c | 43 --
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index ecbcad696b60..d9c000689002 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -34,6 +34,33 @@
 
 #define TEST_VM_ASYNC_OPS_ERROR
 
+/*
+ * Perform userptr PIN accounting against RLIMIT_MEMLOCK for now, similarly
+ * to how RDMA does this.
+ */
+static int xe_vma_mlock_alloc(struct xe_vma *vma, unsigned long num_pages)
+{
+   unsigned long lock_limit, new_pinned;
+   struct mm_struct *mm = vma->userptr.notifier.mm;
+
+   if (!can_do_mlock())
+   return -EPERM;
+
+   lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+   new_pinned = atomic64_add_return(num_pages, &mm->pinned_vm);
+   if (new_pinned > lock_limit && !capable(CAP_IPC_LOCK)) {
+   atomic64_sub(num_pages, &mm->pinned_vm);
+   return -ENOMEM;
+   }
+
+   return 0;
+}
+
+static void xe_vma_mlock_free(struct xe_vma *vma, unsigned long num_pages)
+{
+   atomic64_sub(num_pages, &vma->userptr.notifier.mm->pinned_vm);
+}
+
 /**
  * xe_vma_userptr_check_repin() - Advisory check for repin needed
  * @vma: The userptr vma
@@ -89,9 +116,17 @@ int xe_vma_userptr_pin_pages(struct xe_vma *vma)
!read_only);
pages = vma->userptr.pinned_pages;
} else {
+   if (xe_vma_is_pinned(vma)) {
+   ret = xe_vma_mlock_alloc(vma, num_pages);
+   if (ret)
+   return ret;
+   }
+
pages = kvmalloc_array(num_pages, sizeof(*pages), GFP_KERNEL);
-   if (!pages)
-   return -ENOMEM;
+   if (!pages) {
+   ret = -ENOMEM;
+   goto out_account;
+   }
}
 
pinned = ret = 0;
@@ -187,6 +222,9 @@ int xe_vma_userptr_pin_pages(struct xe_vma *vma)
 mm_closed:
kvfree(pages);
vma->userptr.pinned_pages = NULL;
+out_account:
+   if (xe_vma_is_pinned(vma))
+   xe_vma_mlock_free(vma, num_pages);
return ret;
 }
 
@@ -1004,6 +1042,7 @@ static void xe_vma_destroy_late(struct xe_vma *vma)
unpin_user_pages_dirty_lock(vma->userptr.pinned_pages,
vma->userptr.num_pinned,
!read_only);
+   xe_vma_mlock_free(vma, xe_vma_size(vma) >> PAGE_SHIFT);
kvfree(vma->userptr.pinned_pages);
}
 
-- 
2.41.0



[PATCH 4/4] drm/xe/uapi: Support pinning of userptr vmas

2023-08-18 Thread Thomas Hellström
Support pinning of vmas using XE_VM_BIND_FLAG_PIN, initially for userptr
only. Pinned memory becomes accounted against RLIMIT_MEMLOCK and processes
with CAP_IPC_LOCK will not apply the limit. This is pretty similar to
mlock()'ing userptr memory with the added benefit that the driver is
aware and can ignore some actions in the MMU invalidation notifier.

This will initially become useful for compute VMs on hardware without
mid-thread-preemption capability since with pinned pages, the MMU
invalidation notifier never tries to preempt a running compute kernel.

If that were the only usage we could restrict this to a flag that always
pins userptr VMAs on compute VMs on such hardware, but there are
indications that this may become needed in other situations as well.

>From a more general point of view, the usage pattern of a system may be
such that in most cases it only ever runs a single workload per system
and then the sysadmin would want to configure the system to allow
extensive pinning for performance reasons.

Hence we might want to extend the pinning capability to bo-backed VMAs
as well. How that pinning will be accounted remains an open but to build
on the current drm CGROUP work would be an option.

Signed-off-by: Thomas Hellström 
---
 drivers/gpu/drm/xe/xe_vm.c   | 33 +---
 drivers/gpu/drm/xe/xe_vm_types.h |  2 ++
 include/uapi/drm/xe_drm.h| 18 +
 3 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index d9c000689002..3832f1f21def 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -936,6 +936,7 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
u64 start, u64 end,
bool read_only,
bool is_null,
+   bool pin,
u8 tile_mask)
 {
struct xe_vma *vma;
@@ -967,6 +968,8 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
vma->gpuva.flags |= XE_VMA_READ_ONLY;
if (is_null)
vma->gpuva.flags |= DRM_GPUVA_SPARSE;
+   if (pin)
+   vma->gpuva.flags |= XE_VMA_PINNED;
 
if (tile_mask) {
vma->tile_mask = tile_mask;
@@ -2367,6 +2370,7 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_bo 
*bo,
op->map.read_only =
operation & XE_VM_BIND_FLAG_READONLY;
op->map.is_null = operation & XE_VM_BIND_FLAG_NULL;
+   op->map.pin = operation & XE_VM_BIND_FLAG_PIN;
}
break;
case XE_VM_BIND_OP_UNMAP:
@@ -2431,7 +2435,8 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_bo 
*bo,
 }
 
 static struct xe_vma *new_vma(struct xe_vm *vm, struct drm_gpuva_op_map *op,
- u8 tile_mask, bool read_only, bool is_null)
+ u8 tile_mask, bool read_only, bool is_null,
+ bool pin)
 {
struct xe_bo *bo = op->gem.obj ? gem_to_xe_bo(op->gem.obj) : NULL;
struct xe_vma *vma;
@@ -2447,7 +2452,7 @@ static struct xe_vma *new_vma(struct xe_vm *vm, struct 
drm_gpuva_op_map *op,
}
vma = xe_vma_create(vm, bo, op->gem.offset,
op->va.addr, op->va.addr +
-   op->va.range - 1, read_only, is_null,
+   op->va.range - 1, read_only, is_null, pin,
tile_mask);
if (bo)
xe_bo_unlock(bo, &ww);
@@ -2562,7 +2567,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, 
struct xe_exec_queue *q,
 
vma = new_vma(vm, &op->base.map,
  op->tile_mask, op->map.read_only,
- op->map.is_null);
+ op->map.is_null, op->map.pin);
if (IS_ERR(vma)) {
err = PTR_ERR(vma);
goto free_fence;
@@ -2587,10 +2592,13 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, 
struct xe_exec_queue *q,
bool is_null =
op->base.remap.unmap->va->flags 
&
DRM_GPUVA_SPARSE;
+   bool pin =
+   op->base.remap.unmap->va->flags 
&
+   XE_VMA_PINNED;
 
vma = new_vma(vm, op->base.remap.prev,
  op->tile_mask, read_only,
- is_null);
+

Re: [PATCH v5 08/17] drm/imagination: Add GEM and VM related code

2023-08-18 Thread Danilo Krummrich
Hi Sarah,

On Wed, Aug 16, 2023 at 09:25:23AM +0100, Sarah Walker wrote:
> Add a GEM implementation based on drm_gem_shmem, and support code for the
> PowerVR GPU MMU. The GPU VA manager is used for address space management.
> 
> Changes since v4:
> - Correct sync function in vmap/vunmap function documentation
> - Update for upstream GPU VA manager
> - Fix missing frees when unmapping drm_gpuva objects
> - Always zero GEM BOs on creation
> 
> Changes since v3:
> - Split MMU and VM code
> - Register page table allocations with kmemleak
> - Use drm_dev_{enter,exit}
> 
> Changes since v2:
> - Use GPU VA manager
> - Use drm_gem_shmem
> 
> 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 |5 +-
>  drivers/gpu/drm/imagination/pvr_device.c |   23 +-
>  drivers/gpu/drm/imagination/pvr_device.h |   18 +
>  drivers/gpu/drm/imagination/pvr_drv.c|  302 ++-
>  drivers/gpu/drm/imagination/pvr_gem.c|  396 
>  drivers/gpu/drm/imagination/pvr_gem.h|  177 ++
>  drivers/gpu/drm/imagination/pvr_mmu.c| 2487 ++
>  drivers/gpu/drm/imagination/pvr_mmu.h|  108 +
>  drivers/gpu/drm/imagination/pvr_vm.c |  890 
>  drivers/gpu/drm/imagination/pvr_vm.h |   60 +
>  10 files changed, 4455 insertions(+), 11 deletions(-)
>  create mode 100644 drivers/gpu/drm/imagination/pvr_gem.c
>  create mode 100644 drivers/gpu/drm/imagination/pvr_gem.h
>  create mode 100644 drivers/gpu/drm/imagination/pvr_mmu.c
>  create mode 100644 drivers/gpu/drm/imagination/pvr_mmu.h
>  create mode 100644 drivers/gpu/drm/imagination/pvr_vm.c
>  create mode 100644 drivers/gpu/drm/imagination/pvr_vm.h



> diff --git a/drivers/gpu/drm/imagination/pvr_vm.c 
> b/drivers/gpu/drm/imagination/pvr_vm.c
> new file mode 100644
> index ..616fad3a3325
> --- /dev/null
> +++ b/drivers/gpu/drm/imagination/pvr_vm.c
> @@ -0,0 +1,890 @@
> +// SPDX-License-Identifier: GPL-2.0 OR MIT
> +/* Copyright (c) 2023 Imagination Technologies Ltd. */
> +
> +#include "pvr_vm.h"
> +
> +#include "pvr_device.h"
> +#include "pvr_drv.h"
> +#include "pvr_gem.h"
> +#include "pvr_mmu.h"
> +#include "pvr_rogue_fwif.h"
> +#include "pvr_rogue_heap_config.h"
> +
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +/**
> + * DOC: Memory context
> + *
> + * This is the "top level" datatype in the VM code. It's exposed in the 
> public
> + * API as an opaque handle.
> + */
> +
> +/**
> + * struct pvr_vm_context - Context type which encapsulates an entire page 
> table
> + * tree structure.
> + * @pvr_dev: The PowerVR device to which this context is bound.
> + *
> + * This binding is immutable for the life of the context.
> + * @mmu_ctx: The context for binding to physical memory.
> + * @gpuva_mgr: GPUVA manager object associated with this context.
> + * @lock: Global lock on this entire structure of page tables.
> + * @fw_mem_ctx_obj: Firmware object representing firmware memory context.
> + * @ref_count: Reference count of object.
> + */
> +struct pvr_vm_context {
> + struct pvr_device *pvr_dev;
> + struct pvr_mmu_context *mmu_ctx;
> + struct drm_gpuva_manager gpuva_mgr;
> + struct mutex lock;
> + struct pvr_fw_object *fw_mem_ctx_obj;
> + struct kref ref_count;
> +};
> +
> +/**
> + * pvr_vm_get_page_table_root_addr() - Get the DMA address of the root of the
> + * page table structure behind a VM 
> context.
> + * @vm_ctx: Target VM context.
> + */
> +dma_addr_t pvr_vm_get_page_table_root_addr(struct pvr_vm_context *vm_ctx)
> +{
> + return pvr_mmu_get_root_table_dma_addr(vm_ctx->mmu_ctx);
> +}
> +
> +/**
> + * DOC: Memory mappings
> + */
> +
> +/**
> + * pvr_vm_gpuva_mapping_init() - Setup a mapping object with the specified
> + * parameters ready for mapping using pvr_vm_gpuva_mapping_map().
> + * @va: Pointer to drm_gpuva mapping object.
> + * @device_addr: Device-virtual address at the start of the mapping.
> + * @size: Size of the desired mapping.
> + * @pvr_obj: Target PowerVR memory object.
> + * @pvr_obj_offset: Offset into @pvr_obj to begin mapping from.
> + *
> + * Some parameters of this function are unchecked. It is therefore the 
> callers
> + * responsibility to ensure certain constraints are met. Specifically:
> + *
> + * * @pvr_obj_offset must be less than the size of @pvr_obj,
> + * * The sum of @pvr_obj_offset and @size must be less than or equal to the
> + *   size of @pvr_obj,
> + * * The range specified by @pvr_obj_offset and @size (the "CPU range") must 
> be
> + *   CPU page-aligned both in start position and size, and
> + * * The range specified by @device_addr and @size (the "device range") must 
> be
> + *   device page-aligned both in start position and size.
> + *
> + * Furthermore, it is up to the caller to make sure t

Re: [v2,2/2] doc: uapi: Add document describing dma-buf semantics

2023-08-18 Thread suijingfeng

Hi,


On 2023/8/3 23:47, Daniel Stone wrote:

Since there's a lot of confusion around this, document both the rules
and the best practice around negotiating, allocating, importing, and



Probably, best practices?



using buffers when crossing context/process/device/subsystem boundaries.

This ties up all of dma-buf, formats and modifiers, and their usage.

Signed-off-by: Daniel Stone 
---
  Documentation/driver-api/dma-buf.rst  |   8 +
  Documentation/gpu/drm-uapi.rst|   7 +
  .../userspace-api/dma-buf-alloc-exchange.rst  | 384 ++
  Documentation/userspace-api/index.rst |   1 +
  4 files changed, 400 insertions(+)
  create mode 100644 Documentation/userspace-api/dma-buf-alloc-exchange.rst

v2:
  - Moved to general uAPI section, cross-referenced from dma-buf/DRM
  - Added Pekka's suggested glossary with some small changes
  - Cleanups and clarifications from Simon and James

diff --git a/Documentation/driver-api/dma-buf.rst 
b/Documentation/driver-api/dma-buf.rst
index 862dbc2759d0..0c153d79ccc4 100644
--- a/Documentation/driver-api/dma-buf.rst
+++ b/Documentation/driver-api/dma-buf.rst
@@ -22,6 +22,14 @@ interact with the three main primitives offered by dma-buf:
 allowing implicit (kernel-ordered) synchronization of work to
 preserve the illusion of coherent access
  
+

+Userspace API principles and use
+
+
+For more details on how to design your subsystem's API for dma-buf use, please
+see Documentation/userspace-api/dma-buf-alloc-exchange.rst.
+
+
  Shared DMA Buffers
  --
  
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst

index 65fb3036a580..eef5fd19bc92 100644
--- a/Documentation/gpu/drm-uapi.rst
+++ b/Documentation/gpu/drm-uapi.rst
@@ -486,3 +486,10 @@ and the CRTC index is its position in this array.
  
  .. kernel-doc:: include/uapi/drm/drm_mode.h

 :internal:
+
+
+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.
diff --git a/Documentation/userspace-api/dma-buf-alloc-exchange.rst 
b/Documentation/userspace-api/dma-buf-alloc-exchange.rst
new file mode 100644
index ..090453d2ad78
--- /dev/null
+++ b/Documentation/userspace-api/dma-buf-alloc-exchange.rst
@@ -0,0 +1,384 @@
+.. Copyright 2021-2023 Collabora Ltd.
+
+
+Exchanging pixel buffers
+
+
+As originally designed, the Linux graphics subsystem had extremely limited
+support for sharing pixel-buffer allocations between processes, devices, and
+subsystems. Modern systems require extensive integration between all three
+classes; this document details how applications and kernel subsystems should
+approach this sharing for two-dimensional image data.
+
+It is written with reference to the DRM subsystem for GPU and display devices,
+V4L2 for media devices, and also to Vulkan, EGL and Wayland, for userspace
+support, however any other subsystems should also follow this design and 
advice.
+
+
+Glossary of terms
+=
+
+.. glossary::
+
+image:
+  Conceptually a two-dimensional array of pixels. The pixels may be stored
+  in one or more memory buffers. Has width and height in pixels, pixel
+  format and modifier (implicit or explicit).
+
+row:
+  A span along a single y-axis value, e.g. from co-ordinates (0,100) to
+  (200,100).
+
+scanline:
+  Synonym for row.
+
+column:
+  A span along a single x-axis value, e.g. from co-ordinates (100,0) to
+  (100,100).
+
+memory buffer:
+  A piece of memory for storing (parts of) pixel data. Has stride and size
+  in bytes and at least one handle in some API. May contain one or more
+  planes.
+
+plane:
+  A two-dimensional array of some or all of an image's color and alpha
+  channel values.
+
+pixel:
+  A picture element. Has a single color value which is defined by one or
+  more color channels values, e.g. R, G and B, or Y, Cb and Cr. May also
+  have an alpha value as an additional channel.
+
+pixel data:
+  Bytes or bits that represent some or all of the color/alpha channel 
values
+  of a pixel or an image. The data for one pixel may be spread over several
+  planes or memory buffers depending on format and modifier.
+
+color value:
+  A tuple of numbers, representing a color. Each element in the tuple is a
+  color channel value.
+
+color channel:
+  One of the dimensions in a color model. For example, RGB model has
+  channels R, G, and B. Alpha channel is sometimes counted as a color
+  channel as well.
+
+pixel format:
+  A description of how pixel data represents the pixel's color and alpha
+  values.
+
+modifier:
+  A description of how pixel data is laid out in memory buffers.
+
+alpha:
+  A v

Re: (subset) [PATCH] backlight: lp855x: Drop ret variable in brightness change function

2023-08-18 Thread Lee Jones
On Wed, 09 Aug 2023 13:42:16 +0200, Artur Weber wrote:
> Fixes the following warning:
> 
> drivers/video/backlight/lp855x_bl.c:252:7: warning: variable 'ret' is used
> uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
> 
> 

Applied, thanks!

[1/1] backlight: lp855x: Drop ret variable in brightness change function
  commit: dfd122fe8591d513b5e51313601217b67ae98d13

--
Lee Jones [李琼斯]



Re: [PATCH v2 11/15] drm/panthor: Add the scheduler logical block

2023-08-18 Thread Steven Price
On 09/08/2023 17:53, Boris Brezillon wrote:
> This is the piece of software interacting with the FW scheduler, and
> taking care of some scheduling aspects when the FW comes short of slots
> scheduling slots. Indeed, the FW only expose a few slots, and the kernel
> has to give all submission contexts, a chance to execute their jobs.
> 
> The kernel-side scheduler is timeslice-based, with a round-robin queue
> per priority level.
> 
> Job submission is handled with a 1:1 drm_sched_entity:drm_gpu_scheduler,
> allowing us to delegate the dependency tracking to the core.
> 
> All the gory details should be documented inline.
> 
> v2:
> - Rename the driver (pancsf -> panthor)
> - Rename the file (_mcu -> _fw)
> - Change the license (GPL2 -> MIT + GPL2)
> - Split the driver addition commit
> - Document the code
> - Use drm_dev_{unplug,enter,exit}() to provide safe device removal
> - Move the ping logic to panthor_fw.c
> - Fix various bugs
> 
> Signed-off-by: Boris Brezillon 

Mostly typos below, but there is possibly inverted logic in
sched_queue_work() (and sched_queue_delayed_work()).

> ---
>  drivers/gpu/drm/panthor/panthor_sched.c | 3272 +++
>  drivers/gpu/drm/panthor/panthor_sched.h |   50 +
>  2 files changed, 3322 insertions(+)
>  create mode 100644 drivers/gpu/drm/panthor/panthor_sched.c
>  create mode 100644 drivers/gpu/drm/panthor/panthor_sched.h
> 
> diff --git a/drivers/gpu/drm/panthor/panthor_sched.c 
> b/drivers/gpu/drm/panthor/panthor_sched.c
> new file mode 100644
> index ..c1a516454e5d
> --- /dev/null
> +++ b/drivers/gpu/drm/panthor/panthor_sched.c
> @@ -0,0 +1,3272 @@
> +// SPDX-License-Identifier: GPL-2.0 or MIT
> +/* Copyright 2023 Collabora ltd. */
> +
> +#ifdef CONFIG_ARM_ARCH_TIMER
> +#include 
> +#endif
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "panthor_sched.h"
> +#include "panthor_devfreq.h"
> +#include "panthor_device.h"
> +#include "panthor_gem.h"
> +#include "panthor_heap.h"
> +#include "panthor_regs.h"
> +#include "panthor_gpu.h"
> +#include "panthor_fw.h"
> +#include "panthor_mmu.h"
> +
> +/**
> + * DOC: Scheduler
> + *
> + * Mali CSF hardware adopts a firmware-assited scheduling model, where

s/assited/assisted/

> + * the firmware takes care of scheduling aspects, to some extend.
> + *
> + * The scheduling happens at the scheduling group level, each group
> + * contains 1 to N queues (N is FW/hardware dependent, and exposed
> + * through the firmware interface). Each queue is assigned a command
> + * stream ring buffer, which serves as a way to get jobs submitted to
> + * the GPU, among other things.
> + *
> + * The firmware can schedule a maximum of M groups (M is FW/hardware
> + * dependent, and exposed through the firmware interface). Passed
> + * this maximum number of groups, the kernel must take care of
> + * rotating the groups passed to the firmware so every group gets
> + * a chance to have his queues scheduled for execution.
> + *
> + * The current implementation only supports with kernel-mode queues.
> + * In other terms, userspace doesn't have access to the ring-buffer.
> + * Instead, userspace passes indirect command stream buffers that are
> + * called from the queue ring-buffer by the kernel using a pre-defined
> + * sequence of command stream instructions to ensure the userspace driver
> + * always gets consistent results (cache maintenance,
> + * synchronization, ...).
> + *
> + * We rely on the drm_gpu_scheduler framework to deal with job
> + * dependencies and submission. As any other driver dealing with a
> + * FW-scheduler, we use the 1:1 entity:scheduler mode, such that each
> + * entity has its own job scheduler. When a job is ready to be executed
> + * (all its dependencies are met), it is pushed to the appropriate
> + * queue ring-buffer, and the group is scheduled for execution if it
> + * wasn't already active.
> + *
> + * Kernel-side group scheduling is timeslice-based. When we have less
> + * groups than there are slots, the periodic tick is disabled and we
> + * just let the FW schedule the active groups. When there are more
> + * groups than slots, we let each group a chance to execute stuff for
> + * a given amount of time, and then re-evaluate and pick new groups
> + * to schedule. The group selection algorithm is based on
> + * priority+round-robin.
> + *
> + * Even though user-mode queues is out of the scope right now, the
> + * current design takes them into account by avoiding any guess on the
> + * group/queue state that would be based on information we wouldn't have
> + * if userspace was in charge of the ring-buffer. That's also one of the
> + * reason we don't do 'cooperative' scheduling (encoding FW group slot
> + * reservation as dma_fence that would be returned from the
> + * drm_gpu_schedule

RE: Implement svm without BO concept in xe driver

2023-08-18 Thread Zeng, Oak
Thanks Thomas. I will then look into more details of option 3:

   * create a lean drm layer vram manager, a central control place for vram 
eviction and cgroup accounting. Single LRU for eviction fairness.
   * pretty much move the current ttm_resource eviction/cgroups logic to drm 
layer
   * the eviction/allocation granularity should be flexible so svm can do 2M 
while ttm can do arbitrary size
   * both ttm_resource and svm code should call the new drm_vram_manager for 
eviction/accounting

I will come back with some RFC proof of concept codes later.

Cheers,
Oak

> -Original Message-
> From: Thomas Hellström 
> Sent: August 18, 2023 3:36 AM
> To: Zeng, Oak ; Dave Airlie ; Felix
> Kuehling 
> Cc: Christian König ; Brost, Matthew
> ; maarten.lankho...@linux.intel.com;
> Vishwanathapura, Niranjana ; Welty,
> Brian ; Philip Yang ; intel-
> x...@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Subject: Re: Implement svm without BO concept in xe driver
> 
> 
> On 8/17/23 04:12, Zeng, Oak wrote:
> >> -Original Message-
> >> From: Dave Airlie 
> >> Sent: August 16, 2023 6:52 PM
> >> To: Felix Kuehling 
> >> Cc: Zeng, Oak ; Christian König
> >> ; Thomas Hellström
> >> ; Brost, Matthew
> >> ; maarten.lankho...@linux.intel.com;
> >> Vishwanathapura, Niranjana ; Welty,
> >> Brian ; Philip Yang ; intel-
> >> x...@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> >> Subject: Re: Implement svm without BO concept in xe driver
> >>
> >> On Thu, 17 Aug 2023 at 08:15, Felix Kuehling  
> >> wrote:
> >>> On 2023-08-16 13:30, Zeng, Oak wrote:
>  I spoke with Thomas. We discussed two approaches:
> 
>  1) make ttm_resource a central place for vram management functions such
> as
> >> eviction, cgroup memory accounting. Both the BO-based driver and BO-less
> SVM
> >> codes call into ttm_resource_alloc/free functions for vram allocation/free.
>    *This way BO driver and SVM driver shares the eviction/cgroup 
>  logic, no
> >> need to reimplment LRU eviction list in SVM driver. Cgroup logic should be 
> >> in
> >> ttm_resource layer. +Maarten.
>    *ttm_resource is not a perfect match for SVM to allocate vram. It 
>  is still a
> >> big overhead. The *bo* member of ttm_resource is not needed for SVM - this
> >> might end up with invasive changes to ttm...need to look into more details
> >>> Overhead is a problem. We'd want to be able to allocate, free and evict
> >>> memory at a similar granularity as our preferred migration and page
> >>> fault granularity, which defaults to 2MB in our SVM implementation.
> >>>
> >>>
>  2) svm code allocate memory directly from drm-buddy allocator, and
> expose
> >> memory eviction functions from both ttm and svm so they can evict memory
> >> from each other. For example, expose the ttm_mem_evict_first function
> from
> >> ttm side so hmm/svm code can call it; expose a similar function from svm 
> >> side
> so
> >> ttm can evict hmm memory.
> >>> I like this option. One thing that needs some thought with this is how
> >>> to get some semblance of fairness between the two types of clients.
> >>> Basically how to choose what to evict. And what share of the available
> >>> memory does each side get to use on average. E.g. an idle client may get
> >>> all its memory evicted while a busy client may get a bigger share of the
> >>> available memory.
> >> I'd also like to suggest we try to write any management/generic code
> >> in driver agnostic way as much as possible here. I don't really see
> >> much hw difference should be influencing it.
> >>
> >> I do worry about having effectively 2 LRUs here, you can't really have
> >> two "leasts".
> >>
> >> Like if we hit the shrinker paths who goes first? do we shrink one
> >> object from each side in turn?
> > One way to solve this fairness problem is to create a driver agnostic
> drm_vram_mgr. Maintain a single LRU in drm_vram_mgr. Move the memory
> eviction/cgroups memory accounting logic from ttm_resource manager to
> drm_vram_mgr. Both BO-based driver and SVM driver calls to drm_vram_mgr to
> allocate/free memory.
> >
> > I am not sure whether this meets the 2M allocate/free/evict granularity
> requirement Felix mentioned above. SVM can allocate 2M size blocks. But BO
> driver should be able to allocate any arbitrary sized blocks - So the 
> eviction is also
> arbitrary size.
> 
> This is not far from what a TTM resource manager does with TTM
> resources, only made generic at the drm level, and making the "resource"
> as lean as possible. With 2M granularity this seems plausible.
> 
> >
> >> Also will we have systems where we can expose system SVM but userspace
> >> may choose to not use the fine grained SVM and use one of the older
> >> modes, will that path get emulated on top of SVM or use the BO paths?
> >
> > If by "older modes" you meant the gem_bo_create (such as xe_gem_create or
> amdgpu_gem_create), then today both amd and intel implement those
> interfaces using BO path. 

RE: [PATCH v5 06/11] drm/radeon: Use RMW accessors for changing LNKCTL

2023-08-18 Thread Deucher, Alexander
[Public]

> -Original Message-
> From: Ilpo Järvinen 
> Sent: Monday, July 17, 2023 8:05 AM
> To: linux-...@vger.kernel.org; Bjorn Helgaas ; Lorenzo
> Pieralisi ; Rob Herring ;
> Krzysztof Wilczyński ; Emmanuel Grumbach
> ; Rafael J . Wysocki ;
> Heiner Kallweit ; Lukas Wunner ;
> Andy Shevchenko ; Deucher, Alexander
> ; Koenig, Christian
> ; Pan, Xinhui ; David
> Airlie ; Daniel Vetter ; amd-
> g...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; linux-
> ker...@vger.kernel.org
> Cc: Dean Luick ; Jonas Dreßler
> ; Ilpo Järvinen ;
> sta...@vger.kernel.org
> Subject: [PATCH v5 06/11] drm/radeon: Use RMW accessors for changing
> LNKCTL
>
> Don't assume that only the driver would be accessing LNKCTL. ASPM policy
> changes can trigger write to LNKCTL outside of driver's control.
> And in the case of upstream bridge, the driver does not even own the device
> it's changing the registers for.
>
> Use RMW capability accessors which do proper locking to avoid losing
> concurrent updates to the register value.
>
> Fixes: 8a7cd27679d0 ("drm/radeon/cik: add support for pcie gen1/2/3
> switching")
> Fixes: b9d305dfb66c ("drm/radeon: implement pcie gen2/3 support for SI")
> Suggested-by: Lukas Wunner 
> Signed-off-by: Ilpo Järvinen 
> Cc: sta...@vger.kernel.org

For this and the amdgpu patch:
Acked-by: Alex Deucher 
I'm not sure if this is stable material however.  Is there some issue today?


> ---
>  drivers/gpu/drm/radeon/cik.c | 36 ++-
>  drivers/gpu/drm/radeon/si.c  | 37 ++--
>  2 files changed, 20 insertions(+), 53 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
> index 5819737c21c6..a6f3c811ceb8 100644
> --- a/drivers/gpu/drm/radeon/cik.c
> +++ b/drivers/gpu/drm/radeon/cik.c
> @@ -9534,17 +9534,8 @@ static void cik_pcie_gen3_enable(struct
> radeon_device *rdev)
>   u16 bridge_cfg2, gpu_cfg2;
>   u32 max_lw, current_lw, tmp;
>
> - pcie_capability_read_word(root, PCI_EXP_LNKCTL,
> -   &bridge_cfg);
> - pcie_capability_read_word(rdev->pdev,
> PCI_EXP_LNKCTL,
> -   &gpu_cfg);
> -
> - tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
> - pcie_capability_write_word(root, PCI_EXP_LNKCTL,
> tmp16);
> -
> - tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
> - pcie_capability_write_word(rdev->pdev,
> PCI_EXP_LNKCTL,
> -tmp16);
> + pcie_capability_set_word(root, PCI_EXP_LNKCTL,
> PCI_EXP_LNKCTL_HAWD);
> + pcie_capability_set_word(rdev->pdev,
> PCI_EXP_LNKCTL,
> +PCI_EXP_LNKCTL_HAWD);
>
>   tmp = RREG32_PCIE_PORT(PCIE_LC_STATUS1);
>   max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK)
> >> LC_DETECTED_LINK_WIDTH_SHIFT; @@ -9591,21 +9582,14 @@ static
> void cik_pcie_gen3_enable(struct radeon_device *rdev)
>   msleep(100);
>
>   /* linkctl */
> - pcie_capability_read_word(root,
> PCI_EXP_LNKCTL,
> -   &tmp16);
> - tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
> - tmp16 |= (bridge_cfg &
> PCI_EXP_LNKCTL_HAWD);
> - pcie_capability_write_word(root,
> PCI_EXP_LNKCTL,
> -tmp16);
> -
> - pcie_capability_read_word(rdev->pdev,
> -   PCI_EXP_LNKCTL,
> -   &tmp16);
> - tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
> - tmp16 |= (gpu_cfg &
> PCI_EXP_LNKCTL_HAWD);
> - pcie_capability_write_word(rdev->pdev,
> -PCI_EXP_LNKCTL,
> -tmp16);
> + pcie_capability_clear_and_set_word(root,
> PCI_EXP_LNKCTL,
> +
> PCI_EXP_LNKCTL_HAWD,
> +bridge_cfg &
> +
> PCI_EXP_LNKCTL_HAWD);
> + pcie_capability_clear_and_set_word(rdev-
> >pdev, PCI_EXP_LNKCTL,
> +
> PCI_EXP_LNKCTL_HAWD,
> +gpu_cfg &
> +
> PCI_EXP_LNKCTL_HAWD);
>
>   /* linkctl2 */
>   pcie_capability_read_word(root,
> PCI_EXP_LNKCTL2, diff --git a/drivers/gpu/drm/radeon/si.c
> b/drivers/gpu/drm/radeon/si.c index 8d5e4b25609d..a91012447b56
> 100644
> --- a/drivers/gpu/drm/radeon/si.c
> +++ b/drivers/gpu/drm/radeon/si.c
> @@ -7131,17 +7

Re: [PATCH] drivers: gpu: drm: radeon: possible buffer overflow

2023-08-18 Thread Alex Deucher
Applied.  Thanks!

On Thu, Aug 17, 2023 at 7:34 AM Konstantin Meskhidze
 wrote:
>
> Buffer 'afmt_status' of size 6 could overflow, since index 'afmt_idx' is
> checked after access.
>
> Fixes: 5cc4e5fc293b ("drm/radeon: Cleanup HDMI audio interrupt handling for 
> evergreen")
> Co-developed-by: Ivanov Mikhail 
> Signed-off-by: Konstantin Meskhidze 
> ---
>  drivers/gpu/drm/radeon/evergreen.c | 7 ---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/evergreen.c 
> b/drivers/gpu/drm/radeon/evergreen.c
> index 4f06356d9..f0ae087be 100644
> --- a/drivers/gpu/drm/radeon/evergreen.c
> +++ b/drivers/gpu/drm/radeon/evergreen.c
> @@ -4821,14 +4821,15 @@ int evergreen_irq_process(struct radeon_device *rdev)
> break;
> case 44: /* hdmi */
> afmt_idx = src_data;
> -   if (!(afmt_status[afmt_idx] & AFMT_AZ_FORMAT_WTRIG))
> -   DRM_DEBUG("IH: IH event w/o asserted irq 
> bit?\n");
> -
> if (afmt_idx > 5) {
> DRM_ERROR("Unhandled interrupt: %d %d\n",
>   src_id, src_data);
> break;
> }
> +
> +   if (!(afmt_status[afmt_idx] & AFMT_AZ_FORMAT_WTRIG))
> +   DRM_DEBUG("IH: IH event w/o asserted irq 
> bit?\n");
> +
> afmt_status[afmt_idx] &= ~AFMT_AZ_FORMAT_WTRIG;
> queue_hdmi = true;
> DRM_DEBUG("IH: HDMI%d\n", afmt_idx + 1);
> --
> 2.34.1
>


Re: [PATCH] drm/amd/pm: Fix unsigned expression compared with zero

2023-08-18 Thread Alex Deucher
On Thu, Aug 17, 2023 at 2:07 AM Jiapeng Chong
 wrote:
>
> The val is defined as unsigned int type, if(val<0) is invalid, modify
> to int type.
>
> drivers/gpu/drm/amd/amdgpu/../pm/amdgpu_pm.c:2813 
> amdgpu_hwmon_show_power_input() warn: unsigned 'val' is never less than zero.
> drivers/gpu/drm/amd/amdgpu/../pm/amdgpu_pm.c:2800 
> amdgpu_hwmon_show_power_avg() warn: unsigned 'val' is never less than zero.
>
> Reported-by: Abaci Robot 
> Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=6181
> Signed-off-by: Jiapeng Chong 

Thanks.  The function signatures for amdgpu_hwmon_get_power() and
amdgpu_hwmon_get_sensor_generic() should be fixed up as well.  I'll
send out a fix.

Alex

> ---
>  drivers/gpu/drm/amd/pm/amdgpu_pm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c 
> b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> index 5b1d73b00ef7..fe490e5860d2 100644
> --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> @@ -2794,7 +2794,7 @@ static ssize_t amdgpu_hwmon_show_power_avg(struct 
> device *dev,
>struct device_attribute *attr,
>char *buf)
>  {
> -   unsigned int val;
> +   int val;
>
> val = amdgpu_hwmon_get_power(dev, AMDGPU_PP_SENSOR_GPU_AVG_POWER);
> if (val < 0)
> @@ -2807,7 +2807,7 @@ static ssize_t amdgpu_hwmon_show_power_input(struct 
> device *dev,
>  struct device_attribute *attr,
>  char *buf)
>  {
> -   unsigned int val;
> +   int val;
>
> val = amdgpu_hwmon_get_power(dev, AMDGPU_PP_SENSOR_GPU_INPUT_POWER);
> if (val < 0)
> --
> 2.20.1.7.g153144c
>


Re: Implement svm without BO concept in xe driver

2023-08-18 Thread Felix Kuehling



On 2023-08-18 12:10, Zeng, Oak wrote:

Thanks Thomas. I will then look into more details of option 3:

* create a lean drm layer vram manager, a central control place for vram 
eviction and cgroup accounting. Single LRU for eviction fairness.
* pretty much move the current ttm_resource eviction/cgroups logic to drm 
layer
* the eviction/allocation granularity should be flexible so svm can do 2M 
while ttm can do arbitrary size


SVM will need smaller sizes too, for VMAs that are smaller or not 
aligned to 2MB size.


Regards,
  Felix



* both ttm_resource and svm code should call the new drm_vram_manager for 
eviction/accounting

I will come back with some RFC proof of concept codes later.

Cheers,
Oak


-Original Message-
From: Thomas Hellström 
Sent: August 18, 2023 3:36 AM
To: Zeng, Oak ; Dave Airlie ; Felix
Kuehling 
Cc: Christian König ; Brost, Matthew
; maarten.lankho...@linux.intel.com;
Vishwanathapura, Niranjana ; Welty,
Brian ; Philip Yang ; intel-
x...@lists.freedesktop.org; dri-devel@lists.freedesktop.org
Subject: Re: Implement svm without BO concept in xe driver


On 8/17/23 04:12, Zeng, Oak wrote:

-Original Message-
From: Dave Airlie 
Sent: August 16, 2023 6:52 PM
To: Felix Kuehling 
Cc: Zeng, Oak ; Christian König
; Thomas Hellström
; Brost, Matthew
; maarten.lankho...@linux.intel.com;
Vishwanathapura, Niranjana ; Welty,
Brian ; Philip Yang ; intel-
x...@lists.freedesktop.org; dri-devel@lists.freedesktop.org
Subject: Re: Implement svm without BO concept in xe driver

On Thu, 17 Aug 2023 at 08:15, Felix Kuehling  wrote:

On 2023-08-16 13:30, Zeng, Oak wrote:

I spoke with Thomas. We discussed two approaches:

1) make ttm_resource a central place for vram management functions such

as

eviction, cgroup memory accounting. Both the BO-based driver and BO-less

SVM

codes call into ttm_resource_alloc/free functions for vram allocation/free.

   *This way BO driver and SVM driver shares the eviction/cgroup logic, no

need to reimplment LRU eviction list in SVM driver. Cgroup logic should be in
ttm_resource layer. +Maarten.

   *ttm_resource is not a perfect match for SVM to allocate vram. It is 
still a

big overhead. The *bo* member of ttm_resource is not needed for SVM - this
might end up with invasive changes to ttm...need to look into more details

Overhead is a problem. We'd want to be able to allocate, free and evict
memory at a similar granularity as our preferred migration and page
fault granularity, which defaults to 2MB in our SVM implementation.



2) svm code allocate memory directly from drm-buddy allocator, and

expose

memory eviction functions from both ttm and svm so they can evict memory
from each other. For example, expose the ttm_mem_evict_first function

from

ttm side so hmm/svm code can call it; expose a similar function from svm side

so

ttm can evict hmm memory.

I like this option. One thing that needs some thought with this is how
to get some semblance of fairness between the two types of clients.
Basically how to choose what to evict. And what share of the available
memory does each side get to use on average. E.g. an idle client may get
all its memory evicted while a busy client may get a bigger share of the
available memory.

I'd also like to suggest we try to write any management/generic code
in driver agnostic way as much as possible here. I don't really see
much hw difference should be influencing it.

I do worry about having effectively 2 LRUs here, you can't really have
two "leasts".

Like if we hit the shrinker paths who goes first? do we shrink one
object from each side in turn?

One way to solve this fairness problem is to create a driver agnostic

drm_vram_mgr. Maintain a single LRU in drm_vram_mgr. Move the memory
eviction/cgroups memory accounting logic from ttm_resource manager to
drm_vram_mgr. Both BO-based driver and SVM driver calls to drm_vram_mgr to
allocate/free memory.

I am not sure whether this meets the 2M allocate/free/evict granularity

requirement Felix mentioned above. SVM can allocate 2M size blocks. But BO
driver should be able to allocate any arbitrary sized blocks - So the eviction 
is also
arbitrary size.

This is not far from what a TTM resource manager does with TTM
resources, only made generic at the drm level, and making the "resource"
as lean as possible. With 2M granularity this seems plausible.


Also will we have systems where we can expose system SVM but userspace
may choose to not use the fine grained SVM and use one of the older
modes, will that path get emulated on top of SVM or use the BO paths?

If by "older modes" you meant the gem_bo_create (such as xe_gem_create or

amdgpu_gem_create), then today both amd and intel implement those
interfaces using BO path. We don't have a plan to emulate that old mode on tope
of SVM, afaict.

I think we might end up emulating "older modes" on top of SVM at some
point, not to far out, although what immediately comes to mind would be
eviction ba

[PATCH v2 0/2] Match data improvements for it66121 driver

2023-08-18 Thread Biju Das
This patch series aims to add match data improvements for it66121 driver.

v1->v2:
 * Split the patch into two.
 * patch#1 extend match support for OF tables compared to legacy ID
   lookup and fixes tag.
 * patch#2 simplifies the probe() by using i2c_get_match_data. 
 * Dropped sentence for dropping local variable as it is integral part of
   the patch.

Biju Das (2):
  drm: bridge: it66121: Extend match support for OF tables
  drm: bridge: it66121: Simplify probe()

 drivers/gpu/drm/bridge/ite-it66121.c | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

-- 
2.25.1



[PATCH v2 1/2] drm: bridge: it66121: Extend match support for OF tables

2023-08-18 Thread Biju Das
The driver has OF match table, still it uses ID lookup table for
retrieving match data. Currently the driver is working on the
assumption that a I2C device registered via OF will always match a
legacy I2C device ID. The correct approach is to have an OF device ID
table using of_device_match_data() if the devices are registered via OF.

Fixes: 9a9f4a01bdae ("drm: bridge: it66121: Move VID/PID to new 
it66121_chip_info structure")
Signed-off-by: Biju Das 
---
v2:
 * New patch.
---
 drivers/gpu/drm/bridge/ite-it66121.c | 19 +++
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
b/drivers/gpu/drm/bridge/ite-it66121.c
index 466641c77fe9..ba95ad46e259 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -1523,7 +1523,10 @@ static int it66121_probe(struct i2c_client *client)
 
ctx->dev = dev;
ctx->client = client;
-   ctx->info = (const struct it66121_chip_info *) id->driver_data;
+   if (dev_fwnode(&client->dev))
+   ctx->info = of_device_get_match_data(&client->dev);
+   else
+   ctx->info = (const struct it66121_chip_info *) id->driver_data;
 
of_property_read_u32(ep, "bus-width", &ctx->bus_width);
of_node_put(ep);
@@ -1609,13 +1612,6 @@ static void it66121_remove(struct i2c_client *client)
mutex_destroy(&ctx->lock);
 }
 
-static const struct of_device_id it66121_dt_match[] = {
-   { .compatible = "ite,it66121" },
-   { .compatible = "ite,it6610" },
-   { }
-};
-MODULE_DEVICE_TABLE(of, it66121_dt_match);
-
 static const struct it66121_chip_info it66121_chip_info = {
.id = ID_IT66121,
.vid = 0x4954,
@@ -1628,6 +1624,13 @@ static const struct it66121_chip_info it6610_chip_info = 
{
.pid = 0x0611,
 };
 
+static const struct of_device_id it66121_dt_match[] = {
+   { .compatible = "ite,it66121", &it66121_chip_info },
+   { .compatible = "ite,it6610", &it6610_chip_info },
+   { }
+};
+MODULE_DEVICE_TABLE(of, it66121_dt_match);
+
 static const struct i2c_device_id it66121_id[] = {
{ "it66121", (kernel_ulong_t) &it66121_chip_info },
{ "it6610", (kernel_ulong_t) &it6610_chip_info },
-- 
2.25.1



[PATCH v2 2/2] drm: bridge: it66121: Simplify probe()

2023-08-18 Thread Biju Das
Simplify probe() by replacing of_device_get_match_data() and ID lookup
for retrieving match data by i2c_get_match_data().

Signed-off-by: Biju Das 
---
v1->v2:
 * Dropped sentence for dropping local variable as it is integral part of
   the patch.
---
 drivers/gpu/drm/bridge/ite-it66121.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
b/drivers/gpu/drm/bridge/ite-it66121.c
index ba95ad46e259..a80246ef4ffe 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -1501,7 +1501,6 @@ static const char * const it66121_supplies[] = {
 
 static int it66121_probe(struct i2c_client *client)
 {
-   const struct i2c_device_id *id = i2c_client_get_device_id(client);
u32 revision_id, vendor_ids[2] = { 0 }, device_ids[2] = { 0 };
struct device_node *ep;
int ret;
@@ -1523,10 +1522,7 @@ static int it66121_probe(struct i2c_client *client)
 
ctx->dev = dev;
ctx->client = client;
-   if (dev_fwnode(&client->dev))
-   ctx->info = of_device_get_match_data(&client->dev);
-   else
-   ctx->info = (const struct it66121_chip_info *) id->driver_data;
+   ctx->info = i2c_get_match_data(client);
 
of_property_read_u32(ep, "bus-width", &ctx->bus_width);
of_node_put(ep);
-- 
2.25.1



[PATCH 0/3] Define a final failure state when link training fails

2023-08-18 Thread Gil Dekel
Currently, when link training fails after all fallback values have been
exhausted, the i915 driver seizes to send uevents to userspace. This leave
userspace thinking that the last passing atomic commit was successful, and that
all connectors (displays) are connected and operational, when in fact, the last
link failed to train and the displays remain dark. This manifests as "zombie"
displays in userspace, in which users observe the displays appear in their
display settings page, but they are dark and unresponsive.

Since, at the time of writing, MST link training fallback is not implemented,
failing MST link training is a significantly more common case then a complete
SST link training failure. And with users using MST hubs than ever to connect
multiple displays via their USB-C ports we observe this case often.

This patchset series suggest a solution, in which a final failure state is
defined. In this final state, the connector's bit rate capabilities, namely
max_link_rate and max_link_lane_count, are set to 0. This effectively set the
connector's bandwidth to 0Gbps, thus causing all its modes to be pruned in the
following connector probing.

Next, with this state defined, we emit a link-status=Bad uevent. The next time
userspace probes the connector, it should recognize that the connector has no
modes and ignore it since it is in a bad state.

I am aware that always sending a uevent and never stopping may result in some
userspaces having their expectations broken and enter an infinite loop of
modesets and link-training attempts. However, per DRM link-status spec:
```
 * link-status:
 *  Connector link-status property to indicate the status of link. The
 *  default value of link-status is "GOOD". If something fails during or
 *  after modeset, the kernel driver may set this to "BAD" and issue a
 *  hotplug uevent. Drivers should update this value using
 *  drm_connector_set_link_status_property().
 *
 *  When user-space receives the hotplug uevent and detects a "BAD"
 *  link-status, the sink doesn't receive pixels anymore (e.g. the screen
 *  becomes completely black). The list of available modes may have
 *  changed. User-space is expected to pick a new mode if the current one
 *  has disappeared and perform a new modeset with link-status set to
 *  "GOOD" to re-enable the connector.
```
(form drivers/gpu/drm/drm_connector.c - DOC: standard connector properties)

it seems reasonable to assume that the suggested state is an extension of the
spec's guidelines, in which the next new mode userspace picks for a connector
with no modes is - none, thus breaking the cycle of failed link-training
attempts.

I suspect that, maybe, zeroing out the bit rate capabilities is not the right
way to go, and perhaps marking the connector as disconnected instead may be a
better solution. However, if marking a connector disconnected is the way to go,
We will have to iterate over all MST ports in the MST case and mark the spawned
connectors as disconnected as well.

As a final note I should add that this approach was tested with ChromeOS as
userspace, and we observed that the zombie displays stop showing up once the
connectors are pruned of all their modes and are ignored by userspace.

For your consideration and guidance.
Thanks,

Gil Dekel (3):
  drm/i915/dp_link_training: Add a final failing state to link training
fallback
  drm/i915/dp_link_training: Add a final failing state to link training
fallback for MST
  drm/i915/dp_link_training: Emit a link-status=Bad uevent with trigger
property

Cc: Jani Nikula 
Cc: Manasi Navare 
Cc: Sean Paul 
Signed-off-by: Gil Dekel 
---
 drivers/gpu/drm/i915/display/intel_dp.c   | 50 +--
 drivers/gpu/drm/i915/display/intel_dp.h   |  4 +-
 .../drm/i915/display/intel_dp_link_training.c |  8 +--
 3 files changed, 41 insertions(+), 21 deletions(-)

--
Gil Dekel, Software Engineer, Google / ChromeOS Display and Graphics


[PATCH 1/3] drm/i915/dp_link_training: Add a final failing state to link training fallback

2023-08-18 Thread Gil Dekel
Instead of silently giving up when all link-training fallback values are
exhausted, this patch modifies the fallback's failure branch to reduces
both max_link_lane_count and max_link_rate to zero (0) and continues to
emit uevents until userspace stops attempting to modeset.

By doing so, we ensure the failing connector, which is in
link-status=Bad, has all its modes pruned (due to effectively having a
bandwidth of 0Gbps).

It is then the userspace's responsibility to ignore connectors with no
modes, even if they are marked as connected.

Cc: Jani Nikula 
Cc: Manasi Navare 
Cc: Sean Paul 
Signed-off-by: Gil Dekel 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 964bf0551bdc..1e4dae8aad90 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -276,8 +276,12 @@ static int intel_dp_common_len_rate_limit(const struct 
intel_dp *intel_dp,

 static int intel_dp_common_rate(struct intel_dp *intel_dp, int index)
 {
+   /* This occurs when max link rate drops to 0 via link training 
fallback*/
+   if (index < 0)
+   return 0;
+
if (drm_WARN_ON(&dp_to_i915(intel_dp)->drm,
-   index < 0 || index >= intel_dp->num_common_rates))
+   index >= intel_dp->num_common_rates))
return 162000;

return intel_dp->common_rates[index];
@@ -318,6 +322,9 @@ static int intel_dp_max_common_lane_count(struct intel_dp 
*intel_dp)
 int intel_dp_max_lane_count(struct intel_dp *intel_dp)
 {
switch (intel_dp->max_link_lane_count) {
+   /* This occurs when max link lane count drops to 0 via link training 
fallback*/
+   case 0:
+   return 0;
case 1:
case 2:
case 4:
@@ -672,7 +679,14 @@ int intel_dp_get_link_train_fallback_values(struct 
intel_dp *intel_dp,
intel_dp->max_link_lane_count = lane_count >> 1;
} else {
drm_err(&i915->drm, "Link Training Unsuccessful\n");
-   return -1;
+   /*
+* Ensure all of the connector's modes are pruned in the next
+* probe by effectively reducing its bandwidth to 0 so userspace
+* can ignore it within the next modeset attempt.
+*/
+   intel_dp->max_link_rate = 0;
+   intel_dp->max_link_lane_count = 0;
+   return 0;
}

return 0;
--
Gil Dekel, Software Engineer, Google / ChromeOS Display and Graphics


[PATCH 2/3] drm/i915/dp_link_training: Add a final failing state to link training fallback for MST

2023-08-18 Thread Gil Dekel
Currently, MST link training has no fallback whatsoever. This means that
if an MST base connector fails to link-train once, the training
completely fails, which makes this case significantly more common than a
complete SST link training failure.

Until MST fallback is fully implemented, this patch adds a final failure
case to MST link training (similar to SST). In particular, this patch
zeros out both max_link_rate and max_link_lane_count. In addition, it
stops reseting MST params so the zeroing of the bit rate fields stick.
This ensures that the MST base connector's modes will be completely
pruned, since it is effectively left with 0Gbps bandwidth.

Once again, it is the userspace's responsibility to ignore connectors
with no modes, even if they are marked as connected.

Cc: Jani Nikula 
Cc: Manasi Navare 
Cc: Sean Paul 
Signed-off-by: Gil Dekel 
---
 drivers/gpu/drm/i915/display/intel_dp.c   | 29 ++-
 drivers/gpu/drm/i915/display/intel_dp.h   |  4 +--
 .../drm/i915/display/intel_dp_link_training.c |  8 ++---
 3 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 1e4dae8aad90..aee3845edd2d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -630,26 +630,31 @@ static bool 
intel_dp_can_link_train_fallback_for_edp(struct intel_dp *intel_dp,
return true;
 }

-int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
-   int link_rate, u8 lane_count)
+void intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
+int link_rate, u8 lane_count)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int index;

/*
 * TODO: Enable fallback on MST links once MST link compute can handle
-* the fallback params.
+* the fallback params. For now, similar to the SST case, ensure all of
+* the base connector's modes are pruned in the next connector probe by
+* effectively reducing its bandwidth to 0 so userspace can ignore it
+* within the next modeset attempt.
 */
if (intel_dp->is_mst) {
drm_err(&i915->drm, "Link Training Unsuccessful\n");
-   return -1;
+   intel_dp->max_link_rate = 0;
+   intel_dp->max_link_lane_count = 0;
+   return;
}

if (intel_dp_is_edp(intel_dp) && !intel_dp->use_max_params) {
drm_dbg_kms(&i915->drm,
"Retrying Link training for eDP with max 
parameters\n");
intel_dp->use_max_params = true;
-   return 0;
+   return;
}

index = intel_dp_rate_index(intel_dp->common_rates,
@@ -662,7 +667,7 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp 
*intel_dp,
  lane_count)) {
drm_dbg_kms(&i915->drm,
"Retrying Link training for eDP with same 
parameters\n");
-   return 0;
+   return;
}
intel_dp->max_link_rate = intel_dp_common_rate(intel_dp, index 
- 1);
intel_dp->max_link_lane_count = lane_count;
@@ -673,7 +678,7 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp 
*intel_dp,
  lane_count >> 1)) 
{
drm_dbg_kms(&i915->drm,
"Retrying Link training for eDP with same 
parameters\n");
-   return 0;
+   return;
}
intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
intel_dp->max_link_lane_count = lane_count >> 1;
@@ -686,10 +691,7 @@ int intel_dp_get_link_train_fallback_values(struct 
intel_dp *intel_dp,
 */
intel_dp->max_link_rate = 0;
intel_dp->max_link_lane_count = 0;
-   return 0;
}
-
-   return 0;
 }

 u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
@@ -4920,10 +4922,11 @@ intel_dp_detect(struct drm_connector *connector,
intel_dp_configure_mst(intel_dp);

/*
-* TODO: Reset link params when switching to MST mode, until MST
-* supports link training fallback params.
+* Note: Even though MST link training fallback is not yet implemented,
+* do not reset. This is because the base connector needs to have all
+* its modes pruned when link training for the MST port fails.
 */
-   if (intel_dp->reset_link_params || intel_dp->is_mst) {
+   if (intel_dp->reset_link_params) {
intel_dp_reset_max_link_params(intel_dp);
intel_dp->reset_link_params = false;
   

[PATCH 3/3] drm/i915/dp_link_training: Emit a link-status=Bad uevent with trigger property

2023-08-18 Thread Gil Dekel
When a link-training attempt fails, emit a uevent to user space that
includes the trigger property, which in this case will be
link-statue=Bad.

This will allow userspace to parse the uevent property and better
understand the reason for the previous display configuration failure.

Cc: Jani Nikula 
Cc: Manasi Navare 
Cc: Sean Paul 
Signed-off-by: Gil Dekel 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index aee3845edd2d..772979f163df 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -42,6 +42,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "g4x_dp.h"
 #include "i915_drv.h"
@@ -5604,10 +5605,12 @@ static void intel_dp_modeset_retry_work_fn(struct 
work_struct *work)
 {
struct intel_connector *intel_connector;
struct drm_connector *connector;
+   struct drm_property *link_status_property;

intel_connector = container_of(work, typeof(*intel_connector),
   modeset_retry_work);
connector = &intel_connector->base;
+   link_status_property = connector->dev->mode_config.link_status_property;
drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s]\n", connector->base.id,
connector->name);

@@ -5620,7 +5623,7 @@ static void intel_dp_modeset_retry_work_fn(struct 
work_struct *work)
   DRM_MODE_LINK_STATUS_BAD);
mutex_unlock(&connector->dev->mode_config.mutex);
/* Send Hotplug uevent so userspace can reprobe */
-   drm_kms_helper_connector_hotplug_event(connector);
+   drm_sysfs_connector_property_event(connector, link_status_property);
 }

 bool
--
Gil Dekel, Software Engineer, Google / ChromeOS Display and Graphics


  1   2   >