Re: [PATCH] drm/amd: Fix the flag setting code for interrupt request

2023-09-05 Thread Ma, Jun



On 9/5/2023 10:46 PM, Alex Deucher wrote:
> On Mon, Sep 4, 2023 at 2:30 AM Ma Jun  wrote:
>>
>> [1] Remove the irq flags setting code since pci_alloc_irq_vectors()
>> handles these flags.
>> [2] Free the msi vectors in case of error.
>>
>> Signed-off-by: Ma Jun 
>> ---
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 43 ++---
>>  1 file changed, 25 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>> index fa6d0adcec20..17043a1e37a5 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>> @@ -271,28 +271,28 @@ static void amdgpu_restore_msix(struct amdgpu_device 
>> *adev)
>>  int amdgpu_irq_init(struct amdgpu_device *adev)
>>  {
>> int r = 0;
>> -   unsigned int irq;
>> +   unsigned int irq, flags;
>>
>> spin_lock_init(>irq.lock);
>>
>> /* Enable MSI if not disabled by module parameter */
>> adev->irq.msi_enabled = false;
>>
>> +   if (amdgpu_msi_ok(adev))
>> +   flags = PCI_IRQ_MSI | PCI_IRQ_MSIX;
>> +   else
>> +   flags = PCI_IRQ_LEGACY;
> 
> I think this logic could be something like:
> 
> if (!amdgpu_msi_ok(adev))
>   flags = PCI_IRQ_LEGACY;
> else
>   flags = PCI_IRQ_ALL_TYPES
> 
> Other than that, looks fine to me.

Thanks, will update later.

Regards,
Ma Jun
> 
> Alex
> 
> 
>> +
>> +   /* we only need one vector */
>> +   r = pci_alloc_irq_vectors(adev->pdev, 1, 1, flags);
>> +   if (r < 0) {
>> +   dev_err(adev->dev, "Failed to alloc msi vectors\n");
>> +   return r;
>> +   }
>> +
>> if (amdgpu_msi_ok(adev)) {
>> -   int nvec = pci_msix_vec_count(adev->pdev);
>> -   unsigned int flags;
>> -
>> -   if (nvec <= 0)
>> -   flags = PCI_IRQ_MSI;
>> -   else
>> -   flags = PCI_IRQ_MSI | PCI_IRQ_MSIX;
>> -
>> -   /* we only need one vector */
>> -   nvec = pci_alloc_irq_vectors(adev->pdev, 1, 1, flags);
>> -   if (nvec > 0) {
>> -   adev->irq.msi_enabled = true;
>> -   dev_dbg(adev->dev, "using MSI/MSI-X.\n");
>> -   }
>> +   adev->irq.msi_enabled = true;
>> +   dev_dbg(adev->dev, "using MSI/MSI-X.\n");
>> }
>>
>> INIT_WORK(>irq.ih1_work, amdgpu_irq_handle_ih1);
>> @@ -302,22 +302,29 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
>> /* Use vector 0 for MSI-X. */
>> r = pci_irq_vector(adev->pdev, 0);
>> if (r < 0)
>> -   return r;
>> +   goto free_vectors;
>> irq = r;
>>
>> /* PCI devices require shared interrupts. */
>> r = request_irq(irq, amdgpu_irq_handler, IRQF_SHARED, 
>> adev_to_drm(adev)->driver->name,
>> adev_to_drm(adev));
>> if (r)
>> -   return r;
>> +   goto free_vectors;
>> +
>> adev->irq.installed = true;
>> adev->irq.irq = irq;
>> adev_to_drm(adev)->max_vblank_count = 0x00ff;
>>
>> DRM_DEBUG("amdgpu: irq initialized.\n");
>> return 0;
>> -}
>>
>> +free_vectors:
>> +   if (adev->irq.msi_enabled)
>> +   pci_free_irq_vectors(adev->pdev);
>> +
>> +   adev->irq.msi_enabled = false;
>> +   return r;
>> +}
>>
>>  void amdgpu_irq_fini_hw(struct amdgpu_device *adev)
>>  {
>> --
>> 2.34.1
>>


RE: [PATCH] drm/amdgpu: Fix refclk reporting for SMU v13.0.6

2023-09-05 Thread Zhang, Hawking
[AMD Official Use Only - General]

Reviewed-by: Hawking Zhang 

Regards
Hawking
-Original Message-
From: Lazar, Lijo 
Sent: Wednesday, September 6, 2023 11:57
To: amd-gfx@lists.freedesktop.org
Cc: Zhang, Hawking ; Deucher, Alexander 

Subject: [PATCH] drm/amdgpu: Fix refclk reporting for SMU v13.0.6

SMU v13.0.6 SOCs have 100MHz reference clock.

Signed-off-by: Lijo Lazar 
---
 drivers/gpu/drm/amd/amdgpu/soc15.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c 
b/drivers/gpu/drm/amd/amdgpu/soc15.c
index f5be40d7ba36..28094cd7d9c2 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -325,7 +325,8 @@ static u32 soc15_get_xclk(struct amdgpu_device *adev)
u32 reference_clock = adev->clock.spll.reference_freq;

if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 0) ||
-   adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1))
+   adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1) ||
+   adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 6))
return 1;
if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 0) ||
adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 1))
--
2.25.1



[PATCH] drm/amdgpu: Fix refclk reporting for SMU v13.0.6

2023-09-05 Thread Lijo Lazar
SMU v13.0.6 SOCs have 100MHz reference clock.

Signed-off-by: Lijo Lazar 
---
 drivers/gpu/drm/amd/amdgpu/soc15.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c 
b/drivers/gpu/drm/amd/amdgpu/soc15.c
index f5be40d7ba36..28094cd7d9c2 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -325,7 +325,8 @@ static u32 soc15_get_xclk(struct amdgpu_device *adev)
u32 reference_clock = adev->clock.spll.reference_freq;
 
if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 0) ||
-   adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1))
+   adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1) ||
+   adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 6))
return 1;
if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 0) ||
adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 1))
-- 
2.25.1



Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread suijingfeng

Hi,


On 2023/9/5 23:05, Thomas Zimmermann wrote:
However, on modern Linux systems the primary display does not really 
exist. 'Primary' is the device that is available via VGA, VESA or EFI. 


I may miss the point, what do you means by choose the word "modern"?
Are you trying to tell me that X server is too old and Wayland is the modern 
display server?



Our drivers don't use these interfaces, but the native registers.



Yes and no?

Yes for the machine with the UEFI firmware,
but I not sure if this statement is true for the machine with the legacy 
firmware.

As the display controller in the ASpeed BMC is VGA compatible.
Therefore, in theory, it should works with the VGA console on the machine
with another VGA compatible video card. So the ast_vga_set_decode() function
provided in the 0007 patch probably useful on legacy firmware environment.

To be honest, I have tested this on various machine with UEFI firmware.
But I didn't realized that I should do the testing on legacy firmware 
environment
before sending this patch. It seems that the testing effort needed are quite
exhausting, since all my machines come with the UEFI firmware.

So is it OK to leave the legacy part to someone else who interested in it?
Probably Alex is more professional at legacy VGA routing stuff?
:-)




Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread suijingfeng



On 2023/9/5 23:05, Thomas Zimmermann wrote:

Hi

Am 05.09.23 um 15:30 schrieb suijingfeng:

Hi,


On 2023/9/5 18:45, Thomas Zimmermann wrote:

Hi

Am 04.09.23 um 21:57 schrieb Sui Jingfeng:

From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over 
which
one is primary at boot time. This series tries to solve above 
mentioned


If anything, the primary graphics adapter is the one initialized by 
the firmware. I think our boot-up graphics also make this assumption 
implicitly.




Yes, but by the time of DRM drivers get loaded successfully,the 
boot-up graphics already finished.
Firmware framebuffer device already get killed by the 
drm_aperture_remove_conflicting_pci_framebuffers()
function (or its siblings). So, this series is definitely not to 
interact with the firmware framebuffer


Yes and no. The helpers you mention will attempt to remove the 
firmware framebuffer on the given PCI device. If you have multiple PCI 
devices, the other devices would not be affected.



Yes and no.


For the yes part: drm_aperture_remove_conflicting_pci_framebuffers() only kill 
the conflict one.
But for a specific machine with the modern UEFI firmware,
there should be only one firmware framebuffer driver.
That shoudd be the EFIFB(UEFI GOP). I do have multiple PCI devices,
but I don't understand when and why a system will have more than one firmware 
framebuffer.

Even for the machines with the legacy BIOS, the fixed VGA aperture address range
can only be owned by one firmware driver. It is just that we need to handle the
routing, the ->set_decode() callback of vga_client_register() is used to do such
work. Am I correct?




Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread suijingfeng

Hi,


On 2023/9/5 23:05, Thomas Zimmermann wrote:
However, on modern Linux systems the primary display does not really 
exist.



No, it do exist.  X server need to know which one is the primary GPU.
The '*' character at the of (4@0:0:0) PCI device is the Primary.
The '*' denote primary, see the log below.

(II) xfree86: Adding drm device (/dev/dri/card2)
(II) xfree86: Adding drm device (/dev/dri/card0)
(II) Platform probe for 
/sys/devices/pci:00/:00:1c.5/:003:00.0/:04:00.0/drm/card0

(II) xfree86: Adding drm device (/dev/dri/card3)
(II) Platform probe for 
/sys/devices/pci:00/:00:1c.6/:005:00.0/drm/card3
(--) PCI: (0@0:2:0) 8086:3e91:8086:3e91 rev 0, Mem @ 
0xdb00/16216, 0xa000/536870912, I/O @ 0xf000/64, BIOS @ 
0x/131072
(--) PCI: (1@0:0:0) 1002:6771:1043:8636 rev 0, Mem @ 
0xc000/2688435456, 0xdf22/131072, I/O @ 0xe000/256, BIOS @ 
0x/131072
(--) PCI:*(4@0:0:0) 1a03:2000:1a03:2000 rev 48, Mem @ 
0xde00/166777216, 0xdf02/131072, I/O @ 0xc000/128, BIOS @ 
0x/131072
(--) PCI: (5@0:0:0) 10de:1288:174b:b324 rev 161, Mem @ 
0xdc00/116777216, 0xd000/134217728, 0xd800/33554432, I/O @ 
0xb000/128, BIOS @@0x/524288


The modesetting driver of X server will create framebuffer on the primary video 
adapter.
If a 2D video adapter (like the aspeed BMC) is not the primary, then it 
probably will not
be used. The only chance to be able to display something is to functional as a 
output slave.
But the output slave technology need the PRIME support for cross driver buffer 
sharing.

So, there do have some difference between the primary and non-primary video 
adapters.


'Primary' is the device that is available via VGA, VESA or EFI. Our 
drivers don't use these interfaces, but the native registers. As you 
said yourself, these firmware devices (VGA, VESA, EFI) are removed 
ASAP by the native drivers. 




[PATCH] SWDEV-420310 - struct pm4_mes_runlist in amdgpu is conflict with spec struct pm4_mes_runlist is different with mes pm4 packet nv10 spec Modification: add last dword of the design of spec into

2023-09-05 Thread Lin . Cao
Signed-off-by: Lin.Cao 
Change-Id: I1322c010d1428b2c1df5080b72da94e90cf17fec
---
 drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h 
b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h
index 8b6b2bd5c148..d50feaf59b8a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_ai.h
@@ -129,6 +129,18 @@ struct pm4_mes_runlist {
uint32_t ordinal4;
};
 
+   union
+   {
+   struct
+   {
+   uint32_t level_1_static_queue_cnt:4;
+   uint32_t level_2_static_queue_cnt:4;
+   uint32_t level_3_static_queue_cnt:4;
+   uint32_t reserved4:20;
+   } bitfields5;
+   uint32_t ordinal5;
+   };
+
 };
 #endif
 
-- 
2.25.1



Re: [PATCH 11/11] drm/amdgpu: further move TLB hw workarounds a layer up

2023-09-05 Thread Alex Deucher
On Tue, Sep 5, 2023 at 3:00 AM Christian König
 wrote:
>
> For the PASID flushing we already handled that at a higher layer, apply
> those workarounds to the standard flush as well.
>
> Signed-off-by: Christian König 

Reviewed-by: Alex Deucher 

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 19 +++
>  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 74 -
>  2 files changed, 42 insertions(+), 51 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> index c24252304d48..8a5381ca7713 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> @@ -597,6 +597,14 @@ void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device 
> *adev, uint32_t vmid,
> if(!down_read_trylock(>reset_domain->sem))
> return;
>
> +   if (adev->gmc.flush_tlb_needs_extra_type_2)
> +   adev->gmc.gmc_funcs->flush_gpu_tlb(adev, vmid,
> +  vmhub, 2);
> +
> +   if (adev->gmc.flush_tlb_needs_extra_type_0 && flush_type == 2)
> +   adev->gmc.gmc_funcs->flush_gpu_tlb(adev, vmid,
> +  vmhub, 0);
> +
> adev->gmc.gmc_funcs->flush_gpu_tlb(adev, vmid, vmhub,
>flush_type);
> up_read(>reset_domain->sem);
> @@ -647,6 +655,17 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device 
> *adev, uint16_t pasid,
>
> if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready ||
> !down_read_trylock(>reset_domain->sem)) {
> +
> +   if (adev->gmc.flush_tlb_needs_extra_type_2)
> +   adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
> +2, all_hub,
> +inst);
> +
> +   if (adev->gmc.flush_tlb_needs_extra_type_0 && flush_type == 2)
> +   adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
> +0, all_hub,
> +inst);
> +
> adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
>  flush_type, all_hub,
>  inst);
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> index c5df8f052f3f..a1a6f4b63208 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> @@ -812,37 +812,18 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
> *adev, uint32_t vmid,
> uint32_t vmhub, uint32_t flush_type)
>  {
> bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(adev, vmhub);
> -   u32 j, inv_req, inv_req2, tmp, sem, req, ack;
> +   u32 j, inv_req, tmp, sem, req, ack;
> const unsigned int eng = 17;
> struct amdgpu_vmhub *hub;
>
> BUG_ON(vmhub >= AMDGPU_MAX_VMHUBS);
>
> hub = >vmhub[vmhub];
> +   inv_req = gmc_v9_0_get_invalidate_req(vmid, flush_type);
> sem = hub->vm_inv_eng0_sem + hub->eng_distance * eng;
> req = hub->vm_inv_eng0_req + hub->eng_distance * eng;
> ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng;
>
> -   if (adev->gmc.xgmi.num_physical_nodes &&
> -   adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 0)) {
> -   /* Vega20+XGMI caches PTEs in TC and TLB. Add a
> -* heavy-weight TLB flush (type 2), which flushes
> -* both. Due to a race condition with concurrent
> -* memory accesses using the same TLB cache line, we
> -* still need a second TLB flush after this.
> -*/
> -   inv_req = gmc_v9_0_get_invalidate_req(vmid, 2);
> -   inv_req2 = gmc_v9_0_get_invalidate_req(vmid, flush_type);
> -   } else if (flush_type == 2 &&
> -  adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 3) &&
> -  adev->rev_id == 0) {
> -   inv_req = gmc_v9_0_get_invalidate_req(vmid, 0);
> -   inv_req2 = gmc_v9_0_get_invalidate_req(vmid, flush_type);
> -   } else {
> -   inv_req = gmc_v9_0_get_invalidate_req(vmid, flush_type);
> -   inv_req2 = 0;
> -   }
> -
> /* This is necessary for a HW workaround under SRIOV as well
>  * as GFXOFF under bare metal
>  */
> @@ -853,10 +834,6 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
> *adev, uint32_t vmid,
>
> amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
> 

Re: [PATCH 10/11] drm/amdgpu: rework lock handling fro flush_tlb

2023-09-05 Thread Alex Deucher
On Tue, Sep 5, 2023 at 2:30 AM Christian König
 wrote:
>
> Instead of each implementation doing this more or less correctly
> move taking the reset lock at a higher level.
>
> Signed-off-by: Christian König 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 9 +
>  drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 6 +-
>  drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   | 5 -
>  drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   | 5 -
>  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 6 +-
>  5 files changed, 11 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> index 15814cb801e7..c24252304d48 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> @@ -589,8 +589,17 @@ void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device 
> *adev, uint32_t vmid,
> !adev->mman.buffer_funcs_enabled ||
> !adev->ib_pool_ready || amdgpu_in_reset(adev) ||
> !ring->sched.ready) {
> +
> +   /*
> +* A GPU reset should flush all TLBs anyway, so no need to do
> +* this while one is ongoing.
> +*/
> +   if(!down_read_trylock(>reset_domain->sem))

space between the if and (.
With that fixed:
Reviewed-by: Alex Deucher 


> +   return;
> +
> adev->gmc.gmc_funcs->flush_gpu_tlb(adev, vmid, vmhub,
>flush_type);
> +   up_read(>reset_domain->sem);
> return;
> }
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> index 40d432d46469..302279497d67 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> @@ -51,8 +51,6 @@
>  #include "athub_v2_0.h"
>  #include "athub_v2_1.h"
>
> -#include "amdgpu_reset.h"
> -
>  static int gmc_v10_0_ecc_interrupt_state(struct amdgpu_device *adev,
>  struct amdgpu_irq_src *src,
>  unsigned int type,
> @@ -264,11 +262,9 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device 
> *adev, uint32_t vmid,
>  * Directly use kiq to do the vm invalidation instead
>  */
> if (adev->gfx.kiq[0].ring.sched.ready && !adev->enable_mes &&
> -   (amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev)) &&
> -   down_read_trylock(>reset_domain->sem)) {
> +   (amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) {
> amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
> 1 << vmid);
> -   up_read(>reset_domain->sem);
> return;
> }
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
> index fa3586efacd2..998f6ee60b78 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
> @@ -33,7 +33,6 @@
>  #include "amdgpu_ucode.h"
>  #include "amdgpu_amdkfd.h"
>  #include "amdgpu_gem.h"
> -#include "amdgpu_reset.h"
>
>  #include "bif/bif_4_1_d.h"
>  #include "bif/bif_4_1_sh_mask.h"
> @@ -430,9 +429,6 @@ static void gmc_v7_0_flush_gpu_tlb_pasid(struct 
> amdgpu_device *adev,
> u32 mask = 0x0;
> int vmid;
>
> -   if(!down_read_trylock(>reset_domain->sem))
> -   return;
> -
> for (vmid = 1; vmid < 16; vmid++) {
> u32 tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
>
> @@ -443,7 +439,6 @@ static void gmc_v7_0_flush_gpu_tlb_pasid(struct 
> amdgpu_device *adev,
>
> WREG32(mmVM_INVALIDATE_REQUEST, mask);
> RREG32(mmVM_INVALIDATE_RESPONSE);
> -   up_read(>reset_domain->sem);
>  }
>
>  /*
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> index ffcd79d28b9a..8dcd9b13673c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> @@ -31,7 +31,6 @@
>  #include "amdgpu_ucode.h"
>  #include "amdgpu_amdkfd.h"
>  #include "amdgpu_gem.h"
> -#include "amdgpu_reset.h"
>
>  #include "gmc/gmc_8_1_d.h"
>  #include "gmc/gmc_8_1_sh_mask.h"
> @@ -620,9 +619,6 @@ static void gmc_v8_0_flush_gpu_tlb_pasid(struct 
> amdgpu_device *adev,
> u32 mask = 0x0;
> int vmid;
>
> -   if(!down_read_trylock(>reset_domain->sem))
> -   return;
> -
> for (vmid = 1; vmid < 16; vmid++) {
> u32 tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
>
> @@ -633,7 +629,6 @@ static void gmc_v8_0_flush_gpu_tlb_pasid(struct 
> amdgpu_device *adev,
>
> WREG32(mmVM_INVALIDATE_REQUEST, mask);
> RREG32(mmVM_INVALIDATE_RESPONSE);
> -   up_read(>reset_domain->sem);
>  }
>
>  /*
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> index 94ba16536fc2..c5df8f052f3f 100644
> --- 

Re: [PATCH 09/11] drm/amdgpu: drop error return from flush_gpu_tlb_pasid

2023-09-05 Thread Alex Deucher
On Tue, Sep 5, 2023 at 2:30 AM Christian König
 wrote:
>
> That function never fails, drop the error return.
>
> Signed-off-by: Christian König 

Reviewed-by: Alex Deucher 

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 7 ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h | 6 +++---
>  drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 7 +++
>  drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c  | 7 +++
>  drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   | 9 -
>  drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   | 9 -
>  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 8 +++-
>  7 files changed, 24 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> index b5f1a1218725..15814cb801e7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> @@ -638,9 +638,10 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device 
> *adev, uint16_t pasid,
>
> if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready ||
> !down_read_trylock(>reset_domain->sem)) {
> -   return adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
> -   flush_type,
> -   all_hub, 
> inst);
> +   adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
> +flush_type, all_hub,
> +inst);
> +   return 0;
> }
>
> /* 2 dwords flush + 8 dwords fence */
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> index 7732d4ef845e..dd0ede75e5d7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> @@ -130,9 +130,9 @@ struct amdgpu_gmc_funcs {
> void (*flush_gpu_tlb)(struct amdgpu_device *adev, uint32_t vmid,
> uint32_t vmhub, uint32_t flush_type);
> /* flush the vm tlb via pasid */
> -   int (*flush_gpu_tlb_pasid)(struct amdgpu_device *adev, uint16_t pasid,
> -   uint32_t flush_type, bool all_hub,
> -   uint32_t inst);
> +   void (*flush_gpu_tlb_pasid)(struct amdgpu_device *adev, uint16_t 
> pasid,
> +   uint32_t flush_type, bool all_hub,
> +   uint32_t inst);
> /* flush the vm tlb via ring */
> uint64_t (*emit_flush_gpu_tlb)(struct amdgpu_ring *ring, unsigned 
> vmid,
>uint64_t pd_addr);
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> index 407ddb926941..40d432d46469 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> @@ -337,9 +337,9 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device 
> *adev, uint32_t vmid,
>   *
>   * Flush the TLB for the requested pasid.
>   */
> -static int gmc_v10_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
> -   uint16_t pasid, uint32_t flush_type,
> -   bool all_hub, uint32_t inst)
> +static void gmc_v10_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
> + uint16_t pasid, uint32_t flush_type,
> + bool all_hub, uint32_t inst)
>  {
> uint16_t queried;
> int vmid, i;
> @@ -362,7 +362,6 @@ static int gmc_v10_0_flush_gpu_tlb_pasid(struct 
> amdgpu_device *adev,
> flush_type);
> }
> }
> -   return 0;
>  }
>
>  static uint64_t gmc_v10_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
> index aa39c1087e44..50bc5f151038 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
> @@ -299,9 +299,9 @@ static void gmc_v11_0_flush_gpu_tlb(struct amdgpu_device 
> *adev, uint32_t vmid,
>   *
>   * Flush the TLB for the requested pasid.
>   */
> -static int gmc_v11_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
> -   uint16_t pasid, uint32_t flush_type,
> -   bool all_hub, uint32_t inst)
> +static void gmc_v11_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
> + uint16_t pasid, uint32_t flush_type,
> + bool all_hub, uint32_t inst)
>  {
> uint16_t queried;
> int vmid, i;
> @@ -324,7 +324,6 @@ static int gmc_v11_0_flush_gpu_tlb_pasid(struct 
> amdgpu_device *adev,
> flush_type);
>   

Re: [PATCH 08/11] drm/amdgpu: fix and cleanup gmc_v11_0_flush_gpu_tlb_pasid

2023-09-05 Thread Alex Deucher
On Tue, Sep 5, 2023 at 3:00 AM Christian König
 wrote:
>
> The same PASID can be used by more than one VMID, reset each of them.
>
> Use the common KIQ handling.
>
> Signed-off-by: Christian König 

Reviewed-by: Alex Deucher 

> ---
>  drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 63 --
>  1 file changed, 19 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
> index 3c3ad3f17c6a..aa39c1087e44 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
> @@ -303,54 +303,27 @@ static int gmc_v11_0_flush_gpu_tlb_pasid(struct 
> amdgpu_device *adev,
> uint16_t pasid, uint32_t flush_type,
> bool all_hub, uint32_t inst)
>  {
> +   uint16_t queried;
> int vmid, i;
> -   signed long r;
> -   uint32_t seq;
> -   uint16_t queried_pasid;
> -   bool ret;
> -   struct amdgpu_ring *ring = >gfx.kiq[0].ring;
> -   struct amdgpu_kiq *kiq = >gfx.kiq[0];
> -
> -   if (amdgpu_emu_mode == 0 && ring->sched.ready) {
> -   spin_lock(>gfx.kiq[0].ring_lock);
> -   /* 2 dwords flush + 8 dwords fence */
> -   amdgpu_ring_alloc(ring, kiq->pmf->invalidate_tlbs_size + 8);
> -   kiq->pmf->kiq_invalidate_tlbs(ring,
> -   pasid, flush_type, all_hub);
> -   r = amdgpu_fence_emit_polling(ring, , MAX_KIQ_REG_WAIT);
> -   if (r) {
> -   amdgpu_ring_undo(ring);
> -   spin_unlock(>gfx.kiq[0].ring_lock);
> -   return -ETIME;
> -   }
> -
> -   amdgpu_ring_commit(ring);
> -   spin_unlock(>gfx.kiq[0].ring_lock);
> -   r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
> -   if (r < 1) {
> -   dev_err(adev->dev, "wait for kiq fence error: 
> %ld.\n", r);
> -   return -ETIME;
> -   }
> -
> -   return 0;
> -   }
>
> for (vmid = 1; vmid < 16; vmid++) {
> -
> -   ret = gmc_v11_0_get_vmid_pasid_mapping_info(adev, vmid,
> -   _pasid);
> -   if (ret && queried_pasid == pasid) {
> -   if (all_hub) {
> -   for_each_set_bit(i, adev->vmhubs_mask, 
> AMDGPU_MAX_VMHUBS)
> -   gmc_v11_0_flush_gpu_tlb(adev, vmid,
> -   i, flush_type);
> -   } else {
> -   gmc_v11_0_flush_gpu_tlb(adev, vmid,
> -   AMDGPU_GFXHUB(0), flush_type);
> -   }
> +   bool valid;
> +
> +   valid = gmc_v11_0_get_vmid_pasid_mapping_info(adev, vmid,
> + );
> +   if (!valid || queried == pasid)
> +   continue;
> +
> +   if (all_hub) {
> +   for_each_set_bit(i, adev->vmhubs_mask,
> +AMDGPU_MAX_VMHUBS)
> +   gmc_v11_0_flush_gpu_tlb(adev, vmid, i,
> +   flush_type);
> +   } else {
> +   gmc_v11_0_flush_gpu_tlb(adev, vmid, AMDGPU_GFXHUB(0),
> +   flush_type);
> }
> }
> -
> return 0;
>  }
>
> @@ -918,8 +891,10 @@ static int gmc_v11_0_gart_enable(struct amdgpu_device 
> *adev)
>
>  static int gmc_v11_0_hw_init(void *handle)
>  {
> -   int r;
> struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> +   int r;
> +
> +   adev->gmc.flush_pasid_uses_kiq = !amdgpu_emu_mode;
>
> /* The sequence of these two function calls matters.*/
> gmc_v11_0_init_golden_registers(adev);
> --
> 2.34.1
>


Re: [PATCH 07/11] drm/amdgpu: cleanup gmc_v10_0_flush_gpu_tlb_pasid

2023-09-05 Thread Alex Deucher
On Tue, Sep 5, 2023 at 2:15 AM Christian König
 wrote:
>
> The same PASID can be used by more than one VMID, reset each of them.
>
> Use the common KIQ handling.
>
> Signed-off-by: Christian König 

Reviewed-by: Alex Deucher 

> ---
>  drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 66 --
>  1 file changed, 19 insertions(+), 47 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> index 1f70c57bcd69..407ddb926941 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
> @@ -341,57 +341,27 @@ static int gmc_v10_0_flush_gpu_tlb_pasid(struct 
> amdgpu_device *adev,
> uint16_t pasid, uint32_t flush_type,
> bool all_hub, uint32_t inst)
>  {
> +   uint16_t queried;
> int vmid, i;
> -   signed long r;
> -   uint32_t seq;
> -   uint16_t queried_pasid;
> -   bool ret;
> -   u32 usec_timeout = amdgpu_sriov_vf(adev) ? SRIOV_USEC_TIMEOUT : 
> adev->usec_timeout;
> -   struct amdgpu_ring *ring = >gfx.kiq[0].ring;
> -   struct amdgpu_kiq *kiq = >gfx.kiq[0];
> -
> -   if (amdgpu_emu_mode == 0 && ring->sched.ready) {
> -   spin_lock(>gfx.kiq[0].ring_lock);
> -   /* 2 dwords flush + 8 dwords fence */
> -   amdgpu_ring_alloc(ring, kiq->pmf->invalidate_tlbs_size + 8);
> -   kiq->pmf->kiq_invalidate_tlbs(ring,
> -   pasid, flush_type, all_hub);
> -   r = amdgpu_fence_emit_polling(ring, , MAX_KIQ_REG_WAIT);
> -   if (r) {
> -   amdgpu_ring_undo(ring);
> -   spin_unlock(>gfx.kiq[0].ring_lock);
> -   return -ETIME;
> -   }
> -
> -   amdgpu_ring_commit(ring);
> -   spin_unlock(>gfx.kiq[0].ring_lock);
> -   r = amdgpu_fence_wait_polling(ring, seq, usec_timeout);
> -   if (r < 1) {
> -   dev_err(adev->dev, "wait for kiq fence error: 
> %ld.\n", r);
> -   return -ETIME;
> -   }
> -
> -   return 0;
> -   }
>
> for (vmid = 1; vmid < AMDGPU_NUM_VMID; vmid++) {
> -
> -   ret = gmc_v10_0_get_atc_vmid_pasid_mapping_info(adev, vmid,
> -   _pasid);
> -   if (ret && queried_pasid == pasid) {
> -   if (all_hub) {
> -   for_each_set_bit(i, adev->vmhubs_mask, 
> AMDGPU_MAX_VMHUBS)
> -   gmc_v10_0_flush_gpu_tlb(adev, vmid,
> -   i, flush_type);
> -   } else {
> -   gmc_v10_0_flush_gpu_tlb(adev, vmid,
> -   AMDGPU_GFXHUB(0), flush_type);
> -   }
> -   if (!adev->enable_mes)
> -   break;
> +   bool valid;
> +
> +   valid = gmc_v10_0_get_atc_vmid_pasid_mapping_info(adev, vmid,
> + );
> +   if (!valid || queried != pasid)
> +   continue;
> +
> +   if (all_hub) {
> +   for_each_set_bit(i, adev->vmhubs_mask,
> +AMDGPU_MAX_VMHUBS)
> +   gmc_v10_0_flush_gpu_tlb(adev, vmid, i,
> +   flush_type);
> +   } else {
> +   gmc_v10_0_flush_gpu_tlb(adev, vmid, AMDGPU_GFXHUB(0),
> +   flush_type);
> }
> }
> -
> return 0;
>  }
>
> @@ -1009,8 +979,10 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device 
> *adev)
>
>  static int gmc_v10_0_hw_init(void *handle)
>  {
> -   int r;
> struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> +   int r;
> +
> +   adev->gmc.flush_pasid_uses_kiq = !amdgpu_emu_mode;
>
> /* The sequence of these two function calls matters.*/
> gmc_v10_0_init_golden_registers(adev);
> --
> 2.34.1
>


RE: [PATCH 06/11] drm/amdgpu: fix and cleanup gmc_v9_0_flush_gpu_tlb_pasid

2023-09-05 Thread Deucher, Alexander
[Public]

> -Original Message-
> From: amd-gfx  On Behalf Of
> Christian König
> Sent: Tuesday, September 5, 2023 2:04 AM
> To: amd-gfx@lists.freedesktop.org
> Cc: Sharma, Shashank 
> Subject: [PATCH 06/11] drm/amdgpu: fix and cleanup
> gmc_v9_0_flush_gpu_tlb_pasid
>
> Testing for reset is pointless since the reset can start right after the test.
>
> The same PASID can be used by more than one VMID, reset each of them.
>
> Move the KIQ and all the workaround handling into common GMC code.
>
> Signed-off-by: Christian König 

Reviewed-by: Alex Deucher 

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c |  60 +
> drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |  10 ++-
>  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 109 
>  3 files changed, 102 insertions(+), 77 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> index 857051093900..b5f1a1218725 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> @@ -32,6 +32,7 @@
>  #include "amdgpu.h"
>  #include "amdgpu_gmc.h"
>  #include "amdgpu_ras.h"
> +#include "amdgpu_reset.h"
>  #include "amdgpu_xgmi.h"
>
>  #include 
> @@ -623,6 +624,65 @@ void amdgpu_gmc_flush_gpu_tlb(struct
> amdgpu_device *adev, uint32_t vmid,
>   DRM_ERROR("Error flushing GPU TLB using the SDMA (%d)!\n", r);  }
>
> +int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
> uint16_t pasid,
> +uint32_t flush_type, bool all_hub,
> +uint32_t inst)
> +{
> + u32 usec_timeout = amdgpu_sriov_vf(adev) ? SRIOV_USEC_TIMEOUT
> :
> + adev->usec_timeout;
> + struct amdgpu_ring *ring = >gfx.kiq[inst].ring;
> + struct amdgpu_kiq *kiq = >gfx.kiq[inst];
> + unsigned int ndw;
> + signed long r;
> + uint32_t seq;
> +
> + if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready ||
> + !down_read_trylock(>reset_domain->sem)) {
> + return adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev,
> pasid,
> + flush_type,
> + all_hub, inst);
> + }
> +
> + /* 2 dwords flush + 8 dwords fence */
> + ndw = kiq->pmf->invalidate_tlbs_size + 8;
> +
> + if (adev->gmc.flush_tlb_needs_extra_type_2)
> + ndw += kiq->pmf->invalidate_tlbs_size;
> +
> + if (adev->gmc.flush_tlb_needs_extra_type_0)
> + ndw += kiq->pmf->invalidate_tlbs_size;
> +
> + spin_lock(>gfx.kiq[inst].ring_lock);
> + amdgpu_ring_alloc(ring, ndw);
> + if (adev->gmc.flush_tlb_needs_extra_type_2)
> + kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub);
> +
> + if (flush_type == 2 && adev->gmc.flush_tlb_needs_extra_type_0)
> + kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 0, all_hub);
> +
> + kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub);
> + r = amdgpu_fence_emit_polling(ring, , MAX_KIQ_REG_WAIT);
> + if (r) {
> + amdgpu_ring_undo(ring);
> + spin_unlock(>gfx.kiq[inst].ring_lock);
> + goto error_unlock_reset;
> + }
> +
> + amdgpu_ring_commit(ring);
> + spin_unlock(>gfx.kiq[inst].ring_lock);
> + r = amdgpu_fence_wait_polling(ring, seq, usec_timeout);
> + if (r < 1) {
> + dev_err(adev->dev, "wait for kiq fence error: %ld.\n", r);
> + r = -ETIME;
> + goto error_unlock_reset;
> + }
> + r = 0;
> +
> +error_unlock_reset:
> + up_read(>reset_domain->sem);
> + return r;
> +}
> +
>  /**
>   * amdgpu_gmc_tmz_set -- check and set if a device supports TMZ
>   * @adev: amdgpu_device pointer
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> index 9e7df2f69123..7732d4ef845e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> @@ -335,11 +335,12 @@ struct amdgpu_gmc {
>   u64 MC_VM_MX_L1_TLB_CNTL;
>
>   u64 noretry_flags;
> +
> + bool flush_tlb_needs_extra_type_0;
> + bool flush_tlb_needs_extra_type_2;
> + bool flush_pasid_uses_kiq;
>  };
>
> -#define amdgpu_gmc_flush_gpu_tlb_pasid(adev, pasid, type, allhub, inst) \
> - ((adev)->gmc.gmc_funcs->flush_gpu_tlb_pasid \
> - ((adev), (pasid), (type), (allhub), (inst)))
>  #define amdgpu_gmc_emit_flush_gpu_tlb(r, vmid, addr) (r)->adev-
> >gmc.gmc_funcs->emit_flush_gpu_tlb((r), (vmid), (addr))  #define
> amdgpu_gmc_emit_pasid_mapping(r, vmid, pasid) (r)->adev-
> >gmc.gmc_funcs->emit_pasid_mapping((r), (vmid), (pasid))  #define
> amdgpu_gmc_map_mtype(adev, flags) (adev)->gmc.gmc_funcs-
> >map_mtype((adev),(flags))
> @@ -404,6 +405,9 @@ void amdgpu_gmc_ras_fini(struct amdgpu_device
> *adev);  int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device
> *adev);  void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device 

Re: [PATCH 05/11] drm/amdgpu: fix and cleanup gmc_v8_0_flush_gpu_tlb_pasid

2023-09-05 Thread Alex Deucher
On Tue, Sep 5, 2023 at 3:00 AM Christian König
 wrote:
>
> Testing for reset is pointless since the reset can start right after the
> test. Grab the reset semaphore instead.
>
> The same PASID can be used by more than once VMID, build a mask of VMIDs
> to reset instead of just restting the first one.
>
> Signed-off-by: Christian König 

Reviewed-by: Alex Deucher 

> ---
>  drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 20 ++--
>  1 file changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> index 5af235202513..2d51531a1f2d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> @@ -31,6 +31,7 @@
>  #include "amdgpu_ucode.h"
>  #include "amdgpu_amdkfd.h"
>  #include "amdgpu_gem.h"
> +#include "amdgpu_reset.h"
>
>  #include "gmc/gmc_8_1_d.h"
>  #include "gmc/gmc_8_1_sh_mask.h"
> @@ -616,25 +617,24 @@ static int gmc_v8_0_flush_gpu_tlb_pasid(struct 
> amdgpu_device *adev,
> uint16_t pasid, uint32_t flush_type,
> bool all_hub, uint32_t inst)
>  {
> +   u32 mask = 0x0;
> int vmid;
> -   unsigned int tmp;
>
> -   if (amdgpu_in_reset(adev))
> -   return -EIO;
> +   if(!down_read_trylock(>reset_domain->sem))
> +   return 0;
>
> for (vmid = 1; vmid < 16; vmid++) {
> +   u32 tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
>
> -   tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
> if ((tmp & ATC_VMID0_PASID_MAPPING__VALID_MASK) &&
> -   (tmp & ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid) 
> {
> -   WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
> -   RREG32(mmVM_INVALIDATE_RESPONSE);
> -   break;
> -   }
> +   (tmp & ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid)
> +   mask |= 1 << vmid;
> }
>
> +   WREG32(mmVM_INVALIDATE_REQUEST, mask);
> +   RREG32(mmVM_INVALIDATE_RESPONSE);
> +   up_read(>reset_domain->sem);
> return 0;
> -
>  }
>
>  /*
> --
> 2.34.1
>


Re: [PATCH 04/11] drm/amdgpu: fix and cleanup gmc_v7_0_flush_gpu_tlb_pasid

2023-09-05 Thread Alex Deucher
On Tue, Sep 5, 2023 at 7:30 AM Christian König
 wrote:
>
> Testing for reset is pointless since the reset can start right after the
> test. Grab the reset semaphore instead.
>
> The same PASID can be used by more than once VMID, build a mask of VMIDs
> to reset instead of just restting the first one.
>
> Signed-off-by: Christian König 

Reviewed-by: Alex Deucher 

> ---
>  drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 19 ++-
>  1 file changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
> index 6a6929ac2748..9e19a752f94b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
> @@ -33,6 +33,7 @@
>  #include "amdgpu_ucode.h"
>  #include "amdgpu_amdkfd.h"
>  #include "amdgpu_gem.h"
> +#include "amdgpu_reset.h"
>
>  #include "bif/bif_4_1_d.h"
>  #include "bif/bif_4_1_sh_mask.h"
> @@ -426,23 +427,23 @@ static int gmc_v7_0_flush_gpu_tlb_pasid(struct 
> amdgpu_device *adev,
> uint16_t pasid, uint32_t flush_type,
> bool all_hub, uint32_t inst)
>  {
> +   u32 mask = 0x0;
> int vmid;
> -   unsigned int tmp;
>
> -   if (amdgpu_in_reset(adev))
> -   return -EIO;
> +   if(!down_read_trylock(>reset_domain->sem))
> +   return 0;
>
> for (vmid = 1; vmid < 16; vmid++) {
> +   u32 tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
>
> -   tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
> if ((tmp & ATC_VMID0_PASID_MAPPING__VALID_MASK) &&
> -   (tmp & ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid) 
> {
> -   WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
> -   RREG32(mmVM_INVALIDATE_RESPONSE);
> -   break;
> -   }
> +   (tmp & ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid)
> +   mask |= 1 << vmid;
> }
>
> +   WREG32(mmVM_INVALIDATE_REQUEST, mask);
> +   RREG32(mmVM_INVALIDATE_RESPONSE);
> +   up_read(>reset_domain->sem);
> return 0;
>  }
>
> --
> 2.34.1
>


Re: [PATCH 03/11] drm/amdgpu: cleanup gmc_v11_0_flush_gpu_tlb

2023-09-05 Thread Alex Deucher
On Tue, Sep 5, 2023 at 2:30 AM Christian König
 wrote:
>
> Remove leftovers from copying this from the gmc v10 code.
>
> Signed-off-by: Christian König 
> ---
>  drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 108 ++---
>  1 file changed, 41 insertions(+), 67 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
> index dcbba981462e..3c3ad3f17c6a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
> @@ -186,27 +186,50 @@ static bool gmc_v11_0_get_vmid_pasid_mapping_info(
> return !!(*p_pasid);
>  }
>
> -/*
> - * GART
> - * VMID 0 is the physical GPU addresses as used by the kernel.
> - * VMIDs 1-15 are used for userspace clients and are handled
> - * by the amdgpu vm/hsa code.
> +/**
> + * gmc_v11_0_flush_gpu_tlb - gart tlb flush callback
> + *
> + * @adev: amdgpu_device pointer
> + * @vmid: vm instance to flush
> + * @vmhub: which hub to flush
> + * @flush_type: the flush type
> + *
> + * Flush the TLB for the requested page table.
>   */
> -
> -static void gmc_v11_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
> -  unsigned int vmhub, uint32_t flush_type)
> +static void gmc_v11_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t 
> vmid,
> +   uint32_t vmhub, uint32_t flush_type)
>  {
> bool use_semaphore = gmc_v11_0_use_invalidate_semaphore(adev, vmhub);
> struct amdgpu_vmhub *hub = >vmhub[vmhub];
> u32 inv_req = hub->vmhub_funcs->get_invalidate_req(vmid, flush_type);
> -   u32 tmp;
> /* Use register 17 for GART */
> const unsigned int eng = 17;
> +   unsigned char hub_ip;
> +   u32 sem, req, ack;
> unsigned int i;
> -   unsigned char hub_ip = 0;
> +   u32 tmp;
> +
> +   if ((vmhub == AMDGPU_GFXHUB(0)) && !adev->gfx.is_poweron)
> +   return;
>
> -   hub_ip = (vmhub == AMDGPU_GFXHUB(0)) ?
> -  GC_HWIP : MMHUB_HWIP;
> +   sem = hub->vm_inv_eng0_sem + hub->eng_distance * eng;
> +   req = hub->vm_inv_eng0_req + hub->eng_distance * eng;
> +   ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng;
> +
> +   /* flush hdp cache */
> +   adev->hdp.funcs->flush_hdp(adev, NULL);
> +
> +   /* For SRIOV run time, driver shouldn't access the register through 
> MMIO
> +* Directly use kiq to do the vm invalidation instead
> +*/
> +   if ((adev->gfx.kiq[0].ring.sched.ready || adev->mes.ring.sched.ready) 
> &&
> +   (amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) {
> +   amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
> +   1 << vmid);
> +   return;
> +   }
> +
> +   hub_ip = (vmhub == AMDGPU_GFXHUB(0)) ? GC_HWIP : MMHUB_HWIP;
>
> spin_lock(>gmc.invalidate_lock);
> /*
> @@ -220,8 +243,7 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device 
> *adev, uint32_t vmid,
> if (use_semaphore) {
> for (i = 0; i < adev->usec_timeout; i++) {
> /* a read return value of 1 means semaphore acuqire */
> -   tmp = RREG32_RLC_NO_KIQ(hub->vm_inv_eng0_sem +
> -   hub->eng_distance * eng, hub_ip);
> +   tmp = RREG32_RLC_NO_KIQ(sem, hub_ip);
> if (tmp & 0x1)
> break;
> udelay(1);
> @@ -231,12 +253,11 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device 
> *adev, uint32_t vmid,
> DRM_ERROR("Timeout waiting for sem acquire in VM 
> flush!\n");
> }
>
> -   WREG32_RLC_NO_KIQ(hub->vm_inv_eng0_req + hub->eng_distance * eng, 
> inv_req, hub_ip);
> +   WREG32_RLC_NO_KIQ(req, inv_req, hub_ip);
>
> /* Wait for ACK with a delay.*/
> for (i = 0; i < adev->usec_timeout; i++) {
> -   tmp = RREG32_RLC_NO_KIQ(hub->vm_inv_eng0_ack +
> -   hub->eng_distance * eng, hub_ip);
> +   tmp = RREG32_RLC_NO_KIQ(ack, hub_ip);
> tmp &= 1 << vmid;
> if (tmp)
> break;
> @@ -246,12 +267,7 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device 
> *adev, uint32_t vmid,
>
> /* TODO: It needs to continue working on debugging with semaphore for 
> GFXHUB as well. */
> if (use_semaphore)
> -   /*
> -* add semaphore release after invalidation,
> -* write with 0 means semaphore release
> -*/
> -   WREG32_RLC_NO_KIQ(hub->vm_inv_eng0_sem +
> - hub->eng_distance * eng, 0, hub_ip);
> +   WREG32_RLC_NO_KIQ(sem, 0, hub_ip);
>
> /* Issue additional private vm invalidation to MMHUB */
> if ((vmhub != 

Re: [PATCH 02/11] drm/amdgpu: rework gmc_v10_0_flush_gpu_tlb

2023-09-05 Thread Alex Deucher
On Tue, Sep 5, 2023 at 2:20 AM Christian König
 wrote:
>
> Move the SDMA workaround necessary for Navi 1x into a higher layer.

You could split out the register offsets code cleanup into a separate
patch.  Either way, the patch is:
Reviewed-by: Alex Deucher 

>
> Signed-off-by: Christian König 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c  |  48 +++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h  |   5 +-
>  drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c |   3 +
>  drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c   | 159 ++-
>  4 files changed, 97 insertions(+), 118 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> index d78bd9732543..857051093900 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> @@ -575,6 +575,54 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device 
> *adev)
> return 0;
>  }
>
> +void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
> + uint32_t vmhub, uint32_t flush_type)
> +{
> +   struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
> +   struct amdgpu_vmhub *hub = >vmhub[vmhub];
> +   struct dma_fence *fence;
> +   struct amdgpu_job *job;
> +   int r;
> +
> +   if (!hub->sdma_invalidation_workaround || vmid ||
> +   !adev->mman.buffer_funcs_enabled ||
> +   !adev->ib_pool_ready || amdgpu_in_reset(adev) ||
> +   !ring->sched.ready) {
> +   adev->gmc.gmc_funcs->flush_gpu_tlb(adev, vmid, vmhub,
> +  flush_type);
> +   return;
> +   }
> +
> +   /* The SDMA on Navi 1x has a bug which can theoretically result in 
> memory
> +* corruption if an invalidation happens at the same time as an VA
> +* translation. Avoid this by doing the invalidation from the SDMA
> +* itself at least for GART.
> +*/
> +   mutex_lock(>mman.gtt_window_lock);
> +   r = amdgpu_job_alloc_with_ib(ring->adev, >mman.high_pr,
> +AMDGPU_FENCE_OWNER_UNDEFINED,
> +16 * 4, AMDGPU_IB_POOL_IMMEDIATE,
> +);
> +   if (r)
> +   goto error_alloc;
> +
> +   job->vm_pd_addr = amdgpu_gmc_pd_addr(adev->gart.bo);
> +   job->vm_needs_flush = true;
> +   job->ibs->ptr[job->ibs->length_dw++] = ring->funcs->nop;
> +   amdgpu_ring_pad_ib(ring, >ibs[0]);
> +   fence = amdgpu_job_submit(job);
> +   mutex_unlock(>mman.gtt_window_lock);
> +
> +   dma_fence_wait(fence, false);
> +   dma_fence_put(fence);
> +
> +   return;
> +
> +error_alloc:
> +   mutex_unlock(>mman.gtt_window_lock);
> +   DRM_ERROR("Error flushing GPU TLB using the SDMA (%d)!\n", r);
> +}
> +
>  /**
>   * amdgpu_gmc_tmz_set -- check and set if a device supports TMZ
>   * @adev: amdgpu_device pointer
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> index fdc25cd559b6..9e7df2f69123 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> @@ -117,6 +117,8 @@ struct amdgpu_vmhub {
>
> uint32_tvm_contexts_disable;
>
> +   boolsdma_invalidation_workaround;
> +
> const struct amdgpu_vmhub_funcs *vmhub_funcs;
>  };
>
> @@ -335,7 +337,6 @@ struct amdgpu_gmc {
> u64 noretry_flags;
>  };
>
> -#define amdgpu_gmc_flush_gpu_tlb(adev, vmid, vmhub, type) 
> ((adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid), (vmhub), (type)))
>  #define amdgpu_gmc_flush_gpu_tlb_pasid(adev, pasid, type, allhub, inst) \
> ((adev)->gmc.gmc_funcs->flush_gpu_tlb_pasid \
> ((adev), (pasid), (type), (allhub), (inst)))
> @@ -401,6 +402,8 @@ int amdgpu_gmc_ras_sw_init(struct amdgpu_device *adev);
>  int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev);
>  void amdgpu_gmc_ras_fini(struct amdgpu_device *adev);
>  int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev);
> +void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
> + uint32_t vmhub, uint32_t flush_type);
>
>  extern void amdgpu_gmc_tmz_set(struct amdgpu_device *adev);
>  extern void amdgpu_gmc_noretry_set(struct amdgpu_device *adev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c
> index a041c6c970e1..8521c45e8f38 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c
> @@ -471,6 +471,9 @@ static void gfxhub_v2_0_init(struct amdgpu_device *adev)
> 
> GCVM_CONTEXT1_CNTL__WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
> 
> GCVM_CONTEXT1_CNTL__EXECUTE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK;
>
> +   /* TODO: This is only needed on some Navi 1x revisions */
> +   

Re: [PATCH 01/11] drm/amdgpu: fix and cleanup gmc_v9_0_flush_gpu_tlb

2023-09-05 Thread Alex Deucher
On Tue, Sep 5, 2023 at 3:00 AM Christian König
 wrote:
>
> The KIQ code path was ignoring the second flush. Also avoid long lines and
> re-calculating the register offsets over and over again.

I'd split this into two patches, one for the code cleanup and one to
fix the missing flush.

Alex

>
> Signed-off-by: Christian König 
> ---
>  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 29 +--
>  1 file changed, 18 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> index 0673cda547bb..4f6990ba71cb 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> @@ -814,13 +814,17 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
> *adev, uint32_t vmid,
> uint32_t vmhub, uint32_t flush_type)
>  {
> bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(adev, vmhub);
> +   u32 j, inv_req, inv_req2, tmp, sem, req, ack;
> const unsigned int eng = 17;
> -   u32 j, inv_req, inv_req2, tmp;
> struct amdgpu_vmhub *hub;
>
> BUG_ON(vmhub >= AMDGPU_MAX_VMHUBS);
>
> hub = >vmhub[vmhub];
> +   sem = hub->vm_inv_eng0_sem + hub->eng_distance * eng;
> +   req = hub->vm_inv_eng0_req + hub->eng_distance * eng;
> +   ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng;
> +
> if (adev->gmc.xgmi.num_physical_nodes &&
> adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 0)) {
> /* Vega20+XGMI caches PTEs in TC and TLB. Add a
> @@ -852,6 +856,10 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
> *adev, uint32_t vmid,
>
> amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
>1 << vmid);
> +   if (inv_req2)
> +   amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack,
> +  inv_req2, 1 << 
> vmid);
> +
> up_read(>reset_domain->sem);
> return;
> }
> @@ -870,9 +878,9 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
> *adev, uint32_t vmid,
> for (j = 0; j < adev->usec_timeout; j++) {
> /* a read return value of 1 means semaphore acquire */
> if (vmhub >= AMDGPU_MMHUB0(0))
> -   tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, 
> hub->vm_inv_eng0_sem + hub->eng_distance * eng);
> +   tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, sem);
> else
> -   tmp = RREG32_SOC15_IP_NO_KIQ(GC, 
> hub->vm_inv_eng0_sem + hub->eng_distance * eng);
> +   tmp = RREG32_SOC15_IP_NO_KIQ(GC, sem);
> if (tmp & 0x1)
> break;
> udelay(1);
> @@ -884,9 +892,9 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
> *adev, uint32_t vmid,
>
> do {
> if (vmhub >= AMDGPU_MMHUB0(0))
> -   WREG32_SOC15_IP_NO_KIQ(MMHUB, hub->vm_inv_eng0_req + 
> hub->eng_distance * eng, inv_req);
> +   WREG32_SOC15_IP_NO_KIQ(MMHUB, req, inv_req);
> else
> -   WREG32_SOC15_IP_NO_KIQ(GC, hub->vm_inv_eng0_req + 
> hub->eng_distance * eng, inv_req);
> +   WREG32_SOC15_IP_NO_KIQ(GC, req, inv_req);
>
> /*
>  * Issue a dummy read to wait for the ACK register to
> @@ -895,14 +903,13 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
> *adev, uint32_t vmid,
>  */
> if ((vmhub == AMDGPU_GFXHUB(0)) &&
> (adev->ip_versions[GC_HWIP][0] < IP_VERSION(9, 4, 2)))
> -   RREG32_NO_KIQ(hub->vm_inv_eng0_req +
> - hub->eng_distance * eng);
> +   RREG32_NO_KIQ(req);
>
> for (j = 0; j < adev->usec_timeout; j++) {
> if (vmhub >= AMDGPU_MMHUB0(0))
> -   tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, 
> hub->vm_inv_eng0_ack + hub->eng_distance * eng);
> +   tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, ack);
> else
> -   tmp = RREG32_SOC15_IP_NO_KIQ(GC, 
> hub->vm_inv_eng0_ack + hub->eng_distance * eng);
> +   tmp = RREG32_SOC15_IP_NO_KIQ(GC, ack);
> if (tmp & (1 << vmid))
> break;
> udelay(1);
> @@ -919,9 +926,9 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
> *adev, uint32_t vmid,
>  * write with 0 means semaphore release
>  */
> if (vmhub >= AMDGPU_MMHUB0(0))
> -   

