diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/nv.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/nv.c | 156 | 
1 files changed, 152 insertions, 4 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c index 8eeba8096493..ac02dd707c44 100644 --- a/drivers/gpu/drm/amd/amdgpu/nv.c +++ b/drivers/gpu/drm/amd/amdgpu/nv.c @@ -49,6 +49,7 @@  #include "gfxhub_v2_0.h"  #include "mmhub_v2_0.h"  #include "nbio_v2_3.h" +#include "nbio_v7_2.h"  #include "nv.h"  #include "navi10_ih.h"  #include "gfx_v10_0.h" @@ -95,6 +96,21 @@ static u64 nv_pcie_rreg64(struct amdgpu_device *adev, u32 reg)  	return amdgpu_device_indirect_rreg64(adev, address, data, reg);  } +static u32 nv_pcie_port_rreg(struct amdgpu_device *adev, u32 reg) +{ +	unsigned long flags, address, data; +	u32 r; +	address = adev->nbio.funcs->get_pcie_port_index_offset(adev); +	data = adev->nbio.funcs->get_pcie_port_data_offset(adev); + +	spin_lock_irqsave(&adev->pcie_idx_lock, flags); +	WREG32(address, reg * 4); +	(void)RREG32(address); +	r = RREG32(data); +	spin_unlock_irqrestore(&adev->pcie_idx_lock, flags); +	return r; +} +  static void nv_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v)  {  	unsigned long address, data; @@ -105,6 +121,21 @@ static void nv_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v)  	amdgpu_device_indirect_wreg64(adev, address, data, reg, v);  } +static void nv_pcie_port_wreg(struct amdgpu_device *adev, u32 reg, u32 v) +{ +	unsigned long flags, address, data; + +	address = adev->nbio.funcs->get_pcie_port_index_offset(adev); +	data = adev->nbio.funcs->get_pcie_port_data_offset(adev); + +	spin_lock_irqsave(&adev->pcie_idx_lock, flags); +	WREG32(address, reg * 4); +	(void)RREG32(address); +	WREG32(data, v); +	(void)RREG32(data); +	spin_unlock_irqrestore(&adev->pcie_idx_lock, flags); +} +  static u32 nv_didt_rreg(struct amdgpu_device *adev, u32 reg)  {  	unsigned long flags, address, data; @@ -254,7 +285,8 @@ static int nv_read_register(struct amdgpu_device *adev, u32 se_num,  	*value = 0;  	for (i = 0; i < ARRAY_SIZE(nv_allowed_read_registers); i++) {  		en = &nv_allowed_read_registers[i]; -		if (reg_offset != +		if ((i == 7 && (adev->sdma.num_instances == 1)) || /* some asics don't have SDMA1 */ +		    reg_offset !=  		    (adev->reg_offset[en->hwip][en->inst][en->seg] + en->reg_offset))  			continue; @@ -443,6 +475,12 @@ legacy_init:  	case CHIP_NAVY_FLOUNDER:  		sienna_cichlid_reg_base_init(adev);  		break; +	case CHIP_VANGOGH: +		vangogh_reg_base_init(adev); +		break; +	case CHIP_DIMGREY_CAVEFISH: +		dimgrey_cavefish_reg_base_init(adev); +		break;  	default:  		return -EINVAL;  	} @@ -468,8 +506,13 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)  {  	int r; -	adev->nbio.funcs = &nbio_v2_3_funcs; -	adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg; +	if (adev->flags & AMD_IS_APU) { +		adev->nbio.funcs = &nbio_v7_2_funcs; +		adev->nbio.hdp_flush_reg = &nbio_v7_2_hdp_flush_reg; +	} else { +		adev->nbio.funcs = &nbio_v2_3_funcs; +		adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg; +	}  	if (adev->asic_type == CHIP_SIENNA_CICHLID)  		adev->gmc.xgmi.supported = true; @@ -535,7 +578,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)  		if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))  			amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);  		if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP && -		    is_support_sw_smu(adev) && !amdgpu_sriov_vf(adev)) +		    is_support_sw_smu(adev))  			amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);  		if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))  			amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); @@ -575,6 +618,44 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)  		    is_support_sw_smu(adev))  			amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);  		break; +	case CHIP_VANGOGH: +		amdgpu_device_ip_block_add(adev, &nv_common_ip_block); +		amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); +		amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); +		if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) +			amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); +		amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); +		if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) +			amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); +#if defined(CONFIG_DRM_AMD_DC) +		else if (amdgpu_device_has_dc_support(adev)) +			amdgpu_device_ip_block_add(adev, &dm_ip_block); +#endif +		amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); +		amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block); +		amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); +		amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); +		break; +	case CHIP_DIMGREY_CAVEFISH: +		amdgpu_device_ip_block_add(adev, &nv_common_ip_block); +		amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); +		amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); +		if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) +			amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); +		if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP && +		    is_support_sw_smu(adev)) +			amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); +		if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) +			amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); +#if defined(CONFIG_DRM_AMD_DC) +                else if (amdgpu_device_has_dc_support(adev)) +                        amdgpu_device_ip_block_add(adev, &dm_ip_block); +#endif +		amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); +		amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block); +		amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); +		amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); +		break;  	default:  		return -EINVAL;  	} @@ -671,6 +752,29 @@ static void nv_pre_asic_init(struct amdgpu_device *adev)  {  } +static int nv_update_umd_stable_pstate(struct amdgpu_device *adev, +				       bool enter) +{ +	if (enter) +		amdgpu_gfx_rlc_enter_safe_mode(adev); +	else +		amdgpu_gfx_rlc_exit_safe_mode(adev); + +	if (adev->gfx.funcs->update_perfmon_mgcg) +		adev->gfx.funcs->update_perfmon_mgcg(adev, !enter); + +	/* +	 * The ASPM function is not fully enabled and verified on +	 * Navi yet. Temporarily skip this until ASPM enabled. +	 */ +#if 0 +	if (adev->nbio.funcs->enable_aspm) +		adev->nbio.funcs->enable_aspm(adev, !enter); +#endif + +	return 0; +} +  static const struct amdgpu_asic_funcs nv_asic_funcs =  {  	.read_disabled_bios = &nv_read_disabled_bios, @@ -691,6 +795,7 @@ static const struct amdgpu_asic_funcs nv_asic_funcs =  	.get_pcie_replay_count = &nv_get_pcie_replay_count,  	.supports_baco = &nv_asic_supports_baco,  	.pre_asic_init = &nv_pre_asic_init, +	.update_umd_stable_pstate = &nv_update_umd_stable_pstate,  };  static int nv_common_early_init(void *handle) @@ -706,6 +811,8 @@ static int nv_common_early_init(void *handle)  	adev->pcie_wreg = &nv_pcie_wreg;  	adev->pcie_rreg64 = &nv_pcie_rreg64;  	adev->pcie_wreg64 = &nv_pcie_wreg64; +	adev->pciep_rreg = &nv_pcie_port_rreg; +	adev->pciep_wreg = &nv_pcie_port_wreg;  	/* TODO: will add them during VCN v2 implementation */  	adev->uvd_ctx_rreg = NULL; @@ -833,6 +940,46 @@ static int nv_common_early_init(void *handle)  		adev->external_rev_id = adev->rev_id + 0x32;  		break; +	case CHIP_VANGOGH: +		adev->apu_flags |= AMD_APU_IS_VANGOGH; +		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | +			AMD_CG_SUPPORT_GFX_MGLS | +			AMD_CG_SUPPORT_GFX_CP_LS | +			AMD_CG_SUPPORT_GFX_RLC_LS | +			AMD_CG_SUPPORT_GFX_CGCG | +			AMD_CG_SUPPORT_GFX_CGLS | +			AMD_CG_SUPPORT_GFX_3D_CGCG | +			AMD_CG_SUPPORT_GFX_3D_CGLS | +			AMD_CG_SUPPORT_MC_MGCG | +			AMD_CG_SUPPORT_MC_LS | +			AMD_CG_SUPPORT_GFX_FGCG | +			AMD_CG_SUPPORT_VCN_MGCG | +			AMD_CG_SUPPORT_JPEG_MGCG; +		adev->pg_flags = AMD_PG_SUPPORT_GFX_PG | +			AMD_PG_SUPPORT_VCN | +			AMD_PG_SUPPORT_VCN_DPG | +			AMD_PG_SUPPORT_JPEG; +		if (adev->apu_flags & AMD_APU_IS_VANGOGH) +			adev->external_rev_id = adev->rev_id + 0x01; +		break; +	case CHIP_DIMGREY_CAVEFISH: +		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | +			AMD_CG_SUPPORT_GFX_CGCG | +			AMD_CG_SUPPORT_GFX_3D_CGCG | +			AMD_CG_SUPPORT_VCN_MGCG | +			AMD_CG_SUPPORT_JPEG_MGCG | +			AMD_CG_SUPPORT_MC_MGCG | +			AMD_CG_SUPPORT_MC_LS | +			AMD_CG_SUPPORT_HDP_MGCG | +			AMD_CG_SUPPORT_HDP_LS | +			AMD_CG_SUPPORT_IH_CG; +		adev->pg_flags = AMD_PG_SUPPORT_VCN | +			AMD_PG_SUPPORT_VCN_DPG | +			AMD_PG_SUPPORT_JPEG | +			AMD_PG_SUPPORT_ATHUB | +			AMD_PG_SUPPORT_MMHUB; +		adev->external_rev_id = adev->rev_id + 0x3c; +		break;  	default:  		/* FIXME: not supported yet */  		return -EINVAL; @@ -1060,6 +1207,7 @@ static int nv_common_set_clockgating_state(void *handle,  	case CHIP_NAVI12:  	case CHIP_SIENNA_CICHLID:  	case CHIP_NAVY_FLOUNDER: +	case CHIP_DIMGREY_CAVEFISH:  		adev->nbio.funcs->update_medium_grain_clock_gating(adev,  				state == AMD_CG_STATE_GATE);  		adev->nbio.funcs->update_medium_grain_light_sleep(adev, | 
