[1/5] drm/amdgpu:changes of virtualization cases probe (v2)

Submitted by Alex Deucher on Sept. 19, 2016, 5:12 p.m.

Details

Message ID 1474305161-11435-1-git-send-email-alexander.deucher@amd.com
State New
Headers show
Series "Series without cover letter" ( rev: 1 ) in AMD X.Org drivers

Not browsing as part of any series.

Commit Message

Alex Deucher Sept. 19, 2016, 5:12 p.m.
From: Monk Liu <Monk.Liu@amd.com>

1,Changes on virtualization detections
2,Don't load smu & mc firmware if using sr-iov bios
3,skip vPost for sriov & force vPost if dev pass-through

v2: agd: fix missed SI case

Signed-off-by: Monk Liu <Monk.Liu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        | 38 +++++++++++++++++++++++-------
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 25 ++++++++++----------
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c    |  2 +-
 drivers/gpu/drm/amd/amdgpu/cik.c           |  7 ------
 drivers/gpu/drm/amd/amdgpu/fiji_smc.c      |  2 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c      |  4 +++-
 drivers/gpu/drm/amd/amdgpu/iceland_smc.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/si.c            |  7 ------
 drivers/gpu/drm/amd/amdgpu/tonga_smc.c     |  2 +-
 drivers/gpu/drm/amd/amdgpu/vi.c            | 36 ++++++++++++++++++----------
 10 files changed, 74 insertions(+), 51 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index ee45d9f..ff6e683 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1827,6 +1827,8 @@  struct amdgpu_asic_funcs {
 	bool (*read_disabled_bios)(struct amdgpu_device *adev);
 	bool (*read_bios_from_rom)(struct amdgpu_device *adev,
 				   u8 *bios, u32 length_bytes);
+	void (*detect_hw_virtualization) (struct amdgpu_device *adev);
+	void (*detect_sriov_bios)(struct amdgpu_device *adev);
 	int (*read_register)(struct amdgpu_device *adev, u32 se_num,
 			     u32 sh_num, u32 reg_offset, u32 *value);
 	void (*set_vga_state)(struct amdgpu_device *adev, bool state);
@@ -1836,8 +1838,6 @@  struct amdgpu_asic_funcs {
 	/* MM block clocks */
 	int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk);
 	int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk);
-	/* query virtual capabilities */
-	u32 (*get_virtual_caps)(struct amdgpu_device *adev);
 	/* static power management */
 	int (*get_pcie_lanes)(struct amdgpu_device *adev);
 	void (*set_pcie_lanes)(struct amdgpu_device *adev, int lanes);
@@ -1934,15 +1934,36 @@  struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev);
 void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device);
 
 
+#define AMDGPU_SRIOV_CAPS_SRIOV_VBIOS  (1 << 0) /* vBIOS is sr-iov ready */
+#define AMDGPU_SRIOV_CAPS_ENABLE_IOV   (1 << 1) /* sr-iov is enabled on this GPU */
+#define AMDGPU_SRIOV_CAPS_IS_VF        (1 << 2) /* this GPU is a virtual function */
+#define AMDGPU_PASSTHROUGH_MODE        (1 << 3) /* thw whole GPU is pass through for VM */
 /* GPU virtualization */
-#define AMDGPU_VIRT_CAPS_SRIOV_EN       (1 << 0)
-#define AMDGPU_VIRT_CAPS_IS_VF          (1 << 1)
 struct amdgpu_virtualization {
-	bool supports_sr_iov;
-	bool is_virtual;
-	u32 caps;
+	uint32_t virtual_caps;
 };
 
+#define amdgpu_sriov_enabled(adev) \
+((adev)->virtualization.virtual_caps & AMDGPU_SRIOV_CAPS_ENABLE_IOV)
+
+#define amdgpu_sriov_vf(adev) \
+((adev)->virtualization.virtual_caps & AMDGPU_SRIOV_CAPS_IS_VF)
+
+#define amdgpu_sriov_bios(adev) \
+((adev)->virtualization.virtual_caps & AMDGPU_SRIOV_CAPS_SRIOV_VBIOS)
+
+#define amdgpu_passthrough(adev) \
+((adev)->virtualization.virtual_caps & AMDGPU_PASSTHROUGH_MODE)
+
+static inline bool is_virtual_machine(void)
+{
+#ifdef CONFIG_X86
+	return boot_cpu_has(X86_FEATURE_HYPERVISOR);
+#else
+	return false;
+#endif
+}
+
 /*
  * Core structure, functions and helpers.
  */
@@ -2260,12 +2281,13 @@  amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
 #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_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_get_pcie_lanes(adev) (adev)->asic_funcs->get_pcie_lanes((adev))
 #define amdgpu_set_pcie_lanes(adev, l) (adev)->asic_funcs->set_pcie_lanes((adev), (l))
 #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_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l))
