Re: [PATCH v2 6/6] drm/msm/dsi: fix DSC for the bonded DSI case

2023-11-14 Thread Dmitry Baryshkov
On Wed, 15 Nov 2023 at 01:00, Jonathan Marek  wrote:
>
> For the bonded DSI case, DSC pic_width and timing calculations should use
> the width of a single panel instead of the total combined width.
>
> Signed-off-by: Jonathan Marek 

Fixes tag?

I'll wait for the Tested-by by Marijn, otherwise LGTM.

> ---
>  drivers/gpu/drm/msm/dsi/dsi.h |  3 ++-
>  drivers/gpu/drm/msm/dsi/dsi_host.c| 20 +++-
>  drivers/gpu/drm/msm/dsi/dsi_manager.c |  2 +-
>  3 files changed, 14 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
> index 28379b1af63f..3a641e69447c 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi.h
> +++ b/drivers/gpu/drm/msm/dsi/dsi.h
> @@ -93,7 +93,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host);
>  int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host,
>   const struct drm_display_mode *mode);
>  enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
> -   const struct drm_display_mode 
> *mode);
> +   const struct drm_display_mode 
> *mode,
> +   bool is_bonded_dsi);
>  unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host);
>  int msm_dsi_host_register(struct mipi_dsi_host *host);
>  void msm_dsi_host_unregister(struct mipi_dsi_host *host);
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
> b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index 892a463a7e03..cf06736e5a60 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -940,8 +940,7 @@ static void dsi_timing_setup(struct msm_dsi_host 
> *msm_host, bool is_bonded_dsi)
>mode->hdisplay, mode->vdisplay);
> return;
> }
> -

Nit: keep it please.

> -   dsc->pic_width = mode->hdisplay;
> +   dsc->pic_width = hdisplay;
> dsc->pic_height = mode->vdisplay;
> DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height);
>
> @@ -952,6 +951,11 @@ static void dsi_timing_setup(struct msm_dsi_host 
> *msm_host, bool is_bonded_dsi)
> if (ret)
> return;
>
> +   if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO)
> +   dsi_update_dsc_timing(msm_host, false, hdisplay);
> +   else
> +   dsi_update_dsc_timing(msm_host, true, hdisplay);
> +
> /* Divide the display by 3 but keep back/font porch and
>  * pulse width same
>  */
> @@ -968,9 +972,6 @@ static void dsi_timing_setup(struct msm_dsi_host 
> *msm_host, bool is_bonded_dsi)
> }
>
> if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) {
> -   if (msm_host->dsc)
> -   dsi_update_dsc_timing(msm_host, false, 
> mode->hdisplay);
> -
> dsi_write(msm_host, REG_DSI_ACTIVE_H,
> DSI_ACTIVE_H_START(ha_start) |
> DSI_ACTIVE_H_END(ha_end));
> @@ -989,9 +990,6 @@ static void dsi_timing_setup(struct msm_dsi_host 
> *msm_host, bool is_bonded_dsi)
> DSI_ACTIVE_VSYNC_VPOS_START(vs_start) |
> DSI_ACTIVE_VSYNC_VPOS_END(vs_end));
> } else {/* command mode */
> -   if (msm_host->dsc)
> -   dsi_update_dsc_timing(msm_host, true, mode->hdisplay);
> -
> /* image data and 1 byte write_memory_start cmd */
> if (!msm_host->dsc)
> wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1;
> @@ -2479,7 +2477,8 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host 
> *host,
>  }
>
>  enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
> -   const struct drm_display_mode 
> *mode)
> +   const struct drm_display_mode 
> *mode,
> +   bool is_bonded_dsi)
>  {
> struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
> struct drm_dsc_config *dsc = msm_host->dsc;
> @@ -2489,6 +2488,9 @@ enum drm_mode_status msm_dsi_host_check_dsc(struct 
> mipi_dsi_host *host,
> if (!msm_host->dsc)
> return MODE_OK;
>
> +   if (is_bonded_dsi)
> +   pic_width = mode->hdisplay / 2;
> +
> if (pic_width % dsc->slice_width) {
> pr_err("DSI: pic_width %d has to be multiple of slice %d\n",
>pic_width, dsc->slice_width);
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c 
> b/drivers/gpu/drm/msm/dsi/dsi_manager.c
> index 896f369fdd53..2ca1a7ca3659 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
> @@ -455,7 +455,7 @@ static enum drm_mode_status 
> 

Re: [PATCH v2 5/6] drm/msm/dsi: support DSC configurations with slice_per_pkt > 1

2023-11-14 Thread Dmitry Baryshkov
On Wed, 15 Nov 2023 at 01:00, Jonathan Marek  wrote:
>
> Add a dsc_slice_per_pkt field to mipi_dsi_device struct and the necessary
> changes to msm driver to support this field.
>
> Note that the removed "pkt_per_line = slice_per_intf * slice_per_pkt"
> comment is incorrect.
>
> Signed-off-by: Jonathan Marek 
> ---
>  drivers/gpu/drm/msm/dsi/dsi_host.c | 25 ++---
>  include/drm/drm_mipi_dsi.h |  1 +
>  2 files changed, 11 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
> b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index 842765063b1b..892a463a7e03 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -161,6 +161,7 @@ struct msm_dsi_host {
>
> struct drm_display_mode *mode;
> struct drm_dsc_config *dsc;
> +   unsigned int dsc_slice_per_pkt;
>
> /* connected device info */
> unsigned int channel;
> @@ -857,17 +858,10 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
> *msm_host, bool is_cmd_mod
> slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay);
>
> total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
> -   bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
> +   bytes_per_pkt = dsc->slice_chunk_size * msm_host->dsc_slice_per_pkt;
>
> eol_byte_num = total_bytes_per_intf % 3;
> -
> -   /*
> -* Typically, pkt_per_line = slice_per_intf * slice_per_pkt.
> -*
> -* Since the current driver only supports slice_per_pkt = 1,
> -* pkt_per_line will be equal to slice per intf for now.
> -*/
> -   pkt_per_line = slice_per_intf;
> +   pkt_per_line = slice_per_intf / msm_host->dsc_slice_per_pkt;
>
> if (is_cmd_mode) /* packet data type */
> reg = 
> DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE);
> @@ -1004,12 +998,8 @@ static void dsi_timing_setup(struct msm_dsi_host 
> *msm_host, bool is_bonded_dsi)
> else
> /*
>  * When DSC is enabled, WC = slice_chunk_size * 
> slice_per_pkt + 1.
> -* Currently, the driver only supports default value 
> of slice_per_pkt = 1
> -*
> -* TODO: Expand mipi_dsi_device struct to hold 
> slice_per_pkt info
> -*   and adjust DSC math to account for 
> slice_per_pkt.
>  */
> -   wc = msm_host->dsc->slice_chunk_size + 1;
> +   wc = msm_host->dsc->slice_chunk_size * 
> msm_host->dsc_slice_per_pkt + 1;
>
> dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL,
> DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) |
> @@ -1636,8 +1626,13 @@ static int dsi_host_attach(struct mipi_dsi_host *host,
> msm_host->lanes = dsi->lanes;
> msm_host->format = dsi->format;
> msm_host->mode_flags = dsi->mode_flags;
> -   if (dsi->dsc)
> +   if (dsi->dsc) {
> msm_host->dsc = dsi->dsc;
> +   msm_host->dsc_slice_per_pkt = dsi->dsc_slice_per_pkt;
> +   /* for backwards compatibility, assume 1 if not set */
> +   if (!msm_host->dsc_slice_per_pkt)
> +   msm_host->dsc_slice_per_pkt = 1;
> +   }
>
> /* Some gpios defined in panel DT need to be controlled by host */
> ret = dsi_host_init_panel_gpios(msm_host, >dev);
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index c9df0407980c..3e32fa52d94b 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -193,6 +193,7 @@ struct mipi_dsi_device {
> unsigned long hs_rate;
> unsigned long lp_rate;
> struct drm_dsc_config *dsc;
> +   unsigned int dsc_slice_per_pkt;

Missing documentation. Also maybe this chunk should go into a separate
patch so that it can gain more attention from DRM maintainers?

>  };
>
>  #define MIPI_DSI_MODULE_PREFIX "mipi-dsi:"
> --
> 2.26.1
>


-- 
With best wishes
Dmitry


Re: [PATCH v2 4/6] drm/msm/dsi: add a comment to explain pkt_per_line encoding

2023-11-14 Thread Dmitry Baryshkov
On Wed, 15 Nov 2023 at 01:00, Jonathan Marek  wrote:
>
> Make it clear why the pkt_per_line value is being "divided by 2".
>
> Signed-off-by: Jonathan Marek 
> ---
>  drivers/gpu/drm/msm/dsi/dsi_host.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
> b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index 66f198e21a7e..842765063b1b 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -877,6 +877,8 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
> *msm_host, bool is_cmd_mod
> /* DSI_VIDEO_COMPRESSION_MODE & DSI_COMMAND_COMPRESSION_MODE
>  * registers have similar offsets, so for below common code use
>  * DSI_VIDEO_COMPRESSION_MODE_ for setting bits
> +*
> +* pkt_per_line is log2 encoded, >>1 works for supported values 
> (1,2,4)
>  */
> reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_PKT_PER_LINE(pkt_per_line >> 
> 1);

Should we switch to ffs() or fls() instead?

> reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_EOL_BYTE_NUM(eol_byte_num);
> --
> 2.26.1
>


-- 
With best wishes
Dmitry


Re: [PATCH v2 3/6] drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC (fix video mode DSC)

2023-11-14 Thread Dmitry Baryshkov
On Wed, 15 Nov 2023 at 01:00, Jonathan Marek  wrote:
>
> Video mode DSC won't work if this field is not set correctly. Set it to fix
> video mode DSC (for slice_per_pkt==1 cases at least).
>
> Fixes: 08802f515c3 ("drm/msm/dsi: Add support for DSC configuration")
> Signed-off-by: Jonathan Marek 
> ---
>  drivers/gpu/drm/msm/dsi/dsi_host.c | 3 +++
>  1 file changed, 3 insertions(+)

Reviewed-by: Dmitry Baryshkov 

--
With best wishes
Dmitry


Re: [PATCH v2 2/6] drm/msm/dsi: set video mode widebus enable bit when widebus is enabled

2023-11-14 Thread Dmitry Baryshkov
On Wed, 15 Nov 2023 at 01:00, Jonathan Marek  wrote:
>
> The value returned by msm_dsi_wide_bus_enabled() doesn't match what the
> driver is doing in video mode. Fix that by actually enabling widebus for
> video mode.
>
> Fixes: efcbd6f9cdeb ("drm/msm/dsi: Enable widebus for DSI")
> Signed-off-by: Jonathan Marek 
> ---
>  drivers/gpu/drm/msm/dsi/dsi.xml.h  | 1 +
>  drivers/gpu/drm/msm/dsi/dsi_host.c | 2 ++
>  2 files changed, 3 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h 
> b/drivers/gpu/drm/msm/dsi/dsi.xml.h
> index 2a7d980e12c3..f0b3cdc020a1 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi.xml.h
> +++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h
> @@ -231,6 +231,7 @@ static inline uint32_t DSI_VID_CFG0_TRAFFIC_MODE(enum 
> dsi_traffic_mode val)
>  #define DSI_VID_CFG0_HSA_POWER_STOP0x0001
>  #define DSI_VID_CFG0_HBP_POWER_STOP0x0010
>  #define DSI_VID_CFG0_HFP_POWER_STOP0x0100
> +#define DSI_VID_CFG0_DATABUS_WIDEN 0x0200

BTW, could you please push this register to mesa?

>  #define DSI_VID_CFG0_PULSE_MODE_HSA_HE 0x1000
>
>  #define REG_DSI_VID_CFG1   0x001c

-- 
With best wishes
Dmitry


Re: [PATCH v2 2/6] drm/msm/dsi: set video mode widebus enable bit when widebus is enabled

2023-11-14 Thread Dmitry Baryshkov
On Wed, 15 Nov 2023 at 01:00, Jonathan Marek  wrote:
>
> The value returned by msm_dsi_wide_bus_enabled() doesn't match what the
> driver is doing in video mode. Fix that by actually enabling widebus for
> video mode.
>
> Fixes: efcbd6f9cdeb ("drm/msm/dsi: Enable widebus for DSI")
> Signed-off-by: Jonathan Marek 
> ---
>  drivers/gpu/drm/msm/dsi/dsi.xml.h  | 1 +
>  drivers/gpu/drm/msm/dsi/dsi_host.c | 2 ++
>  2 files changed, 3 insertions(+)

Reviewed-by: Dmitry Baryshkov 

-- 
With best wishes
Dmitry


Re: [Spice-devel] [PATCH AUTOSEL 6.5 2/6] drm/qxl: prevent memory leak

2023-11-14 Thread Frediano Ziglio
Il giorno mer 15 nov 2023 alle ore 06:57 Sasha Levin
 ha scritto:
>
> From: Zongmin Zhou 
>
> [ Upstream commit 0e8b9f258baed25f1c5672613699247c76b007b5 ]
>
> The allocated memory for qdev->dumb_heads should be released
> in qxl_destroy_monitors_object before qxl suspend.
> otherwise,qxl_create_monitors_object will be called to

Minor, typo: otherwise -> Otherwise.

> reallocate memory for qdev->dumb_heads after qxl resume,
> it will cause memory leak.
>
> Signed-off-by: Zongmin Zhou 
> Link: 
> https://lore.kernel.org/r/20230801025309.4049813-1-zhouzong...@kylinos.cn
> Reviewed-by: Dave Airlie 
> Signed-off-by: Maxime Ripard 
> Signed-off-by: Sasha Levin 
> ---
>  drivers/gpu/drm/qxl/qxl_display.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
> b/drivers/gpu/drm/qxl/qxl_display.c
> index 6492a70e3c396..404b0483bb7cb 100644
> --- a/drivers/gpu/drm/qxl/qxl_display.c
> +++ b/drivers/gpu/drm/qxl/qxl_display.c
> @@ -1229,6 +1229,9 @@ int qxl_destroy_monitors_object(struct qxl_device *qdev)
> if (!qdev->monitors_config_bo)
> return 0;
>
> +   kfree(qdev->dumb_heads);
> +   qdev->dumb_heads = NULL;
> +
> qdev->monitors_config = NULL;
> qdev->ram_header->monitors_config = 0;
>

Frediano



Re: [REGRESSION]: nouveau: Asynchronous wait on fence

2023-11-14 Thread Owen T. Heisler

On 10/31/23 04:18, Linux regression tracking (Thorsten Leemhuis) wrote:

On 28.10.23 04:46, Owen T. Heisler wrote:

#regzbot introduced: d386a4b54607cf6f76e23815c2c9a3abc1d66882
#regzbot link: https://gitlab.freedesktop.org/drm/nouveau/-/issues/180

## Problem

1. Connect external display to DVI port on dock and run X with both
    displays in use.
2. Wait hours or days.
3. Suddenly the secondary Nvidia-connected display turns off and X stops
    responding to keyboard/mouse input. In *some* cases it is possible to
    switch to a virtual TTY with Ctrl+Alt+Fn and log in there.



You thus might want to check if the problem occurs with 6.6 -- and
ideally also check if reverting the culprit there fixes things for you.


Hi Thorsten and others,

The problem also occurs with v6.6. Here is a decoded kernel log from an 
untainted kernel:


https://gitlab.freedesktop.org/drm/nouveau/uploads/c120faf09da46f9c74006df9f1d14442/async-wait-on-fence-180.log

The culprit commit does not revert cleanly on v6.6. I have not yet 
attempted to resolve the conflicts.


I have also updated the bug description at
.

Thanks,
Owen


Re: [PATCH v2] drm/amd/display: fix NULL dereference

2023-11-14 Thread José Pekkarinen

On 2023-11-14 23:01, Hamza Mahfooz wrote:

On 11/14/23 10:27, José Pekkarinen wrote:

The following patch will fix a minor issue where a debug message is
referencing an struct that has just being checked whether is null or
not. This has been noticed by using coccinelle, in the following 
output:


drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c:540:25-29: 
ERROR: aconnector is NULL but dereferenced.


Fixes: 5d72e247e58c9 ("drm/amd/display: switch DC over to the new DRM 
logging macros")


You only need the first 12 characters of the hash here. I have fixed it
for you and applied the patch in this case. But, in the future please
test your patches against `./scripts/checkpatch.pl` before submitting
them.


Oops! Sorry I didn't notice! Thanks!

José.


[PATCH AUTOSEL 5.10 2/3] drm/amdgpu: fix software pci_unplug on some chips

2023-11-14 Thread Sasha Levin
From: Vitaly Prosyak 

[ Upstream commit 4638e0c29a3f2294d5de0d052a4b8c9f33ccb957 ]

When software 'pci unplug' using IGT is executed we got a sysfs directory
entry is NULL for differant ras blocks like hdp, umc, etc.
Before call 'sysfs_remove_file_from_group' and 'sysfs_remove_group'
check that 'sd' is  not NULL.

[  +0.01] RIP: 0010:sysfs_remove_group+0x83/0x90
[  +0.02] Code: 31 c0 31 d2 31 f6 31 ff e9 9a a8 b4 00 4c 89 e7 e8 f2 a2 ff 
ff eb c2 49 8b 55 00 48 8b 33 48 c7 c7 80 65 94 82 e8 cd 82 bb ff <0f> 0b eb cc 
66 0f 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90
[  +0.01] RSP: 0018:c90002067c90 EFLAGS: 00010246
[  +0.02] RAX:  RBX: 824ea180 RCX: 
[  +0.01] RDX:  RSI:  RDI: 
[  +0.01] RBP: c90002067ca8 R08:  R09: 
[  +0.01] R10:  R11:  R12: 
[  +0.01] R13: 88810a395f48 R14: 888101aab0d0 R15: 
[  +0.01] FS:  7f5ddaa43a00() GS:88841e80() 
knlGS:
[  +0.02] CS:  0010 DS:  ES:  CR0: 80050033
[  +0.01] CR2: 7f8ffa61ba50 CR3: 000106432000 CR4: 00350ef0
[  +0.01] Call Trace:
[  +0.01]  
[  +0.01]  ? show_regs+0x72/0x90
[  +0.02]  ? sysfs_remove_group+0x83/0x90
[  +0.02]  ? __warn+0x8d/0x160
[  +0.01]  ? sysfs_remove_group+0x83/0x90
[  +0.01]  ? report_bug+0x1bb/0x1d0
[  +0.03]  ? handle_bug+0x46/0x90
[  +0.01]  ? exc_invalid_op+0x19/0x80
[  +0.02]  ? asm_exc_invalid_op+0x1b/0x20
[  +0.03]  ? sysfs_remove_group+0x83/0x90
[  +0.01]  dpm_sysfs_remove+0x61/0x70
[  +0.02]  device_del+0xa3/0x3d0
[  +0.02]  ? ktime_get_mono_fast_ns+0x46/0xb0
[  +0.02]  device_unregister+0x18/0x70
[  +0.01]  i2c_del_adapter+0x26d/0x330
[  +0.02]  arcturus_i2c_control_fini+0x25/0x50 [amdgpu]
[  +0.000236]  smu_sw_fini+0x38/0x260 [amdgpu]
[  +0.000241]  amdgpu_device_fini_sw+0x116/0x670 [amdgpu]
[  +0.000186]  ? mutex_lock+0x13/0x50
[  +0.03]  amdgpu_driver_release_kms+0x16/0x40 [amdgpu]
[  +0.000192]  drm_minor_release+0x4f/0x80 [drm]
[  +0.25]  drm_release+0xfe/0x150 [drm]
[  +0.27]  __fput+0x9f/0x290
[  +0.02]  fput+0xe/0x20
[  +0.02]  task_work_run+0x61/0xa0
[  +0.02]  exit_to_user_mode_prepare+0x150/0x170
[  +0.02]  syscall_exit_to_user_mode+0x2a/0x50

Cc: Hawking Zhang 
Cc: Luben Tuikov 
Cc: Alex Deucher 
Cc: Christian Koenig 
Signed-off-by: Vitaly Prosyak 
Reviewed-by: Luben Tuikov 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 3638f0e12a2b8..a8f1c4969fac7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -1031,7 +1031,8 @@ static void amdgpu_ras_sysfs_remove_bad_page_node(struct 
amdgpu_device *adev)
 {
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
 
-   sysfs_remove_file_from_group(>dev->kobj,
+   if (adev->dev->kobj.sd)
+   sysfs_remove_file_from_group(>dev->kobj,
>badpages_attr.attr,
RAS_FS_NAME);
 }
@@ -1048,7 +1049,8 @@ static int amdgpu_ras_sysfs_remove_feature_node(struct 
amdgpu_device *adev)
.attrs = attrs,
};
 
-   sysfs_remove_group(>dev->kobj, );
+   if (adev->dev->kobj.sd)
+   sysfs_remove_group(>dev->kobj, );
 
return 0;
 }
@@ -1096,7 +1098,8 @@ int amdgpu_ras_sysfs_remove(struct amdgpu_device *adev,
if (!obj || !obj->attr_inuse)
return -EINVAL;
 
-   sysfs_remove_file_from_group(>dev->kobj,
+   if (adev->dev->kobj.sd)
+   sysfs_remove_file_from_group(>dev->kobj,
>sysfs_attr.attr,
RAS_FS_NAME);
obj->attr_inuse = 0;
-- 
2.42.0



[PATCH AUTOSEL 5.15 3/4] drm/amdgpu: fix software pci_unplug on some chips

2023-11-14 Thread Sasha Levin
From: Vitaly Prosyak 

[ Upstream commit 4638e0c29a3f2294d5de0d052a4b8c9f33ccb957 ]

When software 'pci unplug' using IGT is executed we got a sysfs directory
entry is NULL for differant ras blocks like hdp, umc, etc.
Before call 'sysfs_remove_file_from_group' and 'sysfs_remove_group'
check that 'sd' is  not NULL.

[  +0.01] RIP: 0010:sysfs_remove_group+0x83/0x90
[  +0.02] Code: 31 c0 31 d2 31 f6 31 ff e9 9a a8 b4 00 4c 89 e7 e8 f2 a2 ff 
ff eb c2 49 8b 55 00 48 8b 33 48 c7 c7 80 65 94 82 e8 cd 82 bb ff <0f> 0b eb cc 
66 0f 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90
[  +0.01] RSP: 0018:c90002067c90 EFLAGS: 00010246
[  +0.02] RAX:  RBX: 824ea180 RCX: 
[  +0.01] RDX:  RSI:  RDI: 
[  +0.01] RBP: c90002067ca8 R08:  R09: 
[  +0.01] R10:  R11:  R12: 
[  +0.01] R13: 88810a395f48 R14: 888101aab0d0 R15: 
[  +0.01] FS:  7f5ddaa43a00() GS:88841e80() 
knlGS:
[  +0.02] CS:  0010 DS:  ES:  CR0: 80050033
[  +0.01] CR2: 7f8ffa61ba50 CR3: 000106432000 CR4: 00350ef0
[  +0.01] Call Trace:
[  +0.01]  
[  +0.01]  ? show_regs+0x72/0x90
[  +0.02]  ? sysfs_remove_group+0x83/0x90
[  +0.02]  ? __warn+0x8d/0x160
[  +0.01]  ? sysfs_remove_group+0x83/0x90
[  +0.01]  ? report_bug+0x1bb/0x1d0
[  +0.03]  ? handle_bug+0x46/0x90
[  +0.01]  ? exc_invalid_op+0x19/0x80
[  +0.02]  ? asm_exc_invalid_op+0x1b/0x20
[  +0.03]  ? sysfs_remove_group+0x83/0x90
[  +0.01]  dpm_sysfs_remove+0x61/0x70
[  +0.02]  device_del+0xa3/0x3d0
[  +0.02]  ? ktime_get_mono_fast_ns+0x46/0xb0
[  +0.02]  device_unregister+0x18/0x70
[  +0.01]  i2c_del_adapter+0x26d/0x330
[  +0.02]  arcturus_i2c_control_fini+0x25/0x50 [amdgpu]
[  +0.000236]  smu_sw_fini+0x38/0x260 [amdgpu]
[  +0.000241]  amdgpu_device_fini_sw+0x116/0x670 [amdgpu]
[  +0.000186]  ? mutex_lock+0x13/0x50
[  +0.03]  amdgpu_driver_release_kms+0x16/0x40 [amdgpu]
[  +0.000192]  drm_minor_release+0x4f/0x80 [drm]
[  +0.25]  drm_release+0xfe/0x150 [drm]
[  +0.27]  __fput+0x9f/0x290
[  +0.02]  fput+0xe/0x20
[  +0.02]  task_work_run+0x61/0xa0
[  +0.02]  exit_to_user_mode_prepare+0x150/0x170
[  +0.02]  syscall_exit_to_user_mode+0x2a/0x50

Cc: Hawking Zhang 
Cc: Luben Tuikov 
Cc: Alex Deucher 
Cc: Christian Koenig 
Signed-off-by: Vitaly Prosyak 
Reviewed-by: Luben Tuikov 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 96a8fd0ca1df3..439ea256ed252 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -1192,7 +1192,8 @@ static void amdgpu_ras_sysfs_remove_bad_page_node(struct 
amdgpu_device *adev)
 {
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
 
-   sysfs_remove_file_from_group(>dev->kobj,
+   if (adev->dev->kobj.sd)
+   sysfs_remove_file_from_group(>dev->kobj,
>badpages_attr.attr,
RAS_FS_NAME);
 }
@@ -1209,7 +1210,8 @@ static int amdgpu_ras_sysfs_remove_feature_node(struct 
amdgpu_device *adev)
.attrs = attrs,
};
 
-   sysfs_remove_group(>dev->kobj, );
+   if (adev->dev->kobj.sd)
+   sysfs_remove_group(>dev->kobj, );
 
return 0;
 }
@@ -1257,7 +1259,8 @@ int amdgpu_ras_sysfs_remove(struct amdgpu_device *adev,
if (!obj || !obj->attr_inuse)
return -EINVAL;
 
-   sysfs_remove_file_from_group(>dev->kobj,
+   if (adev->dev->kobj.sd)
+   sysfs_remove_file_from_group(>dev->kobj,
>sysfs_attr.attr,
RAS_FS_NAME);
obj->attr_inuse = 0;
-- 
2.42.0



[PATCH AUTOSEL 5.15 2/4] drm/qxl: prevent memory leak

2023-11-14 Thread Sasha Levin
From: Zongmin Zhou 

[ Upstream commit 0e8b9f258baed25f1c5672613699247c76b007b5 ]

The allocated memory for qdev->dumb_heads should be released
in qxl_destroy_monitors_object before qxl suspend.
otherwise,qxl_create_monitors_object will be called to
reallocate memory for qdev->dumb_heads after qxl resume,
it will cause memory leak.

Signed-off-by: Zongmin Zhou 
Link: https://lore.kernel.org/r/20230801025309.4049813-1-zhouzong...@kylinos.cn
Reviewed-by: Dave Airlie 
Signed-off-by: Maxime Ripard 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/qxl/qxl_display.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
b/drivers/gpu/drm/qxl/qxl_display.c
index 9e0a1e8360117..dc04412784a0d 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -1221,6 +1221,9 @@ int qxl_destroy_monitors_object(struct qxl_device *qdev)
if (!qdev->monitors_config_bo)
return 0;
 
+   kfree(qdev->dumb_heads);
+   qdev->dumb_heads = NULL;
+
qdev->monitors_config = NULL;
qdev->ram_header->monitors_config = 0;
 
-- 
2.42.0



[PATCH AUTOSEL 6.1 5/6] drm/amdgpu: fix software pci_unplug on some chips

2023-11-14 Thread Sasha Levin
From: Vitaly Prosyak 

[ Upstream commit 4638e0c29a3f2294d5de0d052a4b8c9f33ccb957 ]

When software 'pci unplug' using IGT is executed we got a sysfs directory
entry is NULL for differant ras blocks like hdp, umc, etc.
Before call 'sysfs_remove_file_from_group' and 'sysfs_remove_group'
check that 'sd' is  not NULL.

[  +0.01] RIP: 0010:sysfs_remove_group+0x83/0x90
[  +0.02] Code: 31 c0 31 d2 31 f6 31 ff e9 9a a8 b4 00 4c 89 e7 e8 f2 a2 ff 
ff eb c2 49 8b 55 00 48 8b 33 48 c7 c7 80 65 94 82 e8 cd 82 bb ff <0f> 0b eb cc 
66 0f 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90
[  +0.01] RSP: 0018:c90002067c90 EFLAGS: 00010246
[  +0.02] RAX:  RBX: 824ea180 RCX: 
[  +0.01] RDX:  RSI:  RDI: 
[  +0.01] RBP: c90002067ca8 R08:  R09: 
[  +0.01] R10:  R11:  R12: 
[  +0.01] R13: 88810a395f48 R14: 888101aab0d0 R15: 
[  +0.01] FS:  7f5ddaa43a00() GS:88841e80() 
knlGS:
[  +0.02] CS:  0010 DS:  ES:  CR0: 80050033
[  +0.01] CR2: 7f8ffa61ba50 CR3: 000106432000 CR4: 00350ef0
[  +0.01] Call Trace:
[  +0.01]  
[  +0.01]  ? show_regs+0x72/0x90
[  +0.02]  ? sysfs_remove_group+0x83/0x90
[  +0.02]  ? __warn+0x8d/0x160
[  +0.01]  ? sysfs_remove_group+0x83/0x90
[  +0.01]  ? report_bug+0x1bb/0x1d0
[  +0.03]  ? handle_bug+0x46/0x90
[  +0.01]  ? exc_invalid_op+0x19/0x80
[  +0.02]  ? asm_exc_invalid_op+0x1b/0x20
[  +0.03]  ? sysfs_remove_group+0x83/0x90
[  +0.01]  dpm_sysfs_remove+0x61/0x70
[  +0.02]  device_del+0xa3/0x3d0
[  +0.02]  ? ktime_get_mono_fast_ns+0x46/0xb0
[  +0.02]  device_unregister+0x18/0x70
[  +0.01]  i2c_del_adapter+0x26d/0x330
[  +0.02]  arcturus_i2c_control_fini+0x25/0x50 [amdgpu]
[  +0.000236]  smu_sw_fini+0x38/0x260 [amdgpu]
[  +0.000241]  amdgpu_device_fini_sw+0x116/0x670 [amdgpu]
[  +0.000186]  ? mutex_lock+0x13/0x50
[  +0.03]  amdgpu_driver_release_kms+0x16/0x40 [amdgpu]
[  +0.000192]  drm_minor_release+0x4f/0x80 [drm]
[  +0.25]  drm_release+0xfe/0x150 [drm]
[  +0.27]  __fput+0x9f/0x290
[  +0.02]  fput+0xe/0x20
[  +0.02]  task_work_run+0x61/0xa0
[  +0.02]  exit_to_user_mode_prepare+0x150/0x170
[  +0.02]  syscall_exit_to_user_mode+0x2a/0x50

Cc: Hawking Zhang 
Cc: Luben Tuikov 
Cc: Alex Deucher 
Cc: Christian Koenig 
Signed-off-by: Vitaly Prosyak 
Reviewed-by: Luben Tuikov 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 09fc464f5f128..9fe2eae88ec17 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -1273,7 +1273,8 @@ static void amdgpu_ras_sysfs_remove_bad_page_node(struct 
amdgpu_device *adev)
 {
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
 
-   sysfs_remove_file_from_group(>dev->kobj,
+   if (adev->dev->kobj.sd)
+   sysfs_remove_file_from_group(>dev->kobj,
>badpages_attr.attr,
RAS_FS_NAME);
 }
@@ -1290,7 +1291,8 @@ static int amdgpu_ras_sysfs_remove_feature_node(struct 
amdgpu_device *adev)
.attrs = attrs,
};
 
-   sysfs_remove_group(>dev->kobj, );
+   if (adev->dev->kobj.sd)
+   sysfs_remove_group(>dev->kobj, );
 
return 0;
 }
@@ -1337,7 +1339,8 @@ int amdgpu_ras_sysfs_remove(struct amdgpu_device *adev,
if (!obj || !obj->attr_inuse)
return -EINVAL;
 
-   sysfs_remove_file_from_group(>dev->kobj,
+   if (adev->dev->kobj.sd)
+   sysfs_remove_file_from_group(>dev->kobj,
>sysfs_attr.attr,
RAS_FS_NAME);
obj->attr_inuse = 0;
-- 
2.42.0



[PATCH AUTOSEL 6.1 2/6] drm/qxl: prevent memory leak

2023-11-14 Thread Sasha Levin
From: Zongmin Zhou 

[ Upstream commit 0e8b9f258baed25f1c5672613699247c76b007b5 ]

The allocated memory for qdev->dumb_heads should be released
in qxl_destroy_monitors_object before qxl suspend.
otherwise,qxl_create_monitors_object will be called to
reallocate memory for qdev->dumb_heads after qxl resume,
it will cause memory leak.

Signed-off-by: Zongmin Zhou 
Link: https://lore.kernel.org/r/20230801025309.4049813-1-zhouzong...@kylinos.cn
Reviewed-by: Dave Airlie 
Signed-off-by: Maxime Ripard 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/qxl/qxl_display.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
b/drivers/gpu/drm/qxl/qxl_display.c
index a152a7c6db215..f91a86225d5e7 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -1229,6 +1229,9 @@ int qxl_destroy_monitors_object(struct qxl_device *qdev)
if (!qdev->monitors_config_bo)
return 0;
 
+   kfree(qdev->dumb_heads);
+   qdev->dumb_heads = NULL;
+
qdev->monitors_config = NULL;
qdev->ram_header->monitors_config = 0;
 
-- 
2.42.0



[PATCH AUTOSEL 6.5 5/6] drm/amdgpu: fix software pci_unplug on some chips

2023-11-14 Thread Sasha Levin
From: Vitaly Prosyak 

[ Upstream commit 4638e0c29a3f2294d5de0d052a4b8c9f33ccb957 ]

When software 'pci unplug' using IGT is executed we got a sysfs directory
entry is NULL for differant ras blocks like hdp, umc, etc.
Before call 'sysfs_remove_file_from_group' and 'sysfs_remove_group'
check that 'sd' is  not NULL.

[  +0.01] RIP: 0010:sysfs_remove_group+0x83/0x90
[  +0.02] Code: 31 c0 31 d2 31 f6 31 ff e9 9a a8 b4 00 4c 89 e7 e8 f2 a2 ff 
ff eb c2 49 8b 55 00 48 8b 33 48 c7 c7 80 65 94 82 e8 cd 82 bb ff <0f> 0b eb cc 
66 0f 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90
[  +0.01] RSP: 0018:c90002067c90 EFLAGS: 00010246
[  +0.02] RAX:  RBX: 824ea180 RCX: 
[  +0.01] RDX:  RSI:  RDI: 
[  +0.01] RBP: c90002067ca8 R08:  R09: 
[  +0.01] R10:  R11:  R12: 
[  +0.01] R13: 88810a395f48 R14: 888101aab0d0 R15: 
[  +0.01] FS:  7f5ddaa43a00() GS:88841e80() 
knlGS:
[  +0.02] CS:  0010 DS:  ES:  CR0: 80050033
[  +0.01] CR2: 7f8ffa61ba50 CR3: 000106432000 CR4: 00350ef0
[  +0.01] Call Trace:
[  +0.01]  
[  +0.01]  ? show_regs+0x72/0x90
[  +0.02]  ? sysfs_remove_group+0x83/0x90
[  +0.02]  ? __warn+0x8d/0x160
[  +0.01]  ? sysfs_remove_group+0x83/0x90
[  +0.01]  ? report_bug+0x1bb/0x1d0
[  +0.03]  ? handle_bug+0x46/0x90
[  +0.01]  ? exc_invalid_op+0x19/0x80
[  +0.02]  ? asm_exc_invalid_op+0x1b/0x20
[  +0.03]  ? sysfs_remove_group+0x83/0x90
[  +0.01]  dpm_sysfs_remove+0x61/0x70
[  +0.02]  device_del+0xa3/0x3d0
[  +0.02]  ? ktime_get_mono_fast_ns+0x46/0xb0
[  +0.02]  device_unregister+0x18/0x70
[  +0.01]  i2c_del_adapter+0x26d/0x330
[  +0.02]  arcturus_i2c_control_fini+0x25/0x50 [amdgpu]
[  +0.000236]  smu_sw_fini+0x38/0x260 [amdgpu]
[  +0.000241]  amdgpu_device_fini_sw+0x116/0x670 [amdgpu]
[  +0.000186]  ? mutex_lock+0x13/0x50
[  +0.03]  amdgpu_driver_release_kms+0x16/0x40 [amdgpu]
[  +0.000192]  drm_minor_release+0x4f/0x80 [drm]
[  +0.25]  drm_release+0xfe/0x150 [drm]
[  +0.27]  __fput+0x9f/0x290
[  +0.02]  fput+0xe/0x20
[  +0.02]  task_work_run+0x61/0xa0
[  +0.02]  exit_to_user_mode_prepare+0x150/0x170
[  +0.02]  syscall_exit_to_user_mode+0x2a/0x50

Cc: Hawking Zhang 
Cc: Luben Tuikov 
Cc: Alex Deucher 
Cc: Christian Koenig 
Signed-off-by: Vitaly Prosyak 
Reviewed-by: Luben Tuikov 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 7d5019a884024..2003be3390aab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -1380,7 +1380,8 @@ static void amdgpu_ras_sysfs_remove_bad_page_node(struct 
amdgpu_device *adev)
 {
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
 
-   sysfs_remove_file_from_group(>dev->kobj,
+   if (adev->dev->kobj.sd)
+   sysfs_remove_file_from_group(>dev->kobj,
>badpages_attr.attr,
RAS_FS_NAME);
 }
@@ -1397,7 +1398,8 @@ static int amdgpu_ras_sysfs_remove_feature_node(struct 
amdgpu_device *adev)
.attrs = attrs,
};
 
-   sysfs_remove_group(>dev->kobj, );
+   if (adev->dev->kobj.sd)
+   sysfs_remove_group(>dev->kobj, );
 
return 0;
 }
@@ -1444,7 +1446,8 @@ int amdgpu_ras_sysfs_remove(struct amdgpu_device *adev,
if (!obj || !obj->attr_inuse)
return -EINVAL;
 
-   sysfs_remove_file_from_group(>dev->kobj,
+   if (adev->dev->kobj.sd)
+   sysfs_remove_file_from_group(>dev->kobj,
>sysfs_attr.attr,
RAS_FS_NAME);
obj->attr_inuse = 0;
-- 
2.42.0



[PATCH AUTOSEL 6.5 2/6] drm/qxl: prevent memory leak

2023-11-14 Thread Sasha Levin
From: Zongmin Zhou 

[ Upstream commit 0e8b9f258baed25f1c5672613699247c76b007b5 ]

The allocated memory for qdev->dumb_heads should be released
in qxl_destroy_monitors_object before qxl suspend.
otherwise,qxl_create_monitors_object will be called to
reallocate memory for qdev->dumb_heads after qxl resume,
it will cause memory leak.

Signed-off-by: Zongmin Zhou 
Link: https://lore.kernel.org/r/20230801025309.4049813-1-zhouzong...@kylinos.cn
Reviewed-by: Dave Airlie 
Signed-off-by: Maxime Ripard 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/qxl/qxl_display.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
b/drivers/gpu/drm/qxl/qxl_display.c
index 6492a70e3c396..404b0483bb7cb 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -1229,6 +1229,9 @@ int qxl_destroy_monitors_object(struct qxl_device *qdev)
if (!qdev->monitors_config_bo)
return 0;
 
+   kfree(qdev->dumb_heads);
+   qdev->dumb_heads = NULL;
+
qdev->monitors_config = NULL;
qdev->ram_header->monitors_config = 0;
 
-- 
2.42.0



[PATCH AUTOSEL 6.6 5/6] drm/amdgpu: fix software pci_unplug on some chips

2023-11-14 Thread Sasha Levin
From: Vitaly Prosyak 

[ Upstream commit 4638e0c29a3f2294d5de0d052a4b8c9f33ccb957 ]

When software 'pci unplug' using IGT is executed we got a sysfs directory
entry is NULL for differant ras blocks like hdp, umc, etc.
Before call 'sysfs_remove_file_from_group' and 'sysfs_remove_group'
check that 'sd' is  not NULL.

[  +0.01] RIP: 0010:sysfs_remove_group+0x83/0x90
[  +0.02] Code: 31 c0 31 d2 31 f6 31 ff e9 9a a8 b4 00 4c 89 e7 e8 f2 a2 ff 
ff eb c2 49 8b 55 00 48 8b 33 48 c7 c7 80 65 94 82 e8 cd 82 bb ff <0f> 0b eb cc 
66 0f 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90
[  +0.01] RSP: 0018:c90002067c90 EFLAGS: 00010246
[  +0.02] RAX:  RBX: 824ea180 RCX: 
[  +0.01] RDX:  RSI:  RDI: 
[  +0.01] RBP: c90002067ca8 R08:  R09: 
[  +0.01] R10:  R11:  R12: 
[  +0.01] R13: 88810a395f48 R14: 888101aab0d0 R15: 
[  +0.01] FS:  7f5ddaa43a00() GS:88841e80() 
knlGS:
[  +0.02] CS:  0010 DS:  ES:  CR0: 80050033
[  +0.01] CR2: 7f8ffa61ba50 CR3: 000106432000 CR4: 00350ef0
[  +0.01] Call Trace:
[  +0.01]  
[  +0.01]  ? show_regs+0x72/0x90
[  +0.02]  ? sysfs_remove_group+0x83/0x90
[  +0.02]  ? __warn+0x8d/0x160
[  +0.01]  ? sysfs_remove_group+0x83/0x90
[  +0.01]  ? report_bug+0x1bb/0x1d0
[  +0.03]  ? handle_bug+0x46/0x90
[  +0.01]  ? exc_invalid_op+0x19/0x80
[  +0.02]  ? asm_exc_invalid_op+0x1b/0x20
[  +0.03]  ? sysfs_remove_group+0x83/0x90
[  +0.01]  dpm_sysfs_remove+0x61/0x70
[  +0.02]  device_del+0xa3/0x3d0
[  +0.02]  ? ktime_get_mono_fast_ns+0x46/0xb0
[  +0.02]  device_unregister+0x18/0x70
[  +0.01]  i2c_del_adapter+0x26d/0x330
[  +0.02]  arcturus_i2c_control_fini+0x25/0x50 [amdgpu]
[  +0.000236]  smu_sw_fini+0x38/0x260 [amdgpu]
[  +0.000241]  amdgpu_device_fini_sw+0x116/0x670 [amdgpu]
[  +0.000186]  ? mutex_lock+0x13/0x50
[  +0.03]  amdgpu_driver_release_kms+0x16/0x40 [amdgpu]
[  +0.000192]  drm_minor_release+0x4f/0x80 [drm]
[  +0.25]  drm_release+0xfe/0x150 [drm]
[  +0.27]  __fput+0x9f/0x290
[  +0.02]  fput+0xe/0x20
[  +0.02]  task_work_run+0x61/0xa0
[  +0.02]  exit_to_user_mode_prepare+0x150/0x170
[  +0.02]  syscall_exit_to_user_mode+0x2a/0x50

Cc: Hawking Zhang 
Cc: Luben Tuikov 
Cc: Alex Deucher 
Cc: Christian Koenig 
Signed-off-by: Vitaly Prosyak 
Reviewed-by: Luben Tuikov 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 163445baa4fc8..6f6341f702789 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -1373,7 +1373,8 @@ static void amdgpu_ras_sysfs_remove_bad_page_node(struct 
amdgpu_device *adev)
 {
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
 
-   sysfs_remove_file_from_group(>dev->kobj,
+   if (adev->dev->kobj.sd)
+   sysfs_remove_file_from_group(>dev->kobj,
>badpages_attr.attr,
RAS_FS_NAME);
 }
@@ -1390,7 +1391,8 @@ static int amdgpu_ras_sysfs_remove_feature_node(struct 
amdgpu_device *adev)
.attrs = attrs,
};
 
-   sysfs_remove_group(>dev->kobj, );
+   if (adev->dev->kobj.sd)
+   sysfs_remove_group(>dev->kobj, );
 
return 0;
 }
@@ -1437,7 +1439,8 @@ int amdgpu_ras_sysfs_remove(struct amdgpu_device *adev,
if (!obj || !obj->attr_inuse)
return -EINVAL;
 
-   sysfs_remove_file_from_group(>dev->kobj,
+   if (adev->dev->kobj.sd)
+   sysfs_remove_file_from_group(>dev->kobj,
>sysfs_attr.attr,
RAS_FS_NAME);
obj->attr_inuse = 0;
-- 
2.42.0



[PATCH AUTOSEL 6.6 2/6] drm/qxl: prevent memory leak

2023-11-14 Thread Sasha Levin
From: Zongmin Zhou 

[ Upstream commit 0e8b9f258baed25f1c5672613699247c76b007b5 ]

The allocated memory for qdev->dumb_heads should be released
in qxl_destroy_monitors_object before qxl suspend.
otherwise,qxl_create_monitors_object will be called to
reallocate memory for qdev->dumb_heads after qxl resume,
it will cause memory leak.

Signed-off-by: Zongmin Zhou 
Link: https://lore.kernel.org/r/20230801025309.4049813-1-zhouzong...@kylinos.cn
Reviewed-by: Dave Airlie 
Signed-off-by: Maxime Ripard 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/qxl/qxl_display.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
b/drivers/gpu/drm/qxl/qxl_display.c
index 6492a70e3c396..404b0483bb7cb 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -1229,6 +1229,9 @@ int qxl_destroy_monitors_object(struct qxl_device *qdev)
if (!qdev->monitors_config_bo)
return 0;
 
+   kfree(qdev->dumb_heads);
+   qdev->dumb_heads = NULL;
+
qdev->monitors_config = NULL;
qdev->ram_header->monitors_config = 0;
 
-- 
2.42.0




Re: [PATCH v3 7/7] PCI: Exclude PCIe ports used for virtual links in pcie_bandwidth_available()

2023-11-14 Thread Lazar, Lijo




On 11/15/2023 1:37 AM, Mario Limonciello wrote:

The USB4 spec specifies that PCIe ports that are used for tunneling
PCIe traffic over USB4 fabric will be hardcoded to advertise 2.5GT/s and
behave as a PCIe Gen1 device. The actual performance of these ports is
controlled by the fabric implementation.

Callers for pcie_bandwidth_available() will always find the PCIe ports
used for tunneling as a limiting factor potentially leading to incorrect
performance decisions.

To prevent such problems check explicitly for ports that are marked as
virtual links or as thunderbolt controllers and skip them when looking
for bandwidth limitations of the hierarchy. If the only device connected
is a port used for tunneling then report that device.

Callers to pcie_bandwidth_available() could make this change on their
own as well but then they wouldn't be able to detect other potential
speed bottlenecks from the hierarchy without duplicating
pcie_bandwidth_available() logic.

Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2925#note_2145860
Link: https://www.usb.org/document-library/usb4r-specification-v20
   USB4 V2 with Errata and ECN through June 2023
   Section 11.2.1
Signed-off-by: Mario Limonciello 
---
v2->v3:
  * Split from previous patch version
  * Look for thunderbolt or virtual link
---
  drivers/pci/pci.c | 19 +++
  1 file changed, 19 insertions(+)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 0ff7883cc774..b1fb2258b211 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -6269,11 +6269,20 @@ static u32 pcie_calc_bw_limits(struct pci_dev *dev, u32 
bw,
   * limiting_dev, speed, and width pointers are supplied) information about
   * that point.  The bandwidth returned is in Mb/s, i.e., megabits/second of
   * raw bandwidth.
+ *
+ * This excludes the bandwidth calculation that has been returned from a
+ * PCIe device that is used for transmitting tunneled PCIe traffic over a 
virtual
+ * link part of larger hierarchy. Examples include Thunderbolt3 and USB4 links.
+ * The calculation is excluded because the USB4 specification specifies that 
the
+ * max speed returned from PCIe configuration registers for the tunneling link 
is
+ * always PCI 1x 2.5 GT/s.  When only tunneled devices are present, the 
bandwidth
+ * returned is the bandwidth available from the first tunneled device.
   */
  u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev 
**limiting_dev,
 enum pci_bus_speed *speed,
 enum pcie_link_width *width)
  {
+   struct pci_dev *vdev = NULL;
u32 bw = 0;
  
  	if (speed)

@@ -6282,10 +6291,20 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, 
struct pci_dev **limiting_dev,
*width = PCIE_LNK_WIDTH_UNKNOWN;
  
  	while (dev) {

+   if (dev->is_virtual_link || dev->is_thunderbolt) {
+   if (!vdev)
+   vdev = dev;
+   goto skip;
+   }


One problem with this is it *silently* ignores the bandwidth limiting 
device - the bandwidth may not be really available if there are virtual 
links in between. That is a change in behavior from the messages shown 
in __pcie_print_link_status.


Thanks,
Lijo


bw = pcie_calc_bw_limits(dev, bw, limiting_dev, speed, width);
+skip:
dev = pci_upstream_bridge(dev);
}
  
+	/* If nothing "faster" found on hierarchy, limit to first virtual link */

+   if (vdev && !bw)
+   bw = pcie_calc_bw_limits(vdev, bw, limiting_dev, speed, width);
+
return bw;
  }
  EXPORT_SYMBOL(pcie_bandwidth_available);


Re: [Intel-gfx] [PATCH] drm/i915/display: Fix phys_base to be relative not absolute

2023-11-14 Thread Rodrigo Vivi
On Sun, Nov 05, 2023 at 05:27:03PM +, Paz Zcharya wrote:
> Fix the value of variable `phys_base` to be the relative offset in
> stolen memory, and not the absolute offset of the GSM.

to me it looks like the other way around. phys_base is the physical
base address for the frame_buffer. Setting it to zero doesn't seem
to make that relative. And also doesn't look right.

> 
> Currently, the value of `phys_base` is set to "Surface Base Address,"
> which in the case of Meter Lake is 0xfc00_.

I don't believe this is a fixed value. IIRC this comes from the register
set by video bios, where the idea is to reuse the fb that was used so
far.

With this in mind I don't understand how that could overflow. Maybe
the size of the stolen is not right? maybe the size? maybe different
memory region?

> This causes the
> function `i915_gem_object_create_region_at` to fail in line 128, when
> it attempts to verify that the range does not overflow:
> 
> if (range_overflows(offset, size, resource_size(>region)))
>   return ERR_PTR(-EINVAL);
> 
> where:
>   offset = 0xfc00
>   size = 0x8ca000
>   mem->region.end + 1 = 0x440
>   mem->region.start = 0x80
>   resource_size(>region) = 0x3c0
> 
> call stack:
>   i915_gem_object_create_region_at
>   initial_plane_vma
>   intel_alloc_initial_plane_obj
>   intel_find_initial_plane_obj
>   intel_crtc_initial_plane_config
> 
> Looking at the flow coming next, we see that `phys_base` is only used
> once, in function `_i915_gem_object_stolen_init`, in the context of
> the offset *in* the stolen memory. Combining that with an
> examinination of the history of the file seems to indicate the
> current value set is invalid.
> 
> call stack (functions using `phys_base`)
>   _i915_gem_object_stolen_init
>   __i915_gem_object_create_region
>   i915_gem_object_create_region_at
>   initial_plane_vma
>   intel_alloc_initial_plane_obj
>   intel_find_initial_plane_obj
>   intel_crtc_initial_plane_config
> 
> [drm:_i915_gem_object_stolen_init] creating preallocated stolen
> object: stolen_offset=0x, size=0x008ca000
> 
> Signed-off-by: Paz Zcharya 
> ---
> 
>  drivers/gpu/drm/i915/display/intel_plane_initial.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c 
> b/drivers/gpu/drm/i915/display/intel_plane_initial.c
> index a55c09cbd0e4..e696cb13756a 100644
> --- a/drivers/gpu/drm/i915/display/intel_plane_initial.c
> +++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c
> @@ -90,7 +90,7 @@ initial_plane_vma(struct drm_i915_private *i915,
>   "Using phys_base=%pa, based on initial plane 
> programming\n",
>   _base);
>   } else {
> - phys_base = base;
> + phys_base = 0;
>   mem = i915->mm.stolen_region;
>   }
>  
> -- 
> 2.42.0.869.gea05f2083d-goog
> 


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

2023-11-14 Thread Andy Yan



On 11/15/23 05:54, Heiko Stübner wrote:

Am Dienstag, 14. November 2023, 12:28:41 CET schrieb Andy Yan:

From: Andy Yan 

The vop2 on rk3588 is similar to which on rk356x
but with 4 video outputs and need to reference
more grf modules.

Signed-off-by: Andy Yan 
---

  .../display/rockchip/rockchip-vop2.yaml   | 25 +++
  1 file changed, 25 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml 
b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
index b60b90472d42..c333c651da1a 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
@@ -20,6 +20,7 @@ properties:
  enum:
- rockchip,rk3566-vop
- rockchip,rk3568-vop
+  - rockchip,rk3588-vop
  
reg:

  items:
@@ -48,6 +49,8 @@ properties:
- description: Pixel clock for video port 0.
- description: Pixel clock for video port 1.
- description: Pixel clock for video port 2.
+  - description: Pixel clock for video port 4.
+  - description: Peripheral clock for vop on rk3588.
  
clock-names:

  items:
@@ -56,12 +59,29 @@ properties:
- const: dclk_vp0
- const: dclk_vp1
- const: dclk_vp2
+  - const: dclk_vp3
+  - const: pclk_vop

with the error Rob's bot reported, I guess both clocks and clock-names
need a minItems element to mark these new clocks essentially as optional?


Yes, when add minItems for clocks and clkock-names, the erro gone.

Considering we also have vop2 based soc(rk3562) only have one video port,

so it is better to set the minItems as 3 here?




rockchip,grf:
  $ref: /schemas/types.yaml#/definitions/phandle
  description:
Phandle to GRF regs used for misc control
  
+  rockchip,vo-grf:

+$ref: /schemas/types.yaml#/definitions/phandle
+description:
+  Phandle to VO GRF regs used for misc control, required for rk3588
+
+  rockchip,vop-grf:
+$ref: /schemas/types.yaml#/definitions/phandle
+description:
+  Phandle to VOP GRF regs used for misc control, required for rk3588
+
+  rockchip,pmu:
+$ref: /schemas/types.yaml#/definitions/phandle
+description:
+  Phandle to PMU regs used for misc control, required for rk3588
+
ports:
  $ref: /schemas/graph.yaml#/properties/ports
  
@@ -81,6 +101,11 @@ properties:

  description:
Output endpoint of VP2
  
+  port@3:

+$ref: /schemas/graph.yaml#/properties/port
+description:
+  Output endpoint of VP3
+
iommus:
  maxItems: 1
  







Re: [PATCH 09/11] drm/rockchip: vop2: Add support for rk3588

2023-11-14 Thread Andy Yan

Hi Heiko:

On 11/15/23 07:34, Heiko Stübner wrote:

Hi Andy,

Am Dienstag, 14. November 2023, 12:28:55 CET schrieb Andy Yan:

From: Andy Yan 

VOP2 on rk3588:

Four video ports:
VP0 Max 4096x2160
VP1 Max 4096x2160
VP2 Max 4096x2160
VP3 Max 2048x1080

4 4K Cluster windows with AFBC/line RGB and AFBC-only YUV support
4 4K Esmart windows with line RGB/YUV support

Signed-off-by: Andy Yan 

not a review yet, but when testing and the display sets a mode,
I always get a bunch of

rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at 
vp0

messages in the log (initial mode to console, starting glmark2 from console,
stopping glmark2 to the console).

I'm not sure what is up with that, have you seen these messages as well
at some point?


Yes, it will raise POST_BUF_EMPTY when set a mode,  it needs some fix 
like [0]:



I still trying to find a appropriate way to do it with the upstream 
code, as it doesn't affect the


real display function(I must admit that the POST_BUF_EMPTY irq is very 
annoying), so l let  it as


it is in the current version.

By the way, can you see the glmark2 rending on your HDMI monitor now?

[0]https://github.com/Fruit-Pi/kernel/commit/29af993b46f024360e6d02c0d26c9fd3057aa918



Thanks
Heiko





Re: [PATCH v1] drm/virtio: Fix return value for VIRTGPU_CONTEXT_PARAM_DEBUG_NAME

2023-11-14 Thread Dmitry Osipenko
On 11/12/23 01:42, Dmitry Osipenko wrote:
> The strncpy_from_user() returns number of copied bytes and not zero on
> success. The non-zero return value of ioctl is treated as error. Return
> zero on success instead of the number of copied bytes.
> 
> Fixes: 7add80126bce ("drm/uapi: add explicit virtgpu context debug name")
> Signed-off-by: Dmitry Osipenko 
> ---
>  drivers/gpu/drm/virtio/virtgpu_ioctl.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c 
> b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> index 1e2042419f95..e4f76f315550 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> @@ -665,6 +665,7 @@ static int virtio_gpu_context_init_ioctl(struct 
> drm_device *dev,
>   goto out_unlock;
>  
>   vfpriv->explicit_debug_name = true;
> + ret = 0;
>   break;
>   default:
>   ret = -EINVAL;

Applied to misc-next

-- 
Best regards,
Dmitry



Re: [PATCH] drm/sched: Define pr_fmt() for DRM using pr_*()

2023-11-14 Thread Luben Tuikov
On 2023-11-14 07:20, Jani Nikula wrote:
> On Mon, 13 Nov 2023, Luben Tuikov  wrote:
>> Hi Jani,
>>
>> On 2023-11-10 07:40, Jani Nikula wrote:
>>> On Thu, 09 Nov 2023, Luben Tuikov  wrote:
 Define pr_fmt() as "[drm] " for DRM code using pr_*() facilities, 
 especially
 when no devices are available. This makes it easier to browse kernel logs.
>>>
>>> Please do not merge patches before people have actually had a chance to
>>> look at them. This was merged *way* too quickly.
>>>
>>> This does not do what you think it does, and it's not robust enough.
>>>
>>> The drm_print.[ch] facilities use very few pr_*() calls directly. The
>>> users of pr_*() calls do not necessarily include  at
>>> all, and really don't have to.
>>>
>>> Even the ones that do include it, usually have  includes
>>> first, and  includes next. Notably,  includes
>>> .
>>>
>>> And, of course,  defines pr_fmt() itself if not already
>>> defined.
>>>
 Signed-off-by: Luben Tuikov 
 ---
  include/drm/drm_print.h | 14 ++
  1 file changed, 14 insertions(+)

 diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
 index a93a387f8a1a15..e8fe60d0eb8783 100644
 --- a/include/drm/drm_print.h
 +++ b/include/drm/drm_print.h
 @@ -26,6 +26,20 @@
  #ifndef DRM_PRINT_H_
  #define DRM_PRINT_H_
  
 +/* Define this before including linux/printk.h, so that the format
 + * string in pr_*() macros is correctly set for DRM. If a file wants
 + * to define this to something else, it should do so before including
 + * this header file.
>>>
>>> The only way this would work is by including  as the
>>> very first header, and that's fragile at best.
>>>
 + *
 + * It is encouraged code using pr_err() to prefix their format with
 + * the string "*ERROR* ", to make it easier to scan kernel logs. For
 + * instance,
 + *   pr_err("*ERROR* ", args).
>>>
>>> No, it's encouraged not to use pr_*() at all, and prefer drm device
>>> based logging, or device based logging.
>>>
>>> I'd rather this whole thing was just reverted.
>>
>> The revert has been pushed--thanks for R-B-ing it.
>>
>> FWIW, I wanted a device-less DRM print, with a prefix "[drm] *ERROR* ",
>> because this is what we scan for, especially when we get a blank screen at 
>> boot/modprobe.
>> There's a few cases in DRM where when we return -E... it's most likely a 
>> blank screen result,
>> as was the case with a recent debug I had with amdgpu when pushing the 
>> variable sched->rq.
>>
>> So then I went by this, in linux/printk.h:
>>
>> /**
>>  * pr_fmt - used by the pr_*() macros to generate the printk format string
>>  * @fmt: format string passed from a pr_*() macro
>>  *
>>  * This macro can be used to generate a unified format string for pr_*()
>>  * macros. A common use is to prefix all pr_*() messages in a file with a 
>> common
>>  * string. For example, defining this at the top of a source file:
>>  *
>>  *#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>>  *
>>  * would prefix all pr_info, pr_emerg... messages in the file with the module
>>  * name.
>>  */
>> #ifndef pr_fmt
>> #define pr_fmt(fmt) fmt
>> #endif
>>
>> Any suggestions as to a device-less DRM print with prefix "[drm] *ERROR* "?
> 
> I don't think there's a way to do that using pr_fmt for an entire driver
> or subsystem. That really only works for individual compilation units.
> 
> We have DRM_ERROR() which does the trick, but the documentation says
> it's been deprecated in favor pr_err()... though I think drm_err()
> should be preferred over pr_err() where possible.

Yes, that's what made me use pr_err() and the pr_fmt() modification...

> 
> Maybe we should extend 7911902129a8 ("drm/print: Handle potentially NULL
> drm_devices in drm_dbg_*") to __drm_printk() and handle NULL drm device
> gracefully.

Yeah, that actually would work.

> 
> With just "(drm) ? (drm)->dev : NULL" the output will have "(NULL device
> *)" which works but is a bit meh, but maybe something like this is
> possible (untested):

So, I don't mind the ternary op, really. So long as we get the "*ERROR* ",
on drm_err(), because it really helps us debug when we get a blank screen. :-)

> diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
> index a93a387f8a1a..d16affece5b7 100644
> --- a/include/drm/drm_print.h
> +++ b/include/drm/drm_print.h
> @@ -452,9 +452,13 @@ void __drm_dev_dbg(struct _ddebug *desc, const struct 
> device *dev,
>   */
>  
>  /* Helper for struct drm_device based logging. */
> -#define __drm_printk(drm, level, type, fmt, ...) \
> - dev_##level##type((drm)->dev, "[drm] " fmt, ##__VA_ARGS__)
> -
> +#define __drm_printk(drm, level, type, fmt, ...) \
> + do {\
> + if (drm)\
> + dev_##level##type((drm)->dev, "[drm] " fmt, 
> ##__VA_ARGS__); \
> + 

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

2023-11-14 Thread Luben Tuikov
On 2023-11-13 22:08, Stephen Rothwell wrote:
> Hi Luben,
> 
> BTW, cherry picking commits does not avoid conflicts - in fact it can
> cause conflicts if there are further changes to the files affected by
> the cherry picked commit in either the tree/branch the commit was
> cheery picked from or the destination tree/branch (I have to deal with
> these all the time when merging the drm trees in linux-next).  Much
> better is to cross merge the branches so that the patch only appears
> once or have a shared branches that are merged by any other branch that
> needs the changes.
> 
> I understand that things are not done like this in the drm trees :-(

Hi Stephen,

Thank you for the clarification--understood. I'll be more careful in the future.
Thanks again! :-)
-- 
Regards,
Luben


OpenPGP_0x4C15479431A334AF.asc
Description: OpenPGP public key


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH 09/11] drm/rockchip: vop2: Add support for rk3588

2023-11-14 Thread Heiko Stübner
Hi Andy,

Am Dienstag, 14. November 2023, 12:28:55 CET schrieb Andy Yan:
> From: Andy Yan 
> 
> VOP2 on rk3588:
> 
> Four video ports:
> VP0 Max 4096x2160
> VP1 Max 4096x2160
> VP2 Max 4096x2160
> VP3 Max 2048x1080
> 
> 4 4K Cluster windows with AFBC/line RGB and AFBC-only YUV support
> 4 4K Esmart windows with line RGB/YUV support
> 
> Signed-off-by: Andy Yan 

not a review yet, but when testing and the display sets a mode,
I always get a bunch of

rockchip-drm display-subsystem: [drm] *ERROR* POST_BUF_EMPTY irq err at 
vp0

messages in the log (initial mode to console, starting glmark2 from console,
stopping glmark2 to the console).

I'm not sure what is up with that, have you seen these messages as well
at some point?

Thanks
Heiko





[PATCH v2 6/6] drm/msm/dsi: fix DSC for the bonded DSI case

2023-11-14 Thread Jonathan Marek
For the bonded DSI case, DSC pic_width and timing calculations should use
the width of a single panel instead of the total combined width.

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/dsi/dsi.h |  3 ++-
 drivers/gpu/drm/msm/dsi/dsi_host.c| 20 +++-
 drivers/gpu/drm/msm/dsi/dsi_manager.c |  2 +-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 28379b1af63f..3a641e69447c 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -93,7 +93,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host);
 int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host,
  const struct drm_display_mode *mode);
 enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
-   const struct drm_display_mode 
*mode);
+   const struct drm_display_mode *mode,
+   bool is_bonded_dsi);
 unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host);
 int msm_dsi_host_register(struct mipi_dsi_host *host);
 void msm_dsi_host_unregister(struct mipi_dsi_host *host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 892a463a7e03..cf06736e5a60 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -940,8 +940,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, 
bool is_bonded_dsi)
   mode->hdisplay, mode->vdisplay);
return;
}
-
-   dsc->pic_width = mode->hdisplay;
+   dsc->pic_width = hdisplay;
dsc->pic_height = mode->vdisplay;
DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height);
 
@@ -952,6 +951,11 @@ static void dsi_timing_setup(struct msm_dsi_host 
*msm_host, bool is_bonded_dsi)
if (ret)
return;
 
+   if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO)
+   dsi_update_dsc_timing(msm_host, false, hdisplay);
+   else
+   dsi_update_dsc_timing(msm_host, true, hdisplay);
+
/* Divide the display by 3 but keep back/font porch and
 * pulse width same
 */
@@ -968,9 +972,6 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, 
bool is_bonded_dsi)
}
 
if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) {
-   if (msm_host->dsc)
-   dsi_update_dsc_timing(msm_host, false, mode->hdisplay);
-
dsi_write(msm_host, REG_DSI_ACTIVE_H,
DSI_ACTIVE_H_START(ha_start) |
DSI_ACTIVE_H_END(ha_end));
@@ -989,9 +990,6 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, 
bool is_bonded_dsi)
DSI_ACTIVE_VSYNC_VPOS_START(vs_start) |
DSI_ACTIVE_VSYNC_VPOS_END(vs_end));
} else {/* command mode */
-   if (msm_host->dsc)
-   dsi_update_dsc_timing(msm_host, true, mode->hdisplay);
-
/* image data and 1 byte write_memory_start cmd */
if (!msm_host->dsc)
wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1;
@@ -2479,7 +2477,8 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host 
*host,
 }
 
 enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
