Skip to content

Commit

Permalink
drm/amdgpu: create a new file for doorbell manager
Browse files Browse the repository at this point in the history
This patch:
- creates a new file for doorbell management.
- moves doorbell code from amdgpu_device.c to this file.

V2:
 - remove doc from function declaration (Christian)
 - remove 'device' from function names to make it consistent (Alex)
 - add SPDX license identifier (Luben)

V3:
 - change license to MIT license(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>
  • Loading branch information
Shashank Sharma authored and Alex Deucher committed Jul 18, 2023
1 parent b222556 commit 43c064d
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 171 deletions.
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/amdgpu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ subdir-ccflags-$(CONFIG_DRM_AMDGPU_WERROR) += -Werror
amdgpu-y := amdgpu_drv.o

# add KMS driver
amdgpu-y += amdgpu_device.o amdgpu_kms.o \
amdgpu-y += amdgpu_device.o amdgpu_doorbell_mgr.o amdgpu_kms.o \
amdgpu_atombios.o atombios_crtc.o amdgpu_connectors.o \
atom.o amdgpu_fence.o amdgpu_ttm.o amdgpu_object.o amdgpu_gart.o \
amdgpu_encoders.o amdgpu_display.o amdgpu_i2c.o \
Expand Down
175 changes: 5 additions & 170 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,94 +588,6 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
}
}

/**
* amdgpu_mm_rdoorbell - read a doorbell dword
*
* @adev: amdgpu_device pointer
* @index: doorbell index
*
* Returns the value in the doorbell aperture at the
* requested doorbell index (CIK).
*/
u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
{
if (amdgpu_device_skip_hw_access(adev))
return 0;

if (index < adev->doorbell.num_kernel_doorbells) {
return readl(adev->doorbell.ptr + index);
} else {
DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
return 0;
}
}

/**
* amdgpu_mm_wdoorbell - write a doorbell dword
*
* @adev: amdgpu_device pointer
* @index: doorbell index
* @v: value to write
*
* Writes @v to the doorbell aperture at the
* requested doorbell index (CIK).
*/
void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
{
if (amdgpu_device_skip_hw_access(adev))
return;

if (index < adev->doorbell.num_kernel_doorbells) {
writel(v, adev->doorbell.ptr + index);
} else {
DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
}
}

/**
* amdgpu_mm_rdoorbell64 - read a doorbell Qword
*
* @adev: amdgpu_device pointer
* @index: doorbell index
*
* Returns the value in the doorbell aperture at the
* requested doorbell index (VEGA10+).
*/
u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
{
if (amdgpu_device_skip_hw_access(adev))
return 0;

if (index < adev->doorbell.num_kernel_doorbells) {
return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
} else {
DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
return 0;
}
}

/**
* amdgpu_mm_wdoorbell64 - write a doorbell Qword
*
* @adev: amdgpu_device pointer
* @index: doorbell index
* @v: value to write
*
* Writes @v to the doorbell aperture at the
* requested doorbell index (VEGA10+).
*/
void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
{
if (amdgpu_device_skip_hw_access(adev))
return;

if (index < adev->doorbell.num_kernel_doorbells) {
atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
} else {
DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
}
}

/**
* amdgpu_device_indirect_rreg - read an indirect register
*
Expand Down Expand Up @@ -1135,83 +1047,6 @@ int amdgpu_device_pci_reset(struct amdgpu_device *adev)
return pci_reset_function(adev->pdev);
}

/*
* GPU doorbell aperture helpers function.
*/
/**
* amdgpu_device_doorbell_init - Init doorbell driver information.
*
* @adev: amdgpu_device pointer
*
* Init doorbell driver information (CIK)
* Returns 0 on success, error on failure.
*/
static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
{

/* No doorbell on SI hardware generation */
if (adev->asic_type < CHIP_BONAIRE) {
adev->doorbell.base = 0;
adev->doorbell.size = 0;
adev->doorbell.num_kernel_doorbells = 0;
adev->doorbell.ptr = NULL;
return 0;
}

if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET)
return -EINVAL;