+#define amdgpu_asic_detect_hw_virtualization(adev) (adev)->asic_funcs->detect_hw_virtualization((adev))
+#define amdgpu_asic_detect_sriov_bios(adev) (adev)->asic_funcs->detect_sriov_bios((adev))
 #define amdgpu_asic_read_register(adev, se, sh, offset, v)((adev)->asic_funcs->read_register((adev), (se), (sh), (offset), (v)))
 #define amdgpu_gart_flush_gpu_tlb(adev, vmid) (adev)->gart.gart_funcs->flush_gpu_tlb((adev), (vmid))
 #define amdgpu_gart_set_pte_pde(adev, pt, idx, addr, flags) (adev)->gart.gart_funcs->set_pte_pde((adev), (pt), (idx), (addr), (flags))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 377d818..2df5f00 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -110,7 +110,7 @@  void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
 		    bool always_indirect)
 {
 	trace_amdgpu_mm_wreg(adev->pdev->device, reg, v);
-	
+
 	if ((reg * 4) < adev->rmmio_size && !always_indirect)
 		writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
 	else {
@@ -1648,25 +1648,26 @@  int amdgpu_device_init(struct amdgpu_device *adev,
 		goto failed;
 	}
 
-	/* See if the asic supports SR-IOV */
-	adev->virtualization.supports_sr_iov =
-		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);
+	/* detect if we are with an SRIOV vbios */
+	if (adev->asic_funcs->detect_sriov_bios)
+		amdgpu_asic_detect_sriov_bios(adev);
 
 	/* Post card if necessary */
-	if (!amdgpu_card_posted(adev) ||
-	    (adev->virtualization.is_virtual &&
-	     !(adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN))) {
+	if (!amdgpu_sriov_vf(adev) &&
+		(!amdgpu_card_posted(adev) || amdgpu_passthrough(adev))) {
 		if (!adev->bios) {
 			dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n");
 			r = -EINVAL;
 			goto failed;
 		}
 		DRM_INFO("GPU not posted. posting now...\n");
-		amdgpu_atom_asic_init(adev->mode_info.atom_context);
+		r = amdgpu_atom_asic_init(adev->mode_info.atom_context);
+		if (r) {
+			dev_err(adev->dev, "gpu post error!\n");
+			goto failed;
+		}
+	} else {
+		DRM_INFO("GPU post is not needed\n");
 	}
 
 	/* Initialize clocks */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index c96ae10..0c5f36d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -485,7 +485,7 @@  amdgpu_pci_shutdown(struct pci_dev *pdev)
 	/* if we are running in a VM, make sure the device
 	 * torn down properly on reboot/shutdown
 	 */
-	if (adev->virtualization.is_virtual)
+	if (amdgpu_passthrough(adev))
 		amdgpu_pci_remove(pdev);
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
index 825de80..e61fdee 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik.c
@@ -963,12 +963,6 @@  static bool cik_read_bios_from_rom(struct amdgpu_device *adev,
 	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[] = {
 	{mmGRBM_STATUS, false},
 	{mmGB_ADDR_CONFIG, false},
@@ -2390,7 +2384,6 @@  static const struct amdgpu_asic_funcs cik_asic_funcs =
 	.get_xclk = &cik_get_xclk,
 	.set_uvd_clocks = &cik_set_uvd_clocks,
 	.set_vce_clocks = &cik_set_vce_clocks,
-	.get_virtual_caps = &cik_get_virtual_caps,
 };
 
 static int cik_common_early_init(void *handle)
diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_smc.c b/drivers/gpu/drm/amd/amdgpu/fiji_smc.c
index b3e19ba..8cfb0a3 100644
--- a/drivers/gpu/drm/amd/amdgpu/fiji_smc.c
+++ b/drivers/gpu/drm/amd/amdgpu/fiji_smc.c
@@ -275,7 +275,7 @@  static int fiji_smu_upload_firmware_image(struct amdgpu_device *adev)
 	/* Skip SMC ucode loading on SR-IOV capable boards.
 	 * vbios does this for us in asic_init in that case.
 	 */
-	if (adev->virtualization.supports_sr_iov)
+	if (amdgpu_sriov_bios(adev))
 		return 0;
 
 	hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data;
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index 8e7127f..6ec8e01 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -261,8 +261,10 @@  static int gmc_v8_0_mc_load_microcode(struct amdgpu_device *adev)
 
 	/* Skip MC ucode loading on SR-IOV capable boards.
 	 * vbios does this for us in asic_init in that case.
+	 * Skip MC ucode loading on VF, because hypervisor will do that
+	 * for this adaptor.
 	 */
-	if (adev->virtualization.supports_sr_iov)
+	if (amdgpu_sriov_bios(adev))
 		return 0;
 
 	hdr = (const struct mc_firmware_header_v1_0 *)adev->mc.fw->data;
diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_smc.c b/drivers/gpu/drm/amd/amdgpu/iceland_smc.c
index ef7c27d..c6e004a 100644
--- a/drivers/gpu/drm/amd/amdgpu/iceland_smc.c
+++ b/drivers/gpu/drm/amd/amdgpu/iceland_smc.c
@@ -282,7 +282,7 @@  static int iceland_smu_upload_firmware_image(struct amdgpu_device *adev)
 	/* Skip SMC ucode loading on SR-IOV capable boards.
 	 * vbios does this for us in asic_init in that case.
 	 */
-	if (adev->virtualization.supports_sr_iov)
+	if (amdgpu_sriov_bios(adev))
 		return 0;
 
 	hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data;
diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
index fee76b8..a0b6b7e 100644
--- a/drivers/gpu/drm/amd/amdgpu/si.c
+++ b/drivers/gpu/drm/amd/amdgpu/si.c
@@ -952,12 +952,6 @@  static void si_smc_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
 	spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
 }
 
-static u32 si_get_virtual_caps(struct amdgpu_device *adev)
-{
-	/* SI does not support SR-IOV */
-	return 0;
-}
-
 static struct amdgpu_allowed_register_entry si_allowed_read_registers[] = {
 	{GRBM_STATUS, false},
 	{GB_ADDR_CONFIG, false},
@@ -1133,7 +1127,6 @@  static const struct amdgpu_asic_funcs si_asic_funcs =
 	.get_xclk = &si_get_xclk,
 	.set_uvd_clocks = &si_set_uvd_clocks,
 	.set_vce_clocks = NULL,
-	.get_virtual_caps = &si_get_virtual_caps,
 };
 
 static uint32_t si_get_rev_id(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_smc.c b/drivers/gpu/drm/amd/amdgpu/tonga_smc.c
index 940de18..1e71e81 100644
--- a/drivers/gpu/drm/amd/amdgpu/tonga_smc.c
+++ b/drivers/gpu/drm/amd/amdgpu/tonga_smc.c
@@ -275,7 +275,7 @@  static int tonga_smu_upload_firmware_image(struct amdgpu_device *adev)
 	/* Skip SMC ucode loading on SR-IOV capable boards.
 	 * vbios does this for us in asic_init in that case.
 	 */
-	if (adev->virtualization.supports_sr_iov)
+	if (amdgpu_sriov_bios(adev))
 		return 0;
 
 	hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data;
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index b688e2f..5141393 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -445,18 +445,25 @@  static bool vi_read_bios_from_rom(struct amdgpu_device *adev,
 	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;
+static void vi_detect_hw_virtualization(struct amdgpu_device *adev) {
+	uint32_t reg = RREG32(mmBIF_IOV_FUNC_IDENTIFIER);
+	/* bit0: 0 means pf and 1 means vf */
+	/* bit31: 0 means disable IOV and 1 means enable */
+	if (reg & 1)
+		adev->virtualization.virtual_caps |= AMDGPU_SRIOV_CAPS_IS_VF;
+
+	if (reg & 0x80000000)
+		adev->virtualization.virtual_caps |= AMDGPU_SRIOV_CAPS_ENABLE_IOV;
+
+	if (reg == 0) {
+		if (is_virtual_machine()) /* passthrough mode exclus sr-iov mode */
+			adev->virtualization.virtual_caps |= AMDGPU_PASSTHROUGH_MODE;
+	}
+}
 
-	return caps;
+static void vi_detect_sriov_bios(struct amdgpu_device *adev) {
+	if (amdgpu_atombios_has_gpu_virtualization_table(adev))
+		adev->virtualization.virtual_caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS;
 }
 
 static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = {
@@ -1521,13 +1528,14 @@  static const struct amdgpu_asic_funcs vi_asic_funcs =
 {
 	.read_disabled_bios = &vi_read_disabled_bios,
 	.read_bios_from_rom = &vi_read_bios_from_rom,
+	.detect_hw_virtualization = vi_detect_hw_virtualization,
+	.detect_sriov_bios = vi_detect_sriov_bios,
 	.read_register = &vi_read_register,
 	.reset = &vi_asic_reset,
 	.set_vga_state = &vi_vga_set_state,
 	.get_xclk = &vi_get_xclk,
 	.set_uvd_clocks = &vi_set_uvd_clocks,
 	.set_vce_clocks = &vi_set_vce_clocks,
-	.get_virtual_caps = &vi_get_virtual_caps,
 };
 
 static int vi_common_early_init(void *handle)
@@ -1657,6 +1665,10 @@  static int vi_common_early_init(void *handle)
 		return -EINVAL;
 	}
 
+	/* in early init stage, vbios code won't work */
+	if (adev->asic_funcs->detect_hw_virtualization)
+		amdgpu_asic_detect_hw_virtualization(adev);
+
 	if (amdgpu_smc_load_fw && smc_enabled)
 		adev->firmware.smu_load = true;
 

Comments

On 09/20/2016 03:12 AM, Alex Deucher wrote:
> From: Monk Liu <Monk.Liu@amd.com>
> 
> 1,Changes on virtualization detections
> 2,Don't load smu & mc firmware if using sr-iov bios
> 3,skip vPost for sriov & force vPost if dev pass-through
> 
> v2: agd: fix missed SI case
> 
> Signed-off-by: Monk Liu <Monk.Liu@amd.com>
> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h        | 38 +++++++++++++++++++++++-------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 25 ++++++++++----------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c    |  2 +-
>  drivers/gpu/drm/amd/amdgpu/cik.c           |  7 ------
>  drivers/gpu/drm/amd/amdgpu/fiji_smc.c      |  2 +-
>  drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c      |  4 +++-
>  drivers/gpu/drm/amd/amdgpu/iceland_smc.c   |  2 +-
>  drivers/gpu/drm/amd/amdgpu/si.c            |  7 ------
>  drivers/gpu/drm/amd/amdgpu/tonga_smc.c     |  2 +-
>  drivers/gpu/drm/amd/amdgpu/vi.c            | 36 ++++++++++++++++++----------
>  10 files changed, 74 insertions(+), 51 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index ee45d9f..ff6e683 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -1827,6 +1827,8 @@ struct amdgpu_asic_funcs {
>  	bool (*read_disabled_bios)(struct amdgpu_device *adev);
>  	bool (*read_bios_from_rom)(struct amdgpu_device *adev,
>  				   u8 *bios, u32 length_bytes);
> +	void (*detect_hw_virtualization) (struct amdgpu_device *adev);
> +	void (*detect_sriov_bios)(struct amdgpu_device *adev);
>  	int (*read_register)(struct amdgpu_device *adev, u32 se_num,
>  			     u32 sh_num, u32 reg_offset, u32 *value);
>  	void (*set_vga_state)(struct amdgpu_device *adev, bool state);
> @@ -1836,8 +1838,6 @@ struct amdgpu_asic_funcs {
>  	/* MM block clocks */
>  	int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk);
>  	int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk);
> -	/* query virtual capabilities */
> -	u32 (*get_virtual_caps)(struct amdgpu_device *adev);
>  	/* static power management */
>  	int (*get_pcie_lanes)(struct amdgpu_device *adev);
>  	void (*set_pcie_lanes)(struct amdgpu_device *adev, int lanes);
> @@ -1934,15 +1934,36 @@ struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev);
>  void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device);
>  
>  
> +#define AMDGPU_SRIOV_CAPS_SRIOV_VBIOS  (1 << 0) /* vBIOS is sr-iov ready */
> +#define AMDGPU_SRIOV_CAPS_ENABLE_IOV   (1 << 1) /* sr-iov is enabled on this GPU */
> +#define AMDGPU_SRIOV_CAPS_IS_VF        (1 << 2) /* this GPU is a virtual function */
> +#define AMDGPU_PASSTHROUGH_MODE        (1 << 3) /* thw whole GPU is pass through for VM */
>  /* GPU virtualization */
> -#define AMDGPU_VIRT_CAPS_SRIOV_EN       (1 << 0)
> -#define AMDGPU_VIRT_CAPS_IS_VF          (1 << 1)
>  struct amdgpu_virtualization {
> -	bool supports_sr_iov;
> -	bool is_virtual;
> -	u32 caps;
> +	uint32_t virtual_caps;
>  };
>  
> +#define amdgpu_sriov_enabled(adev) \
> +((adev)->virtualization.virtual_caps & AMDGPU_SRIOV_CAPS_ENABLE_IOV)
> +
> +#define amdgpu_sriov_vf(adev) \
> +((adev)->virtualization.virtual_caps & AMDGPU_SRIOV_CAPS_IS_VF)
> +
> +#define amdgpu_sriov_bios(adev) \
> +((adev)->virtualization.virtual_caps & AMDGPU_SRIOV_CAPS_SRIOV_VBIOS)
> +
> +#define amdgpu_passthrough(adev) \
> +((adev)->virtualization.virtual_caps & AMDGPU_PASSTHROUGH_MODE)
> +
> +static inline bool is_virtual_machine(void)
> +{
> +#ifdef CONFIG_X86
> +	return boot_cpu_has(X86_FEATURE_HYPERVISOR);
> +#else
> +	return false;
> +#endif
> +}
> +
>  /*
>   * Core structure, functions and helpers.
>   */
> @@ -2260,12 +2281,13 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
>  #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_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_get_pcie_lanes(adev) (adev)->asic_funcs->get_pcie_lanes((adev))
>  #define amdgpu_set_pcie_lanes(adev, l) (adev)->asic_funcs->set_pcie_lanes((adev), (l))
>  #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_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l))
> +#define amdgpu_asic_detect_hw_virtualization(adev) (adev)->asic_funcs->detect_hw_virtualization((adev))
> +#define amdgpu_asic_detect_sriov_bios(adev) (adev)->asic_funcs->detect_sriov_bios((adev))
>  #define amdgpu_asic_read_register(adev, se, sh, offset, v)((adev)->asic_funcs->read_register((adev), (se), (sh), (offset), (v)))
>  #define amdgpu_gart_flush_gpu_tlb(adev, vmid) (adev)->gart.gart_funcs->flush_gpu_tlb((adev), (vmid))
>  #define amdgpu_gart_set_pte_pde(adev, pt, idx, addr, flags) (adev)->gart.gart_funcs->set_pte_pde((adev), (pt), (idx), (addr), (flags))
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 377d818..2df5f00 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -110,7 +110,7 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
>  		    bool always_indirect)
>  {
>  	trace_amdgpu_mm_wreg(adev->pdev->device, reg, v);
> -	
> +
>  	if ((reg * 4) < adev->rmmio_size && !always_indirect)
>  		writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
>  	else {
> @@ -1648,25 +1648,26 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>  		goto failed;
>  	}
>  
> -	/* See if the asic supports SR-IOV */
> -	adev->virtualization.supports_sr_iov =
> -		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);
> +	/* detect if we are with an SRIOV vbios */
> +	if (adev->asic_funcs->detect_sriov_bios)
> +		amdgpu_asic_detect_sriov_bios(adev);
>  
>  	/* Post card if necessary */
> -	if (!amdgpu_card_posted(adev) ||
> -	    (adev->virtualization.is_virtual &&
> -	     !(adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN))) {
> +	if (!amdgpu_sriov_vf(adev) &&
> +		(!amdgpu_card_posted(adev) || amdgpu_passthrough(adev))) {
>  		if (!adev->bios) {
>  			dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n");
>  			r = -EINVAL;
>  			goto failed;
>  		}
>  		DRM_INFO("GPU not posted. posting now...\n");
> -		amdgpu_atom_asic_init(adev->mode_info.atom_context);
> +		r = amdgpu_atom_asic_init(adev->mode_info.atom_context);
> +		if (r) {
> +			dev_err(adev->dev, "gpu post error!\n");
> +			goto failed;
> +		}
> +	} else {
> +		DRM_INFO("GPU post is not needed\n");
>  	}
>  
>  	/* Initialize clocks */
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index c96ae10..0c5f36d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -485,7 +485,7 @@ amdgpu_pci_shutdown(struct pci_dev *pdev)
>  	/* if we are running in a VM, make sure the device
>  	 * torn down properly on reboot/shutdown
>  	 */
> -	if (adev->virtualization.is_virtual)
> +	if (amdgpu_passthrough(adev))
>  		amdgpu_pci_remove(pdev);
>  }
>  
> diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
> index 825de80..e61fdee 100644
> --- a/drivers/gpu/drm/amd/amdgpu/cik.c
> +++ b/drivers/gpu/drm/amd/amdgpu/cik.c
> @@ -963,12 +963,6 @@ static bool cik_read_bios_from_rom(struct amdgpu_device *adev,
>  	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[] = {
>  	{mmGRBM_STATUS, false},
>  	{mmGB_ADDR_CONFIG, false},
> @@ -2390,7 +2384,6 @@ static const struct amdgpu_asic_funcs cik_asic_funcs =
>  	.get_xclk = &cik_get_xclk,
>  	.set_uvd_clocks = &cik_set_uvd_clocks,
>  	.set_vce_clocks = &cik_set_vce_clocks,
> -	.get_virtual_caps = &cik_get_virtual_caps,
>  };
>  
>  static int cik_common_early_init(void *handle)
> diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_smc.c b/drivers/gpu/drm/amd/amdgpu/fiji_smc.c
> index b3e19ba..8cfb0a3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/fiji_smc.c
> +++ b/drivers/gpu/drm/amd/amdgpu/fiji_smc.c
> @@ -275,7 +275,7 @@ static int fiji_smu_upload_firmware_image(struct amdgpu_device *adev)
>  	/* Skip SMC ucode loading on SR-IOV capable boards.
>  	 * vbios does this for us in asic_init in that case.
>  	 */
> -	if (adev->virtualization.supports_sr_iov)
> +	if (amdgpu_sriov_bios(adev))
>  		return 0;
>  
>  	hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data;
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> index 8e7127f..6ec8e01 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
> @@ -261,8 +261,10 @@ static int gmc_v8_0_mc_load_microcode(struct amdgpu_device *adev)
>  
>  	/* Skip MC ucode loading on SR-IOV capable boards.
>  	 * vbios does this for us in asic_init in that case.
> +	 * Skip MC ucode loading on VF, because hypervisor will do that
> +	 * for this adaptor.
>  	 */
> -	if (adev->virtualization.supports_sr_iov)
> +	if (amdgpu_sriov_bios(adev))
>  		return 0;
>  
>  	hdr = (const struct mc_firmware_header_v1_0 *)adev->mc.fw->data;
> diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_smc.c b/drivers/gpu/drm/amd/amdgpu/iceland_smc.c
> index ef7c27d..c6e004a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/iceland_smc.c
> +++ b/drivers/gpu/drm/amd/amdgpu/iceland_smc.c
> @@ -282,7 +282,7 @@ static int iceland_smu_upload_firmware_image(struct amdgpu_device *adev)
>  	/* Skip SMC ucode loading on SR-IOV capable boards.
>  	 * vbios does this for us in asic_init in that case.
>  	 */
> -	if (adev->virtualization.supports_sr_iov)
> +	if (amdgpu_sriov_bios(adev))
>  		return 0;
>  
>  	hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data;
> diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
> index fee76b8..a0b6b7e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/si.c
> +++ b/drivers/gpu/drm/amd/amdgpu/si.c
> @@ -952,12 +952,6 @@ static void si_smc_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
>  	spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
>  }
>  
> -static u32 si_get_virtual_caps(struct amdgpu_device *adev)
> -{
> -	/* SI does not support SR-IOV */
> -	return 0;
> -}
> -
>  static struct amdgpu_allowed_register_entry si_allowed_read_registers[] = {
>  	{GRBM_STATUS, false},
>  	{GB_ADDR_CONFIG, false},
> @@ -1133,7 +1127,6 @@ static const struct amdgpu_asic_funcs si_asic_funcs =
>  	.get_xclk = &si_get_xclk,
>  	.set_uvd_clocks = &si_set_uvd_clocks,
>  	.set_vce_clocks = NULL,
> -	.get_virtual_caps = &si_get_virtual_caps,
>  };
>  
>  static uint32_t si_get_rev_id(struct amdgpu_device *adev)
> diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_smc.c b/drivers/gpu/drm/amd/amdgpu/tonga_smc.c
> index 940de18..1e71e81 100644
> --- a/drivers/gpu/drm/amd/amdgpu/tonga_smc.c
> +++ b/drivers/gpu/drm/amd/amdgpu/tonga_smc.c
> @@ -275,7 +275,7 @@ static int tonga_smu_upload_firmware_image(struct amdgpu_device *adev)
>  	/* Skip SMC ucode loading on SR-IOV capable boards.
>  	 * vbios does this for us in asic_init in that case.
>  	 */
> -	if (adev->virtualization.supports_sr_iov)
> +	if (amdgpu_sriov_bios(adev))
>  		return 0;
>  
>  	hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data;
> diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
> index b688e2f..5141393 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vi.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vi.c
> @@ -445,18 +445,25 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev,
>  	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;
> +static void vi_detect_hw_virtualization(struct amdgpu_device *adev) {
> +	uint32_t reg = RREG32(mmBIF_IOV_FUNC_IDENTIFIER);
> +	/* bit0: 0 means pf and 1 means vf */
> +	/* bit31: 0 means disable IOV and 1 means enable */
> +	if (reg & 1)
> +		adev->virtualization.virtual_caps |= AMDGPU_SRIOV_CAPS_IS_VF;
> +
> +	if (reg & 0x80000000)
> +		adev->virtualization.virtual_caps |= AMDGPU_SRIOV_CAPS_ENABLE_IOV;
> +
> +	if (reg == 0) {
> +		if (is_virtual_machine()) /* passthrough mode exclus sr-iov mode */
> +			adev->virtualization.virtual_caps |= AMDGPU_PASSTHROUGH_MODE;
> +	}
> +}
>  
> -	return caps;
> +static void vi_detect_sriov_bios(struct amdgpu_device *adev) {
> +	if (amdgpu_atombios_has_gpu_virtualization_table(adev))
> +		adev->virtualization.virtual_caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS;
>  }
>  
>  static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = {
> @@ -1521,13 +1528,14 @@ static const struct amdgpu_asic_funcs vi_asic_funcs =
>  {
>  	.read_disabled_bios = &vi_read_disabled_bios,
>  	.read_bios_from_rom = &vi_read_bios_from_rom,
> +	.detect_hw_virtualization = vi_detect_hw_virtualization,
> +	.detect_sriov_bios = vi_detect_sriov_bios,

Why add it here and remove it later? Can these two sets be squashed
together?

>  	.read_register = &vi_read_register,
>  	.reset = &vi_asic_reset,
>  	.set_vga_state = &vi_vga_set_state,
>  	.get_xclk = &vi_get_xclk,
>  	.set_uvd_clocks = &vi_set_uvd_clocks,
>  	.set_vce_clocks = &vi_set_vce_clocks,
> -	.get_virtual_caps = &vi_get_virtual_caps,
>  };
>  
>  static int vi_common_early_init(void *handle)
> @@ -1657,6 +1665,10 @@ static int vi_common_early_init(void *handle)
>  		return -EINVAL;
>  	}
>  
> +	/* in early init stage, vbios code won't work */
> +	if (adev->asic_funcs->detect_hw_virtualization)
> +		amdgpu_asic_detect_hw_virtualization(adev);
> +
>  	if (amdgpu_smc_load_fw && smc_enabled)
>  		adev->firmware.smu_load = true;
>  
>
> -----Original Message-----

> From: Edward O'Callaghan [mailto:funfunctor@folklore1984.net]

> Sent: Monday, September 19, 2016 7:38 PM

> To: Alex Deucher; amd-gfx@lists.freedesktop.org

> Cc: Deucher, Alexander; Liu, Monk

> Subject: Re: [PATCH 1/5] drm/amdgpu:changes of virtualization cases probe

> (v2)

> 

> 

> 

> On 09/20/2016 03:12 AM, Alex Deucher wrote:

> > From: Monk Liu <Monk.Liu@amd.com>

> >

> > 1,Changes on virtualization detections

> > 2,Don't load smu & mc firmware if using sr-iov bios

> > 3,skip vPost for sriov & force vPost if dev pass-through

> >

> > v2: agd: fix missed SI case

> >

> > Signed-off-by: Monk Liu <Monk.Liu@amd.com>

> > Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> > Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

> > ---

> >  drivers/gpu/drm/amd/amdgpu/amdgpu.h        | 38

> +++++++++++++++++++++++-------

> >  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 25 ++++++++++--------

> --

> >  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c    |  2 +-

> >  drivers/gpu/drm/amd/amdgpu/cik.c           |  7 ------

> >  drivers/gpu/drm/amd/amdgpu/fiji_smc.c      |  2 +-

> >  drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c      |  4 +++-

> >  drivers/gpu/drm/amd/amdgpu/iceland_smc.c   |  2 +-

> >  drivers/gpu/drm/amd/amdgpu/si.c            |  7 ------

> >  drivers/gpu/drm/amd/amdgpu/tonga_smc.c     |  2 +-

> >  drivers/gpu/drm/amd/amdgpu/vi.c            | 36 ++++++++++++++++++------

> ----

> >  10 files changed, 74 insertions(+), 51 deletions(-)

> >

> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h

> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h

> > index ee45d9f..ff6e683 100644

> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h

> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h

> > @@ -1827,6 +1827,8 @@ struct amdgpu_asic_funcs {

> >  	bool (*read_disabled_bios)(struct amdgpu_device *adev);

> >  	bool (*read_bios_from_rom)(struct amdgpu_device *adev,

> >  				   u8 *bios, u32 length_bytes);

> > +	void (*detect_hw_virtualization) (struct amdgpu_device *adev);

> > +	void (*detect_sriov_bios)(struct amdgpu_device *adev);

> >  	int (*read_register)(struct amdgpu_device *adev, u32 se_num,

> >  			     u32 sh_num, u32 reg_offset, u32 *value);

> >  	void (*set_vga_state)(struct amdgpu_device *adev, bool state);

> > @@ -1836,8 +1838,6 @@ struct amdgpu_asic_funcs {

> >  	/* MM block clocks */

> >  	int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32

> dclk);

> >  	int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32

> ecclk);

> > -	/* query virtual capabilities */

> > -	u32 (*get_virtual_caps)(struct amdgpu_device *adev);

> >  	/* static power management */

> >  	int (*get_pcie_lanes)(struct amdgpu_device *adev);

> >  	void (*set_pcie_lanes)(struct amdgpu_device *adev, int lanes);

> > @@ -1934,15 +1934,36 @@ struct cgs_device

> *amdgpu_cgs_create_device(struct amdgpu_device *adev);

> >  void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device);

