drm/radeon: Add ATC VMID<-->PASID functions to kfd->kgd
authorAlexey Skidanov <Alexey.Skidanov@amd.com>
Tue, 19 May 2015 16:25:01 +0000 (19:25 +0300)
committerOded Gabbay <oded.gabbay@gmail.com>
Wed, 3 Jun 2015 08:34:46 +0000 (11:34 +0300)
This patch adds three new interfaces to kfd2kgd interface file of radeon.

The interfaces are:

- Check if a specific VMID has a valid PASID mapping
- Retrieve the PASID which is mapped to a specific VMID
- Issue a VMID invalidation request to the ATC

Signed-off-by: Alexey Skidanov <Alexey.Skidanov@amd.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
drivers/gpu/drm/amd/include/kgd_kfd_interface.h
drivers/gpu/drm/radeon/cikd.h
drivers/gpu/drm/radeon/radeon_kfd.c

index afde1b75eeee5a424a9a34cbdb94eefb7dfb6d12..9080daa116b60031e156f0d10e200d2017c2950e 100644 (file)
@@ -175,6 +175,14 @@ struct kfd2kgd_calls {
        uint32_t (*address_watch_get_offset)(struct kgd_dev *kgd,
                                        unsigned int watch_point_id,
                                        unsigned int reg_offset);
+       bool (*get_atc_vmid_pasid_mapping_valid)(
+                                       struct kgd_dev *kgd,
+                                       uint8_t vmid);
+       uint16_t (*get_atc_vmid_pasid_mapping_pasid)(
+                                       struct kgd_dev *kgd,
+                                       uint8_t vmid);
+       void (*write_vmid_invalidate_request)(struct kgd_dev *kgd,
+                                       uint8_t vmid);
 
        uint16_t (*get_fw_version)(struct kgd_dev *kgd,
                                enum kgd_engine_type type);
index b33ba3b0808bbd9b1755f14310a95cff150bffe1..391ff9d5d70668326cea4ff4a078eeec673198bd 100644 (file)
 #define VCE_CMD_IB_AUTO                0x00000005
 #define VCE_CMD_SEMAPHORE      0x00000006
 
-#define ATC_VMID0_PASID_MAPPING                                        0x339Cu
-#define        ATC_VMID_PASID_MAPPING_UPDATE_STATUS    0x3398u
-#define        ATC_VMID_PASID_MAPPING_VALID                            (1U << 31)
+#define ATC_VMID_PASID_MAPPING_UPDATE_STATUS           0x3398u
+#define ATC_VMID0_PASID_MAPPING                                0x339Cu
+#define ATC_VMID_PASID_MAPPING_PASID_MASK              (0xFFFF)
+#define ATC_VMID_PASID_MAPPING_PASID_SHIFT             0
+#define ATC_VMID_PASID_MAPPING_VALID_MASK              (0x1 << 31)
+#define ATC_VMID_PASID_MAPPING_VALID_SHIFT             31
 
 #define ATC_VM_APERTURE0_CNTL                                  0x3310u
 #define        ATS_ACCESS_MODE_NEVER                                           0
index fd9590de26056c8719d881c4be5ebfd44dd928af..e476c331f3fa6e3c91d4a5203f0aab8829028dfa 100644 (file)
@@ -99,6 +99,11 @@ static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd,
                                        unsigned int watch_point_id,
                                        unsigned int reg_offset);
 
+static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd, uint8_t vmid);
+static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd,
+                                                       uint8_t vmid);
+static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid);
+
 static const struct kfd2kgd_calls kfd2kgd = {
        .init_gtt_mem_allocation = alloc_gtt_mem,
        .free_gtt_mem = free_gtt_mem,
@@ -119,6 +124,9 @@ static const struct kfd2kgd_calls kfd2kgd = {
        .address_watch_execute = kgd_address_watch_execute,
        .wave_control_execute = kgd_wave_control_execute,
        .address_watch_get_offset = kgd_address_watch_get_offset,
+       .get_atc_vmid_pasid_mapping_pasid = get_atc_vmid_pasid_mapping_pasid,
+       .get_atc_vmid_pasid_mapping_valid = get_atc_vmid_pasid_mapping_valid,
+       .write_vmid_invalidate_request = write_vmid_invalidate_request,
        .get_fw_version = get_fw_version
 };
 
@@ -395,8 +403,8 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid,
         * the SW cleared it.
         * So the protocol is to always wait & clear.
         */
-       uint32_t pasid_mapping = (pasid == 0) ? 0 :
-                               (uint32_t)pasid | ATC_VMID_PASID_MAPPING_VALID;
+       uint32_t pasid_mapping = (pasid == 0) ? 0 : (uint32_t)pasid |
+                                       ATC_VMID_PASID_MAPPING_VALID_MASK;
 
        write_register(kgd, ATC_VMID0_PASID_MAPPING + vmid*sizeof(uint32_t),
                        pasid_mapping);
@@ -778,6 +786,32 @@ static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd,
        return watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX + reg_offset];
 }
 
+static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd, uint8_t vmid)
+{
+       uint32_t reg;
+       struct radeon_device *rdev = (struct radeon_device *) kgd;
+
+       reg = RREG32(ATC_VMID0_PASID_MAPPING + vmid*4);
+       return reg & ATC_VMID_PASID_MAPPING_VALID_MASK;
+}
+
+static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd,
+                                                       uint8_t vmid)
+{
+       uint32_t reg;
+       struct radeon_device *rdev = (struct radeon_device *) kgd;
+
+       reg = RREG32(ATC_VMID0_PASID_MAPPING + vmid*4);
+       return reg & ATC_VMID_PASID_MAPPING_PASID_MASK;
+}
+
+static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid)
+{
+       struct radeon_device *rdev = (struct radeon_device *) kgd;
+
+       return WREG32(VM_INVALIDATE_REQUEST, 1 << vmid);
+}
+
 static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
 {
        struct radeon_device *rdev = (struct radeon_device *) kgd;