-   const struct drm_display_mode *mode)
+   const struct drm_display_mode *mode,
+   bool is_bonded_dsi)
 {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
struct drm_dsc_config *dsc = msm_host->dsc;
@@ -2489,6 +2488,9 @@ enum drm_mode_status msm_dsi_host_check_dsc(struct 
mipi_dsi_host *host,
if (!msm_host->dsc)
return MODE_OK;
 
+   if (is_bonded_dsi)
+   pic_width = mode->hdisplay / 2;
+
if (pic_width % dsc->slice_width) {
pr_err("DSI: pic_width %d has to be multiple of slice %d\n",
   pic_width, dsc->slice_width);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c 
b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index 896f369fdd53..2ca1a7ca3659 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -455,7 +455,7 @@ static enum drm_mode_status 
dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge,
return MODE_ERROR;
}
 
-   return msm_dsi_host_check_dsc(host, mode);
+   return msm_dsi_host_check_dsc(host, mode, IS_BONDED_DSI());
 }
 
 static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = {
-- 
2.26.1



[PATCH v2 5/6] drm/msm/dsi: support DSC configurations with slice_per_pkt > 1

2023-11-14 Thread Jonathan Marek
Add a dsc_slice_per_pkt field to mipi_dsi_device struct and the necessary
changes to msm driver to support this field.

Note that the removed "pkt_per_line = slice_per_intf * slice_per_pkt"
comment is incorrect.

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 25 ++---
 include/drm/drm_mipi_dsi.h |  1 +
 2 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 842765063b1b..892a463a7e03 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -161,6 +161,7 @@ struct msm_dsi_host {
 
struct drm_display_mode *mode;
struct drm_dsc_config *dsc;
+   unsigned int dsc_slice_per_pkt;
 
/* connected device info */
unsigned int channel;
@@ -857,17 +858,10 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay);
 
total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
-   bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
+   bytes_per_pkt = dsc->slice_chunk_size * msm_host->dsc_slice_per_pkt;
 
eol_byte_num = total_bytes_per_intf % 3;
-
-   /*
-* Typically, pkt_per_line = slice_per_intf * slice_per_pkt.
-*
-* Since the current driver only supports slice_per_pkt = 1,
-* pkt_per_line will be equal to slice per intf for now.
-*/
-   pkt_per_line = slice_per_intf;
+   pkt_per_line = slice_per_intf / msm_host->dsc_slice_per_pkt;
 
if (is_cmd_mode) /* packet data type */
reg = 
DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE);
@@ -1004,12 +998,8 @@ static void dsi_timing_setup(struct msm_dsi_host 
*msm_host, bool is_bonded_dsi)
else
/*
 * When DSC is enabled, WC = slice_chunk_size * 
slice_per_pkt + 1.
-* Currently, the driver only supports default value of 
slice_per_pkt = 1
-*
-* TODO: Expand mipi_dsi_device struct to hold 
slice_per_pkt info
-*   and adjust DSC math to account for 
slice_per_pkt.
 */
-   wc = msm_host->dsc->slice_chunk_size + 1;
+   wc = msm_host->dsc->slice_chunk_size * 
msm_host->dsc_slice_per_pkt + 1;
 
dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL,
DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) |
@@ -1636,8 +1626,13 @@ static int dsi_host_attach(struct mipi_dsi_host *host,
msm_host->lanes = dsi->lanes;
msm_host->format = dsi->format;
msm_host->mode_flags = dsi->mode_flags;
-   if (dsi->dsc)
+   if (dsi->dsc) {
msm_host->dsc = dsi->dsc;
+   msm_host->dsc_slice_per_pkt = dsi->dsc_slice_per_pkt;
+   /* for backwards compatibility, assume 1 if not set */
+   if (!msm_host->dsc_slice_per_pkt)
+   msm_host->dsc_slice_per_pkt = 1;
+   }
 
/* Some gpios defined in panel DT need to be controlled by host */
ret = dsi_host_init_panel_gpios(msm_host, >dev);
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index c9df0407980c..3e32fa52d94b 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -193,6 +193,7 @@ struct mipi_dsi_device {
unsigned long hs_rate;
unsigned long lp_rate;
struct drm_dsc_config *dsc;
+   unsigned int dsc_slice_per_pkt;
 };
 
 #define MIPI_DSI_MODULE_PREFIX "mipi-dsi:"
-- 
2.26.1



[PATCH v2 4/6] drm/msm/dsi: add a comment to explain pkt_per_line encoding

2023-11-14 Thread Jonathan Marek
Make it clear why the pkt_per_line value is being "divided by 2".

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 66f198e21a7e..842765063b1b 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -877,6 +877,8 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
/* DSI_VIDEO_COMPRESSION_MODE & DSI_COMMAND_COMPRESSION_MODE
 * registers have similar offsets, so for below common code use
 * DSI_VIDEO_COMPRESSION_MODE_ for setting bits
+*
+* pkt_per_line is log2 encoded, >>1 works for supported values (1,2,4)
 */
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_PKT_PER_LINE(pkt_per_line >> 1);
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_EOL_BYTE_NUM(eol_byte_num);
-- 
2.26.1



[PATCH v2 3/6] drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC (fix video mode DSC)

2023-11-14 Thread Jonathan Marek
Video mode DSC won't work if this field is not set correctly. Set it to fix
video mode DSC (for slice_per_pkt==1 cases at least).

Fixes: 08802f515c3 ("drm/msm/dsi: Add support for DSC configuration")
Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index f2c1cbd08d4d..66f198e21a7e 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -849,6 +849,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
u32 slice_per_intf, total_bytes_per_intf;
u32 pkt_per_line;
u32 eol_byte_num;
+   u32 bytes_per_pkt;
 
/* first calculate dsc parameters and then program
 * compress mode registers
@@ -856,6 +857,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay);
 
total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
+   bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
 
eol_byte_num = total_bytes_per_intf % 3;
 
@@ -893,6 +895,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, 
reg_ctrl);
dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, 
reg_ctrl2);
} else {
+   reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_WC(bytes_per_pkt);
dsi_write(msm_host, REG_DSI_VIDEO_COMPRESSION_MODE_CTRL, reg);
}
 }
-- 
2.26.1



[PATCH v2 2/6] drm/msm/dsi: set video mode widebus enable bit when widebus is enabled

2023-11-14 Thread Jonathan Marek
The value returned by msm_dsi_wide_bus_enabled() doesn't match what the
driver is doing in video mode. Fix that by actually enabling widebus for
video mode.

Fixes: efcbd6f9cdeb ("drm/msm/dsi: Enable widebus for DSI")
Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/dsi/dsi.xml.h  | 1 +
 drivers/gpu/drm/msm/dsi/dsi_host.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h 
b/drivers/gpu/drm/msm/dsi/dsi.xml.h
index 2a7d980e12c3..f0b3cdc020a1 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.xml.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h
@@ -231,6 +231,7 @@ static inline uint32_t DSI_VID_CFG0_TRAFFIC_MODE(enum 
dsi_traffic_mode val)
 #define DSI_VID_CFG0_HSA_POWER_STOP0x0001
 #define DSI_VID_CFG0_HBP_POWER_STOP0x0010
 #define DSI_VID_CFG0_HFP_POWER_STOP0x0100
+#define DSI_VID_CFG0_DATABUS_WIDEN 0x0200
 #define DSI_VID_CFG0_PULSE_MODE_HSA_HE 0x1000
 
 #define REG_DSI_VID_CFG1   0x001c
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index deeecdfd6c4e..f2c1cbd08d4d 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -745,6 +745,8 @@ static void dsi_ctrl_enable(struct msm_dsi_host *msm_host,
data |= DSI_VID_CFG0_TRAFFIC_MODE(dsi_get_traffic_mode(flags));
data |= DSI_VID_CFG0_DST_FORMAT(dsi_get_vid_fmt(mipi_fmt));
data |= DSI_VID_CFG0_VIRT_CHANNEL(msm_host->channel);
+   if (msm_dsi_host_is_wide_bus_enabled(_host->base))
+   data |= DSI_VID_CFG0_DATABUS_WIDEN;
dsi_write(msm_host, REG_DSI_VID_CFG0, data);
 
/* Do not swap RGB colors */
-- 
2.26.1



[PATCH v2 1/6] drm/msm/dpu: fix video mode DSC for DSI

2023-11-14 Thread Jonathan Marek
Add necessary DPU changes for DSC to work with DSI video mode.

Note this changes the logic to enable HCTL to match downstream, it will
now be enabled for the no-DSC no-widebus case.

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h|  2 +-
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c| 11 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 13 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h |  1 +
 5 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 1cf7ff6caff4..d745c8678b9d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2477,7 +2477,7 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct 
drm_encoder *encoder)
return INTF_MODE_NONE;
 }
 
-unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc)
+unsigned int dpu_encoder_helper_get_dsc(const struct dpu_encoder_phys 
*phys_enc)
 {
struct drm_encoder *encoder = phys_enc->parent;
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index 6f04c3d56e77..7e27a7da0887 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -332,7 +332,7 @@ static inline enum dpu_3d_blend_mode 
dpu_encoder_helper_get_3d_blend_mode(
  *   used for this encoder.
  * @phys_enc: Pointer to physical encoder structure
  */
-unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc);
+unsigned int dpu_encoder_helper_get_dsc(const struct dpu_encoder_phys 
*phys_enc);
 
 /**
  * dpu_encoder_helper_split_config - split display configuration helper 
function
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index a01fda711883..df10800a9615 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -100,6 +100,8 @@ static void drm_mode_to_intf_timing_params(
}
 
timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent);
+   if (dpu_encoder_helper_get_dsc(phys_enc))
+   timing->compression_en = true;
 
/*
 * for DP, divide the horizonal parameters by 2 when
@@ -112,6 +114,15 @@ static void drm_mode_to_intf_timing_params(
timing->h_front_porch = timing->h_front_porch >> 1;
timing->hsync_pulse_width = timing->hsync_pulse_width >> 1;
}
+
+   /*
+* for DSI, if compression is enabled, then divide the horizonal active
+* timing parameters by compression ratio.
+*/
+   if (phys_enc->hw_intf->cap->type != INTF_DP && timing->compression_en) {
+   timing->width = timing->width / 3; /* XXX: don't assume 3:1 
compression ratio */
+   timing->xres = timing->width;
+   }
 }
 
 static u32 get_horizontal_total(const struct dpu_hw_intf_timing_params *timing)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
index e8b8908d3e12..d6fe45a6da2d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -166,10 +166,21 @@ static void dpu_hw_intf_setup_timing_engine(struct 
dpu_hw_intf *ctx,
 * video timing. It is recommended to enable it for all cases, except
 * if compression is enabled in 1 pixel per clock mode
 */
+   if (!p->compression_en || p->wide_bus_en)
+   intf_cfg2 |= INTF_CFG2_DATA_HCTL_EN;
+
if (p->wide_bus_en)
-   intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN | INTF_CFG2_DATA_HCTL_EN;
+   intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN;
 
data_width = p->width;
+   if (p->wide_bus_en && !dp_intf)
+   data_width = p->width >> 1;
+
+   if (p->compression_en)
+   intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS;
+
+   if (p->compression_en && dp_intf)
+   DPU_ERROR("missing adjustments for DSC+DP\n");
 
hsync_data_start_x = hsync_start_x;
hsync_data_end_x =  hsync_start_x + data_width - 1;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
index c539025c418b..15a5fdadd0a0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
@@ -33,6 +33,7 @@ struct dpu_hw_intf_timing_params {
u32 hsync_skew;
 
bool wide_bus_en;
+   bool compression_en;
 };
 
 struct dpu_hw_intf_prog_fetch {
-- 
2.26.1



[PATCH v2 0/6] drm/msm: DSI DSC video mode fixes

2023-11-14 Thread Jonathan Marek
v2: added new patches (first two patches) to get DSC video mode running with
the upstream DPU driver (tested with the vtdr6130 panel)

Jonathan Marek (6):
  drm/msm/dpu: fix video mode DSC for DSI
  drm/msm/dsi: set video mode widebus enable bit when widebus is enabled
  drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC (fix video mode DSC)
  drm/msm/dsi: add a comment to explain pkt_per_line encoding
  drm/msm/dsi: support DSC configurations with slice_per_pkt > 1
  drm/msm/dsi: fix DSC for the bonded DSI case

 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  2 +-
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |  2 +-
 .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c  | 11 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c   | 13 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h   |  1 +
 drivers/gpu/drm/msm/dsi/dsi.h |  3 +-
 drivers/gpu/drm/msm/dsi/dsi.xml.h |  1 +
 drivers/gpu/drm/msm/dsi/dsi_host.c| 50 ++-
 drivers/gpu/drm/msm/dsi/dsi_manager.c |  2 +-
 include/drm/drm_mipi_dsi.h|  1 +
 10 files changed, 58 insertions(+), 28 deletions(-)

-- 
2.26.1



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

2023-11-14 Thread Linus Walleij
On Mon, Aug 7, 2023 at 8:06 AM Liu Ying  wrote:

> Add the device link when panel bridge is attached and delete the link
> when panel bridge is detached.  The drm device is the consumer while
> the panel device is the supplier.  This makes sure that the drm device
> suspends eariler and resumes later than the panel device, hence resolves
> problems where the order is reversed, like the problematic case mentioned
> in the below link.
>
> Link: 
> https://lore.kernel.org/lkml/capdykfr0xjru_udkoukq_q8rwaukyql+8fv-7s1ctmqi7u3...@mail.gmail.com/T/
> Suggested-by: Ulf Hansson 
> Signed-off-by: Liu Ying 
> ---
> v2->v3:
> * Improve commit message s/swapped/reversed/.

This patch causes a regression in the Ux500 MCDE
drivers/gpu/drm/mcde/* driver with the nt35510 panel
drivers/gpu/drm/panel/panel-novatek-nt35510.c
my dmesg looks like this:

[1.678680] mcde a035.mcde: MCDE clk rate 19968 Hz
[1.684448] mcde a035.mcde: found MCDE HW revision 3.0 (dev 8,
metal fix 0)
[1.692840] mcde-dsi a0351000.dsi: HW revision 0x02327457
[1.699310] mcde-dsi a0351000.dsi: attached DSI device with 2 lanes
[1.705627] mcde-dsi a0351000.dsi: format , 24bpp
[1.711059] mcde-dsi a0351000.dsi: mode flags: 0400
[1.716400] mcde-dsi a0351000.dsi: registered DSI host
[1.722473] mcde-dsi a0352000.dsi: HW revision 0x02327457
[1.727874] mcde-dsi a0352000.dsi: registered DSI host
[1.733734] mcde-dsi a0353000.dsi: HW revision 0x02327457
[1.739135] mcde-dsi a0353000.dsi: registered DSI host
[1.814971] mcde-dsi a0351000.dsi: connected to panel
[1.820037] mcde-dsi a0351000.dsi: initialized MCDE DSI bridge
[1.825958] mcde a035.mcde: bound a0351000.dsi (ops
mcde_dsi_component_ops)
[1.833312] mcde-dsi a0352000.dsi: unused DSI interface
[1.838531] mcde a035.mcde: bound a0352000.dsi (ops
mcde_dsi_component_ops)
[1.845886] mcde-dsi a0353000.dsi: unused DSI interface
[1.851135] mcde a035.mcde: bound a0353000.dsi (ops
mcde_dsi_component_ops)
[1.858917] [drm:panel_bridge_attach] *ERROR* Failed to add device
link between a035.mcde and a0351000.dsi.0
[1.869171] [drm:drm_bridge_attach] *ERROR* failed to attach bridge
/soc/mcde@a035/dsi@a0351000/panel to encoder None-34: -22
[1.880920] [drm:drm_bridge_attach] *ERROR* failed to attach bridge
/soc/mcde@a035/dsi@a0351000 to encoder None-34: -22
[1.892120] mcde a035.mcde: failed to attach display output bridge
[1.898773] mcde a035.mcde: adev bind failed: -22
[1.903991] mcde a035.mcde: failed to add component master
[1.909912] mcde: probe of a035.mcde failed with error -22
[1.916656] [ cut here ]
[1.921295] WARNING: CPU: 1 PID: 1 at drivers/regulator/core.c:2996
_regulator_disable+0x130/0x190
[1.930297] unbalanced disables for AUX6
[1.934265] Modules linked in:
[1.937347] CPU: 1 PID: 1 Comm: swapper/0 Not tainted
6.6.0-08649-g7d461b291e65 #3
[1.944915] Hardware name: ST-Ericsson Ux5x0 platform (Device Tree Support)
[1.951873]  unwind_backtrace from show_stack+0x10/0x14
[1.957122]  show_stack from dump_stack_lvl+0x40/0x4c
[1.962188]  dump_stack_lvl from __warn+0x84/0xc8
[1.966918]  __warn from warn_slowpath_fmt+0x124/0x190
[1.972076]  warn_slowpath_fmt from _regulator_disable+0x130/0x190
[1.978271]  _regulator_disable from regulator_bulk_disable+0x5c/0x100
[1.984802]  regulator_bulk_disable from nt35510_remove+0x1c/0x58
[1.990905]  nt35510_remove from mipi_dsi_drv_remove+0x18/0x20
[1.996765]  mipi_dsi_drv_remove from
device_release_driver_internal+0x184/0x1f8
[2.004180]  device_release_driver_internal from bus_remove_device+0xc0/0xe4
[2.011230]  bus_remove_device from device_del+0x14c/0x464
[2.016723]  device_del from device_unregister+0xc/0x20
[2.021972]  device_unregister from mipi_dsi_remove_device_fn+0x34/0x3c
[2.028594]  mipi_dsi_remove_device_fn from device_for_each_child+0x64/0xa4
[2.035583]  device_for_each_child from mipi_dsi_host_unregister+0x24/0x50
[2.042480]  mipi_dsi_host_unregister from platform_remove+0x20/0x5c
[2.048858]  platform_remove from device_release_driver_internal+0x184/0x1f8
[2.055908]  device_release_driver_internal from bus_remove_device+0xc0/0xe4
[2.062957]  bus_remove_device from device_del+0x14c/0x464
[2.068450]  device_del from platform_device_del.part.0+0x10/0x74
[2.074554]  platform_device_del.part.0 from
platform_device_unregister+0x18/0x24
[2.082061]  platform_device_unregister from
of_platform_device_destroy+0x9c/0xac
[2.089569]  of_platform_device_destroy from
device_for_each_child_reverse+0x78/0xbc
[2.097320]  device_for_each_child_reverse from
devm_of_platform_populate_release+0x34/0x48
[2.105682]  devm_of_platform_populate_release from
devres_release_all+0x94/0xf8
[2.113098]  devres_release_all from device_unbind_cleanup+0xc/0x60
[2.119384]  device_unbind_cleanup 

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

2023-11-14 Thread Heiko Stübner
Am Dienstag, 14. November 2023, 12:28:41 CET schrieb Andy Yan:
> From: Andy Yan 
> 
> The vop2 on rk3588 is similar to which on rk356x
> but with 4 video outputs and need to reference
> more grf modules.
> 
> Signed-off-by: Andy Yan 
> ---
> 
>  .../display/rockchip/rockchip-vop2.yaml   | 25 +++
>  1 file changed, 25 insertions(+)
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml 
> b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
> index b60b90472d42..c333c651da1a 100644
> --- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
> +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
> @@ -20,6 +20,7 @@ properties:
>  enum:
>- rockchip,rk3566-vop
>- rockchip,rk3568-vop
> +  - rockchip,rk3588-vop
>  
>reg:
>  items:
> @@ -48,6 +49,8 @@ properties:
>- description: Pixel clock for video port 0.
>- description: Pixel clock for video port 1.
>- description: Pixel clock for video port 2.
> +  - description: Pixel clock for video port 4.
> +  - description: Peripheral clock for vop on rk3588.
>  
>clock-names:
>  items:
> @@ -56,12 +59,29 @@ properties:
>- const: dclk_vp0
>- const: dclk_vp1
>- const: dclk_vp2
> +  - const: dclk_vp3
> +  - const: pclk_vop

with the error Rob's bot reported, I guess both clocks and clock-names
need a minItems element to mark these new clocks essentially as optional?


>rockchip,grf:
>  $ref: /schemas/types.yaml#/definitions/phandle
>  description:
>Phandle to GRF regs used for misc control
>  
> +  rockchip,vo-grf:
> +$ref: /schemas/types.yaml#/definitions/phandle
> +description:
> +  Phandle to VO GRF regs used for misc control, required for rk3588
> +
> +  rockchip,vop-grf:
> +$ref: /schemas/types.yaml#/definitions/phandle
> +description:
> +  Phandle to VOP GRF regs used for misc control, required for rk3588
> +
> +  rockchip,pmu:
> +$ref: /schemas/types.yaml#/definitions/phandle
> +description:
> +  Phandle to PMU regs used for misc control, required for rk3588
> +
>ports:
>  $ref: /schemas/graph.yaml#/properties/ports
>  
> @@ -81,6 +101,11 @@ properties:
>  description:
>Output endpoint of VP2
>  
> +  port@3:
> +$ref: /schemas/graph.yaml#/properties/port
> +description:
> +  Output endpoint of VP3
> +
>iommus:
>  maxItems: 1
>  
> 






Re: [PATCH] nouveau/gsp/r535: Fix a NULL vs error pointer bug

2023-11-14 Thread Danilo Krummrich

On 11/8/23 08:40, Dan Carpenter wrote:

The r535_gsp_cmdq_get() function returns error pointers but this code
checks for NULL.  Also we need to propagate the error pointer back to
the callers in r535_gsp_rpc_get().  Returning NULL will lead to a NULL
pointer dereference.

Fixes: 176fdcbddfd2 ("drm/nouveau/gsp/r535: add support for booting GSP-RM")
Signed-off-by: Dan Carpenter 


Reviewed-by: Danilo Krummrich 


---
  drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
index e31f9641114b..f8409e2f9fef 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
@@ -689,8 +689,8 @@ r535_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 argc)
struct nvfw_gsp_rpc *rpc;
  
  	rpc = r535_gsp_cmdq_get(gsp, ALIGN(sizeof(*rpc) + argc, sizeof(u64)));

-   if (!rpc)
-   return NULL;
+   if (IS_ERR(rpc))
+   return ERR_CAST(rpc);
  
  	rpc->header_version = 0x0300;

rpc->signature = ('C' << 24) | ('P' << 16) | ('R' << 8) | 'V';




Re: [PATCH v1 1/1] drm/i915/gt: Dont wait forever when idling in suspend

2023-11-14 Thread Teres Alexis, Alan Previn
On Tue, 2023-11-14 at 08:22 -0800, Teres Alexis, Alan Previn wrote:
> When suspending, add a timeout when calling
> intel_gt_pm_wait_for_idle else if we have a leaked
> wakeref (which would be indicative of a bug elsewhere
> in the driver), driver will at exit the suspend-resume
> cycle, after the kernel detects the held reference and
> prints a message to abort suspending instead of hanging
> in the kernel forever which then requires serial connection
> or ramoops dump to debug further.
NOTE: this patch originates from Patch#3 of this other series
https://patchwork.freedesktop.org/series/121916/ (rev 5 and prior)
and was decided to be moved out as its own patch since this
patch is trying to improve general debuggability as opposed
to resolving that bug being resolved in above series.
alan:snip

> +int intel_wakeref_wait_for_idle(struct intel_wakeref *wf, int timeout_ms)
>  {
> - int err;
> + int err = 0;
>  
>   might_sleep();
>  
> - err = wait_var_event_killable(>wakeref,
> -   !intel_wakeref_is_active(wf));
> + if (!timeout_ms)
> + err = wait_var_event_killable(>wakeref,
> +   !intel_wakeref_is_active(wf));
> + else if (wait_var_event_timeout(>wakeref,
> + !intel_wakeref_is_active(wf),
> + msecs_to_jiffies(timeout_ms)) < 1)
> + err = -ETIMEDOUT;
> +
alan: paraphrasing feedback from Tvrtko on the originating series this patch:
it would be good idea to add error-injection into this timeout to ensure
we dont have any other subsytem that could inadvertently leak an rpm
wakeref (and catch such bugs in future pre-merge).




Re: [PATCH v2] drm/amd/display: fix NULL dereference

2023-11-14 Thread Hamza Mahfooz

On 11/14/23 10:27, José Pekkarinen wrote:

The following patch will fix a minor issue where a debug message is
referencing an struct that has just being checked whether is null or
not. This has been noticed by using coccinelle, in the following output:

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c:540:25-29: ERROR: 
aconnector is NULL but dereferenced.

Fixes: 5d72e247e58c9 ("drm/amd/display: switch DC over to the new DRM logging 
macros")


You only need the first 12 characters of the hash here. I have fixed it
for you and applied the patch in this case. But, in the future please
test your patches against `./scripts/checkpatch.pl` before submitting
them.


Signed-off-by: José Pekkarinen 
---
[v1 -> v2]: Remove the debugging message, requested by Hamza

  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 5 +
  1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index ed784cf27d39..c7a29bb737e2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -536,11 +536,8 @@ bool dm_helpers_dp_read_dpcd(
  
  	struct amdgpu_dm_connector *aconnector = link->priv;
  
-	if (!aconnector) {

-   drm_dbg_dp(aconnector->base.dev,
-  "Failed to find connector for link!\n");
+   if (!aconnector)
return false;
-   }
  
  	return drm_dp_dpcd_read(>dm_dp_aux.aux, address, data,

size) == size;

--
Hamza



[PATCH v3 5/7] PCI: ACPI: Detect PCIe root ports that are used for tunneling

2023-11-14 Thread Mario Limonciello
USB4 routers support a feature called "PCIe tunneling". This
allows PCIe traffic to be transmitted over USB4 fabric.

PCIe root ports that are used in this fashion can be discovered
by device specific data that specifies the USB4 router they are
connected to. For the PCI core, the specific connection information
doesn't matter, but it's interesting to know that this root port is
used for tunneling traffic. This will allow other decisions to be
made based upon it.

Detect the `usb4-host-interface` _DSD and if it's found save it
into a new `is_virtual_link` bit in `struct pci_device`.

Link: https://www.usb.org/document-library/usb4r-specification-v20
  USB4 V2 with Errata and ECN through June 2023
  Section 2.2.10.3
Link: 
https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/usb4-acpi-requirements#port-mapping-_dsd-for-usb-3x-and-pcie
Signed-off-by: Mario Limonciello 
---
v2->v3:
 * Use is_virtual_link to be future proof to other types of virtual
   links.
 * Update commit message
---
 drivers/pci/pci-acpi.c | 16 
 include/linux/pci.h|  1 +
 2 files changed, 17 insertions(+)

diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 004575091596..4a94d2fd8fb9 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -1415,12 +1415,28 @@ static void pci_acpi_set_external_facing(struct pci_dev 
*dev)
dev->external_facing = 1;
 }
 
+static void pci_acpi_set_virtual_link(struct pci_dev *dev)
+{
+   if (!pci_is_pcie(dev))
+   return;
+
+   switch (pci_pcie_type(dev)) {
+   case PCI_EXP_TYPE_ROOT_PORT:
+   case PCI_EXP_TYPE_DOWNSTREAM:
+   dev->is_virtual_link = device_property_present(>dev, 
"usb4-host-interface");
+   break;
+   default:
+   return;
+   }
+}
+
 void pci_acpi_setup(struct device *dev, struct acpi_device *adev)
 {
struct pci_dev *pci_dev = to_pci_dev(dev);
 
pci_acpi_optimize_delay(pci_dev, adev->handle);
pci_acpi_set_external_facing(pci_dev);
+   pci_acpi_set_virtual_link(pci_dev);
pci_acpi_add_edr_notifier(pci_dev);
 
pci_acpi_add_pm_notifier(adev, pci_dev);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 20a6e4fc3060..83fbd0d7040e 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -441,6 +441,7 @@ struct pci_dev {
unsigned intis_hotplug_bridge:1;
unsigned intshpc_managed:1; /* SHPC owned by shpchp */
unsigned intis_thunderbolt:1;   /* Thunderbolt controller */
+   unsigned intis_virtual_link:1;  /* Tunneled (virtual) PCIe link 
*/
unsigned intno_command_complete:1;  /* No command completion */
/*
 * Devices marked being untrusted are the ones that can potentially
-- 
2.34.1



[PATCH v3 7/7] PCI: Exclude PCIe ports used for virtual links in pcie_bandwidth_available()

2023-11-14 Thread Mario Limonciello
The USB4 spec specifies that PCIe ports that are used for tunneling
PCIe traffic over USB4 fabric will be hardcoded to advertise 2.5GT/s and
behave as a PCIe Gen1 device. The actual performance of these ports is
controlled by the fabric implementation.

Callers for pcie_bandwidth_available() will always find the PCIe ports
used for tunneling as a limiting factor potentially leading to incorrect
performance decisions.

To prevent such problems check explicitly for ports that are marked as
virtual links or as thunderbolt controllers and skip them when looking
for bandwidth limitations of the hierarchy. If the only device connected
is a port used for tunneling then report that device.

Callers to pcie_bandwidth_available() could make this change on their
own as well but then they wouldn't be able to detect other potential
speed bottlenecks from the hierarchy without duplicating
pcie_bandwidth_available() logic.

Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2925#note_2145860
Link: https://www.usb.org/document-library/usb4r-specification-v20
  USB4 V2 with Errata and ECN through June 2023
  Section 11.2.1
Signed-off-by: Mario Limonciello 
---
v2->v3:
 * Split from previous patch version
 * Look for thunderbolt or virtual link
---
 drivers/pci/pci.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 0ff7883cc774..b1fb2258b211 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -6269,11 +6269,20 @@ static u32 pcie_calc_bw_limits(struct pci_dev *dev, u32 
bw,
  * limiting_dev, speed, and width pointers are supplied) information about
  * that point.  The bandwidth returned is in Mb/s, i.e., megabits/second of
  * raw bandwidth.
+ *
+ * This excludes the bandwidth calculation that has been returned from a
+ * PCIe device that is used for transmitting tunneled PCIe traffic over a 
virtual
+ * link part of larger hierarchy. Examples include Thunderbolt3 and USB4 links.
+ * The calculation is excluded because the USB4 specification specifies that 
the
+ * max speed returned from PCIe configuration registers for the tunneling link 
is
+ * always PCI 1x 2.5 GT/s.  When only tunneled devices are present, the 
bandwidth
+ * returned is the bandwidth available from the first tunneled device.
  */
 u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev 
**limiting_dev,
 enum pci_bus_speed *speed,
 enum pcie_link_width *width)
 {
+   struct pci_dev *vdev = NULL;
u32 bw = 0;
 
if (speed)
@@ -6282,10 +6291,20 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, 
struct pci_dev **limiting_dev,
*width = PCIE_LNK_WIDTH_UNKNOWN;
 
while (dev) {
+   if (dev->is_virtual_link || dev->is_thunderbolt) {
+   if (!vdev)
+   vdev = dev;
+   goto skip;
+   }
bw = pcie_calc_bw_limits(dev, bw, limiting_dev, speed, width);
+skip:
dev = pci_upstream_bridge(dev);
}
 
+   /* If nothing "faster" found on hierarchy, limit to first virtual link 
*/
+   if (vdev && !bw)
+   bw = pcie_calc_bw_limits(vdev, bw, limiting_dev, speed, width);
+
return bw;
 }
 EXPORT_SYMBOL(pcie_bandwidth_available);
-- 
2.34.1



[PATCH v3 6/7] PCI: Split up some logic in pcie_bandwidth_available() to separate function

2023-11-14 Thread Mario Limonciello
The logic to calculate bandwidth limits may be used at multiple call sites
so split it up into its own static function instead.

No intended functional changes.

Suggested-by: Ilpo Järvinen 
Signed-off-by: Mario Limonciello 
---
v2->v3:
 * Split from previous patch version
---
 drivers/pci/pci.c | 60 +++
 1 file changed, 34 insertions(+), 26 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 55bc3576a985..0ff7883cc774 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -6224,6 +6224,38 @@ int pcie_set_mps(struct pci_dev *dev, int mps)
 }
 EXPORT_SYMBOL(pcie_set_mps);
 
+static u32 pcie_calc_bw_limits(struct pci_dev *dev, u32 bw,
+  struct pci_dev **limiting_dev,
+  enum pci_bus_speed *speed,
+  enum pcie_link_width *width)
+{
+   enum pcie_link_width next_width;
+   enum pci_bus_speed next_speed;
+   u32 next_bw;
+   u16 lnksta;
+
+   pcie_capability_read_word(dev, PCI_EXP_LNKSTA, );
+
+   next_speed = pcie_link_speed[FIELD_GET(PCI_EXP_LNKSTA_CLS, lnksta)];
+   next_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, lnksta);
+
+   next_bw = next_width * PCIE_SPEED2MBS_ENC(next_speed);
+
+   /* Check if current device limits the total bandwidth */
+   if (!bw || next_bw <= bw) {
+   bw = next_bw;
+
+   if (limiting_dev)
+   *limiting_dev = dev;
+   if (speed)
+   *speed = next_speed;
+   if (width)
+   *width = next_width;
+   }
+
+   return bw;
+}
+
 /**
  * pcie_bandwidth_available - determine minimum link settings of a PCIe
  *   device and its bandwidth limitation
@@ -6242,39 +6274,15 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, 
struct pci_dev **limiting_dev,
 enum pci_bus_speed *speed,
 enum pcie_link_width *width)
 {
-   u16 lnksta;
-   enum pci_bus_speed next_speed;
-   enum pcie_link_width next_width;
-   u32 bw, next_bw;
+   u32 bw = 0;
 
if (speed)
*speed = PCI_SPEED_UNKNOWN;
if (width)
*width = PCIE_LNK_WIDTH_UNKNOWN;
 
-   bw = 0;
-
while (dev) {
-   pcie_capability_read_word(dev, PCI_EXP_LNKSTA, );
-
-   next_speed = pcie_link_speed[FIELD_GET(PCI_EXP_LNKSTA_CLS,
-  lnksta)];
-   next_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, lnksta);
-
-   next_bw = next_width * PCIE_SPEED2MBS_ENC(next_speed);
-
-   /* Check if current device limits the total bandwidth */
-   if (!bw || next_bw <= bw) {
-   bw = next_bw;
-
-   if (limiting_dev)
-   *limiting_dev = dev;
-   if (speed)
-   *speed = next_speed;
-   if (width)
-   *width = next_width;
-   }
-
+   bw = pcie_calc_bw_limits(dev, bw, limiting_dev, speed, width);
dev = pci_upstream_bridge(dev);
}
 
-- 
2.34.1



[PATCH v3 4/7] PCI: pciehp: Move check for is_thunderbolt into a quirk

2023-11-14 Thread Mario Limonciello
commit 493fb50e958c ("PCI: pciehp: Assume NoCompl+ for Thunderbolt
ports") added a check into pciehp code to explicitly set NoCompl+
for all Intel Thunderbolt controllers, including those that don't
need it.

This overloaded the purpose of the `is_thunderbolt` member of
`struct pci_device` because that means that any controller that
identifies as thunderbolt would set NoCompl+ even if it doesn't
suffer this deficiency. As that commit helpfully specifies all the
controllers with the problem, move them into a PCI quirk.

Signed-off-by: Mario Limonciello 
---
v2->v3:
 * Reword commit message
 * Update comments
---
 drivers/pci/hotplug/pciehp_hpc.c |  6 +-
 drivers/pci/quirks.c | 20 
 include/linux/pci.h  |  1 +
 3 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index b1d0a1b3917d..40f7a26fb98f 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -992,11 +992,7 @@ struct controller *pcie_init(struct pcie_device *dev)
if (pdev->hotplug_user_indicators)
slot_cap &= ~(PCI_EXP_SLTCAP_AIP | PCI_EXP_SLTCAP_PIP);
 
-   /*
-* We assume no Thunderbolt controllers support Command Complete events,
-* but some controllers falsely claim they do.
-*/
-   if (pdev->is_thunderbolt)
+   if (pdev->no_command_complete)
slot_cap |= PCI_EXP_SLTCAP_NCCS;
 
ctrl->slot_cap = slot_cap;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index ea476252280a..fa9b82cd7b3b 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3809,6 +3809,26 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PORT_RIDGE,
quirk_thunderbolt_hotplug_msi);
 
+/*
+ * Certain Thunderbolt 1 controllers falsely claim to support Command
+ * Completed events.
+ */
+static void quirk_thunderbolt_command_complete(struct pci_dev *pdev)
+{
+   pdev->no_command_complete = 1;
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LIGHT_RIDGE,
+   quirk_thunderbolt_command_complete);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EAGLE_RIDGE,
+   quirk_thunderbolt_command_complete);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LIGHT_PEAK,
+   quirk_thunderbolt_command_complete);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C,
+   quirk_thunderbolt_command_complete);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_2C,
+   quirk_thunderbolt_command_complete);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PORT_RIDGE,
+   quirk_thunderbolt_command_complete);
 #ifdef CONFIG_ACPI
 /*
  * Apple: Shutdown Cactus Ridge Thunderbolt controller.
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1fbca2bd92e8..20a6e4fc3060 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -441,6 +441,7 @@ struct pci_dev {
unsigned intis_hotplug_bridge:1;
unsigned intshpc_managed:1; /* SHPC owned by shpchp */
unsigned intis_thunderbolt:1;   /* Thunderbolt controller */
+   unsigned intno_command_complete:1;  /* No command completion */
/*
 * Devices marked being untrusted are the ones that can potentially
 * execute DMA attacks and similar. They are typically connected
-- 
2.34.1



[PATCH v3 3/7] PCI: Drop pci_is_thunderbolt_attached()

2023-11-14 Thread Mario Limonciello
All callers have switched to dev_is_removable() for detecting
hotpluggable PCIe devices.

Signed-off-by: Mario Limonciello 
---
v2->v3:
 * No changes
---
 include/linux/pci.h | 22 --
 1 file changed, 22 deletions(-)

diff --git a/include/linux/pci.h b/include/linux/pci.h
index 60ca768bc867..1fbca2bd92e8 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -2645,28 +2645,6 @@ static inline bool pci_ari_enabled(struct pci_bus *bus)
return bus->self && bus->self->ari_enabled;
 }
 
-/**
- * pci_is_thunderbolt_attached - whether device is on a Thunderbolt daisy chain
- * @pdev: PCI device to check
- *
- * Walk upwards from @pdev and check for each encountered bridge if it's part
- * of a Thunderbolt controller.  Reaching the host bridge means @pdev is not
- * Thunderbolt-attached.  (But rather soldered to the mainboard usually.)
- */
-static inline bool pci_is_thunderbolt_attached(struct pci_dev *pdev)
-{
-   struct pci_dev *parent = pdev;
-
-   if (pdev->is_thunderbolt)
-   return true;
-
-   while ((parent = pci_upstream_bridge(parent)))
-   if (parent->is_thunderbolt)
-   return true;
-
-   return false;
-}
-
 #if defined(CONFIG_PCIEPORTBUS) || defined(CONFIG_EEH)
 void pci_uevent_ers(struct pci_dev *pdev, enum  pci_ers_result err_type);
 #endif
-- 
2.34.1



[PATCH v3 2/7] drm/radeon: Switch from pci_is_thunderbolt_attached() to dev_is_removable()

2023-11-14 Thread Mario Limonciello
pci_is_thunderbolt_attached() looks at the hierarchy of the PCIe device
to determine if any bridge along the way has the is_thunderbolt bit set.
This bit will only be set when one of the devices in the hierarchy is an
Intel Thunderbolt device.

However PCIe devices can be connected to USB4 hubs and routers which won't
necessarily set the is_thunderbolt bit. These devices will however be
marked as externally facing which means they are marked removable by
pci_set_removable().

Look whether the device is marked removable to determine it's
connected to a Thunderbolt controller or USB4 router.

Signed-off-by: Mario Limonciello 
---
v2->v3:
 * Update commit message
---
 drivers/gpu/drm/radeon/radeon_device.c | 4 ++--
 drivers/gpu/drm/radeon/radeon_kms.c| 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index afbb3a80c0c6..ba0ca0694d18 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1429,7 +1429,7 @@ int radeon_device_init(struct radeon_device *rdev,
 
if (rdev->flags & RADEON_IS_PX)
runtime = true;
-   if (!pci_is_thunderbolt_attached(rdev->pdev))
+   if (!dev_is_removable(>pdev->dev))
vga_switcheroo_register_client(rdev->pdev,
   _switcheroo_ops, runtime);
if (runtime)
@@ -1519,7 +1519,7 @@ void radeon_device_fini(struct radeon_device *rdev)
radeon_bo_evict_vram(rdev);
radeon_audio_component_fini(rdev);
radeon_fini(rdev);
-   if (!pci_is_thunderbolt_attached(rdev->pdev))
+   if (!dev_is_removable(>pdev->dev))
vga_switcheroo_unregister_client(rdev->pdev);
if (rdev->flags & RADEON_IS_PX)
vga_switcheroo_fini_domain_pm_ops(rdev->dev);
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c 
b/drivers/gpu/drm/radeon/radeon_kms.c
index a16590c6247f..ead912a58ab8 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -138,7 +138,7 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned 
long flags)
if ((radeon_runtime_pm != 0) &&
radeon_has_atpx() &&
((flags & RADEON_IS_IGP) == 0) &&
-   !pci_is_thunderbolt_attached(pdev))
+   !dev_is_removable(>dev))
flags |= RADEON_IS_PX;
 
/* radeon_device_init should report only fatal error
-- 
2.34.1



[PATCH v3 1/7] drm/nouveau: Switch from pci_is_thunderbolt_attached() to dev_is_removable()

2023-11-14 Thread Mario Limonciello
pci_is_thunderbolt_attached() looks at the hierarchy of the PCIe device
to determine if any bridge along the way has the is_thunderbolt bit set.
This bit will only be set when one of the devices in the hierarchy is an
Intel Thunderbolt device.

However PCIe devices can be connected to USB4 hubs and routers which won't
necessarily set the is_thunderbolt bit. These devices will however be
marked as externally facing which means they are marked removable by
pci_set_removable().

Look whether the device is marked removable to determine it's
connected to a Thunderbolt controller or USB4 router.

Signed-off-by: Mario Limonciello 
---
v2->v3:
 * Update commit message
---
 drivers/gpu/drm/nouveau/nouveau_vga.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c 
b/drivers/gpu/drm/nouveau/nouveau_vga.c
index f8bf0ec26844..14215b7ca187 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vga.c
+++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
@@ -94,8 +94,8 @@ nouveau_vga_init(struct nouveau_drm *drm)
 
vga_client_register(pdev, nouveau_vga_set_decode);
 
-   /* don't register Thunderbolt eGPU with vga_switcheroo */
-   if (pci_is_thunderbolt_attached(pdev))
+   /* don't register USB4/Thunderbolt eGPU with vga_switcheroo */
+   if (dev_is_removable(>dev))
return;
 
vga_switcheroo_register_client(pdev, _switcheroo_ops, runtime);
@@ -118,7 +118,7 @@ nouveau_vga_fini(struct nouveau_drm *drm)
 
vga_client_unregister(pdev);
 
-   if (pci_is_thunderbolt_attached(pdev))
+   if (dev_is_removable(>dev))
return;
 
vga_switcheroo_unregister_client(pdev);
-- 
2.34.1



[PATCH v3 0/7] Improvements to pcie_bandwidth_available() for eGPUs

2023-11-14 Thread Mario Limonciello
The wrong values are reported from pcie_bandwidth_available() which
can cause problems for performance of eGPUs.

This series overhauls Thunderbolt related device detection and uses
the changes to change the behavior of pcie_bandwidth_available().

v2->v3:
 * Stop lumping all thunderbolt VSEC and USB4 devices together, introduce
   is_virtual_link instead
 * Drop unnecessary patches

Mario Limonciello (7):
  drm/nouveau: Switch from pci_is_thunderbolt_attached() to
dev_is_removable()
  drm/radeon: Switch from pci_is_thunderbolt_attached() to
dev_is_removable()
  PCI: Drop pci_is_thunderbolt_attached()
  PCI: pciehp: Move check for is_thunderbolt into a quirk
  PCI: ACPI: Detect PCIe root ports that are used for tunneling
  PCI: Split up some logic in pcie_bandwidth_available() to separate
function
  PCI: Exclude PCIe ports used for virtual links in
pcie_bandwidth_available()

 drivers/gpu/drm/nouveau/nouveau_vga.c  |  6 +-
 drivers/gpu/drm/radeon/radeon_device.c |  4 +-
 drivers/gpu/drm/radeon/radeon_kms.c|  2 +-
 drivers/pci/hotplug/pciehp_hpc.c   |  6 +-
 drivers/pci/pci-acpi.c | 16 ++
 drivers/pci/pci.c  | 77 +-
 drivers/pci/quirks.c   | 20 +++
 include/linux/pci.h| 24 +---
 8 files changed, 97 insertions(+), 58 deletions(-)

base-commit: b85ea95d086471afb4ad062012a4d73cd328fa86
-- 
2.34.1



Re: [Nouveau] [PATCH] nouveau: don't fail driver load if no display hw present.

2023-11-14 Thread Danilo Krummrich

On 11/5/23 21:37, Dave Airlie wrote:

From: Dave Airlie 

If we get back ENODEV don't fail load.


Maybe worth to note why this is OK in this case, might not be obvious
to future readers of the code.



Fixes: 15740541e8f0 ("drm/nouveau/devinit/tu102-: prepare for GSP-RM")


Maybe I'm missing something subtle here, but did you maybe pick the wrong
commit here? At a first glance it looks like commit 073bde453635
("drm/nouveau/kms/nv50-: disable dcb parsing") introduced the issue.

- Danilo


Link: https://gitlab.freedesktop.org/drm/nouveau/-/issues/270
Signed-off-by: Dave Airlie 
---
  drivers/gpu/drm/nouveau/nouveau_display.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c 
b/drivers/gpu/drm/nouveau/nouveau_display.c
index d8c92521226d..f28f9a857458 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -726,6 +726,11 @@ nouveau_display_create(struct drm_device *dev)
  
  	if (nouveau_modeset != 2) {

ret = nvif_disp_ctor(>client.device, "kmsDisp", 0, 
>disp);
+   /* no display hw */
+   if (ret == -ENODEV) {
+   ret = 0;
+   goto disp_create_err;
+   }
  
  		if (!ret && (disp->disp.outp_mask || drm->vbios.dcb.entries)) {

nouveau_display_create_properties(dev);


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

2023-11-14 Thread Teres Alexis, Alan Previn
On Tue, 2023-11-14 at 17:52 +, Tvrtko Ursulin wrote:
> On 14/11/2023 17:37, Teres Alexis, Alan Previn wrote:
> > On Tue, 2023-11-14 at 17:27 +, Tvrtko Ursulin wrote:
> > > On 13/11/2023 17:57, Teres Alexis, Alan Previn wrote:
> > > > On Wed, 2023-10-25 at 13:58 +0100, Tvrtko Ursulin wrote:
> > > > > On 04/10/2023 18:59, Teres Alexis, Alan Previn wrote:
> > > > > > On Thu, 2023-09-28 at 13:46 +0100, Tvrtko Ursulin wrote:
> > > > > > > On 27/09/2023 17:36, Teres Alexis, Alan Previn wrote:
> 
alan:snip

> > alan: So i did trace back the gt->wakeref before i posted these patches and
> > see that within these runtime get/put calls, i believe the first 'get' leads
> > to __intel_wakeref_get_first which calls intel_runtime_pm_get via rpm_get
> > helper and eventually executes a pm_runtime_get_sync(rpm->kdev); (hanging 
> > off
> > i915_device). (naturally there is a corresponding mirros for the 
> > '_put_last').
> > So this means the first-get and last-put lets the kernel know. Thats why 
> > when
> > i tested this patch, it did actually cause the suspend to abort from kernel 
> > side
> > and the kernel would print a message indicating i915 was the one that didnt
> > release all refs.
> 
> Ah that would be much better then.
> 
> Do you know if everything gets resumed/restored correctly in that case 
> or we would need some additional work to maybe early exit from callers 
> of wait_for_suspend()?
alan: So assuming we are still discussing about a "potentially new
future leaked-wakeref bug" (i.e. putting aside the fact that
Patch #1 + #2 resolves this specific series' bug), based on the
previous testing we did, after this timeout-bail trigger,
the suspend flow bails and gt/guc operation does actually continue
as normal. However, its been a long time since we tested this so
i am not sure of how accidental-new-future bugs might play to this
assumption especially if some other subsystem that leaked the rpm
wakref but that subsystem did NOT get reset like how GuC is reset
at the end of suspend.

> 
> What I would also ask is to see if something like injecting a probing 
> failure is feasible, so we can have this new timeout exit path 
> constantly/regularly tested in CI.
alan: Thats a good idea. In line with this, i would like to point out that
rev6 of this series has been posted but i removed this Patch #3. However i did
post this Patch #3 as a standalone patch here: 
https://patchwork.freedesktop.org/series/126414/
as i anticipate this patch will truly help with future issue debuggability.

That said, i shall post a review on that patch with your suggestion to add
an injected probe error for the suspend-resume flow and follow up on that one
separately.

> 
> Regards,
> 
> Tvrtko
> 
> > alan: Anyways, i have pulled this patch out of rev6 of this series and 
> > created a
> > separate standalone patch for this patch #3 that we review independently.
> > 



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

2023-11-14 Thread Teres Alexis, Alan Previn
On Tue, 2023-11-14 at 12:36 -0500, Vivi, Rodrigo wrote:
> On Tue, Nov 14, 2023 at 05:27:18PM +, Tvrtko Ursulin wrote:
> > 
> > On 13/11/2023 17:57, Teres Alexis, Alan Previn wrote:
> > > On Wed, 2023-10-25 at 13:58 +0100, Tvrtko Ursulin wrote:
> > > > On 04/10/2023 18:59, Teres Alexis, Alan Previn wrote:
> > > > > On Thu, 2023-09-28 at 13:46 +0100, Tvrtko Ursulin wrote:
> > > > > > On 27/09/2023 17:36, Teres Alexis, Alan Previn wrote:
> 
> That's a good point.
> Well, current code is already bad and buggy on suspend-resume. We could get
> suspend stuck forever without any clue of what happened.
> At least the proposed patch add some gt_warn. But, yes, the right thing
> to do should be entirely abort the suspend in case of timeout, besides the
> gt_warn.
alan: yes - thats was the whole idea for Patch #3. Only after putting such
code did we have much better debuggability on real world production platforms
+ config that may not have serial-port or ramoops-dump by default.

Btw, as per previous comments by Tvrtko - which i agreed with, I have
moved this one single patch into a separate patch on its own.
See here: https://patchwork.freedesktop.org/series/126414/
(I also maintained the RB from you Rodrigo because the patch did not changed).
And yes, the gt_warn is still in place :)


Re: [PATCH 4/4] drm/msm/dsi: fix DSC for the bonded DSI case

2023-11-14 Thread Jonathan Marek

On 11/14/23 1:28 PM, Marijn Suijten wrote:

On what hardware have you been testing this?  Dmitry and I have a stack of
patches to resolve support for Active CTL programming on newer hardware (DPU
5.0+ IIRC), where a single CTL is responsible for programming multiple INTF and
DSC blocks as used in bonded DSI.



I am also using DPU 6+ but I won't be posting patches for DPU to support 
this as I am not using the upstream DPU codebase.



On 2023-11-14 12:42:16, Jonathan Marek wrote:

For the bonded DSI case, DSC pic_width and timing calculations should use
the width of a single panel instead of the total combined width.

Signed-off-by: Jonathan Marek 
---
  drivers/gpu/drm/msm/dsi/dsi.h |  3 ++-
  drivers/gpu/drm/msm/dsi/dsi_host.c| 20 +++-
  drivers/gpu/drm/msm/dsi/dsi_manager.c |  2 +-
  3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 28379b1af63f..3a641e69447c 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -93,7 +93,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host);
  int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host,
  const struct drm_display_mode *mode);
  enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
-   const struct drm_display_mode 
*mode);
+   const struct drm_display_mode *mode,
+   bool is_bonded_dsi);
  unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host);
  int msm_dsi_host_register(struct mipi_dsi_host *host);
  void msm_dsi_host_unregister(struct mipi_dsi_host *host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 7284346ab787..a6286eb9d006 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -938,8 +938,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, 
bool is_bonded_dsi)
   mode->hdisplay, mode->vdisplay);
return;
}
-
-   dsc->pic_width = mode->hdisplay;
+   dsc->pic_width = hdisplay;


In my testing and debugging on CMDmode panels downstream this value/register
was always programmed to the _full_ width of the bonded panel.  Is that maybe
different for video mode?



downstream dual DSI panel timings are specified for a single panel 
("qcom,mdss-dsi-panel-width" is for a single panel, not both panels)



dsc->pic_height = mode->vdisplay;
DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height);
  
@@ -950,6 +949,11 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)

if (ret)
return;
  
+		if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO)

+   dsi_update_dsc_timing(msm_host, false, hdisplay);
+   else
+   dsi_update_dsc_timing(msm_host, true, hdisplay);
+


Such cleanups (which appear unrelated) should probably be posted as separate
patches.

- Marijn



Its not unrelated, dsi_update_dsc_timing call is moved up so it can use 
the single-panel "hdisplay" value before it gets adjusted for DSC.



/* Divide the display by 3 but keep back/font porch and
 * pulse width same
 */
@@ -966,9 +970,6 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, 
bool is_bonded_dsi)
}
  
  	if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) {

-   if (msm_host->dsc)
-   dsi_update_dsc_timing(msm_host, false, mode->hdisplay);
-
dsi_write(msm_host, REG_DSI_ACTIVE_H,
DSI_ACTIVE_H_START(ha_start) |
DSI_ACTIVE_H_END(ha_end));
@@ -987,9 +988,6 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, 
bool is_bonded_dsi)
DSI_ACTIVE_VSYNC_VPOS_START(vs_start) |
DSI_ACTIVE_VSYNC_VPOS_END(vs_end));
} else {/* command mode */
-   if (msm_host->dsc)
-   dsi_update_dsc_timing(msm_host, true, mode->hdisplay);
-
/* image data and 1 byte write_memory_start cmd */
if (!msm_host->dsc)
wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1;
@@ -2487,7 +2485,8 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host 
*host,
  }
  
  enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,

-   const struct drm_display_mode *mode)
+   const struct drm_display_mode *mode,
+   bool is_bonded_dsi)
  {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
struct 

Re: [PATCH i-g-t 2/2] lib/kunit: Execute test cases synchronously

2023-11-14 Thread Janusz Krzysztofik
Hi Mauro,

Thanks for review.  

On Friday, 10 November 2023 08:52:04 CET Mauro Carvalho Chehab wrote:
> On Mon,  6 Nov 2023 10:59:38 +0100
> Janusz Krzysztofik  wrote:
> 
> > Up to now we've been loading a KUnit test module in background and parsing
> > in parallel its KTAP output with results from all the module's test cases.
> > However, recent KUnit implementation is capable of executing only those
> > test cases that match a user filter specified on test module load.

Having read your comments below, I think that in the first place I need to 
extend this part of my commit description with a more exhaustive explanation 
of my intentions standing behind this series, so its purpose is more clear to 
readers.

Why do we want to execute test cases separately, one test case per one load of 
the KUnit test module?  Because we want to be able to fully synchronize IGT 
output with KTAP output.  That's the main goal of this series.  Without that, 
each CI report from an individual IGT dynamic sub-subtest may contain kernel 
messages not related to its corresponding KUnit test case while missing those 
related.  That's about not misleading not only humans who will be reading 
those reports, but also IGT runner which makes its go / no go decisions based 
on that output.

The only way to reach the goal I can see is to execute individual KUnit test 
cases synchronously to their corresponding IGT dynamic sub-subtests.  That can 
be obtained by executing only one test case per load of KUnit test module. The 
same approach has been successfully used for years with i915 selftests.

> > Stop loading the KUnit test module in background once per the whole
> > subtest.  Instead, load the module on each dynamic sub-subtest execution
> > with a filter that selects a specific test case and wait for its
> > completion.  If successful and no kernel taint then parse the whole KTAP
> > report it has produced and translate it to IGT result of the sub-subtest.
> > 
> > With that in place, we no longer need to skip the whole subtest on a
> > failure from module loading or KTAP reading or parsing.  Since such event
> > is now local to execution of an individual test case, only fail its
> > corresponding dynamic sub-subtests and continue with subsequent ones.
> > However, still omit execution of subsequent test cases once the kernel
> > gets tainted.
> 
> The main reason why loading the module in background was done in the
> first place was because if there is a BUG() or PANIC() or gpu hang
> while executing KUnit, the dmesg KUnit parser was not producing anything,
> and were blocking normal dmesg parsing by IGT runner. 

No, that was not the reason.  See 
https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/commit/f033d0533b3075beef173f4d0e59f355f0d6c545
 
for an explanation of why loading the module in background was implemented.

> While I didn't
> test such changes, we need to check what will be there at the JSON file
> when IGT resume run is enabled, and those kind of bugs are triggered.

I'm not sure what you mean.

> -
> 
> Yet, let's take one step back, as IMO this may not solve the issues.

What do you mean by one step back?  Do you suggest that we should not only 
forget about executing test cases one by one, but also revert the former 
changes that introduced obtaining a list of test cases in advance because of 
issues already introduced by those changes to CI Xe runs?  As you know, those 
issues are caused by the Xe driver itself, which incorrectly depends on KUnit 
base module and makes it impossible to reload that module without also 
reloading the Xe driver.  This series is has nothing to do with those issues. 
Fixing them, in the Xe driver, not in IGT, is what I'm going to focus on next.

> See, when you say:  
> 
> > only fail its
> > corresponding dynamic sub-subtests and continue with subsequent ones.
> 
> When a normal failure happens on KUnit, other tests will be executed. This
> is the normal KUnit behavior. So, except if we're doing something wrong on
> Xe or KMS tests, the other subtests after the failure will be tested.

The paragraph you extracted my words from was not about a normal KUnit 
failure, only (quoting myself) "a failure from module loading or KTAP reading 
or parsing".  Such a failure, not related to actual results from KUnit test 
cases executed, makes awaiting and parsing more KTAP output problematic, I 
believe, if not completely pointless.  That paragraph doesn't describe the 
goals of the changes, only their impact on behavior of IGT KUnit tests.

> However, if such failure is calling BUG_ON(), then the driver will be
> tainted, and will prevent module unload. On such case, it doesn't matter
> if tests are executed in batch or not: IGT will try to unload the
> KUnit module but it will fail due to BUG_ON() behavior.

OK, but if that doesn't matter then I can see no problem in applying the 
proposed changes, as long as their main goal -- synchronization of IGT output 
with KTAP output -- is 

Re: [PATCH 4/4] drm/msm/dsi: fix DSC for the bonded DSI case

2023-11-14 Thread Marijn Suijten
On what hardware have you been testing this?  Dmitry and I have a stack of
patches to resolve support for Active CTL programming on newer hardware (DPU
5.0+ IIRC), where a single CTL is responsible for programming multiple INTF and
DSC blocks as used in bonded DSI.

On 2023-11-14 12:42:16, Jonathan Marek wrote:
> For the bonded DSI case, DSC pic_width and timing calculations should use
> the width of a single panel instead of the total combined width.
> 
> Signed-off-by: Jonathan Marek 
> ---
>  drivers/gpu/drm/msm/dsi/dsi.h |  3 ++-
>  drivers/gpu/drm/msm/dsi/dsi_host.c| 20 +++-
>  drivers/gpu/drm/msm/dsi/dsi_manager.c |  2 +-
>  3 files changed, 14 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
> index 28379b1af63f..3a641e69447c 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi.h
> +++ b/drivers/gpu/drm/msm/dsi/dsi.h
> @@ -93,7 +93,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host);
>  int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host,
> const struct drm_display_mode *mode);
>  enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
> - const struct drm_display_mode 
> *mode);
> + const struct drm_display_mode *mode,
> + bool is_bonded_dsi);
>  unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host);
>  int msm_dsi_host_register(struct mipi_dsi_host *host);
>  void msm_dsi_host_unregister(struct mipi_dsi_host *host);
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
> b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index 7284346ab787..a6286eb9d006 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -938,8 +938,7 @@ static void dsi_timing_setup(struct msm_dsi_host 
> *msm_host, bool is_bonded_dsi)
>  mode->hdisplay, mode->vdisplay);
>   return;
>   }
> -
> - dsc->pic_width = mode->hdisplay;
> + dsc->pic_width = hdisplay;

In my testing and debugging on CMDmode panels downstream this value/register
was always programmed to the _full_ width of the bonded panel.  Is that maybe
different for video mode?

>   dsc->pic_height = mode->vdisplay;
>   DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height);
>  
> @@ -950,6 +949,11 @@ static void dsi_timing_setup(struct msm_dsi_host 
> *msm_host, bool is_bonded_dsi)
>   if (ret)
>   return;
>  
> + if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO)
> + dsi_update_dsc_timing(msm_host, false, hdisplay);
> + else
> + dsi_update_dsc_timing(msm_host, true, hdisplay);
> +

Such cleanups (which appear unrelated) should probably be posted as separate
patches.

- Marijn

>   /* Divide the display by 3 but keep back/font porch and
>* pulse width same
>*/
> @@ -966,9 +970,6 @@ static void dsi_timing_setup(struct msm_dsi_host 
> *msm_host, bool is_bonded_dsi)
>   }
>  
>   if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) {
> - if (msm_host->dsc)
> - dsi_update_dsc_timing(msm_host, false, mode->hdisplay);
> -
>   dsi_write(msm_host, REG_DSI_ACTIVE_H,
>   DSI_ACTIVE_H_START(ha_start) |
>   DSI_ACTIVE_H_END(ha_end));
> @@ -987,9 +988,6 @@ static void dsi_timing_setup(struct msm_dsi_host 
> *msm_host, bool is_bonded_dsi)
>   DSI_ACTIVE_VSYNC_VPOS_START(vs_start) |
>   DSI_ACTIVE_VSYNC_VPOS_END(vs_end));
>   } else {/* command mode */
> - if (msm_host->dsc)
> - dsi_update_dsc_timing(msm_host, true, mode->hdisplay);
> -
>   /* image data and 1 byte write_memory_start cmd */
>   if (!msm_host->dsc)
>   wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1;
> @@ -2487,7 +2485,8 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host 
> *host,
>  }
>  
>  enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
> - const struct drm_display_mode *mode)
> + const struct drm_display_mode *mode,
> + bool is_bonded_dsi)
>  {
>   struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
>   struct drm_dsc_config *dsc = msm_host->dsc;
> @@ -2497,6 +2496,9 @@ enum drm_mode_status msm_dsi_host_check_dsc(struct 
> mipi_dsi_host *host,
>   if (!msm_host->dsc)
>   return MODE_OK;
>  
> + if (is_bonded_dsi)
> + pic_width = mode->hdisplay / 2;
> +
>   if (pic_width % dsc->slice_width) {
>   pr_err("DSI: pic_width %d has to be multiple 

Re: [PATCH 2/6] drm: Add drm_atomic_helper_buffer_damage_{iter_init,merged}() helpers

2023-11-14 Thread Javier Martinez Canillas
Thomas Zimmermann  writes:

> Hi
>
> Am 14.11.23 um 16:58 schrieb Javier Martinez Canillas:
>> Thomas Zimmermann  writes:
>> 
>> Hello Thomas,
>> 
>> Thanks a lot for your feedback.
>> 
>>> Hi
>>>
>>> Am 09.11.23 um 18:24 schrieb Javier Martinez Canillas:
 To be used by drivers that do per-buffer (e.g: virtio-gpu) uploads (rather
 than per-plane uploads), since these type of drivers need to handle buffer
 damages instead of frame damages.

 The drm_atomic_helper_buffer_damage_iter_init() has the same logic than
 drm_atomic_helper_damage_iter_init() but it also takes into account if the
 framebuffer attached to plane's state has changed since the last update.

 And the drm_atomic_helper_buffer_damage_merged() is just a version of the
 drm_atomic_helper_damage_merged() helper, but it uses the iter_init helper
 that is mentioned above.

 Fixes: 01f05940a9a7 ("drm/virtio: Enable fb damage clips property for the 
 primary plane")
 Cc:  # v6.4+
 Reported-by: nerdopolis 
 Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218115
 Suggested-by: Sima Vetter 
 Signed-off-by: Javier Martinez Canillas 
 ---

drivers/gpu/drm/drm_damage_helper.c | 79 ++---
include/drm/drm_damage_helper.h |  7 +++
2 files changed, 80 insertions(+), 6 deletions(-)

 diff --git a/drivers/gpu/drm/drm_damage_helper.c 
 b/drivers/gpu/drm/drm_damage_helper.c
 index aa2325567918..b72062c9d31c 100644
 --- a/drivers/gpu/drm/drm_damage_helper.c
 +++ b/drivers/gpu/drm/drm_damage_helper.c
 @@ -204,7 +204,8 @@ EXPORT_SYMBOL(drm_atomic_helper_dirtyfb);
static void
__drm_atomic_helper_damage_iter_init(struct 
 drm_atomic_helper_damage_iter *iter,
 const struct drm_plane_state 
 *old_state,
 -   const struct drm_plane_state *state)
 +   const struct drm_plane_state *state,
 +   bool buffer_damage)
>>>
>>> I think it would be preferable to drop patches one and two and instead
>>> add this parameter directly to drm_atomic_helper_damage_iter_init() and
>>> drm_atomic_helper_damage_merged().  That's a bit of churn, but more
>>> readable code.
>>>
>> 
>> Makes sense. I'll do that in v2.
>
> Instead of modifying these function interfaces, it might be even better 
> to introduce a state flag in struct drm_plane_state that you can modify 
> in the plane's atomic_check helper. Something simple like this:
>
>if (old_fb != new_fb)
>  plane_state->ignore_damage_clips = true;
>
> in the affected drivers/planes. In drm_atomic_helper_damage_iter_init() 
> you can use it to generate a full update. This avoids the churn and is 
> in line with the overall check/commit design of the DRM framework.
>

Thanks. That indeed seems more aligned with the rest of the DRM framework.

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



Re: [PATCH 0/6] drm: Allow the damage helpers to handle buffer damage

2023-11-14 Thread Javier Martinez Canillas
Thomas Zimmermann  writes:

Hello Thomas,

> Hi

[...]

>>> And why does it flicker? Is there old data stored somewhere?
>>>
>> 
>> It flickers because the framebuffer changed and so the damage tracking
>> is not used correctly to flush the damaged areas to the backing storage.
>
> I think I got it from the links in patch 5.  In out other drivers, 
> there's a single backing storage for each plane (for example in the 
> video memory). Here, there's a backing storage for each buffer. On page

Correct, that's what I understood too.

> flips, the plane changes its backing storage.  Our GEM buffer is up to 
> date, but the respective backing storage is missing all the intermediate 
> changes.
>
> If I'm not mistaken, an entirely different solution would be to 
> implement a per-plane back storage in these drivers.
>

I believe so but I'm not sure if that's possible since the virtio-gpu spec
defines that the VM should send a VIRTIO_GPU_CMD_RESOURCE_FLUSH to the VMM
in the host to do an update and the granularity for that is a framebuffer.

For that reason the only solution (other than forcing a full plane update
like this patch-set does) is to implement tracking suppor for buffer damage.

> Best regards
> Thomas
>

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



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

2023-11-14 Thread Tvrtko Ursulin



On 14/11/2023 17:37, Teres Alexis, Alan Previn wrote:

On Tue, 2023-11-14 at 17:27 +, Tvrtko Ursulin wrote:

On 13/11/2023 17:57, Teres Alexis, Alan Previn wrote:

On Wed, 2023-10-25 at 13:58 +0100, Tvrtko Ursulin wrote:

On 04/10/2023 18:59, Teres Alexis, Alan Previn wrote:

On Thu, 2023-09-28 at 13:46 +0100, Tvrtko Ursulin wrote:

On 27/09/2023 17:36, Teres Alexis, Alan Previn wrote:

alan: snip



alan: I won't say its NOT fixing anything - i am saying it's not fixing
this specific bug where we have the outstanding G2H from a context destruction
operation that got dropped. I am okay with dropping this patch in the next rev
but shall post a separate stand alone version of Patch3 - because I believe
all other i915 subsystems that take runtime-pm's DO NOT wait forever when 
entering
suspend - but GT is doing this. This means if there ever was a bug introduced,
it would require serial port or ramoops collection to debug. So i think such a
patch, despite not fixing this specific bug will be very helpful for 
debuggability
of future issues. After all, its better to fail our suspend when we have a bug
rather than to hang the kernel forever.


Issue I have is that I am not seeing how it fails the suspend when
nothing is passed out from *void* wait_suspend(gt). To me it looks the
suspend just carries on. And if so, it sounds dangerous to allow it to
do that with any future/unknown bugs in the suspend sequence. Existing
timeout wedges the GPU (and all that entails). New code just says "meh
I'll just carry on regardless".


alan: So i did trace back the gt->wakeref before i posted these patches and
see that within these runtime get/put calls, i believe the first 'get' leads
to __intel_wakeref_get_first which calls intel_runtime_pm_get via rpm_get
helper and eventually executes a pm_runtime_get_sync(rpm->kdev); (hanging off
i915_device). (naturally there is a corresponding mirros for the '_put_last').
So this means the first-get and last-put lets the kernel know. Thats why when
i tested this patch, it did actually cause the suspend to abort from kernel side
and the kernel would print a message indicating i915 was the one that didnt
release all refs.


Ah that would be much better then.

Do you know if everything gets resumed/restored correctly in that case 
or we would need some additional work to maybe early exit from callers 
of wait_for_suspend()?


What I would also ask is to see if something like injecting a probing 
failure is feasible, so we can have this new timeout exit path 
constantly/regularly tested in CI.


Regards,

Tvrtko


alan: Anyways, i have pulled this patch out of rev6 of this series and created a
separate standalone patch for this patch #3 that we review independently.



Re: [PATCH] iosys-map: Rename locals used inside macros

2023-11-14 Thread Lucas De Marchi

On Tue, Oct 24, 2023 at 08:10:32AM -0500, Lucas De Marchi wrote:

On Tue, Oct 24, 2023 at 01:07:10PM +0200, Michał Winiarski wrote:

Widely used variable names can be used by macro users, potentially
leading to name collisions.
Suffix locals used inside the macros with an underscore, to reduce the
collision potential.

Suggested-by: Lucas De Marchi 
Signed-off-by: Michał Winiarski 


`git show --color-words` shows this is doing exactly what it should.

Reviewed-by: Lucas De Marchi 


applied to drm-misc-next. Thanks

Lucas De Marchi



Maybe note in the commit message the compilation error we get with
clang? Although that's in the xe driver that is still not merged
upstream... so not really required.

thanks
Lucas De Marchi


[PATCH 4/4] drm/msm/dsi: fix DSC for the bonded DSI case

2023-11-14 Thread Jonathan Marek
For the bonded DSI case, DSC pic_width and timing calculations should use
the width of a single panel instead of the total combined width.

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/dsi/dsi.h |  3 ++-
 drivers/gpu/drm/msm/dsi/dsi_host.c| 20 +++-
 drivers/gpu/drm/msm/dsi/dsi_manager.c |  2 +-
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 28379b1af63f..3a641e69447c 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -93,7 +93,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host);
 int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host,
  const struct drm_display_mode *mode);
 enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
-   const struct drm_display_mode 
*mode);
+   const struct drm_display_mode *mode,
+   bool is_bonded_dsi);
 unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host);
 int msm_dsi_host_register(struct mipi_dsi_host *host);
 void msm_dsi_host_unregister(struct mipi_dsi_host *host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 7284346ab787..a6286eb9d006 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -938,8 +938,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, 
bool is_bonded_dsi)
   mode->hdisplay, mode->vdisplay);