> >

> >

> > +#define AMDGPU_SRIOV_CAPS_SRIOV_VBIOS  (1 << 0) /* vBIOS is sr-iov

> ready */

> > +#define AMDGPU_SRIOV_CAPS_ENABLE_IOV   (1 << 1) /* sr-iov is

> enabled on this GPU */

> > +#define AMDGPU_SRIOV_CAPS_IS_VF        (1 << 2) /* this GPU is a virtual

> function */

> > +#define AMDGPU_PASSTHROUGH_MODE        (1 << 3) /* thw whole GPU

> is pass through for VM */

> >  /* GPU virtualization */

> > -#define AMDGPU_VIRT_CAPS_SRIOV_EN       (1 << 0)

> > -#define AMDGPU_VIRT_CAPS_IS_VF          (1 << 1)

> >  struct amdgpu_virtualization {

> > -	bool supports_sr_iov;

> > -	bool is_virtual;

> > -	u32 caps;

> > +	uint32_t virtual_caps;

> >  };

> >

> > +#define amdgpu_sriov_enabled(adev) \

> > +((adev)->virtualization.virtual_caps &

> AMDGPU_SRIOV_CAPS_ENABLE_IOV)

> > +

> > +#define amdgpu_sriov_vf(adev) \

> > +((adev)->virtualization.virtual_caps & AMDGPU_SRIOV_CAPS_IS_VF)