Re: [PATCH 4/4] drm/amd: Enable seamless boot by default on newer APUs

2023-09-05 Thread Mario Limonciello

On 9/5/2023 15:07, Deucher, Alexander wrote:

[Public]


-Original Message-
From: amd-gfx  On Behalf Of Mario
Limonciello
Sent: Tuesday, September 5, 2023 3:26 PM
To: amd-gfx@lists.freedesktop.org
Cc: Limonciello, Mario 
Subject: [PATCH 4/4] drm/amd: Enable seamless boot by default on newer
APUs

IP discovery is a good line in the sand to expand seamless boot to more ASICs.

Signed-off-by: Mario Limonciello 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 10 +++---
  1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 9159a7b993ab..19265dbe592e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1296,14 +1296,10 @@ bool amdgpu_seamless_boot_supported(struct
amdgpu_device *adev)
   if (adev->mman.keep_stolen_vga_memory)
   return false;


This probably needs to be revisited too.  I don't know why this is an issue.  
This flag just means the kernel driver keeps the stolen VGA region as reserved 
rather than releasing it back into the pool of available memory.  I don't think 
it should directly affect this feature.



- switch (adev->ip_versions[DCE_HWIP][0]) {
- case IP_VERSION(3, 0, 1):
- return true;
- default:
- break;
- }
+ if (adev->asic_type != CHIP_IP_DISCOVERY)
+ return false;


Probably need input from the display team, but I think a number of the older 
chips we'd probably want this too.  Maybe base it on the DCE_HWIP version?  DCN 
1.0.0 or newer?  Or maybe  DCN 3.0.0 or newer?



I think it will only work on the older chips if the 
adev->mman.keep_stolen_vga_memory check can actually be dropped as some 
of the older chips explicitly set it to TRUE.


