Re: [PATCH v12 00/18] drm: Add Samsung MIPI DSIM bridge

2023-01-30 Thread Alexander Stein
Hi Rasmus,

Am Montag, 30. Januar 2023, 13:45:38 CET schrieb Rasmus Villemoes:
> On 27/01/2023 12.30, Marek Vasut wrote:
> > On 1/27/23 12:04, Jagan Teki wrote:
> >>> Thanks, but that's exactly what I'm doing, and I don't see any
> >>> modification of imx8mp.dtsi in that branch. I'm basically looking for
> >>> help to do the equivalent of
> >>> 
> >>>88775338cd58 - arm64: dts: imx8mm: Add MIPI DSI pipeline
> >>>f964f67dd6ee - arm64: dts: imx8mm: Add eLCDIF node support
> >>> 
> >>> for imx8mp in order to test those patches on our boards (we have two
> >>> variants).
> >> 
> >> Marek, any help here, thanks.
> > 
> > Try attached patch.
> 
> Thanks. I removed the lcdif2 and ldb nodes I had added from Alexander's
> patch (94e6197dadc9 in linux-next) in order to apply it. I get a couple
> of errors during boot:
> 
>   clk: /soc@0/bus@32c0/mipi_dsi@32e6: failed to reparent
> media_apb to sys_pll1_266m: -22
> 
> and enabling a pr_debug in clk_core_set_parent_nolock() shows that this
> is because
> 
>   clk_core_set_parent_nolock: clk sys_pll1_266m can not be parent of clk
> media_apb
> 
> Further, the mipi_dsi fails to probe due to
> 
>   /soc@0/bus@32c0/mipi_dsi@32e6: failed to get
> 'samsung,burst-clock-frequency' property
> 
> All other .dtsi files seem to have those samsung,burst-clock-frequency
> and samsung,esc-clock-frequency properties, so I suppose those should
> also go into the imx8mp.dtsi and are not something that the board .dts
> file should supply(?).
> 
> 
> [There's also some differences between your patch and Alexander's
> regarding the lcdif2 and ldb nodes, so while my lvds display still sorta
> works, I get
> 
>   fsl-ldb 32ec.blk-ctrl:lvds-ldb: Configured LDB clock (29700
> Hz) does not match requested LVDS clock: 34650 Hz
> 
> and the image is oddly distorted/shifted. But I suppose that's
> orthogonal to getting the lcdif1 -> mipi-dsi -> ... pipeline working.]

It seems my patch indicates exactly what's your problem here. Your clock rate 
configuration for LCDIF2 and LDB are not compatible (ratio 1:7). For now 
manual clock config is necessary in this case.
Check the clock tree in debugfs how your root clocks are configured and if it 
affects lcdif1 and lcdif2.

Best regards
Alexander




Re: linux-next: manual merge of the usb tree with the drm-intel-fixes tree

2023-01-30 Thread Greg KH
On Tue, Jan 31, 2023 at 01:03:05PM +1100, Stephen Rothwell wrote:
> Hi all,
> 
> Today's linux-next merge of the usb tree got a conflict in:
> 
>   drivers/gpu/drm/i915/gt/intel_engine_cs.c
> 
> between commit:
> 
>   5bc4b43d5c6c ("drm/i915: Fix up locking around dumping requests lists")
> 
> from the drm-intel-fixes tree and commit:
> 
>   4d70c74659d9 ("i915: Move list_count() to list.h as list_count_nodes() for 
> broader use")
> 
> from the usb tree.
> 
> I fixed it up (the former removed the code changed by the latter) and
> can carry the fix as necessary. This is now fixed as far as linux-next
> is concerned, but any non trivial conflicts should be mentioned to your
> upstream maintainer when your tree is submitted for merging.  You may
> also want to consider cooperating with the maintainer of the conflicting
> tree to minimise any particularly complex conflicts.

Thanks for the merge resolution.

greg k-h


RE: [PATCH] drm/amdgpu/fence: Fix oops due to non-matching drm_sched init/fini

2023-01-30 Thread Chen, Guchun
Hi Piccoli,

I agree with Alex's point, using ring->sched.name for such check is not a good 
way. BTW, can you please attach a full dmesg long in bad case to help me 
understand more?

Regards,
Guchun

-Original Message-
From: Alex Deucher  
Sent: Tuesday, January 31, 2023 6:30 AM
To: Guilherme G. Piccoli 
Cc: amd-...@lists.freedesktop.org; ker...@gpiccoli.net; Chen, Guchun 
; Pan, Xinhui ; 
dri-devel@lists.freedesktop.org; Tuikov, Luben ; 
Limonciello, Mario ; kernel-...@igalia.com; Deucher, 
Alexander ; Koenig, Christian 

Subject: Re: [PATCH] drm/amdgpu/fence: Fix oops due to non-matching drm_sched 
init/fini

On Mon, Jan 30, 2023 at 4:51 PM Guilherme G. Piccoli  
wrote:
>
> + Luben
>
> (sorry, missed that in the first submission).
>
> On 30/01/2023 18:45, Guilherme G. Piccoli wrote:
> > Currently amdgpu calls drm_sched_fini() from the fence driver sw 
> > fini routine - such function is expected to be called only after the 
> > respective init function - drm_sched_init() - was executed successfully.
> >
> > Happens that we faced a driver probe failure in the Steam Deck 
> > recently, and the function drm_sched_fini() was called even without 
> > its counter-part had been previously called, causing the following oops:
> >
> > amdgpu: probe of :04:00.0 failed with error -110
> > BUG: kernel NULL pointer dereference, address: 0090 PGD 
> > 0 P4D 0
> > Oops: 0002 [#1] PREEMPT SMP NOPTI
> > CPU: 0 PID: 609 Comm: systemd-udevd Not tainted 6.2.0-rc3-gpiccoli 
> > #338 Hardware name: Valve Jupiter/Jupiter, BIOS F7A0113 11/04/2022
> > RIP: 0010:drm_sched_fini+0x84/0xa0 [gpu_sched] [...] Call Trace:
> >  
> >  amdgpu_fence_driver_sw_fini+0xc8/0xd0 [amdgpu]
> >  amdgpu_device_fini_sw+0x2b/0x3b0 [amdgpu]
> >  amdgpu_driver_release_kms+0x16/0x30 [amdgpu]
> >  devm_drm_dev_init_release+0x49/0x70
> >  [...]
> >
> > To prevent that, check if the drm_sched was properly initialized for 
> > a given ring before calling its fini counter-part.
> >
> > Notice ideally we'd use sched.ready for that; such field is set as 
> > the latest thing on drm_sched_init(). But amdgpu seems to "override" 
> > the meaning of such field - in the above oops for example, it was a 
> > GFX ring causing the crash, and the sched.ready field was set to 
> > true in the ring init routine, regardless of the state of the DRM 
> > scheduler. Hence, we ended-up using another sched field.
> >> > Fixes: 067f44c8b459 ("drm/amdgpu: avoid over-handle of fence 
> >> > driver fini in s3 test (v2)")
> > Cc: Andrey Grodzovsky 
> > Cc: Guchun Chen 
> > Cc: Mario Limonciello 
> > Signed-off-by: Guilherme G. Piccoli 
> > ---
> >
> >
> > Hi folks, first of all thanks in advance for reviews / comments!
> > Notice that I've used the Fixes tag more in the sense to bring it to 
> > stable, I didn't find a good patch candidate that added the call to 
> > drm_sched_fini(), was reaching way too old commits...so
> > 067f44c8b459 seems a good candidate - or maybe not?
> >
> > Now, with regards sched.ready, spent a bit of time to figure what 
> > was happening...would be feasible maybe to stop using that to mark 
> > some kind ring status? I think it should be possible to add a flag 
> > to the ring structure for that, and free sched.ready from being 
> > manipulate by the amdgpu driver, what's your thoughts on that?

It's been a while, but IIRC, we used to have a ring->ready field in the driver 
which at some point got migrated out of the driver into the GPU scheduler and 
the driver side code never got cleaned up.  I think we should probably just 
drop the driver messing with that field and leave it up to the drm scheduler.

Alex


> >
> > I could try myself, but first of course I'd like to raise the 
> > "temperature" on this topic and check if somebody is already working 
> > on that.
> >
> > Cheers,
> >
> > Guilherme
> >
> >
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 8 +++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c 
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > index 00444203220d..e154eb8241fb 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > @@ -618,7 +618,13 @@ void amdgpu_fence_driver_sw_fini(struct amdgpu_device 
> > *adev)
> >   if (!ring || !ring->fence_drv.initialized)
> >   continue;
> >
> > - if (!ring->no_scheduler)
> > + /*
> > +  * Notice we check for sched.name since there's some
> > +  * override on the meaning of sched.ready by amdgpu.
> > +  * The natural check would be sched.ready, which is
> > +  * set as drm_sched_init() finishes...
> > +  */
> > + if (!ring->no_scheduler && ring->sched.name)
> >   drm_sched_fini(>sched);
> >
> >   for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j)


Re: Bug report: kernel oops in vmw_fb_dirty_flush()

2023-01-30 Thread Keyu Tao

Hi Rusin,

Thank you for your timely response. I tested that this bug is not 
reproducible in v6.2-rc5 yesterday.


On 1/31/23 03:54, Zack Rusin wrote:

On Tue, 2023-01-31 at 00:36 +0800, Keyu Tao wrote:

!! External Email

Hi vmwgfx maintainers,

An out-of-bound access in vmwgfx specific framebuffer implementation can
be easily triggered by fbterm (a framebuffer terminal emulator) when it
is going to scroll screen.

With some debugging, it seems that vmw_fb_dirty_flush() cannot handle
the vinfo.yoffset correctly after calling `ioctl(fbdev_fd,
FBIOPAN_DISPLAY, );`, and then subsequent access to the mapped
memory area causes the oops.

As current mainline vmwgfx implementation (in Linux 6.2-rc) has removed
this framebuffer implementation, this bug can be triggered only in Linux
stable. I have tested it with vanilla 6.1.8 and 5.10.165 and they all oops.

This bug is reported in
<
https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugs.debian.org%2
Fcgi-
bin%2Fbugreport.cgi%3Fbug%3D1029602=05%7C01%7Czackr%40vmware.com%7C63862e731c
3b4a97796808db02e03145%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C1%7C63810693415592
2769%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiL
CJXVCI6Mn0%3D%7C2000%7C%7C%7C=uVOtDBAyn%2BDx5w8r1twuKO4Xd0Lma6zCr2ie3lQ%2BRR
E%3D=0> first, and
the maintainer there suggests me to report this issue to upstream :)

Relevant information (for self-compiled Linux 6.1.8):

- /proc/version: Linux version 6.1.8 (tao@mira) (gcc (Debian 10.2.1-6)
10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.2) #7 SMP
PREEMPT_DYNAMIC Mon Jan 30 21:09:02 CST 2023

- Linux distribution: Debian GNU/Linux 11 (bullseye)

- Architecture (uname -mi): x86_64 unknown

- Virtualization software: VMware Fusion 13 Player

- How to reproduce:
    1. Install (or compile) fbterm
    2. Run fbterm under a tty (by a user with read & write permission to
/dev/fb0, usually users in video group), and try to make it scroll (for
example by pressing Enter for a few seconds)
    3. The graphics hang and it oops.



Thanks a lot for the detailed report. Is there any chance that you could try 
any of
the 6.2 rc releases to see if you can reproduce? We removed all of the hand 
rolled
fb code and ported it to drm helpers in change:
df42523c12f8 ("drm/vmwgfx: Port the framebuffer code to drm fb helpers")
which for the first time got into the official kernel in v6.2-rc1 . So any 
kernel
after that shouldn't crash with fbterm, if anyone could verify that'd be much
appreciated.

z


Re: [PATCH v2 10/27] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()

2023-01-30 Thread Abhinav Kumar




On 12/29/2022 11:18 AM, Dmitry Baryshkov wrote:

There is no need to pass full dpu_hw_pipe_cfg instance to
_dpu_hw_sspp_setup_scaler3, pass just struct dpu_format pointer.

Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 9 -
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 7 +++
  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 4 ++--
  3 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index f7f81ab08fa2..176cd6dc9a69 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -415,19 +415,18 @@ static void dpu_hw_sspp_setup_pe_config(struct 
dpu_hw_sspp *ctx,
  }
  
  static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,

-   struct dpu_hw_pipe_cfg *sspp,
-   void *scaler_cfg)
+   struct dpu_hw_scaler3_cfg *scaler3_cfg,
+   const struct dpu_format *format)
  {
u32 idx;
-   struct dpu_hw_scaler3_cfg *scaler3_cfg = scaler_cfg;
  
-	if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, ) || !sspp

+   if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, )
|| !scaler3_cfg)


Do we need to check for !format ?


return;
  
  	dpu_hw_setup_scaler3(>hw, scaler3_cfg, idx,

ctx->cap->sblk->scaler_blk.version,
-   sspp->layout.format);
+   format);
  }
  
  static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index f5aae563741a..c713343378aa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -317,13 +317,12 @@ struct dpu_hw_sspp_ops {
  
  	/**

 * setup_scaler - setup scaler
-* @ctx: Pointer to pipe context
-* @pipe_cfg: Pointer to pipe configuration
 * @scaler_cfg: Pointer to scaler configuration


This doc needs to be fixed from scaler_cfg to scaler3_cfg


+* @format: pixel format parameters
 */
void (*setup_scaler)(struct dpu_hw_sspp *ctx,
-   struct dpu_hw_pipe_cfg *pipe_cfg,
-   void *scaler_cfg);
+   struct dpu_hw_scaler3_cfg *scaler3_cfg,
+   const struct dpu_format *format);
  
  	/**

 * get_scaler_ver - get scaler h/w version
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 172a2c012917..cbff4dea8662 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -677,8 +677,8 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe 
*pipe,
if (pipe_hw->ops.setup_scaler &&
pipe->multirect_index != DPU_SSPP_RECT_1)
pipe_hw->ops.setup_scaler(pipe_hw,
-   pipe_cfg,
-   _cfg);
+   _cfg,
+   fmt);
  }
  
  /**


[PATCH v2 7/8] drm/vmwgfx: Abstract placement selection

2023-01-30 Thread Zack Rusin
From: Zack Rusin 

Problem with explicit placement selection in vmwgfx is that by the time
the buffer object needs to be validated the information about which
placement was supposed to be used is lost. To workaround this the driver
had a bunch of state in various places e.g. as_mob or cpu_blit to
somehow convey the information on which placement was intended.

Fix it properly by allowing the buffer objects to hold their preferred
placement so it can be reused whenever needed. This makes the entire
validation pipeline a lot easier both to understand and maintain.

Signed-off-by: Zack Rusin 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.c| 145 +++--
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.h|  25 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_context.c   |   9 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c   |  11 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c   |   3 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h   |   2 -
 drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c   |  35 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_gem.c   |   5 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c   |  22 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.h   |  21 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c  |  11 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h |   3 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c  |  13 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_shader.c|  15 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_so.c|   4 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c  | 304 ++
 drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c  |   3 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c   |   6 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c|  47 ---
 drivers/gpu/drm/vmwgfx/vmwgfx_va.c|   4 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_validation.c|  74 ++---
 drivers/gpu/drm/vmwgfx/vmwgfx_validation.h|   6 +-
 22 files changed, 312 insertions(+), 456 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
index c6dc733f6d45..d8f6ccecf4bf 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
@@ -135,11 +135,17 @@ int vmw_bo_pin_in_vram_or_gmr(struct vmw_private 
*dev_priv,
goto out_unreserve;
}
 
-   ret = ttm_bo_validate(bo, _vram_gmr_placement, );
+   vmw_bo_placement_set(buf,
+VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM,
+VMW_BO_DOMAIN_GMR);
+   ret = ttm_bo_validate(bo, >placement, );
if (likely(ret == 0) || ret == -ERESTARTSYS)
goto out_unreserve;
 
-   ret = ttm_bo_validate(bo, _vram_placement, );
+   vmw_bo_placement_set(buf,
+VMW_BO_DOMAIN_VRAM,
+VMW_BO_DOMAIN_VRAM);
+   ret = ttm_bo_validate(bo, >placement, );
 
 out_unreserve:
if (!ret)
@@ -190,17 +196,8 @@ int vmw_bo_pin_in_start_of_vram(struct vmw_private 
*dev_priv,
 {
struct ttm_operation_ctx ctx = {interruptible, false };
struct ttm_buffer_object *bo = >base;
-   struct ttm_placement placement;
-   struct ttm_place place;
int ret = 0;
 
-   place = vmw_vram_placement.placement[0];
-   place.lpfn = PFN_UP(bo->resource->size);
-   placement.num_placement = 1;
-   placement.placement = 
-   placement.num_busy_placement = 1;
-   placement.busy_placement = 
-
vmw_execbuf_release_pinned_bo(dev_priv);
ret = ttm_bo_reserve(bo, interruptible, false, NULL);
if (unlikely(ret != 0))
@@ -216,14 +213,21 @@ int vmw_bo_pin_in_start_of_vram(struct vmw_private 
*dev_priv,
bo->resource->start > 0 &&
buf->base.pin_count == 0) {
ctx.interruptible = false;
-   (void) ttm_bo_validate(bo, _sys_placement, );
+   vmw_bo_placement_set(buf,
+VMW_BO_DOMAIN_SYS,
+VMW_BO_DOMAIN_SYS);
+   (void)ttm_bo_validate(bo, >placement, );
}
 
+   vmw_bo_placement_set(buf,
+VMW_BO_DOMAIN_VRAM,
+VMW_BO_DOMAIN_VRAM);
+   buf->places[0].lpfn = PFN_UP(bo->resource->size);
if (buf->base.pin_count > 0)
-   ret = ttm_resource_compat(bo->resource, )
+   ret = ttm_resource_compat(bo->resource, >placement)
? 0 : -EINVAL;
else
-   ret = ttm_bo_validate(bo, , );
+   ret = ttm_bo_validate(bo, >placement, );
 
/* For some reason we didn't end up at the start of vram */
WARN_ON(ret == 0 && bo->resource->start != 0);
@@ -431,7 +435,7 @@ int vmw_bo_create_kernel(struct vmw_private *dev_priv, 
unsigned long size,
 }
 
 int vmw_bo_create(struct vmw_private *vmw,
- size_t size, struct ttm_placement *placement,
+ size_t size, u32 domain, u32 busy_domain,
  bool interruptible, bool 

[PATCH v2 8/8] drm/vmwgfx: Stop using raw ttm_buffer_object's

2023-01-30 Thread Zack Rusin
From: Zack Rusin 

Various bits of the driver used raw ttm_buffer_object instead of the
driver specific vmw_bo object. All those places used to duplicate
the mapped bo caching policy of vmw_bo.

Instead of duplicating all of that code and special casing various
functions to work both with vmw_bo and raw ttm_buffer_object's unify
the buffer object handling code.

As part of that work fix the naming of bo's, e.g. insted of generic
backup use 'guest_memory' because that's what it really is.

All of it makes the driver easier to maintain and the code easier to
read. Saves 100+ loc as well.

Signed-off-by: Zack Rusin 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.c| 204 +---
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.h|  60 ++---
 drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c   |   4 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c|  44 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_context.c   |  16 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c   |  51 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c   |  17 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h   |  53 +++--
 drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c   |  14 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_gem.c   |  37 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c   | 105 -
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.h   |   6 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c   |   4 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_mob.c   |  38 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c   |   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c|  51 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c  | 220 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h |   7 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c  |  29 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_shader.c|  49 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_so.c|   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c  |   8 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c  |   8 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c   |  98 
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c|  66 ++
 drivers/gpu/drm/vmwgfx/vmwgfx_va.c|   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_validation.c|  62 +++--
 27 files changed, 566 insertions(+), 691 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
index d8f6ccecf4bf..63486802c8fd 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
@@ -32,6 +32,12 @@
 
 #include 
 
+static void vmw_bo_release(struct vmw_bo *vbo)
+{
+   vmw_bo_unmap(vbo);
+   drm_gem_object_release(>tbo.base);
+}
+
 /**
  * vmw_bo_free - vmw_bo destructor
  *
@@ -43,26 +49,10 @@ static void vmw_bo_free(struct ttm_buffer_object *bo)
 
WARN_ON(vbo->dirty);
WARN_ON(!RB_EMPTY_ROOT(>res_tree));
-   vmw_bo_unmap(vbo);
-   drm_gem_object_release(>base);
+   vmw_bo_release(vbo);
kfree(vbo);
 }
 
-/**
- * bo_is_vmw - check if the buffer object is a _bo
- * @bo: ttm buffer object to be checked
- *
- * Uses destroy function associated with the object to determine if this is
- * a _bo.
- *
- * Returns:
- * true if the object is of _bo type, false if not.
- */
-static bool bo_is_vmw(struct ttm_buffer_object *bo)
-{
-   return bo->destroy == _bo_free;
-}
-
 /**
  * vmw_bo_pin_in_placement - Validate a buffer to placement.
  *
@@ -79,7 +69,7 @@ static int vmw_bo_pin_in_placement(struct vmw_private 
*dev_priv,
   bool interruptible)
 {
struct ttm_operation_ctx ctx = {interruptible, false };
-   struct ttm_buffer_object *bo = >base;
+   struct ttm_buffer_object *bo = >tbo;
int ret;
 
vmw_execbuf_release_pinned_bo(dev_priv);
@@ -88,7 +78,7 @@ static int vmw_bo_pin_in_placement(struct vmw_private 
*dev_priv,
if (unlikely(ret != 0))
goto err;
 
-   if (buf->base.pin_count > 0)
+   if (buf->tbo.pin_count > 0)
ret = ttm_resource_compat(bo->resource, placement)
? 0 : -EINVAL;
else
@@ -120,7 +110,7 @@ int vmw_bo_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
  bool interruptible)
 {
struct ttm_operation_ctx ctx = {interruptible, false };
-   struct ttm_buffer_object *bo = >base;
+   struct ttm_buffer_object *bo = >tbo;
int ret;
 
vmw_execbuf_release_pinned_bo(dev_priv);
@@ -129,7 +119,7 @@ int vmw_bo_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
if (unlikely(ret != 0))
goto err;
 
-   if (buf->base.pin_count > 0) {
+   if (buf->tbo.pin_count > 0) {
ret = ttm_resource_compat(bo->resource, _vram_gmr_placement)
? 0 : -EINVAL;
goto out_unreserve;
@@ -195,7 +185,7 @@ int vmw_bo_pin_in_start_of_vram(struct vmw_private 
*dev_priv,
bool interruptible)
 {
struct ttm_operation_ctx ctx = {interruptible, 

[PATCH v2 5/8] drm/vmwgfx: Cleanup the vmw bo usage in the cursor paths

2023-01-30 Thread Zack Rusin
From: Zack Rusin 

Base mapped count is useless because the ttm unmap functions handle
null maps just fine so completely remove all the code related to it.

Signed-off-by: Zack Rusin 
Reviewed-by: Martin Krastev 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.h  |  3 ---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 12 +---
 2 files changed, 1 insertion(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h 
b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
index e2dadd68a16d..2ede1e28d7ce 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
@@ -44,7 +44,6 @@ struct vmw_resource;
  * struct vmw_bo - TTM buffer object with vmwgfx additions
  * @base: The TTM buffer object
  * @res_tree: RB tree of resources using this buffer object as a backing MOB
- * @base_mapped_count: ttm BO mapping count; used by KMS atomic helpers.
  * @cpu_writers: Number of synccpu write grabs. Protected by reservation when
  * increased. May be decreased without reservation.
  * @dx_query_ctx: DX context if this buffer object is used as a DX query MOB
@@ -55,8 +54,6 @@ struct vmw_resource;
 struct vmw_bo {
struct ttm_buffer_object base;
struct rb_root res_tree;
-   /* For KMS atomic helpers: ttm bo mapping count */
-   atomic_t base_mapped_count;
 
atomic_t cpu_writers;
/* Not ref-counted.  Protected by binding_mutex */
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 6780391c57ea..1082218a1cfc 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -669,8 +669,7 @@ vmw_du_cursor_plane_cleanup_fb(struct drm_plane *plane,
const int ret = ttm_bo_reserve(>bo->base, true, false, 
NULL);
 
if (likely(ret == 0)) {
-   if (atomic_read(>bo->base_mapped_count) == 0)
-   ttm_bo_kunmap(>bo->map);
+   ttm_bo_kunmap(>bo->map);
ttm_bo_unreserve(>bo->base);
}
}
@@ -744,9 +743,6 @@ vmw_du_cursor_plane_prepare_fb(struct drm_plane *plane,
 
ret = ttm_bo_kmap(>bo->base, 0, PFN_UP(size), 
>bo->map);
 
-   if (likely(ret == 0))
-   atomic_inc(>bo->base_mapped_count);
-
ttm_bo_unreserve(>bo->base);
 
if (unlikely(ret != 0))
@@ -786,7 +782,6 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state);
struct vmw_plane_state *old_vps = vmw_plane_state_to_vps(old_state);
s32 hotspot_x, hotspot_y;
-   bool dummy;
 
hotspot_x = du->hotspot_x;
hotspot_y = du->hotspot_y;
@@ -828,11 +823,6 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
hotspot_x, hotspot_y);
}
 
-   if (vps->bo) {
-   if (ttm_kmap_obj_virtual(>bo->map, ))
-   atomic_dec(>bo->base_mapped_count);
-   }
-
du->cursor_x = new_state->crtc_x + du->set_gui_x;
du->cursor_y = new_state->crtc_y + du->set_gui_y;
 
-- 
2.38.1



[PATCH v2 6/8] drm/vmwgfx: Rename dummy to is_iomem

2023-01-30 Thread Zack Rusin
From: Zack Rusin 

Rename dummy to is_iomem because that's what it is even if we're not
activelly using it. Makes the code easier to read.

Signed-off-by: Zack Rusin 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 1082218a1cfc..e83286e08837 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -153,9 +153,9 @@ static void vmw_cursor_update_mob(struct vmw_private 
*dev_priv,
SVGAGBCursorHeader *header;
SVGAGBAlphaCursorHeader *alpha_header;
const u32 image_size = width * height * sizeof(*image);
-   bool dummy;
+   bool is_iomem;
 
-   header = ttm_kmap_obj_virtual(>cursor.map, );
+   header = ttm_kmap_obj_virtual(>cursor.map, _iomem);
alpha_header = >header.alphaHeader;
 
memset(header, 0, sizeof(*header));
@@ -185,13 +185,13 @@ static u32 vmw_du_cursor_mob_size(u32 w, u32 h)
  */
 static u32 *vmw_du_cursor_plane_acquire_image(struct vmw_plane_state *vps)
 {
-   bool dummy;
+   bool is_iomem;
if (vps->surf) {
if (vps->surf_mapped)
return vmw_bo_map_and_cache(vps->surf->res.backup);
return vps->surf->snooper.image;
} else if (vps->bo)
-   return ttm_kmap_obj_virtual(>bo->map, );
+   return ttm_kmap_obj_virtual(>bo->map, _iomem);
return NULL;
 }
 
@@ -364,7 +364,7 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
SVGA3dCopyBox *box;
unsigned box_count;
void *virtual;
-   bool dummy;
+   bool is_iomem;
struct vmw_dma_cmd {
SVGA3dCmdHeader header;
SVGA3dCmdSurfaceDMA dma;
@@ -424,7 +424,7 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
if (unlikely(ret != 0))
goto err_unreserve;
 
-   virtual = ttm_kmap_obj_virtual(, );
+   virtual = ttm_kmap_obj_virtual(, _iomem);
 
if (box->w == VMW_CURSOR_SNOOP_WIDTH && cmd->dma.guest.pitch == 
image_pitch) {
memcpy(srf->snooper.image, virtual,
@@ -658,14 +658,14 @@ vmw_du_cursor_plane_cleanup_fb(struct drm_plane *plane,
 {
struct vmw_cursor_plane *vcp = vmw_plane_to_vcp(plane);
struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
-   bool dummy;
+   bool is_iomem;
 
if (vps->surf_mapped) {
vmw_bo_unmap(vps->surf->res.backup);
vps->surf_mapped = false;
}
 
-   if (vps->bo && ttm_kmap_obj_virtual(>bo->map, )) {
+   if (vps->bo && ttm_kmap_obj_virtual(>bo->map, _iomem)) {
const int ret = ttm_bo_reserve(>bo->base, true, false, 
NULL);
 
if (likely(ret == 0)) {
-- 
2.38.1



[PATCH v2 3/8] drm/vmwgfx: Rename vmw_buffer_object to vmw_bo

2023-01-30 Thread Zack Rusin
From: Zack Rusin 

The rest of the drivers which are using ttm have mostly standardized on
driver_prefix_bo as the name for subclasses of the TTM buffer object.
Make vmwgfx match the rest of the drivers and follow the same naming
semantics.

This is especially clear given that the name of the file in which the
object was defined is vmw_bo.c.

Signed-off-by: Zack Rusin 
Reviewed-by: Martin Krastev 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.c   |  94 -
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.h   | 189 +++
 drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c  |  10 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c   |   9 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_context.c  |  11 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c  |   9 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c  |   7 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h  | 184 ++
 drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c  |  53 +++---
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c|   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_gem.c  |  27 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c  |  17 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.h  |  12 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_mob.c  |   7 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c  |  18 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c   |  27 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |  29 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c |  15 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_shader.c   |  15 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c |  13 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c |   9 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c  |   9 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c   |   3 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_validation.c   |  30 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_validation.h   |   6 +-
 25 files changed, 419 insertions(+), 386 deletions(-)
 create mode 100644 drivers/gpu/drm/vmwgfx/vmwgfx_bo.h

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
index 8aaeeecd2016..b6dc0baef350 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0 OR MIT
 /**
  *
- * Copyright © 2011-2018 VMware, Inc., Palo Alto, CA., USA
+ * Copyright © 2011-2023 VMware, Inc., Palo Alto, CA., USA
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -26,55 +26,41 @@
  *
  **/
 
-#include 
-
+#include "vmwgfx_bo.h"
 #include "vmwgfx_drv.h"
-#include "ttm_object.h"
 
 
-/**
- * vmw_buffer_object - Convert a struct ttm_buffer_object to a struct
- * vmw_buffer_object.
- *
- * @bo: Pointer to the TTM buffer object.
- * Return: Pointer to the struct vmw_buffer_object embedding the
- * TTM buffer object.
- */
-static struct vmw_buffer_object *
-vmw_buffer_object(struct ttm_buffer_object *bo)
-{
-   return container_of(bo, struct vmw_buffer_object, base);
-}
+#include 
 
 /**
- * vmw_bo_bo_free - vmw buffer object destructor
+ * vmw_bo_free - vmw_bo destructor
  *
  * @bo: Pointer to the embedded struct ttm_buffer_object
  */
-static void vmw_bo_bo_free(struct ttm_buffer_object *bo)
+static void vmw_bo_free(struct ttm_buffer_object *bo)
 {
-   struct vmw_buffer_object *vmw_bo = vmw_buffer_object(bo);
+   struct vmw_bo *vbo = to_vmw_bo(>base);
 
-   WARN_ON(vmw_bo->dirty);
-   WARN_ON(!RB_EMPTY_ROOT(_bo->res_tree));
-   vmw_bo_unmap(vmw_bo);
+   WARN_ON(vbo->dirty);
+   WARN_ON(!RB_EMPTY_ROOT(>res_tree));
+   vmw_bo_unmap(vbo);
drm_gem_object_release(>base);
-   kfree(vmw_bo);
+   kfree(vbo);
 }
 
 /**
- * bo_is_vmw - check if the buffer object is a _buffer_object
+ * bo_is_vmw - check if the buffer object is a _bo
  * @bo: ttm buffer object to be checked
  *
  * Uses destroy function associated with the object to determine if this is
- * a _buffer_object.
+ * a _bo.
  *
  * Returns:
- * true if the object is of _buffer_object type, false if not.
+ * true if the object is of _bo type, false if not.
  */
 static bool bo_is_vmw(struct ttm_buffer_object *bo)
 {
-   return bo->destroy == _bo_bo_free;
+   return bo->destroy == _bo_free;
 }
 
 /**
@@ -88,7 +74,7 @@ static bool bo_is_vmw(struct ttm_buffer_object *bo)
  * -ERESTARTSYS if interrupted by a signal
  */
 int vmw_bo_pin_in_placement(struct vmw_private *dev_priv,
-   struct vmw_buffer_object *buf,
+   struct vmw_bo *buf,
struct ttm_placement *placement,
bool interruptible)
 {
@@ -130,7 +116,7 @@ int vmw_bo_pin_in_placement(struct vmw_private *dev_priv,
  * -ERESTARTSYS if interrupted by a signal
  */
 int vmw_bo_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
- struct 

[PATCH v2 4/8] drm/vmwgfx: Simplify fb pinning

2023-01-30 Thread Zack Rusin
From: Zack Rusin 

Only the legacy display unit requires pinning of the fb memory in vram.
Both the screen objects and screen targets can present from any buffer.
That makes the pinning abstraction pointless. Simplify all of the code
and move it to the legacy display unit, the only place that needs it.

Signed-off-by: Zack Rusin 
Reviewed-by: Martin Krastev 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.c  |  8 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.h  |  4 --
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 66 -
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.h |  4 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 57 +
 5 files changed, 54 insertions(+), 85 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
index b6dc0baef350..c6dc733f6d45 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
@@ -73,10 +73,10 @@ static bool bo_is_vmw(struct ttm_buffer_object *bo)
  * Return: Zero on success, Negative error code on failure. In particular
  * -ERESTARTSYS if interrupted by a signal
  */
-int vmw_bo_pin_in_placement(struct vmw_private *dev_priv,
-   struct vmw_bo *buf,
-   struct ttm_placement *placement,
-   bool interruptible)
+static int vmw_bo_pin_in_placement(struct vmw_private *dev_priv,
+  struct vmw_bo *buf,
+  struct ttm_placement *placement,
+  bool interruptible)
 {
struct ttm_operation_ctx ctx = {interruptible, false };
struct ttm_buffer_object *bo = >base;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h 
b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
index 03ef4059c0d2..e2dadd68a16d 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
@@ -82,10 +82,6 @@ int vmw_bo_init(struct vmw_private *dev_priv,
 int vmw_bo_unref_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_priv);
 
-int vmw_bo_pin_in_placement(struct vmw_private *vmw_priv,
-   struct vmw_bo *bo,
-   struct ttm_placement *placement,
-   bool interruptible);
 int vmw_bo_pin_in_vram(struct vmw_private *dev_priv,
   struct vmw_bo *buf,
   bool interruptible);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index ad41396c0a5d..6780391c57ea 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1487,69 +1487,6 @@ static const struct drm_framebuffer_funcs 
vmw_framebuffer_bo_funcs = {
.dirty = vmw_framebuffer_bo_dirty_ext,
 };
 
-/*
- * Pin the bofer in a location suitable for access by the
- * display system.
- */
-static int vmw_framebuffer_pin(struct vmw_framebuffer *vfb)
-{
-   struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
-   struct vmw_bo *buf;
-   struct ttm_placement *placement;
-   int ret;
-
-   buf = vfb->bo ?  vmw_framebuffer_to_vfbd(>base)->buffer :
-   vmw_framebuffer_to_vfbs(>base)->surface->res.backup;
-
-   if (!buf)
-   return 0;
-
-   switch (dev_priv->active_display_unit) {
-   case vmw_du_legacy:
-   vmw_overlay_pause_all(dev_priv);
-   ret = vmw_bo_pin_in_start_of_vram(dev_priv, buf, false);
-   vmw_overlay_resume_all(dev_priv);
-   break;
-   case vmw_du_screen_object:
-   case vmw_du_screen_target:
-   if (vfb->bo) {
-   if (dev_priv->capabilities & SVGA_CAP_3D) {
-   /*
-* Use surface DMA to get content to
-* sreen target surface.
-*/
-   placement = _vram_gmr_placement;
-   } else {
-   /* Use CPU blit. */
-   placement = _sys_placement;
-   }
-   } else {
-   /* Use surface / image update */
-   placement = _mob_placement;
-   }
-
-   return vmw_bo_pin_in_placement(dev_priv, buf, placement, false);
-   default:
-   return -EINVAL;
-   }
-
-   return ret;
-}
-
-static int vmw_framebuffer_unpin(struct vmw_framebuffer *vfb)
-{
-   struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
-   struct vmw_bo *buf;
-
-   buf = vfb->bo ?  vmw_framebuffer_to_vfbd(>base)->buffer :
-   vmw_framebuffer_to_vfbs(>base)->surface->res.backup;
-
-   if (WARN_ON(!buf))
-   return 0;
-
-   return vmw_bo_unpin(dev_priv, buf, false);
-}
-
 /**
  * vmw_create_bo_proxy - create a proxy surface for the buffer object
  *
@@ -1766,9 +1703,6 @@ vmw_kms_new_framebuffer(struct 

[PATCH v2 2/8] drm/vmwgfx: Remove the duplicate bo_free function

2023-01-30 Thread Zack Rusin
From: Zack Rusin 

Remove the explicit bo_free parameter which was switching between
vmw_bo_bo_free and vmw_gem_destroy which had exactly the same
implementation.

It makes no sense to keep parameter which is always the same, remove it
and all code referencing it. Instead use the vmw_bo_bo_free directly.

Signed-off-by: Zack Rusin 
Reviewed-by: Martin Krastev 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.c   | 49 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c  |  2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c  |  3 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h  |  6 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_gem.c  | 18 +
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |  3 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c |  2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_shader.c   |  2 +-
 8 files changed, 27 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
index aa1cd5126a32..8aaeeecd2016 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
@@ -46,6 +46,22 @@ vmw_buffer_object(struct ttm_buffer_object *bo)
return container_of(bo, struct vmw_buffer_object, base);
 }
 
+/**
+ * vmw_bo_bo_free - vmw buffer object destructor
+ *
+ * @bo: Pointer to the embedded struct ttm_buffer_object
+ */
+static void vmw_bo_bo_free(struct ttm_buffer_object *bo)
+{
+   struct vmw_buffer_object *vmw_bo = vmw_buffer_object(bo);
+
+   WARN_ON(vmw_bo->dirty);
+   WARN_ON(!RB_EMPTY_ROOT(_bo->res_tree));
+   vmw_bo_unmap(vmw_bo);
+   drm_gem_object_release(>base);
+   kfree(vmw_bo);
+}
+
 /**
  * bo_is_vmw - check if the buffer object is a _buffer_object
  * @bo: ttm buffer object to be checked
@@ -58,8 +74,7 @@ vmw_buffer_object(struct ttm_buffer_object *bo)
  */
 static bool bo_is_vmw(struct ttm_buffer_object *bo)
 {
-   return bo->destroy == _bo_bo_free ||
-  bo->destroy == _gem_destroy;
+   return bo->destroy == _bo_bo_free;
 }
 
 /**
@@ -376,23 +391,6 @@ void vmw_bo_unmap(struct vmw_buffer_object *vbo)
ttm_bo_kunmap(>map);
 }
 
-
-/**
- * vmw_bo_bo_free - vmw buffer object destructor
- *
- * @bo: Pointer to the embedded struct ttm_buffer_object
- */
-void vmw_bo_bo_free(struct ttm_buffer_object *bo)
-{
-   struct vmw_buffer_object *vmw_bo = vmw_buffer_object(bo);
-
-   WARN_ON(vmw_bo->dirty);
-   WARN_ON(!RB_EMPTY_ROOT(_bo->res_tree));
-   vmw_bo_unmap(vmw_bo);
-   drm_gem_object_release(>base);
-   kfree(vmw_bo);
-}
-
 /* default destructor */
 static void vmw_bo_default_destroy(struct ttm_buffer_object *bo)
 {
@@ -449,13 +447,10 @@ int vmw_bo_create_kernel(struct vmw_private *dev_priv, 
unsigned long size,
 int vmw_bo_create(struct vmw_private *vmw,
  size_t size, struct ttm_placement *placement,
  bool interruptible, bool pin,
- void (*bo_free)(struct ttm_buffer_object *bo),
  struct vmw_buffer_object **p_bo)
 {
int ret;
 
-   BUG_ON(!bo_free);
-
*p_bo = kmalloc(sizeof(**p_bo), GFP_KERNEL);
if (unlikely(!*p_bo)) {
DRM_ERROR("Failed to allocate a buffer.\n");
@@ -463,8 +458,7 @@ int vmw_bo_create(struct vmw_private *vmw,
}
 
ret = vmw_bo_init(vmw, *p_bo, size,
- placement, interruptible, pin,
- bo_free);
+ placement, interruptible, pin);
if (unlikely(ret != 0))
goto out_error;
 
@@ -484,7 +478,6 @@ int vmw_bo_create(struct vmw_private *vmw,
  * @placement: Initial placement.
  * @interruptible: Whether waits should be performed interruptible.
  * @pin: If the BO should be created pinned at a fixed location.
- * @bo_free: The buffer object destructor.
  * Returns: Zero on success, negative error code on error.
  *
  * Note that on error, the code will free the buffer object.
@@ -492,8 +485,7 @@ int vmw_bo_create(struct vmw_private *vmw,
 int vmw_bo_init(struct vmw_private *dev_priv,
struct vmw_buffer_object *vmw_bo,
size_t size, struct ttm_placement *placement,
-   bool interruptible, bool pin,
-   void (*bo_free)(struct ttm_buffer_object *bo))
+   bool interruptible, bool pin)
 {
struct ttm_operation_ctx ctx = {
.interruptible = interruptible,
@@ -503,7 +495,6 @@ int vmw_bo_init(struct vmw_private *dev_priv,
struct drm_device *vdev = _priv->drm;
int ret;
 
-   WARN_ON_ONCE(!bo_free);
memset(vmw_bo, 0, sizeof(*vmw_bo));
BUILD_BUG_ON(TTM_MAX_BO_PRIORITY <= 3);
vmw_bo->base.priority = 3;
@@ -513,7 +504,7 @@ int vmw_bo_init(struct vmw_private *dev_priv,
drm_gem_private_object_init(vdev, _bo->base.base, size);
 
ret = ttm_bo_init_reserved(bdev, _bo->base, ttm_bo_type_device,
-  placement, 0, , NULL, NULL, bo_free);
+ 

[PATCH v2 1/8] drm/vmwgfx: Use the common gem mmap instead of the custom code

2023-01-30 Thread Zack Rusin
From: Zack Rusin 

Before vmwgfx supported gem it needed to implement the entire mmap logic
explicitly. With GEM support that's not needed and the generic code
can be used by simply setting the vm_ops to vmwgfx specific ones on the
gem object itself.

Removes a lot of code from vmwgfx without any functional difference.

Signed-off-by: Zack Rusin 
Reviewed-by: Thomas Zimmermann 
Reviewed-by: Martin Krastev 
---
 drivers/gpu/drm/vmwgfx/Makefile  |   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c  |   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h  |   6 --
 drivers/gpu/drm/vmwgfx/vmwgfx_gem.c  |   8 ++
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c | 110 ---
 5 files changed, 10 insertions(+), 118 deletions(-)
 delete mode 100644 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c

diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile
index 2a644f035597..e94479d9cd5b 100644
--- a/drivers/gpu/drm/vmwgfx/Makefile
+++ b/drivers/gpu/drm/vmwgfx/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
vmwgfx_ioctl.o vmwgfx_resource.o vmwgfx_ttm_buffer.o \
-   vmwgfx_cmd.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \
+   vmwgfx_cmd.o vmwgfx_irq.o vmwgfx_ldu.o \
vmwgfx_overlay.o vmwgfx_gmrid_manager.o vmwgfx_fence.o \
vmwgfx_bo.o vmwgfx_scrn.o vmwgfx_context.o \
vmwgfx_surface.o vmwgfx_prime.o vmwgfx_mob.o vmwgfx_shader.o \
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index bd02cb0e6837..e0c2e3748015 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -1566,7 +1566,7 @@ static const struct file_operations vmwgfx_driver_fops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = vmw_unlocked_ioctl,
-   .mmap = vmw_mmap,
+   .mmap = drm_gem_mmap,
.poll = drm_poll,
.read = drm_read,
 #if defined(CONFIG_COMPAT)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h 
b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 5acbf5849b27..4dfa5044a9e7 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -1053,12 +1053,6 @@ vmw_is_cursor_bypass3_enabled(const struct vmw_private 
*dev_priv)
return (vmw_fifo_caps(dev_priv) & SVGA_FIFO_CAP_CURSOR_BYPASS_3) != 0;
 }
 
-/**
- * TTM glue - vmwgfx_ttm_glue.c
- */
-
-extern int vmw_mmap(struct file *filp, struct vm_area_struct *vma);
-
 /**
  * TTM buffer object driver - vmwgfx_ttm_buffer.c
  */
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
index ce609e7d758f..ba4ddd9f7a7e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
@@ -103,6 +103,13 @@ static struct sg_table *vmw_gem_object_get_sg_table(struct 
drm_gem_object *obj)
return drm_prime_pages_to_sg(obj->dev, vmw_tt->dma_ttm.pages, 
vmw_tt->dma_ttm.num_pages);
 }
 
+static const struct vm_operations_struct vmw_vm_ops = {
+   .pfn_mkwrite = vmw_bo_vm_mkwrite,
+   .page_mkwrite = vmw_bo_vm_mkwrite,
+   .fault = vmw_bo_vm_fault,
+   .open = ttm_bo_vm_open,
+   .close = ttm_bo_vm_close,
+};
 
 static const struct drm_gem_object_funcs vmw_gem_object_funcs = {
.free = vmw_gem_object_free,
@@ -115,6 +122,7 @@ static const struct drm_gem_object_funcs 
vmw_gem_object_funcs = {
.vmap = drm_gem_ttm_vmap,
.vunmap = drm_gem_ttm_vunmap,
.mmap = drm_gem_ttm_mmap,
+   .vm_ops = _vm_ops,
 };
 
 /**
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c
deleted file mode 100644
index 265f7c48d856..
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c
+++ /dev/null
@@ -1,110 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR MIT
-/**
- *
- * Copyright 2009-2011 VMware, Inc., Palo Alto, CA., USA
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * 

[PATCH v2 0/8] drm/vmwgfx: Refactor the buffer object code

2023-01-30 Thread Zack Rusin
From: Zack Rusin 

v2: Fix all the issues which Thomas pointed out in the initial review
and split the "simplify fb pinning" change into two commits with the
second one being just the rename.

The series refactors the buffer object code to make more alike the
other ttm drivers. The placement becomes a property of the bo which makes
it a lot easier to correctly validate based on the current usage.
vmwgfx tends to do more validation due to forced moves, because the
buffer placement sometimes need to change due to userspace commands, i.e.
some commands e.g. SURFACE_DMA implies GMR's which are really deprecated
in favor of MOB's, but the x11 driver still uses GMR's so buffers tend
to flip between GMR's and MOB's a bit when running on X11.
   
The functionality remains largely unchanged, but the LOC are reduced by
about 400 and the groundwork is done for adding prime support with SG
ttm buffers.

Zack Rusin (8):
  drm/vmwgfx: Use the common gem mmap instead of the custom code
  drm/vmwgfx: Remove the duplicate bo_free function
  drm/vmwgfx: Rename vmw_buffer_object to vmw_bo
  drm/vmwgfx: Simplify fb pinning
  drm/vmwgfx: Cleanup the vmw bo usage in the cursor paths
  drm/vmwgfx: Rename dummy to is_iomem
  drm/vmwgfx: Abstract placement selection
  drm/vmwgfx: Stop using raw ttm_buffer_object's

 drivers/gpu/drm/vmwgfx/Makefile   |   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.c| 392 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.h| 203 +
 drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c   |  14 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c|  53 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_context.c   |  36 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c   |  65 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c   |  26 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h   | 245 +++
 drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c   | 102 +++--
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c |   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_gem.c   |  89 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c   | 230 --
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.h   |  43 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c   |  57 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_mob.c   |  45 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c   |  20 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c|  68 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c  | 243 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h |  10 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c  |  53 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_shader.c|  65 +--
 drivers/gpu/drm/vmwgfx/vmwgfx_so.c|   6 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c  | 323 ++-
 drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c  |  20 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c   | 111 ++---
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c| 116 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c  | 110 -
 drivers/gpu/drm/vmwgfx/vmwgfx_va.c|   6 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_validation.c| 150 +++
 drivers/gpu/drm/vmwgfx/vmwgfx_validation.h|  10 +-
 31 files changed, 1248 insertions(+), 1667 deletions(-)
 create mode 100644 drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
 delete mode 100644 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c

-- 
2.38.1



linux-next: manual merge of the usb tree with the drm-intel-fixes tree

2023-01-30 Thread Stephen Rothwell
Hi all,

Today's linux-next merge of the usb tree got a conflict in:

  drivers/gpu/drm/i915/gt/intel_engine_cs.c

between commit:

  5bc4b43d5c6c ("drm/i915: Fix up locking around dumping requests lists")

from the drm-intel-fixes tree and commit:

  4d70c74659d9 ("i915: Move list_count() to list.h as list_count_nodes() for 
broader use")

from the usb tree.

I fixed it up (the former removed the code changed by the latter) and
can carry the fix as necessary. This is now fixed as far as linux-next
is concerned, but any non trivial conflicts should be mentioned to your
upstream maintainer when your tree is submitted for merging.  You may
also want to consider cooperating with the maintainer of the conflicting
tree to minimise any particularly complex conflicts.

-- 
Cheers,
Stephen Rothwell


pgp9Olk_G3QQ4.pgp
Description: OpenPGP digital signature


[PATCH v3 2/2] drm/panel: boe-tv101wum-nl6: Fine tune the panel power sequence

2023-01-30 Thread xinlei.lee
From: Xinlei Lee 

For "boe,tv105wum-nw0" this special panel, it is stipulated in
the panel spec that MIPI needs to keep the LP11 state before
the lcm_reset pin is pulled high.

Signed-off-by: Xinlei Lee 
---
 drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c 
b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index f0093035f1ff..67df61de64ae 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -36,6 +36,7 @@ struct panel_desc {
const struct panel_init_cmd *init_cmds;
unsigned int lanes;
bool discharge_on_disable;
+   bool lp11_before_reset;
 };
 
 struct boe_panel {
@@ -1261,6 +1262,10 @@ static int boe_panel_prepare(struct drm_panel *panel)
 
usleep_range(1, 11000);
 
+   if (boe->desc->lp11_before_reset) {
+   mipi_dsi_dcs_nop(boe->dsi);
+   usleep_range(1000, 2000);
+   }
gpiod_set_value(boe->enable_gpio, 1);
usleep_range(1000, 2000);
gpiod_set_value(boe->enable_gpio, 0);
@@ -1487,6 +1492,7 @@ static const struct panel_desc boe_tv105wum_nw0_desc = {
.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
  MIPI_DSI_MODE_LPM,
.init_cmds = boe_init_cmd,
+   .lp11_before_reset = true,
 };
 
 static int boe_panel_get_modes(struct drm_panel *panel,
-- 
2.18.0



[PATCH v3 1/2] drm/panel: boe-tv101wum-nl6: Remove extra delay

2023-01-30 Thread xinlei.lee
From: Xinlei Lee 

Reduce the delay after LCM reset by removing an extra delay in the
initialization commands array. The required delay of at least 6ms after
reset is guaranteed by boe_panel_prepare().

Signed-off-by: Xinlei Lee 
---
 drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c 
b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index 857a2f0420d7..f0093035f1ff 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -780,7 +780,6 @@ static const struct panel_init_cmd inx_hj110iz_init_cmd[] = 
{
 };
 
 static const struct panel_init_cmd boe_init_cmd[] = {
-   _INIT_DELAY_CMD(24),
_INIT_DCS_CMD(0xB0, 0x05),
_INIT_DCS_CMD(0xB1, 0xE5),
_INIT_DCS_CMD(0xB3, 0x52),
-- 
2.18.0



[PATCH v3 0/2] Reduce lcm_reset to DSI LP11 send cmd time

2023-01-30 Thread xinlei.lee
From: Xinlei Lee 

The panel spec stipulates that after lcm_reset is pulled high, cmd
should be sent to initialize the panel. Within the allowable range of
the DSI spec, this time needs to be reduced to avoid panel exceptions.

Base on the branch of linus/master v6.2.

Change since v2:
1. Remove the applied patch.
2. Change the commit title and the description.

Change since v1:
1. Added fine-tuning panel power sequence modification.

Xinlei Lee (2):
  drm/panel: boe-tv101wum-nl6: Reduce lcm_reset to send initial code
time
  drm/panel: boe-tv101wum-nl6: Fine tune the panel power sequence

 drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

-- 
2.18.0



[PATCH -next] drm/client: fix kernel-doc warning in drm_client.h

2023-01-30 Thread Randy Dunlap
scripts/kernel-doc complains about the comment for hotplug_failed,
so fix it:

include/drm/drm_client.h:111: warning: Incorrect use of kernel-doc format:  
* @hotplug failed:

Fixes: 6a9d5ad3af65 ("drm/client: Add hotplug_failed flag")
Signed-off-by: Randy Dunlap 
Cc: Thomas Zimmermann 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Javier Martinez Canillas 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: dri-devel@lists.freedesktop.org
---
 include/drm/drm_client.h |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff -- a/include/drm/drm_client.h b/include/drm/drm_client.h
--- a/include/drm/drm_client.h
+++ b/include/drm/drm_client.h
@@ -108,7 +108,7 @@ struct drm_client_dev {
struct drm_mode_set *modesets;
 
/**
-* @hotplug failed:
+* @hotplug_failed:
 *
 * Set by client hotplug helpers if the hotplugging failed
 * before. It is usually not tried again.


Re: [PATCH 1/2] dt-bindings: display: bridge: Add NXP i.MX93 parallel display format configuration

2023-01-30 Thread Liu Ying
On Mon, 2023-01-30 at 15:39 -0600, Rob Herring wrote:
> On Mon, Jan 30, 2023 at 04:39:05PM +0800, Liu Ying wrote:
> > On Sun, 2023-01-29 at 12:46 +0100, Krzysztof Kozlowski wrote:
> > > On 28/01/2023 04:47, Liu Ying wrote:
> > > > NXP i.MX93 mediamix blk-ctrl contains one DISPLAY_MUX register
> > > > which
> > > > configures parallel display format by using the
> > > > "PARALLEL_DISP_FORMAT"
> > > > field. Add device tree bindings for the display format
> > > > configuration.
> > > > 
> > > > Signed-off-by: Liu Ying 
> > > > ---
> > > >  .../display/bridge/nxp,imx93-pdfc.yaml| 78
> > > > +++
> > > >  1 file changed, 78 insertions(+)
> > > >  create mode 100644
> > > > Documentation/devicetree/bindings/display/bridge/nxp,imx93-
> > > > pdfc.yaml
> > > > 
> > > > diff --git
> > > > a/Documentation/devicetree/bindings/display/bridge/nxp,imx93-
> > > > pdfc.yaml
> > > > b/Documentation/devicetree/bindings/display/bridge/nxp,imx93-
> > > > pdfc.yaml
> > > > new file mode 100644
> > > > index ..a84bfb46b01d
> > > > --- /dev/null
> > > > +++
> > > > b/Documentation/devicetree/bindings/display/bridge/nxp,imx93-
> > > > pdfc.yaml
> > > > @@ -0,0 +1,78 @@
> > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: 
> > > > 
https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevicetree.org%2Fschemas%2Fdisplay%2Fbridge%2Fnxp%2Cimx93-pdfc.yaml%23=05%7C01%7Cvictor.liu%40nxp.com%7C3e8db7ce3170451bc0e208db030a6ad0%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C638107115502467822%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C=c%2BQ%2Bhpov6L9b905ozKPrkWiTzaRD3ZFsEh0urw5evsQ%3D=0
> > > > +$schema: 
> > > > 
https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevicetree.org%2Fmeta-schemas%2Fcore.yaml%23=05%7C01%7Cvictor.liu%40nxp.com%7C3e8db7ce3170451bc0e208db030a6ad0%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C638107115502467822%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C=SkPZLJIR9uoqk4mRqSsfu963S%2Baa7xXmyCqzR36LJ30%3D=0
> > > > +
> > > > +title: NXP i.MX93 Parallel Display Format Configuration
> > > > +
> > > > +maintainers:
> > > > +  - Liu Ying 
> > > > +
> > > > +description: |
> > > > +  The i.MX93 mediamix blk-ctrl contains one DISPLAY_MUX
> > > > register
> > > > which
> > > > +  configures parallel display format by using the
> > > > "PARALLEL_DISP_FORMAT"
> > > > +  field.
> > > > +
> > > > +properties:
> > > > +  compatible:
> > > > +const: nxp,imx93-pdfc
> > > 
> > > 
> > > Based on description, I have doubts this is a separate bridge
> > > device.
> > > Why this is not part of display driver/bindings?
> > 
> > The relevant display controller in i.MX93 SoC is LCDIF. From
> > hardware
> > design PoV, the parallel display format configuration logic is not
> > a
> > part of LCDIF. Instead, it's a part of i.MX93 mediamix blk-ctrl.
> > The
> > blk-ctrl includes controls for miscellaneous devices with small
> > logics,
> > like this parallel display format configuration, LVDS Display
> > Bridge(LDB, see fsl,ldb.yaml) and so on. The below pipeline
> > describes
> > data flow of a parallel display LCD panel:
> > 
> > DRAM -> LCDIF -> parallel display format configuration -> LCD panel
> > 
> > So, the parallel display format configuration appears to be a
> > separate
> > bridge.
> > 
> > > 
> > > We do not create usually devices for single registers, because
> > > they
> > > are
> > > not a devices. Devices are a bit more complex - have some pin
> > > inputs/outputs, not a register only. Of course there are
> > > exception,
> > > but
> > > this one does not look like one.
> > 
> > IMHO, this one is a standalone device although it is controlled by
> > one
> > single register. It's input pins connect to LCDIF and output pins
> > connect to i.MX93 SoC's pins/pads.
> 
> Fair enough. It needs to be defined as part of the mediamix blkctrl 
> schema though.

Do you mean that we can keep this schema and need to allow child
devices in fsl,imx93-media-blk-ctrl.yaml?

Cc'ing Peng.

Peng, it appears that you are listed in the maintainers of fsl,imx93-
media-blk-ctrl.yaml. I think it needs to be extended to allow child
devices. Do you consider to do that?

Regards,
Liu Ying

> 
> Rob



Re: [PATCH drm-next 05/14] drm/nouveau: new VM_BIND uapi interfaces

2023-01-30 Thread Danilo Krummrich

On 1/30/23 14:02, Christian König wrote:

Am 29.01.23 um 19:46 schrieb Danilo Krummrich:

On 1/27/23 22:09, Danilo Krummrich wrote:

On 1/27/23 16:17, Christian König wrote:

Am 27.01.23 um 15:44 schrieb Danilo Krummrich:

[SNIP]


What you want is one component for tracking the VA allocations 
(drm_mm based) and a different component/interface for tracking 
the VA mappings (probably rb tree based).


That's what the GPUVA manager is doing. There are gpuva_regions 
which correspond to VA allocations and gpuvas which represent the 
mappings. Both are tracked separately (currently both with a 
separate drm_mm, though). However, the GPUVA manager needs to 
take regions into account when dealing with mappings to make sure 
the GPUVA manager doesn't propose drivers to merge over region 
boundaries. Speaking from userspace PoV, the kernel wouldn't 
merge mappings from different VKBuffer objects even if they're 
virtually and physically contiguous.


That are two completely different things and shouldn't be handled 
in a single component.


They are different things, but they're related in a way that for 
handling the mappings (in particular merging and sparse) the GPUVA 
manager needs to know the VA allocation (or region) boundaries.


I have the feeling there might be a misunderstanding. Userspace is 
in charge to actually allocate a portion of VA space and manage it. 
The GPUVA manager just needs to know about those VA space 
allocations and hence keeps track of them.


The GPUVA manager is not meant to be an allocator in the sense of 
finding and providing a hole for a given request.


Maybe the non-ideal choice of using drm_mm was implying something 
else.


Uff, well long story short that doesn't even remotely match the 
requirements. This way the GPUVA manager won't be usable for a whole 
bunch of use cases.


What we have are mappings which say X needs to point to Y with this 
and hw dependent flags.


The whole idea of having ranges is not going to fly. Neither with 
AMD GPUs and I strongly think not with Intels XA either.


A range in the sense of the GPUVA manager simply represents a VA 
space allocation (which in case of Nouveau is taken in userspace). 
Userspace allocates the portion of VA space and lets the kernel know 
about it. The current implementation needs that for the named 
reasons. So, I think there is no reason why this would work with one 
GPU, but not with another. It's just part of the design choice of the 
manager.


And I'm absolutely happy to discuss the details of the manager 
implementation though.




We should probably talk about the design of the GPUVA manager once 
more when this should be applicable to all GPU drivers.


That's what I try to figure out with this RFC, how to make it 
appicable for all GPU drivers, so I'm happy to discuss this. :-)


Yeah, that was really good idea :) That proposal here is really far 
away from the actual requirements.




And those are the ones I'm looking for. Do you mind sharing the 
requirements for amdgpu in particular?


For sparse residency the kernel also needs to know the region 
boundaries to make sure that it keeps sparse mappings around.


What?


When userspace creates a new VKBuffer with the 
VK_BUFFER_CREATE_SPARSE_BINDING_BIT the kernel may need to create 
sparse mappings in order to ensure that using this buffer without 
any memory backed mappings doesn't fault the GPU.


Currently, the implementation does this the following way:

1. Userspace creates a new VKBuffer and hence allocates a portion 
of the VA space for it. It calls into the kernel indicating the new 
VA space region and the fact that the region is sparse.


2. The kernel picks up the region and stores it in the GPUVA 
manager, the driver creates the corresponding sparse mappings / 
page table entries.


3. Userspace might ask the driver to create a couple of memory 
backed mappings for this particular VA region. The GPUVA manager 
stores the mapping parameters, the driver creates the corresponding 
page table entries.


4. Userspace might ask to unmap all the memory backed mappings from 
this particular VA region. The GPUVA manager removes the mapping 
parameters, the driver cleans up the corresponding page table 
entries. However, the driver also needs to re-create the sparse 
mappings, since it's a sparse buffer, hence it needs to know the 
boundaries of the region it needs to create the sparse mappings in.


Again, this is not how things are working. First of all the kernel 
absolutely should *NOT* know about those regions.


What we have inside the kernel is the information what happens if an 
address X is accessed. On AMD HW this can be:


1. Route to the PCIe bus because the mapped BO is stored in system 
memory.
2. Route to the internal MC because the mapped BO is stored in local 
memory.

3. Route to other GPUs in the same hive.
4. Route to some doorbell to kick of other work.
...
x. Ignore write, return 0 on reads (this is what is used for sparse 

Re: [PATCH v5] drm/mediatek: Add support for AR30 and BA30

2023-01-30 Thread Chun-Kuang Hu
Hi, Justin:

Justin Green  於 2023年1月31日 週二 上午4:36寫道:
>
> Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver.
>
> Tested using "modetest -P" on an MT8195.
>
> Signed-off-by: Justin Green 
> ---
> v2:
>  * Rebase and resolve merge conflicts with the AFBC patch.
> v3:
>  * Moved 10-bit support detection to mtk_disk_ovl.c
> v4:
>  * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c
> v5:
>  * Minor style adjustments per checkpatch.pl
>
>  drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 ++
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 75 +
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 27 
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 ++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++
>  drivers/gpu/drm/mediatek/mtk_drm_plane.c| 28 +++-
>  drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
>  8 files changed, 146 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
> b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> index 33e61a136bbc..6ad22ce75b81 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> @@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
>  void mtk_ovl_unregister_vblank_cb(struct device *dev);
>  void mtk_ovl_enable_vblank(struct device *dev);
>  void mtk_ovl_disable_vblank(struct device *dev);
> +const u32 *mtk_ovl_get_formats(struct device *dev);
> +size_t mtk_ovl_get_num_formats(struct device *dev);
>
>  void mtk_rdma_bypass_shadow(struct device *dev);
>  int mtk_rdma_clk_enable(struct device *dev);
> @@ -122,4 +124,6 @@ void mtk_mdp_rdma_start(struct device *dev, struct 
> cmdq_pkt *cmdq_pkt);
>  void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt);
>  void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
>  struct cmdq_pkt *cmdq_pkt);
> +const u32 *mtk_rdma_get_formats(struct device *dev);
> +size_t mtk_rdma_get_num_formats(struct device *dev);
>  #endif
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index 84daeaffab6a..1db70a77560f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -41,6 +41,7 @@
>  #define DISP_REG_OVL_RDMA_CTRL(n)  (0x00c0 + 0x20 * (n))
>  #define DISP_REG_OVL_RDMA_GMC(n)   (0x00c8 + 0x20 * (n))
>  #define DISP_REG_OVL_ADDR_MT2701   0x0040
> +#define DISP_REG_OVL_CLRFMT_EXT0x02D0
>  #define DISP_REG_OVL_ADDR_MT8173   0x0f40
>  #define DISP_REG_OVL_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * 
> (n))
>  #define DISP_REG_OVL_HDR_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * 
> (n) + 0x04)
> @@ -61,11 +62,45 @@
> 0 : OVL_CON_CLRFMT_RGB)
>  #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
> OVL_CON_CLRFMT_RGB : 0)
> +#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl))
> +#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl)   (depth << 4 * (ovl))
> +#define OVL_CON_CLRFMT_8_BIT   0x00
> +#define OVL_CON_CLRFMT_10_BIT  0x01
>  #defineOVL_CON_AEN BIT(8)
>  #defineOVL_CON_ALPHA   0xff
>  #defineOVL_CON_VIRT_FLIP   BIT(9)
>  #defineOVL_CON_HORZ_FLIP   BIT(10)
>
> +static const u32 formats_mt8173[] = {
> +   DRM_FORMAT_XRGB,
> +   DRM_FORMAT_ARGB,
> +   DRM_FORMAT_BGRX,
> +   DRM_FORMAT_BGRA,
> +   DRM_FORMAT_ABGR,
> +   DRM_FORMAT_XBGR,
> +   DRM_FORMAT_RGB888,
> +   DRM_FORMAT_BGR888,
> +   DRM_FORMAT_RGB565,
> +   DRM_FORMAT_UYVY,
> +   DRM_FORMAT_YUYV,
> +};
> +
> +static const u32 formats_mt8195[] = {
> +   DRM_FORMAT_XRGB,
> +   DRM_FORMAT_ARGB,
> +   DRM_FORMAT_ARGB2101010,
> +   DRM_FORMAT_BGRX,
> +   DRM_FORMAT_BGRA,
> +   DRM_FORMAT_BGRA1010102,
> +   DRM_FORMAT_ABGR,
> +   DRM_FORMAT_XBGR,
> +   DRM_FORMAT_RGB888,
> +   DRM_FORMAT_BGR888,
> +   DRM_FORMAT_RGB565,
> +   DRM_FORMAT_UYVY,
> +   DRM_FORMAT_YUYV,
> +};
> +
>  struct mtk_disp_ovl_data {
> unsigned int addr;
> unsigned int gmc_bits;
> @@ -73,6 +108,7 @@ struct mtk_disp_ovl_data {
> bool fmt_rgb565_is_0;
> bool smi_id_en;
> bool supports_afbc;
> +   bool supports_10bit;

For different SoC, the supported formats may be numerous combination,
so I would like to place the formats directly in private date. That
means

const u32 formats;
size_t num_formats

>  };
>
>  /*
> @@ -188,6 +224,26 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, 
> struct cmdq_pkt *cmdq_pkt
>DISP_REG_OVL_DATAPATH_CON, 

Re: [PATCH] [v2] vfio-mdev: add back CONFIG_VFIO dependency

2023-01-30 Thread Alex Williamson
On Thu, 26 Jan 2023 22:08:31 +0100
Arnd Bergmann  wrote:

> From: Arnd Bergmann 
> 
> CONFIG_VFIO_MDEV cannot be selected when VFIO itself is
> disabled, otherwise we get a link failure:
> 
> WARNING: unmet direct dependencies detected for VFIO_MDEV
>   Depends on [n]: VFIO [=n]
>   Selected by [y]:
>   - SAMPLE_VFIO_MDEV_MTTY [=y] && SAMPLES [=y]
>   - SAMPLE_VFIO_MDEV_MDPY [=y] && SAMPLES [=y]
>   - SAMPLE_VFIO_MDEV_MBOCHS [=y] && SAMPLES [=y]
> /home/arnd/cross/arm64/gcc-13.0.1-nolibc/x86_64-linux/bin/x86_64-linux-ld: 
> samples/vfio-mdev/mdpy.o: in function `mdpy_remove':
> mdpy.c:(.text+0x1e1): undefined reference to `vfio_unregister_group_dev'
> /home/arnd/cross/arm64/gcc-13.0.1-nolibc/x86_64-linux/bin/x86_64-linux-ld: 
> samples/vfio-mdev/mdpy.o: in function `mdpy_probe':
> mdpy.c:(.text+0x149e): undefined reference to `_vfio_alloc_device'
> 
> Fixes: 8bf8c5ee1f38 ("vfio-mdev: turn VFIO_MDEV into a selectable symbol")
> Signed-off-by: Arnd Bergmann 
> ---
> v2: fix the s390 and drm drivers as well, in addition to the
> sample code.
> ---
>  arch/s390/Kconfig| 4 +++-
>  drivers/gpu/drm/i915/Kconfig | 1 +
>  samples/Kconfig  | 3 +++
>  3 files changed, 7 insertions(+), 1 deletion(-)

Applied to vfio next branch for v6.3.  Thanks,

Alex



Re: (subset) [PATCH 1/8] drm/msm/dsi: Allow 2 CTRLs on v2.5.0

2023-01-30 Thread Bjorn Andersson
On Fri, 20 Jan 2023 22:00:53 +0100, Konrad Dybcio wrote:
> v2.5.0 support was originally added for SC7280, but this hw is also
> present on SM8350, which has one more DSI host. Bump up the dsi count
> and fill in the register of the secondary host to allow it to probe.
> 
> This should not have any adverse effects on SC7280, as the secondary
> CTRL will only be touched if it's defined, anyway.
> 
> [...]

Applied, thanks!

[2/8] arm64: dts: qcom: sm8350: Add missing #address/size-cells to DSIn
  commit: 6636818ecf0f1d448360835017473cf94a0ee967
[3/8] arm64: dts: qcom: sm8350: Fix DSI1 interrupt
  commit: 1eed7995d9da0489e5a46c13bd888ffa987ead98
[4/8] arm64: dts: qcom: sm8350: Feed DSI1 PHY clocks to DISPCC
  commit: 0af6a4012b3815ebca7b8080a286edc01e4a89e1
[5/8] arm64: dts: qcom: sm8350: Fix DSI PHY compatibles
  commit: 45cd807de14388010a279765486c13f8ac540dfa
[6/8] arm64: dts: qcom: sm8350: Fix DSI PLL size
  commit: e3e654ced376060d64ede8e2dfde0b1bac0f9086
[7/8] arm64: dts: qcom: sm8350: Add mdss_ prefix to DSIn out labels
  commit: 2a07efb8c08619888428cc8fd47643c438111f29
[8/8] arm64: dts: qcom: sm8350: Hook up DSI1 to MDP
  commit: b904227a4b693fbb9d5eabc9d7100dc01d9eb973

Best regards,
-- 
Bjorn Andersson 


Re: linux-6.2-rc4+ hangs on poweroff/reboot: Bisected

2023-01-30 Thread Ben Skeggs
On Tue, 31 Jan 2023 at 09:09, Chris Clayton  wrote:
>
> Hi again.
>
> On 30/01/2023 20:19, Chris Clayton wrote:
> > Thanks, Ben.
>
> 
>
> >> Hey,
> >>
> >> This is a complete shot-in-the-dark, as I don't see this behaviour on
> >> *any* of my boards.  Could you try the attached patch please?
> >
> > Unfortunately, the patch made no difference.
> >
> > I've been looking at how the graphics on my laptop is set up, and have a 
> > bit of a worry about whether the firmware might
> > be playing a part in this problem. In order to offload video decoding to 
> > the NVidia TU117 GPU, it seems the scrubber
> > firmware must be available, but as far as I know,that has not been released 
> > by NVidia. To get it to work, I followed
> > what ubuntu have done and the scrubber in /lib/firmware/nvidia/tu117/nvdec/ 
> > is a symlink to
> > ../../tu116/nvdev/scrubber.bin. That, of course, means that some of the 
> > firmware loaded is for a different card is being
> > loaded. I note that processing related to firmware is being changed in the 
> > patch. Might my set up be at the root of my
> > problem?
> >
> > I'll have a fiddle an see what I can work out.
> >
> > Chris
> >
> >>
> >> Thanks,
> >> Ben.
> >>
> >>>
>
> Well, my fiddling has got my system rebooting and shutting down successfully 
> again. I found that if I delete the symlink
> to the scrubber firmware, reboot and shutdown work again. There are however, 
> a number of other files in the tu117
> firmware directory tree that that are symlinks to actual files in its tu116 
> counterpart. So I deleted all of those too.
> Unfortunately, the absence of one or more of those symlinks causes Xorg to 
> fail to start. I've reinstated all the links
> except scrubber and I now have a system that works as it did until I tried to 
> run a kernel that includes the bad commit
> I identified in my bisection. That includes offloading video decoding to the 
> NVidia card, so what ever I read that said
> the scrubber firmware was needed seems to have been wrong. I get a new 
> message that (nouveau :01:00.0: fb: VPR
> locked, but no scrubber binary!), but, hey, we can't have everything.
>
> If you still want to get to the bottom of this, let me know what you need me 
> to provide and I'll do my best. I suspect
> you might want to because there will a n awful lot of Ubuntu-based systems 
> out there with that scrubber.bin symlink in
> place. On the other hand,m it could but quite a while before ubuntu are 
> deploying 6.2 or later kernels.
The symlinks are correct - whole groups of GPUs share the same FW, and
we use symlinks in linux-firmware to represent this.

I don't really have any ideas how/why this patch causes issues with
shutdown - it's a path that only gets executed during initialisation.
Can you try and capture the kernel log during shutdown ("dmesg -w"
over ssh? netconsole?), and see if there's any relevant messages
providing a hint at what's going on?  Alternatively, you could try
unloading the module (you will have to stop X/wayland/gdm/etc/etc
first) and seeing if that hangs too.

Ben.

>
> Thanks,
>
> Chris
>
> 


Re: [PATCH 1/3] drm/nouveau/devinit/tu102-: wait for GFW_BOOT_PROGRESS == COMPLETED

2023-01-30 Thread Ben Skeggs
On Tue, 31 Jan 2023 at 09:19, Lyude Paul  wrote:
>
> For the whole series:
>
> Reviewed-by: Lyude Paul 
>
> Will push to drm-misc-fixes in just a moment
Thank you Lyude!  Much appreciated.

Ben.

>
> On Tue, 2023-01-31 at 08:37 +1000, Ben Skeggs wrote:
> > Starting from Turing, the driver is no longer responsible for initiating
> > DEVINIT when required as the GPU started loading a FW image from ROM and
> > executing DEVINIT itself after power-on.
> >
> > However - we apparently still need to wait for it to complete.
> >
> > This should correct some issues with runpm on some systems, where we get
> > control of the HW before it's been fully reinitialised after resume from
> > suspend.
> >
> > Signed-off-by: Ben Skeggs 
> > ---
> >  .../drm/nouveau/nvkm/subdev/devinit/tu102.c   | 23 +++
> >  1 file changed, 23 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c 
> > b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c
> > index 634f64f88fc8..81a1ad2c88a7 100644
> > --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c
> > +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c
> > @@ -65,10 +65,33 @@ tu102_devinit_pll_set(struct nvkm_devinit *init, u32 
> > type, u32 freq)
> >   return ret;
> >  }
> >
> > +static int
> > +tu102_devinit_wait(struct nvkm_device *device)
> > +{
> > + unsigned timeout = 50 + 2000;
> > +
> > + do {
> > + if (nvkm_rd32(device, 0x118128) & 0x0001) {
> > + if ((nvkm_rd32(device, 0x118234) & 0x00ff) == 
> > 0xff)
> > + return 0;
> > + }
> > +
> > + usleep_range(1000, 2000);
> > + } while (timeout--);
> > +
> > + return -ETIMEDOUT;
> > +}
> > +
> >  int
> >  tu102_devinit_post(struct nvkm_devinit *base, bool post)
> >  {
> >   struct nv50_devinit *init = nv50_devinit(base);
> > + int ret;
> > +
> > + ret = tu102_devinit_wait(init->base.subdev.device);
> > + if (ret)
> > + return ret;
> > +
> >   gm200_devinit_preos(init, post);
> >   return 0;
> >  }
>
> --
> Cheers,
>  Lyude Paul (she/her)
>  Software Engineer at Red Hat
>


Re: [PATCH 1/3] drm/nouveau/devinit/tu102-: wait for GFW_BOOT_PROGRESS == COMPLETED

2023-01-30 Thread Lyude Paul
For the whole series:

Reviewed-by: Lyude Paul 

Will push to drm-misc-fixes in just a moment

On Tue, 2023-01-31 at 08:37 +1000, Ben Skeggs wrote:
> Starting from Turing, the driver is no longer responsible for initiating
> DEVINIT when required as the GPU started loading a FW image from ROM and
> executing DEVINIT itself after power-on.
> 
> However - we apparently still need to wait for it to complete.
> 
> This should correct some issues with runpm on some systems, where we get
> control of the HW before it's been fully reinitialised after resume from
> suspend.
> 
> Signed-off-by: Ben Skeggs 
> ---
>  .../drm/nouveau/nvkm/subdev/devinit/tu102.c   | 23 +++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c 
> b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c
> index 634f64f88fc8..81a1ad2c88a7 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c
> @@ -65,10 +65,33 @@ tu102_devinit_pll_set(struct nvkm_devinit *init, u32 
> type, u32 freq)
>   return ret;
>  }
>  
> +static int
> +tu102_devinit_wait(struct nvkm_device *device)
> +{
> + unsigned timeout = 50 + 2000;
> +
> + do {
> + if (nvkm_rd32(device, 0x118128) & 0x0001) {
> + if ((nvkm_rd32(device, 0x118234) & 0x00ff) == 0xff)
> + return 0;
> + }
> +
> + usleep_range(1000, 2000);
> + } while (timeout--);
> +
> + return -ETIMEDOUT;
> +}
> +
>  int
>  tu102_devinit_post(struct nvkm_devinit *base, bool post)
>  {
>   struct nv50_devinit *init = nv50_devinit(base);
> + int ret;
> +
> + ret = tu102_devinit_wait(init->base.subdev.device);
> + if (ret)
> + return ret;
> +
>   gm200_devinit_preos(init, post);
>   return 0;
>  }

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



Re: [PATCH v9 0/9] Register Type-C mode-switch in DP bridge endpoints

2023-01-30 Thread Lyude Paul
Don't know if this still needs reviews from me (feel free to respond if it
does!), but I wanted to say nice work! This is something I've wanted to see
added to DRM for a while ♥


On Mon, 2023-01-09 at 16:40 +0800, Pin-yen Lin wrote:
> This series introduces bindings for anx7625/it6505 to register Type-C
> mode-switch in their output endpoints, and use data-lanes property to
> describe the pin connections.
> 
> The first two patch modifies fwnode_graph_devcon_matches and
> cros_typec_init_ports to enable the registration of the switches.
> 
> Patch 4~6 introduce the bindings for anx7625 and the corresponding driver
> modifications.
> 
> Patch 7~9 add similar bindings and driver changes for it6505.
> 
> v7: 
> https://lore.kernel.org/all/20230105132457.4125372-1-treapk...@chromium.org/
> v6: 
> https://lore.kernel.org/all/20221124102056.393220-1-treapk...@chromium.org/
> v5: 
> https://lore.kernel.org/linux-usb/20220622173605.1168416-1-pmal...@chromium.org/
> 
> Changes in v9:
> - Collected Reviewed-by tag
> - Fixed subject prefix again
> - Changed the naming of the example node for it6505
> 
> Changes in v8:
> - Fixed the build issue when CONFIG_TYPEC=m
> - Fixed some style issues
> - Fixed the subject prefixes for the bindings patch
> - Fixed the bindings for data-lanes properties
> 
> Changes in v7:
> - Fix the long comment lines
> - Extracted the common codes to a helper function
> - Fixed style issues in anx7625 driver
> - Removed DT property validation in anx7625 driver.
> - Fixed style issues in it6505 driver
> - Removed the redundant sleep in it6505 driver
> - Removed DT property validation in it6505 driver
> - Rebased to drm-misc-next
> - Fixed indentations in bindings patches
> - Added a new patch to fix indentations in Kconfig
> 
> Changes in v6:
> - Changed it6505_typec_mux_set callback function to accommodate with
>   the latest drm-misc patches
> - Changed the driver implementation to accommodate with the new binding
> - Dropped typec-switch binding and use endpoints and data-lanes properties
>   to describe the pin connections
> - Added new patches (patch 1,2,4) to fix probing issues
> - Changed the bindings of it6505/anx7625 and modified the drivers
>   accordingly
> - Merged it6505/anx7625 driver changes into a single patch
> 
> Pin-yen Lin (7):
>   drm/display: Add Type-C switch helpers
>   dt-bindings: display: bridge: anx7625: Add mode-switch support
>   drm/bridge: anx7625: Check for Type-C during panel registration
>   drm/bridge: anx7625: Register Type C mode switches
>   dt-bindings: display: bridge: it6505: Add mode-switch support
>   drm/bridge: it6505: Fix Kconfig indentation
>   drm/bridge: it6505: Register Type C mode switches
> 
> Prashant Malani (2):
>   device property: Add remote endpoint to devcon matcher
>   platform/chrome: cros_ec_typec: Purge blocking switch devlinks
> 
>  .../display/bridge/analogix,anx7625.yaml  |  99 -
>  .../bindings/display/bridge/ite,it6505.yaml   |  93 ++--
>  drivers/base/property.c   |  15 ++
>  drivers/gpu/drm/bridge/Kconfig|  21 +--
>  drivers/gpu/drm/bridge/analogix/Kconfig   |   1 +
>  drivers/gpu/drm/bridge/analogix/anx7625.c | 101 +-
>  drivers/gpu/drm/bridge/analogix/anx7625.h |  13 ++
>  drivers/gpu/drm/bridge/ite-it6505.c   | 119 +++-
>  drivers/gpu/drm/display/drm_dp_helper.c   | 132 ++
>  drivers/platform/chrome/cros_ec_typec.c   |  10 ++
>  include/drm/display/drm_dp_helper.h   |  16 +++
>  11 files changed, 591 insertions(+), 29 deletions(-)
> 

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



Re: linux-6.2-rc4+ hangs on poweroff/reboot: Bisected

2023-01-30 Thread Chris Clayton
Hi again.

On 30/01/2023 20:19, Chris Clayton wrote:
> Thanks, Ben.



>> Hey,
>>
>> This is a complete shot-in-the-dark, as I don't see this behaviour on
>> *any* of my boards.  Could you try the attached patch please?
> 
> Unfortunately, the patch made no difference.
> 
> I've been looking at how the graphics on my laptop is set up, and have a bit 
> of a worry about whether the firmware might
> be playing a part in this problem. In order to offload video decoding to the 
> NVidia TU117 GPU, it seems the scrubber
> firmware must be available, but as far as I know,that has not been released 
> by NVidia. To get it to work, I followed
> what ubuntu have done and the scrubber in /lib/firmware/nvidia/tu117/nvdec/ 
> is a symlink to
> ../../tu116/nvdev/scrubber.bin. That, of course, means that some of the 
> firmware loaded is for a different card is being
> loaded. I note that processing related to firmware is being changed in the 
> patch. Might my set up be at the root of my
> problem?
> 
> I'll have a fiddle an see what I can work out.
> 
> Chris
> 
>>
>> Thanks,
>> Ben.
>>
>>>

Well, my fiddling has got my system rebooting and shutting down successfully 
again. I found that if I delete the symlink
to the scrubber firmware, reboot and shutdown work again. There are however, a 
number of other files in the tu117
firmware directory tree that that are symlinks to actual files in its tu116 
counterpart. So I deleted all of those too.
Unfortunately, the absence of one or more of those symlinks causes Xorg to fail 
to start. I've reinstated all the links
except scrubber and I now have a system that works as it did until I tried to 
run a kernel that includes the bad commit
I identified in my bisection. That includes offloading video decoding to the 
NVidia card, so what ever I read that said
the scrubber firmware was needed seems to have been wrong. I get a new message 
that (nouveau :01:00.0: fb: VPR
locked, but no scrubber binary!), but, hey, we can't have everything.

If you still want to get to the bottom of this, let me know what you need me to 
provide and I'll do my best. I suspect
you might want to because there will a n awful lot of Ubuntu-based systems out 
there with that scrubber.bin symlink in
place. On the other hand,m it could but quite a while before ubuntu are 
deploying 6.2 or later kernels.

Thanks,

Chris




[pull] drm/msm: drm-msm-next-2023-01-30 for v6.3

2023-01-30 Thread Rob Clark
Hi Dave & Daniel,

Here is msm-next for v6.3.  There is one devfreq patch to address a
build break issue in configurations without PM_DEVFREQ enabled (such
as COMPILE_TEST=y).

The following changes since commit 03a0a1040895711e12c15ab28d4d1812928e171d:

  Merge tag 'drm-misc-next-2023-01-03' of
git://anongit.freedesktop.org/drm/drm-misc into drm-next (2023-01-04
14:59:25 +0100)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/msm.git tags/drm-msm-next-2023-01-30

for you to fetch changes up to dbd7a2a941b8cbf9e5f79a777ed9fe0090eebb61:

  PM / devfreq: Fix build issues with devfreq disabled (2023-01-30
07:37:40 -0800)


msm-next for v6.3

There is one devfreq patch, maintainer acked to land via msm-next to
avoid a build break on platforms that do not support PM_DEVFREQ.  And
otherwise the usual assortment:

GPU:
- Add MSM_SUBMIT_BO_NO_IMPLICIT
- a2xx: Support to load legacy firmware
- a6xx: GPU devcore dump updates for a650/a660
- GPU devfreq tuning and fixes

DPU, DSI, MDSS:
- Support for SM8350, SM8450 SM8550 and SC8280XP platform

Core:
- Added bindings for SM8150 (driver support already present)

DPU:
- Partial support for DSC on SM8150 and SM8250
- Fixed color transformation matrix being lost on suspend/resume
- Include DSC blocks into register snapshot
- Misc HW catalog fixes

DP:
- Support for DP on SDM845 and SC8280XP platforms
- HPD fixes
- Support for limiting DP link rate via DT property, this enables
- Support for HBR3 rates.

DSI:
- Validate display modes according to the DSI OPP table
- DSI PHY support for the SM6375 platform
- Fixed byte intf clock selection for 14nm PHYs
- Fix the case of empty OPP tables (fixing db410c)
- DT schema rework and fixes

HDMI:
- Turn 8960 HDMI PHY into clock provider,
- Make 8960 HDMI PHY use PXO clock from DT

MDP5:
- Schema conversion to YAML


Abhinav Kumar (2):
  drm/msm/dsi: add a helper method to compute the dsi byte clk
  drm/msm/dsi: implement opp table based check for
dsi_mgr_bridge_mode_valid()

Adam Skladowski (2):
  dt-bindings: display: msm: Rename mdss node name in example
  dt-bindings: msm: dsi-phy-28nm: Document fam-b compatible

Akhil P Oommen (5):
  drm/msm/a6xx: Avoid gx gbit halt during rpm suspend
  drm/msm/adreno: Fix null ptr access in adreno_gpu_cleanup()
  drm/msm: Fix failure paths in msm_drm_init()
  drm/msm/a6xx: Update a6xx gpu coredump
  drm/msm/a6xx: Update ROQ size in coredump

Bjorn Andersson (10):
  dt-bindings: msm/dp: Add SDM845 and SC8280XP compatibles
  drm/msm/dp: Stop using DP id as index in desc
  drm/msm/dp: Add DP and EDP compatibles for SC8280XP
  drm/msm/dp: Add SDM845 DisplayPort instance
  drm/msm/dp: Rely on hpd_enable/disable callbacks
  drm/msm/dp: Implement hpd_notify()
  dt-bindings: display/msm: Add binding for SC8280XP MDSS
  drm/msm/dpu: Introduce SC8280XP
  drm/msm: Introduce SC8280XP MDSS
  drm/msm/dp: Remove INIT_SETUP delay

Bryan O'Donoghue (7):
  dt-bindings: msm: dsi-phy-28nm: Add missing qcom,
dsi-phy-regulator-ldo-mode
  dt-bindings: msm: dsi-controller-main: Fix operating-points-v2 constraint
  dt-bindings: msm: dsi-controller-main: Fix power-domain constraint
  dt-bindings: msm: dsi-controller-main: Fix description of core clock
  dt-bindings: msm: dsi-controller-main: Add vdd* descriptions back in
  dt-bindings: msm: dsi-controller-main: Add compatible strings
for every current SoC
  dt-bindings: msm: dsi-controller-main: Document clocks on a per
compatible basis

Christophe JAILLET (1):
  drm/msm/hdmi: Fix the error handling path of msm_hdmi_dev_probe()

Dmitry Baryshkov (57):
  drm/msm: another fix for the headless Adreno GPU
  dt-bindings: display/msm: add sm8350 and sm8450 DSI PHYs
  drm/msm/dsi/phy: rework register setting for 7nm PHY
  drm/msm/mdp4: convert to drm_crtc_handle_vblank()
  drm/msm/mdp5: convert to drm_crtc_handle_vblank()
  dt-bindings: display/msm: *mdss.yaml: split required properties clauses
  drm/msm: clean event_thread->worker in case of an error
  dt-bindings: display/msm: gpu: add rbcpr clock
  dt-bindings: display/msm: qcom, sdm845-mdss: document the DP device
  dt-bindings: display/msm: *dpu.yaml: split required properties clauses
  dt-bindings: display/msm: add support for the display on SM8450
  drm/msm/dpu: merge all MDP TOP registers to dpu_hwio.h
  drm/msm/dpu: add support for MDP_TOP blackhole
  drm/msm/dpu: add support for SM8450
  drm/msm: mdss add support for SM8450
  drm/msm/dpu: disable DSC blocks for SM8350
  drm/msm/a2xx: support loading legacy (iMX) firmware
  dt-bindings: display/msm: qcom, mdss: fix HDMI PHY node names
  drm/msm/dpu: remove dpu_encoder_virt_ops
  drm/msm/dpu: merge two CRTC debugfs dirs
  

Re: [PATCH v2 3/3] drm: Call vga_switcheroo_process_delayed_switch() in drm_lastclose

2023-01-30 Thread Lyude Paul
Acked-by: Lyude Paul 

On Thu, 2023-01-12 at 21:11 +0100, Thomas Zimmermann wrote:
> Several lastclose helpers call vga_switcheroo_process_delayed_switch().
> It's better to call the helper from drm_lastclose() after the kernel
> client's screen has been restored. This way, all drivers can benefit
> without having to implement their own lastclose helper. For drivers
> without vga-switcheroo, vga_switcheroo_process_delayed_switch() does
> nothing.
> 
> There was an earlier patchset to do something similar. [1]
> 
> v2:
>   * handle vga_switcheroo_client_fb_set() in a separate patch
>   * also update i915, nouveau and radeon
>   * remove unnecessary include statements
>   * update vga-switcheroo docs
> 
> Suggested-by: Alexander Deucher 
> Signed-off-by: Thomas Zimmermann 
> Reviewed-by: Daniel Vetter 
> Reviewed-by: Alex Deucher 
> Link: 
> https://lore.kernel.org/amd-gfx/20221020143603.563929-1-alexander.deuc...@amd.com/
>  # 1
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h |  1 -
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  2 --
>  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 13 -
>  drivers/gpu/drm/drm_file.c  |  3 +++
>  drivers/gpu/drm/i915/i915_driver.c  | 25 ++---
>  drivers/gpu/drm/nouveau/nouveau_drm.c   |  1 -
>  drivers/gpu/drm/nouveau/nouveau_vga.c   |  7 ---
>  drivers/gpu/drm/nouveau/nouveau_vga.h   |  1 -
>  drivers/gpu/drm/radeon/radeon_drv.c |  2 +-
>  drivers/gpu/drm/radeon/radeon_drv.h |  1 -
>  drivers/gpu/drm/radeon/radeon_kms.c | 18 --
>  drivers/gpu/vga/vga_switcheroo.c|  4 ++--
>  12 files changed, 8 insertions(+), 70 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 63c921c55fb9..7120b9b6e580 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -1330,7 +1330,6 @@ extern const int amdgpu_max_kms_ioctl;
>  
>  int amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags);
>  void amdgpu_driver_unload_kms(struct drm_device *dev);
> -void amdgpu_driver_lastclose_kms(struct drm_device *dev);
>  int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file 
> *file_priv);
>  void amdgpu_driver_postclose_kms(struct drm_device *dev,
>struct drm_file *file_priv);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index 1353ffd08988..783c1e284a22 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -34,7 +34,6 @@
>  #include 
>  #include 
>  #include 
> -#include 
>  #include 
>  #include 
>  #include 
> @@ -2785,7 +2784,6 @@ static const struct drm_driver amdgpu_kms_driver = {
>   DRIVER_SYNCOBJ_TIMELINE,
>   .open = amdgpu_driver_open_kms,
>   .postclose = amdgpu_driver_postclose_kms,
> - .lastclose = amdgpu_driver_lastclose_kms,
>   .ioctls = amdgpu_ioctls_kms,
>   .num_ioctls = ARRAY_SIZE(amdgpu_ioctls_kms),
>   .dumb_create = amdgpu_mode_dumb_create,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 7aa7e52ca784..a37be02fb2fc 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -34,7 +34,6 @@
>  #include "amdgpu_vce.h"
>  #include "atom.h"
>  
> -#include 
>  #include 
>  #include 
>  #include 
> @@ -1104,18 +1103,6 @@ int amdgpu_info_ioctl(struct drm_device *dev, void 
> *data, struct drm_file *filp)
>  /*
>   * Outdated mess for old drm with Xorg being in charge (void function now).
>   */
> -/**
> - * amdgpu_driver_lastclose_kms - drm callback for last close
> - *
> - * @dev: drm dev pointer
> - *
> - * Switch vga_switcheroo state after last close (all asics).
> - */
> -void amdgpu_driver_lastclose_kms(struct drm_device *dev)
> -{
> - drm_fb_helper_lastclose(dev);
> - vga_switcheroo_process_delayed_switch();
> -}
>  
>  /**
>   * amdgpu_driver_open_kms - drm callback for open
> diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
> index a51ff8cee049..314c309db9a3 100644
> --- a/drivers/gpu/drm/drm_file.c
> +++ b/drivers/gpu/drm/drm_file.c
> @@ -38,6 +38,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> @@ -460,6 +461,8 @@ void drm_lastclose(struct drm_device * dev)
>   drm_legacy_dev_reinit(dev);
>  
>   drm_client_dev_restore(dev);
> +
> + vga_switcheroo_process_delayed_switch();
>  }
>  
>  /**
> diff --git a/drivers/gpu/drm/i915/i915_driver.c 
> b/drivers/gpu/drm/i915/i915_driver.c
> index 33e231b120c1..bf6ad8620970 100644
> --- a/drivers/gpu/drm/i915/i915_driver.c
> +++ b/drivers/gpu/drm/i915/i915_driver.c
> @@ -29,6 +29,7 @@
>  
>  #include 
>  #include 
> +#include  /* for FBINFO_STATE_ */
>  #include 
>  #include 
>  #include 
> @@ -37,7 +38,6 @@
>  #include 
>  #include 
>  #include 

Re: [PATCH v1 10/14] drm/msm/disp/dpu: add supports of DSC encoder v1.2 engine

2023-01-30 Thread Abhinav Kumar




On 1/30/2023 2:31 PM, Marijn Suijten wrote:

Abhinav,

On 2023-01-30 13:22:03, Abhinav Kumar wrote:

Hi Marijn

On 1/30/2023 12:16 PM, Marijn Suijten wrote:

On 2023-01-24 15:52:46, Kuogee Hsieh wrote:



If only replying to a small chunk somewhere in the middle of a diff
and/or large review, please cut out unnecessary bits to make your reply
easier to find :)


+   data = (dsc->flatness_min_qp & 0x1f);
+   data |= (dsc->flatness_max_qp & 0x1f) << 5;
+   data |= (dsc_info->det_thresh_flatness & 0xff) << 10;

dpu_hw_dsc.c computes this on the fly.  After removing that, and
using initial_lines from the function parameters, only
dsc_info->num_active_ss_per_enc remains.  Do you really need that
msm_display_dsc_info struct here, do you need it at all?


I ported these code from our down stream code base.

I make it work first, then clean it up will follow.

I submit it for review since it looks like you guy like to have code sooner.


Correct, I was looking forward to these patches albeit complete with the
promised DSI support from Jessica, which still seems to be pending.



DSI support is still being worked upon.

I dont think we promised DSC 1.2 will come with DSI together in the same
series. It was always going to be DSC 1.2 + DP followed by another
series from Jessica for DSI.

Lets set the expectations right.


Not saying that these patches were promised as part of this series (as
said, "which still seem to be pending"), just making clear that this
series if of no use to me (no hurry to get the code in my hands sooner)
until the DSI patches are also shared which I would have started working
on myself if I didn't know QUIC was picking it up to distract from the
current v1.1 broken-ness on SM8150 and SM8250.



This is being by Quic for everyone's benefit. So that we can land a 
working DSC 1.2 solution for DSI as a working example for all future 
panels. We only took it up to help others like you and linaro team to 
give a working example of a DSC 1.2 panel with command mode in upstream.




To set my (and at least Neil's) expectations straight as well: DSC 1.2
HW support should come in a separate series without DP support.  Smaller
series (not to mention appropriately split-up patches) lead to a
decrease in scope, less dependencies and hopefully more efficient v2 -
for all involved.



As I already wrote earlier, we will fix the mistakes of v1, make v2 
better and it will be split up better. But DSC 1.2 HW support had to be 
pushed along with DP or DSI to show its working. We chose DP to go with 
it as it aligns better with our upstream plans.




- Marijn


[PATCH 3/3] drm/nouveau/acr/gm20b: regression fixes

2023-01-30 Thread Ben Skeggs
Missed some Tegra-specific quirks when reworking ACR to support Ampere.

Fixes: 2541626cfb79 ("drm/nouveau/acr: use common falcon HS FW code for ACR 
FWs")
Signed-off-by: Ben Skeggs 
Tested-by: Diogo Ivo 
Tested-By: Nicolas Chauvet 
---
 drivers/gpu/drm/nouveau/nvkm/core/firmware.c|  3 +++
 drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c | 14 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c |  2 +-
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/core/firmware.c 
b/drivers/gpu/drm/nouveau/nvkm/core/firmware.c
index fcf2a002f6cb..91fb494d4009 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/firmware.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/firmware.c
@@ -151,6 +151,9 @@ nvkm_firmware_mem_page(struct nvkm_memory *memory)
 static enum nvkm_memory_target
 nvkm_firmware_mem_target(struct nvkm_memory *memory)
 {
+   if (nvkm_firmware_mem(memory)->device->func->tegra)
+   return NVKM_MEM_TARGET_NCOH;
+
return NVKM_MEM_TARGET_HOST;
 }
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c 
b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
index 393ade9f7e6c..b7da3ab44c27 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
@@ -48,6 +48,16 @@ gm200_flcn_pio_dmem_rd(struct nvkm_falcon *falcon, u8 port, 
const u8 *img, int l
img += 4;
len -= 4;
}
+
+   /* Sigh.  Tegra PMU FW's init message... */
+   if (len) {
+   u32 data = nvkm_falcon_rd32(falcon, 0x1c4 + (port * 8));
+
+   while (len--) {
+   *(u8 *)img++ = data & 0xff;
+   data >>= 8;
+   }
+   }
 }
 
 static void
@@ -64,6 +74,8 @@ gm200_flcn_pio_dmem_wr(struct nvkm_falcon *falcon, u8 port, 
const u8 *img, int l
img += 4;
len -= 4;
}
+
+   WARN_ON(len);
 }
 
 static void
@@ -74,7 +86,7 @@ gm200_flcn_pio_dmem_wr_init(struct nvkm_falcon *falcon, u8 
port, bool sec, u32 d
 
 const struct nvkm_falcon_func_pio
 gm200_flcn_dmem_pio = {
-   .min = 4,
+   .min = 1,
.max = 0x100,
.wr_init = gm200_flcn_pio_dmem_wr_init,
.wr = gm200_flcn_pio_dmem_wr,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c
index a72403777329..2ed04da3621d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c
@@ -225,7 +225,7 @@ gm20b_pmu_init(struct nvkm_pmu *pmu)
 
pmu->initmsg_received = false;
 
-   nvkm_falcon_load_dmem(falcon, , addr_args, sizeof(args), 0);
+   nvkm_falcon_pio_wr(falcon, (u8 *), 0, 0, DMEM, addr_args, 
sizeof(args), 0, false);
nvkm_falcon_start(falcon);
return 0;
 }
-- 
2.35.1



[PATCH 2/3] drm/nouveau/fb/tu102-: fix register used to determine scrub status

2023-01-30 Thread Ben Skeggs
Turing apparently needs to use the same register we use on Ampere.

Not executing the scrubber ucode when required would result in large
areas of VRAM being inaccessible to the driver.

Signed-off-by: Ben Skeggs 
---
 .../gpu/drm/nouveau/include/nvkm/subdev/fb.h  |  1 +
 .../gpu/drm/nouveau/nvkm/engine/device/base.c | 10 ++--
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild |  1 +
 .../gpu/drm/nouveau/nvkm/subdev/fb/ga102.c|  8 +--
 .../gpu/drm/nouveau/nvkm/subdev/fb/gv100.c|  5 --
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h |  2 +
 .../gpu/drm/nouveau/nvkm/subdev/fb/tu102.c| 55 +++
 7 files changed, 65 insertions(+), 17 deletions(-)
 create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fb/tu102.c

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
index 40768373cdd9..c5a4f49ee206 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
@@ -97,6 +97,7 @@ int gp100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, 
int inst, struct n
 int gp102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct 
nvkm_fb **);
 int gp10b_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct 
nvkm_fb **);
 int gv100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct 
nvkm_fb **);
+int tu102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct 
nvkm_fb **);
 int ga100_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct 
nvkm_fb **);
 int ga102_fb_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct 
nvkm_fb **);
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
index 364fea320cb3..1c81e5b34d29 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
@@ -2405,7 +2405,7 @@ nv162_chipset = {
.bus  = { 0x0001, gf100_bus_new },
.devinit  = { 0x0001, tu102_devinit_new },
.fault= { 0x0001, tu102_fault_new },
-   .fb   = { 0x0001, gv100_fb_new },
+   .fb   = { 0x0001, tu102_fb_new },
.fuse = { 0x0001, gm107_fuse_new },
.gpio = { 0x0001, gk104_gpio_new },
.gsp  = { 0x0001, gv100_gsp_new },
@@ -2440,7 +2440,7 @@ nv164_chipset = {
.bus  = { 0x0001, gf100_bus_new },
.devinit  = { 0x0001, tu102_devinit_new },
.fault= { 0x0001, tu102_fault_new },
-   .fb   = { 0x0001, gv100_fb_new },
+   .fb   = { 0x0001, tu102_fb_new },
.fuse = { 0x0001, gm107_fuse_new },
.gpio = { 0x0001, gk104_gpio_new },
.gsp  = { 0x0001, gv100_gsp_new },
@@ -2475,7 +2475,7 @@ nv166_chipset = {
.bus  = { 0x0001, gf100_bus_new },
.devinit  = { 0x0001, tu102_devinit_new },
.fault= { 0x0001, tu102_fault_new },
-   .fb   = { 0x0001, gv100_fb_new },
+   .fb   = { 0x0001, tu102_fb_new },
.fuse = { 0x0001, gm107_fuse_new },
.gpio = { 0x0001, gk104_gpio_new },
.gsp  = { 0x0001, gv100_gsp_new },
@@ -2510,7 +2510,7 @@ nv167_chipset = {
.bus  = { 0x0001, gf100_bus_new },
.devinit  = { 0x0001, tu102_devinit_new },
.fault= { 0x0001, tu102_fault_new },
-   .fb   = { 0x0001, gv100_fb_new },
+   .fb   = { 0x0001, tu102_fb_new },
.fuse = { 0x0001, gm107_fuse_new },
.gpio = { 0x0001, gk104_gpio_new },
.gsp  = { 0x0001, gv100_gsp_new },
@@ -2545,7 +2545,7 @@ nv168_chipset = {
.bus  = { 0x0001, gf100_bus_new },
.devinit  = { 0x0001, tu102_devinit_new },
.fault= { 0x0001, tu102_fault_new },
-   .fb   = { 0x0001, gv100_fb_new },
+   .fb   = { 0x0001, tu102_fb_new },
.fuse = { 0x0001, gm107_fuse_new },
.gpio = { 0x0001, gk104_gpio_new },
.gsp  = { 0x0001, gv100_gsp_new },
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild
index 5d0bab8ecb43..6ba5120a2ebe 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild
@@ -32,6 +32,7 @@ nvkm-y += nvkm/subdev/fb/gp100.o
 nvkm-y += nvkm/subdev/fb/gp102.o
 nvkm-y += nvkm/subdev/fb/gp10b.o
 nvkm-y += nvkm/subdev/fb/gv100.o
+nvkm-y += nvkm/subdev/fb/tu102.o
 nvkm-y += nvkm/subdev/fb/ga100.o
 nvkm-y += nvkm/subdev/fb/ga102.o
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c
index 8b7c8ea5e8a5..5a21b0ae4595 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ga102.c
@@ -40,12 +40,6 @@ 

[PATCH 1/3] drm/nouveau/devinit/tu102-: wait for GFW_BOOT_PROGRESS == COMPLETED

2023-01-30 Thread Ben Skeggs
Starting from Turing, the driver is no longer responsible for initiating
DEVINIT when required as the GPU started loading a FW image from ROM and
executing DEVINIT itself after power-on.

However - we apparently still need to wait for it to complete.

This should correct some issues with runpm on some systems, where we get
control of the HW before it's been fully reinitialised after resume from
suspend.

Signed-off-by: Ben Skeggs 
---
 .../drm/nouveau/nvkm/subdev/devinit/tu102.c   | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c
index 634f64f88fc8..81a1ad2c88a7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c
@@ -65,10 +65,33 @@ tu102_devinit_pll_set(struct nvkm_devinit *init, u32 type, 
u32 freq)
return ret;
 }
 
+static int
+tu102_devinit_wait(struct nvkm_device *device)
+{
+   unsigned timeout = 50 + 2000;
+
+   do {
+   if (nvkm_rd32(device, 0x118128) & 0x0001) {
+   if ((nvkm_rd32(device, 0x118234) & 0x00ff) == 0xff)
+   return 0;
+   }
+
+   usleep_range(1000, 2000);
+   } while (timeout--);
+
+   return -ETIMEDOUT;
+}
+
 int
 tu102_devinit_post(struct nvkm_devinit *base, bool post)
 {
struct nv50_devinit *init = nv50_devinit(base);
+   int ret;
+
+   ret = tu102_devinit_wait(init->base.subdev.device);
+   if (ret)
+   return ret;
+
gm200_devinit_preos(init, post);
return 0;
 }
-- 
2.35.1



Re: [PATCH v1 10/14] drm/msm/disp/dpu: add supports of DSC encoder v1.2 engine

2023-01-30 Thread Marijn Suijten
Abhinav,

On 2023-01-30 13:22:03, Abhinav Kumar wrote:
> Hi Marijn
> 
> On 1/30/2023 12:16 PM, Marijn Suijten wrote:
> > On 2023-01-24 15:52:46, Kuogee Hsieh wrote:
> > 
> > 
> > 
> > If only replying to a small chunk somewhere in the middle of a diff
> > and/or large review, please cut out unnecessary bits to make your reply
> > easier to find :)
> > 
>  +data = (dsc->flatness_min_qp & 0x1f);
>  +data |= (dsc->flatness_max_qp & 0x1f) << 5;
>  +data |= (dsc_info->det_thresh_flatness & 0xff) << 10;
> >>> dpu_hw_dsc.c computes this on the fly.  After removing that, and
> >>> using initial_lines from the function parameters, only
> >>> dsc_info->num_active_ss_per_enc remains.  Do you really need that
> >>> msm_display_dsc_info struct here, do you need it at all?
> >>
> >> I ported these code from our down stream code base.
> >>
> >> I make it work first, then clean it up will follow.
> >>
> >> I submit it for review since it looks like you guy like to have code 
> >> sooner.
> > 
> > Correct, I was looking forward to these patches albeit complete with the
> > promised DSI support from Jessica, which still seems to be pending.
> > 
> 
> DSI support is still being worked upon.
> 
> I dont think we promised DSC 1.2 will come with DSI together in the same 
> series. It was always going to be DSC 1.2 + DP followed by another 
> series from Jessica for DSI.
> 
> Lets set the expectations right.

Not saying that these patches were promised as part of this series (as
said, "which still seem to be pending"), just making clear that this
series if of no use to me (no hurry to get the code in my hands sooner)
until the DSI patches are also shared which I would have started working
on myself if I didn't know QUIC was picking it up to distract from the
current v1.1 broken-ness on SM8150 and SM8250.

To set my (and at least Neil's) expectations straight as well: DSC 1.2
HW support should come in a separate series without DP support.  Smaller
series (not to mention appropriately split-up patches) lead to a
decrease in scope, less dependencies and hopefully more efficient v2 -
for all involved.

- Marijn


Re: [PATCH] drm/amdgpu/fence: Fix oops due to non-matching drm_sched init/fini

2023-01-30 Thread Alex Deucher
On Mon, Jan 30, 2023 at 4:51 PM Guilherme G. Piccoli
 wrote:
>
> + Luben
>
> (sorry, missed that in the first submission).
>
> On 30/01/2023 18:45, Guilherme G. Piccoli wrote:
> > Currently amdgpu calls drm_sched_fini() from the fence driver sw fini
> > routine - such function is expected to be called only after the
> > respective init function - drm_sched_init() - was executed successfully.
> >
> > Happens that we faced a driver probe failure in the Steam Deck
> > recently, and the function drm_sched_fini() was called even without
> > its counter-part had been previously called, causing the following oops:
> >
> > amdgpu: probe of :04:00.0 failed with error -110
> > BUG: kernel NULL pointer dereference, address: 0090
> > PGD 0 P4D 0
> > Oops: 0002 [#1] PREEMPT SMP NOPTI
> > CPU: 0 PID: 609 Comm: systemd-udevd Not tainted 6.2.0-rc3-gpiccoli #338
> > Hardware name: Valve Jupiter/Jupiter, BIOS F7A0113 11/04/2022
> > RIP: 0010:drm_sched_fini+0x84/0xa0 [gpu_sched]
> > [...]
> > Call Trace:
> >  
> >  amdgpu_fence_driver_sw_fini+0xc8/0xd0 [amdgpu]
> >  amdgpu_device_fini_sw+0x2b/0x3b0 [amdgpu]
> >  amdgpu_driver_release_kms+0x16/0x30 [amdgpu]
> >  devm_drm_dev_init_release+0x49/0x70
> >  [...]
> >
> > To prevent that, check if the drm_sched was properly initialized for a
> > given ring before calling its fini counter-part.
> >
> > Notice ideally we'd use sched.ready for that; such field is set as the 
> > latest
> > thing on drm_sched_init(). But amdgpu seems to "override" the meaning of 
> > such
> > field - in the above oops for example, it was a GFX ring causing the crash, 
> > and
> > the sched.ready field was set to true in the ring init routine, regardless 
> > of
> > the state of the DRM scheduler. Hence, we ended-up using another sched 
> > field.
> >> > Fixes: 067f44c8b459 ("drm/amdgpu: avoid over-handle of fence driver fini 
> >> > in s3 test (v2)")
> > Cc: Andrey Grodzovsky 
> > Cc: Guchun Chen 
> > Cc: Mario Limonciello 
> > Signed-off-by: Guilherme G. Piccoli 
> > ---
> >
> >
> > Hi folks, first of all thanks in advance for reviews / comments!
> > Notice that I've used the Fixes tag more in the sense to bring it
> > to stable, I didn't find a good patch candidate that added the
> > call to drm_sched_fini(), was reaching way too old commits...so
> > 067f44c8b459 seems a good candidate - or maybe not?
> >
> > Now, with regards sched.ready, spent a bit of time to figure what
> > was happening...would be feasible maybe to stop using that to
> > mark some kind ring status? I think it should be possible to add a
> > flag to the ring structure for that, and free sched.ready from
> > being manipulate by the amdgpu driver, what's your thoughts on that?

It's been a while, but IIRC, we used to have a ring->ready field in
the driver which at some point got migrated out of the driver into the
GPU scheduler and the driver side code never got cleaned up.  I think
we should probably just drop the driver messing with that field and
leave it up to the drm scheduler.

Alex


> >
> > I could try myself, but first of course I'd like to raise the
> > "temperature" on this topic and check if somebody is already working
> > on that.
> >
> > Cheers,
> >
> > Guilherme
> >
> >
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 8 +++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c 
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > index 00444203220d..e154eb8241fb 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> > @@ -618,7 +618,13 @@ void amdgpu_fence_driver_sw_fini(struct amdgpu_device 
> > *adev)
> >   if (!ring || !ring->fence_drv.initialized)
> >   continue;
> >
> > - if (!ring->no_scheduler)
> > + /*
> > +  * Notice we check for sched.name since there's some
> > +  * override on the meaning of sched.ready by amdgpu.
> > +  * The natural check would be sched.ready, which is
> > +  * set as drm_sched_init() finishes...
> > +  */
> > + if (!ring->no_scheduler && ring->sched.name)
> >   drm_sched_fini(>sched);
> >
> >   for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j)


Re: [PATCH v2 06/27] drm/msm/dpu: move pipe_hw to dpu_plane_state

2023-01-30 Thread Abhinav Kumar




On 12/29/2022 11:18 AM, Dmitry Baryshkov wrote:

In preparation to adding fully virtualized planes, move struct
dpu_hw_sspp instance from struct dpu_plane to struct dpu_plane_state, as
it will become a part of state (allocated during atomic check) rather
than part of a plane (allocated during boot).



I was thinking about a couple of things about this patch:

1) Since we are moving away from using "pipe" and using "sspp", perhaps 
we can rename pipe_hw to hw_sspp in the below struct


--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -35,6 +35,8 @@  struct dpu_plane_state {
uint32_t multirect_mode;
bool pending;

+   struct dpu_hw_pipe *hw_sspp;
+
u64 plane_fetch_bw;
u64 plane_clk;
 };

2) I still dont see any comment as promised in v1 about why we are doing 
this in dpu_plane_reset().


https://patchwork.freedesktop.org/patch/473155/?series=99909=1#comment_875365

I think what we need to mention is that the dpu_plane_reset() is the one 
which allocates the plane state today and hence pipe_hw can only be 
assigned there.


Rest LGTM.



Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 102 --
  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   2 +
  2 files changed, 57 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 43fb8e00ada6..7ba954c7b3e0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -104,7 +104,6 @@ struct dpu_plane {
  
  	enum dpu_sspp pipe;
  
-	struct dpu_hw_sspp *pipe_hw;

uint32_t color_fill;
bool is_error;
bool is_rt_pipe;
@@ -279,6 +278,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
struct drm_framebuffer *fb, struct dpu_hw_pipe_cfg *pipe_cfg)
  {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
const struct dpu_format *fmt = NULL;
u64 qos_lut;
u32 total_fl = 0, lut_usage;
@@ -310,7 +310,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
fmt ? (char *)>base.pixel_format : NULL,
pdpu->is_rt_pipe, total_fl, qos_lut);
  
-	pdpu->pipe_hw->ops.setup_creq_lut(pdpu->pipe_hw, qos_lut);

+   pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut);
  }
  
  /**

@@ -322,6 +322,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane 
*plane,
struct drm_framebuffer *fb)
  {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
const struct dpu_format *fmt = NULL;
u32 danger_lut, safe_lut;
  
@@ -361,7 +362,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane,

danger_lut,
safe_lut);
  
-	pdpu->pipe_hw->ops.setup_danger_safe_lut(pdpu->pipe_hw,

+   pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw,
danger_lut, safe_lut);
  }
  
@@ -375,14 +376,15 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,

bool enable, u32 flags)
  {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
  
  	memset(_qos_cfg, 0, sizeof(pipe_qos_cfg));
  
  	if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {

-   pipe_qos_cfg.creq_vblank = 
pdpu->pipe_hw->cap->sblk->creq_vblank;
+   pipe_qos_cfg.creq_vblank = 
pstate->pipe_hw->cap->sblk->creq_vblank;
pipe_qos_cfg.danger_vblank =
-   pdpu->pipe_hw->cap->sblk->danger_vblank;
+   pstate->pipe_hw->cap->sblk->danger_vblank;
pipe_qos_cfg.vblank_en = enable;
}
  
@@ -408,7 +410,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,

pipe_qos_cfg.danger_vblank,
pdpu->is_rt_pipe);
  
-	pdpu->pipe_hw->ops.setup_qos_ctrl(pdpu->pipe_hw,

+   pstate->pipe_hw->ops.setup_qos_ctrl(pstate->pipe_hw,
_qos_cfg);
  }
  
@@ -422,18 +424,19 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,

struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
  {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
struct dpu_vbif_set_ot_params ot_params;
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
  
  	memset(_params, 0, sizeof(ot_params));

-   ot_params.xin_id = pdpu->pipe_hw->cap->xin_id;
-   ot_params.num = pdpu->pipe_hw->idx - SSPP_NONE;
+   ot_params.xin_id = pstate->pipe_hw->cap->xin_id;
+   ot_params.num = pstate->pipe_hw->idx - SSPP_NONE;
 

Re: [PATCH] drm/amdgpu/fence: Fix oops due to non-matching drm_sched init/fini

2023-01-30 Thread Guilherme G. Piccoli
+ Luben

(sorry, missed that in the first submission).

On 30/01/2023 18:45, Guilherme G. Piccoli wrote:
> Currently amdgpu calls drm_sched_fini() from the fence driver sw fini
> routine - such function is expected to be called only after the
> respective init function - drm_sched_init() - was executed successfully.
> 
> Happens that we faced a driver probe failure in the Steam Deck
> recently, and the function drm_sched_fini() was called even without
> its counter-part had been previously called, causing the following oops:
> 
> amdgpu: probe of :04:00.0 failed with error -110
> BUG: kernel NULL pointer dereference, address: 0090
> PGD 0 P4D 0
> Oops: 0002 [#1] PREEMPT SMP NOPTI
> CPU: 0 PID: 609 Comm: systemd-udevd Not tainted 6.2.0-rc3-gpiccoli #338
> Hardware name: Valve Jupiter/Jupiter, BIOS F7A0113 11/04/2022
> RIP: 0010:drm_sched_fini+0x84/0xa0 [gpu_sched]
> [...]
> Call Trace:
>  
>  amdgpu_fence_driver_sw_fini+0xc8/0xd0 [amdgpu]
>  amdgpu_device_fini_sw+0x2b/0x3b0 [amdgpu]
>  amdgpu_driver_release_kms+0x16/0x30 [amdgpu]
>  devm_drm_dev_init_release+0x49/0x70
>  [...]
> 
> To prevent that, check if the drm_sched was properly initialized for a
> given ring before calling its fini counter-part.
> 
> Notice ideally we'd use sched.ready for that; such field is set as the latest
> thing on drm_sched_init(). But amdgpu seems to "override" the meaning of such
> field - in the above oops for example, it was a GFX ring causing the crash, 
> and
> the sched.ready field was set to true in the ring init routine, regardless of
> the state of the DRM scheduler. Hence, we ended-up using another sched field.
> 
> Fixes: 067f44c8b459 ("drm/amdgpu: avoid over-handle of fence driver fini in 
> s3 test (v2)")
> Cc: Andrey Grodzovsky 
> Cc: Guchun Chen 
> Cc: Mario Limonciello 
> Signed-off-by: Guilherme G. Piccoli 
> ---
> 
> 
> Hi folks, first of all thanks in advance for reviews / comments!
> Notice that I've used the Fixes tag more in the sense to bring it
> to stable, I didn't find a good patch candidate that added the
> call to drm_sched_fini(), was reaching way too old commits...so
> 067f44c8b459 seems a good candidate - or maybe not?
> 
> Now, with regards sched.ready, spent a bit of time to figure what
> was happening...would be feasible maybe to stop using that to
> mark some kind ring status? I think it should be possible to add a
> flag to the ring structure for that, and free sched.ready from
> being manipulate by the amdgpu driver, what's your thoughts on that?
> 
> I could try myself, but first of course I'd like to raise the
> "temperature" on this topic and check if somebody is already working
> on that.
> 
> Cheers,
> 
> Guilherme
> 
> 
>  drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 8 +++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> index 00444203220d..e154eb8241fb 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
> @@ -618,7 +618,13 @@ void amdgpu_fence_driver_sw_fini(struct amdgpu_device 
> *adev)
>   if (!ring || !ring->fence_drv.initialized)
>   continue;
>  
> - if (!ring->no_scheduler)
> + /*
> +  * Notice we check for sched.name since there's some
> +  * override on the meaning of sched.ready by amdgpu.
> +  * The natural check would be sched.ready, which is
> +  * set as drm_sched_init() finishes...
> +  */
> + if (!ring->no_scheduler && ring->sched.name)
>   drm_sched_fini(>sched);
>  
>   for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j)


Re: [PATCH 1/5] drm/amd/amdgpu revert "implement tdr advanced mode"

2023-01-30 Thread Luben Tuikov
The series is,

Acked-by: Luben Tuikov 

We don't want the kernel to be in the business of retrying client's
requests. Instead we want the kernel to provide a conduit for such
requests to be sent, executed by the GPU, and a result returned.
If the kernel cannot process requests for any reason, e.g. GPU
is being reset, or in recovery, or OOM, or there's a problem with
the request, etc., the driver should return the request back to
the client (user space), and let the client decide how to proceed.

Regards,
Luben

On 2022-10-26 11:35, Christian König wrote:
> This reverts commit e6c6338f393b74ac0b303d567bb918b44ae7ad75.
> 
> This feature basically re-submits one job after another to
> figure out which one was the one causing a hang.
> 
> This is obviously incompatible with gang-submit which requires
> that multiple jobs run at the same time. It's also absolutely
> not helpful to crash the hardware multiple times if a clean
> recovery is desired.
> 
> For testing and debugging environments we should rather disable
> recovery alltogether to be able to inspect the state with a hw
> debugger.
> 
> Additional to that the sw implementation is clearly buggy and causes
> reference count issues for the hardware fence.
> 
> Signed-off-by: Christian König 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 103 -
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c|   2 +-
>  drivers/gpu/drm/scheduler/sched_main.c |  58 ++--
>  include/drm/gpu_scheduler.h|   3 -
>  4 files changed, 10 insertions(+), 156 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 6f958603c8cc..d4584e577b51 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -5070,94 +5070,6 @@ static int amdgpu_device_suspend_display_audio(struct 
> amdgpu_device *adev)
>   return 0;
>  }
>  
> -static void amdgpu_device_recheck_guilty_jobs(
> - struct amdgpu_device *adev, struct list_head *device_list_handle,
> - struct amdgpu_reset_context *reset_context)
> -{
> - int i, r = 0;
> -
> - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
> - struct amdgpu_ring *ring = adev->rings[i];
> - int ret = 0;
> - struct drm_sched_job *s_job;
> -
> - if (!ring || !ring->sched.thread)
> - continue;
> -
> - s_job = list_first_entry_or_null(>sched.pending_list,
> - struct drm_sched_job, list);
> - if (s_job == NULL)
> - continue;
> -
> - /* clear job's guilty and depend the folowing step to decide 
> the real one */
> - drm_sched_reset_karma(s_job);
> - drm_sched_resubmit_jobs_ext(>sched, 1);
> -
> - if (!s_job->s_fence->parent) {
> - DRM_WARN("Failed to get a HW fence for job!");
> - continue;
> - }
> -
> - ret = dma_fence_wait_timeout(s_job->s_fence->parent, false, 
> ring->sched.timeout);
> - if (ret == 0) { /* timeout */
> - DRM_ERROR("Found the real bad job! ring:%s, 
> job_id:%llx\n",
> - ring->sched.name, s_job->id);
> -
> -
> - amdgpu_fence_driver_isr_toggle(adev, true);
> -
> - /* Clear this failed job from fence array */
> - amdgpu_fence_driver_clear_job_fences(ring);
> -
> - amdgpu_fence_driver_isr_toggle(adev, false);
> -
> - /* Since the job won't signal and we go for
> -  * another resubmit drop this parent pointer
> -  */
> - dma_fence_put(s_job->s_fence->parent);
> - s_job->s_fence->parent = NULL;
> -
> - /* set guilty */
> - drm_sched_increase_karma(s_job);
> - amdgpu_reset_prepare_hwcontext(adev, reset_context);
> -retry:
> - /* do hw reset */
> - if (amdgpu_sriov_vf(adev)) {
> - amdgpu_virt_fini_data_exchange(adev);
> - r = amdgpu_device_reset_sriov(adev, false);
> - if (r)
> - adev->asic_reset_res = r;
> - } else {
> - clear_bit(AMDGPU_SKIP_HW_RESET,
> -   _context->flags);
> - r = amdgpu_do_asic_reset(device_list_handle,
> -  reset_context);
> - if (r && r == -EAGAIN)
> - goto retry;
> - }
> -
> - /*
> -  * add reset counter so that the following
> - 

[PATCH] drm/amdgpu/fence: Fix oops due to non-matching drm_sched init/fini

2023-01-30 Thread Guilherme G. Piccoli
Currently amdgpu calls drm_sched_fini() from the fence driver sw fini
routine - such function is expected to be called only after the
respective init function - drm_sched_init() - was executed successfully.

Happens that we faced a driver probe failure in the Steam Deck
recently, and the function drm_sched_fini() was called even without
its counter-part had been previously called, causing the following oops:

amdgpu: probe of :04:00.0 failed with error -110
BUG: kernel NULL pointer dereference, address: 0090
PGD 0 P4D 0
Oops: 0002 [#1] PREEMPT SMP NOPTI
CPU: 0 PID: 609 Comm: systemd-udevd Not tainted 6.2.0-rc3-gpiccoli #338
Hardware name: Valve Jupiter/Jupiter, BIOS F7A0113 11/04/2022
RIP: 0010:drm_sched_fini+0x84/0xa0 [gpu_sched]
[...]
Call Trace:
 
 amdgpu_fence_driver_sw_fini+0xc8/0xd0 [amdgpu]
 amdgpu_device_fini_sw+0x2b/0x3b0 [amdgpu]
 amdgpu_driver_release_kms+0x16/0x30 [amdgpu]
 devm_drm_dev_init_release+0x49/0x70
 [...]

To prevent that, check if the drm_sched was properly initialized for a
given ring before calling its fini counter-part.

Notice ideally we'd use sched.ready for that; such field is set as the latest
thing on drm_sched_init(). But amdgpu seems to "override" the meaning of such
field - in the above oops for example, it was a GFX ring causing the crash, and
the sched.ready field was set to true in the ring init routine, regardless of
the state of the DRM scheduler. Hence, we ended-up using another sched field.

Fixes: 067f44c8b459 ("drm/amdgpu: avoid over-handle of fence driver fini in s3 
test (v2)")
Cc: Andrey Grodzovsky 
Cc: Guchun Chen 
Cc: Mario Limonciello 
Signed-off-by: Guilherme G. Piccoli 
---


Hi folks, first of all thanks in advance for reviews / comments!
Notice that I've used the Fixes tag more in the sense to bring it
to stable, I didn't find a good patch candidate that added the
call to drm_sched_fini(), was reaching way too old commits...so
067f44c8b459 seems a good candidate - or maybe not?

Now, with regards sched.ready, spent a bit of time to figure what
was happening...would be feasible maybe to stop using that to
mark some kind ring status? I think it should be possible to add a
flag to the ring structure for that, and free sched.ready from
being manipulate by the amdgpu driver, what's your thoughts on that?

I could try myself, but first of course I'd like to raise the
"temperature" on this topic and check if somebody is already working
on that.

Cheers,

Guilherme


 drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 00444203220d..e154eb8241fb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -618,7 +618,13 @@ void amdgpu_fence_driver_sw_fini(struct amdgpu_device 
*adev)
if (!ring || !ring->fence_drv.initialized)
continue;
 
-   if (!ring->no_scheduler)
+   /*
+* Notice we check for sched.name since there's some
+* override on the meaning of sched.ready by amdgpu.
+* The natural check would be sched.ready, which is
+* set as drm_sched_init() finishes...
+*/
+   if (!ring->no_scheduler && ring->sched.name)
drm_sched_fini(>sched);
 
for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j)
-- 
2.39.0



Re: [PATCH 1/2] dt-bindings: display: bridge: Add NXP i.MX93 parallel display format configuration

2023-01-30 Thread Rob Herring
On Mon, Jan 30, 2023 at 04:39:05PM +0800, Liu Ying wrote:
> On Sun, 2023-01-29 at 12:46 +0100, Krzysztof Kozlowski wrote:
> > On 28/01/2023 04:47, Liu Ying wrote:
> > > NXP i.MX93 mediamix blk-ctrl contains one DISPLAY_MUX register
> > > which
> > > configures parallel display format by using the
> > > "PARALLEL_DISP_FORMAT"
> > > field. Add device tree bindings for the display format
> > > configuration.
> > > 
> > > Signed-off-by: Liu Ying 
> > > ---
> > >  .../display/bridge/nxp,imx93-pdfc.yaml| 78
> > > +++
> > >  1 file changed, 78 insertions(+)
> > >  create mode 100644
> > > Documentation/devicetree/bindings/display/bridge/nxp,imx93-
> > > pdfc.yaml
> > > 
> > > diff --git
> > > a/Documentation/devicetree/bindings/display/bridge/nxp,imx93-
> > > pdfc.yaml
> > > b/Documentation/devicetree/bindings/display/bridge/nxp,imx93-
> > > pdfc.yaml
> > > new file mode 100644
> > > index ..a84bfb46b01d
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/display/bridge/nxp,imx93-
> > > pdfc.yaml
> > > @@ -0,0 +1,78 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: 
> > > https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevicetree.org%2Fschemas%2Fdisplay%2Fbridge%2Fnxp%2Cimx93-pdfc.yaml%23=05%7C01%7Cvictor.liu%40nxp.com%7C7fb1b69849974435787008db01ee832c%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C638105896131701918%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C=kkX5B45NTsmDKKzxjOiE6MaE4zkMVbMe4ILammVSwMc%3D=0
> > > +$schema: 
> > > https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevicetree.org%2Fmeta-schemas%2Fcore.yaml%23=05%7C01%7Cvictor.liu%40nxp.com%7C7fb1b69849974435787008db01ee832c%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C638105896131701918%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C=vIVpdEjIo6H3V8T7iTbDwz4Bmn0d%2BQB4BCJNJ0OzKJw%3D=0
> > > +
> > > +title: NXP i.MX93 Parallel Display Format Configuration
> > > +
> > > +maintainers:
> > > +  - Liu Ying 
> > > +
> > > +description: |
> > > +  The i.MX93 mediamix blk-ctrl contains one DISPLAY_MUX register
> > > which
> > > +  configures parallel display format by using the
> > > "PARALLEL_DISP_FORMAT"
> > > +  field.
> > > +
> > > +properties:
> > > +  compatible:
> > > +const: nxp,imx93-pdfc
> > 
> > 
> > Based on description, I have doubts this is a separate bridge device.
> > Why this is not part of display driver/bindings?
> 
> The relevant display controller in i.MX93 SoC is LCDIF. From hardware
> design PoV, the parallel display format configuration logic is not a
> part of LCDIF. Instead, it's a part of i.MX93 mediamix blk-ctrl. The
> blk-ctrl includes controls for miscellaneous devices with small logics,
> like this parallel display format configuration, LVDS Display
> Bridge(LDB, see fsl,ldb.yaml) and so on. The below pipeline describes
> data flow of a parallel display LCD panel:
> 
> DRAM -> LCDIF -> parallel display format configuration -> LCD panel
> 
> So, the parallel display format configuration appears to be a separate
> bridge.
> 
> > 
> > We do not create usually devices for single registers, because they
> > are
> > not a devices. Devices are a bit more complex - have some pin
> > inputs/outputs, not a register only. Of course there are exception,
> > but
> > this one does not look like one.
> 
> IMHO, this one is a standalone device although it is controlled by one
> single register. It's input pins connect to LCDIF and output pins
> connect to i.MX93 SoC's pins/pads.

Fair enough. It needs to be defined as part of the mediamix blkctrl 
schema though.

Rob


Re: [PATCH v1 10/14] drm/msm/disp/dpu: add supports of DSC encoder v1.2 engine

2023-01-30 Thread Abhinav Kumar

Hi Marijn

On 1/30/2023 12:16 PM, Marijn Suijten wrote:

On 2023-01-24 15:52:46, Kuogee Hsieh wrote:



If only replying to a small chunk somewhere in the middle of a diff
and/or large review, please cut out unnecessary bits to make your reply
easier to find :)


+   data = (dsc->flatness_min_qp & 0x1f);
+   data |= (dsc->flatness_max_qp & 0x1f) << 5;
+   data |= (dsc_info->det_thresh_flatness & 0xff) << 10;

dpu_hw_dsc.c computes this on the fly.  After removing that, and
using initial_lines from the function parameters, only
dsc_info->num_active_ss_per_enc remains.  Do you really need that
msm_display_dsc_info struct here, do you need it at all?


I ported these code from our down stream code base.

I make it work first, then clean it up will follow.

I submit it for review since it looks like you guy like to have code sooner.


Correct, I was looking forward to these patches albeit complete with the
promised DSI support from Jessica, which still seems to be pending.



DSI support is still being worked upon.

I dont think we promised DSC 1.2 will come with DSI together in the same 
series. It was always going to be DSC 1.2 + DP followed by another 
series from Jessica for DSI.


Lets set the expectations right.

Thanks

Abhinav

When sending patches to that extent, with the intent of getting quick
turnaround but knowing that they are not ready for prime time yet (or
were they, based on your "submit it for review" mention? Don't you mean
testing?), please annotate the series with an RFC tag accompanied with a
description what still needs to be done and why.  That would have saved
a great deal of comments and review.


yes, eliminate msm_display_dsc_info is my next target and hope it can be
done.


Thank you.  Again, if that was the intent from the get-go, that's
perfect material to put in an RFC series' cover letter.

- Marijn


Re: [Intel-gfx] [PATCH] drm/i915/pcode: Wait 10 seconds for pcode to settle

2023-01-30 Thread Andi Shyti
Hi Rodrigo,

first of all, thanks for looking into this!

> > > > > > In the call flow invoked by intel_pcode_init(), I've added brief 
> > > > > > comments
> > > > > > where further clarification is needed in this scenario, and a 
> > > > > > description of
> > > > > > the suspicious scenario at the bottom.
> > > > > > 
> > > > > > -
> > > > > > intel_pcode_init()
> > > > > >  |
> > > > > >  +-> skl_pcode_request(uncore, DG1_PCODE_STATUS,
> > > > > >DG1_UNCORE_GET_INIT_STATUS,
> > > > > >DG1_UNCORE_INIT_STATUS_COMPLETE,
> > > > > >DG1_UNCORE_INIT_STATUS_COMPLETE, 18);
> > > > > >|
> > > > > >+-> skl_pcode_try_request()
> > > > > >  |
> > > > > >  +->  *status = __snb_pcode_rw(uncore, mbox, , 
> > > > > > NULL,
> > > > > >500, 0, true);
> > > > > > 
> > > > > > -
> > > > > > static int __snb_pcode_rw(struct intel_uncore *uncore, u32 mbox,
> > > > > >   u32 *val, u32 *val1,
> > > > > >   int fast_timeout_us, int slow_timeout_ms,
> > > > > >   bool is_read)
> > > > > > {
> > > > > > ...
> > > > > > /* Before writing a value to the GEN6_PCODE_DATA register,
> > > > > >check if the bit in the GEN6_PCODE_MAILBOX register 
> > > > > > indicates
> > > > > >BUSY. */
> > > > > > if (intel_uncore_read_fw(uncore, GEN6_PCODE_MAILBOX) & 
> > > > > > GEN6_PCODE_READY)
> > > > > > return -EAGAIN;
> > > > > 
> > > > > what if we fail here because the punit is still initializing and
> > > > > will be ready, say, in 10 seconds?
> > > > > 
> > > > > GG, without going any further, we fail here! The -EAGAIN we
> > > > > receive from the test comes from this point. We don't fail with
> > > > > -ETIMEDOUT, but with -EAGAIN and the reason is because the punit
> > > > > is not ready to perform the very fist communication and we fail
> > > > > the probing.
> > > > > 
> > > > > It doesn't mean, though, that there is anything wrong, we just
> > > > > need to wait a bit before "taking drastic decisions"!
> > > > > 
> > > > > This patch is suggesting to wait up to 10s for the punit to be
> > > > > ready and eventually try to probe again... and, indeed, it works!
> > > > 
> > > > As GG, what I still don't understand is how this extra 10 seconds
> > > > wait helps... have you tried to simple add the 10 to the 180 and
> > > > make the code 190 sec instead?
> > > 
> > > maybe I haven't been able to explain the issue properly.
> > > 
> > > I can even set that timer to 2hrs and a half and nothing changes
> > > because we fail before.
> > > 
> > > Here it's not a matter of how much do I wait but when do I check
> > > the pcode readiness (i.e. signalled by the GEN6_PCODE_READY bit
> > > in the GEN6_PCODE_MAILBOX register).
> > > 
> > > During a normal run we are always sure that communicating with
> > > the punit works, because we made it sure during the previous
> > > transaction.
> > > 
> > > During probe there is no previous transaction and we start
> > > communicating with the punit without making sure that it is
> > > ready. And indeed some times it is not, so that we suppress the
> > > probing on purpose instead of giving it another chance.
> > > 
> > > I admit that the commit message is not written properly and
> > > rather misleading, but here it's not at all a matter of how much
> > > do I wait.
> > 
> > The commit message was initially confused because it looks like
> > we are just adding a wait, without doing anything
> > 
> > But looking to the code we can see that it will wait until
> > pcode is ready with a timeout of 10 seconds.
> > 
> > But if pcode is ready in 10 seconds, why pcode is not ready
> > in 190 seconds. We are doing absolutely nothing more that could
> > make pcode ready in 10 seconds that won't be in 190.
> > 
> > This is what we are missing here... The code as is doesn't make
> > a lot of sense to us and it looks like it is solving the issue
> > by the 10 extra seconds and not by some special status checking.
> 
> Okay, after an offline talk I am convinced now that we need some
> check like this in some place.
> 
> But the commit message needs be be fully re-written.
> 
> It needs to be clear that underneath, the pcode communication
> functions will do a check for ready without any wait, what will
> make desired timeout to never really wait for the pcode done
> and prematurely return.
> 
> at __snb_pcode_rw():
> 
>  if (intel_uncore_read_fw(uncore, GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY)
> return -EAGAIN;
> 
> So, for this reason we need to ensure that pcode is really ready
> before we wait.
> 
> Other options are to handle the EAGAIN return and then wait.
> Or even change the 

[PATCH v5] drm/mediatek: Add support for AR30 and BA30

2023-01-30 Thread Justin Green
Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver.

Tested using "modetest -P" on an MT8195.

Signed-off-by: Justin Green 
---
v2:
 * Rebase and resolve merge conflicts with the AFBC patch.
v3:
 * Moved 10-bit support detection to mtk_disk_ovl.c
v4:
 * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c
v5:
 * Minor style adjustments per checkpatch.pl

 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 ++
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 75 +
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 27 
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.c| 28 +++-
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
 8 files changed, 146 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 33e61a136bbc..6ad22ce75b81 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
 void mtk_ovl_unregister_vblank_cb(struct device *dev);
 void mtk_ovl_enable_vblank(struct device *dev);
 void mtk_ovl_disable_vblank(struct device *dev);
+const u32 *mtk_ovl_get_formats(struct device *dev);
+size_t mtk_ovl_get_num_formats(struct device *dev);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
@@ -122,4 +124,6 @@ void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt 
*cmdq_pkt);
 void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt);
 void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
 struct cmdq_pkt *cmdq_pkt);
+const u32 *mtk_rdma_get_formats(struct device *dev);
+size_t mtk_rdma_get_num_formats(struct device *dev);
 #endif
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 84daeaffab6a..1db70a77560f 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -41,6 +41,7 @@
 #define DISP_REG_OVL_RDMA_CTRL(n)  (0x00c0 + 0x20 * (n))
 #define DISP_REG_OVL_RDMA_GMC(n)   (0x00c8 + 0x20 * (n))
 #define DISP_REG_OVL_ADDR_MT2701   0x0040
+#define DISP_REG_OVL_CLRFMT_EXT0x02D0
 #define DISP_REG_OVL_ADDR_MT8173   0x0f40
 #define DISP_REG_OVL_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * (n))
 #define DISP_REG_OVL_HDR_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * (n) 
+ 0x04)
@@ -61,11 +62,45 @@
0 : OVL_CON_CLRFMT_RGB)
 #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
OVL_CON_CLRFMT_RGB : 0)
+#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl))
+#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl)   (depth << 4 * (ovl))
+#define OVL_CON_CLRFMT_8_BIT   0x00
+#define OVL_CON_CLRFMT_10_BIT  0x01
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff
 #defineOVL_CON_VIRT_FLIP   BIT(9)
 #defineOVL_CON_HORZ_FLIP   BIT(10)
 
+static const u32 formats_mt8173[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
+static const u32 formats_mt8195[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ARGB2101010,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_BGRA1010102,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
@@ -73,6 +108,7 @@ struct mtk_disp_ovl_data {
bool fmt_rgb565_is_0;
bool smi_id_en;
bool supports_afbc;
+   bool supports_10bit;
 };
 
 /*
@@ -188,6 +224,26 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, 
struct cmdq_pkt *cmdq_pkt
   DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx));
 }
 
+static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format,
+ struct cmdq_pkt *cmdq_pkt)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+   unsigned int reg;
+   unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT;
+
+   reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT);
+   reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);
+
+   if (format == DRM_FORMAT_RGBA1010102 ||
+   

[PATCH v4] drm/mediatek: Add support for AR30 and BA30

2023-01-30 Thread Justin Green
Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver.

Tested using "modetest -P" on an MT8195.

Signed-off-by: Justin Green 
---
v2:
 * Rebase and resolve merge conflicts with the AFBC patch.
v3:
 * Moved 10-bit support detection to mtk_disk_ovl.c
v4:
 * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c

 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 ++
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 75 +
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 27 
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.c| 28 +++-
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
 8 files changed, 146 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 33e61a136bbc..c292022b8270 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
 void mtk_ovl_unregister_vblank_cb(struct device *dev);
 void mtk_ovl_enable_vblank(struct device *dev);
 void mtk_ovl_disable_vblank(struct device *dev);
+const u32* mtk_ovl_get_formats(struct device *dev);
+size_t mtk_ovl_get_num_formats(struct device *dev);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
@@ -122,4 +124,6 @@ void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt 
*cmdq_pkt);
 void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt);
 void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
 struct cmdq_pkt *cmdq_pkt);
+const u32* mtk_rdma_get_formats(struct device *dev);
+size_t mtk_rdma_get_num_formats(struct device *dev);
 #endif
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 84daeaffab6a..781cd18f94ba 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -41,6 +41,7 @@
 #define DISP_REG_OVL_RDMA_CTRL(n)  (0x00c0 + 0x20 * (n))
 #define DISP_REG_OVL_RDMA_GMC(n)   (0x00c8 + 0x20 * (n))
 #define DISP_REG_OVL_ADDR_MT2701   0x0040
+#define DISP_REG_OVL_CLRFMT_EXT0x02D0
 #define DISP_REG_OVL_ADDR_MT8173   0x0f40
 #define DISP_REG_OVL_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * (n))
 #define DISP_REG_OVL_HDR_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * (n) 
+ 0x04)
@@ -61,11 +62,45 @@
0 : OVL_CON_CLRFMT_RGB)
 #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
OVL_CON_CLRFMT_RGB : 0)
+#define OVL_CON_CLRFMT_BIT_DEPTH_MASK(ovl) (0xFF << 4 * (ovl))
+#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl)   (depth << 4 * (ovl))
+#define OVL_CON_CLRFMT_8_BIT   0x00
+#define OVL_CON_CLRFMT_10_BIT  0x01
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff
 #defineOVL_CON_VIRT_FLIP   BIT(9)
 #defineOVL_CON_HORZ_FLIP   BIT(10)
 
+static const u32 formats_mt8173[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
+static const u32 formats_mt8195[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ARGB2101010,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_BGRA1010102,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
@@ -73,6 +108,7 @@ struct mtk_disp_ovl_data {
bool fmt_rgb565_is_0;
bool smi_id_en;
bool supports_afbc;
+   bool supports_10bit;
 };
 
 /*
@@ -188,6 +224,26 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, 
struct cmdq_pkt *cmdq_pkt
   DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx));
 }
 
+static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format,
+ struct cmdq_pkt *cmdq_pkt)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+   unsigned int reg;
+   unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT;
+
+   reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT);
+   reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);
+
+   if (format == DRM_FORMAT_RGBA1010102 ||
+   format == DRM_FORMAT_BGRA1010102 ||
+   

Re: [PATCH v1 09/14] drm/msm/dsi: export struct msm_compression_info to dpu encoder

2023-01-30 Thread Marijn Suijten
On 2023-01-23 10:24:29, Kuogee Hsieh wrote:

> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> index d612419..70a74ed 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c

> @@ -892,6 +894,10 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state 
> *disp_state, struct msm_k
>  
>   pm_runtime_get_sync(_kms->pdev->dev);
>  
> + for (i = 0; i < cat->dsc_count; i++)
> + msm_disp_snapshot_add_block(disp_state, cat->dsc[i].len,
> + dpu_kms->mmio + cat->dsc[i].base, "dsc_%d", i);
> +

Note that we've landed snapshotting of the DSC block in [1] because we
need it now, and - as discussed elsewhere - is perfect material to be
submitted in a standalone, appropriately described/titled patch (fine to
be part of a series, as long as that patch comprises this single diff).

[1]: 
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=a7efe60e36b9c0e966d7f82ac90a89b591d984e9

Keep in mind that it was added at the bottom of dpu_kms_mdp_snapshot()
instead of the top, so git might not clean it up or mark it as conflict
during a rebase; don't forget to drop it from v2 :)

>   /* dump CTL sub-blocks HW regs info */
>   for (i = 0; i < cat->ctl_count; i++)
>   msm_disp_snapshot_add_block(disp_state, cat->ctl[i].len,



- Marijn


Re: linux-6.2-rc4+ hangs on poweroff/reboot: Bisected

2023-01-30 Thread Chris Clayton
Thanks, Ben.

On 30/01/2023 01:09, Ben Skeggs wrote:
> On Sat, 28 Jan 2023 at 21:29, Chris Clayton  wrote:
>>
>>
>>
>> On 28/01/2023 05:42, Linux kernel regression tracking (Thorsten Leemhuis) 
>> wrote:
>>> On 27.01.23 20:46, Chris Clayton wrote:
 [Resend because the mail client on my phone decided to turn HTML on behind 
 my back, so my reply got bounced.]

 Thanks Thorsten.

 I did try to revert but it didnt revert cleanly and I don't have the 
 knowledge to fix it up.

 The patch was part of a merge that included a number of related patches. 
 Tomorrow, I'll try to revert the lot and report
 back.
>>>
>>> You are free to do so, but there is no need for that from my side. I
>>> only wanted to know if a simple revert would do the trick; if it
>>> doesn't, it in my experience often is best to leave things to the
>>> developers of the code in question,
>>
>> Sound advice, Thorsten. Way to many conflicts for me to resolve.
> Hey,
> 
> This is a complete shot-in-the-dark, as I don't see this behaviour on
> *any* of my boards.  Could you try the attached patch please?

Unfortunately, the patch made no difference.

I've been looking at how the graphics on my laptop is set up, and have a bit of 
a worry about whether the firmware might
be playing a part in this problem. In order to offload video decoding to the 
NVidia TU117 GPU, it seems the scrubber
firmware must be available, but as far as I know,that has not been released by 
NVidia. To get it to work, I followed
what ubuntu have done and the scrubber in /lib/firmware/nvidia/tu117/nvdec/ is 
a symlink to
../../tu116/nvdev/scrubber.bin. That, of course, means that some of the 
firmware loaded is for a different card is being
loaded. I note that processing related to firmware is being changed in the 
patch. Might my set up be at the root of my
problem?

I'll have a fiddle an see what I can work out.

Chris

> 
> Thanks,
> Ben.
> 
>>
>> as they know it best and thus have a
>>> better idea which hidden side effect a more complex revert might have.
>>>
>>> Ciao, Thorsten
>>>
 On 27/01/2023 11:20, Linux kernel regression tracking (Thorsten Leemhuis) 
 wrote:
> Hi, this is your Linux kernel regression tracker. Top-posting for once,
> to make this easily accessible to everyone.
>
> @nouveau-maintainers, did anyone take a look at this? The report is
> already 8 days old and I don't see a single reply. Sure, we'll likely
> get a -rc8, but still it would be good to not fix this on the finish line.
>
> Chris, btw, did you try if you can revert the commit on top of latest
> mainline? And if so, does it fix the problem?
>
> Ciao, Thorsten (wearing his 'the Linux kernel's regression tracker' hat)
> --
> Everything you wanna know about Linux kernel regression tracking:
> https://linux-regtracking.leemhuis.info/about/#tldr
> If I did something stupid, please tell me, as explained on that page.
>
> #regzbot poke
>
> On 19.01.23 15:33, Linux kernel regression tracking (Thorsten Leemhuis)
> wrote:
>> [adding various lists and the two other nouveau maintainers to the list
>> of recipients]
>
>> On 18.01.23 21:59, Chris Clayton wrote:
>>> Hi.
>>>
>>> I build and installed the lastest development kernel earlier this week. 
>>> I've found that when I try the laptop down (or
>>> reboot it), it hangs right at the end of closing the current session. 
>>> The last line I see on  the screen when rebooting is:
>>>
>>>   sd 4:0:0:0: [sda] Synchronising SCSI cache
>>>
>>> when closing down I see one additional line:
>>>
>>>   sd 4:0:0:0 [sda]Stopping disk
>>>
>>> In both cases the machine then hangs and I have to hold down the power 
>>> button fot a few seconds to switch it off.
>>>
>>> Linux 6.1 is OK but 6.2-rc1 hangs, so I bisected between this two and 
>>> landed on:
>>>
>>>   # first bad commit: [0e44c21708761977dcbea9b846b51a6fb684907a] 
>>> drm/nouveau/flcn: new code to load+boot simple HS FWs
>>> (VPR scrubber)
>>>
>>> I built and installed a kernel with 
>>> f15cde64b66161bfa74fb58f4e5697d8265b802e (the parent of the bad commit) 
>>> checked out
>>> and that shuts down and reboots fine. It the did the same with the bad 
>>> commit checked out and that does indeed hang, so
>>> I'm confident the bisect outcome is OK.
>>>
>>> Kernels 6.1.6 and 5.15.88 are also OK.
>>>
>>> My system had dual GPUs - one intel and one NVidia. Related extracts 
>>> from 'lscpi -v' is:
>>>
>>> 00:02.0 VGA compatible controller: Intel Corporation CometLake-H GT2 
>>> [UHD Graphics] (rev 05) (prog-if 00 [VGA controller])
>>> Subsystem: CLEVO/KAPOK Computer CometLake-H GT2 [UHD Graphics]
>>>
>>> Flags: bus master, fast devsel, latency 0, IRQ 142
>>>
>>> Memory at c200 

Re: [PATCH v1 10/14] drm/msm/disp/dpu: add supports of DSC encoder v1.2 engine

2023-01-30 Thread Marijn Suijten
On 2023-01-24 15:52:46, Kuogee Hsieh wrote:



If only replying to a small chunk somewhere in the middle of a diff
and/or large review, please cut out unnecessary bits to make your reply
easier to find :)

> >> +  data = (dsc->flatness_min_qp & 0x1f);
> >> +  data |= (dsc->flatness_max_qp & 0x1f) << 5;
> >> +  data |= (dsc_info->det_thresh_flatness & 0xff) << 10;
> > dpu_hw_dsc.c computes this on the fly.  After removing that, and
> > using initial_lines from the function parameters, only
> > dsc_info->num_active_ss_per_enc remains.  Do you really need that
> > msm_display_dsc_info struct here, do you need it at all?
> 
> I ported these code from our down stream code base.
> 
> I make it work first, then clean it up will follow.
> 
> I submit it for review since it looks like you guy like to have code sooner.

Correct, I was looking forward to these patches albeit complete with the
promised DSI support from Jessica, which still seems to be pending.

When sending patches to that extent, with the intent of getting quick
turnaround but knowing that they are not ready for prime time yet (or
were they, based on your "submit it for review" mention? Don't you mean
testing?), please annotate the series with an RFC tag accompanied with a
description what still needs to be done and why.  That would have saved
a great deal of comments and review.

> yes, eliminate msm_display_dsc_info is my next target and hope it can be 
> done.

Thank you.  Again, if that was the intent from the get-go, that's
perfect material to put in an RFC series' cover letter.

- Marijn


Re: [PATCH v2 6/6] drm/debugfs: Make the struct drm_debugfs_entry independent of DRM device

2023-01-30 Thread kernel test robot
Hi Maíra,

Thank you for the patch! Yet something to improve:

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

url:
https://github.com/intel-lab-lkp/linux/commits/Ma-ra-Canal/drm-debugfs-Introduce-wrapper-for-debugfs-list/20230130-203549
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:
https://lore.kernel.org/r/20230130123008.287141-7-mcanal%40igalia.com
patch subject: [PATCH v2 6/6] drm/debugfs: Make the struct drm_debugfs_entry 
independent of DRM device
config: x86_64-rhel-8.3-kselftests 
(https://download.01.org/0day-ci/archive/20230131/202301310330.jvo5mu9t-...@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-8) 11.3.0
reproduce (this is a W=1 build):
# 
https://github.com/intel-lab-lkp/linux/commit/2b098c9687b25368fa4a9e128963a13723aace67
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Ma-ra-Canal/drm-debugfs-Introduce-wrapper-for-debugfs-list/20230130-203549
git checkout 2b098c9687b25368fa4a9e128963a13723aace67
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=x86_64 olddefconfig
make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/gpu/drm/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

   drivers/gpu/drm/drm_gem_vram_helper.c: In function 'drm_vram_mm_debugfs':
>> drivers/gpu/drm/drm_gem_vram_helper.c:961:40: error: 'struct 
>> drm_debugfs_entry' has no member named 'dev'
 961 | struct drm_vram_mm *vmm = entry->dev->vram_mm;
 |^~


vim +961 drivers/gpu/drm/drm_gem_vram_helper.c

6b5ce4a1fb8489 Thomas Zimmermann 2019-09-11  953  
6b5ce4a1fb8489 Thomas Zimmermann 2019-09-11  954  /*
6b5ce4a1fb8489 Thomas Zimmermann 2019-09-11  955   * struct drm_vram_mm
6b5ce4a1fb8489 Thomas Zimmermann 2019-09-11  956   */
6b5ce4a1fb8489 Thomas Zimmermann 2019-09-11  957  
6454c853ce9fa8 Maíra Canal   2023-01-30  958  static int 
drm_vram_mm_debugfs(struct seq_file *m, struct drm_device *dev, void *data)
6b5ce4a1fb8489 Thomas Zimmermann 2019-09-11  959  {
6fd80729f14e3f Maíra Canal   2022-12-19  960struct 
drm_debugfs_entry *entry = m->private;
6fd80729f14e3f Maíra Canal   2022-12-19 @961struct drm_vram_mm *vmm 
= entry->dev->vram_mm;
9de59bc201496f Dave Airlie   2020-08-04  962struct 
ttm_resource_manager *man = ttm_manager_type(>bdev, TTM_PL_VRAM);
6b5ce4a1fb8489 Thomas Zimmermann 2019-09-11  963struct drm_printer p = 
drm_seq_file_printer(m);
6b5ce4a1fb8489 Thomas Zimmermann 2019-09-11  964  
9de59bc201496f Dave Airlie   2020-08-04  965
ttm_resource_manager_debug(man, );
6b5ce4a1fb8489 Thomas Zimmermann 2019-09-11  966return 0;
6b5ce4a1fb8489 Thomas Zimmermann 2019-09-11  967  }
6b5ce4a1fb8489 Thomas Zimmermann 2019-09-11  968  

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


[PATCH] drm/amd/display: Trivial swizzle-related code clean-ups

2023-01-30 Thread Guilherme G. Piccoli
This is a very trivial code clean-up related to commit 5468c36d6285
("drm/amd/display: Filter Invalid 420 Modes for HDMI TMDS"). This commit
added a validation on driver probe to prevent invalid TMDS modes, but one
of the fake properties (swizzle) ended-up causing a warning on driver
probe; was reported here: https://gitlab.freedesktop.org/drm/amd/-/issues/2264.

It was fixed by commit 105a8b8698e2 ("drm/amd/display: patch cases with
unknown plane state to prevent warning"), but the validation code had
a double variable assignment, which we hereby remove. Also, the fix relies
in the dcn2{0,1}patch_unknown_plane_state() callbacks, so while at it we
took the opportunity to perform a small code clean-up in such routines.

Cc: Aurabindo Pillai 
Cc: Daniel Wheeler 
Cc: Fangzhi Zuo 
Cc: Harry Wentland 
Cc: Leo Li 
Cc: Mark Broadworth 
Cc: Melissa Wen 
Cc: Rodrigo Siqueira 
Cc: Sung Joon Kim 
Cc: Swapnil Patel 
Signed-off-by: Guilherme G. Piccoli 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 -
 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 8 ++--
 drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 6 ++
 3 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 86a2f7f58550..e71e94663d14 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6336,7 +6336,6 @@ static enum dc_status 
dm_validate_stream_and_context(struct dc *dc,
dc_plane_state->plane_size.surface_size.width  = stream->src.width;
dc_plane_state->plane_size.chroma_size.height  = stream->src.height;
dc_plane_state->plane_size.chroma_size.width   = stream->src.width;
-   dc_plane_state->tiling_info.gfx9.swizzle =  DC_SW_UNKNOWN;
dc_plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB;
dc_plane_state->tiling_info.gfx9.swizzle = DC_SW_UNKNOWN;
dc_plane_state->rotation = ROTATION_ANGLE_0;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index 531f405d2554..3af24ef9cb2d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -2225,14 +2225,10 @@ enum dc_status dcn20_patch_unknown_plane_state(struct 
dc_plane_state *plane_stat
enum surface_pixel_format surf_pix_format = plane_state->format;
unsigned int bpp = resource_pixel_format_to_bpp(surf_pix_format);
 
-   enum swizzle_mode_values swizzle = DC_SW_LINEAR;
-
+   plane_state->tiling_info.gfx9.swizzle = DC_SW_64KB_S;
if (bpp == 64)
-   swizzle = DC_SW_64KB_D;
-   else
-   swizzle = DC_SW_64KB_S;
+   plane_state->tiling_info.gfx9.swizzle = DC_SW_64KB_D;
 
-   plane_state->tiling_info.gfx9.swizzle = swizzle;
return DC_OK;
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
index fbcf0afeae0d..8f9244fe5c86 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
@@ -1393,15 +1393,13 @@ static uint32_t read_pipe_fuses(struct dc_context *ctx)
 
 static enum dc_status dcn21_patch_unknown_plane_state(struct dc_plane_state 
*plane_state)
 {
-   enum dc_status result = DC_OK;
-
if (plane_state->ctx->dc->debug.disable_dcc == DCC_ENABLE) {
plane_state->dcc.enable = 1;
/* align to our worst case block width */
plane_state->dcc.meta_pitch = ((plane_state->src_rect.width + 
1023) / 1024) * 1024;
}
-   result = dcn20_patch_unknown_plane_state(plane_state);
-   return result;
+
+   return dcn20_patch_unknown_plane_state(plane_state);
 }
 
 static const struct resource_funcs dcn21_res_pool_funcs = {
-- 
2.39.0



Re: Bug report: kernel oops in vmw_fb_dirty_flush()

2023-01-30 Thread Zack Rusin
On Tue, 2023-01-31 at 00:36 +0800, Keyu Tao wrote:
> !! External Email
> 
> Hi vmwgfx maintainers,
> 
> An out-of-bound access in vmwgfx specific framebuffer implementation can
> be easily triggered by fbterm (a framebuffer terminal emulator) when it
> is going to scroll screen.
> 
> With some debugging, it seems that vmw_fb_dirty_flush() cannot handle
> the vinfo.yoffset correctly after calling `ioctl(fbdev_fd,
> FBIOPAN_DISPLAY, );`, and then subsequent access to the mapped
> memory area causes the oops.
> 
> As current mainline vmwgfx implementation (in Linux 6.2-rc) has removed
> this framebuffer implementation, this bug can be triggered only in Linux
> stable. I have tested it with vanilla 6.1.8 and 5.10.165 and they all oops.
> 
> This bug is reported in
> <
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugs.debian.org%2
> Fcgi-
> bin%2Fbugreport.cgi%3Fbug%3D1029602=05%7C01%7Czackr%40vmware.com%7C63862e731c
> 3b4a97796808db02e03145%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C1%7C63810693415592
> 2769%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiL
> CJXVCI6Mn0%3D%7C2000%7C%7C%7C=uVOtDBAyn%2BDx5w8r1twuKO4Xd0Lma6zCr2ie3lQ%2BRR
> E%3D=0> first, and
> the maintainer there suggests me to report this issue to upstream :)
> 
> Relevant information (for self-compiled Linux 6.1.8):
> 
> - /proc/version: Linux version 6.1.8 (tao@mira) (gcc (Debian 10.2.1-6)
> 10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.2) #7 SMP
> PREEMPT_DYNAMIC Mon Jan 30 21:09:02 CST 2023
> 
> - Linux distribution: Debian GNU/Linux 11 (bullseye)
> 
> - Architecture (uname -mi): x86_64 unknown
> 
> - Virtualization software: VMware Fusion 13 Player
> 
> - How to reproduce:
>    1. Install (or compile) fbterm
>    2. Run fbterm under a tty (by a user with read & write permission to
> /dev/fb0, usually users in video group), and try to make it scroll (for
> example by pressing Enter for a few seconds)
>    3. The graphics hang and it oops.
> 

Thanks a lot for the detailed report. Is there any chance that you could try 
any of
the 6.2 rc releases to see if you can reproduce? We removed all of the hand 
rolled
fb code and ported it to drm helpers in change:
df42523c12f8 ("drm/vmwgfx: Port the framebuffer code to drm fb helpers")
which for the first time got into the official kernel in v6.2-rc1 . So any 
kernel
after that shouldn't crash with fbterm, if anyone could verify that'd be much
appreciated.

z


Re: [PATCH 2/2] drm/tegra: add scanout support for implicit tiling parameters

2023-01-30 Thread kernel test robot
Hi Diogo,

Thank you for the patch! Yet something to improve:

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

url:
https://github.com/intel-lab-lkp/linux/commits/Diogo-Ivo/drm-tegra-add-sector-layout-to-SET-GET_TILING-IOCTLs/20230120-190334
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git for-next
patch link:
https://lore.kernel.org/r/20230120105858.214440-3-diogo.ivo%40tecnico.ulisboa.pt
patch subject: [PATCH 2/2] drm/tegra: add scanout support for implicit tiling 
parameters
config: arm64-randconfig-r016-20230130 
(https://download.01.org/0day-ci/archive/20230131/202301310334.4oiy5kgy-...@intel.com/config)
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 
4196ca3278f78c6e19246e54ab0ecb364e37d66a)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# install arm64 cross compiling tool for clang build
# apt-get install binutils-aarch64-linux-gnu
# 
https://github.com/intel-lab-lkp/linux/commit/fffef2135ccf679112cc60dee0532494c1389c78
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Diogo-Ivo/drm-tegra-add-sector-layout-to-SET-GET_TILING-IOCTLs/20230120-190334
git checkout fffef2135ccf679112cc60dee0532494c1389c78
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=arm64 olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/gpu/drm/tegra/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

>> drivers/gpu/drm/tegra/fb.c:149:4: error: expected expression
   unsigned long height = planes[0]->tiling.value;
   ^
>> drivers/gpu/drm/tegra/fb.c:151:8: error: use of undeclared identifier 
>> 'height'
   if (height > 5) {
   ^
>> drivers/gpu/drm/tegra/fb.c:151:8: error: use of undeclared identifier 
>> 'height'
>> drivers/gpu/drm/tegra/fb.c:151:8: error: use of undeclared identifier 
>> 'height'
   drivers/gpu/drm/tegra/fb.c:153:6: error: use of undeclared identifier 
'height'
   height);
   ^
   drivers/gpu/drm/tegra/fb.c:159:49: error: use of undeclared identifier 
'height'
   modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(height);
^
   6 errors generated.


vim +149 drivers/gpu/drm/tegra/fb.c

   110  
   111  static struct drm_framebuffer *tegra_fb_alloc(struct drm_device *drm,
   112const struct 
drm_mode_fb_cmd2 *mode_cmd,
   113struct tegra_bo **planes,
   114unsigned int num_planes)
   115  {
   116  struct drm_framebuffer *fb;
   117  unsigned int i;
   118  int err;
   119  struct drm_mode_fb_cmd2 mode_cmd_local;
   120  
   121  fb = kzalloc(sizeof(*fb), GFP_KERNEL);
   122  if (!fb)
   123  return ERR_PTR(-ENOMEM);
   124  
   125  /* Check for implicitly defined modifiers using
   126   * the state defined by tegra_gem_set_tiling().
   127   */
   128  if (!(mode_cmd->flags & DRM_MODE_FB_MODIFIERS)) {
   129  uint64_t modifier;
   130  
   131  mode_cmd_local = *mode_cmd;
   132  
   133  switch (planes[0]->tiling.mode) {
   134  case TEGRA_BO_TILING_MODE_PITCH:
   135  modifier = DRM_FORMAT_MOD_LINEAR;
   136  break;
   137  
   138  case TEGRA_BO_TILING_MODE_TILED:
   139  modifier = DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED;
   140  break;
   141  
   142  /* With all rigour this reconstruction of the modifier 
is
   143   * incomplete, as it skips some fields (like page kind).
   144   * However, along with the sector layout below it should
   145   * contain all the bits of information needed by the
   146   * sc

Re: [PATCH v2 6/6] drm/debugfs: Make the struct drm_debugfs_entry independent of DRM device

2023-01-30 Thread kernel test robot
Hi Maíra,

Thank you for the patch! Yet something to improve:

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

url:
https://github.com/intel-lab-lkp/linux/commits/Ma-ra-Canal/drm-debugfs-Introduce-wrapper-for-debugfs-list/20230130-203549
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:
https://lore.kernel.org/r/20230130123008.287141-7-mcanal%40igalia.com
patch subject: [PATCH v2 6/6] drm/debugfs: Make the struct drm_debugfs_entry 
independent of DRM device
config: x86_64-rhel-8.3-rust 
(https://download.01.org/0day-ci/archive/20230131/202301310356.xzcdafmm-...@intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project 
f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/intel-lab-lkp/linux/commit/2b098c9687b25368fa4a9e128963a13723aace67
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Ma-ra-Canal/drm-debugfs-Introduce-wrapper-for-debugfs-list/20230130-203549
git checkout 2b098c9687b25368fa4a9e128963a13723aace67
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=x86_64 olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/gpu/drm/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

>> drivers/gpu/drm/drm_gem_vram_helper.c:961:35: error: no member named 'dev' 
>> in 'struct drm_debugfs_entry'
   struct drm_vram_mm *vmm = entry->dev->vram_mm;
 ~  ^
   1 error generated.


vim +961 drivers/gpu/drm/drm_gem_vram_helper.c

6b5ce4a1fb84898 Thomas Zimmermann 2019-09-11  953  
6b5ce4a1fb84898 Thomas Zimmermann 2019-09-11  954  /*
6b5ce4a1fb84898 Thomas Zimmermann 2019-09-11  955   * struct drm_vram_mm
6b5ce4a1fb84898 Thomas Zimmermann 2019-09-11  956   */
6b5ce4a1fb84898 Thomas Zimmermann 2019-09-11  957  
6454c853ce9fa83 Maíra Canal   2023-01-30  958  static int 
drm_vram_mm_debugfs(struct seq_file *m, struct drm_device *dev, void *data)
6b5ce4a1fb84898 Thomas Zimmermann 2019-09-11  959  {
6fd80729f14e3f7 Maíra Canal   2022-12-19  960   struct 
drm_debugfs_entry *entry = m->private;
6fd80729f14e3f7 Maíra Canal   2022-12-19 @961   struct drm_vram_mm *vmm 
= entry->dev->vram_mm;
9de59bc201496f2 Dave Airlie   2020-08-04  962   struct 
ttm_resource_manager *man = ttm_manager_type(>bdev, TTM_PL_VRAM);
6b5ce4a1fb84898 Thomas Zimmermann 2019-09-11  963   struct drm_printer p = 
drm_seq_file_printer(m);
6b5ce4a1fb84898 Thomas Zimmermann 2019-09-11  964  
9de59bc201496f2 Dave Airlie   2020-08-04  965   
ttm_resource_manager_debug(man, );
6b5ce4a1fb84898 Thomas Zimmermann 2019-09-11  966   return 0;
6b5ce4a1fb84898 Thomas Zimmermann 2019-09-11  967  }
6b5ce4a1fb84898 Thomas Zimmermann 2019-09-11  968  

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


Re: [PATCH 0/3] Reserve dspps based on user request

2023-01-30 Thread Dmitry Baryshkov

On 30/01/2023 17:21, Kalyan Thota wrote:

This series will enable color features on sc7280 target which has primary panel 
as eDP

The series removes dspp allocation based on encoder type and allows the dspp 
reservation
based on user request via ctm.

The series will release/reserve the dpu resources when ever there is a topology 
change
to suit the new requirements.


Nit: the subject of the cover letter should include the version, if you 
are including one into the individual patches Subject.




Kalyan Thota (3):
   drm/msm/disp/dpu1: clear dspp reservations in rm release
   drm/msm/disp/dpu1: add dspps into reservation if there is a ctm
 request
   drm/msm/disp/dpu1: reserve the resources on topology change

  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h|  1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 54 +++--
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  4 ++-
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  2 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  |  6 ++--
  5 files changed, 50 insertions(+), 17 deletions(-)



--
With best wishes
Dmitry



Re: [v1 3/3] drm/msm/disp/dpu1: reserve the resources on topology change

2023-01-30 Thread Dmitry Baryshkov

On 30/01/2023 17:21, Kalyan Thota wrote:

Some features like ctm can be enabled dynamically. Release and reserve
the dpu resources whenever a topology change occurs such that
required hw blocks are allocated appropriately.

Changes in v1:
- Avoid mode_set call directly instead change the mode_changed (Dmitry)


Thanks, I like the overall idea. Minor nits below.

Also, could you please fix your scripts to include the PATCH keyword 
into the subject? If you do `git format-patches -# -v#`, where # is the 
number of commits to include and the version of the patchset, it will do 
the trick on its own.




Signed-off-by: Kalyan Thota 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h|  2 ++
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 42 ++---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  4 ++-
  3 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 539b68b..58e8c72 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -204,6 +204,7 @@ struct dpu_crtc {
   * @hw_ctls   : List of active ctl paths
   * @crc_source: CRC source
   * @crc_frame_skip_count: Number of frames skipped before getting CRC
+ * @ctm_enabled   : Cached ctm reservation state


Nit: we do not reserve CTMs. We reserve DSPPs.
So, ctm_enabled is 'Cached color management enablement state'.


   */
  struct dpu_crtc_state {
struct drm_crtc_state base;
@@ -225,6 +226,7 @@ struct dpu_crtc_state {
  
  	enum dpu_crtc_crc_source crc_source;

int crc_frame_skip_count;
+   bool ctm_enabled;
  };
  
  #define to_dpu_crtc_state(x) \

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 3bd46b4..0ddf2c9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -217,6 +217,22 @@ static u32 dither_matrix[DITHER_MATRIX_SZ] = {
15, 7, 13, 5, 3, 11, 1, 9, 12, 4, 14, 6, 0, 8, 2, 10
  };
  
+static bool _dpu_enc_is_dspps_changed(struct drm_crtc_state *crtc_state,

+   struct msm_display_topology topology)
+{
+   struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
+
+   if (drm_atomic_crtc_needs_modeset(crtc_state))
+   return true;
+
+   if ((cstate->ctm_enabled && !topology.num_dspp) ||
+   (!cstate->ctm_enabled && topology.num_dspp)) {
+   crtc_state->mode_changed = true;
+   return true;
+   }
+
+   return false;
+}
  
  bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc)

  {
@@ -638,25 +654,21 @@ static int dpu_encoder_virt_atomic_check(
if (ret) {
DPU_ERROR_ENC(dpu_enc,
"mode unsupported, phys idx %d\n", i);
-   break;
+   return ret;


This deserves a separate commit with the proper Fixes: tag.


}
}
  
  	topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state);
  
+	_dpu_enc_is_dspps_changed(crtc_state, topology);

+
/* Reserve dynamic resources now. */
-   if (!ret) {
-   /*
-* Release and Allocate resources on every modeset
-* Dont allocate when active is false.
-*/
-   if (drm_atomic_crtc_needs_modeset(crtc_state)) {
-   dpu_rm_release(global_state, drm_enc);
+   if (drm_atomic_crtc_needs_modeset(crtc_state)) {
+   dpu_rm_release(global_state, drm_enc);
  
-			if (!crtc_state->active_changed || crtc_state->active)

-   ret = dpu_rm_reserve(_kms->rm, global_state,
-   drm_enc, crtc_state, topology);
-   }
+   if (crtc_state->enable)
+   ret = dpu_rm_reserve(_kms->rm, global_state,
+   drm_enc, crtc_state, topology);
}
  
  	trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);

@@ -1027,7 +1039,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
-   int num_lm, num_ctl, num_pp, num_dsc;
+   int num_lm, num_ctl, num_pp, num_dsc, num_dspp;
unsigned int dsc_mask = 0;
int i;
  
@@ -1058,7 +1070,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,

drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
num_lm = dpu_rm_get_assigned_resources(_kms->rm, global_state,
drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
-   dpu_rm_get_assigned_resources(_kms->rm, global_state,
+  

Re: [PATCH v4 2/2] dt-bindings: display: simple-framebuffer: Document the panel node

2023-01-30 Thread Rob Herring


On Thu, 26 Jan 2023 18:24:35 +, Rayyan Ansari wrote:
> Document the new panel node and what it is used for.
> 
> Signed-off-by: Rayyan Ansari 
> ---
>  .../devicetree/bindings/display/simple-framebuffer.yaml  | 9 +
>  1 file changed, 9 insertions(+)
> 

Reviewed-by: Rob Herring 


Re: [v1 2/3] drm/msm/disp/dpu1: add dspps into reservation if there is a ctm request

2023-01-30 Thread Dmitry Baryshkov

On 30/01/2023 17:21, Kalyan Thota wrote:

Add dspp blocks into the topology for reservation, if there is a ctm
request for that composition.

Changes in v1:
- Minor nits (Dmitry)

Signed-off-by: Kalyan Thota 
Reviewed-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 13 ++---
  1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 9c6817b..3bd46b4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -545,7 +545,8 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
  static struct msm_display_topology dpu_encoder_get_topology(
struct dpu_encoder_virt *dpu_enc,
struct dpu_kms *dpu_kms,
-   struct drm_display_mode *mode)
+   struct drm_display_mode *mode,
+   struct drm_crtc_state *crtc_state)
  {
struct msm_display_topology topology = {0};
int i, intf_count = 0;
@@ -573,11 +574,9 @@ static struct msm_display_topology 
dpu_encoder_get_topology(
else
topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
  
-	if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) {

-   if (dpu_kms->catalog->dspp &&
-   (dpu_kms->catalog->dspp_count >= topology.num_lm))
-   topology.num_dspp = topology.num_lm;
-   }
+   if (dpu_kms->catalog->dspp &&
+   crtc_state->ctm && (dpu_kms->catalog->dspp_count >= 
topology.num_lm))


This condition doesn't look correct anymore for the following reasons:
- if there are no DSPPs we will completely ignore the ctm property
- if there are not enough DSPPs, the CTM property will be ignore

I think, this should be just:

if (crtc_state->ctm)
topology.num_dspp = topology.num_lm;





+   topology.num_dspp = topology.num_lm;
  
  	topology.num_enc = 0;

topology.num_intf = intf_count;
@@ -643,7 +642,7 @@ static int dpu_encoder_virt_atomic_check(
}
}
  
-	topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode);

+   topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, 
crtc_state);
  
  	/* Reserve dynamic resources now. */

if (!ret) {


--
With best wishes
Dmitry



Bug report: kernel oops in vmw_fb_dirty_flush()

2023-01-30 Thread Keyu Tao

Hi vmwgfx maintainers,

An out-of-bound access in vmwgfx specific framebuffer implementation can 
be easily triggered by fbterm (a framebuffer terminal emulator) when it 
is going to scroll screen.


With some debugging, it seems that vmw_fb_dirty_flush() cannot handle 
the vinfo.yoffset correctly after calling `ioctl(fbdev_fd, 
FBIOPAN_DISPLAY, );`, and then subsequent access to the mapped 
memory area causes the oops.


As current mainline vmwgfx implementation (in Linux 6.2-rc) has removed 
this framebuffer implementation, this bug can be triggered only in Linux 
stable. I have tested it with vanilla 6.1.8 and 5.10.165 and they all oops.


This bug is reported in 
 first, and 
the maintainer there suggests me to report this issue to upstream :)


Relevant information (for self-compiled Linux 6.1.8):

- /proc/version: Linux version 6.1.8 (tao@mira) (gcc (Debian 10.2.1-6) 
10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.2) #7 SMP 
PREEMPT_DYNAMIC Mon Jan 30 21:09:02 CST 2023


- Linux distribution: Debian GNU/Linux 11 (bullseye)

- Architecture (uname -mi): x86_64 unknown

- Virtualization software: VMware Fusion 13 Player

- How to reproduce:
  1. Install (or compile) fbterm
  2. Run fbterm under a tty (by a user with read & write permission to 
/dev/fb0, usually users in video group), and try to make it scroll (for 
example by pressing Enter for a few seconds)

  3. The graphics hang and it oops.

- decoded oops message:

[   31.519514] BUG: unable to handle page fault for address: 
a7c5019d6000

[   31.519843] #PF: supervisor write access in kernel mode
[   31.520149] #PF: error_code(0x0002) - not-present page
[   31.520453] PGD 167 P4D 167 PUD 11bc067 PMD 31f0d067 PTE 0
[   31.520784] Oops: 0002 [#1] PREEMPT SMP PTI
[   31.521022] CPU: 0 PID: 7 Comm: kworker/0:0 Kdump: loaded Not tainted 
6.1.8 #7
[   31.521266] Hardware name: VMware, Inc. VMware Virtual Platform/440BX 
Desktop Reference Platform, BIOS 6.00 11/12/2020

[   31.521796] Workqueue: events vmw_fb_dirty_flush [vmwgfx]
[   31.522080] RIP: 0010:memcpy_orig 
(/home/tao/Downloads/linux-6.1.8/arch/x86/lib/memcpy_64.S:85)
[ 31.522396] Code: 00 48 89 f8 48 83 fa 20 72 7e 40 38 fe 7c 35 48 83 ea 
20 48 83 ea 20 4c 8b 06 4c 8b 4e 08 4c 8b 56 10 4c 8b 5e 18 48 8d 76 20 
<4c> 89 07 4c 89 4f 08 4c 89 57 10 4c 89 5f 18 48 8d 7f 20 73 d4 83

All code

   0:   00 48 89add%cl,-0x77(%rax)
   3:   f8  clc
   4:   48 83 fa 20 cmp$0x20,%rdx
   8:   72 7e   jb 0x88
   a:   40 38 fecmp%dil,%sil
   d:   7c 35   jl 0x44
   f:   48 83 ea 20 sub$0x20,%rdx
  13:   48 83 ea 20 sub$0x20,%rdx
  17:   4c 8b 06mov(%rsi),%r8
  1a:   4c 8b 4e 08 mov0x8(%rsi),%r9
  1e:   4c 8b 56 10 mov0x10(%rsi),%r10
  22:   4c 8b 5e 18 mov0x18(%rsi),%r11
  26:   48 8d 76 20 lea0x20(%rsi),%rsi
  2a:*  4c 89 07mov%r8,(%rdi)   <-- trapping 
instruction
  2d:   4c 89 4f 08 mov%r9,0x8(%rdi)
  31:   4c 89 57 10 mov%r10,0x10(%rdi)
  35:   4c 89 5f 18 mov%r11,0x18(%rdi)
  39:   48 8d 7f 20 lea0x20(%rdi),%rdi
  3d:   73 d4   jae0x13
  3f:   83  .byte 0x83

Code starting with the faulting instruction
===
   0:   4c 89 07mov%r8,(%rdi)
   3:   4c 89 4f 08 mov%r9,0x8(%rdi)
   7:   4c 89 57 10 mov%r10,0x10(%rdi)
   b:   4c 89 5f 18 mov%r11,0x18(%rdi)
   f:   48 8d 7f 20 lea0x20(%rdi),%rdi
  13:   73 d4   jae0xffe9
  15:   83  .byte 0x83
[   31.523208] RSP: 0018:a7c50005be10 EFLAGS: 00010202
[   31.523555] RAX: a7c5019d5c00 RBX: 0c80 RCX: 
0c80
[   31.523841] RDX: 0840 RSI: a7c500e73a20 RDI: 
a7c5019d6000
[   31.524071] RBP:  R08:  R09: 

[   31.524299] R10:  R11:  R12: 
a7c500e73600
[   31.524525] R13: 97ba70af4cd8 R14: 97ba70b4 R15: 
97ba70af4800
[   31.524753] FS:  () GS:97ba9180() 
knlGS:

[   31.524981] CS:  0010 DS:  ES:  CR0: 80050033
[   31.525209] CR2: a7c5019d6000 CR3: 37a10002 CR4: 
003706f0

[   31.525440] Call Trace:
[   31.525670]  
[   31.525900] vmw_fb_dirty_flush 
(/home/tao/Downloads/linux-6.1.8/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c:244) 
vmwgfx
[   31.526162] process_one_work 
(/home/tao/Downloads/linux-6.1.8/kernel/workqueue.c:2289)
[   31.526399] worker_thread 
(/home/tao/Downloads/linux-6.1.8/./include/linux/list.h:292 

Re: [PATCH v2 2/2] drm/msm/dp: Return IRQ_NONE for unhandled interrupts

2023-01-30 Thread Kuogee Hsieh



On 1/26/2023 5:09 PM, Douglas Anderson wrote:

If our interrupt handler gets called and we don't really handle the
interrupt then we should return IRQ_NONE. The current interrupt
handler didn't do this, so let's fix it.

NOTE: for some of the cases it's clear that we should return IRQ_NONE
and some cases it's clear that we should return IRQ_HANDLED. However,
there are a few that fall somewhere in between. Specifically, the
documentation for when to return IRQ_NONE vs. IRQ_HANDLED is probably
best spelled out in the commit message of commit d9e4ad5badf4
("Document that IRQ_NONE should be returned when IRQ not actually
handled"). That commit makes it clear that we should return
IRQ_HANDLED if we've done something to make the interrupt stop
happening.

The case where it's unclear is, for instance, in dp_aux_isr() after
we've read the interrupt using dp_catalog_aux_get_irq() and confirmed
that "isr" is non-zero. The function dp_catalog_aux_get_irq() not only
reads the interrupts but it also "ack"s all the interrupts that are
returned. For an "unknown" interrupt this has a very good chance of
actually stopping the interrupt from happening. That would mean we've
identified that it's our device and done something to stop them from
happening and should return IRQ_HANDLED. Specifically, it should be
noted that most interrupts that need "ack"ing are ones that are
one-time events and doing an "ack" is enough to clear them. However,
since these interrupts are unknown then, by definition, it's unknown
if "ack"ing them is truly enough to clear them. It's possible that we
also need to remove the original source of the interrupt. In this
case, IRQ_NONE would be a better choice.

Given that returning an occasional IRQ_NONE isn't the absolute end of
the world, however, let's choose that course of action. The IRQ
framework will forgive a few IRQ_NONE returns now and again (and it
won't even log them, which is why we have to log them ourselves). This
means that if we _do_ end hitting an interrupt where "ack"ing isn't
enough the kernel will eventually detect the problem and shut our
device down.

Signed-off-by: Douglas Anderson 

Tested-by: Kuogee Hsieh 
Reviewed-by: Kuogee Hsieh 


---

(no changes since v1)

  drivers/gpu/drm/msm/dp/dp_aux.c | 12 +++-
  drivers/gpu/drm/msm/dp/dp_aux.h |  2 +-
  drivers/gpu/drm/msm/dp/dp_ctrl.c| 10 --
  drivers/gpu/drm/msm/dp/dp_ctrl.h|  2 +-
  drivers/gpu/drm/msm/dp/dp_display.c |  8 +---
  5 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
index 84f9e3e5f964..8e3b677f35e6 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.c
+++ b/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -368,14 +368,14 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux,
return ret;
  }
  
-void dp_aux_isr(struct drm_dp_aux *dp_aux)

+irqreturn_t dp_aux_isr(struct drm_dp_aux *dp_aux)
  {
u32 isr;
struct dp_aux_private *aux;
  
  	if (!dp_aux) {

DRM_ERROR("invalid input\n");
-   return;
+   return IRQ_NONE;
}
  
  	aux = container_of(dp_aux, struct dp_aux_private, dp_aux);

@@ -384,11 +384,11 @@ void dp_aux_isr(struct drm_dp_aux *dp_aux)
  
  	/* no interrupts pending, return immediately */

if (!isr)
-   return;
+   return IRQ_NONE;
  
  	if (!aux->cmd_busy) {

DRM_ERROR("Unexpected DP AUX IRQ %#010x when not busy\n", isr);
-   return;
+   return IRQ_NONE;
}
  
  	/*

@@ -420,10 +420,12 @@ void dp_aux_isr(struct drm_dp_aux *dp_aux)
aux->aux_error_num = DP_AUX_ERR_NONE;
} else {
DRM_WARN("Unexpected interrupt: %#010x\n", isr);
-   return;
+   return IRQ_NONE;
}
  
  	complete(>comp);

+
+   return IRQ_HANDLED;
  }
  
  void dp_aux_reconfig(struct drm_dp_aux *dp_aux)

diff --git a/drivers/gpu/drm/msm/dp/dp_aux.h b/drivers/gpu/drm/msm/dp/dp_aux.h
index e930974bcb5b..511305da4f66 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.h
+++ b/drivers/gpu/drm/msm/dp/dp_aux.h
@@ -11,7 +11,7 @@
  
  int dp_aux_register(struct drm_dp_aux *dp_aux);

  void dp_aux_unregister(struct drm_dp_aux *dp_aux);
-void dp_aux_isr(struct drm_dp_aux *dp_aux);
+irqreturn_t dp_aux_isr(struct drm_dp_aux *dp_aux);
  void dp_aux_init(struct drm_dp_aux *dp_aux);
  void dp_aux_deinit(struct drm_dp_aux *dp_aux);
  void dp_aux_reconfig(struct drm_dp_aux *dp_aux);
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index dd26ca651a05..1a5377ef1967 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -1979,27 +1979,33 @@ int dp_ctrl_off(struct dp_ctrl *dp_ctrl)
return ret;
  }
  
-void dp_ctrl_isr(struct dp_ctrl *dp_ctrl)

+irqreturn_t dp_ctrl_isr(struct dp_ctrl *dp_ctrl)
  {
struct dp_ctrl_private *ctrl;
u32 isr;
+   irqreturn_t ret = 

Re: [Freedreno] [PATCH v2 1/2] drm/msm/dp: Clean up handling of DP AUX interrupts

2023-01-30 Thread Kuogee Hsieh



On 1/26/2023 5:09 PM, Douglas Anderson wrote:

The DP AUX interrupt handling was a bit of a mess.
* There were two functions (one for "native" transfers and one for
   "i2c" transfers) that were quite similar. It was hard to say how
   many of the differences between the two functions were on purpose
   and how many of them were just an accident of how they were coded.
* Each function sometimes used "else if" to test for error bits and
   sometimes didn't and again it was hard to say if this was on purpose
   or just an accident.
* The two functions wouldn't notice whether "unknown" bits were
   set. For instance, there seems to be a bit "DP_INTR_PLL_UNLOCKED"
   and if it was set there would be no indication.
* The two functions wouldn't notice if more than one error was set.

Let's fix this by being more consistent / explicit about what we're
doing.

By design this could cause different handling for AUX transfers,
though I'm not actually aware of any bug fixed as a result of
this patch (this patch was created because we simply noticed how odd
the old code was by code inspection). Specific notes here:
1. In the old native transfer case if we got "done + wrong address"
we'd ignore the "wrong address" (because of the "else if"). Now we
won't.
2. In the old native transfer case if we got "done + timeout" we'd
ignore the "timeout" (because of the "else if"). Now we won't.
3. In the old native transfer case we'd see "nack_defer" and translate
it to the error number for "nack". This differed from the i2c
transfer case where "nack_defer" was given the error number for
"nack_defer". This 100% can't matter because the only user of this
error number treats "nack defer" the same as "nack", so it's clear
that the difference between the "native" and "i2c" was pointless
here.
4. In the old i2c transfer case if we got "done" plus any error
besides "nack" or "defer" then we'd ignore the error. Now we don't.
5. If there is more than one error signaled by the hardware it's
possible that we'll report a different one than we used to. I don't
know if this matters. If someone is aware of a case this matters we
should document it and change the code to make it explicit.
6. One quirk we keep (I don't know if this is important) is that in
the i2c transfer case if we see "done + defer" we report that as a
"nack". That seemed too intentional in the old code to just drop.

After this change we will add extra logging, including:
* A warning if we see more than one error bit set.
* A warning if we see an unexpected interrupt.
* A warning if we get an AUX transfer interrupt when shouldn't.

It actually turns out that as a result of this change then at boot we
sometimes see an error:
   [drm:dp_aux_isr] *ERROR* Unexpected DP AUX IRQ 0x0100 when not busy
This normal, when suspend/unplug the pll will  loss locked and at that 
time aux is not busy.

That means that, during init, we are seeing DP_INTR_PLL_UNLOCKED. For
now I'm going to say that leaving this error reported in the logs is
OK-ish and hopefully it will encourage someone to track down what's
going on at init time.

One last note here is that this change renames one of the interrupt
bits. The bit named "i2c done" clearly was used for native transfers
being done too, so I renamed it to indicate this.

Signed-off-by: Douglas Anderson 

Tested-by: Kuogee Hsieh 
Reviewed-by: Kuogee Hsieh 


---
I don't have good test coverage for this change and it does have the
potential to change behavior. I confirmed that eDP and DP still
continue to work OK on one machine. Hopefully folks can test it more.

Changes in v2:
- Moved DP_INTR_AUX_XFER_DONE to the end of the if else chain.

  drivers/gpu/drm/msm/dp/dp_aux.c | 80 -
  drivers/gpu/drm/msm/dp/dp_catalog.c |  2 +-
  drivers/gpu/drm/msm/dp/dp_catalog.h |  2 +-
  3 files changed, 36 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
index cc3efed593aa..84f9e3e5f964 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.c
+++ b/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -162,47 +162,6 @@ static ssize_t dp_aux_cmd_fifo_rx(struct dp_aux_private 
*aux,
return i;
  }
  
-static void dp_aux_native_handler(struct dp_aux_private *aux, u32 isr)

-{
-   if (isr & DP_INTR_AUX_I2C_DONE)
-   aux->aux_error_num = DP_AUX_ERR_NONE;
-   else if (isr & DP_INTR_WRONG_ADDR)
-   aux->aux_error_num = DP_AUX_ERR_ADDR;
-   else if (isr & DP_INTR_TIMEOUT)
-   aux->aux_error_num = DP_AUX_ERR_TOUT;
-   if (isr & DP_INTR_NACK_DEFER)
-   aux->aux_error_num = DP_AUX_ERR_NACK;
-   if (isr & DP_INTR_AUX_ERROR) {
-   aux->aux_error_num = DP_AUX_ERR_PHY;
-   dp_catalog_aux_clear_hw_interrupts(aux->catalog);
-   }
-}
-
-static void dp_aux_i2c_handler(struct dp_aux_private *aux, u32 isr)
-{
-   if (isr & DP_INTR_AUX_I2C_DONE) {
-  

Re: [PATCH v3 8/8] drm/i915/guc: Update GT/GuC messages in intel_uc.c

2023-01-30 Thread John Harrison

On 1/28/2023 11:59, Michal Wajdeczko wrote:

Use new macros to have common prefix that also include GT#.

v2: pass gt to print_fw_ver
v3: prefer guc_dbg in suspend/resume logs

Signed-off-by: Michal Wajdeczko 
Cc: John Harrison 

Reviewed-by: John Harrison 


---
  drivers/gpu/drm/i915/gt/uc/intel_uc.c | 80 +--
  1 file changed, 39 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 9a8a1abf71d7..de7f987cf611 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -6,11 +6,13 @@
  #include 
  
  #include "gt/intel_gt.h"

+#include "gt/intel_gt_print.h"
  #include "gt/intel_reset.h"
  #include "intel_gsc_fw.h"
  #include "intel_gsc_uc.h"
  #include "intel_guc.h"
  #include "intel_guc_ads.h"
+#include "intel_guc_print.h"
  #include "intel_guc_submission.h"
  #include "gt/intel_rps.h"
  #include "intel_uc.h"
@@ -67,14 +69,14 @@ static int __intel_uc_reset_hw(struct intel_uc *uc)
  
  	ret = intel_reset_guc(gt);

if (ret) {
-   DRM_ERROR("Failed to reset GuC, ret = %d\n", ret);
+   gt_err(gt, "Failed to reset GuC, ret = %d\n", ret);
return ret;
}
  
  	guc_status = intel_uncore_read(gt->uncore, GUC_STATUS);

-   WARN(!(guc_status & GS_MIA_IN_RESET),
-"GuC status: 0x%x, MIA core expected to be in reset\n",
-guc_status);
+   gt_WARN(gt, !(guc_status & GS_MIA_IN_RESET),
+   "GuC status: 0x%x, MIA core expected to be in reset\n",
+   guc_status);
  
  	return ret;

  }
@@ -252,15 +254,13 @@ static int guc_enable_communication(struct intel_guc *guc)
intel_guc_ct_event_handler(>ct);
spin_unlock_irq(gt->irq_lock);
  
-	drm_dbg(>drm, "GuC communication enabled\n");

+   guc_dbg(guc, "communication enabled\n");
  
  	return 0;

  }
  
  static void guc_disable_communication(struct intel_guc *guc)

  {
-   struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
-
/*
 * Events generated during or after CT disable are logged by guc in
 * via mmio. Make sure the register is clear before disabling CT since
@@ -280,11 +280,12 @@ static void guc_disable_communication(struct intel_guc 
*guc)
 */
guc_get_mmio_msg(guc);
  
-	drm_dbg(>drm, "GuC communication disabled\n");

+   guc_dbg(guc, "communication disabled\n");
  }
  
  static void __uc_fetch_firmwares(struct intel_uc *uc)

  {
+   struct intel_gt *gt = uc_to_gt(uc);
int err;
  
  	GEM_BUG_ON(!intel_uc_wants_guc(uc));

@@ -293,15 +294,13 @@ static void __uc_fetch_firmwares(struct intel_uc *uc)
if (err) {
/* Make sure we transition out of transient "SELECTED" state */
if (intel_uc_wants_huc(uc)) {
-   drm_dbg(_to_gt(uc)->i915->drm,
-   "Failed to fetch GuC: %d disabling HuC\n", err);
+   gt_dbg(gt, "Failed to fetch GuC fw (%pe) disabling 
HuC\n", ERR_PTR(err));
intel_uc_fw_change_status(>huc.fw,
  INTEL_UC_FIRMWARE_ERROR);
}
  
  		if (intel_uc_wants_gsc_uc(uc)) {

-   drm_dbg(_to_gt(uc)->i915->drm,
-   "Failed to fetch GuC: %d disabling GSC\n", err);
+   gt_dbg(gt, "Failed to fetch GuC fw (%pe) disabling 
GSC\n", ERR_PTR(err));
intel_uc_fw_change_status(>gsc.fw,
  INTEL_UC_FIRMWARE_ERROR);
}
@@ -382,7 +381,7 @@ static int uc_init_wopcm(struct intel_uc *uc)
int err;
  
  	if (unlikely(!base || !size)) {

-   i915_probe_error(gt->i915, "Unsuccessful WOPCM partitioning\n");
+   gt_probe_error(gt, "Unsuccessful WOPCM partitioning\n");
return -E2BIG;
}
  
@@ -413,13 +412,13 @@ static int uc_init_wopcm(struct intel_uc *uc)

return 0;
  
  err_out:

-   i915_probe_error(gt->i915, "Failed to init uC WOPCM registers!\n");
-   i915_probe_error(gt->i915, "%s(%#x)=%#x\n", "DMA_GUC_WOPCM_OFFSET",
-i915_mmio_reg_offset(DMA_GUC_WOPCM_OFFSET),
-intel_uncore_read(uncore, DMA_GUC_WOPCM_OFFSET));
-   i915_probe_error(gt->i915, "%s(%#x)=%#x\n", "GUC_WOPCM_SIZE",
-i915_mmio_reg_offset(GUC_WOPCM_SIZE),
-intel_uncore_read(uncore, GUC_WOPCM_SIZE));
+   gt_probe_error(gt, "Failed to init uC WOPCM registers!\n");
+   gt_probe_error(gt, "%s(%#x)=%#x\n", "DMA_GUC_WOPCM_OFFSET",
+  i915_mmio_reg_offset(DMA_GUC_WOPCM_OFFSET),
+  intel_uncore_read(uncore, DMA_GUC_WOPCM_OFFSET));
+   gt_probe_error(gt, "%s(%#x)=%#x\n", "GUC_WOPCM_SIZE",
+  i915_mmio_reg_offset(GUC_WOPCM_SIZE),
+ 

Re: [PATCH v3 6/8] drm/i915/guc: Update GuC messages in intel_guc_log.c

2023-01-30 Thread John Harrison

On 1/28/2023 11:59, Michal Wajdeczko wrote:

Use new macros to have common prefix that also include GT#.

v2: drop redundant GuC strings, minor improvements
v3: more message improvements

Signed-off-by: Michal Wajdeczko 
Cc: John Harrison 

Reviewed-by: John Harrison 


---
  drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 38 +++---
  1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
index 68331c538b0a..c3792ddeec80 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
@@ -12,6 +12,7 @@
  #include "i915_memcpy.h"
  #include "intel_guc_capture.h"
  #include "intel_guc_log.h"
+#include "intel_guc_print.h"
  
  #if defined(CONFIG_DRM_I915_DEBUG_GUC)

  #define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_2M
@@ -39,7 +40,6 @@ struct guc_log_section {
  static void _guc_log_init_sizes(struct intel_guc_log *log)
  {
struct intel_guc *guc = log_to_guc(log);
-   struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
static const struct guc_log_section sections[GUC_LOG_SECTIONS_LIMIT] = {
{
GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT,
@@ -82,12 +82,12 @@ static void _guc_log_init_sizes(struct intel_guc_log *log)
}
  
  		if (!IS_ALIGNED(log->sizes[i].bytes, log->sizes[i].units))

-   drm_err(>drm, "Mis-aligned GuC log %s size: 0x%X vs 
0x%X!",
+   guc_err(guc, "Mis-aligned log %s size: 0x%X vs 0x%X!\n",
sections[i].name, log->sizes[i].bytes, 
log->sizes[i].units);
log->sizes[i].count = log->sizes[i].bytes / log->sizes[i].units;
  
  		if (!log->sizes[i].count) {

-   drm_err(>drm, "Zero GuC log %s size!", 
sections[i].name);
+   guc_err(guc, "Zero log %s size!\n", sections[i].name);
} else {
/* Size is +1 unit */
log->sizes[i].count--;
@@ -95,14 +95,14 @@ static void _guc_log_init_sizes(struct intel_guc_log *log)
  
  		/* Clip to field size */

if (log->sizes[i].count > sections[i].max) {
-   drm_err(>drm, "GuC log %s size too large: %d vs 
%d!",
+   guc_err(guc, "log %s size too large: %d vs %d!\n",
sections[i].name, log->sizes[i].count + 1, 
sections[i].max + 1);
log->sizes[i].count = sections[i].max;
}
}
  
  	if (log->sizes[GUC_LOG_SECTIONS_CRASH].units != log->sizes[GUC_LOG_SECTIONS_DEBUG].units) {

-   drm_err(>drm, "Unit mis-match for GuC log crash and debug 
sections: %d vs %d!",
+   guc_err(guc, "Unit mismatch for crash and debug sections: %d vs 
%d!\n",
log->sizes[GUC_LOG_SECTIONS_CRASH].units,
log->sizes[GUC_LOG_SECTIONS_DEBUG].units);
log->sizes[GUC_LOG_SECTIONS_CRASH].units = 
log->sizes[GUC_LOG_SECTIONS_DEBUG].units;
@@ -374,6 +374,7 @@ size_t intel_guc_get_log_buffer_offset(struct intel_guc_log 
*log,
  
  static void _guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log)

  {
+   struct intel_guc *guc = log_to_guc(log);
unsigned int buffer_size, read_offset, write_offset, bytes_to_copy, 
full_cnt;
struct guc_log_buffer_state *log_buf_state, *log_buf_snapshot_state;
struct guc_log_buffer_state log_buf_state_local;
@@ -383,7 +384,7 @@ static void _guc_log_copy_debuglogs_for_relay(struct 
intel_guc_log *log)
  
  	mutex_lock(>relay.lock);
  
-	if (WARN_ON(!intel_guc_log_relay_created(log)))

+   if (guc_WARN_ON(guc, !intel_guc_log_relay_created(log)))
goto out_unlock;
  
  	/* Get the pointer to shared GuC log buffer */

@@ -398,7 +399,7 @@ static void _guc_log_copy_debuglogs_for_relay(struct 
intel_guc_log *log)
 * Used rate limited to avoid deluge of messages, logs might be
 * getting consumed by User at a slow rate.
 */
-   DRM_ERROR_RATELIMITED("no sub-buffer to copy general logs\n");
+   guc_err_ratelimited(guc, "no sub-buffer to copy general 
logs\n");
log->relay.full_count++;
  
  		goto out_unlock;

@@ -451,7 +452,7 @@ static void _guc_log_copy_debuglogs_for_relay(struct 
intel_guc_log *log)
write_offset = buffer_size;
} else if (unlikely((read_offset > buffer_size) ||
(write_offset > buffer_size))) {
-   DRM_ERROR("invalid log buffer state\n");
+   guc_err(guc, "invalid log buffer state\n");
/* copy whole buffer as offsets are unreliable */
read_offset = 0;
write_offset = buffer_size;
@@ -547,7 +548,7 @@ static int 

Re: [Intel-gfx] [PATCH] drm/i915/pcode: Wait 10 seconds for pcode to settle

2023-01-30 Thread Rodrigo Vivi
On Mon, Jan 30, 2023 at 11:37:29AM -0500, Rodrigo Vivi wrote:
> On Mon, Jan 30, 2023 at 05:12:48PM +0100, Andi Shyti wrote:
> > Hi Rodrigo,
> > 
> > > > > In the call flow invoked by intel_pcode_init(), I've added brief 
> > > > > comments
> > > > > where further clarification is needed in this scenario, and a 
> > > > > description of
> > > > > the suspicious scenario at the bottom.
> > > > > 
> > > > > -
> > > > > intel_pcode_init()
> > > > >  |
> > > > >  +-> skl_pcode_request(uncore, DG1_PCODE_STATUS,
> > > > >DG1_UNCORE_GET_INIT_STATUS,
> > > > >DG1_UNCORE_INIT_STATUS_COMPLETE,
> > > > >DG1_UNCORE_INIT_STATUS_COMPLETE, 18);
> > > > >|
> > > > >+-> skl_pcode_try_request()
> > > > >  |
> > > > >  +->  *status = __snb_pcode_rw(uncore, mbox, , 
> > > > > NULL,
> > > > >500, 0, true);
> > > > > 
> > > > > -
> > > > > static int __snb_pcode_rw(struct intel_uncore *uncore, u32 mbox,
> > > > > u32 *val, u32 *val1,
> > > > > int fast_timeout_us, int slow_timeout_ms,
> > > > > bool is_read)
> > > > > {
> > > > > ...
> > > > > /* Before writing a value to the GEN6_PCODE_DATA register,
> > > > >check if the bit in the GEN6_PCODE_MAILBOX register 
> > > > > indicates
> > > > >BUSY. */
> > > > >   if (intel_uncore_read_fw(uncore, GEN6_PCODE_MAILBOX) & 
> > > > > GEN6_PCODE_READY)
> > > > >   return -EAGAIN;
> > > > 
> > > > what if we fail here because the punit is still initializing and
> > > > will be ready, say, in 10 seconds?
> > > > 
> > > > GG, without going any further, we fail here! The -EAGAIN we
> > > > receive from the test comes from this point. We don't fail with
> > > > -ETIMEDOUT, but with -EAGAIN and the reason is because the punit
> > > > is not ready to perform the very fist communication and we fail
> > > > the probing.
> > > > 
> > > > It doesn't mean, though, that there is anything wrong, we just
> > > > need to wait a bit before "taking drastic decisions"!
> > > > 
> > > > This patch is suggesting to wait up to 10s for the punit to be
> > > > ready and eventually try to probe again... and, indeed, it works!
> > > 
> > > As GG, what I still don't understand is how this extra 10 seconds
> > > wait helps... have you tried to simple add the 10 to the 180 and
> > > make the code 190 sec instead?
> > 
> > maybe I haven't been able to explain the issue properly.
> > 
> > I can even set that timer to 2hrs and a half and nothing changes
> > because we fail before.
> > 
> > Here it's not a matter of how much do I wait but when do I check
> > the pcode readiness (i.e. signalled by the GEN6_PCODE_READY bit
> > in the GEN6_PCODE_MAILBOX register).
> > 
> > During a normal run we are always sure that communicating with
> > the punit works, because we made it sure during the previous
> > transaction.
> > 
> > During probe there is no previous transaction and we start
> > communicating with the punit without making sure that it is
> > ready. And indeed some times it is not, so that we suppress the
> > probing on purpose instead of giving it another chance.
> > 
> > I admit that the commit message is not written properly and
> > rather misleading, but here it's not at all a matter of how much
> > do I wait.
> 
> The commit message was initially confused because it looks like
> we are just adding a wait, without doing anything
> 
> But looking to the code we can see that it will wait until
> pcode is ready with a timeout of 10 seconds.
> 
> But if pcode is ready in 10 seconds, why pcode is not ready
> in 190 seconds. We are doing absolutely nothing more that could
> make pcode ready in 10 seconds that won't be in 190.
> 
> This is what we are missing here... The code as is doesn't make
> a lot of sense to us and it looks like it is solving the issue
> by the 10 extra seconds and not by some special status checking.

Okay, after an offline talk I am convinced now that we need some
check like this in some place.

But the commit message needs be be fully re-written.

It needs to be clear that underneath, the pcode communication
functions will do a check for ready without any wait, what will
make desired timeout to never really wait for the pcode done
and prematurely return.

at __snb_pcode_rw():

 if (intel_uncore_read_fw(uncore, GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY)
return -EAGAIN;

So, for this reason we need to ensure that pcode is really ready
before we wait.

Other options are to handle the EAGAIN return and then wait.
Or even change the __snb_pcode_rw to ensure that it is ready...

Something like:

-   if (intel_uncore_read_fw(uncore, GEN6_PCODE_MAILBOX) & 

Re: [PATCH v2 3/4] dt-bindings: panel: Introduce dual-link LVDS panel

2023-01-30 Thread Rob Herring
On Tue, Jan 24, 2023 at 03:42:37PM +0530, Aradhya Bhatia wrote:
> Dual-link LVDS interfaces have 2 links, with even pixels traveling on
> one link, and odd pixels on the other. These panels are also generic in
> nature, with no documented constraints, much like their single-link
> counterparts, "panel-lvds".
> 
> Add a new compatible, "panel-dual-lvds", and a dt-binding document for
> these panels.
> 
> Signed-off-by: Aradhya Bhatia 
> ---
>  .../display/panel/panel-dual-lvds.yaml| 149 ++
>  MAINTAINERS   |   1 +
>  2 files changed, 150 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/display/panel/panel-dual-lvds.yaml
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/panel/panel-dual-lvds.yaml 
> b/Documentation/devicetree/bindings/display/panel/panel-dual-lvds.yaml
> new file mode 100644
> index ..e2ce1768e9a3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/panel/panel-dual-lvds.yaml
> @@ -0,0 +1,149 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/panel/panel-dual-lvds.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Generic Dual-Link LVDS Display Panel
> +
> +maintainers:
> +  - Aradhya Bhatia 
> +  - Thierry Reding 
> +
> +description: |
> +  A dual-LVDS interface is a dual-link connection with the even pixels
> +  traveling on one link, and the odd pixels traveling on the other.
> +
> +allOf:
> +  - $ref: panel-common.yaml#
> +  - $ref: /schemas/display/lvds.yaml#
> +
> +properties:
> +  compatible:
> +items:
> +  - enum:
> +  - lincolntech,lcd185-101ct
> +  - microtips,mf-101hiebcaf0
> +  - const: panel-dual-lvds

Why do we need a new compatible? You have ports and properties to see if 
the panel is dual link.

We already have dual link LVDS supported in advantech,idk-2121wr.yaml 
which says is compatible with 'panel-lvds', so that decision has already 
been made. The hint was you added the compatible match to the driver 
with 0 other changes needed.

That schema is missing type definitions and constraints for 
dual-lvds-odd-pixels/dual-lvds-even-pixels so there does need to be some 
changes to add those.

> +
> +  ports:
> +$ref: /schemas/graph.yaml#/properties/ports
> +
> +properties:
> +  port@0:
> +$ref: /schemas/graph.yaml#/$defs/port-base
> +unevaluatedProperties: false
> +description: The sink for first set of LVDS pixels.
> +
> +properties:
> +  dual-lvds-odd-pixels:
> +type: boolean
> +
> +  dual-lvds-even-pixels:
> +type: boolean
> +
> +oneOf:
> +  - required: [dual-lvds-odd-pixels]
> +  - required: [dual-lvds-even-pixels]
> +
> +  port@1:
> +$ref: /schemas/graph.yaml#/$defs/port-base
> +unevaluatedProperties: false
> +description: The sink for second set of LVDS pixels.
> +
> +properties:
> +  dual-lvds-even-pixels:
> +type: boolean
> +
> +  dual-lvds-odd-pixels:
> +type: boolean
> +
> +oneOf:
> +  - required: [dual-lvds-even-pixels]
> +  - required: [dual-lvds-odd-pixels]
> +
> +allOf:
> +  - if:
> +  properties:
> +port@0:
> +  required:
> +- dual-lvds-odd-pixels
> +then:
> +  properties:
> +port@1:
> +  properties:
> +dual-lvds-odd-pixels: false
> +
> +  - if:
> +  properties:
> +port@0:
> +  required:
> +- dual-lvds-even-pixels
> +then:
> +  properties:
> +port@1:
> +  properties:
> +dual-lvds-even-pixels: false
> +
> +required:
> +  - port@0
> +  - port@1
> +
> +  port: false
> +
> +unevaluatedProperties: false
> +
> +required:
> +  - compatible
> +  - width-mm
> +  - height-mm
> +  - data-mapping
> +  - panel-timing
> +  - ports
> +
> +examples:
> +  - |
> +panel {
> +  compatible = "microtips,mf-101hiebcaf0", "panel-dual-lvds";
> +
> +  width-mm = <217>;
> +  height-mm = <136>;
> +
> +  data-mapping = "vesa-24";
> +
> +  panel-timing {
> +clock-frequency = <150275000>;
> +hactive = <1920>;
> +vactive = <1200>;
> +hfront-porch = <32>;
> +hsync-len = <52>;
> +hback-porch = <24>;
> +vfront-porch = <24>;
> +vsync-len = <8>;
> +vback-porch = <3>;
> +de-active = <1>;
> +  };
> +
> +  ports {
> +#address-cells = <1>;
> +#size-cells = <0>;
> +
> +port@0 {
> +  reg = <0>;
> +  dual-lvds-odd-pixels;
> +  lcd_in0: endpoint {
> +remote-endpoint = <_out0>;
> +  };
> +};
> +
> +port@1 {
> +  reg = <1>;
> +  

Re: [Intel-gfx] [PATCH] drm/i915/pcode: Wait 10 seconds for pcode to settle

2023-01-30 Thread Rodrigo Vivi
On Mon, Jan 30, 2023 at 05:12:48PM +0100, Andi Shyti wrote:
> Hi Rodrigo,
> 
> > > > In the call flow invoked by intel_pcode_init(), I've added brief 
> > > > comments
> > > > where further clarification is needed in this scenario, and a 
> > > > description of
> > > > the suspicious scenario at the bottom.
> > > > 
> > > > -
> > > > intel_pcode_init()
> > > >  |
> > > >  +-> skl_pcode_request(uncore, DG1_PCODE_STATUS,
> > > >DG1_UNCORE_GET_INIT_STATUS,
> > > >DG1_UNCORE_INIT_STATUS_COMPLETE,
> > > >DG1_UNCORE_INIT_STATUS_COMPLETE, 18);
> > > >|
> > > >+-> skl_pcode_try_request()
> > > >  |
> > > >  +->  *status = __snb_pcode_rw(uncore, mbox, , NULL,
> > > >500, 0, true);
> > > > 
> > > > -
> > > > static int __snb_pcode_rw(struct intel_uncore *uncore, u32 mbox,
> > > >   u32 *val, u32 *val1,
> > > >   int fast_timeout_us, int slow_timeout_ms,
> > > >   bool is_read)
> > > > {
> > > > ...
> > > > /* Before writing a value to the GEN6_PCODE_DATA register,
> > > >check if the bit in the GEN6_PCODE_MAILBOX register indicates
> > > >BUSY. */
> > > > if (intel_uncore_read_fw(uncore, GEN6_PCODE_MAILBOX) & 
> > > > GEN6_PCODE_READY)
> > > > return -EAGAIN;
> > > 
> > > what if we fail here because the punit is still initializing and
> > > will be ready, say, in 10 seconds?
> > > 
> > > GG, without going any further, we fail here! The -EAGAIN we
> > > receive from the test comes from this point. We don't fail with
> > > -ETIMEDOUT, but with -EAGAIN and the reason is because the punit
> > > is not ready to perform the very fist communication and we fail
> > > the probing.
> > > 
> > > It doesn't mean, though, that there is anything wrong, we just
> > > need to wait a bit before "taking drastic decisions"!
> > > 
> > > This patch is suggesting to wait up to 10s for the punit to be
> > > ready and eventually try to probe again... and, indeed, it works!
> > 
> > As GG, what I still don't understand is how this extra 10 seconds
> > wait helps... have you tried to simple add the 10 to the 180 and
> > make the code 190 sec instead?
> 
> maybe I haven't been able to explain the issue properly.
> 
> I can even set that timer to 2hrs and a half and nothing changes
> because we fail before.
> 
> Here it's not a matter of how much do I wait but when do I check
> the pcode readiness (i.e. signalled by the GEN6_PCODE_READY bit
> in the GEN6_PCODE_MAILBOX register).
> 
> During a normal run we are always sure that communicating with
> the punit works, because we made it sure during the previous
> transaction.
> 
> During probe there is no previous transaction and we start
> communicating with the punit without making sure that it is
> ready. And indeed some times it is not, so that we suppress the
> probing on purpose instead of giving it another chance.
> 
> I admit that the commit message is not written properly and
> rather misleading, but here it's not at all a matter of how much
> do I wait.

The commit message was initially confused because it looks like
we are just adding a wait, without doing anything

But looking to the code we can see that it will wait until
pcode is ready with a timeout of 10 seconds.

But if pcode is ready in 10 seconds, why pcode is not ready
in 190 seconds. We are doing absolutely nothing more that could
make pcode ready in 10 seconds that won't be in 190.

This is what we are missing here... The code as is doesn't make
a lot of sense to us and it looks like it is solving the issue
by the 10 extra seconds and not by some special status checking.

> 
> Thanks, Rodrigo!
> Andi
> 
> > > 
> > > Andi
> > > 
> > > > 
> > > > /* write value to GEN6_PCODE_DATA register */
> > > > intel_uncore_write_fw(uncore, GEN6_PCODE_DATA, *val);
> > > > 
> > > > intel_uncore_write_fw(uncore, GEN6_PCODE_DATA1, val1 ? *val1 : 
> > > > 0);
> > > > 
> > > > /* In this scenario, the value
> > > >"DG1_PCODE_STATUS | GEN6_PCODE_READY"
> > > >is written to the GEN6_PCODE_MAILBOX register,
> > > >so that the Busy status of the GEN6_PCODE_MAILBOX register
> > > >can be checked later.
> > > >(When the value of the GEN6_PCODE_READY bit of the
> > > > GEN6_PCODE_MAILBOX register changes to 0, the operation can
> > > > be considered completed.) */
> > > > intel_uncore_write_fw(uncore,
> > > >   GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | 
> > > > mbox);
> > > > 
> > > > /* In this scenario, verify that the BUSY status bit in the
> > > >

Re: [PATCH 4/4] DRM: BRIDGE: TFP410: If connected, use I2C for polled HPD status.

2023-01-30 Thread Jon Cormier
On Sat, Jan 28, 2023 at 7:47 PM kernel test robot  wrote:
>
> Hi Jonathan,
>
> Thank you for the patch! Perhaps something to improve:
Good bot.
>
> [auto build test WARNING on 93f875a8526a291005e7f38478079526c843cbec]
>
> url:
> https://github.com/intel-lab-lkp/linux/commits/Jonathan-Cormier/dt-bindings-display-bridge-tfp410-Add-tfp410-i2c-example/20230128-183627
> base:   93f875a8526a291005e7f38478079526c843cbec
> patch link:
> https://lore.kernel.org/r/20230125-tfp410_i2c-v1-4-66a4d4e390b7%40criticallink.com
> patch subject: [PATCH 4/4] DRM: BRIDGE: TFP410: If connected, use I2C for 
> polled HPD status.
> config: i386-randconfig-a006 
> (https://download.01.org/0day-ci/archive/20230129/202301290803.ous19eab-...@intel.com/config)
> compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project 
> f28c006a5895fc0e329fe15fead81e37457cb1d1)
> reproduce (this is a W=1 build):
> wget 
> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
> ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # 
> https://github.com/intel-lab-lkp/linux/commit/c4659fa4c02b62087c095ca99978e5eac8b490de
> git remote add linux-review https://github.com/intel-lab-lkp/linux
> git fetch --no-tags linux-review 
> Jonathan-Cormier/dt-bindings-display-bridge-tfp410-Add-tfp410-i2c-example/20230128-183627
> git checkout c4659fa4c02b62087c095ca99978e5eac8b490de
> # save the config file
> mkdir build_dir && cp config build_dir/.config
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
> O=build_dir ARCH=i386 olddefconfig
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
> O=build_dir ARCH=i386 SHELL=/bin/bash drivers/gpu/drm/bridge/
>
> If you fix the issue, kindly add following tag where applicable
> | Reported-by: kernel test robot 
>
> All warnings (new ones prefixed by >>):
>
> >> drivers/gpu/drm/bridge/ti-tfp410.c:111:6: warning: unused variable 'val' 
> >> [-Wunused-variable]
>u32 val;
>^
>1 warning generated.
This has already been fixed in V2 of the patch series.
>
>
> vim +/val +111 drivers/gpu/drm/bridge/ti-tfp410.c
>
>106
>107  static enum drm_connector_status
>108  tfp410_connector_detect(struct drm_connector *connector, bool force)
>109  {
>110  struct tfp410 *dvi = drm_connector_to_tfp410(connector);
>  > 111  u32 val;
>112  unsigned int ret;
>113
>114  if (dvi->i2c) {
>115  ret = regmap_test_bits(dvi->regmap, 
> TFP410_REG_CTL_2_MODE, TFP410_BIT_HTPLG);
>116  if (ret < 0)
>117  dev_err(dvi->dev, "%s failed to read HTPLG 
> bit : %d\n", __func__, ret);
>118  else
>119  return ret ? connector_status_connected : 
> connector_status_disconnected;
>120  }
>121
>122  return drm_bridge_detect(dvi->next_bridge);
>123  }
>124
>
> --
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests


Re: [PATCH] drm/i915/pcode: Wait 10 seconds for pcode to settle

2023-01-30 Thread Andi Shyti
Hi Rodrigo,

> > > In the call flow invoked by intel_pcode_init(), I've added brief comments
> > > where further clarification is needed in this scenario, and a description 
> > > of
> > > the suspicious scenario at the bottom.
> > > 
> > > -
> > > intel_pcode_init()
> > >  |
> > >  +-> skl_pcode_request(uncore, DG1_PCODE_STATUS,
> > >DG1_UNCORE_GET_INIT_STATUS,
> > >DG1_UNCORE_INIT_STATUS_COMPLETE,
> > >DG1_UNCORE_INIT_STATUS_COMPLETE, 18);
> > >|
> > >+-> skl_pcode_try_request()
> > >  |
> > >  +->  *status = __snb_pcode_rw(uncore, mbox, , NULL,
> > >500, 0, true);
> > > 
> > > -
> > > static int __snb_pcode_rw(struct intel_uncore *uncore, u32 mbox,
> > > u32 *val, u32 *val1,
> > > int fast_timeout_us, int slow_timeout_ms,
> > > bool is_read)
> > > {
> > > ...
> > > /* Before writing a value to the GEN6_PCODE_DATA register,
> > >check if the bit in the GEN6_PCODE_MAILBOX register indicates
> > >BUSY. */
> > >   if (intel_uncore_read_fw(uncore, GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY)
> > >   return -EAGAIN;
> > 
> > what if we fail here because the punit is still initializing and
> > will be ready, say, in 10 seconds?
> > 
> > GG, without going any further, we fail here! The -EAGAIN we
> > receive from the test comes from this point. We don't fail with
> > -ETIMEDOUT, but with -EAGAIN and the reason is because the punit
> > is not ready to perform the very fist communication and we fail
> > the probing.
> > 
> > It doesn't mean, though, that there is anything wrong, we just
> > need to wait a bit before "taking drastic decisions"!
> > 
> > This patch is suggesting to wait up to 10s for the punit to be
> > ready and eventually try to probe again... and, indeed, it works!
> 
> As GG, what I still don't understand is how this extra 10 seconds
> wait helps... have you tried to simple add the 10 to the 180 and
> make the code 190 sec instead?

maybe I haven't been able to explain the issue properly.

I can even set that timer to 2hrs and a half and nothing changes
because we fail before.

Here it's not a matter of how much do I wait but when do I check
the pcode readiness (i.e. signalled by the GEN6_PCODE_READY bit
in the GEN6_PCODE_MAILBOX register).

During a normal run we are always sure that communicating with
the punit works, because we made it sure during the previous
transaction.

During probe there is no previous transaction and we start
communicating with the punit without making sure that it is
ready. And indeed some times it is not, so that we suppress the
probing on purpose instead of giving it another chance.

I admit that the commit message is not written properly and
rather misleading, but here it's not at all a matter of how much
do I wait.

Thanks, Rodrigo!
Andi

> > 
> > Andi
> > 
> > > 
> > > /* write value to GEN6_PCODE_DATA register */
> > >   intel_uncore_write_fw(uncore, GEN6_PCODE_DATA, *val);
> > > 
> > >   intel_uncore_write_fw(uncore, GEN6_PCODE_DATA1, val1 ? *val1 : 0);
> > > 
> > > /* In this scenario, the value
> > >"DG1_PCODE_STATUS | GEN6_PCODE_READY"
> > >is written to the GEN6_PCODE_MAILBOX register,
> > >so that the Busy status of the GEN6_PCODE_MAILBOX register
> > >can be checked later.
> > >(When the value of the GEN6_PCODE_READY bit of the
> > > GEN6_PCODE_MAILBOX register changes to 0, the operation can
> > > be considered completed.) */
> > >   intel_uncore_write_fw(uncore,
> > > GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
> > > 
> > > /* In this scenario, verify that the BUSY status bit in the
> > >GEN6_PCODE_MAILBOX register turns off for up to 500us. */
> > >   if (__intel_wait_for_register_fw(uncore,
> > >GEN6_PCODE_MAILBOX,
> > >GEN6_PCODE_READY, 0,
> > >fast_timeout_us,
> > >slow_timeout_ms,
> > >))
> > >   return -ETIMEDOUT;
> > > /* If there is a failure here, it may be considered that the
> > >"DG1_PCODE_STATUS | GEN6_PCODE_READY" operation was not
> > >completed within 500us */
> > > ...
> > > }
> > > 
> > > int skl_pcode_request(struct intel_uncore *uncore, u32 mbox, u32 request,
> > > u32 reply_mask, u32 reply, int timeout_base_ms)
> > > {
> > >   u32 status;
> > >   int ret;
> > > 
> > >   mutex_lock(>i915->sb_lock);
> > > 
> > > #define COND \
> > >   skl_pcode_try_request(uncore, 

Re: [REGRESSION] GM20B probe fails after commit 2541626cfb79

2023-01-30 Thread Nicolas Chauvet
Le dim. 29 janv. 2023 à 23:36, Ben Skeggs  a écrit :
>
> On Fri, 27 Jan 2023 at 20:42, Diogo Ivo  wrote:
> >
> > On Fri, Jan 27, 2023 at 04:00:59PM +1000, Ben Skeggs wrote:
> > > On Fri, 20 Jan 2023 at 21:37, Diogo Ivo  
> > > wrote:
> > > >
> > > > On Wed, Jan 18, 2023 at 11:28:49AM +1000, Ben Skeggs wrote:
> > > > > On Mon, 16 Jan 2023 at 22:27, Diogo Ivo 
> > > > >  wrote:
> > > > > > On Mon, Jan 16, 2023 at 07:45:05AM +1000, David Airlie wrote:
> > > > > > > As a quick check can you try changing
> > > > > > >
> > > > > > > drivers/gpu/drm/nouveau/nvkm/core/firmware.c:nvkm_firmware_mem_target
> > > > > > > from NVKM_MEM_TARGET_HOST to NVKM_MEM_TARGET_NCOH ?
> > > >
> > > > > In addition to Dave's change, can you try changing the
> > > > > nvkm_falcon_load_dmem() call in gm20b_pmu_init() to:
> > > > >
> > > > > nvkm_falcon_pio_wr(falcon, (u8 *), 0, 0, DMEM, addr_args,
> > > > > sizeof(args), 0, false);
> > > >
> > > > Chiming in just to say that with this change I see the same as Nicolas
> > > > except that the init message size is 255 instead of 0:
> > > >
> > > > [2.196934] nouveau 5700.gpu: pmu: unexpected init message size 
> > > > 255 vs 42
> > > I've attached an entirely untested patch (to go on top of the other
> > > hacks/fixes so far), that will hopefully get us a little further.
> >
> > Hello,
> >
> > Thank you for the patch! I can confirm that it fixes the problem
> > on the Pixel C, and everything works as before the regression.
> > With this, for the combination of patches
> >
> > Tested-by: Diogo Ivo 
> >
> > which I can resend after testing the final patch version.
> Thank you (both!) for testing!
>
> I've attached a "final" version of a patch that I'll send (assuming it
> still works ;)) after re-testing.  There's only a minor change to
> avoid breaking the non-Tegra path, so I expect it should be fine.

Fine with me.
Tested-By: Nicolas Chauvet 

Thanks.


Re: [PATCH] [v2] accel: fix CONFIG_DRM dependencies

2023-01-30 Thread Jeffrey Hugo

On 1/27/2023 3:14 PM, Arnd Bergmann wrote:

From: Arnd Bergmann 

At the moment, accel drivers can be built-in even with CONFIG_DRM=m,
but this causes a link failure:

x86_64-linux-ld: drivers/accel/ivpu/ivpu_drv.o: in function `ivpu_dev_init':
ivpu_drv.c:(.text+0x1535): undefined reference to `drmm_kmalloc'
x86_64-linux-ld: ivpu_drv.c:(.text+0x1562): undefined reference to 
`drmm_kmalloc'
x86_64-linux-ld: drivers/accel/ivpu/ivpu_drv.o: in function `ivpu_remove':
ivpu_drv.c:(.text+0x1faa): undefined reference to `drm_dev_unregister'
x86_64-linux-ld: drivers/accel/ivpu/ivpu_drv.o: in function `ivpu_probe':
ivpu_drv.c:(.text+0x1fef): undefined reference to `__devm_drm_dev_alloc'

The problem is that DRM_ACCEL is a 'bool' symbol symbol, so driver that
only depend on DRM_ACCEL but not also on DRM do not see the restriction
to =m configs.

To ensure that each accel driver has an implied dependency on CONFIG_DRM,
enclose the entire Kconfig file in an if/endif check.

Fixes: 8bf4889762a8 ("drivers/accel: define kconfig and register a new major")
Signed-off-by: Arnd Bergmann 


Reviewed-by: Jeffrey Hugo 


[v1 1/3] drm/msm/disp/dpu1: clear dspp reservations in rm release

2023-01-30 Thread Kalyan Thota
Clear dspp reservations from the global state during
rm release

Signed-off-by: Kalyan Thota 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 73b3442..718ea0a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -572,6 +572,8 @@ void dpu_rm_release(struct dpu_global_state *global_state,
ARRAY_SIZE(global_state->ctl_to_enc_id), enc->base.id);
_dpu_rm_clear_mapping(global_state->dsc_to_enc_id,
ARRAY_SIZE(global_state->dsc_to_enc_id), enc->base.id);
+   _dpu_rm_clear_mapping(global_state->dspp_to_enc_id,
+   ARRAY_SIZE(global_state->dspp_to_enc_id), enc->base.id);
 }
 
 int dpu_rm_reserve(
-- 
2.7.4



[v1 3/3] drm/msm/disp/dpu1: reserve the resources on topology change

2023-01-30 Thread Kalyan Thota
Some features like ctm can be enabled dynamically. Release and reserve
the dpu resources whenever a topology change occurs such that
required hw blocks are allocated appropriately.

Changes in v1:
- Avoid mode_set call directly instead change the mode_changed (Dmitry)

Signed-off-by: Kalyan Thota 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h|  2 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 42 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  4 ++-
 3 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 539b68b..58e8c72 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -204,6 +204,7 @@ struct dpu_crtc {
  * @hw_ctls   : List of active ctl paths
  * @crc_source: CRC source
  * @crc_frame_skip_count: Number of frames skipped before getting CRC
+ * @ctm_enabled   : Cached ctm reservation state
  */
 struct dpu_crtc_state {
struct drm_crtc_state base;
@@ -225,6 +226,7 @@ struct dpu_crtc_state {
 
enum dpu_crtc_crc_source crc_source;
int crc_frame_skip_count;
+   bool ctm_enabled;
 };
 
 #define to_dpu_crtc_state(x) \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 3bd46b4..0ddf2c9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -217,6 +217,22 @@ static u32 dither_matrix[DITHER_MATRIX_SZ] = {
15, 7, 13, 5, 3, 11, 1, 9, 12, 4, 14, 6, 0, 8, 2, 10
 };
 
+static bool _dpu_enc_is_dspps_changed(struct drm_crtc_state *crtc_state,
+   struct msm_display_topology topology)
+{
+   struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
+
+   if (drm_atomic_crtc_needs_modeset(crtc_state))
+   return true;
+
+   if ((cstate->ctm_enabled && !topology.num_dspp) ||
+   (!cstate->ctm_enabled && topology.num_dspp)) {
+   crtc_state->mode_changed = true;
+   return true;
+   }
+
+   return false;
+}
 
 bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc)
 {
@@ -638,25 +654,21 @@ static int dpu_encoder_virt_atomic_check(
if (ret) {
DPU_ERROR_ENC(dpu_enc,
"mode unsupported, phys idx %d\n", i);
-   break;
+   return ret;
}
}
 
topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, 
crtc_state);
 
+   _dpu_enc_is_dspps_changed(crtc_state, topology);
+
/* Reserve dynamic resources now. */
-   if (!ret) {
-   /*
-* Release and Allocate resources on every modeset
-* Dont allocate when active is false.
-*/
-   if (drm_atomic_crtc_needs_modeset(crtc_state)) {
-   dpu_rm_release(global_state, drm_enc);
+   if (drm_atomic_crtc_needs_modeset(crtc_state)) {
+   dpu_rm_release(global_state, drm_enc);
 
-   if (!crtc_state->active_changed || crtc_state->active)
-   ret = dpu_rm_reserve(_kms->rm, global_state,
-   drm_enc, crtc_state, topology);
-   }
+   if (crtc_state->enable)
+   ret = dpu_rm_reserve(_kms->rm, global_state,
+   drm_enc, crtc_state, topology);
}
 
trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
@@ -1027,7 +1039,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
-   int num_lm, num_ctl, num_pp, num_dsc;
+   int num_lm, num_ctl, num_pp, num_dsc, num_dspp;
unsigned int dsc_mask = 0;
int i;
 
@@ -1058,7 +1070,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
num_lm = dpu_rm_get_assigned_resources(_kms->rm, global_state,
drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
-   dpu_rm_get_assigned_resources(_kms->rm, global_state,
+   num_dspp = dpu_rm_get_assigned_resources(_kms->rm, global_state,
drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
ARRAY_SIZE(hw_dspp));
 
@@ -1089,7 +1101,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
}
 
cstate->num_mixers = num_lm;
-
+   cstate->ctm_enabled = !!num_dspp;
dpu_enc->connector = conn_state->connector;
 
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
diff --git 

[PATCH 0/3] Reserve dspps based on user request

2023-01-30 Thread Kalyan Thota
This series will enable color features on sc7280 target which has primary panel 
as eDP

The series removes dspp allocation based on encoder type and allows the dspp 
reservation
based on user request via ctm.

The series will release/reserve the dpu resources when ever there is a topology 
change
to suit the new requirements.

Kalyan Thota (3):
  drm/msm/disp/dpu1: clear dspp reservations in rm release
  drm/msm/disp/dpu1: add dspps into reservation if there is a ctm
request
  drm/msm/disp/dpu1: reserve the resources on topology change

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h|  1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 54 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  4 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  |  6 ++--
 5 files changed, 50 insertions(+), 17 deletions(-)

-- 
2.7.4



[v1 2/3] drm/msm/disp/dpu1: add dspps into reservation if there is a ctm request

2023-01-30 Thread Kalyan Thota
Add dspp blocks into the topology for reservation, if there is a ctm
request for that composition.

Changes in v1:
- Minor nits (Dmitry)

Signed-off-by: Kalyan Thota 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 9c6817b..3bd46b4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -545,7 +545,8 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
 static struct msm_display_topology dpu_encoder_get_topology(
struct dpu_encoder_virt *dpu_enc,
struct dpu_kms *dpu_kms,
-   struct drm_display_mode *mode)
+   struct drm_display_mode *mode,
+   struct drm_crtc_state *crtc_state)
 {
struct msm_display_topology topology = {0};
int i, intf_count = 0;
@@ -573,11 +574,9 @@ static struct msm_display_topology 
dpu_encoder_get_topology(
else
topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
 
-   if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI) {
-   if (dpu_kms->catalog->dspp &&
-   (dpu_kms->catalog->dspp_count >= topology.num_lm))
-   topology.num_dspp = topology.num_lm;
-   }
+   if (dpu_kms->catalog->dspp &&
+   crtc_state->ctm && (dpu_kms->catalog->dspp_count >= 
topology.num_lm))
+   topology.num_dspp = topology.num_lm;
 
topology.num_enc = 0;
topology.num_intf = intf_count;
@@ -643,7 +642,7 @@ static int dpu_encoder_virt_atomic_check(
}
}
 
-   topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode);
+   topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, 
crtc_state);
 
/* Reserve dynamic resources now. */
if (!ret) {
-- 
2.7.4



[PATCH v12 14/14] drm/msm/disp/dpu: update dpu_enc crtc state on crtc enable/disable during self refresh

2023-01-30 Thread Vinod Polimera
Populate the enocder software structure to reflect the updated
crtc appropriately during crtc enable/disable for a new commit
while taking care of the self refresh transitions when crtc
disable is triggered from the drm self refresh library.

Signed-off-by: Vinod Polimera 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 29 +
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 60e5984..b1ec0c3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1022,8 +1022,17 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
 
DRM_DEBUG_KMS("crtc%d\n", crtc->base.id);
 
-   if (old_crtc_state->self_refresh_active)
+   /* If disable is triggered while in self refresh mode,
+* reset the encoder software state so that in enable
+* it won't trigger a warn while assigning crtc.
+*/
+   if (old_crtc_state->self_refresh_active) {
+   drm_for_each_encoder_mask(encoder, crtc->dev,
+   old_crtc_state->encoder_mask) {
+   dpu_encoder_assign_crtc(encoder, NULL);
+   }
return;
+   }
 
/* Disable/save vblank irq handling */
drm_crtc_vblank_off(crtc);
@@ -1036,7 +1045,14 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
 */
if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_VIDEO)
release_bandwidth = true;
-   dpu_encoder_assign_crtc(encoder, NULL);
+
+   /*
+* If disable is triggered during psr active(e.g: screen dim in 
PSR),
+* we will need encoder->crtc connection to process the device 
sleep &
+* preserve it during psr sequence.
+*/
+   if (!crtc->state->self_refresh_active)
+   dpu_encoder_assign_crtc(encoder, NULL);
}
 
/* wait for frame_event_done completion */
@@ -1084,6 +1100,9 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct drm_encoder *encoder;
bool request_bandwidth = false;
+   struct drm_crtc_state *old_crtc_state;
+
+   old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
 
pm_runtime_get_sync(crtc->dev->dev);
 
@@ -1106,8 +1125,10 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
trace_dpu_crtc_enable(DRMID(crtc), true, dpu_crtc);
dpu_crtc->enabled = true;
 
-   drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)
-   dpu_encoder_assign_crtc(encoder, crtc);
+   if (!old_crtc_state->self_refresh_active) {
+   drm_for_each_encoder_mask(encoder, crtc->dev, 
crtc->state->encoder_mask)
+   dpu_encoder_assign_crtc(encoder, crtc);
+   }
 
/* Enable/restore vblank irq handling */
drm_crtc_vblank_on(crtc);
-- 
2.7.4



[PATCH v12 13/14] drm/msm/disp/dpu: add PSR support for eDP interface in dpu driver

2023-01-30 Thread Vinod Polimera
Enable PSR on eDP interface using drm self-refresh librabry.
This patch uses a trigger from self-refresh library to enter/exit
into PSR, when there are no updates from framework.

Signed-off-by: Kalyan Thota 
Signed-off-by: Vinod Polimera 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 13 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 14 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  2 +-
 3 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index f29a339..60e5984 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "dpu_kms.h"
 #include "dpu_hw_lm.h"
@@ -1021,6 +1022,9 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
 
DRM_DEBUG_KMS("crtc%d\n", crtc->base.id);
 
+   if (old_crtc_state->self_refresh_active)
+   return;
+
/* Disable/save vblank irq handling */
drm_crtc_vblank_off(crtc);
 
@@ -1577,7 +1581,7 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, 
struct drm_plane *plane,
 {
struct drm_crtc *crtc = NULL;
struct dpu_crtc *dpu_crtc = NULL;
-   int i;
+   int i, ret;
 
dpu_crtc = kzalloc(sizeof(*dpu_crtc), GFP_KERNEL);
if (!dpu_crtc)
@@ -1614,6 +1618,13 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, 
struct drm_plane *plane,
/* initialize event handling */
spin_lock_init(_crtc->event_lock);
 
+   ret = drm_self_refresh_helper_init(crtc);
+   if (ret) {
+   DPU_ERROR("Failed to initialize %s with self-refresh helpers 
%d\n",
+   crtc->name, ret);
+   return ERR_PTR(ret);
+   }
+
DRM_DEBUG_KMS("%s: successfully initialized crtc\n", dpu_crtc->name);
return crtc;
 }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 01b7509..450abb1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -1212,11 +1213,24 @@ static void dpu_encoder_virt_atomic_disable(struct 
drm_encoder *drm_enc,
struct drm_atomic_state *state)
 {
struct dpu_encoder_virt *dpu_enc = NULL;
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *old_state = NULL;
int i = 0;
 
dpu_enc = to_dpu_encoder_virt(drm_enc);
DPU_DEBUG_ENC(dpu_enc, "\n");
 
+   crtc = drm_atomic_get_old_crtc_for_encoder(state, drm_enc);
+   if (crtc)
+   old_state = drm_atomic_get_old_crtc_state(state, crtc);
+
+   /*
+* The encoder is already disabled if self refresh mode was set earlier,
+* in the old_state for the corresponding crtc.
+*/
+   if (old_state && old_state->self_refresh_active)
+   return;
+
mutex_lock(_enc->enc_lock);
dpu_enc->enabled = false;
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index a683bd9..681dd2e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -491,7 +491,7 @@ static void dpu_kms_wait_for_commit_done(struct msm_kms 
*kms,
return;
}
 
-   if (!crtc->state->active) {
+   if (!drm_atomic_crtc_effectively_active(crtc->state)) {
DPU_DEBUG("[crtc:%d] not active\n", crtc->base.id);
return;
}
-- 
2.7.4



[PATCH v12 12/14] drm/msm/disp/dpu: use atomic enable/disable callbacks for encoder functions

2023-01-30 Thread Vinod Polimera
Use atomic variants for encoder callback functions such that
certain states like self-refresh can be accessed as part of
enable/disable sequence.

Signed-off-by: Kalyan Thota 
Signed-off-by: Vinod Polimera 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index c237003..01b7509 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1171,7 +1171,8 @@ void dpu_encoder_virt_runtime_resume(struct drm_encoder 
*drm_enc)
mutex_unlock(_enc->enc_lock);
 }
 
-static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc)
+static void dpu_encoder_virt_atomic_enable(struct drm_encoder *drm_enc,
+   struct drm_atomic_state *state)
 {
struct dpu_encoder_virt *dpu_enc = NULL;
int ret = 0;
@@ -1207,7 +1208,8 @@ static void dpu_encoder_virt_enable(struct drm_encoder 
*drm_enc)
mutex_unlock(_enc->enc_lock);
 }
 
-static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
+static void dpu_encoder_virt_atomic_disable(struct drm_encoder *drm_enc,
+   struct drm_atomic_state *state)
 {
struct dpu_encoder_virt *dpu_enc = NULL;
int i = 0;
@@ -2388,8 +2390,8 @@ static void dpu_encoder_frame_done_timeout(struct 
timer_list *t)
 
 static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = {
.atomic_mode_set = dpu_encoder_virt_atomic_mode_set,
-   .disable = dpu_encoder_virt_disable,
-   .enable = dpu_encoder_virt_enable,
+   .atomic_disable = dpu_encoder_virt_atomic_disable,
+   .atomic_enable = dpu_encoder_virt_atomic_enable,
.atomic_check = dpu_encoder_virt_atomic_check,
 };
 
-- 
2.7.4



[PATCH v12 10/14] drm/bridge: use atomic enable/disable callbacks for panel bridge

2023-01-30 Thread Vinod Polimera
Use atomic variants for panel bridge callback functions such that
certain states like self-refresh can be accessed as part of
enable/disable sequence.

Signed-off-by: Sankeerth Billakanti 
Signed-off-by: Vinod Polimera 
Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Daniel Vetter 
---
 drivers/gpu/drm/bridge/panel.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index e8aae3c..04e9fb0 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -109,28 +109,32 @@ static void panel_bridge_detach(struct drm_bridge *bridge)
drm_connector_cleanup(connector);
 }
 
-static void panel_bridge_pre_enable(struct drm_bridge *bridge)
+static void panel_bridge_atomic_pre_enable(struct drm_bridge *bridge,
+   struct drm_bridge_state *old_bridge_state)
 {
struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
 
drm_panel_prepare(panel_bridge->panel);
 }
 
-static void panel_bridge_enable(struct drm_bridge *bridge)
+static void panel_bridge_atomic_enable(struct drm_bridge *bridge,
+   struct drm_bridge_state *old_bridge_state)
 {
struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
 
drm_panel_enable(panel_bridge->panel);
 }
 
-static void panel_bridge_disable(struct drm_bridge *bridge)
+static void panel_bridge_atomic_disable(struct drm_bridge *bridge,
+   struct drm_bridge_state *old_bridge_state)
 {
struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
 
drm_panel_disable(panel_bridge->panel);
 }
 
-static void panel_bridge_post_disable(struct drm_bridge *bridge)
+static void panel_bridge_atomic_post_disable(struct drm_bridge *bridge,
+   struct drm_bridge_state *old_bridge_state)
 {
struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
 
@@ -159,10 +163,10 @@ static void panel_bridge_debugfs_init(struct drm_bridge 
*bridge,
 static const struct drm_bridge_funcs panel_bridge_bridge_funcs = {
.attach = panel_bridge_attach,
.detach = panel_bridge_detach,
-   .pre_enable = panel_bridge_pre_enable,
-   .enable = panel_bridge_enable,
-   .disable = panel_bridge_disable,
-   .post_disable = panel_bridge_post_disable,
+   .atomic_pre_enable = panel_bridge_atomic_pre_enable,
+   .atomic_enable = panel_bridge_atomic_enable,
+   .atomic_disable = panel_bridge_atomic_disable,
+   .atomic_post_disable = panel_bridge_atomic_post_disable,
.get_modes = panel_bridge_get_modes,
.atomic_reset = drm_atomic_helper_bridge_reset,
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
-- 
2.7.4



[PATCH v12 11/14] drm/bridge: add psr support for panel bridge callbacks

2023-01-30 Thread Vinod Polimera
This change will handle the psr entry exit cases in the panel
bridge atomic callback functions. For example, the panel power
should not turn off if the panel is entering psr.

Signed-off-by: Sankeerth Billakanti 
Signed-off-by: Vinod Polimera 
Reviewed-by: Daniel Vetter 
---
 drivers/gpu/drm/bridge/panel.c | 48 ++
 1 file changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index 04e9fb0..a2c6f30 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -113,6 +113,18 @@ static void panel_bridge_atomic_pre_enable(struct 
drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
 {
struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
+   struct drm_atomic_state *atomic_state = old_bridge_state->base.state;
+   struct drm_encoder *encoder = bridge->encoder;
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *old_crtc_state;
+
+   crtc = drm_atomic_get_new_crtc_for_encoder(atomic_state, encoder);
+   if (!crtc)
+   return;
+
+   old_crtc_state = drm_atomic_get_old_crtc_state(atomic_state, crtc);
+   if (old_crtc_state && old_crtc_state->self_refresh_active)
+   return;
 
drm_panel_prepare(panel_bridge->panel);
 }
@@ -121,6 +133,18 @@ static void panel_bridge_atomic_enable(struct drm_bridge 
*bridge,
struct drm_bridge_state *old_bridge_state)
 {
struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
+   struct drm_atomic_state *atomic_state = old_bridge_state->base.state;
+   struct drm_encoder *encoder = bridge->encoder;
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *old_crtc_state;
+
+   crtc = drm_atomic_get_new_crtc_for_encoder(atomic_state, encoder);
+   if (!crtc)
+   return;
+
+   old_crtc_state = drm_atomic_get_old_crtc_state(atomic_state, crtc);
+   if (old_crtc_state && old_crtc_state->self_refresh_active)
+   return;
 
drm_panel_enable(panel_bridge->panel);
 }
@@ -129,6 +153,18 @@ static void panel_bridge_atomic_disable(struct drm_bridge 
*bridge,
struct drm_bridge_state *old_bridge_state)
 {
struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
+   struct drm_atomic_state *atomic_state = old_bridge_state->base.state;
+   struct drm_encoder *encoder = bridge->encoder;
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *new_crtc_state;
+
+   crtc = drm_atomic_get_old_crtc_for_encoder(atomic_state, encoder);
+   if (!crtc)
+   return;
+
+   new_crtc_state = drm_atomic_get_new_crtc_state(atomic_state, crtc);
+   if (new_crtc_state && new_crtc_state->self_refresh_active)
+   return;
 
drm_panel_disable(panel_bridge->panel);
 }
@@ -137,6 +173,18 @@ static void panel_bridge_atomic_post_disable(struct 
drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
 {
struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
+   struct drm_atomic_state *atomic_state = old_bridge_state->base.state;
+   struct drm_encoder *encoder = bridge->encoder;
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *new_crtc_state;
+
+   crtc = drm_atomic_get_old_crtc_for_encoder(atomic_state, encoder);
+   if (!crtc)
+   return;
+
+   new_crtc_state = drm_atomic_get_new_crtc_state(atomic_state, crtc);
+   if (new_crtc_state && new_crtc_state->self_refresh_active)
+   return;
 
drm_panel_unprepare(panel_bridge->panel);
 }
-- 
2.7.4



[PATCH v12 08/14] drm/msm/dp: use the eDP bridge ops to validate eDP modes

2023-01-30 Thread Vinod Polimera
The eDP and DP interfaces shared the bridge operations and
the eDP specific changes were implemented under is_edp check.
To add psr support for eDP, we started using a new set of eDP
bridge ops. We are moving the eDP specific code in the
dp_bridge_mode_valid function to a new eDP function,
edp_bridge_mode_valid under the eDP bridge ops.

Signed-off-by: Sankeerth Billakanti 
Signed-off-by: Vinod Polimera 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dp/dp_display.c |  8 
 drivers/gpu/drm/msm/dp/dp_drm.c | 34 +-
 2 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 86ed80c..ffb21a6 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -996,14 +996,6 @@ enum drm_mode_status dp_bridge_mode_valid(struct 
drm_bridge *bridge,
return -EINVAL;
}
 
-   /*
-* The eDP controller currently does not have a reliable way of
-* enabling panel power to read sink capabilities. So, we rely
-* on the panel driver to populate only supported modes for now.
-*/
-   if (dp->is_edp)
-   return MODE_OK;
-
if (mode->clock > DP_MAX_PIXEL_CLK_KHZ)
return MODE_CLOCK_HIGH;
 
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 3b38bd9..029e08c 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -226,12 +226,44 @@ static void edp_bridge_atomic_post_disable(struct 
drm_bridge *drm_bridge,
dp_bridge_atomic_post_disable(drm_bridge, old_bridge_state);
 }
 
+/**
+ * edp_bridge_mode_valid - callback to determine if specified mode is valid
+ * @bridge: Pointer to drm bridge structure
+ * @info: display info
+ * @mode: Pointer to drm mode structure
+ * Returns: Validity status for specified mode
+ */
+static enum drm_mode_status edp_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
+ const struct drm_display_mode *mode)
+{
+   struct msm_dp *dp;
+   int mode_pclk_khz = mode->clock;
+
+   dp = to_dp_bridge(bridge)->dp_display;
+
+   if (!dp || !mode_pclk_khz || !dp->connector) {
+   DRM_ERROR("invalid params\n");
+   return -EINVAL;
+   }
+
+   if (mode->clock > DP_MAX_PIXEL_CLK_KHZ)
+   return MODE_CLOCK_HIGH;
+
+   /*
+* The eDP controller currently does not have a reliable way of
+* enabling panel power to read sink capabilities. So, we rely
+* on the panel driver to populate only supported modes for now.
+*/
+   return MODE_OK;
+}
+
 static const struct drm_bridge_funcs edp_bridge_ops = {
.atomic_enable = edp_bridge_atomic_enable,
.atomic_disable = edp_bridge_atomic_disable,
.atomic_post_disable = edp_bridge_atomic_post_disable,
.mode_set = dp_bridge_mode_set,
-   .mode_valid = dp_bridge_mode_valid,
+   .mode_valid = edp_bridge_mode_valid,
.atomic_reset = drm_atomic_helper_bridge_reset,
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
-- 
2.7.4



[PATCH v12 09/14] drm/msm/dp: disable self_refresh_aware after entering psr

2023-01-30 Thread Vinod Polimera
From: Sankeerth Billakanti 

Updated frames get queued if self_refresh_aware is set when the
sink is in psr. To support bridge enable and avoid queuing of update
frames, reset the self_refresh_aware state after entering psr.

Signed-off-by: Sankeerth Billakanti 
Signed-off-by: Vinod Polimera 
---
 drivers/gpu/drm/msm/dp/dp_drm.c | 25 -
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 029e08c..01ca148b 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -134,6 +134,8 @@ static void edp_bridge_atomic_enable(struct drm_bridge 
*drm_bridge,
struct drm_crtc_state *old_crtc_state;
struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
struct msm_dp *dp = dp_bridge->dp_display;
+   struct drm_connector *connector;
+   struct drm_connector_state *conn_state = NULL;
 
/*
 * Check the old state of the crtc to determine if the panel
@@ -150,10 +152,20 @@ static void edp_bridge_atomic_enable(struct drm_bridge 
*drm_bridge,
 
if (old_crtc_state && old_crtc_state->self_refresh_active) {
dp_display_set_psr(dp, false);
-   return;
+   goto psr_aware;
}
 
dp_bridge_atomic_enable(drm_bridge, old_bridge_state);
+
+psr_aware:
+   connector = drm_atomic_get_new_connector_for_encoder(atomic_state,
+   drm_bridge->encoder);
+   if (connector)
+   conn_state = drm_atomic_get_new_connector_state(atomic_state,
+   connector);
+
+   if (conn_state)
+   conn_state->self_refresh_aware = dp->psr_supported;
 }
 
 static void edp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
@@ -164,6 +176,14 @@ static void edp_bridge_atomic_disable(struct drm_bridge 
*drm_bridge,
struct drm_crtc_state *new_crtc_state = NULL, *old_crtc_state = NULL;
struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
struct msm_dp *dp = dp_bridge->dp_display;
+   struct drm_connector *connector;
+   struct drm_connector_state *conn_state = NULL;
+
+   connector = drm_atomic_get_old_connector_for_encoder(atomic_state,
+   drm_bridge->encoder);
+   if (connector)
+   conn_state = drm_atomic_get_new_connector_state(atomic_state,
+   connector);
 
crtc = drm_atomic_get_old_crtc_for_encoder(atomic_state,
   drm_bridge->encoder);
@@ -190,6 +210,9 @@ static void edp_bridge_atomic_disable(struct drm_bridge 
*drm_bridge,
 * when display disable occurs while the sink is in psr state.
 */
if (new_crtc_state->self_refresh_active) {
+   if (conn_state)
+   conn_state->self_refresh_aware = false;
+
dp_display_set_psr(dp, true);
return;
} else if (old_crtc_state->self_refresh_active) {
-- 
2.7.4



[PATCH v12 07/14] drm/msm/dp: Add basic PSR support for eDP

2023-01-30 Thread Vinod Polimera
Add support for basic panel self refresh (PSR) feature for eDP.
Add a new interface to set PSR state in the sink from DPU.
Program the eDP controller to issue PSR enter and exit SDP to
the sink.

Signed-off-by: Sankeerth Billakanti 
Signed-off-by: Vinod Polimera 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dp/dp_catalog.c |  80 ++
 drivers/gpu/drm/msm/dp/dp_catalog.h |   4 ++
 drivers/gpu/drm/msm/dp/dp_ctrl.c|  80 ++
 drivers/gpu/drm/msm/dp/dp_ctrl.h|   3 +
 drivers/gpu/drm/msm/dp/dp_display.c |  19 ++
 drivers/gpu/drm/msm/dp/dp_display.h |   2 +
 drivers/gpu/drm/msm/dp/dp_drm.c | 133 +++-
 drivers/gpu/drm/msm/dp/dp_link.c|  36 ++
 drivers/gpu/drm/msm/dp/dp_panel.c   |  22 ++
 drivers/gpu/drm/msm/dp/dp_panel.h   |   6 ++
 drivers/gpu/drm/msm/dp/dp_reg.h |  27 
 11 files changed, 411 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c 
b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 676279d..c12a5d9 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -47,6 +47,14 @@
 #define DP_INTERRUPT_STATUS2_MASK \
(DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_MASK_SHIFT)
 
+#define DP_INTERRUPT_STATUS4 \
+   (PSR_UPDATE_INT | PSR_CAPTURE_INT | PSR_EXIT_INT | \
+   PSR_UPDATE_ERROR_INT | PSR_WAKE_ERROR_INT)
+
+#define DP_INTERRUPT_MASK4 \
+   (PSR_UPDATE_MASK | PSR_CAPTURE_MASK | PSR_EXIT_MASK | \
+   PSR_UPDATE_ERROR_MASK | PSR_WAKE_ERROR_MASK)
+
 struct dp_catalog_private {
struct device *dev;
struct drm_device *drm_dev;
@@ -359,6 +367,23 @@ void dp_catalog_ctrl_lane_mapping(struct dp_catalog 
*dp_catalog)
ln_mapping);
 }
 
+void dp_catalog_ctrl_psr_mainlink_enable(struct dp_catalog *dp_catalog,
+   bool enable)
+{
+   u32 val;
+   struct dp_catalog_private *catalog = container_of(dp_catalog,
+   struct dp_catalog_private, dp_catalog);
+
+   val = dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+
+   if (enable)
+   val |= DP_MAINLINK_CTRL_ENABLE;
+   else
+   val &= ~DP_MAINLINK_CTRL_ENABLE;
+
+   dp_write_link(catalog, REG_DP_MAINLINK_CTRL, val);
+}
+
 void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog *dp_catalog,
bool enable)
 {
@@ -610,6 +635,47 @@ void dp_catalog_ctrl_hpd_config(struct dp_catalog 
*dp_catalog)
dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN);
 }
 
+static void dp_catalog_enable_sdp(struct dp_catalog_private *catalog)
+{
+   /* trigger sdp */
+   dp_write_link(catalog, MMSS_DP_SDP_CFG3, UPDATE_SDP);
+   dp_write_link(catalog, MMSS_DP_SDP_CFG3, 0x0);
+}
+
+void dp_catalog_ctrl_config_psr(struct dp_catalog *dp_catalog)
+{
+   struct dp_catalog_private *catalog = container_of(dp_catalog,
+   struct dp_catalog_private, dp_catalog);
+   u32 config;
+
+   /* enable PSR1 function */
+   config = dp_read_link(catalog, REG_PSR_CONFIG);
+   config |= PSR1_SUPPORTED;
+   dp_write_link(catalog, REG_PSR_CONFIG, config);
+
+   dp_write_ahb(catalog, REG_DP_INTR_MASK4, DP_INTERRUPT_MASK4);
+   dp_catalog_enable_sdp(catalog);
+}
+
+void dp_catalog_ctrl_set_psr(struct dp_catalog *dp_catalog, bool enter)
+{
+   struct dp_catalog_private *catalog = container_of(dp_catalog,
+   struct dp_catalog_private, dp_catalog);
+   u32 cmd;
+
+   cmd = dp_read_link(catalog, REG_PSR_CMD);
+
+   cmd &= ~(PSR_ENTER | PSR_EXIT);
+
+   if (enter)
+   cmd |= PSR_ENTER;
+   else
+   cmd |= PSR_EXIT;
+
+   dp_catalog_enable_sdp(catalog);
+   dp_write_link(catalog, REG_PSR_CMD, cmd);
+}
+
 u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog)
 {
struct dp_catalog_private *catalog = container_of(dp_catalog,
@@ -645,6 +711,20 @@ u32 dp_catalog_hpd_get_intr_status(struct dp_catalog 
*dp_catalog)
return isr & (mask | ~DP_DP_HPD_INT_MASK);
 }
 
+u32 dp_catalog_ctrl_read_psr_interrupt_status(struct dp_catalog *dp_catalog)
+{
+   struct dp_catalog_private *catalog = container_of(dp_catalog,
+   struct dp_catalog_private, dp_catalog);
+   u32 intr, intr_ack;
+
+   intr = dp_read_ahb(catalog, REG_DP_INTR_STATUS4);
+   intr_ack = (intr & DP_INTERRUPT_STATUS4)
+   << DP_INTERRUPT_STATUS_ACK_SHIFT;
+   dp_write_ahb(catalog, REG_DP_INTR_STATUS4, intr_ack);
+
+   return intr;
+}
+
 int dp_catalog_ctrl_get_interrupt(struct dp_catalog *dp_catalog)
 {
struct dp_catalog_private *catalog = container_of(dp_catalog,
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h 
b/drivers/gpu/drm/msm/dp/dp_catalog.h
index 1f717f4..2174bb5 100644
--- 

[PATCH v12 06/14] drm/msm/dp: use atomic callbacks for DP bridge ops

2023-01-30 Thread Vinod Polimera
Use atomic variants for DP bridge callback functions so that
the atomic state can be accessed in the interface drivers.
The atomic state will help the driver find out if the display
is in self refresh state.

Signed-off-by: Sankeerth Billakanti 
Signed-off-by: Vinod Polimera 
Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Douglas Anderson 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 9 ++---
 drivers/gpu/drm/msm/dp/dp_drm.c | 6 +++---
 drivers/gpu/drm/msm/dp/dp_drm.h | 9 ++---
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index bde1a7c..985287e 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1652,7 +1652,8 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct 
drm_device *dev,
return 0;
 }
 
-void dp_bridge_enable(struct drm_bridge *drm_bridge)
+void dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
+struct drm_bridge_state *old_bridge_state)
 {
struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
struct msm_dp *dp = dp_bridge->dp_display;
@@ -1707,7 +1708,8 @@ void dp_bridge_enable(struct drm_bridge *drm_bridge)
mutex_unlock(_display->event_mutex);
 }
 
-void dp_bridge_disable(struct drm_bridge *drm_bridge)
+void dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
+ struct drm_bridge_state *old_bridge_state)
 {
struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
struct msm_dp *dp = dp_bridge->dp_display;
@@ -1718,7 +1720,8 @@ void dp_bridge_disable(struct drm_bridge *drm_bridge)
dp_ctrl_push_idle(dp_display->ctrl);
 }
 
-void dp_bridge_post_disable(struct drm_bridge *drm_bridge)
+void dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
+  struct drm_bridge_state *old_bridge_state)
 {
struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
struct msm_dp *dp = dp_bridge->dp_display;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 275370f..3252d50 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -94,9 +94,9 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state   = drm_atomic_helper_bridge_destroy_state,
.atomic_reset   = drm_atomic_helper_bridge_reset,
-   .enable   = dp_bridge_enable,
-   .disable  = dp_bridge_disable,
-   .post_disable = dp_bridge_post_disable,
+   .atomic_enable  = dp_bridge_atomic_enable,
+   .atomic_disable = dp_bridge_atomic_disable,
+   .atomic_post_disable= dp_bridge_atomic_post_disable,
.mode_set = dp_bridge_mode_set,
.mode_valid   = dp_bridge_mode_valid,
.get_modes= dp_bridge_get_modes,
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h
index 250f7c6..afe79b8 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.h
+++ b/drivers/gpu/drm/msm/dp/dp_drm.h
@@ -23,9 +23,12 @@ struct drm_connector *dp_drm_connector_init(struct msm_dp 
*dp_display, struct dr
 struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device 
*dev,
struct drm_encoder *encoder);
 
-void dp_bridge_enable(struct drm_bridge *drm_bridge);
-void dp_bridge_disable(struct drm_bridge *drm_bridge);
-void dp_bridge_post_disable(struct drm_bridge *drm_bridge);
+void dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
+struct drm_bridge_state *old_bridge_state);
+void dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
+ struct drm_bridge_state *old_bridge_state);
+void dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
+  struct drm_bridge_state *old_bridge_state);
 enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
  const struct drm_display_info *info,
  const struct drm_display_mode *mode);
-- 
2.7.4



[PATCH v12 04/14] drm/msm/disp/dpu: reset the datapath after timing engine disable

2023-01-30 Thread Vinod Polimera
Reset the datapath after disabling the timing gen, such that
it can start on a clean slate when the intf is enabled back.
This was a recommended sequence from the DPU HW programming guide.

Signed-off-by: Vinod Polimera 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 1 +
 1 file changed, 1 insertion(+)

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 0396084..3a37429 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
@@ -588,6 +588,7 @@ static void dpu_encoder_phys_vid_disable(struct 
dpu_encoder_phys *phys_enc)
}
}
 
+   dpu_encoder_helper_phys_cleanup(phys_enc);
phys_enc->enable_state = DPU_ENC_DISABLED;
 }
 
-- 
2.7.4



[PATCH v12 05/14] drm: add helper functions to retrieve old and new crtc

2023-01-30 Thread Vinod Polimera
Add new helper functions, drm_atomic_get_old_crtc_for_encoder
and drm_atomic_get_new_crtc_for_encoder to retrieve the
corresponding crtc for the encoder.

Signed-off-by: Sankeerth Billakanti 
Signed-off-by: Vinod Polimera 
Reviewed-by: Douglas Anderson 
Reviewed-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_atomic.c | 60 
 include/drm/drm_atomic.h |  7 ++
 2 files changed, 67 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 5457c02..7cc39f6 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -985,6 +985,66 @@ drm_atomic_get_new_connector_for_encoder(const struct 
drm_atomic_state *state,
 EXPORT_SYMBOL(drm_atomic_get_new_connector_for_encoder);
 
 /**
+ * drm_atomic_get_old_crtc_for_encoder - Get old crtc for an encoder
+ * @state: Atomic state
+ * @encoder: The encoder to fetch the crtc state for
+ *
+ * This function finds and returns the crtc that was connected to @encoder
+ * as specified by the @state.
+ *
+ * Returns: The old crtc connected to @encoder, or NULL if the encoder is
+ * not connected.
+ */
+struct drm_crtc *
+drm_atomic_get_old_crtc_for_encoder(struct drm_atomic_state *state,
+   struct drm_encoder *encoder)
+{
+   struct drm_connector *connector;
+   struct drm_connector_state *conn_state;
+
+   connector = drm_atomic_get_old_connector_for_encoder(state, encoder);
+   if (!connector)
+   return NULL;
+
+   conn_state = drm_atomic_get_old_connector_state(state, connector);
+   if (!conn_state)
+   return NULL;
+
+   return conn_state->crtc;
+}
+EXPORT_SYMBOL(drm_atomic_get_old_crtc_for_encoder);
+
+/**
+ * drm_atomic_get_new_crtc_for_encoder - Get new crtc for an encoder
+ * @state: Atomic state
+ * @encoder: The encoder to fetch the crtc state for
+ *
+ * This function finds and returns the crtc that will be connected to @encoder
+ * as specified by the @state.
+ *
+ * Returns: The new crtc connected to @encoder, or NULL if the encoder is
+ * not connected.
+ */
+struct drm_crtc *
+drm_atomic_get_new_crtc_for_encoder(struct drm_atomic_state *state,
+   struct drm_encoder *encoder)
+{
+   struct drm_connector *connector;
+   struct drm_connector_state *conn_state;
+
+   connector = drm_atomic_get_new_connector_for_encoder(state, encoder);
+   if (!connector)
+   return NULL;
+
+   conn_state = drm_atomic_get_new_connector_state(state, connector);
+   if (!conn_state)
+   return NULL;
+
+   return conn_state->crtc;
+}
+EXPORT_SYMBOL(drm_atomic_get_new_crtc_for_encoder);
+
+/**
  * drm_atomic_get_connector_state - get connector state
  * @state: global atomic state object
  * @connector: connector to get state object for
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 92586ab..9a022ca 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -528,6 +528,13 @@ struct drm_connector *
 drm_atomic_get_new_connector_for_encoder(const struct drm_atomic_state *state,
 struct drm_encoder *encoder);
 
+struct drm_crtc *
+drm_atomic_get_old_crtc_for_encoder(struct drm_atomic_state *state,
+struct drm_encoder *encoder);
+struct drm_crtc *
+drm_atomic_get_new_crtc_for_encoder(struct drm_atomic_state *state,
+struct drm_encoder *encoder);
+
 /**
  * drm_atomic_get_existing_crtc_state - get CRTC state, if it exists
  * @state: global atomic state object
-- 
2.7.4



[PATCH v12 03/14] drm/msm/disp/dpu: wait for extra vsync till timing engine status is disabled

2023-01-30 Thread Vinod Polimera
There can be a race between timing gen disable and vblank irq. The
wait post timing gen disable may return early but intf disable sequence
might not be completed. Ensure that, intf status is disabled before
we retire the function.

Signed-off-by: Vinod Polimera 
Reviewed-by: Dmitry Baryshkov 
---
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c| 21 +
 1 file changed, 21 insertions(+)

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 48c4810..0396084 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
@@ -523,6 +523,7 @@ static void dpu_encoder_phys_vid_disable(struct 
dpu_encoder_phys *phys_enc)
 {
unsigned long lock_flags;
int ret;
+   struct intf_status intf_status = {0};
 
if (!phys_enc->parent || !phys_enc->parent->dev) {
DPU_ERROR("invalid encoder/device\n");
@@ -567,6 +568,26 @@ static void dpu_encoder_phys_vid_disable(struct 
dpu_encoder_phys *phys_enc)
}
}
 
+   if (phys_enc->hw_intf && phys_enc->hw_intf->ops.get_status)
+   phys_enc->hw_intf->ops.get_status(phys_enc->hw_intf, 
_status);
+
+   /*
+* Wait for a vsync if timing en status is on after timing engine
+* is disabled.
+*/
+   if (intf_status.is_en && dpu_encoder_phys_vid_is_master(phys_enc)) {
+   spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
+   dpu_encoder_phys_inc_pending(phys_enc);
+   spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
+   ret = dpu_encoder_phys_vid_wait_for_vblank(phys_enc);
+   if (ret) {
+   atomic_set(_enc->pending_kickoff_cnt, 0);
+   DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n",
+ DRMID(phys_enc->parent),
+ phys_enc->hw_intf->idx - INTF_0, ret);
+   }
+   }
+
phys_enc->enable_state = DPU_ENC_DISABLED;
 }
 
-- 
2.7.4



[PATCH v12 02/14] drm/msm/disp/dpu: get timing engine status from intf status register

2023-01-30 Thread Vinod Polimera
Recommended way of reading the interface timing gen status is via
status register. Timing gen status register will give a reliable status
of the interface especially during ON/OFF transitions. This support was
added from DPU version 5.0.0.

Signed-off-by: Vinod Polimera 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |  6 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 12 +++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c|  8 +++-
 3 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index cf053e8..ce6e9e6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -78,9 +78,11 @@
 
 #define INTF_SDM845_MASK (0)
 
-#define INTF_SC7180_MASK BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE)
+#define INTF_SC7180_MASK \
+   (BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) | 
BIT(DPU_INTF_STATUS_SUPPORTED))
 
-#define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN)
+#define INTF_SC7280_MASK \
+   (INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN))
 
 #define IRQ_SDM845_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
 BIT(MDP_SSPP_TOP0_INTR2) | \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index ddab9ca..08cd1a1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -213,17 +213,19 @@ enum {
 
 /**
  * INTF sub-blocks
- * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which
- *  pixel data arrives to this INTF
- * @DPU_INTF_TE INTF block has TE configuration support
- * @DPU_DATA_HCTL_ENAllows data to be transferred at different rate
-than video timing
+ * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which
+ *  pixel data arrives to this INTF
+ * @DPU_INTF_TE INTF block has TE configuration support
+ * @DPU_DATA_HCTL_ENAllows data to be transferred at different 
rate
+ *  than video timing
+ * @DPU_INTF_STATUS_SUPPORTED   INTF block has INTF_STATUS register
  * @DPU_INTF_MAX
  */
 enum {
DPU_INTF_INPUT_CTRL = 0x1,
DPU_INTF_TE,
DPU_DATA_HCTL_EN,
+   DPU_INTF_STATUS_SUPPORTED,
DPU_INTF_MAX
 };
 
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 7ce66bf..84ee2ef 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -62,6 +62,7 @@
 #define   INTF_LINE_COUNT   0x0B0
 
 #define   INTF_MUX  0x25C
+#define   INTF_STATUS   0x26C
 
 #define INTF_CFG_ACTIVE_H_EN   BIT(29)
 #define INTF_CFG_ACTIVE_V_EN   BIT(30)
@@ -297,8 +298,13 @@ static void dpu_hw_intf_get_status(
struct intf_status *s)
 {
struct dpu_hw_blk_reg_map *c = >hw;
+   unsigned long cap = intf->cap->features;
+
+   if (cap & BIT(DPU_INTF_STATUS_SUPPORTED))
+   s->is_en = DPU_REG_READ(c, INTF_STATUS) & BIT(0);
+   else
+   s->is_en = DPU_REG_READ(c, INTF_TIMING_ENGINE_EN);
 
-   s->is_en = DPU_REG_READ(c, INTF_TIMING_ENGINE_EN);
s->is_prog_fetch_en = !!(DPU_REG_READ(c, INTF_CONFIG) & BIT(31));
if (s->is_en) {
s->frame_count = DPU_REG_READ(c, INTF_FRAME_COUNT);
-- 
2.7.4



[PATCH v12 00/14] Add PSR support for eDP

2023-01-30 Thread Vinod Polimera
Changes in v2:
  - Use dp bridge to set psr entry/exit instead of dpu_enocder.
  - Don't modify whitespaces.
  - Set self refresh aware from atomic_check.
  - Set self refresh aware only if psr is supported.
  - Provide a stub for msm_dp_display_set_psr.
  - Move dp functions to bridge code.

Changes in v3:
  - Change callback names to reflect atomic interfaces.
  - Move bridge callback change to separate patch as suggested by Dmitry.
  - Remove psr function declaration from msm_drv.h.
  - Set self_refresh_aware flag only if psr is supported.
  - Modify the variable names to simpler form.
  - Define bit fields for PSR settings.
  - Add comments explaining the steps to enter/exit psr.
  - Change DRM_INFO to drm_dbg_db. 

Changes in v4:
  - Move the get crtc functions to drm_atomic.
  - Add atomic functions for DP bridge too.
  - Add ternary operator to choose eDP or DP ops.
  - Return true/false instead of 1/0.
  - mode_valid missing in the eDP bridge ops.
  - Move the functions to get crtc into drm_atomic.c.
  - Fix compilation issues.
  - Remove dpu_assign_crtc and get crtc from drm_enc instead of dpu_enc.
  - Check for crtc state enable while reserving resources.

Changes in v5:
  - Move the mode_valid changes into a different patch.
  - Complete psr_op_comp only when isr is set.
  - Move the DP atomic callback changes to a different patch.
  - Get crtc from drm connector state crtc.
  - Move to separate patch for check for crtc state enable while
reserving resources.

Changes in v6:
  - Remove crtc from dpu_encoder_virt struct.
  - fix crtc check during vblank toggle crtc.
  - Misc changes. 

Changes in v7:
  - Add fix for underrun issue on kasan build.

Changes in v8:
  - Drop the enc spinlock as it won't serve any purpose in
protetcing conn state.(Dmitry/Doug)

Changes in v9:
  - Update commit message and fix alignment using spaces.(Marijn)
  - Misc changes.(Marijn)

Changes in v10:
  - Get crtc cached in dpu_enc during obj init.(Dmitry)

Changes in v11:
  - Remove crtc cached in dpu_enc during obj init.
  - Update dpu_enc crtc state on crtc enable/disable during self refresh.

Changes in v12:
  - Update sc7180 intf mask to get intf timing gen status
based on DPU_INTF_STATUS_SUPPORTED bit.(Dmitry)
  - Remove "clear active interface in the datapath cleanup" change
as it is already included.
  - Move core changes to top of the series.(Dmitry)

Sankeerth Billakanti (1):
  drm/msm/dp: disable self_refresh_aware after entering psr

Vinod Polimera (13):
  drm/msm/disp/dpu: check for crtc enable rather than crtc active to
release shared resources
  drm/msm/disp/dpu: get timing engine status from intf status register
  drm/msm/disp/dpu: wait for extra vsync till timing engine status is
disabled
  drm/msm/disp/dpu: reset the datapath after timing engine disable
  drm: add helper functions to retrieve old and new crtc
  drm/msm/dp: use atomic callbacks for DP bridge ops
  drm/msm/dp: Add basic PSR support for eDP
  drm/msm/dp: use the eDP bridge ops to validate eDP modes
  drm/bridge: use atomic enable/disable callbacks for panel bridge
  drm/bridge: add psr support for panel bridge callbacks
  drm/msm/disp/dpu: use atomic enable/disable callbacks for encoder
functions
  drm/msm/disp/dpu: add PSR support for eDP interface in dpu driver
  drm/msm/disp/dpu: update dpu_enc crtc state on crtc enable/disable
during self refresh

 drivers/gpu/drm/bridge/panel.c |  68 +++-
 drivers/gpu/drm/drm_atomic.c   |  60 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c   |  40 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c|  26 ++-
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c   |  22 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |   6 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  12 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c|   8 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c|   2 +-
 drivers/gpu/drm/msm/dp/dp_catalog.c|  80 +
 drivers/gpu/drm/msm/dp/dp_catalog.h|   4 +
 drivers/gpu/drm/msm/dp/dp_ctrl.c   |  80 +
 drivers/gpu/drm/msm/dp/dp_ctrl.h   |   3 +
 drivers/gpu/drm/msm/dp/dp_display.c|  36 ++--
 drivers/gpu/drm/msm/dp/dp_display.h|   2 +
 drivers/gpu/drm/msm/dp/dp_drm.c| 194 -
 drivers/gpu/drm/msm/dp/dp_drm.h|   9 +-
 drivers/gpu/drm/msm/dp/dp_link.c   |  36 
 drivers/gpu/drm/msm/dp/dp_panel.c  |  22 +++
 drivers/gpu/drm/msm/dp/dp_panel.h  |   6 +
 drivers/gpu/drm/msm/dp/dp_reg.h|  27 +++
 include/drm/drm_atomic.h   |   7 +
 22 files changed, 706 insertions(+), 44 deletions(-)

-- 
2.7.4



[PATCH v12 01/14] drm/msm/disp/dpu: check for crtc enable rather than crtc active to release shared resources

2023-01-30 Thread Vinod Polimera
According to KMS documentation, The driver must not release any shared
resources if active is set to false but enable still true.

Fixes: ccc862b957c6 ("drm/msm/dpu: Fix reservation failures in modeset")
Signed-off-by: Vinod Polimera 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 758261e..c237003 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -652,7 +652,7 @@ static int dpu_encoder_virt_atomic_check(
if (drm_atomic_crtc_needs_modeset(crtc_state)) {
dpu_rm_release(global_state, drm_enc);
 
-   if (!crtc_state->active_changed || crtc_state->active)
+   if (!crtc_state->active_changed || crtc_state->enable)
ret = dpu_rm_reserve(_kms->rm, global_state,
drm_enc, crtc_state, topology);
}
-- 
2.7.4



Re: [PATCH 0/2] drm/tegra: handle implicit scanout modifiers

2023-01-30 Thread Diogo Ivo
On Tue, Jan 24, 2023 at 03:25:09PM +0100, Thierry Reding wrote:
> On Fri, Jan 20, 2023 at 10:58:56AM +, Diogo Ivo wrote:
> > Hello!
> > 
> > This patch series adds support for correctly displaying tiled
> > framebuffers when no modifiers are reported by userspace.
> > 
> > Patch 1 adds the sector_layout parameter to the SET/GET_TILING
> > IOCTLs so that userspace can set this field appropriately.
> > 
> > Patch 2 adds handling of the case where the buffer object
> > passed to create a framebuffer is allocated with non-linear
> > tiling but no modifier is reported.
> > 
> > Diogo Ivo (2):
> >   drm/tegra: add sector layout to SET/GET_TILING IOCTLs
> >   drm/tegra: add scanout support for implicit tiling parameters
> > 
> >  drivers/gpu/drm/tegra/drm.c  | 29 ++
> >  drivers/gpu/drm/tegra/fb.c   | 59 ++--
> >  include/uapi/drm/tegra_drm.h | 16 ++
> >  3 files changed, 96 insertions(+), 8 deletions(-)
> 
> We really don't want to use SET_TILING and GET_TILING IOCTLs anymore.
> These only exist for backwards compatibility with very old userspace.
> New code should use standard DRM/KMS mechanisms to deal with
> framebuffer modifiers.

Hello,

Thank you for your review! This implementation is basically a copy of
what vc4 already does when importing resources with no modifiers
specified by userspace.

I looked into the DRM/KMS infrastructure and did not find a mechanism
to do this, but perhaps I am missing something; if this is the case,
I would be happy to submit a more fitting implementation, since handling
these implicit modifiers allows us to lift the restriction of linear
scanout buffers.

Best regards,
Diogo


Re: [PATCH] drm/i915/pcode: Wait 10 seconds for pcode to settle

2023-01-30 Thread Rodrigo Vivi
On Mon, Jan 30, 2023 at 09:48:31AM +0100, Andi Shyti wrote:
> Hi GG,
> 
> thanks for the deep analysis!
> 
> > Hi Andi,
> > In the call flow invoked by intel_pcode_init(), I've added brief comments
> > where further clarification is needed in this scenario, and a description of
> > the suspicious scenario at the bottom.
> > 
> > -
> > intel_pcode_init()
> >  |
> >  +-> skl_pcode_request(uncore, DG1_PCODE_STATUS,
> >DG1_UNCORE_GET_INIT_STATUS,
> >DG1_UNCORE_INIT_STATUS_COMPLETE,
> >DG1_UNCORE_INIT_STATUS_COMPLETE, 18);
> >|
> >+-> skl_pcode_try_request()
> >  |
> >  +->  *status = __snb_pcode_rw(uncore, mbox, , NULL,
> >500, 0, true);
> > 
> > -
> > static int __snb_pcode_rw(struct intel_uncore *uncore, u32 mbox,
> >   u32 *val, u32 *val1,
> >   int fast_timeout_us, int slow_timeout_ms,
> >   bool is_read)
> > {
> > ...
> > /* Before writing a value to the GEN6_PCODE_DATA register,
> >check if the bit in the GEN6_PCODE_MAILBOX register indicates
> >BUSY. */
> > if (intel_uncore_read_fw(uncore, GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY)
> > return -EAGAIN;
> 
> what if we fail here because the punit is still initializing and
> will be ready, say, in 10 seconds?
> 
> GG, without going any further, we fail here! The -EAGAIN we
> receive from the test comes from this point. We don't fail with
> -ETIMEDOUT, but with -EAGAIN and the reason is because the punit
> is not ready to perform the very fist communication and we fail
> the probing.
> 
> It doesn't mean, though, that there is anything wrong, we just
> need to wait a bit before "taking drastic decisions"!
> 
> This patch is suggesting to wait up to 10s for the punit to be
> ready and eventually try to probe again... and, indeed, it works!

As GG, what I still don't understand is how this extra 10 seconds
wait helps... have you tried to simple add the 10 to the 180 and
make the code 190 sec instead?

> 
> Andi
> 
> > 
> > /* write value to GEN6_PCODE_DATA register */
> > intel_uncore_write_fw(uncore, GEN6_PCODE_DATA, *val);
> > 
> > intel_uncore_write_fw(uncore, GEN6_PCODE_DATA1, val1 ? *val1 : 0);
> > 
> > /* In this scenario, the value
> >"DG1_PCODE_STATUS | GEN6_PCODE_READY"
> >is written to the GEN6_PCODE_MAILBOX register,
> >so that the Busy status of the GEN6_PCODE_MAILBOX register
> >can be checked later.
> >(When the value of the GEN6_PCODE_READY bit of the
> > GEN6_PCODE_MAILBOX register changes to 0, the operation can
> > be considered completed.) */
> > intel_uncore_write_fw(uncore,
> >   GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
> > 
> > /* In this scenario, verify that the BUSY status bit in the
> >GEN6_PCODE_MAILBOX register turns off for up to 500us. */
> > if (__intel_wait_for_register_fw(uncore,
> >  GEN6_PCODE_MAILBOX,
> >  GEN6_PCODE_READY, 0,
> >  fast_timeout_us,
> >  slow_timeout_ms,
> >  ))
> > return -ETIMEDOUT;
> > /* If there is a failure here, it may be considered that the
> >"DG1_PCODE_STATUS | GEN6_PCODE_READY" operation was not
> >completed within 500us */
> > ...
> > }
> > 
> > int skl_pcode_request(struct intel_uncore *uncore, u32 mbox, u32 request,
> >   u32 reply_mask, u32 reply, int timeout_base_ms)
> > {
> > u32 status;
> > int ret;
> > 
> > mutex_lock(>i915->sb_lock);
> > 
> > #define COND \
> > skl_pcode_try_request(uncore, mbox, request, reply_mask, reply, )
> > 
> > /* the first trial for skl_pcode_try_request() can return
> >-EAGAIN or -ETIMEDOUT. And the code did not check the error
> >code here, so we don't know how far the __snb_pcode_rw()
> >function went. It is not known whether the pcode_mailbox
> >status was busy before writing the value to the
> >GEN6_PCODE_DATA register or after.*/
> > if (COND) {
> > ret = 0;
> > goto out;
> > }
> > 
> > /* In this scenario, skl_pcode_try_request() is invoked every
> >10us for 180 seconds. When skl_pcode_try_request() returns
> >-EAGAIN and -ETIMEDOUT by _wait_for(),
> >-ETIMEDOUT is returned to a variable ret. */
> > 
> > ret = _wait_for(COND, timeout_base_ms * 1000, 10, 10);
> > 
> > if (!ret)
> > 

[PATCH v4 18/21] staging: media: tegra-video: add syncpts for Tegra20 to struct tegra_vi

2023-01-30 Thread Luca Ceresoli
In preparation to implement Tegra20 parallel video capture, add a variable
to hold the required syncpt and document all the syncpt variables.

Signed-off-by: Luca Ceresoli 
Reviewed-by: Dmitry Osipenko 

---

Changed in v4:
 - Added review tags

Changed in v3:
 - recycle mw_ack_sp[0] instead of adding out_sp

No changes in v2
---
 drivers/staging/media/tegra-video/vi.h | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index 8fadca33bcc9..d5e1ed4217e0 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -117,11 +117,13 @@ struct tegra_vi {
  * @vi: Tegra video input device structure
  * @frame_start_sp: host1x syncpoint pointer to synchronize programmed capture
  * start condition with hardware frame start events through host1x
- * syncpoint counters.
+ * syncpoint counters. (Tegra210)
  * @mw_ack_sp: host1x syncpoint pointer to synchronize programmed memory write
  * ack trigger condition with hardware memory write done at end of
- * frame through host1x syncpoint counters.
+ * frame through host1x syncpoint counters (On Tegra20 used for the
+ *  OUT_1 syncpt)
  * @sp_incr_lock: protects cpu syncpoint increment.
+ * @next_out_sp_idx: next expected value for mw_ack_sp[0], i.e. OUT_1 (Tegra20)
  *
  * @kthread_start_capture: kthread to start capture of single frame when
  * vb buffer is available. This thread programs VI CSI hardware
@@ -173,6 +175,7 @@ struct tegra_vi_channel {
struct host1x_syncpt *mw_ack_sp[GANG_PORTS_MAX];
/* protects the cpu syncpoint increment */
spinlock_t sp_incr_lock[GANG_PORTS_MAX];
+   u32 next_out_sp_idx;
 
struct task_struct *kthread_start_capture;
wait_queue_head_t start_wait;
-- 
2.34.1



[PATCH v4 17/21] staging: media: tegra-video: move syncpt init/free to a per-soc op

2023-01-30 Thread Luca Ceresoli
tegra_channel_host1x_syncpt_init() gets the host1x syncpts needed for the
Tegra210 implementation, and tegra_channel_host1x_syncpts_free() puts
them.

Tegra20 needs to get and put a different syncpt. In preparation for adding
Tegra20 support, move these functions to new ops in the soc-specific
`struct tegra_vi_ops` .

No functional changes.

Signed-off-by: Luca Ceresoli 
Reviewed-by: Dmitry Osipenko 

---

Changed in v4:
 - Added review tags

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/tegra210.c | 52 
 drivers/staging/media/tegra-video/vi.c   | 52 ++--
 drivers/staging/media/tegra-video/vi.h   |  5 ++
 3 files changed, 60 insertions(+), 49 deletions(-)

diff --git a/drivers/staging/media/tegra-video/tegra210.c 
b/drivers/staging/media/tegra-video/tegra210.c
index 28d3d05c12c4..d47ba79bac75 100644
--- a/drivers/staging/media/tegra-video/tegra210.c
+++ b/drivers/staging/media/tegra-video/tegra210.c
@@ -179,6 +179,56 @@ static u32 vi_csi_read(struct tegra_vi_channel *chan, u8 
portno,
 /*
  * Tegra210 VI channel capture operations
  */
+
+static int tegra210_channel_host1x_syncpt_init(struct tegra_vi_channel *chan)
+{
+   struct tegra_vi *vi = chan->vi;
+   unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
+   struct host1x_syncpt *fs_sp;
+   struct host1x_syncpt *mw_sp;
+   int ret, i;
+
+   for (i = 0; i < chan->numgangports; i++) {
+   fs_sp = host1x_syncpt_request(>client, flags);
+   if (!fs_sp) {
+   dev_err(vi->dev, "failed to request frame start 
syncpoint\n");
+   ret = -ENOMEM;
+   goto free_syncpts;
+   }
+
+   mw_sp = host1x_syncpt_request(>client, flags);
+   if (!mw_sp) {
+   dev_err(vi->dev, "failed to request memory ack 
syncpoint\n");
+   host1x_syncpt_put(fs_sp);
+   ret = -ENOMEM;
+   goto free_syncpts;
+   }
+
+   chan->frame_start_sp[i] = fs_sp;
+   chan->mw_ack_sp[i] = mw_sp;
+   spin_lock_init(>sp_incr_lock[i]);
+   }
+
+   return 0;
+
+free_syncpts:
+   for (i = 0; i < chan->numgangports; i++) {
+   host1x_syncpt_put(chan->mw_ack_sp[i]);
+   host1x_syncpt_put(chan->frame_start_sp[i]);
+   }
+   return ret;
+}
+
+static void tegra210_channel_host1x_syncpt_free(struct tegra_vi_channel *chan)
+{
+   int i;
+
+   for (i = 0; i < chan->numgangports; i++) {
+   host1x_syncpt_put(chan->mw_ack_sp[i]);
+   host1x_syncpt_put(chan->frame_start_sp[i]);
+   }
+}
+
 static void tegra210_fmt_align(struct v4l2_pix_format *pix, unsigned int bpp)
 {
unsigned int min_bpl;
@@ -758,6 +808,8 @@ static const struct tegra_video_format 
tegra210_video_formats[] = {
 
 /* Tegra210 VI operations */
 static const struct tegra_vi_ops tegra210_vi_ops = {
+   .channel_host1x_syncpt_init = tegra210_channel_host1x_syncpt_init,
+   .channel_host1x_syncpt_free = tegra210_channel_host1x_syncpt_free,
.vi_fmt_align = tegra210_fmt_align,
.vi_start_streaming = tegra210_vi_start_streaming,
.vi_stop_streaming = tegra210_vi_stop_streaming,
diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 22f6d6478d3e..760606c65a97 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -973,21 +973,11 @@ static int tegra_channel_setup_ctrl_handler(struct 
tegra_vi_channel *chan)
return 0;
 }
 
-static void tegra_channel_host1x_syncpts_free(struct tegra_vi_channel *chan)
-{
-   int i;
-
-   for (i = 0; i < chan->numgangports; i++) {
-   host1x_syncpt_put(chan->mw_ack_sp[i]);
-   host1x_syncpt_put(chan->frame_start_sp[i]);
-   }
-}
-
 static void tegra_channel_cleanup(struct tegra_vi_channel *chan)
 {
v4l2_ctrl_handler_free(>ctrl_handler);
media_entity_cleanup(>video.entity);
-   tegra_channel_host1x_syncpts_free(chan);
+   chan->vi->ops->channel_host1x_syncpt_free(chan);
mutex_destroy(>video_lock);
 }
 
@@ -1005,42 +995,6 @@ void tegra_channels_cleanup(struct tegra_vi *vi)
}
 }
 
-static int tegra_channel_host1x_syncpt_init(struct tegra_vi_channel *chan)
-{
-   struct tegra_vi *vi = chan->vi;
-   unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
-   struct host1x_syncpt *fs_sp;
-   struct host1x_syncpt *mw_sp;
-   int ret, i;
-
-   for (i = 0; i < chan->numgangports; i++) {
-   fs_sp = host1x_syncpt_request(>client, flags);
-   if (!fs_sp) {
-   dev_err(vi->dev, "failed to request frame start 
syncpoint\n");
-   ret = -ENOMEM;
-   goto free_syncpts;
-   }
-
-   mw_sp = 

[PATCH v4 19/21] staging: media: tegra-video: add hooks for planar YUV and H/V flip

2023-01-30 Thread Luca Ceresoli
Tegra20 supports planar YUV422 capture, which can be implemented by writing
U and V base address registers in addition to the "main" base buffer
address register.

It also supports H and V flip, which among others requires to write the
start address (i.e. the 1st offset to write, at the end of the buffer or
line) in more registers for Y and, for planar formats, U and V.

Add minimal hooks in VI to allow per-SoC optional support to those
features:

 - variables in struct tegra_vi for the U and V buffer base offsets
 - variables in struct tegra_vi for the Y, U and V buffer start offsets
 - an optional per-soc VI operation to compute those values on queue setup

Signed-off-by: Luca Ceresoli 
Reviewed-by: Dmitry Osipenko 

---

Changed in v4:
 - Added review tags

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/vi.c |  4 
 drivers/staging/media/tegra-video/vi.h | 14 ++
 2 files changed, 18 insertions(+)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 760606c65a97..4a066b61ab8e 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -92,6 +92,7 @@ tegra_get_format_by_fourcc(struct tegra_vi *vi, u32 fourcc)
 /*
  * videobuf2 queue operations
  */
+
 static int tegra_channel_queue_setup(struct vb2_queue *vq,
 unsigned int *nbuffers,
 unsigned int *nplanes,
@@ -107,6 +108,9 @@ static int tegra_channel_queue_setup(struct vb2_queue *vq,
sizes[0] = chan->format.sizeimage;
alloc_devs[0] = chan->vi->dev;
 
+   if (chan->vi->ops->channel_queue_setup)
+   chan->vi->ops->channel_queue_setup(chan);
+
return 0;
 }
 
diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index d5e1ed4217e0..0503eb678556 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -47,6 +47,7 @@ struct tegra_vi_channel;
  * @channel_host1x_syncpt_free: free all synchronization points
  * @vi_fmt_align: modify `pix` to fit the hardware alignment
  * requirements and fill image geometry
+ * @channel_queue_setup: additional operations at the end of 
vb2_ops::queue_setup
  * @vi_start_streaming: starts media pipeline, subdevice streaming, sets up
  * VI for capture and runs capture start and capture finish
  * kthreads for capturing frames to buffer and returns them back.
@@ -58,6 +59,7 @@ struct tegra_vi_ops {
int (*channel_host1x_syncpt_init)(struct tegra_vi_channel *chan);
void (*channel_host1x_syncpt_free)(struct tegra_vi_channel *chan);
void (*vi_fmt_align)(struct v4l2_pix_format *pix, unsigned int bpp);
+   void (*channel_queue_setup)(struct tegra_vi_channel *chan);
int (*vi_start_streaming)(struct vb2_queue *vq, u32 count);
void (*vi_stop_streaming)(struct vb2_queue *vq);
 };
@@ -148,6 +150,12 @@ struct tegra_vi {
  * @queue: vb2 buffers queue
  * @sequence: V4L2 buffers sequence number
  *
+ * @addr_offset_u: U plane base address, relative to buffer base address (only 
for planar)
+ * @addr_offset_v: V plane base address, relative to buffer base address (only 
for planar)
+ * @start_offset:   1st Y byte to write, relative to buffer base address (for 
H/V flip)
+ * @start_offset_u: 1st U byte to write, relative to buffer base address (for 
H/V flip)
+ * @start_offset_v: 1st V byte to write, relative to buffer base address (for 
H/V flip)
+ *
  * @capture: list of queued buffers for capture
  * @start_lock: protects the capture queued list
  * @done: list of capture done queued buffers
@@ -187,6 +195,12 @@ struct tegra_vi_channel {
struct vb2_queue queue;
u32 sequence;
 
+   unsigned int addr_offset_u;
+   unsigned int addr_offset_v;
+   unsigned int start_offset;
+   unsigned int start_offset_u;
+   unsigned int start_offset_v;
+
struct list_head capture;
/* protects the capture queued list */
spinlock_t start_lock;
-- 
2.34.1



[PATCH v4 20/21] staging: media: tegra-video: add H/V flip controls

2023-01-30 Thread Luca Ceresoli
Tegra20 can do horizontal and vertical image flip, but Tegra210 cannot
(either the hardware, or this driver).

In preparation to adding Tegra20 support, add a flag in struct tegra_vi_soc
so the generic vi.c code knows whether the flip controls should be added or
not.

Also provide a generic implementation that simply sets two flags in the
channel struct. The Tegra20 implementation will enable flipping at stream
start based on those flags.

Signed-off-by: Luca Ceresoli 
Reviewed-by: Dmitry Osipenko 

---

Changed in v4:
 - Added review tags

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/vi.c | 14 +-
 drivers/staging/media/tegra-video/vi.h |  8 
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 4a066b61ab8e..d1c6877163c2 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -29,7 +29,7 @@
 #include "vi.h"
 #include "video.h"
 
-#define MAX_CID_CONTROLS   1
+#define MAX_CID_CONTROLS   3
 
 /**
  * struct tegra_vi_graph_entity - Entity in the video graph
@@ -893,6 +893,12 @@ static int vi_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY:
chan->syncpt_timeout_retry = ctrl->val;
break;
+   case V4L2_CID_HFLIP:
+   chan->hflip = ctrl->val;
+   break;
+   case V4L2_CID_VFLIP:
+   chan->vflip = ctrl->val;
+   break;
default:
return -EINVAL;
}
@@ -964,6 +970,12 @@ static int tegra_channel_setup_ctrl_handler(struct 
tegra_vi_channel *chan)
v4l2_ctrl_handler_free(>ctrl_handler);
return ret;
}
+
+   if (chan->vi->soc->has_h_v_flip) {
+   v4l2_ctrl_new_std(>ctrl_handler, _ctrl_ops, 
V4L2_CID_HFLIP, 0, 1, 1, 0);
+   v4l2_ctrl_new_std(>ctrl_handler, _ctrl_ops, 
V4L2_CID_VFLIP, 0, 1, 1, 0);
+   }
+
 #endif
 
/* setup the controls */
diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index 0503eb678556..8fa817757059 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -74,6 +74,7 @@ struct tegra_vi_ops {
  * @hw_revision: VI hw_revision
  * @vi_max_channels: supported max streaming channels
  * @vi_max_clk_hz: VI clock max frequency
+ * @has_h_v_flip: the chip can do H adn V flip, and the driver implements it
  */
 struct tegra_vi_soc {
const struct tegra_video_format *video_formats;
@@ -83,6 +84,7 @@ struct tegra_vi_soc {
u32 hw_revision;
unsigned int vi_max_channels;
unsigned int vi_max_clk_hz;
+   bool has_h_v_flip:1;
 };
 
 /**
@@ -170,6 +172,9 @@ struct tegra_vi {
  * @syncpt_timeout_retry: syncpt timeout retry count for the capture
  * @pg_mode: test pattern generator mode (disabled/direct/patch)
  * @notifier: V4L2 asynchronous subdevs notifier
+ *
+ * @hflip: Horizontal flip is enabled
+ * @vflip: Vertical flip is enabled
  */
 struct tegra_vi_channel {
struct list_head list;
@@ -218,6 +223,9 @@ struct tegra_vi_channel {
enum tegra_vi_pg_mode pg_mode;
 
struct v4l2_async_notifier notifier;
+
+   bool hflip:1;
+   bool vflip:1;
 };
 
 /**
-- 
2.34.1



[PATCH v4 21/21] staging: media: tegra-video: add support for Tegra20 parallel input

2023-01-30 Thread Luca Ceresoli
The VI peripheral of Tegra supports capturing from MIPI CSI-2 or parallel
video (called VIP in the docs).

The staging tegra-video driver currently implements MIPI CSI-2 video
capture for Tegra210. Add support for parallel video capture (VIP) on
Tegra20. With the generalizations added to the VI driver in previous
commits, this is only a matter of adding the vip.c and tegra20.c
implementations and registering them.

Unfortunately there was no documentation available for the VI or VIP
peripherals of Tegra20 (or any other Tegra chips). This implementation has
been based entirely on the code from a vendor kernel based on Linux 3.1 and
massively adapted to fit into the tegra-video driver. Parts of this code is
definitely non-optimal to say the least (especially tegra20_vi_enable() and
the single-frame capture logic), but it was impossible to improve it.

Signed-off-by: Luca Ceresoli 
Reviewed-by: Dmitry Osipenko 

---

Changed in v4:
 - Added review tags

Changed in v3 (suggested by Dmitry Osipenko):
 - merged the VIP patch and the Tegra20 patch to avoid chicken-egg problem
   due to the two modules depending on each other at build time
 - move tegra20_vip_soc to vip.c
 - remove channel@0 node from device tree parsing
 - remove unused variable

Changed in v2:
 - fix tegra20_vi_enable() to clear bit when on==false
 - clamp width/height from set/try_fmt to avoid returning sizeimage=0
   (fixes v4l2-compliance)
---
 drivers/staging/media/tegra-video/Makefile  |   2 +
 drivers/staging/media/tegra-video/tegra20.c | 661 
 drivers/staging/media/tegra-video/vi.c  |   3 +
 drivers/staging/media/tegra-video/vi.h  |   3 +
 drivers/staging/media/tegra-video/video.c   |   5 +
 drivers/staging/media/tegra-video/video.h   |   1 +
 drivers/staging/media/tegra-video/vip.c | 290 +
 drivers/staging/media/tegra-video/vip.h |  68 ++
 8 files changed, 1033 insertions(+)
 create mode 100644 drivers/staging/media/tegra-video/tegra20.c
 create mode 100644 drivers/staging/media/tegra-video/vip.c
 create mode 100644 drivers/staging/media/tegra-video/vip.h

diff --git a/drivers/staging/media/tegra-video/Makefile 
b/drivers/staging/media/tegra-video/Makefile
index dfa2ef8f99ef..6c7552e05109 100644
--- a/drivers/staging/media/tegra-video/Makefile
+++ b/drivers/staging/media/tegra-video/Makefile
@@ -2,7 +2,9 @@
 tegra-video-objs := \
video.o \
vi.o \
+   vip.o \
csi.o
 
+tegra-video-$(CONFIG_ARCH_TEGRA_2x_SOC)  += tegra20.o
 tegra-video-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210.o
 obj-$(CONFIG_VIDEO_TEGRA) += tegra-video.o
diff --git a/drivers/staging/media/tegra-video/tegra20.c 
b/drivers/staging/media/tegra-video/tegra20.c
new file mode 100644
index ..ac048bbd58f0
--- /dev/null
+++ b/drivers/staging/media/tegra-video/tegra20.c
@@ -0,0 +1,661 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Tegra20-specific VI implementation
+ *
+ * Copyright (C) 2022 SKIDATA GmbH
+ * Author: Luca Ceresoli 
+ */
+
+/*
+ * This source file contains Tegra20 supported video formats,
+ * VI and VIP SoC specific data, operations and registers accessors.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "vip.h"
+#include "vi.h"
+
+#define TEGRA_VI_SYNCPT_WAIT_TIMEOUT   msecs_to_jiffies(200)
+
+/* This are just good-sense numbers. The actual min/max is not documented. */
+#define TEGRA20_MIN_WIDTH  32U
+#define TEGRA20_MIN_HEIGHT 32U
+#define TEGRA20_MAX_WIDTH  2048U
+#define TEGRA20_MAX_HEIGHT 2048U
+
+/* --
+ * Registers
+ */
+
+#define TEGRA_VI_CONT_SYNCPT_OUT_1 0x0060
+#define   VI_CONT_SYNCPT_OUT_1_CONTINUOUS_SYNCPT   BIT(8)
+#define   VI_CONT_SYNCPT_OUT_1_SYNCPT_IDX_SFT  0
+
+#define TEGRA_VI_VI_INPUT_CONTROL  0x0088
+#define   VI_INPUT_FIELD_DETECTBIT(27)
+#define   VI_INPUT_BT656   BIT(25)
+#define   VI_INPUT_YUV_INPUT_FORMAT_SFT8  /* bits [9:8] */
+#define   VI_INPUT_YUV_INPUT_FORMAT_UYVY   (0 << 
VI_INPUT_YUV_INPUT_FORMAT_SFT)
+#define   VI_INPUT_YUV_INPUT_FORMAT_VYUY   (1 << 
VI_INPUT_YUV_INPUT_FORMAT_SFT)
+#define   VI_INPUT_YUV_INPUT_FORMAT_YUYV   (2 << 
VI_INPUT_YUV_INPUT_FORMAT_SFT)
+#define   VI_INPUT_YUV_INPUT_FORMAT_YVYU   (3 << 
VI_INPUT_YUV_INPUT_FORMAT_SFT)
+#define   VI_INPUT_INPUT_FORMAT_SFT2  /* bits 
[5:2] */
+#define   VI_INPUT_INPUT_FORMAT_YUV422 (0 << 
VI_INPUT_INPUT_FORMAT_SFT)
+#define   VI_INPUT_VIP_INPUT_ENABLEBIT(1)
+
+#define TEGRA_VI_VI_CORE_CONTROL   0x008c
+#define   VI_VI_CORE_CONTROL_PLANAR_CONV_IN_SEL_EXTBIT(31)
+#define   VI_VI_CORE_CONTROL_CSC_INPUT_SEL_EXT BIT(30)
+#define   

[PATCH v4 15/21] staging: media: tegra-video: move MIPI calibration calls from VI to CSI

2023-01-30 Thread Luca Ceresoli
The CSI module does not handle all the MIPI lane calibration procedure,
leaving a small part of it to the VI module. In doing this,
tegra_channel_enable_stream() (vi.c) manipulates the private data of the
upstream subdev casting it to struct 'tegra_csi_channel', which will be
wrong after introducing a VIP (parallel video input) channel.

This prevents adding support for the VIP module.  It also breaks the
logical isolation between modules.

Since the lane calibration requirement does not exist in the parallel input
module, moving the calibration function to a per-module op is not
optimal. Instead move the calibration procedure in the CSI module, together
with the rest of the calibration procedures. After this change,
tegra_channel_enable_stream() just calls v4l2_subdev_call() to ask for a
stream start/stop to the CSI module, which in turn knows all the
CSI-specific details to implement it.

Signed-off-by: Luca Ceresoli 
Reviewed-by: Dmitry Osipenko 

---

Changed in v4:
 - Added review tags

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/csi.c | 44 
 drivers/staging/media/tegra-video/vi.c  | 54 ++---
 2 files changed, 48 insertions(+), 50 deletions(-)

diff --git a/drivers/staging/media/tegra-video/csi.c 
b/drivers/staging/media/tegra-video/csi.c
index 9a03d5ccdf3c..b93fc879ef3a 100644
--- a/drivers/staging/media/tegra-video/csi.c
+++ b/drivers/staging/media/tegra-video/csi.c
@@ -328,12 +328,42 @@ static int tegra_csi_enable_stream(struct v4l2_subdev 
*subdev)
}
 
csi_chan->pg_mode = chan->pg_mode;
+
+   /*
+* Tegra CSI receiver can detect the first LP to HS transition.
+* So, start the CSI stream-on prior to sensor stream-on and
+* vice-versa for stream-off.
+*/
ret = csi->ops->csi_start_streaming(csi_chan);
if (ret < 0)
goto finish_calibration;
 
+   if (csi_chan->mipi) {
+   struct v4l2_subdev *src_subdev;
+   /*
+* TRM has incorrectly documented to wait for done status from
+* calibration logic after CSI interface power on.
+* As per the design, calibration results are latched and 
applied
+* to the pads only when the link is in LP11 state which will 
happen
+* during the sensor stream-on.
+* CSI subdev stream-on triggers start of MIPI pads calibration.
+* Wait for calibration to finish here after sensor subdev 
stream-on.
+*/
+   src_subdev = tegra_channel_get_remote_source_subdev(chan);
+   ret = v4l2_subdev_call(src_subdev, video, s_stream, true);
+   err = tegra_mipi_finish_calibration(csi_chan->mipi);
+
+   if (ret < 0 && ret != -ENOIOCTLCMD)
+   goto disable_csi_stream;
+
+   if (err < 0)
+   dev_warn(csi->dev, "MIPI calibration failed: %d\n", 
err);
+   }
+
return 0;
 
+disable_csi_stream:
+   csi->ops->csi_stop_streaming(csi_chan);
 finish_calibration:
if (csi_chan->mipi)
tegra_mipi_finish_calibration(csi_chan->mipi);
@@ -352,10 +382,24 @@ static int tegra_csi_enable_stream(struct v4l2_subdev 
*subdev)
 
 static int tegra_csi_disable_stream(struct v4l2_subdev *subdev)
 {
+   struct tegra_vi_channel *chan = v4l2_get_subdev_hostdata(subdev);
struct tegra_csi_channel *csi_chan = to_csi_chan(subdev);
struct tegra_csi *csi = csi_chan->csi;
int err;
 
+   /*
+* Stream-off subdevices in reverse order to stream-on.
+* Remote source subdev in TPG mode is same as CSI subdev.
+*/
+   if (csi_chan->mipi) {
+   struct v4l2_subdev *src_subdev;
+
+   src_subdev = tegra_channel_get_remote_source_subdev(chan);
+   err = v4l2_subdev_call(src_subdev, video, s_stream, false);
+   if (err < 0 && err != -ENOIOCTLCMD)
+   dev_err_probe(csi->dev, err, "source subdev stream off 
failed\n");
+   }
+
csi->ops->csi_stop_streaming(csi_chan);
 
if (csi_chan->mipi) {
diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 3762fd273514..a26eb1ca869f 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -187,49 +187,15 @@ tegra_channel_get_remote_source_subdev(struct 
tegra_vi_channel *chan)
 
 static int tegra_channel_enable_stream(struct tegra_vi_channel *chan)
 {
-   struct v4l2_subdev *csi_subdev, *src_subdev;
-   struct tegra_csi_channel *csi_chan;
-   int ret, err;
+   struct v4l2_subdev *subdev;
+   int ret;
 
-   /*
-* Tegra CSI receiver can detect the first LP to HS transition.
-* So, start the CSI stream-on prior to sensor stream-on and
-* vice-versa for stream-off.
-*/
-   csi_subdev = 

[PATCH v4 16/21] staging: media: tegra-video: add a per-soc enable/disable op

2023-01-30 Thread Luca Ceresoli
The Tegra20 VI needs an additional operation to enable the VI, add an
operation for that.

Signed-off-by: Luca Ceresoli 
Reviewed-by: Dmitry Osipenko 

---

Changed in v4:
 - Added review tags

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/vi.c | 7 +++
 drivers/staging/media/tegra-video/vi.h | 4 
 2 files changed, 11 insertions(+)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index a26eb1ca869f..22f6d6478d3e 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -1853,6 +1853,9 @@ static int tegra_vi_probe(struct platform_device *pdev)
vi->client.ops = _client_ops;
vi->client.dev = >dev;
 
+   if (vi->ops->vi_enable)
+   vi->ops->vi_enable(vi, true);
+
ret = host1x_client_register(>client);
if (ret < 0) {
dev_err(>dev,
@@ -1863,6 +1866,8 @@ static int tegra_vi_probe(struct platform_device *pdev)
return 0;
 
 rpm_disable:
+   if (vi->ops->vi_enable)
+   vi->ops->vi_enable(vi, false);
pm_runtime_disable(>dev);
return ret;
 }
@@ -1879,6 +1884,8 @@ static int tegra_vi_remove(struct platform_device *pdev)
return err;
}
 
+   if (vi->ops->vi_enable)
+   vi->ops->vi_enable(vi, false);
pm_runtime_disable(>dev);
 
return 0;
diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index 879547073371..851c4f3fcb91 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -37,8 +37,11 @@ enum tegra_vi_pg_mode {
TEGRA_VI_PG_PATCH,
 };
 
+struct tegra_vi;
+
 /**
  * struct tegra_vi_ops - Tegra VI operations
+ * @vi_enable: soc-specific operations needed to enable/disable the VI 
peripheral
  * @vi_fmt_align: modify `pix` to fit the hardware alignment
  * requirements and fill image geometry
  * @vi_start_streaming: starts media pipeline, subdevice streaming, sets up
@@ -48,6 +51,7 @@ enum tegra_vi_pg_mode {
  * back any queued buffers.
  */
 struct tegra_vi_ops {
+   int (*vi_enable)(struct tegra_vi *vi, bool on);
void (*vi_fmt_align)(struct v4l2_pix_format *pix, unsigned int bpp);
int (*vi_start_streaming)(struct vb2_queue *vq, u32 count);
void (*vi_stop_streaming)(struct vb2_queue *vq);
-- 
2.34.1



[PATCH v4 14/21] staging: media: tegra-video: move default format to soc-specific data

2023-01-30 Thread Luca Ceresoli
The tegra_default_format in vi.c is specific to Tegra210 CSI.

In preparation for adding Tegra20 VIP support, move the default format to a
new field in the soc-specific `struct tegra_vi_soc`. Instead of an entire
format struct, only store a pointer to an item in the existing format
array.

No functional changes. The format pointed to is the same that used to be in
vi.c.

Signed-off-by: Luca Ceresoli 
Reviewed-by: Dmitry Osipenko 

---

Changed in v4:
 - Added review tags

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/tegra210.c |  2 ++
 drivers/staging/media/tegra-video/vi.c   | 11 +--
 drivers/staging/media/tegra-video/vi.h   |  2 ++
 3 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/media/tegra-video/tegra210.c 
b/drivers/staging/media/tegra-video/tegra210.c
index 71483d0c19bf..28d3d05c12c4 100644
--- a/drivers/staging/media/tegra-video/tegra210.c
+++ b/drivers/staging/media/tegra-video/tegra210.c
@@ -771,8 +771,10 @@ const struct tegra_vi_soc tegra210_vi_soc = {
.hw_revision = 3,
.vi_max_channels = 6,
 #if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
+   .default_video_format = _video_formats[0],
.vi_max_clk_hz = 49920,
 #else
+   .default_video_format = _video_formats[4],
.vi_max_clk_hz = 99840,
 #endif
 };
diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index a76cad0e3026..3762fd273514 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -44,15 +44,6 @@ struct tegra_vi_graph_entity {
struct v4l2_subdev *subdev;
 };
 
-static const struct tegra_video_format tegra_default_format = {
-   .img_dt = TEGRA_IMAGE_DT_RAW10,
-   .bit_width = 10,
-   .code = MEDIA_BUS_FMT_SRGGB10_1X10,
-   .bpp = 2,
-   .img_fmt = TEGRA_IMAGE_FORMAT_DEF,
-   .fourcc = V4L2_PIX_FMT_SRGGB10,
-};
-
 static inline struct tegra_vi *
 host1x_client_to_vi(struct host1x_client *client)
 {
@@ -,7 +1102,7 @@ static int tegra_channel_init(struct tegra_vi_channel 
*chan)
init_waitqueue_head(>done_wait);
 
/* initialize the video format */
-   chan->fmtinfo = _default_format;
+   chan->fmtinfo = chan->vi->soc->default_video_format;
chan->format.pixelformat = chan->fmtinfo->fourcc;
chan->format.colorspace = V4L2_COLORSPACE_SRGB;
chan->format.field = V4L2_FIELD_NONE;
diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index 1021c730b595..879547073371 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -58,6 +58,7 @@ struct tegra_vi_ops {
  *
  * @video_formats: supported video formats
  * @nformats: total video formats
+ * @default_video_format: default video format (pointer to a @video_formats 
item)
  * @ops: vi operations
  * @hw_revision: VI hw_revision
  * @vi_max_channels: supported max streaming channels
@@ -66,6 +67,7 @@ struct tegra_vi_ops {
 struct tegra_vi_soc {
const struct tegra_video_format *video_formats;
const unsigned int nformats;
+   const struct tegra_video_format *default_video_format;
const struct tegra_vi_ops *ops;
u32 hw_revision;
unsigned int vi_max_channels;
-- 
2.34.1



[PATCH v4 13/21] staging: media: tegra-video: move tegra_channel_fmt_align to a per-soc op

2023-01-30 Thread Luca Ceresoli
tegra_channel_fmt_align() takes care of the size constraints, alignment and
rounding requirements of the Tegra210 VI peripheral. Tegra20 has different
constraints.

In preparation for adding Tegra20 support, move this function to a new op
in the soc-specific `struct tegra_vi_ops` .

Also move to tegra210.c the T210-specific defines used in the moved code.

No functional changes.

Signed-off-by: Luca Ceresoli 
Reviewed-by: Dmitry Osipenko 

---

Changed in v4:
 - Added review tags

No changes in v3
No changes in v2
---
 drivers/staging/media/tegra-video/tegra210.c | 36 ++
 drivers/staging/media/tegra-video/vi.c   | 40 +++-
 drivers/staging/media/tegra-video/vi.h   |  9 ++---
 3 files changed, 44 insertions(+), 41 deletions(-)

diff --git a/drivers/staging/media/tegra-video/tegra210.c 
b/drivers/staging/media/tegra-video/tegra210.c
index eb19dd5107ce..71483d0c19bf 100644
--- a/drivers/staging/media/tegra-video/tegra210.c
+++ b/drivers/staging/media/tegra-video/tegra210.c
@@ -17,6 +17,13 @@
 #include "csi.h"
 #include "vi.h"
 
+#define TEGRA210_MIN_WIDTH 32U
+#define TEGRA210_MAX_WIDTH 32768U
+#define TEGRA210_MIN_HEIGHT32U
+#define TEGRA210_MAX_HEIGHT32768U
+
+#define SURFACE_ALIGN_BYTES64
+
 #define TEGRA_VI_SYNCPT_WAIT_TIMEOUT   msecs_to_jiffies(200)
 
 /* Tegra210 VI registers */
@@ -172,6 +179,34 @@ static u32 vi_csi_read(struct tegra_vi_channel *chan, u8 
portno,
 /*
  * Tegra210 VI channel capture operations
  */
+static void tegra210_fmt_align(struct v4l2_pix_format *pix, unsigned int bpp)
+{
+   unsigned int min_bpl;
+   unsigned int max_bpl;
+   unsigned int bpl;
+
+   /*
+* The transfer alignment requirements are expressed in bytes.
+* Clamp the requested width and height to the limits.
+*/
+   pix->width = clamp(pix->width, TEGRA210_MIN_WIDTH, TEGRA210_MAX_WIDTH);
+   pix->height = clamp(pix->height, TEGRA210_MIN_HEIGHT, 
TEGRA210_MAX_HEIGHT);
+
+   /* Clamp the requested bytes per line value. If the maximum bytes per
+* line value is zero, the module doesn't support user configurable
+* line sizes. Override the requested value with the minimum in that
+* case.
+*/
+   min_bpl = pix->width * bpp;
+   max_bpl = rounddown(TEGRA210_MAX_WIDTH, SURFACE_ALIGN_BYTES);
+   bpl = roundup(pix->bytesperline, SURFACE_ALIGN_BYTES);
+
+   pix->bytesperline = clamp(bpl, min_bpl, max_bpl);
+   pix->sizeimage = pix->bytesperline * pix->height;
+   if (pix->pixelformat == V4L2_PIX_FMT_NV16)
+   pix->sizeimage *= 2;
+}
+
 static int tegra_channel_capture_setup(struct tegra_vi_channel *chan,
   u8 portno)
 {
@@ -723,6 +758,7 @@ static const struct tegra_video_format 
tegra210_video_formats[] = {
 
 /* Tegra210 VI operations */
 static const struct tegra_vi_ops tegra210_vi_ops = {
+   .vi_fmt_align = tegra210_fmt_align,
.vi_start_streaming = tegra210_vi_start_streaming,
.vi_stop_streaming = tegra210_vi_stop_streaming,
 };
diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 4e48eaa0fbdc..a76cad0e3026 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -456,36 +456,6 @@ static int tegra_channel_get_format(struct file *file, 
void *fh,
return 0;
 }
 
-static void tegra_channel_fmt_align(struct tegra_vi_channel *chan,
-   struct v4l2_pix_format *pix,
-   unsigned int bpp)
-{
-   unsigned int min_bpl;
-   unsigned int max_bpl;
-   unsigned int bpl;
-
-   /*
-* The transfer alignment requirements are expressed in bytes.
-* Clamp the requested width and height to the limits.
-*/
-   pix->width = clamp(pix->width, TEGRA_MIN_WIDTH, TEGRA_MAX_WIDTH);
-   pix->height = clamp(pix->height, TEGRA_MIN_HEIGHT, TEGRA_MAX_HEIGHT);
-
-   /* Clamp the requested bytes per line value. If the maximum bytes per
-* line value is zero, the module doesn't support user configurable
-* line sizes. Override the requested value with the minimum in that
-* case.
-*/
-   min_bpl = pix->width * bpp;
-   max_bpl = rounddown(TEGRA_MAX_WIDTH, SURFACE_ALIGN_BYTES);
-   bpl = roundup(pix->bytesperline, SURFACE_ALIGN_BYTES);
-
-   pix->bytesperline = clamp(bpl, min_bpl, max_bpl);
-   pix->sizeimage = pix->bytesperline * pix->height;
-   if (pix->pixelformat == V4L2_PIX_FMT_NV16)
-   pix->sizeimage *= 2;
-}
-
 static int __tegra_channel_try_format(struct tegra_vi_channel *chan,
  struct v4l2_pix_format *pix)
 {
@@ -561,7 +531,7 @@ static int __tegra_channel_try_format(struct 
tegra_vi_channel *chan,
return ret;
 
v4l2_fill_pix_format(pix, );
-   

  1   2   >