[PATCH v3 1/3] drm/amdgpu: split amdgpu_device_access_vram() into two small parts

Christian König christian.koenig at amd.com
Fri Jul 16 08:34:09 UTC 2021


Am 16.07.21 um 10:23 schrieb Kevin Wang:
> 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 at amd.com>

Reviewed-by: Christian König <christian.koenig at amd.com> for the series.

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  7 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 98 ++++++++++++++++------
>   2 files changed, 79 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 61a0897e984a..54cf647bd018 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -1109,8 +1109,13 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>   void amdgpu_device_fini(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,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index eb1f3f42e00b..37fa199be8b3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -285,7 +285,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
> @@ -293,19 +293,60 @@ 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;
>   
> +	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);
> +}
> +
> +/**
> + * 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);
> @@ -317,30 +358,37 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
>   			memcpy_fromio(buf, addr, count);
>   		}
>   
> -		if (count == size)
> -			return;
> -
> -		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);
>   }
>   
>   /*



More information about the amd-gfx mailing list