diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/vi.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vi.c | 535 | 
1 files changed, 494 insertions, 41 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 03a31c53aec3..c0d9aad7126f 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -77,7 +77,11 @@  #if defined(CONFIG_DRM_AMD_ACP)  #include "amdgpu_acp.h"  #endif +#include "dce_virtual.h" +MODULE_FIRMWARE("amdgpu/topaz_smc.bin"); +MODULE_FIRMWARE("amdgpu/tonga_smc.bin"); +MODULE_FIRMWARE("amdgpu/fiji_smc.bin");  MODULE_FIRMWARE("amdgpu/polaris10_smc.bin");  MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin");  MODULE_FIRMWARE("amdgpu/polaris11_smc.bin"); @@ -444,18 +448,21 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev,  	return true;  } -static u32 vi_get_virtual_caps(struct amdgpu_device *adev) +static void vi_detect_hw_virtualization(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; +	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; +	}  }  static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = { @@ -822,6 +829,60 @@ static const struct amdgpu_ip_block_version topaz_ip_blocks[] =  	},  }; +static const struct amdgpu_ip_block_version topaz_ip_blocks_vd[] = +{ +	/* ORDER MATTERS! */ +	{ +		.type = AMD_IP_BLOCK_TYPE_COMMON, +		.major = 2, +		.minor = 0, +		.rev = 0, +		.funcs = &vi_common_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_GMC, +		.major = 7, +		.minor = 4, +		.rev = 0, +		.funcs = &gmc_v7_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_IH, +		.major = 2, +		.minor = 4, +		.rev = 0, +		.funcs = &iceland_ih_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_SMC, +		.major = 7, +		.minor = 1, +		.rev = 0, +		.funcs = &amdgpu_pp_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_DCE, +		.major = 1, +		.minor = 0, +		.rev = 0, +		.funcs = &dce_virtual_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_GFX, +		.major = 8, +		.minor = 0, +		.rev = 0, +		.funcs = &gfx_v8_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_SDMA, +		.major = 2, +		.minor = 4, +		.rev = 0, +		.funcs = &sdma_v2_4_ip_funcs, +	}, +}; +  static const struct amdgpu_ip_block_version tonga_ip_blocks[] =  {  	/* ORDER MATTERS! */ @@ -890,6 +951,74 @@ static const struct amdgpu_ip_block_version tonga_ip_blocks[] =  	},  }; +static const struct amdgpu_ip_block_version tonga_ip_blocks_vd[] = +{ +	/* ORDER MATTERS! */ +	{ +		.type = AMD_IP_BLOCK_TYPE_COMMON, +		.major = 2, +		.minor = 0, +		.rev = 0, +		.funcs = &vi_common_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_GMC, +		.major = 8, +		.minor = 0, +		.rev = 0, +		.funcs = &gmc_v8_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_IH, +		.major = 3, +		.minor = 0, +		.rev = 0, +		.funcs = &tonga_ih_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_SMC, +		.major = 7, +		.minor = 1, +		.rev = 0, +		.funcs = &amdgpu_pp_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_DCE, +		.major = 10, +		.minor = 0, +		.rev = 0, +		.funcs = &dce_virtual_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_GFX, +		.major = 8, +		.minor = 0, +		.rev = 0, +		.funcs = &gfx_v8_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_SDMA, +		.major = 3, +		.minor = 0, +		.rev = 0, +		.funcs = &sdma_v3_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_UVD, +		.major = 5, +		.minor = 0, +		.rev = 0, +		.funcs = &uvd_v5_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_VCE, +		.major = 3, +		.minor = 0, +		.rev = 0, +		.funcs = &vce_v3_0_ip_funcs, +	}, +}; +  static const struct amdgpu_ip_block_version fiji_ip_blocks[] =  {  	/* ORDER MATTERS! */ @@ -958,6 +1087,74 @@ static const struct amdgpu_ip_block_version fiji_ip_blocks[] =  	},  }; +static const struct amdgpu_ip_block_version fiji_ip_blocks_vd[] = +{ +	/* ORDER MATTERS! */ +	{ +		.type = AMD_IP_BLOCK_TYPE_COMMON, +		.major = 2, +		.minor = 0, +		.rev = 0, +		.funcs = &vi_common_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_GMC, +		.major = 8, +		.minor = 5, +		.rev = 0, +		.funcs = &gmc_v8_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_IH, +		.major = 3, +		.minor = 0, +		.rev = 0, +		.funcs = &tonga_ih_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_SMC, +		.major = 7, +		.minor = 1, +		.rev = 0, +		.funcs = &amdgpu_pp_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_DCE, +		.major = 10, +		.minor = 1, +		.rev = 0, +		.funcs = &dce_virtual_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_GFX, +		.major = 8, +		.minor = 0, +		.rev = 0, +		.funcs = &gfx_v8_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_SDMA, +		.major = 3, +		.minor = 0, +		.rev = 0, +		.funcs = &sdma_v3_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_UVD, +		.major = 6, +		.minor = 0, +		.rev = 0, +		.funcs = &uvd_v6_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_VCE, +		.major = 3, +		.minor = 0, +		.rev = 0, +		.funcs = &vce_v3_0_ip_funcs, +	}, +}; +  static const struct amdgpu_ip_block_version polaris11_ip_blocks[] =  {  	/* ORDER MATTERS! */ @@ -1026,6 +1223,74 @@ static const struct amdgpu_ip_block_version polaris11_ip_blocks[] =  	},  }; +static const struct amdgpu_ip_block_version polaris11_ip_blocks_vd[] = +{ +	/* ORDER MATTERS! */ +	{ +		.type = AMD_IP_BLOCK_TYPE_COMMON, +		.major = 2, +		.minor = 0, +		.rev = 0, +		.funcs = &vi_common_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_GMC, +		.major = 8, +		.minor = 1, +		.rev = 0, +		.funcs = &gmc_v8_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_IH, +		.major = 3, +		.minor = 1, +		.rev = 0, +		.funcs = &tonga_ih_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_SMC, +		.major = 7, +		.minor = 2, +		.rev = 0, +		.funcs = &amdgpu_pp_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_DCE, +		.major = 11, +		.minor = 2, +		.rev = 0, +		.funcs = &dce_virtual_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_GFX, +		.major = 8, +		.minor = 0, +		.rev = 0, +		.funcs = &gfx_v8_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_SDMA, +		.major = 3, +		.minor = 1, +		.rev = 0, +		.funcs = &sdma_v3_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_UVD, +		.major = 6, +		.minor = 3, +		.rev = 0, +		.funcs = &uvd_v6_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_VCE, +		.major = 3, +		.minor = 4, +		.rev = 0, +		.funcs = &vce_v3_0_ip_funcs, +	}, +}; +  static const struct amdgpu_ip_block_version cz_ip_blocks[] =  {  	/* ORDER MATTERS! */ @@ -1103,34 +1368,142 @@ static const struct amdgpu_ip_block_version cz_ip_blocks[] =  #endif  }; +static const struct amdgpu_ip_block_version cz_ip_blocks_vd[] = +{ +	/* ORDER MATTERS! */ +	{ +		.type = AMD_IP_BLOCK_TYPE_COMMON, +		.major = 2, +		.minor = 0, +		.rev = 0, +		.funcs = &vi_common_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_GMC, +		.major = 8, +		.minor = 0, +		.rev = 0, +		.funcs = &gmc_v8_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_IH, +		.major = 3, +		.minor = 0, +		.rev = 0, +		.funcs = &cz_ih_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_SMC, +		.major = 8, +		.minor = 0, +		.rev = 0, +		.funcs = &amdgpu_pp_ip_funcs +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_DCE, +		.major = 11, +		.minor = 0, +		.rev = 0, +		.funcs = &dce_virtual_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_GFX, +		.major = 8, +		.minor = 0, +		.rev = 0, +		.funcs = &gfx_v8_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_SDMA, +		.major = 3, +		.minor = 0, +		.rev = 0, +		.funcs = &sdma_v3_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_UVD, +		.major = 6, +		.minor = 0, +		.rev = 0, +		.funcs = &uvd_v6_0_ip_funcs, +	}, +	{ +		.type = AMD_IP_BLOCK_TYPE_VCE, +		.major = 3, +		.minor = 0, +		.rev = 0, +		.funcs = &vce_v3_0_ip_funcs, +	}, +#if defined(CONFIG_DRM_AMD_ACP) +	{ +		.type = AMD_IP_BLOCK_TYPE_ACP, +		.major = 2, +		.minor = 2, +		.rev = 0, +		.funcs = &acp_ip_funcs, +	}, +#endif +}; +  int vi_set_ip_blocks(struct amdgpu_device *adev)  { -	switch (adev->asic_type) { -	case CHIP_TOPAZ: -		adev->ip_blocks = topaz_ip_blocks; -		adev->num_ip_blocks = ARRAY_SIZE(topaz_ip_blocks); -		break; -	case CHIP_FIJI: -		adev->ip_blocks = fiji_ip_blocks; -		adev->num_ip_blocks = ARRAY_SIZE(fiji_ip_blocks); -		break; -	case CHIP_TONGA: -		adev->ip_blocks = tonga_ip_blocks; -		adev->num_ip_blocks = ARRAY_SIZE(tonga_ip_blocks); -		break; -	case CHIP_POLARIS11: -	case CHIP_POLARIS10: -		adev->ip_blocks = polaris11_ip_blocks; -		adev->num_ip_blocks = ARRAY_SIZE(polaris11_ip_blocks); -		break; -	case CHIP_CARRIZO: -	case CHIP_STONEY: -		adev->ip_blocks = cz_ip_blocks; -		adev->num_ip_blocks = ARRAY_SIZE(cz_ip_blocks); -		break; -	default: -		/* FIXME: not supported yet */ -		return -EINVAL; +	if (adev->enable_virtual_display) { +		switch (adev->asic_type) { +		case CHIP_TOPAZ: +			adev->ip_blocks = topaz_ip_blocks_vd; +			adev->num_ip_blocks = ARRAY_SIZE(topaz_ip_blocks_vd); +			break; +		case CHIP_FIJI: +			adev->ip_blocks = fiji_ip_blocks_vd; +			adev->num_ip_blocks = ARRAY_SIZE(fiji_ip_blocks_vd); +			break; +		case CHIP_TONGA: +			adev->ip_blocks = tonga_ip_blocks_vd; +			adev->num_ip_blocks = ARRAY_SIZE(tonga_ip_blocks_vd); +			break; +		case CHIP_POLARIS11: +		case CHIP_POLARIS10: +			adev->ip_blocks = polaris11_ip_blocks_vd; +			adev->num_ip_blocks = ARRAY_SIZE(polaris11_ip_blocks_vd); +			break; + +		case CHIP_CARRIZO: +		case CHIP_STONEY: +			adev->ip_blocks = cz_ip_blocks_vd; +			adev->num_ip_blocks = ARRAY_SIZE(cz_ip_blocks_vd); +			break; +		default: +			/* FIXME: not supported yet */ +			return -EINVAL; +		} +	} else { +		switch (adev->asic_type) { +		case CHIP_TOPAZ: +			adev->ip_blocks = topaz_ip_blocks; +			adev->num_ip_blocks = ARRAY_SIZE(topaz_ip_blocks); +			break; +		case CHIP_FIJI: +			adev->ip_blocks = fiji_ip_blocks; +			adev->num_ip_blocks = ARRAY_SIZE(fiji_ip_blocks); +			break; +		case CHIP_TONGA: +			adev->ip_blocks = tonga_ip_blocks; +			adev->num_ip_blocks = ARRAY_SIZE(tonga_ip_blocks); +			break; +		case CHIP_POLARIS11: +		case CHIP_POLARIS10: +			adev->ip_blocks = polaris11_ip_blocks; +			adev->num_ip_blocks = ARRAY_SIZE(polaris11_ip_blocks); +			break; +		case CHIP_CARRIZO: +		case CHIP_STONEY: +			adev->ip_blocks = cz_ip_blocks; +			adev->num_ip_blocks = ARRAY_SIZE(cz_ip_blocks); +			break; +		default: +			/* FIXME: not supported yet */ +			return -EINVAL; +		}  	}  	return 0; @@ -1154,13 +1527,13 @@ 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,  	.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) @@ -1248,8 +1621,17 @@ static int vi_common_early_init(void *handle)  			AMD_CG_SUPPORT_HDP_MGCG |  			AMD_CG_SUPPORT_HDP_LS |  			AMD_CG_SUPPORT_SDMA_MGCG | -			AMD_CG_SUPPORT_SDMA_LS; +			AMD_CG_SUPPORT_SDMA_LS | +			AMD_CG_SUPPORT_VCE_MGCG; +		/* rev0 hardware requires workarounds to support PG */  		adev->pg_flags = 0; +		if (adev->rev_id != 0x00) { +			adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG | +				AMD_PG_SUPPORT_GFX_SMG | +				AMD_PG_SUPPORT_GFX_PIPELINE | +				AMD_PG_SUPPORT_UVD | +				AMD_PG_SUPPORT_VCE; +		}  		adev->external_rev_id = adev->rev_id + 0x1;  		break;  	case CHIP_STONEY: @@ -1267,14 +1649,24 @@ static int vi_common_early_init(void *handle)  			AMD_CG_SUPPORT_HDP_MGCG |  			AMD_CG_SUPPORT_HDP_LS |  			AMD_CG_SUPPORT_SDMA_MGCG | -			AMD_CG_SUPPORT_SDMA_LS; -		adev->external_rev_id = adev->rev_id + 0x1; +			AMD_CG_SUPPORT_SDMA_LS | +			AMD_CG_SUPPORT_VCE_MGCG; +		adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG | +			AMD_PG_SUPPORT_GFX_SMG | +			AMD_PG_SUPPORT_GFX_PIPELINE | +			AMD_PG_SUPPORT_UVD | +			AMD_PG_SUPPORT_VCE; +		adev->external_rev_id = adev->rev_id + 0x61;  		break;  	default:  		/* FIXME: not supported yet */  		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; @@ -1418,6 +1810,63 @@ static void vi_update_rom_medium_grain_clock_gating(struct amdgpu_device *adev,  		WREG32_SMC(ixCGTT_ROM_CLK_CTRL0, data);  } +static int vi_common_set_clockgating_state_by_smu(void *handle, +					   enum amd_clockgating_state state) +{ +	uint32_t msg_id, pp_state; +	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	void *pp_handle = adev->powerplay.pp_handle; + +	if (state == AMD_CG_STATE_UNGATE) +		pp_state = 0; +	else +		pp_state = PP_STATE_CG | PP_STATE_LS; + +	msg_id = PP_CG_MSG_ID(PP_GROUP_SYS, +		       PP_BLOCK_SYS_MC, +		       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS, +		       pp_state); +	amd_set_clockgating_by_smu(pp_handle, msg_id); + +	msg_id = PP_CG_MSG_ID(PP_GROUP_SYS, +		       PP_BLOCK_SYS_SDMA, +		       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS, +		       pp_state); +	amd_set_clockgating_by_smu(pp_handle, msg_id); + +	msg_id = PP_CG_MSG_ID(PP_GROUP_SYS, +		       PP_BLOCK_SYS_HDP, +		       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS, +		       pp_state); +	amd_set_clockgating_by_smu(pp_handle, msg_id); + +	msg_id = PP_CG_MSG_ID(PP_GROUP_SYS, +		       PP_BLOCK_SYS_BIF, +		       PP_STATE_SUPPORT_LS, +		       pp_state); +	amd_set_clockgating_by_smu(pp_handle, msg_id); + +	msg_id = PP_CG_MSG_ID(PP_GROUP_SYS, +		       PP_BLOCK_SYS_BIF, +		       PP_STATE_SUPPORT_CG, +		       pp_state); +	amd_set_clockgating_by_smu(pp_handle, msg_id); + +	msg_id = PP_CG_MSG_ID(PP_GROUP_SYS, +		       PP_BLOCK_SYS_DRM, +		       PP_STATE_SUPPORT_LS, +		       pp_state); +	amd_set_clockgating_by_smu(pp_handle, msg_id); + +	msg_id = PP_CG_MSG_ID(PP_GROUP_SYS, +		       PP_BLOCK_SYS_ROM, +		       PP_STATE_SUPPORT_CG, +		       pp_state); +	amd_set_clockgating_by_smu(pp_handle, msg_id); + +	return 0; +} +  static int vi_common_set_clockgating_state(void *handle,  					   enum amd_clockgating_state state)  { @@ -1443,6 +1892,10 @@ static int vi_common_set_clockgating_state(void *handle,  		vi_update_hdp_light_sleep(adev,  				state == AMD_CG_STATE_GATE ? true : false);  		break; +	case CHIP_TONGA: +	case CHIP_POLARIS10: +	case CHIP_POLARIS11: +		vi_common_set_clockgating_state_by_smu(adev, state);  	default:  		break;  	}  |