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

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
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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,
+75 −30
Original line number Diff line number Diff line
@@ -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);
}

/*