Commit 048af66b authored by Kevin Wang's avatar Kevin Wang Committed by Alex Deucher

drm/amdgpu: split amdgpu_device_access_vram() into two small parts

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: default avatarKevin Wang <kevin1.wang@amd.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 9ce5ed6e
...@@ -1108,8 +1108,13 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev); ...@@ -1108,8 +1108,13 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev);
int amdgpu_gpu_wait_for_idle(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, 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 amdgpu_device_rreg(struct amdgpu_device *adev,
uint32_t reg, uint32_t acc_flags); uint32_t reg, uint32_t acc_flags);
void amdgpu_device_wreg(struct amdgpu_device *adev, void amdgpu_device_wreg(struct amdgpu_device *adev,
......
...@@ -287,7 +287,7 @@ bool amdgpu_device_supports_smart_shift(struct drm_device *dev) ...@@ -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 * @adev: amdgpu_device pointer
* @pos: offset of the buffer in vram * @pos: offset of the buffer in vram
...@@ -295,22 +295,65 @@ bool amdgpu_device_supports_smart_shift(struct drm_device *dev) ...@@ -295,22 +295,65 @@ bool amdgpu_device_supports_smart_shift(struct drm_device *dev)
* @size: read/write size, sizeof(@buf) must > @size * @size: read/write size, sizeof(@buf) must > @size
* @write: true - write to vram, otherwise - read from vram * @write: true - write to vram, otherwise - read from vram
*/ */
void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos, void amdgpu_device_mm_access(struct amdgpu_device *adev, loff_t pos,
uint32_t *buf, size_t size, bool write) void *buf, size_t size, bool write)
{ {
unsigned long flags; unsigned long flags;
uint32_t hi = ~0; uint32_t hi = ~0, tmp = 0;
uint32_t *data = buf;
uint64_t last; uint64_t last;
int idx; int idx;
if (!drm_dev_enter(&adev->ddev, &idx)) if (!drm_dev_enter(&adev->ddev, &idx))
return; 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 #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); last = min(pos + size, adev->gmc.visible_vram_size);
if (last > pos) { if (last > pos) {
void __iomem *addr = adev->mman.aper_base_kaddr + pos; addr = adev->mman.aper_base_kaddr + pos;
size_t count = last - pos; count = last - pos;
if (write) { if (write) {
memcpy_toio(addr, buf, count); memcpy_toio(addr, buf, count);
...@@ -322,35 +365,37 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos, ...@@ -322,35 +365,37 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
memcpy_fromio(buf, addr, count); memcpy_fromio(buf, addr, count);
} }
if (count == size)
goto exit;
pos += count;
buf += count / 4;
size -= count;
} }
return count;
#else
return 0;
#endif #endif
}
spin_lock_irqsave(&adev->mmio_idx_lock, flags); /**
for (last = pos + size; pos < last; pos += 4) { * amdgpu_device_vram_access - read/write a buffer in vram
uint32_t tmp = pos >> 31; *
* @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); /* try to using vram apreature to access vram first */
if (tmp != hi) { count = amdgpu_device_aper_access(adev, pos, buf, size, write);
WREG32_NO_KIQ(mmMM_INDEX_HI, tmp); size -= count;
hi = tmp; if (size) {
} /* using MM to access rest vram */
if (write) pos += count;
WREG32_NO_KIQ(mmMM_DATA, *buf++); buf += count;
else amdgpu_device_mm_access(adev, pos, buf, size, write);
*buf++ = RREG32_NO_KIQ(mmMM_DATA);
} }
spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
#ifdef CONFIG_64BIT
exit:
#endif
drm_dev_exit(idx);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment