amdgpu: fix asic initialization for virtualized environments (v2)
When executing in a PCI passthrough based virtuzliation environemnt, the hypervisor will usually attempt to send a PCIe bus reset signal to the ASIC when the VM reboots. In this scenario, the card is not correctly initialized, but we still consider it to be posted. Therefore, in a passthrough based environemnt we should always post the card to guarantee it is in a good state for driver initialization. However, if we are operating in SR-IOV mode it is up to the GIM driver to manage the asic state, therefore we should not post the card (and shouldn't be able to do it either). v2: add missing semi-colon Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Andres Rodriguez <andres.rodriguez@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
9ef8537e68
commit
048765ad5a
|
@ -1822,6 +1822,8 @@ struct amdgpu_asic_funcs {
|
||||||
/* MM block clocks */
|
/* MM block clocks */
|
||||||
int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk);
|
int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk);
|
||||||
int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk);
|
int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk);
|
||||||
|
/* query virtual capabilities */
|
||||||
|
u32 (*get_virtual_caps)(struct amdgpu_device *adev);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1916,8 +1918,12 @@ void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device);
|
||||||
|
|
||||||
|
|
||||||
/* GPU virtualization */
|
/* GPU virtualization */
|
||||||
|
#define AMDGPU_VIRT_CAPS_SRIOV_EN (1 << 0)
|
||||||
|
#define AMDGPU_VIRT_CAPS_IS_VF (1 << 1)
|
||||||
struct amdgpu_virtualization {
|
struct amdgpu_virtualization {
|
||||||
bool supports_sr_iov;
|
bool supports_sr_iov;
|
||||||
|
bool is_virtual;
|
||||||
|
u32 caps;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2206,6 +2212,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
|
||||||
#define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev))
|
#define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev))
|
||||||
#define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d))
|
#define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d))
|
||||||
#define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec))
|
#define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec))
|
||||||
|
#define amdgpu_asic_get_virtual_caps(adev) ((adev)->asic_funcs->get_virtual_caps((adev)))
|
||||||
#define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev))
|
#define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev))
|
||||||
#define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev))
|
#define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev))
|
||||||
#define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l))
|
#define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l))
|
||||||
|
|
|
@ -1385,6 +1385,15 @@ static int amdgpu_resume(struct amdgpu_device *adev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool amdgpu_device_is_virtual(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_X86
|
||||||
|
return boot_cpu_has(X86_FEATURE_HYPERVISOR);
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* amdgpu_device_init - initialize the driver
|
* amdgpu_device_init - initialize the driver
|
||||||
*
|
*
|
||||||
|
@ -1519,8 +1528,14 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||||
adev->virtualization.supports_sr_iov =
|
adev->virtualization.supports_sr_iov =
|
||||||
amdgpu_atombios_has_gpu_virtualization_table(adev);
|
amdgpu_atombios_has_gpu_virtualization_table(adev);
|
||||||
|
|
||||||
|
/* Check if we are executing in a virtualized environment */
|
||||||
|
adev->virtualization.is_virtual = amdgpu_device_is_virtual();
|
||||||
|
adev->virtualization.caps = amdgpu_asic_get_virtual_caps(adev);
|
||||||
|
|
||||||
/* Post card if necessary */
|
/* Post card if necessary */
|
||||||
if (!amdgpu_card_posted(adev)) {
|
if (!amdgpu_card_posted(adev) ||
|
||||||
|
(adev->virtualization.is_virtual &&
|
||||||
|
!adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN)) {
|
||||||
if (!adev->bios) {
|
if (!adev->bios) {
|
||||||
dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n");
|
dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -962,6 +962,12 @@ static bool cik_read_bios_from_rom(struct amdgpu_device *adev,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 cik_get_virtual_caps(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
/* CIK does not support SR-IOV */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = {
|
static const struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = {
|
||||||
{mmGRBM_STATUS, false},
|
{mmGRBM_STATUS, false},
|
||||||
{mmGB_ADDR_CONFIG, false},
|
{mmGB_ADDR_CONFIG, false},
|
||||||
|
@ -2007,6 +2013,7 @@ static const struct amdgpu_asic_funcs cik_asic_funcs =
|
||||||
.get_xclk = &cik_get_xclk,
|
.get_xclk = &cik_get_xclk,
|
||||||
.set_uvd_clocks = &cik_set_uvd_clocks,
|
.set_uvd_clocks = &cik_set_uvd_clocks,
|
||||||
.set_vce_clocks = &cik_set_vce_clocks,
|
.set_vce_clocks = &cik_set_vce_clocks,
|
||||||
|
.get_virtual_caps = &cik_get_virtual_caps,
|
||||||
/* these should be moved to their own ip modules */
|
/* these should be moved to their own ip modules */
|
||||||
.get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter,
|
.get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter,
|
||||||
.wait_for_mc_idle = &gmc_v7_0_mc_wait_for_idle,
|
.wait_for_mc_idle = &gmc_v7_0_mc_wait_for_idle,
|
||||||
|
|
|
@ -421,6 +421,20 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 vi_get_virtual_caps(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
u32 caps = 0;
|
||||||
|
u32 reg = RREG32(mmBIF_IOV_FUNC_IDENTIFIER);
|
||||||
|
|
||||||
|
if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, IOV_ENABLE))
|
||||||
|
caps |= AMDGPU_VIRT_CAPS_SRIOV_EN;
|
||||||
|
|
||||||
|
if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, FUNC_IDENTIFIER))
|
||||||
|
caps |= AMDGPU_VIRT_CAPS_IS_VF;
|
||||||
|
|
||||||
|
return caps;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = {
|
static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = {
|
||||||
{mmGB_MACROTILE_MODE7, true},
|
{mmGB_MACROTILE_MODE7, true},
|
||||||
};
|
};
|
||||||
|
@ -1118,6 +1132,7 @@ static const struct amdgpu_asic_funcs vi_asic_funcs =
|
||||||
.get_xclk = &vi_get_xclk,
|
.get_xclk = &vi_get_xclk,
|
||||||
.set_uvd_clocks = &vi_set_uvd_clocks,
|
.set_uvd_clocks = &vi_set_uvd_clocks,
|
||||||
.set_vce_clocks = &vi_set_vce_clocks,
|
.set_vce_clocks = &vi_set_vce_clocks,
|
||||||
|
.get_virtual_caps = &vi_get_virtual_caps,
|
||||||
/* these should be moved to their own ip modules */
|
/* these should be moved to their own ip modules */
|
||||||
.get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter,
|
.get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter,
|
||||||
.wait_for_mc_idle = &gmc_v8_0_mc_wait_for_idle,
|
.wait_for_mc_idle = &gmc_v8_0_mc_wait_for_idle,
|
||||||
|
|
Loading…
Reference in New Issue