> > +

> > +#define amdgpu_sriov_bios(adev) \

> > +((adev)->virtualization.virtual_caps &

> AMDGPU_SRIOV_CAPS_SRIOV_VBIOS)

> > +

> > +#define amdgpu_passthrough(adev) \

> > +((adev)->virtualization.virtual_caps & AMDGPU_PASSTHROUGH_MODE)

> > +

> > +static inline bool is_virtual_machine(void)

> > +{

> > +#ifdef CONFIG_X86

> > +	return boot_cpu_has(X86_FEATURE_HYPERVISOR);

> > +#else

> > +	return false;

> > +#endif

> > +}

> > +

> >  /*

> >   * Core structure, functions and helpers.

> >   */

> > @@ -2260,12 +2281,13 @@ amdgpu_get_sdma_instance(struct

> amdgpu_ring *ring)

> >  #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_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_get_pcie_lanes(adev) (adev)->asic_funcs-

> >get_pcie_lanes((adev))

> >  #define amdgpu_set_pcie_lanes(adev, l) (adev)->asic_funcs-

> >set_pcie_lanes((adev), (l))

> >  #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_bios_from_rom(adev, b, l) (adev)-

> >asic_funcs->read_bios_from_rom((adev), (b), (l))

> > +#define amdgpu_asic_detect_hw_virtualization(adev) (adev)-

