diff options
author | Andres Rodriguez <andres.rodriguez@amd.com> | 2016-06-11 02:51:32 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-06-13 15:25:20 -0400 |
commit | 048765ad5af7c8939603b4c6cb96293ffa05e00d (patch) | |
tree | 5c5218841c6f789c0ae22e67f64dd2182cf2a58c | |
parent | 9ef8537e68941d858924a3eacee5a1945767cbab (diff) |
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>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/cik.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vi.c | 15 |
4 files changed, 45 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 01c36b8d6222..70af26d97d28 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -1822,6 +1822,8 @@ struct amdgpu_asic_funcs { | |||
1822 | /* MM block clocks */ | 1822 | /* MM block clocks */ |
1823 | int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk); | 1823 | int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk); |
1824 | int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk); | 1824 | int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk); |
1825 | /* query virtual capabilities */ | ||
1826 | u32 (*get_virtual_caps)(struct amdgpu_device *adev); | ||
1825 | }; | 1827 | }; |
1826 | 1828 | ||
1827 | /* | 1829 | /* |
@@ -1916,8 +1918,12 @@ void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device); | |||
1916 | 1918 | ||
1917 | 1919 | ||
1918 | /* GPU virtualization */ | 1920 | /* GPU virtualization */ |
1921 | #define AMDGPU_VIRT_CAPS_SRIOV_EN (1 << 0) | ||
1922 | #define AMDGPU_VIRT_CAPS_IS_VF (1 << 1) | ||
1919 | struct amdgpu_virtualization { | 1923 | struct amdgpu_virtualization { |
1920 | bool supports_sr_iov; | 1924 | bool supports_sr_iov; |
1925 | bool is_virtual; | ||
1926 | u32 caps; | ||
1921 | }; | 1927 | }; |
1922 | 1928 | ||
1923 | /* | 1929 | /* |
@@ -2206,6 +2212,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) | |||
2206 | #define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev)) | 2212 | #define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev)) |
2207 | #define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d)) | 2213 | #define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d)) |
2208 | #define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec)) | 2214 | #define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec)) |
2215 | #define amdgpu_asic_get_virtual_caps(adev) ((adev)->asic_funcs->get_virtual_caps((adev))) | ||
2209 | #define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev)) | 2216 | #define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev)) |
2210 | #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev)) | 2217 | #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev)) |
2211 | #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l)) | 2218 | #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l)) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 964f31404f17..66482b429458 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -1385,6 +1385,15 @@ static int amdgpu_resume(struct amdgpu_device *adev) | |||
1385 | return 0; | 1385 | return 0; |
1386 | } | 1386 | } |
1387 | 1387 | ||
1388 | static bool amdgpu_device_is_virtual(void) | ||
1389 | { | ||
1390 | #ifdef CONFIG_X86 | ||
1391 | return boot_cpu_has(X86_FEATURE_HYPERVISOR); | ||
1392 | #else | ||
1393 | return false; | ||
1394 | #endif | ||
1395 | } | ||
1396 | |||
1388 | /** | 1397 | /** |
1389 | * amdgpu_device_init - initialize the driver | 1398 | * amdgpu_device_init - initialize the driver |
1390 | * | 1399 | * |
@@ -1519,8 +1528,14 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1519 | adev->virtualization.supports_sr_iov = | 1528 | adev->virtualization.supports_sr_iov = |
1520 | amdgpu_atombios_has_gpu_virtualization_table(adev); | 1529 | amdgpu_atombios_has_gpu_virtualization_table(adev); |
1521 | 1530 | ||
1531 | /* Check if we are executing in a virtualized environment */ | ||
1532 | adev->virtualization.is_virtual = amdgpu_device_is_virtual(); | ||
1533 | adev->virtualization.caps = amdgpu_asic_get_virtual_caps(adev); | ||
1534 | |||
1522 | /* Post card if necessary */ | 1535 | /* Post card if necessary */ |
1523 | if (!amdgpu_card_posted(adev)) { | 1536 | if (!amdgpu_card_posted(adev) || |
1537 | (adev->virtualization.is_virtual && | ||
1538 | !adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN)) { | ||
1524 | if (!adev->bios) { | 1539 | if (!adev->bios) { |
1525 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); | 1540 | dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); |
1526 | return -EINVAL; | 1541 | return -EINVAL; |
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c index 07bc795a4ca9..910431808542 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik.c +++ b/drivers/gpu/drm/amd/amdgpu/cik.c | |||
@@ -962,6 +962,12 @@ static bool cik_read_bios_from_rom(struct amdgpu_device *adev, | |||
962 | return true; | 962 | return true; |
963 | } | 963 | } |
964 | 964 | ||
965 | static u32 cik_get_virtual_caps(struct amdgpu_device *adev) | ||
966 | { | ||
967 | /* CIK does not support SR-IOV */ | ||
968 | return 0; | ||
969 | } | ||
970 | |||
965 | static const struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = { | 971 | static const struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = { |
966 | {mmGRBM_STATUS, false}, | 972 | {mmGRBM_STATUS, false}, |
967 | {mmGB_ADDR_CONFIG, false}, | 973 | {mmGB_ADDR_CONFIG, false}, |
@@ -2007,6 +2013,7 @@ static const struct amdgpu_asic_funcs cik_asic_funcs = | |||
2007 | .get_xclk = &cik_get_xclk, | 2013 | .get_xclk = &cik_get_xclk, |
2008 | .set_uvd_clocks = &cik_set_uvd_clocks, | 2014 | .set_uvd_clocks = &cik_set_uvd_clocks, |
2009 | .set_vce_clocks = &cik_set_vce_clocks, | 2015 | .set_vce_clocks = &cik_set_vce_clocks, |
2016 | .get_virtual_caps = &cik_get_virtual_caps, | ||
2010 | /* these should be moved to their own ip modules */ | 2017 | /* these should be moved to their own ip modules */ |
2011 | .get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter, | 2018 | .get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter, |
2012 | .wait_for_mc_idle = &gmc_v7_0_mc_wait_for_idle, | 2019 | .wait_for_mc_idle = &gmc_v7_0_mc_wait_for_idle, |
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 2c88d0b66cf3..a65c96029476 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c | |||
@@ -421,6 +421,20 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev, | |||
421 | return true; | 421 | return true; |
422 | } | 422 | } |
423 | 423 | ||
424 | static u32 vi_get_virtual_caps(struct amdgpu_device *adev) | ||
425 | { | ||
426 | u32 caps = 0; | ||
427 | u32 reg = RREG32(mmBIF_IOV_FUNC_IDENTIFIER); | ||
428 | |||
429 | if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, IOV_ENABLE)) | ||
430 | caps |= AMDGPU_VIRT_CAPS_SRIOV_EN; | ||
431 | |||
432 | if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, FUNC_IDENTIFIER)) | ||
433 | caps |= AMDGPU_VIRT_CAPS_IS_VF; | ||
434 | |||
435 | return caps; | ||
436 | } | ||
437 | |||
424 | static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = { | 438 | static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = { |
425 | {mmGB_MACROTILE_MODE7, true}, | 439 | {mmGB_MACROTILE_MODE7, true}, |
426 | }; | 440 | }; |
@@ -1118,6 +1132,7 @@ static const struct amdgpu_asic_funcs vi_asic_funcs = | |||
1118 | .get_xclk = &vi_get_xclk, | 1132 | .get_xclk = &vi_get_xclk, |
1119 | .set_uvd_clocks = &vi_set_uvd_clocks, | 1133 | .set_uvd_clocks = &vi_set_uvd_clocks, |
1120 | .set_vce_clocks = &vi_set_vce_clocks, | 1134 | .set_vce_clocks = &vi_set_vce_clocks, |
1135 | .get_virtual_caps = &vi_get_virtual_caps, | ||
1121 | /* these should be moved to their own ip modules */ | 1136 | /* these should be moved to their own ip modules */ |
1122 | .get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter, | 1137 | .get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter, |
1123 | .wait_for_mc_idle = &gmc_v8_0_mc_wait_for_idle, | 1138 | .wait_for_mc_idle = &gmc_v8_0_mc_wait_for_idle, |