/* 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).
*/
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))
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;
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);
}
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;
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.
*/
adev->doorbell.base = 0;
adev->doorbell.size = 0;
adev->doorbell.num_kernel_doorbells = 0;
- adev->doorbell.ptr = NULL;
return 0;
}
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;
}
*/
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);
}