> >asic_funcs->detect_hw_virtualization((adev))

> > +#define amdgpu_asic_detect_sriov_bios(adev) (adev)->asic_funcs-

> >detect_sriov_bios((adev))

> >  #define amdgpu_asic_read_register(adev, se, sh, offset, v)((adev)-

> >asic_funcs->read_register((adev), (se), (sh), (offset), (v)))

> >  #define amdgpu_gart_flush_gpu_tlb(adev, vmid) (adev)-

> >gart.gart_funcs->flush_gpu_tlb((adev), (vmid))

> >  #define amdgpu_gart_set_pte_pde(adev, pt, idx, addr, flags) (adev)-

> >gart.gart_funcs->set_pte_pde((adev), (pt), (idx), (addr), (flags))

> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c

> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c

> > index 377d818..2df5f00 100644

> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c

> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c

> > @@ -110,7 +110,7 @@ void amdgpu_mm_wreg(struct amdgpu_device

> *adev, uint32_t reg, uint32_t v,

> >  		    bool always_indirect)

> >  {

> >  	trace_amdgpu_mm_wreg(adev->pdev->device, reg, v);

> > -

> > +

> >  	if ((reg * 4) < adev->rmmio_size && !always_indirect)

> >  		writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));

> >  	else {

> > @@ -1648,25 +1648,26 @@ int amdgpu_device_init(struct amdgpu_device

> *adev,

> >  		goto failed;

> >  	}

> >

> > -	/* See if the asic supports SR-IOV */

> > -	adev->virtualization.supports_sr_iov =

> > -		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);

