drm/amdgpu: split amdgpu_device_access_vram() into two small parts
authorKevin Wang <kevin1.wang@amd.com>
Fri, 16 Jul 2021 17:57:49 +0000 (13:57 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 16 Jul 2021 17:58:13 +0000 (13:58 -0400)
split amdgpu_device_access_vram()
1. amdgpu_device_mm_access(): using MM_INDEX/MM_DATA to access vram
2. amdgpu_device_aper_access(): using vram aperature to access vram (option)

Signed-off-by: Kevin Wang <kevin1.wang@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c

index 8ac6eb9..dbaa79d 100644 (file)
@@ -1108,8 +1108,13 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev);
 
 int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev);
 
+void amdgpu_device_mm_access(struct amdgpu_device *adev, loff_t pos,
+                            void *buf, size_t size, bool write);
+size_t amdgpu_device_aper_access(struct amdgpu_device *adev, loff_t pos,
+                                void *buf, size_t size, bool write);
+
 void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
-                              uint32_t *buf, size_t size, bool write);
+                              void *buf, size_t size, bool write);
 uint32_t amdgpu_device_rreg(struct amdgpu_device *adev,
                            uint32_t reg, uint32_t acc_flags);
 void amdgpu_device_wreg(struct amdgpu_device *adev,
index f3fd5ec..26ccccb 100644 (file)
@@ -287,7 +287,7 @@ bool amdgpu_device_supports_smart_shift(struct drm_device *dev)
  */
 
 /**
- * amdgpu_device_vram_access - read/write a buffer in vram
+ * amdgpu_device_mm_access - access vram by MM_INDEX/MM_DATA
  *
  * @adev: amdgpu_device pointer
  * @pos: offset of the buffer in vram
@@ -295,22 +295,65 @@ bool amdgpu_device_supports_smart_shift(struct drm_device *dev)
  * @size: read/write size, sizeof(@buf) must > @size
  * @write: true - write to vram, otherwise - read from vram
  */
-void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
-                              uint32_t *buf, size_t size, bool write)
+void amdgpu_device_mm_access(struct amdgpu_device *adev, loff_t pos,
+                            void *buf, size_t size, bool write)
 {
        unsigned long flags;
-       uint32_t hi = ~0;
+       uint32_t hi = ~0, tmp = 0;
+       uint32_t *data = buf;
        uint64_t last;
        int idx;
 
        if (!drm_dev_enter(&adev->ddev, &idx))
                return;
 
+       BUG_ON(!IS_ALIGNED(pos, 4) || !IS_ALIGNED(size, 4));
+
+       spin_lock_irqsave(&adev->mmio_idx_lock, flags);
+       for (last = pos + size; pos < last; pos += 4) {
+               tmp = pos >> 31;
+
+               WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x80000000);
+               if (tmp != hi) {
+                       WREG32_NO_KIQ(mmMM_INDEX_HI, tmp);
+                       hi = tmp;
+               }
+               if (write)
+                       WREG32_NO_KIQ(mmMM_DATA, *data++);
+               else
+                       *data++ = RREG32_NO_KIQ(mmMM_DATA);
+       }
+
+       spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
+       drm_dev_exit(idx);
+}
+
+/**
+ * amdgpu_device_vram_access - access vram by vram aperature
+ *
+ * @adev: amdgpu_device pointer
+ * @pos: offset of the buffer in vram
+ * @buf: virtual address of the buffer in system memory
+ * @size: read/write size, sizeof(@buf) must > @size
+ * @write: true - write to vram, otherwise - read from vram
+ *
+ * The return value means how many bytes have been transferred.
+ */
+size_t amdgpu_device_aper_access(struct amdgpu_device *adev, loff_t pos,
+                                void *buf, size_t size, bool write)
+{
 #ifdef CONFIG_64BIT
+       void __iomem *addr;
+       size_t count = 0;
+       uint64_t last;
+
+       if (!adev->mman.aper_base_kaddr)
+               return 0;
+
        last = min(pos + size, adev->gmc.visible_vram_size);
        if (last > pos) {
-               void __iomem *addr = adev->mman.aper_base_kaddr + pos;
-               size_t count = last - pos;
+               addr = adev->mman.aper_base_kaddr + pos;
+               count = last - pos;
 
                if (write) {
                        memcpy_toio(addr, buf, count);
@@ -322,35 +365,37 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
                        memcpy_fromio(buf, addr, count);
                }
 
-               if (count == size)
-                       goto exit;
-
-               pos += count;
-               buf += count / 4;
-               size -= count;
        }
+
+       return count;
+#else
+       return 0;
 #endif
+}
 
-       spin_lock_irqsave(&adev->mmio_idx_lock, flags);
-       for (last = pos + size; pos < last; pos += 4) {
-               uint32_t tmp = pos >> 31;
+/**
+ * amdgpu_device_vram_access - read/write a buffer in vram
+ *
+ * @adev: amdgpu_device pointer
+ * @pos: offset of the buffer in vram
+ * @buf: virtual address of the buffer in system memory
+ * @size: read/write size, sizeof(@buf) must > @size
+ * @write: true - write to vram, otherwise - read from vram
+ */
+void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
+                              void *buf, size_t size, bool write)
+{
+       size_t count;
 
-               WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t)pos) | 0x80000000);
-               if (tmp != hi) {
-                       WREG32_NO_KIQ(mmMM_INDEX_HI, tmp);
-                       hi = tmp;
-               }
-               if (write)
-                       WREG32_NO_KIQ(mmMM_DATA, *buf++);
-               else
-                       *buf++ = RREG32_NO_KIQ(mmMM_DATA);
+       /* try to using vram apreature to access vram first */
+       count = amdgpu_device_aper_access(adev, pos, buf, size, write);
+       size -= count;
+       if (size) {
+               /* using MM to access rest vram */
+               pos += count;
+               buf += count;
+               amdgpu_device_mm_access(adev, pos, buf, size, write);
        }
-       spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
-
-#ifdef CONFIG_64BIT
-exit:
-#endif
-       drm_dev_exit(idx);
 }
 
 /*