[PATCH 2/5] drm/amdgpu: export function to flush TLB via pasid

2019-12-19 Thread Alex Sierra
This can be used directly from amdgpu and amdkfd to invalidate
TLB through pasid.
It supports gmc v7, v8, v9 and v10.

Change-Id: I6563a8eba2e42d1a67fa2547156c20da41d1e490
Signed-off-by: Alex Sierra 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |  6 ++
 drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 81 
 drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   | 33 ++
 drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   | 34 ++
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 84 +
 5 files changed, 238 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
index b499a3de8bb6..b6413a56f546 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
@@ -92,6 +92,9 @@ struct amdgpu_gmc_funcs {
/* flush the vm tlb via mmio */
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);
/* flush the vm tlb via ring */
uint64_t (*emit_flush_gpu_tlb)(struct amdgpu_ring *ring, unsigned vmid,
   uint64_t pd_addr);
@@ -216,6 +219,9 @@ struct amdgpu_gmc {
 };
 
 #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) \
+   ((adev)->gmc.gmc_funcs->flush_gpu_tlb_pasid \
+   ((adev), (pasid), (type), (allhub)))
 #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))
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index f5725336a5f2..b1a5408a8d7e 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -30,6 +30,8 @@
 #include "hdp/hdp_5_0_0_sh_mask.h"
 #include "gc/gc_10_1_0_sh_mask.h"
 #include "mmhub/mmhub_2_0_0_sh_mask.h"
+#include "athub/athub_2_0_0_sh_mask.h"
+#include "athub/athub_2_0_0_offset.h"
 #include "dcn/dcn_2_0_0_offset.h"
 #include "dcn/dcn_2_0_0_sh_mask.h"
 #include "oss/osssys_5_0_0_offset.h"
@@ -37,6 +39,7 @@
 #include "navi10_enum.h"
 
 #include "soc15.h"
+#include "soc15d.h"
 #include "soc15_common.h"
 
 #include "nbio_v2_3.h"
@@ -234,6 +237,48 @@ static bool gmc_v10_0_use_invalidate_semaphore(struct 
amdgpu_device *adev,
(!amdgpu_sriov_vf(adev)));
 }
 
+static bool gmc_v10_0_get_atc_vmid_pasid_mapping_info(
+   struct amdgpu_device *adev,
+   uint8_t vmid, uint16_t *p_pasid)
+{
+   uint32_t value;
+
+   value = RREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING)
++ vmid);
+   *p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK;
+
+   return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
+}
+
+static int gmc_v10_0_invalidate_tlbs_with_kiq(struct amdgpu_device *adev,
+   uint16_t pasid, uint32_t flush_type,
+   bool all_hub)
+{
+   signed long r;
+   uint32_t seq;
+   struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
+
+   spin_lock(&adev->gfx.kiq.ring_lock);
+   amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs package*/
+   amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0));
+   amdgpu_ring_write(ring,
+   PACKET3_INVALIDATE_TLBS_DST_SEL(1) |
+   PACKET3_INVALIDATE_TLBS_ALL_HUB(all_hub) |
+   PACKET3_INVALIDATE_TLBS_PASID(pasid) |
+   PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(flush_type));
+   amdgpu_fence_emit_polling(ring, &seq);
+   amdgpu_ring_commit(ring);
+   spin_unlock(&adev->gfx.kiq.ring_lock);
+
+   r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
+   if (r < 1) {
+   DRM_ERROR("wait for kiq fence error: %ld.\n", r);
+   return -ETIME;
+   }
+
+   return 0;
+}
+
 /*
  * GART
  * VMID 0 is the physical GPU addresses as used by the kernel.
@@ -380,6 +425,41 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
DRM_ERROR("Error flushing GPU TLB using the SDMA (%d)!\n", r);
 }
 
+/**
+ * gmc_v10_0_flush_gpu_tlb_pasid - tlb flush via pasid
+ *
+ * @adev: amdgpu_device pointer
+ * @pasid: pasid to be flush
+ *
+ * Flush the TLB for the requested pasid.
+ */
+static int gmc_v10_0_flush_gpu_tlb_pasid(struct amdgpu_device

[PATCH 2/5] drm/amdgpu: export function to flush TLB via pasid

2020-01-02 Thread Alex Sierra
This can be used directly from amdgpu and amdkfd to invalidate
TLB through pasid.
It supports gmc v7, v8, v9 and v10.

Change-Id: I6563a8eba2e42d1a67fa2547156c20da41d1e490
Signed-off-by: Alex Sierra 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |  6 ++
 drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 87 
 drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   | 33 +
 drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   | 34 ++
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 89 +
 5 files changed, 249 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
index b499a3de8bb6..b6413a56f546 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
@@ -92,6 +92,9 @@ struct amdgpu_gmc_funcs {
/* flush the vm tlb via mmio */
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);
/* flush the vm tlb via ring */
uint64_t (*emit_flush_gpu_tlb)(struct amdgpu_ring *ring, unsigned vmid,
   uint64_t pd_addr);
@@ -216,6 +219,9 @@ struct amdgpu_gmc {
 };
 
 #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) \
+   ((adev)->gmc.gmc_funcs->flush_gpu_tlb_pasid \
+   ((adev), (pasid), (type), (allhub)))
 #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))
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index f5725336a5f2..11a2252e60f6 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -30,6 +30,8 @@
 #include "hdp/hdp_5_0_0_sh_mask.h"
 #include "gc/gc_10_1_0_sh_mask.h"
 #include "mmhub/mmhub_2_0_0_sh_mask.h"
+#include "athub/athub_2_0_0_sh_mask.h"
+#include "athub/athub_2_0_0_offset.h"
 #include "dcn/dcn_2_0_0_offset.h"
 #include "dcn/dcn_2_0_0_sh_mask.h"
 #include "oss/osssys_5_0_0_offset.h"
@@ -37,6 +39,7 @@
 #include "navi10_enum.h"
 
 #include "soc15.h"
+#include "soc15d.h"
 #include "soc15_common.h"
 
 #include "nbio_v2_3.h"
@@ -234,6 +237,48 @@ static bool gmc_v10_0_use_invalidate_semaphore(struct 
amdgpu_device *adev,
(!amdgpu_sriov_vf(adev)));
 }
 
+static bool gmc_v10_0_get_atc_vmid_pasid_mapping_info(
+   struct amdgpu_device *adev,
+   uint8_t vmid, uint16_t *p_pasid)
+{
+   uint32_t value;
+
+   value = RREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING)
++ vmid);
+   *p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK;
+
+   return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
+}
+
+static int gmc_v10_0_invalidate_tlbs_with_kiq(struct amdgpu_device *adev,
+   uint16_t pasid, uint32_t flush_type,
+   bool all_hub)
+{
+   signed long r;
+   uint32_t seq;
+   struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
+
+   spin_lock(&adev->gfx.kiq.ring_lock);
+   amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs package*/
+   amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0));
+   amdgpu_ring_write(ring,
+   PACKET3_INVALIDATE_TLBS_DST_SEL(1) |
+   PACKET3_INVALIDATE_TLBS_ALL_HUB(all_hub) |
+   PACKET3_INVALIDATE_TLBS_PASID(pasid) |
+   PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(flush_type));
+   amdgpu_fence_emit_polling(ring, &seq);
+   amdgpu_ring_commit(ring);
+   spin_unlock(&adev->gfx.kiq.ring_lock);
+
+   r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
+   if (r < 1) {
+   DRM_ERROR("wait for kiq fence error: %ld.\n", r);
+   return -ETIME;
+   }
+
+   return 0;
+}
+
 /*
  * GART
  * VMID 0 is the physical GPU addresses as used by the kernel.
@@ -380,6 +425,47 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
DRM_ERROR("Error flushing GPU TLB using the SDMA (%d)!\n", r);
 }
 
+/**
+ * gmc_v10_0_flush_gpu_tlb_pasid - tlb flush via pasid
+ *
+ * @adev: amdgpu_device pointer
+ * @pasid: pasid to be flush
+ *
+ * Flush the TLB for the requested pasid.
+ */
+static int gmc_v10_0_flush_gpu_tlb_pasid(struct amdgpu_device 

Re: [PATCH 2/5] drm/amdgpu: export function to flush TLB via pasid

2019-12-20 Thread Felix Kuehling

On 2019-12-20 1:24, Alex Sierra wrote:

This can be used directly from amdgpu and amdkfd to invalidate
TLB through pasid.
It supports gmc v7, v8, v9 and v10.


Two small corrections inline to make the behaviour between KIQ and 
MMIO-based flushing consistent. Looks good otherwise.





Change-Id: I6563a8eba2e42d1a67fa2547156c20da41d1e490
Signed-off-by: Alex Sierra 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |  6 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 81 
  drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   | 33 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   | 34 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 84 +
  5 files changed, 238 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
index b499a3de8bb6..b6413a56f546 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
@@ -92,6 +92,9 @@ struct amdgpu_gmc_funcs {
/* flush the vm tlb via mmio */
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);
/* flush the vm tlb via ring */
uint64_t (*emit_flush_gpu_tlb)(struct amdgpu_ring *ring, unsigned vmid,
   uint64_t pd_addr);
@@ -216,6 +219,9 @@ struct amdgpu_gmc {
  };
  
  #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) \
+   ((adev)->gmc.gmc_funcs->flush_gpu_tlb_pasid \
+   ((adev), (pasid), (type), (allhub)))
  #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))
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index f5725336a5f2..b1a5408a8d7e 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -30,6 +30,8 @@
  #include "hdp/hdp_5_0_0_sh_mask.h"
  #include "gc/gc_10_1_0_sh_mask.h"
  #include "mmhub/mmhub_2_0_0_sh_mask.h"
+#include "athub/athub_2_0_0_sh_mask.h"
+#include "athub/athub_2_0_0_offset.h"
  #include "dcn/dcn_2_0_0_offset.h"
  #include "dcn/dcn_2_0_0_sh_mask.h"
  #include "oss/osssys_5_0_0_offset.h"
@@ -37,6 +39,7 @@
  #include "navi10_enum.h"
  
  #include "soc15.h"

+#include "soc15d.h"
  #include "soc15_common.h"
  
  #include "nbio_v2_3.h"

@@ -234,6 +237,48 @@ static bool gmc_v10_0_use_invalidate_semaphore(struct 
amdgpu_device *adev,
(!amdgpu_sriov_vf(adev)));
  }
  
