RE: [enable VCN2.0 for NV12 SRIOV 3/6] drm/amdgpu: implement initialization part on VCN2.0 for SRIOV

2020-03-05 Thread Liu, Monk
Okay, no problem 

_
Monk Liu|GPU Virtualization Team |AMD


-Original Message-
From: Liu, Leo  
Sent: Friday, March 6, 2020 12:08 AM
To: Liu, Monk ; amd-gfx@lists.freedesktop.org
Subject: Re: [enable VCN2.0 for NV12 SRIOV 3/6] drm/amdgpu: implement 
initialization part on VCN2.0 for SRIOV


On 2020-03-05 8:33 a.m., Monk Liu wrote:
> one dec ring and one enc ring
It seems more than that, you might add more messages.


>
> Signed-off-by: Monk Liu 
> ---
>   drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 231 
> +-
>   1 file changed, 228 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c 
> b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
> index c387c81..421e5bf 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
> @@ -29,6 +29,7 @@
>   #include "soc15d.h"
>   #include "amdgpu_pm.h"
>   #include "amdgpu_psp.h"
> +#include "mmsch_v2_0.h"
>   
>   #include "vcn/vcn_2_0_0_offset.h"
>   #include "vcn/vcn_2_0_0_sh_mask.h"
> @@ -54,7 +55,7 @@ static int vcn_v2_0_set_powergating_state(void *handle,
>   enum amd_powergating_state state);
>   static int vcn_v2_0_pause_dpg_mode(struct amdgpu_device *adev,
>   int inst_idx, struct dpg_pause_state 
> *new_state);
> -
> +static int vcn_v2_0_start_sriov(struct amdgpu_device *adev);

Please keep the empty line here.


