mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	drm/amdgpu: create kernel doorbell pages
This patch:
- creates a doorbell page for graphics driver usages.
- adds a few new varlables in adev->doorbell structure to
  keep track of kernel's doorbell-bo.
- removes the adev->doorbell.ptr variable, replaces it with
  kernel-doorbell-bo's cpu address.
V2: - Create doorbell BO directly, no wrappe functions (Alex)
    - no additional doorbell structure (Alex, Christian)
    - Use doorbell_cpu_ptr, remove ioremap (Christian, Alex)
    - Allocate one extra page of doorbells for MES (Alex)
V4: Move MES doorbell base init into MES related patch (Christian)
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
			
			
This commit is contained in:
		
							parent
							
								
									36f3f375ed
								
							
						
					
					
						commit
						54c30d2a8d
					
				
					 3 changed files with 53 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -31,10 +31,15 @@ struct amdgpu_doorbell {
 | 
			
		|||
	/* doorbell mmio */
 | 
			
		||||
	resource_size_t		base;
 | 
			
		||||
	resource_size_t		size;
 | 
			
		||||
	u32 __iomem		*ptr;
 | 
			
		||||
 | 
			
		||||
	/* Number of doorbells reserved for amdgpu kernel driver */
 | 
			
		||||
	u32 num_kernel_doorbells;
 | 
			
		||||
 | 
			
		||||
	/* Kernel doorbells */
 | 
			
		||||
	struct amdgpu_bo *kernel_doorbells;
 | 
			
		||||
 | 
			
		||||
	/* For CPU access of doorbells */
 | 
			
		||||
	uint32_t *cpu_addr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Reserved doorbells for amdgpu (including multimedia).
 | 
			
		||||
| 
						 | 
				
			
			@ -350,6 +355,7 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
 | 
			
		|||
 */
 | 
			
		||||
int amdgpu_doorbell_init(struct amdgpu_device *adev);
 | 
			
		||||
void amdgpu_doorbell_fini(struct amdgpu_device *adev);
 | 
			
		||||
int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev);
 | 
			
		||||
 | 
			
		||||
#define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
 | 
			
		||||
#define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
 | 
			
		|||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (index < adev->doorbell.num_kernel_doorbells)
 | 
			
		||||
		return readl(adev->doorbell.ptr + index);
 | 
			
		||||
		return readl(adev->doorbell.cpu_addr + index);
 | 
			
		||||
 | 
			
		||||
	DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
 | 
			
		||||
	return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
 | 
			
		|||
		return;
 | 
			
		||||
 | 
			
		||||
	if (index < adev->doorbell.num_kernel_doorbells)
 | 
			
		||||
		writel(v, adev->doorbell.ptr + index);
 | 
			
		||||
		writel(v, adev->doorbell.cpu_addr + index);
 | 
			
		||||
	else
 | 
			
		||||
		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
 | 
			
		|||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (index < adev->doorbell.num_kernel_doorbells)
 | 
			
		||||
		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
 | 
			
		||||
		return atomic64_read((atomic64_t *)(adev->doorbell.cpu_addr + index));
 | 
			
		||||
 | 
			
		||||
	DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
 | 
			
		||||
	return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -103,11 +103,43 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
 | 
			
		|||
		return;
 | 
			
		||||
 | 
			
		||||
	if (index < adev->doorbell.num_kernel_doorbells)
 | 
			
		||||
		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
 | 
			
		||||
		atomic64_set((atomic64_t *)(adev->doorbell.cpu_addr + index), v);
 | 
			
		||||
	else
 | 
			
		||||
		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells for graphics
 | 
			
		||||
 *
 | 
			
		||||
 * @adev: amdgpu_device pointer
 | 
			
		||||
 *
 | 
			
		||||
 * Creates doorbells for graphics driver usages.
 | 
			
		||||
 * returns 0 on success, error otherwise.
 | 
			
		||||
 */
 | 
			
		||||
int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev)
 | 
			
		||||
{
 | 
			
		||||
	int r;
 | 
			
		||||
	int size;
 | 
			
		||||
 | 
			
		||||
	/* Reserve first num_kernel_doorbells (page-aligned) for kernel ops */
 | 
			
		||||
	size = ALIGN(adev->doorbell.num_kernel_doorbells * sizeof(u32), PAGE_SIZE);
 | 
			
		||||
 | 
			
		||||
	r = amdgpu_bo_create_kernel(adev,
 | 
			
		||||
				    size,
 | 
			
		||||
				    PAGE_SIZE,
 | 
			
		||||
				    AMDGPU_GEM_DOMAIN_DOORBELL,
 | 
			
		||||
				    &adev->doorbell.kernel_doorbells,
 | 
			
		||||
				    NULL,
 | 
			
		||||
				    (void **)&adev->doorbell.cpu_addr);
 | 
			
		||||
	if (r) {
 | 
			
		||||
		DRM_ERROR("Failed to allocate kernel doorbells, err=%d\n", r);
 | 
			
		||||
		return r;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	adev->doorbell.num_kernel_doorbells = size / sizeof(u32);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * GPU doorbell aperture helpers function.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -127,7 +159,6 @@ int amdgpu_doorbell_init(struct amdgpu_device *adev)
 | 
			
		|||
		adev->doorbell.base = 0;
 | 
			
		||||
		adev->doorbell.size = 0;
 | 
			
		||||
		adev->doorbell.num_kernel_doorbells = 0;
 | 
			
		||||
		adev->doorbell.ptr = NULL;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -156,12 +187,6 @@ int amdgpu_doorbell_init(struct amdgpu_device *adev)
 | 
			
		|||
	if (adev->asic_type >= CHIP_VEGA10)
 | 
			
		||||
		adev->doorbell.num_kernel_doorbells += 0x400;
 | 
			
		||||
 | 
			
		||||
	adev->doorbell.ptr = ioremap(adev->doorbell.base,
 | 
			
		||||
				     adev->doorbell.num_kernel_doorbells *
 | 
			
		||||
				     sizeof(u32));
 | 
			
		||||
	if (adev->doorbell.ptr == NULL)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -174,6 +199,7 @@ int amdgpu_doorbell_init(struct amdgpu_device *adev)
 | 
			
		|||
 */
 | 
			
		||||
void amdgpu_doorbell_fini(struct amdgpu_device *adev)
 | 
			
		||||
{
 | 
			
		||||
	iounmap(adev->doorbell.ptr);
 | 
			
		||||
	adev->doorbell.ptr = NULL;
 | 
			
		||||
	amdgpu_bo_free_kernel(&adev->doorbell.kernel_doorbells,
 | 
			
		||||
			      NULL,
 | 
			
		||||
			      (void **)&adev->doorbell.cpu_addr);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1945,6 +1945,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
 | 
			
		|||
		return r;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Create a boorbell page for kernel usages */
 | 
			
		||||
	r = amdgpu_doorbell_create_kernel_doorbells(adev);
 | 
			
		||||
	if (r) {
 | 
			
		||||
		DRM_ERROR("Failed to initialize kernel doorbells.\n");
 | 
			
		||||
		return r;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Initialize preemptible memory pool */
 | 
			
		||||
	r = amdgpu_preempt_mgr_init(adev);
 | 
			
		||||
	if (r) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue