diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/vi.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vi.c | 153 |
1 files changed, 134 insertions, 19 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 2adc1c855e85..652e76644c31 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -31,6 +31,7 @@ #include "amdgpu_vce.h" #include "amdgpu_ucode.h" #include "atom.h" +#include "amd_pcie.h" #include "gmc/gmc_8_1_d.h" #include "gmc/gmc_8_1_sh_mask.h" @@ -71,6 +72,7 @@ #include "uvd_v5_0.h" #include "uvd_v6_0.h" #include "vce_v3_0.h" +#include "amdgpu_powerplay.h" /* * Indirect registers accessor @@ -376,6 +378,38 @@ static bool vi_read_disabled_bios(struct amdgpu_device *adev) WREG32_SMC(ixROM_CNTL, rom_cntl); return r; } + +static bool vi_read_bios_from_rom(struct amdgpu_device *adev, + u8 *bios, u32 length_bytes) +{ + u32 *dw_ptr; + unsigned long flags; + u32 i, length_dw; + + if (bios == NULL) + return false; + if (length_bytes == 0) + return false; + /* APU vbios image is part of sbios image */ + if (adev->flags & AMD_IS_APU) + return false; + + dw_ptr = (u32 *)bios; + length_dw = ALIGN(length_bytes, 4) / 4; + /* take the smc lock since we are using the smc index */ + spin_lock_irqsave(&adev->smc_idx_lock, flags); + /* set rom index to 0 */ + WREG32(mmSMC_IND_INDEX_0, ixROM_INDEX); + WREG32(mmSMC_IND_DATA_0, 0); + /* set index to data for continous read */ + WREG32(mmSMC_IND_INDEX_0, ixROM_DATA); + for (i = 0; i < length_dw; i++) + dw_ptr[i] = RREG32(mmSMC_IND_DATA_0); + spin_unlock_irqrestore(&adev->smc_idx_lock, flags); + + return true; +} + static struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = { {mmGB_MACROTILE_MODE7, true}, }; @@ -1019,9 +1053,6 @@ static int vi_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk) static void vi_pcie_gen3_enable(struct amdgpu_device *adev) { - u32 mask; - int ret; - if (pci_is_root_bus(adev->pdev->bus)) return; @@ -1031,11 +1062,8 @@ static void vi_pcie_gen3_enable(struct amdgpu_device *adev) if (adev->flags & AMD_IS_APU) return; - ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask); - if (ret != 0) - return; - - if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80))) + if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 | + CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3))) return; /* todo */ @@ -1098,7 +1126,7 @@ static const struct amdgpu_ip_block_version topaz_ip_blocks[] = .major = 7, .minor = 1, .rev = 0, - .funcs = &iceland_dpm_ip_funcs, + .funcs = &amdgpu_pp_ip_funcs, }, { .type = AMD_IP_BLOCK_TYPE_GFX, @@ -1145,7 +1173,7 @@ static const struct amdgpu_ip_block_version tonga_ip_blocks[] = .major = 7, .minor = 1, .rev = 0, - .funcs = &tonga_dpm_ip_funcs, + .funcs = &amdgpu_pp_ip_funcs, }, { .type = AMD_IP_BLOCK_TYPE_DCE, @@ -1213,7 +1241,7 @@ static const struct amdgpu_ip_block_version fiji_ip_blocks[] = .major = 7, .minor = 1, .rev = 0, - .funcs = &fiji_dpm_ip_funcs, + .funcs = &amdgpu_pp_ip_funcs, }, { .type = AMD_IP_BLOCK_TYPE_DCE, @@ -1281,7 +1309,7 @@ static const struct amdgpu_ip_block_version cz_ip_blocks[] = .major = 8, .minor = 0, .rev = 0, - .funcs = &cz_dpm_ip_funcs, + .funcs = &amdgpu_pp_ip_funcs }, { .type = AMD_IP_BLOCK_TYPE_DCE, @@ -1354,20 +1382,18 @@ int vi_set_ip_blocks(struct amdgpu_device *adev) static uint32_t vi_get_rev_id(struct amdgpu_device *adev) { - if (adev->asic_type == CHIP_TOPAZ) - return (RREG32(mmPCIE_EFUSE4) & PCIE_EFUSE4__STRAP_BIF_ATI_REV_ID_MASK) - >> PCIE_EFUSE4__STRAP_BIF_ATI_REV_ID__SHIFT; - else if (adev->flags & AMD_IS_APU) + if (adev->flags & AMD_IS_APU) return (RREG32_SMC(ATI_REV_ID_FUSE_MACRO__ADDRESS) & ATI_REV_ID_FUSE_MACRO__MASK) >> ATI_REV_ID_FUSE_MACRO__SHIFT; else - return (RREG32(mmCC_DRM_ID_STRAPS) & CC_DRM_ID_STRAPS__ATI_REV_ID_MASK) - >> CC_DRM_ID_STRAPS__ATI_REV_ID__SHIFT; + return (RREG32(mmPCIE_EFUSE4) & PCIE_EFUSE4__STRAP_BIF_ATI_REV_ID_MASK) + >> PCIE_EFUSE4__STRAP_BIF_ATI_REV_ID__SHIFT; } 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, .read_register = &vi_read_register, .reset = &vi_asic_reset, .set_vga_state = &vi_vga_set_state, @@ -1416,7 +1442,8 @@ static int vi_common_early_init(void *handle) break; case CHIP_FIJI: adev->has_uvd = true; - adev->cg_flags = 0; + adev->cg_flags = AMDGPU_CG_SUPPORT_UVD_MGCG | + AMDGPU_CG_SUPPORT_VCE_MGCG; adev->pg_flags = 0; adev->external_rev_id = adev->rev_id + 0x3c; break; @@ -1442,6 +1469,8 @@ static int vi_common_early_init(void *handle) if (amdgpu_smc_load_fw && smc_enabled) adev->firmware.smu_load = true; + amdgpu_get_pcie_info(adev); + return 0; } @@ -1515,9 +1544,95 @@ static int vi_common_soft_reset(void *handle) return 0; } +static void fiji_update_bif_medium_grain_light_sleep(struct amdgpu_device *adev, + bool enable) +{ + uint32_t temp, data; + + temp = data = RREG32_PCIE(ixPCIE_CNTL2); + + if (enable) + data |= PCIE_CNTL2__SLV_MEM_LS_EN_MASK | + PCIE_CNTL2__MST_MEM_LS_EN_MASK | + PCIE_CNTL2__REPLAY_MEM_LS_EN_MASK; + else + data &= ~(PCIE_CNTL2__SLV_MEM_LS_EN_MASK | + PCIE_CNTL2__MST_MEM_LS_EN_MASK | + PCIE_CNTL2__REPLAY_MEM_LS_EN_MASK); + + if (temp != data) + WREG32_PCIE(ixPCIE_CNTL2, data); +} + +static void fiji_update_hdp_medium_grain_clock_gating(struct amdgpu_device *adev, + bool enable) +{ + uint32_t temp, data; + + temp = data = RREG32(mmHDP_HOST_PATH_CNTL); + + if (enable) + data &= ~HDP_HOST_PATH_CNTL__CLOCK_GATING_DIS_MASK; + else + data |= HDP_HOST_PATH_CNTL__CLOCK_GATING_DIS_MASK; + + if (temp != data) + WREG32(mmHDP_HOST_PATH_CNTL, data); +} + +static void fiji_update_hdp_light_sleep(struct amdgpu_device *adev, + bool enable) +{ + uint32_t temp, data; + + temp = data = RREG32(mmHDP_MEM_POWER_LS); + + if (enable) + data |= HDP_MEM_POWER_LS__LS_ENABLE_MASK; + else + data &= ~HDP_MEM_POWER_LS__LS_ENABLE_MASK; + + if (temp != data) + WREG32(mmHDP_MEM_POWER_LS, data); +} + +static void fiji_update_rom_medium_grain_clock_gating(struct amdgpu_device *adev, + bool enable) +{ + uint32_t temp, data; + + temp = data = RREG32_SMC(ixCGTT_ROM_CLK_CTRL0); + + if (enable) + data &= ~(CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE0_MASK | + CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE1_MASK); + else + data |= CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE0_MASK | + CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE1_MASK; + + if (temp != data) + WREG32_SMC(ixCGTT_ROM_CLK_CTRL0, data); +} + static int vi_common_set_clockgating_state(void *handle, enum amd_clockgating_state state) { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + switch (adev->asic_type) { + case CHIP_FIJI: + fiji_update_bif_medium_grain_light_sleep(adev, + state == AMD_CG_STATE_GATE ? true : false); + fiji_update_hdp_medium_grain_clock_gating(adev, + state == AMD_CG_STATE_GATE ? true : false); + fiji_update_hdp_light_sleep(adev, + state == AMD_CG_STATE_GATE ? true : false); + fiji_update_rom_medium_grain_clock_gating(adev, + state == AMD_CG_STATE_GATE ? true : false); + break; + default: + break; + } return 0; } |