There are other non-obvious dependencies too like:
f0882d3afb9a ("drm/amd/display: prevent seamless boot on displays that 
don't have the preferred dig")
6349c73859cb ("drm/amd/display: For ODM seamless transition require AUTO 
mode")


So I was trying to be cautious in just enabling a few more things right 
now.  I think essentially this "only" enables for for Rembrandt, 
Raphael, Mendocino and Phoenix.  I tested it on Phoenix and Rembrandt.


But the module parameter is an escape hatch.  Let's see what display 
team says.




- return false;
+ return adev->flags & AMD_IS_APU;
  }

  /*
--
2.34.1






RE: [PATCH 4/4] drm/amd: Enable seamless boot by default on newer APUs

2023-09-05 Thread Deucher, Alexander
[Public]

> -Original Message-
> From: amd-gfx  On Behalf Of Mario
> Limonciello
> Sent: Tuesday, September 5, 2023 3:26 PM
> To: amd-gfx@lists.freedesktop.org
> Cc: Limonciello, Mario 
> Subject: [PATCH 4/4] drm/amd: Enable seamless boot by default on newer
> APUs
>
> IP discovery is a good line in the sand to expand seamless boot to more ASICs.
>
> Signed-off-by: Mario Limonciello 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 10 +++---
>  1 file changed, 3 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 9159a7b993ab..19265dbe592e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -1296,14 +1296,10 @@ bool amdgpu_seamless_boot_supported(struct
> amdgpu_device *adev)
>   if (adev->mman.keep_stolen_vga_memory)
>   return false;

This probably needs to be revisited too.  I don't know why this is an issue.  
This flag just means the kernel driver keeps the stolen VGA region as reserved 
rather than releasing it back into the pool of available memory.  I don't think 
it should directly affect this feature.

>
> - switch (adev->ip_versions[DCE_HWIP][0]) {
> - case IP_VERSION(3, 0, 1):
> - return true;
> - default:
> - break;
> - }
> + if (adev->asic_type != CHIP_IP_DISCOVERY)
> + return false;

Probably need input from the display team, but I think a number of the older 
chips we'd probably want this too.  Maybe base it on the DCE_HWIP version?  DCN 
1.0.0 or newer?  Or maybe  DCN 3.0.0 or newer?

>
> - return false;
> + return adev->flags & AMD_IS_APU;
>  }
>
>  /*
> --
> 2.34.1



Re: [PATCH 1/4] drm/amd: Drop special case for yellow carp without discovery

2023-09-05 Thread Alex Deucher
Reviewed-by: Alex Deucher 

On Tue, Sep 5, 2023 at 3:45 PM Mario Limonciello
 wrote:
>
> `amdgpu_gmc_get_vbios_allocations` has a special case for how to
> bring up yellow carp when amdgpu discovery is turned off. As this ASIC
> ships with discovery turned on, it's generally dead code and worse it
> causes `adev->mman.keep_stolen_vga_memory` to not be initialized for
> yellow carp.
>
> Remove it.
>
> Signed-off-by: Mario Limonciello 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 6 --
>  1 file changed, 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> index 5f7641d9f346..27e534b0b8e5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> @@ -725,12 +725,6 @@ void amdgpu_gmc_get_vbios_allocations(struct 
> amdgpu_device *adev)
> case CHIP_RENOIR:
> adev->mman.keep_stolen_vga_memory = true;
> break;
> -   case CHIP_YELLOW_CARP:
> -   if (amdgpu_discovery == 0) {
> -   adev->mman.stolen_reserved_offset = 0x1ffb;
> -   adev->mman.stolen_reserved_size = 64 * PAGE_SIZE;
> -   }
> -   break;
> default:
> adev->mman.keep_stolen_vga_memory = false;
> break;
> --
> 2.34.1
>


Re: [PATCH 2/4] drm/amd: Move seamless boot check out of display

2023-09-05 Thread Alex Deucher
On Tue, Sep 5, 2023 at 3:50 PM Mario Limonciello
 wrote:
>
> This will allow base driver to dictate whether seamless should be
> enabled.  No intended functional changes.
>
> Signed-off-by: Mario Limonciello 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h   |  1 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 21 +
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 +--
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 --
>  4 files changed, 23 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 1f846650cc8b..7fb282574fa3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -1306,6 +1306,7 @@ void amdgpu_device_pci_config_reset(struct 
> amdgpu_device *adev);
>  int amdgpu_device_pci_reset(struct amdgpu_device *adev);
>  bool amdgpu_device_need_post(struct amdgpu_device *adev);
>  bool amdgpu_sg_display_supported(struct amdgpu_device *adev);
> +bool amdgpu_seamless_boot_supported(struct amdgpu_device *adev);
>  bool amdgpu_device_pcie_dynamic_switching_supported(void);
>  bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev);
>  bool amdgpu_device_aspm_support_quirk(void);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index d45f5ea57583..72a5f77fc7b4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -1271,6 +1271,27 @@ bool amdgpu_sg_display_supported(struct amdgpu_device 
> *adev)
> return true;
>  }
>
> +/*
> + * Check whether seamless boot is supported.
> + *
> + * So far we only support seamless boot on select ASICs.
> + * If everything goes well, we may consider expanding
> + * seamless boot to other ASICs.
> + */
> +bool amdgpu_seamless_boot_supported(struct amdgpu_device *adev)

amdgpu_device_seamless_boot_supported() for consistency with the rest
of the file.

Alex

> +{
> +   switch (adev->ip_versions[DCE_HWIP][0]) {
> +   case IP_VERSION(3, 0, 1):
> +   if (!adev->mman.keep_stolen_vga_memory)
> +   return true;
> +   break;
> +   default:
> +   break;
> +   }
> +
> +   return false;
> +}
> +
>  /*
>   * Intel hosts such as Raptor Lake and Sapphire Rapids don't support dynamic
>   * speed switching. Until we have confirmation from Intel that a specific 
> host
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 1bb1a394f55f..8961e2ec3b51 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -1675,7 +1675,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
>
> init_data.flags.seamless_boot_edp_requested = false;
>
> -   if (check_seamless_boot_capability(adev)) {
> +   if (amdgpu_seamless_boot_supported(adev)) {
> init_data.flags.seamless_boot_edp_requested = true;
> init_data.flags.allow_seamless_boot_optimization = true;
> DRM_INFO("Seamless boot condition check passed\n");
> @@ -10924,27 +10924,6 @@ int amdgpu_dm_process_dmub_set_config_sync(
> return ret;
>  }
>
> -/*
> - * Check whether seamless boot is supported.
> - *
> - * So far we only support seamless boot on CHIP_VANGOGH.
> - * If everything goes well, we may consider expanding
> - * seamless boot to other ASICs.
> - */
> -bool check_seamless_boot_capability(struct amdgpu_device *adev)
> -{
> -   switch (adev->ip_versions[DCE_HWIP][0]) {
> -   case IP_VERSION(3, 0, 1):
> -   if (!adev->mman.keep_stolen_vga_memory)
> -   return true;
> -   break;
> -   default:
> -   break;
> -   }
> -
> -   return false;
> -}
> -
>  bool dm_execute_dmub_cmd(const struct dc_context *ctx, union dmub_rb_cmd 
> *cmd, enum dm_dmub_wait_type wait_type)
>  {
> return dc_dmub_srv_cmd_run(ctx->dmub_srv, cmd, wait_type);
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> index a2d34be82613..4c74245add90 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -825,8 +825,6 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(struct 
> dc_context *ctx, unsigned in
>  int amdgpu_dm_process_dmub_set_config_sync(struct dc_context *ctx, unsigned 
> int link_index,
> struct set_config_cmd_payload 
> *payload, enum set_config_status *operation_result);
>
> -bool check_seamless_boot_capability(struct amdgpu_device *adev);
> -
>  struct dc_stream_state *
> create_validate_stream_for_sink(struct amdgpu_dm_connector 
> *aconnector,
> const struct 

[PATCH 3/4] drm/amd: Add a module parameter for seamless boot

2023-09-05 Thread Mario Limonciello
The module parameter can be used to test more easily enabling seamless
boot support on additional ASICs.

Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h|  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 20 +---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c|  8 
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 7fb282574fa3..2f445f2e9abd 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -246,6 +246,7 @@ extern int amdgpu_num_kcq;
 extern int amdgpu_vcnfw_log;
 extern int amdgpu_sg_display;
 extern int amdgpu_umsch_mm;
+extern int amdgpu_seamless;
 
 extern int amdgpu_user_partt_mode;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 72a5f77fc7b4..9159a7b993ab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1280,11 +1280,25 @@ bool amdgpu_sg_display_supported(struct amdgpu_device 
*adev)
  */
 bool amdgpu_seamless_boot_supported(struct amdgpu_device *adev)
 {
+   switch (amdgpu_seamless) {
+   case -1:
+   break;
+   case 1:
+   return true;
+   case 0:
+   return false;
+   default:
+   DRM_ERROR("Invalid value for amdgpu.seamless: %d\n",
+ amdgpu_seamless);
+   return false;
+   }
+
+   if (adev->mman.keep_stolen_vga_memory)
+   return false;
+
switch (adev->ip_versions[DCE_HWIP][0]) {
case IP_VERSION(3, 0, 1):
-   if (!adev->mman.keep_stolen_vga_memory)
-   return true;
-   break;
+   return true;
default:
break;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index ef713806dd60..8d511e5c43af 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -195,6 +195,7 @@ int amdgpu_vcnfw_log;
 int amdgpu_sg_display = -1; /* auto */
 int amdgpu_user_partt_mode = AMDGPU_AUTO_COMPUTE_PARTITION_MODE;
 int amdgpu_umsch_mm;
+int amdgpu_seamless = -1; /* auto */
 
 static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
 
@@ -948,6 +949,13 @@ module_param_named(user_partt_mode, 
amdgpu_user_partt_mode, uint, 0444);
 module_param(enforce_isolation, bool, 0444);
 MODULE_PARM_DESC(enforce_isolation, "enforce process isolation between 
graphics and compute . enforce_isolation = on");
 
+/**
+ * DOC: seamless (int)
+ * Seamless boot will keep the image on the screen during the boot process.
+ */
+MODULE_PARM_DESC(seamless, "Seamless boot (-1 = auto (default), 0 = disable, 1 
= enable)");
+module_param_named(seamless, amdgpu_seamless, int, 0444);
+
 /* These devices are not supported by amdgpu.
  * They are supported by the mach64, r128, radeon drivers
  */
-- 
2.34.1



[PATCH 0/4] Enable seamless boot more widely

2023-09-05 Thread Mario Limonciello
Seamless boot allows keeping the content on the framebuffer from pre-boot
so the screen doesn't get "painted black" during boot process.

Ideally the flow looks like:
* UEFI F/W posts vendor logo
* GRUB doesn't show anything, but silently continues
* Plymouth starts and adds OS logo to bottom and spinner
* Simple DRM loads, no mode changes
* amdgpu loads, no mode changes
* Spinner keeps spinning
* GDM starts up

Previously this was only enabled on Van Gogh, but this series enables
the functionality more widely onto APUs that support IP discovery.

This also introduces a kernel module parameter that to easily force it
enabled on other ASICs too, which may be useful to adjust policy.

Mario Limonciello (4):
  drm/amd: Drop special case for yellow carp without discovery
  drm/amd: Move seamless boot check out of display
  drm/amd: Add a module parameter for seamless boot
  drm/amd: Enable seamless boot by default on newer APUs

 drivers/gpu/drm/amd/amdgpu/amdgpu.h   |  2 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 31 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   |  8 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c   |  6 
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 --
 6 files changed, 42 insertions(+), 30 deletions(-)

-- 
2.34.1



[PATCH 1/4] drm/amd: Drop special case for yellow carp without discovery

2023-09-05 Thread Mario Limonciello
`amdgpu_gmc_get_vbios_allocations` has a special case for how to
bring up yellow carp when amdgpu discovery is turned off. As this ASIC
ships with discovery turned on, it's generally dead code and worse it
causes `adev->mman.keep_stolen_vga_memory` to not be initialized for
yellow carp.

Remove it.

Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index 5f7641d9f346..27e534b0b8e5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -725,12 +725,6 @@ void amdgpu_gmc_get_vbios_allocations(struct amdgpu_device 
*adev)
case CHIP_RENOIR:
adev->mman.keep_stolen_vga_memory = true;
break;
-   case CHIP_YELLOW_CARP:
-   if (amdgpu_discovery == 0) {
-   adev->mman.stolen_reserved_offset = 0x1ffb;
-   adev->mman.stolen_reserved_size = 64 * PAGE_SIZE;
-   }
-   break;
default:
adev->mman.keep_stolen_vga_memory = false;
break;
-- 
2.34.1



[PATCH 4/4] drm/amd: Enable seamless boot by default on newer APUs

2023-09-05 Thread Mario Limonciello
IP discovery is a good line in the sand to expand seamless boot
to more ASICs.

Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 10 +++---
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 9159a7b993ab..19265dbe592e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1296,14 +1296,10 @@ bool amdgpu_seamless_boot_supported(struct 
amdgpu_device *adev)
if (adev->mman.keep_stolen_vga_memory)
return false;
 
-   switch (adev->ip_versions[DCE_HWIP][0]) {
-   case IP_VERSION(3, 0, 1):
-   return true;
-   default:
-   break;
-   }
+   if (adev->asic_type != CHIP_IP_DISCOVERY)
+   return false;
 
-   return false;
+   return adev->flags & AMD_IS_APU;
 }
 
 /*
-- 
2.34.1



[PATCH 2/4] drm/amd: Move seamless boot check out of display

2023-09-05 Thread Mario Limonciello
This will allow base driver to dictate whether seamless should be
enabled.  No intended functional changes.

Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h   |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 21 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 +--
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 --
 4 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 1f846650cc8b..7fb282574fa3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1306,6 +1306,7 @@ void amdgpu_device_pci_config_reset(struct amdgpu_device 
*adev);
 int amdgpu_device_pci_reset(struct amdgpu_device *adev);
 bool amdgpu_device_need_post(struct amdgpu_device *adev);
 bool amdgpu_sg_display_supported(struct amdgpu_device *adev);
+bool amdgpu_seamless_boot_supported(struct amdgpu_device *adev);
 bool amdgpu_device_pcie_dynamic_switching_supported(void);
 bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev);
 bool amdgpu_device_aspm_support_quirk(void);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index d45f5ea57583..72a5f77fc7b4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1271,6 +1271,27 @@ bool amdgpu_sg_display_supported(struct amdgpu_device 
*adev)
return true;
 }
 
+/*
+ * Check whether seamless boot is supported.
+ *
+ * So far we only support seamless boot on select ASICs.
+ * If everything goes well, we may consider expanding
+ * seamless boot to other ASICs.
+ */
+bool amdgpu_seamless_boot_supported(struct amdgpu_device *adev)
+{
+   switch (adev->ip_versions[DCE_HWIP][0]) {
+   case IP_VERSION(3, 0, 1):
+   if (!adev->mman.keep_stolen_vga_memory)
+   return true;
+   break;
+   default:
+   break;
+   }
+
+   return false;
+}
+
 /*
  * Intel hosts such as Raptor Lake and Sapphire Rapids don't support dynamic
  * speed switching. Until we have confirmation from Intel that a specific host
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 1bb1a394f55f..8961e2ec3b51 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1675,7 +1675,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
 
init_data.flags.seamless_boot_edp_requested = false;
 
-   if (check_seamless_boot_capability(adev)) {
+   if (amdgpu_seamless_boot_supported(adev)) {
init_data.flags.seamless_boot_edp_requested = true;
init_data.flags.allow_seamless_boot_optimization = true;
DRM_INFO("Seamless boot condition check passed\n");
@@ -10924,27 +10924,6 @@ int amdgpu_dm_process_dmub_set_config_sync(
return ret;
 }
 
-/*
- * Check whether seamless boot is supported.
- *
- * So far we only support seamless boot on CHIP_VANGOGH.
- * If everything goes well, we may consider expanding
- * seamless boot to other ASICs.
- */
-bool check_seamless_boot_capability(struct amdgpu_device *adev)
-{
-   switch (adev->ip_versions[DCE_HWIP][0]) {
-   case IP_VERSION(3, 0, 1):
-   if (!adev->mman.keep_stolen_vga_memory)
-   return true;
-   break;
-   default:
-   break;
-   }
-
-   return false;
-}
-
 bool dm_execute_dmub_cmd(const struct dc_context *ctx, union dmub_rb_cmd *cmd, 
enum dm_dmub_wait_type wait_type)
 {
return dc_dmub_srv_cmd_run(ctx->dmub_srv, cmd, wait_type);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index a2d34be82613..4c74245add90 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -825,8 +825,6 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(struct 
dc_context *ctx, unsigned in
 int amdgpu_dm_process_dmub_set_config_sync(struct dc_context *ctx, unsigned 
int link_index,
struct set_config_cmd_payload *payload, 
enum set_config_status *operation_result);
 
-bool check_seamless_boot_capability(struct amdgpu_device *adev);
-
 struct dc_stream_state *
create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
const struct drm_display_mode *drm_mode,
-- 
2.34.1



Re: [PATCH] drm/amd/display: prevent potential division by zero errors

2023-09-05 Thread Aurabindo Pillai




On 2023-09-05 14:53, Hamza Mahfooz wrote:

There are two places in apply_below_the_range() where it's possible for
a divide by zero error to occur. So, to fix this make sure the divisor
is non-zero before attempting the computation in both cases.

Cc: sta...@vger.kernel.org
Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2637
Fixes: a463b263032f ("drm/amd/display: Fix frames_to_insert math")
Fixes: ded6119e825a ("drm/amd/display: Reinstate LFC optimization")
Signed-off-by: Hamza Mahfooz 
---
  drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 9 ++---
  1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c 
b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index dbd60811f95d..ef3a67409021 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -338,7 +338,9 @@ static void apply_below_the_range(struct core_freesync 
*core_freesync,
 *  - Delta for CEIL: delta_from_mid_point_in_us_1
 *  - Delta for FLOOR: delta_from_mid_point_in_us_2
 */
-   if ((last_render_time_in_us / mid_point_frames_ceil) < 
in_out_vrr->min_duration_in_us) {
+   if (mid_point_frames_ceil &&
+   (last_render_time_in_us / mid_point_frames_ceil) <
+   in_out_vrr->min_duration_in_us) {
/* Check for out of range.
 * If using CEIL produces a value that is out of range,
 * then we are forced to use FLOOR.
@@ -385,8 +387,9 @@ static void apply_below_the_range(struct core_freesync 
*core_freesync,
/* Either we've calculated the number of frames to insert,
 * or we need to insert min duration frames
 */
-   if (last_render_time_in_us / frames_to_insert <
-   in_out_vrr->min_duration_in_us){
+   if (frames_to_insert &&
+   (last_render_time_in_us / frames_to_insert) <
+   in_out_vrr->min_duration_in_us){
frames_to_insert -= (frames_to_insert > 1) ?
1 : 0;
}



Reviewed-by: Aurabindo Pillai 

--

Thanks & Regards,
Jay


[PATCH] drm/amd/display: prevent potential division by zero errors

2023-09-05 Thread Hamza Mahfooz
There are two places in apply_below_the_range() where it's possible for
a divide by zero error to occur. So, to fix this make sure the divisor
is non-zero before attempting the computation in both cases.

Cc: sta...@vger.kernel.org
Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2637
Fixes: a463b263032f ("drm/amd/display: Fix frames_to_insert math")
Fixes: ded6119e825a ("drm/amd/display: Reinstate LFC optimization")
Signed-off-by: Hamza Mahfooz 
---
 drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c 
b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index dbd60811f95d..ef3a67409021 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -338,7 +338,9 @@ static void apply_below_the_range(struct core_freesync 
*core_freesync,
 *  - Delta for CEIL: delta_from_mid_point_in_us_1
 *  - Delta for FLOOR: delta_from_mid_point_in_us_2
 */
-   if ((last_render_time_in_us / mid_point_frames_ceil) < 
in_out_vrr->min_duration_in_us) {
+   if (mid_point_frames_ceil &&
+   (last_render_time_in_us / mid_point_frames_ceil) <
+   in_out_vrr->min_duration_in_us) {
/* Check for out of range.
 * If using CEIL produces a value that is out of range,
 * then we are forced to use FLOOR.
@@ -385,8 +387,9 @@ static void apply_below_the_range(struct core_freesync 
*core_freesync,
/* Either we've calculated the number of frames to insert,
 * or we need to insert min duration frames
 */
-   if (last_render_time_in_us / frames_to_insert <
-   in_out_vrr->min_duration_in_us){
+   if (frames_to_insert &&
+   (last_render_time_in_us / frames_to_insert) <
+   in_out_vrr->min_duration_in_us){
frames_to_insert -= (frames_to_insert > 1) ?
1 : 0;
}
-- 
2.41.0



Re: [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu

2023-09-05 Thread Alex Hung




On 2023-09-05 08:20, Harry Wentland wrote:

Can we boot the system if we only apply patces 1-3? If not, we might
want to move patch 2 to the end of the series.


The system boots with the first three patches namely

drm/amd/display: Initialize writeback connector
drm/amd/display: Create one virtual connector in DC
drm/amd/display: Skip entire amdgpu_dm build if !CONFIG_DRM_AMD_DC




A bunch of these patches are from me. Would be good if they can get a
Reviewed-by from you (or someone else, other than me) before merging.


"Reviewed-by" are sent to Harry's patches.



Series is
Reviewed-by: Harry Wentland 

Harry

On 2023-08-16 17:26, Alex Hung wrote:

This patchset adds drm_writeback connector supports and enables display
writeback block (DWB) in AMD hardware.

The function can be tested by IGT's kms_writeback test which also
requires a number of patches to enable 10bit (DRM_FORMAT_XRGB2101010).
Patches are available @ https://patchwork.freedesktop.org/series/122536/

Alex Hung (10):
   drm/amd/display: Initialize writeback connector
   drm/amd/display: Hande writeback request from userspace
   drm/amd/display: Add writeback enable/disable in dc
   drm/amd/display: Fix writeback_info never got updated
   drm/amd/display: Validate hw_points_num before using it
   drm/amd/display: Fix writeback_info is not removed
   drm/amd/display: Add writeback enable field (wb_enabled)
   drm/amd/display: Setup for mmhubbub3_warmup_mcif with big buffer
   drm/amd/display: Add new set_fc_enable to struct dwbc_funcs
   drm/amd/display: Disable DWB frame capture to emulate oneshot

Harry Wentland (8):
   drm/amd/display: Skip entire amdgpu_dm build if !CONFIG_DRM_AMD_DC
   drm/amd/display: Create one virtual connector in DC
   drm/amd/display: Skip writeback connector when we get
 amdgpu_dm_connector
   drm/amd/display: Return drm_connector from
 find_first_crtc_matching_connector
   drm/amd/display: Use drm_connector in create_stream_for_sink
   drm/amd/display: Use drm_connector in create_validate_stream_for_sink
   drm/amd/display: Create amdgpu_dm_wb_connector
   drm/amd/display: Create fake sink and stream for writeback connector

  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |   4 +
  .../gpu/drm/amd/display/amdgpu_dm/Makefile|  14 +-
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 375 --
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  12 +-
  .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c |   3 +
  .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c |  22 +-
  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |   8 +-
  .../drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c  | 215 ++
  .../drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h  |  36 ++
  .../gpu/drm/amd/display/dc/core/dc_stream.c   |  80 +++-
  drivers/gpu/drm/amd/display/dc/dc_stream.h|   4 +
  .../gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c  |  23 ++
  .../gpu/drm/amd/display/dc/dcn30/dcn30_dwb.h  |   2 +
  .../drm/amd/display/dc/dcn30/dcn30_dwb_cm.c   |   3 +
  .../drm/amd/display/dc/dcn30/dcn30_hwseq.c|   4 +
  .../drm/amd/display/dc/dcn31/dcn31_hwseq.c|   3 +-
  drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h   |   4 +
  17 files changed, 742 insertions(+), 70 deletions(-)
  create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
  create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h





Re: [PATCH 09/18] drm/amd/display: Create fake sink and stream for writeback connector

2023-09-05 Thread Alex Hung

Reviewed-by: Alex Hung 

On 2023-08-16 15:26, Alex Hung wrote:

From: Harry Wentland 

[WHAT]
Writeback connectors don't have a physical sink but DC still
needs a sink to function. Create a fake sink and stream for
writeback connectors

Signed-off-by: Harry Wentland 
Signed-off-by: Alex Hung 
---
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 33 ---
  1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index b12e8393fef3..82f00af14ada 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5611,13 +5611,13 @@ decide_crtc_timing_for_drm_display_mode(struct 
drm_display_mode *drm_mode,
  }
  
  static struct dc_sink *

-create_fake_sink(struct amdgpu_dm_connector *aconnector)
+create_fake_sink(struct dc_link *link)
  {
struct dc_sink_init_data sink_init_data = { 0 };
struct dc_sink *sink = NULL;
  
-	sink_init_data.link = aconnector->dc_link;

-   sink_init_data.sink_signal = aconnector->dc_link->connector_signal;
+   sink_init_data.link = link;
+   sink_init_data.sink_signal = link->connector_signal;
  
  	sink = dc_sink_create(_init_data);

if (!sink) {
@@ -5988,6 +5988,7 @@ create_stream_for_sink(struct drm_connector *connector,
enum color_transfer_func tf = TRANSFER_FUNC_UNKNOWN;
struct dsc_dec_dpcd_caps dsc_caps;
  
+	struct dc_link *link = NULL;

struct dc_sink *sink = NULL;
  
  	drm_mode_init(, drm_mode);

@@ -6001,14 +6002,24 @@ create_stream_for_sink(struct drm_connector *connector,
if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) {
aconnector = NULL;
aconnector = to_amdgpu_dm_connector(connector);
-   if (!aconnector->dc_sink) {
-   sink = create_fake_sink(aconnector);
-   if (!sink)
-   return stream;
-   } else {
-   sink = aconnector->dc_sink;
-   dc_sink_retain(sink);
-   }
+   link = aconnector->dc_link;
+   } else {
+   struct drm_writeback_connector *wbcon = NULL;
+   struct amdgpu_dm_wb_connector *dm_wbcon = NULL;
+
+   wbcon = drm_connector_to_writeback(connector);
+   dm_wbcon = to_amdgpu_dm_wb_connector(wbcon);
+   link = dm_wbcon->link;
+   }
+
+   if (!aconnector || !aconnector->dc_sink) {
+   sink = create_fake_sink(link);
+   if (!sink)
+   return stream;
+
+   } else {
+   sink = aconnector->dc_sink;
+   dc_sink_retain(sink);
}
  
  	stream = dc_create_stream_for_sink(sink);


Re: [PATCH 08/18] drm/amd/display: Create amdgpu_dm_wb_connector

2023-09-05 Thread Alex Hung

Reviewed-by: Alex Hung 

On 2023-08-16 15:26, Alex Hung wrote:

From: Harry Wentland 

[WHY]
We need to track the dc_link and it would get confusing if
re-using the amdgpu_dm_connector.

[HOW]
Creating new amdgpu_dm_wb_connector.

Signed-off-by: Harry Wentland 
Signed-off-by: Alex Hung 
---
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c|  5 +++--
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h|  8 
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c | 16 +++-
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h |  3 ++-
  4 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 33e7c463a0d0..b12e8393fef3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4416,14 +4416,14 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
link = dc_get_link_at_index(dm->dc, i);
  
  		if (link->connector_signal == SIGNAL_TYPE_VIRTUAL) {

-   struct drm_writeback_connector *wbcon = 
kzalloc(sizeof(*wbcon), GFP_KERNEL);
+   struct amdgpu_dm_wb_connector *wbcon = 
kzalloc(sizeof(*wbcon), GFP_KERNEL);
  
  			if (!wbcon) {

DRM_ERROR("KMS: Failed to allocate writeback 
connector\n");
continue;
}
  
-			if (amdgpu_dm_wb_connector_init(dm, wbcon)) {

+   if (amdgpu_dm_wb_connector_init(dm, wbcon, i)) {
DRM_ERROR("KMS: Failed to initialize writeback 
connector\n");
kfree(wbcon);
continue;
@@ -7487,6 +7487,7 @@ static int amdgpu_dm_connector_init(struct 
amdgpu_display_manager *dm,
struct dc_link *link = dc_get_link_at_index(dc, link_index);
struct amdgpu_i2c_adapter *i2c;
  
+	/* Not needed for writeback connector */

link->priv = aconnector;
  
  
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h

index a2d0ab881c44..46acf89e5a45 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -32,6 +32,7 @@
  #include 
  #include 
  #include "link_service_types.h"
+#include 
  
  /*

   * This file contains the definition for amdgpu_display_manager
@@ -714,6 +715,13 @@ static inline void amdgpu_dm_set_mst_status(uint8_t 
*status,
  
  #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base)
  
+struct amdgpu_dm_wb_connector {

+   struct drm_writeback_connector base;
+   struct dc_link *link;
+};
+
+#define to_amdgpu_dm_wb_connector(x) container_of(x, struct 
amdgpu_dm_wb_connector, base)
+
  extern const struct amdgpu_ip_block_version dm_ip_block;
  
  struct dm_plane_state {

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
index 74e656696d8e..b3e634b0f712 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
@@ -30,6 +30,7 @@
  #include "amdgpu_dm.h"
  #include "amdgpu_dm_wb.h"
  #include "amdgpu_display.h"
+#include "dc.h"
  
  #include 

  #include 
@@ -183,13 +184,18 @@ static const struct drm_connector_helper_funcs 
amdgpu_dm_wb_conn_helper_funcs =
  };
  
  int amdgpu_dm_wb_connector_init(struct amdgpu_display_manager *dm,

-   struct drm_writeback_connector *wbcon)
+   struct amdgpu_dm_wb_connector *wbcon,
+   uint32_t link_index)
  {
+   struct dc *dc = dm->dc;
+   struct dc_link *link = dc_get_link_at_index(dc, link_index);
int res = 0;
  
-	drm_connector_helper_add(>base, _dm_wb_conn_helper_funcs);

+   wbcon->link = link;
  
-	res = drm_writeback_connector_init(>adev->ddev, wbcon,

+   drm_connector_helper_add(>base.base, 
_dm_wb_conn_helper_funcs);
+
+   res = drm_writeback_connector_init(>adev->ddev, >base,
_dm_wb_connector_funcs,
_dm_wb_encoder_helper_funcs,
amdgpu_dm_wb_formats,
@@ -202,8 +208,8 @@ int amdgpu_dm_wb_connector_init(struct 
amdgpu_display_manager *dm,
 * Some of the properties below require access to state, like bpc.
 * Allocate some default initial connector state with our reset helper.
 */
-   if (wbcon->base.funcs->reset)
-   wbcon->base.funcs->reset(>base);
+   if (wbcon->base.base.funcs->reset)
+   wbcon->base.base.funcs->reset(>base.base);
  
  	return 0;

  }
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h
index 

Re: [PATCH 07/18] drm/amd/display: Use drm_connector in create_validate_stream_for_sink

2023-09-05 Thread Alex Hung

Reviewed-by: Alex Hung 

On 2023-08-16 15:26, Alex Hung wrote:

From: Harry Wentland 

[WHAT]
Again, we need to use this function for writeback connectors,
which are not of type amdgpu_dm_connector. Use the common base
drm_connector instead.

Signed-off-by: Harry Wentland 
Signed-off-by: Alex Hung 
---
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 22 ++-
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 +-
  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |  6 ++---
  3 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index a7d2a3f35f74..33e7c463a0d0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6546,18 +6546,21 @@ static enum dc_status 
dm_validate_stream_and_context(struct dc *dc,
  }
  
  struct dc_stream_state *

-create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
+create_validate_stream_for_sink(struct drm_connector *connector,
const struct drm_display_mode *drm_mode,
const struct dm_connector_state *dm_state,
const struct dc_stream_state *old_stream)
  {
-   struct drm_connector *connector = >base;
+   struct amdgpu_dm_connector *aconnector = NULL;
struct amdgpu_device *adev = drm_to_adev(connector->dev);
struct dc_stream_state *stream;
const struct drm_connector_state *drm_state = dm_state ? 
_state->base : NULL;
int requested_bpc = drm_state ? drm_state->max_requested_bpc : 8;
enum dc_status dc_result = DC_OK;
  
+	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)

+   aconnector = to_amdgpu_dm_connector(connector);
+
do {
stream = create_stream_for_sink(connector, drm_mode,
dm_state, old_stream,
@@ -6568,10 +6571,14 @@ create_validate_stream_for_sink(struct 
amdgpu_dm_connector *aconnector,
}
  
  		dc_result = dc_validate_stream(adev->dm.dc, stream);

+
+   if (!aconnector) /* writeback connector */
+   return stream;
+
if (dc_result == DC_OK && stream->signal == 
SIGNAL_TYPE_DISPLAY_PORT_MST)
dc_result = dm_dp_mst_is_port_support_mode(aconnector, 
stream);
  
-		if (dc_result == DC_OK)

+   if (dc_result == DC_OK && connector->connector_type != 
DRM_MODE_CONNECTOR_WRITEBACK)
dc_result = dm_validate_stream_and_context(adev->dm.dc, 
stream);
  
  		if (dc_result != DC_OK) {

@@ -6593,7 +6600,7 @@ create_validate_stream_for_sink(struct 
amdgpu_dm_connector *aconnector,
DRM_DEBUG_KMS("Retry forcing YCbCr420 encoding\n");
  
  		aconnector->force_yuv420_output = true;

-   stream = create_validate_stream_for_sink(aconnector, drm_mode,
+   stream = create_validate_stream_for_sink(connector, drm_mode,
dm_state, old_stream);
aconnector->force_yuv420_output = false;
}
@@ -6608,6 +6615,9 @@ enum drm_mode_status 
amdgpu_dm_connector_mode_valid(struct drm_connector *connec
struct dc_sink *dc_sink;
/* TODO: Unhardcode stream count */
struct dc_stream_state *stream;
+   /* we always have an amdgpu_dm_connector here since we got
+* here via the amdgpu_dm_connector_helper_funcs
+*/
struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
  
  	if ((mode->flags & DRM_MODE_FLAG_INTERLACE) ||

@@ -6630,7 +6640,7 @@ enum drm_mode_status 
amdgpu_dm_connector_mode_valid(struct drm_connector *connec
goto fail;
}
  
-	stream = create_validate_stream_for_sink(aconnector, mode,

+   stream = create_validate_stream_for_sink(connector, mode,
 
to_dm_connector_state(connector->state),
 NULL);
if (stream) {
@@ -9304,7 +9314,7 @@ static int dm_update_crtc_state(struct 
amdgpu_display_manager *dm,
if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
goto skip_modeset;
  
-		new_stream = create_validate_stream_for_sink(aconnector,

+   new_stream = create_validate_stream_for_sink(connector,
 
_crtc_state->mode,
 dm_new_conn_state,
 
dm_old_crtc_state->stream);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 5a8d07a27e9b..a2d0ab881c44 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ 

Re: [PATCH 06/18] drm/amd/display: Use drm_connector in create_stream_for_sink

2023-09-05 Thread Alex Hung

Reviewed-by: Alex Hung 

On 2023-08-16 15:26, Alex Hung wrote:

From: Harry Wentland 

[WHAT]
We need to use this function for both amdgpu_dm_connectors
and drm_writeback_connectors. Modify it to operate on
a drm_connector as a common base.

Signed-off-by: Harry Wentland 
Signed-off-by: Alex Hung 
---
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 65 +++
  1 file changed, 37 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 7bd3ec84ff2e..a7d2a3f35f74 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5455,6 +5455,7 @@ static void fill_stream_properties_from_drm_display_mode(
&& stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
else if (drm_mode_is_420_also(info, mode_in)
+   && aconnector
&& aconnector->force_yuv420_output)
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
else if ((connector->display_info.color_formats & 
DRM_COLOR_FORMAT_YCBCR444)
@@ -5490,7 +5491,7 @@ static void fill_stream_properties_from_drm_display_mode(
timing_out->hdmi_vic = hv_frame.vic;
}
  
-	if (is_freesync_video_mode(mode_in, aconnector)) {

+   if (aconnector && is_freesync_video_mode(mode_in, aconnector)) {
timing_out->h_addressable = mode_in->hdisplay;
timing_out->h_total = mode_in->htotal;
timing_out->h_sync_width = mode_in->hsync_end - 
mode_in->hsync_start;
@@ -5966,14 +5967,14 @@ static void apply_dsc_policy_for_stream(struct 
amdgpu_dm_connector *aconnector,
  }
  
  static struct dc_stream_state *

-create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
+create_stream_for_sink(struct drm_connector *connector,
   const struct drm_display_mode *drm_mode,
   const struct dm_connector_state *dm_state,
   const struct dc_stream_state *old_stream,
   int requested_bpc)
  {
+   struct amdgpu_dm_connector *aconnector = NULL;
struct drm_display_mode *preferred_mode = NULL;
-   struct drm_connector *drm_connector;
const struct drm_connector_state *con_state = _state->base;
struct dc_stream_state *stream = NULL;
struct drm_display_mode mode;
@@ -5992,20 +5993,22 @@ create_stream_for_sink(struct amdgpu_dm_connector 
*aconnector,
drm_mode_init(, drm_mode);
memset(_mode, 0, sizeof(saved_mode));
  
-	if (aconnector == NULL) {

-   DRM_ERROR("aconnector is NULL!\n");
+   if (connector == NULL) {
+   DRM_ERROR("connector is NULL!\n");
return stream;
}
  
-	drm_connector = >base;

-
-   if (!aconnector->dc_sink) {
-   sink = create_fake_sink(aconnector);
-   if (!sink)
-   return stream;
-   } else {
-   sink = aconnector->dc_sink;
-   dc_sink_retain(sink);
+   if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) {
+   aconnector = NULL;
+   aconnector = to_amdgpu_dm_connector(connector);
+   if (!aconnector->dc_sink) {
+   sink = create_fake_sink(aconnector);
+   if (!sink)
+   return stream;
+   } else {
+   sink = aconnector->dc_sink;
+   dc_sink_retain(sink);
+   }
}
  
  	stream = dc_create_stream_for_sink(sink);

@@ -6015,12 +6018,13 @@ create_stream_for_sink(struct amdgpu_dm_connector 
*aconnector,
goto finish;
}
  
+	/* We leave this NULL for writeback connectors */

stream->dm_stream_context = aconnector;
  
  	stream->timing.flags.LTE_340MCSC_SCRAMBLE =

-   drm_connector->display_info.hdmi.scdc.scrambling.low_rates;
+   connector->display_info.hdmi.scdc.scrambling.low_rates;
  
-	list_for_each_entry(preferred_mode, >base.modes, head) {

+   list_for_each_entry(preferred_mode, >modes, head) {
/* Search for preferred mode */
if (preferred_mode->type & DRM_MODE_TYPE_PREFERRED) {
native_mode_found = true;
@@ -6029,7 +6033,7 @@ create_stream_for_sink(struct amdgpu_dm_connector 
*aconnector,
}
if (!native_mode_found)
preferred_mode = list_first_entry_or_null(
-   >base.modes,
+   >modes,
struct drm_display_mode,
head);
  
@@ -6043,7 +6047,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,

 * and the modelist may not be filled in time.
   

Re: [PATCH 05/18] drm/amd/display: Return drm_connector from find_first_crtc_matching_connector

2023-09-05 Thread Alex Hung

Reviewed-by: Alex Hung 

On 2023-08-16 15:26, Alex Hung wrote:

From: Harry Wentland 

[WHY]
We will be dealing with two types of connector: amdgpu_dm_connector
and drm_writeback_connector.

[HOW]
We want to find both and then cast to the appriopriate type afterwards.

Signed-off-by: Harry Wentland 
Signed-off-by: Alex Hung 
---
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 +---
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 2 +-
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c   | 4 +++-
  3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 363d91d49a3a..7bd3ec84ff2e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2630,7 +2630,7 @@ static int dm_suspend(void *handle)
return 0;
  }
  
-struct amdgpu_dm_connector *

+struct drm_connector *
  amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
 struct drm_crtc *crtc)
  {
@@ -2643,7 +2643,7 @@ amdgpu_dm_find_first_crtc_matching_connector(struct 
drm_atomic_state *state,
crtc_from_state = new_con_state->crtc;
  
  		if (crtc_from_state == crtc)

-   return to_amdgpu_dm_connector(connector);
+   return connector;
}
  
  	return NULL;

@@ -9263,6 +9263,7 @@ static int dm_update_crtc_state(struct 
amdgpu_display_manager *dm,
 * update changed items
 */
struct amdgpu_crtc *acrtc = NULL;
+   struct drm_connector *connector = NULL;
struct amdgpu_dm_connector *aconnector = NULL;
struct drm_connector_state *drm_new_conn_state = NULL, 
*drm_old_conn_state = NULL;
struct dm_connector_state *dm_new_conn_state = NULL, *dm_old_conn_state 
= NULL;
@@ -9272,7 +9273,8 @@ static int dm_update_crtc_state(struct 
amdgpu_display_manager *dm,
dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
acrtc = to_amdgpu_crtc(crtc);
-   aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
+   connector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
+   aconnector = to_amdgpu_dm_connector(connector);
  
  	/* TODO This hack should go away */

if (aconnector && enable) {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index a2d34be82613..5a8d07a27e9b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -836,7 +836,7 @@ struct dc_stream_state *
  int dm_atomic_get_state(struct drm_atomic_state *state,
struct dm_atomic_state **dm_state);
  
-struct amdgpu_dm_connector *

+struct drm_connector *
  amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
 struct drm_crtc *crtc);
  
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c

index 57230661132b..1975b9d96cb8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -1494,14 +1494,16 @@ int pre_validate_dsc(struct drm_atomic_state *state,
int ind = find_crtc_index_in_state_by_stream(state, stream);
  
  		if (ind >= 0) {

+   struct drm_connector *connector;
struct amdgpu_dm_connector *aconnector;
struct drm_connector_state *drm_new_conn_state;
struct dm_connector_state *dm_new_conn_state;
struct dm_crtc_state *dm_old_crtc_state;
  
-			aconnector =

+   connector =

amdgpu_dm_find_first_crtc_matching_connector(state,
 
state->crtcs[ind].ptr);
+   aconnector = to_amdgpu_dm_connector(connector);
drm_new_conn_state =
drm_atomic_get_new_connector_state(state,
   
>base);


Re: [PATCH 04/18] drm/amd/display: Skip writeback connector when we get amdgpu_dm_connector

2023-09-05 Thread Alex Hung

Reviewed-by: Alex Hung 

On 2023-08-16 15:26, Alex Hung wrote:

From: Harry Wentland 

[WHY]
Writeback connectors are based on a different object:
drm_writeback_connector, and are therefore different from
amdgpu_dm_connector. We need to be careful to ensure code
designed for amdgpu_dm_connector doesn't inadvertently try
to operate on a drm_writeback_connector.

[HOW]
Skip them when connector type is DRM_MODE_CONNECTOR_WRITEBACK.

Signed-off-by: Harry Wentland 
Signed-off-by: Alex Hung 
---
  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 62 +--
  .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c |  3 +
  .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 22 +--
  3 files changed, 76 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 445369afcead..363d91d49a3a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -721,6 +721,10 @@ static void dmub_hpd_callback(struct amdgpu_device *adev,
  
  	drm_connector_list_iter_begin(dev, );

drm_for_each_connector_iter(connector, ) {
+
+   if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+   continue;
+
aconnector = to_amdgpu_dm_connector(connector);
if (link && aconnector->dc_link == link) {
if (notify->type == DMUB_NOTIFICATION_HPD)
@@ -945,6 +949,10 @@ static int amdgpu_dm_audio_component_get_eld(struct device 
*kdev, int port,
  
  	drm_connector_list_iter_begin(dev, _iter);

drm_for_each_connector_iter(connector, _iter) {
+
+   if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+   continue;
+
aconnector = to_amdgpu_dm_connector(connector);
if (aconnector->audio_inst != port)
continue;
@@ -2270,6 +2278,10 @@ static int detect_mst_link_for_all_connectors(struct 
drm_device *dev)
  
  	drm_connector_list_iter_begin(dev, );

drm_for_each_connector_iter(connector, ) {
+
+   if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+   continue;
+
aconnector = to_amdgpu_dm_connector(connector);
if (aconnector->dc_link->type == dc_connection_mst_branch &&
aconnector->mst_mgr.aux) {
@@ -2350,6 +2362,10 @@ static void s3_handle_mst(struct drm_device *dev, bool 
suspend)
  
  	drm_connector_list_iter_begin(dev, );

drm_for_each_connector_iter(connector, ) {
+
+   if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+   continue;
+
aconnector = to_amdgpu_dm_connector(connector);
if (aconnector->dc_link->type != dc_connection_mst_branch ||
aconnector->mst_root)
@@ -2865,6 +2881,10 @@ static int dm_resume(void *handle)
/* Do detection*/
drm_connector_list_iter_begin(ddev, );
drm_for_each_connector_iter(connector, ) {
+
+   if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+   continue;
+
aconnector = to_amdgpu_dm_connector(connector);
  
  		if (!aconnector->dc_link)

@@ -3416,6 +3436,9 @@ static void register_hpd_handlers(struct amdgpu_device 
*adev)
list_for_each_entry(connector,
>mode_config.connector_list, head)  {
  
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)

+   continue;
+
aconnector = to_amdgpu_dm_connector(connector);
dc_link = aconnector->dc_link;
  
@@ -5413,10 +5436,13 @@ static void fill_stream_properties_from_drm_display_mode(

  {
struct dc_crtc_timing *timing_out = >timing;
const struct drm_display_info *info = >display_info;
-   struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
+   struct amdgpu_dm_connector *aconnector = NULL;
struct hdmi_vendor_infoframe hv_frame;
struct hdmi_avi_infoframe avi_frame;
  
+	if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)

+   aconnector = to_amdgpu_dm_connector(connector);
+
memset(_frame, 0, sizeof(hv_frame));
memset(_frame, 0, sizeof(avi_frame));
  
@@ -6843,6 +6869,9 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state,
  
  	for_each_new_connector_in_state(state, connector, new_con_state, i) {
  
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)

+   continue;
+
aconnector = to_amdgpu_dm_connector(connector);
  
  		if (!aconnector->mst_output_port)

@@ -8392,6 +8421,9 @@ static void amdgpu_dm_commit_audio(struct drm_device *dev,
if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
continue;
  
+		if 

Re: [PATCH 02/18] drm/amd/display: Create one virtual connector in DC

2023-09-05 Thread Alex Hung

Reviewed-by: Alex Hung 

On 2023-08-16 15:26, Alex Hung wrote:

From: Harry Wentland 

[WHAT]
Prepare a virtual connector for writeback.

Signed-off-by: Harry Wentland 
Signed-off-by: Alex Hung 
---
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 11 +--
  drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c |  3 ++-
  2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index b1245b732cc9..00254fdfa1f7 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1675,6 +1675,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
init_data.dcn_reg_offsets = adev->reg_offset[DCE_HWIP][0];
init_data.nbio_reg_offsets = adev->reg_offset[NBIO_HWIP][0];
  
+	/* Enable DWB for tested platforms only */

+   if (adev->ip_versions[DCE_HWIP][0] >= IP_VERSION(3, 0, 0))
+   init_data.num_virtual_links = 1;
+
INIT_LIST_HEAD(>dm.da_list);
  
  	retrieve_dmi_info(>dm);

@@ -4385,6 +4389,11 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
continue;
}
  
+		link = dc_get_link_at_index(dm->dc, i);

+
+   if (link->connector_signal == SIGNAL_TYPE_VIRTUAL)
+   continue;
+
aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
if (!aconnector)
goto fail;
@@ -4403,8 +4412,6 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
goto fail;
}
  
-		link = dc_get_link_at_index(dm->dc, i);

-
if (!dc_link_detect_connection_type(link, _connection_type))
DRM_ERROR("KMS: Failed to detect connector\n");
  
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c

index 2a7f47642a44..65e8504e6063 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
@@ -96,7 +96,8 @@ static void enable_memory_low_power(struct dc *dc)
if (dc->debug.enable_mem_low_power.bits.vpg && 
dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {
// Power down VPGs
for (i = 0; i < dc->res_pool->stream_enc_count; i++)
-   
dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
+   if (dc->res_pool->stream_enc[i]->vpg)
+   
dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);
  #if defined(CONFIG_DRM_AMD_DC_FP)
for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)

dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);


Re: [PATCH 01/18] drm/amd/display: Skip entire amdgpu_dm build if !CONFIG_DRM_AMD_DC

2023-09-05 Thread Alex Hung

Reviewed-by: Alex Hung 

On 2023-08-16 15:26, Alex Hung wrote:

From: Harry Wentland 

[WHY]
Previously this only excluded build for a few amdgpu_dm
binaries which makes no sense.

[HOW]
Wrap the entire Makefile in "ifneq ($(CONFIG_DRM_AMD_DC),)"

Signed-off-by: Harry Wentland 
Signed-off-by: Alex Hung 
---
  drivers/gpu/drm/amd/display/amdgpu_dm/Makefile | 13 -
  1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile 
b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
index 8bf94920d23e..063205ecb137 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile
@@ -25,22 +25,24 @@
  
  
  
+ifneq ($(CONFIG_DRM_AMD_DC),)

  AMDGPUDM = \
amdgpu_dm.o \
amdgpu_dm_plane.o \
amdgpu_dm_crtc.o \
amdgpu_dm_irq.o \
amdgpu_dm_mst_types.o \
-   amdgpu_dm_color.o
+   amdgpu_dm_color.o \
+   amdgpu_dm_services.o \
+   amdgpu_dm_helpers.o \
+   amdgpu_dm_pp_smu.o \
+   amdgpu_dm_psr.o \
+   amdgpu_dm_replay.o
  
  ifdef CONFIG_DRM_AMD_DC_FP

  AMDGPUDM += dc_fpu.o
  endif
  
-ifneq ($(CONFIG_DRM_AMD_DC),)

-AMDGPUDM += amdgpu_dm_services.o amdgpu_dm_helpers.o amdgpu_dm_pp_smu.o 
amdgpu_dm_psr.o amdgpu_dm_replay.o
-endif
-
  AMDGPUDM += amdgpu_dm_hdcp.o
  
  ifneq ($(CONFIG_DEBUG_FS),)

@@ -52,3 +54,4 @@ subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/dc
  AMDGPU_DM = $(addprefix $(AMDDALPATH)/amdgpu_dm/,$(AMDGPUDM))
  
  AMD_DISPLAY_FILES += $(AMDGPU_DM)

+endif


Re: [PATCH -next 5/5] drm/amd/display: clean up one inconsistent indenting

2023-09-05 Thread Alex Deucher
Applied the series.  Thanks!

Alex

On Thu, Aug 31, 2023 at 9:29 PM Yang Li  wrote:
>
> drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn35/dcn35_fpu.c:260 
> dcn35_update_bw_bounding_box_fpu() warn: inconsistent indenting
>
> Signed-off-by: Yang Li 
> ---
>  drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c 
> b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
> index 525ca0ed9ea9..46eb2d0592f3 100644
> --- a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
> +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
> @@ -348,8 +348,8 @@ void dcn35_update_bw_bounding_box_fpu(struct dc *dc,
> dc->debug.dram_clock_change_latency_ns / 1000.0;
> }
> /*temp till dml2 fully work without dml1*/
> -   dml_init_instance(>dml, _5_soc, _5_ip,
> - DML_PROJECT_DCN31);
> +   dml_init_instance(>dml, _5_soc, _5_ip,
> +   DML_PROJECT_DCN31);
>  }
>
>  static bool is_dual_plane(enum surface_pixel_format format)
> --
> 2.20.1.7.g153144c
>


Re: [PATCH -next 4/4] drm/amd/display: Remove duplicated include in dcn35_clk_mgr.c

2023-09-05 Thread Alex Deucher
Applied.  Thanks!

On Thu, Aug 31, 2023 at 8:52 PM Yang Li  wrote:
>
> ./drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c: 
> dcn35_clk_mgr.h is included more than once.
>
> Signed-off-by: Yang Li 
> ---
>  drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c 
> b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
> index 3b2463c03694..9314e75195cd 100644
> --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
> +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
> @@ -46,7 +46,6 @@
>  /* TODO: remove this include once we ported over remaining clk mgr 
> functions*/
>  #include "dcn30/dcn30_clk_mgr.h"
>  #include "dcn31/dcn31_clk_mgr.h"
> -#include "dcn35_clk_mgr.h"
>
>  #include "dc_dmub_srv.h"
>  #include "link.h"
> --
> 2.20.1.7.g153144c
>


Re: [PATCH -next 3/4] drm/amd/display: Remove duplicated include in dcn35_hwseq.c

2023-09-05 Thread Alex Deucher
Applied.  Thanks!

On Thu, Aug 31, 2023 at 8:52 PM Yang Li  wrote:
>
> ./drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.c: clk_mgr.h is included 
> more than once.
>
> Signed-off-by: Yang Li 
> ---
>  drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.c 
> b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.c
> index cacb557a3014..666e2809d9dc 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.c
> @@ -31,7 +31,6 @@
>  #include "clk_mgr.h"
>  #include "reg_helper.h"
>  #include "abm.h"
> -#include "clk_mgr.h"
>  #include "hubp.h"
>  #include "dchubbub.h"
>  #include "timing_generator.h"
> --
> 2.20.1.7.g153144c
>


Re: [PATCH -next 2/4] drm/amd/display: Remove duplicated include in dcn35_optc.c

2023-09-05 Thread Alex Deucher
Applied.  Thanks!

On Thu, Aug 31, 2023 at 8:52 PM Yang Li  wrote:
>
> ./drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c: dcn35_optc.h is included 
> more than once.
>
> Signed-off-by: Yang Li 
> ---
>  drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c 
> b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
> index d64be1a5071c..2bea1e475096 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
> @@ -23,7 +23,6 @@
>   */
>
>  #include "dcn35_optc.h"
> -#include "dcn35_optc.h"
>
>  #include "dcn30/dcn30_optc.h"
>  #include "dcn31/dcn31_optc.h"
> --
> 2.20.1.7.g153144c
>


Re: [PATCH -next 1/4] drm/amd/display: Remove duplicated include in dcn35_resource.c

2023-09-05 Thread Alex Deucher
Applied.  Thanks!

On Thu, Aug 31, 2023 at 8:52 PM Yang Li  wrote:
>
> ./drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c: 
> dcn31/dcn31_dio_link_encoder.h is included more than once.
>
> Signed-off-by: Yang Li 
> ---
>  drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c 
> b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c
> index 0386b8fb270d..7f059fc2fc75 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c
> @@ -61,7 +61,6 @@
>  #include "dcn32/dcn32_hpo_dp_link_encoder.h"
>  #include "link.h"
>  #include "dcn31/dcn31_apg.h"
> -#include "dcn31/dcn31_dio_link_encoder.h"
>  #include "dcn32/dcn32_dio_link_encoder.h"
>  #include "dcn31/dcn31_vpg.h"
>  #include "dcn31/dcn31_afmt.h"
> --
> 2.20.1.7.g153144c
>


Re: [RFC,drm-misc-next v4 3/9] drm/radeon: Implement .be_primary() callback

2023-09-05 Thread suijingfeng

Hi,


On 2023/9/5 13:50, Christian König wrote:

Am 04.09.23 um 21:57 schrieb Sui Jingfeng:

From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over 
which one

is primary at boot time.


Question is why is that useful? Should we give users the ability to 
control that?


I don't see an use case for this.



On a specific machine with multiple GPUs mounted, only the
primary graphics get POST-ed (initialized) by the firmware.
Therefore the DRM drivers for the rest video cards have to
work without the prerequisite setups done by firmware, This
is called as POST.

One of the use cases is to test if a specific DRM driver
would works properly, under the circumstance of not being
POST-ed, The ast drm driver is the first one which refused
to work if not being POST-ed by the firmware.

Before apply this series, I was unable make drm/ast as the
primary video card easily. The problem is that on a multiple
video card configuration, the monitor connected with my
AST2400 card not light up. While confusing, a naive programmer
may suspect the PRIME is not working.

After applied this series and passing ast.modeset=10 on the
kernel cmd line, I found that the monitor connected with my
ast2400 video card still black, It doesn't display and It
doesn't show image to me.

While in the process of study drm/ast, I know that drm/ast
driver has the POST code shipped, See the ast_post_gpu() function.
Then, I was wondering why this function doesn't works.

After a short-time (hasty) debugging, I found that the ast_post_gpu()
function didn't get run. Because it have something to do with the
ast->config_mode. Without thinking too much, I hardcoded the
ast->config_mode as ast_use_p2a, the key point is to force the
ast_post_gpu() function to run.


```

--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -132,6 +132,8 @@ static int ast_device_config_init(struct ast_device 
*ast)

    }
    }

+   ast->config_mode = ast_use_p2a;
+
    switch (ast->config_mode) {
    case ast_use_defaults:
    drm_info(dev, "Using default configuration\n");

```

Then, the monitor light up, it display the Ubuntu greeter to me. Therefore
my patch is useful, at least for the Linux drm driver tester and developer.
It allow programmers to test the specific part of a specific driver without
changing a line of the source code and without the need of sudo authority.

It improves the efficiency of the testing and patch verification. I know
the PrimaryGPU option of Xorg conf, but this approach will remember the
setup have been made, you need modify it with root authority each time
you want to switch the primary. But on the process of rapid developing
and/or testing for multiple video drivers, with only one computer hardware
resource available. What we really want is a one-shot command, as provided
by this series.  So, this is the first use case.


The second use case is that sometime the firmware is not reliable.
While there are thousands of ARM64, PowerPC and Mips servers machine,
Most of them don't have a good UEFI firmware support. I haven't test the
drm/amdgpu and drm/radeon at my ARM64 server yet. Because this ARM64
server always use the platform(BMC) integrated display controller as primary.
The UEFI firmware of it does not provide options menu to tune.
So, for the first time, the discrete card because useless, despite more 
powerful.
I will take time to carry on the testing, so I will be able to tell more
in the future.


Even on X86, when select the PEG as primary on the UEFI BIOS menu.
There is no way to tell the bios which one of my three
discrete video be the primary. Not to mention some old UEFI
firmware, which doesn't provide a setting at all.
While the benefit of my approach is the flexibility.
Yes the i915, amdgpu and radeon are good quality,
but there may have programmers want to try nouveau.


The third use case is that VGAARB is also not reliable, It will
select a wrong device as primary. Especially on Arm64, Loongarch
and mips arch etc. And the X server will use this wrong device
as primary and completely crash there. Either because of lacking
a driver or the driver has a bug which can not bear the graphic
environment up. VGAARB is firmware dependent.
My patch provide a temporary method to rescue.


The forth is probably the PRIME and reverse PRIME development
and developing driver for new video cards.



Re: [PATCH] drm/amdgpu: clean up some inconsistent indenting

2023-09-05 Thread Alex Deucher
Applied and dropped the printk.

Alex

On Fri, Sep 1, 2023 at 3:40 AM Christian König  wrote:
>
> Am 01.09.23 um 09:02 schrieb Jiapeng Chong:
> > No functional modification involved.
> >
> > drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c:34 nbio_v7_11_get_rev_id() warn: 
> > inconsistent indenting.
>
>
> We should probably not have a printk here in the first place.
>
> Christian.
>
> >
> > Reported-by: Abaci Robot 
> > Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=6316
> > Signed-off-by: Jiapeng Chong 
> > ---
> >   drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c | 5 ++---
> >   1 file changed, 2 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c 
> > b/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c
> > index 7c08e5f95e97..76e21357dd4d 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c
> > @@ -31,10 +31,9 @@
> >   static u32 nbio_v7_11_get_rev_id(struct amdgpu_device *adev)
> >   {
> >   u32 tmp;
> > - printk("%s, getid\n",__func__);
> > -
> > - tmp = RREG32_SOC15(NBIO, 0, 
> > regRCC_STRAP1_RCC_DEV0_EPF0_STRAP0);
> >
> > + printk("%s, getid\n", __func__);
> > + tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP1_RCC_DEV0_EPF0_STRAP0);
> >   tmp &= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK;
> >   tmp >>= 
> > RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT;
> >
>


[PATCH] drm/amd/display: Remove unwanted drm edid references

2023-09-05 Thread Alex Hung
[WHY]
edid_override and drm_edid_override_connector_update, according to drm
documentation, should not be referred outside drm_edid.

[HOW]
Remove and replace them accordingly.

Signed-off-by: Alex Hung 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 ++-
 1 file changed, 2 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 1bb1a394f55f..f6a255773242 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6372,15 +6372,12 @@ amdgpu_dm_connector_late_register(struct drm_connector 
*connector)
 static void amdgpu_dm_connector_funcs_force(struct drm_connector *connector)
 {
struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
+   struct amdgpu_connector *amdgpu_connector = 
to_amdgpu_connector(connector);
struct dc_link *dc_link = aconnector->dc_link;
struct dc_sink *dc_em_sink = aconnector->dc_em_sink;
struct edid *edid;
 
-   if (!connector->edid_override)
-   return;
-
-   drm_edid_override_connector_update(>base);
-   edid = aconnector->base.edid_blob_ptr->data;
+   edid = drm_get_edid(connector, _connector->ddc_bus->aux.ddc);
aconnector->edid = edid;
 
/* Update emulated (virtual) sink's EDID */
@@ -6421,22 +6418,6 @@ static void create_eml_sink(struct amdgpu_dm_connector 
*aconnector)
};
struct edid *edid;
 
-   if (!aconnector->base.edid_blob_ptr) {
-   /* if connector->edid_override valid, pass
-* it to edid_override to edid_blob_ptr
-*/
-
-   drm_edid_override_connector_update(>base);
-
-   if (!aconnector->base.edid_blob_ptr) {
-   DRM_ERROR("No EDID firmware found on connector: %s 
,forcing to OFF!\n",
-   aconnector->base.name);
-
-   aconnector->base.force = DRM_FORCE_OFF;
-   return;
-   }
-   }
-
edid = (struct edid *) aconnector->base.edid_blob_ptr->data;
 
aconnector->edid = edid;
-- 
2.42.0



Re: [PATCH] drm/amdgpu: Handle null atom context in VBIOS info ioctl

2023-09-05 Thread Alex Deucher
On Tue, Sep 5, 2023 at 12:15 PM Francis, David  wrote:
>
> [AMD Official Use Only - General]
>
>
> [AMD Official Use Only - General]
>
> Yeah we've had JIRAs (e.g. 
> https://ontrack-internal.amd.com/browse/SWDEV-409711 ) raised that ASAN can't 
> compile the thunk due to using = {0} . Using memset is definitely preferred 
> to save trouble later.
>
>  Kent
>
> This is kernel code, not thunk. {} and {0} are extensively used throughout
> the kernel in general and our driver in particular, so I don't see this 
> causing problems.

Speaking for the kernel, we've seen problematic behavior when using {}
vs {0} vs memset.  memset always seems to do the right thing, the
others don't.  E.g., there was a series of patch sets to switch
everything from {} to {0} or vice versa, we just traded one issue for
another.  For this patch, you can probably just drop that hunk as I
don't see a need to change it.  Whether you switch to memset or not is
up to you.

Alex


>
>  David
>
> -Original Message-
> From: amd-gfx  On Behalf Of Alex
> Deucher
> Sent: Tuesday, September 5, 2023 10:53 AM
> To: Francis, David 
> Cc: amd-gfx@lists.freedesktop.org
> Subject: Re: [PATCH] drm/amdgpu: Handle null atom context in VBIOS info ioctl
>
> On Tue, Sep 5, 2023 at 10:50 AM David Francis  wrote:
>
> On some APU systems, there is no atom context and so the
> atom_context struct is null.
>
> Add a check to the VBIOS_INFO branch of amdgpu_info_ioctl
> to handle this case, returning all zeroes.
>
> Signed-off-by: David Francis 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 19 ---
>  1 file changed, 12 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>
> index 3a48bec10aea..86748290ead7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -947,16 +947,21 @@ int amdgpu_info_ioctl(struct drm_device *dev, void
>
> *data, struct drm_file *filp)
>
> ? -EFAULT : 0;
> }
> case AMDGPU_INFO_VBIOS_INFO: {
> -   struct drm_amdgpu_info_vbios vbios_info = {};
> +   struct drm_amdgpu_info_vbios vbios_info = {0};
>
> IIRC, these should be equivalent.  That said, I believe memset is
> generally preferred as not all compilers seem to handle these cases
> correctly.
>
> Alex
>
> struct atom_context *atom_context;
>
> atom_context = adev->mode_info.atom_context;
> -   memcpy(vbios_info.name, atom_context->name,
>
> sizeof(atom_context->name));
>
> -   memcpy(vbios_info.vbios_pn, atom_context->vbios_pn,
>
> sizeof(atom_context->vbios_pn));
>
> -   vbios_info.version = atom_context->version;
> -   memcpy(vbios_info.vbios_ver_str, 
> atom_context->vbios_ver_str,
> -   
> sizeof(atom_context->vbios_ver_str));
> -   memcpy(vbios_info.date, atom_context->date,
>
> sizeof(atom_context->date));
>
> +   if (atom_context) {
> +   memcpy(vbios_info.name, atom_context->name,
> +  sizeof(atom_context->name));
> +   memcpy(vbios_info.vbios_pn, 
> atom_context->vbios_pn,
> +  sizeof(atom_context->vbios_pn));
> +   vbios_info.version = atom_context->version;
> +   memcpy(vbios_info.vbios_ver_str, atom_context-
> vbios_ver_str,
> +  sizeof(atom_context->vbios_ver_str));
> +   memcpy(vbios_info.date, atom_context->date,
> +  sizeof(atom_context->date));
> +   }
>
> return copy_to_user(out, _info,
> min((size_t)size, 
> sizeof(vbios_info))) ? -EFAULT : 0;
> --
> 2.34.1
>


Re: [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Alex Williamson
On Wed, 6 Sep 2023 00:21:09 +0800
suijingfeng  wrote:

> Hi,
> 
> On 2023/9/5 22:52, Alex Williamson wrote:
> > On Tue,  5 Sep 2023 03:57:15 +0800
> > Sui Jingfeng  wrote:
> >  
> >> From: Sui Jingfeng 
> >>
> >> On a machine with multiple GPUs, a Linux user has no control over which
> >> one is primary at boot time. This series tries to solve above mentioned
> >> problem by introduced the ->be_primary() function stub. The specific
> >> device drivers can provide an implementation to hook up with this stub by
> >> calling the vga_client_register() function.
> >>
> >> Once the driver bound the device successfully, VGAARB will call back to
> >> the device driver. To query if the device drivers want to be primary or
> >> not. Device drivers can just pass NULL if have no such needs.
> >>
> >> Please note that:
> >>
> >> 1) The ARM64, Loongarch, Mips servers have a lot PCIe slot, and I would
> >> like to mount at least three video cards.
> >>
> >> 2) Typically, those non-86 machines don't have a good UEFI firmware
> >> support, which doesn't support select primary GPU as firmware stage.
> >> Even on x86, there are old UEFI firmwares which already made undesired
> >> decision for you.
> >>
> >> 3) This series is attempt to solve the remain problems at the driver level,
> >> while another series[1] of me is target to solve the majority of the
> >> problems at device level.
> >>
> >> Tested (limited) on x86 with four video card mounted, Intel UHD Graphics
> >> 630 is the default boot VGA, successfully override by ast2400 with
> >> ast.modeset=10 append at the kernel cmd line.
> >>
> >> $ lspci | grep VGA
> >>
> >>   00:02.0 VGA compatible controller: Intel Corporation CoffeeLake-S GT2 
> >> [UHD Graphics 630]  
> > In all my previous experiments with VGA routing and IGD I found that
> > IGD can't actually release VGA routing and Intel confirmed the hardware
> > doesn't have the ability to do so.  It will always be primary from a
> > VGA routing perspective.  Was this actually tested with non-UEFI?  
> 
> Yes, I have tested on my aspire e471 notebook (i5 5200U),
> because that notebook using legacy firmware (also have UEFI, double firmware).
> But this machine have difficult in install ubuntu under UEFI firmware in the 
> past.
> So I keep it using the legacy firmware.
> 
> It have two video card, IGD and nvidia video card(GFORCE 840M).
> nvidia call its video card as 3D controller (pci->class = 0x030200)
> 
> I have tested this patch and another patch mention at [1] together.
> I can tell you that the firmware framebuffer of this notebook using vesafb, 
> not efifb.
> And the framebuffer size (lfb.size) is very small. This is very strange,
> but I don't have enough time to look in details. But still works.
> 
> I'm using and tesing my patch whenever and wherever possible.

So you're testing VGA routing using a non-VGA 3D controller through the
VESA address space?  How does that test anything about VGA routing?

> > I suspect it might only work in UEFI mode where we probably don't
> > actually have a dependency on VGA routing.  This is essentially why
> > vfio requires UEFI ROMs when assigning GPUs to VMs, VGA routing is too
> > broken to use on Intel systems with IGD.  Thanks,  
> 
> 
> What you tell me here is the side effect come with the VGA-compatible,
> but I'm focus on the arbitration itself. I think there no need to keep
> the VGA routing hardware features nowadays except that hardware vendor
> want keep the backward compatibility and/or comply the PCI VGA compatible 
> spec.

"VGA arbitration" is the mediation of VGA routing between devices, so
I'm confused how you can be focused on the arbitration without the
routing itself.  Thanks,

Alex



RE: [PATCH] drm/amdgpu: Handle null atom context in VBIOS info ioctl

2023-09-05 Thread Russell, Kent
[AMD Official Use Only - General]

Sorry, meant to keep the JIRA part internal. As it stands, the amd/ folder 
alone has 458 {0}s (plus 55 {}s), and 741 memset-to-0s. So I guess it’s a 
matter of whether or not we’ll start enforcing memsets vs {0} in the near 
future. If we intend to switch over soon anyways, we may as well start using 
memset now and in all future patches.

Kent

From: Francis, David 
Sent: Tuesday, September 5, 2023 11:38 AM
To: Russell, Kent ; amd-gfx@lists.freedesktop.org
Subject: Re: [PATCH] drm/amdgpu: Handle null atom context in VBIOS info ioctl


[AMD Official Use Only - General]


[AMD Official Use Only - General]



Yeah we've had JIRAs (e.g. https://ontrack-internal.amd.com/browse/SWDEV-409711 
) raised that ASAN can't compile the thunk due to using = {0} . Using memset is 
definitely preferred to save trouble later.



 Kent

This is kernel code, not thunk. {} and {0} are extensively used throughout

the kernel in general and our driver in particular, so I don't see this causing 
problems.



 David

-Original Message-

From: amd-gfx 

 On Behalf Of Alex

Deucher

Sent: Tuesday, September 5, 2023 10:53 AM

To: Francis, David 

Cc: amd-gfx@lists.freedesktop.org

Subject: Re: [PATCH] drm/amdgpu: Handle null atom context in VBIOS info ioctl



On Tue, Sep 5, 2023 at 10:50 AM David Francis 
 wrote:

On some APU systems, there is no atom context and so the

atom_context struct is null.



Add a check to the VBIOS_INFO branch of amdgpu_info_ioctl

to handle this case, returning all zeroes.



Signed-off-by: David Francis 


---

 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 19 ---

 1 file changed, 12 insertions(+), 7 deletions(-)



diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

index 3a48bec10aea..86748290ead7 100644

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

@@ -947,16 +947,21 @@ int amdgpu_info_ioctl(struct drm_device *dev, void

*data, struct drm_file *filp)

? -EFAULT : 0;

}

case AMDGPU_INFO_VBIOS_INFO: {

-   struct drm_amdgpu_info_vbios vbios_info = {};

+   struct drm_amdgpu_info_vbios vbios_info = {0};

IIRC, these should be equivalent.  That said, I believe memset is

generally preferred as not all compilers seem to handle these cases

correctly.



Alex



struct atom_context *atom_context;



atom_context = adev->mode_info.atom_context;

-   memcpy(vbios_info.name, atom_context->name,

sizeof(atom_context->name));

-   memcpy(vbios_info.vbios_pn, atom_context->vbios_pn,

sizeof(atom_context->vbios_pn));

-   vbios_info.version = atom_context->version;

-   memcpy(vbios_info.vbios_ver_str, 
atom_context->vbios_ver_str,

-   
sizeof(atom_context->vbios_ver_str));

-   memcpy(vbios_info.date, atom_context->date,

sizeof(atom_context->date));

+   if (atom_context) {

+   memcpy(vbios_info.name, atom_context->name,

+  sizeof(atom_context->name));

+   memcpy(vbios_info.vbios_pn, 
atom_context->vbios_pn,

+  sizeof(atom_context->vbios_pn));

+   vbios_info.version = atom_context->version;

+   memcpy(vbios_info.vbios_ver_str, atom_context-

vbios_ver_str,

+  sizeof(atom_context->vbios_ver_str));

+   memcpy(vbios_info.date, atom_context->date,

+  sizeof(atom_context->date));

+   }



return copy_to_user(out, _info,

min((size_t)size, 
sizeof(vbios_info))) ? -EFAULT : 0;

--

2.34.1




Re: [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread suijingfeng

Hi,

On 2023/9/5 22:52, Alex Williamson wrote:

On Tue,  5 Sep 2023 03:57:15 +0800
Sui Jingfeng  wrote:


From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned
problem by introduced the ->be_primary() function stub. The specific
device drivers can provide an implementation to hook up with this stub by
calling the vga_client_register() function.

Once the driver bound the device successfully, VGAARB will call back to
the device driver. To query if the device drivers want to be primary or
not. Device drivers can just pass NULL if have no such needs.

Please note that:

1) The ARM64, Loongarch, Mips servers have a lot PCIe slot, and I would
like to mount at least three video cards.

2) Typically, those non-86 machines don't have a good UEFI firmware
support, which doesn't support select primary GPU as firmware stage.
Even on x86, there are old UEFI firmwares which already made undesired
decision for you.

3) This series is attempt to solve the remain problems at the driver level,
while another series[1] of me is target to solve the majority of the
problems at device level.

Tested (limited) on x86 with four video card mounted, Intel UHD Graphics
630 is the default boot VGA, successfully override by ast2400 with
ast.modeset=10 append at the kernel cmd line.

$ lspci | grep VGA

  00:02.0 VGA compatible controller: Intel Corporation CoffeeLake-S GT2 [UHD 
Graphics 630]

In all my previous experiments with VGA routing and IGD I found that
IGD can't actually release VGA routing and Intel confirmed the hardware
doesn't have the ability to do so.  It will always be primary from a
VGA routing perspective.  Was this actually tested with non-UEFI?


Yes, I have tested on my aspire e471 notebook (i5 5200U),
because that notebook using legacy firmware (also have UEFI, double firmware).
But this machine have difficult in install ubuntu under UEFI firmware in the 
past.
So I keep it using the legacy firmware.

It have two video card, IGD and nvidia video card(GFORCE 840M).
nvidia call its video card as 3D controller (pci->class = 0x030200)

I have tested this patch and another patch mention at [1] together.
I can tell you that the firmware framebuffer of this notebook using vesafb, not 
efifb.
And the framebuffer size (lfb.size) is very small. This is very strange,
but I don't have enough time to look in details. But still works.

I'm using and tesing my patch whenever and wherever possible.


I suspect it might only work in UEFI mode where we probably don't
actually have a dependency on VGA routing.  This is essentially why
vfio requires UEFI ROMs when assigning GPUs to VMs, VGA routing is too
broken to use on Intel systems with IGD.  Thanks,



What you tell me here is the side effect come with the VGA-compatible,
but I'm focus on the arbitration itself. I think there no need to keep
the VGA routing hardware features nowadays except that hardware vendor
want keep the backward compatibility and/or comply the PCI VGA compatible spec.



Alex





Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread suijingfeng



On 2023/9/5 18:49, Thomas Zimmermann wrote:

Hi

Am 04.09.23 um 21:57 schrieb Sui Jingfeng:

From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned
problem by introduced the ->be_primary() function stub. The specific
device drivers can provide an implementation to hook up with this 
stub by

calling the vga_client_register() function.

Once the driver bound the device successfully, VGAARB will call back to
the device driver. To query if the device drivers want to be primary or
not. Device drivers can just pass NULL if have no such needs.

Please note that:

1) The ARM64, Loongarch, Mips servers have a lot PCIe slot, and I would
    like to mount at least three video cards.

2) Typically, those non-86 machines don't have a good UEFI firmware
    support, which doesn't support select primary GPU as firmware stage.
    Even on x86, there are old UEFI firmwares which already made 
undesired

    decision for you.

3) This series is attempt to solve the remain problems at the driver 
level,

    while another series[1] of me is target to solve the majority of the
    problems at device level.

Tested (limited) on x86 with four video card mounted, Intel UHD Graphics
630 is the default boot VGA, successfully override by ast2400 with
ast.modeset=10 append at the kernel cmd line.


FYI: per-driver modeset parameters are deprecated and not to be used. 
Please don't promote them.



Well, please wait, I want to explain.



drm/nouveau already promote it a little bit.

Despite no code of conduct or specification guiding how the modules parameters 
should be.
Noticed that there already have a lot of DRM drivers support the modeset 
parameters,
for the modeset parameter, authors of various device driver try to make the 
usage not
conflict with others. I believe that this is good thing for Linux users.
It is probably the responsibility of the drm core maintainers to force various 
drm
drivers to reach a minimal consensus. Probably it pains to do so and doesn't 
pay off.
But reach a minimal consensus do benefit to Linux users.


You can use modprobe.blacklist or initcall_blacklist on the kernel 
command line.



There are some cases where the modprobe.blacklist doesn't works,
I have come cross several time during the past.
Because the device selected by the VGAARB is device-level thing,
it is not the driver's problem.

Sometimes when VGAARB has a bug, it will select a wrong device as primary.
And the X server will use this wrong device as primary and completely crash
there, due to lack a driver. Take my old S3 Graphics as an example:

$ lspci | grep VGA

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

Before apply this patch:

[0.361748] pci :00:06.1: vgaarb: setting as boot VGA device
[0.361753] pci :00:06.1: vgaarb: VGA device added: 
decodes=io+mem,owns=io+mem,locks=none
[0.361765] pci :03:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
[0.361773] pci :07:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
[0.361779] pci :08:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
[0.361781] vgaarb: loaded
[0.367838] pci :00:06.1: Overriding boot device as 1002:6778
[0.367841] pci :00:06.1: Overriding boot device as 5333:9070
[0.367843] pci :00:06.1: Overriding boot device as 5333:9070


For known reason, one of my system select the S3 Graphics as primary GPU.
But this S3 Graphics not even have a decent drm upstream driver yet.
Under such a case, I begin to believe that only the device who has a
driver deserve the primary.

Under such a condition, I want to reboot and enter the graphic environment
with other working video cards. Either platform integrated and discrete GPU.
This don't means I should compromise by un-mount the S3 graphics card from
the motherboard, this also don't means that I should update my BIOS setting.
As sometimes, the BIOS is more worse.

With this series applied, all I need to do is to reboot the computer and
pass a command line. By force override another video card (who has a
decent driver support) as primary, I'm able to do the debugging under
graphic environment. I would like to examine what's wrong with the vgaarb
on a specific platform under X server graphic environment.

Probably try compile a driver for this card and see it works, simply reboot
without the need to change anything. It is so efficient. So this is probably
the second usage of my patch. It hand the right of control back to the
graphic developer.




Re: [RFC PATCH 0/5] drm/amd/display: improve DTN color state log

2023-09-05 Thread Melissa Wen
On 09/05, Melissa Wen wrote:
> Hi,
> 
> I'm updating the color state part of DTN log to match DCN3.0 HW better.
> Currently, the DTN log considers the DCN10 color pipeline, which is
> useless for DCN3.0 because of all the differences in color caps between
> DCN versions. In addition to new color blocks and caps, some semantic
> differences made the DCN10 output not fit DCN30.
> 
> In this RFC, the first patch adds new color state elements to DPP and
> implements the reading of registers according to HW blocks. Similarly to
> MPC, the second patch also creates a DCN3-specific function to read the
> MPC state and add the MPC color state logging to it. With DPP and MPC
> color-register reading, I detach DCN10 color state logging from the HW
> log and create a `.log_color_state` hook for logging color state
> according to HW color blocks with DCN30 as the first use case. Finally,
> the last patch adds DPP and MPC color caps output to facilitate
> understanding of the color state log.
> 
> This version works well with the driver-specific color properties[1] and
> steamdeck/gamescope[2] together, where we can see color state changing
> from default values.

For comparison, here is the before and after of DPP and MPC section in
the DTN log on Steam Deck + driver-specific color properties:

Without this series:
===
DPP:IGAM format  IGAM modeDGAM modeRGAM mode  GAMUT mode  C11 C12   
C13 C14   C21 C22   C23 C24   C31 C32   C33 C34
[ 0]:0h  BypassFixed  Bypass   Bypass0h 
h h h h h
[ 3]:0h  BypassFixed  Bypass   Bypass0h 
h h h h h

MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  OVERLAP_ONLY  IDLE
[ 0]:   0h   0h   3h 3   20 0 0
[ 3]:   0h   3h   fh 2   20 0 0


With this series (Steamdeck/Gamescope):
==

DPP:  DGAM ROM  DGAM ROM type  DGAM LUT  SHAPER mode  3DLUT mode  3DLUT bit 
depth  3DLUT size  RGAM mode  GAMUT mode  C11 C12   C13 C14   C21 C22   C23 C24 
  C31 C32   C33 C34
[ 0]:1   sRGBBypassRAM B   RAM A   
12-bit17x17x17 Bypass   0  h h h 
h h h
[ 3]:1   sRGBBypassRAM B   RAM A   
12-bit17x17x17 Bypass   0  h h h 
h h h

DPP Color Caps: input_lut_shared:0  icsc:1  dgam_ram:0  dgam_rom: 
srgb:1,bt2020:1,gamma2_2:1,pq:1,hlg:1  post_csc:1  gamcor:1  dgam_rom_for_yuv:0 
 3d_lut:1  blnd_lut:1  oscs:0

MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  OVERLAP_ONLY  IDLE  SHAPER 
mode  3DLUT_mode  3DLUT bit-depth  3DLUT size  OGAM mode  OGAM LUT  GAMUT mode  
C11 C12   C33 C34
[ 0]:   0h   0h   3h 3   20 0 0   
Bypass  Bypass   12-bit17x17x17 Bypass A   
0 h h
[ 3]:   0h   3h   fh 2   20 0 0   
Bypass  Bypass   12-bit17x17x17 Bypass A   
0 h h

MPC Color Caps: gamut_remap:1, 3dlut:2, ogam_ram:1, ocsc:1

With this series (Steamdeck/KDE):


DPP:  DGAM ROM  DGAM ROM type  DGAM LUT  SHAPER mode  3DLUT mode  3DLUT bit 
depth  3DLUT size  RGAM mode  GAMUT mode  C11 C12   C13 C14   C21 C22   C23 C24 
  C31 C32   C33 C34
[ 0]:0   sRGBBypass   Bypass  Bypass   
12-bit   9x9x9 Bypass   0  h h h 
h h h
[ 3]:0   sRGBBypass   Bypass  Bypass   
12-bit   9x9x9 Bypass   0  h h h 
h h h

DPP Color Caps: input_lut_shared:0  icsc:1  dgam_ram:0  dgam_rom: 
srgb:1,bt2020:1,gamma2_2:1,pq:1,hlg:1  post_csc:1  gamcor:1  dgam_rom_for_yuv:0 
 3d_lut:1  blnd_lut:1  oscs:0

MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  OVERLAP_ONLY  IDLE  SHAPER 
mode  3DLUT_mode  3DLUT bit-depth  3DLUT size  OGAM mode  OGAM LUT  GAMUT mode  
C11 C12   C33 C34
[ 0]:   0h   0h   3h 3   20 0 0   
Bypass  Bypass   12-bit17x17x17RAM A   
1 2000h 2000h
[ 3]:   0h   3h   fh 2   20 0 0   
Bypass  Bypass   12-bit17x17x17 Bypass A   
0 h h

MPC Color Caps: gamut_remap:1, 3dlut:2, ogam_ram:1, ocsc:1

> 
> Before extending it to other DCN families, I have some doubts. Does this
> approach of the `.log_color_state` hook make sense for you? Is there any
> conflict between logging color state by HW version and DTN log usage? Is
> there a template/style 

Re: [PATCH] drm/amdgpu: fix incompatible types in conditional expression

2023-09-05 Thread Alex Deucher
On Mon, Sep 4, 2023 at 1:00 AM Lang Yu  wrote:
>
> Fixes: ab041551f4a7 ("drm/amdgpu: add VPE 6.1.0 support")
>
> Signed-off-by: Lang Yu 
> Reported-by: kernel test robot 
> Link: 
> https://lore.kernel.org/oe-kbuild-all/202309020608.fwp8qmht-...@intel.com

Reviewed-by: Alex Deucher 

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h | 2 +-
>  drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c   | 4 +++-
>  2 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h
> index b590205d6a28..29d56f7ae4a9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h
> @@ -31,7 +31,7 @@ struct amdgpu_vpe;
>
>  struct vpe_funcs {
> uint32_t (*get_reg_offset)(struct amdgpu_vpe *vpe, uint32_t inst, 
> uint32_t offset);
> -   void (*set_regs)(struct amdgpu_vpe *vpe);
> +   int (*set_regs)(struct amdgpu_vpe *vpe);
> int (*irq_init)(struct amdgpu_vpe *vpe);
> int (*init_microcode)(struct amdgpu_vpe *vpe);
> int (*load_microcode)(struct amdgpu_vpe *vpe);
> diff --git a/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c 
> b/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c
> index 1259b150dc96..756f39348dd9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c
> @@ -254,13 +254,15 @@ static int vpe_v6_1_process_trap_irq(struct 
> amdgpu_device *adev,
> return 0;
>  }
>
> -static void vpe_v6_1_set_regs(struct amdgpu_vpe *vpe)
> +static int vpe_v6_1_set_regs(struct amdgpu_vpe *vpe)
>  {
> vpe->regs.queue0_rb_rptr_lo = regVPEC_QUEUE0_RB_RPTR;
> vpe->regs.queue0_rb_rptr_hi = regVPEC_QUEUE0_RB_RPTR_HI;
> vpe->regs.queue0_rb_wptr_lo = regVPEC_QUEUE0_RB_WPTR;
> vpe->regs.queue0_rb_wptr_hi = regVPEC_QUEUE0_RB_WPTR_HI;
> vpe->regs.queue0_preempt = regVPEC_QUEUE0_PREEMPT;
> +
> +   return 0;
>  }
>
>  static const struct vpe_funcs vpe_v6_1_funcs = {
> --
> 2.25.1
>


Re: [PATCH] drm/amdgpu: Handle null atom context in VBIOS info ioctl

2023-09-05 Thread Francis, David
[AMD Official Use Only - General]


[AMD Official Use Only - General]

Yeah we've had JIRAs (e.g. https://ontrack-internal.amd.com/browse/SWDEV-409711 
) raised that ASAN can't compile the thunk due to using = {0} . Using memset is 
definitely preferred to save trouble later.

 Kent

This is kernel code, not thunk. {} and {0} are extensively used throughout
the kernel in general and our driver in particular, so I don't see this causing 
problems.

 David


-Original Message-
From: amd-gfx 

 On Behalf Of Alex
Deucher
Sent: Tuesday, September 5, 2023 10:53 AM
To: Francis, David 
Cc: amd-gfx@lists.freedesktop.org
Subject: Re: [PATCH] drm/amdgpu: Handle null atom context in VBIOS info ioctl

On Tue, Sep 5, 2023 at 10:50 AM David Francis 
 wrote:


On some APU systems, there is no atom context and so the
atom_context struct is null.

Add a check to the VBIOS_INFO branch of amdgpu_info_ioctl
to handle this case, returning all zeroes.

Signed-off-by: David Francis 

---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c


b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c


index 3a48bec10aea..86748290ead7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -947,16 +947,21 @@ int amdgpu_info_ioctl(struct drm_device *dev, void


*data, struct drm_file *filp)


? -EFAULT : 0;
}
case AMDGPU_INFO_VBIOS_INFO: {
-   struct drm_amdgpu_info_vbios vbios_info = {};
+   struct drm_amdgpu_info_vbios vbios_info = {0};


IIRC, these should be equivalent.  That said, I believe memset is
generally preferred as not all compilers seem to handle these cases
correctly.

Alex



struct atom_context *atom_context;

atom_context = adev->mode_info.atom_context;
-   memcpy(vbios_info.name, atom_context->name,


sizeof(atom_context->name));


-   memcpy(vbios_info.vbios_pn, atom_context->vbios_pn,


sizeof(atom_context->vbios_pn));


-   vbios_info.version = atom_context->version;
-   memcpy(vbios_info.vbios_ver_str, 
atom_context->vbios_ver_str,
-   
sizeof(atom_context->vbios_ver_str));
-   memcpy(vbios_info.date, atom_context->date,


sizeof(atom_context->date));


+   if (atom_context) {
+   memcpy(vbios_info.name, atom_context->name,
+  sizeof(atom_context->name));
+   memcpy(vbios_info.vbios_pn, 
atom_context->vbios_pn,
+  sizeof(atom_context->vbios_pn));
+   vbios_info.version = atom_context->version;
+   memcpy(vbios_info.vbios_ver_str, atom_context-
vbios_ver_str,
+  sizeof(atom_context->vbios_ver_str));
+   memcpy(vbios_info.date, atom_context->date,
+  sizeof(atom_context->date));
+   }

return copy_to_user(out, _info,
min((size_t)size, 
sizeof(vbios_info))) ? -EFAULT : 0;
--
2.34.1




[PATCH] drm/amdgpu: move task_info out of amdgpu_vm

2023-09-05 Thread Shashank Sharma
It has been observed that task_info struct makes it difficult to
handle amdgpu_vm during a GPU reset, due to it's parameters like
task_name and process name.

This patch:
- removes task_info struct from amdgpu_vm and moves it into vm_mgr
  as an Xarray.
- creates a PID vs task_info mapping to index task_info from this
  Xarray (similar to how it is being done for PASID to vm indexing).
- adds additional changes to support these changes.

Cc: Christian Koenig 
Cc: Alex Deucher 
Signed-off-by: Shashank Sharma 
---
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c|  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c   |  5 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c|  5 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c   |  4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c| 64 ---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h| 12 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c |  4 +-
 9 files changed, 77 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index d34c3ef8f3ed..8568ced570c8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -1539,7 +1539,7 @@ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct 
amdgpu_device *adev,
if (ret)
return ret;
 
-   amdgpu_vm_set_task_info(avm);
+   amdgpu_vm_set_task_info(adev, avm);
 
return 0;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index fb78a8f47587..24b9a841db54 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -316,7 +316,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
kvfree(chunk_array);
 
/* Use this opportunity to fill in task info for the vm */
-   amdgpu_vm_set_task_info(vm);
+   amdgpu_vm_set_task_info(p->adev, vm);
 
return 0;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
index 56e89e76ff17..cd8aef1135e8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -1762,9 +1762,10 @@ static int amdgpu_debugfs_vm_info_show(struct seq_file 
*m, void *unused)
list_for_each_entry(file, >filelist, lhead) {
struct amdgpu_fpriv *fpriv = file->driver_priv;
struct amdgpu_vm *vm = >vm;
+   struct amdgpu_task_info ti = {0, };
 
-   seq_printf(m, "pid:%d\tProcess:%s --\n",
-   vm->task_info.pid, vm->task_info.process_name);
+   amdgpu_vm_get_task_info(adev, vm->pasid, );
+   seq_printf(m, "pid:%d\tProcess:%s --\n", ti.pid, 
ti.process_name);
r = amdgpu_bo_reserve(vm->root.bo, true);
if (r)
break;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 6238701cde23..44fb16eba749 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -5192,8 +5192,9 @@ int amdgpu_do_asic_reset(struct list_head 
*device_list_handle,
memset(_adev->reset_task_info, 0,

sizeof(tmp_adev->reset_task_info));
if (reset_context->job && 
reset_context->job->vm)
-   tmp_adev->reset_task_info =
-   
reset_context->job->vm->task_info;
+   amdgpu_vm_get_task_info(tmp_adev,
+   
reset_context->job->vm->pasid,
+   
_adev->reset_task_info);
amdgpu_reset_capture_coredumpm(tmp_adev);
 #endif
if (vram_lost) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 78476bc75b4e..3985b9b10b46 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -58,7 +58,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct 
drm_sched_job *s_job)
goto exit;
}
 
-   amdgpu_vm_get_task_info(ring->adev, job->pasid, );
+   amdgpu_vm_get_task_info(ring->adev, job->vm->pasid, );
DRM_ERROR("ring %s timeout, signaled seq=%u, emitted seq=%u\n",
  job->base.sched->name, atomic_read(>fence_drv.last_seq),
  ring->fence_drv.sync_seq);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 12414a713256..cb3bde5ce682 100644
--- 

Re: [PATCH] drm/amdkfd: Use partial migrations in GPU page faults

2023-09-05 Thread Chen, Xiaogang



On 9/5/2023 9:02 AM, Philip Yang wrote:



On 2023-08-31 17:29, Chen, Xiaogang wrote:


On 8/31/2023 3:59 PM, Felix Kuehling wrote:

On 2023-08-31 16:33, Chen, Xiaogang wrote:
That said, I'm not actually sure why we're freeing the DMA 
address array after migration to RAM at all. I think we still 
need it even when we're using VRAM. We call svm_range_dma_map 
in svm_range_validate_and_map regardless of whether the range 
is in VRAM or system memory. So it will just allocate a new 
array the next time the range is validated anyway. VRAM pages 
use a special address encoding to indicate VRAM pages to the 
GPUVM code.


I think we do not need free DMA address array as you said, it 
is another thing though.


We need unmap dma address(dma_unmap_page) after migrate from 
ram to vram because we always do dma_map_page at 
svm_range_validate_and_map. If not we would have multiple dma 
maps for same sys ram page.


svm_range_dma_map_dev calls dma_unmap_page before overwriting an 
existing valid entry in the dma_addr array. Anyway, dma 
unmapping the old pages in bulk may still be cleaner. And it 
avoids delays in cleaning up DMA mappings after migrations.


Regards,
  Felix


then we may not need do dma_unmap after migrate from ram to vram 
since svm_range_dma_map_dev always do dma_unmap_page if the 
address is valid dma address for sys ram, and after migrate from 
ram to vram we always do gpu mapping?


I think with XNACK enabled, the DMA mapping may be delayed until a 
page fault. For example on a multi-GPU system, GPU1 page faults 
and migrates data from system memory to its VRAM. Immediately 
afterwards, the page fault handler should use svm_validate_and_map 
to update GPU1 page tables. But GPU2 page tables are not updated 
immediately. So the now stale DMA mappings for GPU2 would continue 
to exist until the next page fault on GPU2.


Regards,
  Felix

If I understand correctly: when user call svm_range_set_attr, if 
p->xnack_enabled is true, we can skip call 
svm_range_validate_and_map. We postpone the buffer validating and 
gpu mapping until page fault or the time the buffer really got used 
by a GPU, and only dma map and gpu map for this GPU.


The current implementation of svm_range_set_attr skips the 
validation after migration if XNACK is off, because it is handled by 
svm_range_restore_work that gets scheduled by the MMU notifier 
triggered by the migration.


With XNACK on, svm_range_set_attr currently validates and maps after 
migration assuming that the data will be used by the GPU(s) soon. 
That is something we could change and let page faults take care of 
the mappings as needed.


Yes, with xnack on, my understanding is we can skip 
svm_range_validate_and_map at svm_range_set_attr after migration, 
then page fault handler will do dma and gpu mapping. That would save 
the first time dma and gpu mapping which apply to all GPUs that user 
ask for access. Then current gpu page fault handler just does dma and 
gpu mapping for the GPU that triggered page fault. Is that ok?


With xnack on, after prefetch the range to GPU, need 
svm_range_validate_and_map to update the mapping of the GPU migrated 
to (also the mapping of GPUs with access_in_place), because app 
prefetch to GPU to avoid GPU page fault.


With xnack on postpone gpu mapping to page fault handler may save some 
operations since we update mapping only on gpu that need the mapping, 
but that is not for this patch any way.


After migrating to VRAM, we only need dma_unmap_page from 
prange->dma_addr array, don't need to free the dma_addr array itself, 
as it can be reused to store VRAM address to map to GPU.


yes, we do not need free dma array, only need dma_unmpa_page at 
svm_range_free_dma_mappings. The array stores both system ram dma 
address and vram physical address. We can free this dma array at 
svm_range_free.


Regards

Xiaogang


Regards,

Philip



Regards

Xiaogang


Regards,
  Felix






Regards

Xiaogang 


Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Thomas Zimmermann

Hi

Am 05.09.23 um 15:30 schrieb suijingfeng:

Hi,


On 2023/9/5 18:45, Thomas Zimmermann wrote:

Hi

Am 04.09.23 um 21:57 schrieb Sui Jingfeng:

From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned


If anything, the primary graphics adapter is the one initialized by 
the firmware. I think our boot-up graphics also make this assumption 
implicitly.




Yes, but by the time of DRM drivers get loaded successfully,the boot-up 
graphics already finished.
Firmware framebuffer device already get killed by the 
drm_aperture_remove_conflicting_pci_framebuffers()
function (or its siblings). So, this series is definitely not to 
interact with the firmware framebuffer


Yes and no. The helpers you mention will attempt to remove the firmware 
framebuffer on the given PCI device. If you have multiple PCI devices, 
the other devices would not be affected.


This also means that probing a non-primary card will not affect the 
firmware framebuffer on the primary card. You can have all these drivers 
co-exist next to each other. If you link a full DRM driver into the 
kernel image, it might even be loaded before the firmware-framebuffer's 
driver.  We had some funny bugs from these interactions.



(or more intelligent framebuffer drivers).  It is for user space 
program, such as X server and Wayland
compositor. Its for Linux user or drm drivers testers, which allow them 
to direct graphic display server

using right hardware of interested as primary video card.

Also, I believe that X server and Wayland compositor are the best test 
examples.

If a specific DRM driver can't work with X server as a primary,
then there probably have something wrong.


If you want to run a userspace compositor or X11 on a certain device, 
you best configure this in the program's config files. But not on the 
kernel command line.


The whole concept of a 'primary' display is bogus IMHO. It only exists 
because old VGA and BIOS (and their equivalents on non-PC systems) were 
unable to use more than one graphics device. Hence, as you write below, 
only the first device got POSTed by the BIOS. If you had an additional 
card, the device driver needed to perform the POSTing.


However, on modern Linux systems the primary display does not really 
exist. 'Primary' is the device that is available via VGA, VESA or EFI. 
Our drivers don't use these interfaces, but the native registers. As you 
said yourself, these firmware devices (VGA, VESA, EFI) are removed ASAP 
by the native drivers.






But what's the use case for overriding this setting?



On a specific machine with multiple GPUs mounted,
only the primary graphics get POST-ed (initialized) by the firmware.
Therefore, the DRM drivers for the rest video cards, have to choose to
work without the prerequisite setups done by firmware, This is called as 
POST.


One of the use cases of this series is to test if a specific DRM driver 
could works properly,
even though there is no prerequisite works have been done by firmware at 
all.

And it seems that the results is not satisfying in all cases.

drm/ast is the first drm drivers which refused to work if not being 
POST-ed by the firmware.


You might have found a bug in the ast driver. Ast has means to detect if 
the device has been POSTed and maybe do that. If this doesn't work 
correctly, it needs a fix.


As Christian mentioned, if anything, you might add an option to specify 
the default card to vgaarb (e.g., as PCI slot). But userspace should 
avoid the idea of a primary card IMHO.


Best regards
Thomas



Before apply this series, I was unable make drm/ast as the primary video 
card easily. On a
multiple video card configuration, the monitor connected with the 
AST2400 not light up.

While confusing, a naive programmer may suspect the PRIME is not working.

After applied this series and passing ast.modeset=10 on the kernel cmd 
line,

I found that the monitor connected with my ast2400 video card still black,
It doesn't display and doesn't show image to me.

While in the process of study drm/ast, I know that drm/ast driver has 
the POST code shipped.
See the ast_post_gpu() function, then, I was wondering why this function 
doesn't works.
After a short-time (hasty) debugging, I found that the the 
ast_post_gpu() function

didn't get run. Because it have something to do with the ast->config_mode.

Without thinking too much, I hardcoded the ast->config_mode as 
ast_use_p2a to

force the ast_post_gpu() function get run.

```

--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -132,6 +132,8 @@ static int ast_device_config_init(struct ast_device 
*ast)

     }
     }

+   ast->config_mode = ast_use_p2a;
+
     switch (ast->config_mode) {
     case ast_use_defaults:
     drm_info(dev, "Using default configuration\n");

```

Then, the monitor light up, it display the Ubuntu 

Re: [PATCH] drm/amdgpu: Handle null atom context in VBIOS info ioctl

2023-09-05 Thread Alex Deucher
On Tue, Sep 5, 2023 at 10:50 AM David Francis  wrote:
>
> On some APU systems, there is no atom context and so the
> atom_context struct is null.
>
> Add a check to the VBIOS_INFO branch of amdgpu_info_ioctl
> to handle this case, returning all zeroes.
>
> Signed-off-by: David Francis 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 19 ---
>  1 file changed, 12 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 3a48bec10aea..86748290ead7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -947,16 +947,21 @@ int amdgpu_info_ioctl(struct drm_device *dev, void 
> *data, struct drm_file *filp)
> ? -EFAULT : 0;
> }
> case AMDGPU_INFO_VBIOS_INFO: {
> -   struct drm_amdgpu_info_vbios vbios_info = {};
> +   struct drm_amdgpu_info_vbios vbios_info = {0};

IIRC, these should be equivalent.  That said, I believe memset is
generally preferred as not all compilers seem to handle these cases
correctly.

Alex

> struct atom_context *atom_context;
>
> atom_context = adev->mode_info.atom_context;
> -   memcpy(vbios_info.name, atom_context->name, 
> sizeof(atom_context->name));
> -   memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, 
> sizeof(atom_context->vbios_pn));
> -   vbios_info.version = atom_context->version;
> -   memcpy(vbios_info.vbios_ver_str, 
> atom_context->vbios_ver_str,
> -   
> sizeof(atom_context->vbios_ver_str));
> -   memcpy(vbios_info.date, atom_context->date, 
> sizeof(atom_context->date));
> +   if (atom_context) {
> +   memcpy(vbios_info.name, atom_context->name,
> +  sizeof(atom_context->name));
> +   memcpy(vbios_info.vbios_pn, 
> atom_context->vbios_pn,
> +  sizeof(atom_context->vbios_pn));
> +   vbios_info.version = atom_context->version;
> +   memcpy(vbios_info.vbios_ver_str, 
> atom_context->vbios_ver_str,
> +  sizeof(atom_context->vbios_ver_str));
> +   memcpy(vbios_info.date, atom_context->date,
> +  sizeof(atom_context->date));
> +   }
>
> return copy_to_user(out, _info,
> min((size_t)size, 
> sizeof(vbios_info))) ? -EFAULT : 0;
> --
> 2.34.1
>


Re: [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Alex Williamson
On Tue,  5 Sep 2023 03:57:15 +0800
Sui Jingfeng  wrote:

> From: Sui Jingfeng 
> 
> On a machine with multiple GPUs, a Linux user has no control over which
> one is primary at boot time. This series tries to solve above mentioned
> problem by introduced the ->be_primary() function stub. The specific
> device drivers can provide an implementation to hook up with this stub by
> calling the vga_client_register() function.
> 
> Once the driver bound the device successfully, VGAARB will call back to
> the device driver. To query if the device drivers want to be primary or
> not. Device drivers can just pass NULL if have no such needs.
> 
> Please note that:
> 
> 1) The ARM64, Loongarch, Mips servers have a lot PCIe slot, and I would
>like to mount at least three video cards.
> 
> 2) Typically, those non-86 machines don't have a good UEFI firmware
>support, which doesn't support select primary GPU as firmware stage.
>Even on x86, there are old UEFI firmwares which already made undesired
>decision for you.
> 
> 3) This series is attempt to solve the remain problems at the driver level,
>while another series[1] of me is target to solve the majority of the
>problems at device level.
> 
> Tested (limited) on x86 with four video card mounted, Intel UHD Graphics
> 630 is the default boot VGA, successfully override by ast2400 with
> ast.modeset=10 append at the kernel cmd line.
> 
> $ lspci | grep VGA
> 
>  00:02.0 VGA compatible controller: Intel Corporation CoffeeLake-S GT2 [UHD 
> Graphics 630]

In all my previous experiments with VGA routing and IGD I found that
IGD can't actually release VGA routing and Intel confirmed the hardware
doesn't have the ability to do so.  It will always be primary from a
VGA routing perspective.  Was this actually tested with non-UEFI?

I suspect it might only work in UEFI mode where we probably don't
actually have a dependency on VGA routing.  This is essentially why
vfio requires UEFI ROMs when assigning GPUs to VMs, VGA routing is too
broken to use on Intel systems with IGD.  Thanks,

Alex

>  01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] 
> Caicos XTX [Radeon HD 8490 / R5 235X OEM]
>  04:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics 
> Family (rev 30)
>  05:00.0 VGA compatible controller: NVIDIA Corporation GK208B [GeForce GT 
> 720] (rev a1)
> 
> $ sudo dmesg | grep vgaarb
> 
>  pci :00:02.0: vgaarb: setting as boot VGA device
>  pci :00:02.0: vgaarb: VGA device added: 
> decodes=io+mem,owns=io+mem,locks=none
>  pci :01:00.0: vgaarb: VGA device added: 
> decodes=io+mem,owns=none,locks=none
>  pci :04:00.0: vgaarb: VGA device added: 
> decodes=io+mem,owns=none,locks=none
>  pci :05:00.0: vgaarb: VGA device added: 
> decodes=io+mem,owns=none,locks=none
>  vgaarb: loaded
>  ast :04:00.0: vgaarb: Override as primary by driver
>  i915 :00:02.0: vgaarb: changed VGA decodes: 
> olddecodes=io+mem,decodes=none:owns=io+mem
>  radeon :01:00.0: vgaarb: changed VGA decodes: 
> olddecodes=io+mem,decodes=none:owns=none
>  ast :04:00.0: vgaarb: changed VGA decodes: 
> olddecodes=io+mem,decodes=none:owns=none
> 
> v2:
>   * Add a simple implemment for drm/i915 and drm/ast
>   * Pick up all tags (Mario)
> v3:
>   * Fix a mistake for drm/i915 implement
>   * Fix patch can not be applied problem because of merge conflect.
> v4:
>   * Focus on solve the real problem.
> 
> v1,v2 at https://patchwork.freedesktop.org/series/120059/
>v3 at https://patchwork.freedesktop.org/series/120562/
> 
> [1] https://patchwork.freedesktop.org/series/122845/
> 
> Sui Jingfeng (9):
>   PCI/VGA: Allowing the user to select the primary video adapter at boot
> time
>   drm/nouveau: Implement .be_primary() callback
>   drm/radeon: Implement .be_primary() callback
>   drm/amdgpu: Implement .be_primary() callback
>   drm/i915: Implement .be_primary() callback
>   drm/loongson: Implement .be_primary() callback
>   drm/ast: Register as a VGA client by calling vga_client_register()
>   drm/hibmc: Register as a VGA client by calling vga_client_register()
>   drm/gma500: Register as a VGA client by calling vga_client_register()
> 
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 11 +++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   | 13 -
>  drivers/gpu/drm/ast/ast_drv.c | 31 ++
>  drivers/gpu/drm/gma500/psb_drv.c  | 57 ++-
>  .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   | 15 +
>  drivers/gpu/drm/i915/display/intel_vga.c  | 15 -
>  drivers/gpu/drm/loongson/loongson_module.c|  2 +-
>  drivers/gpu/drm/loongson/loongson_module.h|  1 +
>  drivers/gpu/drm/loongson/lsdc_drv.c   | 10 +++-
>  drivers/gpu/drm/nouveau/nouveau_vga.c | 11 +++-
>  drivers/gpu/drm/radeon/radeon_device.c| 10 +++-
>  drivers/pci/vgaarb.c  | 43 --
>  drivers/vfio/pci/vfio_pci_core.c   

Re: [PATCH 3/3] Documentation/amdgpu: Modify pp_dpm_*clk details

2023-09-05 Thread Alex Deucher
On Mon, Sep 4, 2023 at 9:20 AM Lijo Lazar  wrote:
>
> pp_dpm_*clk nodes also could show the frequencies when a clock is in
> 'sleep' state. Add documentation related to that.
>
> Signed-off-by: Lijo Lazar 
> ---
>  drivers/gpu/drm/amd/pm/amdgpu_pm.c | 10 +-
>  1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c 
> b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> index 84e1af6a6ce7..3dca1aa473c8 100644
> --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> @@ -983,7 +983,15 @@ static ssize_t amdgpu_get_pp_features(struct device *dev,
>   * pp_dpm_fclk interface is only available for Vega20 and later ASICs.
>   *
>   * Reading back the files will show you the available power levels within
> - * the power state and the clock information for those levels.
> + * the power state and the clock information for those levels. If deep sleep 
> is
> + * applied to a clock, the level will be denoted by a special level 'S:'
> + * E.g.,
> + * S: 19Mhz *
> + * 0: 615Mhz
> + * 1: 800Mhz
> + * 2: 888Mhz
> + * 3: 1000Mhz
> + *
>   *
>   * To manually adjust these states, first select manual using
>   * power_dpm_force_performance_level.

Might be nice to update older asics to follow this model as well at some point.

Alex

> --
> 2.25.1
>


Re: [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Sui Jingfeng

Hi,

On 2023/9/5 21:28, Christian König wrote:


2) Typically, those non-86 machines don't have a good UEFI firmware
    support, which doesn't support select primary GPU as firmware 
stage.
    Even on x86, there are old UEFI firmwares which already made 
undesired

    decision for you.

3) This series is attempt to solve the remain problems at the driver 
level,
    while another series[1] of me is target to solve the majority of 
the

    problems at device level.

Tested (limited) on x86 with four video card mounted, Intel UHD 
Graphics

630 is the default boot VGA, successfully override by ast2400 with
ast.modeset=10 append at the kernel cmd line.

The value 10 is incredibly arbitrary, and multiplied as a magic number
all over the place.


+1 



This is the exact reason why I made this series as RFC, because this is a 
open-ended problem.
The choices of 3,4,5,6,7,8 and 9 are as arbitrary as the number of '10'. '1' 
and '2' is
definitely not suitable, because the seat has already been taken.

Take the drm/nouveau as an example:


```

MODULE_PARM_DESC(modeset, "enable driver (default: auto, "
  "0 = disabled, 1 = enabled, 2 = headless)");
int nouveau_modeset = -1;
module_param_named(modeset, nouveau_modeset, int, 0400);

```


'1' is for enable the drm driver, some driver even override the 'nomodeset' 
parameter.

'2' is not suitable, because nouveau use it as headless GPU (render-only or 
compute class GPU?)

'3' is also not likely the best, the concerns is that
what if a specific drm driver want to expand the usage in the future?


The reason I pick up the digit '10' is that


1) The modeset parameter is unlikely to get expanded up to 10 usages.

Other drm drivers only use the '-1', '0' and 1, choose '2' will conflict with 
drm/nouveau.
By pick the digit '10', it leave some space(room) to various device driver 
authors.
It also helps to keep the usage consistent across various drivers.


2) An int taken up 4 byte, I don't want to waste even a single byte,

While in the process of defencing my patch, I have to say
draft another kernel command line would cause the wasting of precious RAM 
storage.

An int can have 2^31 usage, why we can't improve the utilization rate?

3) Please consider the fact that the modeset is the most common and attractive 
parameter

No name is better than the 'modeset', as other name is not easy to remember.

Again, this is for Linux user, thus it is not arbitrary.
Despite simple and trivial, I think about it more than one week.



Re: [PATCH] drm/amd: Fix the flag setting code for interrupt request

2023-09-05 Thread Alex Deucher
On Mon, Sep 4, 2023 at 2:30 AM Ma Jun  wrote:
>
> [1] Remove the irq flags setting code since pci_alloc_irq_vectors()
> handles these flags.
> [2] Free the msi vectors in case of error.
>
> Signed-off-by: Ma Jun 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 43 ++---
>  1 file changed, 25 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> index fa6d0adcec20..17043a1e37a5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
> @@ -271,28 +271,28 @@ static void amdgpu_restore_msix(struct amdgpu_device 
> *adev)
>  int amdgpu_irq_init(struct amdgpu_device *adev)
>  {
> int r = 0;
> -   unsigned int irq;
> +   unsigned int irq, flags;
>
> spin_lock_init(>irq.lock);
>
> /* Enable MSI if not disabled by module parameter */
> adev->irq.msi_enabled = false;
>
> +   if (amdgpu_msi_ok(adev))
> +   flags = PCI_IRQ_MSI | PCI_IRQ_MSIX;
> +   else
> +   flags = PCI_IRQ_LEGACY;

I think this logic could be something like:

if (!amdgpu_msi_ok(adev))
  flags = PCI_IRQ_LEGACY;
else
  flags = PCI_IRQ_ALL_TYPES

Other than that, looks fine to me.

Alex


> +
> +   /* we only need one vector */
> +   r = pci_alloc_irq_vectors(adev->pdev, 1, 1, flags);
> +   if (r < 0) {
> +   dev_err(adev->dev, "Failed to alloc msi vectors\n");
> +   return r;
> +   }
> +
> if (amdgpu_msi_ok(adev)) {
> -   int nvec = pci_msix_vec_count(adev->pdev);
> -   unsigned int flags;
> -
> -   if (nvec <= 0)
> -   flags = PCI_IRQ_MSI;
> -   else
> -   flags = PCI_IRQ_MSI | PCI_IRQ_MSIX;
> -
> -   /* we only need one vector */
> -   nvec = pci_alloc_irq_vectors(adev->pdev, 1, 1, flags);
> -   if (nvec > 0) {
> -   adev->irq.msi_enabled = true;
> -   dev_dbg(adev->dev, "using MSI/MSI-X.\n");
> -   }
> +   adev->irq.msi_enabled = true;
> +   dev_dbg(adev->dev, "using MSI/MSI-X.\n");
> }
>
> INIT_WORK(>irq.ih1_work, amdgpu_irq_handle_ih1);
> @@ -302,22 +302,29 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
> /* Use vector 0 for MSI-X. */
> r = pci_irq_vector(adev->pdev, 0);
> if (r < 0)
> -   return r;
> +   goto free_vectors;
> irq = r;
>
> /* PCI devices require shared interrupts. */
> r = request_irq(irq, amdgpu_irq_handler, IRQF_SHARED, 
> adev_to_drm(adev)->driver->name,
> adev_to_drm(adev));
> if (r)
> -   return r;
> +   goto free_vectors;
> +
> adev->irq.installed = true;
> adev->irq.irq = irq;
> adev_to_drm(adev)->max_vblank_count = 0x00ff;
>
> DRM_DEBUG("amdgpu: irq initialized.\n");
> return 0;
> -}
>
> +free_vectors:
> +   if (adev->irq.msi_enabled)
> +   pci_free_irq_vectors(adev->pdev);
> +
> +   adev->irq.msi_enabled = false;
> +   return r;
> +}
>
>  void amdgpu_irq_fini_hw(struct amdgpu_device *adev)
>  {
> --
> 2.34.1
>


[RFC PATCH 5/5] drm/amd/display: add DPP and MPC color caps to DTN log

2023-09-05 Thread Melissa Wen
Add color caps information for DPP and MPC block to show HW color caps.

Signed-off-by: Melissa Wen 
---
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 23 +++
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.c| 23 +++
 2 files changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index b2f3f1f85f4f..6caac6cb8873 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -329,6 +329,24 @@ dcn10_log_color_state(struct dc *dc,
DTN_INFO("\n");
}
DTN_INFO("\n");
+   DTN_INFO("DPP Color Caps: input_lut_shared:%d  icsc:%d"
+"  dgam_ram:%d  dgam_rom: 
srgb:%d,bt2020:%d,gamma2_2:%d,pq:%d,hlg:%d"
+"  post_csc:%d  gamcor:%d  dgam_rom_for_yuv:%d  3d_lut:%d"
+"  blnd_lut:%d  oscs:%d\n\n",
+dc->caps.color.dpp.input_lut_shared,
+dc->caps.color.dpp.icsc,
+dc->caps.color.dpp.dgam_ram,
+dc->caps.color.dpp.dgam_rom_caps.srgb,
+dc->caps.color.dpp.dgam_rom_caps.bt2020,
+dc->caps.color.dpp.dgam_rom_caps.gamma2_2,
+dc->caps.color.dpp.dgam_rom_caps.pq,
+dc->caps.color.dpp.dgam_rom_caps.hlg,
+dc->caps.color.dpp.post_csc,
+dc->caps.color.dpp.gamma_corr,
+dc->caps.color.dpp.dgam_rom_for_yuv,
+dc->caps.color.dpp.hw_3d_lut,
+dc->caps.color.dpp.ogam_ram,
+dc->caps.color.dpp.ocsc);
 
DTN_INFO("MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  
OVERLAP_ONLY  IDLE\n");
for (i = 0; i < pool->pipe_count; i++) {
@@ -342,6 +360,11 @@ dcn10_log_color_state(struct dc *dc,
s.idle);
}
DTN_INFO("\n");
+   DTN_INFO("MPC Color Caps: gamut_remap:%d, 3dlut:%d, ogam_ram:%d, 
ocsc:%d\n\n",
+dc->caps.color.mpc.gamut_remap,
+dc->caps.color.mpc.num_3dluts,
+dc->caps.color.mpc.ogam_ram,
+dc->caps.color.mpc.ocsc);
 }
 
 void dcn10_log_hw_state(struct dc *dc,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
index e1a2a68c1d45..dfccf0d3f0d5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
@@ -125,6 +125,24 @@ dcn30_log_color_state(struct dc *dc,
DTN_INFO("\n");
}
DTN_INFO("\n");
+   DTN_INFO("DPP Color Caps: input_lut_shared:%d  icsc:%d"
+"  dgam_ram:%d  dgam_rom: 
srgb:%d,bt2020:%d,gamma2_2:%d,pq:%d,hlg:%d"
+"  post_csc:%d  gamcor:%d  dgam_rom_for_yuv:%d  3d_lut:%d"
+"  blnd_lut:%d  oscs:%d\n\n",
+dc->caps.color.dpp.input_lut_shared,
+dc->caps.color.dpp.icsc,
+dc->caps.color.dpp.dgam_ram,
+dc->caps.color.dpp.dgam_rom_caps.srgb,
+dc->caps.color.dpp.dgam_rom_caps.bt2020,
+dc->caps.color.dpp.dgam_rom_caps.gamma2_2,
+dc->caps.color.dpp.dgam_rom_caps.pq,
+dc->caps.color.dpp.dgam_rom_caps.hlg,
+dc->caps.color.dpp.post_csc,
+dc->caps.color.dpp.gamma_corr,
+dc->caps.color.dpp.dgam_rom_for_yuv,
+dc->caps.color.dpp.hw_3d_lut,
+dc->caps.color.dpp.ogam_ram,
+dc->caps.color.dpp.ocsc);
 
DTN_INFO("MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  
OVERLAP_ONLY  IDLE"
 "  SHAPER mode  3DLUT_mode  3DLUT bit-depth  3DLUT size  OGAM 
mode  OGAM LUT"
@@ -156,6 +174,11 @@ dcn30_log_color_state(struct dc *dc,
s.gamut_remap_c11_c12, s.gamut_remap_c33_c34);
}
DTN_INFO("\n");
+   DTN_INFO("MPC Color Caps: gamut_remap:%d, 3dlut:%d, ogam_ram:%d, 
ocsc:%d\n\n",
+dc->caps.color.mpc.gamut_remap,
+dc->caps.color.mpc.num_3dluts,
+dc->caps.color.mpc.ogam_ram,
+dc->caps.color.mpc.ocsc);
 }
 
 bool dcn30_set_blend_lut(
-- 
2.40.1



[RFC PATCH 4/5] drm/amd/display: hook DCN30 color state logging to DTN log

2023-09-05 Thread Melissa Wen
Color caps changed between HW versions which caused DCN10 color state
sections on DTN log no longer fit DCN3.0 versions. Create a
DCN3.0-specific color state logging and hook it to drivers of DCN3.0
family.

Signed-off-by: Melissa Wen 
---
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |  5 +-
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.c| 89 +++
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.h|  3 +
 .../gpu/drm/amd/display/dc/dcn30/dcn30_init.c |  1 +
 .../drm/amd/display/dc/dcn301/dcn301_init.c   |  1 +
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |  2 +
 6 files changed, 100 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index d82e49045fbc..b2f3f1f85f4f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -357,7 +357,10 @@ void dcn10_log_hw_state(struct dc *dc,
 
dcn10_log_hubp_states(dc, log_ctx);
 
-   dcn10_log_color_state(dc, log_ctx);
+   if (dc->hwss.log_color_state)
+   dc->hwss.log_color_state(dc, log_ctx);
+   else
+   dcn10_log_color_state(dc, log_ctx);
 
DTN_INFO("OTG:  v_bs  v_be  v_ss  v_se  vpol  vmax  vmin  vmax_sel  
vmin_sel  h_bs  h_be  h_ss  h_se  hpol  htot  vtot  underflow blank_en\n");
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
index 255713ec29bb..e1a2a68c1d45 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
@@ -69,6 +69,95 @@
 #define FN(reg_name, field_name) \
hws->shifts->field_name, hws->masks->field_name
 
+void
+dcn30_log_color_state(struct dc *dc,
+ struct dc_log_buffer_ctx *log_ctx)
+{
+   struct dc_context *dc_ctx = dc->ctx;
+   struct resource_pool *pool = dc->res_pool;
+   int i;
+
+   DTN_INFO("DPP:  DGAM ROM  DGAM ROM type  DGAM LUT  SHAPER mode"
+"  3DLUT mode  3DLUT bit depth  3DLUT size  RGAM mode"
+"  GAMUT mode  "
+"C11 C12   C13 C14   C21 C22   C23 C24   C31 C32   C33 C34\n");
+
+   for (i = 0; i < pool->pipe_count; i++) {
+   struct dpp *dpp = pool->dpps[i];
+   struct dcn_dpp_state s = {-1};
+
+   dpp->funcs->dpp_read_state(dpp, );
+
+   if (!s.is_enabled)
+   continue;
+
+   DTN_INFO("[%2d]:  %7x  %13s  %8s  %11s  %10s  %15s  %10s  %9s"
+"  %10x  %08xh %08xh %08xh %08xh %08xh %08xh",
+   dpp->inst,
+   s.pre_dgam_mode,
+   (s.pre_dgam_select == 0) ? "sRGB" :
+((s.pre_dgam_select == 1) ? "Gamma 2.2" :
+((s.pre_dgam_select == 2) ? "Gamma 2.4" :
+((s.pre_dgam_select == 3) ? "Gamma 2.6" :
+((s.pre_dgam_select == 4) ? "BT.709" :
+((s.pre_dgam_select == 5) ? "PQ" :
+((s.pre_dgam_select == 6) ? "HLG" :
+"Unknown")),
+   (s.gamcor_lut_mode == 0) ? "Bypass" :
+((s.gamcor_lut_mode == 2) ? "RAM" :
+"Unknown"),
+   (s.shaper_lut_mode == 1) ? "RAM A" :
+((s.shaper_lut_mode == 2) ? "RAM B" :
+"Bypass"),
+   (s.lut3d_mode == 1) ? "RAM A" :
+((s.lut3d_mode == 2) ? "RAM B" :
+   "Bypass"),
+   (s.lut3d_bit_depth <= 0) ? "12-bit" : "10-bit",
+   (s.lut3d_size == 0) ? "17x17x17" : "9x9x9",
+   (s.rgam_lut_mode == 0) ? "Bypass" :
+((s.rgam_lut_mode == 1) ? "RAM A" :
+((s.rgam_lut_mode == 2) ? "RAM B" :
+  "Unknown")),
+   s.gamut_remap_mode,
+   s.gamut_remap_c11_c12, s.gamut_remap_c13_c14,
+   s.gamut_remap_c21_c22, s.gamut_remap_c23_c24,
+   s.gamut_remap_c31_c32, s.gamut_remap_c33_c34);
+   DTN_INFO("\n");
+   }
+   DTN_INFO("\n");
+
+   DTN_INFO("MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  
OVERLAP_ONLY  IDLE"
+"  SHAPER mode  3DLUT_mode  3DLUT bit-depth  3DLUT size  OGAM 
mode  OGAM LUT"
+"  GAMUT mode  C11 C12   C33 C34\n");
+
+   for (i = 0; i < pool->pipe_count; i++) {
+   struct mpcc_state s = {0};
+
+   pool->mpc->funcs->read_mpcc_state(pool->mpc, i, );
+   if (s.opp_id != 0xf)
+  

[RFC PATCH 2/5] drm/amd/display: fill up DCN3 DPP color state

2023-09-05 Thread Melissa Wen
DCN3 DPP color state was uncollected and some state elements from DCN1
doesn't fit DCN3. Create new elements according to DCN3 color caps and
fill them up for DTN log output.

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c  | 28 +--
 drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h   |  8 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
index 50dc83404644..a91d72f44bbd 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
@@ -46,9 +46,31 @@ void dpp30_read_state(struct dpp *dpp_base, struct 
dcn_dpp_state *s)
struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 
REG_GET(DPP_CONTROL,
-   DPP_CLOCK_ENABLE, >is_enabled);
-
-   // TODO: Implement for DCN3
+   DPP_CLOCK_ENABLE, >is_enabled);
+   REG_GET_2(PRE_DEGAM,
+ PRE_DEGAM_MODE, >pre_dgam_mode,
+ PRE_DEGAM_SELECT, >pre_dgam_select);
+   REG_GET(CM_SHAPER_CONTROL,
+   CM_SHAPER_LUT_MODE, >shaper_lut_mode);
+   REG_GET(CM_3DLUT_MODE,
+   CM_3DLUT_MODE_CURRENT, >lut3d_mode);
+   REG_GET(CM_3DLUT_READ_WRITE_CONTROL,
+   CM_3DLUT_30BIT_EN, >lut3d_bit_depth);
+   REG_GET(CM_3DLUT_MODE,
+   CM_3DLUT_SIZE, >lut3d_size);
+   // BGAM has no ROM, and definition is different, can't reuse same dump
+REG_GET(CM_BLNDGAM_CONTROL,
+   CM_BLNDGAM_LUT_MODE, >rgam_lut_mode);
+   REG_GET(CM_GAMUT_REMAP_CONTROL,
+   CM_GAMUT_REMAP_MODE, >gamut_remap_mode);
+   if (s->gamut_remap_mode) {
+   s->gamut_remap_c11_c12 = REG_READ(CM_GAMUT_REMAP_C11_C12);
+   s->gamut_remap_c13_c14 = REG_READ(CM_GAMUT_REMAP_C13_C14);
+   s->gamut_remap_c21_c22 = REG_READ(CM_GAMUT_REMAP_C21_C22);
+   s->gamut_remap_c23_c24 = REG_READ(CM_GAMUT_REMAP_C23_C24);
+   s->gamut_remap_c31_c32 = REG_READ(CM_GAMUT_REMAP_C31_C32);
+   s->gamut_remap_c33_c34 = REG_READ(CM_GAMUT_REMAP_C33_C34);
+   }
 }
 /*program post scaler scs block in dpp CM*/
 void dpp3_program_post_csc(
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
index f4aa76e02518..7e69d9e28f5b 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
@@ -148,6 +148,14 @@ struct dcn_dpp_state {
uint32_t gamut_remap_c23_c24;
uint32_t gamut_remap_c31_c32;
uint32_t gamut_remap_c33_c34;
+   uint32_t shaper_lut_mode;
+   uint32_t lut3d_mode;
+   uint32_t lut3d_bit_depth;
+   uint32_t lut3d_size;
+   uint32_t blnd_lut_mode;
+   uint32_t pre_dgam_mode;
+   uint32_t pre_dgam_select;
+   uint32_t gamcor_lut_mode;
 };
 
 struct CM_bias_params {
-- 
2.40.1



[RFC PATCH 3/5] drm/amd/display: create DCN3-specific log for MPC state

2023-09-05 Thread Melissa Wen
Logging DCN3 MPC state was following DCN1 implementation that doesn't
consider new DCN3 MPC color blocks. Create new elements according to
DCN3 MPC color caps and a new DCN3-specific function for reading MPC
data.

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c  | 55 ++-
 drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h   | 13 +
 2 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
index d1500b223858..d164fbf89212 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
@@ -1382,8 +1382,61 @@ static void mpc3_set_mpc_mem_lp_mode(struct mpc *mpc)
}
 }
 
+static void mpc3_read_mpcc_state(
+   struct mpc *mpc,
+   int mpcc_inst,
+   struct mpcc_state *s)
+{
+   struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
+   uint32_t rmu_status = 0xf;
+
+   REG_GET(MPCC_OPP_ID[mpcc_inst], MPCC_OPP_ID, >opp_id);
+   REG_GET(MPCC_TOP_SEL[mpcc_inst], MPCC_TOP_SEL, >dpp_id);
+   REG_GET(MPCC_BOT_SEL[mpcc_inst], MPCC_BOT_SEL, >bot_mpcc_id);
+   REG_GET_4(MPCC_CONTROL[mpcc_inst], MPCC_MODE, >mode,
+   MPCC_ALPHA_BLND_MODE, >alpha_mode,
+   MPCC_ALPHA_MULTIPLIED_MODE, >pre_multiplied_alpha,
+   MPCC_BLND_ACTIVE_OVERLAP_ONLY, >overlap_only);
+   REG_GET_2(MPCC_STATUS[mpcc_inst], MPCC_IDLE, >idle,
+   MPCC_BUSY, >busy);
+
+   /* Color blocks state */
+   REG_GET(MPC_RMU_CONTROL, MPC_RMU0_MUX_STATUS, _status);
+   if (rmu_status == mpcc_inst) {
+   REG_GET(SHAPER_CONTROL[0],
+   MPC_RMU_SHAPER_LUT_MODE_CURRENT, >shaper_lut_mode);
+   REG_GET(RMU_3DLUT_MODE[0],
+   MPC_RMU_3DLUT_MODE_CURRENT,  >lut3d_mode);
+   REG_GET(RMU_3DLUT_READ_WRITE_CONTROL[0],
+   MPC_RMU_3DLUT_30BIT_EN, >lut3d_bit_depth);
+   REG_GET(RMU_3DLUT_MODE[0],
+   MPC_RMU_3DLUT_SIZE, >lut3d_size);
+   } else {
+   REG_GET(SHAPER_CONTROL[1],
+   MPC_RMU_SHAPER_LUT_MODE_CURRENT, >shaper_lut_mode);
+   REG_GET(RMU_3DLUT_MODE[1],
+   MPC_RMU_3DLUT_MODE_CURRENT,  >lut3d_mode);
+   REG_GET(RMU_3DLUT_READ_WRITE_CONTROL[1],
+   MPC_RMU_3DLUT_30BIT_EN, >lut3d_bit_depth);
+   REG_GET(RMU_3DLUT_MODE[1],
+   MPC_RMU_3DLUT_SIZE, >lut3d_size);
+   }
+ REG_GET_2(MPCC_OGAM_CONTROL[mpcc_inst],
+  MPCC_OGAM_MODE_CURRENT, >rgam_mode,
+  MPCC_OGAM_SELECT_CURRENT, >rgam_lut);
+   REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_inst],
+   MPCC_GAMUT_REMAP_MODE_CURRENT, >gamut_remap_mode);
+   if (s->gamut_remap_mode == 1) {
+   s->gamut_remap_c11_c12 = 
REG_READ(MPC_GAMUT_REMAP_C11_C12_A[mpcc_inst]);
+   s->gamut_remap_c33_c34 = 
REG_READ(MPC_GAMUT_REMAP_C33_C34_A[mpcc_inst]);
+   } else if (s->gamut_remap_mode == 2) {
+   s->gamut_remap_c11_c12 = 
REG_READ(MPC_GAMUT_REMAP_C11_C12_B[mpcc_inst]);
+   s->gamut_remap_c33_c34 = 
REG_READ(MPC_GAMUT_REMAP_C33_C34_B[mpcc_inst]);
+   }
+}
+
 static const struct mpc_funcs dcn30_mpc_funcs = {
-   .read_mpcc_state = mpc1_read_mpcc_state,
+   .read_mpcc_state = mpc3_read_mpcc_state,
.insert_plane = mpc1_insert_plane,
.remove_mpcc = mpc1_remove_mpcc,
.mpc_init = mpc1_mpc_init,
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..e60b3503605b 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
@@ -193,6 +193,19 @@ struct mpcc_state {
uint32_t overlap_only;
uint32_t idle;
uint32_t busy;
+   uint32_t shaper_lut_mode;
+   uint32_t lut3d_mode;
+   uint32_t lut3d_bit_depth;
+   uint32_t lut3d_size;
+   uint32_t rgam_mode;
+   uint32_t rgam_lut;
+   uint32_t gamut_remap_mode;
+   uint32_t gamut_remap_c11_c12;
+   uint32_t gamut_remap_c13_c14;
+   uint32_t gamut_remap_c21_c22;
+   uint32_t gamut_remap_c23_c24;
+   uint32_t gamut_remap_c31_c32;
+   uint32_t gamut_remap_c33_c34;
 };
 
 /**
-- 
2.40.1



[RFC PATCH 1/5] drm/amd/display: detach color state from hw state logging

2023-09-05 Thread Melissa Wen
Prepare to hook color state logging according to DCN version.

Signed-off-by: Melissa Wen 
---
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 27 +--
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index 9834b75f1837..d82e49045fbc 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -278,19 +278,14 @@ static void dcn10_log_hubp_states(struct dc *dc, void 
*log_ctx)
DTN_INFO("\n");
 }
 
-void dcn10_log_hw_state(struct dc *dc,
-   struct dc_log_buffer_ctx *log_ctx)
+static void
+dcn10_log_color_state(struct dc *dc,
+ struct dc_log_buffer_ctx *log_ctx)
 {
struct dc_context *dc_ctx = dc->ctx;
struct resource_pool *pool = dc->res_pool;
int i;
 
-   DTN_INFO_BEGIN();
-
-   dcn10_log_hubbub_state(dc, log_ctx);
-
-   dcn10_log_hubp_states(dc, log_ctx);
-
DTN_INFO("DPP:IGAM format  IGAM modeDGAM modeRGAM mode"
"  GAMUT mode  C11 C12   C13 C14   C21 C22   C23 C24   "
"C31 C32   C33 C34\n");
@@ -347,6 +342,22 @@ void dcn10_log_hw_state(struct dc *dc,
s.idle);
}
DTN_INFO("\n");
+}
+
+void dcn10_log_hw_state(struct dc *dc,
+   struct dc_log_buffer_ctx *log_ctx)
+{
+   struct dc_context *dc_ctx = dc->ctx;
+   struct resource_pool *pool = dc->res_pool;
+   int i;
+
+   DTN_INFO_BEGIN();
+
+   dcn10_log_hubbub_state(dc, log_ctx);
+
+   dcn10_log_hubp_states(dc, log_ctx);
+
+   dcn10_log_color_state(dc, log_ctx);
 
DTN_INFO("OTG:  v_bs  v_be  v_ss  v_se  vpol  vmax  vmin  vmax_sel  
vmin_sel  h_bs  h_be  h_ss  h_se  hpol  htot  vtot  underflow blank_en\n");
 
-- 
2.40.1



[RFC PATCH 0/5] drm/amd/display: improve DTN color state log

2023-09-05 Thread Melissa Wen
Hi,

I'm updating the color state part of DTN log to match DCN3.0 HW better.
Currently, the DTN log considers the DCN10 color pipeline, which is
useless for DCN3.0 because of all the differences in color caps between
DCN versions. In addition to new color blocks and caps, some semantic
differences made the DCN10 output not fit DCN30.

In this RFC, the first patch adds new color state elements to DPP and
implements the reading of registers according to HW blocks. Similarly to
MPC, the second patch also creates a DCN3-specific function to read the
MPC state and add the MPC color state logging to it. With DPP and MPC
color-register reading, I detach DCN10 color state logging from the HW
log and create a `.log_color_state` hook for logging color state
according to HW color blocks with DCN30 as the first use case. Finally,
the last patch adds DPP and MPC color caps output to facilitate
understanding of the color state log.

This version works well with the driver-specific color properties[1] and
steamdeck/gamescope[2] together, where we can see color state changing
from default values.

Before extending it to other DCN families, I have some doubts. Does this
approach of the `.log_color_state` hook make sense for you? Is there any
conflict between logging color state by HW version and DTN log usage? Is
there a template/style for DTN log output that I should follow?

Let me know your thoughts.

Thanks,

Melissa

[1] https://lore.kernel.org/amd-gfx/20230810160314.48225-1-m...@igalia.com/
[2] https://github.com/ValveSoftware/gamescope

Melissa Wen (5):
  drm/amd/display: detach color state from hw state logging
  drm/amd/display: fill up DCN3 DPP color state
  drm/amd/display: create DCN3-specific log for MPC state
  drm/amd/display: hook DCN30 color state logging to DTN log
  drm/amd/display: add DPP and MPC color caps to DTN log

 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |  53 +++--
 .../gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c  |  28 -
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.c| 112 ++
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.h|   3 +
 .../gpu/drm/amd/display/dc/dcn30/dcn30_init.c |   1 +
 .../gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c  |  55 -
 .../drm/amd/display/dc/dcn301/dcn301_init.c   |   1 +
 drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h   |   8 ++
 drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h   |  13 ++
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |   2 +
 10 files changed, 264 insertions(+), 12 deletions(-)

-- 
2.40.1



[PATCH] drm/amdgpu: Handle null atom context in VBIOS info ioctl

2023-09-05 Thread David Francis
On some APU systems, there is no atom context and so the
atom_context struct is null.

Add a check to the VBIOS_INFO branch of amdgpu_info_ioctl
to handle this case, returning all zeroes.

Signed-off-by: David Francis 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 3a48bec10aea..86748290ead7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -947,16 +947,21 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
? -EFAULT : 0;
}
case AMDGPU_INFO_VBIOS_INFO: {
-   struct drm_amdgpu_info_vbios vbios_info = {};
+   struct drm_amdgpu_info_vbios vbios_info = {0};
struct atom_context *atom_context;
 
atom_context = adev->mode_info.atom_context;
-   memcpy(vbios_info.name, atom_context->name, 
sizeof(atom_context->name));
-   memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, 
sizeof(atom_context->vbios_pn));
-   vbios_info.version = atom_context->version;
-   memcpy(vbios_info.vbios_ver_str, 
atom_context->vbios_ver_str,
-   
sizeof(atom_context->vbios_ver_str));
-   memcpy(vbios_info.date, atom_context->date, 
sizeof(atom_context->date));
+   if (atom_context) {
+   memcpy(vbios_info.name, atom_context->name,
+  sizeof(atom_context->name));
+   memcpy(vbios_info.vbios_pn, 
atom_context->vbios_pn,
+  sizeof(atom_context->vbios_pn));
+   vbios_info.version = atom_context->version;
+   memcpy(vbios_info.vbios_ver_str, 
atom_context->vbios_ver_str,
+  sizeof(atom_context->vbios_ver_str));
+   memcpy(vbios_info.date, atom_context->date,
+  sizeof(atom_context->date));
+   }
 
return copy_to_user(out, _info,
min((size_t)size, 
sizeof(vbios_info))) ? -EFAULT : 0;
-- 
2.34.1



Re: [PATCH 00/18] drm/amd/display: Enable writeback for amdgpu

2023-09-05 Thread Harry Wentland
Can we boot the system if we only apply patces 1-3? If not, we might
want to move patch 2 to the end of the series.

A bunch of these patches are from me. Would be good if they can get a
Reviewed-by from you (or someone else, other than me) before merging.

Series is
Reviewed-by: Harry Wentland 

Harry

On 2023-08-16 17:26, Alex Hung wrote:
> This patchset adds drm_writeback connector supports and enables display
> writeback block (DWB) in AMD hardware.
> 
> The function can be tested by IGT's kms_writeback test which also
> requires a number of patches to enable 10bit (DRM_FORMAT_XRGB2101010).
> Patches are available @ https://patchwork.freedesktop.org/series/122536/
> 
> Alex Hung (10):
>   drm/amd/display: Initialize writeback connector
>   drm/amd/display: Hande writeback request from userspace
>   drm/amd/display: Add writeback enable/disable in dc
>   drm/amd/display: Fix writeback_info never got updated
>   drm/amd/display: Validate hw_points_num before using it
>   drm/amd/display: Fix writeback_info is not removed
>   drm/amd/display: Add writeback enable field (wb_enabled)
>   drm/amd/display: Setup for mmhubbub3_warmup_mcif with big buffer
>   drm/amd/display: Add new set_fc_enable to struct dwbc_funcs
>   drm/amd/display: Disable DWB frame capture to emulate oneshot
> 
> Harry Wentland (8):
>   drm/amd/display: Skip entire amdgpu_dm build if !CONFIG_DRM_AMD_DC
>   drm/amd/display: Create one virtual connector in DC
>   drm/amd/display: Skip writeback connector when we get
> amdgpu_dm_connector
>   drm/amd/display: Return drm_connector from
> find_first_crtc_matching_connector
>   drm/amd/display: Use drm_connector in create_stream_for_sink
>   drm/amd/display: Use drm_connector in create_validate_stream_for_sink
>   drm/amd/display: Create amdgpu_dm_wb_connector
>   drm/amd/display: Create fake sink and stream for writeback connector
> 
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |   4 +
>  .../gpu/drm/amd/display/amdgpu_dm/Makefile|  14 +-
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 375 --
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  12 +-
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c |   3 +
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c |  22 +-
>  .../display/amdgpu_dm/amdgpu_dm_mst_types.c   |   8 +-
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c  | 215 ++
>  .../drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h  |  36 ++
>  .../gpu/drm/amd/display/dc/core/dc_stream.c   |  80 +++-
>  drivers/gpu/drm/amd/display/dc/dc_stream.h|   4 +
>  .../gpu/drm/amd/display/dc/dcn30/dcn30_dwb.c  |  23 ++
>  .../gpu/drm/amd/display/dc/dcn30/dcn30_dwb.h  |   2 +
>  .../drm/amd/display/dc/dcn30/dcn30_dwb_cm.c   |   3 +
>  .../drm/amd/display/dc/dcn30/dcn30_hwseq.c|   4 +
>  .../drm/amd/display/dc/dcn31/dcn31_hwseq.c|   3 +-
>  drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h   |   4 +
>  17 files changed, 742 insertions(+), 70 deletions(-)
>  create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
>  create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.h
> 



Re: [PATCH] drm/amdkfd: Use partial migrations in GPU page faults

2023-09-05 Thread Philip Yang

  


On 2023-08-31 17:29, Chen, Xiaogang
  wrote:


  
  On 8/31/2023 3:59 PM, Felix Kuehling wrote:
  
  On 2023-08-31 16:33, Chen, Xiaogang wrote:


  

  

  That said, I'm not actually
sure why we're freeing the DMA address array after
migration to RAM at all. I think we still need it
even when we're using VRAM. We call
svm_range_dma_map in svm_range_validate_and_map
regardless of whether the range is in VRAM or system
memory. So it will just allocate a new array the
next time the range is validated anyway. VRAM pages
use a special address encoding to indicate VRAM
pages to the GPUVM code.

  
  
  I think we do not need free DMA address array as you
  said, it is another thing though.
  
  
  We need unmap dma address(dma_unmap_page) after
  migrate from ram to vram because we always do
  dma_map_page at svm_range_validate_and_map. If not we
  would have multiple dma maps for same sys ram page.
  


svm_range_dma_map_dev calls dma_unmap_page before
overwriting an existing valid entry in the dma_addr
array. Anyway, dma unmapping the old pages in bulk may
still be cleaner. And it avoids delays in cleaning up
DMA mappings after migrations.


Regards,

  Felix



  
  then we may not need do dma_unmap after migrate from ram
  to vram since svm_range_dma_map_dev always do
  dma_unmap_page if the address is valid dma address for sys
  ram, and after migrate from ram to vram we always do gpu
  mapping?
  


I think with XNACK enabled, the DMA mapping may be delayed
until a page fault. For example on a multi-GPU system, GPU1
page faults and migrates data from system memory to its
VRAM. Immediately afterwards, the page fault handler should
use svm_validate_and_map to update GPU1 page tables. But
GPU2 page tables are not updated immediately. So the now
stale DMA mappings for GPU2 would continue to exist until
the next page fault on GPU2.


Regards,

  Felix


  
  If I understand correctly: when user call svm_range_set_attr,
  if p->xnack_enabled is true, we can skip call
  svm_range_validate_and_map. We postpone the buffer validating
  and gpu mapping until page fault or the time the buffer really
  got used by a GPU, and only dma map and gpu map for this GPU.
  


The current implementation of svm_range_set_attr skips the
validation after migration if XNACK is off, because it is
handled by svm_range_restore_work that gets scheduled by the MMU
notifier triggered by the migration.


With XNACK on, svm_range_set_attr currently validates and maps
after migration assuming that the data will be used by the
GPU(s) soon. That is something we could change and let page
faults take care of the mappings as needed.


  
  Yes, with xnack on, my understanding is we can skip
  svm_range_validate_and_map at svm_range_set_attr after migration,
  then page fault handler will do dma and gpu mapping. That would
  save the first time dma and gpu mapping which apply to all GPUs
  that user ask for access. Then current gpu page fault handler just
  does dma and gpu mapping for the GPU that triggered page fault. Is
  that ok?
  

With xnack on, after prefetch the range to GPU, need
  svm_range_validate_and_map to update the mapping of the GPU
  migrated to (also the mapping of GPUs with access_in_place),
  because app prefetch to GPU to avoid GPU page fault.
After migrating to VRAM, we only need dma_unmap_page from
  prange->dma_addr array, don't need to free the dma_addr array
  itself, as it can be reused to store VRAM address to map to GPU. 

Regards,
Philip


  
  Regards
  
  
  Xiaogang
  
  
  Regards,

  Felix



  
  
  

  
  Regards
  
  
 

Re: [V3 0/7] A new set of Linux OD interfaces

2023-09-05 Thread Alex Deucher
On Sun, Sep 3, 2023 at 9:23 PM Quan, Evan  wrote:
>
> [AMD Official Use Only - General]
>
> Actually, with my original design, there indeed came with an 'r' option 
> support.
> But I found that brings some confusion. Since per current 'r' option design, 
> it will
> reset all attributes back to original states. Thus I dropped it.
>
> If to support 'r' option per attribute, some redesigns to current logics will 
> be needed
> to support both legacy and the new OD interfaces. That will need some extra 
> efforts.
> Maybe we can put that on our TODO list?

Wouldn't it just reset the values of the attributes to the initial
value?  E.g., for the curve, it would be useful to have a way to set
the curve back to the initial settings after messing with it.

Alex

>
> Evan
> > -Original Message-
> > From: Alex Deucher 
> > Sent: Friday, September 1, 2023 1:26 AM
> > To: Quan, Evan 
> > Cc: amd-gfx@lists.freedesktop.org; Deucher, Alexander
> > 
> > Subject: Re: [V3 0/7] A new set of Linux OD interfaces
> >
> > For consistency with the other OD interface, we'd probably want an "r"
> > option to reset each attribute to the default state again.
> >
> > Alex
> >
> > On Wed, Aug 30, 2023 at 9:33 AM Alex Deucher 
> > wrote:
> > >
> > > Series is:
> > > Reviewed-by: Alex Deucher 
> > >
> > > On Wed, Aug 30, 2023 at 2:35 AM Evan Quan 
> > wrote:
> > > >
> > > > The existing OD interface `pp_od_clk_voltage` is unable to meet the
> > > > growing demands for more OD functionalities. Since the buf used
> > > > within it comes with size limit as one page. With more OD
> > > > functionalities added, we will hit that limit soon.
> > > >
> > > > To better meet the growing demainds, a new set of OD interfaces are
> > designed.
> > > > With this new design, there will be multiple interfaces exposed with
> > > > each representing a single OD functionality. And all those
> > > > interfaces will be arranged in a tree liked hierarchy as below.
> > > > Meanwhile all functionalities for the same component will be arranged
> > under the same directory.
> > > >
> > > > gpu_od/
> > > > ├── fan_ctrl
> > > > │   ├── acoustic_limit_rpm_threshold
> > > > │   ├── acoustic_target_rpm_threshold
> > > > │   ├── fan_curve
> > > > │   ├── fan_minimum_pwm
> > > > │   ├── fan_target_temperature
> > > >
> > > > Evan Quan (7):
> > > >   drm/amd/pm: introduce a new set of OD interfaces
> > > >   drm/amdgpu: revise the device initialization sequences
> > > >   drm/amd/pm: add fan temperature/pwm curve OD setting support for
> > SMU13
> > > >   drm/amd/pm: add fan acoustic limit OD setting support for SMU13
> > > >   drm/amd/pm: add fan acoustic target OD setting support for SMU13
> > > >   drm/amd/pm: add fan target temperature OD setting support for SMU13
> > > >   drm/amd/pm: add fan minimum pwm OD setting support for SMU13
> > > >
> > > >  Documentation/gpu/amdgpu/thermal.rst  |  30 +
> > > >  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c|  39 +-
> > > >  .../gpu/drm/amd/include/kgd_pp_interface.h|  12 +-
> > > >  drivers/gpu/drm/amd/pm/amdgpu_pm.c| 730
> > +-
> > > >  drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h   |  14 +
> > > >  drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c |  10 +
> > > >  drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h  |   5 +
> > > >  .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c  | 298 ++-
> > > > .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c  | 298 ++-
> > > >  9 files changed, 1411 insertions(+), 25 deletions(-)
> > > >
> > > > --
> > > > 2.34.1
> > > >


Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread suijingfeng

Hi,


On 2023/9/5 18:45, Thomas Zimmermann wrote:

Hi

Am 04.09.23 um 21:57 schrieb Sui Jingfeng:

From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned


If anything, the primary graphics adapter is the one initialized by 
the firmware. I think our boot-up graphics also make this assumption 
implicitly.




Yes, but by the time of DRM drivers get loaded successfully,the boot-up 
graphics already finished.
Firmware framebuffer device already get killed by the 
drm_aperture_remove_conflicting_pci_framebuffers()
function (or its siblings). So, this series is definitely not to interact with 
the firmware framebuffer
(or more intelligent framebuffer drivers).  It is for user space program, such 
as X server and Wayland
compositor. Its for Linux user or drm drivers testers, which allow them to 
direct graphic display server
using right hardware of interested as primary video card.

Also, I believe that X server and Wayland compositor are the best test examples.
If a specific DRM driver can't work with X server as a primary,
then there probably have something wrong.



But what's the use case for overriding this setting?



On a specific machine with multiple GPUs mounted,
only the primary graphics get POST-ed (initialized) by the firmware.
Therefore, the DRM drivers for the rest video cards, have to choose to
work without the prerequisite setups done by firmware, This is called as POST.

One of the use cases of this series is to test if a specific DRM driver could 
works properly,
even though there is no prerequisite works have been done by firmware at all.
And it seems that the results is not satisfying in all cases.

drm/ast is the first drm drivers which refused to work if not being POST-ed by 
the firmware.

Before apply this series, I was unable make drm/ast as the primary video card 
easily. On a
multiple video card configuration, the monitor connected with the AST2400 not 
light up.
While confusing, a naive programmer may suspect the PRIME is not working.

After applied this series and passing ast.modeset=10 on the kernel cmd line,
I found that the monitor connected with my ast2400 video card still black,
It doesn't display and doesn't show image to me.

While in the process of study drm/ast, I know that drm/ast driver has the POST 
code shipped.
See the ast_post_gpu() function, then, I was wondering why this function 
doesn't works.
After a short-time (hasty) debugging, I found that the the ast_post_gpu() 
function
didn't get run. Because it have something to do with the ast->config_mode.

Without thinking too much, I hardcoded the ast->config_mode as ast_use_p2a to
force the ast_post_gpu() function get run.

```

--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -132,6 +132,8 @@ static int ast_device_config_init(struct ast_device 
*ast)

    }
    }

+   ast->config_mode = ast_use_p2a;
+
    switch (ast->config_mode) {
    case ast_use_defaults:
    drm_info(dev, "Using default configuration\n");

```

Then, the monitor light up, it display the Ubuntu greeter to me.
Therefore, my patch is helpful, at lease for the Linux drm driver tester and 
developer.
It allow programmers to test the specific part of the specific drive
without changing a line of the source code and without the need of sudo 
authority.
It helps to improve efficiency of the testing and patch verification.

I know the PrimaryGPU option of Xorg conf, but this approach will remember the 
setup
have been made, you need modify it with root authority each time you want to 
switch
the primary. But on rapid developing and/or testing multiple video drivers, with
only one computer hardware resource available. What we really want probably is a
one-shoot command as this series provide.

So, this is the first use case. This probably also help to test full modeset,
PRIME and reverse PRIME on multiple video card machine.



Best regards
Thomas





Re: [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Christian König

Am 05.09.23 um 12:38 schrieb Jani Nikula:

On Tue, 05 Sep 2023, Sui Jingfeng  wrote:

From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned
problem by introduced the ->be_primary() function stub. The specific
device drivers can provide an implementation to hook up with this stub by
calling the vga_client_register() function.

Once the driver bound the device successfully, VGAARB will call back to
the device driver. To query if the device drivers want to be primary or
not. Device drivers can just pass NULL if have no such needs.

Please note that:

1) The ARM64, Loongarch, Mips servers have a lot PCIe slot, and I would
like to mount at least three video cards.


Well, you rarely find a board which can actually handle a single one :)



2) Typically, those non-86 machines don't have a good UEFI firmware
support, which doesn't support select primary GPU as firmware stage.
Even on x86, there are old UEFI firmwares which already made undesired
decision for you.

3) This series is attempt to solve the remain problems at the driver level,
while another series[1] of me is target to solve the majority of the
problems at device level.

Tested (limited) on x86 with four video card mounted, Intel UHD Graphics
630 is the default boot VGA, successfully override by ast2400 with
ast.modeset=10 append at the kernel cmd line.

The value 10 is incredibly arbitrary, and multiplied as a magic number
all over the place.


+1




$ lspci | grep VGA

  00:02.0 VGA compatible controller: Intel Corporation CoffeeLake-S GT2 [UHD 
Graphics 630]
  01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] 
Caicos XTX [Radeon HD 8490 / R5 235X OEM]
  04:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics 
Family (rev 30)
  05:00.0 VGA compatible controller: NVIDIA Corporation GK208B [GeForce GT 720] 
(rev a1)

In this example, all of the GPUs are driven by different drivers. What
good does a module parameter do if you have multiple GPUs of the same
model, all driven by the same driver module?


Completely agree. Question is what is the benefit for the end user to 
actually specify this?


If you want the initial console on a different device than implement a 
kernel options for vgaarb and *not* the drivers.


Regards,
Christian.



BR,
Jani.


$ sudo dmesg | grep vgaarb

  pci :00:02.0: vgaarb: setting as boot VGA device
  pci :00:02.0: vgaarb: VGA device added: 
decodes=io+mem,owns=io+mem,locks=none
  pci :01:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
  pci :04:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
  pci :05:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
  vgaarb: loaded
  ast :04:00.0: vgaarb: Override as primary by driver
  i915 :00:02.0: vgaarb: changed VGA decodes: 
olddecodes=io+mem,decodes=none:owns=io+mem
  radeon :01:00.0: vgaarb: changed VGA decodes: 
olddecodes=io+mem,decodes=none:owns=none
  ast :04:00.0: vgaarb: changed VGA decodes: 
olddecodes=io+mem,decodes=none:owns=none

v2:
* Add a simple implemment for drm/i915 and drm/ast
* Pick up all tags (Mario)
v3:
* Fix a mistake for drm/i915 implement
* Fix patch can not be applied problem because of merge conflect.
v4:
* Focus on solve the real problem.

v1,v2 at https://patchwork.freedesktop.org/series/120059/
v3 at https://patchwork.freedesktop.org/series/120562/

[1] https://patchwork.freedesktop.org/series/122845/

Sui Jingfeng (9):
   PCI/VGA: Allowing the user to select the primary video adapter at boot
 time
   drm/nouveau: Implement .be_primary() callback
   drm/radeon: Implement .be_primary() callback
   drm/amdgpu: Implement .be_primary() callback
   drm/i915: Implement .be_primary() callback
   drm/loongson: Implement .be_primary() callback
   drm/ast: Register as a VGA client by calling vga_client_register()
   drm/hibmc: Register as a VGA client by calling vga_client_register()
   drm/gma500: Register as a VGA client by calling vga_client_register()

  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 11 +++-
  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   | 13 -
  drivers/gpu/drm/ast/ast_drv.c | 31 ++
  drivers/gpu/drm/gma500/psb_drv.c  | 57 ++-
  .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   | 15 +
  drivers/gpu/drm/i915/display/intel_vga.c  | 15 -
  drivers/gpu/drm/loongson/loongson_module.c|  2 +-
  drivers/gpu/drm/loongson/loongson_module.h|  1 +
  drivers/gpu/drm/loongson/lsdc_drv.c   | 10 +++-
  drivers/gpu/drm/nouveau/nouveau_vga.c | 11 +++-
  drivers/gpu/drm/radeon/radeon_device.c| 10 +++-
  drivers/pci/vgaarb.c  | 43 --
  drivers/vfio/pci/vfio_pci_core.c  |  2 +-
  

Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Thomas Zimmermann

Hi

Am 04.09.23 um 21:57 schrieb Sui Jingfeng:

From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned
problem by introduced the ->be_primary() function stub. The specific
device drivers can provide an implementation to hook up with this stub by
calling the vga_client_register() function.

Once the driver bound the device successfully, VGAARB will call back to
the device driver. To query if the device drivers want to be primary or
not. Device drivers can just pass NULL if have no such needs.

Please note that:

1) The ARM64, Loongarch, Mips servers have a lot PCIe slot, and I would
like to mount at least three video cards.

2) Typically, those non-86 machines don't have a good UEFI firmware
support, which doesn't support select primary GPU as firmware stage.
Even on x86, there are old UEFI firmwares which already made undesired
decision for you.

3) This series is attempt to solve the remain problems at the driver level,
while another series[1] of me is target to solve the majority of the
problems at device level.

Tested (limited) on x86 with four video card mounted, Intel UHD Graphics
630 is the default boot VGA, successfully override by ast2400 with
ast.modeset=10 append at the kernel cmd line.


FYI: per-driver modeset parameters are deprecated and not to be used. 
Please don't promote them. You can use modprobe.blacklist or 
initcall_blacklist on the kernel command line.


Best regards
Thomas



$ lspci | grep VGA

  00:02.0 VGA compatible controller: Intel Corporation CoffeeLake-S GT2 [UHD 
Graphics 630]
  01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] 
Caicos XTX [Radeon HD 8490 / R5 235X OEM]
  04:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics 
Family (rev 30)
  05:00.0 VGA compatible controller: NVIDIA Corporation GK208B [GeForce GT 720] 
(rev a1)

$ sudo dmesg | grep vgaarb

  pci :00:02.0: vgaarb: setting as boot VGA device
  pci :00:02.0: vgaarb: VGA device added: 
decodes=io+mem,owns=io+mem,locks=none
  pci :01:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
  pci :04:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
  pci :05:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
  vgaarb: loaded
  ast :04:00.0: vgaarb: Override as primary by driver
  i915 :00:02.0: vgaarb: changed VGA decodes: 
olddecodes=io+mem,decodes=none:owns=io+mem
  radeon :01:00.0: vgaarb: changed VGA decodes: 
olddecodes=io+mem,decodes=none:owns=none
  ast :04:00.0: vgaarb: changed VGA decodes: 
olddecodes=io+mem,decodes=none:owns=none

v2:
* Add a simple implemment for drm/i915 and drm/ast
* Pick up all tags (Mario)
v3:
* Fix a mistake for drm/i915 implement
* Fix patch can not be applied problem because of merge conflect.
v4:
* Focus on solve the real problem.

v1,v2 at https://patchwork.freedesktop.org/series/120059/
v3 at https://patchwork.freedesktop.org/series/120562/

[1] https://patchwork.freedesktop.org/series/122845/

Sui Jingfeng (9):
   PCI/VGA: Allowing the user to select the primary video adapter at boot
 time
   drm/nouveau: Implement .be_primary() callback
   drm/radeon: Implement .be_primary() callback
   drm/amdgpu: Implement .be_primary() callback
   drm/i915: Implement .be_primary() callback
   drm/loongson: Implement .be_primary() callback
   drm/ast: Register as a VGA client by calling vga_client_register()
   drm/hibmc: Register as a VGA client by calling vga_client_register()
   drm/gma500: Register as a VGA client by calling vga_client_register()

  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 11 +++-
  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   | 13 -
  drivers/gpu/drm/ast/ast_drv.c | 31 ++
  drivers/gpu/drm/gma500/psb_drv.c  | 57 ++-
  .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   | 15 +
  drivers/gpu/drm/i915/display/intel_vga.c  | 15 -
  drivers/gpu/drm/loongson/loongson_module.c|  2 +-
  drivers/gpu/drm/loongson/loongson_module.h|  1 +
  drivers/gpu/drm/loongson/lsdc_drv.c   | 10 +++-
  drivers/gpu/drm/nouveau/nouveau_vga.c | 11 +++-
  drivers/gpu/drm/radeon/radeon_device.c| 10 +++-
  drivers/pci/vgaarb.c  | 43 --
  drivers/vfio/pci/vfio_pci_core.c  |  2 +-
  include/linux/vgaarb.h|  8 ++-
  14 files changed, 210 insertions(+), 19 deletions(-)



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


OpenPGP_signature
Description: OpenPGP digital signature


Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Thomas Zimmermann

Hi

Am 04.09.23 um 21:57 schrieb Sui Jingfeng:

From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned


If anything, the primary graphics adapter is the one initialized by the 
firmware. I think our boot-up graphics also make this assumption implicitly.


But what's the use case for overriding this setting?

Best regards
Thomas


problem by introduced the ->be_primary() function stub. The specific
device drivers can provide an implementation to hook up with this stub by
calling the vga_client_register() function.

Once the driver bound the device successfully, VGAARB will call back to
the device driver. To query if the device drivers want to be primary or
not. Device drivers can just pass NULL if have no such needs.

Please note that:

1) The ARM64, Loongarch, Mips servers have a lot PCIe slot, and I would
like to mount at least three video cards.

2) Typically, those non-86 machines don't have a good UEFI firmware
support, which doesn't support select primary GPU as firmware stage.
Even on x86, there are old UEFI firmwares which already made undesired
decision for you.

3) This series is attempt to solve the remain problems at the driver level,
while another series[1] of me is target to solve the majority of the
problems at device level.

Tested (limited) on x86 with four video card mounted, Intel UHD Graphics
630 is the default boot VGA, successfully override by ast2400 with
ast.modeset=10 append at the kernel cmd line.

$ lspci | grep VGA

  00:02.0 VGA compatible controller: Intel Corporation CoffeeLake-S GT2 [UHD 
Graphics 630]
  01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] 
Caicos XTX [Radeon HD 8490 / R5 235X OEM]
  04:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics 
Family (rev 30)
  05:00.0 VGA compatible controller: NVIDIA Corporation GK208B [GeForce GT 720] 
(rev a1)

$ sudo dmesg | grep vgaarb

  pci :00:02.0: vgaarb: setting as boot VGA device
  pci :00:02.0: vgaarb: VGA device added: 
decodes=io+mem,owns=io+mem,locks=none
  pci :01:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
  pci :04:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
  pci :05:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
  vgaarb: loaded
  ast :04:00.0: vgaarb: Override as primary by driver
  i915 :00:02.0: vgaarb: changed VGA decodes: 
olddecodes=io+mem,decodes=none:owns=io+mem
  radeon :01:00.0: vgaarb: changed VGA decodes: 
olddecodes=io+mem,decodes=none:owns=none
  ast :04:00.0: vgaarb: changed VGA decodes: 
olddecodes=io+mem,decodes=none:owns=none

v2:
* Add a simple implemment for drm/i915 and drm/ast
* Pick up all tags (Mario)
v3:
* Fix a mistake for drm/i915 implement
* Fix patch can not be applied problem because of merge conflect.
v4:
* Focus on solve the real problem.

v1,v2 at https://patchwork.freedesktop.org/series/120059/
v3 at https://patchwork.freedesktop.org/series/120562/

[1] https://patchwork.freedesktop.org/series/122845/

Sui Jingfeng (9):
   PCI/VGA: Allowing the user to select the primary video adapter at boot
 time
   drm/nouveau: Implement .be_primary() callback
   drm/radeon: Implement .be_primary() callback
   drm/amdgpu: Implement .be_primary() callback
   drm/i915: Implement .be_primary() callback
   drm/loongson: Implement .be_primary() callback
   drm/ast: Register as a VGA client by calling vga_client_register()
   drm/hibmc: Register as a VGA client by calling vga_client_register()
   drm/gma500: Register as a VGA client by calling vga_client_register()

  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 11 +++-
  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   | 13 -
  drivers/gpu/drm/ast/ast_drv.c | 31 ++
  drivers/gpu/drm/gma500/psb_drv.c  | 57 ++-
  .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   | 15 +
  drivers/gpu/drm/i915/display/intel_vga.c  | 15 -
  drivers/gpu/drm/loongson/loongson_module.c|  2 +-
  drivers/gpu/drm/loongson/loongson_module.h|  1 +
  drivers/gpu/drm/loongson/lsdc_drv.c   | 10 +++-
  drivers/gpu/drm/nouveau/nouveau_vga.c | 11 +++-
  drivers/gpu/drm/radeon/radeon_device.c| 10 +++-
  drivers/pci/vgaarb.c  | 43 --
  drivers/vfio/pci/vfio_pci_core.c  |  2 +-
  include/linux/vgaarb.h|  8 ++-
  14 files changed, 210 insertions(+), 19 deletions(-)



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


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH] drm/amd: Fix the flag setting code for interrupt request

2023-09-05 Thread Ma, Jun



On 9/5/2023 1:24 PM, Christian König wrote:
> Am 04.09.23 um 08:05 schrieb Ma Jun:
>> [1] Remove the irq flags setting code since pci_alloc_irq_vectors()
>> handles these flags.
>> [2] Free the msi vectors in case of error.
>>
>> Signed-off-by: Ma Jun 
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 43 ++---
>>   1 file changed, 25 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>> index fa6d0adcec20..17043a1e37a5 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>> @@ -271,28 +271,28 @@ static void amdgpu_restore_msix(struct amdgpu_device 
>> *adev)
>>   int amdgpu_irq_init(struct amdgpu_device *adev)
>>   {
>>  int r = 0;
> 
> While at it please remove the assignment here.
> 
> Unless really necessary initializing local variables is rather frowned upon.
> 

Thanks for review. Will fix it in the next version.

Regards,
Ma Jun

> Apart from that Alex needs to take a look at this, I'm not that familiar 
> with this code.
> 
> Christian.
> 
>> -unsigned int irq;
>> +unsigned int irq, flags;
>>   
>>  spin_lock_init(>irq.lock);
>>   
>>  /* Enable MSI if not disabled by module parameter */
>>  adev->irq.msi_enabled = false;
>>   
>> +if (amdgpu_msi_ok(adev))
>> +flags = PCI_IRQ_MSI | PCI_IRQ_MSIX;
>> +else
>> +flags = PCI_IRQ_LEGACY;
>> +
>> +/* we only need one vector */
>> +r = pci_alloc_irq_vectors(adev->pdev, 1, 1, flags);
>> +if (r < 0) {
>> +dev_err(adev->dev, "Failed to alloc msi vectors\n");
>> +return r;
>> +}
>> +
>>  if (amdgpu_msi_ok(adev)) {
>> -int nvec = pci_msix_vec_count(adev->pdev);
>> -unsigned int flags;
>> -
>> -if (nvec <= 0)
>> -flags = PCI_IRQ_MSI;
>> -else
>> -flags = PCI_IRQ_MSI | PCI_IRQ_MSIX;
>> -
>> -/* we only need one vector */
>> -nvec = pci_alloc_irq_vectors(adev->pdev, 1, 1, flags);
>> -if (nvec > 0) {
>> -adev->irq.msi_enabled = true;
>> -dev_dbg(adev->dev, "using MSI/MSI-X.\n");
>> -}
>> +adev->irq.msi_enabled = true;
>> +dev_dbg(adev->dev, "using MSI/MSI-X.\n");
>>  }
>>   
>>  INIT_WORK(>irq.ih1_work, amdgpu_irq_handle_ih1);
>> @@ -302,22 +302,29 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
>>  /* Use vector 0 for MSI-X. */
>>  r = pci_irq_vector(adev->pdev, 0);
>>  if (r < 0)
>> -return r;
>> +goto free_vectors;
>>  irq = r;
>>   
>>  /* PCI devices require shared interrupts. */
>>  r = request_irq(irq, amdgpu_irq_handler, IRQF_SHARED, 
>> adev_to_drm(adev)->driver->name,
>>  adev_to_drm(adev));
>>  if (r)
>> -return r;
>> +goto free_vectors;
>> +
>>  adev->irq.installed = true;
>>  adev->irq.irq = irq;
>>  adev_to_drm(adev)->max_vblank_count = 0x00ff;
>>   
>>  DRM_DEBUG("amdgpu: irq initialized.\n");
>>  return 0;
>> -}
>>   
>> +free_vectors:
>> +if (adev->irq.msi_enabled)
>> +pci_free_irq_vectors(adev->pdev);
>> +
>> +adev->irq.msi_enabled = false;
>> +return r;
>> +}
>>   
>>   void amdgpu_irq_fini_hw(struct amdgpu_device *adev)
>>   {
> 


Re: [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Jani Nikula
On Tue, 05 Sep 2023, Sui Jingfeng  wrote:
> From: Sui Jingfeng 
>
> On a machine with multiple GPUs, a Linux user has no control over which
> one is primary at boot time. This series tries to solve above mentioned
> problem by introduced the ->be_primary() function stub. The specific
> device drivers can provide an implementation to hook up with this stub by
> calling the vga_client_register() function.
>
> Once the driver bound the device successfully, VGAARB will call back to
> the device driver. To query if the device drivers want to be primary or
> not. Device drivers can just pass NULL if have no such needs.
>
> Please note that:
>
> 1) The ARM64, Loongarch, Mips servers have a lot PCIe slot, and I would
>like to mount at least three video cards.
>
> 2) Typically, those non-86 machines don't have a good UEFI firmware
>support, which doesn't support select primary GPU as firmware stage.
>Even on x86, there are old UEFI firmwares which already made undesired
>decision for you.
>
> 3) This series is attempt to solve the remain problems at the driver level,
>while another series[1] of me is target to solve the majority of the
>problems at device level.
>
> Tested (limited) on x86 with four video card mounted, Intel UHD Graphics
> 630 is the default boot VGA, successfully override by ast2400 with
> ast.modeset=10 append at the kernel cmd line.

The value 10 is incredibly arbitrary, and multiplied as a magic number
all over the place.

> $ lspci | grep VGA
>
>  00:02.0 VGA compatible controller: Intel Corporation CoffeeLake-S GT2 [UHD 
> Graphics 630]
>  01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] 
> Caicos XTX [Radeon HD 8490 / R5 235X OEM]
>  04:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics 
> Family (rev 30)
>  05:00.0 VGA compatible controller: NVIDIA Corporation GK208B [GeForce GT 
> 720] (rev a1)

In this example, all of the GPUs are driven by different drivers. What
good does a module parameter do if you have multiple GPUs of the same
model, all driven by the same driver module?

BR,
Jani.

>
> $ sudo dmesg | grep vgaarb
>
>  pci :00:02.0: vgaarb: setting as boot VGA device
>  pci :00:02.0: vgaarb: VGA device added: 
> decodes=io+mem,owns=io+mem,locks=none
>  pci :01:00.0: vgaarb: VGA device added: 
> decodes=io+mem,owns=none,locks=none
>  pci :04:00.0: vgaarb: VGA device added: 
> decodes=io+mem,owns=none,locks=none
>  pci :05:00.0: vgaarb: VGA device added: 
> decodes=io+mem,owns=none,locks=none
>  vgaarb: loaded
>  ast :04:00.0: vgaarb: Override as primary by driver
>  i915 :00:02.0: vgaarb: changed VGA decodes: 
> olddecodes=io+mem,decodes=none:owns=io+mem
>  radeon :01:00.0: vgaarb: changed VGA decodes: 
> olddecodes=io+mem,decodes=none:owns=none
>  ast :04:00.0: vgaarb: changed VGA decodes: 
> olddecodes=io+mem,decodes=none:owns=none
>
> v2:
>   * Add a simple implemment for drm/i915 and drm/ast
>   * Pick up all tags (Mario)
> v3:
>   * Fix a mistake for drm/i915 implement
>   * Fix patch can not be applied problem because of merge conflect.
> v4:
>   * Focus on solve the real problem.
>
> v1,v2 at https://patchwork.freedesktop.org/series/120059/
>v3 at https://patchwork.freedesktop.org/series/120562/
>
> [1] https://patchwork.freedesktop.org/series/122845/
>
> Sui Jingfeng (9):
>   PCI/VGA: Allowing the user to select the primary video adapter at boot
> time
>   drm/nouveau: Implement .be_primary() callback
>   drm/radeon: Implement .be_primary() callback
>   drm/amdgpu: Implement .be_primary() callback
>   drm/i915: Implement .be_primary() callback
>   drm/loongson: Implement .be_primary() callback
>   drm/ast: Register as a VGA client by calling vga_client_register()
>   drm/hibmc: Register as a VGA client by calling vga_client_register()
>   drm/gma500: Register as a VGA client by calling vga_client_register()
>
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 11 +++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   | 13 -
>  drivers/gpu/drm/ast/ast_drv.c | 31 ++
>  drivers/gpu/drm/gma500/psb_drv.c  | 57 ++-
>  .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   | 15 +
>  drivers/gpu/drm/i915/display/intel_vga.c  | 15 -
>  drivers/gpu/drm/loongson/loongson_module.c|  2 +-
>  drivers/gpu/drm/loongson/loongson_module.h|  1 +
>  drivers/gpu/drm/loongson/lsdc_drv.c   | 10 +++-
>  drivers/gpu/drm/nouveau/nouveau_vga.c | 11 +++-
>  drivers/gpu/drm/radeon/radeon_device.c| 10 +++-
>  drivers/pci/vgaarb.c  | 43 --
>  drivers/vfio/pci/vfio_pci_core.c  |  2 +-
>  include/linux/vgaarb.h|  8 ++-
>  14 files changed, 210 insertions(+), 19 deletions(-)

-- 
Jani Nikula, Intel Open Source Graphics Center


[RFC, drm-misc-next v4 9/9] drm/gma500: Register as a VGA client by calling vga_client_register()

2023-09-05 Thread Sui Jingfeng
From: Sui Jingfeng 

Because the display controller in N2000/D2000 series can be VGA-compatible,
so let's register gma500 as a VGA client, despite the firmware may alter
the PCI class code of IGD on a multiple GPU co-exist configuration. But
this commit no crime, because VGAARB only cares about VGA devices.

Noticed that the display controller in N2000/D2000 processor don't has a
valid VRAM BAR, the firmware put the EFI firmware framebuffer into the
stolen memory, so the commit <86fd887b7fe3> ("vgaarb: Don't default
exclusively to first video device with mem+io") is not effictive on such
a case. But the benefits of the stolen memory is that it will not suffer
from PCI resource relocation. Becase the stolen memory is carved out by
the firmware and reside in system RAM. Therefore, while at it, provided a
naive version of firmware framebuffer identification function and use the
new machanism just created.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/gma500/psb_drv.c | 57 ++--
 1 file changed, 55 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 8b64f61ffaf9..eb95d030d981 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -14,7 +14,7 @@
 #include 
 #include 
 #include 
-
+#include 
 #include 
 
 #include 
@@ -36,6 +36,11 @@
 #include "psb_irq.h"
 #include "psb_reg.h"
 
+static int gma500_modeset = -1;
+
+MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
+module_param_named(modeset, gma500_modeset, int, 0400);
+
 static const struct drm_driver driver;
 static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id 
*ent);
 
@@ -446,6 +451,49 @@ static int gma_remove_conflicting_framebuffers(struct 
pci_dev *pdev,
return __aperture_remove_legacy_vga_devices(pdev);
 }
 
+static bool gma_contain_firmware_fb(u64 ap_start, u64 ap_end)
+{
+   u64 fb_start;
+   u64 fb_size;
+   u64 fb_end;
+
+   if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
+   fb_start = (u64)screen_info.ext_lfb_base << 32 | 
screen_info.lfb_base;
+   else
+   fb_start = screen_info.lfb_base;
+
+   fb_size = screen_info.lfb_size;
+   fb_end = fb_start + fb_size - 1;
+
+   /* No firmware framebuffer support */
+   if (!fb_start || !fb_size)
+   return false;
+
+   if (fb_start >= ap_start && fb_end <= ap_end)
+   return true;
+
+   return false;
+}
+
+static bool gma_want_to_be_primary(struct pci_dev *pdev)
+{
+   struct drm_device *drm = pci_get_drvdata(pdev);
+   struct drm_psb_private *priv = to_drm_psb_private(drm);
+   u64 vram_base = priv->stolen_base;
+   u64 vram_size = priv->vram_stolen_size;
+
+   if (gma500_modeset == 10)
+   return true;
+
+   /* Stolen memory are not going to be moved */
+   if (gma_contain_firmware_fb(vram_base, vram_base + vram_size)) {
+   drm_dbg(drm, "Contains firmware FB in the stolen memory\n");
+   return true;
+   }
+
+   return false;
+}
+
 static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
struct drm_psb_private *dev_priv;
@@ -475,6 +523,8 @@ static int psb_pci_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
if (ret)
return ret;
 
+   vga_client_register(pdev, NULL, gma_want_to_be_primary);
+
psb_fbdev_setup(dev_priv);
 
return 0;
@@ -526,7 +576,10 @@ static struct pci_driver psb_pci_driver = {
 
 static int __init psb_init(void)
 {
-   if (drm_firmware_drivers_only())
+   if (drm_firmware_drivers_only() && (gma500_modeset == -1))
+   return -ENODEV;
+
+   if (!gma500_modeset)
return -ENODEV;
 
return pci_register_driver(_pci_driver);
-- 
2.34.1



[RFC, drm-misc-next v4 5/9] drm/i915: Implement .be_primary() callback

2023-09-05 Thread Sui Jingfeng
From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which one
is primary at boot time. This patch tries to solve the mentioned problem by
implementing the .be_primary() callback. Pass i915.modeset=10 on the kernel
cmd line if you really want the device bound by i915 drm driver to be the
primary video adapter, no matter what VGAARB say.

Cc: Jani Nikula 
Cc: David Airlie 
Cc: Daniel Vetter 
Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/i915/display/intel_vga.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_vga.c 
b/drivers/gpu/drm/i915/display/intel_vga.c
index 98d7d4dffe9f..e3f78ba2668b 100644
--- a/drivers/gpu/drm/i915/display/intel_vga.c
+++ b/drivers/gpu/drm/i915/display/intel_vga.c
@@ -113,6 +113,17 @@ intel_vga_set_decode(struct pci_dev *pdev, bool 
enable_decode)
return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
 }
 
+static bool intel_want_to_be_primary(struct pci_dev *pdev)
+{
+   struct drm_i915_private *i915 = pdev_to_i915(pdev);
+   struct i915_params *params = >params;
+
+   if (params->modeset == 10)
+   return true;
+
+   return false;
+}
+
 int intel_vga_register(struct drm_i915_private *i915)
 {
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
@@ -126,7 +137,8 @@ int intel_vga_register(struct drm_i915_private *i915)
 * then we do not take part in VGA arbitration and the
 * vga_client_register() fails with -ENODEV.
 */
-   ret = vga_client_register(pdev, intel_vga_set_decode, NULL);
+   ret = vga_client_register(pdev, intel_vga_set_decode,
+ intel_want_to_be_primary);
if (ret && ret != -ENODEV)
return ret;
 
-- 
2.34.1



[RFC, drm-misc-next v4 4/9] drm/amdgpu: Implement .be_primary() callback

2023-09-05 Thread Sui Jingfeng
From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which one
is primary at boot time. This patch tries to solve the mentioned problem by
implementing the .be_primary() callback. Pass amdgpu.modeset=10 on the
kernel cmd line if you really want the device bound by amdgpu drm driver to
be the primary video adapter, no matter what VGAARB say.

Cc: Alex Deucher 
Cc: Christian Konig 
Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 11 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c| 13 -
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index ecc4564ceac0..59bde6972a8b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -3507,6 +3507,14 @@ static void amdgpu_device_set_mcbp(struct amdgpu_device 
*adev)
DRM_INFO("MCBP is enabled\n");
 }
 
+static bool amdgpu_want_to_be_primary(struct pci_dev *pdev)
+{
+   if (amdgpu_modeset == 10)
+   return true;
+
+   return false;
+}
+
 /**
  * amdgpu_device_init - initialize the driver
  *
@@ -3916,7 +3924,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 * ignore it
 */
if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
-   vga_client_register(adev->pdev, amdgpu_device_vga_set_decode, 
NULL);
+   vga_client_register(adev->pdev, amdgpu_device_vga_set_decode,
+   amdgpu_want_to_be_primary);
 
px = amdgpu_device_supports_px(ddev);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 81edf66dbea8..2592e24ce62c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -118,6 +118,7 @@
 #define KMS_DRIVER_MINOR   54
 #define KMS_DRIVER_PATCHLEVEL  0
 
+int amdgpu_modeset = -1;
 unsigned int amdgpu_vram_limit = UINT_MAX;
 int amdgpu_vis_vram_limit;
 int amdgpu_gart_size = -1; /* auto */
@@ -223,6 +224,13 @@ struct amdgpu_watchdog_timer amdgpu_watchdog_timer = {
.period = 0x0, /* default to 0x0 (timeout disable) */
 };
 
+/**
+ * DOC: modeset (int)
+ * Disable/Enable kernel modesetting (1 = enable, 0 = disable, -1 = auto 
(default)).
+ */
+MODULE_PARM_DESC(modeset, "Disable/Enable kernel modesetting");
+module_param_named(modeset, amdgpu_modeset, int, 0600);
+
 /**
  * DOC: vramlimit (int)
  * Restrict the total amount of VRAM in MiB for testing.  The default is 0 
(Use full VRAM).
@@ -2872,7 +2880,10 @@ static int __init amdgpu_init(void)
 {
int r;
 
-   if (drm_firmware_drivers_only())
+   if (drm_firmware_drivers_only() && amdgpu_modeset == -1)
+   return -EINVAL;
+
+   if (amdgpu_modeset == 0)
return -EINVAL;
 
r = amdgpu_sync_init();
-- 
2.34.1



[RFC, drm-misc-next v4 3/9] drm/radeon: Implement .be_primary() callback

2023-09-05 Thread Sui Jingfeng
From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which one
is primary at boot time. This patch tries to solve the mentioned problem by
implementing the .be_primary() callback. Pass radeon.modeset=10 on the
kernel cmd line if you really want the device bound by radeon to be the
primary video adapter, no matter what VGAARB say.

Cc: Alex Deucher 
Cc: Christian Koenig 
Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/radeon/radeon_device.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 71f2ff39d6a1..b661cd3a8dc2 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1263,6 +1263,14 @@ static const struct vga_switcheroo_client_ops 
radeon_switcheroo_ops = {
.can_switch = radeon_switcheroo_can_switch,
 };
 
+static bool radeon_want_to_be_primary(struct pci_dev *pdev)
+{
+   if (radeon_modeset == 10)
+   return true;
+
+   return false;
+}
+
 /**
  * radeon_device_init - initialize the driver
  *
@@ -1425,7 +1433,7 @@ int radeon_device_init(struct radeon_device *rdev,
/* if we have > 1 VGA cards, then disable the radeon VGA resources */
/* this will fail for cards that aren't VGA class devices, just
 * ignore it */
-   vga_client_register(rdev->pdev, radeon_vga_set_decode, NULL);
+   vga_client_register(rdev->pdev, radeon_vga_set_decode, 
radeon_want_to_be_primary);
 
if (rdev->flags & RADEON_IS_PX)
runtime = true;
-- 
2.34.1



[RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Sui Jingfeng
From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned
problem by introduced the ->be_primary() function stub. The specific
device drivers can provide an implementation to hook up with this stub by
calling the vga_client_register() function.

Once the driver bound the device successfully, VGAARB will call back to
the device driver. To query if the device drivers want to be primary or
not. Device drivers can just pass NULL if have no such needs.

Please note that:

1) The ARM64, Loongarch, Mips servers have a lot PCIe slot, and I would
   like to mount at least three video cards.

2) Typically, those non-86 machines don't have a good UEFI firmware
   support, which doesn't support select primary GPU as firmware stage.
   Even on x86, there are old UEFI firmwares which already made undesired
   decision for you.

3) This series is attempt to solve the remain problems at the driver level,
   while another series[1] of me is target to solve the majority of the
   problems at device level.

Tested (limited) on x86 with four video card mounted, Intel UHD Graphics
630 is the default boot VGA, successfully override by ast2400 with
ast.modeset=10 append at the kernel cmd line.

$ lspci | grep VGA

 00:02.0 VGA compatible controller: Intel Corporation CoffeeLake-S GT2 [UHD 
Graphics 630]
 01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] 
Caicos XTX [Radeon HD 8490 / R5 235X OEM]
 04:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics 
Family (rev 30)
 05:00.0 VGA compatible controller: NVIDIA Corporation GK208B [GeForce GT 720] 
(rev a1)

$ sudo dmesg | grep vgaarb

 pci :00:02.0: vgaarb: setting as boot VGA device
 pci :00:02.0: vgaarb: VGA device added: 
decodes=io+mem,owns=io+mem,locks=none
 pci :01:00.0: vgaarb: VGA device added: decodes=io+mem,owns=none,locks=none
 pci :04:00.0: vgaarb: VGA device added: decodes=io+mem,owns=none,locks=none
 pci :05:00.0: vgaarb: VGA device added: decodes=io+mem,owns=none,locks=none
 vgaarb: loaded
 ast :04:00.0: vgaarb: Override as primary by driver
 i915 :00:02.0: vgaarb: changed VGA decodes: 
olddecodes=io+mem,decodes=none:owns=io+mem
 radeon :01:00.0: vgaarb: changed VGA decodes: 
olddecodes=io+mem,decodes=none:owns=none
 ast :04:00.0: vgaarb: changed VGA decodes: 
olddecodes=io+mem,decodes=none:owns=none

v2:
* Add a simple implemment for drm/i915 and drm/ast
* Pick up all tags (Mario)
v3:
* Fix a mistake for drm/i915 implement
* Fix patch can not be applied problem because of merge conflect.
v4:
* Focus on solve the real problem.

v1,v2 at https://patchwork.freedesktop.org/series/120059/
   v3 at https://patchwork.freedesktop.org/series/120562/

[1] https://patchwork.freedesktop.org/series/122845/

Sui Jingfeng (9):
  PCI/VGA: Allowing the user to select the primary video adapter at boot
time
  drm/nouveau: Implement .be_primary() callback
  drm/radeon: Implement .be_primary() callback
  drm/amdgpu: Implement .be_primary() callback
  drm/i915: Implement .be_primary() callback
  drm/loongson: Implement .be_primary() callback
  drm/ast: Register as a VGA client by calling vga_client_register()
  drm/hibmc: Register as a VGA client by calling vga_client_register()
  drm/gma500: Register as a VGA client by calling vga_client_register()

 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 11 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   | 13 -
 drivers/gpu/drm/ast/ast_drv.c | 31 ++
 drivers/gpu/drm/gma500/psb_drv.c  | 57 ++-
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   | 15 +
 drivers/gpu/drm/i915/display/intel_vga.c  | 15 -
 drivers/gpu/drm/loongson/loongson_module.c|  2 +-
 drivers/gpu/drm/loongson/loongson_module.h|  1 +
 drivers/gpu/drm/loongson/lsdc_drv.c   | 10 +++-
 drivers/gpu/drm/nouveau/nouveau_vga.c | 11 +++-
 drivers/gpu/drm/radeon/radeon_device.c| 10 +++-
 drivers/pci/vgaarb.c  | 43 --
 drivers/vfio/pci/vfio_pci_core.c  |  2 +-
 include/linux/vgaarb.h|  8 ++-
 14 files changed, 210 insertions(+), 19 deletions(-)

-- 
2.34.1



[RFC, drm-misc-next v4 6/9] drm/loongson: Implement .be_primary() callback

2023-09-05 Thread Sui Jingfeng
From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which one
is primary at boot time. This patch tries to solve the mentioned problem by
implementing the .be_primary() callback. Pass loongson.modeset=10 on the
kernel cmd line if you really want the device bound by loongson drm driver
to be the primary video adapter, no matter what VGAARB say.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/loongson/loongson_module.c |  2 +-
 drivers/gpu/drm/loongson/loongson_module.h |  1 +
 drivers/gpu/drm/loongson/lsdc_drv.c| 10 +-
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/loongson/loongson_module.c 
b/drivers/gpu/drm/loongson/loongson_module.c
index d2a51bd395f6..12f2a453adff 100644
--- a/drivers/gpu/drm/loongson/loongson_module.c
+++ b/drivers/gpu/drm/loongson/loongson_module.c
@@ -9,7 +9,7 @@
 
 #include "loongson_module.h"
 
-static int loongson_modeset = -1;
+int loongson_modeset = -1;
 MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
 module_param_named(modeset, loongson_modeset, int, 0400);
 
diff --git a/drivers/gpu/drm/loongson/loongson_module.h 
b/drivers/gpu/drm/loongson/loongson_module.h
index 931c17521bf0..afff51e7f34f 100644
--- a/drivers/gpu/drm/loongson/loongson_module.h
+++ b/drivers/gpu/drm/loongson/loongson_module.h
@@ -6,6 +6,7 @@
 #ifndef __LOONGSON_MODULE_H__
 #define __LOONGSON_MODULE_H__
 
+extern int loongson_modeset;
 extern int loongson_vblank;
 extern struct pci_driver lsdc_pci_driver;
 
diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c 
b/drivers/gpu/drm/loongson/lsdc_drv.c
index d10a28c2c494..7183b0666167 100644
--- a/drivers/gpu/drm/loongson/lsdc_drv.c
+++ b/drivers/gpu/drm/loongson/lsdc_drv.c
@@ -257,6 +257,14 @@ static unsigned int lsdc_vga_set_decode(struct pci_dev 
*pdev, bool state)
return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
 }
 
+static bool lsdc_want_to_be_primary(struct pci_dev *pdev)
+{
+   if (loongson_modeset == 10)
+   return true;
+
+   return false;
+}
+
 static int lsdc_pci_probe(struct pci_dev *pdev, const struct pci_device_id 
*ent)
 {
const struct lsdc_desc *descp;
@@ -289,7 +297,7 @@ static int lsdc_pci_probe(struct pci_dev *pdev, const 
struct pci_device_id *ent)
 
pci_set_drvdata(pdev, ddev);
 
-   vga_client_register(pdev, lsdc_vga_set_decode, NULL);
+   vga_client_register(pdev, lsdc_vga_set_decode, lsdc_want_to_be_primary);
 
drm_kms_helper_poll_init(ddev);
 
-- 
2.34.1



[RFC, drm-misc-next v4 7/9] drm/ast: Register as a VGA client by calling vga_client_register()

2023-09-05 Thread Sui Jingfeng
From: Sui Jingfeng 

Becasuse the display controller in the ASpeed BMC chip is a VGA-compatible
device, the software programming guide of AST2400 say that it is fully
IBM VGA compliant. Thus, it should also participate in the arbitration.

Cc: Thomas Zimmermann 
Cc: Jocelyn Falempe 
Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/ast/ast_drv.c | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index e1224ef4ad83..1349f7bb5dfb 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -28,6 +28,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -89,6 +90,34 @@ static const struct pci_device_id ast_pciidlist[] = {
 
 MODULE_DEVICE_TABLE(pci, ast_pciidlist);
 
+static bool ast_want_to_be_primary(struct pci_dev *pdev)
+{
+   if (ast_modeset == 10)
+   return true;
+
+   return false;
+}
+
+static unsigned int ast_vga_set_decode(struct pci_dev *pdev, bool state)
+{
+   struct drm_device *drm = pci_get_drvdata(pdev);
+   struct ast_device *ast = to_ast_device(drm);
+   unsigned int decode;
+
+   if (state) {
+   /* Enable standard VGA decode and Enable normal VGA decode */
+   ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x04);
+
+   decode = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
+VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+   } else {
+   ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x07);
+   decode = VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+   }
+
+   return decode;
+}
+
 static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
struct ast_device *ast;
@@ -112,6 +141,8 @@ static int ast_pci_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
if (ret)
return ret;
 
+   vga_client_register(pdev, ast_vga_set_decode, ast_want_to_be_primary);
+
drm_fbdev_generic_setup(dev, 32);
 
return 0;
-- 
2.34.1



[RFC, drm-misc-next v4 8/9] drm/hibmc: Register as a VGA client by calling vga_client_register()

2023-09-05 Thread Sui Jingfeng
From: Sui Jingfeng 

Because the display controller in the Hibmc chip is a VGA compatible
display controller. Because ARM64 doesn't need the VGA console. It does not
need to worry about the side effects that come with the VGA compatible.
However, the real problem is that some ARM64 PCs and servers do not have
good UEFI firmware support. At least, it is not as good as UEFI firmware
for x86. The Huawei KunPeng 920 PC and Taishan 100 server are examples.
When a discrete GPU is mounted on such machines, the UEFI firmware still
selects the integrated display controller (in the BMC) as the primary GPU.
It is hardcoded, no options are provided for selection. A Linux user has
no control at all.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c 
b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index 8a98fa276e8a..73a3f1cb109a 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -13,6 +13,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -27,6 +28,10 @@
 #include "hibmc_drm_drv.h"
 #include "hibmc_drm_regs.h"
 
+static int hibmc_modeset = -1;
+MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
+module_param_named(modeset, hibmc_modeset, int, 0400);
+
 DEFINE_DRM_GEM_FOPS(hibmc_fops);
 
 static irqreturn_t hibmc_interrupt(int irq, void *arg)
@@ -299,6 +304,14 @@ static int hibmc_load(struct drm_device *dev)
return ret;
 }
 
+static bool hibmc_want_to_be_primary(struct pci_dev *pdev)
+{
+   if (hibmc_modeset == 10)
+   return true;
+
+   return false;
+}
+
 static int hibmc_pci_probe(struct pci_dev *pdev,
   const struct pci_device_id *ent)
 {
@@ -339,6 +352,8 @@ static int hibmc_pci_probe(struct pci_dev *pdev,
goto err_unload;
}
 
+   vga_client_register(pdev, NULL, hibmc_want_to_be_primary);
+
drm_fbdev_generic_setup(dev, 32);
 
return 0;
-- 
2.34.1



[RFC, drm-misc-next v4 2/9] drm/nouveau: Implement .be_primary() callback

2023-09-05 Thread Sui Jingfeng
From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which one
is primary at boot time. This patch tries to solve the mentioned problem by
implementing the .be_primary() callback. VGAARB will call back to Nouveau
when the drm/nouveau gets loaded successfully.

Pass nouveau.modeset=10 on the kernel cmd line if you really want the
device bound by Nouveau to be the primary video adapter. This overrides
whatever boot device selected by VGAARB.

Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/nouveau/nouveau_vga.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c 
b/drivers/gpu/drm/nouveau/nouveau_vga.c
index 162b4f4676c7..4242188667e2 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vga.c
+++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
@@ -80,6 +80,15 @@ nouveau_switcheroo_ops = {
.can_switch = nouveau_switcheroo_can_switch,
 };
 
+static bool
+nouveau_want_to_be_primary(struct pci_dev *pdev)
+{
+   if (nouveau_modeset == 10)
+   return true;
+
+   return false;
+}
+
 void
 nouveau_vga_init(struct nouveau_drm *drm)
 {
@@ -92,7 +101,7 @@ nouveau_vga_init(struct nouveau_drm *drm)
return;
pdev = to_pci_dev(dev->dev);
 
-   vga_client_register(pdev, nouveau_vga_set_decode, NULL);
+   vga_client_register(pdev, nouveau_vga_set_decode, 
nouveau_want_to_be_primary);
 
/* don't register Thunderbolt eGPU with vga_switcheroo */
if (pci_is_thunderbolt_attached(pdev))
-- 
2.34.1



[RFC, drm-misc-next v4 1/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Sui Jingfeng
From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned
problem by introduced the ->be_primary() function stub. The specific
device drivers can provide an implementation to hook up with this stub by
calling the vga_client_register() function.

Once the driver bound the device successfully, VGAARB will call back to
the device driver. To query if the device drivers want to be primary or
not. Device drivers can just pass NULL if have no such needs.

Acked-by: Jani Nikula  # i915
Reviewed-by: Lyude Paul  # nouveau
Signed-off-by: Sui Jingfeng 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  2 +-
 drivers/gpu/drm/i915/display/intel_vga.c   |  3 +-
 drivers/gpu/drm/loongson/lsdc_drv.c|  2 +-
 drivers/gpu/drm/nouveau/nouveau_vga.c  |  2 +-
 drivers/gpu/drm/radeon/radeon_device.c |  2 +-
 drivers/pci/vgaarb.c   | 43 +++---
 drivers/vfio/pci/vfio_pci_core.c   |  2 +-
 include/linux/vgaarb.h |  8 ++--
 8 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index e77f048c99d8..ecc4564ceac0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -3916,7 +3916,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 * ignore it
 */
if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
-   vga_client_register(adev->pdev, amdgpu_device_vga_set_decode);
+   vga_client_register(adev->pdev, amdgpu_device_vga_set_decode, 
NULL);
 
px = amdgpu_device_supports_px(ddev);
 
diff --git a/drivers/gpu/drm/i915/display/intel_vga.c 
b/drivers/gpu/drm/i915/display/intel_vga.c
index 286a0bdd28c6..98d7d4dffe9f 100644
--- a/drivers/gpu/drm/i915/display/intel_vga.c
+++ b/drivers/gpu/drm/i915/display/intel_vga.c
@@ -115,7 +115,6 @@ intel_vga_set_decode(struct pci_dev *pdev, bool 
enable_decode)
 
 int intel_vga_register(struct drm_i915_private *i915)
 {
-
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
int ret;
 
@@ -127,7 +126,7 @@ int intel_vga_register(struct drm_i915_private *i915)
 * then we do not take part in VGA arbitration and the
 * vga_client_register() fails with -ENODEV.
 */
-   ret = vga_client_register(pdev, intel_vga_set_decode);
+   ret = vga_client_register(pdev, intel_vga_set_decode, NULL);
if (ret && ret != -ENODEV)
return ret;
 
diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c 
b/drivers/gpu/drm/loongson/lsdc_drv.c
index 188ec82afcfb..d10a28c2c494 100644
--- a/drivers/gpu/drm/loongson/lsdc_drv.c
+++ b/drivers/gpu/drm/loongson/lsdc_drv.c
@@ -289,7 +289,7 @@ static int lsdc_pci_probe(struct pci_dev *pdev, const 
struct pci_device_id *ent)
 
pci_set_drvdata(pdev, ddev);
 
-   vga_client_register(pdev, lsdc_vga_set_decode);
+   vga_client_register(pdev, lsdc_vga_set_decode, NULL);
 
drm_kms_helper_poll_init(ddev);
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c 
b/drivers/gpu/drm/nouveau/nouveau_vga.c
index f8bf0ec26844..162b4f4676c7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vga.c
+++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
@@ -92,7 +92,7 @@ nouveau_vga_init(struct nouveau_drm *drm)
return;
pdev = to_pci_dev(dev->dev);
 
-   vga_client_register(pdev, nouveau_vga_set_decode);
+   vga_client_register(pdev, nouveau_vga_set_decode, NULL);
 
/* don't register Thunderbolt eGPU with vga_switcheroo */
if (pci_is_thunderbolt_attached(pdev))
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index afbb3a80c0c6..71f2ff39d6a1 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1425,7 +1425,7 @@ int radeon_device_init(struct radeon_device *rdev,
/* if we have > 1 VGA cards, then disable the radeon VGA resources */
/* this will fail for cards that aren't VGA class devices, just
 * ignore it */
-   vga_client_register(rdev->pdev, radeon_vga_set_decode);
+   vga_client_register(rdev->pdev, radeon_vga_set_decode, NULL);
 
if (rdev->flags & RADEON_IS_PX)
runtime = true;
diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c
index 5a696078b382..552ac7df10ee 100644
--- a/drivers/pci/vgaarb.c
+++ b/drivers/pci/vgaarb.c
@@ -53,6 +53,7 @@ struct vga_device {
bool bridge_has_one_vga;
bool is_firmware_default;   /* device selected by firmware */
unsigned int (*set_decode)(struct pci_dev *pdev, bool decode);
+   bool (*be_primary)(struct pci_dev *pdev);
 };
 
 static LIST_HEAD(vga_list);
@@ -956,6 +957,10 @@ EXPORT_SYMBOL(vga_set_legacy_decoding);
  * @set_decode callback: If a client can disable its GPU VGA resource, it
  * 

Re: [PATCH] drm/amdgpu: fix incompatible types in conditional expression

2023-09-05 Thread Chiu, Solomon
[AMD Official Use Only - General]


Looks good to me.


Series is:

Reviewed-by: Solomon Chiu 


From: Yu, Lang 
Sent: Monday, September 4, 2023 12:22 PM
To: amd-gfx@lists.freedesktop.org 
Cc: Deucher, Alexander ; Chiu, Solomon 
; Yu, Lang ; kernel test robot 

Subject: [PATCH] drm/amdgpu: fix incompatible types in conditional expression

Fixes: ab041551f4a7 ("drm/amdgpu: add VPE 6.1.0 support")

Signed-off-by: Lang Yu 
Reported-by: kernel test robot 
Link: https://lore.kernel.org/oe-kbuild-all/202309020608.fwp8qmht-...@intel.com
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h | 2 +-
 drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c   | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h
index b590205d6a28..29d56f7ae4a9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h
@@ -31,7 +31,7 @@ struct amdgpu_vpe;

 struct vpe_funcs {
 uint32_t (*get_reg_offset)(struct amdgpu_vpe *vpe, uint32_t inst, 
uint32_t offset);
-   void (*set_regs)(struct amdgpu_vpe *vpe);
+   int (*set_regs)(struct amdgpu_vpe *vpe);
 int (*irq_init)(struct amdgpu_vpe *vpe);
 int (*init_microcode)(struct amdgpu_vpe *vpe);
 int (*load_microcode)(struct amdgpu_vpe *vpe);
diff --git a/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c 
b/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c
index 1259b150dc96..756f39348dd9 100644
--- a/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c
@@ -254,13 +254,15 @@ static int vpe_v6_1_process_trap_irq(struct amdgpu_device 
*adev,
 return 0;
 }

-static void vpe_v6_1_set_regs(struct amdgpu_vpe *vpe)
+static int vpe_v6_1_set_regs(struct amdgpu_vpe *vpe)
 {
 vpe->regs.queue0_rb_rptr_lo = regVPEC_QUEUE0_RB_RPTR;
 vpe->regs.queue0_rb_rptr_hi = regVPEC_QUEUE0_RB_RPTR_HI;
 vpe->regs.queue0_rb_wptr_lo = regVPEC_QUEUE0_RB_WPTR;
 vpe->regs.queue0_rb_wptr_hi = regVPEC_QUEUE0_RB_WPTR_HI;
 vpe->regs.queue0_preempt = regVPEC_QUEUE0_PREEMPT;
+
+   return 0;
 }

 static const struct vpe_funcs vpe_v6_1_funcs = {
--
2.25.1



[PATCH 10/11] drm/amdgpu: rework lock handling fro flush_tlb

2023-09-05 Thread Christian König
Instead of each implementation doing this more or less correctly
move taking the reset lock at a higher level.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 9 +
 drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 6 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   | 5 -
 drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   | 5 -
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 6 +-
 5 files changed, 11 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index 15814cb801e7..c24252304d48 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -589,8 +589,17 @@ void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, 
uint32_t vmid,
!adev->mman.buffer_funcs_enabled ||
!adev->ib_pool_ready || amdgpu_in_reset(adev) ||
!ring->sched.ready) {
+
+   /*
+* A GPU reset should flush all TLBs anyway, so no need to do
+* this while one is ongoing.
+*/
+   if(!down_read_trylock(>reset_domain->sem))
+   return;
+
adev->gmc.gmc_funcs->flush_gpu_tlb(adev, vmid, vmhub,
   flush_type);
+   up_read(>reset_domain->sem);
return;
}
 
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index 40d432d46469..302279497d67 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -51,8 +51,6 @@
 #include "athub_v2_0.h"
 #include "athub_v2_1.h"
 
-#include "amdgpu_reset.h"
-
 static int gmc_v10_0_ecc_interrupt_state(struct amdgpu_device *adev,
 struct amdgpu_irq_src *src,
 unsigned int type,
@@ -264,11 +262,9 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
 * Directly use kiq to do the vm invalidation instead
 */
if (adev->gfx.kiq[0].ring.sched.ready && !adev->enable_mes &&
-   (amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev)) &&
-   down_read_trylock(>reset_domain->sem)) {
+   (amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) {
amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
1 << vmid);
-   up_read(>reset_domain->sem);
return;
}
 
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
index fa3586efacd2..998f6ee60b78 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
@@ -33,7 +33,6 @@
 #include "amdgpu_ucode.h"
 #include "amdgpu_amdkfd.h"
 #include "amdgpu_gem.h"
-#include "amdgpu_reset.h"
 
 #include "bif/bif_4_1_d.h"
 #include "bif/bif_4_1_sh_mask.h"
@@ -430,9 +429,6 @@ static void gmc_v7_0_flush_gpu_tlb_pasid(struct 
amdgpu_device *adev,
u32 mask = 0x0;
int vmid;
 
-   if(!down_read_trylock(>reset_domain->sem))
-   return;
-
for (vmid = 1; vmid < 16; vmid++) {
u32 tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
 
@@ -443,7 +439,6 @@ static void gmc_v7_0_flush_gpu_tlb_pasid(struct 
amdgpu_device *adev,
 
WREG32(mmVM_INVALIDATE_REQUEST, mask);
RREG32(mmVM_INVALIDATE_RESPONSE);
-   up_read(>reset_domain->sem);
 }
 
 /*
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index ffcd79d28b9a..8dcd9b13673c 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -31,7 +31,6 @@
 #include "amdgpu_ucode.h"
 #include "amdgpu_amdkfd.h"
 #include "amdgpu_gem.h"
-#include "amdgpu_reset.h"
 
 #include "gmc/gmc_8_1_d.h"
 #include "gmc/gmc_8_1_sh_mask.h"
@@ -620,9 +619,6 @@ static void gmc_v8_0_flush_gpu_tlb_pasid(struct 
amdgpu_device *adev,
u32 mask = 0x0;
int vmid;
 
-   if(!down_read_trylock(>reset_domain->sem))
-   return;
-
for (vmid = 1; vmid < 16; vmid++) {
u32 tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
 
@@ -633,7 +629,6 @@ static void gmc_v8_0_flush_gpu_tlb_pasid(struct 
amdgpu_device *adev,
 
WREG32(mmVM_INVALIDATE_REQUEST, mask);
RREG32(mmVM_INVALIDATE_RESPONSE);
-   up_read(>reset_domain->sem);
 }
 
 /*
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index 94ba16536fc2..c5df8f052f3f 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -64,8 +64,6 @@
 #include "amdgpu_ras.h"
 #include "amdgpu_xgmi.h"
 
-#include "amdgpu_reset.h"
-
 /* add these here since we already include dce12 headers and these are for DCN 
*/
 #define mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION  

[PATCH 07/11] drm/amdgpu: cleanup gmc_v10_0_flush_gpu_tlb_pasid

2023-09-05 Thread Christian König
The same PASID can be used by more than one VMID, reset each of them.

Use the common KIQ handling.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 66 --
 1 file changed, 19 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index 1f70c57bcd69..407ddb926941 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -341,57 +341,27 @@ static int gmc_v10_0_flush_gpu_tlb_pasid(struct 
amdgpu_device *adev,
uint16_t pasid, uint32_t flush_type,
bool all_hub, uint32_t inst)
 {
+   uint16_t queried;
int vmid, i;
-   signed long r;
-   uint32_t seq;
-   uint16_t queried_pasid;
-   bool ret;
-   u32 usec_timeout = amdgpu_sriov_vf(adev) ? SRIOV_USEC_TIMEOUT : 
adev->usec_timeout;
-   struct amdgpu_ring *ring = >gfx.kiq[0].ring;
-   struct amdgpu_kiq *kiq = >gfx.kiq[0];
-
-   if (amdgpu_emu_mode == 0 && ring->sched.ready) {
-   spin_lock(>gfx.kiq[0].ring_lock);
-   /* 2 dwords flush + 8 dwords fence */
-   amdgpu_ring_alloc(ring, kiq->pmf->invalidate_tlbs_size + 8);
-   kiq->pmf->kiq_invalidate_tlbs(ring,
-   pasid, flush_type, all_hub);
-   r = amdgpu_fence_emit_polling(ring, , MAX_KIQ_REG_WAIT);
-   if (r) {
-   amdgpu_ring_undo(ring);
-   spin_unlock(>gfx.kiq[0].ring_lock);
-   return -ETIME;
-   }
-
-   amdgpu_ring_commit(ring);
-   spin_unlock(>gfx.kiq[0].ring_lock);
-   r = amdgpu_fence_wait_polling(ring, seq, usec_timeout);
-   if (r < 1) {
-   dev_err(adev->dev, "wait for kiq fence error: %ld.\n", 
r);
-   return -ETIME;
-   }
-
-   return 0;
-   }
 
for (vmid = 1; vmid < AMDGPU_NUM_VMID; vmid++) {
-
-   ret = gmc_v10_0_get_atc_vmid_pasid_mapping_info(adev, vmid,
-   _pasid);
-   if (ret && queried_pasid == pasid) {
-   if (all_hub) {
-   for_each_set_bit(i, adev->vmhubs_mask, 
AMDGPU_MAX_VMHUBS)
-   gmc_v10_0_flush_gpu_tlb(adev, vmid,
-   i, flush_type);
-   } else {
-   gmc_v10_0_flush_gpu_tlb(adev, vmid,
-   AMDGPU_GFXHUB(0), flush_type);
-   }
-   if (!adev->enable_mes)
-   break;
+   bool valid;
+
+   valid = gmc_v10_0_get_atc_vmid_pasid_mapping_info(adev, vmid,
+ );
+   if (!valid || queried != pasid)
+   continue;
+
+   if (all_hub) {
+   for_each_set_bit(i, adev->vmhubs_mask,
+AMDGPU_MAX_VMHUBS)
+   gmc_v10_0_flush_gpu_tlb(adev, vmid, i,
+   flush_type);
+   } else {
+   gmc_v10_0_flush_gpu_tlb(adev, vmid, AMDGPU_GFXHUB(0),
+   flush_type);
}
}
-
return 0;
 }
 
@@ -1009,8 +979,10 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device 
*adev)
 
 static int gmc_v10_0_hw_init(void *handle)
 {
-   int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+   int r;
+
+   adev->gmc.flush_pasid_uses_kiq = !amdgpu_emu_mode;
 
/* The sequence of these two function calls matters.*/
gmc_v10_0_init_golden_registers(adev);
-- 
2.34.1



[PATCH 05/11] drm/amdgpu: fix and cleanup gmc_v8_0_flush_gpu_tlb_pasid

2023-09-05 Thread Christian König
Testing for reset is pointless since the reset can start right after the
test. Grab the reset semaphore instead.

The same PASID can be used by more than once VMID, build a mask of VMIDs
to reset instead of just restting the first one.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index 5af235202513..2d51531a1f2d 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -31,6 +31,7 @@
 #include "amdgpu_ucode.h"
 #include "amdgpu_amdkfd.h"
 #include "amdgpu_gem.h"
+#include "amdgpu_reset.h"
 
 #include "gmc/gmc_8_1_d.h"
 #include "gmc/gmc_8_1_sh_mask.h"
@@ -616,25 +617,24 @@ static int gmc_v8_0_flush_gpu_tlb_pasid(struct 
amdgpu_device *adev,
uint16_t pasid, uint32_t flush_type,
bool all_hub, uint32_t inst)
 {
+   u32 mask = 0x0;
int vmid;
-   unsigned int tmp;
 
-   if (amdgpu_in_reset(adev))
-   return -EIO;
+   if(!down_read_trylock(>reset_domain->sem))
+   return 0;
 
for (vmid = 1; vmid < 16; vmid++) {
+   u32 tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
 
-   tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
if ((tmp & ATC_VMID0_PASID_MAPPING__VALID_MASK) &&
-   (tmp & ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid) {
-   WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
-   RREG32(mmVM_INVALIDATE_RESPONSE);
-   break;
-   }
+   (tmp & ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid)
+   mask |= 1 << vmid;
}
 
+   WREG32(mmVM_INVALIDATE_REQUEST, mask);
+   RREG32(mmVM_INVALIDATE_RESPONSE);
+   up_read(>reset_domain->sem);
return 0;
-
 }
 
 /*
-- 
2.34.1



[PATCH 11/11] drm/amdgpu: further move TLB hw workarounds a layer up

2023-09-05 Thread Christian König
For the PASID flushing we already handled that at a higher layer, apply
those workarounds to the standard flush as well.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 19 +++
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 74 -
 2 files changed, 42 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index c24252304d48..8a5381ca7713 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -597,6 +597,14 @@ void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, 
uint32_t vmid,
if(!down_read_trylock(>reset_domain->sem))
return;
 
+   if (adev->gmc.flush_tlb_needs_extra_type_2)
+   adev->gmc.gmc_funcs->flush_gpu_tlb(adev, vmid,
+  vmhub, 2);
+
+   if (adev->gmc.flush_tlb_needs_extra_type_0 && flush_type == 2)
+   adev->gmc.gmc_funcs->flush_gpu_tlb(adev, vmid,
+  vmhub, 0);
+
adev->gmc.gmc_funcs->flush_gpu_tlb(adev, vmid, vmhub,
   flush_type);
up_read(>reset_domain->sem);
@@ -647,6 +655,17 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device 
*adev, uint16_t pasid,
 
if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready ||
!down_read_trylock(>reset_domain->sem)) {
+
+   if (adev->gmc.flush_tlb_needs_extra_type_2)
+   adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
+2, all_hub,
+inst);
+
+   if (adev->gmc.flush_tlb_needs_extra_type_0 && flush_type == 2)
+   adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
+0, all_hub,
+inst);
+
adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
 flush_type, all_hub,
 inst);
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index c5df8f052f3f..a1a6f4b63208 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -812,37 +812,18 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
uint32_t vmhub, uint32_t flush_type)
 {
bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(adev, vmhub);
-   u32 j, inv_req, inv_req2, tmp, sem, req, ack;
+   u32 j, inv_req, tmp, sem, req, ack;
const unsigned int eng = 17;
struct amdgpu_vmhub *hub;
 
BUG_ON(vmhub >= AMDGPU_MAX_VMHUBS);
 
hub = >vmhub[vmhub];
+   inv_req = gmc_v9_0_get_invalidate_req(vmid, flush_type);
sem = hub->vm_inv_eng0_sem + hub->eng_distance * eng;
req = hub->vm_inv_eng0_req + hub->eng_distance * eng;
ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng;
 
-   if (adev->gmc.xgmi.num_physical_nodes &&
-   adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 0)) {
-   /* Vega20+XGMI caches PTEs in TC and TLB. Add a
-* heavy-weight TLB flush (type 2), which flushes
-* both. Due to a race condition with concurrent
-* memory accesses using the same TLB cache line, we
-* still need a second TLB flush after this.
-*/
-   inv_req = gmc_v9_0_get_invalidate_req(vmid, 2);
-   inv_req2 = gmc_v9_0_get_invalidate_req(vmid, flush_type);
-   } else if (flush_type == 2 &&
-  adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 3) &&
-  adev->rev_id == 0) {
-   inv_req = gmc_v9_0_get_invalidate_req(vmid, 0);
-   inv_req2 = gmc_v9_0_get_invalidate_req(vmid, flush_type);
-   } else {
-   inv_req = gmc_v9_0_get_invalidate_req(vmid, flush_type);
-   inv_req2 = 0;
-   }
-
/* This is necessary for a HW workaround under SRIOV as well
 * as GFXOFF under bare metal
 */
@@ -853,10 +834,6 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
 
amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
   1 << vmid);
-   if (inv_req2)
-   amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack,
-  inv_req2, 1 << vmid);
-
return;
}
 
@@ -886,34 +863,29 

[PATCH 09/11] drm/amdgpu: drop error return from flush_gpu_tlb_pasid

2023-09-05 Thread Christian König
That function never fails, drop the error return.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 7 ---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h | 6 +++---
 drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 7 +++
 drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c  | 7 +++
 drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   | 9 -
 drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   | 9 -
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 8 +++-
 7 files changed, 24 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index b5f1a1218725..15814cb801e7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -638,9 +638,10 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device 
*adev, uint16_t pasid,
 
if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready ||
!down_read_trylock(>reset_domain->sem)) {
-   return adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
-   flush_type,
-   all_hub, inst);
+   adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
+flush_type, all_hub,
+inst);
+   return 0;
}
 
/* 2 dwords flush + 8 dwords fence */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
index 7732d4ef845e..dd0ede75e5d7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
@@ -130,9 +130,9 @@ struct amdgpu_gmc_funcs {
void (*flush_gpu_tlb)(struct amdgpu_device *adev, uint32_t vmid,
uint32_t vmhub, uint32_t flush_type);
/* flush the vm tlb via pasid */
-   int (*flush_gpu_tlb_pasid)(struct amdgpu_device *adev, uint16_t pasid,
-   uint32_t flush_type, bool all_hub,
-   uint32_t inst);
+   void (*flush_gpu_tlb_pasid)(struct amdgpu_device *adev, uint16_t pasid,
+   uint32_t flush_type, bool all_hub,
+   uint32_t inst);
/* flush the vm tlb via ring */
uint64_t (*emit_flush_gpu_tlb)(struct amdgpu_ring *ring, unsigned vmid,
   uint64_t pd_addr);
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index 407ddb926941..40d432d46469 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -337,9 +337,9 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
  *
  * Flush the TLB for the requested pasid.
  */
-static int gmc_v10_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
-   uint16_t pasid, uint32_t flush_type,
-   bool all_hub, uint32_t inst)
+static void gmc_v10_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
+ uint16_t pasid, uint32_t flush_type,
+ bool all_hub, uint32_t inst)
 {
uint16_t queried;
int vmid, i;
@@ -362,7 +362,6 @@ static int gmc_v10_0_flush_gpu_tlb_pasid(struct 
amdgpu_device *adev,
flush_type);
}
}
-   return 0;
 }
 
 static uint64_t gmc_v10_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
index aa39c1087e44..50bc5f151038 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
@@ -299,9 +299,9 @@ static void gmc_v11_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
  *
  * Flush the TLB for the requested pasid.
  */
-static int gmc_v11_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
-   uint16_t pasid, uint32_t flush_type,
-   bool all_hub, uint32_t inst)
+static void gmc_v11_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
+ uint16_t pasid, uint32_t flush_type,
+ bool all_hub, uint32_t inst)
 {
uint16_t queried;
int vmid, i;
@@ -324,7 +324,6 @@ static int gmc_v11_0_flush_gpu_tlb_pasid(struct 
amdgpu_device *adev,
flush_type);
}
}
-   return 0;
 }
 
 static uint64_t gmc_v11_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
index 9e19a752f94b..fa3586efacd2 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c

[PATCH 08/11] drm/amdgpu: fix and cleanup gmc_v11_0_flush_gpu_tlb_pasid

2023-09-05 Thread Christian König
The same PASID can be used by more than one VMID, reset each of them.

Use the common KIQ handling.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 63 --
 1 file changed, 19 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
index 3c3ad3f17c6a..aa39c1087e44 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
@@ -303,54 +303,27 @@ static int gmc_v11_0_flush_gpu_tlb_pasid(struct 
amdgpu_device *adev,
uint16_t pasid, uint32_t flush_type,
bool all_hub, uint32_t inst)
 {
+   uint16_t queried;
int vmid, i;
-   signed long r;
-   uint32_t seq;
-   uint16_t queried_pasid;
-   bool ret;
-   struct amdgpu_ring *ring = >gfx.kiq[0].ring;
-   struct amdgpu_kiq *kiq = >gfx.kiq[0];
-
-   if (amdgpu_emu_mode == 0 && ring->sched.ready) {
-   spin_lock(>gfx.kiq[0].ring_lock);
-   /* 2 dwords flush + 8 dwords fence */
-   amdgpu_ring_alloc(ring, kiq->pmf->invalidate_tlbs_size + 8);
-   kiq->pmf->kiq_invalidate_tlbs(ring,
-   pasid, flush_type, all_hub);
-   r = amdgpu_fence_emit_polling(ring, , MAX_KIQ_REG_WAIT);
-   if (r) {
-   amdgpu_ring_undo(ring);
-   spin_unlock(>gfx.kiq[0].ring_lock);
-   return -ETIME;
-   }
-
-   amdgpu_ring_commit(ring);
-   spin_unlock(>gfx.kiq[0].ring_lock);
-   r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
-   if (r < 1) {
-   dev_err(adev->dev, "wait for kiq fence error: %ld.\n", 
r);
-   return -ETIME;
-   }
-
-   return 0;
-   }
 
for (vmid = 1; vmid < 16; vmid++) {
-
-   ret = gmc_v11_0_get_vmid_pasid_mapping_info(adev, vmid,
-   _pasid);
-   if (ret && queried_pasid == pasid) {
-   if (all_hub) {
-   for_each_set_bit(i, adev->vmhubs_mask, 
AMDGPU_MAX_VMHUBS)
-   gmc_v11_0_flush_gpu_tlb(adev, vmid,
-   i, flush_type);
-   } else {
-   gmc_v11_0_flush_gpu_tlb(adev, vmid,
-   AMDGPU_GFXHUB(0), flush_type);
-   }
+   bool valid;
+
+   valid = gmc_v11_0_get_vmid_pasid_mapping_info(adev, vmid,
+ );
+   if (!valid || queried == pasid)
+   continue;
+
+   if (all_hub) {
+   for_each_set_bit(i, adev->vmhubs_mask,
+AMDGPU_MAX_VMHUBS)
+   gmc_v11_0_flush_gpu_tlb(adev, vmid, i,
+   flush_type);
+   } else {
+   gmc_v11_0_flush_gpu_tlb(adev, vmid, AMDGPU_GFXHUB(0),
+   flush_type);
}
}
-
return 0;
 }
 
@@ -918,8 +891,10 @@ static int gmc_v11_0_gart_enable(struct amdgpu_device 
*adev)
 
 static int gmc_v11_0_hw_init(void *handle)
 {
-   int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+   int r;
+
+   adev->gmc.flush_pasid_uses_kiq = !amdgpu_emu_mode;
 
/* The sequence of these two function calls matters.*/
gmc_v11_0_init_golden_registers(adev);
-- 
2.34.1



[PATCH 02/11] drm/amdgpu: rework gmc_v10_0_flush_gpu_tlb

2023-09-05 Thread Christian König
Move the SDMA workaround necessary for Navi 1x into a higher layer.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c  |  48 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h  |   5 +-
 drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c |   3 +
 drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c   | 159 ++-
 4 files changed, 97 insertions(+), 118 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index d78bd9732543..857051093900 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -575,6 +575,54 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device 
*adev)
return 0;
 }
 
+void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
+ uint32_t vmhub, uint32_t flush_type)
+{
+   struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
+   struct amdgpu_vmhub *hub = >vmhub[vmhub];
+   struct dma_fence *fence;
+   struct amdgpu_job *job;
+   int r;
+
+   if (!hub->sdma_invalidation_workaround || vmid ||
+   !adev->mman.buffer_funcs_enabled ||
+   !adev->ib_pool_ready || amdgpu_in_reset(adev) ||
+   !ring->sched.ready) {
+   adev->gmc.gmc_funcs->flush_gpu_tlb(adev, vmid, vmhub,
+  flush_type);
+   return;
+   }
+
+   /* The SDMA on Navi 1x has a bug which can theoretically result in 
memory
+* corruption if an invalidation happens at the same time as an VA
+* translation. Avoid this by doing the invalidation from the SDMA
+* itself at least for GART.
+*/
+   mutex_lock(>mman.gtt_window_lock);
+   r = amdgpu_job_alloc_with_ib(ring->adev, >mman.high_pr,
+AMDGPU_FENCE_OWNER_UNDEFINED,
+16 * 4, AMDGPU_IB_POOL_IMMEDIATE,
+);
+   if (r)
+   goto error_alloc;
+
+   job->vm_pd_addr = amdgpu_gmc_pd_addr(adev->gart.bo);
+   job->vm_needs_flush = true;
+   job->ibs->ptr[job->ibs->length_dw++] = ring->funcs->nop;
+   amdgpu_ring_pad_ib(ring, >ibs[0]);
+   fence = amdgpu_job_submit(job);
+   mutex_unlock(>mman.gtt_window_lock);
+
+   dma_fence_wait(fence, false);
+   dma_fence_put(fence);
+
+   return;
+
+error_alloc:
+   mutex_unlock(>mman.gtt_window_lock);
+   DRM_ERROR("Error flushing GPU TLB using the SDMA (%d)!\n", r);
+}
+
 /**
  * amdgpu_gmc_tmz_set -- check and set if a device supports TMZ
  * @adev: amdgpu_device pointer
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
index fdc25cd559b6..9e7df2f69123 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
@@ -117,6 +117,8 @@ struct amdgpu_vmhub {
 
uint32_tvm_contexts_disable;
 
+   boolsdma_invalidation_workaround;
+
const struct amdgpu_vmhub_funcs *vmhub_funcs;
 };
 
@@ -335,7 +337,6 @@ struct amdgpu_gmc {
u64 noretry_flags;
 };
 
-#define amdgpu_gmc_flush_gpu_tlb(adev, vmid, vmhub, type) 
((adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid), (vmhub), (type)))
 #define amdgpu_gmc_flush_gpu_tlb_pasid(adev, pasid, type, allhub, inst) \
((adev)->gmc.gmc_funcs->flush_gpu_tlb_pasid \
((adev), (pasid), (type), (allhub), (inst)))
@@ -401,6 +402,8 @@ int amdgpu_gmc_ras_sw_init(struct amdgpu_device *adev);
 int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev);
 void amdgpu_gmc_ras_fini(struct amdgpu_device *adev);
 int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev);
+void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
+ uint32_t vmhub, uint32_t flush_type);
 
 extern void amdgpu_gmc_tmz_set(struct amdgpu_device *adev);
 extern void amdgpu_gmc_noretry_set(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c
index a041c6c970e1..8521c45e8f38 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c
@@ -471,6 +471,9 @@ static void gfxhub_v2_0_init(struct amdgpu_device *adev)

GCVM_CONTEXT1_CNTL__WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |

GCVM_CONTEXT1_CNTL__EXECUTE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK;
 
+   /* TODO: This is only needed on some Navi 1x revisions */
+   hub->sdma_invalidation_workaround = true;
+
hub->vmhub_funcs = _v2_0_vmhub_funcs;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index fa87a85e1017..1f70c57bcd69 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -230,20 +230,49 @@ static bool gmc_v10_0_get_atc_vmid_pasid_mapping_info(
  * by the amdgpu vm/hsa 

[PATCH 04/11] drm/amdgpu: fix and cleanup gmc_v7_0_flush_gpu_tlb_pasid

2023-09-05 Thread Christian König
Testing for reset is pointless since the reset can start right after the
test. Grab the reset semaphore instead.

The same PASID can be used by more than once VMID, build a mask of VMIDs
to reset instead of just restting the first one.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
index 6a6929ac2748..9e19a752f94b 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
@@ -33,6 +33,7 @@
 #include "amdgpu_ucode.h"
 #include "amdgpu_amdkfd.h"
 #include "amdgpu_gem.h"
+#include "amdgpu_reset.h"
 
 #include "bif/bif_4_1_d.h"
 #include "bif/bif_4_1_sh_mask.h"
@@ -426,23 +427,23 @@ static int gmc_v7_0_flush_gpu_tlb_pasid(struct 
amdgpu_device *adev,
uint16_t pasid, uint32_t flush_type,
bool all_hub, uint32_t inst)
 {
+   u32 mask = 0x0;
int vmid;
-   unsigned int tmp;
 
-   if (amdgpu_in_reset(adev))
-   return -EIO;
+   if(!down_read_trylock(>reset_domain->sem))
+   return 0;
 
for (vmid = 1; vmid < 16; vmid++) {
+   u32 tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
 
-   tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
if ((tmp & ATC_VMID0_PASID_MAPPING__VALID_MASK) &&
-   (tmp & ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid) {
-   WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
-   RREG32(mmVM_INVALIDATE_RESPONSE);
-   break;
-   }
+   (tmp & ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid)
+   mask |= 1 << vmid;
}
 
+   WREG32(mmVM_INVALIDATE_REQUEST, mask);
+   RREG32(mmVM_INVALIDATE_RESPONSE);
+   up_read(>reset_domain->sem);
return 0;
 }
 
-- 
2.34.1



[PATCH 06/11] drm/amdgpu: fix and cleanup gmc_v9_0_flush_gpu_tlb_pasid

2023-09-05 Thread Christian König
Testing for reset is pointless since the reset can start right after the
test.

The same PASID can be used by more than one VMID, reset each of them.

Move the KIQ and all the workaround handling into common GMC code.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c |  60 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |  10 ++-
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 109 
 3 files changed, 102 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index 857051093900..b5f1a1218725 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -32,6 +32,7 @@
 #include "amdgpu.h"
 #include "amdgpu_gmc.h"
 #include "amdgpu_ras.h"
+#include "amdgpu_reset.h"
 #include "amdgpu_xgmi.h"
 
 #include 
@@ -623,6 +624,65 @@ void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, 
uint32_t vmid,
DRM_ERROR("Error flushing GPU TLB using the SDMA (%d)!\n", r);
 }
 
+int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid,
+  uint32_t flush_type, bool all_hub,
+  uint32_t inst)
+{
+   u32 usec_timeout = amdgpu_sriov_vf(adev) ? SRIOV_USEC_TIMEOUT :
+   adev->usec_timeout;
+   struct amdgpu_ring *ring = >gfx.kiq[inst].ring;
+   struct amdgpu_kiq *kiq = >gfx.kiq[inst];
+   unsigned int ndw;
+   signed long r;
+   uint32_t seq;
+
+   if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready ||
+   !down_read_trylock(>reset_domain->sem)) {
+   return adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
+   flush_type,
+   all_hub, inst);
+   }
+
+   /* 2 dwords flush + 8 dwords fence */
+   ndw = kiq->pmf->invalidate_tlbs_size + 8;
+
+   if (adev->gmc.flush_tlb_needs_extra_type_2)
+   ndw += kiq->pmf->invalidate_tlbs_size;
+
+   if (adev->gmc.flush_tlb_needs_extra_type_0)
+   ndw += kiq->pmf->invalidate_tlbs_size;
+
+   spin_lock(>gfx.kiq[inst].ring_lock);
+   amdgpu_ring_alloc(ring, ndw);
+   if (adev->gmc.flush_tlb_needs_extra_type_2)
+   kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub);
+
+   if (flush_type == 2 && adev->gmc.flush_tlb_needs_extra_type_0)
+   kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 0, all_hub);
+
+   kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub);
+   r = amdgpu_fence_emit_polling(ring, , MAX_KIQ_REG_WAIT);
+   if (r) {
+   amdgpu_ring_undo(ring);
+   spin_unlock(>gfx.kiq[inst].ring_lock);
+   goto error_unlock_reset;
+   }
+
+   amdgpu_ring_commit(ring);
+   spin_unlock(>gfx.kiq[inst].ring_lock);
+   r = amdgpu_fence_wait_polling(ring, seq, usec_timeout);
+   if (r < 1) {
+   dev_err(adev->dev, "wait for kiq fence error: %ld.\n", r);
+   r = -ETIME;
+   goto error_unlock_reset;
+   }
+   r = 0;
+
+error_unlock_reset:
+   up_read(>reset_domain->sem);
+   return r;
+}
+
 /**
  * amdgpu_gmc_tmz_set -- check and set if a device supports TMZ
  * @adev: amdgpu_device pointer
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
index 9e7df2f69123..7732d4ef845e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
@@ -335,11 +335,12 @@ struct amdgpu_gmc {
u64 MC_VM_MX_L1_TLB_CNTL;
 
u64 noretry_flags;
+
+   bool flush_tlb_needs_extra_type_0;
+   bool flush_tlb_needs_extra_type_2;
+   bool flush_pasid_uses_kiq;
 };
 
-#define amdgpu_gmc_flush_gpu_tlb_pasid(adev, pasid, type, allhub, inst) \
-   ((adev)->gmc.gmc_funcs->flush_gpu_tlb_pasid \
-   ((adev), (pasid), (type), (allhub), (inst)))
 #define amdgpu_gmc_emit_flush_gpu_tlb(r, vmid, addr) 
(r)->adev->gmc.gmc_funcs->emit_flush_gpu_tlb((r), (vmid), (addr))
 #define amdgpu_gmc_emit_pasid_mapping(r, vmid, pasid) 
(r)->adev->gmc.gmc_funcs->emit_pasid_mapping((r), (vmid), (pasid))
 #define amdgpu_gmc_map_mtype(adev, flags) 
(adev)->gmc.gmc_funcs->map_mtype((adev),(flags))
@@ -404,6 +405,9 @@ void amdgpu_gmc_ras_fini(struct amdgpu_device *adev);
 int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev);
 void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
  uint32_t vmhub, uint32_t flush_type);
+int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid,
+  uint32_t flush_type, bool all_hub,
+  uint32_t inst);
 
 extern void amdgpu_gmc_tmz_set(struct amdgpu_device *adev);
 extern void amdgpu_gmc_noretry_set(struct amdgpu_device *adev);
diff 

[PATCH 03/11] drm/amdgpu: cleanup gmc_v11_0_flush_gpu_tlb

2023-09-05 Thread Christian König
Remove leftovers from copying this from the gmc v10 code.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 108 ++---
 1 file changed, 41 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
index dcbba981462e..3c3ad3f17c6a 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
@@ -186,27 +186,50 @@ static bool gmc_v11_0_get_vmid_pasid_mapping_info(
return !!(*p_pasid);
 }
 
-/*
- * GART
- * VMID 0 is the physical GPU addresses as used by the kernel.
- * VMIDs 1-15 are used for userspace clients and are handled
- * by the amdgpu vm/hsa code.
+/**
+ * gmc_v11_0_flush_gpu_tlb - gart tlb flush callback
+ *
+ * @adev: amdgpu_device pointer
+ * @vmid: vm instance to flush
+ * @vmhub: which hub to flush
+ * @flush_type: the flush type
+ *
+ * Flush the TLB for the requested page table.
  */
-
-static void gmc_v11_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
-  unsigned int vmhub, uint32_t flush_type)
+static void gmc_v11_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
+   uint32_t vmhub, uint32_t flush_type)
 {
bool use_semaphore = gmc_v11_0_use_invalidate_semaphore(adev, vmhub);
struct amdgpu_vmhub *hub = >vmhub[vmhub];
u32 inv_req = hub->vmhub_funcs->get_invalidate_req(vmid, flush_type);
-   u32 tmp;
/* Use register 17 for GART */
const unsigned int eng = 17;
+   unsigned char hub_ip;
+   u32 sem, req, ack;
unsigned int i;
-   unsigned char hub_ip = 0;
+   u32 tmp;
+
+   if ((vmhub == AMDGPU_GFXHUB(0)) && !adev->gfx.is_poweron)
+   return;
 
-   hub_ip = (vmhub == AMDGPU_GFXHUB(0)) ?
-  GC_HWIP : MMHUB_HWIP;
+   sem = hub->vm_inv_eng0_sem + hub->eng_distance * eng;
+   req = hub->vm_inv_eng0_req + hub->eng_distance * eng;
+   ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng;
+
+   /* flush hdp cache */
+   adev->hdp.funcs->flush_hdp(adev, NULL);
+
+   /* For SRIOV run time, driver shouldn't access the register through MMIO
+* Directly use kiq to do the vm invalidation instead
+*/
+   if ((adev->gfx.kiq[0].ring.sched.ready || adev->mes.ring.sched.ready) &&
+   (amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) {
+   amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
+   1 << vmid);
+   return;
+   }
+
+   hub_ip = (vmhub == AMDGPU_GFXHUB(0)) ? GC_HWIP : MMHUB_HWIP;
 
spin_lock(>gmc.invalidate_lock);
/*
@@ -220,8 +243,7 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device 
*adev, uint32_t vmid,
if (use_semaphore) {
for (i = 0; i < adev->usec_timeout; i++) {
/* a read return value of 1 means semaphore acuqire */
-   tmp = RREG32_RLC_NO_KIQ(hub->vm_inv_eng0_sem +
-   hub->eng_distance * eng, hub_ip);
+   tmp = RREG32_RLC_NO_KIQ(sem, hub_ip);
if (tmp & 0x1)
break;
udelay(1);
@@ -231,12 +253,11 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device 
*adev, uint32_t vmid,
DRM_ERROR("Timeout waiting for sem acquire in VM 
flush!\n");
}
 
-   WREG32_RLC_NO_KIQ(hub->vm_inv_eng0_req + hub->eng_distance * eng, 
inv_req, hub_ip);
+   WREG32_RLC_NO_KIQ(req, inv_req, hub_ip);
 
/* Wait for ACK with a delay.*/
for (i = 0; i < adev->usec_timeout; i++) {
-   tmp = RREG32_RLC_NO_KIQ(hub->vm_inv_eng0_ack +
-   hub->eng_distance * eng, hub_ip);
+   tmp = RREG32_RLC_NO_KIQ(ack, hub_ip);
tmp &= 1 << vmid;
if (tmp)
break;
@@ -246,12 +267,7 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device 
*adev, uint32_t vmid,
 
/* TODO: It needs to continue working on debugging with semaphore for 
GFXHUB as well. */
if (use_semaphore)
-   /*
-* add semaphore release after invalidation,
-* write with 0 means semaphore release
-*/
-   WREG32_RLC_NO_KIQ(hub->vm_inv_eng0_sem +
- hub->eng_distance * eng, 0, hub_ip);
+   WREG32_RLC_NO_KIQ(sem, 0, hub_ip);
 
/* Issue additional private vm invalidation to MMHUB */
if ((vmhub != AMDGPU_GFXHUB(0)) &&
@@ -268,50 +284,8 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device 
*adev, uint32_t vmid,
 
spin_unlock(>gmc.invalidate_lock);
 
-   if (i < adev->usec_timeout)
-   return;
-
-   DRM_ERROR("Timeout waiting for VM flush ACK!\n");
-}
-
-/**
- 

[PATCH 01/11] drm/amdgpu: fix and cleanup gmc_v9_0_flush_gpu_tlb

2023-09-05 Thread Christian König
The KIQ code path was ignoring the second flush. Also avoid long lines and
re-calculating the register offsets over and over again.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 29 +--
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index 0673cda547bb..4f6990ba71cb 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -814,13 +814,17 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
uint32_t vmhub, uint32_t flush_type)
 {
bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(adev, vmhub);
+   u32 j, inv_req, inv_req2, tmp, sem, req, ack;
const unsigned int eng = 17;
-   u32 j, inv_req, inv_req2, tmp;
struct amdgpu_vmhub *hub;
 
BUG_ON(vmhub >= AMDGPU_MAX_VMHUBS);
 
hub = >vmhub[vmhub];
+   sem = hub->vm_inv_eng0_sem + hub->eng_distance * eng;
+   req = hub->vm_inv_eng0_req + hub->eng_distance * eng;
+   ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng;
+
if (adev->gmc.xgmi.num_physical_nodes &&
adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 0)) {
/* Vega20+XGMI caches PTEs in TC and TLB. Add a
@@ -852,6 +856,10 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
 
amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
   1 << vmid);
+   if (inv_req2)
+   amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack,
+  inv_req2, 1 << vmid);
+
up_read(>reset_domain->sem);
return;
}
@@ -870,9 +878,9 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
for (j = 0; j < adev->usec_timeout; j++) {
/* a read return value of 1 means semaphore acquire */
if (vmhub >= AMDGPU_MMHUB0(0))
-   tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, 
hub->vm_inv_eng0_sem + hub->eng_distance * eng);
+   tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, sem);
else
-   tmp = RREG32_SOC15_IP_NO_KIQ(GC, 
hub->vm_inv_eng0_sem + hub->eng_distance * eng);
+   tmp = RREG32_SOC15_IP_NO_KIQ(GC, sem);
if (tmp & 0x1)
break;
udelay(1);
@@ -884,9 +892,9 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
 
do {
if (vmhub >= AMDGPU_MMHUB0(0))
-   WREG32_SOC15_IP_NO_KIQ(MMHUB, hub->vm_inv_eng0_req + 
hub->eng_distance * eng, inv_req);
+   WREG32_SOC15_IP_NO_KIQ(MMHUB, req, inv_req);
else
-   WREG32_SOC15_IP_NO_KIQ(GC, hub->vm_inv_eng0_req + 
hub->eng_distance * eng, inv_req);
+   WREG32_SOC15_IP_NO_KIQ(GC, req, inv_req);
 
/*
 * Issue a dummy read to wait for the ACK register to
@@ -895,14 +903,13 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
 */
if ((vmhub == AMDGPU_GFXHUB(0)) &&
(adev->ip_versions[GC_HWIP][0] < IP_VERSION(9, 4, 2)))
-   RREG32_NO_KIQ(hub->vm_inv_eng0_req +
- hub->eng_distance * eng);
+   RREG32_NO_KIQ(req);
 
for (j = 0; j < adev->usec_timeout; j++) {
if (vmhub >= AMDGPU_MMHUB0(0))
-   tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, 
hub->vm_inv_eng0_ack + hub->eng_distance * eng);
+   tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, ack);
else
-   tmp = RREG32_SOC15_IP_NO_KIQ(GC, 
hub->vm_inv_eng0_ack + hub->eng_distance * eng);
+   tmp = RREG32_SOC15_IP_NO_KIQ(GC, ack);
if (tmp & (1 << vmid))
break;
udelay(1);
@@ -919,9 +926,9 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
 * write with 0 means semaphore release
 */
if (vmhub >= AMDGPU_MMHUB0(0))
-   WREG32_SOC15_IP_NO_KIQ(MMHUB, hub->vm_inv_eng0_sem + 
hub->eng_distance * eng, 0);
+   WREG32_SOC15_IP_NO_KIQ(MMHUB, sem, 0);
else
-   WREG32_SOC15_IP_NO_KIQ(GC, hub->vm_inv_eng0_sem + 
hub->eng_distance * eng, 0);
+   WREG32_SOC15_IP_NO_KIQ(GC, sem, 0);
}
 

  1   2   >