+static bool gmc_v10_0_get_atc_vmid_pasid_mapping_info(

+   struct amdgpu_device *adev,
+   uint8_t vmid, uint16_t *p_pasid)
+{
+   uint32_t value;
+
+   value = RREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING)
++ vmid);
+   *p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK;
+
+   return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
+}
+
+static int gmc_v10_0_invalidate_tlbs_with_kiq(struct amdgpu_device *adev,
+   uint16_t pasid, uint32_t flush_type,
+   bool all_hub)
+{
+   signed long r;
+   uint32_t seq;
+   struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
+
+   spin_lock(&adev->gfx.kiq.ring_lock);
+   amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs package*/
+   amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0));
+   amdgpu_ring_write(ring,
+   PACKET3_INVALIDATE_TLBS_DST_SEL(1) |
+   PACKET3_INVALIDATE_TLBS_ALL_HUB(all_hub) |
+   PACKET3_INVALIDATE_TLBS_PASID(pasid) |
+   PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(flush_type));
+   amdgpu_fence_emit_polling(ring, &seq);
+   amdgpu_ring_commit(ring);
+   spin_unlock(&adev->gfx.kiq.ring_lock);
+
+   r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
+   if (r < 1) {
+   DRM_ERROR("wait for kiq fence error: %ld.\n", r);
+   return -ETIME;
+   }
+
+   return 0;
+}
+
  /*
   * GART
   * VMID 0 is the physical GPU addresses as used by the kernel.
@@ -380,6 +425,41 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
DRM_ERROR("Error flushing GPU TLB using the SDMA (%d)!\n", r);
  }
  
+/**

+ * gmc_v10_0_flush_gpu_tlb_pasid

Re: [PATCH 2/5] drm/amdgpu: export function to flush TLB via pasid

2019-12-20 Thread Yong Zhao



On 2019-12-20 1:24 a.m., Alex Sierra wrote:

This can be used directly from amdgpu and amdkfd to invalidate
TLB through pasid.
It supports gmc v7, v8, v9 and v10.

Change-Id: I6563a8eba2e42d1a67fa2547156c20da41d1e490
Signed-off-by: Alex Sierra 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |  6 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 81 
  drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   | 33 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   | 34 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 84 +
  5 files changed, 238 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
index b499a3de8bb6..b6413a56f546 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
@@ -92,6 +92,9 @@ struct amdgpu_gmc_funcs {
/* flush the vm tlb via mmio */
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);
/* flush the vm tlb via ring */
uint64_t (*emit_flush_gpu_tlb)(struct amdgpu_ring *ring, unsigned vmid,
   uint64_t pd_addr);
@@ -216,6 +219,9 @@ struct amdgpu_gmc {
  };
  
  #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) \
+   ((adev)->gmc.gmc_funcs->flush_gpu_tlb_pasid \
+   ((adev), (pasid), (type), (allhub)))
  #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))
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index f5725336a5f2..b1a5408a8d7e 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -30,6 +30,8 @@
  #include "hdp/hdp_5_0_0_sh_mask.h"
  #include "gc/gc_10_1_0_sh_mask.h"
  #include "mmhub/mmhub_2_0_0_sh_mask.h"
+#include "athub/athub_2_0_0_sh_mask.h"
+#include "athub/athub_2_0_0_offset.h"
  #include "dcn/dcn_2_0_0_offset.h"
  #include "dcn/dcn_2_0_0_sh_mask.h"
  #include "oss/osssys_5_0_0_offset.h"
@@ -37,6 +39,7 @@
  #include "navi10_enum.h"
  
  #include "soc15.h"

+#include "soc15d.h"
  #include "soc15_common.h"
  
  #include "nbio_v2_3.h"

@@ -234,6 +237,48 @@ static bool gmc_v10_0_use_invalidate_semaphore(struct 
amdgpu_device *adev,
(!amdgpu_sriov_vf(adev)));
  }
  
+static bool gmc_v10_0_get_atc_vmid_pasid_mapping_info(

+   struct amdgpu_device *adev,
+   uint8_t vmid, uint16_t *p_pasid)
+{
+   uint32_t value;
+
+   value = RREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING)
++ vmid);
+   *p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK;
+
+   return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
+}
+
+static int gmc_v10_0_invalidate_tlbs_with_kiq(struct amdgpu_device *adev,
+   uint16_t pasid, uint32_t flush_type,
+   bool all_hub)
+{
+   signed long r;
+   uint32_t seq;
+   struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
+
+   spin_lock(&adev->gfx.kiq.ring_lock);
+   amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs package*/
+   amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0));
+   amdgpu_ring_write(ring,
+   PACKET3_INVALIDATE_TLBS_DST_SEL(1) |
+   PACKET3_INVALIDATE_TLBS_ALL_HUB(all_hub) |
+   PACKET3_INVALIDATE_TLBS_PASID(pasid) |
+   PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(flush_type));
+   amdgpu_fence_emit_polling(ring, &seq);
+   amdgpu_ring_commit(ring);
+   spin_unlock(&adev->gfx.kiq.ring_lock);
+
+   r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
+   if (r < 1) {
+   DRM_ERROR("wait for kiq fence error: %ld.\n", r);
+   return -ETIME;
+   }
+
+   return 0;
+}
+
  /*
   * GART
   * VMID 0 is the physical GPU addresses as used by the kernel.
@@ -380,6 +425,41 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
DRM_ERROR("Error flushing GPU TLB using the SDMA (%d)!\n", r);
  }
  
+/**

+ * gmc_v10_0_flush_gpu_tlb_pasid - tlb flush via pasid
+ *
+ * @adev: amdgpu_device pointer
+ * @pasid: pasid to be flush
+ *
+ * Flush the TLB for the r

Re: [PATCH 2/5] drm/amdgpu: export function to flush TLB via pasid

2020-01-02 Thread Yong Zhao

See one inline comment. Other than that:

Acked-by: Yong Zhao 

On 2020-01-02 4:11 p.m., Alex Sierra wrote:

This can be used directly from amdgpu and amdkfd to invalidate
TLB through pasid.
It supports gmc v7, v8, v9 and v10.

Change-Id: I6563a8eba2e42d1a67fa2547156c20da41d1e490
Signed-off-by: Alex Sierra 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |  6 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 87 
  drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   | 33 +
  drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   | 34 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 89 +
  5 files changed, 249 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
index b499a3de8bb6..b6413a56f546 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
@@ -92,6 +92,9 @@ struct amdgpu_gmc_funcs {
/* flush the vm tlb via mmio */
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);
/* flush the vm tlb via ring */
uint64_t (*emit_flush_gpu_tlb)(struct amdgpu_ring *ring, unsigned vmid,
   uint64_t pd_addr);
@@ -216,6 +219,9 @@ struct amdgpu_gmc {
  };
  
  #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) \
+   ((adev)->gmc.gmc_funcs->flush_gpu_tlb_pasid \
+   ((adev), (pasid), (type), (allhub)))
  #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))
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index f5725336a5f2..11a2252e60f6 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -30,6 +30,8 @@
  #include "hdp/hdp_5_0_0_sh_mask.h"
  #include "gc/gc_10_1_0_sh_mask.h"
  #include "mmhub/mmhub_2_0_0_sh_mask.h"
+#include "athub/athub_2_0_0_sh_mask.h"
+#include "athub/athub_2_0_0_offset.h"
  #include "dcn/dcn_2_0_0_offset.h"
  #include "dcn/dcn_2_0_0_sh_mask.h"
  #include "oss/osssys_5_0_0_offset.h"
@@ -37,6 +39,7 @@
  #include "navi10_enum.h"
  
  #include "soc15.h"

+#include "soc15d.h"
  #include "soc15_common.h"
  
  #include "nbio_v2_3.h"

@@ -234,6 +237,48 @@ static bool gmc_v10_0_use_invalidate_semaphore(struct 
amdgpu_device *adev,
(!amdgpu_sriov_vf(adev)));
  }
  
+static bool gmc_v10_0_get_atc_vmid_pasid_mapping_info(

+   struct amdgpu_device *adev,
+   uint8_t vmid, uint16_t *p_pasid)
+{
+   uint32_t value;
+
+   value = RREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING)
++ vmid);
+   *p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK;
+
+   return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
+}
+
+static int gmc_v10_0_invalidate_tlbs_with_kiq(struct amdgpu_device *adev,
+   uint16_t pasid, uint32_t flush_type,
+   bool all_hub)
+{
+   signed long r;
+   uint32_t seq;
+   struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
+
+   spin_lock(&adev->gfx.kiq.ring_lock);
+   amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs package*/
+   amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0));
+   amdgpu_ring_write(ring,
+   PACKET3_INVALIDATE_TLBS_DST_SEL(1) |
+   PACKET3_INVALIDATE_TLBS_ALL_HUB(all_hub) |
+   PACKET3_INVALIDATE_TLBS_PASID(pasid) |
+   PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(flush_type));
+   amdgpu_fence_emit_polling(ring, &seq);
+   amdgpu_ring_commit(ring);
+   spin_unlock(&adev->gfx.kiq.ring_lock);
+
+   r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
+   if (r < 1) {
+   DRM_ERROR("wait for kiq fence error: %ld.\n", r);
+   return -ETIME;
+   }
+
+   return 0;
+}
+
  /*
   * GART
   * VMID 0 is the physical GPU addresses as used by the kernel.
@@ -380,6 +425,47 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
DRM_ERROR("Error flushing GPU TLB using the SDMA (%d)!\n", r);
  }
  
+/**

+ * gmc_v10_0_flush_gpu_tlb_pasid - tlb flush via pasid
+ *
+ * @adev: amdgpu_device pointer

Re: [PATCH 2/5] drm/amdgpu: export function to flush TLB via pasid

2020-01-05 Thread Christian König

Am 20.12.19 um 07:24 schrieb Alex Sierra:

This can be used directly from amdgpu and amdkfd to invalidate
TLB through pasid.
It supports gmc v7, v8, v9 and v10.

Change-Id: I6563a8eba2e42d1a67fa2547156c20da41d1e490
Signed-off-by: Alex Sierra 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |  6 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 81 
  drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   | 33 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   | 34 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 84 +
  5 files changed, 238 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
index b499a3de8bb6..b6413a56f546 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
@@ -92,6 +92,9 @@ struct amdgpu_gmc_funcs {
/* flush the vm tlb via mmio */
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);
/* flush the vm tlb via ring */
uint64_t (*emit_flush_gpu_tlb)(struct amdgpu_ring *ring, unsigned vmid,
   uint64_t pd_addr);
@@ -216,6 +219,9 @@ struct amdgpu_gmc {
  };
  
  #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) \
+   ((adev)->gmc.gmc_funcs->flush_gpu_tlb_pasid \
+   ((adev), (pasid), (type), (allhub)))
  #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))
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
index f5725336a5f2..b1a5408a8d7e 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
@@ -30,6 +30,8 @@
  #include "hdp/hdp_5_0_0_sh_mask.h"
  #include "gc/gc_10_1_0_sh_mask.h"
  #include "mmhub/mmhub_2_0_0_sh_mask.h"
+#include "athub/athub_2_0_0_sh_mask.h"
+#include "athub/athub_2_0_0_offset.h"
  #include "dcn/dcn_2_0_0_offset.h"
  #include "dcn/dcn_2_0_0_sh_mask.h"
  #include "oss/osssys_5_0_0_offset.h"
@@ -37,6 +39,7 @@
  #include "navi10_enum.h"
  
  #include "soc15.h"

+#include "soc15d.h"
  #include "soc15_common.h"
  
  #include "nbio_v2_3.h"

@@ -234,6 +237,48 @@ static bool gmc_v10_0_use_invalidate_semaphore(struct 
amdgpu_device *adev,
(!amdgpu_sriov_vf(adev)));
  }
  
