Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e99a44e authored by Monk Liu's avatar Monk Liu Committed by Alex Deucher
Browse files

drm/amdgpu:changes of virtualization cases probe (v3)



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: squash in Rays's fix for the missed SI case
v3: agd: squash in additional fixes for CIK, SI, cleanup

Signed-off-by: default avatarMonk Liu <Monk.Liu@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ecab7668
Loading
Loading
Loading
Loading
+28 −8
Original line number Diff line number Diff line
@@ -1827,6 +1827,7 @@ 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);
	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 +1837,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 +1933,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 +2280,12 @@ 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_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))
+15 −18
Original line number Diff line number Diff line
@@ -1485,13 +1485,10 @@ static int amdgpu_resume(struct amdgpu_device *adev)
	return 0;
}

static bool amdgpu_device_is_virtual(void)
static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev)
{
#ifdef CONFIG_X86
	return boot_cpu_has(X86_FEATURE_HYPERVISOR);
#else
	return false;
#endif
	if (amdgpu_atombios_has_gpu_virtualization_table(adev))
		adev->virtualization.virtual_caps |= AMDGPU_SRIOV_CAPS_SRIOV_VBIOS;
}

/**
@@ -1648,25 +1645,25 @@ 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 */
	amdgpu_device_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 */
+1 −1
Original line number Diff line number Diff line
@@ -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);
}

+7 −7
Original line number Diff line number Diff line
@@ -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},
@@ -1641,6 +1635,12 @@ static uint32_t cik_get_rev_id(struct amdgpu_device *adev)
		>> CC_DRM_ID_STRAPS__ATI_REV_ID__SHIFT;
}

static void cik_detect_hw_virtualization(struct amdgpu_device *adev)
{
	if (is_virtual_machine()) /* passthrough mode */
		adev->virtualization.virtual_caps |= AMDGPU_PASSTHROUGH_MODE;
}

static const struct amdgpu_ip_block_version bonaire_ip_blocks[] =
{
	/* ORDER MATTERS! */
@@ -2384,13 +2384,13 @@ static const struct amdgpu_asic_funcs cik_asic_funcs =
{
	.read_disabled_bios = &cik_read_disabled_bios,
	.read_bios_from_rom = &cik_read_bios_from_rom,
	.detect_hw_virtualization = cik_detect_hw_virtualization,
	.read_register = &cik_read_register,
	.reset = &cik_asic_reset,
	.set_vga_state = &cik_vga_set_state,
	.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)
+1 −1
Original line number Diff line number Diff line
@@ -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;
Loading