return;
}
-
-   dsc->pic_width = mode->hdisplay;
+   dsc->pic_width = hdisplay;
dsc->pic_height = mode->vdisplay;
DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height);
 
@@ -950,6 +949,11 @@ static void dsi_timing_setup(struct msm_dsi_host 
*msm_host, bool is_bonded_dsi)
if (ret)
return;
 
+   if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO)
+   dsi_update_dsc_timing(msm_host, false, hdisplay);
+   else
+   dsi_update_dsc_timing(msm_host, true, hdisplay);
+
/* Divide the display by 3 but keep back/font porch and
 * pulse width same
 */
@@ -966,9 +970,6 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, 
bool is_bonded_dsi)
}
 
if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) {
-   if (msm_host->dsc)
-   dsi_update_dsc_timing(msm_host, false, mode->hdisplay);
-
dsi_write(msm_host, REG_DSI_ACTIVE_H,
DSI_ACTIVE_H_START(ha_start) |
DSI_ACTIVE_H_END(ha_end));
@@ -987,9 +988,6 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, 
bool is_bonded_dsi)
DSI_ACTIVE_VSYNC_VPOS_START(vs_start) |
DSI_ACTIVE_VSYNC_VPOS_END(vs_end));
} else {/* command mode */
-   if (msm_host->dsc)
-   dsi_update_dsc_timing(msm_host, true, mode->hdisplay);
-
/* image data and 1 byte write_memory_start cmd */
if (!msm_host->dsc)
wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1;
@@ -2487,7 +2485,8 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host 
*host,
 }
 
 enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
