Re: [PATCH] omap: dsi: do not WARN on detach if dsidev was never attached

2023-09-19 Thread Tony Lindgren
* H. Nikolaus Schaller  [230919 13:38]:
> dsi_init_output() called by dsi_probe() may fail. In that
> case mipi_dsi_host_unregister() is called which may call
> omap_dsi_host_detach() with uninitialized dsi->dsidev
> because omap_dsi_host_attach() was never called before.
> 
> This happens if the panel driver asks for an EPROBE_DEFER.
> 
> So let's suppress the WARN() in this special case.

Reviewed-by: Tony Lindgren 

Thanks,

Tony


Re: [PATCH drm-misc-next v3 6/7] drm/gpuvm: generalize dma_resv/extobj handling and GEM validation

2023-09-19 Thread Christian König

Am 19.09.23 um 17:23 schrieb Thomas Hellström:


On 9/19/23 17:16, Danilo Krummrich wrote:

On 9/19/23 14:21, Thomas Hellström wrote:

Hi Christian

On 9/19/23 14:07, Christian König wrote:

Am 13.09.23 um 17:46 schrieb Danilo Krummrich:

On 9/13/23 17:33, Christian König wrote:

Am 13.09.23 um 17:15 schrieb Danilo Krummrich:

On 9/13/23 16:26, Christian König wrote:

Am 13.09.23 um 14:16 schrieb Danilo Krummrich:
As mentioned in a different mail thread, the reply is based on 
the assumption
that we don't support anything else than GPUVM updates from 
the IOCTL.


I think that this assumption is incorrect.


Well, more precisely I should have said "don't support GPUVM 
updated from within
fence signaling critical sections". And looking at the code, 
that doesn't seem what

you're doing there.



Vulkan is just once specific use case, but this here should 
probably be able to handle other use cases as well.


Especially with HMM you get the requirement that you need to be 
able to invalidate GPUVM mappings without grabbing a 
reservation lock.


What do you mean with "invalidate GPUVM mappings" in this 
context? drm_gpuvm_bo_evict()
should only be called from a ttm_device_funcs::move callback, 
we should hold the dma-resv

lock there.


Well the question is which dma-resv lock do we hold?

In the move callback we only hold the dma-resv lock of the BO 
which is moved, but when that is a shared BO then that's not the 
same as the one for the VM.


Correct, Thomas' idea was to use the GEM's dma_resv lock to 
protect drm_gpuvm_bo::evicted
and then actually move the drm_gpuvm_bo to the VM's evicted list 
once we grabbed all
dma-resv locks when locking the VM's BOs using drm_exec. We can 
remove them from the evicted
list on validate(). This way we never touch the evicted list 
without holding at least the VM's

dma-resv lock.

Do you have any concerns about that?


Scratching my head a bit how that is supposed to work.

This implies that you go over all the evicted BOs during validation 
and not just the one mentioned in the CS.


That might work for Vulkan, but is pretty much a no-go for OpenGL.









See what the eviction lock in amdgpu is doing for example.


The eviction_lock seems to protect a VM state "evicting" of 
whether any BO that
is associated with the VM is currently evicting. At the same 
time amdgpu protects
the eviceted list of the VM with a different lock. So this seems 
to be entirely
unrelated. Tracking a "currently evicting" state is not part of 
the GPUVM
implementation currently and hence nothing would change for 
amdgpu there.


Sorry for the confusion we use different terminology in amdgpu.

The eviction lock and evicted state is for the VM page tables, 
e.g. if the whole VM is currently not used and swapped out or 
even de-allocated.


This is necessary because we have cases where we need to access 
the VM data without holding the dma-resv lock of this VM. 
Especially figuring out which parts of an address space contain 
mappings and which doesn't.


I think this is fine, this has nothing to do with lists of evicted 
GEM objects or external GEM
objects, right? Marking mappings (drm_gpuva) as invalidated 
(DRM_GPUVA_INVALIDATED) or accessing

the VA space does not require any dma-resv locks.


I hope so, but I'm not 100% sure.





This is a requirement which comes with HMM handling, you won't 
see this with Vulkan (or OpenGL, VAAPI etc..).



The invalidation lock on the other hand is what in this 
discussion is called eviction lock. This one is needed because 
what I wrote above, during the move callback only the dma-resv of 
the BO which is moved is locked, but not necessarily the dma-resv 
of the VM.


That's yet another thing, right? This is used to track whether 
*any* BO that belongs to the VM is
currently being evicted, correct? As mentioned, as by now this is 
not supported in GPUVM and hence
would be the same driver specific code with the same driver 
specifc lock.


That is most likely a show stopper using this for OpenGL based 
workloads as far as I can see. For those you need to able to figure 
out which non-VM BOs have been evicted and which parts of the VM 
needs updates.


We identify those with a bool in the gpuvm_bo, and that bool is 
protected by the bo_resv. In essence, the "evicted" list must be 
made up-to-date with all relevant locks held before traversing in 
the next exec.


What I still miss with this idea is how do we find all the 
drm_gpuvm_bo structures with the evicted bool set to true? When doing 
the drm_exec dance we come across all external ones and can add them 
to the list if needed, but what about the BOs having the VM's dma-resv?


Oh, they can be added to the evict list directly (no bool needed) in 
the eviction code, like in v3. Since for those we indeed hold the VM's 
dma_resv since it's aliased with the object's dma-resv.


Yeah, I wanted to note what Danilo seems to think about as well. How do 
we figure out the non-VM BOs evicted?


We 

Re: [PATCH 00/10] Add mediate-drm secure flow for SVP

2023-09-19 Thread 胡俊光


[PATCH] drm/i915/perf: Remove gtt_offset from stream->oa_buffer.head/.tail

2023-09-19 Thread Ashutosh Dixit
There is no reason to add gtt_offset to the cached head/tail pointers
stream->oa_buffer.head and stream->oa_buffer.tail. This causes the code to
constantly add gtt_offset and subtract gtt_offset and is error
prone.

It is much simpler to maintain stream->oa_buffer.head and
stream->oa_buffer.tail without adding gtt_offset to them and just allow for
the gtt_offset when reading/writing from/to HW registers.

v2: Minor tweak to commit message due to dropping patch in previous series

Signed-off-by: Ashutosh Dixit 
Reviewed-by: Umesh Nerlige Ramappa 
---
 drivers/gpu/drm/i915/i915_perf.c | 52 
 1 file changed, 13 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 018f42fff4cc0..1347e4ec9dd5a 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -543,10 +543,9 @@ static bool oa_buffer_check_unlocked(struct 
i915_perf_stream *stream)
 {
u32 gtt_offset = i915_ggtt_offset(stream->oa_buffer.vma);
int report_size = stream->oa_buffer.format->size;
-   u32 head, tail, read_tail;
+   u32 tail, hw_tail;
unsigned long flags;
bool pollin;
-   u32 hw_tail;
u32 partial_report_size;
 
/* We have to consider the (unlikely) possibility that read() errors
@@ -556,6 +555,7 @@ static bool oa_buffer_check_unlocked(struct 
i915_perf_stream *stream)
spin_lock_irqsave(>oa_buffer.ptr_lock, flags);
 
hw_tail = stream->perf->ops.oa_hw_tail_read(stream);
+   hw_tail -= gtt_offset;
 
/* The tail pointer increases in 64 byte increments, not in report_size
 * steps. Also the report size may not be a power of 2. Compute
@@ -567,13 +567,6 @@ static bool oa_buffer_check_unlocked(struct 
i915_perf_stream *stream)
/* Subtract partial amount off the tail */
hw_tail = OA_TAKEN(hw_tail, partial_report_size);
 
-   /* NB: The head we observe here might effectively be a little
-* out of date. If a read() is in progress, the head could be
-* anywhere between this head and stream->oa_buffer.tail.
-*/
-   head = stream->oa_buffer.head - gtt_offset;
-   read_tail = stream->oa_buffer.tail - gtt_offset;
-
tail = hw_tail;
 
/* Walk the stream backward until we find a report with report
@@ -587,7 +580,7 @@ static bool oa_buffer_check_unlocked(struct 
i915_perf_stream *stream)
 * memory in the order they were written to.
 * If not : (╯°□°)╯︵ ┻━┻
 */
-   while (OA_TAKEN(tail, read_tail) >= report_size) {
+   while (OA_TAKEN(tail, stream->oa_buffer.tail) >= report_size) {
void *report = stream->oa_buffer.vaddr + tail;
 
if (oa_report_id(stream, report) ||
@@ -601,9 +594,9 @@ static bool oa_buffer_check_unlocked(struct 
i915_perf_stream *stream)
__ratelimit(>perf->tail_pointer_race))
drm_notice(>uncore->i915->drm,
   "unlanded report(s) head=0x%x tail=0x%x 
hw_tail=0x%x\n",
-head, tail, hw_tail);
+stream->oa_buffer.head, tail, hw_tail);
 
-   stream->oa_buffer.tail = gtt_offset + tail;
+   stream->oa_buffer.tail = tail;
 
pollin = OA_TAKEN(stream->oa_buffer.tail,
  stream->oa_buffer.head) >= report_size;
@@ -753,13 +746,6 @@ static int gen8_append_oa_reports(struct i915_perf_stream 
*stream,
 
spin_unlock_irqrestore(>oa_buffer.ptr_lock, flags);
 
-   /*
-* NB: oa_buffer.head/tail include the gtt_offset which we don't want
-* while indexing relative to oa_buf_base.
-*/
-   head -= gtt_offset;
-   tail -= gtt_offset;
-
/*
 * An out of bounds or misaligned head or tail pointer implies a driver
 * bug since we validate + align the tail pointers we read from the
@@ -895,9 +881,8 @@ static int gen8_append_oa_reports(struct i915_perf_stream 
*stream,
 * We removed the gtt_offset for the copy loop above, indexing
 * relative to oa_buf_base so put back here...
 */
-   head += gtt_offset;
intel_uncore_write(uncore, oaheadptr,
-  head & GEN12_OAG_OAHEADPTR_MASK);
+  (head + gtt_offset) & 
GEN12_OAG_OAHEADPTR_MASK);
stream->oa_buffer.head = head;
 
spin_unlock_irqrestore(>oa_buffer.ptr_lock, flags);
@@ -1042,12 +1027,6 @@ static int gen7_append_oa_reports(struct 
i915_perf_stream *stream,
 
spin_unlock_irqrestore(>oa_buffer.ptr_lock, flags);
 
-   /* NB: oa_buffer.head/tail include the gtt_offset which we don't want
-* while indexing relative to oa_buf_base.
-*/
-   head -= gtt_offset;
-   tail -= gtt_offset;
-
/* An out of bounds or misaligned head or tail pointer implies a driver
 * bug since we validate + 

Re: Decrypting tt maps in ttm

2023-09-19 Thread Zack Rusin
On Tue, 2023-09-19 at 09:47 +0200, Christian König wrote:
> !! External Email
>
> Am 19.09.23 um 08:56 schrieb Thomas Hellström:
> >
> > On 9/19/23 07:39, Christian König wrote:
> > > Am 19.09.23 um 03:26 schrieb Zack Rusin:
> > > > On Mon, 2023-09-18 at 16:21 -0400, Alex Deucher wrote:
> > > > > !! External Email
> > > > >
> > > > > On Mon, Sep 18, 2023 at 3:06 PM Thomas Hellström
> > > > >  wrote:
> > > > > >
> > > > > > On 9/18/23 17:52, Zack Rusin wrote:
> > > > > > > On Mon, 2023-09-18 at 17:13 +0200, Thomas Hellström wrote:
> > > > > > > > Hi,
> > > > > > > >
> > > > > > > > On 9/18/23 16:56, Thomas Hellström wrote:
> > > > > > > > > Hi Zack, Christian
> > > > > > > > >
> > > > > > > > > On 9/18/23 13:36, Christian König wrote:
> > > > > > > > > > Hi Zack,
> > > > > > > > > >
> > > > > > > > > > adding Thomas and Daniel.
> > > > > > > > > >
> > > > > > > > > > I briefly remember that I talked with Thomas and some other
> > > > > > > > > > people
> > > > > > > > > > about that quite a while ago as well, but I don't fully
> > > > > > > > > > remember the
> > > > > > > > > > outcome.
> > > > > > > > > Found one old thread, but didn't read it:
> > > > > > > > >
> > > > > > > > > https://lists.freedesktop.org/archives/dri-devel/2019-September/234100.html
> > > > > > > > >
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > /Thomas
> > > > > > > > >
> > > > > > > > >
> > > > > > > > Ugh. Now starting to read that thread I have a vague
> > > > > > > > recollection it all
> > > > > > > > ended with not supporting mapping any device pages whatsoever
> > > > > > > > when SEV
> > > > > > > > was enabled, but rather resorting to llvmpipe and VM-local bos.
> > > > > > > Hi, Thomas.
> > > > > > >
> > > > > > > Thanks for finding this! I'd (of course) like to solve it
> > > > > > > properly and get
> > > > > > > vmwgfx
> > > > > > > running with 3d support with SEV-ES active instead of essentially
> > > > > > > disabling
> > > > > > > the
> > > > > > > driver when SEV-ES is active.
> > > > > > >
> > > > > > > I think there are two separate discussions there, the
> > > > > > > non-controversial one
> > > > > > > and the
> > > > > > > controversial one:
> > > > > > > 1) The non-controversial: is there a case where drivers would
> > > > > > > want encrypted
> > > > > > > memory
> > > > > > > for TT pages but not for io mem mappings? Because if not then as
> > > > > > > Christian
> > > > > > > pointed
> > > > > > > out we could just add pgprot_decrypted to ttm_io_prot and be
> > > > > > > essentially done.
> > > > > > > The
> > > > > > > current method of decrypting io mem but leaving sys mem mappings
> > > > > > > encrypted is
> > > > > > > a bit
> > > > > > > weird anyway.
> > > > > > >
> > > > > > > If the answer to that question is "yes, some driver does want the
> > > > > > > TT mappings
> > > > > > > to be
> > > > > > > encrypted" then your "[PATCH v2 3/4] drm/ttm, drm/vmwgfx:
> > > > > > > Correctly support
> > > > > > > support
> > > > > > > AMD memory encryption" solves that. I think getting one of those
> > > > > > > two in makes
> > > > > > > sense
> > > > > > > regardless of everything else, agreed?
> > > > > > Well, there is more to it I think.
> > > > > >
> > > > > > IIRC, the AMD SME encryption mode has a way for a device to have the
> > > > > > memory controller (?) encrypt / decrypt device traffic by using an
> > > > > > address range alias, so in theory it supports encrypted TT pages, 
> > > > > > and
> > > > > > the dma-layer may indeed hand encrypted DMA pages to TTM on such
> > > > > > systems
> > > > > > depending on the device's DMA mask. That's why I think that
> > > > > > force_dma_unencrypted() export was needed, and If the amdgpu driver
> > > > > > accesses TT memory in SME mode *without* pgprot_decrypted() and it
> > > > > > still
> > > > > > works, then I think that mode is actually used. How could it
> > > > > > otherwise work?
> > > > > For SME, as long as the encrypted bit is set in the physical address
> > > > > used for DMA, the memory controller will handle the encrypt/decrypt
> > > > > for the device.  For devices with a limited dma mask, you need to use
> > > > > the IOMMU so that the encrypted bit is retained when the address hits
> > > > > the memory controller.
> > > > How does that work on systems with swiotlb, e.g. swiotlb=force, or
> > > > i.e. what would
> > > > decrypt the ttm tt mappings when copying between system and vram
> > > > when iommu is
> > > > disabled/absent?
> > >
> > > SME makes it mandatory that all devices can handle the physical
> > > address used for DMA, either native or with the help of IOMMU.
> > >
> > > Hacks like SWIOTLB are not directly supported as far as I know. Maybe
> > > somehow SWIOTLB manually decrypts the data while copying it or
> > > something like this, but I'm not 100% sure if that is actually
> > > implemented.
> > >
> > > Regards,
> > > Christian.
> >
> > A bold guess after looking at various code and patches:
> >
> > 1) Devices under 

Re: [PATCH 00/15] Add CMDQ secure driver for SVP

2023-09-19 Thread 胡俊光


Re: [PATCH 0/5] Add the pci_get_base_class() helper and use it

2023-09-19 Thread suijingfeng

Hi,


On 2023/8/25 21:18, Deucher, Alexander wrote:

[Public]


-Original Message-
From: amd-gfx  On Behalf Of Sui
Jingfeng
Sent: Friday, August 25, 2023 2:27 AM
To: Bjorn Helgaas 
Cc: alsa-de...@alsa-project.org; Sui Jingfeng ;
nouv...@lists.freedesktop.org; linux-ker...@vger.kernel.org; dri-
de...@lists.freedesktop.org; amd-...@lists.freedesktop.org; linux-
p...@vger.kernel.org
Subject: [PATCH 0/5] Add the pci_get_base_class() helper and use it

From: Sui Jingfeng 

There is no function that can be used to get all PCI(e) devices in a system by
matching against its the PCI base class code only, while keep the sub-class code
and the programming interface ignored. Therefore, add the
pci_get_base_class() function to suit the need.

For example, if an application want to process all PCI(e) display devices in a
system, it can achieve such goal by writing the code as following:

 pdev = NULL;
 do {
 pdev = pci_get_base_class(PCI_BASE_CLASS_DISPLAY, pdev);
 if (!pdev)
 break;

 do_something_for_pci_display_device(pdev);
 } while (1);

Sui Jingfeng (5):
   PCI: Add the pci_get_base_class() helper
   ALSA: hda/intel: Use pci_get_base_class() to reduce duplicated code
   drm/nouveau: Use pci_get_base_class() to reduce duplicated code
   drm/amdgpu: Use pci_get_base_class() to reduce duplicated code
   drm/radeon: Use pci_get_base_class() to reduce duplicated code


Series is:
Reviewed-by: Alex Deucher 


Thanks a lot.


What to do next then?

By the way, Bjorn, what's your opinion?
I'm ask because I don't know what to do next with this series.

As they belong to different system of Linux kernel,
the rest of patch (0002 ~ 0005) depend on the first one.

I think, merge the 0001-patch firstly, then wait it arrive at drm-misc, alsa 
branch.
Or, to do something else?



Re: [PATCH v2 0/4] arm64: dts: qcom: qrb5165-rb5: enable DP support

2023-09-19 Thread Bjorn Andersson


On Thu, 17 Aug 2023 17:59:36 +0300, Dmitry Baryshkov wrote:
> Implement DisplayPort support for the Qualcomm RB5 platform.
> 
> Note: while testing this, I had link training issues with several
> dongles with DP connectors. Other DisplayPort-USB-C dongles (with HDMI
> or VGA connectors) work perfectly.
> 
> Dependencies: [1]
> Soft-dependencies: [2], [3]
> 
> [...]

Applied, thanks!

[1/4] arm64: dts: qcom: sm8250: Add DisplayPort device node
  commit: 956aa24b16350a50d3a6beb9237bc35aa2f447d6
[2/4] arm64: dts: qcom: qrb5165-rb5: add onboard USB-C redriver
  commit: d342e1c993bd7589cad9d2da099c6a9c652ecb9f
[3/4] arm64: dts: qcom: qrb5165-rb5: enable displayport controller
  commit: 96387ee7534dc449be35a9bb98b7668da2bed545
[4/4] arm64: dts: qcom: qrb5165-rb5: enable DP altmode
  commit: b3dea914127e9065df003002ed13a2ef40d19877

Best regards,
-- 
Bjorn Andersson 


Re: (subset) [PATCH 0/5] arm64: dts: qcom: qrb5165-rb5: enable DP support

2023-09-19 Thread Bjorn Andersson


On Sun, 09 Jul 2023 07:19:21 +0300, Dmitry Baryshkov wrote:
> Implement DisplayPort support for the Qualcomm RB5 platform.
> 
> Note: while testing this, I had link training issues with several
> dongles with DP connectors. Other DisplayPort-USB-C dongles (with HDMI
> or VGA connectors) work perfectly.
> 
> Dependencies: [1]
> Soft-dependencies: [2], [3]
> 
> [...]

Applied, thanks!

[2/5] arm64: dts: qcom: sm8250: Add DisplayPort device node
  commit: 956aa24b16350a50d3a6beb9237bc35aa2f447d6
[3/5] arm64: dts: qcom: qrb5165-rb5: add onboard USB-C redriver
  commit: d342e1c993bd7589cad9d2da099c6a9c652ecb9f
[4/5] arm64: dts: qcom: qrb5165-rb5: enable displayport controller
  commit: 96387ee7534dc449be35a9bb98b7668da2bed545
[5/5] arm64: dts: qcom: qrb5165-rb5: enable DP altmode
  commit: b3dea914127e9065df003002ed13a2ef40d19877

Best regards,
-- 
Bjorn Andersson 


Re: [PATCH v2 1/4] arm64: dts: qcom: sm8250: Add DisplayPort device node

2023-09-19 Thread Bjorn Andersson
On Thu, Aug 17, 2023 at 05:59:37PM +0300, Dmitry Baryshkov wrote:
> Declare the displayport controller present on the Qualcomm SM8250 SoC.
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  arch/arm64/boot/dts/qcom/sm8250.dtsi | 89 
>  1 file changed, 89 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi 
> b/arch/arm64/boot/dts/qcom/sm8250.dtsi
> index eb00bbd3e1f3..8d705a1713fb 100644
> --- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
> @@ -3638,6 +3638,8 @@ port@1 {
>  
>   port@2 {
>   reg = <2>;
> +
> + usb_1_qmpphy_dp_in: endpoint {};
>   };
>   };
>   };
> @@ -4405,6 +4407,14 @@ dpu_intf2_out: endpoint {
>   remote-endpoint = 
> <_dsi1_in>;
>   };
>   };
> +
> + port@2 {
> + reg = <2>;
> +
> + dpu_intf0_out: endpoint {
> + remote-endpoint = 
> <_dp_in>;
> + };
> + };
>   };
>  
>   mdp_opp_table: opp-table {
> @@ -4432,6 +4442,85 @@ opp-46000 {
>   };
>   };
>  
> + mdss_dp: displayport-controller@ae9 {

displayport-controller does not seem to be a valid child node of the
sm8250 mdss. Please make sure that the binding is updated, if not
already done.

Thanks,
Bjorn


PROBLEM: MT8192 panel_edp_probe trace despite recent eDP and aux-bus support patches

2023-09-19 Thread Leonard Lausen
Dear AngeloGioacchino, Dear Maintainers,

on MT8192 Asurada Spherion (Acer 514), I observe the following trace related to
eDP and aux-bus during bootup with tags/mediatek-drm-next-6.6 merged to v6.5.4
as well as on plain v6.5.4. Despite the trace, the laptop display works. Given
your recent eDP and aux-bus support patches are included in
tags/mediatek-drm-next-6.6, I thought reporting this may be helpful. (I'm
unable to validate v6.6-rc2 currently, as there's a regression breaking boot.) 

[3.808189] [ cut here ]
[3.812840] WARNING: CPU: 7 PID: 10 at drivers/gpu/drm/panel/panel-edp.c:758 
panel_edp_probe+0x488/0x4f0
[3.822370] Modules linked in:
[3.825428] CPU: 7 PID: 10 Comm: kworker/u16:0 Not tainted 6.5.4-cos-mt9+ #1
[3.832476] Hardware name: Google Spherion (rev0 - 3) (DT)
[3.837959] Workqueue: events_unbound deferred_probe_work_func
[3.843797] pstate: 8049 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[3.850757] pc : panel_edp_probe+0x488/0x4f0
[3.855025] lr : panel_edp_probe+0x29c/0x4f0
[3.859291] sp : 8000800d3710
[3.862600] x29: 8000800d3710 x28:  x27: 
[3.869737] x26: 60b44002d005 x25: a4a68e990418 x24: 
[3.875193] usb 1-1: new high-speed USB device number 2 using xhci-mtk
[3.876862] x23: 60b446542680 x22: a4a68db8d5b0 x21: 60b4452d
[3.876869] x20:  x19: 60b441052480 x18: 000a8360
[3.876873] x17: 001f x16:  x15: 0001
[3.904812] x14: 0060f827 x13: 9b00200a4341452d x12: 
[3.911948] x11: 0001 x10:  x9 : 60b446523900
[3.919084] x8 : 60b446523900 x7 : 435e6d06 x6 : 40395246b460
[3.926220] x5 : 0043 x4 : 142b x3 : 004e
[3.933356] x2 :  x1 : a4a68db8d9a0 x0 : 0dae142b
[3.940492] Call trace:
[3.942933]  panel_edp_probe+0x488/0x4f0
[3.946851]  panel_edp_dp_aux_ep_probe+0x38/0x50
[3.951466]  dp_aux_ep_probe+0x34/0xf4
[3.955211]  really_probe+0x148/0x2ac
[3.958868]  __driver_probe_device+0x78/0x12c
[3.963221]  driver_probe_device+0x3c/0x160
[3.967400]  __device_attach_driver+0xb8/0x138
[3.971841]  bus_for_each_drv+0x80/0xdc
[3.975672]  __device_attach+0x9c/0x188
[3.979503]  device_initial_probe+0x14/0x20
[3.983683]  bus_probe_device+0xac/0xb0
[3.987515]  device_add+0x5bc/0x778
[3.990999]  device_register+0x20/0x30
[3.994742]  of_dp_aux_populate_bus+0xc8/0x19c
[3.999181]  devm_of_dp_aux_populate_bus+0x18/0x80
[4.003968]  anx7625_i2c_probe+0x7bc/0x9b4
[4.008062]  i2c_device_probe+0x148/0x290
[4.011724] usb 1-1: New USB device found, idVendor=05e3, idProduct=0610, 
bcdDevice=65.01
[4.012062]  really_probe+0x148/0x2ac
[4.012064]  __driver_probe_device+0x78/0x12c
[4.020243] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[4.023879]  driver_probe_device+0x3c/0x160
[4.023882]  __device_attach_driver+0xb8/0x138
[4.023884]  bus_for_each_drv+0x80/0xdc
[4.028232] usb 1-1: Product: USB2.1 Hub
[4.035347]  __device_attach+0x9c/0x188
[4.035350]  device_initial_probe+0x14/0x20
[4.035353]  bus_probe_device+0xac/0xb0
[4.035355]  deferred_probe_work_func+0x8c/0xc8
[4.039530] usb 1-1: Manufacturer: GenesysLogic
[4.043955]  process_one_work+0x2d0/0x598
[4.048830] hub 1-1:1.0: USB hub found
[4.051689]  worker_thread+0x70/0x434
[4.051691]  kthread+0xfc/0x100
[4.051693]  ret_from_fork+0x10/0x20
[4.051699] irq event stamp: 136828
[4.051701] hardirqs last  enabled at (136827): [] 
_raw_spin_unlock_irqrestore+0x6c/0x98
[4.055841] hub 1-1:1.0: 4 ports detected
[4.059699] hardirqs last disabled at (136828): [] 
el1_dbg+0x24/0x8c
[4.059704] softirqs last  enabled at (134796): [] 
__do_softirq+0x424/0x51c
[4.059706] softirqs last disabled at (134787): [] 
do_softirq+0x10/0x1c
[4.059709] ---[ end trace  ]---

Without your patches, on 6.5.4, the trace looks as follows

[3.834478] [ cut here ]
[3.839126] WARNING: CPU: 5 PID: 10 at drivers/gpu/drm/panel/panel-edp.c:758 
panel_edp_probe+0x488/0x4f0
[3.848629] Modules linked in:
[3.851684] CPU: 5 PID: 10 Comm: kworker/u16:0 Not tainted 6.5.4-cos-mt9 #1
[3.858646] Hardware name: Google Spherion (rev0 - 3) (DT)
[3.864129] Workqueue: events_unbound deferred_probe_work_func
[3.869966] pstate: 8049 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[3.876927] pc : panel_edp_probe+0x488/0x4f0
[3.881195] lr : panel_edp_probe+0x29c/0x4f0
[3.885461] sp : 8000800d3710
[3.888770] x29: 8000800d3710 x28:  x27: 
[3.895907] x26: 31fec002c005 x25: a839d1b90418 x24: 
[3.899112] 

[PATCH -next] drm/bridge: clean up some inconsistent indentings

2023-09-19 Thread Yang Li
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c:336 dw_hdmi_cec_suspend() warn: 
inconsistent indenting

Signed-off-by: Yang Li 
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
index 673661160e54..fe2ff4984fc5 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
@@ -333,9 +333,9 @@ static int __maybe_unused dw_hdmi_cec_suspend(struct device 
*dev)
struct dw_hdmi_cec *cec = dev_get_drvdata(dev);
 
/* store interrupt status/mask registers */
-cec->regs_polarity = dw_hdmi_read(cec, HDMI_CEC_POLARITY);
-cec->regs_mask = dw_hdmi_read(cec, HDMI_CEC_MASK);
-cec->regs_mute_stat0 = dw_hdmi_read(cec, HDMI_IH_MUTE_CEC_STAT0);
+   cec->regs_polarity = dw_hdmi_read(cec, HDMI_CEC_POLARITY);
+   cec->regs_mask = dw_hdmi_read(cec, HDMI_CEC_MASK);
+   cec->regs_mute_stat0 = dw_hdmi_read(cec, HDMI_IH_MUTE_CEC_STAT0);
 
return 0;
 }
-- 
2.20.1.7.g153144c



Re: [PATCH 00/10] Add mediate-drm secure flow for SVP

2023-09-19 Thread Jeffrey Kardatzke
On Mon, Sep 18, 2023 at 11:33 PM Daniel Stone  wrote:
>
> Hi Jason, CK,
>
> On Tue, 19 Sept 2023 at 04:04, Jason-JH.Lin  wrote:
> > The patch series provides drm driver support for enabling secure video
> > path (SVP) playback on MediaiTek hardware in the Linux kernel.
> >
> > [...]
> >
> > Memory Usage in SVP:
> > The overall flow of SVP starts with encrypted video coming in from an
> > outside source into the REE. The REE will then allocate a 'secure
> > buffer' and send the corresponding 'secure handle' along with the
> > encrypted, compressed video data to the TEE. The TEE will then decrypt
> > the video and store the result in the 'secure buffer'. The REE will
> > then allocate a 'secure surface'. The REE will pass the 'secure
> > handles' for both the 'secure buffer' and 'secure surface' into the
> > TEE for video decoding. The video decoder HW will then decode the
> > contents of the 'secure buffer' and place the result in the 'secure
> > surface'. The REE will then attach the 'secure surface' to the overlay
> > plane for rendering of the video.
> >
> > Everything relating to ensuring security of the actual contents of the
> > 'secure buffer' and 'secure surface' is out of scope for the REE and
> > is the responsibility of the TEE.
> >
> > DRM driver handles allocation of gem objects that are backed by a 'secure
> > surface' and for displaying a 'secure surface' on the overlay plane.
> > This introduces a new flag for object creation called
> > DRM_MTK_GEM_CREATE_ENCRYPTED which indicates it should be a 'secure
> > surface'. All changes here are in MediaTek specific code.
>
> To be honest, it seems strange that DRM is being used as the allocator
> for buffers which will mostly be used by codec hardware which is not
> mentioned here. I can understand that minigbm and gbm_gralloc make
> this easy to implement, but it's not really right to add this all to
> mtk-drm just to support some codec features.
The buffers allocated are used as the output for secure video decoding
and then rendering as well. So they aren't just used by the codec HW,
they're also used for display on the overlay plane.

And I'm the user of all the secure video path patches Mediatek has
been posting, this is for secure video playback on ChromeOS ARM
devices. (just mentioning so you know my context in this all)
>
> NXP posted a patchset a while ago to add secure-memory support to
> dma-heaps[0]. This would be much cleaner (e.g. avoiding strcmp on
> allocating name, avoiding mtk-drm being a render node when it can't
> render) I think, and also allow common secure-path semantics between
> different vendors.
>
Yes, I saw that now. I agree that having a common secure-path solution
is preferable. But the two issues you mention with this patchset
aren't directly related to the dma-buf heap implementation I think.

The ugly strcmp can be removed from this patchset...because it doesn't
actually need to check the heap name, it only ever invokes
mtk_drm_gem_create_from_heap for secure memory allocations...so that
should just be renamed mtk_drm_gem_create_from_secure_heap. The RENDER
flag can also be removed. IIUC, that's an artifact of how ChromeOS is
doing the allocations and that it's performing it on a render node.
That can be removed from this patchset and we can address that problem
on the ChromeOS side instead.

Going back to the NXP implementation...the main difference between
that one and what Mediatek is proposing (aside from all their vendor
specific naming of things) is that the NXP patchset does all the
allocation in the kernel itself and the kernel is handing out physical
addresses from the reserved range w/ no virtual address mapping. I
think that would mean you have to always allocate contiguous blocks,
which would be prone to fragmentation.  In the Mediatek
implementation, they are doing the allocations from the heap in the
TEE, so they can deal with physical memory fragmentation through
virtual addresses since they can do SG lists to allocate from
fragmented memory in the TEE.




> Having common secure-path semantics between different vendors would be
> very helpful, because the first question when we add new uAPI is
> 'where is the open-source userspace?'. If there is at least a common
> interface through e.g. dma-heaps, then we could have some standard
> cross-vendor userspace code which would work well with the standard
> interface.
>
Thanks for your feedback, I definitely want to work to get this to
something more usable by a wider range.

> Cheers,
> Daniel
>
> [0]: https://lore.kernel.org/lkml/20220805135330.970-2-olivier.ma...@nxp.com/


[PATCH v6 0/6] Add fdinfo support to Panfrost

2023-09-19 Thread Adrián Larumbe
This patch series adds fdinfo support to the Panfrost DRM driver. It will
display a series of key:value pairs under /proc/pid/fdinfo/fd for render
processes that open the Panfrost DRM file.

The pairs contain basic drm gpu engine and memory region information that
can either be cat by a privileged user or accessed with IGT's gputop
utility.

Changelog:

v1: https://lore.kernel.org/lkml/bb52b872-e41b-3894-285e-b52cfc849...@arm.com/T/

v2: https://lore.kernel.org/lkml/20230901084457.5bc1a...@collabora.com/T/
 - Changed the way gpu cycles and engine time are calculated, using GPU
 registers and taking into account potential resets.
 - Split render engine values into fragment and vertex/tiler ones.
 - Added more fine-grained calculation of RSS size for BO's.
 - Implemente selection of drm-memory region size units
 - Removed locking of shrinker's mutex in GEM obj status function

v3: 
https://lore.kernel.org/lkml/20230905184533.959171-1-adrian.laru...@collabora.com/
 - Changed fdinfo engine names to something more descriptive
 - Mentioned GPU cycle counts aren't an exact measure
 - Handled the case when job->priv might be NULL
 - Handled 32 bit overflow of cycle register
 - Kept fdinfo drm memory stats size unit display within 10k times the
   previous multiplier for more accurate BO size numbers
 - Removed special handling of Prime imported BO RSS
 - Use rss_size only for heap objects
 - Use bo->base.madv instead of specific purgeable flag
 - Fixed kernel test robot warnings

v4: 
https://lore.kernel.org/lkml/20230912084044.955864-1-adrian.laru...@collabora.com/
 - Move cycle counter get and put to panfrost_job_hw_submit and
   panfrost_job_handle_{err,done} for more accuracy
 - Make sure cycle counter refs are released in reset path
 - Drop the model param for toggling cycle counting and do
   leave it down to the debugfs file
 - Don't disable cycle counter when togglint debugfs file,
   let refcounting logic handle it instead.
 - Remove fdinfo data nested structure definion and 'names' field
 - When incrementing BO RSS size in GPU MMU page fault IRQ handler, assume
  granuality of 2MiB for every successful mapping.
 - drm-file picks an fdinfo memory object size unit that doesn't lose precision.

v5: 
https://lore.kernel.org/lkml/20230914223928.2374933-1-adrian.laru...@collabora.com/
 - Removed explicit initialisation of atomic variable for profiling mode,
   as it's allocated with kzalloc.
 - Pass engine utilisation structure to jobs rather than the file context, to 
avoid
   future misusage of the latter.
 - Remove double reading of cycle counter register and ktime in job deqeueue 
function,
   as the scheduler will make sure these values are read over in case of 
requeuing.
 - Moved putting of cycle counting refcnt into panfrost job dequeue
   function to avoid repetition.

v6:
 - Fix wrong swapped-round engine time and cycle values in fdinfo
   drm print statements.

Adrián Larumbe (6):
  drm/panfrost: Add cycle count GPU register definitions
  drm/panfrost: Add fdinfo support GPU load metrics
  drm/panfrost: Add fdinfo support for memory stats
  drm/drm_file: Add DRM obj's RSS reporting function for fdinfo
  drm/panfrost: Implement generic DRM object RSS reporting function
  drm/drm-file: Show finer-grained BO sizes in drm_show_memory_stats

 drivers/gpu/drm/drm_file.c  | 10 +++-
 drivers/gpu/drm/panfrost/Makefile   |  2 +
 drivers/gpu/drm/panfrost/panfrost_debugfs.c | 20 +++
 drivers/gpu/drm/panfrost/panfrost_debugfs.h | 13 +
 drivers/gpu/drm/panfrost/panfrost_devfreq.c |  8 +++
 drivers/gpu/drm/panfrost/panfrost_devfreq.h |  3 ++
 drivers/gpu/drm/panfrost/panfrost_device.c  |  2 +
 drivers/gpu/drm/panfrost/panfrost_device.h  | 13 +
 drivers/gpu/drm/panfrost/panfrost_drv.c | 59 -
 drivers/gpu/drm/panfrost/panfrost_gem.c | 29 ++
 drivers/gpu/drm/panfrost/panfrost_gem.h |  5 ++
 drivers/gpu/drm/panfrost/panfrost_gpu.c | 41 ++
 drivers/gpu/drm/panfrost/panfrost_gpu.h |  4 ++
 drivers/gpu/drm/panfrost/panfrost_job.c | 24 +
 drivers/gpu/drm/panfrost/panfrost_job.h |  5 ++
 drivers/gpu/drm/panfrost/panfrost_mmu.c |  1 +
 drivers/gpu/drm/panfrost/panfrost_regs.h|  5 ++
 include/drm/drm_gem.h   |  9 
 18 files changed, 250 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/panfrost/panfrost_debugfs.c
 create mode 100644 drivers/gpu/drm/panfrost/panfrost_debugfs.h


base-commit: f45acf7acf75921c0409d452f0165f51a19a74fd
-- 
2.42.0



[PATCH v6 4/6] drm/drm_file: Add DRM obj's RSS reporting function for fdinfo

2023-09-19 Thread Adrián Larumbe
Some BO's might be mapped onto physical memory chunkwise and on demand,
like Panfrost's tiler heap. In this case, even though the
drm_gem_shmem_object page array might already be allocated, only a very
small fraction of the BO is currently backed by system memory, but
drm_show_memory_stats will then proceed to add its entire virtual size to
the file's total resident size regardless.

This led to very unrealistic RSS sizes being reckoned for Panfrost, where
said tiler heap buffer is initially allocated with a virtual size of 128
MiB, but only a small part of it will eventually be backed by system memory
after successive GPU page faults.

Provide a new DRM object generic function that would allow drivers to
return a more accurate RSS size for their BOs.

Signed-off-by: Adrián Larumbe 
Reviewed-by: Boris Brezillon 
Reviewed-by: Steven Price 
---
 drivers/gpu/drm/drm_file.c | 5 -
 include/drm/drm_gem.h  | 9 +
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index 883d83bc0e3d..762965e3d503 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -944,7 +944,10 @@ void drm_show_memory_stats(struct drm_printer *p, struct 
drm_file *file)
}
 
if (s & DRM_GEM_OBJECT_RESIDENT) {
-   status.resident += obj->size;
+   if (obj->funcs && obj->funcs->rss)
+   status.resident += obj->funcs->rss(obj);
+   else
+   status.resident += obj->size;
} else {
/* If already purged or not yet backed by pages, don't
 * count it as purgeable:
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index bc9f6aa2f3fe..16364487fde9 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -208,6 +208,15 @@ struct drm_gem_object_funcs {
 */
enum drm_gem_object_status (*status)(struct drm_gem_object *obj);
 
+   /**
+* @rss:
+*
+* Return resident size of the object in physical memory.
+*
+* Called by drm_show_memory_stats().
+*/
+   size_t (*rss)(struct drm_gem_object *obj);
+
/**
 * @vm_ops:
 *
-- 
2.42.0



[PATCH v6 2/6] drm/panfrost: Add fdinfo support GPU load metrics

2023-09-19 Thread Adrián Larumbe
The drm-stats fdinfo tags made available to user space are drm-engine,
drm-cycles, drm-max-freq and drm-curfreq, one per job slot.

This deviates from standard practice in other DRM drivers, where a single
set of key:value pairs is provided for the whole render engine. However,
Panfrost has separate queues for fragment and vertex/tiler jobs, so a
decision was made to calculate bus cycles and workload times separately.

Maximum operating frequency is calculated at devfreq initialisation time.
Current frequency is made available to user space because nvtop uses it
when performing engine usage calculations.

It is important to bear in mind that both GPU cycle and kernel time numbers
provided are at best rough estimations, and always reported in excess from
the actual figure because of two reasons:
 - Excess time because of the delay between the end of a job processing,
   the subsequent job IRQ and the actual time of the sample.
 - Time spent in the engine queue waiting for the GPU to pick up the next
   job.

To avoid race conditions during enablement/disabling, a reference counting
mechanism was introduced, and a job flag that tells us whether a given job
increased the refcount. This is necessary, because user space can toggle
cycle counting through a debugfs file, and a given job might have been in
flight by the time cycle counting was disabled.

The main goal of the debugfs cycle counter knob is letting tools like nvtop
or IGT's gputop switch it at any time, to avoid power waste in case no
engine usage measuring is necessary.

Signed-off-by: Adrián Larumbe 
Reviewed-by: Boris Brezillon 
Reviewed-by: Steven Price 
---
 drivers/gpu/drm/panfrost/Makefile   |  2 +
 drivers/gpu/drm/panfrost/panfrost_debugfs.c | 20 
 drivers/gpu/drm/panfrost/panfrost_debugfs.h | 13 +
 drivers/gpu/drm/panfrost/panfrost_devfreq.c |  8 +++
 drivers/gpu/drm/panfrost/panfrost_devfreq.h |  3 ++
 drivers/gpu/drm/panfrost/panfrost_device.c  |  2 +
 drivers/gpu/drm/panfrost/panfrost_device.h  | 13 +
 drivers/gpu/drm/panfrost/panfrost_drv.c | 57 -
 drivers/gpu/drm/panfrost/panfrost_gpu.c | 41 +++
 drivers/gpu/drm/panfrost/panfrost_gpu.h |  4 ++
 drivers/gpu/drm/panfrost/panfrost_job.c | 24 +
 drivers/gpu/drm/panfrost/panfrost_job.h |  5 ++
 12 files changed, 191 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/panfrost/panfrost_debugfs.c
 create mode 100644 drivers/gpu/drm/panfrost/panfrost_debugfs.h

diff --git a/drivers/gpu/drm/panfrost/Makefile 
b/drivers/gpu/drm/panfrost/Makefile
index 7da2b3f02ed9..2c01c1e7523e 100644
--- a/drivers/gpu/drm/panfrost/Makefile
+++ b/drivers/gpu/drm/panfrost/Makefile
@@ -12,4 +12,6 @@ panfrost-y := \
panfrost_perfcnt.o \
panfrost_dump.o
 
+panfrost-$(CONFIG_DEBUG_FS) += panfrost_debugfs.o
+
 obj-$(CONFIG_DRM_PANFROST) += panfrost.o
diff --git a/drivers/gpu/drm/panfrost/panfrost_debugfs.c 
b/drivers/gpu/drm/panfrost/panfrost_debugfs.c
new file mode 100644
index ..cc14eccba206
--- /dev/null
+++ b/drivers/gpu/drm/panfrost/panfrost_debugfs.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright 2023 Collabora ltd. */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "panfrost_device.h"
+#include "panfrost_gpu.h"
+#include "panfrost_debugfs.h"
+
+void panfrost_debugfs_init(struct drm_minor *minor)
+{
+   struct drm_device *dev = minor->dev;
+   struct panfrost_device *pfdev = 
platform_get_drvdata(to_platform_device(dev->dev));
+
+   debugfs_create_atomic_t("profile", 0600, minor->debugfs_root, 
>profile_mode);
+}
diff --git a/drivers/gpu/drm/panfrost/panfrost_debugfs.h 
b/drivers/gpu/drm/panfrost/panfrost_debugfs.h
new file mode 100644
index ..db1c158bcf2f
--- /dev/null
+++ b/drivers/gpu/drm/panfrost/panfrost_debugfs.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2023 Collabora ltd.
+ */
+
+#ifndef PANFROST_DEBUGFS_H
+#define PANFROST_DEBUGFS_H
+
+#ifdef CONFIG_DEBUG_FS
+void panfrost_debugfs_init(struct drm_minor *minor);
+#endif
+
+#endif  /* PANFROST_DEBUGFS_H */
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c 
b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index 58dfb15a8757..28caffc689e2 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -58,6 +58,7 @@ static int panfrost_devfreq_get_dev_status(struct device *dev,
spin_lock_irqsave(>lock, irqflags);
 
panfrost_devfreq_update_utilization(pfdevfreq);
+   pfdevfreq->current_frequency = status->current_frequency;
 
status->total_time = ktime_to_ns(ktime_add(pfdevfreq->busy_time,
   pfdevfreq->idle_time));
@@ -117,6 +118,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
struct devfreq *devfreq;
struct thermal_cooling_device *cooling;
struct panfrost_devfreq *pfdevfreq = 

[PATCH v6 6/6] drm/drm-file: Show finer-grained BO sizes in drm_show_memory_stats

2023-09-19 Thread Adrián Larumbe
The current implementation will try to pick the highest available size
display unit as soon as the BO size exceeds that of the previous
multiplier. That can lead to loss of precision in contexts of low memory
usage.

The new selection criteria try to preserve precision, whilst also
increasing the display unit selection threshold to render more accurate
values.

Signed-off-by: Adrián Larumbe 
Reviewed-by: Boris Brezillon 
Reviewed-by: Steven Price 
---
 drivers/gpu/drm/drm_file.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index 762965e3d503..34cfa128ffe5 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -872,6 +872,8 @@ void drm_send_event(struct drm_device *dev, struct 
drm_pending_event *e)
 }
 EXPORT_SYMBOL(drm_send_event);
 
+#define UPPER_UNIT_THRESHOLD 100
+
 static void print_size(struct drm_printer *p, const char *stat,
   const char *region, u64 sz)
 {
@@ -879,7 +881,8 @@ static void print_size(struct drm_printer *p, const char 
*stat,
unsigned u;
 
for (u = 0; u < ARRAY_SIZE(units) - 1; u++) {
-   if (sz < SZ_1K)
+   if ((sz & (SZ_1K - 1)) &&
+   sz < UPPER_UNIT_THRESHOLD * SZ_1K)
break;
sz = div_u64(sz, SZ_1K);
}
-- 
2.42.0



[PATCH v6 5/6] drm/panfrost: Implement generic DRM object RSS reporting function

2023-09-19 Thread Adrián Larumbe
BO's RSS is updated every time new pages are allocated on demand and mapped
for the object at GPU page fault's IRQ handler, but only for heap buffers.
The reason this is unnecessary for non-heap buffers is that they are mapped
onto the GPU's VA space and backed by physical memory in their entirety at
BO creation time.

This calculation is unnecessary for imported PRIME objects, since heap
buffers cannot be exported by our driver, and the actual BO RSS size is the
one reported in its attached dmabuf structure.

Signed-off-by: Adrián Larumbe 
Reviewed-by: Boris Brezillon 
Reviewed-by: Steven Price 
---
 drivers/gpu/drm/panfrost/panfrost_gem.c | 15 +++
 drivers/gpu/drm/panfrost/panfrost_gem.h |  5 +
 drivers/gpu/drm/panfrost/panfrost_mmu.c |  1 +
 3 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c 
b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 7d8f83d20539..4365434b48db 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -208,6 +208,20 @@ static enum drm_gem_object_status 
panfrost_gem_status(struct drm_gem_object *obj
return res;
 }
 
+static size_t panfrost_gem_rss(struct drm_gem_object *obj)
+{
+   struct panfrost_gem_object *bo = to_panfrost_bo(obj);
+
+   if (bo->is_heap) {
+   return bo->heap_rss_size;
+   } else if (bo->base.pages) {
+   WARN_ON(bo->heap_rss_size);
+   return bo->base.base.size;
+   } else {
+   return 0;
+   }
+}
+
 static const struct drm_gem_object_funcs panfrost_gem_funcs = {
.free = panfrost_gem_free_object,
.open = panfrost_gem_open,
@@ -220,6 +234,7 @@ static const struct drm_gem_object_funcs panfrost_gem_funcs 
= {
.vunmap = drm_gem_shmem_object_vunmap,
.mmap = drm_gem_shmem_object_mmap,
.status = panfrost_gem_status,
+   .rss = panfrost_gem_rss,
.vm_ops = _gem_shmem_vm_ops,
 };
 
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h 
b/drivers/gpu/drm/panfrost/panfrost_gem.h
index ad2877eeeccd..13c0a8149c3a 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.h
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.h
@@ -36,6 +36,11 @@ struct panfrost_gem_object {
 */
atomic_t gpu_usecount;
 
+   /*
+* Object chunk size currently mapped onto physical memory
+*/
+   size_t heap_rss_size;
+
bool noexec :1;
bool is_heap:1;
 };
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c 
b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index d54d4e7b2195..7b1490cdaa48 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -522,6 +522,7 @@ static int panfrost_mmu_map_fault_addr(struct 
panfrost_device *pfdev, int as,
   IOMMU_WRITE | IOMMU_READ | IOMMU_NOEXEC, sgt);
 
bomapping->active = true;
+   bo->heap_rss_size += SZ_2;
 
dev_dbg(pfdev->dev, "mapped page fault @ AS%d %llx", as, addr);
 
-- 
2.42.0



[PATCH v6 1/6] drm/panfrost: Add cycle count GPU register definitions

2023-09-19 Thread Adrián Larumbe
These GPU registers will be used when programming the cycle counter, which
we need for providing accurate fdinfo drm-cycles values to user space.

Signed-off-by: Adrián Larumbe 
Reviewed-by: Boris Brezillon 
Reviewed-by: Steven Price 
---
 drivers/gpu/drm/panfrost/panfrost_regs.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h 
b/drivers/gpu/drm/panfrost/panfrost_regs.h
index 919f44ac853d..55ec807550b3 100644
--- a/drivers/gpu/drm/panfrost/panfrost_regs.h
+++ b/drivers/gpu/drm/panfrost/panfrost_regs.h
@@ -46,6 +46,8 @@
 #define   GPU_CMD_SOFT_RESET   0x01
 #define   GPU_CMD_PERFCNT_CLEAR0x03
 #define   GPU_CMD_PERFCNT_SAMPLE   0x04
+#define   GPU_CMD_CYCLE_COUNT_START0x05
+#define   GPU_CMD_CYCLE_COUNT_STOP 0x06
 #define   GPU_CMD_CLEAN_CACHES 0x07
 #define   GPU_CMD_CLEAN_INV_CACHES 0x08
 #define GPU_STATUS 0x34
@@ -73,6 +75,9 @@
 #define GPU_PRFCNT_TILER_EN0x74
 #define GPU_PRFCNT_MMU_L2_EN   0x7c
 
+#define GPU_CYCLE_COUNT_LO 0x90
+#define GPU_CYCLE_COUNT_HI 0x94
+
 #define GPU_THREAD_MAX_THREADS 0x0A0   /* (RO) Maximum number of 
threads per core */
 #define GPU_THREAD_MAX_WORKGROUP_SIZE  0x0A4   /* (RO) Maximum workgroup size 
*/
 #define GPU_THREAD_MAX_BARRIER_SIZE0x0A8   /* (RO) Maximum threads waiting 
at a barrier */
-- 
2.42.0



[PATCH v6 3/6] drm/panfrost: Add fdinfo support for memory stats

2023-09-19 Thread Adrián Larumbe
A new DRM GEM object function is added so that drm_show_memory_stats can
provide more accurate memory usage numbers.

Ideally, in panfrost_gem_status, the BO's purgeable flag would be checked
after locking the driver's shrinker mutex, but drm_show_memory_stats takes
over the drm file's object handle database spinlock, so there's potential
for a race condition here.

Signed-off-by: Adrián Larumbe 
Reviewed-by: Boris Brezillon 
Reviewed-by: Steven Price 
---
 drivers/gpu/drm/panfrost/panfrost_drv.c |  2 ++
 drivers/gpu/drm/panfrost/panfrost_gem.c | 14 ++
 2 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 3c93a11deab1..8cd9331ac4b8 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -567,6 +567,8 @@ static void panfrost_show_fdinfo(struct drm_printer *p, 
struct drm_file *file)
struct panfrost_device *pfdev = dev->dev_private;
 
panfrost_gpu_show_fdinfo(pfdev, file->driver_priv, p);
+
+   drm_show_memory_stats(p, file);
 }
 
 static const struct file_operations panfrost_drm_driver_fops = {
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c 
b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 3c812fbd126f..7d8f83d20539 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -195,6 +195,19 @@ static int panfrost_gem_pin(struct drm_gem_object *obj)
return drm_gem_shmem_pin(>base);
 }
 
+static enum drm_gem_object_status panfrost_gem_status(struct drm_gem_object 
*obj)
+{
+   struct panfrost_gem_object *bo = to_panfrost_bo(obj);
+   enum drm_gem_object_status res = 0;
+
+   res |= (bo->base.madv == PANFROST_MADV_DONTNEED) ?
+   DRM_GEM_OBJECT_PURGEABLE : 0;
+
+   res |= (bo->base.pages) ? DRM_GEM_OBJECT_RESIDENT : 0;
+
+   return res;
+}
+
 static const struct drm_gem_object_funcs panfrost_gem_funcs = {
.free = panfrost_gem_free_object,
.open = panfrost_gem_open,
@@ -206,6 +219,7 @@ static const struct drm_gem_object_funcs panfrost_gem_funcs 
= {
.vmap = drm_gem_shmem_object_vmap,
.vunmap = drm_gem_shmem_object_vunmap,
.mmap = drm_gem_shmem_object_mmap,
+   .status = panfrost_gem_status,
.vm_ops = _gem_shmem_vm_ops,
 };
 
-- 
2.42.0



Re: (subset) [PATCH v4 00/17] drm/msm: Add SM6125 MDSS/DPU hardware and enable Sony Xperia 10 II panel

2023-09-19 Thread Bjorn Andersson


On Sun, 23 Jul 2023 18:08:38 +0200, Marijn Suijten wrote:
> Bring up the SM6125 DPU now that all preliminary series (such as INTF
> TE) have been merged (for me to test the hardware properly), and most
> other conflicting work (barring ongoing catalog *improvements*) has made
> its way in as well or is still being discussed.
> 
> The second part of the series complements that by immediately utilizing
> this hardware in DT, and even enabling the MDSS/DSI nodes complete with
> a 6.0" 1080x2520 panel for Sony's Seine PDX201 (Xperia 10 II).
> 
> [...]

Applied, thanks!

[02/17] arm64: dts: qcom: sm6125: Pad APPS IOMMU address to 8 characters
commit: 310cdafc4a56827d1aeda7cc297939034adb8f99
[03/17] arm64: dts: qcom: sm6125: Sort spmi_bus node numerically by reg
commit: 3d06cee2249f4764f01a9f602ec1cc1bf4562ca6
[14/17] arm64: dts: qcom: sm6125: Switch fixed xo_board clock to RPM XO clock
commit: cbe82d7d0b149aa9c0c000f7ffd2b18bfd248d35
[15/17] arm64: dts: qcom: sm6125: Add dispcc node
commit: 491ec067c3e6d382de1583b7f5b1095ddea2
[16/17] arm64: dts: qcom: sm6125: Add display hardware nodes
commit: 0865d23a02260a76963bd18d9ae603e77cdd0eba
[17/17] arm64: dts: qcom: sm6125-seine: Configure MDSS, DSI and panel
commit: 5078dfe3c5c7b8d2d6494c26de81a4f3d4a5a3d7

Best regards,
-- 
Bjorn Andersson 


Re: (subset) [PATCH v4 00/11] drm/panel and i2c-hid: Allow panels and touchscreens to power sequence together

2023-09-19 Thread Bjorn Andersson


On Thu, 27 Jul 2023 10:16:27 -0700, Douglas Anderson wrote:
> The big motivation for this patch series is mostly described in the patch
> ("drm/panel: Add a way for other devices to follow panel state"), but to
> quickly summarize here: for touchscreens that are connected to a panel we
> need the ability to power sequence the two device together. This is not a
> new need, but so far we've managed to get by through a combination of
> inefficiency, added costs, or perhaps just a little bit of brokenness.
> It's time to do better. This patch series allows us to do better.
> 
> [...]

Applied, thanks!

[11/11] arm64: dts: qcom: sc7180: Link trogdor touchscreens to the panels
commit: 989aac9dea7fcfc33b5eedc4ae44abbf71460a4d

Best regards,
-- 
Bjorn Andersson 


Re: [PATCH] drm: remove drm_bridge_hpd_disable() from drm_bridge_connector_destroy()

2023-09-19 Thread Abhinav Kumar

Hi Laurent

On 9/19/2023 11:12 AM, Laurent Pinchart wrote:

Hi Abhinav,

Thank you for the patch.

On Tue, Sep 19, 2023 at 10:48:12AM -0700, Abhinav Kumar wrote:

drm_bridge_hpd_enable()/drm_bridge_hpd_disable() callbacks call into
the respective driver's hpd_enable()/hpd_disable() ops. These ops control
the HPD enable/disable logic which in some cases like MSM can be a
dedicate hardware block to control the HPD.

During probe_defer cases, a connector can be initialized and then later
destroyed till the probe is retried. During connector destroy in these
cases, the hpd_disable() callback gets called without a corresponding
hpd_enable() leading to an unbalanced state potentially causing even
a crash.

This can be avoided by the respective drivers maintaining their own
state logic to ensure that a hpd_disable() without a corresponding
hpd_enable() just returns without doing anything.

However, to have a generic fix it would be better to avoid the
hpd_disable() callback from the connector destroy path and let
the hpd_enable() / hpd_disable() balance be maintained by the
corresponding drm_bridge_connector_enable_hpd() /
drm_bridge_connector_disable_hpd() APIs which should get called by
drm_kms_helper_disable_hpd().


The change makes sense to me, but I'm a bit worried this could introduce
a regression by leaving HPD enabled in some cases.

I agree that bridges shouldn't track the HPD state, it should be tracked
by the core and the .enable_hpd() and .disable_hpd() operations should
be balanced. Their documentation, however, doesn't clearly state this,
and the documentation of the callers of these operations is also fairly
unclear.

Could you perhaps try to improve the documentation ? With that,



Yes, sure, Let me upload another patch to improve the documentation of 
.enable_hpd(), .disable_hpd() and its callers.



Reviewed-by: Laurent Pinchart 

for this patch.



Thanks

Abhinav


changes in v2:
- minor change in commit text (Dmitry)

Signed-off-by: Abhinav Kumar 
Reviewed-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/drm_bridge_connector.c | 6 --
  1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_bridge_connector.c 
b/drivers/gpu/drm/drm_bridge_connector.c
index 1da93d5a1f61..c4dba39acfd8 100644
--- a/drivers/gpu/drm/drm_bridge_connector.c
+++ b/drivers/gpu/drm/drm_bridge_connector.c
@@ -187,12 +187,6 @@ static void drm_bridge_connector_destroy(struct 
drm_connector *connector)
struct drm_bridge_connector *bridge_connector =
to_drm_bridge_connector(connector);
  
-	if (bridge_connector->bridge_hpd) {

-   struct drm_bridge *hpd = bridge_connector->bridge_hpd;
-
-   drm_bridge_hpd_disable(hpd);
-   }
-
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
  




Re: [Nouveau] [PATCH] nouveau/u_memcpya: fix NULL vs error pointer bug

2023-09-19 Thread Danilo Krummrich

On 9/16/23 16:24, Dan Carpenter wrote:

On Sat, Sep 16, 2023 at 01:41:43AM +0200, Danilo Krummrich wrote:

Hi Dan,

On 9/15/23 14:59, Dan Carpenter wrote:

The u_memcpya() function is supposed to return error pointers on
error.  Returning NULL will lead to an Oops.

Fixes: 68132cc6d1bc ("nouveau/u_memcpya: use vmemdup_user")
Signed-off-by: Dan Carpenter 
---
   drivers/gpu/drm/nouveau/nouveau_drv.h | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 3666a7403e47..52a708a98915 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -193,7 +193,7 @@ u_memcpya(uint64_t user, unsigned int nmemb, unsigned int 
size)
size_t bytes;
if (unlikely(check_mul_overflow(nmemb, size, )))
-   return NULL;
+   return ERR_PTR(-ENOMEM);


I plan to replace this function with an upcoming vmemdup_array_user() helper,
which returns -EOVERFLOW instead, hence mind using that?

Unless you disagree, no need to resubmit the patch, I can change it
before applying the patch.


Generally, I would say that ENOMEM is the correct error code.  I feel
like someone thinks EOVERFLOW means integer overflow and that's not
correct.  I means like if you pass a number higher than INT_MAX to
kstroint().

But I don't care strongly about this.  You can change it if you want to.


I seems that vmemdup_array_user() will keep using EOVERFLOW, hence aligning to
that.

Pushed the patch to drm-misc-fixes, thanks!



regards,
dan carpenter





Re: [PATCH 8/9] dt-bindings: reserved-memory: MediaTek: Add reserved memory for SVP

2023-09-19 Thread Jeffrey Kardatzke
On Mon, Sep 18, 2023 at 3:47 AM Yong Wu (吴勇)  wrote:
>
> On Tue, 2023-09-12 at 10:53 -0500, Rob Herring wrote:
> >
> > External email : Please do not click links or open attachments until
> > you have verified the sender or the content.
> >  On Tue, Sep 12, 2023 at 11:13:50AM +0100, Robin Murphy wrote:
> > > On 12/09/2023 9:28 am, Krzysztof Kozlowski wrote:
> > > > On 12/09/2023 08:16, Yong Wu (吴勇) wrote:
> > > > > Hi Rob,
> > > > >
> > > > > Thanks for your review.
> > > > >
> > > > > On Mon, 2023-09-11 at 10:44 -0500, Rob Herring wrote:
> > > > > >
> > > > > > External email : Please do not click links or open
> > attachments until
> > > > > > you have verified the sender or the content.
> > > > > >   On Mon, Sep 11, 2023 at 10:30:37AM +0800, Yong Wu wrote:
> > > > > > > This adds the binding for describing a CMA memory for
> > MediaTek
> > > > > > SVP(Secure
> > > > > > > Video Path).
> > > > > >
> > > > > > CMA is a Linux thing. How is this related to CMA?
> > > > >
> > > > > > >
> > > > > > > Signed-off-by: Yong Wu 
> > > > > > > ---
> > > > > > >   .../mediatek,secure_cma_chunkmem.yaml | 42
> > > > > > +++
> > > > > > >   1 file changed, 42 insertions(+)
> > > > > > >   create mode 100644
> > Documentation/devicetree/bindings/reserved-
> > > > > > memory/mediatek,secure_cma_chunkmem.yaml
> > > > > > >
> > > > > > > diff --git a/Documentation/devicetree/bindings/reserved-
> > > > > > memory/mediatek,secure_cma_chunkmem.yaml
> > > > > > b/Documentation/devicetree/bindings/reserved-
> > > > > > memory/mediatek,secure_cma_chunkmem.yaml
> > > > > > > new file mode 100644
> > > > > > > index ..cc10e00d35c4
> > > > > > > --- /dev/null
> > > > > > > +++ b/Documentation/devicetree/bindings/reserved-
> > > > > > memory/mediatek,secure_cma_chunkmem.yaml
> > > > > > > @@ -0,0 +1,42 @@
> > > > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > > > > +%YAML 1.2
> > > > > > > +---
> > > > > > > +$id:
> > > > > >
> > http://devicetree.org/schemas/reserved-memory/mediatek,secure_cma_chunkmem.yaml#
> > > > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > > > > +
> > > > > > > +title: MediaTek Secure Video Path Reserved Memory
> > > > > >
> > > > > > What makes this specific to Mediatek? Secure video path is
> > fairly
> > > > > > common, right?
> > > > >
> > > > > Here we just reserve a buffer and would like to create a dma-
> > buf secure
> > > > > heap for SVP, then the secure engines(Vcodec and DRM) could
> > prepare
> > > > > secure buffer through it.
> > > > > But the heap driver is pure SW driver, it is not platform
> > device and
> > > >
> > > > All drivers are pure SW.
> > > >
> > > > > we don't have a corresponding HW unit for it. Thus I don't
> > think I
> > > > > could create a platform dtsi node and use "memory-region"
> > pointer to
> > > > > the region. I used RESERVEDMEM_OF_DECLARE currently(The code is
> > in
> > > > > [9/9]). Sorry if this is not right.
> > > >
> > > > If this is not for any hardware and you already understand this
> > (since
> > > > you cannot use other bindings) then you cannot have custom
> > bindings for
> > > > it either.
> > > >
> > > > >
> > > > > Then in our usage case, is there some similar method to do
> > this? or
> > > > > any other suggestion?
> > > >
> > > > Don't stuff software into DTS.
> > >
> > > Aren't most reserved-memory bindings just software policy if you
> > look at it
> > > that way, though? IIUC this is a pool of memory that is visible and
> > > available to the Non-Secure OS, but is fundamentally owned by the
> > Secure
> > > TEE, and pages that the TEE allocates from it will become
> > physically
> > > inaccessible to the OS. Thus the platform does impose constraints
> > on how the
> > > Non-Secure OS may use it, and per the rest of the reserved-memory
> > bindings,
> > > describing it as a "reusable" reservation seems entirely
> > appropriate. If
> > > anything that's *more* platform-related and so DT-relevant than
> > typical
> > > arbitrary reservations which just represent "save some memory to
> > dedicate to
> > > a particular driver" and don't actually bear any relationship to
> > firmware or
> > > hardware at all.
> >
> > Yes, a memory range defined by hardware or firmware is within scope
> > of
> > DT. (CMA at aribitrary address was questionable.)
>

Before I reply, my context is that I'm using these patches from
Mediatek on ChromeOS to implement secure video playback.

> I guess the memory range is not "defined" by HW in our case, but this
> reserve buffer is indeed prepared for and used by HW.
>
The memory range is defined in the firmware. The TEE is configured
with the same address/size that is being set in this DT node. (so
based on comments already, this is appropriate to put in the DT).

> If this is a normal reserved buffer for some device, we could define a
> reserved-memory with "shared-dma-pool", then the device use it via
> "memory-region" property, is this 

[PATCH v3 44/44] drm/nouveau/kms/nv50-: disable dcb parsing

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- nvkm should provide all this info now
- preparation for GSP-RM

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/nouveau_bios.c| 8 +---
 drivers/gpu/drm/nouveau/nouveau_display.c | 8 
 drivers/gpu/drm/nouveau/nvif/disp.c   | 2 +-
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c 
b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 189903b65edc9..9e878cdc8e38e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -2093,9 +2093,11 @@ nouveau_bios_init(struct drm_device *dev)
if (!NVInitVBIOS(dev))
return -ENODEV;
 
-   ret = parse_dcb_table(dev, bios);
-   if (ret)
-   return ret;
+   if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA) {
+   ret = parse_dcb_table(dev, bios);
+   if (ret)
+   return ret;
+   }
 
if (!bios->major_version)   /* we don't run version 0 bios */
return 0;
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c 
b/drivers/gpu/drm/nouveau/nouveau_display.c
index 99977e5fe7161..d8c92521226d9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -724,10 +724,10 @@ nouveau_display_create(struct drm_device *dev)
drm_kms_helper_poll_init(dev);
drm_kms_helper_poll_disable(dev);
 
-   if (nouveau_modeset != 2 && drm->vbios.dcb.entries) {
-   ret = nvif_disp_ctor(>client.device, "kmsDisp", 0,
->disp);
-   if (ret == 0) {
+   if (nouveau_modeset != 2) {
+   ret = nvif_disp_ctor(>client.device, "kmsDisp", 0, 
>disp);
+
+   if (!ret && (disp->disp.outp_mask || drm->vbios.dcb.entries)) {
nouveau_display_create_properties(dev);
if (disp->disp.object.oclass < NV50_DISP) {
dev->mode_config.fb_modifiers_not_supported = 
true;
diff --git a/drivers/gpu/drm/nouveau/nvif/disp.c 
b/drivers/gpu/drm/nouveau/nvif/disp.c
index 09915f2715afd..097246e10cdb7 100644
--- a/drivers/gpu/drm/nouveau/nvif/disp.c
+++ b/drivers/gpu/drm/nouveau/nvif/disp.c
@@ -60,7 +60,7 @@ nvif_disp_ctor(struct nvif_device *device, const char *name, 
s32 oclass, struct
cid = nvif_sclass(>object, disps, oclass);
disp->object.client = NULL;
if (cid < 0) {
-   NVIF_ERRON(cid, >object, "[NEW disp%04x] not 
supported", oclass);
+   NVIF_DEBUG(>object, "[NEW disp%04x] not supported", 
oclass);
return cid;
}
 
-- 
2.41.0



[PATCH v3 43/44] drm/nouveau/kms/nv50-: create outputs based on nvkm info

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- preparation for GSP-RM

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c   | 97 ++-
 drivers/gpu/drm/nouveau/dispnv50/disp.h   |  2 -
 drivers/gpu/drm/nouveau/include/nvif/if0012.h | 31 +-
 drivers/gpu/drm/nouveau/include/nvif/outp.h   | 40 
 drivers/gpu/drm/nouveau/nouveau_connector.c   |  2 +-
 drivers/gpu/drm/nouveau/nvif/outp.c   | 44 +
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c |  5 +-
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.h   |  2 +
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  | 50 ++
 9 files changed, 223 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index e2fa748e66f16..dcd19c4183894 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -66,8 +66,6 @@
 #include "nouveau_fence.h"
 #include "nv50_display.h"
 
-#include 
-
 /**
  * EVO channel
  */
@@ -1704,7 +1702,7 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, 
struct drm_atomic_state *sta
}
 
if (head->func->display_id)
-   head->func->display_id(head, BIT(nv_encoder->dcb->id));
+   head->func->display_id(head, BIT(nv_encoder->outp.id));
 
nv_encoder->update(nv_encoder, nv_crtc->index, asyh, proto, depth);
 }
@@ -1736,16 +1734,6 @@ nv50_sor_func = {
.destroy = nv50_sor_destroy,
 };
 
-bool nv50_has_mst(struct nouveau_drm *drm)
-{
-   struct nvkm_bios *bios = nvxx_bios(>client.device);
-   u32 data;
-   u8 ver, hdr, cnt, len;
-
-   data = nvbios_dp_table(bios, , , , );
-   return data && ver >= 0x40 && (nvbios_rd08(bios, data + 0x08) & 0x04);
-}
-
 static int
 nv50_sor_create(struct nouveau_encoder *nv_encoder)
 {
@@ -1798,15 +1786,15 @@ nv50_sor_create(struct nouveau_encoder *nv_encoder)
nv_encoder->i2c = _connector->aux.ddc;
}
 
-   if (nv_connector->type != DCB_CONNECTOR_eDP &&
-   nv50_has_mst(drm)) {
+   if (nv_connector->type != DCB_CONNECTOR_eDP && 
nv_encoder->outp.info.dp.mst) {
ret = nv50_mstm_new(nv_encoder, _connector->aux,
16, nv_connector->base.base.id,
_encoder->dp.mstm);
if (ret)
return ret;
}
-   } else {
+   } else
+   if (nv_encoder->outp.info.ddc != NVIF_OUTP_DDC_INVALID) {
struct nvkm_i2c_bus *bus =
nvkm_i2c_bus_find(i2c, dcbe->i2c_index);
if (bus)
@@ -1927,12 +1915,12 @@ nv50_pior_create(struct nouveau_encoder *nv_encoder)
 
switch (dcbe->type) {
case DCB_OUTPUT_TMDS:
-   bus  = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_EXT(dcbe->extdev));
+   bus  = nvkm_i2c_bus_find(i2c, nv_encoder->outp.info.ddc);
ddc  = bus ? >i2c : NULL;
type = DRM_MODE_ENCODER_TMDS;
break;
case DCB_OUTPUT_DP:
-   aux  = nvkm_i2c_aux_find(i2c, NVKM_I2C_AUX_EXT(dcbe->extdev));
+   aux  = nvkm_i2c_aux_find(i2c, nv_encoder->outp.info.dp.aux);
ddc  = aux ? >i2c : NULL;
type = DRM_MODE_ENCODER_TMDS;
break;
@@ -2693,12 +2681,10 @@ int
 nv50_display_create(struct drm_device *dev)
 {
struct nouveau_drm *drm = nouveau_drm(dev);
-   struct dcb_table *dcb = >vbios.dcb;
struct drm_connector *connector, *tmp;
struct nv50_disp *disp;
-   struct dcb_output *dcbe;
int ret, i;
-   bool has_mst = nv50_has_mst(drm);
+   bool has_mst = false;
 
disp = kzalloc(sizeof(*disp), GFP_KERNEL);
if (!disp)
@@ -2775,54 +2761,75 @@ nv50_display_create(struct drm_device *dev)
}
 
/* create encoder/connector objects based on VBIOS DCB table */
-   for (i = 0, dcbe = >entry[0]; i < dcb->entries; i++, dcbe++) {
+   for_each_set_bit(i, >disp->outp_mask, 
sizeof(disp->disp->outp_mask) * 8) {
struct nouveau_encoder *outp;
 
outp = kzalloc(sizeof(*outp), GFP_KERNEL);
if (!outp)
break;
 
-   ret = nvif_outp_ctor(disp->disp, "kmsOutp", dcbe->id, 
>outp);
+   ret = nvif_outp_ctor(disp->disp, "kmsOutp", i, >outp);
if (ret) {
kfree(outp);
continue;
}
 
-   connector = nouveau_connector_create(dev, dcbe->connector);
+   connector = nouveau_connector_create(dev, 

[PATCH v3 41/44] drm/nouveau/kms/nv50-: name aux channels after their connector

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- removes use of VBIOS data for naming
- preparation for GSP-RM

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/nouveau_connector.c | 25 -
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c 
b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 063cefe26be20..73657736ce838 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -400,10 +400,8 @@ nouveau_connector_destroy(struct drm_connector *connector)
kfree(nv_connector->edid);
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
-   if (nv_connector->aux.transfer) {
+   if (nv_connector->aux.transfer)
drm_dp_cec_unregister_connector(_connector->aux);
-   kfree(nv_connector->aux.name);
-   }
nvif_conn_dtor(_connector->conn);
kfree(connector);
 }
@@ -1280,13 +1278,11 @@ struct drm_connector *
 nouveau_connector_create(struct drm_device *dev,
 const struct dcb_output *dcbe)
 {
-   const struct drm_connector_funcs *funcs = _connector_funcs;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_display *disp = nouveau_display(dev);
struct nouveau_connector *nv_connector = NULL;
struct drm_connector *connector;
struct drm_connector_list_iter conn_iter;
-   char aux_name[48] = {0};
int index = dcbe->connector;
int type, ret = 0;
bool dummy;
@@ -1376,7 +1372,13 @@ nouveau_connector_create(struct drm_device *dev,
}
}
 
-   switch ((type = drm_conntype_from_dcb(nv_connector->type))) {
+   type = drm_conntype_from_dcb(nv_connector->type);
+   if (type == DRM_MODE_CONNECTOR_LVDS)
+   drm_connector_init(dev, connector, 
_connector_funcs_lvds, type);
+   else
+   drm_connector_init(dev, connector, _connector_funcs, 
type);
+
+   switch (type) {
case DRM_MODE_CONNECTOR_LVDS:
ret = nouveau_bios_parse_lvds_table(dev, 0, , );
if (ret) {
@@ -1385,24 +1387,16 @@ nouveau_connector_create(struct drm_device *dev,
return ERR_PTR(ret);
}
 
-   funcs = _connector_funcs_lvds;
break;
case DRM_MODE_CONNECTOR_DisplayPort:
case DRM_MODE_CONNECTOR_eDP:
nv_connector->aux.dev = connector->kdev;
nv_connector->aux.drm_dev = dev;
nv_connector->aux.transfer = nouveau_connector_aux_xfer;
-   snprintf(aux_name, sizeof(aux_name), "sor-%04x-%04x",
-dcbe->hasht, dcbe->hashm);
-   nv_connector->aux.name = kstrdup(aux_name, GFP_KERNEL);
-   if (!nv_connector->aux.name) {
-   kfree(nv_connector);
-   return ERR_PTR(-ENOMEM);
-   }
+   nv_connector->aux.name = connector->name;
drm_dp_aux_init(_connector->aux);
break;
default:
-   funcs = _connector_funcs;
break;
}
 
@@ -1417,7 +1411,6 @@ nouveau_connector_create(struct drm_device *dev,
connector->interlace_allowed = false;
connector->doublescan_allowed = false;
 
-   drm_connector_init(dev, connector, funcs, type);
drm_connector_helper_add(connector, _connector_helper_funcs);
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
 
-- 
2.41.0



[PATCH v3 39/44] drm/nouveau/kms/nv50-: create heads based on nvkm head mask

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

No need to go poking HW directly, and probably shouldn't on GSP-RM.

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 18 +++---
 1 file changed, 3 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index d6de5ee89d543..2134502ec04e2 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -2692,13 +2692,12 @@ nv50_display_destroy(struct drm_device *dev)
 int
 nv50_display_create(struct drm_device *dev)
 {
-   struct nvif_device *device = _drm(dev)->client.device;
struct nouveau_drm *drm = nouveau_drm(dev);
struct dcb_table *dcb = >vbios.dcb;
struct drm_connector *connector, *tmp;
struct nv50_disp *disp;
struct dcb_output *dcbe;
-   int crtcs, ret, i;
+   int ret, i;
bool has_mst = nv50_has_mst(drm);
 
disp = kzalloc(sizeof(*disp), GFP_KERNEL);
@@ -2776,20 +2775,9 @@ nv50_display_create(struct drm_device *dev)
}
 
/* create crtc objects to represent the hw heads */
-   if (disp->disp->object.oclass >= GV100_DISP)
-   crtcs = nvif_rd32(>object, 0x610060) & 0xff;
-   else
-   if (disp->disp->object.oclass >= GF110_DISP)
-   crtcs = nvif_rd32(>object, 0x612004) & 0xf;
-   else
-   crtcs = 0x3;
-
-   for (i = 0; i < fls(crtcs); i++) {
+   for_each_set_bit(i, >disp->head_mask, 
sizeof(disp->disp->head_mask) * 8) {
struct nv50_head *head;
 
-   if (!(crtcs & (1 << i)))
-   continue;
-
head = nv50_head_create(dev, i);
if (IS_ERR(head)) {
ret = PTR_ERR(head);
@@ -2814,7 +2802,7 @@ nv50_display_create(struct drm_device *dev)
 * Once these issues are closed, this should be
 * removed
 */
-   head->msto->encoder.possible_crtcs = crtcs;
+   head->msto->encoder.possible_crtcs = 
disp->disp->head_mask;
}
}
 
-- 
2.41.0



[PATCH v3 38/44] drm/nouveau/disp/nv50-: skip DCB_OUTPUT_TV

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

We've never supported it.

Signed-off-by: Ben Skeggs 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
index 4be09ec4fd5c2..2d05e2f7e46b8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
@@ -1656,7 +1656,6 @@ nv50_disp_oneinit(struct nvkm_disp *disp)
 
switch (dcbE.type) {
case DCB_OUTPUT_ANALOG:
-   case DCB_OUTPUT_TV:
case DCB_OUTPUT_TMDS:
case DCB_OUTPUT_LVDS:
ret = nvkm_outp_new(disp, i, , );
@@ -1664,6 +1663,7 @@ nv50_disp_oneinit(struct nvkm_disp *disp)
case DCB_OUTPUT_DP:
ret = nvkm_dp_new(disp, i, , );
break;
+   case DCB_OUTPUT_TV:
case DCB_OUTPUT_WFD:
/* No support for WFD yet. */
ret = -ENODEV;
-- 
2.41.0



[PATCH v3 40/44] drm/nouveau/kms/nv50-: create heads after outps/conns

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- output info will be used later to determine MST support

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 64 -
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 2134502ec04e2..26d59346703e3 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -2774,38 +2774,6 @@ nv50_display_create(struct drm_device *dev)
dev->mode_config.cursor_height = 64;
}
 
-   /* create crtc objects to represent the hw heads */
-   for_each_set_bit(i, >disp->head_mask, 
sizeof(disp->disp->head_mask) * 8) {
-   struct nv50_head *head;
-
-   head = nv50_head_create(dev, i);
-   if (IS_ERR(head)) {
-   ret = PTR_ERR(head);
-   goto out;
-   }
-
-   if (has_mst) {
-   head->msto = nv50_msto_new(dev, head, i);
-   if (IS_ERR(head->msto)) {
-   ret = PTR_ERR(head->msto);
-   head->msto = NULL;
-   goto out;
-   }
-
-   /*
-* FIXME: This is a hack to workaround the following
-* issues:
-*
-* https://gitlab.gnome.org/GNOME/mutter/issues/759
-* 
https://gitlab.freedesktop.org/xorg/xserver/merge_requests/277
-*
-* Once these issues are closed, this should be
-* removed
-*/
-   head->msto->encoder.possible_crtcs = 
disp->disp->head_mask;
-   }
-   }
-
/* create encoder/connector objects based on VBIOS DCB table */
for (i = 0, dcbe = >entry[0]; i < dcb->entries; i++, dcbe++) {
struct nouveau_encoder *outp;
@@ -2868,6 +2836,38 @@ nv50_display_create(struct drm_device *dev)
connector->funcs->destroy(connector);
}
 
+   /* create crtc objects to represent the hw heads */
+   for_each_set_bit(i, >disp->head_mask, 
sizeof(disp->disp->head_mask) * 8) {
+   struct nv50_head *head;
+
+   head = nv50_head_create(dev, i);
+   if (IS_ERR(head)) {
+   ret = PTR_ERR(head);
+   goto out;
+   }
+
+   if (has_mst) {
+   head->msto = nv50_msto_new(dev, head, i);
+   if (IS_ERR(head->msto)) {
+   ret = PTR_ERR(head->msto);
+   head->msto = NULL;
+   goto out;
+   }
+
+   /*
+* FIXME: This is a hack to workaround the following
+* issues:
+*
+* https://gitlab.gnome.org/GNOME/mutter/issues/759
+* 
https://gitlab.freedesktop.org/xorg/xserver/merge_requests/277
+*
+* Once these issues are closed, this should be
+* removed
+*/
+   head->msto->encoder.possible_crtcs = 
disp->disp->head_mask;
+   }
+   }
+
/* Disable vblank irqs aggressively for power-saving, safe on nv50+ */
dev->vblank_disable_immediate = true;
 
-- 
2.41.0



[PATCH v3 37/44] drm/nouveau/disp: move outp init/fini paths to chipset code

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- pre-nv5x doesn't use any of this
- preparation for GSP-RM

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 .../gpu/drm/nouveau/nvkm/engine/disp/base.c   | 31 +++
 .../gpu/drm/nouveau/nvkm/engine/disp/conn.c   | 10 --
 .../gpu/drm/nouveau/nvkm/engine/disp/conn.h   |  2 --
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c |  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/nv50.c   | 14 +
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.c   | 20 ++--
 6 files changed, 22 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
index 1dbe68f9a0e07..39f7e7ce9f4a2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
@@ -102,18 +102,14 @@ static int
 nvkm_disp_fini(struct nvkm_engine *engine, bool suspend)
 {
struct nvkm_disp *disp = nvkm_disp(engine);
-   struct nvkm_conn *conn;
struct nvkm_outp *outp;
 
if (disp->func->fini)
disp->func->fini(disp);
 
list_for_each_entry(outp, >outps, head) {
-   nvkm_outp_fini(outp);
-   }
-
-   list_for_each_entry(conn, >conns, head) {
-   nvkm_conn_fini(conn);
+   if (outp->func->fini)
+   outp->func->fini(outp);
}
 
return 0;
@@ -123,16 +119,12 @@ static int
 nvkm_disp_init(struct nvkm_engine *engine)
 {
struct nvkm_disp *disp = nvkm_disp(engine);
-   struct nvkm_conn *conn;
struct nvkm_outp *outp;
struct nvkm_ior *ior;
 
-   list_for_each_entry(conn, >conns, head) {
-   nvkm_conn_init(conn);
-   }
-
list_for_each_entry(outp, >outps, head) {
-   nvkm_outp_init(outp);
+   if (outp->func->init)
+   outp->func->init(outp);
}
 
if (disp->func->init) {
@@ -156,9 +148,7 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
 {
struct nvkm_disp *disp = nvkm_disp(engine);
struct nvkm_subdev *subdev = >engine.subdev;
-   struct nvkm_outp *outp;
struct nvkm_head *head;
-   struct nvkm_ior *ior;
int ret, i;
 
if (disp->func->oneinit) {
@@ -167,19 +157,6 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
return ret;
}
 
-   /* Enforce identity-mapped SOR assignment for panels, which have
-* certain bits (ie. backlight controls) wired to a specific SOR.
-*/
-   list_for_each_entry(outp, >outps, head) {
-   if (outp->conn->info.type == DCB_CONNECTOR_LVDS ||
-   outp->conn->info.type == DCB_CONNECTOR_eDP) {
-   ior = nvkm_ior_find(disp, SOR, ffs(outp->info.or) - 1);
-   if (!WARN_ON(!ior))
-   ior->identity = true;
-   outp->identity = true;
-   }
-   }
-
i = 0;
list_for_each_entry(head, >heads, head)
i = max(i, head->id + 1);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.c
index fbdae11378646..ff88a5a5253a7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.c
@@ -29,16 +29,6 @@
 
 #include 
 
-void
-nvkm_conn_fini(struct nvkm_conn *conn)
-{
-}
-
-void
-nvkm_conn_init(struct nvkm_conn *conn)
-{
-}
-
 void
 nvkm_conn_del(struct nvkm_conn **pconn)
 {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.h 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.h
index a0600e72b0ecd..01c3146c7066f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.h
@@ -19,8 +19,6 @@ struct nvkm_conn {
 int nvkm_conn_new(struct nvkm_disp *, int index, struct nvbios_connE *,
  struct nvkm_conn **);
 void nvkm_conn_del(struct nvkm_conn **);
-void nvkm_conn_init(struct nvkm_conn *);
-void nvkm_conn_fini(struct nvkm_conn *);
 
 #define CONN_MSG(c,l,f,a...) do {  
\
struct nvkm_conn *_conn = (c);\
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
index aaa7796946ceb..b35fae96d855d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
@@ -603,6 +603,7 @@ nvkm_dp_fini(struct nvkm_outp *outp)
 static void
 nvkm_dp_init(struct nvkm_outp *outp)
 {
+   nvkm_outp_init(outp);
nvkm_dp_enable(outp, outp->dp.enabled);
 }
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
index 7343b24f10eb7..4be09ec4fd5c2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
+++ 

[PATCH v3 36/44] drm/nouveau/disp: move outp/conn construction to chipset code

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- pre-nv5x doesn't use any of this, has its own version DRM-side
- preparation for GSP-RM

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 .../gpu/drm/nouveau/nvkm/engine/disp/base.c   | 117 +
 .../gpu/drm/nouveau/nvkm/engine/disp/nv50.c   | 122 +-
 2 files changed, 121 insertions(+), 118 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
index 73104b59f97fe..1dbe68f9a0e07 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
@@ -23,15 +23,12 @@
  */
 #include "priv.h"
 #include "conn.h"
-#include "dp.h"
 #include "head.h"
 #include "ior.h"
 #include "outp.h"
 
 #include 
 #include 
-#include 
-#include 
 
 #include 
 #include 
@@ -159,123 +156,11 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
 {
struct nvkm_disp *disp = nvkm_disp(engine);
struct nvkm_subdev *subdev = >engine.subdev;
-   struct nvkm_bios *bios = subdev->device->bios;
-   struct nvkm_outp *outp, *outt, *pair;
-   struct nvkm_conn *conn;
+   struct nvkm_outp *outp;
struct nvkm_head *head;
struct nvkm_ior *ior;
-   struct nvbios_connE connE;
-   struct dcb_output dcbE;
-   u8  hpd = 0, ver, hdr;
-   u32 data;
int ret, i;
 
-   /* Create output path objects for each VBIOS display path. */
-   i = -1;
-   while ((data = dcb_outp_parse(bios, ++i, , , ))) {
-   if (ver < 0x40) /* No support for chipsets prior to NV50. */
-   break;
-   if (dcbE.type == DCB_OUTPUT_UNUSED)
-   continue;
-   if (dcbE.type == DCB_OUTPUT_EOL)
-   break;
-   outp = NULL;
-
-   switch (dcbE.type) {
-   case DCB_OUTPUT_ANALOG:
-   case DCB_OUTPUT_TV:
-   case DCB_OUTPUT_TMDS:
-   case DCB_OUTPUT_LVDS:
-   ret = nvkm_outp_new(disp, i, , );
-   break;
-   case DCB_OUTPUT_DP:
-   ret = nvkm_dp_new(disp, i, , );
-   break;
-   case DCB_OUTPUT_WFD:
-   /* No support for WFD yet. */
-   ret = -ENODEV;
-   continue;
-   default:
-   nvkm_warn(subdev, "dcb %d type %d unknown\n",
- i, dcbE.type);
-   continue;
-   }
-
-   if (ret) {
-   if (outp) {
-   if (ret != -ENODEV)
-   OUTP_ERR(outp, "ctor failed: %d", ret);
-   else
-   OUTP_DBG(outp, "not supported");
-   nvkm_outp_del();
-   continue;
-   }
-   nvkm_error(subdev, "failed to create outp %d\n", i);
-   continue;
-   }
-
-   list_add_tail(>head, >outps);
-   hpd = max(hpd, (u8)(dcbE.connector + 1));
-   }
-
-   /* Create connector objects based on available output paths. */
-   list_for_each_entry_safe(outp, outt, >outps, head) {
-   /* VBIOS data *should* give us the most useful information. */
-   data = nvbios_connEp(bios, outp->info.connector, , ,
-);
-
-   /* No bios connector data... */
-   if (!data) {
-   /* Heuristic: anything with the same ccb index is
-* considered to be on the same connector, any
-* output path without an associated ccb entry will
-* be put on its own connector.
-*/
-   int ccb_index = outp->info.i2c_index;
-   if (ccb_index != 0xf) {
-   list_for_each_entry(pair, >outps, head) {
-   if (pair->info.i2c_index == ccb_index) {
-   outp->conn = pair->conn;
-   break;
-   }
-   }
-   }
-
-   /* Connector shared with another output path. */
-   if (outp->conn)
-   continue;
-
-   memset(, 0x00, sizeof(connE));
-   connE.type = DCB_CONNECTOR_NONE;
-   i = -1;
-   } else {
-   i = outp->info.connector;
-   }
-
-   /* Check that we haven't already created this connector. */
- 

[PATCH v3 35/44] drm/nouveau/disp: add dp mst id get/put methods

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- preparation for GSP-RM

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c   | 32 ---
 drivers/gpu/drm/nouveau/dispnv50/head.h   |  1 +
 drivers/gpu/drm/nouveau/dispnv50/headc57d.c   | 14 
 drivers/gpu/drm/nouveau/include/nvif/if0012.h | 18 +++
 drivers/gpu/drm/nouveau/include/nvif/outp.h   |  2 ++
 drivers/gpu/drm/nouveau/nvif/outp.c   | 29 +
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 15 +
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.h   |  2 ++
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  | 28 
 9 files changed, 137 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index d8ed23ddd2e4c..d6de5ee89d543 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -869,6 +869,8 @@ struct nv50_msto {
struct nv50_mstc *mstc;
bool disabled;
bool enabled;
+
+   u32 display_id;
 };
 
 struct nouveau_encoder *nv50_real_outp(struct drm_encoder *encoder)
@@ -897,10 +899,17 @@ nv50_msto_cleanup(struct drm_atomic_state *state,
drm_atomic_get_old_mst_topology_state(state, mgr);
const struct drm_dp_mst_atomic_payload *old_payload =
drm_atomic_get_mst_payload_state(old_mst_state, 
msto->mstc->port);
+   struct nv50_mstc *mstc = msto->mstc;
+   struct nv50_mstm *mstm = mstc->mstm;
 
NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
 
if (msto->disabled) {
+   if (msto->head->func->display_id) {
+   nvif_outp_dp_mst_id_put(>outp->outp, 
msto->display_id);
+   msto->display_id = 0;
+   }
+
msto->mstc = NULL;
msto->disabled = false;
drm_dp_remove_payload_part2(mgr, new_mst_state, old_payload, 
new_payload);
@@ -1041,6 +1050,11 @@ nv50_msto_atomic_enable(struct drm_encoder *encoder, 
struct drm_atomic_state *st
nouveau_dp_train(mstm->outp, true, 0, 0);
}
 
+   if (head->func->display_id) {
+   if (!WARN_ON(nvif_outp_dp_mst_id_get(>outp->outp, 
>display_id)))
+   head->func->display_id(head, msto->display_id);
+   }
+
if (mstm->outp->outp.or.link & 1)
proto = NV917D_SOR_SET_CONTROL_PROTOCOL_DP_A;
else
@@ -1061,6 +1075,9 @@ nv50_msto_atomic_disable(struct drm_encoder *encoder, 
struct drm_atomic_state *s
struct nv50_mstc *mstc = msto->mstc;
struct nv50_mstm *mstm = mstc->mstm;
 
+   if (msto->head->func->display_id)
+   msto->head->func->display_id(msto->head, 0);
+
mstm->outp->update(mstm->outp, msto->head->base.index, NULL, 0, 0);
mstm->modified = true;
if (!--mstm->links)
@@ -1544,7 +1561,7 @@ static void
 nv50_sor_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state 
*state)
 {
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
-   struct nouveau_crtc *nv_crtc = nouveau_crtc(nv_encoder->crtc);
+   struct nv50_head *head = nv50_head(nv_encoder->crtc);
struct nouveau_connector *nv_connector = 
nv50_outp_get_old_connector(state, nv_encoder);
 #ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
@@ -1563,7 +1580,7 @@ nv50_sor_atomic_disable(struct drm_encoder *encoder, 
struct drm_atomic_state *st
 #endif
 
if (nv_encoder->dcb->type == DCB_OUTPUT_TMDS && 
nv_encoder->hdmi.enabled) {
-   nvif_outp_hdmi(_encoder->outp, nv_crtc->index,
+   nvif_outp_hdmi(_encoder->outp, head->base.index,
   false, 0, 0, 0, false, false, false);
nv_encoder->hdmi.enabled = false;
}
@@ -1571,8 +1588,11 @@ nv50_sor_atomic_disable(struct drm_encoder *encoder, 
struct drm_atomic_state *st
if (nv_encoder->dcb->type == DCB_OUTPUT_DP)
nouveau_dp_power_down(nv_encoder);
 
-   nv_encoder->update(nv_encoder, nv_crtc->index, NULL, 0, 0);
-   nv50_audio_disable(encoder, nv_crtc);
+   if (head->func->display_id)
+   head->func->display_id(head, 0);
+
+   nv_encoder->update(nv_encoder, head->base.index, NULL, 0, 0);
+   nv50_audio_disable(encoder, >base);
nv_encoder->crtc = NULL;
 }
 
@@ -1585,6 +1605,7 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, 
struct drm_atomic_state *sta
nv50_head_atom(drm_atomic_get_new_crtc_state(state, 
_crtc->base));
struct drm_display_mode *mode = >state.adjusted_mode;
struct nv50_disp *disp = nv50_disp(encoder->dev);
+   struct nv50_head *head = nv50_head(_crtc->base);
struct nvif_outp *outp = _encoder->outp;
struct drm_device *dev = 

[PATCH v3 34/44] drm/nouveau/disp: add dp sst config method

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

This is presently unused on HW, we read a bunch of regs and calculate
the watermark during the second supervisor interrupt.

I don't want to change this yet as I need to re-remember how older HW
works exactly, but RM wants this info via RPC.

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/include/nvif/if0012.h | 12 +++
 drivers/gpu/drm/nouveau/include/nvif/outp.h   |  1 +
 drivers/gpu/drm/nouveau/nvif/outp.c   | 18 
 .../gpu/drm/nouveau/nvkm/engine/disp/ior.h|  2 ++
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  | 21 +++
 5 files changed, 54 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h 
b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
index 00ce0a46c152b..6fb297b65ae87 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
@@ -36,6 +36,7 @@ union nvif_outp_args {
 #define NVIF_OUTP_V0_DP_RATES  0x72
 #define NVIF_OUTP_V0_DP_TRAIN  0x73
 #define NVIF_OUTP_V0_DP_DRIVE  0x74
+#define NVIF_OUTP_V0_DP_SST0x75
 #define NVIF_OUTP_V0_DP_MST_VCPI   0x78
 
 union nvif_outp_detect_args {
@@ -222,6 +223,17 @@ union nvif_outp_dp_drive_args {
} v0;
 };
 
+union nvif_outp_dp_sst_args {
+   struct nvif_outp_dp_sst_v0 {
+   __u8  version;
+   __u8  head;
+   __u8  pad02[2];
+   __u32 watermark;
+   __u32 hblanksym;
+   __u32 vblanksym;
+   } v0;
+};
+
 union nvif_outp_dp_mst_vcpi_args {
struct nvif_outp_dp_mst_vcpi_v0 {
__u8  version;
diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h 
b/drivers/gpu/drm/nouveau/include/nvif/outp.h
index b4f97fabecbdc..881cbed5f0ee3 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/outp.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/outp.h
@@ -68,6 +68,7 @@ int nvif_outp_dp_train(struct nvif_outp *, u8 
dpcd[DP_RECEIVER_CAP_SIZE],
   u8 lttprs, u8 link_nr, u32 link_bw, bool mst, bool 
post_lt_adj,
   bool retrain);
 int nvif_outp_dp_drive(struct nvif_outp *, u8 link_nr, u8 pe[4], u8 vs[4]);
+int nvif_outp_dp_sst(struct nvif_outp *, int head, u32 watermark, u32 
hblanksym, u32 vblanksym);
 int nvif_outp_dp_mst_vcpi(struct nvif_outp *, int head,
  u8 start_slot, u8 num_slots, u16 pbn, u16 
aligned_pbn);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvif/outp.c 
b/drivers/gpu/drm/nouveau/nvif/outp.c
index 5fe5523587e6a..952103aa93b78 100644
--- a/drivers/gpu/drm/nouveau/nvif/outp.c
+++ b/drivers/gpu/drm/nouveau/nvif/outp.c
@@ -46,6 +46,24 @@ nvif_outp_dp_mst_vcpi(struct nvif_outp *outp, int head,
return ret;
 }
 
+int
+nvif_outp_dp_sst(struct nvif_outp *outp, int head, u32 watermark, u32 
hblanksym, u32 vblanksym)
+{
+   struct nvif_outp_dp_sst_v0 args;
+   int ret;
+
+   args.version = 0;
+   args.head = head;
+   args.watermark = watermark;
+   args.hblanksym = hblanksym;
+   args.vblanksym = vblanksym;
+   ret = nvif_object_mthd(>object, NVIF_OUTP_V0_DP_SST, , 
sizeof(args));
+   NVIF_ERRON(ret, >object,
+  "[DP_SST head:%d watermark:%d hblanksym:%d vblanksym:%d]",
+  args.head, args.watermark, args.hblanksym, args.vblanksym);
+   return ret;
+}
+
 int
 nvif_outp_dp_drive(struct nvif_outp *outp, u8 link_nr, u8 pe[4], u8 vs[4])
 {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
index 8686e5c044a5d..9beb9d1e86334 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
@@ -84,6 +84,8 @@ struct nvkm_ior_func {
void (*pattern)(struct nvkm_ior *, int pattern);
void (*drive)(struct nvkm_ior *, int ln, int pc,
  int dc, int pe, int tx_pu);
+   int (*sst)(struct nvkm_ior *, int head, bool ef,
+  u32 watermark, u32 hblanksym, u32 vblanksym);
void (*vcpi)(struct nvkm_ior *, int head, u8 slot,
 u8 slot_nr, u16 pbn, u16 aligned);
void (*audio)(struct nvkm_ior *, int head, bool enable);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index b634e76c2a9ba..225f88fbdae0f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -45,6 +45,26 @@ nvkm_uoutp_mthd_dp_mst_vcpi(struct nvkm_outp *outp, void 
*argv, u32 argc)
return 0;
 }
 
+static int
+nvkm_uoutp_mthd_dp_sst(struct nvkm_outp *outp, void *argv, u32 argc)
+{
+   union nvif_outp_dp_sst_args *args = argv;
+   struct nvkm_disp *disp = outp->disp;
+   struct nvkm_ior *ior = outp->ior;
+
+   if (argc != sizeof(args->v0) || 

[PATCH v3 29/44] drm/nouveau/kms/nv50-: split DP disable+enable into two modesets

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

Link training can finally be moved out of the supervisor sequence,
but first we need to split DP modesets into separate disable and
enable sequences to be able to perform link training between them
instead.

- preparation for GSP-RM

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index ee53bc5d10042..48e099ed7d51c 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -2375,7 +2375,8 @@ nv50_disp_outp_atomic_check_clr(struct nv50_atom *atom,
if (IS_ERR(outp))
return PTR_ERR(outp);
 
-   if (outp->encoder->encoder_type == DRM_MODE_ENCODER_DPMST) {
+   if (outp->encoder->encoder_type == DRM_MODE_ENCODER_DPMST ||
+   nouveau_encoder(outp->encoder)->dcb->type == DCB_OUTPUT_DP) 
{
outp->flush_disable = true;
atom->flush_disable = true;
}
-- 
2.41.0



[PATCH v3 33/44] drm/nouveau/disp: move link training out of supervisor

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- preparation for GSP-RM

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/include/nvif/if0012.h |  11 ++
 drivers/gpu/drm/nouveau/include/nvif/outp.h   |   1 +
 drivers/gpu/drm/nouveau/nouveau_dp.c  | 122 ++-
 drivers/gpu/drm/nouveau/nvif/outp.c   |  16 ++
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 148 +-
 .../gpu/drm/nouveau/nvkm/engine/disp/nv50.c   |  13 --
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.c   |  18 ++-
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.h   |   8 +-
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  |  27 +++-
 9 files changed, 218 insertions(+), 146 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h 
b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
index 14972b942be7e..00ce0a46c152b 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
@@ -35,6 +35,7 @@ union nvif_outp_args {
 #define NVIF_OUTP_V0_DP_AUX_XFER   0x71
 #define NVIF_OUTP_V0_DP_RATES  0x72
 #define NVIF_OUTP_V0_DP_TRAIN  0x73
+#define NVIF_OUTP_V0_DP_DRIVE  0x74
 #define NVIF_OUTP_V0_DP_MST_VCPI   0x78
 
 union nvif_outp_detect_args {
@@ -211,6 +212,16 @@ union nvif_outp_dp_train_args {
} v0;
 };
 
+union nvif_outp_dp_drive_args {
+   struct nvif_outp_dp_drive_v0 {
+   __u8  version;
+   __u8  pad01[2];
+   __u8  lanes;
+   __u8  pe[4];
+   __u8  vs[4];
+   } v0;
+};
+
 union nvif_outp_dp_mst_vcpi_args {
struct nvif_outp_dp_mst_vcpi_v0 {
__u8  version;
diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h 
b/drivers/gpu/drm/nouveau/include/nvif/outp.h
index 9a78483e0289d..b4f97fabecbdc 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/outp.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/outp.h
@@ -67,6 +67,7 @@ int nvif_outp_dp_rates(struct nvif_outp *, struct 
nvif_outp_dp_rate *rate, int r
 int nvif_outp_dp_train(struct nvif_outp *, u8 dpcd[DP_RECEIVER_CAP_SIZE],
   u8 lttprs, u8 link_nr, u32 link_bw, bool mst, bool 
post_lt_adj,
   bool retrain);
+int nvif_outp_dp_drive(struct nvif_outp *, u8 link_nr, u8 pe[4], u8 vs[4]);
 int nvif_outp_dp_mst_vcpi(struct nvif_outp *, int head,
  u8 start_slot, u8 num_slots, u16 pbn, u16 
aligned_pbn);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c 
b/drivers/gpu/drm/nouveau/nouveau_dp.c
index 9280daf325341..7de7707ec6a89 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -320,15 +320,83 @@ nouveau_dp_power_down(struct nouveau_encoder *outp)
 static bool
 nouveau_dp_train_link(struct nouveau_encoder *outp, bool retrain)
 {
-   int ret;
+   struct drm_dp_aux *aux = >conn->aux;
+   bool post_lt = false;
+   int ret, retries = 0;
+
+   if ( (outp->dp.dpcd[DP_MAX_LANE_COUNT] & 0x20) &&
+   !(outp->dp.dpcd[DP_MAX_DOWNSPREAD] & DP_TPS4_SUPPORTED))
+   post_lt = true;
 
+retry:
ret = nvif_outp_dp_train(>outp, outp->dp.dpcd,
  outp->dp.lttpr.nr,
  outp->dp.lt.nr,
  outp->dp.lt.bw,
  outp->dp.lt.mst,
- false,
+ post_lt,
  retrain);
+   if (ret)
+   return false;
+
+   if (post_lt) {
+   u8 stat[DP_LINK_STATUS_SIZE];
+   u8 prev[2];
+   u8 time = 0, adjusts = 0, tmp;
+
+   ret = drm_dp_dpcd_read_phy_link_status(aux, DP_PHY_DPRX, stat);
+   if (ret)
+   return false;
+
+   for (;;) {
+   if (!drm_dp_channel_eq_ok(stat, outp->dp.lt.nr)) {
+   ret = 1;
+   break;
+   }
+
+   if (!(stat[2] & 0x02))
+   break;
+
+   msleep(5);
+   time += 5;
+
+   memcpy(prev, [4], sizeof(prev));
+   ret = drm_dp_dpcd_read_phy_link_status(aux, 
DP_PHY_DPRX, stat);
+   if (ret)
+   break;
+
+   if (!memcmp(prev, [4], sizeof(prev))) {
+   if (time > 200)
+   break;
+   } else {
+   u8 pe[4], vs[4];
+
+   if (adjusts++ == 6)
+   break;
+
+   for (int i = 0; i < outp->dp.lt.nr; i++) {
+   

[PATCH v3 32/44] drm/nouveau/disp: add dp train method

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- passes DPCD information from DRM to NVKM
- removes NVKM's own sink caps handling
- link still trained from supervisor, more patches to come

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c   |   6 +-
 drivers/gpu/drm/nouveau/include/nvif/if0012.h |  25 ++--
 drivers/gpu/drm/nouveau/include/nvif/outp.h   |   7 +-
 drivers/gpu/drm/nouveau/nouveau_dp.c  |  75 +--
 drivers/gpu/drm/nouveau/nouveau_encoder.h |   7 ++
 drivers/gpu/drm/nouveau/nvif/outp.c   |  38 +++---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 118 +++---
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.h   |   2 +
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  |  41 +++---
 9 files changed, 143 insertions(+), 176 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 1ea4b113058cd..d8ed23ddd2e4c 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1038,7 +1038,7 @@ nv50_msto_atomic_enable(struct drm_encoder *encoder, 
struct drm_atomic_state *st
 
if (!mstm->links++) {
nvif_outp_acquire_sor(>outp->outp, false /*TODO: MST 
audio... */);
-   nvif_outp_acquire_dp(>outp->outp, mstm->outp->dp.dpcd, 0, 
0, false, true);
+   nouveau_dp_train(mstm->outp, true, 0, 0);
}
 
if (mstm->outp->outp.or.link & 1)
@@ -1661,7 +1661,7 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, 
struct drm_atomic_state *sta
nvif_outp_lvds(_encoder->outp, lvds_dual, lvds_8bpc);
break;
case DCB_OUTPUT_DP:
-   nvif_outp_acquire_dp(_encoder->outp, nv_encoder->dp.dpcd, 0, 
0, hda, false);
+   nouveau_dp_train(nv_encoder, false, mode->clock, asyh->or.bpc);
depth = nv50_dp_bpc_to_depth(asyh->or.bpc);
 
if (nv_encoder->outp.or.link & 1)
@@ -1852,7 +1852,7 @@ nv50_pior_atomic_enable(struct drm_encoder *encoder, 
struct drm_atomic_state *st
break;
case DCB_OUTPUT_DP:
ctrl |= NVDEF(NV507D, PIOR_SET_CONTROL, PROTOCOL, EXT_TMDS_ENC);
-   nvif_outp_acquire_dp(_encoder->outp, nv_encoder->dp.dpcd, 0, 
0, false, false);
+   nouveau_dp_train(nv_encoder, false, 
asyh->state.adjusted_mode.clock, 6);
break;
default:
BUG();
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h 
b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
index ddc8e3d858235..14972b942be7e 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
@@ -34,7 +34,7 @@ union nvif_outp_args {
 #define NVIF_OUTP_V0_DP_AUX_PWR0x70
 #define NVIF_OUTP_V0_DP_AUX_XFER   0x71
 #define NVIF_OUTP_V0_DP_RATES  0x72
-#define NVIF_OUTP_V0_DP_RETRAIN0x73
+#define NVIF_OUTP_V0_DP_TRAIN  0x73
 #define NVIF_OUTP_V0_DP_MST_VCPI   0x78
 
 union nvif_outp_detect_args {
@@ -71,7 +71,6 @@ union nvif_outp_acquire_args {
 #define NVIF_OUTP_ACQUIRE_V0_DAC  0x00
 #define NVIF_OUTP_ACQUIRE_V0_SOR  0x01
 #define NVIF_OUTP_ACQUIRE_V0_PIOR 0x02
-#define NVIF_OUTP_ACQUIRE_V0_DP  0x04
__u8 type;
__u8 or;
__u8 link;
@@ -80,14 +79,6 @@ union nvif_outp_acquire_args {
struct {
__u8 hda;
} sor;
-   struct {
-   __u8 link_nr; /* 0 = highest possible. */
-   __u8 link_bw; /* 0 = highest possible, DP BW 
code otherwise. */
-   __u8 hda;
-   __u8 mst;
-   __u8 pad04[4];
-   __u8 dpcd[DP_RECEIVER_CAP_SIZE];
-   } dp;
};
} v0;
 };
@@ -207,9 +198,17 @@ union nvif_outp_dp_rates_args {
} v0;
 };
 
-union nvif_outp_dp_retrain_args {
-   struct nvif_outp_dp_retrain_vn {
-   } vn;
+union nvif_outp_dp_train_args {
+   struct nvif_outp_dp_train_v0 {
+   __u8  version;
+   __u8  retrain;
+   __u8  mst;
+   __u8  lttprs;
+   __u8  post_lt_adj;
+   __u8  link_nr;
+   __u32 link_bw;
+   __u8 dpcd[DP_RECEIVER_CAP_SIZE];
+   } v0;
 };
 
 union nvif_outp_dp_mst_vcpi_args {
diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h 
b/drivers/gpu/drm/nouveau/include/nvif/outp.h
index 596d543acd302..9a78483e0289d 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/outp.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/outp.h
@@ -31,8 +31,6 @@ int nvif_outp_load_detect(struct nvif_outp *, u32 loadval);
 int nvif_outp_acquire_dac(struct nvif_outp *);
 int nvif_outp_acquire_sor(struct nvif_outp *, bool hda);
 int 

[PATCH v3 31/44] drm/nouveau/kms/nv50-: fixup sink D3 before tearing down link

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- fixes bug preventing this on SST
- implement for MST

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c   | 13 +++--
 drivers/gpu/drm/nouveau/nouveau_dp.c  | 15 +++
 drivers/gpu/drm/nouveau/nouveau_encoder.h |  1 +
 3 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 1fcd1b36a2751..1ea4b113058cd 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1300,6 +1300,7 @@ nv50_mstm_cleanup(struct drm_atomic_state *state,
}
 
if (mstm->disabled) {
+   nouveau_dp_power_down(mstm->outp);
nvif_outp_release(>outp->outp);
mstm->disabled = false;
}
@@ -1551,7 +1552,6 @@ nv50_sor_atomic_disable(struct drm_encoder *encoder, 
struct drm_atomic_state *st
 #endif
struct drm_dp_aux *aux = _connector->aux;
int ret;
-   u8 pwr;
 
 #ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
if (backlight && backlight->uses_dpcd) {
@@ -1568,15 +1568,8 @@ nv50_sor_atomic_disable(struct drm_encoder *encoder, 
struct drm_atomic_state *st
nv_encoder->hdmi.enabled = false;
}
 
-   if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
-   ret = drm_dp_dpcd_readb(aux, DP_SET_POWER, );
-
-   if (ret == 0) {
-   pwr &= ~DP_SET_POWER_MASK;
-   pwr |=  DP_SET_POWER_D3;
-   drm_dp_dpcd_writeb(aux, DP_SET_POWER, pwr);
-   }
-   }
+   if (nv_encoder->dcb->type == DCB_OUTPUT_DP)
+   nouveau_dp_power_down(nv_encoder);
 
nv_encoder->update(nv_encoder, nv_crtc->index, NULL, 0, 0);
nv50_audio_disable(encoder, nv_crtc);
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c 
b/drivers/gpu/drm/nouveau/nouveau_dp.c
index f26769bca1950..1c0b992fe2416 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -284,6 +284,21 @@ nouveau_dp_detect(struct nouveau_connector *nv_connector,
return ret;
 }
 
+void
+nouveau_dp_power_down(struct nouveau_encoder *outp)
+{
+   struct drm_dp_aux *aux = >conn->aux;
+   int ret;
+   u8 pwr;
+
+   ret = drm_dp_dpcd_readb(aux, DP_SET_POWER, );
+   if (ret == 1) {
+   pwr &= ~DP_SET_POWER_MASK;
+   pwr |=  DP_SET_POWER_D3;
+   drm_dp_dpcd_writeb(aux, DP_SET_POWER, pwr);
+   }
+}
+
 bool
 nouveau_dp_link_check(struct nouveau_connector *nv_connector)
 {
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h 
b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index 123d0ecf5f586..ed31db58176c3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -155,6 +155,7 @@ enum nouveau_dp_status {
 };
 
 int nouveau_dp_detect(struct nouveau_connector *, struct nouveau_encoder *);
+void nouveau_dp_power_down(struct nouveau_encoder *);
 bool nouveau_dp_link_check(struct nouveau_connector *);
 void nouveau_dp_irq(struct work_struct *);
 enum drm_mode_status nv50_dp_mode_valid(struct nouveau_encoder *,
-- 
2.41.0



[PATCH v3 30/44] drm/nouveau/kms/nv50-: flush mst disables together

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- fixes some issues tearing down modes on tiled displays

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 11 +--
 drivers/gpu/drm/nouveau/dispnv50/disp.h |  1 -
 2 files changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 48e099ed7d51c..1fcd1b36a2751 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -2084,13 +2084,6 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state 
*state)
help->atomic_disable(encoder, state);
outp->disabled = true;
interlock[NV50_DISP_INTERLOCK_CORE] |= 1;
-   if (outp->flush_disable) {
-   nv50_disp_atomic_commit_wndw(state, interlock);
-   nv50_disp_atomic_commit_core(state, interlock);
-   memset(interlock, 0x00, sizeof(interlock));
-
-   flushed = true;
-   }
}
}
 
@@ -2376,10 +2369,8 @@ nv50_disp_outp_atomic_check_clr(struct nv50_atom *atom,
return PTR_ERR(outp);
 
if (outp->encoder->encoder_type == DRM_MODE_ENCODER_DPMST ||
-   nouveau_encoder(outp->encoder)->dcb->type == DCB_OUTPUT_DP) 
{
-   outp->flush_disable = true;
+   nouveau_encoder(outp->encoder)->dcb->type == DCB_OUTPUT_DP)
atom->flush_disable = true;
-   }
outp->clr.ctrl = true;
atom->lock_core = true;
}
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.h 
b/drivers/gpu/drm/nouveau/dispnv50/disp.h
index 42209f5b06f91..1e5601223c753 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.h
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.h
@@ -83,7 +83,6 @@ struct nv50_outp_atom {
struct list_head head;
 
struct drm_encoder *encoder;
-   bool flush_disable;
 
bool disabled;
bool enabled;
-- 
2.41.0



[PATCH v3 28/44] drm/nouveau/disp: add dp rates method

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- moves building of link rates table from NVKM to DRM
- preparing to move link training out of supervisor

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/include/nvif/if0012.h |  13 ++
 drivers/gpu/drm/nouveau/include/nvif/outp.h   |   8 +
 drivers/gpu/drm/nouveau/nouveau_dp.c  | 143 ++
 drivers/gpu/drm/nouveau/nouveau_encoder.h |  12 +-
 drivers/gpu/drm/nouveau/nvif/outp.c   |  21 +++
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c |  66 
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.h   |   1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  |  24 +++
 8 files changed, 189 insertions(+), 99 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h 
b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
index 94f1e55b0ce6c..ddc8e3d858235 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
@@ -33,6 +33,7 @@ union nvif_outp_args {
 
 #define NVIF_OUTP_V0_DP_AUX_PWR0x70
 #define NVIF_OUTP_V0_DP_AUX_XFER   0x71
+#define NVIF_OUTP_V0_DP_RATES  0x72
 #define NVIF_OUTP_V0_DP_RETRAIN0x73
 #define NVIF_OUTP_V0_DP_MST_VCPI   0x78
 
@@ -194,6 +195,18 @@ union nvif_outp_dp_aux_xfer_args {
} v0;
 };
 
+union nvif_outp_dp_rates_args {
+   struct nvif_outp_dp_rates_v0 {
+   __u8  version;
+   __u8  pad01[6];
+   __u8  rates;
+   struct {
+   __s8  dpcd;
+   __u32 rate;
+   } rate[8];
+   } v0;
+};
+
 union nvif_outp_dp_retrain_args {
struct nvif_outp_dp_retrain_vn {
} vn;
diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h 
b/drivers/gpu/drm/nouveau/include/nvif/outp.h
index dd4dd0e2a7a1d..596d543acd302 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/outp.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/outp.h
@@ -59,6 +59,14 @@ int nvif_outp_hda_eld(struct nvif_outp *, int head, void 
*data, u32 size);
 
 int nvif_outp_dp_aux_pwr(struct nvif_outp *, bool enable);
 int nvif_outp_dp_aux_xfer(struct nvif_outp *, u8 type, u8 *size, u32 addr, u8 
*data);
+
+struct nvif_outp_dp_rate {
+   int dpcd; /* -1 for non-indexed rates */
+   u32 rate;
+};
+
+int nvif_outp_dp_rates(struct nvif_outp *, struct nvif_outp_dp_rate *rate, int 
rate_nr);
+
 int nvif_outp_dp_retrain(struct nvif_outp *);
 int nvif_outp_dp_mst_vcpi(struct nvif_outp *, int head,
  u8 start_slot, u8 num_slots, u16 pbn, u16 
aligned_pbn);
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c 
b/drivers/gpu/drm/nouveau/nouveau_dp.c
index 01aa9b9c74a2a..f26769bca1950 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -42,6 +42,21 @@ nouveau_dp_has_sink_count(struct drm_connector *connector,
return drm_dp_read_sink_count_cap(connector, outp->dp.dpcd, 
>dp.desc);
 }
 
+static bool
+nouveau_dp_probe_lttpr(struct nouveau_encoder *outp)
+{
+   u8 rev, size = sizeof(rev);
+   int ret;
+
+   ret = nvif_outp_dp_aux_xfer(>outp, DP_AUX_NATIVE_READ, ,
+   
DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV,
+   );
+   if (ret || size < sizeof(rev) || rev < 0x14)
+   return false;
+
+   return true;
+}
+
 static enum drm_connector_status
 nouveau_dp_probe_dpcd(struct nouveau_connector *nv_connector,
  struct nouveau_encoder *outp)
@@ -53,10 +68,99 @@ nouveau_dp_probe_dpcd(struct nouveau_connector 
*nv_connector,
int ret;
u8 *dpcd = outp->dp.dpcd;
 
+   outp->dp.lttpr.nr = 0;
+   outp->dp.rate_nr  = 0;
+   outp->dp.link_nr  = 0;
+   outp->dp.link_bw  = 0;
+
+   if (connector->connector_type != DRM_MODE_CONNECTOR_eDP &&
+   nouveau_dp_probe_lttpr(outp) &&
+   !drm_dp_read_dpcd_caps(aux, dpcd) &&
+   !drm_dp_read_lttpr_common_caps(aux, dpcd, outp->dp.lttpr.caps)) {
+   int nr = drm_dp_lttpr_count(outp->dp.lttpr.caps);
+
+   if (nr > 0)
+   outp->dp.lttpr.nr = nr;
+   }
+
ret = drm_dp_read_dpcd_caps(aux, dpcd);
if (ret < 0)
goto out;
 
+   outp->dp.link_nr = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
+   if (outp->dcb->dpconf.link_nr < outp->dp.link_nr)
+   outp->dp.link_nr = outp->dcb->dpconf.link_nr;
+
+   if (outp->dp.lttpr.nr) {
+   int links = drm_dp_lttpr_max_lane_count(outp->dp.lttpr.caps);
+
+   if (links && links < outp->dp.link_nr)
+   outp->dp.link_nr = links;
+   }
+
+   if (connector->connector_type == DRM_MODE_CONNECTOR_eDP && 
dpcd[DP_DPCD_REV] >= 0x13) {
+   __le16 rates[DP_MAX_SUPPORTED_RATES];
+
+   ret = drm_dp_dpcd_read(aux, DP_SUPPORTED_LINK_RATES, rates, 

[PATCH v3 27/44] drm/nouveau/disp: add dp aux xfer method

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- preparation for GSP-RM

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c   | 32 +--
 drivers/gpu/drm/nouveau/include/nvif/if0012.h | 12 +++
 drivers/gpu/drm/nouveau/include/nvif/outp.h   |  2 ++
 drivers/gpu/drm/nouveau/nouveau_connector.c   | 12 ++-
 drivers/gpu/drm/nouveau/nouveau_encoder.h |  1 -
 drivers/gpu/drm/nouveau/nvif/outp.c   | 24 ++
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 14 
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.h   |  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  | 27 +---
 9 files changed, 94 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 11b11284a3218..ee53bc5d10042 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1704,14 +1704,13 @@ nv50_sor_destroy(struct drm_encoder *encoder)
 {
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
 
-   nvif_outp_dtor(_encoder->outp);
-
nv50_mstm_del(_encoder->dp.mstm);
drm_encoder_cleanup(encoder);
 
if (nv_encoder->dcb->type == DCB_OUTPUT_DP)
mutex_destroy(_encoder->dp.hpd_irq_lock);
 
+   nvif_outp_dtor(_encoder->outp);
kfree(encoder);
 }
 
@@ -1764,22 +1763,22 @@ nv50_sor_create(struct nouveau_encoder *nv_encoder)
nv50_outp_dump_caps(drm, nv_encoder);
 
if (dcbe->type == DCB_OUTPUT_DP) {
-   struct nvkm_i2c_aux *aux =
-   nvkm_i2c_aux_find(i2c, dcbe->i2c_index);
-
mutex_init(_encoder->dp.hpd_irq_lock);
 
-   if (aux) {
-   if (disp->disp->object.oclass < GF110_DISP) {
-   /* HW has no support for address-only
-* transactions, so we're required to
-* use custom I2C-over-AUX code.
-*/
-   nv_encoder->i2c = >i2c;
-   } else {
-   nv_encoder->i2c = _connector->aux.ddc;
-   }
-   nv_encoder->aux = aux;
+   if (disp->disp->object.oclass < GF110_DISP) {
+   /* HW has no support for address-only
+* transactions, so we're required to
+* use custom I2C-over-AUX code.
+*/
+   struct nvkm_i2c_aux *aux;
+
+   aux = nvkm_i2c_aux_find(i2c, dcbe->i2c_index);
+   if (!aux)
+   return -EINVAL;
+
+   nv_encoder->i2c = >i2c;
+   } else {
+   nv_encoder->i2c = _connector->aux.ddc;
}
 
if (nv_connector->type != DCB_CONNECTOR_eDP &&
@@ -1925,7 +1924,6 @@ nv50_pior_create(struct nouveau_encoder *nv_encoder)
}
 
nv_encoder->i2c = ddc;
-   nv_encoder->aux = aux;
 
encoder = to_drm_encoder(nv_encoder);
drm_encoder_init(connector->dev, encoder, _pior_func, type,
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h 
b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
index ee4cec541a90e..94f1e55b0ce6c 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
@@ -32,6 +32,7 @@ union nvif_outp_args {
 #define NVIF_OUTP_V0_HDA_ELD   0x61
 
 #define NVIF_OUTP_V0_DP_AUX_PWR0x70
+#define NVIF_OUTP_V0_DP_AUX_XFER   0x71
 #define NVIF_OUTP_V0_DP_RETRAIN0x73
 #define NVIF_OUTP_V0_DP_MST_VCPI   0x78
 
@@ -182,6 +183,17 @@ union nvif_outp_dp_aux_pwr_args {
} v0;
 };
 
+union nvif_outp_dp_aux_xfer_args {
+   struct nvif_outp_dp_aux_xfer_v0 {
+   __u8  version;
+   __u8  pad01;
+   __u8  type;
+   __u8  size;
+   __u32 addr;
+   __u8  data[16];
+   } v0;
+};
+
 union nvif_outp_dp_retrain_args {
struct nvif_outp_dp_retrain_vn {
} vn;
diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h 
b/drivers/gpu/drm/nouveau/include/nvif/outp.h
index 0ddaec9416eed..dd4dd0e2a7a1d 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/outp.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/outp.h
@@ -56,7 +56,9 @@ int nvif_outp_hdmi(struct nvif_outp *, int head, bool enable, 
u8 max_ac_packet,
 
 int nvif_outp_infoframe(struct nvif_outp *, u8 type, struct 
nvif_outp_infoframe_v0 *, u32 size);
 int nvif_outp_hda_eld(struct nvif_outp *, int head, void *data, u32 size);
+
 int nvif_outp_dp_aux_pwr(struct nvif_outp *, bool enable);
+int nvif_outp_dp_aux_xfer(struct nvif_outp *, u8 type, u8 *size, u32 addr, u8 
*data);
 int nvif_outp_dp_retrain(struct nvif_outp *);
 int 

[PATCH v3 26/44] drm/nouveau/disp: move dp aux pwr method to HAL

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- preparation for GSP-RM

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c| 9 +
 drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h  | 4 
 drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c | 6 +++---
 3 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
index 0e6e388003765..99fe7ef07a443 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
@@ -41,6 +41,14 @@
  */
 #define AMPERE_IED_HACK(disp) ((disp)->engine.subdev.device->card_type >= 
GA100)
 
+static int
+nvkm_dp_aux_pwr(struct nvkm_outp *outp, bool pu)
+{
+   outp->dp.enabled = pu;
+   nvkm_dp_enable(outp, outp->dp.enabled);
+   return 0;
+}
+
 struct lt_state {
struct nvkm_outp *outp;
 
@@ -814,6 +822,7 @@ nvkm_dp_func = {
.disable = nvkm_dp_disable,
.bl.get = nvkm_outp_bl_get,
.bl.set = nvkm_outp_bl_set,
+   .dp.aux_pwr = nvkm_dp_aux_pwr,
 };
 
 int
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
index 38b6b43a9f200..513794a278a91 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
@@ -104,6 +104,10 @@ struct nvkm_outp_func {
int (*get)(struct nvkm_outp *);
int (*set)(struct nvkm_outp *, int level);
} bl;
+
+   struct {
+   int (*aux_pwr)(struct nvkm_outp *, bool pu);
+   } dp;
 };
 
 #define OUTP_MSG(o,l,f,a...) do {  
\
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index 7574f22006441..6ca364e953bd7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -75,10 +75,10 @@ nvkm_uoutp_mthd_dp_aux_pwr(struct nvkm_outp *outp, void 
*argv, u32 argc)
 
if (argc != sizeof(args->v0) || args->v0.version != 0)
return -ENOSYS;
+   if (!outp->func->dp.aux_pwr)
+   return -EINVAL;
 
-   outp->dp.enabled = !!args->v0.state;
-   nvkm_dp_enable(outp, outp->dp.enabled);
-   return 0;
+   return outp->func->dp.aux_pwr(outp, !!args->v0.state);
 }
 
 static int
-- 
2.41.0



[PATCH v3 25/44] drm/nouveau/disp: add hdmi audio hal function

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

This just adds a hook for RM to use, HW paths remain untouched, but
should probably be cleaned up to use this too at some point.

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h   |  1 +
 drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c | 10 +-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
index 6e750890bcc93..8686e5c044a5d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
@@ -74,6 +74,7 @@ struct nvkm_ior_func {
 bool scrambling_low_rates);
void (*infoframe_avi)(struct nvkm_ior *, int head, void *data, 
u32 size);
void (*infoframe_vsi)(struct nvkm_ior *, int head, void *data, 
u32 size);
+   void (*audio)(struct nvkm_ior *, int head, bool enable);
} *hdmi;
 
const struct nvkm_ior_func_dp {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index ad75dc5c50cf7..7574f22006441 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -99,12 +99,20 @@ nvkm_uoutp_mthd_hda_eld(struct nvkm_outp *outp, void *argv, 
u32 argc)
if (argc && args->v0.data[0]) {
if (outp->info.type == DCB_OUTPUT_DP)
ior->func->dp->audio(ior, args->v0.head, true);
+   else
+   if (ior->func->hdmi->audio)
+   ior->func->hdmi->audio(ior, args->v0.head, true);
+
ior->func->hda->hpd(ior, args->v0.head, true);
ior->func->hda->eld(ior, args->v0.head, args->v0.data, argc);
} else {
+   ior->func->hda->hpd(ior, args->v0.head, false);
+
if (outp->info.type == DCB_OUTPUT_DP)
ior->func->dp->audio(ior, args->v0.head, false);
-   ior->func->hda->hpd(ior, args->v0.head, false);
+   else
+   if (ior->func->hdmi->audio)
+   ior->func->hdmi->audio(ior, args->v0.head, false);
}
 
return 0;
-- 
2.41.0



[PATCH v3 24/44] drm/nouveau/disp: add output lvds config method

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- was previously part of acquire()

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c  |  2 +-
 drivers/gpu/drm/nouveau/include/nvif/if0012.h| 16 ++--
 drivers/gpu/drm/nouveau/include/nvif/outp.h  |  3 ++-
 drivers/gpu/drm/nouveau/nvif/outp.c  | 15 +++
 drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c | 14 --
 5 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 50a0ff304291e..11b11284a3218 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1665,7 +1665,7 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, 
struct drm_atomic_state *sta
lvds_8bpc = true;
}
 
-   nvif_outp_acquire_lvds(_encoder->outp, lvds_dual, lvds_8bpc);
+   nvif_outp_lvds(_encoder->outp, lvds_dual, lvds_8bpc);
break;
case DCB_OUTPUT_DP:
nvif_outp_acquire_dp(_encoder->outp, nv_encoder->dp.dpcd, 0, 
0, hda, false);
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h 
b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
index f878784593b43..ee4cec541a90e 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
@@ -24,6 +24,8 @@ union nvif_outp_args {
 #define NVIF_OUTP_V0_BL_GET0x30
 #define NVIF_OUTP_V0_BL_SET0x31
 
+#define NVIF_OUTP_V0_LVDS  0x40
+
 #define NVIF_OUTP_V0_HDMI  0x50
 
 #define NVIF_OUTP_V0_INFOFRAME 0x60
@@ -67,7 +69,6 @@ union nvif_outp_acquire_args {
 #define NVIF_OUTP_ACQUIRE_V0_DAC  0x00
 #define NVIF_OUTP_ACQUIRE_V0_SOR  0x01
 #define NVIF_OUTP_ACQUIRE_V0_PIOR 0x02
-#define NVIF_OUTP_ACQUIRE_V0_LVDS0x03
 #define NVIF_OUTP_ACQUIRE_V0_DP  0x04
__u8 type;
__u8 or;
@@ -77,11 +78,6 @@ union nvif_outp_acquire_args {
struct {
__u8 hda;
} sor;
-   struct {
-   __u8 dual;
-   __u8 bpc8;
-   __u8 pad02[6];
-   } lvds;
struct {
__u8 link_nr; /* 0 = highest possible. */
__u8 link_bw; /* 0 = highest possible, DP BW 
code otherwise. */
@@ -135,6 +131,14 @@ union nvif_outp_bl_set_args {
} v0;
 };
 
+union nvif_outp_lvds_args {
+   struct nvif_outp_lvds_v0 {
+   __u8  version;
+   __u8  dual;
+   __u8  bpc8;
+   } v0;
+};
+
 union nvif_outp_hdmi_args {
struct nvif_outp_hdmi_v0 {
__u8 version;
diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h 
b/drivers/gpu/drm/nouveau/include/nvif/outp.h
index ef63d22b62f84..0ddaec9416eed 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/outp.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/outp.h
@@ -31,7 +31,6 @@ int nvif_outp_load_detect(struct nvif_outp *, u32 loadval);
 int nvif_outp_acquire_dac(struct nvif_outp *);
 int nvif_outp_acquire_sor(struct nvif_outp *, bool hda);
 int nvif_outp_acquire_pior(struct nvif_outp *);
-int nvif_outp_acquire_lvds(struct nvif_outp *, bool dual, bool bpc8);
 int nvif_outp_acquire_dp(struct nvif_outp *outp, u8 dpcd[DP_RECEIVER_CAP_SIZE],
 int link_nr, int link_bw, bool hda, bool mst);
 int nvif_outp_inherit_rgb_crt(struct nvif_outp *outp, u8 *proto_out);
@@ -50,6 +49,8 @@ nvif_outp_acquired(struct nvif_outp *outp)
 int nvif_outp_bl_get(struct nvif_outp *);
 int nvif_outp_bl_set(struct nvif_outp *, int level);
 
+int nvif_outp_lvds(struct nvif_outp *, bool dual, bool bpc8);
+
 int nvif_outp_hdmi(struct nvif_outp *, int head, bool enable, u8 
max_ac_packet, u8 rekey, u32 khz,
   bool scdc, bool scdc_scrambling, bool scdc_low_rates);
 
diff --git a/drivers/gpu/drm/nouveau/nvif/outp.c 
b/drivers/gpu/drm/nouveau/nvif/outp.c
index 5a3c0dd7d5324..dbb0986f05558 100644
--- a/drivers/gpu/drm/nouveau/nvif/outp.c
+++ b/drivers/gpu/drm/nouveau/nvif/outp.c
@@ -150,18 +150,17 @@ nvif_outp_hdmi(struct nvif_outp *outp, int head, bool 
enable, u8 max_ac_packet,
 }
 
 int
-nvif_outp_acquire_lvds(struct nvif_outp *outp, bool dual, bool bpc8)
+nvif_outp_lvds(struct nvif_outp *outp, bool dual, bool bpc8)
 {
-   struct nvif_outp_acquire_v0 args;
+   struct nvif_outp_lvds_v0 args;
int ret;
 
-   args.lvds.dual = dual;
-   args.lvds.bpc8 = bpc8;
+   args.version = 0;
+   args.dual = dual;
+   args.bpc8 = bpc8;
 
-   ret = nvif_outp_acquire(outp, NVIF_OUTP_ACQUIRE_V0_LVDS, );
-   NVIF_ERRON(ret, >object,
-  "[ACQUIRE proto:LVDS dual:%d 8bpc:%d] or:%d 

[PATCH v3 23/44] drm/nouveau/disp: add output backlight control methods

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- preparation for GSP-RM

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/include/nvif/if0012.h | 17 
 drivers/gpu/drm/nouveau/include/nvif/outp.h   |  3 +
 drivers/gpu/drm/nouveau/nouveau_backlight.c   | 90 ++-
 drivers/gpu/drm/nouveau/nvif/outp.c   | 27 ++
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c |  2 +
 .../gpu/drm/nouveau/nvkm/engine/disp/g84.c|  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/g94.c|  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/ga102.c  |  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/gf119.c  |  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/gk104.c  |  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/gm107.c  |  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/gm200.c  |  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/gp100.c  |  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/gt215.c  | 38 
 .../gpu/drm/nouveau/nvkm/engine/disp/gv100.c  |  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/ior.h|  7 ++
 .../gpu/drm/nouveau/nvkm/engine/disp/mcp89.c  |  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/nv50.c   | 32 +++
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.c   | 38 
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.h   |  8 ++
 .../gpu/drm/nouveau/nvkm/engine/disp/tu102.c  |  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  | 41 +
 22 files changed, 233 insertions(+), 81 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h 
b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
index 230084d675ec2..f878784593b43 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
@@ -21,6 +21,9 @@ union nvif_outp_args {
 
 #define NVIF_OUTP_V0_LOAD_DETECT   0x20
 
+#define NVIF_OUTP_V0_BL_GET0x30
+#define NVIF_OUTP_V0_BL_SET0x31
+
 #define NVIF_OUTP_V0_HDMI  0x50
 
 #define NVIF_OUTP_V0_INFOFRAME 0x60
@@ -118,6 +121,20 @@ union nvif_outp_release_args {
} vn;
 };
 
+union nvif_outp_bl_get_args {
+   struct nvif_outp_bl_get_v0 {
+   __u8  version;
+   __u8  level;
+   } v0;
+};
+
+union nvif_outp_bl_set_args {
+   struct nvif_outp_bl_set_v0 {
+   __u8  version;
+   __u8  level;
+   } v0;
+};
+
 union nvif_outp_hdmi_args {
struct nvif_outp_hdmi_v0 {
__u8 version;
diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h 
b/drivers/gpu/drm/nouveau/include/nvif/outp.h
index ea60d418d7f09..ef63d22b62f84 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/outp.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/outp.h
@@ -47,6 +47,9 @@ nvif_outp_acquired(struct nvif_outp *outp)
return outp->or.id >= 0;
 }
 
+int nvif_outp_bl_get(struct nvif_outp *);
+int nvif_outp_bl_set(struct nvif_outp *, int level);
+
 int nvif_outp_hdmi(struct nvif_outp *, int head, bool enable, u8 
max_ac_packet, u8 rekey, u32 khz,
   bool scdc, bool scdc_scrambling, bool scdc_low_rates);
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c 
b/drivers/gpu/drm/nouveau/nouveau_backlight.c
index 91b5ecc575380..d47442125fa18 100644
--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
@@ -109,42 +109,6 @@ nv40_backlight_init(struct nouveau_encoder *encoder,
return 0;
 }
 
-static int
-nv50_get_intensity(struct backlight_device *bd)
-{
-   struct nouveau_encoder *nv_encoder = bl_get_data(bd);
-   struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
-   struct nvif_object *device = >client.device.object;
-   int or = ffs(nv_encoder->dcb->or) - 1;
-   u32 div = 1025;
-   u32 val;
-
-   val  = nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(or));
-   val &= NV50_PDISP_SOR_PWM_CTL_VAL;
-   return ((val * 100) + (div / 2)) / div;
-}
-
-static int
-nv50_set_intensity(struct backlight_device *bd)
-{
-   struct nouveau_encoder *nv_encoder = bl_get_data(bd);
-   struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
-   struct nvif_object *device = >client.device.object;
-   int or = ffs(nv_encoder->dcb->or) - 1;
-   u32 div = 1025;
-   u32 val = (bd->props.brightness * div) / 100;
-
-   nvif_wr32(device, NV50_PDISP_SOR_PWM_CTL(or),
- NV50_PDISP_SOR_PWM_CTL_NEW | val);
-   return 0;
-}
-
-static const struct backlight_ops nv50_bl_ops = {
-   .options = BL_CORE_SUSPENDRESUME,
-   .get_brightness = nv50_get_intensity,
-   .update_status = nv50_set_intensity,
-};
-
 /*
  * eDP brightness callbacks need to happen under lock, since we need to
  * enable/disable the backlight ourselves for modesets
@@ -238,53 +202,25 @@ static const struct backlight_ops nv50_edp_bl_ops = {
 };
 
 static int
-nva3_get_intensity(struct backlight_device *bd)
+nv50_get_intensity(struct backlight_device *bd)
 {
struct nouveau_encoder *nv_encoder = bl_get_data(bd);
-

[PATCH v3 14/44] drm/nouveau/disp: update SOR routing immediately on acquire()

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- was previously delayed until second supervisor interrupt

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c  | 2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
index 5b55598e09c85..b288ea6658da6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
@@ -48,8 +48,8 @@ nvkm_outp_route(struct nvkm_disp *disp)
 
list_for_each_entry(ior, >iors, head) {
if ((outp = ior->asy.outp)) {
-   OUTP_DBG(outp, "acquire %s", ior->name);
if (ior->asy.outp != ior->arm.outp) {
+   OUTP_DBG(outp, "acquire %s", ior->name);
if (ior->func->route.set)
ior->func->route.set(outp, ior);
ior->arm.outp = ior->asy.outp;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index d71bc188047e3..042a43c22061e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -235,6 +235,8 @@ nvkm_uoutp_mthd_acquire(struct nvkm_outp *outp, void *argv, 
u32 argc)
if (ret)
return ret;
 
+   nvkm_outp_route(outp->disp);
+
args->v0.or = outp->ior->id;
args->v0.link = outp->ior->asy.link;
return 0;
-- 
2.41.0



[PATCH v3 22/44] drm/nouveau/disp: remove SOR routing updates from supervisor

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- these shouldn't be necessary now, and are done in acquire()/release()
- preparation for GSP-RM, where we don't control the supervisor

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c | 1 -
 drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c | 1 -
 drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c  | 1 -
 3 files changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
index a48e9bdf4cd07..937baae6a3ebb 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
@@ -1038,7 +1038,6 @@ gf119_disp_super(struct work_struct *work)
continue;
nv50_disp_super_2_0(disp, head);
}
-   nvkm_outp_route(disp);
list_for_each_entry(head, >heads, head) {
if (!(mask[head->id] & 0x0001))
continue;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c
index 4ebc030e40d12..7ac59bab6309f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c
@@ -863,7 +863,6 @@ gv100_disp_super(struct work_struct *work)
continue;
nv50_disp_super_2_0(disp, head);
}
-   nvkm_outp_route(disp);
list_for_each_entry(head, >heads, head) {
if (!(mask[head->id] & 0x0001))
continue;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
index be81168029604..a4ce605177895 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
@@ -1371,7 +1371,6 @@ nv50_disp_super(struct work_struct *work)
continue;
nv50_disp_super_2_0(disp, head);
}
-   nvkm_outp_route(disp);
list_for_each_entry(head, >heads, head) {
if (!(super & (0x0200 << head->id)))
continue;
-- 
2.41.0



[PATCH v3 21/44] drm/nouveau/disp: release outputs post-modeset

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

Prior to this commit, KMS would call release() prior to modeset, and the
second supervisor interrupt would update SOR routing if needed.

Now, KMS will call release() post-modeset and update routing immediately.

- preparation for GSP-RM

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c| 18 --
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.c|  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c   |  2 ++
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index ab048cf25d866..50a0ff304291e 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -477,7 +477,6 @@ nv50_dac_atomic_disable(struct drm_encoder *encoder, struct 
drm_atomic_state *st
 
core->func->dac->ctrl(core, nv_encoder->outp.or.id, ctrl, NULL);
nv_encoder->crtc = NULL;
-   nvif_outp_release(_encoder->outp);
 }
 
 static void
@@ -1300,6 +1299,11 @@ nv50_mstm_cleanup(struct drm_atomic_state *state,
}
}
 
+   if (mstm->disabled) {
+   nvif_outp_release(>outp->outp);
+   mstm->disabled = false;
+   }
+
mstm->modified = false;
 }
 
@@ -1334,12 +1338,6 @@ nv50_mstm_prepare(struct drm_atomic_state *state,
nv50_msto_prepare(state, mst_state, >mgr, 
msto);
}
}
-
-   if (mstm->disabled) {
-   if (!mstm->links)
-   nvif_outp_release(>outp->outp);
-   mstm->disabled = false;
-   }
 }
 
 static struct drm_connector *
@@ -1582,7 +1580,6 @@ nv50_sor_atomic_disable(struct drm_encoder *encoder, 
struct drm_atomic_state *st
 
nv_encoder->update(nv_encoder, nv_crtc->index, NULL, 0, 0);
nv50_audio_disable(encoder, nv_crtc);
-   nvif_outp_release(_encoder->outp);
nv_encoder->crtc = NULL;
 }
 
@@ -1827,7 +1824,6 @@ nv50_pior_atomic_disable(struct drm_encoder *encoder, 
struct drm_atomic_state *s
 
core->func->pior->ctrl(core, nv_encoder->outp.or.id, ctrl, NULL);
nv_encoder->crtc = NULL;
-   nvif_outp_release(_encoder->outp);
 }
 
 static void
@@ -1990,8 +1986,10 @@ nv50_disp_atomic_commit_core(struct drm_atomic_state 
*state, u32 *interlock)
  nv_encoder->conn, NULL, NULL);
outp->enabled = outp->disabled = false;
} else {
-   if (outp->disabled)
+   if (outp->disabled) {
+   nvif_outp_release(_encoder->outp);
outp->disabled = false;
+   }
}
}
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
index b288ea6658da6..20a013f1bbbac 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
@@ -238,6 +238,7 @@ void
 nvkm_outp_release(struct nvkm_outp *outp)
 {
nvkm_outp_release_or(outp, NVKM_OUTP_USER);
+   nvkm_outp_route(outp->disp);
 }
 
 void
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index ffd174091454f..40cbb4ddc0378 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -188,6 +188,8 @@ nvkm_uoutp_mthd_release(struct nvkm_outp *outp, void *argv, 
u32 argc)
 
if (argc != sizeof(args->vn))
return -ENOSYS;
+   if (!outp->ior)
+   return -EINVAL;
 
nvkm_outp_release(outp);
return 0;
-- 
2.41.0



[PATCH v3 18/44] drm/nouveau/kms/nv50-: move audio enable post-modeset

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- adds tracking for post-UPDATE modeset operations, similar to mst[mo]'s
- audio won't work on RM without this
- we should probably have been doing this anyway

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 35 ++---
 drivers/gpu/drm/nouveau/dispnv50/disp.h |  3 +++
 2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 8fa3bb8c2f41e..99aa8d208711c 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -707,6 +707,18 @@ nv50_audio_supported(struct drm_encoder *encoder)
disp->disp->object.oclass == GT206_DISP)
return false;
 
+   if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) {
+   struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+   switch (nv_encoder->dcb->type) {
+   case DCB_OUTPUT_TMDS:
+   case DCB_OUTPUT_DP:
+   break;
+   default:
+   return false;
+   }
+   }
+
return true;
 }
 
@@ -829,8 +841,6 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct 
nouveau_crtc *nv_crtc,
size = 0;
 
nvif_outp_infoframe(_encoder->outp, NVIF_OUTP_INFOFRAME_V0_VSI, 
, size);
-
-   nv50_audio_enable(encoder, nv_crtc, nv_connector, state, mode);
 }
 
 /**
@@ -1660,8 +1670,6 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, 
struct drm_atomic_state *sta
else
proto = NV887D_SOR_SET_CONTROL_PROTOCOL_DP_B;
 
-   nv50_audio_enable(encoder, nv_crtc, nv_connector, state, mode);
-
 #ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
backlight = nv_connector->backlight;
if (backlight && backlight->uses_dpcd)
@@ -1939,7 +1947,9 @@ nv50_disp_atomic_commit_core(struct drm_atomic_state 
*state, u32 *interlock)
struct drm_dp_mst_topology_state *mst_state;
struct nouveau_drm *drm = nouveau_drm(state->dev);
struct nv50_disp *disp = nv50_disp(drm->dev);
+   struct nv50_atom *atom = nv50_atom(state);
struct nv50_core *core = disp->core;
+   struct nv50_outp_atom *outp;
struct nv50_mstm *mstm;
int i;
 
@@ -1962,6 +1972,21 @@ nv50_disp_atomic_commit_core(struct drm_atomic_state 
*state, u32 *interlock)
if (mstm->modified)
nv50_mstm_cleanup(state, mst_state, mstm);
}
+
+   list_for_each_entry(outp, >outp, head) {
+   if (outp->encoder->encoder_type != DRM_MODE_ENCODER_DPMST) {
+   struct nouveau_encoder *nv_encoder = 
nouveau_encoder(outp->encoder);
+
+   if (outp->enabled) {
+   nv50_audio_enable(outp->encoder, 
nouveau_crtc(nv_encoder->crtc),
+ nv_encoder->conn, NULL, NULL);
+   outp->enabled = outp->disabled = false;
+   } else {
+   if (outp->disabled)
+   outp->disabled = false;
+   }
+   }
+   }
 }
 
 static void
@@ -2053,6 +2078,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state 
*state)
 
if (outp->clr.mask) {
help->atomic_disable(encoder, state);
+   outp->disabled = true;
interlock[NV50_DISP_INTERLOCK_CORE] |= 1;
if (outp->flush_disable) {
nv50_disp_atomic_commit_wndw(state, interlock);
@@ -2092,6 +2118,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state 
*state)
 
if (outp->set.mask) {
help->atomic_enable(encoder, state);
+   outp->enabled = true;
interlock[NV50_DISP_INTERLOCK_CORE] = 1;
}
}
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.h 
b/drivers/gpu/drm/nouveau/dispnv50/disp.h
index 9d66c9c726c35..42209f5b06f91 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.h
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.h
@@ -85,6 +85,9 @@ struct nv50_outp_atom {
struct drm_encoder *encoder;
bool flush_disable;
 
+   bool disabled;
+   bool enabled;
+
union nv50_outp_atom_mask {
struct {
bool ctrl:1;
-- 
2.41.0



[PATCH v3 20/44] drm/nouveau/disp: move hdmi disable out of release()

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- release() is being moved post-modeset, preserve hdmi behaviour for now

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c  |  8 
 drivers/gpu/drm/nouveau/nouveau_encoder.h|  6 +-
 drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c | 15 +++
 3 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 7a7b3464a6671..ab048cf25d866 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -842,6 +842,8 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct 
nouveau_crtc *nv_crtc,
size = 0;
 
nvif_outp_infoframe(_encoder->outp, NVIF_OUTP_INFOFRAME_V0_VSI, 
, size);
+
+   nv_encoder->hdmi.enabled = true;
 }
 
 /**
@@ -1562,6 +1564,12 @@ nv50_sor_atomic_disable(struct drm_encoder *encoder, 
struct drm_atomic_state *st
}
 #endif
 
+   if (nv_encoder->dcb->type == DCB_OUTPUT_TMDS && 
nv_encoder->hdmi.enabled) {
+   nvif_outp_hdmi(_encoder->outp, nv_crtc->index,
+  false, 0, 0, 0, false, false, false);
+   nv_encoder->hdmi.enabled = false;
+   }
+
if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
ret = drm_dp_dpcd_readb(aux, DP_SET_POWER, );
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h 
b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index ea8ef10e71aae..b3a9415ba879c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -69,7 +69,11 @@ struct nouveau_encoder {
 
struct nv04_output_reg restore;
 
-   union {
+   struct {
+   struct {
+   bool enabled;
+   } hdmi;
+
struct {
struct nv50_mstm *mstm;
int link_nr;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index 8ba96323e1de5..ffd174091454f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -154,6 +154,13 @@ nvkm_uoutp_mthd_hdmi(struct nvkm_outp *outp, void *argv, 
u32 argc)
(args->v0.scdc && !ior->func->hdmi->scdc))
return -EINVAL;
 
+   if (!args->v0.enable) {
+   ior->func->hdmi->infoframe_avi(ior, args->v0.head, NULL, 0);
+   ior->func->hdmi->infoframe_vsi(ior, args->v0.head, NULL, 0);
+   ior->func->hdmi->ctrl(ior, args->v0.head, false, 0, 0);
+   return 0;
+   }
+
ior->func->hdmi->ctrl(ior, args->v0.head, args->v0.enable,
  args->v0.max_ac_packet, args->v0.rekey);
if (ior->func->hdmi->scdc)
@@ -177,19 +184,11 @@ nvkm_uoutp_mthd_acquire_lvds(struct nvkm_outp *outp, bool 
dual, bool bpc8)
 static int
 nvkm_uoutp_mthd_release(struct nvkm_outp *outp, void *argv, u32 argc)
 {
-   struct nvkm_head *head = outp->asy.head;
-   struct nvkm_ior *ior = outp->ior;
union nvif_outp_release_args *args = argv;
 
if (argc != sizeof(args->vn))
return -ENOSYS;
 
-   if (ior->func->hdmi && head) {
-   ior->func->hdmi->infoframe_avi(ior, head->id, NULL, 0);
-   ior->func->hdmi->infoframe_vsi(ior, head->id, NULL, 0);
-   ior->func->hdmi->ctrl(ior, head->id, false, 0, 0);
-   }
-
nvkm_outp_release(outp);
return 0;
 }
-- 
2.41.0



[PATCH v3 19/44] drm/nouveau/disp: add output hdmi config method

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- was previously part of acquire()
- preparation for GSP-RM

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c   | 10 ++---
 drivers/gpu/drm/nouveau/include/nvif/if0012.h | 28 --
 drivers/gpu/drm/nouveau/include/nvif/outp.h   |  5 ++-
 drivers/gpu/drm/nouveau/nvif/outp.c   | 33 +
 .../gpu/drm/nouveau/nvkm/engine/disp/gm200.c  | 16 ++--
 .../gpu/drm/nouveau/nvkm/engine/disp/ior.h|  5 ++-
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  | 37 +--
 7 files changed, 74 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 99aa8d208711c..7a7b3464a6671 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -778,7 +778,6 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct 
nouveau_crtc *nv_crtc,
struct drm_hdmi_info *hdmi = _connector->base.display_info.hdmi;
union hdmi_infoframe infoframe = { 0 };
const u8 rekey = 56; /* binary driver, and tegra, constant */
-   u8 scdc = 0;
u32 max_ac_packet;
struct {
struct nvif_outp_infoframe_v0 infoframe;
@@ -791,8 +790,9 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct 
nouveau_crtc *nv_crtc,
max_ac_packet -= 18; /* constant from tegra */
max_ac_packet /= 32;
 
-   if (hdmi->scdc.scrambling.supported) {
+   if (nv_encoder->i2c && hdmi->scdc.scrambling.supported) {
const bool high_tmds_clock_ratio = mode->clock > 34;
+   u8 scdc;
 
ret = drm_scdc_readb(nv_encoder->i2c, SCDC_TMDS_CONFIG, );
if (ret < 0) {
@@ -812,8 +812,9 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct 
nouveau_crtc *nv_crtc,
 scdc, ret);
}
 
-   ret = nvif_outp_acquire_tmds(_encoder->outp, nv_crtc->index, true,
-max_ac_packet, rekey, scdc, hda);
+   ret = nvif_outp_hdmi(_encoder->outp, nv_crtc->index, true, 
max_ac_packet, rekey,
+mode->clock, hdmi->scdc.supported, 
hdmi->scdc.scrambling.supported,
+hdmi->scdc.scrambling.low_rates);
if (ret)
return;
 
@@ -1852,7 +1853,6 @@ nv50_pior_atomic_enable(struct drm_encoder *encoder, 
struct drm_atomic_state *st
switch (nv_encoder->dcb->type) {
case DCB_OUTPUT_TMDS:
ctrl |= NVDEF(NV507D, PIOR_SET_CONTROL, PROTOCOL, EXT_TMDS_ENC);
-   nvif_outp_acquire_tmds(_encoder->outp, false, false, 0, 0, 
0, false);
break;
case DCB_OUTPUT_DP:
ctrl |= NVDEF(NV507D, PIOR_SET_CONTROL, PROTOCOL, EXT_TMDS_ENC);
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h 
b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
index 57bc4b2f2b170..230084d675ec2 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
@@ -21,6 +21,8 @@ union nvif_outp_args {
 
 #define NVIF_OUTP_V0_LOAD_DETECT   0x20
 
+#define NVIF_OUTP_V0_HDMI  0x50
+
 #define NVIF_OUTP_V0_INFOFRAME 0x60
 #define NVIF_OUTP_V0_HDA_ELD   0x61
 
@@ -62,7 +64,6 @@ union nvif_outp_acquire_args {
 #define NVIF_OUTP_ACQUIRE_V0_DAC  0x00
 #define NVIF_OUTP_ACQUIRE_V0_SOR  0x01
 #define NVIF_OUTP_ACQUIRE_V0_PIOR 0x02
-#define NVIF_OUTP_ACQUIRE_V0_TMDS0x05
 #define NVIF_OUTP_ACQUIRE_V0_LVDS0x03
 #define NVIF_OUTP_ACQUIRE_V0_DP  0x04
__u8 type;
@@ -73,17 +74,6 @@ union nvif_outp_acquire_args {
struct {
__u8 hda;
} sor;
-   struct {
-   __u8 head;
-   __u8 hdmi;
-   __u8 hdmi_max_ac_packet;
-   __u8 hdmi_rekey;
-#define NVIF_OUTP_ACQUIRE_V0_TMDS_HDMI_SCDC_SCRAMBLE (1 << 0)
-#define NVIF_OUTP_ACQUIRE_V0_TMDS_HDMI_SCDC_DIV_BY_4 (1 << 1)
-   __u8 hdmi_scdc;
-   __u8 hdmi_hda;
-   __u8 pad06[2];
-   } tmds;
struct {
__u8 dual;
__u8 bpc8;
@@ -128,6 +118,20 @@ union nvif_outp_release_args {
} vn;
 };
 
+union nvif_outp_hdmi_args {
+   struct nvif_outp_hdmi_v0 {
+   __u8 version;
+   __u8 head;
+   __u8 enable;
+   __u8 max_ac_packet;
+   __u8 rekey;
+   __u8 scdc;
+   __u8 scdc_scrambling;
+   __u8 scdc_low_rates;
+   __u32 khz;
+   } v0;
+};
+
 union nvif_outp_infoframe_args {
struct nvif_outp_infoframe_v0 {
   

[PATCH v3 17/44] drm/nouveau/kms/nv50-: keep output state around until modeset complete

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- we'll want this info post-UPDATE for later patches

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index a72cb74184472..8fa3bb8c2f41e 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -2080,7 +2080,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state 
*state)
nv50_crc_atomic_init_notifier_contexts(state);
 
/* Update output path(s). */
-   list_for_each_entry_safe(outp, outt, >outp, head) {
+   list_for_each_entry(outp, >outp, head) {
const struct drm_encoder_helper_funcs *help;
struct drm_encoder *encoder;
 
@@ -2094,9 +2094,6 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state 
*state)
help->atomic_enable(encoder, state);
interlock[NV50_DISP_INTERLOCK_CORE] = 1;
}
-
-   list_del(>head);
-   kfree(outp);
}
 
/* Update head(s). */
@@ -2194,6 +2191,11 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state 
*state)
if (atom->lock_core)
mutex_unlock(>mutex);
 
+   list_for_each_entry_safe(outp, outt, >outp, head) {
+   list_del(>head);
+   kfree(outp);
+   }
+
/* Wait for HW to signal completion. */
for_each_new_plane_in_state(state, plane, new_plane_state, i) {
struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);
-- 
2.41.0



[PATCH v3 15/44] drm/nouveau/kms/nv50-: pull some common init out of OR-specific code

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- cleanup before additional changes

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c   | 69 ---
 drivers/gpu/drm/nouveau/nouveau_encoder.h |  2 +
 2 files changed, 38 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 814d2be34d202..5c88d2e5321b1 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -554,34 +554,27 @@ nv50_dac_func = {
 };
 
 static int
-nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe)
+nv50_dac_create(struct nouveau_encoder *nv_encoder)
 {
+   struct drm_connector *connector = _encoder->conn->base;
struct nouveau_drm *drm = nouveau_drm(connector->dev);
-   struct nv50_disp *disp = nv50_disp(connector->dev);
struct nvkm_i2c *i2c = nvxx_i2c(>client.device);
struct nvkm_i2c_bus *bus;
-   struct nouveau_encoder *nv_encoder;
struct drm_encoder *encoder;
+   struct dcb_output *dcbe = nv_encoder->dcb;
int type = DRM_MODE_ENCODER_DAC;
 
-   nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
-   if (!nv_encoder)
-   return -ENOMEM;
-   nv_encoder->dcb = dcbe;
-
bus = nvkm_i2c_bus_find(i2c, dcbe->i2c_index);
if (bus)
nv_encoder->i2c = >i2c;
 
encoder = to_drm_encoder(nv_encoder);
-   encoder->possible_crtcs = dcbe->heads;
-   encoder->possible_clones = 0;
drm_encoder_init(connector->dev, encoder, _dac_func, type,
 "dac-%04x-%04x", dcbe->hasht, dcbe->hashm);
drm_encoder_helper_add(encoder, _dac_help);
 
drm_connector_attach_encoder(connector, encoder);
-   return nvif_outp_ctor(disp->disp, nv_encoder->base.base.name, dcbe->id, 
_encoder->outp);
+   return 0;
 }
 
 /*
@@ -1726,13 +1719,14 @@ bool nv50_has_mst(struct nouveau_drm *drm)
 }
 
 static int
-nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
+nv50_sor_create(struct nouveau_encoder *nv_encoder)
 {
+   struct drm_connector *connector = _encoder->conn->base;
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_drm *drm = nouveau_drm(connector->dev);
struct nvkm_i2c *i2c = nvxx_i2c(>client.device);
-   struct nouveau_encoder *nv_encoder;
struct drm_encoder *encoder;
+   struct dcb_output *dcbe = nv_encoder->dcb;
struct nv50_disp *disp = nv50_disp(connector->dev);
int type, ret;
 
@@ -1745,15 +1739,9 @@ nv50_sor_create(struct drm_connector *connector, struct 
dcb_output *dcbe)
break;
}
 
-   nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
-   if (!nv_encoder)
-   return -ENOMEM;
-   nv_encoder->dcb = dcbe;
nv_encoder->update = nv50_sor_update;
 
encoder = to_drm_encoder(nv_encoder);
-   encoder->possible_crtcs = dcbe->heads;
-   encoder->possible_clones = 0;
drm_encoder_init(connector->dev, encoder, _sor_func, type,
 "sor-%04x-%04x", dcbe->hasht, dcbe->hashm);
drm_encoder_helper_add(encoder, _sor_help);
@@ -1797,7 +1785,7 @@ nv50_sor_create(struct drm_connector *connector, struct 
dcb_output *dcbe)
nv_encoder->i2c = >i2c;
}
 
-   return nvif_outp_ctor(disp->disp, nv_encoder->base.base.name, dcbe->id, 
_encoder->outp);
+   return 0;
 }
 
 /**
@@ -1897,8 +1885,9 @@ nv50_pior_func = {
 };
 
 static int
-nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe)
+nv50_pior_create(struct nouveau_encoder *nv_encoder)
 {
+   struct drm_connector *connector = _encoder->conn->base;
struct drm_device *dev = connector->dev;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nv50_disp *disp = nv50_disp(dev);
@@ -1906,8 +1895,8 @@ nv50_pior_create(struct drm_connector *connector, struct 
dcb_output *dcbe)
struct nvkm_i2c_bus *bus = NULL;
struct nvkm_i2c_aux *aux = NULL;
struct i2c_adapter *ddc;
-   struct nouveau_encoder *nv_encoder;
struct drm_encoder *encoder;
+   struct dcb_output *dcbe = nv_encoder->dcb;
int type;
 
switch (dcbe->type) {
@@ -1925,16 +1914,10 @@ nv50_pior_create(struct drm_connector *connector, 
struct dcb_output *dcbe)
return -ENODEV;
}
 
-   nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
-   if (!nv_encoder)
-   return -ENOMEM;
-   nv_encoder->dcb = dcbe;
nv_encoder->i2c = ddc;
nv_encoder->aux = aux;
 
encoder = to_drm_encoder(nv_encoder);
-   encoder->possible_crtcs = dcbe->heads;
-   encoder->possible_clones = 0;

[PATCH v3 16/44] drm/nouveau/kms/nv50-: remove nv_encoder.audio.connector

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- use nv_encoder.conn instead, outp->conn never changes

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c   | 4 +---
 drivers/gpu/drm/nouveau/nouveau_encoder.h | 1 -
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 5c88d2e5321b1..a72cb74184472 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -611,7 +611,7 @@ nv50_audio_component_get_eld(struct device *kdev, int port, 
int dev_id,
continue; /* TODO */
 
nv_encoder = nouveau_encoder(encoder);
-   nv_connector = nouveau_connector(nv_encoder->audio.connector);
+   nv_connector = nv_encoder->conn;
nv_crtc = nouveau_crtc(nv_encoder->crtc);
 
if (!nv_crtc || nv_encoder->outp.or.id != port || 
nv_crtc->index != dev_id)
@@ -723,7 +723,6 @@ nv50_audio_disable(struct drm_encoder *encoder, struct 
nouveau_crtc *nv_crtc)
mutex_lock(>audio.lock);
if (nv_encoder->audio.enabled) {
nv_encoder->audio.enabled = false;
-   nv_encoder->audio.connector = NULL;
nvif_outp_hda_eld(_encoder->outp, nv_crtc->index, NULL, 0);
}
mutex_unlock(>audio.lock);
@@ -748,7 +747,6 @@ nv50_audio_enable(struct drm_encoder *encoder, struct 
nouveau_crtc *nv_crtc,
nvif_outp_hda_eld(_encoder->outp, nv_crtc->index, 
nv_connector->base.eld,
  drm_eld_size(nv_connector->base.eld));
nv_encoder->audio.enabled = true;
-   nv_encoder->audio.connector = _connector->base;
 
mutex_unlock(>audio.lock);
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h 
b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index b1554ad9d929b..ea8ef10e71aae 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -62,7 +62,6 @@ struct nouveau_encoder {
/* Protected by nouveau_drm.audio.lock */
struct {
bool enabled;
-   struct drm_connector *connector;
} audio;
 
struct drm_display_mode mode;
-- 
2.41.0



[PATCH v3 13/44] drm/nouveau/disp: add acquire_sor/pior()

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- preparing to move protocol-specific args out of acquire() again
- avoid re-acquiring acquired output, will matter when enforced later
- sor/pior done at same time due to shared tmds/dp handling

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c   | 15 ++
 drivers/gpu/drm/nouveau/include/nvif/if0012.h |  7 -
 drivers/gpu/drm/nouveau/include/nvif/outp.h   |  2 ++
 drivers/gpu/drm/nouveau/nvif/outp.c   | 24 
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  | 28 ++-
 5 files changed, 50 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 62fd910ffef61..814d2be34d202 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -1034,7 +1034,7 @@ nv50_msto_atomic_enable(struct drm_encoder *encoder, 
struct drm_atomic_state *st
return;
 
if (!mstm->links++) {
-   /*XXX: MST audio. */
+   nvif_outp_acquire_sor(>outp->outp, false /*TODO: MST 
audio... */);
nvif_outp_acquire_dp(>outp->outp, mstm->outp->dp.dpcd, 0, 
0, false, true);
}
 
@@ -1602,15 +1602,17 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, 
struct drm_atomic_state *sta
 
if ((disp->disp->object.oclass == GT214_DISP ||
 disp->disp->object.oclass >= GF110_DISP) &&
+   nv_encoder->dcb->type != DCB_OUTPUT_LVDS &&
drm_detect_monitor_audio(nv_connector->edid))
hda = true;
 
+   if (!nvif_outp_acquired(outp))
+   nvif_outp_acquire_sor(outp, hda);
+
switch (nv_encoder->dcb->type) {
case DCB_OUTPUT_TMDS:
-   if (disp->disp->object.oclass == NV50_DISP ||
-   !drm_detect_hdmi_monitor(nv_connector->edid))
-   nvif_outp_acquire_tmds(outp, nv_crtc->index, false, 0, 
0, 0, false);
-   else
+   if (disp->disp->object.oclass != NV50_DISP &&
+   drm_detect_hdmi_monitor(nv_connector->edid))
nv50_hdmi_enable(encoder, nv_crtc, nv_connector, state, 
mode, hda);
 
if (nv_encoder->outp.or.link & 1) {
@@ -1850,6 +1852,9 @@ nv50_pior_atomic_enable(struct drm_encoder *encoder, 
struct drm_atomic_state *st
default: asyh->or.depth = NV837D_PIOR_SET_CONTROL_PIXEL_DEPTH_DEFAULT; 
break;
}
 
+   if (!nvif_outp_acquired(_encoder->outp))
+   nvif_outp_acquire_pior(_encoder->outp);
+
switch (nv_encoder->dcb->type) {
case DCB_OUTPUT_TMDS:
ctrl |= NVDEF(NV507D, PIOR_SET_CONTROL, PROTOCOL, EXT_TMDS_ENC);
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h 
b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
index d139d070c0bc6..57bc4b2f2b170 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
@@ -60,7 +60,9 @@ union nvif_outp_acquire_args {
struct nvif_outp_acquire_v0 {
__u8 version;
 #define NVIF_OUTP_ACQUIRE_V0_DAC  0x00
-#define NVIF_OUTP_ACQUIRE_V0_TMDS0x02
+#define NVIF_OUTP_ACQUIRE_V0_SOR  0x01
+#define NVIF_OUTP_ACQUIRE_V0_PIOR 0x02
+#define NVIF_OUTP_ACQUIRE_V0_TMDS0x05
 #define NVIF_OUTP_ACQUIRE_V0_LVDS0x03
 #define NVIF_OUTP_ACQUIRE_V0_DP  0x04
__u8 type;
@@ -68,6 +70,9 @@ union nvif_outp_acquire_args {
__u8 link;
__u8 pad04[4];
union {
+   struct {
+   __u8 hda;
+   } sor;
struct {
__u8 head;
__u8 hdmi;
diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h 
b/drivers/gpu/drm/nouveau/include/nvif/outp.h
index c6d8823ef782c..a9090424dbf7e 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/outp.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/outp.h
@@ -29,6 +29,8 @@ int nvif_outp_edid_get(struct nvif_outp *, u8 **pedid);
 
 int nvif_outp_load_detect(struct nvif_outp *, u32 loadval);
 int nvif_outp_acquire_dac(struct nvif_outp *);
+int nvif_outp_acquire_sor(struct nvif_outp *, bool hda);
+int nvif_outp_acquire_pior(struct nvif_outp *);
 int nvif_outp_acquire_tmds(struct nvif_outp *, int head,
   bool hdmi, u8 max_ac_packet, u8 rekey, u8 scdc, bool 
hda);
 int nvif_outp_acquire_lvds(struct nvif_outp *, bool dual, bool bpc8);
diff --git a/drivers/gpu/drm/nouveau/nvif/outp.c 
b/drivers/gpu/drm/nouveau/nvif/outp.c
index 41c4de40895f0..81dbda52117ec 100644
--- a/drivers/gpu/drm/nouveau/nvif/outp.c
+++ b/drivers/gpu/drm/nouveau/nvif/outp.c
@@ -187,6 +187,30 @@ nvif_outp_acquire(struct nvif_outp *outp, u8 type, struct 
nvif_outp_acquire_v0 *
return 0;
 }
 
+int
+nvif_outp_acquire_pior(struct 

[PATCH v3 12/44] drm/nouveau/disp: add acquire_dac()

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- preparing to move protocol-specific args out of acquire() again
- avoid re-acquiring acquired output, will matter when enforced later
- this one is basically just a rename

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c  |  3 ++-
 drivers/gpu/drm/nouveau/include/nvif/if0012.h|  5 ++---
 drivers/gpu/drm/nouveau/include/nvif/outp.h  |  9 -
 drivers/gpu/drm/nouveau/nvif/outp.c  | 10 +-
 drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c |  4 ++--
 5 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 290f3c80ba4eb..62fd910ffef61 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -502,7 +502,8 @@ nv50_dac_atomic_enable(struct drm_encoder *encoder, struct 
drm_atomic_state *sta
 
ctrl |= NVDEF(NV507D, DAC_SET_CONTROL, PROTOCOL, RGB_CRT);
 
-   nvif_outp_acquire_rgb_crt(_encoder->outp);
+   if (!nvif_outp_acquired(_encoder->outp))
+   nvif_outp_acquire_dac(_encoder->outp);
 
core->func->dac->ctrl(core, nv_encoder->outp.or.id, ctrl, asyh);
asyh->or.depth = 0;
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h 
b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
index 6cfc885e0aa9a..d139d070c0bc6 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
@@ -59,12 +59,11 @@ union nvif_outp_load_detect_args {
 union nvif_outp_acquire_args {
struct nvif_outp_acquire_v0 {
__u8 version;
-#define NVIF_OUTP_ACQUIRE_V0_RGB_CRT 0x00
-#define NVIF_OUTP_ACQUIRE_V0_TV  0x01
+#define NVIF_OUTP_ACQUIRE_V0_DAC  0x00
 #define NVIF_OUTP_ACQUIRE_V0_TMDS0x02
 #define NVIF_OUTP_ACQUIRE_V0_LVDS0x03
 #define NVIF_OUTP_ACQUIRE_V0_DP  0x04
-   __u8 proto;
+   __u8 type;
__u8 or;
__u8 link;
__u8 pad04[4];
diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h 
b/drivers/gpu/drm/nouveau/include/nvif/outp.h
index 23776057bfea8..c6d8823ef782c 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/outp.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/outp.h
@@ -28,7 +28,7 @@ enum nvif_outp_detect_status nvif_outp_detect(struct 
nvif_outp *);
 int nvif_outp_edid_get(struct nvif_outp *, u8 **pedid);
 
 int nvif_outp_load_detect(struct nvif_outp *, u32 loadval);
-int nvif_outp_acquire_rgb_crt(struct nvif_outp *);
+int nvif_outp_acquire_dac(struct nvif_outp *);
 int nvif_outp_acquire_tmds(struct nvif_outp *, int head,
   bool hdmi, u8 max_ac_packet, u8 rekey, u8 scdc, bool 
hda);
 int nvif_outp_acquire_lvds(struct nvif_outp *, bool dual, bool bpc8);
@@ -40,6 +40,13 @@ int nvif_outp_inherit_tmds(struct nvif_outp *outp, u8 
*proto_out);
 int nvif_outp_inherit_dp(struct nvif_outp *outp, u8 *proto_out);
 
 void nvif_outp_release(struct nvif_outp *);
+
+static inline bool
+nvif_outp_acquired(struct nvif_outp *outp)
+{
+   return outp->or.id >= 0;
+}
+
 int nvif_outp_infoframe(struct nvif_outp *, u8 type, struct 
nvif_outp_infoframe_v0 *, u32 size);
 int nvif_outp_hda_eld(struct nvif_outp *, int head, void *data, u32 size);
 int nvif_outp_dp_aux_pwr(struct nvif_outp *, bool enable);
diff --git a/drivers/gpu/drm/nouveau/nvif/outp.c 
b/drivers/gpu/drm/nouveau/nvif/outp.c
index eecccfc17c1c6..41c4de40895f0 100644
--- a/drivers/gpu/drm/nouveau/nvif/outp.c
+++ b/drivers/gpu/drm/nouveau/nvif/outp.c
@@ -171,12 +171,12 @@ nvif_outp_release(struct nvif_outp *outp)
 }
 
 static inline int
-nvif_outp_acquire(struct nvif_outp *outp, u8 proto, struct 
nvif_outp_acquire_v0 *args)
+nvif_outp_acquire(struct nvif_outp *outp, u8 type, struct nvif_outp_acquire_v0 
*args)
 {
int ret;
 
args->version = 0;
-   args->proto = proto;
+   args->type = type;
 
ret = nvif_mthd(>object, NVIF_OUTP_V0_ACQUIRE, args, 
sizeof(*args));
if (ret)
@@ -188,13 +188,13 @@ nvif_outp_acquire(struct nvif_outp *outp, u8 proto, 
struct nvif_outp_acquire_v0
 }
 
 int
-nvif_outp_acquire_rgb_crt(struct nvif_outp *outp)
+nvif_outp_acquire_dac(struct nvif_outp *outp)
 {
struct nvif_outp_acquire_v0 args;
int ret;
 
-   ret = nvif_outp_acquire(outp, NVIF_OUTP_ACQUIRE_V0_RGB_CRT, );
-   NVIF_ERRON(ret, >object, "[ACQUIRE proto:RGB_CRT] or:%d", 
args.or);
+   ret = nvif_outp_acquire(outp, NVIF_OUTP_ACQUIRE_V0_DAC, );
+   NVIF_ERRON(ret, >object, "[ACQUIRE DAC] or:%d", args.or);
return ret;
 }
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index d56a87ae5b265..73c6227446fb8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -217,8 +217,8 @@ 

[PATCH v3 11/44] drm/nouveau/disp: shuffle to make upcoming diffs prettier

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- preparing to move protocol-specific args out of acquire() again
- no code changes

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/nvif/outp.c   | 106 +-
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  |  74 ++--
 2 files changed, 91 insertions(+), 89 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvif/outp.c 
b/drivers/gpu/drm/nouveau/nvif/outp.c
index 795658f0c920c..eecccfc17c1c6 100644
--- a/drivers/gpu/drm/nouveau/nvif/outp.c
+++ b/drivers/gpu/drm/nouveau/nvif/outp.c
@@ -54,6 +54,28 @@ nvif_outp_dp_retrain(struct nvif_outp *outp)
return ret;
 }
 
+static inline int nvif_outp_acquire(struct nvif_outp *, u8, struct 
nvif_outp_acquire_v0 *);
+
+int
+nvif_outp_acquire_dp(struct nvif_outp *outp, u8 dpcd[DP_RECEIVER_CAP_SIZE],
+int link_nr, int link_bw, bool hda, bool mst)
+{
+   struct nvif_outp_acquire_v0 args;
+   int ret;
+
+   args.dp.link_nr = link_nr;
+   args.dp.link_bw = link_bw;
+   args.dp.hda = hda;
+   args.dp.mst = mst;
+   memcpy(args.dp.dpcd, dpcd, sizeof(args.dp.dpcd));
+
+   ret = nvif_outp_acquire(outp, NVIF_OUTP_ACQUIRE_V0_DP, );
+   NVIF_ERRON(ret, >object,
+  "[ACQUIRE proto:DP link_nr:%d link_bw:%02x hda:%d mst:%d] 
or:%d link:%d",
+  args.dp.link_nr, args.dp.link_bw, args.dp.hda, args.dp.mst, 
args.or, args.link);
+   return ret;
+}
+
 int
 nvif_outp_dp_aux_pwr(struct nvif_outp *outp, bool enable)
 {
@@ -101,48 +123,26 @@ nvif_outp_infoframe(struct nvif_outp *outp, u8 type, 
struct nvif_outp_infoframe_
return ret;
 }
 
-void
-nvif_outp_release(struct nvif_outp *outp)
-{
-   int ret = nvif_mthd(>object, NVIF_OUTP_V0_RELEASE, NULL, 0);
-   NVIF_ERRON(ret, >object, "[RELEASE]");
-   outp->or.id = -1;
-}
-
-static inline int
-nvif_outp_acquire(struct nvif_outp *outp, u8 proto, struct 
nvif_outp_acquire_v0 *args)
-{
-   int ret;
-
-   args->version = 0;
-   args->proto = proto;
-
-   ret = nvif_mthd(>object, NVIF_OUTP_V0_ACQUIRE, args, 
sizeof(*args));
-   if (ret)
-   return ret;
-
-   outp->or.id = args->or;
-   outp->or.link = args->link;
-   return 0;
-}
-
 int
-nvif_outp_acquire_dp(struct nvif_outp *outp, u8 dpcd[DP_RECEIVER_CAP_SIZE],
-int link_nr, int link_bw, bool hda, bool mst)
+nvif_outp_acquire_tmds(struct nvif_outp *outp, int head,
+  bool hdmi, u8 max_ac_packet, u8 rekey, u8 scdc, bool hda)
 {
struct nvif_outp_acquire_v0 args;
int ret;
 
-   args.dp.link_nr = link_nr;
-   args.dp.link_bw = link_bw;
-   args.dp.hda = hda;
-   args.dp.mst = mst;
-   memcpy(args.dp.dpcd, dpcd, sizeof(args.dp.dpcd));
+   args.tmds.head = head;
+   args.tmds.hdmi = hdmi;
+   args.tmds.hdmi_max_ac_packet = max_ac_packet;
+   args.tmds.hdmi_rekey = rekey;
+   args.tmds.hdmi_scdc = scdc;
+   args.tmds.hdmi_hda = hda;
 
-   ret = nvif_outp_acquire(outp, NVIF_OUTP_ACQUIRE_V0_DP, );
+   ret = nvif_outp_acquire(outp, NVIF_OUTP_ACQUIRE_V0_TMDS, );
NVIF_ERRON(ret, >object,
-  "[ACQUIRE proto:DP link_nr:%d link_bw:%02x hda:%d mst:%d] 
or:%d link:%d",
-  args.dp.link_nr, args.dp.link_bw, args.dp.hda, args.dp.mst, 
args.or, args.link);
+  "[ACQUIRE proto:TMDS head:%d hdmi:%d max_ac_packet:%d 
rekey:%d scdc:%d hda:%d]"
+  " or:%d link:%d", args.tmds.head, args.tmds.hdmi, 
args.tmds.hdmi_max_ac_packet,
+  args.tmds.hdmi_rekey, args.tmds.hdmi_scdc, 
args.tmds.hdmi_hda,
+  args.or, args.link);
return ret;
 }
 
@@ -162,27 +162,29 @@ nvif_outp_acquire_lvds(struct nvif_outp *outp, bool dual, 
bool bpc8)
return ret;
 }
 
-int
-nvif_outp_acquire_tmds(struct nvif_outp *outp, int head,
-  bool hdmi, u8 max_ac_packet, u8 rekey, u8 scdc, bool hda)
+void
+nvif_outp_release(struct nvif_outp *outp)
+{
+   int ret = nvif_mthd(>object, NVIF_OUTP_V0_RELEASE, NULL, 0);
+   NVIF_ERRON(ret, >object, "[RELEASE]");
+   outp->or.id = -1;
+}
+
+static inline int
+nvif_outp_acquire(struct nvif_outp *outp, u8 proto, struct 
nvif_outp_acquire_v0 *args)
 {
-   struct nvif_outp_acquire_v0 args;
int ret;
 
-   args.tmds.head = head;
-   args.tmds.hdmi = hdmi;
-   args.tmds.hdmi_max_ac_packet = max_ac_packet;
-   args.tmds.hdmi_rekey = rekey;
-   args.tmds.hdmi_scdc = scdc;
-   args.tmds.hdmi_hda = hda;
+   args->version = 0;
+   args->proto = proto;
 
-   ret = nvif_outp_acquire(outp, NVIF_OUTP_ACQUIRE_V0_TMDS, );
-   NVIF_ERRON(ret, >object,
-  "[ACQUIRE proto:TMDS head:%d hdmi:%d max_ac_packet:%d 
rekey:%d scdc:%d hda:%d]"
-  " or:%d link:%d", args.tmds.head, args.tmds.hdmi, 

[PATCH v3 09/44] drm/nouveau/disp: rename internal output acquire/release functions

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

These will be made static later in the patch series, after the code that
uses them has been cleaned up in preparation for GSP-RM support.

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c  | 10 --
 drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h  |  5 +++--
 drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c | 16 
 3 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
index fb061144438dc..3ed93df475fcc 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
@@ -89,7 +89,7 @@ nvkm_outp_xlat(struct nvkm_outp *outp, enum nvkm_ior_type 
*type)
 }
 
 void
-nvkm_outp_release(struct nvkm_outp *outp, u8 user)
+nvkm_outp_release_or(struct nvkm_outp *outp, u8 user)
 {
struct nvkm_ior *ior = outp->ior;
OUTP_TRACE(outp, "release %02x &= %02x %p", outp->acquired, ~user, ior);
@@ -142,7 +142,7 @@ nvkm_outp_acquire_hda(struct nvkm_outp *outp, enum 
nvkm_ior_type type,
 }
 
 int
-nvkm_outp_acquire(struct nvkm_outp *outp, u8 user, bool hda)
+nvkm_outp_acquire_or(struct nvkm_outp *outp, u8 user, bool hda)
 {
struct nvkm_ior *ior = outp->ior;
enum nvkm_ior_proto proto;
@@ -234,6 +234,12 @@ nvkm_outp_detect(struct nvkm_outp *outp)
return ret;
 }
 
+void
+nvkm_outp_release(struct nvkm_outp *outp)
+{
+   nvkm_outp_release_or(outp, NVKM_OUTP_USER);
+}
+
 void
 nvkm_outp_fini(struct nvkm_outp *outp)
 {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
index 1cd70868f2255..76d83fb9c6e59 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
@@ -77,8 +77,9 @@ void nvkm_outp_fini(struct nvkm_outp *);
 
 int nvkm_outp_detect(struct nvkm_outp *);
 
-int nvkm_outp_acquire(struct nvkm_outp *, u8 user, bool hda);
-void nvkm_outp_release(struct nvkm_outp *, u8 user);
+int nvkm_outp_acquire_or(struct nvkm_outp *, u8 user, bool hda);
+void nvkm_outp_release(struct nvkm_outp *);
+void nvkm_outp_release_or(struct nvkm_outp *, u8 user);
 void nvkm_outp_route(struct nvkm_disp *);
 
 struct nvkm_outp_func {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index 0c4ffa3ffb288..828db77af242b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -141,7 +141,7 @@ nvkm_uoutp_mthd_release(struct nvkm_outp *outp, void *argv, 
u32 argc)
ior->func->hdmi->ctrl(ior, head->id, false, 0, 0);
}
 
-   nvkm_outp_release(outp, NVKM_OUTP_USER);
+   nvkm_outp_release(outp);
return 0;
 }
 
@@ -151,7 +151,7 @@ nvkm_uoutp_mthd_acquire_dp(struct nvkm_outp *outp, u8 
dpcd[DP_RECEIVER_CAP_SIZE]
 {
int ret;
 
-   ret = nvkm_outp_acquire(outp, NVKM_OUTP_USER, hda);
+   ret = nvkm_outp_acquire_or(outp, NVKM_OUTP_USER, hda);
if (ret)
return ret;
 
@@ -172,7 +172,7 @@ nvkm_uoutp_mthd_acquire_tmds(struct nvkm_outp *outp, u8 
head, u8 hdmi, u8 hdmi_m
if (!(outp->asy.head = nvkm_head_find(outp->disp, head)))
return -EINVAL;
 
-   ret = nvkm_outp_acquire(outp, NVKM_OUTP_USER, hdmi && hdmi_hda);
+   ret = nvkm_outp_acquire_or(outp, NVKM_OUTP_USER, hdmi && hdmi_hda);
if (ret)
return ret;
 
@@ -182,7 +182,7 @@ nvkm_uoutp_mthd_acquire_tmds(struct nvkm_outp *outp, u8 
head, u8 hdmi, u8 hdmi_m
if (!ior->func->hdmi ||
hdmi_max_ac_packet > 0x1f || hdmi_rekey > 0x7f ||
(hdmi_scdc && !ior->func->hdmi->scdc)) {
-   nvkm_outp_release(outp, NVKM_OUTP_USER);
+   nvkm_outp_release_or(outp, NVKM_OUTP_USER);
return -EINVAL;
}
 
@@ -203,7 +203,7 @@ nvkm_uoutp_mthd_acquire_lvds(struct nvkm_outp *outp, bool 
dual, bool bpc8)
outp->lvds.dual = dual;
outp->lvds.bpc8 = bpc8;
 
-   return nvkm_outp_acquire(outp, NVKM_OUTP_USER, false);
+   return nvkm_outp_acquire_or(outp, NVKM_OUTP_USER, false);
 }
 
 static int
@@ -219,7 +219,7 @@ nvkm_uoutp_mthd_acquire(struct nvkm_outp *outp, void *argv, 
u32 argc)
 
switch (args->v0.proto) {
case NVIF_OUTP_ACQUIRE_V0_RGB_CRT:
-   ret = nvkm_outp_acquire(outp, NVKM_OUTP_USER, false);
+   ret = nvkm_outp_acquire_or(outp, NVKM_OUTP_USER, false);
break;
case NVIF_OUTP_ACQUIRE_V0_TMDS:
ret = nvkm_uoutp_mthd_acquire_tmds(outp, args->v0.tmds.head,
@@ -261,7 +261,7 @@ nvkm_uoutp_mthd_load_detect(struct nvkm_outp *outp, void 
*argv, u32 argc)
if (argc != sizeof(args->v0) || 

[PATCH v3 10/44] drm/nouveau/kms: Add INHERIT ioctl to nvkm/nvif for reading IOR state

2023-09-19 Thread Lyude Paul
Now that we're supporting things like Ada and the GSP, there's situations
where we really need to actually know the display state that we're starting
with when loading the driver in order to prevent breaking GSP expectations.
The first step in doing this is making it so that we can read the current
state of IORs from nvkm in DRM, so that we can fill in said into into the
atomic state.

We do this by introducing an INHERIT ioctl to nvkm/nvif. This is basically
another form of ACQUIRE, except that it will only acquire the given output
path for userspace if it's already set up in hardware. This way, we can go
through and probe each outp object we have in DRM in order to figure out
the current hardware state of each one. If the outp isn't in use, it simply
returns -ENODEV.

This is also part of the work that will be required for implementing GSP
support for display. While the GSP should mostly work without this commit,
this commit should fix some edge case bugs that can occur on initial driver
load. This also paves the way for some of the initial groundwork for
fastboot support.

Signed-off-by: Lyude Paul 
Signed-off-by: Ben Skeggs 
Acked-by: Danilo Krummrich 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c   | 101 ++
 drivers/gpu/drm/nouveau/include/nvif/if0012.h |  23 
 drivers/gpu/drm/nouveau/include/nvif/outp.h   |   5 +
 drivers/gpu/drm/nouveau/nvif/outp.c   |  68 
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c |   1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.c   |  39 ---
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.h   |   3 +
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  |  64 +++
 8 files changed, 291 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 889ff667d0293..290f3c80ba4eb 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -2519,6 +2519,104 @@ nv50_display_fini(struct drm_device *dev, bool runtime, 
bool suspend)
cancel_work_sync(>hpd_work);
 }
 
+static inline void
+nv50_display_read_hw_or_state(struct drm_device *dev, struct nv50_disp *disp,
+ struct nouveau_encoder *outp)
+{
+   struct drm_crtc *crtc;
+   struct drm_connector_list_iter conn_iter;
+   struct drm_connector *conn;
+   struct nv50_head_atom *armh;
+   const u32 encoder_mask = drm_encoder_mask(>base.base);
+   bool found_conn = false, found_head = false;
+   u8 proto;
+   int head_idx;
+   int ret;
+
+   switch (outp->dcb->type) {
+   case DCB_OUTPUT_TMDS:
+   ret = nvif_outp_inherit_tmds(>outp, );
+   break;
+   case DCB_OUTPUT_DP:
+   ret = nvif_outp_inherit_dp(>outp, );
+   break;
+   case DCB_OUTPUT_LVDS:
+   ret = nvif_outp_inherit_lvds(>outp, );
+   break;
+   case DCB_OUTPUT_ANALOG:
+   ret = nvif_outp_inherit_rgb_crt(>outp, );
+   break;
+   default:
+   drm_dbg_kms(dev, "Readback for %s not implemented yet, 
skipping\n",
+   outp->base.base.name);
+   drm_WARN_ON(dev, true);
+   return;
+   }
+
+   if (ret < 0)
+   return;
+
+   head_idx = ret;
+
+   drm_for_each_crtc(crtc, dev) {
+   if (crtc->index != head_idx)
+   continue;
+
+   armh = nv50_head_atom(crtc->state);
+   found_head = true;
+   break;
+   }
+   if (drm_WARN_ON(dev, !found_head))
+   return;
+
+   /* Figure out which connector is being used by this encoder */
+   drm_connector_list_iter_begin(dev, _iter);
+   nouveau_for_each_non_mst_connector_iter(conn, _iter) {
+   if (nouveau_connector(conn)->index == outp->dcb->connector) {
+   found_conn = true;
+   break;
+   }
+   }
+   drm_connector_list_iter_end(_iter);
+   if (drm_WARN_ON(dev, !found_conn))
+   return;
+
+   armh->state.encoder_mask = encoder_mask;
+   armh->state.connector_mask = drm_connector_mask(conn);
+   armh->state.active = true;
+   armh->state.enable = true;
+   pm_runtime_get_noresume(dev->dev);
+
+   outp->crtc = crtc;
+   outp->ctrl = NVVAL(NV507D, SOR_SET_CONTROL, PROTOCOL, proto) | 
BIT(crtc->index);
+
+   drm_connector_get(conn);
+   conn->state->crtc = crtc;
+   conn->state->best_encoder = >base.base;
+}
+
+/* Read back the currently programmed display state */
+static void
+nv50_display_read_hw_state(struct nouveau_drm *drm)
+{
+   struct drm_device *dev = drm->dev;
+   struct drm_encoder *encoder;
+   struct drm_modeset_acquire_ctx ctx;
+   struct nv50_disp *disp = nv50_disp(dev);
+   int ret;
+
+   DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
+
+   

[PATCH v3 07/44] drm/nouveau/disp: add output detect method

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

This will check the relevant hotplug pin and skip the DDC probe we
currently do if a display is present.

- preparation for GSP-RM.

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/include/nvif/conn.h   |  5 --
 drivers/gpu/drm/nouveau/include/nvif/if0011.h | 11 
 drivers/gpu/drm/nouveau/include/nvif/if0012.h | 12 
 drivers/gpu/drm/nouveau/include/nvif/outp.h   |  9 +++
 drivers/gpu/drm/nouveau/nouveau_connector.c   | 60 ---
 drivers/gpu/drm/nouveau/nouveau_dp.c  | 10 +---
 drivers/gpu/drm/nouveau/nvif/conn.c   | 14 -
 drivers/gpu/drm/nouveau/nvif/outp.c   | 25 
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c |  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.c   | 28 +
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.h   |  6 ++
 .../gpu/drm/nouveau/nvkm/engine/disp/uconn.c  | 41 -
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  | 24 
 13 files changed, 145 insertions(+), 101 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvif/conn.h 
b/drivers/gpu/drm/nouveau/include/nvif/conn.h
index dc355e1dfafa0..8a6017a358976 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/conn.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/conn.h
@@ -18,11 +18,6 @@ nvif_conn_id(struct nvif_conn *conn)
return conn->object.handle;
 }
 
-#define NVIF_CONN_HPD_STATUS_UNSUPPORTED 0 /* negative if query fails */
-#define NVIF_CONN_HPD_STATUS_NOT_PRESENT 1
-#define NVIF_CONN_HPD_STATUS_PRESENT 2
-int nvif_conn_hpd_status(struct nvif_conn *);
-
 int nvif_conn_event_ctor(struct nvif_conn *, const char *name, 
nvif_event_func, u8 types,
 struct nvif_event *);
 #endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0011.h 
b/drivers/gpu/drm/nouveau/include/nvif/if0011.h
index 69b0b779f9424..0c25288a5a789 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0011.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0011.h
@@ -20,15 +20,4 @@ union nvif_conn_event_args {
__u8 pad02[6];
} v0;
 };
-
-#define NVIF_CONN_V0_HPD_STATUS 0x
-
-union nvif_conn_hpd_status_args {
-   struct nvif_conn_hpd_status_v0 {
-   __u8 version;
-   __u8 support;
-   __u8 present;
-   __u8 pad03[5];
-   } v0;
-};
 #endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h 
b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
index 7c56f653070c9..923bc30af2a92 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
@@ -12,6 +12,8 @@ union nvif_outp_args {
} v0;
 };
 
+#define NVIF_OUTP_V0_DETECT0x00
+
 #define NVIF_OUTP_V0_ACQUIRE   0x11
 #define NVIF_OUTP_V0_RELEASE   0x12
 
@@ -24,6 +26,16 @@ union nvif_outp_args {
 #define NVIF_OUTP_V0_DP_RETRAIN0x73
 #define NVIF_OUTP_V0_DP_MST_VCPI   0x78
 
+union nvif_outp_detect_args {
+   struct nvif_outp_detect_v0 {
+   __u8 version;
+#define NVIF_OUTP_DETECT_V0_NOT_PRESENT 0x00
+#define NVIF_OUTP_DETECT_V0_PRESENT 0x01
+#define NVIF_OUTP_DETECT_V0_UNKNOWN 0x02
+   __u8 status;
+   } v0;
+};
+
 union nvif_outp_load_detect_args {
struct nvif_outp_load_detect_v0 {
__u8  version;
diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h 
b/drivers/gpu/drm/nouveau/include/nvif/outp.h
index fa76a7b5e4b37..c3e1e4d2f1a11 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/outp.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/outp.h
@@ -17,6 +17,15 @@ struct nvif_outp {
 
 int nvif_outp_ctor(struct nvif_disp *, const char *name, int id, struct 
nvif_outp *);
 void nvif_outp_dtor(struct nvif_outp *);
+
+enum nvif_outp_detect_status {
+   NOT_PRESENT,
+   PRESENT,
+   UNKNOWN,
+};
+
+enum nvif_outp_detect_status nvif_outp_detect(struct nvif_outp *);
+
 int nvif_outp_load_detect(struct nvif_outp *, u32 loadval);
 int nvif_outp_acquire_rgb_crt(struct nvif_outp *);
 int nvif_outp_acquire_tmds(struct nvif_outp *, int head,
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c 
b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 68b4fb4bec63f..a290a2844547c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -413,6 +413,7 @@ nouveau_connector_ddc_detect(struct drm_connector 
*connector)
 {
struct drm_device *dev = connector->dev;
struct pci_dev *pdev = to_pci_dev(dev->dev);
+   struct nouveau_connector *conn = nouveau_connector(connector);
struct nouveau_encoder *nv_encoder = NULL, *found = NULL;
struct drm_encoder *encoder;
int ret;
@@ -421,33 +422,48 @@ nouveau_connector_ddc_detect(struct drm_connector 
*connector)
drm_connector_for_each_possible_encoder(connector, encoder) {
nv_encoder = nouveau_encoder(encoder);
 
-   switch 

[PATCH v3 08/44] drm/nouveau/disp: add output method to fetch edid

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- needed to support TMDS EDID on RM

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/include/nvif/if0012.h | 10 +++
 drivers/gpu/drm/nouveau/include/nvif/outp.h   |  1 +
 drivers/gpu/drm/nouveau/nouveau_connector.c   | 22 --
 drivers/gpu/drm/nouveau/nvif/outp.c   | 30 +++
 .../gpu/drm/nouveau/nvkm/engine/disp/outp.h   |  1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  | 15 ++
 6 files changed, 70 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h 
b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
index 923bc30af2a92..725d6e8e3d2d3 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
@@ -13,6 +13,7 @@ union nvif_outp_args {
 };
 
 #define NVIF_OUTP_V0_DETECT0x00
+#define NVIF_OUTP_V0_EDID_GET  0x01
 
 #define NVIF_OUTP_V0_ACQUIRE   0x11
 #define NVIF_OUTP_V0_RELEASE   0x12
@@ -36,6 +37,15 @@ union nvif_outp_detect_args {
} v0;
 };
 
+union nvif_outp_edid_get_args {
+   struct nvif_outp_edid_get_v0 {
+   __u8  version;
+   __u8  pad01;
+   __u16 size;
+   __u8  data[2048];
+   } v0;
+};
+
 union nvif_outp_load_detect_args {
struct nvif_outp_load_detect_v0 {
__u8  version;
diff --git a/drivers/gpu/drm/nouveau/include/nvif/outp.h 
b/drivers/gpu/drm/nouveau/include/nvif/outp.h
index c3e1e4d2f1a11..7c2c34a84fbd8 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/outp.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/outp.h
@@ -25,6 +25,7 @@ enum nvif_outp_detect_status {
 };
 
 enum nvif_outp_detect_status nvif_outp_detect(struct nvif_outp *);
+int nvif_outp_edid_get(struct nvif_outp *, u8 **pedid);
 
 int nvif_outp_load_detect(struct nvif_outp *, u32 loadval);
 int nvif_outp_acquire_rgb_crt(struct nvif_outp *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c 
b/drivers/gpu/drm/nouveau/nouveau_connector.c
index a290a2844547c..c079686fa2408 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -570,7 +570,6 @@ nouveau_connector_detect(struct drm_connector *connector, 
bool force)
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_encoder *nv_encoder = NULL;
struct nouveau_encoder *nv_partner;
-   struct i2c_adapter *i2c;
int type;
int ret;
enum drm_connector_status conn_status = connector_status_disconnected;
@@ -593,15 +592,20 @@ nouveau_connector_detect(struct drm_connector *connector, 
bool force)
}
 
nv_encoder = nouveau_connector_ddc_detect(connector);
-   if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) {
-   struct edid *new_edid;
+   if (nv_encoder) {
+   struct edid *new_edid = NULL;
 
-   if ((vga_switcheroo_handler_flags() &
-VGA_SWITCHEROO_CAN_SWITCH_DDC) &&
-   nv_connector->type == DCB_CONNECTOR_LVDS)
-   new_edid = drm_get_edid_switcheroo(connector, i2c);
-   else
-   new_edid = drm_get_edid(connector, i2c);
+   if (nv_encoder->i2c) {
+   if ((vga_switcheroo_handler_flags() & 
VGA_SWITCHEROO_CAN_SWITCH_DDC) &&
+   nv_connector->type == DCB_CONNECTOR_LVDS)
+   new_edid = drm_get_edid_switcheroo(connector, 
nv_encoder->i2c);
+   else
+   new_edid = drm_get_edid(connector, 
nv_encoder->i2c);
+   } else {
+   ret = nvif_outp_edid_get(_encoder->outp, (u8 
**)_edid);
+   if (ret < 0)
+   return connector_status_disconnected;
+   }
 
nouveau_connector_set_edid(nv_connector, new_edid);
if (!nv_connector->edid) {
diff --git a/drivers/gpu/drm/nouveau/nvif/outp.c 
b/drivers/gpu/drm/nouveau/nvif/outp.c
index 7f1daab35a0d2..10480142eea5a 100644
--- a/drivers/gpu/drm/nouveau/nvif/outp.c
+++ b/drivers/gpu/drm/nouveau/nvif/outp.c
@@ -210,6 +210,36 @@ nvif_outp_load_detect(struct nvif_outp *outp, u32 loadval)
return ret < 0 ? ret : args.load;
 }
 
+int
+nvif_outp_edid_get(struct nvif_outp *outp, u8 **pedid)
+{
+   struct nvif_outp_edid_get_v0 *args;
+   int ret;
+
+   args = kmalloc(sizeof(*args), GFP_KERNEL);
+   if (!args)
+   return -ENOMEM;
+
+   args->version = 0;
+
+   ret = nvif_mthd(>object, NVIF_OUTP_V0_EDID_GET, args, 
sizeof(*args));
+   NVIF_ERRON(ret, >object, "[EDID_GET] size:%d", args->size);
+   if (ret)
+   goto done;
+
+   *pedid = kmalloc(args->size, GFP_KERNEL);
+   if (!*pedid) {
+   ret = -ENOMEM;
+   

[PATCH v3 02/44] drm/nouveau/imem: support allocations not preserved across suspend

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

Will initially be used to tag some large grctx allocations which don't
need to be saved, to speedup suspend/resume.

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 .../drm/nouveau/include/nvkm/core/memory.h|  1 +
 .../drm/nouveau/include/nvkm/subdev/instmem.h |  2 +-
 drivers/gpu/drm/nouveau/nvkm/core/memory.c| 15 +--
 .../drm/nouveau/nvkm/subdev/instmem/base.c| 19 ++-
 .../drm/nouveau/nvkm/subdev/instmem/priv.h|  1 +
 5 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h 
b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h
index d3b6a68ddda36..fc0f389813916 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h
@@ -12,6 +12,7 @@ struct nvkm_tags {
 };
 
 enum nvkm_memory_target {
+   NVKM_MEM_TARGET_INST_SR_LOST, /* instance memory - not preserved across 
suspend */
NVKM_MEM_TARGET_INST, /* instance memory */
NVKM_MEM_TARGET_VRAM, /* video memory */
NVKM_MEM_TARGET_HOST, /* coherent system memory */
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h 
b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
index fcdaefc99fe85..92a36ddfc29ff 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
@@ -26,7 +26,7 @@ struct nvkm_instmem {
 
 u32 nvkm_instmem_rd32(struct nvkm_instmem *, u32 addr);
 void nvkm_instmem_wr32(struct nvkm_instmem *, u32 addr, u32 data);
-int nvkm_instobj_new(struct nvkm_instmem *, u32 size, u32 align, bool zero,
+int nvkm_instobj_new(struct nvkm_instmem *, u32 size, u32 align, bool zero, 
bool preserve,
 struct nvkm_memory **);
 int nvkm_instobj_wrap(struct nvkm_device *, struct nvkm_memory *, struct 
nvkm_memory **);
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/memory.c 
b/drivers/gpu/drm/nouveau/nvkm/core/memory.c
index c69daac9bac7b..a705c2dfca809 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/memory.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/memory.c
@@ -140,12 +140,23 @@ nvkm_memory_new(struct nvkm_device *device, enum 
nvkm_memory_target target,
 {
struct nvkm_instmem *imem = device->imem;
struct nvkm_memory *memory;
+   bool preserve = true;
int ret;
 
-   if (unlikely(target != NVKM_MEM_TARGET_INST || !imem))
+   if (unlikely(!imem))
return -ENOSYS;
 
-   ret = nvkm_instobj_new(imem, size, align, zero, );
+   switch (target) {
+   case NVKM_MEM_TARGET_INST_SR_LOST:
+   preserve = false;
+   break;
+   case NVKM_MEM_TARGET_INST:
+   break;
+   default:
+   return -ENOSYS;
+   }
+
+   ret = nvkm_instobj_new(imem, size, align, zero, preserve, );
if (ret)
return ret;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
index e0e4f97be0294..24886eabe8dc3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
@@ -94,15 +94,21 @@ nvkm_instobj_wrap(struct nvkm_device *device,
  struct nvkm_memory *memory, struct nvkm_memory **pmemory)
 {
struct nvkm_instmem *imem = device->imem;
+   int ret;
 
if (!imem->func->memory_wrap)
return -ENOSYS;
 
-   return imem->func->memory_wrap(imem, memory, pmemory);
+   ret = imem->func->memory_wrap(imem, memory, pmemory);
+   if (ret)
+   return ret;
+
+   container_of(*pmemory, struct nvkm_instobj, memory)->preserve = true;
+   return 0;
 }
 
 int
-nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero,
+nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero, 
bool preserve,
 struct nvkm_memory **pmemory)
 {
struct nvkm_subdev *subdev = >subdev;
@@ -130,6 +136,7 @@ nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 
align, bool zero,
nvkm_done(memory);
}
 
+   container_of(memory, struct nvkm_instobj, memory)->preserve = preserve;
 done:
if (ret)
nvkm_memory_unref();
@@ -176,9 +183,11 @@ nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend)
 
if (suspend) {
list_for_each_entry(iobj, >list, head) {
-   int ret = nvkm_instobj_save(iobj);
-   if (ret)
-   return ret;
+   if (iobj->preserve) {
+   int ret = nvkm_instobj_save(iobj);
+   if (ret)
+   return ret;
+   }
}
 
nvkm_bar_bar2_fini(subdev->device);
diff --git 

[PATCH v3 04/44] drm/nouveau/mmu/gp100-: always invalidate TLBs at CACHE_LEVEL_ALL

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

Fixes some issues when running on top of RM.

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c | 2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c
index f3630d0e0d55d..bddac77f48f06 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp100.c
@@ -558,7 +558,7 @@ gp100_vmm_invalidate_pdb(struct nvkm_vmm *vmm, u64 addr)
 void
 gp100_vmm_flush(struct nvkm_vmm *vmm, int depth)
 {
-   u32 type = (5 /* CACHE_LEVEL_UP_TO_PDE3 */ - depth) << 24;
+   u32 type = 0;
if (atomic_read(>engref[NVKM_SUBDEV_BAR]))
type |= 0x0004; /* HUB_ONLY */
type |= 0x0001; /* PAGE_ALL */
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c
index 6cb5eefa45e9a..0095d58d4d9a1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c
@@ -27,7 +27,7 @@ static void
 tu102_vmm_flush(struct nvkm_vmm *vmm, int depth)
 {
struct nvkm_device *device = vmm->mmu->subdev.device;
-   u32 type = (5 /* CACHE_LEVEL_UP_TO_PDE3 */ - depth) << 24;
+   u32 type = 0;
 
type |= 0x0001; /* PAGE_ALL */
if (atomic_read(>engref[NVKM_SUBDEV_BAR]))
-- 
2.41.0



[PATCH v3 06/44] drm/nouveau/disp: rearrange output methods

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

- preparation for a bunch of API changes, to make diffs prettier

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/include/nvif/if0012.h | 19 +++
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  | 12 ++--
 2 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0012.h 
b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
index 16d4ad5023a3e..7c56f653070c9 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0012.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0012.h
@@ -12,14 +12,17 @@ union nvif_outp_args {
} v0;
 };
 
-#define NVIF_OUTP_V0_LOAD_DETECT 0x00
-#define NVIF_OUTP_V0_ACQUIRE 0x01
-#define NVIF_OUTP_V0_RELEASE 0x02
-#define NVIF_OUTP_V0_INFOFRAME   0x03
-#define NVIF_OUTP_V0_HDA_ELD 0x04
-#define NVIF_OUTP_V0_DP_AUX_PWR  0x05
-#define NVIF_OUTP_V0_DP_RETRAIN  0x06
-#define NVIF_OUTP_V0_DP_MST_VCPI 0x07
+#define NVIF_OUTP_V0_ACQUIRE   0x11
+#define NVIF_OUTP_V0_RELEASE   0x12
+
+#define NVIF_OUTP_V0_LOAD_DETECT   0x20
+
+#define NVIF_OUTP_V0_INFOFRAME 0x60
+#define NVIF_OUTP_V0_HDA_ELD   0x61
+
+#define NVIF_OUTP_V0_DP_AUX_PWR0x70
+#define NVIF_OUTP_V0_DP_RETRAIN0x73
+#define NVIF_OUTP_V0_DP_MST_VCPI   0x78
 
 union nvif_outp_load_detect_args {
struct nvif_outp_load_detect_v0 {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index fc283a4a1522a..440ea52cc7d2b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -279,11 +279,11 @@ static int
 nvkm_uoutp_mthd_acquired(struct nvkm_outp *outp, u32 mthd, void *argv, u32 
argc)
 {
switch (mthd) {
-   case NVIF_OUTP_V0_RELEASE: return nvkm_uoutp_mthd_release(outp, 
argv, argc);
-   case NVIF_OUTP_V0_INFOFRAME  : return nvkm_uoutp_mthd_infoframe  (outp, 
argv, argc);
-   case NVIF_OUTP_V0_HDA_ELD: return nvkm_uoutp_mthd_hda_eld(outp, 
argv, argc);
-   case NVIF_OUTP_V0_DP_RETRAIN : return nvkm_uoutp_mthd_dp_retrain (outp, 
argv, argc);
-   case NVIF_OUTP_V0_DP_MST_VCPI: return nvkm_uoutp_mthd_dp_mst_vcpi(outp, 
argv, argc);
+   case NVIF_OUTP_V0_RELEASE  : return nvkm_uoutp_mthd_release  
(outp, argv, argc);
+   case NVIF_OUTP_V0_INFOFRAME: return nvkm_uoutp_mthd_infoframe
(outp, argv, argc);
+   case NVIF_OUTP_V0_HDA_ELD  : return nvkm_uoutp_mthd_hda_eld  
(outp, argv, argc);
+   case NVIF_OUTP_V0_DP_RETRAIN   : return nvkm_uoutp_mthd_dp_retrain   
(outp, argv, argc);
+   case NVIF_OUTP_V0_DP_MST_VCPI  : return nvkm_uoutp_mthd_dp_mst_vcpi  
(outp, argv, argc);
default:
break;
}
@@ -295,8 +295,8 @@ static int
 nvkm_uoutp_mthd_noacquire(struct nvkm_outp *outp, u32 mthd, void *argv, u32 
argc)
 {
switch (mthd) {
-   case NVIF_OUTP_V0_LOAD_DETECT: return nvkm_uoutp_mthd_load_detect(outp, 
argv, argc);
case NVIF_OUTP_V0_ACQUIRE: return nvkm_uoutp_mthd_acquire(outp, 
argv, argc);
+   case NVIF_OUTP_V0_LOAD_DETECT: return nvkm_uoutp_mthd_load_detect(outp, 
argv, argc);
case NVIF_OUTP_V0_DP_AUX_PWR : return nvkm_uoutp_mthd_dp_aux_pwr (outp, 
argv, argc);
default:
break;
-- 
2.41.0



[PATCH v3 05/44] drm/nouveau/kms/nv50-: fix mst payload alloc fail crashing evo

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

Programming -1 (vc_start_slot, if alloc fails) into HW probably isn't
the best idea.

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/dispnv50/disp.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c 
b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 39e9ba4139c7d..889ff667d0293 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -916,23 +916,27 @@ nv50_msto_prepare(struct drm_atomic_state *state,
struct nv50_mstc *mstc = msto->mstc;
struct nv50_mstm *mstm = mstc->mstm;
struct drm_dp_mst_atomic_payload *payload;
+   int ret = 0;
 
NV_ATOMIC(drm, "%s: msto prepare\n", msto->encoder.name);
 
payload = drm_atomic_get_mst_payload_state(mst_state, mstc->port);
 
-   // TODO: Figure out if we want to do a better job of handling VCPI 
allocation failures here?
if (msto->disabled) {
drm_dp_remove_payload_part1(mgr, mst_state, payload);
-
nvif_outp_dp_mst_vcpi(>outp->outp, 
msto->head->base.index, 0, 0, 0, 0);
+   ret = 1;
} else {
if (msto->enabled)
-   drm_dp_add_payload_part1(mgr, mst_state, payload);
+   ret = drm_dp_add_payload_part1(mgr, mst_state, payload);
+   }
 
+   if (ret == 0) {
nvif_outp_dp_mst_vcpi(>outp->outp, msto->head->base.index,
  payload->vc_start_slot, 
payload->time_slots,
  payload->pbn, payload->time_slots * 
mst_state->pbn_div);
+   } else {
+   nvif_outp_dp_mst_vcpi(>outp->outp, 
msto->head->base.index, 0, 0, 0, 0);
}
 }
 
-- 
2.41.0



[PATCH v3 03/44] drm/nouveau/gr/gf100-: lose contents of global ctxbufs across suspend

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

Some of these buffers are quite large, and there's no need to preserve
them across suspend.

Mark the contents as lost to speedup suspend/resume.

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c 
b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
index 3648868bb9fc5..c494a1ff2d572 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
@@ -2032,18 +2032,18 @@ gf100_gr_oneinit(struct nvkm_gr *base)
}
 
/* Allocate global context buffers. */
-   ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 
gr->func->grctx->pagepool_size,
- 0x100, false, >pagepool);
+   ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST_SR_LOST,
+ gr->func->grctx->pagepool_size, 0x100, false, 
>pagepool);
if (ret)
return ret;
 
-   ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 
gr->func->grctx->bundle_size,
+   ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST_SR_LOST, 
gr->func->grctx->bundle_size,
  0x100, false, >bundle_cb);
if (ret)
return ret;
 
-   ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 
gr->func->grctx->attrib_cb_size(gr),
- 0x1000, false, >attrib_cb);
+   ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST_SR_LOST,
+ gr->func->grctx->attrib_cb_size(gr), 0x1000, 
false, >attrib_cb);
if (ret)
return ret;
 
-- 
2.41.0



[PATCH v3 00/44] drm/nouveau: initial support for GSP-RM 535.54.04 (and Ada GPUs)

2023-09-19 Thread Lyude Paul
Hey everyone! I'm just going through and rebasing Ben's display patches
so I can push them in just a moment :).

(*the rest of this email can be read in Ben Skegg's voice*)

The primary issue being tackled here is that, for historical reasons (we
didn't know any better / couldn't make it work reliably otherwise), some
operations (SOR routing, DP link training) were performed during the 2nd
HW supervisor interrupt.

We don't have control of the display supervisor when running on top of
RM, so this needed to be untangled and fixed - which, is one of the main
aims of this patch series.

The ordering of this series is pretty important, so take care if/when
backporting patches from it.

Beyond that main goal, various other interfaces have been added or
extended to provide the information that RM will need for its version of
similar interfaces.

Ben Skeggs (43):
  drm/nouveau/devinit/tu102-: remove attempt at loading PreOS
  drm/nouveau/imem: support allocations not preserved across suspend
  drm/nouveau/gr/gf100-: lose contents of global ctxbufs across suspend
  drm/nouveau/mmu/gp100-: always invalidate TLBs at CACHE_LEVEL_ALL
  drm/nouveau/kms/nv50-: fix mst payload alloc fail crashing evo
  drm/nouveau/disp: rearrange output methods
  drm/nouveau/disp: add output detect method
  drm/nouveau/disp: add output method to fetch edid
  drm/nouveau/disp: rename internal output acquire/release functions
  drm/nouveau/disp: shuffle to make upcoming diffs prettier
  drm/nouveau/disp: add acquire_dac()
  drm/nouveau/disp: add acquire_sor/pior()
  drm/nouveau/disp: update SOR routing immediately on acquire()
  drm/nouveau/kms/nv50-: pull some common init out of OR-specific code
  drm/nouveau/kms/nv50-: remove nv_encoder.audio.connector
  drm/nouveau/kms/nv50-: keep output state around until modeset complete
  drm/nouveau/kms/nv50-: move audio enable post-modeset
  drm/nouveau/disp: add output hdmi config method
  drm/nouveau/disp: move hdmi disable out of release()
  drm/nouveau/disp: release outputs post-modeset
  drm/nouveau/disp: remove SOR routing updates from supervisor
  drm/nouveau/disp: add output backlight control methods
  drm/nouveau/disp: add output lvds config method
  drm/nouveau/disp: add hdmi audio hal function
  drm/nouveau/disp: move dp aux pwr method to HAL
  drm/nouveau/disp: add dp aux xfer method
  drm/nouveau/disp: add dp rates method
  drm/nouveau/kms/nv50-: split DP disable+enable into two modesets
  drm/nouveau/kms/nv50-: flush mst disables together
  drm/nouveau/kms/nv50-: fixup sink D3 before tearing down link
  drm/nouveau/disp: add dp train method
  drm/nouveau/disp: move link training out of supervisor
  drm/nouveau/disp: add dp sst config method
  drm/nouveau/disp: add dp mst id get/put methods
  drm/nouveau/disp: move outp/conn construction to chipset code
  drm/nouveau/disp: move outp init/fini paths to chipset code
  drm/nouveau/disp/nv50-: skip DCB_OUTPUT_TV
  drm/nouveau/kms/nv50-: create heads based on nvkm head mask
  drm/nouveau/kms/nv50-: create heads after outps/conns
  drm/nouveau/kms/nv50-: name aux channels after their connector
  drm/nouveau/kms/nv50-: create connectors based on nvkm info
  drm/nouveau/kms/nv50-: create outputs based on nvkm info
  drm/nouveau/kms/nv50-: disable dcb parsing

Lyude Paul (1):
  drm/nouveau/kms: Add INHERIT ioctl to nvkm/nvif for reading IOR state

 drivers/gpu/drm/nouveau/dispnv04/disp.c   |   2 +-
 drivers/gpu/drm/nouveau/dispnv50/disp.c   | 511 +++---
 drivers/gpu/drm/nouveau/dispnv50/disp.h   |   6 +-
 drivers/gpu/drm/nouveau/dispnv50/head.h   |   1 +
 drivers/gpu/drm/nouveau/dispnv50/headc57d.c   |  14 +
 drivers/gpu/drm/nouveau/include/nvif/conn.h   |  20 +-
 drivers/gpu/drm/nouveau/include/nvif/if0011.h |  21 +-
 drivers/gpu/drm/nouveau/include/nvif/if0012.h | 249 +++--
 drivers/gpu/drm/nouveau/include/nvif/outp.h   |  96 +++-
 .../drm/nouveau/include/nvkm/core/memory.h|   1 +
 .../drm/nouveau/include/nvkm/subdev/instmem.h |   2 +-
 drivers/gpu/drm/nouveau/nouveau_backlight.c   |  90 +--
 drivers/gpu/drm/nouveau/nouveau_bios.c|   8 +-
 drivers/gpu/drm/nouveau/nouveau_connector.c   | 252 -
 drivers/gpu/drm/nouveau/nouveau_connector.h   |   3 +-
 drivers/gpu/drm/nouveau/nouveau_display.c |   8 +-
 drivers/gpu/drm/nouveau/nouveau_dp.c  | 345 ++--
 drivers/gpu/drm/nouveau/nouveau_encoder.h |  30 +-
 drivers/gpu/drm/nouveau/nvif/conn.c   |  36 +-
 drivers/gpu/drm/nouveau/nvif/disp.c   |   2 +-
 drivers/gpu/drm/nouveau/nvif/outp.c   | 412 --
 drivers/gpu/drm/nouveau/nvkm/core/memory.c|  15 +-
 .../gpu/drm/nouveau/nvkm/engine/disp/base.c   | 146 +
 .../gpu/drm/nouveau/nvkm/engine/disp/conn.c   |  10 -
 .../gpu/drm/nouveau/nvkm/engine/disp/conn.h   |   2 -
 drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c | 362 -
 .../gpu/drm/nouveau/nvkm/engine/disp/g84.c|   1 +
 .../gpu/drm/nouveau/nvkm/engine/disp/g94.c|   1 

[PATCH v3 01/44] drm/nouveau/devinit/tu102-: remove attempt at loading PreOS

2023-09-19 Thread Lyude Paul
From: Ben Skeggs 

>From Turing, HW will already have handled this and locked-down the
falcon before we get control.  So this *should* be a no-op.

Signed-off-by: Ben Skeggs 
Reviewed-by: Lyude Paul 
Acked-by: Danilo Krummrich 
Signed-off-by: Lyude Paul 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c
index 81a1ad2c88a7e..40997ad1d101c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/tu102.c
@@ -83,17 +83,9 @@ tu102_devinit_wait(struct nvkm_device *device)
 }
 
 int
-tu102_devinit_post(struct nvkm_devinit *base, bool post)
+tu102_devinit_post(struct nvkm_devinit *init, 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;
+   return tu102_devinit_wait(init->subdev.device);
 }
 
 static const struct nvkm_devinit_func
-- 
2.41.0



Re: [PATCH] gpu: drm: amd: display: fix kernel-doc warnings

2023-09-19 Thread Randy Dunlap
Hi,

On 9/19/23 02:33, Swarup Laxman Kotiaklapudi wrote:
> Fix kernel-doc warnings discovered in AMD gpu display driver.
> Fixes these warnings:
> ./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:110: warning:
> Function parameter or member 'overlap_only'
> not described in 'mpcc_blnd_cfg'.
> 
> ./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:110: warning:
> Function parameter or member 'bottom_gain_mode'
> not described in 'mpcc_blnd_cfg'.
> 
> ./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:110: warning:
> Function parameter or member 'background_color_bpc'
> not described in 'mpcc_blnd_cfg'.
> 
> ./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:110:
> warning: Function parameter or member 'top_gain'
> not described in 'mpcc_blnd_cfg'.
> 
> ./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:110:
> warning: Function parameter or member 'bottom_inside_gain'
> not described in 'mpcc_blnd_cfg'.
> 
> ./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:110:
> warning: Function parameter or member 'bottom_outside_gain'
> not described in 'mpcc_blnd_cfg'.
> 
> Signed-off-by: Swarup Laxman Kotiaklapudi 

Thanks for fixing these kernel-doc warnings.

Tested-by: Randy Dunlap 
Acked-by: Randy Dunlap 


> ---
>  drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h 
> b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
> index 8d86159d9de0..61a2406dcc53 100644
> --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
> +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
> @@ -91,6 +91,12 @@ enum mpcc_alpha_blend_mode {
>   * @global_gain: used when blend mode considers both pixel alpha and plane
>   * alpha value and assumes the global alpha value.
>   * @global_alpha: plane alpha value
> + * @overlap_only: whether overlapping of different planes is allowed
> + * @bottom_gain_mode: blend mode for bottom gain setting
> + * @background_color_bpc: background color for bpc
> + * @top_gain: top gain setting
> + * @bottom_inside_gain: blend mode for bottom inside
> + * @bottom_outside_gain:  blend mode for bottom outside
>   */
>  struct mpcc_blnd_cfg {
>   struct tg_color black_color;/* background color */

-- 
~Randy


Re: [PATCH] drm/mst: check connector state before dereference

2023-09-19 Thread Mario Limonciello

On 9/19/2023 15:51, Fangzhi Zuo wrote:

We are seeing the crash in the wild that we cannot repro ourselves.
We want to be able to gather more data and the code should never be
allowed to crash.

[8.433306] BUG: kernel NULL pointer dereference, address: 0008
[8.433318] #PF: supervisor read access in kernel mode
[8.433323] #PF: error_code(0x) - not-present page
[8.433327] PGD 0 P4D 0
[8.43] Oops:  [#1] PREEMPT SMP NOPTI
[8.49] CPU: 7 PID: 488 Comm: Xorg Tainted: G   OE  
6.2.10-arch1-1-4-g72efbf0a04ca #2 cb04c5bbf595f3de9363c870cd584da0b91be458
[8.433348] Hardware name: HP HP ProBook 445 G6/85D9, BIOS R80 Ver. 01.21.01 
07/28/2022
[8.433351] RIP: 0010:drm_dp_atomic_find_time_slots+0x5e/0x260 
[drm_display_helper]
[8.433387] Code: 01 00 00 48 8b 85 60 05 00 00 48 63 80 88 00 00 00 3b 43 28 0f 
8d 2e 01 00 00 48 8b 53 30 48 8d 04 80 48 8d 04 c2 48 8b 40 18 <48> 8b 40 08 4d 
8d 65 38 8b 88 90 00 00 00 b8 01 00 00 00 d3 e0 41
[8.433392] RSP: 0018:b7b540ee36b0 EFLAGS: 00010293
[8.433397] RAX:  RBX: 90d6064ae780 RCX: 0224
[8.433401] RDX: 90d6069e0400 RSI: 90d60c496568 RDI: 90d6064ae780
[8.433405] RBP: 90d60c483000 R08: 0407 R09: 90d608c8e850
[8.433408] R10: 0002 R11:  R12: b7b540ee3798
[8.433411] R13: 90d607ab9660 R14: 90d60c496568 R15: 0224
[8.433415] FS:  7fead406e440() GS:90d9201c() 
knlGS:
[8.433419] CS:  0010 DS:  ES:  CR0: 80050033
[8.433423] CR2: 0008 CR3: 000102f96000 CR4: 003506e0
[8.433427] Call Trace:
[8.433431]  
[8.433437]  compute_mst_dsc_configs_for_link+0x31a/0xab0 [amdgpu 
b041282416fbbcc9f3f3583485c4c54bacfbbcf9]
[8.434321]  ? get_page_from_freelist+0x14a5/0x1630
[8.434338]  compute_mst_dsc_configs_for_state+0x1e1/0x250 [amdgpu 
b041282416fbbcc9f3f3583485c4c54bacfbbcf9]
[8.435205]  amdgpu_dm_atomic_check+0xf33/0x11b0 [amdgpu 
b041282416fbbcc9f3f3583485c4c54bacfbbcf9]
[8.435985]  drm_atomic_check_only+0x5c0/0xa30
[8.435994]  drm_atomic_commit+0x5a/0xd0
[8.436001]  ? __pfx___drm_printfn_info+0x10/0x10
[8.436008]  drm_atomic_helper_set_config+0x74/0xb0
[8.436014]  drm_mode_setcrtc+0x515/0x7e0
[8.436023]  ? __pfx_drm_mode_setcrtc+0x10/0x10
[8.436029]  drm_ioctl_kernel+0xcd/0x170
[8.436036]  drm_ioctl+0x233/0x410
[8.436040]  ? __pfx_drm_mode_setcrtc+0x10/0x10
[8.436049]  amdgpu_drm_ioctl+0x4e/0x90 [amdgpu 
b041282416fbbcc9f3f3583485c4c54bacfbbcf9]
[8.436755]  __x64_sys_ioctl+0x94/0xd0
[8.436763]  do_syscall_64+0x5f/0x90
[8.436772]  ? amdgpu_drm_ioctl+0x71/0x90 [amdgpu 
b041282416fbbcc9f3f3583485c4c54bacfbbcf9]
[8.437477]  ? __x64_sys_ioctl+0xac/0xd0
[8.437484]  ? syscall_exit_to_user_mode+0x1b/0x40
[8.437492]  ? do_syscall_64+0x6b/0x90
[8.437499]  ? amdgpu_drm_ioctl+0x71/0x90 [amdgpu 
b041282416fbbcc9f3f3583485c4c54bacfbbcf9]
[8.438193]  ? __x64_sys_ioctl+0xac/0xd0
[8.438199]  ? syscall_exit_to_user_mode+0x1b/0x40
[8.438205]  ? do_syscall_64+0x6b/0x90
[8.438211]  ? syscall_exit_to_user_mode+0x1b/0x40
[8.438217]  ? do_syscall_64+0x6b/0x90
[8.438223]  entry_SYSCALL_64_after_hwframe+0x72/0xdc
[8.438231] RIP: 0033:0x7fead4a3f53f
[8.438258] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 
89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 
ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00 00
[8.438262] RSP: 002b:7ffd20e26be0 EFLAGS: 0246 ORIG_RAX: 
0010
[8.438268] RAX: ffda RBX: 564cc75abfa0 RCX: 7fead4a3f53f
[8.438271] RDX: 7ffd20e26c70 RSI: c06864a2 RDI: 000f
[8.438273] RBP: 7ffd20e26c70 R08:  R09: 564cc75dec90
[8.438276] R10:  R11: 0246 R12: c06864a2
[8.438278] R13: 000f R14: 564cc6cb7f00 R15: 564cc6ab4620
[8.438286]  
[8.438288] Modules linked in: cmac algif_hash algif_skcipher af_alg bnep 
rtw88_8822be snd_hda_codec_realtek intel_rapl_msr intel_rapl_common rtw88_8822b 
snd_hda_codec_generic edac_mce_amd ledtrig_audio snd_hda_codec_hdmi rtw88_pci 
kvm_amd rtw88_core snd_hda_intel kvm snd_intel_dspcfg mac80211 nls_iso8859_1 
snd_intel_sdw_acpi uvcvideo btusb vfat snd_hda_codec irqbypass fat btrtl 
videobuf2_vmalloc crct10dif_pclmul crc32_pclmul videobuf2_memops 
polyval_clmulni btbcm libarc4 snd_hda_core videobuf2_v4l2 polyval_generic 
btintel gf128mul snd_hwdep btmtk ghash_clmulni_intel hid_multitouch 
sha512_ssse3 videodev r8169 snd_pcm cfg80211 bluetooth aesni_intel ucsi_acpi 
realtek typec_ucsi hp_wmi videobuf2_common crypto_simd mdio_devres 
sparse_keymap snd_timer sp5100_tco cryptd typec mc ecdh_generic mousedev joydev 
rapl platform_profile snd 

[PATCH] drm/mst: check connector state before dereference

2023-09-19 Thread Fangzhi Zuo
We are seeing the crash in the wild that we cannot repro ourselves.
We want to be able to gather more data and the code should never be
allowed to crash.

[8.433306] BUG: kernel NULL pointer dereference, address: 0008
[8.433318] #PF: supervisor read access in kernel mode
[8.433323] #PF: error_code(0x) - not-present page
[8.433327] PGD 0 P4D 0
[8.43] Oops:  [#1] PREEMPT SMP NOPTI
[8.49] CPU: 7 PID: 488 Comm: Xorg Tainted: G   OE  
6.2.10-arch1-1-4-g72efbf0a04ca #2 cb04c5bbf595f3de9363c870cd584da0b91be458
[8.433348] Hardware name: HP HP ProBook 445 G6/85D9, BIOS R80 Ver. 01.21.01 
07/28/2022
[8.433351] RIP: 0010:drm_dp_atomic_find_time_slots+0x5e/0x260 
[drm_display_helper]
[8.433387] Code: 01 00 00 48 8b 85 60 05 00 00 48 63 80 88 00 00 00 3b 43 
28 0f 8d 2e 01 00 00 48 8b 53 30 48 8d 04 80 48 8d 04 c2 48 8b 40 18 <48> 8b 40 
08 4d 8d 65 38 8b 88 90 00 00 00 b8 01 00 00 00 d3 e0 41
[8.433392] RSP: 0018:b7b540ee36b0 EFLAGS: 00010293
[8.433397] RAX:  RBX: 90d6064ae780 RCX: 0224
[8.433401] RDX: 90d6069e0400 RSI: 90d60c496568 RDI: 90d6064ae780
[8.433405] RBP: 90d60c483000 R08: 0407 R09: 90d608c8e850
[8.433408] R10: 0002 R11:  R12: b7b540ee3798
[8.433411] R13: 90d607ab9660 R14: 90d60c496568 R15: 0224
[8.433415] FS:  7fead406e440() GS:90d9201c() 
knlGS:
[8.433419] CS:  0010 DS:  ES:  CR0: 80050033
[8.433423] CR2: 0008 CR3: 000102f96000 CR4: 003506e0
[8.433427] Call Trace:
[8.433431]  
[8.433437]  compute_mst_dsc_configs_for_link+0x31a/0xab0 [amdgpu 
b041282416fbbcc9f3f3583485c4c54bacfbbcf9]
[8.434321]  ? get_page_from_freelist+0x14a5/0x1630
[8.434338]  compute_mst_dsc_configs_for_state+0x1e1/0x250 [amdgpu 
b041282416fbbcc9f3f3583485c4c54bacfbbcf9]
[8.435205]  amdgpu_dm_atomic_check+0xf33/0x11b0 [amdgpu 
b041282416fbbcc9f3f3583485c4c54bacfbbcf9]
[8.435985]  drm_atomic_check_only+0x5c0/0xa30
[8.435994]  drm_atomic_commit+0x5a/0xd0
[8.436001]  ? __pfx___drm_printfn_info+0x10/0x10
[8.436008]  drm_atomic_helper_set_config+0x74/0xb0
[8.436014]  drm_mode_setcrtc+0x515/0x7e0
[8.436023]  ? __pfx_drm_mode_setcrtc+0x10/0x10
[8.436029]  drm_ioctl_kernel+0xcd/0x170
[8.436036]  drm_ioctl+0x233/0x410
[8.436040]  ? __pfx_drm_mode_setcrtc+0x10/0x10
[8.436049]  amdgpu_drm_ioctl+0x4e/0x90 [amdgpu 
b041282416fbbcc9f3f3583485c4c54bacfbbcf9]
[8.436755]  __x64_sys_ioctl+0x94/0xd0
[8.436763]  do_syscall_64+0x5f/0x90
[8.436772]  ? amdgpu_drm_ioctl+0x71/0x90 [amdgpu 
b041282416fbbcc9f3f3583485c4c54bacfbbcf9]
[8.437477]  ? __x64_sys_ioctl+0xac/0xd0
[8.437484]  ? syscall_exit_to_user_mode+0x1b/0x40
[8.437492]  ? do_syscall_64+0x6b/0x90
[8.437499]  ? amdgpu_drm_ioctl+0x71/0x90 [amdgpu 
b041282416fbbcc9f3f3583485c4c54bacfbbcf9]
[8.438193]  ? __x64_sys_ioctl+0xac/0xd0
[8.438199]  ? syscall_exit_to_user_mode+0x1b/0x40
[8.438205]  ? do_syscall_64+0x6b/0x90
[8.438211]  ? syscall_exit_to_user_mode+0x1b/0x40
[8.438217]  ? do_syscall_64+0x6b/0x90
[8.438223]  entry_SYSCALL_64_after_hwframe+0x72/0xdc
[8.438231] RIP: 0033:0x7fead4a3f53f
[8.438258] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 
00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 
00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00 00
[8.438262] RSP: 002b:7ffd20e26be0 EFLAGS: 0246 ORIG_RAX: 
0010
[8.438268] RAX: ffda RBX: 564cc75abfa0 RCX: 7fead4a3f53f
[8.438271] RDX: 7ffd20e26c70 RSI: c06864a2 RDI: 000f
[8.438273] RBP: 7ffd20e26c70 R08:  R09: 564cc75dec90
[8.438276] R10:  R11: 0246 R12: c06864a2
[8.438278] R13: 000f R14: 564cc6cb7f00 R15: 564cc6ab4620
[8.438286]  
[8.438288] Modules linked in: cmac algif_hash algif_skcipher af_alg bnep 
rtw88_8822be snd_hda_codec_realtek intel_rapl_msr intel_rapl_common rtw88_8822b 
snd_hda_codec_generic edac_mce_amd ledtrig_audio snd_hda_codec_hdmi rtw88_pci 
kvm_amd rtw88_core snd_hda_intel kvm snd_intel_dspcfg mac80211 nls_iso8859_1 
snd_intel_sdw_acpi uvcvideo btusb vfat snd_hda_codec irqbypass fat btrtl 
videobuf2_vmalloc crct10dif_pclmul crc32_pclmul videobuf2_memops 
polyval_clmulni btbcm libarc4 snd_hda_core videobuf2_v4l2 polyval_generic 
btintel gf128mul snd_hwdep btmtk ghash_clmulni_intel hid_multitouch 
sha512_ssse3 videodev r8169 snd_pcm cfg80211 bluetooth aesni_intel ucsi_acpi 
realtek typec_ucsi hp_wmi videobuf2_common crypto_simd mdio_devres 
sparse_keymap snd_timer sp5100_tco cryptd typec mc ecdh_generic mousedev joydev 
rapl platform_profile snd psmouse rfkill k10temp wmi_bmof i2c_piix4 

Re: [PATCH] drm/imx/lcdc: Fix double-free of driver data

2023-09-19 Thread Uwe Kleine-König
Hello,

On Thu, Jul 06, 2023 at 11:27:31AM +0200, Uwe Kleine-König wrote:
> The struct imx_lcdc driver data is allocated using devm_drm_dev_alloc()
> so it must not be explicitly kfree()d.
> 
> Also drm_kms_helper_poll_fini() should not be called as there is no
> matching drm_kms_helper_poll_init(). So drop the release function
> completely.
> 
> Fixes: c87e859cdeb5 ("drm/imx/lcdc: Implement DRM driver for imx25")
> Signed-off-by: Uwe Kleine-König 

This fix is now waiting for two months to be picked up. Who feels
responsible?

Best regards
Uwe

-- 
Pengutronix e.K.   | Uwe Kleine-König|
Industrial Linux Solutions | https://www.pengutronix.de/ |


signature.asc
Description: PGP signature


Re: [PATCH 1/2] kunit: Warn if tests are slow

2023-09-19 Thread Rae Moar
On Mon, Sep 11, 2023 at 5:51 AM Maxime Ripard  wrote:
>
> Kunit recently gained support to setup attributes, the first one being
> the speed of a given test, then allowing to filter out slow tests.
>
> A slow test is defined in the documentation as taking more than one
> second. There's an another speed attribute called "super slow" but whose
> definition is less clear.
>
> Add support to the test runner to check the test execution time, and
> report tests that should be marked as slow but aren't.
>
> Signed-off-by: Maxime Ripard 

Hi!

I like this idea especially if it was helpful in identifying slow
tests already! I have a few thoughts on this. I share Jani's concern
for warning all tests on slow machines. I can think of a few options.

First, we could increase the threshold to about 2s even though that
would eliminate warnings on potentially slow tests. However, this
would point out the slowest tests.

Second, we could change this to warn users only when they choose by
making this a configurable option or making this a script to output a
list of all unmarked slow tests.

Third, we could leave this as is. As the KUnit warnings do not show up
in the kunit.py output and do not cause the test to fail in any way
they are relatively harmless if they are unwanted by the user.

Not quite sure which I prefer? The second option might be the cleanest
for the user and the time threshold could even be customizable. Let me
know what you think.

> ---
>  lib/kunit/test.c | 16 
>  1 file changed, 16 insertions(+)
>
> diff --git a/lib/kunit/test.c b/lib/kunit/test.c
> index 49698a168437..a3b924501f3d 100644
> --- a/lib/kunit/test.c
> +++ b/lib/kunit/test.c
> @@ -379,6 +379,9 @@ static void kunit_run_case_internal(struct kunit *test,
> struct kunit_suite *suite,
> struct kunit_case *test_case)
>  {
> +   struct timespec64 start, end;
> +   struct timespec64 duration;
> +
> if (suite->init) {
> int ret;
>
> @@ -390,7 +393,20 @@ static void kunit_run_case_internal(struct kunit *test,
> }
> }
>
> +   ktime_get_ts64();
> +
> test_case->run_case(test);
> +
> +   ktime_get_ts64();
> +
> +   duration = timespec64_sub(end, start);
> +
> +   if (duration.tv_sec >= 1 &&
> +   (test_case->attr.speed == KUNIT_SPEED_UNSET ||
> +test_case->attr.speed >= KUNIT_SPEED_NORMAL))
> +   kunit_warn(test,
> +  "Test should be marked slow (runtime: 
> %lld.%09lds)",
> +  duration.tv_sec, duration.tv_nsec);

I would consider moving this if statement into a separate function.

>  }
>
>  static void kunit_case_internal_cleanup(struct kunit *test)
>
> --
> 2.41.0
>
> --
> You received this message because you are subscribed to the Google Groups 
> "KUnit Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to kunit-dev+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/kunit-dev/20230911-kms-slow-tests-v1-1-d3800a69a1a1%40kernel.org.


[PATCH] i915: Limit the length of an sg list to the requested length

2023-09-19 Thread Matthew Wilcox (Oracle)
The folio conversion changed the behaviour of shmem_sg_alloc_table() to
put the entire length of the last folio into the sg list, even if the sg
list should have been shorter.  gen8_ggtt_insert_entries() relied on the
list being the right langth and would overrun the end of the page tables.
Other functions may also have been affected.

Clamp the length of the last entry in the sg list to be the expected
length.

Signed-off-by: Matthew Wilcox (Oracle) 
Fixes: 0b62af28f249 ("i915: convert shmem_sg_free_table() to use a folio_batch")
Cc: sta...@vger.kernel.org # 6.5.x
Link: https://gitlab.freedesktop.org/drm/intel/-/issues/9256
Link: https://lore.kernel.org/lkml/6287208.lov4wx5...@natalenko.name/
Reported-by: Oleksandr Natalenko 
Tested-by: Oleksandr Natalenko 
---
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 8f1633c3fb93..73a4a4eb29e0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -100,6 +100,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, 
struct sg_table *st,
st->nents = 0;
for (i = 0; i < page_count; i++) {
struct folio *folio;
+   unsigned long nr_pages;
const unsigned int shrink[] = {
I915_SHRINK_BOUND | I915_SHRINK_UNBOUND,
0,
@@ -150,6 +151,8 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, 
struct sg_table *st,
}
} while (1);
 
+   nr_pages = min_t(unsigned long,
+   folio_nr_pages(folio), page_count - i);
if (!i ||
sg->length >= max_segment ||
folio_pfn(folio) != next_pfn) {
@@ -157,13 +160,13 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, 
struct sg_table *st,
sg = sg_next(sg);
 
st->nents++;
-   sg_set_folio(sg, folio, folio_size(folio), 0);
+   sg_set_folio(sg, folio, nr_pages * PAGE_SIZE, 0);
} else {
/* XXX: could overflow? */
-   sg->length += folio_size(folio);
+   sg->length += nr_pages * PAGE_SIZE;
}
-   next_pfn = folio_pfn(folio) + folio_nr_pages(folio);
-   i += folio_nr_pages(folio) - 1;
+   next_pfn = folio_pfn(folio) + nr_pages;
+   i += nr_pages - 1;
 
/* Check that the i965g/gm workaround works. */
GEM_BUG_ON(gfp & __GFP_DMA32 && next_pfn >= 0x0010UL);
-- 
2.40.1



Re: [REGRESSION] [BISECTED] Panic in gen8_ggtt_insert_entries() with v6.5

2023-09-19 Thread Matthew Wilcox
On Tue, Sep 19, 2023 at 08:11:47PM +0200, Oleksandr Natalenko wrote:
> I can confirm this one fixes the issue for me on T460s laptop. Thank you!

Yay!

> Should you submit it, please add:
> 
> Fixes: 0b62af28f2 ("i915: convert shmem_sg_free_table() to use a folio_batch")

Thanks for collecting all these; you're making my life really easy.
One minor point is that the standard format for Fixes: is 12 characters,
not 10.  eg,

Documentation/process/5.Posting.rst:Fixes: 1f2e3d4c5b6a ("The first line of 
the commit specified by the first 12 characters of its SHA-1 ID")

I have this in my .gitconfig:

[pretty]
fixes = Fixes: %h (\"%s\")

and in .git/config,

[core]
abbrev = 12

I'm working on the commit message now.


Re: [PATCH 1/2] video: fbdev: core: cfbcopyarea: fix sloppy typing

2023-09-19 Thread Helge Deller

On 9/19/23 20:55, Sergey Shtylyov wrote:

On 9/19/23 10:05 AM, Helge Deller wrote:

In cfb_copyarea(), when initializing *unsigned long const* bits_per_line
__u32 typed fb_fix_screeninfo::line_length gets multiplied by 8u -- which
might overflow __u32; multiplying by 8UL instead should fix that...
Also, that bits_per_line constant is used to advance *unsigned* src_idx
and dst_idx variables -- which might be overflowed as well; declaring
them as *unsigned long* should fix that too...

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: Sergey Shtylyov 
Cc: sta...@vger.kernel.org
---
   drivers/video/fbdev/core/cfbcopyarea.c | 5 +++--
   1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/core/cfbcopyarea.c 
b/drivers/video/fbdev/core/cfbcopyarea.c
index 6d4bfeecee35..b67ba69ea2fb 100644
--- a/drivers/video/fbdev/core/cfbcopyarea.c
+++ b/drivers/video/fbdev/core/cfbcopyarea.c
@@ -382,10 +382,11 @@ void cfb_copyarea(struct fb_info *p, const struct 
fb_copyarea *area)
   {
   u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
   u32 height = area->height, width = area->width;
-    unsigned long const bits_per_line = p->fix.line_length*8u;
+    unsigned long const bits_per_line = p->fix.line_length * 8UL;


you wrote:

__u32 typed fb_fix_screeninfo::line_length gets multiplied by 8u -- which
might overflow __u32; multiplying by 8UL instead should fix that...


This would only be true on 64-bit CPUs, where unsigned long is 64 bits,


Right, Svace was run with the arm64 and x86_64 configs -- and I forgot
to make the emphasis on the 64-bit specifics here...


while on 32-bit CPUs, it's still 32 bits (same as _u32).


Yes, indeed. That *unsigned long const* doesn't seem justified
at all then...


Instead we could make bits_per_line __u32 (or unsigned int) too.


Yes. Will you accept such a patch? :-)


Sure.

Helge


Re: [PATCH 1/2] video: fbdev: core: cfbcopyarea: fix sloppy typing

2023-09-19 Thread Sergey Shtylyov
Hello!

On 9/19/23 10:05 AM, Helge Deller wrote:

>> In cfb_copyarea(), when initializing *unsigned long const* bits_per_line
>> __u32 typed fb_fix_screeninfo::line_length gets multiplied by 8u -- which
>> might overflow __u32; multiplying by 8UL instead should fix that...
>> Also, that bits_per_line constant is used to advance *unsigned* src_idx
>> and dst_idx variables -- which might be overflowed as well; declaring
>> them as *unsigned long* should fix that too...
>>
>> Found by Linux Verification Center (linuxtesting.org) with the Svace static
>> analysis tool.
>>
>> Signed-off-by: Sergey Shtylyov 
>> Cc: sta...@vger.kernel.org
>> ---
>>   drivers/video/fbdev/core/cfbcopyarea.c | 5 +++--
>>   1 file changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/video/fbdev/core/cfbcopyarea.c 
>> b/drivers/video/fbdev/core/cfbcopyarea.c
>> index 6d4bfeecee35..b67ba69ea2fb 100644
>> --- a/drivers/video/fbdev/core/cfbcopyarea.c
>> +++ b/drivers/video/fbdev/core/cfbcopyarea.c
>> @@ -382,10 +382,11 @@ void cfb_copyarea(struct fb_info *p, const struct 
>> fb_copyarea *area)
>>   {
>>   u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
>>   u32 height = area->height, width = area->width;
>> -    unsigned long const bits_per_line = p->fix.line_length*8u;
>> +    unsigned long const bits_per_line = p->fix.line_length * 8UL;
> 
> you wrote:
>> __u32 typed fb_fix_screeninfo::line_length gets multiplied by 8u -- which
>> might overflow __u32; multiplying by 8UL instead should fix that...
> 
> This would only be true on 64-bit CPUs, where unsigned long is 64 bits,

   Right, Svace was run with the arm64 and x86_64 configs -- and I forgot
to make the emphasis on the 64-bit specifics here...

> while on 32-bit CPUs, it's still 32 bits (same as _u32).

   Yes, indeed. That *unsigned long const* doesn't seem justified
at all then...

> Instead we could make bits_per_line __u32 (or unsigned int) too.

   Yes. Will you accept such a patch? :-)

>>   unsigned long __iomem *base = NULL;
>>   int bits = BITS_PER_LONG, bytes = bits >> 3;
>> -    unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;
>> +    unsigned long dst_idx = 0, src_idx = 0;
> 
> An "unsigned int" can address at least up to 4GB, which is fully sufficent 
> here.

   Good to know! :-)

> So, both patches don't have any real effect.
> NAK.

   Thanks for your time!

> Helge

MBR, Sergey


[PATCH] MAINTAINERS: drm/ci: add entries for xfail files

2023-09-19 Thread Helen Koike
DRM CI keeps track of which tests are failing, flaking or being skipped
by the ci in the expectations files. Add entries for those files to the
corresponding driver maintainer, so they can be notified when they
change.

Signed-off-by: Helen Koike 
---

For reference: 
https://www.mail-archive.com/dri-devel@lists.freedesktop.org/msg463165.html

 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 90f13281d297..740a2ce2689c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6614,6 +6614,7 @@ S:Maintained
 B: https://gitlab.freedesktop.org/drm/msm/-/issues
 T: git https://gitlab.freedesktop.org/drm/msm.git
 F: Documentation/devicetree/bindings/display/msm/
+F: drivers/gpu/drm/ci/xfails/msm*
 F: drivers/gpu/drm/msm/
 F: include/uapi/drm/msm_drm.h
 
@@ -6886,6 +6887,7 @@ T:git git://anongit.freedesktop.org/drm/drm-misc
 F: Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml
 F: Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
 F: Documentation/gpu/meson.rst
+F: drivers/gpu/drm/ci/xfails/meson*
 F: drivers/gpu/drm/meson/
 
 DRM DRIVERS FOR ATMEL HLCDC
@@ -6994,6 +6996,7 @@ L:dri-devel@lists.freedesktop.org
 L: linux-media...@lists.infradead.org (moderated for non-subscribers)
 S: Supported
 F: Documentation/devicetree/bindings/display/mediatek/
+F: drivers/gpu/drm/ci/xfails/mediatek*
 F: drivers/gpu/drm/mediatek/
 F: drivers/phy/mediatek/phy-mtk-dp.c
 F: drivers/phy/mediatek/phy-mtk-hdmi*
@@ -7034,6 +7037,7 @@ L:dri-devel@lists.freedesktop.org
 S: Maintained
 T: git git://anongit.freedesktop.org/drm/drm-misc
 F: Documentation/devicetree/bindings/display/rockchip/
+F: drivers/gpu/drm/ci/xfails/rockchip*
 F: drivers/gpu/drm/rockchip/
 
 DRM DRIVERS FOR STI
@@ -10476,6 +10480,7 @@ C:  irc://irc.oftc.net/intel-gfx
 T: git git://anongit.freedesktop.org/drm-intel
 F: Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon
 F: Documentation/gpu/i915.rst
+F: drivers/gpu/drm/ci/xfails/i915*
 F: drivers/gpu/drm/i915/
 F: include/drm/i915*
 F: include/uapi/drm/i915_drm.h
@@ -17862,6 +17867,7 @@ C:  irc://irc.oftc.net/radeon
 T: git https://gitlab.freedesktop.org/agd5f/linux.git
 F: Documentation/gpu/amdgpu/
 F: drivers/gpu/drm/amd/
+F: drivers/gpu/drm/ci/xfails/amd*
 F: drivers/gpu/drm/radeon/
 F: include/uapi/drm/amdgpu_drm.h
 F: include/uapi/drm/radeon_drm.h
@@ -22846,6 +22852,7 @@ L:  dri-devel@lists.freedesktop.org
 L: virtualizat...@lists.linux-foundation.org
 S: Maintained
 T: git git://anongit.freedesktop.org/drm/drm-misc
+F: drivers/gpu/drm/ci/xfails/virtio*
 F: drivers/gpu/drm/virtio/
 F: include/uapi/linux/virtio_gpu.h
 
-- 
2.34.1



Re: [PATCH] drm: remove drm_bridge_hpd_disable() from drm_bridge_connector_destroy()

2023-09-19 Thread Laurent Pinchart
Hi Abhinav,

Thank you for the patch.

On Tue, Sep 19, 2023 at 10:48:12AM -0700, Abhinav Kumar wrote:
> drm_bridge_hpd_enable()/drm_bridge_hpd_disable() callbacks call into
> the respective driver's hpd_enable()/hpd_disable() ops. These ops control
> the HPD enable/disable logic which in some cases like MSM can be a
> dedicate hardware block to control the HPD.
> 
> During probe_defer cases, a connector can be initialized and then later
> destroyed till the probe is retried. During connector destroy in these
> cases, the hpd_disable() callback gets called without a corresponding
> hpd_enable() leading to an unbalanced state potentially causing even
> a crash.
> 
> This can be avoided by the respective drivers maintaining their own
> state logic to ensure that a hpd_disable() without a corresponding
> hpd_enable() just returns without doing anything.
> 
> However, to have a generic fix it would be better to avoid the
> hpd_disable() callback from the connector destroy path and let
> the hpd_enable() / hpd_disable() balance be maintained by the
> corresponding drm_bridge_connector_enable_hpd() /
> drm_bridge_connector_disable_hpd() APIs which should get called by
> drm_kms_helper_disable_hpd().

The change makes sense to me, but I'm a bit worried this could introduce
a regression by leaving HPD enabled in some cases.

I agree that bridges shouldn't track the HPD state, it should be tracked
by the core and the .enable_hpd() and .disable_hpd() operations should
be balanced. Their documentation, however, doesn't clearly state this,
and the documentation of the callers of these operations is also fairly
unclear.

Could you perhaps try to improve the documentation ? With that,

Reviewed-by: Laurent Pinchart 

for this patch.

> changes in v2:
>   - minor change in commit text (Dmitry)
> 
> Signed-off-by: Abhinav Kumar 
> Reviewed-by: Dmitry Baryshkov 
> ---
>  drivers/gpu/drm/drm_bridge_connector.c | 6 --
>  1 file changed, 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_bridge_connector.c 
> b/drivers/gpu/drm/drm_bridge_connector.c
> index 1da93d5a1f61..c4dba39acfd8 100644
> --- a/drivers/gpu/drm/drm_bridge_connector.c
> +++ b/drivers/gpu/drm/drm_bridge_connector.c
> @@ -187,12 +187,6 @@ static void drm_bridge_connector_destroy(struct 
> drm_connector *connector)
>   struct drm_bridge_connector *bridge_connector =
>   to_drm_bridge_connector(connector);
>  
> - if (bridge_connector->bridge_hpd) {
> - struct drm_bridge *hpd = bridge_connector->bridge_hpd;
> -
> - drm_bridge_hpd_disable(hpd);
> - }
> -
>   drm_connector_unregister(connector);
>   drm_connector_cleanup(connector);
>  

-- 
Regards,

Laurent Pinchart


Re: [REGRESSION] [BISECTED] Panic in gen8_ggtt_insert_entries() with v6.5

2023-09-19 Thread Oleksandr Natalenko
Hello.

On úterý 19. září 2023 17:43:40 CEST Matthew Wilcox wrote:
> On Tue, Sep 19, 2023 at 10:26:42AM +0200, Oleksandr Natalenko wrote:
> > Andrzej asked me to try to revert commits 0b62af28f249, e0b72c14d8dc and 
> > 1e0877d58b1e, and reverting those fixed the i915 crash for me. The 
> > e0b72c14d8dc and 1e0877d58b1e commits look like just prerequisites, so I 
> > assume 0b62af28f249 ("i915: convert shmem_sg_free_table() to use a 
> > folio_batch") is the culprit here.
> > 
> > Could you please check this?
> > 
> > Our conversation with Andrzej is available at drm-intel GitLab [1].
> > 
> > Thanks.
> > 
> > [1] https://gitlab.freedesktop.org/drm/intel/-/issues/9256
> 
> Wow, that is some great debugging.  Thanks for all the time & effort
> you and others have invested.  Sorry for breaking your system.
> 
> You're almost right about the "prerequisites", but it's in the other
> direction; 0b62af28f249 is a prerequisite for the later two cleanups,
> so reverting all three is necessary to test 0b62af28f249.
> 
> It seems to me that you've isolated the problem to constructing overly
> long sg lists.  I didn't realise that was going to be a problem, so
> that's my fault.
> 
> Could I ask you to try this patch?  I'll follow up with another patch
> later because I think I made another assumption that may not be valid.

I can confirm this one fixes the issue for me on T460s laptop. Thank you!

Should you submit it, please add:

Fixes: 0b62af28f2 ("i915: convert shmem_sg_free_table() to use a folio_batch")
Cc: sta...@vger.kernel.org # 6.5.x
Link: https://gitlab.freedesktop.org/drm/intel/-/issues/9256
Link: https://lore.kernel.org/lkml/6287208.lov4wx5...@natalenko.name/
Reported-by: Oleksandr Natalenko 
Tested-by: Oleksandr Natalenko 

> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
> index 8f1633c3fb93..73a4a4eb29e0 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
> @@ -100,6 +100,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, 
> struct sg_table *st,
>   st->nents = 0;
>   for (i = 0; i < page_count; i++) {
>   struct folio *folio;
> + unsigned long nr_pages;
>   const unsigned int shrink[] = {
>   I915_SHRINK_BOUND | I915_SHRINK_UNBOUND,
>   0,
> @@ -150,6 +151,8 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, 
> struct sg_table *st,
>   }
>   } while (1);
>  
> + nr_pages = min_t(unsigned long,
> + folio_nr_pages(folio), page_count - i);
>   if (!i ||
>   sg->length >= max_segment ||
>   folio_pfn(folio) != next_pfn) {
> @@ -157,13 +160,13 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, 
> struct sg_table *st,
>   sg = sg_next(sg);
>  
>   st->nents++;
> - sg_set_folio(sg, folio, folio_size(folio), 0);
> + sg_set_folio(sg, folio, nr_pages * PAGE_SIZE, 0);
>   } else {
>   /* XXX: could overflow? */
> - sg->length += folio_size(folio);
> + sg->length += nr_pages * PAGE_SIZE;
>   }
> - next_pfn = folio_pfn(folio) + folio_nr_pages(folio);
> - i += folio_nr_pages(folio) - 1;
> + next_pfn = folio_pfn(folio) + nr_pages;
> + i += nr_pages - 1;
>  
>   /* Check that the i965g/gm workaround works. */
>   GEM_BUG_ON(gfp & __GFP_DMA32 && next_pfn >= 0x0010UL);

-- 
Oleksandr Natalenko (post-factum)

signature.asc
Description: This is a digitally signed message part.


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

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

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

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

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

Re: [PATCH] dt-bindings: display: anx7814: Add definition for anx7816

2023-09-19 Thread Rob Herring


On Mon, 18 Sep 2023 23:49:44 +0200, Alicja Michalska wrote:
> As requested by Robert Foss , this patch adds
> definition for anx7816. It supplements the patch submitted to dri-devel.
> 
> Signed-off-by: Alicja Michalska 
> ---
>  .../devicetree/bindings/display/bridge/analogix,anx7814.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring 



Re: [PATCH] dt-bindings: display: anx7814: Add definition for anx7816

2023-09-19 Thread Rob Herring
On Mon, Sep 18, 2023 at 11:49:44PM +0200, Alicja Michalska wrote:
> As requested by Robert Foss , this patch adds
> definition for anx7816. It supplements the patch submitted to dri-devel.

Please apply with the driver change.

> 
> Signed-off-by: Alicja Michalska 
> ---
>  .../devicetree/bindings/display/bridge/analogix,anx7814.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/bridge/analogix,anx7814.yaml 
> b/Documentation/devicetree/bindings/display/bridge/analogix,anx7814.yaml
> index 4a5e5d9d6f90..4509c496731b 100644
> --- a/Documentation/devicetree/bindings/display/bridge/analogix,anx7814.yaml
> +++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7814.yaml
> @@ -17,6 +17,7 @@ properties:
>- analogix,anx7808
>- analogix,anx7812
>- analogix,anx7814
> +  - analogix,anx7816
>- analogix,anx7818
>  
>reg:
> -- 
> 2.41.0
> 


[PATCH] drm: remove drm_bridge_hpd_disable() from drm_bridge_connector_destroy()

2023-09-19 Thread Abhinav Kumar
drm_bridge_hpd_enable()/drm_bridge_hpd_disable() callbacks call into
the respective driver's hpd_enable()/hpd_disable() ops. These ops control
the HPD enable/disable logic which in some cases like MSM can be a
dedicate hardware block to control the HPD.

During probe_defer cases, a connector can be initialized and then later
destroyed till the probe is retried. During connector destroy in these
cases, the hpd_disable() callback gets called without a corresponding
hpd_enable() leading to an unbalanced state potentially causing even
a crash.

This can be avoided by the respective drivers maintaining their own
state logic to ensure that a hpd_disable() without a corresponding
hpd_enable() just returns without doing anything.

However, to have a generic fix it would be better to avoid the
hpd_disable() callback from the connector destroy path and let
the hpd_enable() / hpd_disable() balance be maintained by the
corresponding drm_bridge_connector_enable_hpd() /
drm_bridge_connector_disable_hpd() APIs which should get called by
drm_kms_helper_disable_hpd().

changes in v2:
- minor change in commit text (Dmitry)

Signed-off-by: Abhinav Kumar 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/drm_bridge_connector.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_bridge_connector.c 
b/drivers/gpu/drm/drm_bridge_connector.c
index 1da93d5a1f61..c4dba39acfd8 100644
--- a/drivers/gpu/drm/drm_bridge_connector.c
+++ b/drivers/gpu/drm/drm_bridge_connector.c
@@ -187,12 +187,6 @@ static void drm_bridge_connector_destroy(struct 
drm_connector *connector)
struct drm_bridge_connector *bridge_connector =
to_drm_bridge_connector(connector);
 
-   if (bridge_connector->bridge_hpd) {
-   struct drm_bridge *hpd = bridge_connector->bridge_hpd;
-
-   drm_bridge_hpd_disable(hpd);
-   }
-
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
 
-- 
2.40.1



Re: [PATCH v3 1/1] backlight: hid_bl: Add VESA VCP HID backlight driver

2023-09-19 Thread Julius Zint


On Wed, 6 Sep 2023, Hans de Goede wrote:

> Hi Julius,
> 
> On 9/4/23 21:02, Julius Zint wrote:
> > 
> > 
> > On Mon, 4 Sep 2023, Thomas Weißschuh wrote:
> > 
> >> +Cc Hans who ins involved with the backlight subsystem
> >>
> >> Hi Julius,
> >>
> >> today I stumbled upon a mail from Hans [0], which explains that the
> >> backlight subsystem is not actually a good fit (yet?) for external
> >> displays.
> >>
> >> It seems a new API is in the works that would better fit, but I'm not
> >> sure about the state of this API. Maybe Hans can clarify.
> >>
> >> This also ties back to my review question how userspace can figure out
> >> to which display a backlight devices applies. So far it can not.
> >>
> >> [0] 
> >> https://lore.kernel.org/lkml/7f2d88de-60c5-e2ff-9b22-acba35cfd...@redhat.com/
> >>
> > 
> > Hi Thomas,
> > 
> > thanks for the hint. I will make sure to give this a proper read and
> > see, if it fits my use case better then the current backlight subsystem.
> 
> Note the actual proposal for the new usespace API for display brightness
> control is here:
> 
> https://lore.kernel.org/dri-devel/b61d3eeb-6213-afac-2e70-7b9791c86...@redhat.com/
> 
> I have finished / stabilized the backlight code refactor which I landed
> in 6.1, which is a prerequisite for the above proposal. But I have not
> been able to make time to actually implement the above proposal; and
> I don't know when I will be able to make time for this.
> 
> > Especially since I wasnt able to properly address your other review
> > comments for now. You are right that the name should align better with
> > the kernel module and also, that it is possible for multiple displays to
> > be attached.
> > 
> > In its current state, this would mean that you could only control the
> > backlight for the first HID device (enough for me :-).
> > 
> > The systemd-backlight@.service uses not only the file name, but also the
> > full bus path for storing/restoring backlights. I did not yet get around
> > to see how the desktops handle brightness control, but since the
> > systemd-backlight@.service already uses the name, its important to stay
> > the same over multiple boots.
> > 
> > I would be able to get a handle on the underlying USB device and use the
> > serial to uniquely (and persistently) name the backlight. But it does
> > feel hacky doing it this way.
> 
> So mutter (gnome-shell compositor library) has a similar issue when saving
> monitor layouts and I can tell you beforehand that monitor serial numbers
> by themselves are not unique enough. Some models just report 123456789
> as serial and if you have a dual-monitor setup with 2 such monitors
> and name the backlight class device -vcp-hid or something like that
> you will still end up with 2 identical names.
> 
> To avoid this when saving monitor layouts mutter saves both the port
> to which the monitor is attached (e.g. DP-1 DP-2) and the serialnumber
> and on startup / monitor hotplug when it checks to see if it has saved
> layout info for the monitor it checks the port+serialnr combination.
> 
> So what I think you should do is figure out a way to map which
> VCP HID device maps to which drm-connector and then use
> the connector-name + serial-nr to generate the backlight device name.
> 
> We will need the mapping the a drm-connector object anyway for
> the new brightness API proposal from above.
> 
> Note this does NOT solve the fact that registering a new backlight
> class device for an external monitor on a laptop will hopelessly
> confuse userspace, see:
> 
> https://lore.kernel.org/lkml/7f2d88de-60c5-e2ff-9b22-acba35cfd...@redhat.com/
> 
> Regards,
> 
> Hans
> 

Thank you for all this additional information. I have watched the talks
and read up upon the mail threads you`ve linked.

I will see if I can make the mapping to the DRM connector and plan to
update this patchset.

Thanks,

Julius

Re: [PATCH] drm/atomic-helper: prevent uaf in wait_for_vblanks

2023-09-19 Thread Michel Dänzer
On 9/18/23 18:53, José Pekkarinen wrote:
> Kasan reported the following in my system:
> 
> [ 3935.321003] 
> ==
> [ 3935.321022] BUG: KASAN: slab-use-after-free in 
> drm_atomic_helper_wait_for_vblanks.part.0+0x116/0x450 [drm_kms_helper]
> [ 3935.321124] Read of size 1 at addr 88818a6f8009 by task 
> kworker/u16:3/5268
> 
> [ 3935.321124] CPU: 7 PID: 5268 Comm: kworker/u16:3 Not tainted 6.6.0-rc2+ #1
> [ 3935.321124] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 
> 02/06/2015
> [ 3935.321124] Workqueue: events_unbound commit_work [drm_kms_helper]
> [ 3935.321124] Call Trace:
> [ 3935.321124]  
> [ 3935.321124]  dump_stack_lvl+0x43/0x60
> [ 3935.321124]  print_report+0xcf/0x660
> [ 3935.321124]  ? remove_entity_load_avg+0xdc/0x100
> [ 3935.321124]  ? __virt_addr_valid+0xd9/0x160
> [ 3935.321124]  ? drm_atomic_helper_wait_for_vblanks.part.0+0x116/0x450 
> [drm_kms_helper]
> [ 3935.321124]  kasan_report+0xda/0x110
> [ 3935.321124]  ? drm_atomic_helper_wait_for_vblanks.part.0+0x116/0x450 
> [drm_kms_helper]
> [ 3935.321124]  drm_atomic_helper_wait_for_vblanks.part.0+0x116/0x450 
> [drm_kms_helper]
> [ 3935.321124]  ? __pfx_drm_atomic_helper_wait_for_vblanks.part.0+0x10/0x10 
> [drm_kms_helper]
> [ 3935.321124]  ? complete_all+0x48/0x100
> [ 3935.321124]  ? _raw_spin_unlock_irqrestore+0x19/0x40
> [ 3935.321124]  ? preempt_count_sub+0x14/0xc0
> [ 3935.321124]  ? _raw_spin_unlock_irqrestore+0x23/0x40
> [ 3935.321124]  ? drm_atomic_helper_commit_hw_done+0x1ac/0x240 
> [drm_kms_helper]
> [ 3935.321124]  drm_atomic_helper_commit_tail+0x82/0x90 [drm_kms_helper]
> [ 3935.321124]  commit_tail+0x15c/0x1d0 [drm_kms_helper]
> [ 3935.323185]  process_one_work+0x31a/0x610
> [ 3935.323185]  worker_thread+0x38e/0x5f0
> [ 3935.323185]  ? __pfx_worker_thread+0x10/0x10
> [ 3935.323185]  kthread+0x184/0x1c0
> [ 3935.323185]  ? __pfx_kthread+0x10/0x10
> [ 3935.323185]  ret_from_fork+0x30/0x50
> [ 3935.323185]  ? __pfx_kthread+0x10/0x10
> [ 3935.323185]  ret_from_fork_asm+0x1b/0x30
> [ 3935.323185]  
> 
> [ 3935.323185] Allocated by task 3751:
> [ 3935.323185]  kasan_save_stack+0x2f/0x50
> [ 3935.323185]  kasan_set_track+0x21/0x30
> [ 3935.323185]  __kasan_kmalloc+0xa6/0xb0
> [ 3935.323185]  drm_atomic_helper_crtc_duplicate_state+0x42/0x70 
> [drm_kms_helper]
> [ 3935.323185]  drm_atomic_get_crtc_state+0xc3/0x1e0 [drm]
> [ 3935.323185]  page_flip_common+0x42/0x160 [drm_kms_helper]
> [ 3935.323185]  drm_atomic_helper_page_flip+0x6b/0xf0 [drm_kms_helper]
> [ 3935.323185]  drm_mode_page_flip_ioctl+0x8ad/0x900 [drm]
> [ 3935.323185]  drm_ioctl_kernel+0x169/0x240 [drm]
> [ 3935.323185]  drm_ioctl+0x399/0x6b0 [drm]
> [ 3935.324772]  __x64_sys_ioctl+0xc5/0x100
> [ 3935.324772]  do_syscall_64+0x5b/0xc0
> [ 3935.324772]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
> 
> [ 3935.324772] Freed by task 3751:
> [ 3935.324772]  kasan_save_stack+0x2f/0x50
> [ 3935.324772]  kasan_set_track+0x21/0x30
> [ 3935.324772]  kasan_save_free_info+0x27/0x40
> [ 3935.324772]  kasan_slab_free+0x166/0x1c0
> [ 3935.324772]  slab_free_freelist_hook+0x9f/0x1e0
> [ 3935.324772]  __kmem_cache_free+0x187/0x2d0
> [ 3935.324772]  drm_atomic_state_default_clear+0x226/0x5e0 [drm]
> [ 3935.324772]  __drm_atomic_state_free+0xc8/0x130 [drm]
> [ 3935.324772]  drm_atomic_helper_update_plane+0x17d/0x1b0 [drm_kms_helper]
> [ 3935.324772]  drm_mode_cursor_universal+0x2a4/0x4d0 [drm]
> [ 3935.324772]  drm_mode_cursor_common+0x1cf/0x430 [drm]
> [ 3935.324772]  drm_mode_cursor_ioctl+0xc6/0x100 [drm]
> [ 3935.326167]  drm_ioctl_kernel+0x169/0x240 [drm]
> [ 3935.326167]  drm_ioctl+0x399/0x6b0 [drm]
> [ 3935.326614]  __x64_sys_ioctl+0xc5/0x100
> [ 3935.326614]  do_syscall_64+0x5b/0xc0
> [ 3935.326614]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
> 
> [ 3935.326614] The buggy address belongs to the object at 88818a6f8000
> which belongs to the cache kmalloc-512 of size 512
> [ 3935.326614] The buggy address is located 9 bytes inside of
> freed 512-byte region [88818a6f8000, 88818a6f8200)
> 
> [ 3935.326614] The buggy address belongs to the physical page:
> [ 3935.326614] page:b0fb0816 refcount:1 mapcount:0 
> mapping: index:0x0 pfn:0x18a6f8
> [ 3935.326614] head:b0fb0816 order:3 entire_mapcount:0 
> nr_pages_mapped:0 pincount:0
> [ 3935.326614] anon flags: 
> 0x17c840(slab|head|node=0|zone=2|lastcpupid=0x1f)
> [ 3935.326614] page_type: 0x()
> [ 3935.326614] raw: 0017c840 888100042c80  
> dead0001
> [ 3935.326614] raw:  80200020 0001 
> 
> [ 3935.326614] page dumped because: kasan: bad access detected
> 
> [ 3935.326614] Memory state around the buggy address:
> [ 3935.326614]  88818a6f7f00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc 
> fc fc
> [ 3935.326614]  88818a6f7f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc 
> 

Re: [PATCH 01/15] dt-bindings: mailbox: Add property for CMDQ secure driver

2023-09-19 Thread Rob Herring
On Tue, Sep 19, 2023 at 03:21:50AM +0800, Jason-JH.Lin wrote:
> Add mboxes to define a GCE loopping thread as a secure irq handler.
> Add mediatek,event to define a GCE software event siganl as a secure
> irq.
> 
> These 2 properties are required for CMDQ secure driver.
> 
> Signed-off-by: Jason-JH.Lin 
> ---
>  .../mailbox/mediatek,gce-mailbox.yaml | 30 +++
>  1 file changed, 24 insertions(+), 6 deletions(-)
> 
> diff --git 
> a/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml 
> b/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml
> index cef9d7601398..5c9aebe83d2d 100644
> --- a/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml
> +++ b/Documentation/devicetree/bindings/mailbox/mediatek,gce-mailbox.yaml
> @@ -49,6 +49,21 @@ properties:
>  items:
>- const: gce
>  
> +  mboxes:
> +description:
> +  A mailbox channel used as a secure irq handler in normal world.
> +  Using mailbox to communicate with GCE to setup looping thread,
> +  it should have this property and a phandle, mailbox specifiers.

All cases of 'mboxes' have a phandle and specifiers. No need to repeat 
that here.

> +$ref: /schemas/types.yaml#/definitions/phandle-array

Already has a type definition too. You need to define how many entries 
and what each entry is if more than one. IOW, the same thing as clocks, 
resets, interrupts, etc.

> +
> +  mediatek,gce-events:

This is used all over. It really needs a single definition which is then 
referenced by the users.

> +description:
> +  The event id which is mapping to a software event signal to gce.
> +  It is used as a secure irq for every secure gce threads.
> +  The event id is defined in the gce header
> +  include/dt-bindings/mailbox/mediatek,-gce.h of each chips.
> +$ref: /schemas/types.yaml#/definitions/uint32-array
> +
>  required:
>- compatible
>- "#mbox-cells"
> @@ -71,20 +86,23 @@ additionalProperties: false
>  
>  examples:
>- |
> -#include 
> +#include 
>  #include 
>  #include 
> +#include 
>  
>  soc {
>  #address-cells = <2>;
>  #size-cells = <2>;
>  
> -gce: mailbox@10212000 {
> -compatible = "mediatek,mt8173-gce";
> -reg = <0 0x10212000 0 0x1000>;
> -interrupts = ;
> +gce0: mailbox@1032 {
> +compatible = "mediatek,mt8188-gce";

Are these new properties only for mt8188? If so, then you need a schema 
saying that. If not, then this is an unnecessary change to the example.

> +reg = <0 0x1032 0 0x4000>;
> +interrupts = ;
>  #mbox-cells = <2>;
> -clocks = < CLK_INFRA_GCE>;
> +clocks = <_ao CLK_INFRA_AO_GCE>;
>  clock-names = "gce";
> +mboxes = < 15 CMDQ_THR_PRIO_1>;

The provider is also a consumer?

> +mediatek,gce-events = ;
>  };
>  };
> -- 
> 2.18.0
> 


Re: [REGRESSION] [BISECTED] Panic in gen8_ggtt_insert_entries() with v6.5

2023-09-19 Thread Matthew Wilcox
On Tue, Sep 19, 2023 at 04:43:41PM +0100, Matthew Wilcox wrote:
> Could I ask you to try this patch?  I'll follow up with another patch
> later because I think I made another assumption that may not be valid.

Ah, no, never mind.  I thought we could start in the middle of a folio,
but we always start constructing the sg list from index 0 of the file,
so we always start at the first page of a folio.  If this patch solves
your problem, then I think we're done.


Re: [REGRESSION] [BISECTED] Panic in gen8_ggtt_insert_entries() with v6.5

2023-09-19 Thread Matthew Wilcox
On Tue, Sep 19, 2023 at 10:26:42AM +0200, Oleksandr Natalenko wrote:
> Andrzej asked me to try to revert commits 0b62af28f249, e0b72c14d8dc and 
> 1e0877d58b1e, and reverting those fixed the i915 crash for me. The 
> e0b72c14d8dc and 1e0877d58b1e commits look like just prerequisites, so I 
> assume 0b62af28f249 ("i915: convert shmem_sg_free_table() to use a 
> folio_batch") is the culprit here.
> 
> Could you please check this?
> 
> Our conversation with Andrzej is available at drm-intel GitLab [1].
> 
> Thanks.
> 
> [1] https://gitlab.freedesktop.org/drm/intel/-/issues/9256

Wow, that is some great debugging.  Thanks for all the time & effort
you and others have invested.  Sorry for breaking your system.

You're almost right about the "prerequisites", but it's in the other
direction; 0b62af28f249 is a prerequisite for the later two cleanups,
so reverting all three is necessary to test 0b62af28f249.

It seems to me that you've isolated the problem to constructing overly
long sg lists.  I didn't realise that was going to be a problem, so
that's my fault.

Could I ask you to try this patch?  I'll follow up with another patch
later because I think I made another assumption that may not be valid.

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 8f1633c3fb93..73a4a4eb29e0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -100,6 +100,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, 
struct sg_table *st,
st->nents = 0;
for (i = 0; i < page_count; i++) {
struct folio *folio;
+   unsigned long nr_pages;
const unsigned int shrink[] = {
I915_SHRINK_BOUND | I915_SHRINK_UNBOUND,
0,
@@ -150,6 +151,8 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, 
struct sg_table *st,
}
} while (1);
 
+   nr_pages = min_t(unsigned long,
+   folio_nr_pages(folio), page_count - i);
if (!i ||
sg->length >= max_segment ||
folio_pfn(folio) != next_pfn) {
@@ -157,13 +160,13 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, 
struct sg_table *st,
sg = sg_next(sg);
 
st->nents++;
-   sg_set_folio(sg, folio, folio_size(folio), 0);
+   sg_set_folio(sg, folio, nr_pages * PAGE_SIZE, 0);
} else {
/* XXX: could overflow? */
-   sg->length += folio_size(folio);
+   sg->length += nr_pages * PAGE_SIZE;
}
-   next_pfn = folio_pfn(folio) + folio_nr_pages(folio);
-   i += folio_nr_pages(folio) - 1;
+   next_pfn = folio_pfn(folio) + nr_pages;
+   i += nr_pages - 1;
 
/* Check that the i965g/gm workaround works. */
GEM_BUG_ON(gfp & __GFP_DMA32 && next_pfn >= 0x0010UL);


Re: [GIT PULL] drm: renesas: shmobile: Atomic conversion + DT support (was: Re: [PATCH v4 00/41] drm: renesas: shmobile: Atomic conversion + DT support)

2023-09-19 Thread Laurent Pinchart
On Tue, Sep 19, 2023 at 04:28:40PM +0200, Geert Uytterhoeven wrote:
> Hi David, Daniel,
> 
> The following changes since commit 0663e1da5ba8e6459e3555ac12c62741668c0d30:
> 
>   drm/dp_mst: Tune down error message during payload addition
> (2023-09-18 16:38:21 +0300)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git
> tags/shmob-drm-atomic-dt-tag1
> 
> for you to fetch changes up to bfea0fa9052aa8d235b24957eb84d9ff20cb87b7:
> 
>   drm: renesas: shmobile: Add DT support (2023-09-19 15:58:04 +0200)
> 
> 
> drm: renesas: shmobile: Atomic conversion + DT support
> 
> Currently, there are two drivers for the LCD controller on Renesas
> SuperH-based and ARM-based SH-Mobile and R-Mobile SoCs:
>   1. sh_mobile_lcdcfb, using the fbdev framework,
>   2. shmob_drm, using the DRM framework.
> However, only the former driver is used, as all platform support
> integrates the former.  None of these drivers support DT-based systems.
> 
> Convert the SH-Mobile DRM driver to atomic modesetting, and add DT
> support, complemented by the customary set of fixes and improvements.
> 
> Link: https://lore.kernel.org/r/cover.1694767208.git.geert+rene...@glider.be/
> 
> This PR is based on today's drm-misc/for-linux-next, to avoid a
> conflict with commit 775b0669e19f2e4a ("drm/shmobile: Convert to
> platform remove callback returning void") in drm-misc/for-linux-next
> .
> Thanks for pulling!
> 
> Geert Uytterhoeven (36):
>   MAINTAINER: Create entry for Renesas SH-Mobile DRM drivers

I'm technically listed as the maintainer for this driver until Geert
takes over, so for this pull request,

Acked-by: Laurent Pinchart 

And after that, shmobile won't need my ack to merge further changes :-)

This is very nice work Geert. I'm looking forward to dropping the
sh_mobile_lcdcfb driver.

>   dt-bindings: display: Add Renesas SH-Mobile LCDC bindings
>   media: uapi: Add MEDIA_BUS_FMT_RGB666_2X9_BE format
>   drm: renesas: shmobile: Fix overlay plane disable
>   drm: renesas: shmobile: Fix ARGB32 overlay format typo
>   drm: renesas: shmobile: Correct encoder/connector types
>   drm: renesas: shmobile: Add support for Runtime PM
>   drm: renesas: shmobile: Restore indentation of shmob_drm_setup_clocks()
>   drm: renesas: shmobile: Use %p4cc to print fourcc code
>   drm: renesas: shmobile: Add missing YCbCr formats
>   drm: renesas: shmobile: Improve shmob_drm_format_info table
>   drm: renesas: shmobile: Improve error handling
>   drm: renesas: shmobile: Convert to use devm_request_irq()
>   drm: renesas: shmobile: Remove custom plane destroy callback
>   drm: renesas: shmobile: Use drmm_universal_plane_alloc()
>   drm: renesas: shmobile: Embed drm_device in shmob_drm_device
>   drm: renesas: shmobile: Convert container helpers to static inline 
> functions
>   drm: renesas: shmobile: Replace .dev_private with container_of()
>   drm: renesas: shmobile: Use media bus formats in platform data
>   drm: renesas: shmobile: Move interface handling to connector setup
>   drm: renesas: shmobile: Unify plane allocation
>   drm: renesas: shmobile: Rename shmob_drm_crtc.crtc
>   drm: renesas: shmobile: Rename shmob_drm_connector.connector
>   drm: renesas: shmobile: Rename shmob_drm_plane.plane
>   drm: renesas: shmobile: Use drm_crtc_handle_vblank()
>   drm: renesas: shmobile: Move shmob_drm_crtc_finish_page_flip()
>   drm: renesas: shmobile: Wait for page flip when turning CRTC off
>   drm: renesas: shmobile: Turn vblank on/off when enabling/disabling CRTC
>   drm: renesas: shmobile: Shutdown the display on remove
>   drm: renesas: shmobile: Cleanup encoder
>   drm: renesas: shmobile: Atomic conversion part 1
>   drm: renesas: shmobile: Atomic conversion part 2
>   drm: renesas: shmobile: Use suspend/resume helpers
>   drm: renesas: shmobile: Remove internal CRTC state tracking
>   drm: renesas: shmobile: Atomic conversion part 3
>   drm: renesas: shmobile: Add DT support
> 
> Laurent Pinchart (5):
>   drm: renesas: shmobile: Remove backlight support
>   drm: renesas: shmobile: Don't set display info width and height twice
>   drm: renesas: shmobile: Rename input clocks
>   drm: renesas: shmobile: Remove support for SYS panels
>   drm: renesas: shmobile: Use struct videomode in platform data
> 
>  .../bindings/display/renesas,shmobile-lcdc.yaml| 130 +
>  .../userspace-api/media/v4l/subdev-formats.rst |  72 +++
>  MAINTAINERS|  13 +-
>  drivers/gpu/drm/renesas/shmobile/Kconfig   |   3 +-
>  drivers/gpu/drm/renesas/shmobile/Makefile  |   3 +-
>  .../gpu/drm/renesas/shmobile/shmob_drm_backlight.c |  82 ---
>  

Re: [PATCH drm-misc-next v3 6/7] drm/gpuvm: generalize dma_resv/extobj handling and GEM validation

2023-09-19 Thread Thomas Hellström



On 9/19/23 17:16, Danilo Krummrich wrote:

On 9/19/23 14:21, Thomas Hellström wrote:

Hi Christian

On 9/19/23 14:07, Christian König wrote:

Am 13.09.23 um 17:46 schrieb Danilo Krummrich:

On 9/13/23 17:33, Christian König wrote:

Am 13.09.23 um 17:15 schrieb Danilo Krummrich:

On 9/13/23 16:26, Christian König wrote:

Am 13.09.23 um 14:16 schrieb Danilo Krummrich:
As mentioned in a different mail thread, the reply is based on 
the assumption
that we don't support anything else than GPUVM updates from the 
IOCTL.


I think that this assumption is incorrect.


Well, more precisely I should have said "don't support GPUVM 
updated from within
fence signaling critical sections". And looking at the code, that 
doesn't seem what

you're doing there.



Vulkan is just once specific use case, but this here should 
probably be able to handle other use cases as well.


Especially with HMM you get the requirement that you need to be 
able to invalidate GPUVM mappings without grabbing a reservation 
lock.


What do you mean with "invalidate GPUVM mappings" in this 
context? drm_gpuvm_bo_evict()
should only be called from a ttm_device_funcs::move callback, we 
should hold the dma-resv

lock there.


Well the question is which dma-resv lock do we hold?

In the move callback we only hold the dma-resv lock of the BO 
which is moved, but when that is a shared BO then that's not the 
same as the one for the VM.


Correct, Thomas' idea was to use the GEM's dma_resv lock to protect 
drm_gpuvm_bo::evicted
and then actually move the drm_gpuvm_bo to the VM's evicted list 
once we grabbed all
dma-resv locks when locking the VM's BOs using drm_exec. We can 
remove them from the evicted
list on validate(). This way we never touch the evicted list 
without holding at least the VM's

dma-resv lock.

Do you have any concerns about that?


Scratching my head a bit how that is supposed to work.

This implies that you go over all the evicted BOs during validation 
and not just the one mentioned in the CS.


That might work for Vulkan, but is pretty much a no-go for OpenGL.









See what the eviction lock in amdgpu is doing for example.


The eviction_lock seems to protect a VM state "evicting" of 
whether any BO that
is associated with the VM is currently evicting. At the same time 
amdgpu protects
the eviceted list of the VM with a different lock. So this seems 
to be entirely
unrelated. Tracking a "currently evicting" state is not part of 
the GPUVM
implementation currently and hence nothing would change for 
amdgpu there.


Sorry for the confusion we use different terminology in amdgpu.

The eviction lock and evicted state is for the VM page tables, 
e.g. if the whole VM is currently not used and swapped out or even 
de-allocated.


This is necessary because we have cases where we need to access 
the VM data without holding the dma-resv lock of this VM. 
Especially figuring out which parts of an address space contain 
mappings and which doesn't.


I think this is fine, this has nothing to do with lists of evicted 
GEM objects or external GEM
objects, right? Marking mappings (drm_gpuva) as invalidated 
(DRM_GPUVA_INVALIDATED) or accessing

the VA space does not require any dma-resv locks.


I hope so, but I'm not 100% sure.





This is a requirement which comes with HMM handling, you won't see 
this with Vulkan (or OpenGL, VAAPI etc..).



The invalidation lock on the other hand is what in this discussion 
is called eviction lock. This one is needed because what I wrote 
above, during the move callback only the dma-resv of the BO which 
is moved is locked, but not necessarily the dma-resv of the VM.


That's yet another thing, right? This is used to track whether 
*any* BO that belongs to the VM is
currently being evicted, correct? As mentioned, as by now this is 
not supported in GPUVM and hence
would be the same driver specific code with the same driver specifc 
lock.


That is most likely a show stopper using this for OpenGL based 
workloads as far as I can see. For those you need to able to figure 
out which non-VM BOs have been evicted and which parts of the VM 
needs updates.


We identify those with a bool in the gpuvm_bo, and that bool is 
protected by the bo_resv. In essence, the "evicted" list must be made 
up-to-date with all relevant locks held before traversing in the next 
exec.


What I still miss with this idea is how do we find all the 
drm_gpuvm_bo structures with the evicted bool set to true? When doing 
the drm_exec dance we come across all external ones and can add them 
to the list if needed, but what about the BOs having the VM's dma-resv?


Oh, they can be added to the evict list directly (no bool needed) in the 
eviction code, like in v3. Since for those we indeed hold the VM's 
dma_resv since it's aliased with the object's dma-resv.


/Thomas







If you mean that we need to unbind all vmas of all vms of evicted bos 
before evicting, We don't do that, at least not in Xe, since evicting 
we wait 

Re: [PATCH drm-misc-next v3 6/7] drm/gpuvm: generalize dma_resv/extobj handling and GEM validation

2023-09-19 Thread Danilo Krummrich

On 9/19/23 14:21, Thomas Hellström wrote:

Hi Christian

On 9/19/23 14:07, Christian König wrote:

Am 13.09.23 um 17:46 schrieb Danilo Krummrich:

On 9/13/23 17:33, Christian König wrote:

Am 13.09.23 um 17:15 schrieb Danilo Krummrich:

On 9/13/23 16:26, Christian König wrote:

Am 13.09.23 um 14:16 schrieb Danilo Krummrich:

As mentioned in a different mail thread, the reply is based on the assumption
that we don't support anything else than GPUVM updates from the IOCTL.


I think that this assumption is incorrect.


Well, more precisely I should have said "don't support GPUVM updated from within
fence signaling critical sections". And looking at the code, that doesn't seem 
what
you're doing there.



Vulkan is just once specific use case, but this here should probably be able to 
handle other use cases as well.

Especially with HMM you get the requirement that you need to be able to 
invalidate GPUVM mappings without grabbing a reservation lock.


What do you mean with "invalidate GPUVM mappings" in this context? 
drm_gpuvm_bo_evict()
should only be called from a ttm_device_funcs::move callback, we should hold 
the dma-resv
lock there.


Well the question is which dma-resv lock do we hold?

In the move callback we only hold the dma-resv lock of the BO which is moved, 
but when that is a shared BO then that's not the same as the one for the VM.


Correct, Thomas' idea was to use the GEM's dma_resv lock to protect 
drm_gpuvm_bo::evicted
and then actually move the drm_gpuvm_bo to the VM's evicted list once we 
grabbed all
dma-resv locks when locking the VM's BOs using drm_exec. We can remove them 
from the evicted
list on validate(). This way we never touch the evicted list without holding at 
least the VM's
dma-resv lock.

Do you have any concerns about that?


Scratching my head a bit how that is supposed to work.

This implies that you go over all the evicted BOs during validation and not 
just the one mentioned in the CS.

That might work for Vulkan, but is pretty much a no-go for OpenGL.









See what the eviction lock in amdgpu is doing for example.


The eviction_lock seems to protect a VM state "evicting" of whether any BO that
is associated with the VM is currently evicting. At the same time amdgpu 
protects
the eviceted list of the VM with a different lock. So this seems to be entirely
unrelated. Tracking a "currently evicting" state is not part of the GPUVM
implementation currently and hence nothing would change for amdgpu there.


Sorry for the confusion we use different terminology in amdgpu.

The eviction lock and evicted state is for the VM page tables, e.g. if the 
whole VM is currently not used and swapped out or even de-allocated.

This is necessary because we have cases where we need to access the VM data 
without holding the dma-resv lock of this VM. Especially figuring out which 
parts of an address space contain mappings and which doesn't.


I think this is fine, this has nothing to do with lists of evicted GEM objects 
or external GEM
objects, right? Marking mappings (drm_gpuva) as invalidated 
(DRM_GPUVA_INVALIDATED) or accessing
the VA space does not require any dma-resv locks.


I hope so, but I'm not 100% sure.





This is a requirement which comes with HMM handling, you won't see this with 
Vulkan (or OpenGL, VAAPI etc..).


The invalidation lock on the other hand is what in this discussion is called 
eviction lock. This one is needed because what I wrote above, during the move 
callback only the dma-resv of the BO which is moved is locked, but not 
necessarily the dma-resv of the VM.


That's yet another thing, right? This is used to track whether *any* BO that 
belongs to the VM is
currently being evicted, correct? As mentioned, as by now this is not supported 
in GPUVM and hence
would be the same driver specific code with the same driver specifc lock.


That is most likely a show stopper using this for OpenGL based workloads as far 
as I can see. For those you need to able to figure out which non-VM BOs have 
been evicted and which parts of the VM needs updates.


We identify those with a bool in the gpuvm_bo, and that bool is protected by the bo_resv. 
In essence, the "evicted" list must be made up-to-date with all relevant locks 
held before traversing in the next exec.


What I still miss with this idea is how do we find all the drm_gpuvm_bo 
structures with the evicted bool set to true? When doing the drm_exec dance we 
come across all external ones and can add them to the list if needed, but what 
about the BOs having the VM's dma-resv?



If you mean that we need to unbind all vmas of all vms of evicted bos before 
evicting, We don't do that, at least not in Xe, since evicting we wait for VM 
idle, and it cant access anything through the stale vmas until they have been 
revalidated and rebound.

/Thomas







Regards,
Christian.





Regards,
Christian.



On Wed, Sep 13, 2023 at 11:14:46AM +0200, Thomas Hellström wrote:

Hi!

On Wed, 2023-09-13 at 01:36 +0200, 

[PATCH v4 0/4] Improve test coverage of TTM

2023-09-19 Thread Karolina Stolarek
Add tests for building blocks of the TTM subsystem, such as ttm_resource,
ttm_resource_manager, ttm_tt and ttm_buffer_object. This series covers
basic functions such as initialization, allocation and clean-up of each
struct. Testing of ttm_buffer_object also includes locking and unlocking
the object for validation, with special scenarios such as an interrupted
wait or deadlock.

Some of the test cases check the bulk move mechanism and how it interacts
with pinned buffers. This is to be seen if we want to add dedicated testing
for bulk move or not. The resource allocation subtests use ttm_sys_manager
for now. Resources that don't use system memory will be indirectly tested
via tests for ttm_bo_validate()/ttm_bo_init_validate(), using a mock
resource manager.

Use kunit_tool script to manually run all the tests:

$ ./tools/testing/kunit/kunit.py run --kunitconfig=drivers/gpu/drm/ttm/tests

To build a kernel with TTM KUnit tests, first enable CONFIG_KUNIT, and
then CONFIG_DRM_TTM_KUNIT_TEST.

Many thanks,
Karolina

v4:
  - First unreserve the object before calling ww_acquire_fini() in
ttm_bo_reserve_double_resv subtest
  - Silence lockdep in ttm_bo_reserve_deadlock subtest (open to suggestions
how to fix it in a different way)
  - Use a genuine GEM object in ttm_buffer_object instead of an empty one

v3:
  - Instead of modifying the main TTM Makefile, use
EXPORT_SYMBOL_FOR_TESTS_ONLY() macro for symbols that are tested but
not widely exported. Thanks to this change, TTM tests can be built
as modules, even when non-exported functions are used
  - Change the description of a patch that fixes ttm_pool_pre_populated()

v2:
  - Remove Makefile for KUnit tests and move the definitions to the
TTM's one
  - Switch on CONFIG_DRM_TTM_KUNIT_TEST=m so the tests and TTM module
are built as one. This allows building the tests as a module, even
if it uses functions that are not exported
  - Fix ttm_pool_pre_populated(); a wrong flag was passed to
ttm_tt_kunit_init() function

Karolina Stolarek (4):
  drm/ttm/tests: Add tests for ttm_resource and ttm_sys_man
  drm/ttm/tests: Add tests for ttm_tt
  drm/ttm/tests: Add tests for ttm_bo functions
  drm/ttm/tests: Fix argument in ttm_tt_kunit_init()

 drivers/gpu/drm/ttm/tests/Makefile|   3 +
 drivers/gpu/drm/ttm/tests/ttm_bo_test.c   | 619 ++
 drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c |  51 +-
 drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h |   4 +
 drivers/gpu/drm/ttm/tests/ttm_pool_test.c |   3 +-
 drivers/gpu/drm/ttm/tests/ttm_resource_test.c | 335 ++
 drivers/gpu/drm/ttm/tests/ttm_tt_test.c   | 295 +
 drivers/gpu/drm/ttm/ttm_resource.c|   3 +
 drivers/gpu/drm/ttm/ttm_tt.c  |   3 +
 9 files changed, 1313 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/ttm/tests/ttm_bo_test.c
 create mode 100644 drivers/gpu/drm/ttm/tests/ttm_resource_test.c
 create mode 100644 drivers/gpu/drm/ttm/tests/ttm_tt_test.c

-- 
2.25.1



[PATCH v4 2/4] drm/ttm/tests: Add tests for ttm_tt

2023-09-19 Thread Karolina Stolarek
Test initialization, creation and destruction of ttm_tt instances.
Export ttm_tt_destroy and ttm_tt_create symbols for testing purposes.

Signed-off-by: Karolina Stolarek 
---
 drivers/gpu/drm/ttm/tests/Makefile|   1 +
 drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c |  20 ++
 drivers/gpu/drm/ttm/tests/ttm_tt_test.c   | 295 ++
 drivers/gpu/drm/ttm/ttm_tt.c  |   3 +
 4 files changed, 319 insertions(+)
 create mode 100644 drivers/gpu/drm/ttm/tests/ttm_tt_test.c

diff --git a/drivers/gpu/drm/ttm/tests/Makefile 
b/drivers/gpu/drm/ttm/tests/Makefile
index c92fe2052ef6..f570530bbb60 100644
--- a/drivers/gpu/drm/ttm/tests/Makefile
+++ b/drivers/gpu/drm/ttm/tests/Makefile
@@ -4,4 +4,5 @@ obj-$(CONFIG_DRM_TTM_KUNIT_TEST) += \
 ttm_device_test.o \
 ttm_pool_test.o \
 ttm_resource_test.o \
+ttm_tt_test.o \
 ttm_kunit_helpers.o
diff --git a/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c 
b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c
index c605f010ea08..76c94d6afef1 100644
--- a/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c
+++ b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c
@@ -2,9 +2,29 @@
 /*
  * Copyright © 2023 Intel Corporation
  */
+#include 
+
 #include "ttm_kunit_helpers.h"
 
+static struct ttm_tt *ttm_tt_simple_create(struct ttm_buffer_object *bo,
+  uint32_t page_flags)
+{
+   struct ttm_tt *tt;
+
+   tt = kzalloc(sizeof(*tt), GFP_KERNEL);
+   ttm_tt_init(tt, bo, 0, ttm_cached, 0);
+
+   return tt;
+}
+
+static void ttm_tt_simple_destroy(struct ttm_device *bdev, struct ttm_tt *ttm)
+{
+   kfree(ttm);
+}
+
 struct ttm_device_funcs ttm_dev_funcs = {
+   .ttm_tt_create = ttm_tt_simple_create,
+   .ttm_tt_destroy = ttm_tt_simple_destroy,
 };
 EXPORT_SYMBOL_GPL(ttm_dev_funcs);
 
diff --git a/drivers/gpu/drm/ttm/tests/ttm_tt_test.c 
b/drivers/gpu/drm/ttm/tests/ttm_tt_test.c
new file mode 100644
index ..4f5fc4d460b4
--- /dev/null
+++ b/drivers/gpu/drm/ttm/tests/ttm_tt_test.c
@@ -0,0 +1,295 @@
+// SPDX-License-Identifier: GPL-2.0 AND MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+#include 
+#include 
+
+#include "ttm_kunit_helpers.h"
+
+#define BO_SIZESZ_4K
+
+struct ttm_tt_test_case {
+   const char *description;
+   uint32_t size;
+   uint32_t extra_pages_num;
+};
+
+static int ttm_tt_test_init(struct kunit *test)
+{
+   struct ttm_test_devices *priv;
+
+   priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
+   KUNIT_ASSERT_NOT_NULL(test, priv);
+
+   priv = ttm_test_devices_all(test);
+   test->priv = priv;
+
+   return 0;
+}
+
+static const struct ttm_tt_test_case ttm_tt_init_basic_cases[] = {
+   {
+   .description = "Page-aligned size",
+   .size = SZ_4K,
+   },
+   {
+   .description = "Extra pages requested",
+   .size = SZ_4K,
+   .extra_pages_num = 1,
+   },
+};
+
+static void ttm_tt_init_case_desc(const struct ttm_tt_test_case *t,
+ char *desc)
+{
+   strscpy(desc, t->description, KUNIT_PARAM_DESC_SIZE);
+}
+
+KUNIT_ARRAY_PARAM(ttm_tt_init_basic, ttm_tt_init_basic_cases,
+ ttm_tt_init_case_desc);
+
+static void ttm_tt_init_basic(struct kunit *test)
+{
+   const struct ttm_tt_test_case *params = test->param_value;
+   struct ttm_buffer_object *bo;
+   struct ttm_tt *tt;
+   uint32_t page_flags = TTM_TT_FLAG_ZERO_ALLOC;
+   enum ttm_caching caching = ttm_cached;
+   uint32_t extra_pages = params->extra_pages_num;
+   int num_pages = params->size >> PAGE_SHIFT;
+   int err;
+
+   tt = kunit_kzalloc(test, sizeof(*tt), GFP_KERNEL);
+   KUNIT_ASSERT_NOT_NULL(test, tt);
+
+   bo = ttm_bo_kunit_init(test, test->priv, params->size);
+
+   err = ttm_tt_init(tt, bo, page_flags, caching, extra_pages);
+   KUNIT_ASSERT_EQ(test, err, 0);
+
+   KUNIT_ASSERT_EQ(test, tt->num_pages, num_pages + extra_pages);
+
+   KUNIT_ASSERT_EQ(test, tt->page_flags, page_flags);
+   KUNIT_ASSERT_EQ(test, tt->caching, caching);
+
+   KUNIT_ASSERT_NULL(test, tt->dma_address);
+   KUNIT_ASSERT_NULL(test, tt->swap_storage);
+}
+
+static void ttm_tt_init_misaligned(struct kunit *test)
+{
+   struct ttm_buffer_object *bo;
+   struct ttm_tt *tt;
+   enum ttm_caching caching = ttm_cached;
+   uint32_t size = SZ_8K;
+   int num_pages = (size + SZ_4K) >> PAGE_SHIFT;
+   int err;
+
+   tt = kunit_kzalloc(test, sizeof(*tt), GFP_KERNEL);
+   KUNIT_ASSERT_NOT_NULL(test, tt);
+
+   bo = ttm_bo_kunit_init(test, test->priv, size);
+
+   /* Make the object size misaligned */
+   bo->base.size += 1;
+
+   err = ttm_tt_init(tt, bo, 0, caching, 0);
+   KUNIT_ASSERT_EQ(test, err, 0);
+
+   KUNIT_ASSERT_EQ(test, tt->num_pages, num_pages);
+}
+
+static void ttm_tt_fini_basic(struct 

[PATCH v4 4/4] drm/ttm/tests: Fix argument in ttm_tt_kunit_init()

2023-09-19 Thread Karolina Stolarek
Remove a leftover definition of page order and pass an empty flag value
in ttm_pool_pre_populated().

Signed-off-by: Karolina Stolarek 
---
 drivers/gpu/drm/ttm/tests/ttm_pool_test.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/ttm/tests/ttm_pool_test.c 
b/drivers/gpu/drm/ttm/tests/ttm_pool_test.c
index 2d9cae8cd984..b97f7b6daf5b 100644
--- a/drivers/gpu/drm/ttm/tests/ttm_pool_test.c
+++ b/drivers/gpu/drm/ttm/tests/ttm_pool_test.c
@@ -78,10 +78,9 @@ static struct ttm_pool *ttm_pool_pre_populated(struct kunit 
*test,
struct ttm_test_devices *devs = priv->devs;
struct ttm_pool *pool;
struct ttm_tt *tt;
-   unsigned long order = __fls(size / PAGE_SIZE);
int err;
 
-   tt = ttm_tt_kunit_init(test, order, caching, size);
+   tt = ttm_tt_kunit_init(test, 0, caching, size);
KUNIT_ASSERT_NOT_NULL(test, tt);
 
pool = kunit_kzalloc(test, sizeof(*pool), GFP_KERNEL);
-- 
2.25.1



[PATCH v4 3/4] drm/ttm/tests: Add tests for ttm_bo functions

2023-09-19 Thread Karolina Stolarek
Test reservation and release of TTM buffer objects. Add tests to check
pin and unpin operations.

Signed-off-by: Karolina Stolarek 
---
 drivers/gpu/drm/ttm/tests/Makefile|   1 +
 drivers/gpu/drm/ttm/tests/ttm_bo_test.c   | 619 ++
 drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c |   6 +
 3 files changed, 626 insertions(+)
 create mode 100644 drivers/gpu/drm/ttm/tests/ttm_bo_test.c

diff --git a/drivers/gpu/drm/ttm/tests/Makefile 
b/drivers/gpu/drm/ttm/tests/Makefile
index f570530bbb60..468535f7eed2 100644
--- a/drivers/gpu/drm/ttm/tests/Makefile
+++ b/drivers/gpu/drm/ttm/tests/Makefile
@@ -5,4 +5,5 @@ obj-$(CONFIG_DRM_TTM_KUNIT_TEST) += \
 ttm_pool_test.o \
 ttm_resource_test.o \
 ttm_tt_test.o \
+ttm_bo_test.o \
 ttm_kunit_helpers.o
diff --git a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c 
b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c
new file mode 100644
index ..f0c829fdb67b
--- /dev/null
+++ b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c
@@ -0,0 +1,619 @@
+// SPDX-License-Identifier: GPL-2.0 AND MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include "ttm_kunit_helpers.h"
+
+#define BO_SIZESZ_8K
+
+struct ttm_bo_test_case {
+   const char *description;
+   bool interruptible;
+   bool no_wait;
+};
+
+static const struct ttm_bo_test_case ttm_bo_reserved_cases[] = {
+   {
+   .description = "Cannot be interrupted and sleeps",
+   .interruptible = false,
+   .no_wait = false,
+   },
+   {
+   .description = "Cannot be interrupted, locks straight away",
+   .interruptible = false,
+   .no_wait = true,
+   },
+   {
+   .description = "Can be interrupted, sleeps",
+   .interruptible = true,
+   .no_wait = false,
+   },
+};
+
+static void ttm_bo_init_case_desc(const struct ttm_bo_test_case *t,
+ char *desc)
+{
+   strscpy(desc, t->description, KUNIT_PARAM_DESC_SIZE);
+}
+
+KUNIT_ARRAY_PARAM(ttm_bo_reserve, ttm_bo_reserved_cases, 
ttm_bo_init_case_desc);
+
+static void ttm_bo_reserve_optimistic_no_ticket(struct kunit *test)
+{
+   const struct ttm_bo_test_case *params = test->param_value;
+   struct ttm_buffer_object *bo;
+   int err;
+
+   bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE);
+
+   err = ttm_bo_reserve(bo, params->interruptible, params->no_wait, NULL);
+   KUNIT_ASSERT_EQ(test, err, 0);
+
+   dma_resv_unlock(bo->base.resv);
+}
+
+static void ttm_bo_reserve_locked_no_sleep(struct kunit *test)
+{
+   struct ttm_buffer_object *bo;
+   bool interruptible = false;
+   bool no_wait = true;
+   int err;
+
+   bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE);
+
+   /* Let's lock it beforehand */
+   dma_resv_lock(bo->base.resv, NULL);
+
+   err = ttm_bo_reserve(bo, interruptible, no_wait, NULL);
+   dma_resv_unlock(bo->base.resv);
+
+   KUNIT_ASSERT_EQ(test, err, -EBUSY);
+}
+
+static void ttm_bo_reserve_no_wait_ticket(struct kunit *test)
+{
+   struct ttm_buffer_object *bo;
+   struct ww_acquire_ctx ctx;
+   bool interruptible = false;
+   bool no_wait = true;
+   int err;
+
+   ww_acquire_init(, _ww_class);
+
+   bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE);
+
+   err = ttm_bo_reserve(bo, interruptible, no_wait, );
+   KUNIT_ASSERT_EQ(test, err, -EBUSY);
+
+   ww_acquire_fini();
+}
+
+static void ttm_bo_reserve_double_resv(struct kunit *test)
+{
+   struct ttm_buffer_object *bo;
+   struct ww_acquire_ctx ctx;
+   bool interruptible = false;
+   bool no_wait = false;
+   int err;
+
+   ww_acquire_init(, _ww_class);
+
+   bo = ttm_bo_kunit_init(test, test->priv, BO_SIZE);
+
+   err = ttm_bo_reserve(bo, interruptible, no_wait, );
+   KUNIT_ASSERT_EQ(test, err, 0);
+
+   err = ttm_bo_reserve(bo, interruptible, no_wait, );
+
+   dma_resv_unlock(bo->base.resv);
+   ww_acquire_fini();
+
+   KUNIT_ASSERT_EQ(test, err, -EALREADY);
+}
+
+/*
+ * A test case heavily inspired by ww_test_edeadlk_normal(). Checks
+ * if -EDEADLK is properly propagated by ttm_bo_reserve()
+ */
+static void ttm_bo_reserve_deadlock(struct kunit *test)
+{
+   struct ttm_buffer_object *bo1, *bo2;
+   struct ww_acquire_ctx ctx1, ctx2;
+   bool interruptible = false;
+   bool no_wait = false;
+   int err;
+
+   bo1 = ttm_bo_kunit_init(test, test->priv, BO_SIZE);
+   bo2 = ttm_bo_kunit_init(test, test->priv, BO_SIZE);
+
+   ww_acquire_init(, _ww_class);
+   mutex_lock(>base.resv->lock.base);
+
+   /* The deadlock will be caught by WW mutex, don't warn about it */
+   lock_release(>base.resv->lock.base.dep_map, 1);
+
+   bo2->base.resv->lock.ctx = 
+ 

[PATCH v4 1/4] drm/ttm/tests: Add tests for ttm_resource and ttm_sys_man

2023-09-19 Thread Karolina Stolarek
Test initialization of ttm_resource using different memory domains.
Add tests for a system memory manager and functions that can be
tested without a fully-featured resource manager. Update
ttm_bo_kunit_init() to initialize BO's kref and a genuine GEM drm
object. Export ttm_resource_alloc for test purposes only.

Signed-off-by: Karolina Stolarek 
---
 drivers/gpu/drm/ttm/tests/Makefile|   1 +
 drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c |  25 +-
 drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h |   4 +
 drivers/gpu/drm/ttm/tests/ttm_resource_test.c | 335 ++
 drivers/gpu/drm/ttm/ttm_resource.c|   3 +
 5 files changed, 367 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/ttm/tests/ttm_resource_test.c

diff --git a/drivers/gpu/drm/ttm/tests/Makefile 
b/drivers/gpu/drm/ttm/tests/Makefile
index ec87c4fc1ad5..c92fe2052ef6 100644
--- a/drivers/gpu/drm/ttm/tests/Makefile
+++ b/drivers/gpu/drm/ttm/tests/Makefile
@@ -3,4 +3,5 @@
 obj-$(CONFIG_DRM_TTM_KUNIT_TEST) += \
 ttm_device_test.o \
 ttm_pool_test.o \
+ttm_resource_test.o \
 ttm_kunit_helpers.o
diff --git a/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c 
b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c
index 81661d8827aa..c605f010ea08 100644
--- a/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c
+++ b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c
@@ -29,19 +29,42 @@ struct ttm_buffer_object *ttm_bo_kunit_init(struct kunit 
*test,
struct ttm_test_devices *devs,
size_t size)
 {
-   struct drm_gem_object gem_obj = { .size = size };
+   struct drm_gem_object gem_obj = { };
struct ttm_buffer_object *bo;
+   int err;
 
bo = kunit_kzalloc(test, sizeof(*bo), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, bo);
 
bo->base = gem_obj;
+   err = drm_gem_object_init(devs->drm, >base, size);
+   KUNIT_ASSERT_EQ(test, err, 0);
+
bo->bdev = devs->ttm_dev;
+   kref_init(>kref);
 
return bo;
 }
 EXPORT_SYMBOL_GPL(ttm_bo_kunit_init);
 
+struct ttm_place *ttm_place_kunit_init(struct kunit *test,
+  uint32_t mem_type, uint32_t flags,
+  size_t size)
+{
+   struct ttm_place *place;
+
+   place = kunit_kzalloc(test, sizeof(*place), GFP_KERNEL);
+   KUNIT_ASSERT_NOT_NULL(test, place);
+
+   place->mem_type = mem_type;
+   place->flags = flags;
+   place->fpfn = size >> PAGE_SHIFT;
+   place->lpfn = place->fpfn + (size >> PAGE_SHIFT);
+
+   return place;
+}
+EXPORT_SYMBOL_GPL(ttm_place_kunit_init);
+
 struct ttm_test_devices *ttm_test_devices_basic(struct kunit *test)
 {
struct ttm_test_devices *devs;
diff --git a/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h 
b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h
index e261e3660d0b..f38140f93c05 100644
--- a/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h
+++ b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -28,6 +29,9 @@ int ttm_device_kunit_init(struct ttm_test_devices *priv,
 struct ttm_buffer_object *ttm_bo_kunit_init(struct kunit *test,
struct ttm_test_devices *devs,
size_t size);
+struct ttm_place *ttm_place_kunit_init(struct kunit *test,
+  uint32_t mem_type, uint32_t flags,
+  size_t size);
 
 struct ttm_test_devices *ttm_test_devices_basic(struct kunit *test);
 struct ttm_test_devices *ttm_test_devices_all(struct kunit *test);
diff --git a/drivers/gpu/drm/ttm/tests/ttm_resource_test.c 
b/drivers/gpu/drm/ttm/tests/ttm_resource_test.c
new file mode 100644
index ..851cdc43dc37
--- /dev/null
+++ b/drivers/gpu/drm/ttm/tests/ttm_resource_test.c
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0 AND MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+#include 
+
+#include "ttm_kunit_helpers.h"
+
+#define RES_SIZE   SZ_4K
+#define TTM_PRIV_DUMMY_REG (TTM_NUM_MEM_TYPES - 1)
+
+struct ttm_resource_test_case {
+   const char *description;
+   uint32_t mem_type;
+   uint32_t flags;
+};
+
+struct ttm_resource_test_priv {
+   struct ttm_test_devices *devs;
+   struct ttm_buffer_object *bo;
+   struct ttm_place *place;
+};
+
+static const struct ttm_resource_manager_func ttm_resource_manager_mock_funcs 
= { };
+
+static int ttm_resource_test_init(struct kunit *test)
+{
+   struct ttm_resource_test_priv *priv;
+
+   priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
+   KUNIT_ASSERT_NOT_NULL(test, priv);
+
+   priv->devs = ttm_test_devices_all(test);
+   KUNIT_ASSERT_NOT_NULL(test, priv->devs);
+
+   test->priv = priv;
+
+   return 0;
+}
+
+static void ttm_resource_test_fini(struct 

Re: [PATCH -next] drm: xlnx: zynqmp_dpsub: Use devm_clk_get_enabled() helper function

2023-09-19 Thread Tomi Valkeinen

On 29/08/2023 10:55, Laurent Pinchart wrote:

Hi Jinjie,

(CC'ing Tomi)

Thank you for the patch.

On Fri, Aug 25, 2023 at 03:23:24PM +0800, Jinjie Ruan wrote:

The devm_clk_get_enabled() helper:
 - calls devm_clk_get()
 - calls clk_prepare_enable() and registers what is needed in order to
   call clk_disable_unprepare() when needed, as a managed resource.

This simplifies the code.


While this indeed simplifies the code, I think we should instead control
the clock dynamically at runtime.

I don't have access to the hardware at the moment. Tomi, would you be
able to give this a go ? I can also write a patch and let you test it if
desired.


I have a small patch that adds runtime resume & suspend callbacks, and 
enables & disables the clock there. But the driver doesn't seem to do a 
proper job of power management:


- It accesses registers without pm_runtime_get
- It initializes registers at probe time, apparently presuming that the 
IP is never turned off, which might cause registers getting reset.
- It uses pm_runtime_get in a couple of places where it's starting the 
video stream, but it seems to forget that there's also the DP AUX and HPD.


Then again, as the HPD is, I think, supposed to be always enabled, the 
device is also always enabled, making the PM management a bit pointless.


I'll look at this a bit more to see if I can sort this out.

 Tomi



[GIT PULL] drm: renesas: shmobile: Atomic conversion + DT support (was: Re: [PATCH v4 00/41] drm: renesas: shmobile: Atomic conversion + DT support)

2023-09-19 Thread Geert Uytterhoeven
Hi David, Daniel,

The following changes since commit 0663e1da5ba8e6459e3555ac12c62741668c0d30:

  drm/dp_mst: Tune down error message during payload addition
(2023-09-18 16:38:21 +0300)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git
tags/shmob-drm-atomic-dt-tag1

for you to fetch changes up to bfea0fa9052aa8d235b24957eb84d9ff20cb87b7:

  drm: renesas: shmobile: Add DT support (2023-09-19 15:58:04 +0200)


drm: renesas: shmobile: Atomic conversion + DT support

Currently, there are two drivers for the LCD controller on Renesas
SuperH-based and ARM-based SH-Mobile and R-Mobile SoCs:
  1. sh_mobile_lcdcfb, using the fbdev framework,
  2. shmob_drm, using the DRM framework.
However, only the former driver is used, as all platform support
integrates the former.  None of these drivers support DT-based systems.

Convert the SH-Mobile DRM driver to atomic modesetting, and add DT
support, complemented by the customary set of fixes and improvements.

Link: https://lore.kernel.org/r/cover.1694767208.git.geert+rene...@glider.be/

This PR is based on today's drm-misc/for-linux-next, to avoid a
conflict with commit 775b0669e19f2e4a ("drm/shmobile: Convert to
platform remove callback returning void") in drm-misc/for-linux-next
.
Thanks for pulling!

Geert Uytterhoeven (36):
  MAINTAINER: Create entry for Renesas SH-Mobile DRM drivers
  dt-bindings: display: Add Renesas SH-Mobile LCDC bindings
  media: uapi: Add MEDIA_BUS_FMT_RGB666_2X9_BE format
  drm: renesas: shmobile: Fix overlay plane disable
  drm: renesas: shmobile: Fix ARGB32 overlay format typo
  drm: renesas: shmobile: Correct encoder/connector types
  drm: renesas: shmobile: Add support for Runtime PM
  drm: renesas: shmobile: Restore indentation of shmob_drm_setup_clocks()
  drm: renesas: shmobile: Use %p4cc to print fourcc code
  drm: renesas: shmobile: Add missing YCbCr formats
  drm: renesas: shmobile: Improve shmob_drm_format_info table
  drm: renesas: shmobile: Improve error handling
  drm: renesas: shmobile: Convert to use devm_request_irq()
  drm: renesas: shmobile: Remove custom plane destroy callback
  drm: renesas: shmobile: Use drmm_universal_plane_alloc()
  drm: renesas: shmobile: Embed drm_device in shmob_drm_device
  drm: renesas: shmobile: Convert container helpers to static
inline functions
  drm: renesas: shmobile: Replace .dev_private with container_of()
  drm: renesas: shmobile: Use media bus formats in platform data
  drm: renesas: shmobile: Move interface handling to connector setup
  drm: renesas: shmobile: Unify plane allocation
  drm: renesas: shmobile: Rename shmob_drm_crtc.crtc
  drm: renesas: shmobile: Rename shmob_drm_connector.connector
  drm: renesas: shmobile: Rename shmob_drm_plane.plane
  drm: renesas: shmobile: Use drm_crtc_handle_vblank()
  drm: renesas: shmobile: Move shmob_drm_crtc_finish_page_flip()
  drm: renesas: shmobile: Wait for page flip when turning CRTC off
  drm: renesas: shmobile: Turn vblank on/off when enabling/disabling CRTC
  drm: renesas: shmobile: Shutdown the display on remove
  drm: renesas: shmobile: Cleanup encoder
  drm: renesas: shmobile: Atomic conversion part 1
  drm: renesas: shmobile: Atomic conversion part 2
  drm: renesas: shmobile: Use suspend/resume helpers
  drm: renesas: shmobile: Remove internal CRTC state tracking
  drm: renesas: shmobile: Atomic conversion part 3
  drm: renesas: shmobile: Add DT support

Laurent Pinchart (5):
  drm: renesas: shmobile: Remove backlight support
  drm: renesas: shmobile: Don't set display info width and height twice
  drm: renesas: shmobile: Rename input clocks
  drm: renesas: shmobile: Remove support for SYS panels
  drm: renesas: shmobile: Use struct videomode in platform data

 .../bindings/display/renesas,shmobile-lcdc.yaml| 130 +
 .../userspace-api/media/v4l/subdev-formats.rst |  72 +++
 MAINTAINERS|  13 +-
 drivers/gpu/drm/renesas/shmobile/Kconfig   |   3 +-
 drivers/gpu/drm/renesas/shmobile/Makefile  |   3 +-
 .../gpu/drm/renesas/shmobile/shmob_drm_backlight.c |  82 ---
 .../gpu/drm/renesas/shmobile/shmob_drm_backlight.h |  19 -
 drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c  | 650 +
 drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h  |  27 +-
 drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c   | 179 +++---
 drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h   |  18 +-
 drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c   |  77 ++-
 drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.h   |   9 +-
 drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 326 ++-
 

  1   2   >