+static bool gmc_v10_0_get_atc_vmid_pasid_mapping_info(

+   struct amdgpu_device *adev,
+   uint8_t vmid, uint16_t *p_pasid)
+{
+   uint32_t value;
+
+   value = RREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING)
++ vmid);
+   *p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK;
+
+   return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
+}
+
+static int gmc_v10_0_invalidate_tlbs_with_kiq(struct amdgpu_device *adev,
+   uint16_t pasid, uint32_t flush_type,
+   bool all_hub)
+{
+   signed long r;
+   uint32_t seq;
+   struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
+
+   spin_lock(&adev->gfx.kiq.ring_lock);
+   amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs package*/
+   amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0));
+   amdgpu_ring_write(ring,
+   PACKET3_INVALIDATE_TLBS_DST_SEL(1) |
+   PACKET3_INVALIDATE_TLBS_ALL_HUB(all_hub) |
+   PACKET3_INVALIDATE_TLBS_PASID(pasid) |
+   PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(flush_type));
+   amdgpu_fence_emit_polling(ring, &seq);
+   amdgpu_ring_commit(ring);
+   spin_unlock(&adev->gfx.kiq.ring_lock);
+
+   r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
+   if (r < 1) {
+   DRM_ERROR("wait for kiq fence error: %ld.\n", r);
+   return -ETIME;
+   }
+
+   return 0;
+}
+
  /*
   * GART
   * VMID 0 is the physical GPU addresses as used by the kernel.
@@ -380,6 +425,41 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device 
*adev, uint32_t vmid,
DRM_ERROR("Error flushing GPU TLB using the SDMA (%d)!\n", r);
  }
  
+/**

+ * gmc_v10_0_flush_gpu_tlb_pasid - tlb flush via pasid
+ *
+ * @adev: amdgpu_device pointer
+ * @pasid: pasid to be flush
+ *
+ * Flush the TLB for the reque

Re: [PATCH 2/5] drm/amdgpu: export function to flush TLB via pasid

2020-01-06 Thread Felix Kuehling

On 2020-01-05 10:41 a.m., Christian König wrote:

Am 20.12.19 um 07:24 schrieb Alex Sierra:

This can be used directly from amdgpu and amdkfd to invalidate
TLB through pasid.
It supports gmc v7, v8, v9 and v10.

Change-Id: I6563a8eba2e42d1a67fa2547156c20da41d1e490
Signed-off-by: Alex Sierra 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |  6 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 81 
  drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   | 33 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   | 34 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 84 +
  5 files changed, 238 insertions(+)

[snip]
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c

index fa025ceeea0f..eb1e64bd56ed 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -38,10 +38,12 @@
  #include "dce/dce_12_0_sh_mask.h"
  #include "vega10_enum.h"
  #include "mmhub/mmhub_1_0_offset.h"
+#include "athub/athub_1_0_sh_mask.h"
  #include "athub/athub_1_0_offset.h"
  #include "oss/osssys_4_0_offset.h"
    #include "soc15.h"
+#include "soc15d.h"
  #include "soc15_common.h"
  #include "umc/umc_6_0_sh_mask.h"
  @@ -434,6 +436,47 @@ static bool 
gmc_v9_0_use_invalidate_semaphore(struct amdgpu_device *adev,

 adev->pdev->device == 0x15d8)));
  }
  +static bool gmc_v9_0_get_atc_vmid_pasid_mapping_info(struct 
amdgpu_device *adev,

+    uint8_t vmid, uint16_t *p_pasid)
+{
+    uint32_t value;
+
+    value = RREG32(SOC15_REG_OFFSET(ATHUB, 0, 
mmATC_VMID0_PASID_MAPPING)

+ + vmid);
+    *p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK;
+
+    return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
+}


Probably better to expose just this function in the GMC interface.


This is called below in gmc_v9_0_flush_gpu_tlb_pasid in the case that 
the KIQ is not ready. It is not needed outside this file, so no need to 
expose it in the GMC interface.






+
+static int gmc_v9_0_invalidate_tlbs_with_kiq(struct amdgpu_device 
*adev,

+    uint16_t pasid, uint32_t flush_type,
+    bool all_hub)
+{
+    signed long r;
+    uint32_t seq;
+    struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
+
+    spin_lock(&adev->gfx.kiq.ring_lock);
+    amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs package*/
+    amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0));
+    amdgpu_ring_write(ring,
+    PACKET3_INVALIDATE_TLBS_DST_SEL(1) |
+    PACKET3_INVALIDATE_TLBS_ALL_HUB(all_hub) |
+    PACKET3_INVALIDATE_TLBS_PASID(pasid) |
+    PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(flush_type));


That stuff is completely unrelated to the GMC and shouldn't be added 
here.


Where else should it go? To me TLB flushing is very much something that 
belongs in this file.


Maybe you'd rather add "flush_tlbs_with_kiq" to amdgpu_ring_funcs and 
implement it in the gfx_v*.c GFX-IP code? I'm not sure that makes much 
sense either because it's only available on the KIQ ring.





Christian.


+    amdgpu_fence_emit_polling(ring, &seq);
+    amdgpu_ring_commit(ring);
+    spin_unlock(&adev->gfx.kiq.ring_lock);
+
+    r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
+    if (r < 1) {
+    DRM_ERROR("wait for kiq fence error: %ld.\n", r);
+    return -ETIME;
+    }
+
+    return 0;
+}
+
  /*
   * GART
   * VMID 0 is the physical GPU addresses as used by the kernel.
@@ -532,6 +575,46 @@ static void gmc_v9_0_flush_gpu_tlb(struct 
amdgpu_device *adev, uint32_t vmid,

  DRM_ERROR("Timeout waiting for VM flush ACK!\n");
  }
  +/**
+ * gmc_v9_0_flush_gpu_tlb_pasid - tlb flush via pasid
+ *
+ * @adev: amdgpu_device pointer
+ * @pasid: pasid to be flush
+ *
+ * Flush the TLB for the requested pasid.
+ */
+static int gmc_v9_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
+    uint16_t pasid, uint32_t flush_type,
+    bool all_hub)