-   const struct drm_display_mode *mode)
+   const struct drm_display_mode *mode,
+   bool is_bonded_dsi)
 {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
struct drm_dsc_config *dsc = msm_host->dsc;
@@ -2497,6 +2496,9 @@ enum drm_mode_status msm_dsi_host_check_dsc(struct 
mipi_dsi_host *host,
if (!msm_host->dsc)
return MODE_OK;
 
+   if (is_bonded_dsi)
+   pic_width = mode->hdisplay / 2;
+
if (pic_width % dsc->slice_width) {
pr_err("DSI: pic_width %d has to be multiple of slice %d\n",
   pic_width, dsc->slice_width);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c 
b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index 896f369fdd53..2ca1a7ca3659 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -455,7 +455,7 @@ static enum drm_mode_status 
dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge,
return MODE_ERROR;
}
 
-   return msm_dsi_host_check_dsc(host, mode);
+   return msm_dsi_host_check_dsc(host, mode, IS_BONDED_DSI());
 }
 
 static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = {
-- 
2.26.1



[PATCH 3/4] drm/msm/dsi: support DSC configurations with slice_per_pkt > 1

2023-11-14 Thread Jonathan Marek
Add a dsc_slice_per_pkt field to mipi_dsi_device struct and the necessary
changes to msm driver to support this field.

Note that the removed "pkt_per_line = slice_per_intf * slice_per_pkt"
comment is incorrect.

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 25 ++---
 include/drm/drm_mipi_dsi.h |  1 +
 2 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 2ea2fc105fbf..7284346ab787 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -161,6 +161,7 @@ struct msm_dsi_host {
 
struct drm_display_mode *mode;
struct drm_dsc_config *dsc;
+   unsigned int dsc_slice_per_pkt;
 
/* connected device info */
unsigned int channel;
@@ -855,17 +856,10 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay);
 
total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
-   bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
+   bytes_per_pkt = dsc->slice_chunk_size * msm_host->dsc_slice_per_pkt;
 
eol_byte_num = total_bytes_per_intf % 3;
-
-   /*
-* Typically, pkt_per_line = slice_per_intf * slice_per_pkt.
-*
-* Since the current driver only supports slice_per_pkt = 1,
-* pkt_per_line will be equal to slice per intf for now.
-*/
-   pkt_per_line = slice_per_intf;
+   pkt_per_line = slice_per_intf / msm_host->dsc_slice_per_pkt;
 
if (is_cmd_mode) /* packet data type */
reg = 
DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE);
@@ -1002,12 +996,8 @@ static void dsi_timing_setup(struct msm_dsi_host 
*msm_host, bool is_bonded_dsi)
else
/*
 * When DSC is enabled, WC = slice_chunk_size * 
slice_per_pkt + 1.
-* Currently, the driver only supports default value of 
slice_per_pkt = 1
-*
-* TODO: Expand mipi_dsi_device struct to hold 
slice_per_pkt info
-*   and adjust DSC math to account for 
slice_per_pkt.
 */
-   wc = msm_host->dsc->slice_chunk_size + 1;
+   wc = msm_host->dsc->slice_chunk_size * 
msm_host->dsc_slice_per_pkt + 1;
 
dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL,
DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) |
@@ -1634,8 +1624,13 @@ static int dsi_host_attach(struct mipi_dsi_host *host,
msm_host->lanes = dsi->lanes;
msm_host->format = dsi->format;
msm_host->mode_flags = dsi->mode_flags;
-   if (dsi->dsc)
+   if (dsi->dsc) {
msm_host->dsc = dsi->dsc;
+   msm_host->dsc_slice_per_pkt = dsi->dsc_slice_per_pkt;
+   /* for backwards compatibility, assume 1 if not set */
+   if (!msm_host->dsc_slice_per_pkt)
+   msm_host->dsc_slice_per_pkt = 1;
+   }
 
/* Some gpios defined in panel DT need to be controlled by host */
ret = dsi_host_init_panel_gpios(msm_host, >dev);
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index c9df0407980c..3e32fa52d94b 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -193,6 +193,7 @@ struct mipi_dsi_device {
unsigned long hs_rate;
unsigned long lp_rate;
struct drm_dsc_config *dsc;
+   unsigned int dsc_slice_per_pkt;
 };
 
 #define MIPI_DSI_MODULE_PREFIX "mipi-dsi:"
-- 
2.26.1



[PATCH 2/4] drm/msm/dsi: add a comment to explain pkt_per_line encoding

2023-11-14 Thread Jonathan Marek
Make it clear why the pkt_per_line value is being "divided by 2".

Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index bddc57726fb9..2ea2fc105fbf 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -875,6 +875,8 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
/* DSI_VIDEO_COMPRESSION_MODE & DSI_COMMAND_COMPRESSION_MODE
 * registers have similar offsets, so for below common code use
 * DSI_VIDEO_COMPRESSION_MODE_ for setting bits
+*
+* pkt_per_line is log2 encoded, >>1 works for supported values (1,2,4)
 */
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_PKT_PER_LINE(pkt_per_line >> 1);
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_EOL_BYTE_NUM(eol_byte_num);
-- 
2.26.1



[PATCH 1/4] drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC (fix video mode DSC)

2023-11-14 Thread Jonathan Marek
Video mode DSC won't work if this field is not set correctly. Set it to fix
video mode DSC (for slice_per_pkt==1 cases at least).

Fixes: 08802f515c3 ("drm/msm/dsi: Add support for DSC configuration")
Signed-off-by: Jonathan Marek 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 9d355cdc3ec1..bddc57726fb9 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -847,6 +847,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
u32 slice_per_intf, total_bytes_per_intf;
u32 pkt_per_line;
u32 eol_byte_num;
+   u32 bytes_per_pkt;
 
/* first calculate dsc parameters and then program
 * compress mode registers
@@ -854,6 +855,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay);
 
total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
+   bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
 
eol_byte_num = total_bytes_per_intf % 3;
 
@@ -891,6 +893,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, 
reg_ctrl);
dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, 
reg_ctrl2);
} else {
+   reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_WC(bytes_per_pkt);
dsi_write(msm_host, REG_DSI_VIDEO_COMPRESSION_MODE_CTRL, reg);
}
 }
-- 
2.26.1



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

2023-11-14 Thread Teres Alexis, Alan Previn
On Tue, 2023-11-14 at 17:27 +, Tvrtko Ursulin wrote:
> On 13/11/2023 17:57, Teres Alexis, Alan Previn wrote:
> > On Wed, 2023-10-25 at 13:58 +0100, Tvrtko Ursulin wrote:
> > > On 04/10/2023 18:59, Teres Alexis, Alan Previn wrote:
> > > > On Thu, 2023-09-28 at 13:46 +0100, Tvrtko Ursulin wrote:
> > > > > On 27/09/2023 17:36, Teres Alexis, Alan Previn wrote:
alan: snip
> 
> > alan: I won't say its NOT fixing anything - i am saying it's not fixing
> > this specific bug where we have the outstanding G2H from a context 
> > destruction
> > operation that got dropped. I am okay with dropping this patch in the next 
> > rev
> > but shall post a separate stand alone version of Patch3 - because I believe
> > all other i915 subsystems that take runtime-pm's DO NOT wait forever when 
> > entering
> > suspend - but GT is doing this. This means if there ever was a bug 
> > introduced,
> > it would require serial port or ramoops collection to debug. So i think 
> > such a
> > patch, despite not fixing this specific bug will be very helpful for 
> > debuggability
> > of future issues. After all, its better to fail our suspend when we have a 
> > bug
> > rather than to hang the kernel forever.
> 
> Issue I have is that I am not seeing how it fails the suspend when 
> nothing is passed out from *void* wait_suspend(gt). To me it looks the 
> suspend just carries on. And if so, it sounds dangerous to allow it to 
> do that with any future/unknown bugs in the suspend sequence. Existing 
> timeout wedges the GPU (and all that entails). New code just says "meh 
> I'll just carry on regardless".

alan: So i did trace back the gt->wakeref before i posted these patches and
see that within these runtime get/put calls, i believe the first 'get' leads
to __intel_wakeref_get_first which calls intel_runtime_pm_get via rpm_get
helper and eventually executes a pm_runtime_get_sync(rpm->kdev); (hanging off
i915_device). (naturally there is a corresponding mirros for the '_put_last').
So this means the first-get and last-put lets the kernel know. Thats why when
i tested this patch, it did actually cause the suspend to abort from kernel side
and the kernel would print a message indicating i915 was the one that didnt
release all refs.

alan: Anyways, i have pulled this patch out of rev6 of this series and created a
separate standalone patch for this patch #3 that we review independently.



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

2023-11-14 Thread Rodrigo Vivi
On Tue, Nov 14, 2023 at 05:27:18PM +, Tvrtko Ursulin wrote:
> 
> On 13/11/2023 17:57, Teres Alexis, Alan Previn wrote:
> > On Wed, 2023-10-25 at 13:58 +0100, Tvrtko Ursulin wrote:
> > > On 04/10/2023 18:59, Teres Alexis, Alan Previn wrote:
> > > > On Thu, 2023-09-28 at 13:46 +0100, Tvrtko Ursulin wrote:
> > > > > On 27/09/2023 17:36, Teres Alexis, Alan Previn wrote:
> > alan:snip
> > > > > It is not possible to wait for lost G2H in something like
> > > > > intel_uc_suspend() and simply declare "bad things happened" if it 
> > > > > times
> > > > > out there, and forcibly clean it all up? (Which would include 
> > > > > releasing
> > > > > all the abandoned pm refs, so this patch wouldn't be needed.)
> > > > > 
> > > > alan: I'm not sure if intel_uc_suspend should be held up by gt-level 
> > > > wakeref
> > > > check unless huc/guc/gsc-uc are the only ones ever taking a gt wakeref.
> > > > 
> > > > As we already know, what we do know from a uc-perspective:
> > > > -  ensure the outstanding guc related workers is flushed which we didnt 
> > > > before
> > > > (addressed by patch #1).
> > > > - any further late H2G-SchedDisable is not leaking wakerefs when 
> > > > calling H2G
> > > > and not realizing it failed (addressed by patch #2).
> > > > - (we already), "forcibly clean it all up" at the end of the 
> > > > intel_uc_suspend
> > > > when we do the guc reset and cleanup all guc-ids. (pre-existing 
> > > > upstream code)
> > > > - we previously didnt have a coherrent guarantee that "this is the end" 
> > > > i.e. no
> > > > more new request after intel_uc_suspend. I mean by code logic, we 
> > > > thought we did
> > > > (thats why intel_uc_suspend ends wth a guc reset), but we now know 
> > > > otherwise.
> > > > So we that fix by adding the additional rcu_barrier (also part of patch 
> > > > #2).
> > > 
> > > It is not clear to me from the above if that includes cleaning up the
> > > outstanding CT replies or no. But anyway..
> > alan: Apologies, i should have made it clearer by citing the actual function
> > name calling out the steps of interest: So if you look at the function
> > "intel_gt_suspend_late", it calls "intel_uc_suspend" which in turn calls
> > "intel_guc_suspend" which does a soft reset onto guc firmware - so after 
> > that
> > we can assume all outstanding G2Hs are done. Going back up the stack,
> > intel_gt_suspend_late finally calls gt_sanitize which calls 
> > "intel_uc_reset_prepare"
> > which calls "intel_guc_submission_reset_prepare" which calls
> > "scrub_guc_desc_for_outstanding_g2h" which does what we are looking for for 
> > all
> > types of outstanding G2H. As per prior review comments, besides closing the 
> > race
> > condition, we were missing an rcu_barrier (which caused new requests to 
> > come in way
> > late). So we have resolved both in Patch #2.
> 
> Cool, I read this as all known bugs are fixed by first two patches.
> 
> > > > That said, patch-3 is NOT fixing a bug in guc -its about "if we ever 
> > > > have
> > > > a future racy gt-wakeref late-leak somewhere - no matter which subsystem
> > > > took it (guc is not the only subsystem taking gt wakerefs), we at
> > > > least don't hang forever in this code. Ofc, based on that, even without
> > > > patch-3 i am confident the issue is resolved anyway.
> > > > So we could just drop patch-3 is you prefer?
> > > 
> > > .. given this it does sound to me that if you are confident patch 3
> > > isn't fixing anything today that it should be dropped.
> > alan: I won't say its NOT fixing anything - i am saying it's not fixing
> > this specific bug where we have the outstanding G2H from a context 
> > destruction
> > operation that got dropped. I am okay with dropping this patch in the next 
> > rev
> > but shall post a separate stand alone version of Patch3 - because I believe
> > all other i915 subsystems that take runtime-pm's DO NOT wait forever when 
> > entering
> > suspend - but GT is doing this. This means if there ever was a bug 
> > introduced,
> > it would require serial port or ramoops collection to debug. So i think 
> > such a
> > patch, despite not fixing this specific bug will be very helpful for 
> > debuggability
> > of future issues. After all, its better to fail our suspend when we have a 
> > bug
> > rather than to hang the kernel forever.
> 
> Issue I have is that I am not seeing how it fails the suspend when nothing
> is passed out from *void* wait_suspend(gt). To me it looks the suspend just
> carries on. And if so, it sounds dangerous to allow it to do that with any
> future/unknown bugs in the suspend sequence. Existing timeout wedges the GPU
> (and all that entails). New code just says "meh I'll just carry on
> regardless".

That's a good point.
Well, current code is already bad and buggy on suspend-resume. We could get
suspend stuck forever without any clue of what happened.
At least the proposed patch add some gt_warn. But, yes, the right thing
to do should be entirely abort the suspend in case 

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

2023-11-14 Thread Tvrtko Ursulin



On 13/11/2023 17:57, Teres Alexis, Alan Previn wrote:

On Wed, 2023-10-25 at 13:58 +0100, Tvrtko Ursulin wrote:

On 04/10/2023 18:59, Teres Alexis, Alan Previn wrote:

On Thu, 2023-09-28 at 13:46 +0100, Tvrtko Ursulin wrote:

On 27/09/2023 17:36, Teres Alexis, Alan Previn wrote:

alan:snip

It is not possible to wait for lost G2H in something like
intel_uc_suspend() and simply declare "bad things happened" if it times
out there, and forcibly clean it all up? (Which would include releasing
all the abandoned pm refs, so this patch wouldn't be needed.)


alan: I'm not sure if intel_uc_suspend should be held up by gt-level wakeref
check unless huc/guc/gsc-uc are the only ones ever taking a gt wakeref.

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


It is not clear to me from the above if that includes cleaning up the
outstanding CT replies or no. But anyway..

alan: Apologies, i should have made it clearer by citing the actual function
name calling out the steps of interest: So if you look at the function
"intel_gt_suspend_late", it calls "intel_uc_suspend" which in turn calls
"intel_guc_suspend" which does a soft reset onto guc firmware - so after that
we can assume all outstanding G2Hs are done. Going back up the stack,
intel_gt_suspend_late finally calls gt_sanitize which calls 
"intel_uc_reset_prepare"
which calls "intel_guc_submission_reset_prepare" which calls
"scrub_guc_desc_for_outstanding_g2h" which does what we are looking for for all
types of outstanding G2H. As per prior review comments, besides closing the race
condition, we were missing an rcu_barrier (which caused new requests to come in 
way
late). So we have resolved both in Patch #2.


Cool, I read this as all known bugs are fixed by first two patches.


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


.. given this it does sound to me that if you are confident patch 3
isn't fixing anything today that it should be dropped.

alan: I won't say its NOT fixing anything - i am saying it's not fixing
this specific bug where we have the outstanding G2H from a context destruction
operation that got dropped. I am okay with dropping this patch in the next rev
but shall post a separate stand alone version of Patch3 - because I believe
all other i915 subsystems that take runtime-pm's DO NOT wait forever when 
entering
suspend - but GT is doing this. This means if there ever was a bug introduced,
it would require serial port or ramoops collection to debug. So i think such a
patch, despite not fixing this specific bug will be very helpful for 
debuggability
of future issues. After all, its better to fail our suspend when we have a bug
rather than to hang the kernel forever.


Issue I have is that I am not seeing how it fails the suspend when 
nothing is passed out from *void* wait_suspend(gt). To me it looks the 
suspend just carries on. And if so, it sounds dangerous to allow it to 
do that with any future/unknown bugs in the suspend sequence. Existing 
timeout wedges the GPU (and all that entails). New code just says "meh 
I'll just carry on regardless".


Regards,

Tvrtko



Re: [PATCH] drm/doc/rfc: SR-IOV support on the new Xe driver

2023-11-14 Thread Michal Wajdeczko



On 14.11.2023 14:22, Vivi, Rodrigo wrote:
> On Tue, 2023-11-14 at 12:37 +, Tvrtko Ursulin wrote:
>>
>> On 10/11/2023 18:22, Michal Wajdeczko wrote:
>>> The Single Root I/O Virtualization (SR-IOV) extension to the PCI
>>> Express (PCIe) specification suite is supported starting from 12th
>>> generation of Intel Graphics processors.
>>>
>>> This RFC aims to explain how do we want to add support for SR-IOV
>>> to the new Xe driver and to propose related additions to the sysfs.
>>>
>>> Signed-off-by: Michal Wajdeczko 
>>> Cc: Oded Gabbay 
>>> Cc: Rodrigo Vivi 
>>> Cc: Joonas Lahtinen 
>>> Cc: Tvrtko Ursulin 
>>> Cc: Daniel Vetter 
>>> ---
>>>   Documentation/gpu/rfc/index.rst |   5 +
>>>   Documentation/gpu/rfc/sysfs-driver-xe-sriov | 501
>>> 
>>>   Documentation/gpu/rfc/xe_sriov.rst  | 192 
>>>   3 files changed, 698 insertions(+)
>>>   create mode 100644 Documentation/gpu/rfc/sysfs-driver-xe-sriov
>>>   create mode 100644 Documentation/gpu/rfc/xe_sriov.rst
>>>
>>> diff --git a/Documentation/gpu/rfc/index.rst
>>> b/Documentation/gpu/rfc/index.rst
>>> index e4f7b005138d..fc5bc447f30d 100644
>>> --- a/Documentation/gpu/rfc/index.rst
>>> +++ b/Documentation/gpu/rfc/index.rst
>>> @@ -35,3 +35,8 @@ host such documentation:
>>>   .. toctree::
>>>   
>>>  xe.rst
>>> +
>>> +.. toctree::
>>> +   :maxdepth: 1
>>> +
>>> +   xe_sriov.rst
>>> diff --git a/Documentation/gpu/rfc/sysfs-driver-xe-sriov
>>> b/Documentation/gpu/rfc/sysfs-driver-xe-sriov
>>> new file mode 100644
>>> index ..77748204dd83
>>> --- /dev/null
>>> +++ b/Documentation/gpu/rfc/sysfs-driver-xe-sriov
>>> @@ -0,0 +1,501 @@
>>> +.. Documentation/ABI/testing/sysfs-driver-xe-sriov
>>> +..
>>> +.. Intel Xe driver ABI (SR-IOV extensions)
>>> +..
>>> +    The Single Root I/O Virtualization (SR-IOV) extension to
>>> +    the PCI Express (PCIe) specification suite is supported
>>> +    starting from 12th generation of Intel Graphics processors.
>>> +
>>> +    This document describes Xe driver specific additions.
>>> +
>>> +    For description of generic SR-IOV sysfs attributes see
>>> +    "Documentation/ABI/testing/sysfs-bus-pci" document.
>>> +
>>> +    /sys/bus/pci/drivers/xe/BDF/
>>> +    ├── sriov_auto_provisioning
>>> +    │   ├── admin_mode
>>> +    │   ├── enabled
>>> +    │   ├── reset_defaults
>>> +    │   ├── resources
>>> +    │   │   ├── default_contexts_quota
>>> +    │   │   ├── default_doorbells_quota
>>> +    │   │   ├── default_ggtt_quota
>>> +    │   │   └── default_lmem_quota
>>> +    │   ├── scheduling
>>> +    │   │   ├── default_exec_quantum_ms
>>> +    │   │   └── default_preempt_timeout_us
>>> +    │   └── monitoring
>>> +    │       ├── default_cat_error_count
>>> +    │       ├── default_doorbell_time_us
>>> +    │       ├── default_engine_reset_count
>>> +    │       ├── default_h2g_time_us
>>> +    │       ├── default_irq_time_us
>>> +    │       └── default_page_fault_count
>>
>>  From the department of bike-shedding, one alternative could be to
>> have 
>> a directory called defaults which avoids having to have the default_ 
>> prefix on everything under it.
> 
> good idea. probably with a '.' prefix to make it hidden like we have
> for other stuff already.
> 
> '.defaults'

but then we will be inconsistent as in this 'other stuff' we use
".defaults" directory to hold RO attributes with min/default/max values,
while here we wanted to define RW attributes that will be applied to VFs

maybe ".template" instead ?

> 
>>
>>> +
>>> +    /sys/bus/pci/drivers/xe/BDF/
>>> +    ├── sriov_extensions
>>
>> Should this be xe_sriov_extensions or if not doesn't it need
>> agreement 
>> to reserve the keyword in Documentation/ABI/testing/sysfs-bus-pci? 
>> Sriov_auto_provisioning too I guess.
>>
>>> +    │   ├── monitoring_period_ms
>>> +    │   ├── strict_scheduling_enabled
>>> +    │   ├── pf
>>> +    │   │   ├── device -> ../../../BDF
>>> +    │   │   ├── priority
>>> +    │   │   ├── tile0
>>> +    │   │   │   ├── gt0
>>> +    │   │   │   │   ├── exec_quantum_ms
>>> +    │   │   │   │   ├── preempt_timeout_us
>>> +    │   │   │   │   └── thresholds
>>> +    │   │   │   │   ├── cat_error_count
>>> +    │   │   │   │   ├── doorbell_time_us
>>> +    │   │   │   │   ├── engine_reset_count
>>> +    │   │   │   │   ├── h2g_time_us
>>> +    │   │   │   │   ├── irq_time_us
>>> +    │   │   │   │   └── page_fault_count
>>> +    │   │   │   └── gtX
>>> +    │   │   └── tileT
>>> +    │   ├── vf1
>>> +    │   │   ├── device -> ../../../BDF+1
>>> +    │   │   ├── stop
>>> +    │   │   ├── tile0
>>> +    │   │   │   ├── ggtt_quota
>>> +    │   │   │   ├── lmem_quota
>>> +    │   │   │   ├── gt0
>>> +    │   │   │   │   ├── contexts_quota
>>> +    │   │   │   │   ├── doorbells_quota
>>> +    │   │   │   │   ├── exec_quantum_ms
>>> +    │   │   │   │   ├── preempt_timeout_us
>>> +    │   │   │   │   └── thresholds
>>> +    │   │   │   │   ├── cat_error_count

Re: [PATCH] drm/doc/rfc: SR-IOV support on the new Xe driver

2023-11-14 Thread Michal Wajdeczko



On 14.11.2023 13:37, Tvrtko Ursulin wrote:
> 
> On 10/11/2023 18:22, Michal Wajdeczko wrote:
>> The Single Root I/O Virtualization (SR-IOV) extension to the PCI
>> Express (PCIe) specification suite is supported starting from 12th
>> generation of Intel Graphics processors.
>>
>> This RFC aims to explain how do we want to add support for SR-IOV
>> to the new Xe driver and to propose related additions to the sysfs.
>>
>> Signed-off-by: Michal Wajdeczko 
>> Cc: Oded Gabbay 
>> Cc: Rodrigo Vivi 
>> Cc: Joonas Lahtinen 
>> Cc: Tvrtko Ursulin 
>> Cc: Daniel Vetter 
>> ---
>>   Documentation/gpu/rfc/index.rst |   5 +
>>   Documentation/gpu/rfc/sysfs-driver-xe-sriov | 501 
>>   Documentation/gpu/rfc/xe_sriov.rst  | 192 
>>   3 files changed, 698 insertions(+)
>>   create mode 100644 Documentation/gpu/rfc/sysfs-driver-xe-sriov
>>   create mode 100644 Documentation/gpu/rfc/xe_sriov.rst
>>
>> diff --git a/Documentation/gpu/rfc/index.rst
>> b/Documentation/gpu/rfc/index.rst
>> index e4f7b005138d..fc5bc447f30d 100644
>> --- a/Documentation/gpu/rfc/index.rst
>> +++ b/Documentation/gpu/rfc/index.rst
>> @@ -35,3 +35,8 @@ host such documentation:
>>   .. toctree::
>>    xe.rst
>> +
>> +.. toctree::
>> +   :maxdepth: 1
>> +
>> +   xe_sriov.rst
>> diff --git a/Documentation/gpu/rfc/sysfs-driver-xe-sriov
>> b/Documentation/gpu/rfc/sysfs-driver-xe-sriov
>> new file mode 100644
>> index ..77748204dd83
>> --- /dev/null
>> +++ b/Documentation/gpu/rfc/sysfs-driver-xe-sriov
>> @@ -0,0 +1,501 @@
>> +.. Documentation/ABI/testing/sysfs-driver-xe-sriov
>> +..
>> +.. Intel Xe driver ABI (SR-IOV extensions)
>> +..
>> +    The Single Root I/O Virtualization (SR-IOV) extension to
>> +    the PCI Express (PCIe) specification suite is supported
>> +    starting from 12th generation of Intel Graphics processors.
>> +
>> +    This document describes Xe driver specific additions.
>> +
>> +    For description of generic SR-IOV sysfs attributes see
>> +    "Documentation/ABI/testing/sysfs-bus-pci" document.
>> +
>> +    /sys/bus/pci/drivers/xe/BDF/
>> +    ├── sriov_auto_provisioning
>> +    │   ├── admin_mode
>> +    │   ├── enabled
>> +    │   ├── reset_defaults
>> +    │   ├── resources
>> +    │   │   ├── default_contexts_quota
>> +    │   │   ├── default_doorbells_quota
>> +    │   │   ├── default_ggtt_quota
>> +    │   │   └── default_lmem_quota
>> +    │   ├── scheduling
>> +    │   │   ├── default_exec_quantum_ms
>> +    │   │   └── default_preempt_timeout_us
>> +    │   └── monitoring
>> +    │       ├── default_cat_error_count
>> +    │       ├── default_doorbell_time_us
>> +    │       ├── default_engine_reset_count
>> +    │       ├── default_h2g_time_us
>> +    │       ├── default_irq_time_us
>> +    │       └── default_page_fault_count
> 
> From the department of bike-shedding, one alternative could be to have a
> directory called defaults which avoids having to have the default_
> prefix on everything under it.

like this ?

/sys/bus/pci/drivers/xe/BDF/
├── sriov_auto_provisioning
│   ├── admin_mode
│   ├── enabled
│   └── defaults
│   ├── resources
│   │   ├── contexts_quota
│   │   ├── doorbells_quota
│   │   ├── ggtt_quota
│   │   └── lmem_quota
│   ├── scheduling
│   │   ├── exec_quantum_ms
│   │   └── preempt_timeout_us
│   └── monitoring
│   ├── cat_error_count
│   ├── doorbell_time_us
│   ├── engine_reset_count
│   ├── h2g_time_us
│   ├── irq_time_us
│   └── page_fault_count


> 
>> +
>> +    /sys/bus/pci/drivers/xe/BDF/
>> +    ├── sriov_extensions
> 
> Should this be xe_sriov_extensions or if not doesn't it need agreement
> to reserve the keyword in Documentation/ABI/testing/sysfs-bus-pci?
> Sriov_auto_provisioning too I guess.

I didn't spot in ABI documents any driver specific additions to device
that were using extra prefix, nor the "reservation" placeholders.

but if we want to go with a prefix, then maybe all our additions at
device level should have one, including already added tileT:

tile0 -> xe_tile0

or even to match existing mei file we should use "xe." prefix instead:

xe.sriov_auto_provisioning
xe.sriov_extension
xe.tile0
xe.mei-gsc...

> 
>> +    │   ├── monitoring_period_ms
>> +    │   ├── strict_scheduling_enabled
>> +    │   ├── pf
>> +    │   │   ├── device -> ../../../BDF
>> +    │   │   ├── priority
>> +    │   │   ├── tile0
>> +    │   │   │   ├── gt0
>> +    │   │   │   │   ├── exec_quantum_ms
>> +    │   │   │   │   ├── preempt_timeout_us
>> +    │   │   │   │   └── thresholds
>> +    │   │   │   │   ├── cat_error_count
>> +    │   │   │   │   ├── doorbell_time_us
>> +    │   │   │   │   ├── engine_reset_count
>> +    │   │   │   │   ├── h2g_time_us
>> +    │   │   │   │   ├── irq_time_us
>> +    │   │   │   │   

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

2023-11-14 Thread Danilo Krummrich

On 10/31/23 16:12, Sarah Walker wrote:

From: Donald Robson 

Determining the start and range of the unmap stage of a remap op is a
common piece of code currently implemented by multiple drivers. Add a
helper for this.

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

Changes since v6:
- Remove use of __always_inline

Signed-off-by: Donald Robson 
Signed-off-by: Sarah Walker 


Reviewed-by: Danilo Krummrich 

Want me to apply the patch?


---
  include/drm/drm_gpuvm.h | 28 
  1 file changed, 28 insertions(+)

diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h
index c7ed6bf441d4..c64585dc4e8e 100644
--- a/include/drm/drm_gpuvm.h
+++ b/include/drm/drm_gpuvm.h
@@ -702,4 +702,32 @@ void drm_gpuva_remap(struct drm_gpuva *prev,
  
  void drm_gpuva_unmap(struct drm_gpuva_op_unmap *op);
  
+/**

+ * drm_gpuva_op_remap_to_unmap_range() - Helper to get the start and range of
+ * the unmap stage of a remap op.
+ * @op: Remap op.
+ * @start_addr: Output pointer for the start of the required unmap.
+ * @range: Output pointer for the length of the required unmap.
+ *
+ * The given start address and range will be set such that they represent the
+ * range of the address space that was previously covered by the mapping being
+ * re-mapped, but is now empty.
+ */
+static inline void
+drm_gpuva_op_remap_to_unmap_range(const struct drm_gpuva_op_remap *op,
+ u64 *start_addr, u64 *range)
+{
+   const u64 va_start = op->prev ?
+op->prev->va.addr + op->prev->va.range :
+op->unmap->va->va.addr;
+   const u64 va_end = op->next ?
+  op->next->va.addr :
+  op->unmap->va->va.addr + op->unmap->va->va.range;
+
+   if (start_addr)
+   *start_addr = va_start;
+   if (range)
+   *range = va_end - va_start;
+}
+
  #endif /* __DRM_GPUVM_H__ */




[PATCH] drm/amdgpu/gmc11: fix logic typo in AGP check

2023-11-14 Thread ivlipski
From: Alex Deucher 

Should be && rather than ||.

Fixes: b2e1cbe6281f ("drm/amdgpu/gmc11: disable AGP on GC 11.5")
Acked-by: Christian König 
Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
index 6dce9b29f675..ba4c82f5e617 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
@@ -640,7 +640,7 @@ static void gmc_v11_0_vram_gtt_location(struct 
amdgpu_device *adev,
amdgpu_gmc_set_agp_default(adev, mc);
amdgpu_gmc_vram_location(adev, >gmc, base);
amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_HIGH);
-   if (!amdgpu_sriov_vf(adev) ||
+   if (!amdgpu_sriov_vf(adev) &&
(amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(11, 5, 0)))
amdgpu_gmc_agp_location(adev, mc);
 
-- 
2.34.1



Re: [PATCH 0/6] drm: Allow the damage helpers to handle buffer damage

2023-11-14 Thread Thomas Zimmermann

Hi

Am 14.11.23 um 17:28 schrieb Javier Martinez Canillas:

Thomas Zimmermann  writes:


Hi Javier

Am 09.11.23 um 18:24 schrieb Javier Martinez Canillas:

Hello,

This series is to fix an issue that surfaced after damage clipping was
enabled for the virtio-gpu by commit 01f05940a9a7 ("drm/virtio: Enable
fb damage clips property for the primary plane").

After that change, flickering artifacts was reported to be present with
both weston and wlroots wayland compositors when running in a virtual
machine. The cause was identified by Sima Vetter, who pointed out that
virtio-gpu does per-buffer uploads and for this reason it needs to do
a buffer damage handling, instead of frame damage handling.


I'm having problem understanding the types of damage. You never say what
buffer damage is. I also don't know what a frame is in this context.

Regular damage handling marks parts of a plane as dirty/damaged. That is
per-plane damage handling. The individual planes more or less
independent from each other.

Buffer damage, I guess, marks the underlying buffer as dirty and
requires synchronization of the buffer with some backing storage. The
planes using that buffer are then updated more or less automatically.

Is that right?



In both cases the damage tracking information is the same, they mark
the damaged regions on the plane in framebuffer coordinates of the
framebuffer attached to the plane.

The problem as far as I understand is whether the driver expects that
to determine the area that changed in the plane (and a plane flush is
enough) or the area that changed since that same buffer was last used.


And why does it flicker? Is there old data stored somewhere?



It flickers because the framebuffer changed and so the damage tracking
is not used correctly to flush the damaged areas to the backing storage.


I think I got it from the links in patch 5.  In out other drivers, 
there's a single backing storage for each plane (for example in the 
video memory). Here, there's a backing storage for each buffer. On page 
flips, the plane changes its backing storage.  Our GEM buffer is up to 
date, but the respective backing storage is missing all the intermediate 
changes.


If I'm not mistaken, an entirely different solution would be to 
implement a per-plane back storage in these drivers.


Best regards
Thomas



This is my understanding at least, please Sima or Simon correct me if I
got this wrong.


Best regards
Thomas





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


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PATCH 04/17] dt-bindings: mmc: samsung,exynos-dw-mshc: add specific compatibles for existing SoC

2023-11-14 Thread Ulf Hansson
On Wed, 8 Nov 2023 at 11:44, Krzysztof Kozlowski
 wrote:
>
> Samsung Exynos SoC reuses several devices from older designs, thus
> historically we kept the old (block's) compatible only.  This works fine
> and there is no bug here, however guidelines expressed in
> Documentation/devicetree/bindings/writing-bindings.rst state that:
> 1. Compatibles should be specific.
> 2. We should add new compatibles in case of bugs or features.
>
> Add compatibles specific to each SoC in front of all old-SoC-like
> compatibles.
>
> While re-indenting the first enum, put also axis,artpec8-dw-mshc in
> alphabetical order.
>
> Signed-off-by: Krzysztof Kozlowski 

Acked-by: Ulf Hansson 

Kind regards
Uffe

>
> ---
>
> I propose to take the patch through Samsung SoC (me). See cover letter
> for explanation.
> ---
>  .../bindings/mmc/samsung,exynos-dw-mshc.yaml  | 25 ---
>  1 file changed, 16 insertions(+), 9 deletions(-)
>
> diff --git 
> a/Documentation/devicetree/bindings/mmc/samsung,exynos-dw-mshc.yaml 
> b/Documentation/devicetree/bindings/mmc/samsung,exynos-dw-mshc.yaml
> index 6ee78a38bd74..5fe65795f796 100644
> --- a/Documentation/devicetree/bindings/mmc/samsung,exynos-dw-mshc.yaml
> +++ b/Documentation/devicetree/bindings/mmc/samsung,exynos-dw-mshc.yaml
> @@ -14,15 +14,22 @@ maintainers:
>
>  properties:
>compatible:
> -enum:
> -  - samsung,exynos4210-dw-mshc
> -  - samsung,exynos4412-dw-mshc
> -  - samsung,exynos5250-dw-mshc
> -  - samsung,exynos5420-dw-mshc
> -  - samsung,exynos5420-dw-mshc-smu
> -  - samsung,exynos7-dw-mshc
> -  - samsung,exynos7-dw-mshc-smu
> -  - axis,artpec8-dw-mshc
> +oneOf:
> +  - enum:
> +  - axis,artpec8-dw-mshc
> +  - samsung,exynos4210-dw-mshc
> +  - samsung,exynos4412-dw-mshc
> +  - samsung,exynos5250-dw-mshc
> +  - samsung,exynos5420-dw-mshc
> +  - samsung,exynos5420-dw-mshc-smu
> +  - samsung,exynos7-dw-mshc
> +  - samsung,exynos7-dw-mshc-smu
> +  - items:
> +  - enum:
> +  - samsung,exynos5433-dw-mshc-smu
> +  - samsung,exynos7885-dw-mshc-smu
> +  - samsung,exynos850-dw-mshc-smu
> +  - const: samsung,exynos7-dw-mshc-smu
>
>reg:
>  maxItems: 1
> --
> 2.34.1
>


Re: [PATCH 2/6] drm: Add drm_atomic_helper_buffer_damage_{iter_init,merged}() helpers

2023-11-14 Thread Thomas Zimmermann

Hi

Am 14.11.23 um 16:58 schrieb Javier Martinez Canillas:

Thomas Zimmermann  writes:

Hello Thomas,

Thanks a lot for your feedback.


Hi

Am 09.11.23 um 18:24 schrieb Javier Martinez Canillas:

To be used by drivers that do per-buffer (e.g: virtio-gpu) uploads (rather
than per-plane uploads), since these type of drivers need to handle buffer
damages instead of frame damages.

The drm_atomic_helper_buffer_damage_iter_init() has the same logic than
drm_atomic_helper_damage_iter_init() but it also takes into account if the
framebuffer attached to plane's state has changed since the last update.

And the drm_atomic_helper_buffer_damage_merged() is just a version of the
drm_atomic_helper_damage_merged() helper, but it uses the iter_init helper
that is mentioned above.

Fixes: 01f05940a9a7 ("drm/virtio: Enable fb damage clips property for the primary 
plane")
Cc:  # v6.4+
Reported-by: nerdopolis 
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218115
Suggested-by: Sima Vetter 
Signed-off-by: Javier Martinez Canillas 
---

   drivers/gpu/drm/drm_damage_helper.c | 79 ++---
   include/drm/drm_damage_helper.h |  7 +++
   2 files changed, 80 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_damage_helper.c 
b/drivers/gpu/drm/drm_damage_helper.c
index aa2325567918..b72062c9d31c 100644
--- a/drivers/gpu/drm/drm_damage_helper.c
+++ b/drivers/gpu/drm/drm_damage_helper.c
@@ -204,7 +204,8 @@ EXPORT_SYMBOL(drm_atomic_helper_dirtyfb);
   static void
   __drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter 
*iter,
 const struct drm_plane_state *old_state,
-const struct drm_plane_state *state)
+const struct drm_plane_state *state,
+bool buffer_damage)


I think it would be preferable to drop patches one and two and instead
add this parameter directly to drm_atomic_helper_damage_iter_init() and
drm_atomic_helper_damage_merged().  That's a bit of churn, but more
readable code.



Makes sense. I'll do that in v2.


Instead of modifying these function interfaces, it might be even better 
to introduce a state flag in struct drm_plane_state that you can modify 
in the plane's atomic_check helper. Something simple like this:


  if (old_fb != new_fb)
plane_state->ignore_damage_clips = true;

in the affected drivers/planes. In drm_atomic_helper_damage_iter_init() 
you can use it to generate a full update. This avoids the churn and is 
in line with the overall check/commit design of the DRM framework.


Best regards
Thomas




Best regards
Thomas





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


OpenPGP_signature.asc
Description: OpenPGP digital signature


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

2023-11-14 Thread Dmitry Baryshkov
On Tue, 14 Nov 2023 at 17:09, Sui Jingfeng  wrote:
>
> From: Sui Jingfeng 
>
> The it66121_create_bridge() and it66121_destroy_bridge() are added to
> export the core functionalities. Create a connector manually by using
> bridge connector helpers when link as a lib.
>
> Signed-off-by: Sui Jingfeng 
> ---
>  drivers/gpu/drm/bridge/ite-it66121.c | 134 +++
>  include/drm/bridge/ite-it66121.h |  17 
>  2 files changed, 113 insertions(+), 38 deletions(-)
>  create mode 100644 include/drm/bridge/ite-it66121.h
>
> diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
> b/drivers/gpu/drm/bridge/ite-it66121.c
> index 8971414a2a60..f5968b679c5d 100644
> --- a/drivers/gpu/drm/bridge/ite-it66121.c
> +++ b/drivers/gpu/drm/bridge/ite-it66121.c
> @@ -22,6 +22,7 @@
>
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -703,14 +704,32 @@ static int it66121_bridge_attach(struct drm_bridge 
> *bridge,
>  enum drm_bridge_attach_flags flags)
>  {
> struct it66121_ctx *ctx = bridge_to_it66121(bridge);
> +   struct drm_bridge *next_bridge = ctx->next_bridge;
> +   struct drm_encoder *encoder = bridge->encoder;
> int ret;
>
> -   if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
> -   return -EINVAL;
> +   if (next_bridge) {
> +   if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
> +   WARN_ON(1);

Why? At least use WARN() instead

> +   flags |= DRM_BRIDGE_ATTACH_NO_CONNECTOR;
> +   }
> +   ret = drm_bridge_attach(encoder, next_bridge, bridge, flags);
> +   if (ret)
> +   return ret;
> +   } else {
> +   struct drm_connector *connector;
>
> -   ret = drm_bridge_attach(bridge->encoder, ctx->next_bridge, bridge, 
> flags);
> -   if (ret)
> -   return ret;
> +   if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
> +   WARN_ON(1);

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

> +
> +   connector = drm_bridge_connector_init(bridge->dev, encoder);
> +   if (IS_ERR(connector))
> +   return PTR_ERR(connector);
> +
> +   drm_connector_attach_encoder(connector, encoder);

This goes into your device driver.

> +
> +   ctx->connector = connector;
> +   }
>
> if (ctx->info->id == ID_IT66121) {
> ret = regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG,
> @@ -1632,16 +1651,13 @@ static const char * const it66121_supplies[] = {
> "vcn33", "vcn18", "vrf12"
>  };
>
> -static int it66121_probe(struct i2c_client *client)
> +int it66121_create_bridge(struct i2c_client *client, bool of_support,
> + bool hpd_support, bool audio_support,
> + struct drm_bridge **bridge)
>  {
> +   struct device *dev = >dev;
> int ret;
> struct it66121_ctx *ctx;
> -   struct device *dev = >dev;
> -
> -   if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
> -   dev_err(dev, "I2C check functionality failed.\n");
> -   return -ENXIO;
> -   }
>
> ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> if (!ctx)
> @@ -1649,24 +1665,19 @@ static int it66121_probe(struct i2c_client *client)
>
> ctx->dev = dev;
> ctx->client = client;
> -   ctx->info = i2c_get_match_data(client);
> -
> -   ret = it66121_of_read_bus_width(dev, >bus_width);
> -   if (ret)
> -   return ret;
> -
> -   ret = it66121_of_get_next_bridge(dev, >next_bridge);
> -   if (ret)
> -   return ret;
> -
> -   i2c_set_clientdata(client, ctx);
> mutex_init(>lock);
>
> -   ret = devm_regulator_bulk_get_enable(dev, 
> ARRAY_SIZE(it66121_supplies),
> -it66121_supplies);
> -   if (ret) {
> -   dev_err(dev, "Failed to enable power supplies\n");
> -   return ret;
> +   if (of_support) {
> +   ret = it66121_of_read_bus_width(dev, >bus_width);
> +   if (ret)
> +   return ret;
> +
> +   ret = it66121_of_get_next_bridge(dev, >next_bridge);
> +   if (ret)
> +   return ret;
> +   } else {
> +   ctx->bus_width = 24;
> +   ctx->next_bridge = NULL;
> }

A better alternative would be to turn OF calls into fwnode calls and
to populate the fwnode properties. See
drivers/platform/x86/intel/chtwc_int33fe.c for example.

>
> it66121_hw_reset(ctx);
> @@ -1679,33 +1690,80 @@ static int it66121_probe(struct i2c_client *client)
> if (ret)
> return ret;
>
> -   if (ctx->vender_id != ctx->info->vid ||
> -   ctx->device_id != 

Re: [PATCH 0/6] drm: Allow the damage helpers to handle buffer damage

2023-11-14 Thread Javier Martinez Canillas
Thomas Zimmermann  writes:

> Hi Javier
>
> Am 09.11.23 um 18:24 schrieb Javier Martinez Canillas:
>> Hello,
>> 
>> This series is to fix an issue that surfaced after damage clipping was
>> enabled for the virtio-gpu by commit 01f05940a9a7 ("drm/virtio: Enable
>> fb damage clips property for the primary plane").
>> 
>> After that change, flickering artifacts was reported to be present with
>> both weston and wlroots wayland compositors when running in a virtual
>> machine. The cause was identified by Sima Vetter, who pointed out that
>> virtio-gpu does per-buffer uploads and for this reason it needs to do
>> a buffer damage handling, instead of frame damage handling.
>
> I'm having problem understanding the types of damage. You never say what 
> buffer damage is. I also don't know what a frame is in this context.
>
> Regular damage handling marks parts of a plane as dirty/damaged. That is 
> per-plane damage handling. The individual planes more or less 
> independent from each other.
>
> Buffer damage, I guess, marks the underlying buffer as dirty and 
> requires synchronization of the buffer with some backing storage. The 
> planes using that buffer are then updated more or less automatically.
>
> Is that right?
>

In both cases the damage tracking information is the same, they mark
the damaged regions on the plane in framebuffer coordinates of the
framebuffer attached to the plane.

The problem as far as I understand is whether the driver expects that
to determine the area that changed in the plane (and a plane flush is
enough) or the area that changed since that same buffer was last used.

> And why does it flicker? Is there old data stored somewhere?
>

It flickers because the framebuffer changed and so the damage tracking
is not used correctly to flush the damaged areas to the backing storage.

This is my understanding at least, please Sima or Simon correct me if I
got this wrong.

> Best regards
> Thomas
>

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



Re: [PATCH] drm/nouveau: Prevents NULL pointer dereference in nouveau_uvmm_sm_prepare

2023-11-14 Thread Danilo Krummrich

Hi Yuran,

On 10/26/23 19:03, Yuran Pereira wrote:

There are instances where the "args" argument passed to
nouveau_uvmm_sm_prepare() is NULL.

I.e. when nouveau_uvmm_sm_prepare() is called from
nouveau_uvmm_sm_unmap_prepare()

```
static int
nouveau_uvmm_sm_unmap_prepare(struct nouveau_uvmm *uvmm,
...
{
 return nouveau_uvmm_sm_prepare(uvmm, new, ops, NULL);
}
```

The problem is that op_map_prepare() which nouveau_uvmm_sm_prepare
calls, dereferences this value, which can lead to a NULL pointer
dereference.


op_map_prepare() can't be called with `args` being NULL, since when called
through nouveau_uvmm_sm_unmap_prepare() we can't hit the DRM_GPUVA_OP_MAP
case at all.

Unmapping something never leads to a new mapping being created, it can lead
to remaps though.



```
static int
op_map_prepare(struct nouveau_uvmm *uvmm,
...
{
 ...
 uvma->region = args->region; <-- Dereferencing of possibly NULL pointer
 uvma->kind = args->kind; <--
 ...
}
```

```
static int
nouveau_uvmm_sm_prepare(struct nouveau_uvmm *uvmm,
...
 struct uvmm_map_args *args)
{
 struct drm_gpuva_op *op;
 u64 vmm_get_start = args ? args->addr : 0;
 u64 vmm_get_end = args ? args->addr + args->range : 0;
 int ret;

 drm_gpuva_for_each_op(op, ops) {
 switch (op->op) {
 case DRM_GPUVA_OP_MAP: {
 u64 vmm_get_range = vmm_get_end - vmm_get_start;

 ret = op_map_prepare(uvmm, >map, >map, args); <---
 if (ret)
 goto unwind;

 if (args && vmm_get_range) {
 ret = nouveau_uvmm_vmm_get(uvmm, vmm_get_start,
vmm_get_range);
 if (ret) {
 op_map_prepare_unwind(new->map);
 goto unwind;
 }
 }
 ...
```

Since the switch "case DRM_GPUVA_OP_MAP", also NULL checks "args"


This check is not required for the reason given above. If you like, you
can change this patch up to remove the args check and add a comment like:

/* args can't be NULL when called for a map operation. */


after the call to op_map_prepare(), my guess is that we should
probably relocate this check to a point before op_map_prepare()
is called.


Yeah, I see how this unnecessary check made you think so.

- Danilo



This patch ensures that the value of args is checked before
calling op_map_prepare()

Addresses-Coverity-ID: 1544574 ("Dereference after null check")
Signed-off-by: Yuran Pereira 
---
  drivers/gpu/drm/nouveau/nouveau_uvmm.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c 
b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
index aae780e4a4aa..6baa481eb2c8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
@@ -620,11 +620,14 @@ nouveau_uvmm_sm_prepare(struct nouveau_uvmm *uvmm,
case DRM_GPUVA_OP_MAP: {
u64 vmm_get_range = vmm_get_end - vmm_get_start;
  
+			if (!args)

+   goto unwind;
+
ret = op_map_prepare(uvmm, >map, >map, args);
if (ret)
goto unwind;
  
-			if (args && vmm_get_range) {

+   if (vmm_get_range) {
ret = nouveau_uvmm_vmm_get(uvmm, vmm_get_start,
   vmm_get_range);
if (ret) {




[PATCH v1 1/1] drm/i915/gt: Dont wait forever when idling in suspend

2023-11-14 Thread Alan Previn
When suspending, add a timeout when calling
intel_gt_pm_wait_for_idle else if we have a leaked
wakeref (which would be indicative of a bug elsewhere
in the driver), driver will at exit the suspend-resume
cycle, after the kernel detects the held reference and
prints a message to abort suspending instead of hanging
in the kernel forever which then requires serial connection
or ramoops dump to debug further.

Signed-off-by: Alan Previn 
Reviewed-by: Rodrigo Vivi 
Tested-by: Mousumi Jana 
---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c |  2 +-
 drivers/gpu/drm/i915/gt/intel_gt_pm.c |  7 ++-
 drivers/gpu/drm/i915/gt/intel_gt_pm.h |  7 ++-
 drivers/gpu/drm/i915/intel_wakeref.c  | 14 ++
 drivers/gpu/drm/i915/intel_wakeref.h  |  6 --
 5 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 40687806d22a..ffef963037f2 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -686,7 +686,7 @@ void intel_engines_release(struct intel_gt *gt)
if (!engine->release)
continue;
 
-   intel_wakeref_wait_for_idle(>wakeref);
+   intel_wakeref_wait_for_idle(>wakeref, 0);
GEM_BUG_ON(intel_engine_pm_is_awake(engine));
 
engine->release(engine);
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c 
b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index f5899d503e23..25cb39ba9fdf 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -306,6 +306,8 @@ int intel_gt_resume(struct intel_gt *gt)
 
 static void wait_for_suspend(struct intel_gt *gt)
 {
+   int final_timeout_ms = (I915_GT_SUSPEND_IDLE_TIMEOUT * 10);
+
if (!intel_gt_pm_is_awake(gt))
return;
 
@@ -318,7 +320,10 @@ static void wait_for_suspend(struct intel_gt *gt)
intel_gt_retire_requests(gt);
}
 
-   intel_gt_pm_wait_for_idle(gt);
+   /* we are suspending, so we shouldn't be waiting forever */
+   if (intel_gt_pm_wait_timeout_for_idle(gt, final_timeout_ms) == 
-ETIMEDOUT)
+   gt_warn(gt, "bailing from %s after %d milisec timeout\n",
+   __func__, final_timeout_ms);
 }
 
 void intel_gt_suspend_prepare(struct intel_gt *gt)
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.h 
b/drivers/gpu/drm/i915/gt/intel_gt_pm.h
index b1eeb5b33918..1757ca4c3077 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.h
@@ -68,7 +68,12 @@ static inline void intel_gt_pm_might_put(struct intel_gt *gt)
 
 static inline int intel_gt_pm_wait_for_idle(struct intel_gt *gt)
 {
-   return intel_wakeref_wait_for_idle(>wakeref);
+   return intel_wakeref_wait_for_idle(>wakeref, 0);
+}
+
+static inline int intel_gt_pm_wait_timeout_for_idle(struct intel_gt *gt, int 
timeout_ms)
+{
+   return intel_wakeref_wait_for_idle(>wakeref, timeout_ms);
 }
 
 void intel_gt_pm_init_early(struct intel_gt *gt);
diff --git a/drivers/gpu/drm/i915/intel_wakeref.c 
b/drivers/gpu/drm/i915/intel_wakeref.c
index 623a69089386..f2611c65246b 100644
--- a/drivers/gpu/drm/i915/intel_wakeref.c
+++ b/drivers/gpu/drm/i915/intel_wakeref.c
@@ -113,14 +113,20 @@ void __intel_wakeref_init(struct intel_wakeref *wf,
 "wakeref.work", >work, 0);
 }
 
-int intel_wakeref_wait_for_idle(struct intel_wakeref *wf)
+int intel_wakeref_wait_for_idle(struct intel_wakeref *wf, int timeout_ms)
 {
-   int err;
+   int err = 0;
 
might_sleep();
 
-   err = wait_var_event_killable(>wakeref,
- !intel_wakeref_is_active(wf));
+   if (!timeout_ms)
+   err = wait_var_event_killable(>wakeref,
+ !intel_wakeref_is_active(wf));
+   else if (wait_var_event_timeout(>wakeref,
+   !intel_wakeref_is_active(wf),
+   msecs_to_jiffies(timeout_ms)) < 1)
+   err = -ETIMEDOUT;
+
if (err)
return err;
 
diff --git a/drivers/gpu/drm/i915/intel_wakeref.h 
b/drivers/gpu/drm/i915/intel_wakeref.h
index ec881b097368..302694a780d2 100644
--- a/drivers/gpu/drm/i915/intel_wakeref.h
+++ b/drivers/gpu/drm/i915/intel_wakeref.h
@@ -251,15 +251,17 @@ __intel_wakeref_defer_park(struct intel_wakeref *wf)
 /**
  * intel_wakeref_wait_for_idle: Wait until the wakeref is idle
  * @wf: the wakeref
+ * @timeout_ms: Timeout in ms, 0 means never timeout.
  *
  * Wait for the earlier asynchronous release of the wakeref. Note
  * this will wait for any third party as well, so make sure you only wait
  * when you have control over the wakeref and trust no one else is acquiring
  * it.
  *
- * Return: 0 on success, error code if killed.
+ * Returns 0 on success, -ETIMEDOUT upon a timeout, or the unlikely
+ * 

Re: [RFC PATCH v2] drm/test: add a test suite for GEM objects backed by shmem

2023-11-14 Thread Marco Pagani



On 2023-11-10 15:41, Maxime Ripard wrote:
> On Wed, Nov 08, 2023 at 02:42:03PM +0100, Marco Pagani wrote:
>> This patch introduces an initial KUnit test suite for GEM objects
>> backed by shmem buffers.
>>
>> Suggested-by: Javier Martinez Canillas 
>> Signed-off-by: Marco Pagani 
>>
>> v2:
>> - Improved description of test cases
>> - Cleaner error handling using KUnit actions
>> - Alphabetical order in Kconfig and Makefile
>> ---
>>  drivers/gpu/drm/Kconfig|   9 +-
>>  drivers/gpu/drm/tests/Makefile |   5 +-
>>  drivers/gpu/drm/tests/drm_gem_shmem_test.c | 381 +
>>  3 files changed, 389 insertions(+), 6 deletions(-)
>>  create mode 100644 drivers/gpu/drm/tests/drm_gem_shmem_test.c
>>
>> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
>> index 3eee8636f847..a2551c8c393a 100644
>> --- a/drivers/gpu/drm/Kconfig
>> +++ b/drivers/gpu/drm/Kconfig
>> @@ -76,14 +76,15 @@ config DRM_KUNIT_TEST
>>  tristate "KUnit tests for DRM" if !KUNIT_ALL_TESTS
>>  depends on DRM && KUNIT
>>  select PRIME_NUMBERS
>> +select DRM_BUDDY
>>  select DRM_DISPLAY_DP_HELPER
>>  select DRM_DISPLAY_HELPER
>> -select DRM_LIB_RANDOM
>> -select DRM_KMS_HELPER
>> -select DRM_BUDDY
>> +select DRM_EXEC
>>  select DRM_EXPORT_FOR_TESTS if m
>> +select DRM_GEM_SHMEM_HELPER
>> +select DRM_KMS_HELPER
>>  select DRM_KUNIT_TEST_HELPERS
>> -select DRM_EXEC
>> +select DRM_LIB_RANDOM
>>  default KUNIT_ALL_TESTS
>>  help
>>This builds unit tests for DRM. This option is not useful for
>> diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile
>> index ba7baa622675..d6183b3d7688 100644
>> --- a/drivers/gpu/drm/tests/Makefile
>> +++ b/drivers/gpu/drm/tests/Makefile
>> @@ -9,15 +9,16 @@ obj-$(CONFIG_DRM_KUNIT_TEST) += \
>>  drm_connector_test.o \
>>  drm_damage_helper_test.o \
>>  drm_dp_mst_helper_test.o \
>> +drm_exec_test.o \
>>  drm_format_helper_test.o \
>>  drm_format_test.o \
>>  drm_framebuffer_test.o \
>> +drm_gem_shmem_test.o \
>>  drm_managed_test.o \
>>  drm_mm_test.o \
>>  drm_modes_test.o \
>>  drm_plane_helper_test.o \
>>  drm_probe_helper_test.o \
>> -drm_rect_test.o \
>> -drm_exec_test.o
>> +drm_rect_test.o
> 
> Thanks for reordering the tests and symbols, but they should part of a
> preliminary patch.
> 

Okay, I'll send it as a separate patch before v3.


>>  CFLAGS_drm_mm_test.o := $(DISABLE_STRUCTLEAK_PLUGIN)
>> diff --git a/drivers/gpu/drm/tests/drm_gem_shmem_test.c 
>> b/drivers/gpu/drm/tests/drm_gem_shmem_test.c
>> new file mode 100644
>> index ..983380490673
>> --- /dev/null
>> +++ b/drivers/gpu/drm/tests/drm_gem_shmem_test.c
>> @@ -0,0 +1,381 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * KUnit test suite for GEM objects backed by shmem buffers
>> + *
>> + * Copyright (C) 2023 Red Hat, Inc.
>> + *
>> + * Author: Marco Pagani 
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#include 
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#define TEST_SIZE   SZ_1M
>> +#define TEST_BYTE   0xae
>> +
>> +struct fake_dev {
>> +struct drm_device drm_dev;
>> +struct device *dev;
> 
> AFAICS, you're not using the dev pointer anywhere. You could remove the
> fake_dev struct entirely and pass the drm_device pointer in test->priv
>

Nice catch, thanks! It's a leftover from the previous version, where it
was used in the .exit function to free the parent dev. I'll drop it in v3.

>> +};
>> +
>> +/*
>> + * Wrappers to avoid an explicit type casting when passing action
>> + * functions to kunit_add_action().
>> + */
>> +static void kfree_wrapper(void *p)
>> +{
>> +kfree(p);
>> +}
>> +
>> +static void sg_free_table_wrapper(void *sgt)
>> +{
>> +sg_free_table(sgt);
>> +}
>> +
>> +static void drm_gem_shmem_free_wrapper(void *shmem)
>> +{
>> +drm_gem_shmem_free(shmem);
>> +}
> 
> I think you need to explicitly cast the pointer (or do a temporary
> assignment to the proper type) to avoid a compiler warning.
> 

Do you mean like:

static void drm_gem_shmem_free_wrapper(void *shmem)
{
drm_gem_shmem_free((struct drm_gem_shmem_object *)shmem);
}

I built the current version with clang 16.0.6 and gcc 13.2.1 but got
no cast warnings. Clang spotted an uninitialized variable, though.

>> +/*
>> + * Test creating a shmem GEM object backed by shmem buffer. The test
>> + * case succeeds if the GEM object is successfully allocated with the
>> + * shmem file node and object functions attributes set, and the size
>> + * attribute is equal to the correct size.
>> + */
> 
> Thanks for all those comments, it's super helpful
> 
>> +static void drm_gem_shmem_test_obj_create(struct kunit *test)
>> +{
>> +struct fake_dev *fdev = test->priv;
>> +struct drm_gem_shmem_object *shmem;
>> +
>> +shmem = 

Re: [RFC PATCH v3 05/12] netdev: netdevice devmem allocator

2023-11-14 Thread Pavel Begunkov

On 11/11/23 17:19, David Ahern wrote:

On 11/10/23 7:26 AM, Pavel Begunkov wrote:

On 11/7/23 23:03, Mina Almasry wrote:

On Tue, Nov 7, 2023 at 2:55 PM David Ahern  wrote:


On 11/7/23 3:10 PM, Mina Almasry wrote:

On Mon, Nov 6, 2023 at 3:44 PM David Ahern  wrote:


On 11/5/23 7:44 PM, Mina Almasry wrote:

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index eeeda849115c..1c351c138a5b 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -843,6 +843,9 @@ struct netdev_dmabuf_binding {
   };

   #ifdef CONFIG_DMA_SHARED_BUFFER
+struct page_pool_iov *
+netdev_alloc_devmem(struct netdev_dmabuf_binding *binding);
+void netdev_free_devmem(struct page_pool_iov *ppiov);


netdev_{alloc,free}_dmabuf?



Can do.


I say that because a dmabuf can be host memory, at least I am not
aware
of a restriction that a dmabuf is device memory.



In my limited experience dma-buf is generally device memory, and
that's really its use case. CONFIG_UDMABUF is a driver that mocks
dma-buf with a memfd which I think is used for testing. But I can do
the rename, it's more clear anyway, I think.


config UDMABUF
  bool "userspace dmabuf misc driver"
  default n
  depends on DMA_SHARED_BUFFER
  depends on MEMFD_CREATE || COMPILE_TEST
  help
    A driver to let userspace turn memfd regions into dma-bufs.
    Qemu can use this to create host dmabufs for guest
framebuffers.


Qemu is just a userspace process; it is no way a special one.

Treating host memory as a dmabuf should radically simplify the io_uring
extension of this set.


I agree actually, and I was about to make that comment to David Wei's
series once I have the time.

David, your io_uring RX zerocopy proposal actually works with devmem
TCP, if you're inclined to do that instead, what you'd do roughly is
(I think):

That would be a Frankenstein's monster api with no good reason for it.


It brings a consistent API from a networking perspective.

io_uring should not need to be in the page pool and memory management
business. Have you or David coded up the re-use of the socket APIs with
dmabuf to see how much smaller it makes the io_uring change - or even
walked through from a theoretical perspective?


Yes, we did the mental exercise, which is why we're converting to pp.
I don't see many opportunities for reuse for the main data path,
potentially apart from using the iov format instead of pages.

If the goal is to minimise the amount of code, it can mimic the tcp
devmem api with netlink, ioctl-ish buffer return, but that'd be a
pretty bad api for io_uring, overly complicated and limiting
optimisation options. If not, then we have to do some buffer
management in io_uring, and I don't see anything wrong with that. It
shouldn't be a burden for networking if all that extra code is
contained in io_uring and only exposed via pp ops and following
the rules.

--
Pavel Begunkov


Re: [PATCH 6/8] drm/bridge: it66121: Add a helper to initialize the DRM bridge structure

2023-11-14 Thread Dmitry Baryshkov
On Tue, 14 Nov 2023 at 17:09, Sui Jingfeng  wrote:
>
> From: Sui Jingfeng 
>
> Helps the it66121_probe() function to reduce weight, no functional change.

This is not a proper commit message.

>
> Signed-off-by: Sui Jingfeng 
> ---
>  drivers/gpu/drm/bridge/ite-it66121.c | 24 +---
>  1 file changed, 17 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
> b/drivers/gpu/drm/bridge/ite-it66121.c
> index f36d05331f25..2f7f00f1bedb 100644
> --- a/drivers/gpu/drm/bridge/ite-it66121.c
> +++ b/drivers/gpu/drm/bridge/ite-it66121.c
> @@ -1004,6 +1004,21 @@ static const struct drm_bridge_funcs 
> it66121_bridge_funcs = {
> .hpd_disable = it66121_bridge_hpd_disable,
>  };
>
> +static void it66121_bridge_init_base(struct drm_bridge *bridge,
> +struct device_node *of_node,
> +bool hpd_support)

At this point there is no reason for the bridge to miss HPD support.

> +{
> +   bridge->funcs = _bridge_funcs;
> +   bridge->type = DRM_MODE_CONNECTOR_HDMIA;
> +   bridge->ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID;
> +   if (hpd_support)
> +   bridge->ops |= DRM_BRIDGE_OP_HPD;
> +
> +   bridge->of_node = of_node;
> +
> +   drm_bridge_add(bridge);
> +}
> +
>  static irqreturn_t it66121_irq_threaded_handler(int irq, void *dev_id)
>  {
> int ret;
> @@ -1637,11 +1652,6 @@ static int it66121_probe(struct i2c_client *client)
> ctx->device_id != ctx->info->pid)
> return -ENODEV;
>
> -   ctx->bridge.funcs = _bridge_funcs;
> -   ctx->bridge.of_node = dev->of_node;
> -   ctx->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
> -   ctx->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | 
> DRM_BRIDGE_OP_HPD;
> -
> ret = devm_request_threaded_irq(dev, client->irq, NULL, 
> it66121_irq_threaded_handler,
> IRQF_ONESHOT, dev_name(dev), ctx);
> if (ret < 0) {
> @@ -1649,9 +1659,9 @@ static int it66121_probe(struct i2c_client *client)
> return ret;
> }
>
> -   it66121_audio_codec_init(ctx, dev);
> +   it66121_bridge_init_base(>bridge, dev->of_node, true);
>
> -   drm_bridge_add(>bridge);
> +   it66121_audio_codec_init(ctx, dev);
>
> dev_info(dev, "IT66121 probed, chip id: 0x%x:0x%x, revision: %u\n",
>  ctx->vender_id, ctx->device_id, ctx->revision);
> --
> 2.34.1
>


-- 
With best wishes
Dmitry


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

2023-11-14 Thread Dmitry Baryshkov
On Tue, 14 Nov 2023 at 17:09, Sui Jingfeng  wrote:
>
> From: Sui Jingfeng 
>
> Read the required chip id data back by calling regmap_bulk_read() once,
> reduce the number of local variables needed in it66121_probe() function.
> And store its values into struct it66121_ctx, as it will be used latter.
>
> Signed-off-by: Sui Jingfeng 
> ---
>  drivers/gpu/drm/bridge/ite-it66121.c | 47 
>  1 file changed, 34 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
> b/drivers/gpu/drm/bridge/ite-it66121.c
> index 7e473beefc79..f36d05331f25 100644
> --- a/drivers/gpu/drm/bridge/ite-it66121.c
> +++ b/drivers/gpu/drm/bridge/ite-it66121.c
> @@ -313,6 +313,9 @@ struct it66121_ctx {
> bool auto_cts;
> } audio;
> const struct it66121_chip_info *info;
> +   u16 vender_id;
> +   u16 device_id;
> +   u8 revision;

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

>  };
>
>  static inline struct it66121_ctx *bridge_to_it66121(struct drm_bridge 
> *bridge)
> @@ -399,6 +402,30 @@ static void it66121_hw_reset(struct it66121_ctx *ctx)
> gpiod_set_value(ctx->gpio_reset, 0);
>  }
>
> +static int it66121_read_chip_id(struct it66121_ctx *ctx, bool verbose)
> +{
> +   u8 id[4];
> +   int ret;
> +
> +   ret = regmap_bulk_read(ctx->regmap, IT66121_VENDOR_ID0_REG, id, 4);
> +   if (ret < 0) {
> +   dev_err(ctx->dev, "Failed to read chip ID: %d\n", ret);
> +   return ret;
> +   }
> +
> +   ctx->vender_id = (u16)id[1] << 8 | id[0];
> +   ctx->device_id = ((u16)(id[3] & IT66121_DEVICE_ID1_MASK) << 8 | 
> id[2]);
> +   /* Revision is shared with DEVICE_ID1 */
> +   ctx->revision = FIELD_GET(IT66121_REVISION_MASK, id[3]);
> +
> +   if (verbose) {
> +   dev_info(ctx->dev, "Found ITE66121: 0x%x%x, revision: %u\n",
> +ctx->vender_id, ctx->device_id, ctx->revision);
> +   }
> +
> +   return 0;
> +}
> +
>  static inline int it66121_preamble_ddc(struct it66121_ctx *ctx)
>  {
> return regmap_write(ctx->regmap, IT66121_MASTER_SEL_REG, 
> IT66121_MASTER_SEL_HOST);
> @@ -1561,7 +1588,6 @@ static const char * const it66121_supplies[] = {
>
>  static int it66121_probe(struct i2c_client *client)
>  {
> -   u32 revision_id, vendor_ids[2] = { 0 }, device_ids[2] = { 0 };
> int ret;
> struct it66121_ctx *ctx;
> struct device *dev = >dev;
> @@ -1603,19 +1629,13 @@ static int it66121_probe(struct i2c_client *client)
> if (IS_ERR(ctx->regmap))
> return PTR_ERR(ctx->regmap);
>
> -   regmap_read(ctx->regmap, IT66121_VENDOR_ID0_REG, _ids[0]);
> -   regmap_read(ctx->regmap, IT66121_VENDOR_ID1_REG, _ids[1]);
> -   regmap_read(ctx->regmap, IT66121_DEVICE_ID0_REG, _ids[0]);
> -   regmap_read(ctx->regmap, IT66121_DEVICE_ID1_REG, _ids[1]);
> -
> -   /* Revision is shared with DEVICE_ID1 */
> -   revision_id = FIELD_GET(IT66121_REVISION_MASK, device_ids[1]);
> -   device_ids[1] &= IT66121_DEVICE_ID1_MASK;
> +   ret = it66121_read_chip_id(ctx, false);
> +   if (ret)
> +   return ret;
>
> -   if ((vendor_ids[1] << 8 | vendor_ids[0]) != ctx->info->vid ||
> -   (device_ids[1] << 8 | device_ids[0]) != ctx->info->pid) {
> +   if (ctx->vender_id != ctx->info->vid ||
> +   ctx->device_id != ctx->info->pid)
> return -ENODEV;
> -   }
>
> ctx->bridge.funcs = _bridge_funcs;
> ctx->bridge.of_node = dev->of_node;
> @@ -1633,7 +1653,8 @@ static int it66121_probe(struct i2c_client *client)
>
> drm_bridge_add(>bridge);
>
> -   dev_info(dev, "IT66121 revision %d probed\n", revision_id);
> +   dev_info(dev, "IT66121 probed, chip id: 0x%x:0x%x, revision: %u\n",
> +ctx->vender_id, ctx->device_id, ctx->revision);
>
> return 0;
>  }
> --
> 2.34.1
>


-- 
With best wishes
Dmitry


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

2023-11-14 Thread Dmitry Baryshkov
On Tue, 14 Nov 2023 at 17:09, Sui Jingfeng  wrote:
>
> From: Sui Jingfeng 
>
> Group the code lines(which with the same functional) into one dedicated
> function, which reduce the weight of it66121_probe() function. Just trivial
> cleanuo, no functional change.
>
> Signed-off-by: Sui Jingfeng 
> ---
>  drivers/gpu/drm/bridge/ite-it66121.c | 53 ++--
>  1 file changed, 34 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
> b/drivers/gpu/drm/bridge/ite-it66121.c
> index 0f78737adc83..7e473beefc79 100644
> --- a/drivers/gpu/drm/bridge/ite-it66121.c
> +++ b/drivers/gpu/drm/bridge/ite-it66121.c
> @@ -340,6 +340,37 @@ static int it66121_of_read_bus_width(struct device *dev, 
> u32 *bus_width)
> return 0;
>  }
>
> +static int it66121_of_get_next_bridge(struct device *dev,
> + struct drm_bridge **next_bridge)

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

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


-- 
With best wishes
Dmitry


Re: [PATCH 2/6] drm: Add drm_atomic_helper_buffer_damage_{iter_init, merged}() helpers

2023-11-14 Thread Javier Martinez Canillas
Thomas Zimmermann  writes:

> Hi
>
> Am 09.11.23 um 18:24 schrieb Javier Martinez Canillas:

[...]

>>  struct drm_rect src;
>>  memset(iter, 0, sizeof(*iter));
>> @@ -223,7 +224,8 @@ __drm_atomic_helper_damage_iter_init(struct 
>> drm_atomic_helper_damage_iter *iter,
>>  iter->plane_src.x2 = (src.x2 >> 16) + !!(src.x2 & 0x);
>>  iter->plane_src.y2 = (src.y2 >> 16) + !!(src.y2 & 0x);
>>   
>> -if (!iter->clips || !drm_rect_equals(>src, _state->src)) {
>> +if (!iter->clips || !drm_rect_equals(>src, _state->src) ||
>> +(buffer_damage && old_state->fb != state->fb)) {
>
> I'd assume that this change effectivly disables damage handling. AFAICT 
> user space often does a page flip with a new framebuffer plus damage 
> data. Now, with each change of the framebuffer we ignore the damage 
> information. It's not a blocker as that's the behavior before 6.4, but 
> we should be aware of it.
>

Yes, which is the goal of this patch since page flip with a new framebuffer
attached to a plane plus damage information can't be supported by drivers
that do per-buffer uploads.

This was causing some weston and wlroots to have flickering artifacts, due
the framebuffers being changed since the last plane update.

For now it was decided with Sima, Simon and Pekka that is the best we can
do and the reason why I add a TODO in patch #6.

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



Re: [PATCH 3/8] drm/bridge: it66121: Add a helper function to read bus width

2023-11-14 Thread Dmitry Baryshkov
On Tue, 14 Nov 2023 at 17:09, Sui Jingfeng  wrote:
>
> From: Sui Jingfeng 
>
> Group those relavent code lines (which with common purpose) into one helper
> function, suppress the dependency on DT to function level. Just trivial
> cleanup, no functional change.
>
> Signed-off-by: Sui Jingfeng 
> ---
>  drivers/gpu/drm/bridge/ite-it66121.c | 32 
>  1 file changed, 23 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
> b/drivers/gpu/drm/bridge/ite-it66121.c
> index 83dbdbfc9ed8..0f78737adc83 100644
> --- a/drivers/gpu/drm/bridge/ite-it66121.c
> +++ b/drivers/gpu/drm/bridge/ite-it66121.c
> @@ -320,6 +320,26 @@ static inline struct it66121_ctx 
> *bridge_to_it66121(struct drm_bridge *bridge)
> return container_of(bridge, struct it66121_ctx, bridge);
>  }
>
> +static int it66121_of_read_bus_width(struct device *dev, u32 *bus_width)

Using a pointer to return int value doesn't look right. Just return a
signed int here and if it is not an error, assign it to ctx->bus_width

> +{
> +   struct device_node *np;
> +   u32 bw;
> +
> +   np = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0);
> +   if (!np)
> +   return -EINVAL;
> +
> +   of_property_read_u32(np, "bus-width", );
> +   of_node_put(np);
> +
> +   if (bw != 12 && bw != 24)
> +   return -EINVAL;
> +
> +   *bus_width = bw;
> +
> +   return 0;
> +}
> +
>  static const struct regmap_range_cfg it66121_regmap_banks[] = {
> {
> .name = "it66121",
> @@ -1525,19 +1545,13 @@ static int it66121_probe(struct i2c_client *client)
> if (!ctx)
> return -ENOMEM;
>
> -   ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0);
> -   if (!ep)
> -   return -EINVAL;
> -
> ctx->dev = dev;
> ctx->client = client;
> ctx->info = i2c_get_match_data(client);
>
> -   of_property_read_u32(ep, "bus-width", >bus_width);
> -   of_node_put(ep);
> -
> -   if (ctx->bus_width != 12 && ctx->bus_width != 24)
> -   return -EINVAL;
> +   ret = it66121_of_read_bus_width(dev, >bus_width);
> +   if (ret)
> +   return ret;
>
> ep = of_graph_get_remote_node(dev->of_node, 1, -1);
> if (!ep) {
> --
> 2.34.1
>


-- 
With best wishes
Dmitry


Re: [PATCH 1/2] drm: Add DRM-managed alloc_workqueue() and alloc_ordered_workqueue()

2023-11-14 Thread Jeffrey Hugo

On 1/17/2023 8:24 PM, Jiasheng Jiang wrote:

On Tue, Jan 10, 2023 at 11:24:47PM +0800, Jiasheng Jiang wrote:

Add drmm_alloc_workqueue() and drmm_alloc_ordered_workqueue(), the helpers
that provide managed workqueue cleanup. The workqueue will be destroyed
with the final reference of the DRM device.

Signed-off-by: Jiasheng Jiang 


Yeah I think this looks nice.

Reviewed-by: Daniel Vetter 

I'm assuming driver maintainers will pick this up, if not please holler.

Also the threading seems broken, it's not a patch series. The b4 tool or
git send-email (of all the patches of the entire series at once, not each
individually) should get this right.

Unfortunately I did't find the right link in the kernel docs, or at least
they're not as detailed as I hoped.

Also your previous submission had iirc a bunch more patches, do you plan
to include them all in the next patch set?


I have found that some previous patches have already been applied.
Need I just convert alloc*workqueue into drmm_alloc*workqueue and remove
the destroy_workqueue?
Or need I convert all the alloc*workqueue in the DRM?

Thanks,
Jiang


Unless I'm missing something, I don't see that this ever got applied.  I 
have a use for this interface in the qaic driver.


Jiang, are you planning on posting a v2?

-Jeff


Re: [PATCH 2/8] drm/bridge: it66121: Add bridge_to_it66121() helper and use it

2023-11-14 Thread Dmitry Baryshkov
On Tue, 14 Nov 2023 at 17:09, Sui Jingfeng  wrote:
>
> From: Sui Jingfeng 
>
> Instead of using the container_of() directly, which avoid the code lines
> too long in horizontial. Just trivial cleanup, no functional change.
>
> Signed-off-by: Sui Jingfeng 

Reviewed-by: Dmitry Baryshkov 


> ---
>  drivers/gpu/drm/bridge/ite-it66121.c | 27 ---
>  1 file changed, 16 insertions(+), 11 deletions(-)

-- 
With best wishes
Dmitry


Re: [PATCH 1/8] drm/bridge: it66121: Use dev replace ctx->dev in the it66121_probe()

2023-11-14 Thread Dmitry Baryshkov
On Tue, 14 Nov 2023 at 17:09, Sui Jingfeng  wrote:
>
> From: Sui Jingfeng 
>
> As the value of 'ctx->dev' has already been cached to the local variable
> 'dev', so keep the usage consistent. Just trivial cleanup, no functional
> change.
>
> Signed-off-by: Sui Jingfeng 

Reviewed-by: Dmitry Baryshkov 


-- 
With best wishes
Dmitry


Re: [PATCH 7/8] drm/bridge: it66121: Add another implementation for getting match data

2023-11-14 Thread Dmitry Baryshkov
On Tue, 14 Nov 2023 at 17:09, Sui Jingfeng  wrote:
>
> From: Sui Jingfeng 
>
> Because if use the i2c_get_match_data() function on our platform, the
> following error will emerge.
>
> [3.597872] ACPI: bus type drm_connector registered
> [3.602877] loongson :00:06.1: Found LS7A1000 bridge chipset, 
> revision: 1
> [3.610013] loongson :00:06.1: [drm] dc: 264MHz, gmc: 529MHz, gpu: 
> 529MHz
> [3.617111] loongson :00:06.1: [drm] Dedicated vram start: 
> 0xe003000, size: 64MiB
> [3.633628] loongson :00:06.1: [drm] Loongson VBIOS version: 0.3
> [3.639944] loongson :00:06.1: [drm] Loongson VBIOS: has 8 DCBs
> [3.646271] Console: switching to colour dummy device 80x25
> [3.651902] loongson :00:06.1: [drm] VRAM: 4096 pages ready
> [3.657791] loongson :00:06.1: [drm] GTT: 32768 pages ready
> [3.663731] loongson :00:06.1: [drm] lsdc-i2c0(sda pin mask=1, scl pin 
> mask=2) created
> [3.671966] loongson :00:06.1: [drm] lsdc-i2c1(sda pin mask=4, scl pin 
> mask=8) created
> [3.680188] loongson :00:06.1: [drm] DisplayPipe-0 has DVO-0 connector
> [3.711860] debugfs: Directory '1-004c' with parent 'regmap' already 
> present!
> [3.720312] CPU 0 Unable to handle kernel paging request at virtual 
> address 0090, era == 92faffec, ra == 92faffc8
> [3.732935] Oops[#1]:
> [3.735187] CPU: 0 PID: 8 Comm: kworker/0:0 Not tainted 6.6.0-rc3+ #941
> [3.741757] Hardware name: Loongson 
> Loongson-3A5000-7A1000-1w-ML5A/Loongson-LS3A5000-7A1000-1w-ML5A, BIOS 
> vUDK2018-LoongArch-V4.0.05-test-stable202305 06/
> [3.755500] Workqueue: events work_for_cpu_fn
> [3.759833] pc 92faffec ra 92faffc8 tp 90010017c000 sp 
> 90010017fb80
> [3.768132] a0  a1 900101c00420 a2 0001 a3 
> 90010017fbc0
> [3.776430] a4 0004 a5  a6 0001 a7 
> 0001
> [3.784727] t0  t1 0001 t2 06124954 t3 
> 0012
> [3.793026] t4 4954 t5 9800b530 t6  t7 
> 00018500
> [3.801324] t8 9001019c90c0 u0 900101c00c00 s9 f000 s0 
> 900101c00400
> [3.809621] s1  s2  s3 93c42cb0 s4 
> 900101c00420
> [3.817920] s5 90010017fc48 s6  s7  s8 
> 937fa000
> [3.826219]ra: 92faffc8 i2c_get_match_data+0x24/0xac
> [3.832189]   ERA: 92faffec i2c_get_match_data+0x48/0xac
> [3.838156]  CRMD: 00b0 (PLV0 -IE -DA +PG DACF=CC DACM=CC -WE)
> [3.844303]  PRMD: 0004 (PPLV0 +PIE -PWE)
> [3.848631]  EUEN:  (-FPE -SXE -ASXE -BTE)
> [3.853391]  ECFG: 00071c1d (LIE=0,2-4,10-12 VS=7)
> [3.858149] ESTAT: 0001 [PIL] (IS= ECode=1 EsubCode=0)
> [3.863599]  BADV: 0090
> [3.867058]  PRID: 0014c011 (Loongson-64bit, Loongson-3A5000)
> [3.872764] Modules linked in:
> [3.875793] Process kworker/0:0 (pid: 8, threadinfo=(ptrval), 
> task=(ptrval))
> [3.884180] Stack : 900101c00400  90010177f428 
> 92ceb734
> [3.892137] 900101c00404 937fa000 90010017fc60 
> 900101c00400
> [3.900093] 900016124954 8c326e68047d36df 004c037fa000 
> 90010017fc50
> [3.908050] 0080 93c44490 90010017fcb0 
> 9001003e9ec0
> [3.916007] 0001 90010044f000 90010017fc60 
> 900101c00400
> [3.923964] 937fa000 92cf05a8 9001003e8000 
> 90010017fcb2
> [3.931920] 00304c17fc68  004c 
> 
> [3.939877] 4031323136365449 6334 004c 
> 
> [3.947833]    
> 
> [3.955790]   900100449a98 
> 8c326e68047d36df
> [3.963746] ...
> [3.966170] Call Trace:
> [3.966172] [<92faffec>] i2c_get_match_data+0x48/0xac
> [3.974304] [<92ceb734>] it66121_create_bridge+0x15c/0x404

This function gets added only in patch 8, it is not broken otherwise.

I can only repeat my suggestion from the previous series: register a
proper I2C device. Don't try to overplay Linux device model.

> [3.980446] [<92cf05a8>] ls7a1000_output_init+0x228/0x248
> [3.986503] [<92cee494>] lsdc_pci_probe+0x4dc/0x5b0
> [3.992038] [<92b86b50>] local_pci_probe+0x48/0xa0
> [3.997487] [<923b5d04>] work_for_cpu_fn+0x1c/0x30
> [4.002936] [<923b7c0c>] process_one_work+0x14c/0x288
> [4.008644] [<923b8084>] worker_thread+0x33c/0x438
> [4.014092] [<923c1ccc>] kthread+0x124/0x130
> [

Re: [PATCH 2/6] drm: Add drm_atomic_helper_buffer_damage_{iter_init,merged}() helpers

2023-11-14 Thread Javier Martinez Canillas
Thomas Zimmermann  writes:

Hello Thomas,

Thanks a lot for your feedback.

> Hi
>
> Am 09.11.23 um 18:24 schrieb Javier Martinez Canillas:
>> To be used by drivers that do per-buffer (e.g: virtio-gpu) uploads (rather
>> than per-plane uploads), since these type of drivers need to handle buffer
>> damages instead of frame damages.
>> 
>> The drm_atomic_helper_buffer_damage_iter_init() has the same logic than
>> drm_atomic_helper_damage_iter_init() but it also takes into account if the
>> framebuffer attached to plane's state has changed since the last update.
>> 
>> And the drm_atomic_helper_buffer_damage_merged() is just a version of the
>> drm_atomic_helper_damage_merged() helper, but it uses the iter_init helper
>> that is mentioned above.
>> 
>> Fixes: 01f05940a9a7 ("drm/virtio: Enable fb damage clips property for the 
>> primary plane")
>> Cc:  # v6.4+
>> Reported-by: nerdopolis 
>> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218115
>> Suggested-by: Sima Vetter 
>> Signed-off-by: Javier Martinez Canillas 
>> ---
>> 
>>   drivers/gpu/drm/drm_damage_helper.c | 79 ++---
>>   include/drm/drm_damage_helper.h |  7 +++
>>   2 files changed, 80 insertions(+), 6 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/drm_damage_helper.c 
>> b/drivers/gpu/drm/drm_damage_helper.c
>> index aa2325567918..b72062c9d31c 100644
>> --- a/drivers/gpu/drm/drm_damage_helper.c
>> +++ b/drivers/gpu/drm/drm_damage_helper.c
>> @@ -204,7 +204,8 @@ EXPORT_SYMBOL(drm_atomic_helper_dirtyfb);
>>   static void
>>   __drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter 
>> *iter,
>>   const struct drm_plane_state *old_state,
>> - const struct drm_plane_state *state)
>> + const struct drm_plane_state *state,
>> + bool buffer_damage)
>
> I think it would be preferable to drop patches one and two and instead 
> add this parameter directly to drm_atomic_helper_damage_iter_init() and 
> drm_atomic_helper_damage_merged().  That's a bit of churn, but more 
> readable code.
>

Makes sense. I'll do that in v2.

> Best regards
> Thomas
>

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



Re: [PATCH] drm: bridge: samsung-dsim: Don't use FORCE_STOP_STATE

2023-11-14 Thread Michael Walle

Hi,


My current guess would be that the issue I was seeing was already fixed
with dd9e329af723 ("drm/bridge: ti-sn65dsi83: Fix enable/disable flow 
to

meet spec") and I didn't properly test both changes separately.


I had the exact same thought, as I've found your second patch.


My cheap scope is not able to capture the DSI signals and I admit that
we didn't use our more expensive equipment to verify the changes back 
then.


Instead, we had an automated test setup to do cyclic on/off switching
for the display and check for a black screen using a sensor. It is 
quite

a hassle to set up and I'm currently not planning to spend that much
effort to verify this change again.


That is actually, what we are also doing right now and how the issue was
found in the first place.

Anyway, I currently don't see any reasons to not revert my changes. 
Your

revert looks correct and seems to work fine as far as I can tell.

Reviewed-by: Frieder Schrempf 


Thanks!

-michael


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

2023-11-14 Thread Alan Previn
If we are at the end of suspend or very early in resume
its possible an async fence signal (via rcu_call) is triggered
to free_engines which could lead us to the execution of
the context destruction worker (after a prior worker flush).

Thus, when suspending, insert rcu_barriers at the start
of i915_gem_suspend (part of driver's suspend prepare) and
again in i915_gem_suspend_late so that all such cases have
completed and context destruction list isn't missing anything.

In destroyed_worker_func, close the race against CT-loss
by checking that CT is enabled before calling into
deregister_destroyed_contexts.

Based on testing, guc_lrc_desc_unpin may still race and fail
as we traverse the GuC's context-destroy list because the
CT could be disabled right before calling GuC's CT send function.

We've witnessed this race condition once every ~6000-8000
suspend-resume cycles while ensuring workloads that render
something onscreen is continuously started just before
we suspend (and the workload is small enough to complete
and trigger the queued engine/context free-up either very
late in suspend or very early in resume).

In such a case, we need to unroll the entire process because
guc-lrc-unpin takes a gt wakeref which only gets released in
the G2H IRQ reply that never comes through in this corner
case. Without the unroll, the taken wakeref is leaked and will
cascade into a kernel hang later at the tail end of suspend in
this function:

   intel_wakeref_wait_for_idle(>wakeref)
   (called by) - intel_gt_pm_wait_for_idle
   (called by) - wait_for_suspend

Thus, do an unroll in guc_lrc_desc_unpin and deregister_destroyed_-
contexts if guc_lrc_desc_unpin fails due to CT send falure.
When unrolling, keep the context in the GuC's destroy-list so
it can get picked up on the next destroy worker invocation
(if suspend aborted) or get fully purged as part of a GuC
sanitization (end of suspend) or a reset flow.

Signed-off-by: Alan Previn 
Signed-off-by: Anshuman Gupta 
Tested-by: Mousumi Jana 
---
 drivers/gpu/drm/i915/gem/i915_gem_pm.c| 10 +++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 81 ---
 2 files changed, 80 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.c 
b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
index 0d812f4d787d..3b27218aabe2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
@@ -28,6 +28,13 @@ void i915_gem_suspend(struct drm_i915_private *i915)
GEM_TRACE("%s\n", dev_name(i915->drm.dev));
 
intel_wakeref_auto(>runtime_pm.userfault_wakeref, 0);
+   /*
+* On rare occasions, we've observed the fence completion triggers
+* free_engines asynchronously via rcu_call. Ensure those are done.
+* This path is only called on suspend, so it's an acceptable cost.
+*/
+   rcu_barrier();
+
flush_workqueue(i915->wq);
 
/*
@@ -160,6 +167,9 @@ void i915_gem_suspend_late(struct drm_i915_private *i915)
 * machine in an unusable condition.
 */
 
+   /* Like i915_gem_suspend, flush tasks staged from fence triggers */
+   rcu_barrier();
+
for_each_gt(gt, i915, i)
intel_gt_suspend_late(gt);
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 9d1915482898..225747115f78 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -236,6 +236,13 @@ set_context_destroyed(struct intel_context *ce)
ce->guc_state.sched_state |= SCHED_STATE_DESTROYED;
 }
 
+static inline void
+clr_context_destroyed(struct intel_context *ce)
+{
+   lockdep_assert_held(>guc_state.lock);
+   ce->guc_state.sched_state &= ~SCHED_STATE_DESTROYED;
+}
+
 static inline bool context_pending_disable(struct intel_context *ce)
 {
return ce->guc_state.sched_state & SCHED_STATE_PENDING_DISABLE;
@@ -613,6 +620,8 @@ static int guc_submission_send_busy_loop(struct intel_guc 
*guc,
 u32 g2h_len_dw,
 bool loop)
 {
+   int ret;
+
/*
 * We always loop when a send requires a reply (i.e. g2h_len_dw > 0),
 * so we don't handle the case where we don't get a reply because we
@@ -623,7 +632,11 @@ static int guc_submission_send_busy_loop(struct intel_guc 
*guc,
if (g2h_len_dw)
atomic_inc(>outstanding_submission_g2h);
 
-   return intel_guc_send_busy_loop(guc, action, len, g2h_len_dw, loop);
+   ret = intel_guc_send_busy_loop(guc, action, len, g2h_len_dw, loop);
+   if (ret)
+   atomic_dec(>outstanding_submission_g2h);
+
+   return ret;
 }
 
 int intel_guc_wait_for_pending_msg(struct intel_guc *guc,
@@ -3286,12 +3299,13 @@ static void guc_context_close(struct intel_context *ce)
spin_unlock_irqrestore(>guc_state.lock, flags);
 }
 
-static inline 

[PATCH v6 1/2] drm/i915/guc: Flush context destruction worker at suspend

2023-11-14 Thread Alan Previn
When suspending, flush the context-guc-id
deregistration worker at the final stages of
intel_gt_suspend_late when we finally call gt_sanitize
that eventually leads down to __uc_sanitize so that
the deregistration worker doesn't fire off later as
we reset the GuC microcontroller.

Signed-off-by: Alan Previn 
Reviewed-by: Rodrigo Vivi 
Tested-by: Mousumi Jana 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 5 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h | 2 ++
 drivers/gpu/drm/i915/gt/uc/intel_uc.c | 2 ++
 3 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index d37698bd6b91..9d1915482898 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1611,6 +1611,11 @@ static void guc_flush_submissions(struct intel_guc *guc)
spin_unlock_irqrestore(_engine->lock, flags);
 }
 
+void intel_guc_submission_flush_work(struct intel_guc *guc)
+{
+   flush_work(>submission_state.destroyed_worker);
+}
+
 static void guc_flush_destroyed_contexts(struct intel_guc *guc);
 
 void intel_guc_submission_reset_prepare(struct intel_guc *guc)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
index c57b29cdb1a6..b6df75622d3b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
@@ -38,6 +38,8 @@ int intel_guc_wait_for_pending_msg(struct intel_guc *guc,
   bool interruptible,
   long timeout);
 
+void intel_guc_submission_flush_work(struct intel_guc *guc);
+
 static inline bool intel_guc_submission_is_supported(struct intel_guc *guc)
 {
return guc->submission_supported;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 27f6561dd731..cb74835b1a13 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -695,6 +695,8 @@ void intel_uc_suspend(struct intel_uc *uc)
return;
}
 
+   intel_guc_submission_flush_work(guc);
+
with_intel_runtime_pm(_to_gt(uc)->i915->runtime_pm, wakeref) {
err = intel_guc_suspend(guc);
if (err)
-- 
2.39.0



[PATCH v6 0/2] Resolve suspend-resume racing with GuC destroy-context-worker

2023-11-14 Thread Alan Previn
This series is the result of debugging issues root caused to
races between the GuC's destroyed_worker_func being triggered
vs repeating suspend-resume cycles with concurrent delayed
fence signals for engine-freeing.

The reproduction steps require that an app is launched right
before the start of the suspend cycle where it creates a
new gem context and submits a tiny workload that would
complete in the middle of the suspend cycle. However this
app uses dma-buffer sharing or dma-fence with non-GPU
objects or signals that eventually triggers a FENCE_FREE
via__i915_sw_fence_notify that connects to engines_notify ->
free_engines_rcu -> intel_context_put ->
kref_put(>ref..) that queues the worker after the GuCs
CTB has been disabled (i.e. after i915-gem's suspend-late).

This sequence is a corner-case and required repeating this
app->suspend->resume cycle ~1500 times across 4 identical
systems to see it once. That said, based on above callstack,
it is clear that merely flushing the context destruction worker,
which is obviously missing and needed, isn't sufficient.

Because of that, this series adds additional patches besides
the obvious (Patch #1) flushing of the worker during the
suspend flows. It also includes (Patch #2) closing a race
between sending the context-deregistration H2G vs the CTB
getting disabled in the midst of it (by detecing the failure
and unrolling the guc-lrc-unpin flow) and adding an additional
rcu_barrier in the gem-suspend flow to purge outstanding
rcu defered tasks that may include context destruction.

This patch was tested and confirmed to be reliably working
after running ~1500 suspend resume cycles on 4 concurrent
machines.

Changes from prior revs:
   v5: - Remove Patch #3 which doesnt solve this exact bug
 but can be a separate patch(Tvrtko).
   v4: - In Patch #2, change the position of the calls into
 rcu_barrier based on latest testing data. (Alan/Anshuman).
   - In Patch #3, fix the timeout value selection for the
 final gt-pm idle-wait that was incorrectly using a 'ns'
 #define as a milisec timeout.
   v3: - In Patch #3, when deregister_context fails, instead
 of calling intel_gt_pm_put(that might sleep), call
 __intel_wakeref_put (without ASYNC flag) (Rodrigo/Anshuman).
   - In wait_for_suspend add an rcu_barrier before we
 proceed to wait for idle. (Anshuman)
   v2: - Patch #2 Restructure code in guc_lrc_desc_unpin so
 it's more readible to differentiate (1)direct guc-id
 cleanup ..vs (2) sending the H2G ctx-destroy action ..
 vs (3) the unrolling steps if the H2G fails.
   - Patch #2 Add a check to close the race sooner by checking
 for intel_guc_is_ready from destroyed_worker_func.
   - Patch #2 When guc_submission_send_busy_loop gets a
 failure from intel_guc_send_busy_loop, we need to undo
 i.e. decrement the outstanding_submission_g2h.
   - Patch #3 In wait_for_suspend, fix checking of return from
 intel_gt_pm_wait_timeout_for_idle to now use -ETIMEDOUT
 and add documentation for intel_wakeref_wait_for_idle.
 (Rodrigo).

Alan Previn (2):
  drm/i915/guc: Flush context destruction worker at suspend
  drm/i915/guc: Close deregister-context race against CT-loss

 drivers/gpu/drm/i915/gem/i915_gem_pm.c| 10 +++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 86 ---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.h |  2 +
 drivers/gpu/drm/i915/gt/uc/intel_uc.c |  2 +
 4 files changed, 89 insertions(+), 11 deletions(-)


base-commit: 3d1e36691e73b3946b4a9ca8132a34f0319ff984
-- 
2.39.0



Re: [PATCH 2/6] drm: Add drm_atomic_helper_buffer_damage_{iter_init, merged}() helpers

2023-11-14 Thread Thomas Zimmermann

Hi

Am 09.11.23 um 18:24 schrieb Javier Martinez Canillas:

To be used by drivers that do per-buffer (e.g: virtio-gpu) uploads (rather
than per-plane uploads), since these type of drivers need to handle buffer
damages instead of frame damages.

The drm_atomic_helper_buffer_damage_iter_init() has the same logic than
drm_atomic_helper_damage_iter_init() but it also takes into account if the
framebuffer attached to plane's state has changed since the last update.

And the drm_atomic_helper_buffer_damage_merged() is just a version of the
drm_atomic_helper_damage_merged() helper, but it uses the iter_init helper
that is mentioned above.

Fixes: 01f05940a9a7 ("drm/virtio: Enable fb damage clips property for the primary 
plane")
Cc:  # v6.4+
Reported-by: nerdopolis 
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218115
Suggested-by: Sima Vetter 
Signed-off-by: Javier Martinez Canillas 
---

  drivers/gpu/drm/drm_damage_helper.c | 79 ++---
  include/drm/drm_damage_helper.h |  7 +++
  2 files changed, 80 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_damage_helper.c 
b/drivers/gpu/drm/drm_damage_helper.c
index aa2325567918..b72062c9d31c 100644
--- a/drivers/gpu/drm/drm_damage_helper.c
+++ b/drivers/gpu/drm/drm_damage_helper.c
@@ -204,7 +204,8 @@ EXPORT_SYMBOL(drm_atomic_helper_dirtyfb);
  static void
  __drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter 
*iter,
 const struct drm_plane_state *old_state,
-const struct drm_plane_state *state)
+const struct drm_plane_state *state,
+bool buffer_damage)
  {
struct drm_rect src;
memset(iter, 0, sizeof(*iter));
@@ -223,7 +224,8 @@ __drm_atomic_helper_damage_iter_init(struct 
drm_atomic_helper_damage_iter *iter,
iter->plane_src.x2 = (src.x2 >> 16) + !!(src.x2 & 0x);
iter->plane_src.y2 = (src.y2 >> 16) + !!(src.y2 & 0x);
  
-	if (!iter->clips || !drm_rect_equals(>src, _state->src)) {

+   if (!iter->clips || !drm_rect_equals(>src, _state->src) ||
+   (buffer_damage && old_state->fb != state->fb)) {


I'd assume that this change effectivly disables damage handling. AFAICT 
user space often does a page flip with a new framebuffer plus damage 
data. Now, with each change of the framebuffer we ignore the damage 
information. It's not a blocker as that's the behavior before 6.4, but 
we should be aware of it.


Best regards
Thomas


iter->clips = NULL;
iter->num_clips = 0;
iter->full_update = true;
@@ -243,6 +245,10 @@ __drm_atomic_helper_damage_iter_init(struct 
drm_atomic_helper_damage_iter *iter,
   * update). Currently this iterator returns full plane src in case plane src
   * changed but that can be changed in future to return damage.
   *
+ * Note that this helper is for drivers that do per-plane uploads and expect
+ * to handle frame damages. Drivers that do per-buffer uploads instead should
+ * use @drm_atomic_helper_buffer_damage_iter_init() that handles buffer 
damages.
+ *
   * For the case when plane is not visible or plane update should not happen 
the
   * first call to iter_next will return false. Note that this helper use 
clipped
   * _plane_state.src, so driver calling this helper should have called
@@ -253,10 +259,37 @@ drm_atomic_helper_damage_iter_init(struct 
drm_atomic_helper_damage_iter *iter,
   const struct drm_plane_state *old_state,
   const struct drm_plane_state *state)
  {
-   __drm_atomic_helper_damage_iter_init(iter, old_state, state);
+   __drm_atomic_helper_damage_iter_init(iter, old_state, state, false);
  }
  EXPORT_SYMBOL(drm_atomic_helper_damage_iter_init);
  
+/**

+ * drm_atomic_helper_buffer_damage_iter_init - Initialize the buffer damage 
iterator.
+ * @iter: The iterator to initialize.
+ * @old_state: Old plane state for validation.
+ * @state: Plane state from which to iterate the damage clips.
+ *
+ * Initialize an iterator, which clips buffer damage
+ * _plane_state.fb_damage_clips to plane _plane_state.src. This 
iterator
+ * returns full plane src in case buffer damage is not present because 
user-space
+ * didn't sent, driver discarded it (it want to do full plane update) or the 
plane
+ * @state has an attached framebuffer that is different than the one in @state 
(it
+ * has changed since the last plane update).
+ *
+ * For the case when plane is not visible or plane update should not happen the
+ * first call to iter_next will return false. Note that this helper use clipped
+ * _plane_state.src, so driver calling this helper should have called
+ * drm_atomic_helper_check_plane_state() earlier.
+ */
+void
+drm_atomic_helper_buffer_damage_iter_init(struct drm_atomic_helper_damage_iter 
*iter,
+ const struct 

Re: [PATCH 2/6] drm: Add drm_atomic_helper_buffer_damage_{iter_init,merged}() helpers

2023-11-14 Thread Thomas Zimmermann

Hi

Am 09.11.23 um 18:24 schrieb Javier Martinez Canillas:

To be used by drivers that do per-buffer (e.g: virtio-gpu) uploads (rather
than per-plane uploads), since these type of drivers need to handle buffer
damages instead of frame damages.

The drm_atomic_helper_buffer_damage_iter_init() has the same logic than
drm_atomic_helper_damage_iter_init() but it also takes into account if the
framebuffer attached to plane's state has changed since the last update.

And the drm_atomic_helper_buffer_damage_merged() is just a version of the
drm_atomic_helper_damage_merged() helper, but it uses the iter_init helper
that is mentioned above.

Fixes: 01f05940a9a7 ("drm/virtio: Enable fb damage clips property for the primary 
plane")
Cc:  # v6.4+
Reported-by: nerdopolis 
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218115
Suggested-by: Sima Vetter 
Signed-off-by: Javier Martinez Canillas 
---

  drivers/gpu/drm/drm_damage_helper.c | 79 ++---
  include/drm/drm_damage_helper.h |  7 +++
  2 files changed, 80 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_damage_helper.c 
b/drivers/gpu/drm/drm_damage_helper.c
index aa2325567918..b72062c9d31c 100644
--- a/drivers/gpu/drm/drm_damage_helper.c
+++ b/drivers/gpu/drm/drm_damage_helper.c
@@ -204,7 +204,8 @@ EXPORT_SYMBOL(drm_atomic_helper_dirtyfb);
  static void
  __drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter 
*iter,
 const struct drm_plane_state *old_state,
-const struct drm_plane_state *state)
+const struct drm_plane_state *state,
+bool buffer_damage)


I think it would be preferable to drop patches one and two and instead 
add this parameter directly to drm_atomic_helper_damage_iter_init() and 
drm_atomic_helper_damage_merged().  That's a bit of churn, but more 
readable code.


Best regards
Thomas


  {
struct drm_rect src;
memset(iter, 0, sizeof(*iter));
@@ -223,7 +224,8 @@ __drm_atomic_helper_damage_iter_init(struct 
drm_atomic_helper_damage_iter *iter,
iter->plane_src.x2 = (src.x2 >> 16) + !!(src.x2 & 0x);
iter->plane_src.y2 = (src.y2 >> 16) + !!(src.y2 & 0x);
  
-	if (!iter->clips || !drm_rect_equals(>src, _state->src)) {

+   if (!iter->clips || !drm_rect_equals(>src, _state->src) ||
+   (buffer_damage && old_state->fb != state->fb)) {
iter->clips = NULL;
iter->num_clips = 0;
iter->full_update = true;
@@ -243,6 +245,10 @@ __drm_atomic_helper_damage_iter_init(struct 
drm_atomic_helper_damage_iter *iter,
   * update). Currently this iterator returns full plane src in case plane src
   * changed but that can be changed in future to return damage.
   *
+ * Note that this helper is for drivers that do per-plane uploads and expect
+ * to handle frame damages. Drivers that do per-buffer uploads instead should
+ * use @drm_atomic_helper_buffer_damage_iter_init() that handles buffer 
damages.
+ *
   * For the case when plane is not visible or plane update should not happen 
the
   * first call to iter_next will return false. Note that this helper use 
clipped
   * _plane_state.src, so driver calling this helper should have called
@@ -253,10 +259,37 @@ drm_atomic_helper_damage_iter_init(struct 
drm_atomic_helper_damage_iter *iter,
   const struct drm_plane_state *old_state,
   const struct drm_plane_state *state)
  {
-   __drm_atomic_helper_damage_iter_init(iter, old_state, state);
+   __drm_atomic_helper_damage_iter_init(iter, old_state, state, false);
  }
  EXPORT_SYMBOL(drm_atomic_helper_damage_iter_init);
  
+/**

+ * drm_atomic_helper_buffer_damage_iter_init - Initialize the buffer damage 
iterator.
+ * @iter: The iterator to initialize.
+ * @old_state: Old plane state for validation.
+ * @state: Plane state from which to iterate the damage clips.
+ *
+ * Initialize an iterator, which clips buffer damage
+ * _plane_state.fb_damage_clips to plane _plane_state.src. This 
iterator
+ * returns full plane src in case buffer damage is not present because 
user-space
+ * didn't sent, driver discarded it (it want to do full plane update) or the 
plane
+ * @state has an attached framebuffer that is different than the one in @state 
(it
+ * has changed since the last plane update).
+ *
+ * For the case when plane is not visible or plane update should not happen the
+ * first call to iter_next will return false. Note that this helper use clipped
+ * _plane_state.src, so driver calling this helper should have called
+ * drm_atomic_helper_check_plane_state() earlier.
+ */
+void
+drm_atomic_helper_buffer_damage_iter_init(struct drm_atomic_helper_damage_iter 
*iter,
+ const struct drm_plane_state 
*old_state,
+ const 

Re: [PATCH 0/6] drm: Allow the damage helpers to handle buffer damage

2023-11-14 Thread Thomas Zimmermann

Hi Javier

Am 09.11.23 um 18:24 schrieb Javier Martinez Canillas:

Hello,

This series is to fix an issue that surfaced after damage clipping was
enabled for the virtio-gpu by commit 01f05940a9a7 ("drm/virtio: Enable
fb damage clips property for the primary plane").

After that change, flickering artifacts was reported to be present with
both weston and wlroots wayland compositors when running in a virtual
machine. The cause was identified by Sima Vetter, who pointed out that
virtio-gpu does per-buffer uploads and for this reason it needs to do
a buffer damage handling, instead of frame damage handling.


I'm having problem understanding the types of damage. You never say what 
buffer damage is. I also don't know what a frame is in this context.


Regular damage handling marks parts of a plane as dirty/damaged. That is 
per-plane damage handling. The individual planes more or less 
independent from each other.


Buffer damage, I guess, marks the underlying buffer as dirty and 
requires synchronization of the buffer with some backing storage. The 
planes using that buffer are then updated more or less automatically.


Is that right?

And why does it flicker? Is there old data stored somewhere?

Best regards
Thomas



Their suggestion was to extend the damage helpers to cover that case
and given that there's isn't a buffer damage accumulation algorithm
(e.g: buffer age), just do a full plane update if the framebuffer that
is attached to a plane changed since the last plane update (page-flip).

Patch #1 is just a refactoring to allow the logic of the frame damage
helpers to be shared by the buffer damage helpers.

Patch #2 adds the helpers that are needed for buffer damage handling.

Patch #3 fixes the virtio-gpu damage handling logic by using the
helper that is required by drivers that need to handle buffer damage.

Patch #4 fixes the vmwgfx similarly, since that driver also needs to
handle buffer damage and should have the same issue (although I have
not tested it due not having a VMWare setup).

Patch #5 adds to the KMS damage tracking kernel-doc some paragraphs
about damage tracking types and references to links that explain
frame damage vs buffer damage.

Finally patch #6 adds an item to the DRM/KMS todo, about the need to
implement some buffer damage accumulation algorithm instead of just
doing a full plane update in this case.

Because commit 01f05940a9a7 landed in v6.4, the first three patches
are marked as Fixes and Cc stable.

I've tested this on a VM with weston, was able to reproduce the issue
reported and the patches did fix the problem.

Please let me know what you think. Specially on the wording since could
made mistakes due just learning about these concepts yesterday thanks to
Sima, Simon and Pekka.

Best regards,
Javier


Javier Martinez Canillas (6):
   drm: Move drm_atomic_helper_damage_{iter_init,merged}() to helpers
   drm: Add drm_atomic_helper_buffer_damage_{iter_init,merged}() helpers
   drm/virtio: Use drm_atomic_helper_buffer_damage_merged() for buffer
 damage
   drm/vmwgfx: Use drm_atomic_helper_buffer_damage_iter_init() for buffer
 damage
   drm/plane: Extend damage tracking kernel-doc
   drm/todo: Add entry about implementing buffer age for damage tracking

  Documentation/gpu/todo.rst |  20 +++
  drivers/gpu/drm/drm_damage_helper.c| 166 +++--
  drivers/gpu/drm/drm_plane.c|  22 +++-
  drivers/gpu/drm/virtio/virtgpu_plane.c |   2 +-
  drivers/gpu/drm/vmwgfx/vmwgfx_kms.c|   2 +-
  include/drm/drm_damage_helper.h|   7 ++
  6 files changed, 173 insertions(+), 46 deletions(-)



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


OpenPGP_signature.asc
Description: OpenPGP digital signature


[PATCH v2] drm/amd/display: fix NULL dereference

2023-11-14 Thread José Pekkarinen
The following patch will fix a minor issue where a debug message is
referencing an struct that has just being checked whether is null or
not. This has been noticed by using coccinelle, in the following output:

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c:540:25-29: ERROR: 
aconnector is NULL but dereferenced.

Fixes: 5d72e247e58c9 ("drm/amd/display: switch DC over to the new DRM logging 
macros")
Signed-off-by: José Pekkarinen 
---
[v1 -> v2]: Remove the debugging message, requested by Hamza

 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index ed784cf27d39..c7a29bb737e2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -536,11 +536,8 @@ bool dm_helpers_dp_read_dpcd(
 
struct amdgpu_dm_connector *aconnector = link->priv;
 
-   if (!aconnector) {
-   drm_dbg_dp(aconnector->base.dev,
-  "Failed to find connector for link!\n");
+   if (!aconnector)
return false;
-   }
 
return drm_dp_dpcd_read(>dm_dp_aux.aux, address, data,
size) == size;
-- 
2.39.2



Re: [Intel-xe] [PATCH v3] Documentation/gpu: VM_BIND locking document

2023-11-14 Thread Thomas Hellström

Hi, Rodrigo

On 11/1/23 21:11, Rodrigo Vivi wrote:

Add the first version of the VM_BIND locking document which is
intended to be part of the xe driver upstreaming agreement.

The document describes and discuss the locking used during exec-
functions, evicton and for userptr gpu-vmas. Intention is to be using the
same nomenclature as the drm-vm-bind-async.rst.

v2:
- s/gvm/gpu_vm/g (Rodrigo Vivi)
- Clarify the userptr seqlock with a pointer to mm/mmu_notifier.c
   (Rodrigo Vivi)
- Adjust commit message accordingly.
- Add SPDX license header.

v3:
- Large update to align with the drm_gpuvm manager locking
- Add "Efficient userptr gpu_vma exec function iteration" section
- Add "Locking at bind- and unbind time" section.

Cc: Rodrigo Vivi
Signed-off-by: Thomas Hellström


Thanks for the review comments. I'll address all these in a v4 shortly.

/Thomas



Re: [PATCH 1/5] dt-bindings: gpu: samsung-rotator: drop redundant quotes

2023-11-14 Thread Rob Herring
On Sun, Nov 12, 2023 at 07:43:59PM +0100, Krzysztof Kozlowski wrote:
> Compatibles should not use quotes in the bindings.

Unfortunately yamllint skips checking these due to a bug handling 
bracketed lists. There's an open issue for it[1].

> Signed-off-by: Krzysztof Kozlowski 
> ---
>  .../devicetree/bindings/gpu/samsung-rotator.yaml | 9 +
>  1 file changed, 5 insertions(+), 4 deletions(-)

Acked-by: Rob Herring 

[1] https://github.com/adrienverge/yamllint/issues/516


Re: [PATCH 00/17] dt-bindings: samsung: add specific compatibles for existing SoC

2023-11-14 Thread Krzysztof Kozlowski


On Wed, 08 Nov 2023 11:43:26 +0100, Krzysztof Kozlowski wrote:
> Merging
> ===
> I propose to take entire patchset through my tree (Samsung SoC), because:
> 1. Next cycle two new SoCs will be coming (Google GS101 and ExynosAutov920), 
> so
>they will touch the same lines in some of the DT bindings (not all, 
> though).
>It is reasonable for me to take the bindings for the new SoCs, to have 
> clean
>`make dtbs_check` on the new DTS.
> 2. Having it together helps me to have clean `make dtbs_check` within my tree
>on the existing DTS.
> 3. No drivers are affected by this change.
> 4. I plan to do the same for Tesla FSD and Exynos ARM32 SoCs, thus expect
>follow up patchsets.
> 
> [...]

Applied, thanks!

[01/17] dt-bindings: hwinfo: samsung,exynos-chipid: add specific compatibles 
for existing SoC

https://git.kernel.org/krzk/linux/c/4be756fd983a0d91c258196b3206e9131e63d62d
[02/17] dt-bindings: i2c: exynos5: add specific compatibles for existing SoC

https://git.kernel.org/krzk/linux/c/9da80ed69eb150617e8c72aeb7fdb9bfc7b97fba
[03/17] dt-bindings: i2c: samsung,s3c2410-i2c: add specific compatibles for 
existing SoC

https://git.kernel.org/krzk/linux/c/c45860f6ee9b52b2e2f9b9255d93b9875e416cb0
[04/17] dt-bindings: mmc: samsung,exynos-dw-mshc: add specific compatibles for 
existing SoC

https://git.kernel.org/krzk/linux/c/5faf7e3d35b819cfa8de971f7e8ed84552c3a676
[05/17] dt-bindings: pinctrl: samsung: add specific compatibles for existing SoC

https://git.kernel.org/krzk/linux/c/3e17c66d1aa322db1d68e842089bd639a88a88bf
[06/17] dt-bindings: rtc: s3c-rtc: add specific compatibles for existing SoC

https://git.kernel.org/krzk/linux/c/b8029fbe90351d1fdd54dceb39b21c4062c94ce1
[07/17] dt-bindings: serial: samsung: add specific compatibles for existing SoC

https://git.kernel.org/krzk/linux/c/6f52f8b78d319ba63ce7fae950d9395d376bb6bf
[08/17] dt-bindings: samsung: exynos-pmu: add specific compatibles for existing 
SoC

https://git.kernel.org/krzk/linux/c/ed856d66b8c679ec1260c3151b2f4f3202aa213b
[09/17] dt-bindings: gpu: arm,mali-midgard: add specific compatibles for 
existing Exynos SoC

https://git.kernel.org/krzk/linux/c/e47d571301460a214c6253c15ff79db20ea50389
[10/17] dt-bindings: iio: samsung,exynos-adc: add specific compatibles for 
existing SoC

https://git.kernel.org/krzk/linux/c/bbe4d4bbacd7f11b601a0c912f3f6270558899d8
[11/17] ASoC: dt-bindings: samsung-i2s: add specific compatibles for existing 
SoC

https://git.kernel.org/krzk/linux/c/4a559c3db839afea05dc0f471823d4401bfc
[12/17] dt-bindings: pwm: samsung: add specific compatibles for existing SoC

https://git.kernel.org/krzk/linux/c/0b549b3f74e39f7b0e787f8ffdfd2cf67c0fdc4b
[13/17] arm64: dts: exynos5433: add specific compatibles to several blocks

https://git.kernel.org/krzk/linux/c/e9a72a20acf7b620e48cd4e268d7c7a4d45e1930
[14/17] arm64: dts: exynos7: add specific compatibles to several blocks

https://git.kernel.org/krzk/linux/c/a1c0d1d35063b79f38120105b5f92ca40445
[15/17] arm64: dts: exynos7885: add specific compatibles to several blocks

https://git.kernel.org/krzk/linux/c/050e7f7217e4d4d73dfcebfbc35b3eafbc36272a
[16/17] arm64: dts: exynos850: add specific compatibles to several blocks

https://git.kernel.org/krzk/linux/c/bd3623def8a93cea94a8689514e557fd4522dd53
[17/17] arm64: dts: exynosautov9: add specific compatibles to several blocks

https://git.kernel.org/krzk/linux/c/2a8ff4d56ef6cb4a7b2b4025ea4366178e4e8eaf

Best regards,
-- 
Krzysztof Kozlowski 



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

2023-11-14 Thread Jani Nikula
Since the edid_firmware module parameter was moved from
drm_kms_helper.ko to drm.ko in v4.15, we've had a backwards
compatibility helper in place, with a DRM_NOTE() suggesting to migrate
to drm.edid_firmware. This was added in commit ac6c35a4d8c7 ("drm: add
backwards compatibility support for drm_kms_helper.edid_firmware").

More than five years and 30+ kernel releases later, drop the backward
compatibility.

v2: Drop the warnings too

Acked-by: Daniel Vetter 
Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/drm_edid_load.c | 16 -
 drivers/gpu/drm/drm_kms_helper_common.c | 32 -
 include/drm/drm_edid.h  |  5 
 3 files changed, 53 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c
index 5d9ef267ebb3..60fcb80bce61 100644
--- a/drivers/gpu/drm/drm_edid_load.c
+++ b/drivers/gpu/drm/drm_edid_load.c
@@ -23,22 +23,6 @@ module_param_string(edid_firmware, edid_firmware, 
sizeof(edid_firmware), 0644);
 MODULE_PARM_DESC(edid_firmware, "Do not probe monitor, use specified EDID blob 
"
"from built-in data or /lib/firmware instead. ");
 
-/* Use only for backward compatibility with drm_kms_helper.edid_firmware */
-int __drm_set_edid_firmware_path(const char *path)
-{
-   scnprintf(edid_firmware, sizeof(edid_firmware), "%s", path);
-
-   return 0;
-}
-EXPORT_SYMBOL(__drm_set_edid_firmware_path);
-
-/* Use only for backward compatibility with drm_kms_helper.edid_firmware */
-int __drm_get_edid_firmware_path(char *buf, size_t bufsize)
-{
-   return scnprintf(buf, bufsize, "%s", edid_firmware);
-}
-EXPORT_SYMBOL(__drm_get_edid_firmware_path);
-
 #define GENERIC_EDIDS 6
 static const char * const generic_edid_name[GENERIC_EDIDS] = {
"edid/800x600.bin",
diff --git a/drivers/gpu/drm/drm_kms_helper_common.c 
b/drivers/gpu/drm/drm_kms_helper_common.c
index 0bf0fc1abf54..0c7550c0462b 100644
--- a/drivers/gpu/drm/drm_kms_helper_common.c
+++ b/drivers/gpu/drm/drm_kms_helper_common.c
@@ -27,38 +27,6 @@
 
 #include 
 
-#include 
-#include 
-
-#include "drm_crtc_helper_internal.h"
-
 MODULE_AUTHOR("David Airlie, Jesse Barnes");
 MODULE_DESCRIPTION("DRM KMS helper");
 MODULE_LICENSE("GPL and additional rights");
-
-#if IS_ENABLED(CONFIG_DRM_LOAD_EDID_FIRMWARE)
-
-/* Backward compatibility for drm_kms_helper.edid_firmware */
-static int edid_firmware_set(const char *val, const struct kernel_param *kp)
-{
-   DRM_NOTE("drm_kms_helper.edid_firmware is deprecated, please use 
drm.edid_firmware instead.\n");
-
-   return __drm_set_edid_firmware_path(val);
-}
-
-static int edid_firmware_get(char *buffer, const struct kernel_param *kp)
-{
-   return __drm_get_edid_firmware_path(buffer, PAGE_SIZE);
-}
-
-static const struct kernel_param_ops edid_firmware_ops = {
-   .set = edid_firmware_set,
-   .get = edid_firmware_get,
-};
-
-module_param_cb(edid_firmware, _firmware_ops, NULL, 0644);
-__MODULE_PARM_TYPE(edid_firmware, "charp");
-MODULE_PARM_DESC(edid_firmware,
-"DEPRECATED. Use drm.edid_firmware module parameter instead.");
-
-#endif
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index e98aa6818700..518d1b8106c7 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -329,11 +329,6 @@ int drm_edid_to_speaker_allocation(const struct edid 
*edid, u8 **sadb);
 int drm_av_sync_delay(struct drm_connector *connector,
  const struct drm_display_mode *mode);
 
-#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
-int __drm_set_edid_firmware_path(const char *path);
-int __drm_get_edid_firmware_path(char *buf, size_t bufsize);
-#endif
-
 bool drm_edid_are_equal(const struct edid *edid1, const struct edid *edid2);
 
 int
-- 
2.39.2



[PATCH 3/8] drm/bridge: it66121: Add a helper function to read bus width

2023-11-14 Thread Sui Jingfeng
From: Sui Jingfeng 

Group those relavent code lines (which with common purpose) into one helper
function, suppress the dependency on DT to function level. Just trivial
cleanup, no functional change.

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

diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
b/drivers/gpu/drm/bridge/ite-it66121.c
index 83dbdbfc9ed8..0f78737adc83 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -320,6 +320,26 @@ static inline struct it66121_ctx *bridge_to_it66121(struct 
drm_bridge *bridge)
return container_of(bridge, struct it66121_ctx, bridge);
 }
 
+static int it66121_of_read_bus_width(struct device *dev, u32 *bus_width)
+{
+   struct device_node *np;
+   u32 bw;
+
+   np = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0);
+   if (!np)
+   return -EINVAL;
+
+   of_property_read_u32(np, "bus-width", );
+   of_node_put(np);
+
+   if (bw != 12 && bw != 24)
+   return -EINVAL;
+
+   *bus_width = bw;
+
+   return 0;
+}
+
 static const struct regmap_range_cfg it66121_regmap_banks[] = {
{
.name = "it66121",
@@ -1525,19 +1545,13 @@ static int it66121_probe(struct i2c_client *client)
if (!ctx)
return -ENOMEM;
 
-   ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0);
-   if (!ep)
-   return -EINVAL;
-
ctx->dev = dev;
ctx->client = client;
ctx->info = i2c_get_match_data(client);
 
-   of_property_read_u32(ep, "bus-width", >bus_width);
-   of_node_put(ep);
-
-   if (ctx->bus_width != 12 && ctx->bus_width != 24)
-   return -EINVAL;
+   ret = it66121_of_read_bus_width(dev, >bus_width);
+   if (ret)
+   return ret;
 
ep = of_graph_get_remote_node(dev->of_node, 1, -1);
if (!ep) {
-- 
2.34.1



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

2023-11-14 Thread Sui Jingfeng
From: Sui Jingfeng 

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

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

diff --git a/drivers/gpu/drm/bridge/ite-it66121.c 
b/drivers/gpu/drm/bridge/ite-it66121.c
index 8971414a2a60..f5968b679c5d 100644
--- a/drivers/gpu/drm/bridge/ite-it66121.c
+++ b/drivers/gpu/drm/bridge/ite-it66121.c
@@ -22,6 +22,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -703,14 +704,32 @@ static int it66121_bridge_attach(struct drm_bridge 
*bridge,
 enum drm_bridge_attach_flags flags)
 {
struct it66121_ctx *ctx = bridge_to_it66121(bridge);
+   struct drm_bridge *next_bridge = ctx->next_bridge;
+   struct drm_encoder *encoder = bridge->encoder;
int ret;
 
-   if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
-   return -EINVAL;
+   if (next_bridge) {
+   if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+   WARN_ON(1);
+   flags |= DRM_BRIDGE_ATTACH_NO_CONNECTOR;
+   }
+   ret = drm_bridge_attach(encoder, next_bridge, bridge, flags);
+   if (ret)
+   return ret;
+   } else {
+   struct drm_connector *connector;
 
-   ret = drm_bridge_attach(bridge->encoder, ctx->next_bridge, bridge, 
flags);
-   if (ret)
-   return ret;
+   if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
+   WARN_ON(1);
+
+   connector = drm_bridge_connector_init(bridge->dev, encoder);
+   if (IS_ERR(connector))
+   return PTR_ERR(connector);
+
+   drm_connector_attach_encoder(connector, encoder);
+
+   ctx->connector = connector;
+   }
 
if (ctx->info->id == ID_IT66121) {
ret = regmap_write_bits(ctx->regmap, IT66121_CLK_BANK_REG,
@@ -1632,16 +1651,13 @@ static const char * const it66121_supplies[] = {
"vcn33", "vcn18", "vrf12"
 };
 
-static int it66121_probe(struct i2c_client *client)
+int it66121_create_bridge(struct i2c_client *client, bool of_support,
+ bool hpd_support, bool audio_support,
+ struct drm_bridge **bridge)
 {
+   struct device *dev = >dev;
int ret;
struct it66121_ctx *ctx;
-   struct device *dev = >dev;
-
-   if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-   dev_err(dev, "I2C check functionality failed.\n");
-   return -ENXIO;
-   }
 
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
@@ -1649,24 +1665,19 @@ static int it66121_probe(struct i2c_client *client)
 
ctx->dev = dev;
ctx->client = client;
-   ctx->info = i2c_get_match_data(client);
-
-   ret = it66121_of_read_bus_width(dev, >bus_width);
-   if (ret)
-   return ret;
-
-   ret = it66121_of_get_next_bridge(dev, >next_bridge);
-   if (ret)
-   return ret;
-
-   i2c_set_clientdata(client, ctx);
mutex_init(>lock);
 
-   ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(it66121_supplies),
-it66121_supplies);
-   if (ret) {
-   dev_err(dev, "Failed to enable power supplies\n");
-   return ret;
+   if (of_support) {
+   ret = it66121_of_read_bus_width(dev, >bus_width);
+   if (ret)
+   return ret;
+
+   ret = it66121_of_get_next_bridge(dev, >next_bridge);
+   if (ret)
+   return ret;
+   } else {
+   ctx->bus_width = 24;
+   ctx->next_bridge = NULL;
}
 
it66121_hw_reset(ctx);
@@ -1679,33 +1690,80 @@ static int it66121_probe(struct i2c_client *client)
if (ret)
return ret;
 
-   if (ctx->vender_id != ctx->info->vid ||
-   ctx->device_id != ctx->info->pid)
+   ctx->info = it66121_get_match_data(ctx->vender_id, ctx->device_id);
+   if (!ctx->info)
return -ENODEV;
 
-   ret = devm_request_threaded_irq(dev, client->irq, NULL, 
it66121_irq_threaded_handler,
-   IRQF_ONESHOT, dev_name(dev), ctx);
-   if (ret < 0) {
-   dev_err(dev, "Failed to request irq %d:%d\n", client->irq, ret);
-   return ret;
+   if (hpd_support) {
+   ret = devm_request_threaded_irq(dev, client->irq, NULL,
+   it66121_irq_threaded_handler,
+  

  1   2   >