amdgpu_asic_init_doorbell_index(adev);

/* doorbell bar mapping */
adev->doorbell.base = pci_resource_start(adev->pdev, 2);
adev->doorbell.size = pci_resource_len(adev->pdev, 2);

if (adev->enable_mes) {
adev->doorbell.num_kernel_doorbells =
adev->doorbell.size / sizeof(u32);
} else {
adev->doorbell.num_kernel_doorbells =
min_t(u32, adev->doorbell.size / sizeof(u32),
adev->doorbell_index.max_assignment+1);
if (adev->doorbell.num_kernel_doorbells == 0)
return -EINVAL;

/* For Vega, reserve and map two pages on doorbell BAR since SDMA
* paging queue doorbell use the second page. The
* AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
* doorbells are in the first page. So with paging queue enabled,
* the max num_kernel_doorbells should + 1 page (0x400 in dword)
*/
if (adev->ip_versions[SDMA0_HWIP][0] >= IP_VERSION(4, 0, 0) &&
adev->ip_versions[SDMA0_HWIP][0] < IP_VERSION(4, 2, 0))
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;
}

/**
* amdgpu_device_doorbell_fini - Tear down doorbell driver information.
*
* @adev: amdgpu_device pointer
*
* Tear down doorbell driver information (CIK)
*/
static void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
{
iounmap(adev->doorbell.ptr);
adev->doorbell.ptr = NULL;
}



/*
* amdgpu_device_wb_*()
* Writeback is the method by which the GPU updates special pages in memory
Expand Down Expand Up @@ -1362,7 +1197,7 @@ int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev)
cmd & ~PCI_COMMAND_MEMORY);

/* Free the VRAM and doorbell BAR, we most likely need to move both. */
amdgpu_device_doorbell_fini(adev);
amdgpu_doorbell_fini(adev);
if (adev->asic_type >= CHIP_BONAIRE)
pci_release_resource(adev->pdev, 2);

Expand All @@ -1379,7 +1214,7 @@ int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev)
/* When the doorbell or fb BAR isn't available we have no chance of
* using the device.
*/
r = amdgpu_device_doorbell_init(adev);
r = amdgpu_doorbell_init(adev);
if (r || (pci_resource_flags(adev->pdev, 0) & IORESOURCE_UNSET))
return -ENODEV;

Expand Down Expand Up @@ -3929,7 +3764,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
dev_info(adev->dev, "PCIE atomic ops is not supported\n");

/* doorbell bar mapping and doorbell index init*/
amdgpu_device_doorbell_init(adev);
amdgpu_doorbell_init(adev);

if (amdgpu_emu_mode == 1) {
/* post the asic on emulation mode */
Expand Down Expand Up @@ -4167,7 +4002,7 @@ static void amdgpu_device_unmap_mmio(struct amdgpu_device *adev)
unmap_mapping_range(adev->ddev.anon_inode->i_mapping, 0, 0, 1);

/* Unmap all mapped bars - Doorbell, registers and VRAM */
amdgpu_device_doorbell_fini(adev);
amdgpu_doorbell_fini(adev);

iounmap(adev->rmmio);
adev->rmmio = NULL;
Expand Down Expand Up @@ -4279,7 +4114,7 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)

iounmap(adev->rmmio);
adev->rmmio = NULL;
amdgpu_device_doorbell_fini(adev);
amdgpu_doorbell_fini(adev);
drm_dev_exit(idx);
}

Expand Down
6 changes: 6 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,12 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v);
u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index);
void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);

/*
* GPU doorbell aperture helpers function.
*/
int amdgpu_doorbell_init(struct amdgpu_device *adev);
void amdgpu_doorbell_fini(struct amdgpu_device *adev);

#define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
#define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
#define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
Expand Down
Loading

0 comments on commit 43c064d

Please sign in to comment.