Christian, do you agree that this function belongs in the GMC interface? 
If not here, where do you suggest moving it?


Regards,
  Felix



+{
+    int vmid, i;
+    uint16_t queried_pasid;
+    bool ret;
+    struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
+
+    if (adev->in_gpu_reset)
+    return -EIO;
+
+    if (ring->sched.ready)
+    return gmc_v9_0_invalidate_tlbs_with_kiq(adev,
+    pasid, flush_type, all_hub);
+
+    for (vmid = 1; vmid < 16; vmid++) {
+
+    ret = gmc_v9_0_get_atc_vmid_pasid_mapping_info(adev, vmid,
+    &queried_pasid);
+    if (ret && queried_pasid == pasid) {
+    for (i = 0; i < adev->num_vmhubs; i++)
+    amdgpu_gmc_flush_gpu_tlb(adev, vmid,
+    i, flush_type);
+    break;
+    }
+    }
+
+    return 0;
+
+}
+
  static uint64_t gmc_v9_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
  unsigned vmid, uint64_t pd_addr)
  {
@@ -693

Re: [PATCH 2/5] drm/amdgpu: export function to flush TLB via pasid

2020-01-06 Thread Christian König

Am 06.01.20 um 17:04 schrieb Felix Kuehling:

On 2020-01-05 10:41 a.m., Christian König wrote:

Am 20.12.19 um 07:24 schrieb Alex Sierra:

This can be used directly from amdgpu and amdkfd to invalidate
TLB through pasid.
It supports gmc v7, v8, v9 and v10.

Change-Id: I6563a8eba2e42d1a67fa2547156c20da41d1e490
Signed-off-by: Alex Sierra 
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |  6 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 81 
  drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   | 33 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   | 34 ++
  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 84 
+

  5 files changed, 238 insertions(+)

[snip]
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c 
b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c

index fa025ceeea0f..eb1e64bd56ed 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -38,10 +38,12 @@
  #include "dce/dce_12_0_sh_mask.h"
  #include "vega10_enum.h"
  #include "mmhub/mmhub_1_0_offset.h"
+#include "athub/athub_1_0_sh_mask.h"
  #include "athub/athub_1_0_offset.h"
  #include "oss/osssys_4_0_offset.h"
    #include "soc15.h"
+#include "soc15d.h"
  #include "soc15_common.h"
  #include "umc/umc_6_0_sh_mask.h"
  @@ -434,6 +436,47 @@ static bool 
gmc_v9_0_use_invalidate_semaphore(struct amdgpu_device *adev,

 adev->pdev->device == 0x15d8)));
  }
  +static bool gmc_v9_0_get_atc_vmid_pasid_mapping_info(struct 
amdgpu_device *adev,

+    uint8_t vmid, uint16_t *p_pasid)
+{
+    uint32_t value;
+
+    value = RREG32(SOC15_REG_OFFSET(ATHUB, 0, 
mmATC_VMID0_PASID_MAPPING)

+ + vmid);
+    *p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK;
+
+    return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
+}


Probably better to expose just this function in the GMC interface.


This is called below in gmc_v9_0_flush_gpu_tlb_pasid in the case that 
the KIQ is not ready. It is not needed outside this file, so no need 
to expose it in the GMC interface.






+
+static int gmc_v9_0_invalidate_tlbs_with_kiq(struct amdgpu_device 
*adev,

+    uint16_t pasid, uint32_t flush_type,
+    bool all_hub)
+{
+    signed long r;
+    uint32_t seq;
+    struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
+
+    spin_lock(&adev->gfx.kiq.ring_lock);
+    amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs package*/
+    amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0));
+    amdgpu_ring_write(ring,
+    PACKET3_INVALIDATE_TLBS_DST_SEL(1) |
+    PACKET3_INVALIDATE_TLBS_ALL_HUB(all_hub) |
+    PACKET3_INVALIDATE_TLBS_PASID(pasid) |
+    PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(flush_type));


That stuff is completely unrelated to the GMC and shouldn't be added 
here.


Where else should it go? To me TLB flushing is very much something 
that belongs in this file.


Maybe you'd rather add "flush_tlbs_with_kiq" to amdgpu_ring_funcs and 
implement it in the gfx_v*.c GFX-IP code? I'm not sure that makes much 
sense either because it's only available on the KIQ ring.


Yes, something like this. We should probably add a amdgpu_kiq_funcs and 
expose the functions needed by the GMC code there.


See the amdgpu_virt_kiq_reg_write_reg_wait() case for reference, it is 
very similar and should probably be added to that function table as well.


Christian.






Christian.


+    amdgpu_fence_emit_polling(ring, &seq);
+    amdgpu_ring_commit(ring);
+    spin_unlock(&adev->gfx.kiq.ring_lock);
+
+    r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
+    if (r < 1) {
+    DRM_ERROR("wait for kiq fence error: %ld.\n", r);
+    return -ETIME;
+    }
+
+    return 0;
+}
+
  /*
   * GART
   * VMID 0 is the physical GPU addresses as used by the kernel.
@@ -532,6 +575,46 @@ static void gmc_v9_0_flush_gpu_tlb(struct 
amdgpu_device *adev, uint32_t vmid,

  DRM_ERROR("Timeout waiting for VM flush ACK!\n");
  }
  +/**
+ * gmc_v9_0_flush_gpu_tlb_pasid - tlb flush via pasid
+ *
+ * @adev: amdgpu_device pointer
+ * @pasid: pasid to be flush
+ *
+ * Flush the TLB for the requested pasid.
+ */
+static int gmc_v9_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
+    uint16_t pasid, uint32_t flush_type,
+    bool all_hub)


