diff options
| author | Kevin Wang <kevin1.wang@amd.com> | 2021-07-16 13:57:49 -0400 | 
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2021-07-16 13:58:13 -0400 | 
| commit | 048af66be7b5ffb107f3696a853a4deb9aa6efec (patch) | |
| tree | d98d8096a5cbeb4a20be086ababc211fb1598366 /drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |
| parent | 9ce5ed6eaac588de2c73bb0262f0ef0b55012225 (diff) | |
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: Kevin Wang <kevin1.wang@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_device.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 105 | 
1 files changed, 75 insertions, 30 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index f3fd5ec710b6..26ccccb9d94f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -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);  }  /* | 