> > +	/* detect if we are with an SRIOV vbios */

> > +	if (adev->asic_funcs->detect_sriov_bios)

> > +		amdgpu_asic_detect_sriov_bios(adev);

> >

> >  	/* Post card if necessary */

> > -	if (!amdgpu_card_posted(adev) ||

> > -	    (adev->virtualization.is_virtual &&

> > -	     !(adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN))) {

> > +	if (!amdgpu_sriov_vf(adev) &&

> > +		(!amdgpu_card_posted(adev) ||

> amdgpu_passthrough(adev))) {

> >  		if (!adev->bios) {

> >  			dev_err(adev->dev, "Card not posted and no BIOS -

> ignoring\n");

> >  			r = -EINVAL;

> >  			goto failed;

> >  		}

> >  		DRM_INFO("GPU not posted. posting now...\n");

> > -		amdgpu_atom_asic_init(adev->mode_info.atom_context);

> > +		r = amdgpu_atom_asic_init(adev-

> >mode_info.atom_context);

> > +		if (r) {

> > +			dev_err(adev->dev, "gpu post error!\n");

> > +			goto failed;

> > +		}

> > +	} else {

> > +		DRM_INFO("GPU post is not needed\n");

> >  	}

> >

> >  	/* Initialize clocks */

> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c

> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c

> > index c96ae10..0c5f36d 100644

> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c

> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c

> > @@ -485,7 +485,7 @@ amdgpu_pci_shutdown(struct pci_dev *pdev)

> >  	/* if we are running in a VM, make sure the device

> >  	 * torn down properly on reboot/shutdown

> >  	 */

> > -	if (adev->virtualization.is_virtual)

> > +	if (amdgpu_passthrough(adev))

> >  		amdgpu_pci_remove(pdev);

> >  }

> >

> > diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c

> b/drivers/gpu/drm/amd/amdgpu/cik.c

> > index 825de80..e61fdee 100644

> > --- a/drivers/gpu/drm/amd/amdgpu/cik.c

> > +++ b/drivers/gpu/drm/amd/amdgpu/cik.c

> > @@ -963,12 +963,6 @@ static bool cik_read_bios_from_rom(struct

> amdgpu_device *adev,

> >  	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[] = {

> >  	{mmGRBM_STATUS, false},

> >  	{mmGB_ADDR_CONFIG, false},

> > @@ -2390,7 +2384,6 @@ static const struct amdgpu_asic_funcs

> cik_asic_funcs =

> >  	.get_xclk = &cik_get_xclk,

> >  	.set_uvd_clocks = &cik_set_uvd_clocks,

> >  	.set_vce_clocks = &cik_set_vce_clocks,

> > -	.get_virtual_caps = &cik_get_virtual_caps,

> >  };

> >

> >  static int cik_common_early_init(void *handle)

> > diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_smc.c

> b/drivers/gpu/drm/amd/amdgpu/fiji_smc.c

> > index b3e19ba..8cfb0a3 100644

> > --- a/drivers/gpu/drm/amd/amdgpu/fiji_smc.c

> > +++ b/drivers/gpu/drm/amd/amdgpu/fiji_smc.c

> > @@ -275,7 +275,7 @@ static int fiji_smu_upload_firmware_image(struct

> amdgpu_device *adev)

> >  	/* Skip SMC ucode loading on SR-IOV capable boards.

> >  	 * vbios does this for us in asic_init in that case.

> >  	 */

> > -	if (adev->virtualization.supports_sr_iov)

> > +	if (amdgpu_sriov_bios(adev))

> >  		return 0;

> >

> >  	hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw-

> >data;

> > diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c

> b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c

> > index 8e7127f..6ec8e01 100644

> > --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c

> > +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c

> > @@ -261,8 +261,10 @@ static int gmc_v8_0_mc_load_microcode(struct

> amdgpu_device *adev)

> >

> >  	/* Skip MC ucode loading on SR-IOV capable boards.

> >  	 * vbios does this for us in asic_init in that case.

> > +	 * Skip MC ucode loading on VF, because hypervisor will do that

> > +	 * for this adaptor.

> >  	 */

> > -	if (adev->virtualization.supports_sr_iov)

> > +	if (amdgpu_sriov_bios(adev))

> >  		return 0;

> >

> >  	hdr = (const struct mc_firmware_header_v1_0 *)adev->mc.fw-

> >data;

> > diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_smc.c

> b/drivers/gpu/drm/amd/amdgpu/iceland_smc.c

> > index ef7c27d..c6e004a 100644

> > --- a/drivers/gpu/drm/amd/amdgpu/iceland_smc.c

> > +++ b/drivers/gpu/drm/amd/amdgpu/iceland_smc.c

> > @@ -282,7 +282,7 @@ static int

> iceland_smu_upload_firmware_image(struct amdgpu_device *adev)

> >  	/* Skip SMC ucode loading on SR-IOV capable boards.

> >  	 * vbios does this for us in asic_init in that case.

> >  	 */

> > -	if (adev->virtualization.supports_sr_iov)

> > +	if (amdgpu_sriov_bios(adev))

> >  		return 0;

> >

> >  	hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw-

> >data;

> > diff --git a/drivers/gpu/drm/amd/amdgpu/si.c

> b/drivers/gpu/drm/amd/amdgpu/si.c

> > index fee76b8..a0b6b7e 100644

> > --- a/drivers/gpu/drm/amd/amdgpu/si.c

> > +++ b/drivers/gpu/drm/amd/amdgpu/si.c

> > @@ -952,12 +952,6 @@ static void si_smc_wreg(struct amdgpu_device

> *adev, u32 reg, u32 v)

> >  	spin_unlock_irqrestore(&adev->smc_idx_lock, flags);

> >  }

> >

> > -static u32 si_get_virtual_caps(struct amdgpu_device *adev)

> > -{

> > -	/* SI does not support SR-IOV */

> > -	return 0;

> > -}

> > -

> >  static struct amdgpu_allowed_register_entry si_allowed_read_registers[]

> = {

> >  	{GRBM_STATUS, false},

> >  	{GB_ADDR_CONFIG, false},

> > @@ -1133,7 +1127,6 @@ static const struct amdgpu_asic_funcs

> si_asic_funcs =

> >  	.get_xclk = &si_get_xclk,

> >  	.set_uvd_clocks = &si_set_uvd_clocks,

> >  	.set_vce_clocks = NULL,

> > -	.get_virtual_caps = &si_get_virtual_caps,

> >  };

> >

> >  static uint32_t si_get_rev_id(struct amdgpu_device *adev)

> > diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_smc.c

> b/drivers/gpu/drm/amd/amdgpu/tonga_smc.c

> > index 940de18..1e71e81 100644

> > --- a/drivers/gpu/drm/amd/amdgpu/tonga_smc.c

> > +++ b/drivers/gpu/drm/amd/amdgpu/tonga_smc.c

> > @@ -275,7 +275,7 @@ static int

> tonga_smu_upload_firmware_image(struct amdgpu_device *adev)

> >  	/* Skip SMC ucode loading on SR-IOV capable boards.

> >  	 * vbios does this for us in asic_init in that case.

> >  	 */

> > -	if (adev->virtualization.supports_sr_iov)

> > +	if (amdgpu_sriov_bios(adev))

> >  		return 0;

> >

> >  	hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw-

> >data;

> > diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c

> b/drivers/gpu/drm/amd/amdgpu/vi.c

> > index b688e2f..5141393 100644

> > --- a/drivers/gpu/drm/amd/amdgpu/vi.c

> > +++ b/drivers/gpu/drm/amd/amdgpu/vi.c

> > @@ -445,18 +445,25 @@ static bool vi_read_bios_from_rom(struct

> amdgpu_device *adev,

> >  	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;

> > +static void vi_detect_hw_virtualization(struct amdgpu_device *adev) {

> > +	uint32_t reg = RREG32(mmBIF_IOV_FUNC_IDENTIFIER);

> > +	/* bit0: 0 means pf and 1 means vf */

> > +	/* bit31: 0 means disable IOV and 1 means enable */

> > +	if (reg & 1)

> > +		adev->virtualization.virtual_caps |=

> AMDGPU_SRIOV_CAPS_IS_VF;

> > +

> > +	if (reg & 0x80000000)

> > +		adev->virtualization.virtual_caps |=

> AMDGPU_SRIOV_CAPS_ENABLE_IOV;

> > +

> > +	if (reg == 0) {

> > +		if (is_virtual_machine()) /* passthrough mode exclus sr-iov

> mode */

> > +			adev->virtualization.virtual_caps |=

> AMDGPU_PASSTHROUGH_MODE;

> > +	}

> > +}

> >

> > -	return caps;

> > +static void vi_detect_sriov_bios(struct amdgpu_device *adev) {

> > +	if (amdgpu_atombios_has_gpu_virtualization_table(adev))

> > +		adev->virtualization.virtual_caps |=

> AMDGPU_SRIOV_CAPS_SRIOV_VBIOS;

> >  }

> >

> >  static const struct amdgpu_allowed_register_entry

> tonga_allowed_read_registers[] = {

> > @@ -1521,13 +1528,14 @@ static const struct amdgpu_asic_funcs

> vi_asic_funcs =

> >  {

> >  	.read_disabled_bios = &vi_read_disabled_bios,

> >  	.read_bios_from_rom = &vi_read_bios_from_rom,

> > +	.detect_hw_virtualization = vi_detect_hw_virtualization,

> > +	.detect_sriov_bios = vi_detect_sriov_bios,

> 

> Why add it here and remove it later? Can these two sets be squashed

> together?


Yes, they will be squashed together when the series goes upstream.  See:
https://cgit.freedesktop.org/~agd5f/linux/commit/?h=drm-next-4.9-wip&id=4e99a44e37bfed8c4f25c94687e8e4ac4ae65086

Alex

> 

> >  	.read_register = &vi_read_register,

> >  	.reset = &vi_asic_reset,

> >  	.set_vga_state = &vi_vga_set_state,

> >  	.get_xclk = &vi_get_xclk,

> >  	.set_uvd_clocks = &vi_set_uvd_clocks,

> >  	.set_vce_clocks = &vi_set_vce_clocks,

> > -	.get_virtual_caps = &vi_get_virtual_caps,

> >  };

> >

> >  static int vi_common_early_init(void *handle)

> > @@ -1657,6 +1665,10 @@ static int vi_common_early_init(void *handle)

> >  		return -EINVAL;

> >  	}

> >

> > +	/* in early init stage, vbios code won't work */

> > +	if (adev->asic_funcs->detect_hw_virtualization)

> > +		amdgpu_asic_detect_hw_virtualization(adev);

> > +

> >  	if (amdgpu_smc_load_fw && smc_enabled)

> >  		adev->firmware.smu_load = true;

> >

> >