Christian, do you agree that this function belongs in the GMC 
interface? If not here, where do you suggest moving it?


Regards,
  Felix



+{
+    int vmid, i;
+    uint16_t queried_pasid;
+    bool ret;
+    struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
+
+    if (adev->in_gpu_reset)
+    return -EIO;
+
+    if (ring->sched.ready)
+    return gmc_v9_0_invalidate_tlbs_with_kiq(adev,
+    pasid, flush_type, all_hub);
+
+    for (vmid = 1; vmid < 16; vmid++) {
+
+    ret = gmc_v9_0_get_atc_vmid_pasid_mapping_info(adev, vmid,
+    &queried_pasid);
+    if (ret && queried_pasid == pasid) {
+    for (i

RE: [PATCH 2/5] drm/amdgpu: export function to flush TLB via pasid

2020-01-06 Thread Sierra Guiza, Alejandro (Alex)
[AMD Official Use Only - Internal Distribution Only]



-Original Message-
From: Koenig, Christian  
Sent: Monday, January 6, 2020 10:23 AM
To: Kuehling, Felix ; amd-gfx@lists.freedesktop.org; 
Sierra Guiza, Alejandro (Alex) 
Subject: Re: [PATCH 2/5] drm/amdgpu: export function to flush TLB via pasid

Am 06.01.20 um 17:04 schrieb Felix Kuehling:
> On 2020-01-05 10:41 a.m., Christian König wrote:
>> Am 20.12.19 um 07:24 schrieb Alex Sierra:
>>> This can be used directly from amdgpu and amdkfd to invalidate TLB 
>>> through pasid.
>>> It supports gmc v7, v8, v9 and v10.
>>>
>>> Change-Id: I6563a8eba2e42d1a67fa2547156c20da41d1e490
>>> Signed-off-by: Alex Sierra 
>>> ---
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |  6 ++
>>>   drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 81 
>>> 
>>>   drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   | 33 ++
>>>   drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   | 34 ++
>>>   drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 84
>>> +
>>>   5 files changed, 238 insertions(+)
> [snip]
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
>>> b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
>>> index fa025ceeea0f..eb1e64bd56ed 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
>>> @@ -38,10 +38,12 @@
>>>   #include "dce/dce_12_0_sh_mask.h"
>>>   #include "vega10_enum.h"
>>>   #include "mmhub/mmhub_1_0_offset.h"
>>> +#include "athub/athub_1_0_sh_mask.h"
>>>   #include "athub/athub_1_0_offset.h"
>>>   #include "oss/osssys_4_0_offset.h"
>>>     #include "soc15.h"
>>> +#include "soc15d.h"
>>>   #include "soc15_common.h"
>>>   #include "umc/umc_6_0_sh_mask.h"
>>>   @@ -434,6 +436,47 @@ static bool
>>> gmc_v9_0_use_invalidate_semaphore(struct amdgpu_device *adev,
>>>  adev->pdev->device == 0x15d8)));
>>>   }
>>>   +static bool gmc_v9_0_get_atc_vmid_pasid_mapping_info(struct
>>> amdgpu_device *adev,
>>> +    uint8_t vmid, uint16_t *p_pasid) {
>>> +    uint32_t value;
>>> +
>>> +    value = RREG32(SOC15_REG_OFFSET(ATHUB, 0,
>>> mmATC_VMID0_PASID_MAPPING)
>>> + + vmid);
>>> +    *p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK;
>>> +
>>> +    return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
>>> +}
>>
>> Probably better to expose just this function in the GMC interface.
>
> This is called below in gmc_v9_0_flush_gpu_tlb_pasid in the case that 
> the KIQ is not ready. It is not needed outside this file, so no need 
> to expose it in the GMC interface.
>
>
>>
>>> +
>>> +static int gmc_v9_0_invalidate_tlbs_with_kiq(struct amdgpu_device
>>> *adev,
>>> +    uint16_t pasid, uint32_t flush_type,
>>> +    bool all_hub)
>>> +{
>>> +    signed long r;
>>> +    uint32_t seq;
>>> +    struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
>>> +
>>> +    spin_lock(&adev->gfx.kiq.ring_lock);
>>> +    amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs 
>>> +package*/
>>> +    amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0));
>>> +    amdgpu_ring_write(ring,
>>> +    PACKET3_INVALIDATE_TLBS_DST_SEL(1) |
>>> +    PACKET3_INVALIDATE_TLBS_ALL_HUB(all_hub) |
>>> +    PACKET3_INVALIDATE_TLBS_PASID(pasid) |
>>> +    PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(flush_type));
>>
>>> That stuff is completely unrelated to the GMC and shouldn't be added
>>> here.
>>
>> Where else should it go? To me TLB flushing is very much something 
>> that belongs in this file.
>>
>> Maybe you'd rather add "flush_tlbs_with_kiq" to amdgpu_ring_funcs and
>> implement it in the gfx_v*.c GFX-IP code? I'm not sure that makes much 
>> sense either because it's only available on the KIQ ring.

>Yes, something like this. We should probably add a amdgpu_kiq_funcs and expose 
>the functions needed by the GMC code there.