>   /**
>* vcn_v2_0_early_init - set function pointers
>*
> @@ -67,7 +68,10 @@ static int vcn_v2_0_early_init(void *handle)
>   struct amdgpu_device *adev = (struct amdgpu_device *)handle;
>   
>   adev->vcn.num_vcn_inst = 1;
> - adev->vcn.num_enc_rings = 2;
> + if (amdgpu_sriov_vf(adev))
> + adev->vcn.num_enc_rings = 1;
> + else
> + adev->vcn.num_enc_rings = 2;
>   
>   vcn_v2_0_set_dec_ring_funcs(adev);
>   vcn_v2_0_set_enc_ring_funcs(adev);
> @@ -154,7 +158,10 @@ static int vcn_v2_0_sw_init(void *handle)
>   for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
>   ring = >vcn.inst->ring_enc[i];
>   ring->use_doorbell = true;
> - ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 
> 1) + 2 + i;
> + if (!amdgpu_sriov_vf(adev))
> + ring->doorbell_index = 
> (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + i;
> + else
> + ring->doorbell_index = 
> (adev->doorbell_index.vcn.vcn_ring0_1 << 1) 
> ++ 1 + i;
>   sprintf(ring->name, "vcn_enc%d", i);
>   r = amdgpu_ring_init(adev, ring, 512, >vcn.inst->irq, 0);
>   if (r)
> @@ -163,6 +170,10 @@ static int vcn_v2_0_sw_init(void *handle)
>   
>   adev->vcn.pause_dpg_mode = vcn_v2_0_pause_dpg_mode;
>   
> + r = amdgpu_virt_alloc_mm_table(adev);
> + if (r)
> + return r;
> +

This is not needed for bare metal.


>   return 0;
>   }
>   
> @@ -178,6 +189,8 @@ static int vcn_v2_0_sw_fini(void *handle)
>   int r;
>   struct amdgpu_device *adev = (struct amdgpu_device *)handle;
>   
> + amdgpu_virt_free_mm_table(adev);
> +

same as above here.


Regards,

Leo



>   r = amdgpu_vcn_suspend(adev);
>   if (r)
>   return r;
> @@ -203,6 +216,9 @@ static int vcn_v2_0_hw_init(void *handle)
>   adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
>ring->doorbell_index, 0);
>   
> + if (amdgpu_sriov_vf(adev))
> + vcn_v2_0_start_sriov(adev);
> +
>   r = amdgpu_ring_test_helper(ring);
>   if (r)
>   goto done;
> @@ -1680,6 +1696,215 @@ static int vcn_v2_0_set_powergating_state(void 
> *handle,
>   return ret;
>   }
>   
> +static int vcn_v2_0_start_mmsch(struct amdgpu_device *adev,
> + struct amdgpu_mm_table *table)
> +{
> + uint32_t data = 0, loop;
> + uint64_t addr = table->gpu_addr;
> + struct mmsch_v2_0_init_header *header;
> + uint32_t size;
> + int i;
> +
> + header = (struct mmsch_v2_0_init_header *)table->cpu_addr;
> + size = header->header_size + header->vcn_table_size;
> +
> + /* 1, write to vce_mmsch_vf_ctx_addr_lo/hi register with GPU mc addr
> +  * of memory descriptor location
> +  */
> + WREG32_SOC15(UVD, 0, mmMMSCH_VF_CTX_ADDR_LO, lower_32_bits(addr));
> + WREG32_SOC15(UVD, 0, mmMMSCH_

Re: [enable VCN2.0 for NV12 SRIOV 3/6] drm/amdgpu: implement initialization part on VCN2.0 for SRIOV

2020-03-05 Thread Leo Liu



On 2020-03-05 8:33 a.m., Monk Liu wrote:

one dec ring and one enc ring

It seems more than that, you might add more messages.




Signed-off-by: Monk Liu 
---
  drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 231 +-
  1 file changed, 228 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c 
b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
index c387c81..421e5bf 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
@@ -29,6 +29,7 @@
  #include "soc15d.h"
  #include "amdgpu_pm.h"
  #include "amdgpu_psp.h"
+#include "mmsch_v2_0.h"
  
  #include "vcn/vcn_2_0_0_offset.h"

  #include "vcn/vcn_2_0_0_sh_mask.h"
@@ -54,7 +55,7 @@ static int vcn_v2_0_set_powergating_state(void *handle,
enum amd_powergating_state state);
  static int vcn_v2_0_pause_dpg_mode(struct amdgpu_device *adev,
int inst_idx, struct dpg_pause_state 
*new_state);
-
+static int vcn_v2_0_start_sriov(struct amdgpu_device *adev);


Please keep the empty line here.



  /**
   * vcn_v2_0_early_init - set function pointers
   *
@@ -67,7 +68,10 @@ static int vcn_v2_0_early_init(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  
  	adev->vcn.num_vcn_inst = 1;

-   adev->vcn.num_enc_rings = 2;
+   if (amdgpu_sriov_vf(adev))
+   adev->vcn.num_enc_rings = 1;
+   else
+   adev->vcn.num_enc_rings = 2;
  
  	vcn_v2_0_set_dec_ring_funcs(adev);

vcn_v2_0_set_enc_ring_funcs(adev);
@@ -154,7 +158,10 @@ static int vcn_v2_0_sw_init(void *handle)
for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
ring = >vcn.inst->ring_enc[i];
ring->use_doorbell = true;
-   ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 
1) + 2 + i;
+   if (!amdgpu_sriov_vf(adev))
+   ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 
<< 1) + 2 + i;
+   else
+   ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 
<< 1) + 1 + i;
sprintf(ring->name, "vcn_enc%d", i);
r = amdgpu_ring_init(adev, ring, 512, >vcn.inst->irq, 0);
if (r)
@@ -163,6 +170,10 @@ static int vcn_v2_0_sw_init(void *handle)
  
  	adev->vcn.pause_dpg_mode = vcn_v2_0_pause_dpg_mode;
  
+	r = amdgpu_virt_alloc_mm_table(adev);

+   if (r)
+   return r;
+


This is not needed for bare metal.



return 0;
  }
  
@@ -178,6 +189,8 @@ static int vcn_v2_0_sw_fini(void *handle)

int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  
+	amdgpu_virt_free_mm_table(adev);

+


same as above here.


Regards,

Leo




r = amdgpu_vcn_suspend(adev);
if (r)
return r;
@@ -203,6 +216,9 @@ static int vcn_v2_0_hw_init(void *handle)
adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
 ring->doorbell_index, 0);
  
+	if (amdgpu_sriov_vf(adev))

+   vcn_v2_0_start_sriov(adev);
+
r = amdgpu_ring_test_helper(ring);
if (r)
goto done;
@@ -1680,6 +1696,215 @@ static int vcn_v2_0_set_powergating_state(void *handle,
return ret;
  }
  
+static int vcn_v2_0_start_mmsch(struct amdgpu_device *adev,

+   struct amdgpu_mm_table *table)
+{
+   uint32_t data = 0, loop;
+   uint64_t addr = table->gpu_addr;
+   struct mmsch_v2_0_init_header *header;
+   uint32_t size;
+   int i;
+
+   header = (struct mmsch_v2_0_init_header *)table->cpu_addr;
+   size = header->header_size + header->vcn_table_size;
+
+   /* 1, write to vce_mmsch_vf_ctx_addr_lo/hi register with GPU mc addr
+* of memory descriptor location
+*/
+   WREG32_SOC15(UVD, 0, mmMMSCH_VF_CTX_ADDR_LO, lower_32_bits(addr));
+   WREG32_SOC15(UVD, 0, mmMMSCH_VF_CTX_ADDR_HI, upper_32_bits(addr));
+
+   /* 2, update vmid of descriptor */
+   data = RREG32_SOC15(UVD, 0, mmMMSCH_VF_VMID);
+   data &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
+   /* use domain0 for MM scheduler */
+   data |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
+   WREG32_SOC15(UVD, 0, mmMMSCH_VF_VMID, data);
+
+   /* 3, notify mmsch about the size of this descriptor */
+   WREG32_SOC15(UVD, 0, mmMMSCH_VF_CTX_SIZE, size);
+
+   /* 4, set resp to zero */
+   WREG32_SOC15(UVD, 0, mmMMSCH_VF_MAILBOX_RESP, 0);
+
+   adev->vcn.inst->ring_dec.wptr = 0;
+   adev->vcn.inst->ring_dec.wptr_old = 0;
+   vcn_v2_0_dec_ring_set_wptr(>vcn.inst->ring_dec);
+
+   for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
+   adev->vcn.inst->ring_enc[i].wptr = 0;
+   adev->vcn.inst->ring_enc[i].wptr_old = 0;
+   vcn_v2_0_enc_ring_set_wptr(>vcn.inst->ring_enc[i]);
+   }
+
+   /* 5, kick off 

[enable VCN2.0 for NV12 SRIOV 3/6] drm/amdgpu: implement initialization part on VCN2.0 for SRIOV

2020-03-05 Thread Monk Liu
one dec ring and one enc ring

Signed-off-by: Monk Liu 
---
 drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 231 +-
 1 file changed, 228 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c 
b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
index c387c81..421e5bf 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
@@ -29,6 +29,7 @@
 #include "soc15d.h"
 #include "amdgpu_pm.h"
 #include "amdgpu_psp.h"
+#include "mmsch_v2_0.h"
 
 #include "vcn/vcn_2_0_0_offset.h"
 #include "vcn/vcn_2_0_0_sh_mask.h"
@@ -54,7 +55,7 @@ static int vcn_v2_0_set_powergating_state(void *handle,
enum amd_powergating_state state);
 static int vcn_v2_0_pause_dpg_mode(struct amdgpu_device *adev,
int inst_idx, struct dpg_pause_state 
*new_state);
-
+static int vcn_v2_0_start_sriov(struct amdgpu_device *adev);
 /**
  * vcn_v2_0_early_init - set function pointers
  *
@@ -67,7 +68,10 @@ static int vcn_v2_0_early_init(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
adev->vcn.num_vcn_inst = 1;
-   adev->vcn.num_enc_rings = 2;
+   if (amdgpu_sriov_vf(adev))
+   adev->vcn.num_enc_rings = 1;
+   else
+   adev->vcn.num_enc_rings = 2;
 
vcn_v2_0_set_dec_ring_funcs(adev);
vcn_v2_0_set_enc_ring_funcs(adev);
@@ -154,7 +158,10 @@ static int vcn_v2_0_sw_init(void *handle)
for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
ring = >vcn.inst->ring_enc[i];
ring->use_doorbell = true;
-   ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 
1) + 2 + i;
+   if (!amdgpu_sriov_vf(adev))
+   ring->doorbell_index = 
(adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + i;
+   else
+   ring->doorbell_index = 
(adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + i;
sprintf(ring->name, "vcn_enc%d", i);
r = amdgpu_ring_init(adev, ring, 512, >vcn.inst->irq, 0);
if (r)
@@ -163,6 +170,10 @@ static int vcn_v2_0_sw_init(void *handle)
 
adev->vcn.pause_dpg_mode = vcn_v2_0_pause_dpg_mode;
 
+   r = amdgpu_virt_alloc_mm_table(adev);
+   if (r)
+   return r;
+
return 0;
 }
 
@@ -178,6 +189,8 @@ static int vcn_v2_0_sw_fini(void *handle)
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+   amdgpu_virt_free_mm_table(adev);
+
r = amdgpu_vcn_suspend(adev);
if (r)
return r;
@@ -203,6 +216,9 @@ static int vcn_v2_0_hw_init(void *handle)
adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
 ring->doorbell_index, 0);
 
+   if (amdgpu_sriov_vf(adev))
+   vcn_v2_0_start_sriov(adev);
+
r = amdgpu_ring_test_helper(ring);
if (r)
goto done;
@@ -1680,6 +1696,215 @@ static int vcn_v2_0_set_powergating_state(void *handle,
return ret;
 }
 
+static int vcn_v2_0_start_mmsch(struct amdgpu_device *adev,
+   struct amdgpu_mm_table *table)
+{
+   uint32_t data = 0, loop;
+   uint64_t addr = table->gpu_addr;
+   struct mmsch_v2_0_init_header *header;
+   uint32_t size;
+   int i;
+
+   header = (struct mmsch_v2_0_init_header *)table->cpu_addr;
+   size = header->header_size + header->vcn_table_size;
+
+   /* 1, write to vce_mmsch_vf_ctx_addr_lo/hi register with GPU mc addr
+* of memory descriptor location
+*/
+   WREG32_SOC15(UVD, 0, mmMMSCH_VF_CTX_ADDR_LO, lower_32_bits(addr));
+   WREG32_SOC15(UVD, 0, mmMMSCH_VF_CTX_ADDR_HI, upper_32_bits(addr));
+
+   /* 2, update vmid of descriptor */
+   data = RREG32_SOC15(UVD, 0, mmMMSCH_VF_VMID);
+   data &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
+   /* use domain0 for MM scheduler */
+   data |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
+   WREG32_SOC15(UVD, 0, mmMMSCH_VF_VMID, data);
+
+   /* 3, notify mmsch about the size of this descriptor */
+   WREG32_SOC15(UVD, 0, mmMMSCH_VF_CTX_SIZE, size);
+
+   /* 4, set resp to zero */
+   WREG32_SOC15(UVD, 0, mmMMSCH_VF_MAILBOX_RESP, 0);
+
+   adev->vcn.inst->ring_dec.wptr = 0;
+   adev->vcn.inst->ring_dec.wptr_old = 0;
+   vcn_v2_0_dec_ring_set_wptr(>vcn.inst->ring_dec);
+
+   for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
+   adev->vcn.inst->ring_enc[i].wptr = 0;
+   adev->vcn.inst->ring_enc[i].wptr_old = 0;
+   vcn_v2_0_enc_ring_set_wptr(>vcn.inst->ring_enc[i]);
+   }
+
+   /* 5, kick off the initialization and wait until
+* VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero
+*/
+   WREG32_SOC15(UVD, 0, mmMMSCH_VF_MAILBOX_HOST, 0x1001);
+
+   data = RREG32_SOC15(UVD, 0,