>See the amdgpu_virt_kiq_reg_write_reg_wait() case for reference, it is very 
>similar and should probably be added to that function table as well.

>Christian.
To summarize: 
1.- The idea is to add a new function pointer to the amdgpu_ring_funcs to flush 

Re: [PATCH 2/5] drm/amdgpu: export function to flush TLB via pasid

2020-01-07 Thread Christian König

Am 07.01.20 um 02:09 schrieb Sierra Guiza, Alejandro (Alex):

[AMD Official Use Only - Internal Distribution Only]



-Original Message-
From: Koenig, Christian 
Sent: Monday, January 6, 2020 10:23 AM
To: Kuehling, Felix ; amd-gfx@lists.freedesktop.org; Sierra 
Guiza, Alejandro (Alex) 
Subject: Re: [PATCH 2/5] drm/amdgpu: export function to flush TLB via pasid

Am 06.01.20 um 17:04 schrieb Felix Kuehling:

On 2020-01-05 10:41 a.m., Christian König wrote:

Am 20.12.19 um 07:24 schrieb Alex Sierra:

This can be used directly from amdgpu and amdkfd to invalidate TLB
through pasid.
It supports gmc v7, v8, v9 and v10.

Change-Id: I6563a8eba2e42d1a67fa2547156c20da41d1e490
Signed-off-by: Alex Sierra 
---
   drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |  6 ++
   drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c  | 81

   drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   | 33 ++
   drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   | 34 ++
   drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 84
+
   5 files changed, 238 insertions(+)

[snip]

diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index fa025ceeea0f..eb1e64bd56ed 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -38,10 +38,12 @@
   #include "dce/dce_12_0_sh_mask.h"
   #include "vega10_enum.h"
   #include "mmhub/mmhub_1_0_offset.h"
+#include "athub/athub_1_0_sh_mask.h"
   #include "athub/athub_1_0_offset.h"
   #include "oss/osssys_4_0_offset.h"
     #include "soc15.h"
+#include "soc15d.h"
   #include "soc15_common.h"
   #include "umc/umc_6_0_sh_mask.h"
   @@ -434,6 +436,47 @@ static bool
gmc_v9_0_use_invalidate_semaphore(struct amdgpu_device *adev,
  adev->pdev->device == 0x15d8)));
   }
   +static bool gmc_v9_0_get_atc_vmid_pasid_mapping_info(struct
amdgpu_device *adev,
+    uint8_t vmid, uint16_t *p_pasid) {
+    uint32_t value;
+
+    value = RREG32(SOC15_REG_OFFSET(ATHUB, 0,
mmATC_VMID0_PASID_MAPPING)
+ + vmid);
+    *p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK;
+
+    return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
+}

Probably better to expose just this function in the GMC interface.

This is called below in gmc_v9_0_flush_gpu_tlb_pasid in the case that
the KIQ is not ready. It is not needed outside this file, so no need
to expose it in the GMC interface.



+
+static int gmc_v9_0_invalidate_tlbs_with_kiq(struct amdgpu_device
*adev,
+    uint16_t pasid, uint32_t flush_type,
+    bool all_hub)
+{
+    signed long r;
+    uint32_t seq;
+    struct amdgpu_ring *ring = &adev->gfx.kiq.ring;
+
+    spin_lock(&adev->gfx.kiq.ring_lock);
+    amdgpu_ring_alloc(ring, 12); /* fence + invalidate_tlbs
+package*/
+    amdgpu_ring_write(ring, PACKET3(PACKET3_INVALIDATE_TLBS, 0));
+    amdgpu_ring_write(ring,
+    PACKET3_INVALIDATE_TLBS_DST_SEL(1) |
+    PACKET3_INVALIDATE_TLBS_ALL_HUB(all_hub) |
+    PACKET3_INVALIDATE_TLBS_PASID(pasid) |
+    PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(flush_type));
That stuff is completely unrelated to the GMC and shouldn't be added
here.

Where else should it go? To me TLB flushing is very much something
that belongs in this file.

Maybe you'd rather add "flush_tlbs_with_kiq" to amdgpu_ring_funcs and
implement it in the gfx_v*.c GFX-IP code? I'm not sure that makes much
sense either because it's only available on the KIQ ring.

Yes, something like this. We should probably add a amdgpu_kiq_funcs and expose 
the functions needed by the GMC code there.
See the amdgpu_virt_kiq_reg_write_reg_wait() case for reference, it is very 
similar and should probably be added to that function table as well.
Christian.

To summarize:
1.- The idea is to add a new function pointer to the amdgpu_ring_funcs to flush 
the tlbs with kiq.


I would add a new amdgpu_kiq_funcs structure for that.


2.- This function pointer should be pointed and implemented on each of the 
gfx_v*.c under the gfx_*_ring_funcs_kiq struct. If this is true, Im not seeing 
this struct on the gfx_v10.c file.
3.- Use the amdgpu_virt_kiq_reg_write_reg_wait as a reference for the 
implementation.


Well yes and no, the amdgpu_virt_kiq_reg_write_reg_wait() was just an 
example of a similar case.


The function amdgpu_virt_kiq_reg_write_reg_wait() should probably be 
cleaned up and moved into the gfx_*.c files as well.


Regards,
Christian.






Christian.

+    amdgpu_fence_emit_polling(ring, &seq);
+    amdgpu_ring_commit(ring);
+    spin_unlock(&adev->gfx.kiq.ring_lock);
+
+    r = amdgpu_fence_wait_polling(ring, seq, adev->usec_timeout);
+    if (r < 1) {
+    DRM_ERROR("wait for kiq fence error: %ld.\n", r);
+    return -ETIME;
+    }
+
+    return 0;