Merge tag 'amd-drm-next-5.11-2020-11-05' of git://people.freedesktop.org/~agd5f/linux into drm-next
amd-drm-next-5.11-2020-11-05: amdgpu: - Add initial support for Vangogh - Add support for Green Sardine - Add initial support for Dimgrey Cavefish - Scatter/Gather display support for Renoir - Updates for Sienna Cichlid - Updates for Navy Flounder - SMU7 power improvements - Modifier support for gfx9+ - CI BACO fixes - Arcturus SMU fixes - Lots of code cleanups - DC fixes - Kernel doc fixes - Add more GPU HW client information to page fault error logging - MPO clock tuning for RV - FP fixes for DCN3 on ARM and PPC radeon: - Expose voltage via hwmon on Sumo APUs amdkfd: - Fix unique id handling - Misc fixes From: Alex Deucher <alexdeucher@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20201105222749.201798-1-alexander.deucher@amd.com
This commit is contained in:
commit
5b8c596976
|
@ -934,7 +934,7 @@ M: Evan Quan <evan.quan@amd.com>
|
|||
L: amd-gfx@lists.freedesktop.org
|
||||
S: Supported
|
||||
T: git git://people.freedesktop.org/~agd5f/linux
|
||||
F: drivers/gpu/drm/amd/powerplay/
|
||||
F: drivers/gpu/drm/amd/pm/powerplay/
|
||||
|
||||
AMD SEATTLE DEVICE TREE SUPPORT
|
||||
M: Brijesh Singh <brijeshkumar.singh@amd.com>
|
||||
|
|
|
@ -55,7 +55,8 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
|
|||
amdgpu_vf_error.o amdgpu_sched.o amdgpu_debugfs.o amdgpu_ids.o \
|
||||
amdgpu_gmc.o amdgpu_mmhub.o amdgpu_xgmi.o amdgpu_csa.o amdgpu_ras.o amdgpu_vm_cpu.o \
|
||||
amdgpu_vm_sdma.o amdgpu_discovery.o amdgpu_ras_eeprom.o amdgpu_nbio.o \
|
||||
amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o amdgpu_rap.o
|
||||
amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o amdgpu_rap.o \
|
||||
amdgpu_fw_attestation.o
|
||||
|
||||
amdgpu-$(CONFIG_PERF_EVENTS) += amdgpu_pmu.o
|
||||
|
||||
|
@ -69,7 +70,8 @@ amdgpu-$(CONFIG_DRM_AMDGPU_SI)+= si.o gmc_v6_0.o gfx_v6_0.o si_ih.o si_dma.o dce
|
|||
amdgpu-y += \
|
||||
vi.o mxgpu_vi.o nbio_v6_1.o soc15.o emu_soc.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o \
|
||||
vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o navi10_reg_init.o navi14_reg_init.o \
|
||||
arct_reg_init.o navi12_reg_init.o mxgpu_nv.o sienna_cichlid_reg_init.o
|
||||
arct_reg_init.o navi12_reg_init.o mxgpu_nv.o sienna_cichlid_reg_init.o vangogh_reg_init.o \
|
||||
nbio_v7_2.o dimgrey_cavefish_reg_init.o
|
||||
|
||||
# add DF block
|
||||
amdgpu-y += \
|
||||
|
@ -81,7 +83,7 @@ amdgpu-y += \
|
|||
gmc_v7_0.o \
|
||||
gmc_v8_0.o \
|
||||
gfxhub_v1_0.o mmhub_v1_0.o gmc_v9_0.o gfxhub_v1_1.o mmhub_v9_4.o \
|
||||
gfxhub_v2_0.o mmhub_v2_0.o gmc_v10_0.o gfxhub_v2_1.o
|
||||
gfxhub_v2_0.o mmhub_v2_0.o gmc_v10_0.o gfxhub_v2_1.o mmhub_v2_3.o
|
||||
|
||||
# add UMC block
|
||||
amdgpu-y += \
|
||||
|
|
|
@ -623,6 +623,8 @@ struct amdgpu_asic_funcs {
|
|||
bool (*supports_baco)(struct amdgpu_device *adev);
|
||||
/* pre asic_init quirks */
|
||||
void (*pre_asic_init)(struct amdgpu_device *adev);
|
||||
/* enter/exit umd stable pstate */
|
||||
int (*update_umd_stable_pstate)(struct amdgpu_device *adev, bool enter);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -723,6 +725,45 @@ struct amd_powerplay {
|
|||
const struct amd_pm_funcs *pp_funcs;
|
||||
};
|
||||
|
||||
/* polaris10 kickers */
|
||||
#define ASICID_IS_P20(did, rid) (((did == 0x67DF) && \
|
||||
((rid == 0xE3) || \
|
||||
(rid == 0xE4) || \
|
||||
(rid == 0xE5) || \
|
||||
(rid == 0xE7) || \
|
||||
(rid == 0xEF))) || \
|
||||
((did == 0x6FDF) && \
|
||||
((rid == 0xE7) || \
|
||||
(rid == 0xEF) || \
|
||||
(rid == 0xFF))))
|
||||
|
||||
#define ASICID_IS_P30(did, rid) ((did == 0x67DF) && \
|
||||
((rid == 0xE1) || \
|
||||
(rid == 0xF7)))
|
||||
|
||||
/* polaris11 kickers */
|
||||
#define ASICID_IS_P21(did, rid) (((did == 0x67EF) && \
|
||||
((rid == 0xE0) || \
|
||||
(rid == 0xE5))) || \
|
||||
((did == 0x67FF) && \
|
||||
((rid == 0xCF) || \
|
||||
(rid == 0xEF) || \
|
||||
(rid == 0xFF))))
|
||||
|
||||
#define ASICID_IS_P31(did, rid) ((did == 0x67EF) && \
|
||||
((rid == 0xE2)))
|
||||
|
||||
/* polaris12 kickers */
|
||||
#define ASICID_IS_P23(did, rid) (((did == 0x6987) && \
|
||||
((rid == 0xC0) || \
|
||||
(rid == 0xC1) || \
|
||||
(rid == 0xC3) || \
|
||||
(rid == 0xC7))) || \
|
||||
((did == 0x6981) && \
|
||||
((rid == 0x00) || \
|
||||
(rid == 0x01) || \
|
||||
(rid == 0x10))))
|
||||
|
||||
#define AMDGPU_RESET_MAGIC_NUM 64
|
||||
#define AMDGPU_MAX_DF_PERFMONS 4
|
||||
struct amdgpu_device {
|
||||
|
@ -1165,6 +1206,8 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
|
|||
#define amdgpu_asic_get_pcie_replay_count(adev) ((adev)->asic_funcs->get_pcie_replay_count((adev)))
|
||||
#define amdgpu_asic_supports_baco(adev) (adev)->asic_funcs->supports_baco((adev))
|
||||
#define amdgpu_asic_pre_asic_init(adev) (adev)->asic_funcs->pre_asic_init((adev))
|
||||
#define amdgpu_asic_update_umd_stable_pstate(adev, enter) \
|
||||
((adev)->asic_funcs->update_umd_stable_pstate ? (adev)->asic_funcs->update_umd_stable_pstate((adev), (enter)) : 0)
|
||||
|
||||
#define amdgpu_inc_vram_lost(adev) atomic_inc(&((adev)->vram_lost_counter));
|
||||
|
||||
|
@ -1294,19 +1337,6 @@ bool amdgpu_device_load_pci_state(struct pci_dev *pdev);
|
|||
|
||||
#include "amdgpu_object.h"
|
||||
|
||||
/* used by df_v3_6.c and amdgpu_pmu.c */
|
||||
#define AMDGPU_PMU_ATTR(_name, _object) \
|
||||
static ssize_t \
|
||||
_name##_show(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
char *page) \
|
||||
{ \
|
||||
BUILD_BUG_ON(sizeof(_object) >= PAGE_SIZE - 1); \
|
||||
return sprintf(page, _object "\n"); \
|
||||
} \
|
||||
\
|
||||
static struct device_attribute pmu_attr_##_name = __ATTR_RO(_name)
|
||||
|
||||
static inline bool amdgpu_is_tmz(struct amdgpu_device *adev)
|
||||
{
|
||||
return adev->gmc.tmz_enabled;
|
||||
|
|
|
@ -36,17 +36,17 @@
|
|||
|
||||
#include "acp_gfx_if.h"
|
||||
|
||||
#define ACP_TILE_ON_MASK 0x03
|
||||
#define ACP_TILE_OFF_MASK 0x02
|
||||
#define ACP_TILE_ON_RETAIN_REG_MASK 0x1f
|
||||
#define ACP_TILE_OFF_RETAIN_REG_MASK 0x20
|
||||
#define ACP_TILE_ON_MASK 0x03
|
||||
#define ACP_TILE_OFF_MASK 0x02
|
||||
#define ACP_TILE_ON_RETAIN_REG_MASK 0x1f
|
||||
#define ACP_TILE_OFF_RETAIN_REG_MASK 0x20
|
||||
|
||||
#define ACP_TILE_P1_MASK 0x3e
|
||||
#define ACP_TILE_P2_MASK 0x3d
|
||||
#define ACP_TILE_DSP0_MASK 0x3b
|
||||
#define ACP_TILE_DSP1_MASK 0x37
|
||||
#define ACP_TILE_P1_MASK 0x3e
|
||||
#define ACP_TILE_P2_MASK 0x3d
|
||||
#define ACP_TILE_DSP0_MASK 0x3b
|
||||
#define ACP_TILE_DSP1_MASK 0x37
|
||||
|
||||
#define ACP_TILE_DSP2_MASK 0x2f
|
||||
#define ACP_TILE_DSP2_MASK 0x2f
|
||||
|
||||
#define ACP_DMA_REGS_END 0x146c0
|
||||
#define ACP_I2S_PLAY_REGS_START 0x14840
|
||||
|
@ -75,8 +75,8 @@
|
|||
#define mmACP_CONTROL 0x5131
|
||||
#define mmACP_STATUS 0x5133
|
||||
#define mmACP_SOFT_RESET 0x5134
|
||||
#define ACP_CONTROL__ClkEn_MASK 0x1
|
||||
#define ACP_SOFT_RESET__SoftResetAud_MASK 0x100
|
||||
#define ACP_CONTROL__ClkEn_MASK 0x1
|
||||
#define ACP_SOFT_RESET__SoftResetAud_MASK 0x100
|
||||
#define ACP_SOFT_RESET__SoftResetAudDone_MASK 0x1000000
|
||||
#define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF
|
||||
#define ACP_SOFT_RESET_DONE_TIME_OUT_VALUE 0x000000FF
|
||||
|
|
|
@ -390,23 +390,17 @@ void amdgpu_amdkfd_get_local_mem_info(struct kgd_dev *kgd,
|
|||
struct kfd_local_mem_info *mem_info)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
|
||||
uint64_t address_mask = adev->dev->dma_mask ? ~*adev->dev->dma_mask :
|
||||
~((1ULL << 32) - 1);
|
||||
resource_size_t aper_limit = adev->gmc.aper_base + adev->gmc.aper_size;
|
||||
|
||||
memset(mem_info, 0, sizeof(*mem_info));
|
||||
if (!(adev->gmc.aper_base & address_mask || aper_limit & address_mask)) {
|
||||
mem_info->local_mem_size_public = adev->gmc.visible_vram_size;
|
||||
mem_info->local_mem_size_private = adev->gmc.real_vram_size -
|
||||
adev->gmc.visible_vram_size;
|
||||
} else {
|
||||
mem_info->local_mem_size_public = 0;
|
||||
mem_info->local_mem_size_private = adev->gmc.real_vram_size;
|
||||
}
|
||||
|
||||
mem_info->local_mem_size_public = adev->gmc.visible_vram_size;
|
||||
mem_info->local_mem_size_private = adev->gmc.real_vram_size -
|
||||
adev->gmc.visible_vram_size;
|
||||
|
||||
mem_info->vram_width = adev->gmc.vram_width;
|
||||
|
||||
pr_debug("Address base: %pap limit %pap public 0x%llx private 0x%llx\n",
|
||||
&adev->gmc.aper_base, &aper_limit,
|
||||
pr_debug("Address base: %pap public 0x%llx private 0x%llx\n",
|
||||
&adev->gmc.aper_base,
|
||||
mem_info->local_mem_size_public,
|
||||
mem_info->local_mem_size_private);
|
||||
|
||||
|
@ -648,6 +642,13 @@ void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
|
||||
|
||||
/* Temp workaround to fix the soft hang observed in certain compute
|
||||
* applications if GFXOFF is enabled.
|
||||
*/
|
||||
if (adev->asic_type == CHIP_SIENNA_CICHLID) {
|
||||
pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled");
|
||||
amdgpu_gfx_off_ctrl(adev, idle);
|
||||
}
|
||||
amdgpu_dpm_switch_power_profile(adev,
|
||||
PP_SMC_POWER_PROFILE_COMPUTE,
|
||||
!idle);
|
||||
|
|
|
@ -304,4 +304,5 @@ const struct kfd2kgd_calls arcturus_kfd2kgd = {
|
|||
kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
|
||||
.set_vm_context_page_table_base =
|
||||
kgd_gfx_v9_set_vm_context_page_table_base,
|
||||
.get_cu_occupancy = kgd_gfx_v9_get_cu_occupancy
|
||||
};
|
||||
|
|
|
@ -799,7 +799,7 @@ static void get_wave_count(struct amdgpu_device *adev, int queue_idx,
|
|||
*
|
||||
* Reading registers referenced above involves programming GRBM appropriately
|
||||
*/
|
||||
static void kgd_gfx_v9_get_cu_occupancy(struct kgd_dev *kgd, int pasid,
|
||||
void kgd_gfx_v9_get_cu_occupancy(struct kgd_dev *kgd, int pasid,
|
||||
int *pasid_wave_cnt, int *max_waves_per_cu)
|
||||
{
|
||||
int qidx;
|
||||
|
|
|
@ -63,3 +63,5 @@ bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd,
|
|||
|
||||
void kgd_gfx_v9_set_vm_context_page_table_base(struct kgd_dev *kgd,
|
||||
uint32_t vmid, uint64_t page_table_base);
|
||||
void kgd_gfx_v9_get_cu_occupancy(struct kgd_dev *kgd, int pasid,
|
||||
int *pasid_wave_cnt, int *max_waves_per_cu);
|
||||
|
|
|
@ -239,8 +239,7 @@ static int amdgpu_amdkfd_remove_eviction_fence(struct amdgpu_bo *bo,
|
|||
if (!old)
|
||||
return 0;
|
||||
|
||||
new = kmalloc(offsetof(typeof(*new), shared[old->shared_max]),
|
||||
GFP_KERNEL);
|
||||
new = kmalloc(struct_size(new, shared, old->shared_max), GFP_KERNEL);
|
||||
if (!new)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -1115,19 +1114,19 @@ void amdgpu_amdkfd_gpuvm_destroy_process_vm(struct kgd_dev *kgd, void *vm)
|
|||
void amdgpu_amdkfd_gpuvm_release_process_vm(struct kgd_dev *kgd, void *vm)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
struct amdgpu_vm *avm = (struct amdgpu_vm *)vm;
|
||||
struct amdgpu_vm *avm = (struct amdgpu_vm *)vm;
|
||||
|
||||
if (WARN_ON(!kgd || !vm))
|
||||
return;
|
||||
return;
|
||||
|
||||
pr_debug("Releasing process vm %p\n", vm);
|
||||
pr_debug("Releasing process vm %p\n", vm);
|
||||
|
||||
/* The original pasid of amdgpu vm has already been
|
||||
* released during making a amdgpu vm to a compute vm
|
||||
* The current pasid is managed by kfd and will be
|
||||
* released on kfd process destroy. Set amdgpu pasid
|
||||
* to 0 to avoid duplicate release.
|
||||
*/
|
||||
/* The original pasid of amdgpu vm has already been
|
||||
* released during making a amdgpu vm to a compute vm
|
||||
* The current pasid is managed by kfd and will be
|
||||
* released on kfd process destroy. Set amdgpu pasid
|
||||
* to 0 to avoid duplicate release.
|
||||
*/
|
||||
amdgpu_vm_release_compute(adev, avm);
|
||||
}
|
||||
|
||||
|
@ -1288,7 +1287,7 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
|
|||
struct ttm_validate_buffer *bo_list_entry;
|
||||
unsigned int mapped_to_gpu_memory;
|
||||
int ret;
|
||||
bool is_imported = 0;
|
||||
bool is_imported = false;
|
||||
|
||||
mutex_lock(&mem->lock);
|
||||
mapped_to_gpu_memory = mem->mapped_to_gpu_memory;
|
||||
|
@ -1695,7 +1694,7 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct kgd_dev *kgd,
|
|||
|
||||
INIT_LIST_HEAD(&(*mem)->bo_va_list);
|
||||
mutex_init(&(*mem)->lock);
|
||||
|
||||
|
||||
(*mem)->alloc_flags =
|
||||
((bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) ?
|
||||
KFD_IOC_ALLOC_MEM_FLAGS_VRAM : KFD_IOC_ALLOC_MEM_FLAGS_GTT)
|
||||
|
|
|
@ -1401,7 +1401,7 @@ static ATOM_VOLTAGE_OBJECT_V3 *amdgpu_atombios_lookup_voltage_object_v3(ATOM_VOL
|
|||
{
|
||||
u32 size = le16_to_cpu(v3->sHeader.usStructureSize);
|
||||
u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V3_1, asVoltageObj[0]);
|
||||
u8 *start = (u8*)v3;
|
||||
u8 *start = (u8 *)v3;
|
||||
|
||||
while (offset < size) {
|
||||
ATOM_VOLTAGE_OBJECT_V3 *vo = (ATOM_VOLTAGE_OBJECT_V3 *)(start + offset);
|
||||
|
|
|
@ -70,7 +70,7 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
|
|||
struct atom_context *ctx = adev->mode_info.atom_context;
|
||||
int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
|
||||
vram_usagebyfirmware);
|
||||
struct vram_usagebyfirmware_v2_1 * firmware_usage;
|
||||
struct vram_usagebyfirmware_v2_1 *firmware_usage;
|
||||
uint32_t start_addr, size;
|
||||
uint16_t data_offset;
|
||||
int usage_bytes = 0;
|
||||
|
@ -149,6 +149,10 @@ static int convert_atom_mem_type_to_vram_type(struct amdgpu_device *adev,
|
|||
case LpDdr4MemType:
|
||||
vram_type = AMDGPU_VRAM_TYPE_DDR4;
|
||||
break;
|
||||
case Ddr5MemType:
|
||||
case LpDdr5MemType:
|
||||
vram_type = AMDGPU_VRAM_TYPE_DDR5;
|
||||
break;
|
||||
default:
|
||||
vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
|
||||
break;
|
||||
|
@ -544,6 +548,7 @@ int amdgpu_mem_train_support(struct amdgpu_device *adev)
|
|||
case HW_REV(11, 0, 5):
|
||||
case HW_REV(11, 0, 7):
|
||||
case HW_REV(11, 0, 11):
|
||||
case HW_REV(11, 0, 12):
|
||||
ret = 1;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -352,17 +352,10 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
|
|||
break;
|
||||
case CHIP_POLARIS11:
|
||||
if (type == CGS_UCODE_ID_SMU) {
|
||||
if (((adev->pdev->device == 0x67ef) &&
|
||||
((adev->pdev->revision == 0xe0) ||
|
||||
(adev->pdev->revision == 0xe5))) ||
|
||||
((adev->pdev->device == 0x67ff) &&
|
||||
((adev->pdev->revision == 0xcf) ||
|
||||
(adev->pdev->revision == 0xef) ||
|
||||
(adev->pdev->revision == 0xff)))) {
|
||||
if (ASICID_IS_P21(adev->pdev->device, adev->pdev->revision)) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "amdgpu/polaris11_k_smc.bin");
|
||||
} else if ((adev->pdev->device == 0x67ef) &&
|
||||
(adev->pdev->revision == 0xe2)) {
|
||||
} else if (ASICID_IS_P31(adev->pdev->device, adev->pdev->revision)) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "amdgpu/polaris11_k2_smc.bin");
|
||||
} else {
|
||||
|
@ -374,21 +367,10 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
|
|||
break;
|
||||
case CHIP_POLARIS10:
|
||||
if (type == CGS_UCODE_ID_SMU) {
|
||||
if (((adev->pdev->device == 0x67df) &&
|
||||
((adev->pdev->revision == 0xe0) ||
|
||||
(adev->pdev->revision == 0xe3) ||
|
||||
(adev->pdev->revision == 0xe4) ||
|
||||
(adev->pdev->revision == 0xe5) ||
|
||||
(adev->pdev->revision == 0xe7) ||
|
||||
(adev->pdev->revision == 0xef))) ||
|
||||
((adev->pdev->device == 0x6fdf) &&
|
||||
((adev->pdev->revision == 0xef) ||
|
||||
(adev->pdev->revision == 0xff)))) {
|
||||
if (ASICID_IS_P20(adev->pdev->device, adev->pdev->revision)) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "amdgpu/polaris10_k_smc.bin");
|
||||
} else if ((adev->pdev->device == 0x67df) &&
|
||||
((adev->pdev->revision == 0xe1) ||
|
||||
(adev->pdev->revision == 0xf7))) {
|
||||
} else if (ASICID_IS_P30(adev->pdev->device, adev->pdev->revision)) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "amdgpu/polaris10_k2_smc.bin");
|
||||
} else {
|
||||
|
@ -399,13 +381,7 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
|
|||
}
|
||||
break;
|
||||
case CHIP_POLARIS12:
|
||||
if (((adev->pdev->device == 0x6987) &&
|
||||
((adev->pdev->revision == 0xc0) ||
|
||||
(adev->pdev->revision == 0xc3))) ||
|
||||
((adev->pdev->device == 0x6981) &&
|
||||
((adev->pdev->revision == 0x00) ||
|
||||
(adev->pdev->revision == 0x01) ||
|
||||
(adev->pdev->revision == 0x10)))) {
|
||||
if (ASICID_IS_P23(adev->pdev->device, adev->pdev->revision)) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "amdgpu/polaris12_k_smc.bin");
|
||||
} else {
|
||||
|
|
|
@ -326,7 +326,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev,
|
|||
increment_us = time_us - adev->mm_stats.last_update_us;
|
||||
adev->mm_stats.last_update_us = time_us;
|
||||
adev->mm_stats.accum_us = min(adev->mm_stats.accum_us + increment_us,
|
||||
us_upper_bound);
|
||||
us_upper_bound);
|
||||
|
||||
/* This prevents the short period of low performance when the VRAM
|
||||
* usage is low and the driver is in debt or doesn't have enough
|
||||
|
@ -1460,7 +1460,7 @@ int amdgpu_cs_fence_to_handle_ioctl(struct drm_device *dev, void *data,
|
|||
dma_fence_put(fence);
|
||||
if (r)
|
||||
return r;
|
||||
r = drm_syncobj_get_fd(syncobj, (int*)&info->out.handle);
|
||||
r = drm_syncobj_get_fd(syncobj, (int *)&info->out.handle);
|
||||
drm_syncobj_put(syncobj);
|
||||
return r;
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
|
|||
enum drm_sched_priority priority;
|
||||
int r;
|
||||
|
||||
entity = kcalloc(1, offsetof(typeof(*entity), fences[amdgpu_sched_jobs]),
|
||||
entity = kzalloc(struct_size(entity, fences, amdgpu_sched_jobs),
|
||||
GFP_KERNEL);
|
||||
if (!entity)
|
||||
return -ENOMEM;
|
||||
|
@ -450,7 +450,7 @@ int amdgpu_ctx_put(struct amdgpu_ctx *ctx)
|
|||
|
||||
void amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx,
|
||||
struct drm_sched_entity *entity,
|
||||
struct dma_fence *fence, uint64_t* handle)
|
||||
struct dma_fence *fence, uint64_t *handle)
|
||||
{
|
||||
struct amdgpu_ctx_entity *centity = to_amdgpu_ctx_entity(entity);
|
||||
uint64_t seq = centity->sequence;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "amdgpu_dm_debugfs.h"
|
||||
#include "amdgpu_ras.h"
|
||||
#include "amdgpu_rap.h"
|
||||
#include "amdgpu_fw_attestation.h"
|
||||
|
||||
/**
|
||||
* amdgpu_debugfs_add_files - Add simple debugfs entries
|
||||
|
@ -169,14 +170,14 @@ static void amdgpu_debugfs_autodump_init(struct amdgpu_device *adev)
|
|||
*
|
||||
* Bit 62: Indicates a GRBM bank switch is needed
|
||||
* Bit 61: Indicates a SRBM bank switch is needed (implies bit 62 is
|
||||
* zero)
|
||||
* zero)
|
||||
* Bits 24..33: The SE or ME selector if needed
|
||||
* Bits 34..43: The SH (or SA) or PIPE selector if needed
|
||||
* Bits 44..53: The INSTANCE (or CU/WGP) or QUEUE selector if needed
|
||||
*
|
||||
* Bit 23: Indicates that the PM power gating lock should be held
|
||||
* This is necessary to read registers that might be
|
||||
* unreliable during a power gating transistion.
|
||||
* This is necessary to read registers that might be
|
||||
* unreliable during a power gating transistion.
|
||||
*
|
||||
* The lower bits are the BYTE offset of the register to read. This
|
||||
* allows reading multiple registers in a single call and having
|
||||
|
@ -864,7 +865,7 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
|
|||
{
|
||||
struct amdgpu_device *adev = f->f_inode->i_private;
|
||||
int r, x;
|
||||
ssize_t result=0;
|
||||
ssize_t result = 0;
|
||||
uint32_t offset, se, sh, cu, wave, simd, data[32];
|
||||
|
||||
if (size & 3 || *pos & 3)
|
||||
|
@ -1210,7 +1211,7 @@ static const char *debugfs_regs_names[] = {
|
|||
|
||||
/**
|
||||
* amdgpu_debugfs_regs_init - Initialize debugfs entries that provide
|
||||
* register access.
|
||||
* register access.
|
||||
*
|
||||
* @adev: The device to attach the debugfs entries to
|
||||
*/
|
||||
|
@ -1338,11 +1339,41 @@ static int amdgpu_debugfs_evict_gtt(struct seq_file *m, void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_debugfs_vm_info(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_info_node *node = (struct drm_info_node *)m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct drm_file *file;
|
||||
int r;
|
||||
|
||||
r = mutex_lock_interruptible(&dev->filelist_mutex);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
list_for_each_entry(file, &dev->filelist, lhead) {
|
||||
struct amdgpu_fpriv *fpriv = file->driver_priv;
|
||||
struct amdgpu_vm *vm = &fpriv->vm;
|
||||
|
||||
seq_printf(m, "pid:%d\tProcess:%s ----------\n",
|
||||
vm->task_info.pid, vm->task_info.process_name);
|
||||
r = amdgpu_bo_reserve(vm->root.base.bo, true);
|
||||
if (r)
|
||||
break;
|
||||
amdgpu_debugfs_vm_bo_info(vm, m);
|
||||
amdgpu_bo_unreserve(vm->root.base.bo);
|
||||
}
|
||||
|
||||
mutex_unlock(&dev->filelist_mutex);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct drm_info_list amdgpu_debugfs_list[] = {
|
||||
{"amdgpu_vbios", amdgpu_debugfs_get_vbios_dump},
|
||||
{"amdgpu_test_ib", &amdgpu_debugfs_test_ib},
|
||||
{"amdgpu_evict_vram", &amdgpu_debugfs_evict_vram},
|
||||
{"amdgpu_evict_gtt", &amdgpu_debugfs_evict_gtt},
|
||||
{"amdgpu_vm_info", &amdgpu_debugfs_vm_info},
|
||||
};
|
||||
|
||||
static void amdgpu_ib_preempt_fences_swap(struct amdgpu_ring *ring,
|
||||
|
@ -1638,6 +1669,8 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
|
|||
|
||||
amdgpu_rap_debugfs_init(adev);
|
||||
|
||||
amdgpu_fw_attestation_debugfs_init(adev);
|
||||
|
||||
return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_list,
|
||||
ARRAY_SIZE(amdgpu_debugfs_list));
|
||||
}
|
||||
|
|
|
@ -80,6 +80,8 @@ MODULE_FIRMWARE("amdgpu/renoir_gpu_info.bin");
|
|||
MODULE_FIRMWARE("amdgpu/navi10_gpu_info.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi14_gpu_info.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin");
|
||||
MODULE_FIRMWARE("amdgpu/vangogh_gpu_info.bin");
|
||||
MODULE_FIRMWARE("amdgpu/green_sardine_gpu_info.bin");
|
||||
|
||||
#define AMDGPU_RESUME_MS 2000
|
||||
|
||||
|
@ -114,6 +116,8 @@ const char *amdgpu_asic_name[] = {
|
|||
"NAVI12",
|
||||
"SIENNA_CICHLID",
|
||||
"NAVY_FLOUNDER",
|
||||
"VANGOGH",
|
||||
"DIMGREY_CAVEFISH",
|
||||
"LAST",
|
||||
};
|
||||
|
||||
|
@ -239,9 +243,11 @@ bool amdgpu_device_supports_baco(struct drm_device *dev)
|
|||
return amdgpu_asic_supports_baco(adev);
|
||||
}
|
||||
|
||||
/*
|
||||
* VRAM access helper functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* VRAM access helper functions.
|
||||
*
|
||||
* amdgpu_device_vram_access - read/write a buffer in vram
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
|
@ -705,7 +711,7 @@ void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev,
|
|||
/**
|
||||
* amdgpu_invalid_rreg - dummy reg read function
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @adev: amdgpu_device pointer
|
||||
* @reg: offset of register
|
||||
*
|
||||
* Dummy register read function. Used for register blocks
|
||||
|
@ -722,7 +728,7 @@ static uint32_t amdgpu_invalid_rreg(struct amdgpu_device *adev, uint32_t reg)
|
|||
/**
|
||||
* amdgpu_invalid_wreg - dummy reg write function
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @adev: amdgpu_device pointer
|
||||
* @reg: offset of register
|
||||
* @v: value to write to the register
|
||||
*
|
||||
|
@ -739,7 +745,7 @@ static void amdgpu_invalid_wreg(struct amdgpu_device *adev, uint32_t reg, uint32
|
|||
/**
|
||||
* amdgpu_invalid_rreg64 - dummy 64 bit reg read function
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @adev: amdgpu_device pointer
|
||||
* @reg: offset of register
|
||||
*
|
||||
* Dummy register read function. Used for register blocks
|
||||
|
@ -756,7 +762,7 @@ static uint64_t amdgpu_invalid_rreg64(struct amdgpu_device *adev, uint32_t reg)
|
|||
/**
|
||||
* amdgpu_invalid_wreg64 - dummy reg write function
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @adev: amdgpu_device pointer
|
||||
* @reg: offset of register
|
||||
* @v: value to write to the register
|
||||
*
|
||||
|
@ -773,7 +779,7 @@ static void amdgpu_invalid_wreg64(struct amdgpu_device *adev, uint32_t reg, uint
|
|||
/**
|
||||
* amdgpu_block_invalid_rreg - dummy reg read function
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @adev: amdgpu_device pointer
|
||||
* @block: offset of instance
|
||||
* @reg: offset of register
|
||||
*
|
||||
|
@ -793,7 +799,7 @@ static uint32_t amdgpu_block_invalid_rreg(struct amdgpu_device *adev,
|
|||
/**
|
||||
* amdgpu_block_invalid_wreg - dummy reg write function
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @adev: amdgpu_device pointer
|
||||
* @block: offset of instance
|
||||
* @reg: offset of register
|
||||
* @v: value to write to the register
|
||||
|
@ -813,7 +819,7 @@ static void amdgpu_block_invalid_wreg(struct amdgpu_device *adev,
|
|||
/**
|
||||
* amdgpu_device_asic_init - Wrapper for atom asic_init
|
||||
*
|
||||
* @dev: drm_device pointer
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Does any asic specific work and then calls atom asic init.
|
||||
*/
|
||||
|
@ -827,7 +833,7 @@ static int amdgpu_device_asic_init(struct amdgpu_device *adev)
|
|||
/**
|
||||
* amdgpu_device_vram_scratch_init - allocate the VRAM scratch page
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Allocates a scratch page of VRAM for use by various things in the
|
||||
* driver.
|
||||
|
@ -844,7 +850,7 @@ static int amdgpu_device_vram_scratch_init(struct amdgpu_device *adev)
|
|||
/**
|
||||
* amdgpu_device_vram_scratch_fini - Free the VRAM scratch page
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Frees the VRAM scratch page.
|
||||
*/
|
||||
|
@ -1370,13 +1376,6 @@ static int amdgpu_device_check_arguments(struct amdgpu_device *adev)
|
|||
|
||||
amdgpu_gmc_tmz_set(adev);
|
||||
|
||||
if (amdgpu_num_kcq == -1) {
|
||||
amdgpu_num_kcq = 8;
|
||||
} else if (amdgpu_num_kcq > 8 || amdgpu_num_kcq < 0) {
|
||||
amdgpu_num_kcq = 8;
|
||||
dev_warn(adev->dev, "set kernel compute queue number to 8 due to invalid parameter provided by user\n");
|
||||
}
|
||||
|
||||
amdgpu_gmc_noretry_set(adev);
|
||||
|
||||
return 0;
|
||||
|
@ -1783,6 +1782,7 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
|
|||
case CHIP_VEGA20:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
default:
|
||||
return 0;
|
||||
case CHIP_VEGA10:
|
||||
|
@ -1803,7 +1803,10 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
|
|||
chip_name = "arcturus";
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
chip_name = "renoir";
|
||||
if (adev->apu_flags & AMD_APU_IS_RENOIR)
|
||||
chip_name = "renoir";
|
||||
else
|
||||
chip_name = "green_sardine";
|
||||
break;
|
||||
case CHIP_NAVI10:
|
||||
chip_name = "navi10";
|
||||
|
@ -1814,6 +1817,9 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
|
|||
case CHIP_NAVI12:
|
||||
chip_name = "navi12";
|
||||
break;
|
||||
case CHIP_VANGOGH:
|
||||
chip_name = "vangogh";
|
||||
break;
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_gpu_info.bin", chip_name);
|
||||
|
@ -1988,7 +1994,12 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
|
|||
case CHIP_NAVI12:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
adev->family = AMDGPU_FAMILY_NV;
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
case CHIP_VANGOGH:
|
||||
if (adev->asic_type == CHIP_VANGOGH)
|
||||
adev->family = AMDGPU_FAMILY_VGH;
|
||||
else
|
||||
adev->family = AMDGPU_FAMILY_NV;
|
||||
|
||||
r = nv_set_ip_blocks(adev);
|
||||
if (r)
|
||||
|
@ -2993,10 +3004,10 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
|
|||
case CHIP_NAVI14:
|
||||
case CHIP_NAVI12:
|
||||
case CHIP_RENOIR:
|
||||
#endif
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
case CHIP_VANGOGH:
|
||||
#endif
|
||||
return amdgpu_dc != 0;
|
||||
#endif
|
||||
|
@ -3011,7 +3022,7 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
|
|||
/**
|
||||
* amdgpu_device_has_dc_support - check if dc is supported
|
||||
*
|
||||
* @adev: amdgpu_device_pointer
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Returns true for supported, false for not supported
|
||||
*/
|
||||
|
@ -4045,7 +4056,7 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev)
|
|||
/**
|
||||
* amdgpu_device_reset_sriov - reset ASIC for SR-IOV vf
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @adev: amdgpu_device pointer
|
||||
* @from_hypervisor: request from hypervisor
|
||||
*
|
||||
* do VF FLR and reinitialize Asic
|
||||
|
@ -4100,7 +4111,7 @@ error:
|
|||
/**
|
||||
* amdgpu_device_has_job_running - check if there is any job in mirror list
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* check if there is any job in mirror list
|
||||
*/
|
||||
|
@ -4128,7 +4139,7 @@ bool amdgpu_device_has_job_running(struct amdgpu_device *adev)
|
|||
/**
|
||||
* amdgpu_device_should_recover_gpu - check if we should try GPU recovery
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Check amdgpu_gpu_recovery and SRIOV status to see if we should try to recover
|
||||
* a hung GPU.
|
||||
|
@ -4477,7 +4488,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
|
|||
/**
|
||||
* amdgpu_device_gpu_recover - reset the asic and recover scheduler
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @adev: amdgpu_device pointer
|
||||
* @job: which job trigger hang
|
||||
*
|
||||
* Attempt to reset the GPU if it has hung (all asics).
|
||||
|
@ -4497,7 +4508,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
bool need_emergency_restart = false;
|
||||
bool audio_suspended = false;
|
||||
|
||||
/**
|
||||
/*
|
||||
* Special case: RAS triggered and full reset isn't supported
|
||||
*/
|
||||
need_emergency_restart = amdgpu_ras_need_emergency_restart(adev);
|
||||
|
|
|
@ -44,11 +44,11 @@ struct amdgpu_df_funcs {
|
|||
void (*enable_ecc_force_par_wr_rmw)(struct amdgpu_device *adev,
|
||||
bool enable);
|
||||
int (*pmc_start)(struct amdgpu_device *adev, uint64_t config,
|
||||
int is_add);
|
||||
int counter_idx, int is_add);
|
||||
int (*pmc_stop)(struct amdgpu_device *adev, uint64_t config,
|
||||
int is_remove);
|
||||
int counter_idx, int is_remove);
|
||||
void (*pmc_get_count)(struct amdgpu_device *adev, uint64_t config,
|
||||
uint64_t *count);
|
||||
int counter_idx, uint64_t *count);
|
||||
uint64_t (*get_fica)(struct amdgpu_device *adev, uint32_t ficaa_val);
|
||||
void (*set_fica)(struct amdgpu_device *adev, uint32_t ficaa_val,
|
||||
uint32_t ficadl_val, uint32_t ficadh_val);
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_gem_framebuffer_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
|
||||
static void amdgpu_display_flip_callback(struct dma_fence *f,
|
||||
|
@ -524,6 +525,10 @@ uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
|
|||
(adev->apu_flags & AMD_APU_IS_PICASSO))
|
||||
domain |= AMDGPU_GEM_DOMAIN_GTT;
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
domain |= AMDGPU_GEM_DOMAIN_GTT;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -533,6 +538,154 @@ uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
|
|||
return domain;
|
||||
}
|
||||
|
||||
static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(afb->base.dev);
|
||||
uint64_t modifier = 0;
|
||||
|
||||
if (!afb->tiling_flags || !AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE)) {
|
||||
modifier = DRM_FORMAT_MOD_LINEAR;
|
||||
} else {
|
||||
int swizzle = AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE);
|
||||
bool has_xor = swizzle >= 16;
|
||||
int block_size_bits;
|
||||
int version;
|
||||
int pipe_xor_bits = 0;
|
||||
int bank_xor_bits = 0;
|
||||
int packers = 0;
|
||||
uint32_t dcc_offset = AMDGPU_TILING_GET(afb->tiling_flags, DCC_OFFSET_256B);
|
||||
|
||||
switch (swizzle >> 2) {
|
||||
case 0: /* 256B */
|
||||
block_size_bits = 8;
|
||||
break;
|
||||
case 1: /* 4KiB */
|
||||
case 5: /* 4KiB _X */
|
||||
block_size_bits = 12;
|
||||
break;
|
||||
case 2: /* 64KiB */
|
||||
case 4: /* 64 KiB _T */
|
||||
case 6: /* 64 KiB _X */
|
||||
block_size_bits = 16;
|
||||
break;
|
||||
default:
|
||||
/* RESERVED or VAR */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (adev->asic_type >= CHIP_SIENNA_CICHLID)
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS;
|
||||
else if (adev->family == AMDGPU_FAMILY_NV)
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX10;
|
||||
else
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX9;
|
||||
|
||||
switch (swizzle & 3) {
|
||||
case 0: /* Z microtiling */
|
||||
return -EINVAL;
|
||||
case 1: /* S microtiling */
|
||||
if (!has_xor)
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX9;
|
||||
break;
|
||||
case 2:
|
||||
if (!has_xor && afb->base.format->cpp[0] != 4)
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX9;
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
}
|
||||
|
||||
if (has_xor) {
|
||||
switch (version) {
|
||||
case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
|
||||
pipe_xor_bits = min(block_size_bits - 8,
|
||||
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes));
|
||||
packers = min(block_size_bits - 8 - pipe_xor_bits,
|
||||
ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs));
|
||||
break;
|
||||
case AMD_FMT_MOD_TILE_VER_GFX10:
|
||||
pipe_xor_bits = min(block_size_bits - 8,
|
||||
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes));
|
||||
break;
|
||||
case AMD_FMT_MOD_TILE_VER_GFX9:
|
||||
pipe_xor_bits = min(block_size_bits - 8,
|
||||
ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes) +
|
||||
ilog2(adev->gfx.config.gb_addr_config_fields.num_se));
|
||||
bank_xor_bits = min(block_size_bits - 8 - pipe_xor_bits,
|
||||
ilog2(adev->gfx.config.gb_addr_config_fields.num_banks));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
modifier = AMD_FMT_MOD |
|
||||
AMD_FMT_MOD_SET(TILE, AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE)) |
|
||||
AMD_FMT_MOD_SET(TILE_VERSION, version) |
|
||||
AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
|
||||
AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
|
||||
AMD_FMT_MOD_SET(PACKERS, packers);
|
||||
|
||||
if (dcc_offset != 0) {
|
||||
bool dcc_i64b = AMDGPU_TILING_GET(afb->tiling_flags, DCC_INDEPENDENT_64B) != 0;
|
||||
bool dcc_i128b = version >= AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS;
|
||||
|
||||
/* Enable constant encode on RAVEN2 and later. */
|
||||
bool dcc_constant_encode = adev->asic_type > CHIP_RAVEN ||
|
||||
(adev->asic_type == CHIP_RAVEN &&
|
||||
adev->external_rev_id >= 0x81);
|
||||
|
||||
int max_cblock_size = dcc_i64b ? AMD_FMT_MOD_DCC_BLOCK_64B :
|
||||
dcc_i128b ? AMD_FMT_MOD_DCC_BLOCK_128B :
|
||||
AMD_FMT_MOD_DCC_BLOCK_256B;
|
||||
|
||||
modifier |= AMD_FMT_MOD_SET(DCC, 1) |
|
||||
AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, dcc_constant_encode) |
|
||||
AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, dcc_i64b) |
|
||||
AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, dcc_i128b) |
|
||||
AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, max_cblock_size);
|
||||
|
||||
afb->base.offsets[1] = dcc_offset * 256 + afb->base.offsets[0];
|
||||
afb->base.pitches[1] = AMDGPU_TILING_GET(afb->tiling_flags, DCC_PITCH_MAX) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
afb->base.modifier = modifier;
|
||||
afb->base.flags |= DRM_MODE_FB_MODIFIERS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_display_get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
|
||||
uint64_t *tiling_flags, bool *tmz_surface)
|
||||
{
|
||||
struct amdgpu_bo *rbo;
|
||||
int r;
|
||||
|
||||
if (!amdgpu_fb) {
|
||||
*tiling_flags = 0;
|
||||
*tmz_surface = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
|
||||
r = amdgpu_bo_reserve(rbo, false);
|
||||
|
||||
if (unlikely(r)) {
|
||||
/* Don't show error message when returning -ERESTARTSYS */
|
||||
if (r != -ERESTARTSYS)
|
||||
DRM_ERROR("Unable to reserve buffer: %d\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (tiling_flags)
|
||||
amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
|
||||
|
||||
if (tmz_surface)
|
||||
*tmz_surface = amdgpu_bo_encrypted(rbo);
|
||||
|
||||
amdgpu_bo_unreserve(rbo);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int amdgpu_display_framebuffer_init(struct drm_device *dev,
|
||||
struct amdgpu_framebuffer *rfb,
|
||||
const struct drm_mode_fb_cmd2 *mode_cmd,
|
||||
|
@ -542,11 +695,25 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev,
|
|||
rfb->base.obj[0] = obj;
|
||||
drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd);
|
||||
ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
|
||||
if (ret) {
|
||||
rfb->base.obj[0] = NULL;
|
||||
return ret;
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = amdgpu_display_get_fb_info(rfb, &rfb->tiling_flags, &rfb->tmz_surface);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
if (dev->mode_config.allow_fb_modifiers &&
|
||||
!(rfb->base.flags & DRM_MODE_FB_MODIFIERS)) {
|
||||
ret = convert_tiling_flags_to_modifier(rfb);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
rfb->base.obj[0] = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct drm_framebuffer *
|
||||
|
|
|
@ -94,16 +94,16 @@
|
|||
#define KMS_DRIVER_MINOR 40
|
||||
#define KMS_DRIVER_PATCHLEVEL 0
|
||||
|
||||
int amdgpu_vram_limit = 0;
|
||||
int amdgpu_vis_vram_limit = 0;
|
||||
int amdgpu_vram_limit;
|
||||
int amdgpu_vis_vram_limit;
|
||||
int amdgpu_gart_size = -1; /* auto */
|
||||
int amdgpu_gtt_size = -1; /* auto */
|
||||
int amdgpu_moverate = -1; /* auto */
|
||||
int amdgpu_benchmarking = 0;
|
||||
int amdgpu_testing = 0;
|
||||
int amdgpu_benchmarking;
|
||||
int amdgpu_testing;
|
||||
int amdgpu_audio = -1;
|
||||
int amdgpu_disp_priority = 0;
|
||||
int amdgpu_hw_i2c = 0;
|
||||
int amdgpu_disp_priority;
|
||||
int amdgpu_hw_i2c;
|
||||
int amdgpu_pcie_gen2 = -1;
|
||||
int amdgpu_msi = -1;
|
||||
char amdgpu_lockup_timeout[AMDGPU_MAX_TIMEOUT_PARAM_LENGTH];
|
||||
|
@ -113,19 +113,19 @@ int amdgpu_aspm = -1;
|
|||
int amdgpu_runtime_pm = -1;
|
||||
uint amdgpu_ip_block_mask = 0xffffffff;
|
||||
int amdgpu_bapm = -1;
|
||||
int amdgpu_deep_color = 0;
|
||||
int amdgpu_deep_color;
|
||||
int amdgpu_vm_size = -1;
|
||||
int amdgpu_vm_fragment_size = -1;
|
||||
int amdgpu_vm_block_size = -1;
|
||||
int amdgpu_vm_fault_stop = 0;
|
||||
int amdgpu_vm_debug = 0;
|
||||
int amdgpu_vm_fault_stop;
|
||||
int amdgpu_vm_debug;
|
||||
int amdgpu_vm_update_mode = -1;
|
||||
int amdgpu_exp_hw_support = 0;
|
||||
int amdgpu_exp_hw_support;
|
||||
int amdgpu_dc = -1;
|
||||
int amdgpu_sched_jobs = 32;
|
||||
int amdgpu_sched_hw_submission = 2;
|
||||
uint amdgpu_pcie_gen_cap = 0;
|
||||
uint amdgpu_pcie_lane_cap = 0;
|
||||
uint amdgpu_pcie_gen_cap;
|
||||
uint amdgpu_pcie_lane_cap;
|
||||
uint amdgpu_cg_mask = 0xffffffff;
|
||||
uint amdgpu_pg_mask = 0xffffffff;
|
||||
uint amdgpu_sdma_phase_quantum = 32;
|
||||
|
@ -133,23 +133,31 @@ char *amdgpu_disable_cu = NULL;
|
|||
char *amdgpu_virtual_display = NULL;
|
||||
/* OverDrive(bit 14) disabled by default*/
|
||||
uint amdgpu_pp_feature_mask = 0xffffbfff;
|
||||
uint amdgpu_force_long_training = 0;
|
||||
int amdgpu_job_hang_limit = 0;
|
||||
uint amdgpu_force_long_training;
|
||||
int amdgpu_job_hang_limit;
|
||||
int amdgpu_lbpw = -1;
|
||||
int amdgpu_compute_multipipe = -1;
|
||||
int amdgpu_gpu_recovery = -1; /* auto */
|
||||
int amdgpu_emu_mode = 0;
|
||||
uint amdgpu_smu_memory_pool_size = 0;
|
||||
/* FBC (bit 0) disabled by default*/
|
||||
uint amdgpu_dc_feature_mask = 0;
|
||||
uint amdgpu_dc_debug_mask = 0;
|
||||
int amdgpu_emu_mode;
|
||||
uint amdgpu_smu_memory_pool_size;
|
||||
/*
|
||||
* FBC (bit 0) disabled by default
|
||||
* MULTI_MON_PP_MCLK_SWITCH (bit 1) enabled by default
|
||||
* - With this, for multiple monitors in sync(e.g. with the same model),
|
||||
* mclk switching will be allowed. And the mclk will be not foced to the
|
||||
* highest. That helps saving some idle power.
|
||||
* DISABLE_FRACTIONAL_PWM (bit 2) disabled by default
|
||||
* PSR (bit 3) disabled by default
|
||||
*/
|
||||
uint amdgpu_dc_feature_mask = 2;
|
||||
uint amdgpu_dc_debug_mask;
|
||||
int amdgpu_async_gfx_ring = 1;
|
||||
int amdgpu_mcbp = 0;
|
||||
int amdgpu_mcbp;
|
||||
int amdgpu_discovery = -1;
|
||||
int amdgpu_mes = 0;
|
||||
int amdgpu_mes;
|
||||
int amdgpu_noretry = -1;
|
||||
int amdgpu_force_asic_type = -1;
|
||||
int amdgpu_tmz = 0;
|
||||
int amdgpu_tmz;
|
||||
int amdgpu_reset_method = -1; /* auto */
|
||||
int amdgpu_num_kcq = -1;
|
||||
|
||||
|
@ -271,7 +279,7 @@ module_param_string(lockup_timeout, amdgpu_lockup_timeout, sizeof(amdgpu_lockup_
|
|||
/**
|
||||
* DOC: dpm (int)
|
||||
* Override for dynamic power management setting
|
||||
* (0 = disable, 1 = enable, 2 = enable sw smu driver for vega20)
|
||||
* (0 = disable, 1 = enable)
|
||||
* The default is -1 (auto).
|
||||
*/
|
||||
MODULE_PARM_DESC(dpm, "DPM support (1 = enable, 0 = disable, -1 = auto)");
|
||||
|
@ -764,7 +772,7 @@ module_param_named(dcdebugmask, amdgpu_dc_debug_mask, uint, 0444);
|
|||
* Defaults to 0, or disabled. Userspace can still override this level later
|
||||
* after boot.
|
||||
*/
|
||||
uint amdgpu_dm_abm_level = 0;
|
||||
uint amdgpu_dm_abm_level;
|
||||
MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) ");
|
||||
module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444);
|
||||
|
||||
|
@ -1089,6 +1097,9 @@ static const struct pci_device_id pciidlist[] = {
|
|||
{0x1002, 0x73AE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID},
|
||||
{0x1002, 0x73BF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID},
|
||||
|
||||
/* Van Gogh */
|
||||
{0x1002, 0x163F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VANGOGH|AMD_IS_APU},
|
||||
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -1495,7 +1506,7 @@ static const struct file_operations amdgpu_driver_kms_fops = {
|
|||
|
||||
int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv)
|
||||
{
|
||||
struct drm_file *file;
|
||||
struct drm_file *file;
|
||||
|
||||
if (!filp)
|
||||
return -EINVAL;
|
||||
|
|
|
@ -207,6 +207,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
|
|||
int ret;
|
||||
unsigned long tmp;
|
||||
|
||||
memset(&mode_cmd, 0, sizeof(mode_cmd));
|
||||
mode_cmd.width = sizes->surface_width;
|
||||
mode_cmd.height = sizes->surface_height;
|
||||
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Copyright 2020 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_psp.h"
|
||||
#include "amdgpu_ucode.h"
|
||||
#include "soc15_common.h"
|
||||
|
||||
#define FW_ATTESTATION_DB_COOKIE 0x143b6a37
|
||||
#define FW_ATTESTATION_RECORD_VALID 1
|
||||
#define FW_ATTESTATION_MAX_SIZE 4096
|
||||
|
||||
typedef struct FW_ATT_DB_HEADER
|
||||
{
|
||||
uint32_t AttDbVersion; /* version of the fwar feature */
|
||||
uint32_t AttDbCookie; /* cookie as an extra check for corrupt data */
|
||||
} FW_ATT_DB_HEADER;
|
||||
|
||||
typedef struct FW_ATT_RECORD
|
||||
{
|
||||
uint16_t AttFwIdV1; /* Legacy FW Type field */
|
||||
uint16_t AttFwIdV2; /* V2 FW ID field */
|
||||
uint32_t AttFWVersion; /* FW Version */
|
||||
uint16_t AttFWActiveFunctionID; /* The VF ID (only in VF Attestation Table) */
|
||||
uint16_t AttSource; /* FW source indicator */
|
||||
uint16_t RecordValid; /* Indicates whether the record is a valid entry */
|
||||
uint8_t AttFwTaId; /* Ta ID (only in TA Attestation Table) */
|
||||
uint8_t Reserved;
|
||||
} FW_ATT_RECORD;
|
||||
|
||||
static ssize_t amdgpu_fw_attestation_debugfs_read(struct file *f,
|
||||
char __user *buf,
|
||||
size_t size,
|
||||
loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
|
||||
uint64_t records_addr = 0;
|
||||
uint64_t vram_pos = 0;
|
||||
FW_ATT_DB_HEADER fw_att_hdr = {0};
|
||||
FW_ATT_RECORD fw_att_record = {0};
|
||||
|
||||
if (size < sizeof(FW_ATT_RECORD)) {
|
||||
DRM_WARN("FW attestation input buffer not enough memory");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((*pos + sizeof(FW_ATT_DB_HEADER)) >= FW_ATTESTATION_MAX_SIZE) {
|
||||
DRM_WARN("FW attestation out of bounds");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (psp_get_fw_attestation_records_addr(&adev->psp, &records_addr)) {
|
||||
DRM_WARN("Failed to get FW attestation record address");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vram_pos = records_addr - adev->gmc.vram_start;
|
||||
|
||||
if (*pos == 0) {
|
||||
amdgpu_device_vram_access(adev,
|
||||
vram_pos,
|
||||
(uint32_t*)&fw_att_hdr,
|
||||
sizeof(FW_ATT_DB_HEADER),
|
||||
false);
|
||||
|
||||
if (fw_att_hdr.AttDbCookie != FW_ATTESTATION_DB_COOKIE) {
|
||||
DRM_WARN("Invalid FW attestation cookie");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_INFO("FW attestation version = 0x%X", fw_att_hdr.AttDbVersion);
|
||||
}
|
||||
|
||||
amdgpu_device_vram_access(adev,
|
||||
vram_pos + sizeof(FW_ATT_DB_HEADER) + *pos,
|
||||
(uint32_t*)&fw_att_record,
|
||||
sizeof(FW_ATT_RECORD),
|
||||
false);
|
||||
|
||||
if (fw_att_record.RecordValid != FW_ATTESTATION_RECORD_VALID)
|
||||
return 0;
|
||||
|
||||
if (copy_to_user(buf, (void*)&fw_att_record, sizeof(FW_ATT_RECORD)))
|
||||
return -EINVAL;
|
||||
|
||||
*pos += sizeof(FW_ATT_RECORD);
|
||||
|
||||
return sizeof(FW_ATT_RECORD);
|
||||
}
|
||||
|
||||
static const struct file_operations amdgpu_fw_attestation_debugfs_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = amdgpu_fw_attestation_debugfs_read,
|
||||
.write = NULL,
|
||||
.llseek = default_llseek
|
||||
};
|
||||
|
||||
static int amdgpu_is_fw_attestation_supported(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->asic_type >= CHIP_SIENNA_CICHLID)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void amdgpu_fw_attestation_debugfs_init(struct amdgpu_device *adev)
|
||||
{
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
if (!amdgpu_is_fw_attestation_supported(adev))
|
||||
return;
|
||||
|
||||
debugfs_create_file("amdgpu_fw_attestation",
|
||||
S_IRUSR,
|
||||
adev_to_drm(adev)->primary->debugfs_root,
|
||||
adev,
|
||||
&amdgpu_fw_attestation_debugfs_ops);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2020 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
#ifndef _AMDGPU_FW_ATTESTATION_H
|
||||
#define _AMDGPU_FW_ATTESTATION_H
|
||||
|
||||
#include "amdgpu.h"
|
||||
|
||||
void amdgpu_fw_attestation_debugfs_init(struct amdgpu_device *adev);
|
||||
#endif
|
|
@ -849,67 +849,6 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
|
|||
}
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
|
||||
#define amdgpu_debugfs_gem_bo_print_flag(m, bo, flag) \
|
||||
if (bo->flags & (AMDGPU_GEM_CREATE_ ## flag)) { \
|
||||
seq_printf((m), " " #flag); \
|
||||
}
|
||||
|
||||
static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data)
|
||||
{
|
||||
struct drm_gem_object *gobj = ptr;
|
||||
struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj);
|
||||
struct seq_file *m = data;
|
||||
|
||||
struct dma_buf_attachment *attachment;
|
||||
struct dma_buf *dma_buf;
|
||||
unsigned domain;
|
||||
const char *placement;
|
||||
unsigned pin_count;
|
||||
|
||||
domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
|
||||
switch (domain) {
|
||||
case AMDGPU_GEM_DOMAIN_VRAM:
|
||||
placement = "VRAM";
|
||||
break;
|
||||
case AMDGPU_GEM_DOMAIN_GTT:
|
||||
placement = " GTT";
|
||||
break;
|
||||
case AMDGPU_GEM_DOMAIN_CPU:
|
||||
default:
|
||||
placement = " CPU";
|
||||
break;
|
||||
}
|
||||
seq_printf(m, "\t0x%08x: %12ld byte %s",
|
||||
id, amdgpu_bo_size(bo), placement);
|
||||
|
||||
pin_count = READ_ONCE(bo->tbo.pin_count);
|
||||
if (pin_count)
|
||||
seq_printf(m, " pin count %d", pin_count);
|
||||
|
||||
dma_buf = READ_ONCE(bo->tbo.base.dma_buf);
|
||||
attachment = READ_ONCE(bo->tbo.base.import_attach);
|
||||
|
||||
if (attachment)
|
||||
seq_printf(m, " imported from %p%s", dma_buf,
|
||||
attachment->peer2peer ? " P2P" : "");
|
||||
else if (dma_buf)
|
||||
seq_printf(m, " exported as %p", dma_buf);
|
||||
|
||||
amdgpu_debugfs_gem_bo_print_flag(m, bo, CPU_ACCESS_REQUIRED);
|
||||
amdgpu_debugfs_gem_bo_print_flag(m, bo, NO_CPU_ACCESS);
|
||||
amdgpu_debugfs_gem_bo_print_flag(m, bo, CPU_GTT_USWC);
|
||||
amdgpu_debugfs_gem_bo_print_flag(m, bo, VRAM_CLEARED);
|
||||
amdgpu_debugfs_gem_bo_print_flag(m, bo, SHADOW);
|
||||
amdgpu_debugfs_gem_bo_print_flag(m, bo, VRAM_CONTIGUOUS);
|
||||
amdgpu_debugfs_gem_bo_print_flag(m, bo, VM_ALWAYS_VALID);
|
||||
amdgpu_debugfs_gem_bo_print_flag(m, bo, EXPLICIT_SYNC);
|
||||
|
||||
seq_printf(m, "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_info_node *node = (struct drm_info_node *)m->private;
|
||||
|
@ -923,6 +862,8 @@ static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
|
|||
|
||||
list_for_each_entry(file, &dev->filelist, lhead) {
|
||||
struct task_struct *task;
|
||||
struct drm_gem_object *gobj;
|
||||
int id;
|
||||
|
||||
/*
|
||||
* Although we have a valid reference on file->pid, that does
|
||||
|
@ -937,7 +878,11 @@ static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
|
|||
rcu_read_unlock();
|
||||
|
||||
spin_lock(&file->table_lock);
|
||||
idr_for_each(&file->object_idr, amdgpu_debugfs_gem_bo_info, m);
|
||||
idr_for_each_entry(&file->object_idr, gobj, id) {
|
||||
struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj);
|
||||
|
||||
amdgpu_bo_print_info(id, bo, m);
|
||||
}
|
||||
spin_unlock(&file->table_lock);
|
||||
}
|
||||
|
||||
|
|
|
@ -804,3 +804,14 @@ failed_undo:
|
|||
failed_kiq_write:
|
||||
dev_err(adev->dev, "failed to write reg:%x\n", reg);
|
||||
}
|
||||
|
||||
int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev)
|
||||
{
|
||||
if (amdgpu_num_kcq == -1) {
|
||||
return 8;
|
||||
} else if (amdgpu_num_kcq > 8 || amdgpu_num_kcq < 0) {
|
||||
dev_warn(adev->dev, "set kernel compute queue number to 8 due to invalid parameter provided by user\n");
|
||||
return 8;
|
||||
}
|
||||
return amdgpu_num_kcq;
|
||||
}
|
||||
|
|
|
@ -218,6 +218,7 @@ struct amdgpu_gfx_funcs {
|
|||
void (*reset_ras_error_count) (struct amdgpu_device *adev);
|
||||
void (*init_spm_golden)(struct amdgpu_device *adev);
|
||||
void (*query_ras_error_status) (struct amdgpu_device *adev);
|
||||
void (*update_perfmon_mgcg)(struct amdgpu_device *adev, bool enable);
|
||||
};
|
||||
|
||||
struct sq_work {
|
||||
|
@ -392,4 +393,5 @@ int amdgpu_gfx_cp_ecc_error_irq(struct amdgpu_device *adev,
|
|||
struct amdgpu_iv_entry *entry);
|
||||
uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg);
|
||||
void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
|
||||
int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev);
|
||||
#endif
|
||||
|
|
|
@ -389,6 +389,7 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
|
|||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
case CHIP_NAVI12:
|
||||
case CHIP_VANGOGH:
|
||||
/* Don't enable it by default yet.
|
||||
*/
|
||||
if (amdgpu_tmz < 1) {
|
||||
|
@ -421,20 +422,30 @@ void amdgpu_gmc_noretry_set(struct amdgpu_device *adev)
|
|||
struct amdgpu_gmc *gmc = &adev->gmc;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
/*
|
||||
* noretry = 0 will cause kfd page fault tests fail
|
||||
* for some ASICs, so set default to 1 for these ASICs.
|
||||
*/
|
||||
if (amdgpu_noretry == -1)
|
||||
gmc->noretry = 1;
|
||||
else
|
||||
gmc->noretry = amdgpu_noretry;
|
||||
break;
|
||||
case CHIP_RAVEN:
|
||||
default:
|
||||
/* Raven currently has issues with noretry
|
||||
* regardless of what we decide for other
|
||||
* asics, we should leave raven with
|
||||
* noretry = 0 until we root cause the
|
||||
* issues.
|
||||
*/
|
||||
if (amdgpu_noretry == -1)
|
||||
gmc->noretry = 0;
|
||||
else
|
||||
gmc->noretry = amdgpu_noretry;
|
||||
break;
|
||||
default:
|
||||
/* default this to 0 for now, but we may want
|
||||
*
|
||||
* default this to 0 for now, but we may want
|
||||
* to change this in the future for certain
|
||||
* GPUs as it can increase performance in
|
||||
* certain cases.
|
||||
|
|
|
@ -81,8 +81,8 @@ static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func;
|
|||
/**
|
||||
* amdgpu_gtt_mgr_init - init GTT manager and DRM MM
|
||||
*
|
||||
* @man: TTM memory type manager
|
||||
* @p_size: maximum size of GTT
|
||||
* @adev: amdgpu_device pointer
|
||||
* @gtt_size: maximum size of GTT
|
||||
*
|
||||
* Allocate and initialize the GTT manager.
|
||||
*/
|
||||
|
@ -123,7 +123,7 @@ int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size)
|
|||
/**
|
||||
* amdgpu_gtt_mgr_fini - free and destroy GTT manager
|
||||
*
|
||||
* @man: TTM memory type manager
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Destroy and free the GTT manager, returns -EBUSY if ranges are still
|
||||
* allocated inside it.
|
||||
|
|
|
@ -325,6 +325,10 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
|
|||
fw_info->ver = adev->dm.dmcub_fw_version;
|
||||
fw_info->feature = 0;
|
||||
break;
|
||||
case AMDGPU_INFO_FW_TOC:
|
||||
fw_info->ver = adev->psp.toc_fw_version;
|
||||
fw_info->feature = adev->psp.toc_feature_version;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1466,6 +1470,13 @@ static int amdgpu_debugfs_firmware_info(struct seq_file *m, void *data)
|
|||
seq_printf(m, "DMCUB feature version: %u, firmware version: 0x%08x\n",
|
||||
fw_info.feature, fw_info.ver);
|
||||
|
||||
/* TOC */
|
||||
query_fw.fw_type = AMDGPU_INFO_FW_TOC;
|
||||
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
seq_printf(m, "TOC feature version: %u, firmware version: 0x%08x\n",
|
||||
fw_info.feature, fw_info.ver);
|
||||
|
||||
seq_printf(m, "VBIOS version: %s\n", ctx->vbios_version);
|
||||
|
||||
|
|
|
@ -302,6 +302,9 @@ struct amdgpu_display_funcs {
|
|||
struct amdgpu_framebuffer {
|
||||
struct drm_framebuffer base;
|
||||
|
||||
uint64_t tiling_flags;
|
||||
bool tmz_surface;
|
||||
|
||||
/* caching for later use */
|
||||
uint64_t address;
|
||||
};
|
||||
|
|
|
@ -53,6 +53,8 @@ struct amdgpu_nbio_funcs {
|
|||
u32 (*get_hdp_flush_done_offset)(struct amdgpu_device *adev);
|
||||
u32 (*get_pcie_index_offset)(struct amdgpu_device *adev);
|
||||
u32 (*get_pcie_data_offset)(struct amdgpu_device *adev);
|
||||
u32 (*get_pcie_port_index_offset)(struct amdgpu_device *adev);
|
||||
u32 (*get_pcie_port_data_offset)(struct amdgpu_device *adev);
|
||||
u32 (*get_rev_id)(struct amdgpu_device *adev);
|
||||
void (*mc_access_enable)(struct amdgpu_device *adev, bool enable);
|
||||
void (*hdp_flush)(struct amdgpu_device *adev, struct amdgpu_ring *ring);
|
||||
|
@ -85,6 +87,8 @@ struct amdgpu_nbio_funcs {
|
|||
void (*query_ras_error_count)(struct amdgpu_device *adev,
|
||||
void *ras_error_status);
|
||||
int (*ras_late_init)(struct amdgpu_device *adev);
|
||||
void (*enable_aspm)(struct amdgpu_device *adev,
|
||||
bool enable);
|
||||
};
|
||||
|
||||
struct amdgpu_nbio {
|
||||
|
|
|
@ -1045,6 +1045,7 @@ static const char *amdgpu_vram_names[] = {
|
|||
"DDR3",
|
||||
"DDR4",
|
||||
"GDDR6",
|
||||
"DDR5"
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1507,3 +1508,77 @@ uint32_t amdgpu_bo_get_preferred_pin_domain(struct amdgpu_device *adev,
|
|||
}
|
||||
return domain;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
#define amdgpu_bo_print_flag(m, bo, flag) \
|
||||
do { \
|
||||
if (bo->flags & (AMDGPU_GEM_CREATE_ ## flag)) { \
|
||||
seq_printf((m), " " #flag); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* amdgpu_debugfs_print_bo_info - print BO info in debugfs file
|
||||
*
|
||||
* @id: Index or Id of the BO
|
||||
* @bo: Requested BO for printing info
|
||||
* @m: debugfs file
|
||||
*
|
||||
* Print BO information in debugfs file
|
||||
*
|
||||
* Returns:
|
||||
* Size of the BO in bytes.
|
||||
*/
|
||||
u64 amdgpu_bo_print_info(int id, struct amdgpu_bo *bo, struct seq_file *m)
|
||||
{
|
||||
struct dma_buf_attachment *attachment;
|
||||
struct dma_buf *dma_buf;
|
||||
unsigned int domain;
|
||||
const char *placement;
|
||||
unsigned int pin_count;
|
||||
u64 size;
|
||||
|
||||
domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
|
||||
switch (domain) {
|
||||
case AMDGPU_GEM_DOMAIN_VRAM:
|
||||
placement = "VRAM";
|
||||
break;
|
||||
case AMDGPU_GEM_DOMAIN_GTT:
|
||||
placement = " GTT";
|
||||
break;
|
||||
case AMDGPU_GEM_DOMAIN_CPU:
|
||||
default:
|
||||
placement = " CPU";
|
||||
break;
|
||||
}
|
||||
|
||||
size = amdgpu_bo_size(bo);
|
||||
seq_printf(m, "\t\t0x%08x: %12lld byte %s",
|
||||
id, size, placement);
|
||||
|
||||
pin_count = READ_ONCE(bo->tbo.pin_count);
|
||||
if (pin_count)
|
||||
seq_printf(m, " pin count %d", pin_count);
|
||||
|
||||
dma_buf = READ_ONCE(bo->tbo.base.dma_buf);
|
||||
attachment = READ_ONCE(bo->tbo.base.import_attach);
|
||||
|
||||
if (attachment)
|
||||
seq_printf(m, " imported from %p", dma_buf);
|
||||
else if (dma_buf)
|
||||
seq_printf(m, " exported as %p", dma_buf);
|
||||
|
||||
amdgpu_bo_print_flag(m, bo, CPU_ACCESS_REQUIRED);
|
||||
amdgpu_bo_print_flag(m, bo, NO_CPU_ACCESS);
|
||||
amdgpu_bo_print_flag(m, bo, CPU_GTT_USWC);
|
||||
amdgpu_bo_print_flag(m, bo, VRAM_CLEARED);
|
||||
amdgpu_bo_print_flag(m, bo, SHADOW);
|
||||
amdgpu_bo_print_flag(m, bo, VRAM_CONTIGUOUS);
|
||||
amdgpu_bo_print_flag(m, bo, VM_ALWAYS_VALID);
|
||||
amdgpu_bo_print_flag(m, bo, EXPLICIT_SYNC);
|
||||
|
||||
seq_puts(m, "\n");
|
||||
|
||||
return size;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -329,6 +329,7 @@ void amdgpu_sa_bo_free(struct amdgpu_device *adev,
|
|||
#if defined(CONFIG_DEBUG_FS)
|
||||
void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager,
|
||||
struct seq_file *m);
|
||||
u64 amdgpu_bo_print_info(int id, struct amdgpu_bo *bo, struct seq_file *m);
|
||||
#endif
|
||||
int amdgpu_debugfs_sa_init(struct amdgpu_device *adev);
|
||||
|
||||
|
|
|
@ -19,17 +19,29 @@
|
|||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Jonathan Kim <jonathan.kim@amd.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/init.h>
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_pmu.h"
|
||||
#include "df_v3_6.h"
|
||||
|
||||
#define PMU_NAME_SIZE 32
|
||||
#define NUM_FORMATS_AMDGPU_PMU 4
|
||||
#define NUM_FORMATS_DF_VEGA20 3
|
||||
#define NUM_EVENTS_DF_VEGA20 8
|
||||
#define NUM_EVENT_TYPES_VEGA20 1
|
||||
#define NUM_EVENTS_VEGA20_XGMI 2
|
||||
#define NUM_EVENTS_VEGA20_MAX NUM_EVENTS_VEGA20_XGMI
|
||||
#define NUM_EVENT_TYPES_ARCTURUS 1
|
||||
#define NUM_EVENTS_ARCTURUS_XGMI 6
|
||||
#define NUM_EVENTS_ARCTURUS_MAX NUM_EVENTS_ARCTURUS_XGMI
|
||||
|
||||
struct amdgpu_pmu_event_attribute {
|
||||
struct device_attribute attr;
|
||||
const char *event_str;
|
||||
unsigned int type;
|
||||
};
|
||||
|
||||
/* record to keep track of pmu entry per pmu type per device */
|
||||
struct amdgpu_pmu_entry {
|
||||
|
@ -37,11 +49,162 @@ struct amdgpu_pmu_entry {
|
|||
struct amdgpu_device *adev;
|
||||
struct pmu pmu;
|
||||
unsigned int pmu_perf_type;
|
||||
char *pmu_type_name;
|
||||
char *pmu_file_prefix;
|
||||
struct attribute_group fmt_attr_group;
|
||||
struct amdgpu_pmu_event_attribute *fmt_attr;
|
||||
struct attribute_group evt_attr_group;
|
||||
struct amdgpu_pmu_event_attribute *evt_attr;
|
||||
};
|
||||
|
||||
static ssize_t amdgpu_pmu_event_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct amdgpu_pmu_event_attribute *amdgpu_pmu_attr;
|
||||
|
||||
amdgpu_pmu_attr = container_of(attr, struct amdgpu_pmu_event_attribute,
|
||||
attr);
|
||||
|
||||
if (!amdgpu_pmu_attr->type)
|
||||
return sprintf(buf, "%s\n", amdgpu_pmu_attr->event_str);
|
||||
|
||||
return sprintf(buf, "%s,type=0x%x\n",
|
||||
amdgpu_pmu_attr->event_str, amdgpu_pmu_attr->type);
|
||||
}
|
||||
|
||||
static LIST_HEAD(amdgpu_pmu_list);
|
||||
|
||||
|
||||
struct amdgpu_pmu_attr {
|
||||
const char *name;
|
||||
const char *config;
|
||||
};
|
||||
|
||||
struct amdgpu_pmu_type {
|
||||
const unsigned int type;
|
||||
const unsigned int num_of_type;
|
||||
};
|
||||
|
||||
struct amdgpu_pmu_config {
|
||||
struct amdgpu_pmu_attr *formats;
|
||||
unsigned int num_formats;
|
||||
struct amdgpu_pmu_attr *events;
|
||||
unsigned int num_events;
|
||||
struct amdgpu_pmu_type *types;
|
||||
unsigned int num_types;
|
||||
};
|
||||
|
||||
/*
|
||||
* Events fall under two categories:
|
||||
* - PMU typed
|
||||
* Events in /sys/bus/event_source/devices/amdgpu_<pmu_type>_<dev_num> have
|
||||
* performance counter operations handled by one IP <pmu_type>. Formats and
|
||||
* events should be defined by <pmu_type>_<asic_type>_formats and
|
||||
* <pmu_type>_<asic_type>_events respectively.
|
||||
*
|
||||
* - Event config typed
|
||||
* Events in /sys/bus/event_source/devices/amdgpu_<dev_num> have performance
|
||||
* counter operations that can be handled by multiple IPs dictated by their
|
||||
* "type" format field. Formats and events should be defined by
|
||||
* amdgpu_pmu_formats and <asic_type>_events respectively. Format field
|
||||
* "type" is generated in amdgpu_pmu_event_show and defined in
|
||||
* <asic_type>_event_config_types.
|
||||
*/
|
||||
|
||||
static struct amdgpu_pmu_attr amdgpu_pmu_formats[NUM_FORMATS_AMDGPU_PMU] = {
|
||||
{ .name = "event", .config = "config:0-7" },
|
||||
{ .name = "instance", .config = "config:8-15" },
|
||||
{ .name = "umask", .config = "config:16-23"},
|
||||
{ .name = "type", .config = "config:56-63"}
|
||||
};
|
||||
|
||||
/* Vega20 events */
|
||||
static struct amdgpu_pmu_attr vega20_events[NUM_EVENTS_VEGA20_MAX] = {
|
||||
{ .name = "xgmi_link0_data_outbound",
|
||||
.config = "event=0x7,instance=0x46,umask=0x2" },
|
||||
{ .name = "xgmi_link1_data_outbound",
|
||||
.config = "event=0x7,instance=0x47,umask=0x2" }
|
||||
};
|
||||
|
||||
static struct amdgpu_pmu_type vega20_types[NUM_EVENT_TYPES_VEGA20] = {
|
||||
{ .type = AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI,
|
||||
.num_of_type = NUM_EVENTS_VEGA20_XGMI }
|
||||
};
|
||||
|
||||
static struct amdgpu_pmu_config vega20_config = {
|
||||
.formats = amdgpu_pmu_formats,
|
||||
.num_formats = ARRAY_SIZE(amdgpu_pmu_formats),
|
||||
.events = vega20_events,
|
||||
.num_events = ARRAY_SIZE(vega20_events),
|
||||
.types = vega20_types,
|
||||
.num_types = ARRAY_SIZE(vega20_types)
|
||||
};
|
||||
|
||||
/* Vega20 data fabric (DF) events */
|
||||
static struct amdgpu_pmu_attr df_vega20_formats[NUM_FORMATS_DF_VEGA20] = {
|
||||
{ .name = "event", .config = "config:0-7" },
|
||||
{ .name = "instance", .config = "config:8-15" },
|
||||
{ .name = "umask", .config = "config:16-23"}
|
||||
};
|
||||
|
||||
static struct amdgpu_pmu_attr df_vega20_events[NUM_EVENTS_DF_VEGA20] = {
|
||||
{ .name = "cake0_pcsout_txdata",
|
||||
.config = "event=0x7,instance=0x46,umask=0x2" },
|
||||
{ .name = "cake1_pcsout_txdata",
|
||||
.config = "event=0x7,instance=0x47,umask=0x2" },
|
||||
{ .name = "cake0_pcsout_txmeta",
|
||||
.config = "event=0x7,instance=0x46,umask=0x4" },
|
||||
{ .name = "cake1_pcsout_txmeta",
|
||||
.config = "event=0x7,instance=0x47,umask=0x4" },
|
||||
{ .name = "cake0_ftiinstat_reqalloc",
|
||||
.config = "event=0xb,instance=0x46,umask=0x4" },
|
||||
{ .name = "cake1_ftiinstat_reqalloc",
|
||||
.config = "event=0xb,instance=0x47,umask=0x4" },
|
||||
{ .name = "cake0_ftiinstat_rspalloc",
|
||||
.config = "event=0xb,instance=0x46,umask=0x8" },
|
||||
{ .name = "cake1_ftiinstat_rspalloc",
|
||||
.config = "event=0xb,instance=0x47,umask=0x8" }
|
||||
};
|
||||
|
||||
static struct amdgpu_pmu_config df_vega20_config = {
|
||||
.formats = df_vega20_formats,
|
||||
.num_formats = ARRAY_SIZE(df_vega20_formats),
|
||||
.events = df_vega20_events,
|
||||
.num_events = ARRAY_SIZE(df_vega20_events),
|
||||
.types = NULL,
|
||||
.num_types = 0
|
||||
};
|
||||
|
||||
/* Arcturus events */
|
||||
static struct amdgpu_pmu_attr arcturus_events[NUM_EVENTS_ARCTURUS_MAX] = {
|
||||
{ .name = "xgmi_link0_data_outbound",
|
||||
.config = "event=0x7,instance=0x4b,umask=0x2" },
|
||||
{ .name = "xgmi_link1_data_outbound",
|
||||
.config = "event=0x7,instance=0x4c,umask=0x2" },
|
||||
{ .name = "xgmi_link2_data_outbound",
|
||||
.config = "event=0x7,instance=0x4d,umask=0x2" },
|
||||
{ .name = "xgmi_link3_data_outbound",
|
||||
.config = "event=0x7,instance=0x4e,umask=0x2" },
|
||||
{ .name = "xgmi_link4_data_outbound",
|
||||
.config = "event=0x7,instance=0x4f,umask=0x2" },
|
||||
{ .name = "xgmi_link5_data_outbound",
|
||||
.config = "event=0x7,instance=0x50,umask=0x2" }
|
||||
};
|
||||
|
||||
static struct amdgpu_pmu_type arcturus_types[NUM_EVENT_TYPES_ARCTURUS] = {
|
||||
{ .type = AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI,
|
||||
.num_of_type = NUM_EVENTS_ARCTURUS_XGMI }
|
||||
};
|
||||
|
||||
static struct amdgpu_pmu_config arcturus_config = {
|
||||
.formats = amdgpu_pmu_formats,
|
||||
.num_formats = ARRAY_SIZE(amdgpu_pmu_formats),
|
||||
.events = arcturus_events,
|
||||
.num_events = ARRAY_SIZE(arcturus_events),
|
||||
.types = arcturus_types,
|
||||
.num_types = ARRAY_SIZE(arcturus_types)
|
||||
};
|
||||
|
||||
/* initialize perf counter */
|
||||
static int amdgpu_perf_event_init(struct perf_event *event)
|
||||
{
|
||||
|
@ -53,6 +216,7 @@ static int amdgpu_perf_event_init(struct perf_event *event)
|
|||
|
||||
/* update the hw_perf_event struct with config data */
|
||||
hwc->config = event->attr.config;
|
||||
hwc->config_base = AMDGPU_PMU_PERF_TYPE_NONE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -64,6 +228,7 @@ static void amdgpu_perf_start(struct perf_event *event, int flags)
|
|||
struct amdgpu_pmu_entry *pe = container_of(event->pmu,
|
||||
struct amdgpu_pmu_entry,
|
||||
pmu);
|
||||
int target_cntr = 0;
|
||||
|
||||
if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
|
||||
return;
|
||||
|
@ -71,19 +236,27 @@ static void amdgpu_perf_start(struct perf_event *event, int flags)
|
|||
WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
|
||||
hwc->state = 0;
|
||||
|
||||
switch (pe->pmu_perf_type) {
|
||||
case PERF_TYPE_AMDGPU_DF:
|
||||
if (!(flags & PERF_EF_RELOAD))
|
||||
pe->adev->df.funcs->pmc_start(pe->adev, hwc->config, 1);
|
||||
switch (hwc->config_base) {
|
||||
case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF:
|
||||
case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI:
|
||||
if (!(flags & PERF_EF_RELOAD)) {
|
||||
target_cntr = pe->adev->df.funcs->pmc_start(pe->adev,
|
||||
hwc->config, 0 /* unused */,
|
||||
1 /* add counter */);
|
||||
if (target_cntr < 0)
|
||||
break;
|
||||
|
||||
pe->adev->df.funcs->pmc_start(pe->adev, hwc->config, 0);
|
||||
hwc->idx = target_cntr;
|
||||
}
|
||||
|
||||
pe->adev->df.funcs->pmc_start(pe->adev, hwc->config,
|
||||
hwc->idx, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
perf_event_update_userpage(event);
|
||||
|
||||
}
|
||||
|
||||
/* read perf counter */
|
||||
|
@ -93,16 +266,16 @@ static void amdgpu_perf_read(struct perf_event *event)
|
|||
struct amdgpu_pmu_entry *pe = container_of(event->pmu,
|
||||
struct amdgpu_pmu_entry,
|
||||
pmu);
|
||||
|
||||
u64 count, prev;
|
||||
|
||||
do {
|
||||
prev = local64_read(&hwc->prev_count);
|
||||
|
||||
switch (pe->pmu_perf_type) {
|
||||
case PERF_TYPE_AMDGPU_DF:
|
||||
pe->adev->df.funcs->pmc_get_count(pe->adev, hwc->config,
|
||||
&count);
|
||||
switch (hwc->config_base) {
|
||||
case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF:
|
||||
case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI:
|
||||
pe->adev->df.funcs->pmc_get_count(pe->adev,
|
||||
hwc->config, hwc->idx, &count);
|
||||
break;
|
||||
default:
|
||||
count = 0;
|
||||
|
@ -124,9 +297,11 @@ static void amdgpu_perf_stop(struct perf_event *event, int flags)
|
|||
if (hwc->state & PERF_HES_UPTODATE)
|
||||
return;
|
||||
|
||||
switch (pe->pmu_perf_type) {
|
||||
case PERF_TYPE_AMDGPU_DF:
|
||||
pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, 0);
|
||||
switch (hwc->config_base) {
|
||||
case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF:
|
||||
case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI:
|
||||
pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, hwc->idx,
|
||||
0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -142,22 +317,39 @@ static void amdgpu_perf_stop(struct perf_event *event, int flags)
|
|||
hwc->state |= PERF_HES_UPTODATE;
|
||||
}
|
||||
|
||||
/* add perf counter */
|
||||
/* add perf counter */
|
||||
static int amdgpu_perf_add(struct perf_event *event, int flags)
|
||||
{
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
int retval;
|
||||
|
||||
int retval = 0, target_cntr;
|
||||
struct amdgpu_pmu_entry *pe = container_of(event->pmu,
|
||||
struct amdgpu_pmu_entry,
|
||||
pmu);
|
||||
|
||||
switch (pe->pmu_perf_type) {
|
||||
case AMDGPU_PMU_PERF_TYPE_DF:
|
||||
hwc->config_base = AMDGPU_PMU_EVENT_CONFIG_TYPE_DF;
|
||||
break;
|
||||
case AMDGPU_PMU_PERF_TYPE_ALL:
|
||||
hwc->config_base = (hwc->config >>
|
||||
AMDGPU_PMU_EVENT_CONFIG_TYPE_SHIFT) &
|
||||
AMDGPU_PMU_EVENT_CONFIG_TYPE_MASK;
|
||||
break;
|
||||
}
|
||||
|
||||
event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
|
||||
|
||||
switch (pe->pmu_perf_type) {
|
||||
case PERF_TYPE_AMDGPU_DF:
|
||||
retval = pe->adev->df.funcs->pmc_start(pe->adev,
|
||||
hwc->config, 1);
|
||||
switch (hwc->config_base) {
|
||||
case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF:
|
||||
case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI:
|
||||
target_cntr = pe->adev->df.funcs->pmc_start(pe->adev,
|
||||
hwc->config, 0 /* unused */,
|
||||
1 /* add counter */);
|
||||
if (target_cntr < 0)
|
||||
retval = target_cntr;
|
||||
else
|
||||
hwc->idx = target_cntr;
|
||||
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
|
@ -170,7 +362,6 @@ static int amdgpu_perf_add(struct perf_event *event, int flags)
|
|||
amdgpu_perf_start(event, PERF_EF_RELOAD);
|
||||
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
||||
/* delete perf counter */
|
||||
|
@ -183,9 +374,11 @@ static void amdgpu_perf_del(struct perf_event *event, int flags)
|
|||
|
||||
amdgpu_perf_stop(event, PERF_EF_UPDATE);
|
||||
|
||||
switch (pe->pmu_perf_type) {
|
||||
case PERF_TYPE_AMDGPU_DF:
|
||||
pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, 1);
|
||||
switch (hwc->config_base) {
|
||||
case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF:
|
||||
case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI:
|
||||
pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, hwc->idx,
|
||||
1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -194,25 +387,92 @@ static void amdgpu_perf_del(struct perf_event *event, int flags)
|
|||
perf_event_update_userpage(event);
|
||||
}
|
||||
|
||||
/* vega20 pmus */
|
||||
|
||||
/* init pmu tracking per pmu type */
|
||||
static int init_pmu_by_type(struct amdgpu_device *adev,
|
||||
const struct attribute_group *attr_groups[],
|
||||
char *pmu_type_name, char *pmu_file_prefix,
|
||||
unsigned int pmu_perf_type,
|
||||
unsigned int num_counters)
|
||||
static void amdgpu_pmu_create_event_attrs_by_type(
|
||||
struct attribute_group *attr_group,
|
||||
struct amdgpu_pmu_event_attribute *pmu_attr,
|
||||
struct amdgpu_pmu_attr events[],
|
||||
int s_offset,
|
||||
int e_offset,
|
||||
unsigned int type)
|
||||
{
|
||||
char pmu_name[PMU_NAME_SIZE];
|
||||
struct amdgpu_pmu_entry *pmu_entry;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
pmu_entry = kzalloc(sizeof(struct amdgpu_pmu_entry), GFP_KERNEL);
|
||||
pmu_attr += s_offset;
|
||||
|
||||
if (!pmu_entry)
|
||||
for (i = s_offset; i < e_offset; i++) {
|
||||
attr_group->attrs[i] = &pmu_attr->attr.attr;
|
||||
sysfs_attr_init(&pmu_attr->attr.attr);
|
||||
pmu_attr->attr.attr.name = events[i].name;
|
||||
pmu_attr->attr.attr.mode = 0444;
|
||||
pmu_attr->attr.show = amdgpu_pmu_event_show;
|
||||
pmu_attr->event_str = events[i].config;
|
||||
pmu_attr->type = type;
|
||||
pmu_attr++;
|
||||
}
|
||||
}
|
||||
|
||||
static void amdgpu_pmu_create_attrs(struct attribute_group *attr_group,
|
||||
struct amdgpu_pmu_event_attribute *pmu_attr,
|
||||
struct amdgpu_pmu_attr events[],
|
||||
int num_events)
|
||||
{
|
||||
amdgpu_pmu_create_event_attrs_by_type(attr_group, pmu_attr, events, 0,
|
||||
num_events, AMDGPU_PMU_EVENT_CONFIG_TYPE_NONE);
|
||||
}
|
||||
|
||||
|
||||
static int amdgpu_pmu_alloc_pmu_attrs(
|
||||
struct attribute_group *fmt_attr_group,
|
||||
struct amdgpu_pmu_event_attribute **fmt_attr,
|
||||
struct attribute_group *evt_attr_group,
|
||||
struct amdgpu_pmu_event_attribute **evt_attr,
|
||||
struct amdgpu_pmu_config *config)
|
||||
{
|
||||
*fmt_attr = kcalloc(config->num_formats, sizeof(**fmt_attr),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!(*fmt_attr))
|
||||
return -ENOMEM;
|
||||
|
||||
pmu_entry->adev = adev;
|
||||
fmt_attr_group->attrs = kcalloc(config->num_formats + 1,
|
||||
sizeof(*fmt_attr_group->attrs), GFP_KERNEL);
|
||||
|
||||
if (!fmt_attr_group->attrs)
|
||||
goto err_fmt_attr_grp;
|
||||
|
||||
*evt_attr = kcalloc(config->num_events, sizeof(**evt_attr), GFP_KERNEL);
|
||||
|
||||
if (!(*evt_attr))
|
||||
goto err_evt_attr;
|
||||
|
||||
evt_attr_group->attrs = kcalloc(config->num_events + 1,
|
||||
sizeof(*evt_attr_group->attrs), GFP_KERNEL);
|
||||
|
||||
if (!evt_attr_group->attrs)
|
||||
goto err_evt_attr_grp;
|
||||
|
||||
return 0;
|
||||
err_evt_attr_grp:
|
||||
kfree(*evt_attr);
|
||||
err_evt_attr:
|
||||
kfree(fmt_attr_group->attrs);
|
||||
err_fmt_attr_grp:
|
||||
kfree(*fmt_attr);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* init pmu tracking per pmu type */
|
||||
static int init_pmu_entry_by_type_and_add(struct amdgpu_pmu_entry *pmu_entry,
|
||||
struct amdgpu_pmu_config *config)
|
||||
{
|
||||
const struct attribute_group *attr_groups[] = {
|
||||
&pmu_entry->fmt_attr_group,
|
||||
&pmu_entry->evt_attr_group,
|
||||
NULL
|
||||
};
|
||||
char pmu_name[PMU_NAME_SIZE];
|
||||
int ret = 0, total_num_events = 0;
|
||||
|
||||
pmu_entry->pmu = (struct pmu){
|
||||
.event_init = amdgpu_perf_event_init,
|
||||
.add = amdgpu_perf_add,
|
||||
|
@ -223,59 +483,178 @@ static int init_pmu_by_type(struct amdgpu_device *adev,
|
|||
.task_ctx_nr = perf_invalid_context,
|
||||
};
|
||||
|
||||
pmu_entry->pmu.attr_groups = attr_groups;
|
||||
pmu_entry->pmu_perf_type = pmu_perf_type;
|
||||
snprintf(pmu_name, PMU_NAME_SIZE, "%s_%d",
|
||||
pmu_file_prefix, adev_to_drm(adev)->primary->index);
|
||||
ret = amdgpu_pmu_alloc_pmu_attrs(&pmu_entry->fmt_attr_group,
|
||||
&pmu_entry->fmt_attr,
|
||||
&pmu_entry->evt_attr_group,
|
||||
&pmu_entry->evt_attr,
|
||||
config);
|
||||
|
||||
if (ret)
|
||||
goto err_out;
|
||||
|
||||
amdgpu_pmu_create_attrs(&pmu_entry->fmt_attr_group, pmu_entry->fmt_attr,
|
||||
config->formats, config->num_formats);
|
||||
|
||||
if (pmu_entry->pmu_perf_type == AMDGPU_PMU_PERF_TYPE_ALL) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < config->num_types; i++) {
|
||||
amdgpu_pmu_create_event_attrs_by_type(
|
||||
&pmu_entry->evt_attr_group,
|
||||
pmu_entry->evt_attr,
|
||||
config->events,
|
||||
total_num_events,
|
||||
total_num_events +
|
||||
config->types[i].num_of_type,
|
||||
config->types[i].type);
|
||||
total_num_events += config->types[i].num_of_type;
|
||||
}
|
||||
} else {
|
||||
amdgpu_pmu_create_attrs(&pmu_entry->evt_attr_group,
|
||||
pmu_entry->evt_attr,
|
||||
config->events, config->num_events);
|
||||
total_num_events = config->num_events;
|
||||
}
|
||||
|
||||
pmu_entry->pmu.attr_groups = kmemdup(attr_groups, sizeof(attr_groups),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!pmu_entry->pmu.attr_groups)
|
||||
goto err_attr_group;
|
||||
|
||||
snprintf(pmu_name, PMU_NAME_SIZE, "%s_%d", pmu_entry->pmu_file_prefix,
|
||||
adev_to_drm(pmu_entry->adev)->primary->index);
|
||||
|
||||
ret = perf_pmu_register(&pmu_entry->pmu, pmu_name, -1);
|
||||
|
||||
if (ret) {
|
||||
kfree(pmu_entry);
|
||||
pr_warn("Error initializing AMDGPU %s PMUs.\n", pmu_type_name);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
goto err_register;
|
||||
|
||||
if (pmu_entry->pmu_perf_type != AMDGPU_PMU_PERF_TYPE_ALL)
|
||||
pr_info("Detected AMDGPU %s Counters. # of Counters = %d.\n",
|
||||
pmu_entry->pmu_type_name, total_num_events);
|
||||
else
|
||||
pr_info("Detected AMDGPU %d Perf Events.\n", total_num_events);
|
||||
|
||||
pr_info("Detected AMDGPU %s Counters. # of Counters = %d.\n",
|
||||
pmu_type_name, num_counters);
|
||||
|
||||
list_add_tail(&pmu_entry->entry, &amdgpu_pmu_list);
|
||||
|
||||
return 0;
|
||||
err_register:
|
||||
kfree(pmu_entry->pmu.attr_groups);
|
||||
err_attr_group:
|
||||
kfree(pmu_entry->fmt_attr_group.attrs);
|
||||
kfree(pmu_entry->fmt_attr);
|
||||
kfree(pmu_entry->evt_attr_group.attrs);
|
||||
kfree(pmu_entry->evt_attr);
|
||||
err_out:
|
||||
pr_warn("Error initializing AMDGPU %s PMUs.\n",
|
||||
pmu_entry->pmu_type_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* init amdgpu_pmu */
|
||||
int amdgpu_pmu_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
/* init df */
|
||||
ret = init_pmu_by_type(adev, df_v3_6_attr_groups,
|
||||
"DF", "amdgpu_df", PERF_TYPE_AMDGPU_DF,
|
||||
DF_V3_6_MAX_COUNTERS);
|
||||
|
||||
/* other pmu types go here*/
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* destroy all pmu data associated with target device */
|
||||
void amdgpu_pmu_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_pmu_entry *pe, *temp;
|
||||
|
||||
list_for_each_entry_safe(pe, temp, &amdgpu_pmu_list, entry) {
|
||||
if (pe->adev == adev) {
|
||||
list_del(&pe->entry);
|
||||
perf_pmu_unregister(&pe->pmu);
|
||||
kfree(pe);
|
||||
}
|
||||
if (pe->adev != adev)
|
||||
continue;
|
||||
list_del(&pe->entry);
|
||||
perf_pmu_unregister(&pe->pmu);
|
||||
kfree(pe->pmu.attr_groups);
|
||||
kfree(pe->fmt_attr_group.attrs);
|
||||
kfree(pe->fmt_attr);
|
||||
kfree(pe->evt_attr_group.attrs);
|
||||
kfree(pe->evt_attr);
|
||||
kfree(pe);
|
||||
}
|
||||
}
|
||||
|
||||
static struct amdgpu_pmu_entry *create_pmu_entry(struct amdgpu_device *adev,
|
||||
unsigned int pmu_type,
|
||||
char *pmu_type_name,
|
||||
char *pmu_file_prefix)
|
||||
{
|
||||
struct amdgpu_pmu_entry *pmu_entry;
|
||||
|
||||
pmu_entry = kzalloc(sizeof(struct amdgpu_pmu_entry), GFP_KERNEL);
|
||||
|
||||
if (!pmu_entry)
|
||||
return pmu_entry;
|
||||
|
||||
pmu_entry->adev = adev;
|
||||
pmu_entry->fmt_attr_group.name = "format";
|
||||
pmu_entry->fmt_attr_group.attrs = NULL;
|
||||
pmu_entry->evt_attr_group.name = "events";
|
||||
pmu_entry->evt_attr_group.attrs = NULL;
|
||||
pmu_entry->pmu_perf_type = pmu_type;
|
||||
pmu_entry->pmu_type_name = pmu_type_name;
|
||||
pmu_entry->pmu_file_prefix = pmu_file_prefix;
|
||||
|
||||
return pmu_entry;
|
||||
}
|
||||
|
||||
/* init amdgpu_pmu */
|
||||
int amdgpu_pmu_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct amdgpu_pmu_entry *pmu_entry, *pmu_entry_df;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
pmu_entry_df = create_pmu_entry(adev, AMDGPU_PMU_PERF_TYPE_DF,
|
||||
"DF", "amdgpu_df");
|
||||
|
||||
if (!pmu_entry_df)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = init_pmu_entry_by_type_and_add(pmu_entry_df,
|
||||
&df_vega20_config);
|
||||
|
||||
if (ret) {
|
||||
kfree(pmu_entry_df);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pmu_entry = create_pmu_entry(adev, AMDGPU_PMU_PERF_TYPE_ALL,
|
||||
"", "amdgpu");
|
||||
|
||||
if (!pmu_entry) {
|
||||
amdgpu_pmu_fini(adev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = init_pmu_entry_by_type_and_add(pmu_entry,
|
||||
&vega20_config);
|
||||
|
||||
if (ret) {
|
||||
kfree(pmu_entry);
|
||||
amdgpu_pmu_fini(adev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
break;
|
||||
case CHIP_ARCTURUS:
|
||||
pmu_entry = create_pmu_entry(adev, AMDGPU_PMU_PERF_TYPE_ALL,
|
||||
"", "amdgpu");
|
||||
if (!pmu_entry)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = init_pmu_entry_by_type_and_add(pmu_entry,
|
||||
&arcturus_config);
|
||||
|
||||
if (ret) {
|
||||
kfree(pmu_entry);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -19,18 +19,38 @@
|
|||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Jonathan Kim <jonathan.kim@amd.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AMDGPU_PMU_H_
|
||||
#define _AMDGPU_PMU_H_
|
||||
|
||||
/* PMU types. */
|
||||
enum amdgpu_pmu_perf_type {
|
||||
PERF_TYPE_AMDGPU_DF = 0,
|
||||
PERF_TYPE_AMDGPU_MAX
|
||||
AMDGPU_PMU_PERF_TYPE_NONE = 0,
|
||||
AMDGPU_PMU_PERF_TYPE_DF,
|
||||
AMDGPU_PMU_PERF_TYPE_ALL
|
||||
};
|
||||
|
||||
/*
|
||||
* PMU type AMDGPU_PMU_PERF_TYPE_ALL can hold events of different "type"
|
||||
* configurations. Event config types are parsed from the 64-bit raw
|
||||
* config (See EVENT_CONFIG_TYPE_SHIFT and EVENT_CONFIG_TYPE_MASK) and
|
||||
* are registered into the HW perf events config_base.
|
||||
*
|
||||
* PMU types with only a single event configuration type
|
||||
* (non-AMDGPU_PMU_PERF_TYPE_ALL) have their event config type auto generated
|
||||
* when the performance counter is added.
|
||||
*/
|
||||
enum amdgpu_pmu_event_config_type {
|
||||
AMDGPU_PMU_EVENT_CONFIG_TYPE_NONE = 0,
|
||||
AMDGPU_PMU_EVENT_CONFIG_TYPE_DF,
|
||||
AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI,
|
||||
AMDGPU_PMU_EVENT_CONFIG_TYPE_MAX
|
||||
};
|
||||
|
||||
#define AMDGPU_PMU_EVENT_CONFIG_TYPE_SHIFT 56
|
||||
#define AMDGPU_PMU_EVENT_CONFIG_TYPE_MASK 0xff
|
||||
|
||||
int amdgpu_pmu_init(struct amdgpu_device *adev);
|
||||
void amdgpu_pmu_fini(struct amdgpu_device *adev);
|
||||
|
||||
|
|
|
@ -100,6 +100,8 @@ static int psp_early_init(void *handle)
|
|||
case CHIP_NAVI12:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
psp_v11_0_set_psp_funcs(psp);
|
||||
psp->autoload_supported = true;
|
||||
break;
|
||||
|
@ -288,6 +290,8 @@ psp_cmd_submit_buf(struct psp_context *psp,
|
|||
skip_unsupport = (psp->cmd_buf_mem->resp.status == TEE_ERROR_NOT_SUPPORTED ||
|
||||
psp->cmd_buf_mem->resp.status == PSP_ERR_UNKNOWN_COMMAND) && amdgpu_sriov_vf(psp->adev);
|
||||
|
||||
memcpy((void*)&cmd->resp, (void*)&psp->cmd_buf_mem->resp, sizeof(struct psp_gfx_resp));
|
||||
|
||||
/* In some cases, psp response status is not 0 even there is no
|
||||
* problem while the command is submitted. Some version of PSP FW
|
||||
* doesn't write 0 to that field.
|
||||
|
@ -308,9 +312,6 @@ psp_cmd_submit_buf(struct psp_context *psp,
|
|||
}
|
||||
}
|
||||
|
||||
/* get xGMI session id from response buffer */
|
||||
cmd->resp.session_id = psp->cmd_buf_mem->resp.session_id;
|
||||
|
||||
if (ucode) {
|
||||
ucode->tmr_mc_addr_lo = psp->cmd_buf_mem->resp.fw_addr_lo;
|
||||
ucode->tmr_mc_addr_hi = psp->cmd_buf_mem->resp.fw_addr_hi;
|
||||
|
@ -509,6 +510,37 @@ static int psp_tmr_terminate(struct psp_context *psp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int psp_get_fw_attestation_records_addr(struct psp_context *psp,
|
||||
uint64_t *output_ptr)
|
||||
{
|
||||
int ret;
|
||||
struct psp_gfx_cmd_resp *cmd;
|
||||
|
||||
if (!output_ptr)
|
||||
return -EINVAL;
|
||||
|
||||
if (amdgpu_sriov_vf(psp->adev))
|
||||
return 0;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd->cmd_id = GFX_CMD_ID_GET_FW_ATTESTATION;
|
||||
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd,
|
||||
psp->fence_buf_mc_addr);
|
||||
|
||||
if (!ret) {
|
||||
*output_ptr = ((uint64_t)cmd->resp.uresp.fwar_db_info.fwar_db_addr_lo) +
|
||||
((uint64_t)cmd->resp.uresp.fwar_db_info.fwar_db_addr_hi << 32);
|
||||
}
|
||||
|
||||
kfree(cmd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void psp_prep_asd_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
|
||||
uint64_t asd_mc, uint32_t size)
|
||||
{
|
||||
|
@ -624,14 +656,14 @@ static void psp_prep_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
|
|||
uint64_t ta_shared_mc,
|
||||
uint32_t ta_shared_size)
|
||||
{
|
||||
cmd->cmd_id = GFX_CMD_ID_LOAD_TA;
|
||||
cmd->cmd_id = GFX_CMD_ID_LOAD_TA;
|
||||
cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(ta_bin_mc);
|
||||
cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(ta_bin_mc);
|
||||
cmd->cmd.cmd_load_ta.app_len = ta_bin_size;
|
||||
cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(ta_bin_mc);
|
||||
cmd->cmd.cmd_load_ta.app_len = ta_bin_size;
|
||||
|
||||
cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(ta_shared_mc);
|
||||
cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(ta_shared_mc);
|
||||
cmd->cmd.cmd_load_ta.cmd_buf_len = ta_shared_size;
|
||||
cmd->cmd.cmd_load_ta.cmd_buf_len = ta_shared_size;
|
||||
}
|
||||
|
||||
static int psp_xgmi_init_shared_buf(struct psp_context *psp)
|
||||
|
@ -655,9 +687,9 @@ static void psp_prep_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd,
|
|||
uint32_t ta_cmd_id,
|
||||
uint32_t session_id)
|
||||
{
|
||||
cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD;
|
||||
cmd->cmd.cmd_invoke_cmd.session_id = session_id;
|
||||
cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id;
|
||||
cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD;
|
||||
cmd->cmd.cmd_invoke_cmd.session_id = session_id;
|
||||
cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id;
|
||||
}
|
||||
|
||||
static int psp_ta_invoke(struct psp_context *psp,
|
||||
|
@ -806,7 +838,7 @@ int psp_xgmi_get_hive_id(struct psp_context *psp, uint64_t *hive_id)
|
|||
struct ta_xgmi_shared_memory *xgmi_cmd;
|
||||
int ret;
|
||||
|
||||
xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf;
|
||||
xgmi_cmd = (struct ta_xgmi_shared_memory *)psp->xgmi_context.xgmi_shared_buf;
|
||||
memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory));
|
||||
|
||||
xgmi_cmd->cmd_id = TA_COMMAND_XGMI__GET_HIVE_ID;
|
||||
|
@ -826,7 +858,7 @@ int psp_xgmi_get_node_id(struct psp_context *psp, uint64_t *node_id)
|
|||
struct ta_xgmi_shared_memory *xgmi_cmd;
|
||||
int ret;
|
||||
|
||||
xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf;
|
||||
xgmi_cmd = (struct ta_xgmi_shared_memory *)psp->xgmi_context.xgmi_shared_buf;
|
||||
memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory));
|
||||
|
||||
xgmi_cmd->cmd_id = TA_COMMAND_XGMI__GET_NODE_ID;
|
||||
|
@ -854,7 +886,7 @@ int psp_xgmi_get_topology_info(struct psp_context *psp,
|
|||
if (!topology || topology->num_nodes > TA_XGMI__MAX_CONNECTED_NODES)
|
||||
return -EINVAL;
|
||||
|
||||
xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf;
|
||||
xgmi_cmd = (struct ta_xgmi_shared_memory *)psp->xgmi_context.xgmi_shared_buf;
|
||||
memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory));
|
||||
|
||||
/* Fill in the shared memory with topology information as input */
|
||||
|
@ -898,7 +930,7 @@ int psp_xgmi_set_topology_info(struct psp_context *psp,
|
|||
if (!topology || topology->num_nodes > TA_XGMI__MAX_CONNECTED_NODES)
|
||||
return -EINVAL;
|
||||
|
||||
xgmi_cmd = (struct ta_xgmi_shared_memory*)psp->xgmi_context.xgmi_shared_buf;
|
||||
xgmi_cmd = (struct ta_xgmi_shared_memory *)psp->xgmi_context.xgmi_shared_buf;
|
||||
memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory));
|
||||
|
||||
topology_info_input = &xgmi_cmd->xgmi_in_message.get_topology_info;
|
||||
|
@ -962,7 +994,7 @@ static int psp_ras_load(struct psp_context *psp)
|
|||
ret = psp_cmd_submit_buf(psp, NULL, cmd,
|
||||
psp->fence_buf_mc_addr);
|
||||
|
||||
ras_cmd = (struct ta_ras_shared_memory*)psp->ras.ras_shared_buf;
|
||||
ras_cmd = (struct ta_ras_shared_memory *)psp->ras.ras_shared_buf;
|
||||
|
||||
if (!ret) {
|
||||
psp->ras.session_id = cmd->resp.session_id;
|
||||
|
@ -1884,7 +1916,7 @@ static int psp_execute_np_fw_load(struct psp_context *psp,
|
|||
static int psp_load_smu_fw(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
struct amdgpu_device* adev = psp->adev;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
struct amdgpu_firmware_info *ucode =
|
||||
&adev->firmware.ucode[AMDGPU_UCODE_ID_SMC];
|
||||
struct amdgpu_ras *ras = psp->ras.ras;
|
||||
|
@ -1950,7 +1982,7 @@ static int psp_np_fw_load(struct psp_context *psp)
|
|||
{
|
||||
int i, ret;
|
||||
struct amdgpu_firmware_info *ucode;
|
||||
struct amdgpu_device* adev = psp->adev;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
if (psp->autoload_supported &&
|
||||
!psp->pmfw_centralized_cstate_management) {
|
||||
|
@ -1974,8 +2006,8 @@ static int psp_np_fw_load(struct psp_context *psp)
|
|||
continue;
|
||||
|
||||
if (psp->autoload_supported &&
|
||||
(adev->asic_type == CHIP_SIENNA_CICHLID ||
|
||||
adev->asic_type == CHIP_NAVY_FLOUNDER) &&
|
||||
(adev->asic_type >= CHIP_SIENNA_CICHLID &&
|
||||
adev->asic_type <= CHIP_DIMGREY_CAVEFISH) &&
|
||||
(ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1 ||
|
||||
ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2 ||
|
||||
ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3))
|
||||
|
@ -2390,7 +2422,7 @@ int psp_init_asd_microcode(struct psp_context *psp,
|
|||
const char *chip_name)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
char fw_name[30];
|
||||
char fw_name[PSP_FW_NAME_LEN];
|
||||
const struct psp_firmware_header_v1_0 *asd_hdr;
|
||||
int err = 0;
|
||||
|
||||
|
@ -2422,11 +2454,47 @@ out:
|
|||
return err;
|
||||
}
|
||||
|
||||
int psp_init_sos_microcode(struct psp_context *psp,
|
||||
int psp_init_toc_microcode(struct psp_context *psp,
|
||||
const char *chip_name)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
char fw_name[30];
|
||||
const struct psp_firmware_header_v1_0 *toc_hdr;
|
||||
int err = 0;
|
||||
|
||||
if (!chip_name) {
|
||||
dev_err(adev->dev, "invalid chip name for toc microcode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_toc.bin", chip_name);
|
||||
err = request_firmware(&adev->psp.toc_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = amdgpu_ucode_validate(adev->psp.toc_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
toc_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.toc_fw->data;
|
||||
adev->psp.toc_fw_version = le32_to_cpu(toc_hdr->header.ucode_version);
|
||||
adev->psp.toc_feature_version = le32_to_cpu(toc_hdr->ucode_feature_version);
|
||||
adev->psp.toc_bin_size = le32_to_cpu(toc_hdr->header.ucode_size_bytes);
|
||||
adev->psp.toc_start_addr = (uint8_t *)toc_hdr +
|
||||
le32_to_cpu(toc_hdr->header.ucode_array_offset_bytes);
|
||||
return 0;
|
||||
out:
|
||||
dev_err(adev->dev, "fail to request/validate toc microcode\n");
|
||||
release_firmware(adev->psp.toc_fw);
|
||||
adev->psp.toc_fw = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
int psp_init_sos_microcode(struct psp_context *psp,
|
||||
const char *chip_name)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
char fw_name[PSP_FW_NAME_LEN];
|
||||
const struct psp_firmware_header_v1_0 *sos_hdr;
|
||||
const struct psp_firmware_header_v1_1 *sos_hdr_v1_1;
|
||||
const struct psp_firmware_header_v1_2 *sos_hdr_v1_2;
|
||||
|
@ -2520,10 +2588,11 @@ int parse_ta_bin_descriptor(struct psp_context *psp,
|
|||
|
||||
switch (desc->fw_type) {
|
||||
case TA_FW_TYPE_PSP_ASD:
|
||||
psp->asd_fw_version = le32_to_cpu(desc->fw_version);
|
||||
psp->asd_fw_version = le32_to_cpu(desc->fw_version);
|
||||
psp->asd_feature_version = le32_to_cpu(desc->fw_version);
|
||||
psp->asd_ucode_size = le32_to_cpu(desc->size_bytes);
|
||||
psp->asd_ucode_size = le32_to_cpu(desc->size_bytes);
|
||||
psp->asd_start_addr = ucode_start_addr;
|
||||
psp->asd_fw = psp->ta_fw;
|
||||
break;
|
||||
case TA_FW_TYPE_PSP_XGMI:
|
||||
psp->ta_xgmi_ucode_version = le32_to_cpu(desc->fw_version);
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#define PSP_DTM_SHARED_MEM_SIZE 0x4000
|
||||
#define PSP_RAP_SHARED_MEM_SIZE 0x4000
|
||||
#define PSP_SHARED_MEM_SIZE 0x4000
|
||||
#define PSP_FW_NAME_LEN 0x24
|
||||
|
||||
struct psp_context;
|
||||
struct psp_xgmi_node_info;
|
||||
|
@ -253,6 +254,11 @@ struct psp_context
|
|||
uint32_t asd_ucode_size;
|
||||
uint8_t *asd_start_addr;
|
||||
|
||||
/* toc firmware */
|
||||
const struct firmware *toc_fw;
|
||||
uint32_t toc_fw_version;
|
||||
uint32_t toc_feature_version;
|
||||
|
||||
/* fence buffer */
|
||||
struct amdgpu_bo *fence_buf_bo;
|
||||
uint64_t fence_buf_mc_addr;
|
||||
|
@ -386,8 +392,12 @@ int psp_ring_cmd_submit(struct psp_context *psp,
|
|||
int index);
|
||||
int psp_init_asd_microcode(struct psp_context *psp,
|
||||
const char *chip_name);
|
||||
int psp_init_toc_microcode(struct psp_context *psp,
|
||||
const char *chip_name);
|
||||
int psp_init_sos_microcode(struct psp_context *psp,
|
||||
const char *chip_name);
|
||||
int psp_init_ta_microcode(struct psp_context *psp,
|
||||
const char *chip_name);
|
||||
int psp_get_fw_attestation_records_addr(struct psp_context *psp,
|
||||
uint64_t *output_ptr);
|
||||
#endif
|
||||
|
|
|
@ -80,6 +80,8 @@ enum amdgpu_ras_retire_page_reservation {
|
|||
|
||||
atomic_t amdgpu_ras_in_intr = ATOMIC_INIT(0);
|
||||
|
||||
static bool amdgpu_ras_check_bad_page_unlock(struct amdgpu_ras *con,
|
||||
uint64_t addr);
|
||||
static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev,
|
||||
uint64_t addr);
|
||||
|
||||
|
@ -516,9 +518,9 @@ struct ras_manager *amdgpu_ras_find_obj(struct amdgpu_device *adev,
|
|||
/* obj end */
|
||||
|
||||
static void amdgpu_ras_parse_status_code(struct amdgpu_device *adev,
|
||||
const char* invoke_type,
|
||||
const char* block_name,
|
||||
enum ta_ras_status ret)
|
||||
const char* invoke_type,
|
||||
const char* block_name,
|
||||
enum ta_ras_status ret)
|
||||
{
|
||||
switch (ret) {
|
||||
case TA_RAS_STATUS__SUCCESS:
|
||||
|
@ -607,7 +609,7 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev,
|
|||
if (!con)
|
||||
return -EINVAL;
|
||||
|
||||
info = kzalloc(sizeof(union ta_ras_cmd_input), GFP_KERNEL);
|
||||
info = kzalloc(sizeof(union ta_ras_cmd_input), GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -953,7 +955,7 @@ static char *amdgpu_ras_badpage_flags_str(unsigned int flags)
|
|||
case AMDGPU_RAS_RETIRE_PAGE_FAULT:
|
||||
default:
|
||||
return "F";
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1551,10 +1553,12 @@ static int amdgpu_ras_badpages_read(struct amdgpu_device *adev,
|
|||
.size = AMDGPU_GPU_PAGE_SIZE,
|
||||
.flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED,
|
||||
};
|
||||
|
||||
if (data->last_reserved <= i)
|
||||
ret = amdgpu_vram_mgr_query_page_status(
|
||||
ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM),
|
||||
data->bps[i].retired_page);
|
||||
if (ret == -EBUSY)
|
||||
(*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_PENDING;
|
||||
else if (data->bps_bo[i] == NULL)
|
||||
else if (ret == -ENOENT)
|
||||
(*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_FAULT;
|
||||
}
|
||||
|
||||
|
@ -1606,12 +1610,9 @@ static int amdgpu_ras_realloc_eh_data_space(struct amdgpu_device *adev,
|
|||
unsigned int new_space = old_space + pages;
|
||||
unsigned int align_space = ALIGN(new_space, 512);
|
||||
void *bps = kmalloc(align_space * sizeof(*data->bps), GFP_KERNEL);
|
||||
struct amdgpu_bo **bps_bo =
|
||||
kmalloc(align_space * sizeof(*data->bps_bo), GFP_KERNEL);
|
||||
|
||||
if (!bps || !bps_bo) {
|
||||
if (!bps) {
|
||||
kfree(bps);
|
||||
kfree(bps_bo);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -1620,14 +1621,8 @@ static int amdgpu_ras_realloc_eh_data_space(struct amdgpu_device *adev,
|
|||
data->count * sizeof(*data->bps));
|
||||
kfree(data->bps);
|
||||
}
|
||||
if (data->bps_bo) {
|
||||
memcpy(bps_bo, data->bps_bo,
|
||||
data->count * sizeof(*data->bps_bo));
|
||||
kfree(data->bps_bo);
|
||||
}
|
||||
|
||||
data->bps = bps;
|
||||
data->bps_bo = bps_bo;
|
||||
data->space_left += align_space - old_space;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1639,6 +1634,7 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev,
|
|||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
struct ras_err_handler_data *data;
|
||||
int ret = 0;
|
||||
uint32_t i;
|
||||
|
||||
if (!con || !con->eh_data || !bps || pages <= 0)
|
||||
return 0;
|
||||
|
@ -1648,16 +1644,26 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev,
|
|||
if (!data)
|
||||
goto out;
|
||||
|
||||
if (data->space_left <= pages)
|
||||
if (amdgpu_ras_realloc_eh_data_space(adev, data, pages)) {
|
||||
for (i = 0; i < pages; i++) {
|
||||
if (amdgpu_ras_check_bad_page_unlock(con,
|
||||
bps[i].retired_page << AMDGPU_GPU_PAGE_SHIFT))
|
||||
continue;
|
||||
|
||||
if (!data->space_left &&
|
||||
amdgpu_ras_realloc_eh_data_space(adev, data, 256)) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(&data->bps[data->count], bps, pages * sizeof(*data->bps));
|
||||
data->count += pages;
|
||||
data->space_left -= pages;
|
||||
amdgpu_vram_mgr_reserve_range(
|
||||
ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM),
|
||||
bps[i].retired_page << AMDGPU_GPU_PAGE_SHIFT,
|
||||
AMDGPU_GPU_PAGE_SIZE);
|
||||
|
||||
memcpy(&data->bps[data->count], &bps[i], sizeof(*data->bps));
|
||||
data->count++;
|
||||
data->space_left--;
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&con->recovery_lock);
|
||||
|
||||
|
@ -1668,7 +1674,7 @@ out:
|
|||
* write error record array to eeprom, the function should be
|
||||
* protected by recovery_lock
|
||||
*/
|
||||
static int amdgpu_ras_save_bad_pages(struct amdgpu_device *adev)
|
||||
int amdgpu_ras_save_bad_pages(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
struct ras_err_handler_data *data;
|
||||
|
@ -1730,6 +1736,20 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool amdgpu_ras_check_bad_page_unlock(struct amdgpu_ras *con,
|
||||
uint64_t addr)
|
||||
{
|
||||
struct ras_err_handler_data *data = con->eh_data;
|
||||
int i;
|
||||
|
||||
addr >>= AMDGPU_GPU_PAGE_SHIFT;
|
||||
for (i = 0; i < data->count; i++)
|
||||
if (addr == data->bps[i].retired_page)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* check if an address belongs to bad page
|
||||
*
|
||||
|
@ -1739,26 +1759,13 @@ static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev,
|
|||
uint64_t addr)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
struct ras_err_handler_data *data;
|
||||
int i;
|
||||
bool ret = false;
|
||||
|
||||
if (!con || !con->eh_data)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&con->recovery_lock);
|
||||
data = con->eh_data;
|
||||
if (!data)
|
||||
goto out;
|
||||
|
||||
addr >>= AMDGPU_GPU_PAGE_SHIFT;
|
||||
for (i = 0; i < data->count; i++)
|
||||
if (addr == data->bps[i].retired_page) {
|
||||
ret = true;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
ret = amdgpu_ras_check_bad_page_unlock(con, addr);
|
||||
mutex_unlock(&con->recovery_lock);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1804,80 +1811,6 @@ static void amdgpu_ras_validate_threshold(struct amdgpu_device *adev,
|
|||
}
|
||||
}
|
||||
|
||||
/* called in gpu recovery/init */
|
||||
int amdgpu_ras_reserve_bad_pages(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
struct ras_err_handler_data *data;
|
||||
uint64_t bp;
|
||||
struct amdgpu_bo *bo = NULL;
|
||||
int i, ret = 0;
|
||||
|
||||
/* Not reserve bad page when amdgpu_bad_page_threshold == 0. */
|
||||
if (!con || !con->eh_data || (amdgpu_bad_page_threshold == 0))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&con->recovery_lock);
|
||||
data = con->eh_data;
|
||||
if (!data)
|
||||
goto out;
|
||||
/* reserve vram at driver post stage. */
|
||||
for (i = data->last_reserved; i < data->count; i++) {
|
||||
bp = data->bps[i].retired_page;
|
||||
|
||||
/* There are two cases of reserve error should be ignored:
|
||||
* 1) a ras bad page has been allocated (used by someone);
|
||||
* 2) a ras bad page has been reserved (duplicate error injection
|
||||
* for one page);
|
||||
*/
|
||||
if (amdgpu_bo_create_kernel_at(adev, bp << AMDGPU_GPU_PAGE_SHIFT,
|
||||
AMDGPU_GPU_PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&bo, NULL))
|
||||
dev_warn(adev->dev, "RAS WARN: reserve vram for "
|
||||
"retired page %llx fail\n", bp);
|
||||
|
||||
data->bps_bo[i] = bo;
|
||||
data->last_reserved = i + 1;
|
||||
bo = NULL;
|
||||
}
|
||||
|
||||
/* continue to save bad pages to eeprom even reesrve_vram fails */
|
||||
ret = amdgpu_ras_save_bad_pages(adev);
|
||||
out:
|
||||
mutex_unlock(&con->recovery_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* called when driver unload */
|
||||
static int amdgpu_ras_release_bad_pages(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
struct ras_err_handler_data *data;
|
||||
struct amdgpu_bo *bo;
|
||||
int i;
|
||||
|
||||
if (!con || !con->eh_data)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&con->recovery_lock);
|
||||
data = con->eh_data;
|
||||
if (!data)
|
||||
goto out;
|
||||
|
||||
for (i = data->last_reserved - 1; i >= 0; i--) {
|
||||
bo = data->bps_bo[i];
|
||||
|
||||
amdgpu_bo_free_kernel(&bo, NULL, NULL);
|
||||
|
||||
data->bps_bo[i] = bo;
|
||||
data->last_reserved = i;
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&con->recovery_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_ras_recovery_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
|
@ -1917,18 +1850,12 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev)
|
|||
ret = amdgpu_ras_load_bad_pages(adev);
|
||||
if (ret)
|
||||
goto free;
|
||||
ret = amdgpu_ras_reserve_bad_pages(adev);
|
||||
if (ret)
|
||||
goto release;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
release:
|
||||
amdgpu_ras_release_bad_pages(adev);
|
||||
free:
|
||||
kfree((*data)->bps);
|
||||
kfree((*data)->bps_bo);
|
||||
kfree(*data);
|
||||
con->eh_data = NULL;
|
||||
out:
|
||||
|
@ -1956,12 +1883,10 @@ static int amdgpu_ras_recovery_fini(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
|
||||
cancel_work_sync(&con->recovery_work);
|
||||
amdgpu_ras_release_bad_pages(adev);
|
||||
|
||||
mutex_lock(&con->recovery_lock);
|
||||
con->eh_data = NULL;
|
||||
kfree(data->bps);
|
||||
kfree(data->bps_bo);
|
||||
kfree(data);
|
||||
mutex_unlock(&con->recovery_lock);
|
||||
|
||||
|
@ -2156,7 +2081,7 @@ void amdgpu_ras_late_fini(struct amdgpu_device *adev,
|
|||
|
||||
amdgpu_ras_sysfs_remove(adev, ras_block);
|
||||
if (ih_info->cb)
|
||||
amdgpu_ras_interrupt_remove_handler(adev, ih_info);
|
||||
amdgpu_ras_interrupt_remove_handler(adev, ih_info);
|
||||
amdgpu_ras_feature_enable(adev, ras_block, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
|
||||
#define AMDGPU_RAS_FLAG_INIT_BY_VBIOS (0x1 << 0)
|
||||
#define AMDGPU_RAS_FLAG_INIT_NEED_RESET (0x1 << 1)
|
||||
#define AMDGPU_RAS_FLAG_SKIP_BAD_PAGE_RESV (0x1 << 2)
|
||||
|
||||
enum amdgpu_ras_block {
|
||||
AMDGPU_RAS_BLOCK__UMC = 0,
|
||||
|
@ -363,14 +362,10 @@ struct ras_err_data {
|
|||
struct ras_err_handler_data {
|
||||
/* point to bad page records array */
|
||||
struct eeprom_table_record *bps;
|
||||
/* point to reserved bo array */
|
||||
struct amdgpu_bo **bps_bo;
|
||||
/* the count of entries */
|
||||
int count;
|
||||
/* the space can place new entries */
|
||||
int space_left;
|
||||
/* last reserved entry's index + 1 */
|
||||
int last_reserved;
|
||||
};
|
||||
|
||||
typedef int (*ras_ih_cb)(struct amdgpu_device *adev,
|
||||
|
@ -506,22 +501,12 @@ bool amdgpu_ras_check_err_threshold(struct amdgpu_device *adev);
|
|||
int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev,
|
||||
struct eeprom_table_record *bps, int pages);
|
||||
|
||||
int amdgpu_ras_reserve_bad_pages(struct amdgpu_device *adev);
|
||||
int amdgpu_ras_save_bad_pages(struct amdgpu_device *adev);
|
||||
|
||||
static inline int amdgpu_ras_reset_gpu(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
|
||||
|
||||
/*
|
||||
* Save bad page to eeprom before gpu reset, i2c may be unstable
|
||||
* in gpu reset.
|
||||
*
|
||||
* Also, exclude the case when ras recovery issuer is
|
||||
* eeprom page write itself.
|
||||
*/
|
||||
if (!(ras->flags & AMDGPU_RAS_FLAG_SKIP_BAD_PAGE_RESV) && in_task())
|
||||
amdgpu_ras_reserve_bad_pages(adev);
|
||||
|
||||
if (atomic_cmpxchg(&ras->in_recovery, 0, 1) == 0)
|
||||
schedule_work(&ras->recovery_work);
|
||||
return 0;
|
||||
|
|
|
@ -27,9 +27,9 @@
|
|||
#include <linux/bits.h>
|
||||
#include "atom.h"
|
||||
|
||||
#define EEPROM_I2C_TARGET_ADDR_VEGA20 0xA0
|
||||
#define EEPROM_I2C_TARGET_ADDR_ARCTURUS 0xA8
|
||||
#define EEPROM_I2C_TARGET_ADDR_ARCTURUS_D342 0xA0
|
||||
#define EEPROM_I2C_TARGET_ADDR_VEGA20 0xA0
|
||||
#define EEPROM_I2C_TARGET_ADDR_ARCTURUS 0xA8
|
||||
#define EEPROM_I2C_TARGET_ADDR_ARCTURUS_D342 0xA0
|
||||
|
||||
/*
|
||||
* The 2 macros bellow represent the actual size in bytes that
|
||||
|
@ -124,11 +124,11 @@ static void __decode_table_header_from_buff(struct amdgpu_ras_eeprom_table_heade
|
|||
{
|
||||
uint32_t *pp = (uint32_t *)buff;
|
||||
|
||||
hdr->header = le32_to_cpu(pp[0]);
|
||||
hdr->version = le32_to_cpu(pp[1]);
|
||||
hdr->header = le32_to_cpu(pp[0]);
|
||||
hdr->version = le32_to_cpu(pp[1]);
|
||||
hdr->first_rec_offset = le32_to_cpu(pp[2]);
|
||||
hdr->tbl_size = le32_to_cpu(pp[3]);
|
||||
hdr->checksum = le32_to_cpu(pp[4]);
|
||||
hdr->tbl_size = le32_to_cpu(pp[3]);
|
||||
hdr->checksum = le32_to_cpu(pp[4]);
|
||||
}
|
||||
|
||||
static int __update_table_header(struct amdgpu_ras_eeprom_control *control,
|
||||
|
@ -149,7 +149,11 @@ static int __update_table_header(struct amdgpu_ras_eeprom_control *control,
|
|||
|
||||
msg.addr = control->i2c_address;
|
||||
|
||||
/* i2c may be unstable in gpu reset */
|
||||
down_read(&adev->reset_sem);
|
||||
ret = i2c_transfer(&adev->pm.smu_i2c, &msg, 1);
|
||||
up_read(&adev->reset_sem);
|
||||
|
||||
if (ret < 1)
|
||||
DRM_ERROR("Failed to write EEPROM table header, ret:%d", ret);
|
||||
|
||||
|
@ -475,7 +479,6 @@ int amdgpu_ras_eeprom_process_recods(struct amdgpu_ras_eeprom_control *control,
|
|||
int i, ret = 0;
|
||||
struct i2c_msg *msgs, *msg;
|
||||
unsigned char *buffs, *buff;
|
||||
bool sched_ras_recovery = false;
|
||||
struct eeprom_table_record *record;
|
||||
struct amdgpu_device *adev = to_amdgpu_device(control);
|
||||
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
|
||||
|
@ -513,7 +516,6 @@ int amdgpu_ras_eeprom_process_recods(struct amdgpu_ras_eeprom_control *control,
|
|||
"Saved bad pages(%d) reaches threshold value(%d).\n",
|
||||
control->num_recs + num, ras->bad_page_cnt_threshold);
|
||||
control->tbl_hdr.header = EEPROM_TABLE_HDR_BAD;
|
||||
sched_ras_recovery = true;
|
||||
}
|
||||
|
||||
/* In case of overflow just start from beginning to not lose newest records */
|
||||
|
@ -557,7 +559,11 @@ int amdgpu_ras_eeprom_process_recods(struct amdgpu_ras_eeprom_control *control,
|
|||
control->next_addr += EEPROM_TABLE_RECORD_SIZE;
|
||||
}
|
||||
|
||||
/* i2c may be unstable in gpu reset */
|
||||
down_read(&adev->reset_sem);
|
||||
ret = i2c_transfer(&adev->pm.smu_i2c, msgs, num);
|
||||
up_read(&adev->reset_sem);
|
||||
|
||||
if (ret < 1) {
|
||||
DRM_ERROR("Failed to process EEPROM table records, ret:%d", ret);
|
||||
|
||||
|
@ -595,20 +601,6 @@ int amdgpu_ras_eeprom_process_recods(struct amdgpu_ras_eeprom_control *control,
|
|||
__update_tbl_checksum(control, records, num, old_hdr_byte_sum);
|
||||
|
||||
__update_table_header(control, buffs);
|
||||
|
||||
if (sched_ras_recovery) {
|
||||
/*
|
||||
* Before scheduling ras recovery, assert the related
|
||||
* flag first, which shall bypass common bad page
|
||||
* reservation execution in amdgpu_ras_reset_gpu.
|
||||
*/
|
||||
amdgpu_ras_get_context(adev)->flags |=
|
||||
AMDGPU_RAS_FLAG_SKIP_BAD_PAGE_RESV;
|
||||
|
||||
dev_warn(adev->dev, "Conduct ras recovery due to bad "
|
||||
"page threshold reached.\n");
|
||||
amdgpu_ras_reset_gpu(adev);
|
||||
}
|
||||
} else if (!__validate_tbl_checksum(control, records, num)) {
|
||||
DRM_WARN("EEPROM Table checksum mismatch!");
|
||||
/* TODO Uncomment when EEPROM read/write is relliable */
|
||||
|
|
|
@ -396,7 +396,7 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
|
|||
return result;
|
||||
|
||||
value = ring->ring[(*pos - 12)/4];
|
||||
r = put_user(value, (uint32_t*)buf);
|
||||
r = put_user(value, (uint32_t *)buf);
|
||||
if (r)
|
||||
return r;
|
||||
buf += 4;
|
||||
|
|
|
@ -75,7 +75,7 @@ int amdgpu_sa_bo_manager_init(struct amdgpu_device *adev,
|
|||
}
|
||||
|
||||
void amdgpu_sa_bo_manager_fini(struct amdgpu_device *adev,
|
||||
struct amdgpu_sa_manager *sa_manager)
|
||||
struct amdgpu_sa_manager *sa_manager)
|
||||
{
|
||||
struct amdgpu_sa_bo *sa_bo, *tmp;
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ int amdgpu_sdma_ras_late_init(struct amdgpu_device *adev,
|
|||
goto free;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
late_fini:
|
||||
amdgpu_ras_late_fini(adev, adev->sdma.ras_if, ih_info);
|
||||
|
|
|
@ -157,10 +157,10 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
|
|||
i, *vram_start, gart_start,
|
||||
(unsigned long long)
|
||||
(gart_addr - adev->gmc.gart_start +
|
||||
(void*)gart_start - gtt_map),
|
||||
(void *)gart_start - gtt_map),
|
||||
(unsigned long long)
|
||||
(vram_addr - adev->gmc.vram_start +
|
||||
(void*)gart_start - gtt_map));
|
||||
(void *)gart_start - gtt_map));
|
||||
amdgpu_bo_kunmap(vram_obj);
|
||||
goto out_lclean_unpin;
|
||||
}
|
||||
|
@ -203,10 +203,10 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
|
|||
i, *gart_start, vram_start,
|
||||
(unsigned long long)
|
||||
(vram_addr - adev->gmc.vram_start +
|
||||
(void*)vram_start - vram_map),
|
||||
(void *)vram_start - vram_map),
|
||||
(unsigned long long)
|
||||
(gart_addr - adev->gmc.gart_start +
|
||||
(void*)vram_start - vram_map));
|
||||
(void *)vram_start - vram_map));
|
||||
amdgpu_bo_kunmap(gtt_obj[i]);
|
||||
goto out_lclean_unpin;
|
||||
}
|
||||
|
|
|
@ -70,10 +70,10 @@ static void amdgpu_ttm_backend_unbind(struct ttm_bo_device *bdev,
|
|||
|
||||
static int amdgpu_ttm_init_on_chip(struct amdgpu_device *adev,
|
||||
unsigned int type,
|
||||
uint64_t size)
|
||||
uint64_t size_in_page)
|
||||
{
|
||||
return ttm_range_man_init(&adev->mman.bdev, type,
|
||||
false, size >> PAGE_SHIFT);
|
||||
false, size_in_page);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1008,7 +1008,7 @@ void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages)
|
|||
}
|
||||
|
||||
/**
|
||||
* amdgpu_ttm_tt_pin_userptr - prepare the sg table with the user pages
|
||||
* amdgpu_ttm_tt_pin_userptr - prepare the sg table with the user pages
|
||||
*
|
||||
* Called by amdgpu_ttm_backend_bind()
|
||||
**/
|
||||
|
@ -1198,7 +1198,7 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)
|
|||
{
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
|
||||
struct ttm_operation_ctx ctx = { false, false };
|
||||
struct amdgpu_ttm_tt *gtt = (void*)bo->ttm;
|
||||
struct amdgpu_ttm_tt *gtt = (void *)bo->ttm;
|
||||
struct ttm_resource tmp;
|
||||
struct ttm_placement placement;
|
||||
struct ttm_place placements;
|
||||
|
@ -1449,7 +1449,7 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
gtt = (void*)bo->ttm;
|
||||
gtt = (void *)bo->ttm;
|
||||
gtt->userptr = addr;
|
||||
gtt->userflags = flags;
|
||||
|
||||
|
|
|
@ -37,10 +37,17 @@
|
|||
|
||||
#define AMDGPU_POISON 0xd0bed0be
|
||||
|
||||
struct amdgpu_vram_reservation {
|
||||
struct list_head node;
|
||||
struct drm_mm_node mm_node;
|
||||
};
|
||||
|
||||
struct amdgpu_vram_mgr {
|
||||
struct ttm_resource_manager manager;
|
||||
struct drm_mm mm;
|
||||
spinlock_t lock;
|
||||
struct list_head reservations_pending;
|
||||
struct list_head reserved_pages;
|
||||
atomic64_t usage;
|
||||
atomic64_t vis_usage;
|
||||
};
|
||||
|
@ -54,7 +61,6 @@ struct amdgpu_gtt_mgr {
|
|||
|
||||
struct amdgpu_mman {
|
||||
struct ttm_bo_device bdev;
|
||||
bool mem_global_referenced;
|
||||
bool initialized;
|
||||
void __iomem *aper_base_kaddr;
|
||||
|
||||
|
@ -119,6 +125,10 @@ void amdgpu_vram_mgr_free_sgt(struct amdgpu_device *adev,
|
|||
struct sg_table *sgt);
|
||||
uint64_t amdgpu_vram_mgr_usage(struct ttm_resource_manager *man);
|
||||
uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_resource_manager *man);
|
||||
int amdgpu_vram_mgr_reserve_range(struct ttm_resource_manager *man,
|
||||
uint64_t start, uint64_t size);
|
||||
int amdgpu_vram_mgr_query_page_status(struct ttm_resource_manager *man,
|
||||
uint64_t start);
|
||||
|
||||
int amdgpu_ttm_init(struct amdgpu_device *adev);
|
||||
void amdgpu_ttm_late_init(struct amdgpu_device *adev);
|
||||
|
|
|
@ -391,6 +391,8 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type)
|
|||
case CHIP_NAVI12:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
if (!load_type)
|
||||
return AMDGPU_FW_LOAD_DIRECT;
|
||||
else
|
||||
|
@ -586,8 +588,8 @@ static int amdgpu_ucode_patch_jt(struct amdgpu_firmware_info *ucode,
|
|||
{
|
||||
const struct gfx_firmware_header_v1_0 *header = NULL;
|
||||
const struct common_firmware_header *comm_hdr = NULL;
|
||||
uint8_t* src_addr = NULL;
|
||||
uint8_t* dst_addr = NULL;
|
||||
uint8_t *src_addr = NULL;
|
||||
uint8_t *dst_addr = NULL;
|
||||
|
||||
if (NULL == ucode->fw)
|
||||
return 0;
|
||||
|
|
|
@ -126,10 +126,11 @@ int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev,
|
|||
err_data->ue_count);
|
||||
|
||||
if ((amdgpu_bad_page_threshold != 0) &&
|
||||
err_data->err_addr_cnt &&
|
||||
err_data->err_addr_cnt) {
|
||||
amdgpu_ras_add_bad_pages(adev, err_data->err_addr,
|
||||
err_data->err_addr_cnt))
|
||||
dev_warn(adev->dev, "Failed to add ras bad page!\n");
|
||||
err_data->err_addr_cnt);
|
||||
amdgpu_ras_save_bad_pages(adev);
|
||||
}
|
||||
|
||||
amdgpu_ras_reset_gpu(adev);
|
||||
}
|
||||
|
|
|
@ -37,24 +37,30 @@
|
|||
#define FIRMWARE_RAVEN "amdgpu/raven_vcn.bin"
|
||||
#define FIRMWARE_PICASSO "amdgpu/picasso_vcn.bin"
|
||||
#define FIRMWARE_RAVEN2 "amdgpu/raven2_vcn.bin"
|
||||
#define FIRMWARE_ARCTURUS "amdgpu/arcturus_vcn.bin"
|
||||
#define FIRMWARE_RENOIR "amdgpu/renoir_vcn.bin"
|
||||
#define FIRMWARE_NAVI10 "amdgpu/navi10_vcn.bin"
|
||||
#define FIRMWARE_NAVI14 "amdgpu/navi14_vcn.bin"
|
||||
#define FIRMWARE_NAVI12 "amdgpu/navi12_vcn.bin"
|
||||
#define FIRMWARE_SIENNA_CICHLID "amdgpu/sienna_cichlid_vcn.bin"
|
||||
#define FIRMWARE_NAVY_FLOUNDER "amdgpu/navy_flounder_vcn.bin"
|
||||
#define FIRMWARE_ARCTURUS "amdgpu/arcturus_vcn.bin"
|
||||
#define FIRMWARE_RENOIR "amdgpu/renoir_vcn.bin"
|
||||
#define FIRMWARE_GREEN_SARDINE "amdgpu/green_sardine_vcn.bin"
|
||||
#define FIRMWARE_NAVI10 "amdgpu/navi10_vcn.bin"
|
||||
#define FIRMWARE_NAVI14 "amdgpu/navi14_vcn.bin"
|
||||
#define FIRMWARE_NAVI12 "amdgpu/navi12_vcn.bin"
|
||||
#define FIRMWARE_SIENNA_CICHLID "amdgpu/sienna_cichlid_vcn.bin"
|
||||
#define FIRMWARE_NAVY_FLOUNDER "amdgpu/navy_flounder_vcn.bin"
|
||||
#define FIRMWARE_VANGOGH "amdgpu/vangogh_vcn.bin"
|
||||
#define FIRMWARE_DIMGREY_CAVEFISH "amdgpu/dimgrey_cavefish_vcn.bin"
|
||||
|
||||
MODULE_FIRMWARE(FIRMWARE_RAVEN);
|
||||
MODULE_FIRMWARE(FIRMWARE_PICASSO);
|
||||
MODULE_FIRMWARE(FIRMWARE_RAVEN2);
|
||||
MODULE_FIRMWARE(FIRMWARE_ARCTURUS);
|
||||
MODULE_FIRMWARE(FIRMWARE_RENOIR);
|
||||
MODULE_FIRMWARE(FIRMWARE_GREEN_SARDINE);
|
||||
MODULE_FIRMWARE(FIRMWARE_NAVI10);
|
||||
MODULE_FIRMWARE(FIRMWARE_NAVI14);
|
||||
MODULE_FIRMWARE(FIRMWARE_NAVI12);
|
||||
MODULE_FIRMWARE(FIRMWARE_SIENNA_CICHLID);
|
||||
MODULE_FIRMWARE(FIRMWARE_NAVY_FLOUNDER);
|
||||
MODULE_FIRMWARE(FIRMWARE_VANGOGH);
|
||||
MODULE_FIRMWARE(FIRMWARE_DIMGREY_CAVEFISH);
|
||||
|
||||
static void amdgpu_vcn_idle_work_handler(struct work_struct *work);
|
||||
|
||||
|
@ -89,7 +95,11 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
|||
adev->vcn.indirect_sram = true;
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
fw_name = FIRMWARE_RENOIR;
|
||||
if (adev->apu_flags & AMD_APU_IS_RENOIR)
|
||||
fw_name = FIRMWARE_RENOIR;
|
||||
else
|
||||
fw_name = FIRMWARE_GREEN_SARDINE;
|
||||
|
||||
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
||||
adev->vcn.indirect_sram = true;
|
||||
|
@ -124,6 +134,15 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
|||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
||||
adev->vcn.indirect_sram = true;
|
||||
break;
|
||||
case CHIP_VANGOGH:
|
||||
fw_name = FIRMWARE_VANGOGH;
|
||||
break;
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
fw_name = FIRMWARE_DIMGREY_CAVEFISH;
|
||||
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
||||
adev->vcn.indirect_sram = true;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -313,6 +332,7 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
|
|||
container_of(work, struct amdgpu_device, vcn.idle_work.work);
|
||||
unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES] = {0};
|
||||
unsigned int i, j;
|
||||
int r = 0;
|
||||
|
||||
for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
|
||||
if (adev->vcn.harvest_config & (1 << j))
|
||||
|
@ -339,8 +359,13 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
|
|||
}
|
||||
|
||||
if (!fences && !atomic_read(&adev->vcn.total_submission_cnt)) {
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
|
||||
AMD_PG_STATE_GATE);
|
||||
r = amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_VIDEO,
|
||||
false);
|
||||
if (r)
|
||||
dev_warn(adev->dev, "(%d) failed to disable video power profile mode\n", r);
|
||||
} else {
|
||||
schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
|
||||
}
|
||||
|
@ -349,9 +374,17 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
|
|||
void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
int r = 0;
|
||||
|
||||
atomic_inc(&adev->vcn.total_submission_cnt);
|
||||
cancel_delayed_work_sync(&adev->vcn.idle_work);
|
||||
|
||||
if (!cancel_delayed_work_sync(&adev->vcn.idle_work)) {
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
r = amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_VIDEO,
|
||||
true);
|
||||
if (r)
|
||||
dev_warn(adev->dev, "(%d) failed to switch to video power profile mode\n", r);
|
||||
}
|
||||
|
||||
mutex_lock(&adev->vcn.vcn_pg_lock);
|
||||
amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
|
||||
|
|
|
@ -59,7 +59,7 @@ void amdgpu_vf_error_trans_all(struct amdgpu_device *adev)
|
|||
return;
|
||||
}
|
||||
/*
|
||||
TODO: Enable these code when pv2vf_info is merged
|
||||
TODO: Enable these code when pv2vf_info is merged
|
||||
AMDGPU_FW_VRAM_PF2VF_READ (adev, feature_flags, &pf2vf_flags);
|
||||
if (!(pf2vf_flags & AMDGIM_FEATURE_ERROR_LOG_COLLECT)) {
|
||||
return;
|
||||
|
|
|
@ -300,7 +300,7 @@ static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo)
|
|||
static void amdgpu_vm_bo_done(struct amdgpu_vm_bo_base *vm_bo)
|
||||
{
|
||||
spin_lock(&vm_bo->vm->invalidated_lock);
|
||||
list_del_init(&vm_bo->vm_status);
|
||||
list_move(&vm_bo->vm_status, &vm_bo->vm->done);
|
||||
spin_unlock(&vm_bo->vm->invalidated_lock);
|
||||
}
|
||||
|
||||
|
@ -1570,7 +1570,8 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
|
|||
/**
|
||||
* amdgpu_vm_bo_update_mapping - update a mapping in the vm page table
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @adev: amdgpu_device pointer of the VM
|
||||
* @bo_adev: amdgpu_device pointer of the mapped BO
|
||||
* @vm: requested vm
|
||||
* @immediate: immediate submission in a page fault
|
||||
* @unlocked: unlocked invalidation during MM callback
|
||||
|
@ -1578,7 +1579,8 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
|
|||
* @start: start of mapped range
|
||||
* @last: last mapped entry
|
||||
* @flags: flags for the entries
|
||||
* @addr: addr to set the area to
|
||||
* @offset: offset into nodes and pages_addr
|
||||
* @nodes: array of drm_mm_nodes with the MC addresses
|
||||
* @pages_addr: DMA addresses to use for mapping
|
||||
* @fence: optional resulting fence
|
||||
*
|
||||
|
@ -1588,15 +1590,18 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
|
|||
* 0 for success, -EINVAL for failure.
|
||||
*/
|
||||
static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
|
||||
struct amdgpu_device *bo_adev,
|
||||
struct amdgpu_vm *vm, bool immediate,
|
||||
bool unlocked, struct dma_resv *resv,
|
||||
uint64_t start, uint64_t last,
|
||||
uint64_t flags, uint64_t addr,
|
||||
uint64_t flags, uint64_t offset,
|
||||
struct drm_mm_node *nodes,
|
||||
dma_addr_t *pages_addr,
|
||||
struct dma_fence **fence)
|
||||
{
|
||||
struct amdgpu_vm_update_params params;
|
||||
enum amdgpu_sync_mode sync_mode;
|
||||
uint64_t pfn;
|
||||
int r;
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
@ -1614,6 +1619,14 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
|
|||
else
|
||||
sync_mode = AMDGPU_SYNC_EXPLICIT;
|
||||
|
||||
pfn = offset >> PAGE_SHIFT;
|
||||
if (nodes) {
|
||||
while (pfn >= nodes->size) {
|
||||
pfn -= nodes->size;
|
||||
++nodes;
|
||||
}
|
||||
}
|
||||
|
||||
amdgpu_vm_eviction_lock(vm);
|
||||
if (vm->evicting) {
|
||||
r = -EBUSY;
|
||||
|
@ -1632,105 +1645,47 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
|
|||
if (r)
|
||||
goto error_unlock;
|
||||
|
||||
r = amdgpu_vm_update_ptes(¶ms, start, last + 1, addr, flags);
|
||||
if (r)
|
||||
goto error_unlock;
|
||||
|
||||
r = vm->update_funcs->commit(¶ms, fence);
|
||||
|
||||
error_unlock:
|
||||
amdgpu_vm_eviction_unlock(vm);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_bo_split_mapping - split a mapping into smaller chunks
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @resv: fences we need to sync to
|
||||
* @pages_addr: DMA addresses to use for mapping
|
||||
* @vm: requested vm
|
||||
* @mapping: mapped range and flags to use for the update
|
||||
* @flags: HW flags for the mapping
|
||||
* @bo_adev: amdgpu_device pointer that bo actually been allocated
|
||||
* @nodes: array of drm_mm_nodes with the MC addresses
|
||||
* @fence: optional resulting fence
|
||||
*
|
||||
* Split the mapping into smaller chunks so that each update fits
|
||||
* into a SDMA IB.
|
||||
*
|
||||
* Returns:
|
||||
* 0 for success, -EINVAL for failure.
|
||||
*/
|
||||
static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev,
|
||||
struct dma_resv *resv,
|
||||
dma_addr_t *pages_addr,
|
||||
struct amdgpu_vm *vm,
|
||||
struct amdgpu_bo_va_mapping *mapping,
|
||||
uint64_t flags,
|
||||
struct amdgpu_device *bo_adev,
|
||||
struct drm_mm_node *nodes,
|
||||
struct dma_fence **fence)
|
||||
{
|
||||
unsigned min_linear_pages = 1 << adev->vm_manager.fragment_size;
|
||||
uint64_t pfn, start = mapping->start;
|
||||
int r;
|
||||
|
||||
/* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here
|
||||
* but in case of something, we filter the flags in first place
|
||||
*/
|
||||
if (!(mapping->flags & AMDGPU_PTE_READABLE))
|
||||
flags &= ~AMDGPU_PTE_READABLE;
|
||||
if (!(mapping->flags & AMDGPU_PTE_WRITEABLE))
|
||||
flags &= ~AMDGPU_PTE_WRITEABLE;
|
||||
|
||||
/* Apply ASIC specific mapping flags */
|
||||
amdgpu_gmc_get_vm_pte(adev, mapping, &flags);
|
||||
|
||||
trace_amdgpu_vm_bo_update(mapping);
|
||||
|
||||
pfn = mapping->offset >> PAGE_SHIFT;
|
||||
if (nodes) {
|
||||
while (pfn >= nodes->size) {
|
||||
pfn -= nodes->size;
|
||||
++nodes;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
dma_addr_t *dma_addr = NULL;
|
||||
uint64_t max_entries;
|
||||
uint64_t addr, last;
|
||||
uint64_t tmp, num_entries, addr;
|
||||
|
||||
max_entries = mapping->last - start + 1;
|
||||
|
||||
num_entries = last - start + 1;
|
||||
if (nodes) {
|
||||
addr = nodes->start << PAGE_SHIFT;
|
||||
max_entries = min((nodes->size - pfn) *
|
||||
AMDGPU_GPU_PAGES_IN_CPU_PAGE, max_entries);
|
||||
num_entries = min((nodes->size - pfn) *
|
||||
AMDGPU_GPU_PAGES_IN_CPU_PAGE, num_entries);
|
||||
} else {
|
||||
addr = 0;
|
||||
}
|
||||
|
||||
if (pages_addr) {
|
||||
uint64_t count;
|
||||
bool contiguous = true;
|
||||
|
||||
for (count = 1;
|
||||
count < max_entries / AMDGPU_GPU_PAGES_IN_CPU_PAGE;
|
||||
++count) {
|
||||
uint64_t idx = pfn + count;
|
||||
if (num_entries > AMDGPU_GPU_PAGES_IN_CPU_PAGE) {
|
||||
uint64_t count;
|
||||
|
||||
if (pages_addr[idx] !=
|
||||
(pages_addr[idx - 1] + PAGE_SIZE))
|
||||
break;
|
||||
contiguous = pages_addr[pfn + 1] ==
|
||||
pages_addr[pfn] + PAGE_SIZE;
|
||||
|
||||
tmp = num_entries /
|
||||
AMDGPU_GPU_PAGES_IN_CPU_PAGE;
|
||||
for (count = 2; count < tmp; ++count) {
|
||||
uint64_t idx = pfn + count;
|
||||
|
||||
if (contiguous != (pages_addr[idx] ==
|
||||
pages_addr[idx - 1] + PAGE_SIZE))
|
||||
break;
|
||||
}
|
||||
num_entries = count *
|
||||
AMDGPU_GPU_PAGES_IN_CPU_PAGE;
|
||||
}
|
||||
|
||||
if (count < min_linear_pages) {
|
||||
if (!contiguous) {
|
||||
addr = pfn << PAGE_SHIFT;
|
||||
dma_addr = pages_addr;
|
||||
params.pages_addr = pages_addr;
|
||||
} else {
|
||||
addr = pages_addr[pfn];
|
||||
max_entries = count *
|
||||
AMDGPU_GPU_PAGES_IN_CPU_PAGE;
|
||||
params.pages_addr = NULL;
|
||||
}
|
||||
|
||||
} else if (flags & (AMDGPU_PTE_VALID | AMDGPU_PTE_PRT)) {
|
||||
|
@ -1738,23 +1693,25 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev,
|
|||
addr += pfn << PAGE_SHIFT;
|
||||
}
|
||||
|
||||
last = start + max_entries - 1;
|
||||
r = amdgpu_vm_bo_update_mapping(adev, vm, false, false, resv,
|
||||
start, last, flags, addr,
|
||||
dma_addr, fence);
|
||||
tmp = start + num_entries;
|
||||
r = amdgpu_vm_update_ptes(¶ms, start, tmp, addr, flags);
|
||||
if (r)
|
||||
return r;
|
||||
goto error_unlock;
|
||||
|
||||
pfn += (last - start + 1) / AMDGPU_GPU_PAGES_IN_CPU_PAGE;
|
||||
pfn += num_entries / AMDGPU_GPU_PAGES_IN_CPU_PAGE;
|
||||
if (nodes && nodes->size == pfn) {
|
||||
pfn = 0;
|
||||
++nodes;
|
||||
}
|
||||
start = last + 1;
|
||||
start = tmp;
|
||||
|
||||
} while (unlikely(start != mapping->last + 1));
|
||||
} while (unlikely(start != last + 1));
|
||||
|
||||
return 0;
|
||||
r = vm->update_funcs->commit(¶ms, fence);
|
||||
|
||||
error_unlock:
|
||||
amdgpu_vm_eviction_unlock(vm);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1832,9 +1789,26 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
|
|||
}
|
||||
|
||||
list_for_each_entry(mapping, &bo_va->invalids, list) {
|
||||
r = amdgpu_vm_bo_split_mapping(adev, resv, pages_addr, vm,
|
||||
mapping, flags, bo_adev, nodes,
|
||||
last_update);
|
||||
uint64_t update_flags = flags;
|
||||
|
||||
/* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here
|
||||
* but in case of something, we filter the flags in first place
|
||||
*/
|
||||
if (!(mapping->flags & AMDGPU_PTE_READABLE))
|
||||
update_flags &= ~AMDGPU_PTE_READABLE;
|
||||
if (!(mapping->flags & AMDGPU_PTE_WRITEABLE))
|
||||
update_flags &= ~AMDGPU_PTE_WRITEABLE;
|
||||
|
||||
/* Apply ASIC specific mapping flags */
|
||||
amdgpu_gmc_get_vm_pte(adev, mapping, &update_flags);
|
||||
|
||||
trace_amdgpu_vm_bo_update(mapping);
|
||||
|
||||
r = amdgpu_vm_bo_update_mapping(adev, bo_adev, vm, false, false,
|
||||
resv, mapping->start,
|
||||
mapping->last, update_flags,
|
||||
mapping->offset, nodes,
|
||||
pages_addr, last_update);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
@ -2042,9 +2016,10 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
|
|||
mapping->start < AMDGPU_GMC_HOLE_START)
|
||||
init_pte_value = AMDGPU_PTE_DEFAULT_ATC;
|
||||
|
||||
r = amdgpu_vm_bo_update_mapping(adev, vm, false, false, resv,
|
||||
mapping->start, mapping->last,
|
||||
init_pte_value, 0, NULL, &f);
|
||||
r = amdgpu_vm_bo_update_mapping(adev, adev, vm, false, false,
|
||||
resv, mapping->start,
|
||||
mapping->last, init_pte_value,
|
||||
0, NULL, NULL, &f);
|
||||
amdgpu_vm_free_mapping(adev, vm, mapping, f);
|
||||
if (r) {
|
||||
dma_fence_put(f);
|
||||
|
@ -2163,7 +2138,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
|
|||
|
||||
|
||||
/**
|
||||
* amdgpu_vm_bo_insert_mapping - insert a new mapping
|
||||
* amdgpu_vm_bo_insert_map - insert a new mapping
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @bo_va: bo_va to store the address
|
||||
|
@ -2820,7 +2795,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
INIT_LIST_HEAD(&vm->invalidated);
|
||||
spin_lock_init(&vm->invalidated_lock);
|
||||
INIT_LIST_HEAD(&vm->freed);
|
||||
|
||||
INIT_LIST_HEAD(&vm->done);
|
||||
|
||||
/* create scheduler entities for page table updates */
|
||||
r = drm_sched_entity_init(&vm->immediate, DRM_SCHED_PRIORITY_NORMAL,
|
||||
|
@ -3372,8 +3347,9 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid,
|
|||
value = 0;
|
||||
}
|
||||
|
||||
r = amdgpu_vm_bo_update_mapping(adev, vm, true, false, NULL, addr,
|
||||
addr + 1, flags, value, NULL, NULL);
|
||||
r = amdgpu_vm_bo_update_mapping(adev, adev, vm, true, false, NULL, addr,
|
||||
addr, flags, value, NULL, NULL,
|
||||
NULL);
|
||||
if (r)
|
||||
goto error_unlock;
|
||||
|
||||
|
@ -3389,3 +3365,99 @@ error_unref:
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
/**
|
||||
* amdgpu_debugfs_vm_bo_info - print BO info for the VM
|
||||
*
|
||||
* @vm: Requested VM for printing BO info
|
||||
* @m: debugfs file
|
||||
*
|
||||
* Print BO information in debugfs file for the VM
|
||||
*/
|
||||
void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
|
||||
{
|
||||
struct amdgpu_bo_va *bo_va, *tmp;
|
||||
u64 total_idle = 0;
|
||||
u64 total_evicted = 0;
|
||||
u64 total_relocated = 0;
|
||||
u64 total_moved = 0;
|
||||
u64 total_invalidated = 0;
|
||||
u64 total_done = 0;
|
||||
unsigned int total_idle_objs = 0;
|
||||
unsigned int total_evicted_objs = 0;
|
||||
unsigned int total_relocated_objs = 0;
|
||||
unsigned int total_moved_objs = 0;
|
||||
unsigned int total_invalidated_objs = 0;
|
||||
unsigned int total_done_objs = 0;
|
||||
unsigned int id = 0;
|
||||
|
||||
seq_puts(m, "\tIdle BOs:\n");
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
total_idle += amdgpu_bo_print_info(id++, bo_va->base.bo, m);
|
||||
}
|
||||
total_idle_objs = id;
|
||||
id = 0;
|
||||
|
||||
seq_puts(m, "\tEvicted BOs:\n");
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->evicted, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
total_evicted += amdgpu_bo_print_info(id++, bo_va->base.bo, m);
|
||||
}
|
||||
total_evicted_objs = id;
|
||||
id = 0;
|
||||
|
||||
seq_puts(m, "\tRelocated BOs:\n");
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->relocated, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
total_relocated += amdgpu_bo_print_info(id++, bo_va->base.bo, m);
|
||||
}
|
||||
total_relocated_objs = id;
|
||||
id = 0;
|
||||
|
||||
seq_puts(m, "\tMoved BOs:\n");
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
total_moved += amdgpu_bo_print_info(id++, bo_va->base.bo, m);
|
||||
}
|
||||
total_moved_objs = id;
|
||||
id = 0;
|
||||
|
||||
seq_puts(m, "\tInvalidated BOs:\n");
|
||||
spin_lock(&vm->invalidated_lock);
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
total_invalidated += amdgpu_bo_print_info(id++, bo_va->base.bo, m);
|
||||
}
|
||||
total_invalidated_objs = id;
|
||||
id = 0;
|
||||
|
||||
seq_puts(m, "\tDone BOs:\n");
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->done, base.vm_status) {
|
||||
if (!bo_va->base.bo)
|
||||
continue;
|
||||
total_done += amdgpu_bo_print_info(id++, bo_va->base.bo, m);
|
||||
}
|
||||
spin_unlock(&vm->invalidated_lock);
|
||||
total_done_objs = id;
|
||||
|
||||
seq_printf(m, "\tTotal idle size: %12lld\tobjs:\t%d\n", total_idle,
|
||||
total_idle_objs);
|
||||
seq_printf(m, "\tTotal evicted size: %12lld\tobjs:\t%d\n", total_evicted,
|
||||
total_evicted_objs);
|
||||
seq_printf(m, "\tTotal relocated size: %12lld\tobjs:\t%d\n", total_relocated,
|
||||
total_relocated_objs);
|
||||
seq_printf(m, "\tTotal moved size: %12lld\tobjs:\t%d\n", total_moved,
|
||||
total_moved_objs);
|
||||
seq_printf(m, "\tTotal invalidated size: %12lld\tobjs:\t%d\n", total_invalidated,
|
||||
total_invalidated_objs);
|
||||
seq_printf(m, "\tTotal done size: %12lld\tobjs:\t%d\n", total_done,
|
||||
total_done_objs);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -76,6 +76,9 @@ struct amdgpu_bo_list_entry;
|
|||
/* PTE is handled as PDE for VEGA10 (Translate Further) */
|
||||
#define AMDGPU_PTE_TF (1ULL << 56)
|
||||
|
||||
/* MALL noalloc for sienna_cichlid, reserved for older ASICs */
|
||||
#define AMDGPU_PTE_NOALLOC (1ULL << 58)
|
||||
|
||||
/* PDE Block Fragment Size for VEGA10 */
|
||||
#define AMDGPU_PDE_BFS(a) ((uint64_t)a << 59)
|
||||
|
||||
|
@ -274,6 +277,9 @@ struct amdgpu_vm {
|
|||
/* BO mappings freed, but not yet updated in the PT */
|
||||
struct list_head freed;
|
||||
|
||||
/* BOs which are invalidated, has been updated in the PTs */
|
||||
struct list_head done;
|
||||
|
||||
/* contains the page directory */
|
||||
struct amdgpu_vm_pt root;
|
||||
struct dma_fence *last_update;
|
||||
|
@ -441,4 +447,8 @@ void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev,
|
|||
struct amdgpu_vm *vm);
|
||||
void amdgpu_vm_del_from_lru_notify(struct ttm_buffer_object *bo);
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -168,8 +168,7 @@ static const struct ttm_resource_manager_func amdgpu_vram_mgr_func;
|
|||
/**
|
||||
* amdgpu_vram_mgr_init - init VRAM manager and DRM MM
|
||||
*
|
||||
* @man: TTM memory type manager
|
||||
* @p_size: maximum size of VRAM
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Allocate and initialize the VRAM manager.
|
||||
*/
|
||||
|
@ -185,6 +184,8 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev)
|
|||
|
||||
drm_mm_init(&mgr->mm, 0, man->size);
|
||||
spin_lock_init(&mgr->lock);
|
||||
INIT_LIST_HEAD(&mgr->reservations_pending);
|
||||
INIT_LIST_HEAD(&mgr->reserved_pages);
|
||||
|
||||
/* Add the two VRAM-related sysfs files */
|
||||
ret = sysfs_create_files(&adev->dev->kobj, amdgpu_vram_mgr_attributes);
|
||||
|
@ -199,7 +200,7 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev)
|
|||
/**
|
||||
* amdgpu_vram_mgr_fini - free and destroy VRAM manager
|
||||
*
|
||||
* @man: TTM memory type manager
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Destroy and free the VRAM manager, returns -EBUSY if ranges are still
|
||||
* allocated inside it.
|
||||
|
@ -209,6 +210,7 @@ void amdgpu_vram_mgr_fini(struct amdgpu_device *adev)
|
|||
struct amdgpu_vram_mgr *mgr = &adev->mman.vram_mgr;
|
||||
struct ttm_resource_manager *man = &mgr->manager;
|
||||
int ret;
|
||||
struct amdgpu_vram_reservation *rsv, *temp;
|
||||
|
||||
ttm_resource_manager_set_used(man, false);
|
||||
|
||||
|
@ -217,6 +219,13 @@ void amdgpu_vram_mgr_fini(struct amdgpu_device *adev)
|
|||
return;
|
||||
|
||||
spin_lock(&mgr->lock);
|
||||
list_for_each_entry_safe(rsv, temp, &mgr->reservations_pending, node)
|
||||
kfree(rsv);
|
||||
|
||||
list_for_each_entry_safe(rsv, temp, &mgr->reserved_pages, node) {
|
||||
drm_mm_remove_node(&rsv->mm_node);
|
||||
kfree(rsv);
|
||||
}
|
||||
drm_mm_takedown(&mgr->mm);
|
||||
spin_unlock(&mgr->lock);
|
||||
|
||||
|
@ -229,7 +238,7 @@ void amdgpu_vram_mgr_fini(struct amdgpu_device *adev)
|
|||
/**
|
||||
* amdgpu_vram_mgr_vis_size - Calculate visible node size
|
||||
*
|
||||
* @adev: amdgpu device structure
|
||||
* @adev: amdgpu_device pointer
|
||||
* @node: MM node structure
|
||||
*
|
||||
* Calculate how many bytes of the MM node are inside visible VRAM
|
||||
|
@ -275,6 +284,101 @@ u64 amdgpu_vram_mgr_bo_visible_size(struct amdgpu_bo *bo)
|
|||
return usage;
|
||||
}
|
||||
|
||||
static void amdgpu_vram_mgr_do_reserve(struct ttm_resource_manager *man)
|
||||
{
|
||||
struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
|
||||
struct amdgpu_device *adev = to_amdgpu_device(mgr);
|
||||
struct drm_mm *mm = &mgr->mm;
|
||||
struct amdgpu_vram_reservation *rsv, *temp;
|
||||
uint64_t vis_usage;
|
||||
|
||||
list_for_each_entry_safe(rsv, temp, &mgr->reservations_pending, node) {
|
||||
if (drm_mm_reserve_node(mm, &rsv->mm_node))
|
||||
continue;
|
||||
|
||||
dev_dbg(adev->dev, "Reservation 0x%llx - %lld, Succeeded\n",
|
||||
rsv->mm_node.start, rsv->mm_node.size);
|
||||
|
||||
vis_usage = amdgpu_vram_mgr_vis_size(adev, &rsv->mm_node);
|
||||
atomic64_add(vis_usage, &mgr->vis_usage);
|
||||
atomic64_add(rsv->mm_node.size << PAGE_SHIFT, &mgr->usage);
|
||||
list_move(&rsv->node, &mgr->reserved_pages);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vram_mgr_reserve_range - Reserve a range from VRAM
|
||||
*
|
||||
* @man: TTM memory type manager
|
||||
* @start: start address of the range in VRAM
|
||||
* @size: size of the range
|
||||
*
|
||||
* Reserve memory from start addess with the specified size in VRAM
|
||||
*/
|
||||
int amdgpu_vram_mgr_reserve_range(struct ttm_resource_manager *man,
|
||||
uint64_t start, uint64_t size)
|
||||
{
|
||||
struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
|
||||
struct amdgpu_vram_reservation *rsv;
|
||||
|
||||
rsv = kzalloc(sizeof(*rsv), GFP_KERNEL);
|
||||
if (!rsv)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&rsv->node);
|
||||
rsv->mm_node.start = start >> PAGE_SHIFT;
|
||||
rsv->mm_node.size = size >> PAGE_SHIFT;
|
||||
|
||||
spin_lock(&mgr->lock);
|
||||
list_add_tail(&mgr->reservations_pending, &rsv->node);
|
||||
amdgpu_vram_mgr_do_reserve(man);
|
||||
spin_unlock(&mgr->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vram_mgr_query_page_status - query the reservation status
|
||||
*
|
||||
* @man: TTM memory type manager
|
||||
* @start: start address of a page in VRAM
|
||||
*
|
||||
* Returns:
|
||||
* -EBUSY: the page is still hold and in pending list
|
||||
* 0: the page has been reserved
|
||||
* -ENOENT: the input page is not a reservation
|
||||
*/
|
||||
int amdgpu_vram_mgr_query_page_status(struct ttm_resource_manager *man,
|
||||
uint64_t start)
|
||||
{
|
||||
struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
|
||||
struct amdgpu_vram_reservation *rsv;
|
||||
int ret;
|
||||
|
||||
spin_lock(&mgr->lock);
|
||||
|
||||
list_for_each_entry(rsv, &mgr->reservations_pending, node) {
|
||||
if ((rsv->mm_node.start <= start) &&
|
||||
(start < (rsv->mm_node.start + rsv->mm_node.size))) {
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry(rsv, &mgr->reserved_pages, node) {
|
||||
if ((rsv->mm_node.start <= start) &&
|
||||
(start < (rsv->mm_node.start + rsv->mm_node.size))) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = -ENOENT;
|
||||
out:
|
||||
spin_unlock(&mgr->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vram_mgr_virt_start - update virtual start address
|
||||
*
|
||||
|
@ -445,6 +549,7 @@ static void amdgpu_vram_mgr_del(struct ttm_resource_manager *man,
|
|||
vis_usage += amdgpu_vram_mgr_vis_size(adev, nodes);
|
||||
++nodes;
|
||||
}
|
||||
amdgpu_vram_mgr_do_reserve(man);
|
||||
spin_unlock(&mgr->lock);
|
||||
|
||||
atomic64_sub(usage, &mgr->usage);
|
||||
|
@ -529,7 +634,7 @@ error_free:
|
|||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vram_mgr_alloc_sgt - allocate and fill a sg table
|
||||
* amdgpu_vram_mgr_free_sgt - allocate and fill a sg table
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @sgt: sg table to free
|
||||
|
|
|
@ -246,7 +246,7 @@ static ssize_t amdgpu_xgmi_show_error(struct device *dev,
|
|||
|
||||
adev->df.funcs->set_fica(adev, ficaa_pie_status_in, 0, 0);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", error_count);
|
||||
return snprintf(buf, PAGE_SIZE, "%u\n", error_count);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ int athub_v2_1_set_clockgating(struct amdgpu_device *adev,
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
athub_v2_1_update_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
athub_v2_1_update_medium_grain_light_sleep(adev,
|
||||
|
|
|
@ -66,13 +66,13 @@ typedef struct {
|
|||
bool abort;
|
||||
} atom_exec_context;
|
||||
|
||||
int amdgpu_atom_debug = 0;
|
||||
static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params);
|
||||
int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t * params);
|
||||
int amdgpu_atom_debug;
|
||||
static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t *params);
|
||||
int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t *params);
|
||||
|
||||
static uint32_t atom_arg_mask[8] =
|
||||
{ 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000,
|
||||
0xFF000000 };
|
||||
{ 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000,
|
||||
0xFF000000 };
|
||||
static int atom_arg_shift[8] = { 0, 0, 8, 16, 0, 8, 16, 24 };
|
||||
|
||||
static int atom_dst_to_src[8][4] = {
|
||||
|
@ -88,7 +88,7 @@ static int atom_dst_to_src[8][4] = {
|
|||
};
|
||||
static int atom_def_dst[8] = { 0, 0, 1, 2, 0, 1, 2, 3 };
|
||||
|
||||
static int debug_depth = 0;
|
||||
static int debug_depth;
|
||||
#ifdef ATOM_DEBUG
|
||||
static void debug_print_spaces(int n)
|
||||
{
|
||||
|
@ -1201,7 +1201,7 @@ static struct {
|
|||
atom_op_div32, ATOM_ARG_WS},
|
||||
};
|
||||
|
||||
static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params)
|
||||
static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t *params)
|
||||
{
|
||||
int base = CU16(ctx->cmd_table + 4 + 2 * index);
|
||||
int len, ws, ps, ptr;
|
||||
|
@ -1262,7 +1262,7 @@ free:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
|
||||
int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t *params)
|
||||
{
|
||||
int r;
|
||||
|
||||
|
@ -1388,8 +1388,8 @@ void amdgpu_atom_destroy(struct atom_context *ctx)
|
|||
}
|
||||
|
||||
bool amdgpu_atom_parse_data_header(struct atom_context *ctx, int index,
|
||||
uint16_t * size, uint8_t * frev, uint8_t * crev,
|
||||
uint16_t * data_start)
|
||||
uint16_t *size, uint8_t *frev, uint8_t *crev,
|
||||
uint16_t *data_start)
|
||||
{
|
||||
int offset = index * 2 + 4;
|
||||
int idx = CU16(ctx->data_table + offset);
|
||||
|
@ -1408,8 +1408,8 @@ bool amdgpu_atom_parse_data_header(struct atom_context *ctx, int index,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool amdgpu_atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
|
||||
uint8_t * crev)
|
||||
bool amdgpu_atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev,
|
||||
uint8_t *crev)
|
||||
{
|
||||
int offset = index * 2 + 4;
|
||||
int idx = CU16(ctx->cmd_table + offset);
|
||||
|
|
|
@ -499,10 +499,8 @@ int amdgpu_atombios_encoder_get_encoder_mode(struct drm_encoder *encoder)
|
|||
} else {
|
||||
return ATOM_ENCODER_MODE_DVI;
|
||||
}
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
return ATOM_ENCODER_MODE_LVDS;
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_DisplayPort:
|
||||
dig_connector = amdgpu_connector->con_priv;
|
||||
if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
|
||||
|
@ -519,20 +517,16 @@ int amdgpu_atombios_encoder_get_encoder_mode(struct drm_encoder *encoder)
|
|||
} else {
|
||||
return ATOM_ENCODER_MODE_DVI;
|
||||
}
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_eDP:
|
||||
return ATOM_ENCODER_MODE_DP;
|
||||
case DRM_MODE_CONNECTOR_DVIA:
|
||||
case DRM_MODE_CONNECTOR_VGA:
|
||||
return ATOM_ENCODER_MODE_CRT;
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_Composite:
|
||||
case DRM_MODE_CONNECTOR_SVIDEO:
|
||||
case DRM_MODE_CONNECTOR_9PinDIN:
|
||||
/* fix me */
|
||||
return ATOM_ENCODER_MODE_TV;
|
||||
/*return ATOM_ENCODER_MODE_CV;*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ u32 amdgpu_atombios_i2c_func(struct i2c_adapter *adap)
|
|||
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
|
||||
}
|
||||
|
||||
void amdgpu_atombios_i2c_channel_trans(struct amdgpu_device* adev, u8 slave_addr, u8 line_number, u8 offset, u8 data)
|
||||
void amdgpu_atombios_i2c_channel_trans(struct amdgpu_device *adev, u8 slave_addr, u8 line_number, u8 offset, u8 data)
|
||||
{
|
||||
PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction);
|
||||
|
|
|
@ -1336,11 +1336,13 @@ cik_asic_reset_method(struct amdgpu_device *adev)
|
|||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_BONAIRE:
|
||||
case CHIP_HAWAII:
|
||||
/* disable baco reset until it works */
|
||||
/* smu7_asic_get_baco_capability(adev, &baco_reset); */
|
||||
baco_reset = false;
|
||||
break;
|
||||
case CHIP_HAWAII:
|
||||
baco_reset = cik_asic_supports_baco(adev);
|
||||
break;
|
||||
default:
|
||||
baco_reset = false;
|
||||
break;
|
||||
|
|
|
@ -195,7 +195,7 @@ static void cik_sdma_ring_set_wptr(struct amdgpu_ring *ring)
|
|||
struct amdgpu_device *adev = ring->adev;
|
||||
|
||||
WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[ring->me],
|
||||
(lower_32_bits(ring->wptr) << 2) & 0x3fffc);
|
||||
(lower_32_bits(ring->wptr) << 2) & 0x3fffc);
|
||||
}
|
||||
|
||||
static void cik_sdma_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
|
||||
|
@ -1071,22 +1071,19 @@ static int cik_sdma_soft_reset(void *handle)
|
|||
{
|
||||
u32 srbm_soft_reset = 0;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
u32 tmp = RREG32(mmSRBM_STATUS2);
|
||||
u32 tmp;
|
||||
|
||||
if (tmp & SRBM_STATUS2__SDMA_BUSY_MASK) {
|
||||
/* sdma0 */
|
||||
tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET);
|
||||
tmp |= SDMA0_F32_CNTL__HALT_MASK;
|
||||
WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp);
|
||||
srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA_MASK;
|
||||
}
|
||||
if (tmp & SRBM_STATUS2__SDMA1_BUSY_MASK) {
|
||||
/* sdma1 */
|
||||
tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET);
|
||||
tmp |= SDMA0_F32_CNTL__HALT_MASK;
|
||||
WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp);
|
||||
srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA1_MASK;
|
||||
}
|
||||
/* sdma0 */
|
||||
tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET);
|
||||
tmp |= SDMA0_F32_CNTL__HALT_MASK;
|
||||
WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp);
|
||||
srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA_MASK;
|
||||
|
||||
/* sdma1 */
|
||||
tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET);
|
||||
tmp |= SDMA0_F32_CNTL__HALT_MASK;
|
||||
WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp);
|
||||
srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA1_MASK;
|
||||
|
||||
if (srbm_soft_reset) {
|
||||
tmp = RREG32(mmSRBM_SOFT_RESET);
|
||||
|
|
|
@ -2202,22 +2202,18 @@ static int dce_v10_0_pick_dig_encoder(struct drm_encoder *encoder)
|
|||
return 1;
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
|
||||
if (dig->linkb)
|
||||
return 3;
|
||||
else
|
||||
return 2;
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
||||
if (dig->linkb)
|
||||
return 5;
|
||||
else
|
||||
return 4;
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
|
||||
return 6;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("invalid encoder_id: 0x%x\n", amdgpu_encoder->encoder_id);
|
||||
return 0;
|
||||
|
@ -2677,7 +2673,7 @@ static int dce_v10_0_crtc_set_base_atomic(struct drm_crtc *crtc,
|
|||
struct drm_framebuffer *fb,
|
||||
int x, int y, enum mode_set_atomic state)
|
||||
{
|
||||
return dce_v10_0_crtc_do_set_base(crtc, fb, x, y, 1);
|
||||
return dce_v10_0_crtc_do_set_base(crtc, fb, x, y, 1);
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs dce_v10_0_crtc_helper_funcs = {
|
||||
|
|
|
@ -2235,22 +2235,18 @@ static int dce_v11_0_pick_dig_encoder(struct drm_encoder *encoder)
|
|||
return 1;
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
|
||||
if (dig->linkb)
|
||||
return 3;
|
||||
else
|
||||
return 2;
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
||||
if (dig->linkb)
|
||||
return 5;
|
||||
else
|
||||
return 4;
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
|
||||
return 6;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("invalid encoder_id: 0x%x\n", amdgpu_encoder->encoder_id);
|
||||
return 0;
|
||||
|
@ -2304,19 +2300,16 @@ static u32 dce_v11_0_pick_pll(struct drm_crtc *crtc)
|
|||
return ATOM_COMBOPHY_PLL1;
|
||||
else
|
||||
return ATOM_COMBOPHY_PLL0;
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
|
||||
if (dig->linkb)
|
||||
return ATOM_COMBOPHY_PLL3;
|
||||
else
|
||||
return ATOM_COMBOPHY_PLL2;
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
||||
if (dig->linkb)
|
||||
return ATOM_COMBOPHY_PLL5;
|
||||
else
|
||||
return ATOM_COMBOPHY_PLL4;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("invalid encoder_id: 0x%x\n", amdgpu_encoder->encoder_id);
|
||||
return ATOM_PPLL_INVALID;
|
||||
|
@ -2785,7 +2778,7 @@ static int dce_v11_0_crtc_set_base_atomic(struct drm_crtc *crtc,
|
|||
struct drm_framebuffer *fb,
|
||||
int x, int y, enum mode_set_atomic state)
|
||||
{
|
||||
return dce_v11_0_crtc_do_set_base(crtc, fb, x, y, 1);
|
||||
return dce_v11_0_crtc_do_set_base(crtc, fb, x, y, 1);
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs dce_v11_0_crtc_helper_funcs = {
|
||||
|
|
|
@ -2567,7 +2567,7 @@ static int dce_v6_0_crtc_set_base_atomic(struct drm_crtc *crtc,
|
|||
struct drm_framebuffer *fb,
|
||||
int x, int y, enum mode_set_atomic state)
|
||||
{
|
||||
return dce_v6_0_crtc_do_set_base(crtc, fb, x, y, 1);
|
||||
return dce_v6_0_crtc_do_set_base(crtc, fb, x, y, 1);
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs dce_v6_0_crtc_helper_funcs = {
|
||||
|
|
|
@ -2498,7 +2498,7 @@ static void dce_v8_0_crtc_disable(struct drm_crtc *crtc)
|
|||
case ATOM_PPLL2:
|
||||
/* disable the ppll */
|
||||
amdgpu_atombios_crtc_program_pll(crtc, amdgpu_crtc->crtc_id, amdgpu_crtc->pll_id,
|
||||
0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
|
||||
0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
|
||||
break;
|
||||
case ATOM_PPLL0:
|
||||
/* disable the ppll */
|
||||
|
@ -2585,7 +2585,7 @@ static int dce_v8_0_crtc_set_base_atomic(struct drm_crtc *crtc,
|
|||
struct drm_framebuffer *fb,
|
||||
int x, int y, enum mode_set_atomic state)
|
||||
{
|
||||
return dce_v8_0_crtc_do_set_base(crtc, fb, x, y, 1);
|
||||
return dce_v8_0_crtc_do_set_base(crtc, fb, x, y, 1);
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs dce_v8_0_crtc_helper_funcs = {
|
||||
|
|
|
@ -41,7 +41,7 @@ static void df_v1_7_sw_fini(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
static void df_v1_7_enable_broadcast_mode(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
bool enable)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
|
|
|
@ -30,72 +30,18 @@
|
|||
#define DF_3_6_SMN_REG_INST_DIST 0x8
|
||||
#define DF_3_6_INST_CNT 8
|
||||
|
||||
/* Defined in global_features.h as FTI_PERFMON_VISIBLE */
|
||||
#define DF_V3_6_MAX_COUNTERS 4
|
||||
|
||||
/* get flags from df perfmon config */
|
||||
#define DF_V3_6_GET_EVENT(x) (x & 0xFFUL)
|
||||
#define DF_V3_6_GET_INSTANCE(x) ((x >> 8) & 0xFFUL)
|
||||
#define DF_V3_6_GET_UNITMASK(x) ((x >> 16) & 0xFFUL)
|
||||
#define DF_V3_6_PERFMON_OVERFLOW 0xFFFFFFFFFFFFULL
|
||||
|
||||
static u32 df_v3_6_channel_number[] = {1, 2, 0, 4, 0, 8, 0,
|
||||
16, 32, 0, 0, 0, 2, 4, 8};
|
||||
|
||||
/* init df format attrs */
|
||||
AMDGPU_PMU_ATTR(event, "config:0-7");
|
||||
AMDGPU_PMU_ATTR(instance, "config:8-15");
|
||||
AMDGPU_PMU_ATTR(umask, "config:16-23");
|
||||
|
||||
/* df format attributes */
|
||||
static struct attribute *df_v3_6_format_attrs[] = {
|
||||
&pmu_attr_event.attr,
|
||||
&pmu_attr_instance.attr,
|
||||
&pmu_attr_umask.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* df format attribute group */
|
||||
static struct attribute_group df_v3_6_format_attr_group = {
|
||||
.name = "format",
|
||||
.attrs = df_v3_6_format_attrs,
|
||||
};
|
||||
|
||||
/* df event attrs */
|
||||
AMDGPU_PMU_ATTR(cake0_pcsout_txdata,
|
||||
"event=0x7,instance=0x46,umask=0x2");
|
||||
AMDGPU_PMU_ATTR(cake1_pcsout_txdata,
|
||||
"event=0x7,instance=0x47,umask=0x2");
|
||||
AMDGPU_PMU_ATTR(cake0_pcsout_txmeta,
|
||||
"event=0x7,instance=0x46,umask=0x4");
|
||||
AMDGPU_PMU_ATTR(cake1_pcsout_txmeta,
|
||||
"event=0x7,instance=0x47,umask=0x4");
|
||||
AMDGPU_PMU_ATTR(cake0_ftiinstat_reqalloc,
|
||||
"event=0xb,instance=0x46,umask=0x4");
|
||||
AMDGPU_PMU_ATTR(cake1_ftiinstat_reqalloc,
|
||||
"event=0xb,instance=0x47,umask=0x4");
|
||||
AMDGPU_PMU_ATTR(cake0_ftiinstat_rspalloc,
|
||||
"event=0xb,instance=0x46,umask=0x8");
|
||||
AMDGPU_PMU_ATTR(cake1_ftiinstat_rspalloc,
|
||||
"event=0xb,instance=0x47,umask=0x8");
|
||||
|
||||
/* df event attributes */
|
||||
static struct attribute *df_v3_6_event_attrs[] = {
|
||||
&pmu_attr_cake0_pcsout_txdata.attr,
|
||||
&pmu_attr_cake1_pcsout_txdata.attr,
|
||||
&pmu_attr_cake0_pcsout_txmeta.attr,
|
||||
&pmu_attr_cake1_pcsout_txmeta.attr,
|
||||
&pmu_attr_cake0_ftiinstat_reqalloc.attr,
|
||||
&pmu_attr_cake1_ftiinstat_reqalloc.attr,
|
||||
&pmu_attr_cake0_ftiinstat_rspalloc.attr,
|
||||
&pmu_attr_cake1_ftiinstat_rspalloc.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* df event attribute group */
|
||||
static struct attribute_group df_v3_6_event_attr_group = {
|
||||
.name = "events",
|
||||
.attrs = df_v3_6_event_attrs
|
||||
};
|
||||
|
||||
/* df event attr groups */
|
||||
const struct attribute_group *df_v3_6_attr_groups[] = {
|
||||
&df_v3_6_format_attr_group,
|
||||
&df_v3_6_event_attr_group,
|
||||
NULL
|
||||
};
|
||||
|
||||
static uint64_t df_v3_6_get_fica(struct amdgpu_device *adev,
|
||||
uint32_t ficaa_val)
|
||||
{
|
||||
|
@ -391,33 +337,28 @@ static void df_v3_6_get_clockgating_state(struct amdgpu_device *adev,
|
|||
}
|
||||
|
||||
/* get assigned df perfmon ctr as int */
|
||||
static int df_v3_6_pmc_config_2_cntr(struct amdgpu_device *adev,
|
||||
uint64_t config)
|
||||
static bool df_v3_6_pmc_has_counter(struct amdgpu_device *adev,
|
||||
uint64_t config,
|
||||
int counter_idx)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DF_V3_6_MAX_COUNTERS; i++) {
|
||||
if ((config & 0x0FFFFFFUL) ==
|
||||
adev->df_perfmon_config_assign_mask[i])
|
||||
return i;
|
||||
}
|
||||
return ((config & 0x0FFFFFFUL) ==
|
||||
adev->df_perfmon_config_assign_mask[counter_idx]);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* get address based on counter assignment */
|
||||
static void df_v3_6_pmc_get_addr(struct amdgpu_device *adev,
|
||||
uint64_t config,
|
||||
int counter_idx,
|
||||
int is_ctrl,
|
||||
uint32_t *lo_base_addr,
|
||||
uint32_t *hi_base_addr)
|
||||
{
|
||||
int target_cntr = df_v3_6_pmc_config_2_cntr(adev, config);
|
||||
|
||||
if (target_cntr < 0)
|
||||
if (!df_v3_6_pmc_has_counter(adev, config, counter_idx))
|
||||
return;
|
||||
|
||||
switch (target_cntr) {
|
||||
switch (counter_idx) {
|
||||
|
||||
case 0:
|
||||
*lo_base_addr = is_ctrl ? smnPerfMonCtlLo4 : smnPerfMonCtrLo4;
|
||||
|
@ -443,15 +384,18 @@ static void df_v3_6_pmc_get_addr(struct amdgpu_device *adev,
|
|||
/* get read counter address */
|
||||
static void df_v3_6_pmc_get_read_settings(struct amdgpu_device *adev,
|
||||
uint64_t config,
|
||||
int counter_idx,
|
||||
uint32_t *lo_base_addr,
|
||||
uint32_t *hi_base_addr)
|
||||
{
|
||||
df_v3_6_pmc_get_addr(adev, config, 0, lo_base_addr, hi_base_addr);
|
||||
df_v3_6_pmc_get_addr(adev, config, counter_idx, 0, lo_base_addr,
|
||||
hi_base_addr);
|
||||
}
|
||||
|
||||
/* get control counter settings i.e. address and values to set */
|
||||
static int df_v3_6_pmc_get_ctrl_settings(struct amdgpu_device *adev,
|
||||
uint64_t config,
|
||||
int counter_idx,
|
||||
uint32_t *lo_base_addr,
|
||||
uint32_t *hi_base_addr,
|
||||
uint32_t *lo_val,
|
||||
|
@ -462,7 +406,8 @@ static int df_v3_6_pmc_get_ctrl_settings(struct amdgpu_device *adev,
|
|||
uint32_t eventsel, instance, unitmask;
|
||||
uint32_t instance_10, instance_5432, instance_76;
|
||||
|
||||
df_v3_6_pmc_get_addr(adev, config, 1, lo_base_addr, hi_base_addr);
|
||||
df_v3_6_pmc_get_addr(adev, config, counter_idx, 1, lo_base_addr,
|
||||
hi_base_addr);
|
||||
|
||||
if ((*lo_base_addr == 0) || (*hi_base_addr == 0)) {
|
||||
DRM_ERROR("[DF PMC] addressing not retrieved! Lo: %x, Hi: %x",
|
||||
|
@ -492,18 +437,13 @@ static int df_v3_6_pmc_get_ctrl_settings(struct amdgpu_device *adev,
|
|||
static int df_v3_6_pmc_add_cntr(struct amdgpu_device *adev,
|
||||
uint64_t config)
|
||||
{
|
||||
int i, target_cntr;
|
||||
|
||||
target_cntr = df_v3_6_pmc_config_2_cntr(adev, config);
|
||||
|
||||
if (target_cntr >= 0)
|
||||
return 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DF_V3_6_MAX_COUNTERS; i++) {
|
||||
if (adev->df_perfmon_config_assign_mask[i] == 0U) {
|
||||
adev->df_perfmon_config_assign_mask[i] =
|
||||
config & 0x0FFFFFFUL;
|
||||
return 0;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -512,59 +452,50 @@ static int df_v3_6_pmc_add_cntr(struct amdgpu_device *adev,
|
|||
|
||||
#define DEFERRED_ARM_MASK (1 << 31)
|
||||
static int df_v3_6_pmc_set_deferred(struct amdgpu_device *adev,
|
||||
uint64_t config, bool is_deferred)
|
||||
int counter_idx, uint64_t config,
|
||||
bool is_deferred)
|
||||
{
|
||||
int target_cntr;
|
||||
|
||||
target_cntr = df_v3_6_pmc_config_2_cntr(adev, config);
|
||||
|
||||
if (target_cntr < 0)
|
||||
if (!df_v3_6_pmc_has_counter(adev, config, counter_idx))
|
||||
return -EINVAL;
|
||||
|
||||
if (is_deferred)
|
||||
adev->df_perfmon_config_assign_mask[target_cntr] |=
|
||||
adev->df_perfmon_config_assign_mask[counter_idx] |=
|
||||
DEFERRED_ARM_MASK;
|
||||
else
|
||||
adev->df_perfmon_config_assign_mask[target_cntr] &=
|
||||
adev->df_perfmon_config_assign_mask[counter_idx] &=
|
||||
~DEFERRED_ARM_MASK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool df_v3_6_pmc_is_deferred(struct amdgpu_device *adev,
|
||||
int counter_idx,
|
||||
uint64_t config)
|
||||
{
|
||||
int target_cntr;
|
||||
|
||||
target_cntr = df_v3_6_pmc_config_2_cntr(adev, config);
|
||||
|
||||
/*
|
||||
* we never get target_cntr < 0 since this funciton is only called in
|
||||
* pmc_count for now but we should check anyways.
|
||||
*/
|
||||
return (target_cntr >= 0 &&
|
||||
(adev->df_perfmon_config_assign_mask[target_cntr]
|
||||
& DEFERRED_ARM_MASK));
|
||||
return (df_v3_6_pmc_has_counter(adev, config, counter_idx) &&
|
||||
(adev->df_perfmon_config_assign_mask[counter_idx]
|
||||
& DEFERRED_ARM_MASK));
|
||||
|
||||
}
|
||||
|
||||
/* release performance counter */
|
||||
static void df_v3_6_pmc_release_cntr(struct amdgpu_device *adev,
|
||||
uint64_t config)
|
||||
uint64_t config,
|
||||
int counter_idx)
|
||||
{
|
||||
int target_cntr = df_v3_6_pmc_config_2_cntr(adev, config);
|
||||
|
||||
if (target_cntr >= 0)
|
||||
adev->df_perfmon_config_assign_mask[target_cntr] = 0ULL;
|
||||
if (df_v3_6_pmc_has_counter(adev, config, counter_idx))
|
||||
adev->df_perfmon_config_assign_mask[counter_idx] = 0ULL;
|
||||
}
|
||||
|
||||
|
||||
static void df_v3_6_reset_perfmon_cntr(struct amdgpu_device *adev,
|
||||
uint64_t config)
|
||||
uint64_t config,
|
||||
int counter_idx)
|
||||
{
|
||||
uint32_t lo_base_addr = 0, hi_base_addr = 0;
|
||||
|
||||
df_v3_6_pmc_get_read_settings(adev, config, &lo_base_addr,
|
||||
df_v3_6_pmc_get_read_settings(adev, config, counter_idx, &lo_base_addr,
|
||||
&hi_base_addr);
|
||||
|
||||
if ((lo_base_addr == 0) || (hi_base_addr == 0))
|
||||
|
@ -573,21 +504,22 @@ static void df_v3_6_reset_perfmon_cntr(struct amdgpu_device *adev,
|
|||
df_v3_6_perfmon_wreg(adev, lo_base_addr, 0, hi_base_addr, 0);
|
||||
}
|
||||
|
||||
/* return available counter if is_add == 1 otherwise return error status. */
|
||||
static int df_v3_6_pmc_start(struct amdgpu_device *adev, uint64_t config,
|
||||
int is_add)
|
||||
int counter_idx, int is_add)
|
||||
{
|
||||
uint32_t lo_base_addr, hi_base_addr, lo_val, hi_val;
|
||||
int err = 0, ret = 0;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_ARCTURUS:
|
||||
if (is_add)
|
||||
return df_v3_6_pmc_add_cntr(adev, config);
|
||||
|
||||
df_v3_6_reset_perfmon_cntr(adev, config);
|
||||
|
||||
ret = df_v3_6_pmc_get_ctrl_settings(adev,
|
||||
config,
|
||||
counter_idx,
|
||||
&lo_base_addr,
|
||||
&hi_base_addr,
|
||||
&lo_val,
|
||||
|
@ -604,7 +536,8 @@ static int df_v3_6_pmc_start(struct amdgpu_device *adev, uint64_t config,
|
|||
hi_val);
|
||||
|
||||
if (err)
|
||||
ret = df_v3_6_pmc_set_deferred(adev, config, true);
|
||||
ret = df_v3_6_pmc_set_deferred(adev, config,
|
||||
counter_idx, true);
|
||||
|
||||
break;
|
||||
default:
|
||||
|
@ -615,15 +548,17 @@ static int df_v3_6_pmc_start(struct amdgpu_device *adev, uint64_t config,
|
|||
}
|
||||
|
||||
static int df_v3_6_pmc_stop(struct amdgpu_device *adev, uint64_t config,
|
||||
int is_remove)
|
||||
int counter_idx, int is_remove)
|
||||
{
|
||||
uint32_t lo_base_addr, hi_base_addr, lo_val, hi_val;
|
||||
int ret = 0;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_ARCTURUS:
|
||||
ret = df_v3_6_pmc_get_ctrl_settings(adev,
|
||||
config,
|
||||
counter_idx,
|
||||
&lo_base_addr,
|
||||
&hi_base_addr,
|
||||
&lo_val,
|
||||
|
@ -635,8 +570,8 @@ static int df_v3_6_pmc_stop(struct amdgpu_device *adev, uint64_t config,
|
|||
|
||||
|
||||
if (is_remove) {
|
||||
df_v3_6_reset_perfmon_cntr(adev, config);
|
||||
df_v3_6_pmc_release_cntr(adev, config);
|
||||
df_v3_6_reset_perfmon_cntr(adev, config, counter_idx);
|
||||
df_v3_6_pmc_release_cntr(adev, config, counter_idx);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -649,6 +584,7 @@ static int df_v3_6_pmc_stop(struct amdgpu_device *adev, uint64_t config,
|
|||
|
||||
static void df_v3_6_pmc_get_count(struct amdgpu_device *adev,
|
||||
uint64_t config,
|
||||
int counter_idx,
|
||||
uint64_t *count)
|
||||
{
|
||||
uint32_t lo_base_addr = 0, hi_base_addr = 0, lo_val = 0, hi_val = 0;
|
||||
|
@ -656,14 +592,15 @@ static void df_v3_6_pmc_get_count(struct amdgpu_device *adev,
|
|||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
df_v3_6_pmc_get_read_settings(adev, config, &lo_base_addr,
|
||||
&hi_base_addr);
|
||||
case CHIP_ARCTURUS:
|
||||
df_v3_6_pmc_get_read_settings(adev, config, counter_idx,
|
||||
&lo_base_addr, &hi_base_addr);
|
||||
|
||||
if ((lo_base_addr == 0) || (hi_base_addr == 0))
|
||||
return;
|
||||
|
||||
/* rearm the counter or throw away count value on failure */
|
||||
if (df_v3_6_pmc_is_deferred(adev, config)) {
|
||||
if (df_v3_6_pmc_is_deferred(adev, config, counter_idx)) {
|
||||
int rearm_err = df_v3_6_perfmon_arm_with_status(adev,
|
||||
lo_base_addr, lo_val,
|
||||
hi_base_addr, hi_val);
|
||||
|
@ -671,7 +608,8 @@ static void df_v3_6_pmc_get_count(struct amdgpu_device *adev,
|
|||
if (rearm_err)
|
||||
return;
|
||||
|
||||
df_v3_6_pmc_set_deferred(adev, config, false);
|
||||
df_v3_6_pmc_set_deferred(adev, config, counter_idx,
|
||||
false);
|
||||
}
|
||||
|
||||
df_v3_6_perfmon_rreg(adev, lo_base_addr, &lo_val,
|
||||
|
|
|
@ -35,15 +35,6 @@ enum DF_V3_6_MGCG {
|
|||
DF_V3_6_MGCG_ENABLE_63_CYCLE_DELAY = 15
|
||||
};
|
||||
|
||||
/* Defined in global_features.h as FTI_PERFMON_VISIBLE */
|
||||
#define DF_V3_6_MAX_COUNTERS 4
|
||||
|
||||
/* get flags from df perfmon config */
|
||||
#define DF_V3_6_GET_EVENT(x) (x & 0xFFUL)
|
||||
#define DF_V3_6_GET_INSTANCE(x) ((x >> 8) & 0xFFUL)
|
||||
#define DF_V3_6_GET_UNITMASK(x) ((x >> 16) & 0xFFUL)
|
||||
#define DF_V3_6_PERFMON_OVERFLOW 0xFFFFFFFFFFFFULL
|
||||
|
||||
extern const struct attribute_group *df_v3_6_attr_groups[];
|
||||
extern const struct amdgpu_df_funcs df_v3_6_funcs;
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2020 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "nv.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
#include "soc15_hw_ip.h"
|
||||
#include "dimgrey_cavefish_ip_offset.h"
|
||||
|
||||
int dimgrey_cavefish_reg_base_init(struct amdgpu_device *adev)
|
||||
{
|
||||
/* HW has more IP blocks, only initialize the block needed by driver */
|
||||
uint32_t i;
|
||||
for (i = 0 ; i < MAX_INSTANCE ; ++i) {
|
||||
adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i]));
|
||||
adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i]));
|
||||
adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i]));
|
||||
adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i]));
|
||||
adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i]));
|
||||
adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i]));
|
||||
adev->reg_offset[VCN_HWIP][i] = (uint32_t *)(&(VCN0_BASE.instance[i]));
|
||||
adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i]));
|
||||
adev->reg_offset[DCE_HWIP][i] = (uint32_t *)(&(DCN_BASE.instance[i]));
|
||||
adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA1_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA2_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SDMA3_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
||||
adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
|
||||
adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i]));
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -99,6 +99,23 @@
|
|||
#define mmGCR_GENERAL_CNTL_Sienna_Cichlid 0x1580
|
||||
#define mmGCR_GENERAL_CNTL_Sienna_Cichlid_BASE_IDX 0
|
||||
|
||||
#define mmSPI_CONFIG_CNTL_1_Vangogh 0x2441
|
||||
#define mmSPI_CONFIG_CNTL_1_Vangogh_BASE_IDX 1
|
||||
#define mmVGT_TF_MEMORY_BASE_HI_Vangogh 0x2261
|
||||
#define mmVGT_TF_MEMORY_BASE_HI_Vangogh_BASE_IDX 1
|
||||
#define mmVGT_HS_OFFCHIP_PARAM_Vangogh 0x224f
|
||||
#define mmVGT_HS_OFFCHIP_PARAM_Vangogh_BASE_IDX 1
|
||||
#define mmVGT_TF_RING_SIZE_Vangogh 0x224e
|
||||
#define mmVGT_TF_RING_SIZE_Vangogh_BASE_IDX 1
|
||||
#define mmVGT_GSVS_RING_SIZE_Vangogh 0x2241
|
||||
#define mmVGT_GSVS_RING_SIZE_Vangogh_BASE_IDX 1
|
||||
#define mmVGT_TF_MEMORY_BASE_Vangogh 0x2250
|
||||
#define mmVGT_TF_MEMORY_BASE_Vangogh_BASE_IDX 1
|
||||
#define mmVGT_ESGS_RING_SIZE_Vangogh 0x2240
|
||||
#define mmVGT_ESGS_RING_SIZE_Vangogh_BASE_IDX 1
|
||||
#define mmSPI_CONFIG_CNTL_Vangogh 0x2440
|
||||
#define mmSPI_CONFIG_CNTL_Vangogh_BASE_IDX 1
|
||||
|
||||
#define mmCP_HYP_PFP_UCODE_ADDR 0x5814
|
||||
#define mmCP_HYP_PFP_UCODE_ADDR_BASE_IDX 1
|
||||
#define mmCP_HYP_PFP_UCODE_DATA 0x5815
|
||||
|
@ -112,6 +129,13 @@
|
|||
#define mmCP_HYP_ME_UCODE_DATA 0x5817
|
||||
#define mmCP_HYP_ME_UCODE_DATA_BASE_IDX 1
|
||||
|
||||
#define mmCPG_PSP_DEBUG 0x5c10
|
||||
#define mmCPG_PSP_DEBUG_BASE_IDX 1
|
||||
#define mmCPC_PSP_DEBUG 0x5c11
|
||||
#define mmCPC_PSP_DEBUG_BASE_IDX 1
|
||||
#define CPC_PSP_DEBUG__GPA_OVERRIDE_MASK 0x00000008L
|
||||
#define CPG_PSP_DEBUG__GPA_OVERRIDE_MASK 0x00000008L
|
||||
|
||||
//CC_GC_SA_UNIT_DISABLE
|
||||
#define mmCC_GC_SA_UNIT_DISABLE 0x0fe9
|
||||
#define mmCC_GC_SA_UNIT_DISABLE_BASE_IDX 0
|
||||
|
@ -128,6 +152,9 @@
|
|||
#define PA_SC_ENHANCE_3__FORCE_PBB_WORKLOAD_MODE_TO_ZERO__SHIFT 0x3
|
||||
#define PA_SC_ENHANCE_3__FORCE_PBB_WORKLOAD_MODE_TO_ZERO_MASK 0x00000008L
|
||||
|
||||
#define mmCGTT_SPI_CS_CLK_CTRL 0x507c
|
||||
#define mmCGTT_SPI_CS_CLK_CTRL_BASE_IDX 1
|
||||
|
||||
MODULE_FIRMWARE("amdgpu/navi10_ce.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi10_pfp.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navi10_me.bin");
|
||||
|
@ -168,6 +195,20 @@ MODULE_FIRMWARE("amdgpu/navy_flounder_mec.bin");
|
|||
MODULE_FIRMWARE("amdgpu/navy_flounder_mec2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navy_flounder_rlc.bin");
|
||||
|
||||
MODULE_FIRMWARE("amdgpu/vangogh_ce.bin");
|
||||
MODULE_FIRMWARE("amdgpu/vangogh_pfp.bin");
|
||||
MODULE_FIRMWARE("amdgpu/vangogh_me.bin");
|
||||
MODULE_FIRMWARE("amdgpu/vangogh_mec.bin");
|
||||
MODULE_FIRMWARE("amdgpu/vangogh_mec2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/vangogh_rlc.bin");
|
||||
|
||||
MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_ce.bin");
|
||||
MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_pfp.bin");
|
||||
MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_me.bin");
|
||||
MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_mec.bin");
|
||||
MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_mec2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_rlc.bin");
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_10_1[] =
|
||||
{
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x00400014),
|
||||
|
@ -3094,6 +3135,7 @@ static const struct soc15_reg_golden golden_settings_gc_rlc_spm_10_1_2_nv12[] =
|
|||
|
||||
static const struct soc15_reg_golden golden_settings_gc_10_3[] =
|
||||
{
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CS_CLK_CTRL, 0x78000000, 0x78000100),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_PS_CLK_CTRL, 0xff7f0fff, 0x78000100),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_RA0_CLK_CTRL, 0xff7f0fff, 0x30000100),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_RA1_CLK_CTRL, 0xff7f0fff, 0x7e000100),
|
||||
|
@ -3177,7 +3219,74 @@ static const struct soc15_reg_golden golden_settings_gc_10_3_2[] =
|
|||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER9_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffbfffff, 0x00a00000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x00000fff, 0x000003ff)
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x00000fff, 0x000003ff),
|
||||
|
||||
/* This is not in GDB yet. Don't remove it. It fixes a GPU hang on Navy Flounder. */
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmLDS_CONFIG, 0x00000020, 0x00000020),
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_10_3_vangogh[] =
|
||||
{
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_RA0_CLK_CTRL, 0xff7f0fff, 0x30000100),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_RA1_CLK_CTRL, 0xff7f0fff, 0x7e000100),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCH_PIPE_STEER, 0x000000ff, 0x000000e4),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG3, 0xffffffff, 0x00000200),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0xffffffff, 0x00800000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_EXCEPTION_CONTROL, 0x7fff0f1f, 0x00b80000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG, 0x0c1807ff, 0x00000142),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL, 0x1ff1ffff, 0x00000500),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL1_PIPE_STEER, 0x000000ff, 0x000000e4),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_0, 0x77777777, 0x32103210),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_1, 0x77777777, 0x32103210),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2A_ADDR_MATCH_MASK, 0xffffffff, 0xfffffff3),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_ADDR_MATCH_MASK, 0xffffffff, 0xfffffff3),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CM_CTRL1, 0xff8fff0f, 0x580f1008),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CTRL3, 0xf7ffffff, 0x00f80988),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_CL_ENHANCE, 0xf17fffff, 0x01200007),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_BINNER_TIMEOUT_COUNTER, 0xffffffff, 0x00000800),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_2, 0xffffffbf, 0x00000020),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1_Vangogh, 0xffffffff, 0x00070103),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQG_CONFIG, 0x000017ff, 0x00001000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, 0x00400000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmVGT_GS_MAX_WAVE_ID, 0x00000fff, 0x000000ff),
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_10_3_4[] =
|
||||
{
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_RA0_CLK_CTRL, 0x30000000, 0x30000100),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_RA1_CLK_CTRL, 0x7e000000, 0x7e000100),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCPF_GCR_CNTL, 0x0007ffff, 0x0000c000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG3, 0x00000280, 0x00000280),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0x07800000, 0x00800000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL, 0x00001d00, 0x00000500),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGE_PC_CNTL, 0x003c0000, 0x00280400),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2A_ADDR_MATCH_MASK, 0xffffffff, 0xffffffcf),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_ADDR_MATCH_MASK, 0xffffffff, 0xffffffcf),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CM_CTRL1, 0x40000000, 0x580f1008),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2C_CTRL3, 0x00040000, 0x00f80988),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_CL_ENHANCE, 0x01000000, 0x01200007),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_BINNER_TIMEOUT_COUNTER, 0xffffffff, 0x00000800),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_2, 0x00000800, 0x00000820),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_CONFIG, 0x0000001f, 0x00180070),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER0_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER1_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER10_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER11_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER12_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER13_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER14_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER15_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER2_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER3_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER4_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER5_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER6_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER7_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER8_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER9_SELECT, 0xf0f001ff, 0x00000000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0x01030000, 0x01030000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0x03a00000, 0x00a00000)
|
||||
};
|
||||
|
||||
#define DEFAULT_SH_MEM_CONFIG \
|
||||
|
@ -3192,7 +3301,7 @@ static void gfx_v10_0_set_irq_funcs(struct amdgpu_device *adev);
|
|||
static void gfx_v10_0_set_gds_init(struct amdgpu_device *adev);
|
||||
static void gfx_v10_0_set_rlc_funcs(struct amdgpu_device *adev);
|
||||
static int gfx_v10_0_get_cu_info(struct amdgpu_device *adev,
|
||||
struct amdgpu_cu_info *cu_info);
|
||||
struct amdgpu_cu_info *cu_info);
|
||||
static uint64_t gfx_v10_0_get_gpu_clock_counter(struct amdgpu_device *adev);
|
||||
static void gfx_v10_0_select_se_sh(struct amdgpu_device *adev, u32 se_num,
|
||||
u32 sh_num, u32 instance);
|
||||
|
@ -3389,7 +3498,16 @@ static void gfx_v10_0_init_golden_registers(struct amdgpu_device *adev)
|
|||
golden_settings_gc_10_3_2,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_10_3_2));
|
||||
break;
|
||||
|
||||
case CHIP_VANGOGH:
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_gc_10_3_vangogh,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_10_3_vangogh));
|
||||
break;
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_gc_10_3_4,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_10_3_4));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -3573,6 +3691,8 @@ static void gfx_v10_0_check_fw_write_wait(struct amdgpu_device *adev)
|
|||
break;
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
adev->gfx.cp_fw_write_wait = true;
|
||||
break;
|
||||
default:
|
||||
|
@ -3640,7 +3760,7 @@ static void gfx_v10_0_check_gfxoff_flag(struct amdgpu_device *adev)
|
|||
if (!gfx_v10_0_navi10_gfxoff_should_enable(adev))
|
||||
adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
|
||||
break;
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
|
||||
break;
|
||||
default:
|
||||
|
@ -3685,6 +3805,12 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
|||
case CHIP_NAVY_FLOUNDER:
|
||||
chip_name = "navy_flounder";
|
||||
break;
|
||||
case CHIP_VANGOGH:
|
||||
chip_name = "vangogh";
|
||||
break;
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
chip_name = "dimgrey_cavefish";
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
@ -4200,11 +4326,26 @@ static void gfx_v10_0_read_wave_vgprs(struct amdgpu_device *adev, uint32_t simd,
|
|||
}
|
||||
|
||||
static void gfx_v10_0_select_me_pipe_q(struct amdgpu_device *adev,
|
||||
u32 me, u32 pipe, u32 q, u32 vm)
|
||||
{
|
||||
nv_grbm_select(adev, me, pipe, q, vm);
|
||||
}
|
||||
u32 me, u32 pipe, u32 q, u32 vm)
|
||||
{
|
||||
nv_grbm_select(adev, me, pipe, q, vm);
|
||||
}
|
||||
|
||||
static void gfx_v10_0_update_perfmon_mgcg(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
uint32_t data, def;
|
||||
|
||||
data = def = RREG32_SOC15(GC, 0, mmRLC_PERFMON_CLK_CNTL);
|
||||
|
||||
if (enable)
|
||||
data |= RLC_PERFMON_CLK_CNTL__PERFMON_CLOCK_STATE_MASK;
|
||||
else
|
||||
data &= ~RLC_PERFMON_CLK_CNTL__PERFMON_CLOCK_STATE_MASK;
|
||||
|
||||
if (data != def)
|
||||
WREG32_SOC15(GC, 0, mmRLC_PERFMON_CLK_CNTL, data);
|
||||
}
|
||||
|
||||
static const struct amdgpu_gfx_funcs gfx_v10_0_gfx_funcs = {
|
||||
.get_gpu_clock_counter = &gfx_v10_0_get_gpu_clock_counter,
|
||||
|
@ -4214,6 +4355,7 @@ static const struct amdgpu_gfx_funcs gfx_v10_0_gfx_funcs = {
|
|||
.read_wave_vgprs = &gfx_v10_0_read_wave_vgprs,
|
||||
.select_me_pipe_q = &gfx_v10_0_select_me_pipe_q,
|
||||
.init_spm_golden = &gfx_v10_0_init_spm_golden_registers,
|
||||
.update_perfmon_mgcg = &gfx_v10_0_update_perfmon_mgcg,
|
||||
};
|
||||
|
||||
static void gfx_v10_0_gpu_early_init(struct amdgpu_device *adev)
|
||||
|
@ -4235,6 +4377,8 @@ static void gfx_v10_0_gpu_early_init(struct amdgpu_device *adev)
|
|||
break;
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
adev->gfx.config.max_hw_contexts = 8;
|
||||
adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
|
||||
adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
|
||||
|
@ -4358,6 +4502,8 @@ static int gfx_v10_0_sw_init(void *handle)
|
|||
break;
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
adev->gfx.me.num_me = 1;
|
||||
adev->gfx.me.num_pipe_per_me = 1;
|
||||
adev->gfx.me.num_queue_per_pipe = 1;
|
||||
|
@ -4617,8 +4763,7 @@ static u32 gfx_v10_0_init_pa_sc_tile_steering_override(struct amdgpu_device *ade
|
|||
|
||||
/* for ASICs that integrates GFX v10.3
|
||||
* pa_sc_tile_steering_override should be set to 0 */
|
||||
if (adev->asic_type == CHIP_SIENNA_CICHLID ||
|
||||
adev->asic_type == CHIP_NAVY_FLOUNDER)
|
||||
if (adev->asic_type >= CHIP_SIENNA_CICHLID)
|
||||
return 0;
|
||||
|
||||
/* init num_sc */
|
||||
|
@ -5855,6 +6000,8 @@ static void gfx_v10_0_cp_gfx_set_doorbell(struct amdgpu_device *adev,
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
tmp = REG_SET_FIELD(0, CP_RB_DOORBELL_RANGE_LOWER,
|
||||
DOORBELL_RANGE_LOWER_Sienna_Cichlid, ring->doorbell_index);
|
||||
WREG32_SOC15(GC, 0, mmCP_RB_DOORBELL_RANGE_LOWER, tmp);
|
||||
|
@ -5988,6 +6135,8 @@ static void gfx_v10_0_cp_compute_enable(struct amdgpu_device *adev, bool enable)
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
WREG32_SOC15(GC, 0, mmCP_MEC_CNTL_Sienna_Cichlid, 0);
|
||||
break;
|
||||
default:
|
||||
|
@ -5998,6 +6147,8 @@ static void gfx_v10_0_cp_compute_enable(struct amdgpu_device *adev, bool enable)
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
WREG32_SOC15(GC, 0, mmCP_MEC_CNTL_Sienna_Cichlid,
|
||||
(CP_MEC_CNTL__MEC_ME1_HALT_MASK |
|
||||
CP_MEC_CNTL__MEC_ME2_HALT_MASK));
|
||||
|
@ -6092,6 +6243,8 @@ static void gfx_v10_0_kiq_setting(struct amdgpu_ring *ring)
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
tmp = RREG32_SOC15(GC, 0, mmRLC_CP_SCHEDULERS_Sienna_Cichlid);
|
||||
tmp &= 0xffffff00;
|
||||
tmp |= (ring->me << 5) | (ring->pipe << 3) | (ring->queue);
|
||||
|
@ -6800,6 +6953,7 @@ static bool gfx_v10_0_check_grbm_cam_remapping(struct amdgpu_device *adev)
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
data = RREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE_Sienna_Cichlid);
|
||||
WREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE_Sienna_Cichlid, 0);
|
||||
WREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE_UMD, pattern);
|
||||
|
@ -6812,6 +6966,8 @@ static bool gfx_v10_0_check_grbm_cam_remapping(struct amdgpu_device *adev)
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
case CHIP_VANGOGH:
|
||||
return true;
|
||||
default:
|
||||
data = RREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE);
|
||||
WREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE, 0);
|
||||
|
@ -6839,6 +6995,8 @@ static void gfx_v10_0_setup_grbm_cam_remapping(struct amdgpu_device *adev)
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
/* mmVGT_TF_RING_SIZE_UMD -> mmVGT_TF_RING_SIZE */
|
||||
data = (SOC15_REG_OFFSET(GC, 0, mmVGT_TF_RING_SIZE_UMD) <<
|
||||
GRBM_CAM_DATA__CAM_ADDR__SHIFT) |
|
||||
|
@ -6954,6 +7112,18 @@ static void gfx_v10_0_setup_grbm_cam_remapping(struct amdgpu_device *adev)
|
|||
WREG32_SOC15(GC, 0, mmGRBM_CAM_DATA, data);
|
||||
}
|
||||
|
||||
static void gfx_v10_0_disable_gpa_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t data;
|
||||
data = RREG32_SOC15(GC, 0, mmCPC_PSP_DEBUG);
|
||||
data |= CPC_PSP_DEBUG__GPA_OVERRIDE_MASK;
|
||||
WREG32_SOC15(GC, 0, mmCPC_PSP_DEBUG, data);
|
||||
|
||||
data = RREG32_SOC15(GC, 0, mmCPG_PSP_DEBUG);
|
||||
data |= CPG_PSP_DEBUG__GPA_OVERRIDE_MASK;
|
||||
WREG32_SOC15(GC, 0, mmCPG_PSP_DEBUG, data);
|
||||
}
|
||||
|
||||
static int gfx_v10_0_hw_init(void *handle)
|
||||
{
|
||||
int r;
|
||||
|
@ -6968,7 +7138,7 @@ static int gfx_v10_0_hw_init(void *handle)
|
|||
* loaded firstly, so in direct type, it has to load smc ucode
|
||||
* here before rlc.
|
||||
*/
|
||||
if (adev->smu.ppt_funcs != NULL) {
|
||||
if (adev->smu.ppt_funcs != NULL && !(adev->flags & AMD_IS_APU)) {
|
||||
r = smu_load_microcode(&adev->smu);
|
||||
if (r)
|
||||
return r;
|
||||
|
@ -6979,6 +7149,7 @@ static int gfx_v10_0_hw_init(void *handle)
|
|||
return r;
|
||||
}
|
||||
}
|
||||
gfx_v10_0_disable_gpa_mode(adev);
|
||||
}
|
||||
|
||||
/* if GRBM CAM not remapped, set up the remapping */
|
||||
|
@ -7136,6 +7307,8 @@ static int gfx_v10_0_soft_reset(void *handle)
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
if (REG_GET_FIELD(tmp, GRBM_STATUS2, RLC_BUSY_Sienna_Cichlid))
|
||||
grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset,
|
||||
GRBM_SOFT_RESET,
|
||||
|
@ -7235,13 +7408,16 @@ static int gfx_v10_0_early_init(void *handle)
|
|||
break;
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
adev->gfx.num_gfx_rings = GFX10_NUM_GFX_RINGS_Sienna_Cichlid;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
adev->gfx.num_compute_rings = amdgpu_num_kcq;
|
||||
adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev),
|
||||
AMDGPU_MAX_COMPUTE_RINGS);
|
||||
|
||||
gfx_v10_0_set_kiq_pm4_funcs(adev);
|
||||
gfx_v10_0_set_ring_funcs(adev);
|
||||
|
@ -7288,6 +7464,8 @@ static void gfx_v10_0_set_safe_mode(struct amdgpu_device *adev)
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE_Sienna_Cichlid, data);
|
||||
|
||||
/* wait for RLC_SAFE_MODE */
|
||||
|
@ -7320,6 +7498,8 @@ static void gfx_v10_0_unset_safe_mode(struct amdgpu_device *adev)
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE_Sienna_Cichlid, data);
|
||||
break;
|
||||
default:
|
||||
|
@ -7344,6 +7524,7 @@ static void gfx_v10_0_update_medium_grain_clock_gating(struct amdgpu_device *ade
|
|||
/* 1 - RLC_CGTT_MGCG_OVERRIDE */
|
||||
def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE);
|
||||
data &= ~(RLC_CGTT_MGCG_OVERRIDE__GRBM_CGTT_SCLK_OVERRIDE_MASK |
|
||||
RLC_CGTT_MGCG_OVERRIDE__RLC_CGTT_SCLK_OVERRIDE_MASK |
|
||||
RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGCG_OVERRIDE_MASK |
|
||||
RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGLS_OVERRIDE_MASK |
|
||||
RLC_CGTT_MGCG_OVERRIDE__ENABLE_CGTS_LEGACY_MASK);
|
||||
|
@ -7480,12 +7661,50 @@ static void gfx_v10_0_update_coarse_grain_clock_gating(struct amdgpu_device *ade
|
|||
}
|
||||
}
|
||||
|
||||
static void gfx_v10_0_update_fine_grain_clock_gating(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
uint32_t def, data;
|
||||
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_FGCG)) {
|
||||
def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE);
|
||||
/* unset FGCG override */
|
||||
data &= ~RLC_CGTT_MGCG_OVERRIDE__GFXIP_FGCG_OVERRIDE_MASK;
|
||||
/* update FGCG override bits */
|
||||
if (def != data)
|
||||
WREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE, data);
|
||||
|
||||
def = data = RREG32_SOC15(GC, 0, mmRLC_CLK_CNTL);
|
||||
/* unset RLC SRAM CLK GATER override */
|
||||
data &= ~RLC_CLK_CNTL__RLC_SRAM_CLK_GATER_OVERRIDE_MASK;
|
||||
/* update RLC SRAM CLK GATER override bits */
|
||||
if (def != data)
|
||||
WREG32_SOC15(GC, 0, mmRLC_CLK_CNTL, data);
|
||||
} else {
|
||||
def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE);
|
||||
/* reset FGCG bits */
|
||||
data |= RLC_CGTT_MGCG_OVERRIDE__GFXIP_FGCG_OVERRIDE_MASK;
|
||||
/* disable FGCG*/
|
||||
if (def != data)
|
||||
WREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE, data);
|
||||
|
||||
def = data = RREG32_SOC15(GC, 0, mmRLC_CLK_CNTL);
|
||||
/* reset RLC SRAM CLK GATER bits */
|
||||
data |= RLC_CLK_CNTL__RLC_SRAM_CLK_GATER_OVERRIDE_MASK;
|
||||
/* disable RLC SRAM CLK*/
|
||||
if (def != data)
|
||||
WREG32_SOC15(GC, 0, mmRLC_CLK_CNTL, data);
|
||||
}
|
||||
}
|
||||
|
||||
static int gfx_v10_0_update_gfx_clock_gating(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev);
|
||||
|
||||
if (enable) {
|
||||
/* enable FGCG firstly*/
|
||||
gfx_v10_0_update_fine_grain_clock_gating(adev, enable);
|
||||
/* CGCG/CGLS should be enabled after MGCG/MGLS
|
||||
* === MGCG + MGLS ===
|
||||
*/
|
||||
|
@ -7503,6 +7722,8 @@ static int gfx_v10_0_update_gfx_clock_gating(struct amdgpu_device *adev,
|
|||
gfx_v10_0_update_3d_clock_gating(adev, enable);
|
||||
/* === MGCG + MGLS === */
|
||||
gfx_v10_0_update_medium_grain_clock_gating(adev, enable);
|
||||
/* disable fgcg at last*/
|
||||
gfx_v10_0_update_fine_grain_clock_gating(adev, enable);
|
||||
}
|
||||
|
||||
if (adev->cg_flags &
|
||||
|
@ -7564,6 +7785,27 @@ static bool gfx_v10_0_is_rlcg_access_range(struct amdgpu_device *adev, u32 offse
|
|||
return gfx_v10_0_check_rlcg_range(adev, offset, NULL, 0);
|
||||
}
|
||||
|
||||
static void gfx_v10_cntl_power_gating(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
u32 data = RREG32_SOC15(GC, 0, mmRLC_PG_CNTL);
|
||||
|
||||
if (enable && (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG))
|
||||
data |= RLC_PG_CNTL__GFX_POWER_GATING_ENABLE_MASK;
|
||||
else
|
||||
data &= ~RLC_PG_CNTL__GFX_POWER_GATING_ENABLE_MASK;
|
||||
|
||||
WREG32_SOC15(GC, 0, mmRLC_PG_CNTL, data);
|
||||
}
|
||||
|
||||
static void gfx_v10_cntl_pg(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev);
|
||||
|
||||
gfx_v10_cntl_power_gating(adev, enable);
|
||||
|
||||
amdgpu_gfx_rlc_exit_safe_mode(adev);
|
||||
}
|
||||
|
||||
static const struct amdgpu_rlc_funcs gfx_v10_0_rlc_funcs = {
|
||||
.is_rlc_enabled = gfx_v10_0_is_rlc_enabled,
|
||||
.set_safe_mode = gfx_v10_0_set_safe_mode,
|
||||
|
@ -7609,8 +7851,12 @@ static int gfx_v10_0_set_powergating_state(void *handle,
|
|||
case CHIP_NAVI12:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
amdgpu_gfx_off_ctrl(adev, enable);
|
||||
break;
|
||||
case CHIP_VANGOGH:
|
||||
gfx_v10_cntl_pg(adev, enable);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -7631,6 +7877,8 @@ static int gfx_v10_0_set_clockgating_state(void *handle,
|
|||
case CHIP_NAVI12:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
gfx_v10_0_update_gfx_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE);
|
||||
break;
|
||||
|
@ -7645,6 +7893,11 @@ static void gfx_v10_0_get_clockgating_state(void *handle, u32 *flags)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int data;
|
||||
|
||||
/* AMD_CG_SUPPORT_GFX_FGCG */
|
||||
data = RREG32_KIQ(SOC15_REG_OFFSET(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE));
|
||||
if (!(data & RLC_CGTT_MGCG_OVERRIDE__GFXIP_FGCG_OVERRIDE_MASK))
|
||||
*flags |= AMD_CG_SUPPORT_GFX_FGCG;
|
||||
|
||||
/* AMD_CG_SUPPORT_GFX_MGCG */
|
||||
data = RREG32_KIQ(SOC15_REG_OFFSET(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE));
|
||||
if (!(data & RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGCG_OVERRIDE_MASK))
|
||||
|
@ -8733,6 +8986,8 @@ static void gfx_v10_0_set_rlc_funcs(struct amdgpu_device *adev)
|
|||
case CHIP_NAVI14:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
adev->gfx.rlc.funcs = &gfx_v10_0_rlc_funcs;
|
||||
break;
|
||||
case CHIP_NAVI12:
|
||||
|
|
|
@ -3064,7 +3064,8 @@ static int gfx_v6_0_early_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->gfx.num_gfx_rings = GFX6_NUM_GFX_RINGS;
|
||||
adev->gfx.num_compute_rings = GFX6_NUM_COMPUTE_RINGS;
|
||||
adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev),
|
||||
GFX6_NUM_COMPUTE_RINGS);
|
||||
adev->gfx.funcs = &gfx_v6_0_gfx_funcs;
|
||||
adev->gfx.rlc.funcs = &gfx_v6_0_rlc_funcs;
|
||||
gfx_v6_0_set_ring_funcs(adev);
|
||||
|
|
|
@ -4238,7 +4238,8 @@ static int gfx_v7_0_early_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->gfx.num_gfx_rings = GFX7_NUM_GFX_RINGS;
|
||||
adev->gfx.num_compute_rings = AMDGPU_MAX_COMPUTE_RINGS;
|
||||
adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev),
|
||||
AMDGPU_MAX_COMPUTE_RINGS);
|
||||
adev->gfx.funcs = &gfx_v7_0_gfx_funcs;
|
||||
adev->gfx.rlc.funcs = &gfx_v7_0_rlc_funcs;
|
||||
gfx_v7_0_set_ring_funcs(adev);
|
||||
|
|
|
@ -729,8 +729,13 @@ static void gfx_v8_0_get_cu_info(struct amdgpu_device *adev);
|
|||
static void gfx_v8_0_ring_emit_ce_meta(struct amdgpu_ring *ring);
|
||||
static void gfx_v8_0_ring_emit_de_meta(struct amdgpu_ring *ring);
|
||||
|
||||
#define CG_ACLK_CNTL__ACLK_DIVIDER_MASK 0x0000007fL
|
||||
#define CG_ACLK_CNTL__ACLK_DIVIDER__SHIFT 0x00000000L
|
||||
|
||||
static void gfx_v8_0_init_golden_registers(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t data;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_TOPAZ:
|
||||
amdgpu_device_program_register_sequence(adev,
|
||||
|
@ -790,11 +795,14 @@ static void gfx_v8_0_init_golden_registers(struct amdgpu_device *adev)
|
|||
amdgpu_device_program_register_sequence(adev,
|
||||
polaris10_golden_common_all,
|
||||
ARRAY_SIZE(polaris10_golden_common_all));
|
||||
WREG32_SMC(ixCG_ACLK_CNTL, 0x0000001C);
|
||||
if (adev->pdev->revision == 0xc7 &&
|
||||
data = RREG32_SMC(ixCG_ACLK_CNTL);
|
||||
data &= ~CG_ACLK_CNTL__ACLK_DIVIDER_MASK;
|
||||
data |= 0x18 << CG_ACLK_CNTL__ACLK_DIVIDER__SHIFT;
|
||||
WREG32_SMC(ixCG_ACLK_CNTL, data);
|
||||
if ((adev->pdev->device == 0x67DF) && (adev->pdev->revision == 0xc7) &&
|
||||
((adev->pdev->subsystem_device == 0xb37 && adev->pdev->subsystem_vendor == 0x1002) ||
|
||||
(adev->pdev->subsystem_device == 0x4a8 && adev->pdev->subsystem_vendor == 0x1043) ||
|
||||
(adev->pdev->subsystem_device == 0x9480 && adev->pdev->subsystem_vendor == 0x1682))) {
|
||||
(adev->pdev->subsystem_device == 0x9480 && adev->pdev->subsystem_vendor == 0x1680))) {
|
||||
amdgpu_atombios_i2c_channel_trans(adev, 0x10, 0x96, 0x1E, 0xDD);
|
||||
amdgpu_atombios_i2c_channel_trans(adev, 0x10, 0x96, 0x1F, 0xD0);
|
||||
}
|
||||
|
@ -5058,7 +5066,7 @@ static int gfx_v8_0_pre_soft_reset(void *handle)
|
|||
gfx_v8_0_cp_compute_enable(adev, false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v8_0_soft_reset(void *handle)
|
||||
|
@ -5295,7 +5303,8 @@ static int gfx_v8_0_early_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->gfx.num_gfx_rings = GFX8_NUM_GFX_RINGS;
|
||||
adev->gfx.num_compute_rings = amdgpu_num_kcq;
|
||||
adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev),
|
||||
AMDGPU_MAX_COMPUTE_RINGS);
|
||||
adev->gfx.funcs = &gfx_v8_0_gfx_funcs;
|
||||
gfx_v8_0_set_ring_funcs(adev);
|
||||
gfx_v8_0_set_irq_funcs(adev);
|
||||
|
|
|
@ -117,6 +117,13 @@ MODULE_FIRMWARE("amdgpu/renoir_mec.bin");
|
|||
MODULE_FIRMWARE("amdgpu/renoir_mec2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/renoir_rlc.bin");
|
||||
|
||||
MODULE_FIRMWARE("amdgpu/green_sardine_ce.bin");
|
||||
MODULE_FIRMWARE("amdgpu/green_sardine_pfp.bin");
|
||||
MODULE_FIRMWARE("amdgpu/green_sardine_me.bin");
|
||||
MODULE_FIRMWARE("amdgpu/green_sardine_mec.bin");
|
||||
MODULE_FIRMWARE("amdgpu/green_sardine_mec2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/green_sardine_rlc.bin");
|
||||
|
||||
#define mmTCP_CHAN_STEER_0_ARCT 0x0b03
|
||||
#define mmTCP_CHAN_STEER_0_ARCT_BASE_IDX 0
|
||||
#define mmTCP_CHAN_STEER_1_ARCT 0x0b04
|
||||
|
@ -787,7 +794,7 @@ static void gfx_v9_0_set_irq_funcs(struct amdgpu_device *adev);
|
|||
static void gfx_v9_0_set_gds_init(struct amdgpu_device *adev);
|
||||
static void gfx_v9_0_set_rlc_funcs(struct amdgpu_device *adev);
|
||||
static int gfx_v9_0_get_cu_info(struct amdgpu_device *adev,
|
||||
struct amdgpu_cu_info *cu_info);
|
||||
struct amdgpu_cu_info *cu_info);
|
||||
static uint64_t gfx_v9_0_get_gpu_clock_counter(struct amdgpu_device *adev);
|
||||
static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring);
|
||||
static u64 gfx_v9_0_ring_get_rptr_compute(struct amdgpu_ring *ring);
|
||||
|
@ -1630,7 +1637,10 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev)
|
|||
chip_name = "arcturus";
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
chip_name = "renoir";
|
||||
if (adev->apu_flags & AMD_APU_IS_RENOIR)
|
||||
chip_name = "renoir";
|
||||
else
|
||||
chip_name = "green_sardine";
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
|
@ -4623,7 +4633,8 @@ static int gfx_v9_0_early_init(void *handle)
|
|||
adev->gfx.num_gfx_rings = 0;
|
||||
else
|
||||
adev->gfx.num_gfx_rings = GFX9_NUM_GFX_RINGS;
|
||||
adev->gfx.num_compute_rings = amdgpu_num_kcq;
|
||||
adev->gfx.num_compute_rings = min(amdgpu_gfx_get_num_kcq(adev),
|
||||
AMDGPU_MAX_COMPUTE_RINGS);
|
||||
gfx_v9_0_set_kiq_pm4_funcs(adev);
|
||||
gfx_v9_0_set_ring_funcs(adev);
|
||||
gfx_v9_0_set_irq_funcs(adev);
|
||||
|
@ -5167,7 +5178,7 @@ static void gfx_v9_0_ring_set_wptr_gfx(struct amdgpu_ring *ring)
|
|||
|
||||
if (ring->use_doorbell) {
|
||||
/* XXX check if swapping is necessary on BE */
|
||||
atomic64_set((atomic64_t*)&adev->wb.wb[ring->wptr_offs], ring->wptr);
|
||||
atomic64_set((atomic64_t *)&adev->wb.wb[ring->wptr_offs], ring->wptr);
|
||||
WDOORBELL64(ring->doorbell_index, ring->wptr);
|
||||
} else {
|
||||
WREG32_SOC15(GC, 0, mmCP_RB0_WPTR, lower_32_bits(ring->wptr));
|
||||
|
@ -5353,7 +5364,7 @@ static void gfx_v9_0_ring_set_wptr_compute(struct amdgpu_ring *ring)
|
|||
|
||||
/* XXX check if swapping is necessary on BE */
|
||||
if (ring->use_doorbell) {
|
||||
atomic64_set((atomic64_t*)&adev->wb.wb[ring->wptr_offs], ring->wptr);
|
||||
atomic64_set((atomic64_t *)&adev->wb.wb[ring->wptr_offs], ring->wptr);
|
||||
WDOORBELL64(ring->doorbell_index, ring->wptr);
|
||||
} else{
|
||||
BUG(); /* only DOORBELL method supported on gfx9 now */
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "gfxhub_v1_0.h"
|
||||
#include "gfxhub_v1_1.h"
|
||||
|
||||
#include "gc/gc_9_0_offset.h"
|
||||
#include "gc/gc_9_0_sh_mask.h"
|
||||
|
@ -412,4 +413,5 @@ const struct amdgpu_gfxhub_funcs gfxhub_v1_0_funcs = {
|
|||
.gart_disable = gfxhub_v1_0_gart_disable,
|
||||
.set_fault_enable_default = gfxhub_v1_0_set_fault_enable_default,
|
||||
.init = gfxhub_v1_0_init,
|
||||
.get_xgmi_info = gfxhub_v1_1_get_xgmi_info,
|
||||
};
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "gfxhub_v1_0.h"
|
||||
#include "gfxhub_v1_1.h"
|
||||
|
||||
#include "gc/gc_9_2_1_offset.h"
|
||||
|
@ -29,7 +28,7 @@
|
|||
|
||||
#include "soc15_common.h"
|
||||
|
||||
static int gfxhub_v1_1_get_xgmi_info(struct amdgpu_device *adev)
|
||||
int gfxhub_v1_1_get_xgmi_info(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 xgmi_lfb_cntl = RREG32_SOC15(GC, 0, mmMC_VM_XGMI_LFB_CNTL);
|
||||
u32 max_region =
|
||||
|
@ -67,13 +66,3 @@ static int gfxhub_v1_1_get_xgmi_info(struct amdgpu_device *adev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct amdgpu_gfxhub_funcs gfxhub_v1_1_funcs = {
|
||||
.get_mc_fb_offset = gfxhub_v1_0_get_mc_fb_offset,
|
||||
.setup_vm_pt_regs = gfxhub_v1_0_setup_vm_pt_regs,
|
||||
.gart_enable = gfxhub_v1_0_gart_enable,
|
||||
.gart_disable = gfxhub_v1_0_gart_disable,
|
||||
.set_fault_enable_default = gfxhub_v1_0_set_fault_enable_default,
|
||||
.init = gfxhub_v1_0_init,
|
||||
.get_xgmi_info = gfxhub_v1_1_get_xgmi_info,
|
||||
};
|
||||
|
|
|
@ -24,6 +24,6 @@
|
|||
#ifndef __GFXHUB_V1_1_H__
|
||||
#define __GFXHUB_V1_1_H__
|
||||
|
||||
extern const struct amdgpu_gfxhub_funcs gfxhub_v1_1_funcs;
|
||||
int gfxhub_v1_1_get_xgmi_info(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "gfxhub_v2_0.h"
|
||||
#include "gfxhub_v2_1.h"
|
||||
#include "mmhub_v2_0.h"
|
||||
#include "mmhub_v2_3.h"
|
||||
#include "athub_v2_0.h"
|
||||
#include "athub_v2_1.h"
|
||||
|
||||
|
@ -106,7 +107,8 @@ static int gmc_v10_0_process_interrupt(struct amdgpu_device *adev,
|
|||
* be updated to avoid reading an incorrect value due to
|
||||
* the new fast GRBM interface.
|
||||
*/
|
||||
if (entry->vmid_src == AMDGPU_GFXHUB_0)
|
||||
if ((entry->vmid_src == AMDGPU_GFXHUB_0) &&
|
||||
(adev->asic_type < CHIP_SIENNA_CICHLID))
|
||||
RREG32(hub->vm_l2_pro_fault_status);
|
||||
|
||||
status = RREG32(hub->vm_l2_pro_fault_status);
|
||||
|
@ -145,7 +147,7 @@ static const struct amdgpu_irq_src_funcs gmc_v10_0_ecc_funcs = {
|
|||
.process = amdgpu_umc_process_ecc_irq,
|
||||
};
|
||||
|
||||
static void gmc_v10_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
static void gmc_v10_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->gmc.vm_fault.num_types = 1;
|
||||
adev->gmc.vm_fault.funcs = &gmc_v10_0_irq_funcs;
|
||||
|
@ -231,7 +233,8 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
|
|||
* Issue a dummy read to wait for the ACK register to be cleared
|
||||
* to avoid a false ACK due to the new fast GRBM interface.
|
||||
*/
|
||||
if (vmhub == AMDGPU_GFXHUB_0)
|
||||
if ((vmhub == AMDGPU_GFXHUB_0) &&
|
||||
(adev->asic_type < CHIP_SIENNA_CICHLID))
|
||||
RREG32_NO_KIQ(hub->vm_inv_eng0_req + hub->eng_distance * eng);
|
||||
|
||||
/* Wait for ACK with a delay.*/
|
||||
|
@ -483,7 +486,8 @@ static void gmc_v10_0_emit_pasid_mapping(struct amdgpu_ring *ring, unsigned vmid
|
|||
/*
|
||||
* PTE format on NAVI 10:
|
||||
* 63:59 reserved
|
||||
* 58:57 reserved
|
||||
* 58 reserved and for sienna_cichlid is used for MALL noalloc
|
||||
* 57 reserved
|
||||
* 56 F
|
||||
* 55 L
|
||||
* 54 reserved
|
||||
|
@ -631,7 +635,14 @@ static void gmc_v10_0_set_umc_funcs(struct amdgpu_device *adev)
|
|||
|
||||
static void gmc_v10_0_set_mmhub_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->mmhub.funcs = &mmhub_v2_0_funcs;
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VANGOGH:
|
||||
adev->mmhub.funcs = &mmhub_v2_3_funcs;
|
||||
break;
|
||||
default:
|
||||
adev->mmhub.funcs = &mmhub_v2_0_funcs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void gmc_v10_0_set_gfxhub_funcs(struct amdgpu_device *adev)
|
||||
|
@ -639,6 +650,8 @@ static void gmc_v10_0_set_gfxhub_funcs(struct amdgpu_device *adev)
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
adev->gfxhub.funcs = &gfxhub_v2_1_funcs;
|
||||
break;
|
||||
default:
|
||||
|
@ -733,6 +746,13 @@ static int gmc_v10_0_mc_init(struct amdgpu_device *adev)
|
|||
adev->gmc.aper_base = pci_resource_start(adev->pdev, 0);
|
||||
adev->gmc.aper_size = pci_resource_len(adev->pdev, 0);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
adev->gmc.aper_base = adev->gfxhub.funcs->get_mc_fb_offset(adev);
|
||||
adev->gmc.aper_size = adev->gmc.real_vram_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* In case the PCI BAR is larger than the actual amount of vram */
|
||||
adev->gmc.visible_vram_size = adev->gmc.aper_size;
|
||||
if (adev->gmc.visible_vram_size > adev->gmc.real_vram_size)
|
||||
|
@ -746,6 +766,8 @@ static int gmc_v10_0_mc_init(struct amdgpu_device *adev)
|
|||
case CHIP_NAVI12:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
default:
|
||||
adev->gmc.gart_size = 512ULL << 20;
|
||||
break;
|
||||
|
@ -790,7 +812,10 @@ static int gmc_v10_0_sw_init(void *handle)
|
|||
|
||||
spin_lock_init(&adev->gmc.invalidate_lock);
|
||||
|
||||
if (adev->asic_type == CHIP_SIENNA_CICHLID && amdgpu_emu_mode == 1) {
|
||||
if ((adev->flags & AMD_IS_APU) && amdgpu_emu_mode == 1) {
|
||||
adev->gmc.vram_type = AMDGPU_VRAM_TYPE_DDR4;
|
||||
adev->gmc.vram_width = 64;
|
||||
} else if (amdgpu_emu_mode == 1) {
|
||||
adev->gmc.vram_type = AMDGPU_VRAM_TYPE_GDDR6;
|
||||
adev->gmc.vram_width = 1 * 128; /* numchan * chansize */
|
||||
} else {
|
||||
|
@ -808,6 +833,8 @@ static int gmc_v10_0_sw_init(void *handle)
|
|||
case CHIP_NAVI12:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
adev->num_vmhubs = 2;
|
||||
/*
|
||||
* To fulfill 4-level page support,
|
||||
|
@ -921,6 +948,8 @@ static void gmc_v10_0_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_NAVI12:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1081,8 +1110,8 @@ static int gmc_v10_0_set_clockgating_state(void *handle,
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
if (adev->asic_type == CHIP_SIENNA_CICHLID ||
|
||||
adev->asic_type == CHIP_NAVY_FLOUNDER)
|
||||
if (adev->asic_type >= CHIP_SIENNA_CICHLID &&
|
||||
adev->asic_type <= CHIP_DIMGREY_CAVEFISH)
|
||||
return athub_v2_1_set_clockgating(adev, state);
|
||||
else
|
||||
return athub_v2_0_set_clockgating(adev, state);
|
||||
|
@ -1094,8 +1123,8 @@ static void gmc_v10_0_get_clockgating_state(void *handle, u32 *flags)
|
|||
|
||||
adev->mmhub.funcs->get_clockgating(adev, flags);
|
||||
|
||||
if (adev->asic_type == CHIP_SIENNA_CICHLID ||
|
||||
adev->asic_type == CHIP_NAVY_FLOUNDER)
|
||||
if (adev->asic_type >= CHIP_SIENNA_CICHLID &&
|
||||
adev->asic_type <= CHIP_DIMGREY_CAVEFISH)
|
||||
athub_v2_1_get_clockgating(adev, flags);
|
||||
else
|
||||
athub_v2_0_get_clockgating(adev, flags);
|
||||
|
|
|
@ -230,36 +230,20 @@ static int gmc_v8_0_init_microcode(struct amdgpu_device *adev)
|
|||
chip_name = "tonga";
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
if (((adev->pdev->device == 0x67ef) &&
|
||||
((adev->pdev->revision == 0xe0) ||
|
||||
(adev->pdev->revision == 0xe5))) ||
|
||||
((adev->pdev->device == 0x67ff) &&
|
||||
((adev->pdev->revision == 0xcf) ||
|
||||
(adev->pdev->revision == 0xef) ||
|
||||
(adev->pdev->revision == 0xff))))
|
||||
chip_name = "polaris11_k";
|
||||
else if ((adev->pdev->device == 0x67ef) &&
|
||||
(adev->pdev->revision == 0xe2))
|
||||
if (ASICID_IS_P21(adev->pdev->device, adev->pdev->revision) ||
|
||||
ASICID_IS_P31(adev->pdev->device, adev->pdev->revision))
|
||||
chip_name = "polaris11_k";
|
||||
else
|
||||
chip_name = "polaris11";
|
||||
break;
|
||||
case CHIP_POLARIS10:
|
||||
if ((adev->pdev->device == 0x67df) &&
|
||||
((adev->pdev->revision == 0xe1) ||
|
||||
(adev->pdev->revision == 0xf7)))
|
||||
if (ASICID_IS_P30(adev->pdev->device, adev->pdev->revision))
|
||||
chip_name = "polaris10_k";
|
||||
else
|
||||
chip_name = "polaris10";
|
||||
break;
|
||||
case CHIP_POLARIS12:
|
||||
if (((adev->pdev->device == 0x6987) &&
|
||||
((adev->pdev->revision == 0xc0) ||
|
||||
(adev->pdev->revision == 0xc3))) ||
|
||||
((adev->pdev->device == 0x6981) &&
|
||||
((adev->pdev->revision == 0x00) ||
|
||||
(adev->pdev->revision == 0x01) ||
|
||||
(adev->pdev->revision == 0x10))))
|
||||
if (ASICID_IS_P23(adev->pdev->device, adev->pdev->revision))
|
||||
chip_name = "polaris12_k";
|
||||
else
|
||||
chip_name = "polaris12";
|
||||
|
|
|
@ -510,15 +510,16 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev,
|
|||
}
|
||||
|
||||
static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
{
|
||||
struct amdgpu_vmhub *hub;
|
||||
bool retry_fault = !!(entry->src_data[1] & 0x80);
|
||||
uint32_t status = 0, cid = 0, rw = 0;
|
||||
u64 addr;
|
||||
char hub_name[10];
|
||||
struct amdgpu_task_info task_info;
|
||||
struct amdgpu_vmhub *hub;
|
||||
const char *mmhub_cid;
|
||||
const char *hub_name;
|
||||
u64 addr;
|
||||
|
||||
addr = (u64)entry->src_data[0] << 12;
|
||||
addr |= ((u64)entry->src_data[1] & 0xf) << 44;
|
||||
|
@ -527,105 +528,103 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
|
|||
entry->timestamp))
|
||||
return 1; /* This also prevents sending it to KFD */
|
||||
|
||||
if (entry->client_id == SOC15_IH_CLIENTID_VMC) {
|
||||
snprintf(hub_name, sizeof(hub_name), "mmhub0");
|
||||
hub = &adev->vmhub[AMDGPU_MMHUB_0];
|
||||
} else if (entry->client_id == SOC15_IH_CLIENTID_VMC1) {
|
||||
snprintf(hub_name, sizeof(hub_name), "mmhub1");
|
||||
hub = &adev->vmhub[AMDGPU_MMHUB_1];
|
||||
} else {
|
||||
snprintf(hub_name, sizeof(hub_name), "gfxhub0");
|
||||
hub = &adev->vmhub[AMDGPU_GFXHUB_0];
|
||||
}
|
||||
|
||||
/* If it's the first fault for this address, process it normally */
|
||||
if (retry_fault && !in_interrupt() &&
|
||||
amdgpu_vm_handle_fault(adev, entry->pasid, addr))
|
||||
return 1; /* This also prevents sending it to KFD */
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
/*
|
||||
* Issue a dummy read to wait for the status register to
|
||||
* be updated to avoid reading an incorrect value due to
|
||||
* the new fast GRBM interface.
|
||||
*/
|
||||
if (entry->vmid_src == AMDGPU_GFXHUB_0)
|
||||
RREG32(hub->vm_l2_pro_fault_status);
|
||||
if (!printk_ratelimit())
|
||||
return 0;
|
||||
|
||||
status = RREG32(hub->vm_l2_pro_fault_status);
|
||||
cid = REG_GET_FIELD(status,
|
||||
VM_L2_PROTECTION_FAULT_STATUS, CID);
|
||||
rw = REG_GET_FIELD(status,
|
||||
VM_L2_PROTECTION_FAULT_STATUS, RW);
|
||||
WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1);
|
||||
if (entry->client_id == SOC15_IH_CLIENTID_VMC) {
|
||||
hub_name = "mmhub0";
|
||||
hub = &adev->vmhub[AMDGPU_MMHUB_0];
|
||||
} else if (entry->client_id == SOC15_IH_CLIENTID_VMC1) {
|
||||
hub_name = "mmhub1";
|
||||
hub = &adev->vmhub[AMDGPU_MMHUB_1];
|
||||
} else {
|
||||
hub_name = "gfxhub0";
|
||||
hub = &adev->vmhub[AMDGPU_GFXHUB_0];
|
||||
}
|
||||
|
||||
if (printk_ratelimit()) {
|
||||
struct amdgpu_task_info task_info;
|
||||
memset(&task_info, 0, sizeof(struct amdgpu_task_info));
|
||||
amdgpu_vm_get_task_info(adev, entry->pasid, &task_info);
|
||||
|
||||
memset(&task_info, 0, sizeof(struct amdgpu_task_info));
|
||||
amdgpu_vm_get_task_info(adev, entry->pasid, &task_info);
|
||||
dev_err(adev->dev,
|
||||
"[%s] %s page fault (src_id:%u ring:%u vmid:%u "
|
||||
"pasid:%u, for process %s pid %d thread %s pid %d)\n",
|
||||
hub_name, retry_fault ? "retry" : "no-retry",
|
||||
entry->src_id, entry->ring_id, entry->vmid,
|
||||
entry->pasid, task_info.process_name, task_info.tgid,
|
||||
task_info.task_name, task_info.pid);
|
||||
dev_err(adev->dev, " in page starting at address 0x%016llx from client %d\n",
|
||||
addr, entry->client_id);
|
||||
|
||||
dev_err(adev->dev,
|
||||
"[%s] %s page fault (src_id:%u ring:%u vmid:%u "
|
||||
"pasid:%u, for process %s pid %d thread %s pid %d)\n",
|
||||
hub_name, retry_fault ? "retry" : "no-retry",
|
||||
entry->src_id, entry->ring_id, entry->vmid,
|
||||
entry->pasid, task_info.process_name, task_info.tgid,
|
||||
task_info.task_name, task_info.pid);
|
||||
dev_err(adev->dev, " in page starting at address 0x%016llx from client %d\n",
|
||||
addr, entry->client_id);
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
dev_err(adev->dev,
|
||||
"VM_L2_PROTECTION_FAULT_STATUS:0x%08X\n",
|
||||
status);
|
||||
if (hub == &adev->vmhub[AMDGPU_GFXHUB_0]) {
|
||||
dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n",
|
||||
cid >= ARRAY_SIZE(gfxhub_client_ids) ? "unknown" : gfxhub_client_ids[cid],
|
||||
cid);
|
||||
} else {
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA10:
|
||||
mmhub_cid = mmhub_client_ids_vega10[cid][rw];
|
||||
break;
|
||||
case CHIP_VEGA12:
|
||||
mmhub_cid = mmhub_client_ids_vega12[cid][rw];
|
||||
break;
|
||||
case CHIP_VEGA20:
|
||||
mmhub_cid = mmhub_client_ids_vega20[cid][rw];
|
||||
break;
|
||||
case CHIP_ARCTURUS:
|
||||
mmhub_cid = mmhub_client_ids_arcturus[cid][rw];
|
||||
break;
|
||||
case CHIP_RAVEN:
|
||||
mmhub_cid = mmhub_client_ids_raven[cid][rw];
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
mmhub_cid = mmhub_client_ids_renoir[cid][rw];
|
||||
break;
|
||||
default:
|
||||
mmhub_cid = NULL;
|
||||
break;
|
||||
}
|
||||
dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n",
|
||||
mmhub_cid ? mmhub_cid : "unknown", cid);
|
||||
}
|
||||
dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
VM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS));
|
||||
dev_err(adev->dev, "\t WALKER_ERROR: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
VM_L2_PROTECTION_FAULT_STATUS, WALKER_ERROR));
|
||||
dev_err(adev->dev, "\t PERMISSION_FAULTS: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
VM_L2_PROTECTION_FAULT_STATUS, PERMISSION_FAULTS));
|
||||
dev_err(adev->dev, "\t MAPPING_ERROR: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
VM_L2_PROTECTION_FAULT_STATUS, MAPPING_ERROR));
|
||||
dev_err(adev->dev, "\t RW: 0x%x\n", rw);
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Issue a dummy read to wait for the status register to
|
||||
* be updated to avoid reading an incorrect value due to
|
||||
* the new fast GRBM interface.
|
||||
*/
|
||||
if (entry->vmid_src == AMDGPU_GFXHUB_0)
|
||||
RREG32(hub->vm_l2_pro_fault_status);
|
||||
|
||||
status = RREG32(hub->vm_l2_pro_fault_status);
|
||||
cid = REG_GET_FIELD(status, VM_L2_PROTECTION_FAULT_STATUS, CID);
|
||||
rw = REG_GET_FIELD(status, VM_L2_PROTECTION_FAULT_STATUS, RW);
|
||||
WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1);
|
||||
|
||||
|
||||
dev_err(adev->dev,
|
||||
"VM_L2_PROTECTION_FAULT_STATUS:0x%08X\n",
|
||||
status);
|
||||
if (hub == &adev->vmhub[AMDGPU_GFXHUB_0]) {
|
||||
dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n",
|
||||
cid >= ARRAY_SIZE(gfxhub_client_ids) ? "unknown" :
|
||||
gfxhub_client_ids[cid],
|
||||
cid);
|
||||
} else {
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA10:
|
||||
mmhub_cid = mmhub_client_ids_vega10[cid][rw];
|
||||
break;
|
||||
case CHIP_VEGA12:
|
||||
mmhub_cid = mmhub_client_ids_vega12[cid][rw];
|
||||
break;
|
||||
case CHIP_VEGA20:
|
||||
mmhub_cid = mmhub_client_ids_vega20[cid][rw];
|
||||
break;
|
||||
case CHIP_ARCTURUS:
|
||||
mmhub_cid = mmhub_client_ids_arcturus[cid][rw];
|
||||
break;
|
||||
case CHIP_RAVEN:
|
||||
mmhub_cid = mmhub_client_ids_raven[cid][rw];
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
mmhub_cid = mmhub_client_ids_renoir[cid][rw];
|
||||
break;
|
||||
default:
|
||||
mmhub_cid = NULL;
|
||||
break;
|
||||
}
|
||||
dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n",
|
||||
mmhub_cid ? mmhub_cid : "unknown", cid);
|
||||
}
|
||||
|
||||
dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
VM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS));
|
||||
dev_err(adev->dev, "\t WALKER_ERROR: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
VM_L2_PROTECTION_FAULT_STATUS, WALKER_ERROR));
|
||||
dev_err(adev->dev, "\t PERMISSION_FAULTS: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
VM_L2_PROTECTION_FAULT_STATUS, PERMISSION_FAULTS));
|
||||
dev_err(adev->dev, "\t MAPPING_ERROR: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
VM_L2_PROTECTION_FAULT_STATUS, MAPPING_ERROR));
|
||||
dev_err(adev->dev, "\t RW: 0x%x\n", rw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1166,15 +1165,7 @@ static void gmc_v9_0_set_mmhub_funcs(struct amdgpu_device *adev)
|
|||
|
||||
static void gmc_v9_0_set_gfxhub_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_ARCTURUS:
|
||||
case CHIP_VEGA20:
|
||||
adev->gfxhub.funcs = &gfxhub_v1_1_funcs;
|
||||
break;
|
||||
default:
|
||||
adev->gfxhub.funcs = &gfxhub_v1_0_funcs;
|
||||
break;
|
||||
}
|
||||
adev->gfxhub.funcs = &gfxhub_v1_0_funcs;
|
||||
}
|
||||
|
||||
static int gmc_v9_0_early_init(void *handle)
|
||||
|
|
|
@ -32,19 +32,19 @@
|
|||
#include "vcn/vcn_2_0_0_sh_mask.h"
|
||||
#include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
|
||||
|
||||
#define mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET 0x1bfff
|
||||
#define mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET 0x1bfff
|
||||
#define mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET 0x4029
|
||||
#define mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET 0x402a
|
||||
#define mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET 0x402b
|
||||
#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ea
|
||||
#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40eb
|
||||
#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40eb
|
||||
#define mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET 0x40cf
|
||||
#define mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET 0x40d1
|
||||
#define mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40e8
|
||||
#define mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40e8
|
||||
#define mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40e9
|
||||
#define mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET 0x4082
|
||||
#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ec
|
||||
#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40ed
|
||||
#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40ed
|
||||
#define mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET 0x4085
|
||||
#define mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET 0x4084
|
||||
#define mmUVD_JRBC_STATUS_INTERNAL_OFFSET 0x4089
|
||||
|
@ -247,7 +247,7 @@ static int jpeg_v2_0_disable_power_gating(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int jpeg_v2_0_enable_power_gating(struct amdgpu_device* adev)
|
||||
static int jpeg_v2_0_enable_power_gating(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
|
||||
uint32_t data;
|
||||
|
@ -274,7 +274,7 @@ static int jpeg_v2_0_enable_power_gating(struct amdgpu_device* adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void jpeg_v2_0_disable_clock_gating(struct amdgpu_device* adev)
|
||||
static void jpeg_v2_0_disable_clock_gating(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t data;
|
||||
|
||||
|
@ -297,7 +297,7 @@ static void jpeg_v2_0_disable_clock_gating(struct amdgpu_device* adev)
|
|||
WREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE, data);
|
||||
}
|
||||
|
||||
static void jpeg_v2_0_enable_clock_gating(struct amdgpu_device* adev)
|
||||
static void jpeg_v2_0_enable_clock_gating(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t data;
|
||||
|
||||
|
|
|
@ -247,7 +247,7 @@ static int jpeg_v2_5_resume(void *handle)
|
|||
return r;
|
||||
}
|
||||
|
||||
static void jpeg_v2_5_disable_clock_gating(struct amdgpu_device* adev, int inst)
|
||||
static void jpeg_v2_5_disable_clock_gating(struct amdgpu_device *adev, int inst)
|
||||
{
|
||||
uint32_t data;
|
||||
|
||||
|
@ -276,7 +276,7 @@ static void jpeg_v2_5_disable_clock_gating(struct amdgpu_device* adev, int inst)
|
|||
WREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL, data);
|
||||
}
|
||||
|
||||
static void jpeg_v2_5_enable_clock_gating(struct amdgpu_device* adev, int inst)
|
||||
static void jpeg_v2_5_enable_clock_gating(struct amdgpu_device *adev, int inst)
|
||||
{
|
||||
uint32_t data;
|
||||
|
||||
|
|
|
@ -213,7 +213,7 @@ static int jpeg_v3_0_resume(void *handle)
|
|||
return r;
|
||||
}
|
||||
|
||||
static void jpeg_v3_0_disable_clock_gating(struct amdgpu_device* adev)
|
||||
static void jpeg_v3_0_disable_clock_gating(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
|
||||
|
@ -243,7 +243,7 @@ static void jpeg_v3_0_disable_clock_gating(struct amdgpu_device* adev)
|
|||
WREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL, data);
|
||||
}
|
||||
|
||||
static void jpeg_v3_0_enable_clock_gating(struct amdgpu_device* adev)
|
||||
static void jpeg_v3_0_enable_clock_gating(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
|
||||
|
@ -286,7 +286,7 @@ static int jpeg_v3_0_disable_static_power_gating(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int jpeg_v3_0_enable_static_power_gating(struct amdgpu_device* adev)
|
||||
static int jpeg_v3_0_enable_static_power_gating(struct amdgpu_device *adev)
|
||||
{
|
||||
/* enable anti hang mechanism */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS),
|
||||
|
|
|
@ -46,7 +46,7 @@ static void mes_v10_1_ring_set_wptr(struct amdgpu_ring *ring)
|
|||
struct amdgpu_device *adev = ring->adev;
|
||||
|
||||
if (ring->use_doorbell) {
|
||||
atomic64_set((atomic64_t*)&adev->wb.wb[ring->wptr_offs],
|
||||
atomic64_set((atomic64_t *)&adev->wb.wb[ring->wptr_offs],
|
||||
ring->wptr);
|
||||
WDOORBELL64(ring->doorbell_index, ring->wptr);
|
||||
} else {
|
||||
|
|
|
@ -409,7 +409,7 @@ static void mmhub_v1_0_set_fault_enable_default(struct amdgpu_device *adev, bool
|
|||
CRASH_ON_NO_RETRY_FAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL,
|
||||
CRASH_ON_RETRY_FAULT, 1);
|
||||
}
|
||||
}
|
||||
|
||||
WREG32_SOC15(MMHUB, 0, mmVM_L2_PROTECTION_FAULT_CNTL, tmp);
|
||||
}
|
||||
|
@ -712,7 +712,7 @@ static int mmhub_v1_0_get_ras_error_count(struct amdgpu_device *adev,
|
|||
uint32_t sec_cnt, ded_cnt;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mmhub_v1_0_ras_fields); i++) {
|
||||
if(mmhub_v1_0_ras_fields[i].reg_offset != reg->reg_offset)
|
||||
if (mmhub_v1_0_ras_fields[i].reg_offset != reg->reg_offset)
|
||||
continue;
|
||||
|
||||
sec_cnt = (value &
|
||||
|
|
|
@ -543,6 +543,7 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
|
||||
def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid);
|
||||
break;
|
||||
|
@ -576,6 +577,7 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
if (def != data)
|
||||
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data);
|
||||
if (def1 != data1)
|
||||
|
@ -598,6 +600,7 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
|
||||
break;
|
||||
default:
|
||||
|
@ -614,6 +617,7 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data);
|
||||
break;
|
||||
default:
|
||||
|
@ -635,6 +639,7 @@ static int mmhub_v2_0_set_clockgating(struct amdgpu_device *adev,
|
|||
case CHIP_NAVI12:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
mmhub_v2_0_update_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE);
|
||||
mmhub_v2_0_update_medium_grain_light_sleep(adev,
|
||||
|
@ -657,6 +662,7 @@ static void mmhub_v2_0_get_clockgating(struct amdgpu_device *adev, u32 *flags)
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
|
||||
data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid);
|
||||
break;
|
||||
|
|
|
@ -0,0 +1,589 @@
|
|||
/*
|
||||
* Copyright 2019 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "amdgpu.h"
|
||||
#include "mmhub_v2_3.h"
|
||||
|
||||
#include "mmhub/mmhub_2_3_0_offset.h"
|
||||
#include "mmhub/mmhub_2_3_0_sh_mask.h"
|
||||
#include "mmhub/mmhub_2_3_0_default.h"
|
||||
#include "navi10_enum.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
|
||||
static const char *mmhub_client_ids_vangogh[][2] = {
|
||||
[0][0] = "MP0",
|
||||
[1][0] = "MP1",
|
||||
[2][0] = "DCEDMC",
|
||||
[3][0] = "DCEVGA",
|
||||
[13][0] = "UTCL2",
|
||||
[26][0] = "OSS",
|
||||
[27][0] = "HDP",
|
||||
[28][0] = "VCN",
|
||||
[29][0] = "VCNU",
|
||||
[30][0] = "JPEG",
|
||||
[0][1] = "MP0",
|
||||
[1][1] = "MP1",
|
||||
[2][1] = "DCEDMC",
|
||||
[3][1] = "DCEVGA",
|
||||
[4][1] = "DCEDWB",
|
||||
[5][1] = "XDP",
|
||||
[26][1] = "OSS",
|
||||
[27][1] = "HDP",
|
||||
[28][1] = "VCN",
|
||||
[29][1] = "VCNU",
|
||||
[30][1] = "JPEG",
|
||||
};
|
||||
|
||||
static uint32_t mmhub_v2_3_get_invalidate_req(unsigned int vmid,
|
||||
uint32_t flush_type)
|
||||
{
|
||||
u32 req = 0;
|
||||
|
||||
/* invalidate using legacy mode on vmid*/
|
||||
req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ,
|
||||
PER_VMID_INVALIDATE_REQ, 1 << vmid);
|
||||
req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, FLUSH_TYPE, flush_type);
|
||||
req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PTES, 1);
|
||||
req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE0, 1);
|
||||
req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE1, 1);
|
||||
req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE2, 1);
|
||||
req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L1_PTES, 1);
|
||||
req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ,
|
||||
CLEAR_PROTECTION_FAULT_STATUS_ADDR, 0);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
static void
|
||||
mmhub_v2_3_print_l2_protection_fault_status(struct amdgpu_device *adev,
|
||||
uint32_t status)
|
||||
{
|
||||
uint32_t cid, rw;
|
||||
const char *mmhub_cid = NULL;
|
||||
|
||||
cid = REG_GET_FIELD(status,
|
||||
MMVM_L2_PROTECTION_FAULT_STATUS, CID);
|
||||
rw = REG_GET_FIELD(status,
|
||||
MMVM_L2_PROTECTION_FAULT_STATUS, RW);
|
||||
|
||||
dev_err(adev->dev,
|
||||
"MMVM_L2_PROTECTION_FAULT_STATUS:0x%08X\n",
|
||||
status);
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VANGOGH:
|
||||
mmhub_cid = mmhub_client_ids_vangogh[cid][rw];
|
||||
break;
|
||||
default:
|
||||
mmhub_cid = NULL;
|
||||
break;
|
||||
}
|
||||
dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n",
|
||||
mmhub_cid ? mmhub_cid : "unknown", cid);
|
||||
dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
MMVM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS));
|
||||
dev_err(adev->dev, "\t WALKER_ERROR: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
MMVM_L2_PROTECTION_FAULT_STATUS, WALKER_ERROR));
|
||||
dev_err(adev->dev, "\t PERMISSION_FAULTS: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
MMVM_L2_PROTECTION_FAULT_STATUS, PERMISSION_FAULTS));
|
||||
dev_err(adev->dev, "\t MAPPING_ERROR: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
MMVM_L2_PROTECTION_FAULT_STATUS, MAPPING_ERROR));
|
||||
dev_err(adev->dev, "\t RW: 0x%x\n", rw);
|
||||
}
|
||||
|
||||
static void mmhub_v2_3_setup_vm_pt_regs(struct amdgpu_device *adev,
|
||||
uint32_t vmid,
|
||||
uint64_t page_table_base)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0];
|
||||
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32,
|
||||
hub->ctx_addr_distance * vmid, lower_32_bits(page_table_base));
|
||||
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32,
|
||||
hub->ctx_addr_distance * vmid, upper_32_bits(page_table_base));
|
||||
}
|
||||
|
||||
static void mmhub_v2_3_init_gart_aperture_regs(struct amdgpu_device *adev)
|
||||
{
|
||||
uint64_t pt_base = amdgpu_gmc_pd_addr(adev->gart.bo);
|
||||
|
||||
mmhub_v2_3_setup_vm_pt_regs(adev, 0, pt_base);
|
||||
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32,
|
||||
(u32)(adev->gmc.gart_start >> 12));
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32,
|
||||
(u32)(adev->gmc.gart_start >> 44));
|
||||
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32,
|
||||
(u32)(adev->gmc.gart_end >> 12));
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32,
|
||||
(u32)(adev->gmc.gart_end >> 44));
|
||||
}
|
||||
|
||||
static void mmhub_v2_3_init_system_aperture_regs(struct amdgpu_device *adev)
|
||||
{
|
||||
uint64_t value;
|
||||
uint32_t tmp;
|
||||
|
||||
/* Disable AGP. */
|
||||
WREG32_SOC15(MMHUB, 0, mmMMMC_VM_AGP_BASE, 0);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMMC_VM_AGP_TOP, 0);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMMC_VM_AGP_BOT, 0x00FFFFFF);
|
||||
|
||||
/* Program the system aperture low logical page number. */
|
||||
WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_LOW_ADDR,
|
||||
adev->gmc.vram_start >> 18);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
|
||||
adev->gmc.vram_end >> 18);
|
||||
|
||||
/* Set default page address. */
|
||||
value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start +
|
||||
adev->vm_manager.vram_base_offset;
|
||||
WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
|
||||
(u32)(value >> 12));
|
||||
WREG32_SOC15(MMHUB, 0, mmMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
|
||||
(u32)(value >> 44));
|
||||
|
||||
/* Program "protection fault". */
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32,
|
||||
(u32)(adev->dummy_page_addr >> 12));
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32,
|
||||
(u32)((u64)adev->dummy_page_addr >> 44));
|
||||
|
||||
tmp = RREG32_SOC15(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_CNTL2);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL2,
|
||||
ACTIVE_PAGE_MIGRATION_PTE_READ_RETRY, 1);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_CNTL2, tmp);
|
||||
}
|
||||
|
||||
static void mmhub_v2_3_init_tlb_regs(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
/* Setup TLB control */
|
||||
tmp = RREG32_SOC15(MMHUB, 0, mmMMMC_VM_MX_L1_TLB_CNTL);
|
||||
|
||||
tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, 3);
|
||||
tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
|
||||
ENABLE_ADVANCED_DRIVER_MODEL, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
|
||||
SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
|
||||
tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0);
|
||||
tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
|
||||
MTYPE, MTYPE_UC); /* UC, uncached */
|
||||
|
||||
WREG32_SOC15(MMHUB, 0, mmMMMC_VM_MX_L1_TLB_CNTL, tmp);
|
||||
}
|
||||
|
||||
static void mmhub_v2_3_init_cache_regs(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
/* Setup L2 cache */
|
||||
tmp = RREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, ENABLE_L2_CACHE, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 0);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL,
|
||||
ENABLE_DEFAULT_PAGE_OUT_TO_SYSTEM_MEMORY, 1);
|
||||
/* XXX for emulation, Refer to closed source code.*/
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, L2_PDE0_CACHE_TAG_GENERATION_MODE,
|
||||
0);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, PDE_FAULT_CLASSIFICATION, 0);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, IDENTITY_MODE_FRAGMENT_SIZE, 0);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL, tmp);
|
||||
|
||||
tmp = RREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL2);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL2, tmp);
|
||||
|
||||
tmp = mmMMVM_L2_CNTL3_DEFAULT;
|
||||
if (adev->gmc.translate_further) {
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 12);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3,
|
||||
L2_CACHE_BIGK_FRAGMENT_SIZE, 9);
|
||||
} else {
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 9);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3,
|
||||
L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
|
||||
}
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL3, tmp);
|
||||
|
||||
tmp = mmMMVM_L2_CNTL4_DEFAULT;
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL4, VMC_TAP_PDE_REQUEST_PHYSICAL, 0);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL4, VMC_TAP_PTE_REQUEST_PHYSICAL, 0);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL4, tmp);
|
||||
|
||||
tmp = mmMMVM_L2_CNTL5_DEFAULT;
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
|
||||
WREG32_SOC15(GC, 0, mmMMVM_L2_CNTL5, tmp);
|
||||
}
|
||||
|
||||
static void mmhub_v2_3_enable_system_domain(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = RREG32_SOC15(MMHUB, 0, mmMMVM_CONTEXT0_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, PAGE_TABLE_DEPTH, 0);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL,
|
||||
RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_CONTEXT0_CNTL, tmp);
|
||||
}
|
||||
|
||||
static void mmhub_v2_3_disable_identity_aperture(struct amdgpu_device *adev)
|
||||
{
|
||||
WREG32_SOC15(MMHUB, 0,
|
||||
mmMMVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_LO32,
|
||||
0xFFFFFFFF);
|
||||
WREG32_SOC15(MMHUB, 0,
|
||||
mmMMVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_HI32,
|
||||
0x0000000F);
|
||||
|
||||
WREG32_SOC15(MMHUB, 0,
|
||||
mmMMVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_LO32, 0);
|
||||
WREG32_SOC15(MMHUB, 0,
|
||||
mmMMVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_HI32, 0);
|
||||
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_LO32,
|
||||
0);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_HI32,
|
||||
0);
|
||||
}
|
||||
|
||||
static void mmhub_v2_3_setup_vmid_config(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0];
|
||||
int i;
|
||||
uint32_t tmp;
|
||||
|
||||
for (i = 0; i <= 14; i++) {
|
||||
tmp = RREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_CNTL, i);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, ENABLE_CONTEXT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, PAGE_TABLE_DEPTH,
|
||||
adev->vm_manager.num_level);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
|
||||
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
|
||||
DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT,
|
||||
1);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
|
||||
PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
|
||||
VALID_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
|
||||
READ_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
|
||||
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
|
||||
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
|
||||
PAGE_TABLE_BLOCK_SIZE,
|
||||
adev->vm_manager.block_size - 9);
|
||||
/* Send no-retry XNACK on fault to suppress VM fault storm. */
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
|
||||
RETRY_PERMISSION_OR_INVALID_PAGE_FAULT,
|
||||
!amdgpu_noretry);
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_CNTL,
|
||||
i * hub->ctx_distance, tmp);
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32,
|
||||
i * hub->ctx_addr_distance, 0);
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32,
|
||||
i * hub->ctx_addr_distance, 0);
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_PAGE_TABLE_END_ADDR_LO32,
|
||||
i * hub->ctx_addr_distance,
|
||||
lower_32_bits(adev->vm_manager.max_pfn - 1));
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT1_PAGE_TABLE_END_ADDR_HI32,
|
||||
i * hub->ctx_addr_distance,
|
||||
upper_32_bits(adev->vm_manager.max_pfn - 1));
|
||||
}
|
||||
}
|
||||
|
||||
static void mmhub_v2_3_program_invalidation(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0];
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 18; ++i) {
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0,
|
||||
mmMMVM_INVALIDATE_ENG0_ADDR_RANGE_LO32,
|
||||
i * hub->eng_addr_distance, 0xffffffff);
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0,
|
||||
mmMMVM_INVALIDATE_ENG0_ADDR_RANGE_HI32,
|
||||
i * hub->eng_addr_distance, 0x1f);
|
||||
}
|
||||
}
|
||||
|
||||
static int mmhub_v2_3_gart_enable(struct amdgpu_device *adev)
|
||||
{
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
/*
|
||||
* MMMC_VM_FB_LOCATION_BASE/TOP is NULL for VF, becuase they are
|
||||
* VF copy registers so vbios post doesn't program them, for
|
||||
* SRIOV driver need to program them
|
||||
*/
|
||||
WREG32_SOC15(MMHUB, 0, mmMMMC_VM_FB_LOCATION_BASE,
|
||||
adev->gmc.vram_start >> 24);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMMC_VM_FB_LOCATION_TOP,
|
||||
adev->gmc.vram_end >> 24);
|
||||
}
|
||||
|
||||
/* GART Enable. */
|
||||
mmhub_v2_3_init_gart_aperture_regs(adev);
|
||||
mmhub_v2_3_init_system_aperture_regs(adev);
|
||||
mmhub_v2_3_init_tlb_regs(adev);
|
||||
mmhub_v2_3_init_cache_regs(adev);
|
||||
|
||||
mmhub_v2_3_enable_system_domain(adev);
|
||||
mmhub_v2_3_disable_identity_aperture(adev);
|
||||
mmhub_v2_3_setup_vmid_config(adev);
|
||||
mmhub_v2_3_program_invalidation(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mmhub_v2_3_gart_disable(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0];
|
||||
u32 tmp;
|
||||
u32 i;
|
||||
|
||||
/* Disable all tables */
|
||||
for (i = 0; i < 16; i++)
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0, mmMMVM_CONTEXT0_CNTL,
|
||||
i * hub->ctx_distance, 0);
|
||||
|
||||
/* Setup TLB control */
|
||||
tmp = RREG32_SOC15(MMHUB, 0, mmMMMC_VM_MX_L1_TLB_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 0);
|
||||
tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
|
||||
ENABLE_ADVANCED_DRIVER_MODEL, 0);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMMC_VM_MX_L1_TLB_CNTL, tmp);
|
||||
|
||||
/* Setup L2 cache */
|
||||
tmp = RREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, ENABLE_L2_CACHE, 0);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL, tmp);
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL3, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* mmhub_v2_3_set_fault_enable_default - update GART/VM fault handling
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @value: true redirects VM faults to the default page
|
||||
*/
|
||||
static void mmhub_v2_3_set_fault_enable_default(struct amdgpu_device *adev,
|
||||
bool value)
|
||||
{
|
||||
u32 tmp;
|
||||
tmp = RREG32_SOC15(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
|
||||
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
|
||||
PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
|
||||
PDE1_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
|
||||
PDE2_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
|
||||
TRANSLATE_FURTHER_PROTECTION_FAULT_ENABLE_DEFAULT,
|
||||
value);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
|
||||
NACK_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
|
||||
DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
|
||||
VALID_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
|
||||
READ_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
|
||||
WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
|
||||
EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
|
||||
if (!value) {
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
|
||||
CRASH_ON_NO_RETRY_FAULT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
|
||||
CRASH_ON_RETRY_FAULT, 1);
|
||||
}
|
||||
WREG32_SOC15(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_CNTL, tmp);
|
||||
}
|
||||
|
||||
static const struct amdgpu_vmhub_funcs mmhub_v2_3_vmhub_funcs = {
|
||||
.print_l2_protection_fault_status = mmhub_v2_3_print_l2_protection_fault_status,
|
||||
.get_invalidate_req = mmhub_v2_3_get_invalidate_req,
|
||||
};
|
||||
|
||||
static void mmhub_v2_3_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0];
|
||||
|
||||
hub->ctx0_ptb_addr_lo32 =
|
||||
SOC15_REG_OFFSET(MMHUB, 0,
|
||||
mmMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32);
|
||||
hub->ctx0_ptb_addr_hi32 =
|
||||
SOC15_REG_OFFSET(MMHUB, 0,
|
||||
mmMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32);
|
||||
hub->vm_inv_eng0_sem =
|
||||
SOC15_REG_OFFSET(MMHUB, 0,
|
||||
mmMMVM_INVALIDATE_ENG0_SEM);
|
||||
hub->vm_inv_eng0_req =
|
||||
SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_INVALIDATE_ENG0_REQ);
|
||||
hub->vm_inv_eng0_ack =
|
||||
SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_INVALIDATE_ENG0_ACK);
|
||||
hub->vm_context0_cntl =
|
||||
SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_CONTEXT0_CNTL);
|
||||
hub->vm_l2_pro_fault_status =
|
||||
SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_STATUS);
|
||||
hub->vm_l2_pro_fault_cntl =
|
||||
SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_L2_PROTECTION_FAULT_CNTL);
|
||||
|
||||
hub->ctx_distance = mmMMVM_CONTEXT1_CNTL - mmMMVM_CONTEXT0_CNTL;
|
||||
hub->ctx_addr_distance = mmMMVM_CONTEXT1_PAGE_TABLE_BASE_ADDR_LO32 -
|
||||
mmMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32;
|
||||
hub->eng_distance = mmMMVM_INVALIDATE_ENG1_REQ -
|
||||
mmMMVM_INVALIDATE_ENG0_REQ;
|
||||
hub->eng_addr_distance = mmMMVM_INVALIDATE_ENG1_ADDR_RANGE_LO32 -
|
||||
mmMMVM_INVALIDATE_ENG0_ADDR_RANGE_LO32;
|
||||
|
||||
hub->vm_cntx_cntl_vm_fault = MMVM_CONTEXT1_CNTL__RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
|
||||
MMVM_CONTEXT1_CNTL__DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
|
||||
MMVM_CONTEXT1_CNTL__PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
|
||||
MMVM_CONTEXT1_CNTL__VALID_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
|
||||
MMVM_CONTEXT1_CNTL__READ_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
|
||||
MMVM_CONTEXT1_CNTL__WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
|
||||
MMVM_CONTEXT1_CNTL__EXECUTE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK;
|
||||
|
||||
hub->vmhub_funcs = &mmhub_v2_3_vmhub_funcs;
|
||||
}
|
||||
|
||||
static void
|
||||
mmhub_v2_3_update_medium_grain_clock_gating(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
uint32_t def, data, def1, data1;
|
||||
|
||||
def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG);
|
||||
def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2);
|
||||
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG)) {
|
||||
data |= MM_ATC_L2_MISC_CG__ENABLE_MASK;
|
||||
|
||||
data1 &= ~(DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_RDRET_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK);
|
||||
|
||||
} else {
|
||||
data &= ~MM_ATC_L2_MISC_CG__ENABLE_MASK;
|
||||
|
||||
data1 |= (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_RDRET_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK);
|
||||
}
|
||||
|
||||
if (def != data)
|
||||
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
|
||||
if (def1 != data1)
|
||||
WREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2, data1);
|
||||
}
|
||||
|
||||
static void
|
||||
mmhub_v2_3_update_medium_grain_light_sleep(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
uint32_t def, data;
|
||||
|
||||
def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG);
|
||||
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_LS))
|
||||
data |= MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
|
||||
else
|
||||
data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
|
||||
|
||||
if (def != data)
|
||||
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
|
||||
}
|
||||
|
||||
static int mmhub_v2_3_set_clockgating(struct amdgpu_device *adev,
|
||||
enum amd_clockgating_state state)
|
||||
{
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return 0;
|
||||
|
||||
mmhub_v2_3_update_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
mmhub_v2_3_update_medium_grain_light_sleep(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mmhub_v2_3_get_clockgating(struct amdgpu_device *adev, u32 *flags)
|
||||
{
|
||||
int data, data1;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
*flags = 0;
|
||||
|
||||
data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG);
|
||||
data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2);
|
||||
|
||||
/* AMD_CG_SUPPORT_MC_MGCG */
|
||||
if ((data & MM_ATC_L2_MISC_CG__ENABLE_MASK) &&
|
||||
!(data1 & (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_RDRET_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK |
|
||||
DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK)))
|
||||
*flags |= AMD_CG_SUPPORT_MC_MGCG;
|
||||
|
||||
/* AMD_CG_SUPPORT_MC_LS */
|
||||
if (data & MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK)
|
||||
*flags |= AMD_CG_SUPPORT_MC_LS;
|
||||
}
|
||||
|
||||
const struct amdgpu_mmhub_funcs mmhub_v2_3_funcs = {
|
||||
.ras_late_init = amdgpu_mmhub_ras_late_init,
|
||||
.init = mmhub_v2_3_init,
|
||||
.gart_enable = mmhub_v2_3_gart_enable,
|
||||
.set_fault_enable_default = mmhub_v2_3_set_fault_enable_default,
|
||||
.gart_disable = mmhub_v2_3_gart_disable,
|
||||
.set_clockgating = mmhub_v2_3_set_clockgating,
|
||||
.get_clockgating = mmhub_v2_3_get_clockgating,
|
||||
.setup_vm_pt_regs = mmhub_v2_3_setup_vm_pt_regs,
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 2019 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef __MMHUB_V2_3_H__
|
||||
#define __MMHUB_V2_3_H__
|
||||
|
||||
extern const struct amdgpu_mmhub_funcs mmhub_v2_3_funcs;
|
||||
|
||||
#endif
|
|
@ -314,6 +314,8 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN_Sienna_Cichlid);
|
||||
ih_chicken = REG_SET_FIELD(ih_chicken,
|
||||
IH_CHICKEN, MC_SPACE_GPA_ENABLE, 1);
|
||||
|
@ -660,8 +662,11 @@ static int navi10_ih_sw_init(void *handle)
|
|||
/* use gpu virtual address for ih ring
|
||||
* until ih_checken is programmed to allow
|
||||
* use bus address for ih ring by psp bl */
|
||||
use_bus_addr =
|
||||
(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) ? false : true;
|
||||
if ((adev->flags & AMD_IS_APU) ||
|
||||
(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP))
|
||||
use_bus_addr = false;
|
||||
else
|
||||
use_bus_addr = true;
|
||||
r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 256 * 1024, use_bus_addr);
|
||||
if (r)
|
||||
return r;
|
||||
|
|
|
@ -28,10 +28,12 @@
|
|||
#include "nbio/nbio_2_3_offset.h"
|
||||
#include "nbio/nbio_2_3_sh_mask.h"
|
||||
#include <uapi/linux/kfd_ioctl.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#define smnPCIE_CONFIG_CNTL 0x11180044
|
||||
#define smnCPM_CONTROL 0x11180460
|
||||
#define smnPCIE_CNTL2 0x11180070
|
||||
#define smnPCIE_LC_CNTL 0x11140280
|
||||
|
||||
#define mmBIF_SDMA2_DOORBELL_RANGE 0x01d6
|
||||
#define mmBIF_SDMA2_DOORBELL_RANGE_BASE_IDX 2
|
||||
|
@ -312,6 +314,42 @@ static void nbio_v2_3_init_registers(struct amdgpu_device *adev)
|
|||
WREG32_PCIE(smnPCIE_CONFIG_CNTL, data);
|
||||
}
|
||||
|
||||
#define NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT 0x00000000 // off by default, no gains over L1
|
||||
#define NAVI10_PCIE__LC_L1_INACTIVITY_DEFAULT 0x00000009 // 1=1us, 9=1ms
|
||||
#define NAVI10_PCIE__LC_L1_INACTIVITY_TBT_DEFAULT 0x0000000E // 4ms
|
||||
|
||||
static void nbio_v2_3_enable_aspm(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
uint32_t def, data;
|
||||
|
||||
def = data = RREG32_PCIE(smnPCIE_LC_CNTL);
|
||||
|
||||
if (enable) {
|
||||
/* Disable ASPM L0s/L1 first */
|
||||
data &= ~(PCIE_LC_CNTL__LC_L0S_INACTIVITY_MASK | PCIE_LC_CNTL__LC_L1_INACTIVITY_MASK);
|
||||
|
||||
data |= NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT << PCIE_LC_CNTL__LC_L0S_INACTIVITY__SHIFT;
|
||||
|
||||
if (pci_is_thunderbolt_attached(adev->pdev))
|
||||
data |= NAVI10_PCIE__LC_L1_INACTIVITY_TBT_DEFAULT << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT;
|
||||
else
|
||||
data |= NAVI10_PCIE__LC_L1_INACTIVITY_DEFAULT << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT;
|
||||
|
||||
data &= ~PCIE_LC_CNTL__LC_PMI_TO_L1_DIS_MASK;
|
||||
} else {
|
||||
/* Disbale ASPM L1 */
|
||||
data &= ~PCIE_LC_CNTL__LC_L1_INACTIVITY_MASK;
|
||||
/* Disable ASPM TxL0s */
|
||||
data &= ~PCIE_LC_CNTL__LC_L0S_INACTIVITY_MASK;
|
||||
/* Disable ACPI L1 */
|
||||
data |= PCIE_LC_CNTL__LC_PMI_TO_L1_DIS_MASK;
|
||||
}
|
||||
|
||||
if (def != data)
|
||||
WREG32_PCIE(smnPCIE_LC_CNTL, data);
|
||||
}
|
||||
|
||||
const struct amdgpu_nbio_funcs nbio_v2_3_funcs = {
|
||||
.get_hdp_flush_req_offset = nbio_v2_3_get_hdp_flush_req_offset,
|
||||
.get_hdp_flush_done_offset = nbio_v2_3_get_hdp_flush_done_offset,
|
||||
|
@ -332,4 +370,5 @@ const struct amdgpu_nbio_funcs nbio_v2_3_funcs = {
|
|||
.ih_control = nbio_v2_3_ih_control,
|
||||
.init_registers = nbio_v2_3_init_registers,
|
||||
.remap_hdp_registers = nbio_v2_3_remap_hdp_registers,
|
||||
.enable_aspm = nbio_v2_3_enable_aspm,
|
||||
};
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
static u32 nbio_v6_1_get_rev_id(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0);
|
||||
u32 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0);
|
||||
|
||||
tmp &= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK;
|
||||
tmp >>= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT;
|
||||
|
@ -114,7 +114,7 @@ static void nbio_v6_1_enable_doorbell_selfring_aperture(struct amdgpu_device *ad
|
|||
static void nbio_v6_1_ih_doorbell_range(struct amdgpu_device *adev,
|
||||
bool use_doorbell, int doorbell_index)
|
||||
{
|
||||
u32 ih_doorbell_range = RREG32_SOC15(NBIO, 0 , mmBIF_IH_DOORBELL_RANGE);
|
||||
u32 ih_doorbell_range = RREG32_SOC15(NBIO, 0, mmBIF_IH_DOORBELL_RANGE);
|
||||
|
||||
if (use_doorbell) {
|
||||
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, OFFSET, doorbell_index);
|
||||
|
|
|
@ -43,7 +43,7 @@ static void nbio_v7_0_remap_hdp_registers(struct amdgpu_device *adev)
|
|||
|
||||
static u32 nbio_v7_0_get_rev_id(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0);
|
||||
u32 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0);
|
||||
|
||||
tmp &= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK;
|
||||
tmp >>= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT;
|
||||
|
@ -126,7 +126,7 @@ static void nbio_v7_0_enable_doorbell_selfring_aperture(struct amdgpu_device *ad
|
|||
static void nbio_v7_0_ih_doorbell_range(struct amdgpu_device *adev,
|
||||
bool use_doorbell, int doorbell_index)
|
||||
{
|
||||
u32 ih_doorbell_range = RREG32_SOC15(NBIO, 0 , mmBIF_IH_DOORBELL_RANGE);
|
||||
u32 ih_doorbell_range = RREG32_SOC15(NBIO, 0, mmBIF_IH_DOORBELL_RANGE);
|
||||
|
||||
if (use_doorbell) {
|
||||
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, OFFSET, doorbell_index);
|
||||
|
|
|
@ -0,0 +1,341 @@
|
|||
/*
|
||||
* Copyright 2020 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "nbio_v7_2.h"
|
||||
|
||||
#include "nbio/nbio_7_2_0_offset.h"
|
||||
#include "nbio/nbio_7_2_0_sh_mask.h"
|
||||
#include <uapi/linux/kfd_ioctl.h>
|
||||
|
||||
static void nbio_v7_2_remap_hdp_registers(struct amdgpu_device *adev)
|
||||
{
|
||||
WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL,
|
||||
adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL);
|
||||
WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_REG_FLUSH_CNTL,
|
||||
adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_REG_FLUSH_CNTL);
|
||||
}
|
||||
|
||||
static u32 nbio_v7_2_get_rev_id(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0);
|
||||
|
||||
tmp &= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK;
|
||||
tmp >>= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static void nbio_v7_2_mc_access_enable(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN,
|
||||
BIF_BX0_BIF_FB_EN__FB_READ_EN_MASK |
|
||||
BIF_BX0_BIF_FB_EN__FB_WRITE_EN_MASK);
|
||||
else
|
||||
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN, 0);
|
||||
}
|
||||
|
||||
static void nbio_v7_2_hdp_flush(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring)
|
||||
{
|
||||
if (!ring || !ring->funcs->emit_wreg)
|
||||
WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
|
||||
else
|
||||
amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
|
||||
}
|
||||
|
||||
static u32 nbio_v7_2_get_memsize(struct amdgpu_device *adev)
|
||||
{
|
||||
return RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF0_0_RCC_CONFIG_MEMSIZE);
|
||||
}
|
||||
|
||||
static void nbio_v7_2_sdma_doorbell_range(struct amdgpu_device *adev, int instance,
|
||||
bool use_doorbell, int doorbell_index,
|
||||
int doorbell_size)
|
||||
{
|
||||
u32 reg = SOC15_REG_OFFSET(NBIO, 0, regGDC0_BIF_SDMA0_DOORBELL_RANGE);
|
||||
u32 doorbell_range = RREG32_PCIE_PORT(reg);
|
||||
|
||||
if (use_doorbell) {
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC0_BIF_SDMA0_DOORBELL_RANGE,
|
||||
OFFSET, doorbell_index);
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC0_BIF_SDMA0_DOORBELL_RANGE,
|
||||
SIZE, doorbell_size);
|
||||
} else {
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC0_BIF_SDMA0_DOORBELL_RANGE,
|
||||
SIZE, 0);
|
||||
}
|
||||
|
||||
WREG32_PCIE_PORT(reg, doorbell_range);
|
||||
}
|
||||
|
||||
static void nbio_v7_2_vcn_doorbell_range(struct amdgpu_device *adev, bool use_doorbell,
|
||||
int doorbell_index, int instance)
|
||||
{
|
||||
u32 reg = SOC15_REG_OFFSET(NBIO, 0, regGDC0_BIF_VCN0_DOORBELL_RANGE);
|
||||
u32 doorbell_range = RREG32_PCIE_PORT(reg);
|
||||
|
||||
if (use_doorbell) {
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC0_BIF_VCN0_DOORBELL_RANGE, OFFSET,
|
||||
doorbell_index);
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC0_BIF_VCN0_DOORBELL_RANGE, SIZE, 8);
|
||||
} else {
|
||||
doorbell_range = REG_SET_FIELD(doorbell_range,
|
||||
GDC0_BIF_VCN0_DOORBELL_RANGE, SIZE, 0);
|
||||
}
|
||||
|
||||
WREG32_PCIE_PORT(reg, doorbell_range);
|
||||
}
|
||||
|
||||
static void nbio_v7_2_enable_doorbell_aperture(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF0_0_RCC_DOORBELL_APER_EN);
|
||||
reg = REG_SET_FIELD(reg, RCC_DEV0_EPF0_0_RCC_DOORBELL_APER_EN,
|
||||
BIF_DOORBELL_APER_EN, enable ? 1 : 0);
|
||||
|
||||
WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF0_0_RCC_DOORBELL_APER_EN, reg);
|
||||
}
|
||||
|
||||
static void nbio_v7_2_enable_doorbell_selfring_aperture(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
u32 tmp = 0;
|
||||
|
||||
if (enable) {
|
||||
tmp = REG_SET_FIELD(tmp, BIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL,
|
||||
DOORBELL_SELFRING_GPA_APER_EN, 1) |
|
||||
REG_SET_FIELD(tmp, BIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL,
|
||||
DOORBELL_SELFRING_GPA_APER_MODE, 1) |
|
||||
REG_SET_FIELD(tmp, BIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL,
|
||||
DOORBELL_SELFRING_GPA_APER_SIZE, 0);
|
||||
|
||||
WREG32_SOC15(NBIO, 0,
|
||||
regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_LOW,
|
||||
lower_32_bits(adev->doorbell.base));
|
||||
WREG32_SOC15(NBIO, 0,
|
||||
regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_HIGH,
|
||||
upper_32_bits(adev->doorbell.base));
|
||||
}
|
||||
|
||||
WREG32_SOC15(NBIO, 0, regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL,
|
||||
tmp);
|
||||
}
|
||||
|
||||
|
||||
static void nbio_v7_2_ih_doorbell_range(struct amdgpu_device *adev,
|
||||
bool use_doorbell, int doorbell_index)
|
||||
{
|
||||
u32 ih_doorbell_range = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regGDC0_BIF_IH_DOORBELL_RANGE));
|
||||
|
||||
if (use_doorbell) {
|
||||
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
|
||||
GDC0_BIF_IH_DOORBELL_RANGE, OFFSET,
|
||||
doorbell_index);
|
||||
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
|
||||
GDC0_BIF_IH_DOORBELL_RANGE, SIZE,
|
||||
2);
|
||||
} else {
|
||||
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range,
|
||||
GDC0_BIF_IH_DOORBELL_RANGE, SIZE,
|
||||
0);
|
||||
}
|
||||
|
||||
WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regGDC0_BIF_IH_DOORBELL_RANGE),
|
||||
ih_doorbell_range);
|
||||
}
|
||||
|
||||
static void nbio_v7_2_ih_control(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 interrupt_cntl;
|
||||
|
||||
/* setup interrupt control */
|
||||
WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL2,
|
||||
adev->dummy_page_addr >> 8);
|
||||
|
||||
interrupt_cntl = RREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL);
|
||||
/*
|
||||
* INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=0 - dummy read disabled with msi, enabled without msi
|
||||
* INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=1 - dummy read controlled by IH_DUMMY_RD_EN
|
||||
*/
|
||||
interrupt_cntl = REG_SET_FIELD(interrupt_cntl, BIF_BX0_INTERRUPT_CNTL,
|
||||
IH_DUMMY_RD_OVERRIDE, 0);
|
||||
|
||||
/* INTERRUPT_CNTL__IH_REQ_NONSNOOP_EN_MASK=1 if ring is in non-cacheable memory, e.g., vram */
|
||||
interrupt_cntl = REG_SET_FIELD(interrupt_cntl, BIF_BX0_INTERRUPT_CNTL,
|
||||
IH_REQ_NONSNOOP_EN, 0);
|
||||
|
||||
WREG32_SOC15(NBIO, 0, regBIF_BX0_INTERRUPT_CNTL, interrupt_cntl);
|
||||
}
|
||||
|
||||
static void nbio_v7_2_update_medium_grain_clock_gating(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
uint32_t def, data;
|
||||
|
||||
def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regCPM_CONTROL));
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_BIF_MGCG)) {
|
||||
data |= (CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK |
|
||||
CPM_CONTROL__TXCLK_DYN_GATE_ENABLE_MASK |
|
||||
CPM_CONTROL__TXCLK_LCNT_GATE_ENABLE_MASK |
|
||||
CPM_CONTROL__TXCLK_REGS_GATE_ENABLE_MASK |
|
||||
CPM_CONTROL__TXCLK_PRBS_GATE_ENABLE_MASK |
|
||||
CPM_CONTROL__REFCLK_REGS_GATE_ENABLE_MASK);
|
||||
} else {
|
||||
data &= ~(CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK |
|
||||
CPM_CONTROL__TXCLK_DYN_GATE_ENABLE_MASK |
|
||||
CPM_CONTROL__TXCLK_LCNT_GATE_ENABLE_MASK |
|
||||
CPM_CONTROL__TXCLK_REGS_GATE_ENABLE_MASK |
|
||||
CPM_CONTROL__TXCLK_PRBS_GATE_ENABLE_MASK |
|
||||
CPM_CONTROL__REFCLK_REGS_GATE_ENABLE_MASK);
|
||||
}
|
||||
|
||||
if (def != data)
|
||||
WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regCPM_CONTROL), data);
|
||||
}
|
||||
|
||||
static void nbio_v7_2_update_medium_grain_light_sleep(struct amdgpu_device *adev,
|
||||
bool enable)
|
||||
{
|
||||
uint32_t def, data;
|
||||
|
||||
def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CNTL2));
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_BIF_LS)) {
|
||||
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 (def != data)
|
||||
WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CNTL2), data);
|
||||
}
|
||||
|
||||
static void nbio_v7_2_get_clockgating_state(struct amdgpu_device *adev,
|
||||
u32 *flags)
|
||||
{
|
||||
int data;
|
||||
|
||||
/* AMD_CG_SUPPORT_BIF_MGCG */
|
||||
data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regCPM_CONTROL));
|
||||
if (data & CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK)
|
||||
*flags |= AMD_CG_SUPPORT_BIF_MGCG;
|
||||
|
||||
/* AMD_CG_SUPPORT_BIF_LS */
|
||||
data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CNTL2));
|
||||
if (data & PCIE_CNTL2__SLV_MEM_LS_EN_MASK)
|
||||
*flags |= AMD_CG_SUPPORT_BIF_LS;
|
||||
}
|
||||
|
||||
static u32 nbio_v7_2_get_hdp_flush_req_offset(struct amdgpu_device *adev)
|
||||
{
|
||||
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_REQ);
|
||||
}
|
||||
|
||||
static u32 nbio_v7_2_get_hdp_flush_done_offset(struct amdgpu_device *adev)
|
||||
{
|
||||
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_DONE);
|
||||
}
|
||||
|
||||
static u32 nbio_v7_2_get_pcie_index_offset(struct amdgpu_device *adev)
|
||||
{
|
||||
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX0_PCIE_INDEX2);
|
||||
}
|
||||
|
||||
static u32 nbio_v7_2_get_pcie_data_offset(struct amdgpu_device *adev)
|
||||
{
|
||||
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX0_PCIE_DATA2);
|
||||
}
|
||||
|
||||
static u32 nbio_v7_2_get_pcie_port_index_offset(struct amdgpu_device *adev)
|
||||
{
|
||||
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_RSMU_INDEX);
|
||||
}
|
||||
|
||||
static u32 nbio_v7_2_get_pcie_port_data_offset(struct amdgpu_device *adev)
|
||||
{
|
||||
return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_RSMU_DATA);
|
||||
}
|
||||
|
||||
const struct nbio_hdp_flush_reg nbio_v7_2_hdp_flush_reg = {
|
||||
.ref_and_mask_cp0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP0_MASK,
|
||||
.ref_and_mask_cp1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP1_MASK,
|
||||
.ref_and_mask_cp2 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP2_MASK,
|
||||
.ref_and_mask_cp3 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP3_MASK,
|
||||
.ref_and_mask_cp4 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP4_MASK,
|
||||
.ref_and_mask_cp5 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP5_MASK,
|
||||
.ref_and_mask_cp6 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP6_MASK,
|
||||
.ref_and_mask_cp7 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP7_MASK,
|
||||
.ref_and_mask_cp8 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP8_MASK,
|
||||
.ref_and_mask_cp9 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP9_MASK,
|
||||
.ref_and_mask_sdma0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA0_MASK,
|
||||
.ref_and_mask_sdma1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA1_MASK,
|
||||
};
|
||||
|
||||
static void nbio_v7_2_init_registers(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t def, data;
|
||||
|
||||
def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CONFIG_CNTL));
|
||||
data = REG_SET_FIELD(data, PCIE_CONFIG_CNTL, CI_SWUS_MAX_READ_REQUEST_SIZE_MODE, 1);
|
||||
data = REG_SET_FIELD(data, PCIE_CONFIG_CNTL, CI_SWUS_MAX_READ_REQUEST_SIZE_PRIV, 1);
|
||||
|
||||
if (def != data)
|
||||
WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CONFIG_CNTL),
|
||||
data);
|
||||
}
|
||||
|
||||
const struct amdgpu_nbio_funcs nbio_v7_2_funcs = {
|
||||
.get_hdp_flush_req_offset = nbio_v7_2_get_hdp_flush_req_offset,
|
||||
.get_hdp_flush_done_offset = nbio_v7_2_get_hdp_flush_done_offset,
|
||||
.get_pcie_index_offset = nbio_v7_2_get_pcie_index_offset,
|
||||
.get_pcie_data_offset = nbio_v7_2_get_pcie_data_offset,
|
||||
.get_pcie_port_index_offset = nbio_v7_2_get_pcie_port_index_offset,
|
||||
.get_pcie_port_data_offset = nbio_v7_2_get_pcie_port_data_offset,
|
||||
.get_rev_id = nbio_v7_2_get_rev_id,
|
||||
.mc_access_enable = nbio_v7_2_mc_access_enable,
|
||||
.hdp_flush = nbio_v7_2_hdp_flush,
|
||||
.get_memsize = nbio_v7_2_get_memsize,
|
||||
.sdma_doorbell_range = nbio_v7_2_sdma_doorbell_range,
|
||||
.vcn_doorbell_range = nbio_v7_2_vcn_doorbell_range,
|
||||
.enable_doorbell_aperture = nbio_v7_2_enable_doorbell_aperture,
|
||||
.enable_doorbell_selfring_aperture = nbio_v7_2_enable_doorbell_selfring_aperture,
|
||||
.ih_doorbell_range = nbio_v7_2_ih_doorbell_range,
|
||||
.update_medium_grain_clock_gating = nbio_v7_2_update_medium_grain_clock_gating,
|
||||
.update_medium_grain_light_sleep = nbio_v7_2_update_medium_grain_light_sleep,
|
||||
.get_clockgating_state = nbio_v7_2_get_clockgating_state,
|
||||
.ih_control = nbio_v7_2_ih_control,
|
||||
.init_registers = nbio_v7_2_init_registers,
|
||||
.remap_hdp_registers = nbio_v7_2_remap_hdp_registers,
|
||||
};
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright 2020 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NBIO_V7_2_H__
|
||||
#define __NBIO_V7_2_H__
|
||||
|
||||
#include "soc15_common.h"
|
||||
|
||||
extern const struct nbio_hdp_flush_reg nbio_v7_2_hdp_flush_reg;
|
||||
extern const struct amdgpu_nbio_funcs nbio_v7_2_funcs;
|
||||
|
||||
#endif
|
|
@ -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;
|
||||
}
|
||||
|
@ -455,10 +493,11 @@ void nv_set_virt_ops(struct amdgpu_device *adev)
|
|||
adev->virt.ops = &xgpu_nv_virt_ops;
|
||||
}
|
||||
|
||||
static bool nv_is_blockchain_sku(struct pci_dev *pdev)
|
||||
static bool nv_is_headless_sku(struct pci_dev *pdev)
|
||||
{
|
||||
if (pdev->device == 0x731E &&
|
||||
(pdev->revision == 0xC6 || pdev->revision == 0xC7))
|
||||
if ((pdev->device == 0x731E &&
|
||||
(pdev->revision == 0xC6 || pdev->revision == 0xC7)) ||
|
||||
(pdev->device == 0x7340 && pdev->revision == 0xC9))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -467,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;
|
||||
|
@ -492,7 +536,7 @@ int nv_set_ip_blocks(struct amdgpu_device *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) &&
|
||||
!nv_is_blockchain_sku(adev->pdev))
|
||||
!nv_is_headless_sku(adev->pdev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
#endif
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
|
@ -500,7 +544,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
|||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT &&
|
||||
!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (!nv_is_blockchain_sku(adev->pdev))
|
||||
if (!nv_is_headless_sku(adev->pdev))
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block);
|
||||
if (adev->enable_mes)
|
||||
|
@ -575,6 +619,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 +753,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 +796,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 +812,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 +941,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 +1208,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,
|
||||
|
|
|
@ -34,4 +34,6 @@ int navi10_reg_base_init(struct amdgpu_device *adev);
|
|||
int navi14_reg_base_init(struct amdgpu_device *adev);
|
||||
int navi12_reg_base_init(struct amdgpu_device *adev);
|
||||
int sienna_cichlid_reg_base_init(struct amdgpu_device *adev);
|
||||
void vangogh_reg_base_init(struct amdgpu_device *adev);
|
||||
int dimgrey_cavefish_reg_base_init(struct amdgpu_device *adev);
|
||||
#endif
|
||||
|
|
|
@ -86,21 +86,22 @@ struct psp_gfx_ctrl
|
|||
/* TEE Gfx Command IDs for the ring buffer interface. */
|
||||
enum psp_gfx_cmd_id
|
||||
{
|
||||
GFX_CMD_ID_LOAD_TA = 0x00000001, /* load TA */
|
||||
GFX_CMD_ID_UNLOAD_TA = 0x00000002, /* unload TA */
|
||||
GFX_CMD_ID_INVOKE_CMD = 0x00000003, /* send command to TA */
|
||||
GFX_CMD_ID_LOAD_ASD = 0x00000004, /* load ASD Driver */
|
||||
GFX_CMD_ID_SETUP_TMR = 0x00000005, /* setup TMR region */
|
||||
GFX_CMD_ID_LOAD_IP_FW = 0x00000006, /* load HW IP FW */
|
||||
GFX_CMD_ID_DESTROY_TMR = 0x00000007, /* destroy TMR region */
|
||||
GFX_CMD_ID_SAVE_RESTORE = 0x00000008, /* save/restore HW IP FW */
|
||||
GFX_CMD_ID_SETUP_VMR = 0x00000009, /* setup VMR region */
|
||||
GFX_CMD_ID_DESTROY_VMR = 0x0000000A, /* destroy VMR region */
|
||||
GFX_CMD_ID_PROG_REG = 0x0000000B, /* program regs */
|
||||
GFX_CMD_ID_CLEAR_VF_FW = 0x0000000D, /* Clear VF FW, to be used on VF shutdown. */
|
||||
GFX_CMD_ID_LOAD_TA = 0x00000001, /* load TA */
|
||||
GFX_CMD_ID_UNLOAD_TA = 0x00000002, /* unload TA */
|
||||
GFX_CMD_ID_INVOKE_CMD = 0x00000003, /* send command to TA */
|
||||
GFX_CMD_ID_LOAD_ASD = 0x00000004, /* load ASD Driver */
|
||||
GFX_CMD_ID_SETUP_TMR = 0x00000005, /* setup TMR region */
|
||||
GFX_CMD_ID_LOAD_IP_FW = 0x00000006, /* load HW IP FW */
|
||||
GFX_CMD_ID_DESTROY_TMR = 0x00000007, /* destroy TMR region */
|
||||
GFX_CMD_ID_SAVE_RESTORE = 0x00000008, /* save/restore HW IP FW */
|
||||
GFX_CMD_ID_SETUP_VMR = 0x00000009, /* setup VMR region */
|
||||
GFX_CMD_ID_DESTROY_VMR = 0x0000000A, /* destroy VMR region */
|
||||
GFX_CMD_ID_PROG_REG = 0x0000000B, /* program regs */
|
||||
GFX_CMD_ID_CLEAR_VF_FW = 0x0000000D, /* Clear VF FW, to be used on VF shutdown. */
|
||||
GFX_CMD_ID_GET_FW_ATTESTATION = 0x0000000F, /* Query GPUVA of the Fw Attestation DB */
|
||||
/* IDs upto 0x1F are reserved for older programs (Raven, Vega 10/12/20) */
|
||||
GFX_CMD_ID_LOAD_TOC = 0x00000020, /* Load TOC and obtain TMR size */
|
||||
GFX_CMD_ID_AUTOLOAD_RLC = 0x00000021, /* Indicates all graphics fw loaded, start RLC autoload */
|
||||
GFX_CMD_ID_LOAD_TOC = 0x00000020, /* Load TOC and obtain TMR size */
|
||||
GFX_CMD_ID_AUTOLOAD_RLC = 0x00000021, /* Indicates all graphics fw loaded, start RLC autoload */
|
||||
};
|
||||
|
||||
/* Command to load Trusted Application binary into PSP OS. */
|
||||
|
@ -285,6 +286,25 @@ union psp_gfx_commands
|
|||
struct psp_gfx_cmd_load_toc cmd_load_toc;
|
||||
};
|
||||
|
||||
struct psp_gfx_uresp_reserved
|
||||
{
|
||||
uint32_t reserved[8];
|
||||
};
|
||||
|
||||
/* Command-specific response for Fw Attestation Db */
|
||||
struct psp_gfx_uresp_fwar_db_info
|
||||
{
|
||||
uint32_t fwar_db_addr_lo;
|
||||
uint32_t fwar_db_addr_hi;
|
||||
};
|
||||
|
||||
/* Union of command-specific responses for GPCOM ring. */
|
||||
union psp_gfx_uresp
|
||||
{
|
||||
struct psp_gfx_uresp_reserved reserved;
|
||||
struct psp_gfx_uresp_fwar_db_info fwar_db_info;
|
||||
};
|
||||
|
||||
/* Structure of GFX Response buffer.
|
||||
* For GPCOM I/F it is part of GFX_CMD_RESP buffer, for RBI
|
||||
* it is separate buffer.
|
||||
|
@ -297,9 +317,11 @@ struct psp_gfx_resp
|
|||
uint32_t fw_addr_hi; /* +12 bits [63:32] of FW address within TMR (in response to cmd_load_ip_fw command) */
|
||||
uint32_t tmr_size; /* +16 size of the TMR to be reserved including MM fw and Gfx fw in response to cmd_load_toc command */
|
||||
|
||||
uint32_t reserved[3];
|
||||
uint32_t reserved[11];
|
||||
|
||||
/* total 32 bytes */
|
||||
union psp_gfx_uresp uresp; /* +64 response union containing command-specific responses */
|
||||
|
||||
/* total 96 bytes */
|
||||
};
|
||||
|
||||
/* Structure of Command buffer pointed by psp_gfx_rb_frame.cmd_buf_addr_hi
|
||||
|
|
|
@ -59,6 +59,10 @@ MODULE_FIRMWARE("amdgpu/sienna_cichlid_sos.bin");
|
|||
MODULE_FIRMWARE("amdgpu/sienna_cichlid_ta.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navy_flounder_sos.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navy_flounder_ta.bin");
|
||||
MODULE_FIRMWARE("amdgpu/vangogh_asd.bin");
|
||||
MODULE_FIRMWARE("amdgpu/vangogh_toc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_sos.bin");
|
||||
MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_asd.bin");
|
||||
|
||||
/* address block */
|
||||
#define smnMP1_FIRMWARE_FLAGS 0x3010024
|
||||
|
@ -77,7 +81,7 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
|
|||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
const char *chip_name;
|
||||
char fw_name[30];
|
||||
char fw_name[PSP_FW_NAME_LEN];
|
||||
int err = 0;
|
||||
const struct ta_firmware_header_v1_0 *ta_hdr;
|
||||
|
||||
|
@ -105,24 +109,26 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
|
|||
case CHIP_NAVY_FLOUNDER:
|
||||
chip_name = "navy_flounder";
|
||||
break;
|
||||
case CHIP_VANGOGH:
|
||||
chip_name = "vangogh";
|
||||
break;
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
chip_name = "dimgrey_cavefish";
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
err = psp_init_sos_microcode(psp, chip_name);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (adev->asic_type != CHIP_SIENNA_CICHLID &&
|
||||
adev->asic_type != CHIP_NAVY_FLOUNDER) {
|
||||
err = psp_init_asd_microcode(psp, chip_name);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_ARCTURUS:
|
||||
err = psp_init_sos_microcode(psp, chip_name);
|
||||
if (err)
|
||||
return err;
|
||||
err = psp_init_asd_microcode(psp, chip_name);
|
||||
if (err)
|
||||
return err;
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
|
||||
err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev);
|
||||
if (err) {
|
||||
|
@ -150,6 +156,12 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
|
|||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
case CHIP_NAVI12:
|
||||
err = psp_init_sos_microcode(psp, chip_name);
|
||||
if (err)
|
||||
return err;
|
||||
err = psp_init_asd_microcode(psp, chip_name);
|
||||
if (err)
|
||||
return err;
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
break;
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
|
||||
|
@ -180,10 +192,26 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
|
|||
break;
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
err = psp_init_sos_microcode(psp, chip_name);
|
||||
if (err)
|
||||
return err;
|
||||
err = psp_init_ta_microcode(&adev->psp, chip_name);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
err = psp_init_sos_microcode(psp, chip_name);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
case CHIP_VANGOGH:
|
||||
err = psp_init_asd_microcode(psp, chip_name);
|
||||
if (err)
|
||||
return err;
|
||||
err = psp_init_toc_microcode(psp, chip_name);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
@ -407,8 +435,8 @@ static int psp_v11_0_ring_init(struct psp_context *psp,
|
|||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
if ((!amdgpu_sriov_vf(adev)) &&
|
||||
(adev->asic_type != CHIP_SIENNA_CICHLID) &&
|
||||
(adev->asic_type != CHIP_NAVY_FLOUNDER))
|
||||
!(adev->asic_type >= CHIP_SIENNA_CICHLID &&
|
||||
adev->asic_type <= CHIP_DIMGREY_CAVEFISH))
|
||||
psp_v11_0_reroute_ih(psp);
|
||||
|
||||
ring = &psp->km_ring;
|
||||
|
@ -615,7 +643,7 @@ static int psp_v11_0_memory_training_send_msg(struct psp_context *psp, int msg)
|
|||
static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops)
|
||||
{
|
||||
struct psp_memory_training_context *ctx = &psp->mem_train_ctx;
|
||||
uint32_t *pcache = (uint32_t*)ctx->sys_cache;
|
||||
uint32_t *pcache = (uint32_t *)ctx->sys_cache;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
uint32_t p2c_header[4];
|
||||
uint32_t sz;
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
MODULE_FIRMWARE("amdgpu/renoir_asd.bin");
|
||||
MODULE_FIRMWARE("amdgpu/renoir_ta.bin");
|
||||
MODULE_FIRMWARE("amdgpu/green_sardine_asd.bin");
|
||||
|
||||
/* address block */
|
||||
#define smnMP1_FIRMWARE_FLAGS 0x3010024
|
||||
|
@ -54,7 +55,10 @@ static int psp_v12_0_init_microcode(struct psp_context *psp)
|
|||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RENOIR:
|
||||
chip_name = "renoir";
|
||||
if (adev->apu_flags & AMD_APU_IS_RENOIR)
|
||||
chip_name = "renoir";
|
||||
else
|
||||
chip_name = "green_sardine";
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
|
|
|
@ -69,6 +69,7 @@ MODULE_FIRMWARE("amdgpu/picasso_sdma.bin");
|
|||
MODULE_FIRMWARE("amdgpu/raven2_sdma.bin");
|
||||
MODULE_FIRMWARE("amdgpu/arcturus_sdma.bin");
|
||||
MODULE_FIRMWARE("amdgpu/renoir_sdma.bin");
|
||||
MODULE_FIRMWARE("amdgpu/green_sardine_sdma.bin");
|
||||
|
||||
#define SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK 0x000000F8L
|
||||
#define SDMA0_POWER_CNTL__ON_OFF_STATUS_DURATION_TIME_MASK 0xFC000000L
|
||||
|
@ -568,7 +569,7 @@ static void sdma_v4_0_destroy_inst_ctx(struct amdgpu_device *adev)
|
|||
break;
|
||||
}
|
||||
|
||||
memset((void*)adev->sdma.instance, 0,
|
||||
memset((void *)adev->sdma.instance, 0,
|
||||
sizeof(struct amdgpu_sdma_instance) * AMDGPU_MAX_SDMA_INSTANCES);
|
||||
}
|
||||
|
||||
|
@ -619,7 +620,10 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev)
|
|||
chip_name = "arcturus";
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
chip_name = "renoir";
|
||||
if (adev->apu_flags & AMD_APU_IS_RENOIR)
|
||||
chip_name = "renoir";
|
||||
else
|
||||
chip_name = "green_sardine";
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
|
@ -639,8 +643,8 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev)
|
|||
if (adev->asic_type == CHIP_ARCTURUS) {
|
||||
/* Acturus will leverage the same FW memory
|
||||
for every SDMA instance */
|
||||
memcpy((void*)&adev->sdma.instance[i],
|
||||
(void*)&adev->sdma.instance[0],
|
||||
memcpy((void *)&adev->sdma.instance[i],
|
||||
(void *)&adev->sdma.instance[0],
|
||||
sizeof(struct amdgpu_sdma_instance));
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -46,6 +46,9 @@
|
|||
|
||||
MODULE_FIRMWARE("amdgpu/sienna_cichlid_sdma.bin");
|
||||
MODULE_FIRMWARE("amdgpu/navy_flounder_sdma.bin");
|
||||
MODULE_FIRMWARE("amdgpu/dimgrey_cavefish_sdma.bin");
|
||||
|
||||
MODULE_FIRMWARE("amdgpu/vangogh_sdma.bin");
|
||||
|
||||
#define SDMA1_REG_OFFSET 0x600
|
||||
#define SDMA3_REG_OFFSET 0x400
|
||||
|
@ -87,6 +90,8 @@ static void sdma_v5_2_init_golden_registers(struct amdgpu_device *adev)
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -124,7 +129,7 @@ static void sdma_v5_2_destroy_inst_ctx(struct amdgpu_device *adev)
|
|||
break;
|
||||
}
|
||||
|
||||
memset((void*)adev->sdma.instance, 0,
|
||||
memset((void *)adev->sdma.instance, 0,
|
||||
sizeof(struct amdgpu_sdma_instance) * AMDGPU_MAX_SDMA_INSTANCES);
|
||||
}
|
||||
|
||||
|
@ -160,6 +165,12 @@ static int sdma_v5_2_init_microcode(struct amdgpu_device *adev)
|
|||
case CHIP_NAVY_FLOUNDER:
|
||||
chip_name = "navy_flounder";
|
||||
break;
|
||||
case CHIP_VANGOGH:
|
||||
chip_name = "vangogh";
|
||||
break;
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
chip_name = "dimgrey_cavefish";
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
@ -175,10 +186,10 @@ static int sdma_v5_2_init_microcode(struct amdgpu_device *adev)
|
|||
goto out;
|
||||
|
||||
for (i = 1; i < adev->sdma.num_instances; i++) {
|
||||
if (adev->asic_type == CHIP_SIENNA_CICHLID ||
|
||||
adev->asic_type == CHIP_NAVY_FLOUNDER) {
|
||||
memcpy((void*)&adev->sdma.instance[i],
|
||||
(void*)&adev->sdma.instance[0],
|
||||
if (adev->asic_type >= CHIP_SIENNA_CICHLID &&
|
||||
adev->asic_type <= CHIP_DIMGREY_CAVEFISH) {
|
||||
memcpy((void *)&adev->sdma.instance[i],
|
||||
(void *)&adev->sdma.instance[0],
|
||||
sizeof(struct amdgpu_sdma_instance));
|
||||
} else {
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma%d.bin", chip_name, i);
|
||||
|
@ -696,7 +707,7 @@ static int sdma_v5_2_gfx_resume(struct amdgpu_device *adev)
|
|||
temp &= 0xFF0FFF;
|
||||
temp |= ((CACHE_READ_POLICY_L2__DEFAULT << 12) |
|
||||
(CACHE_WRITE_POLICY_L2__DEFAULT << 14) |
|
||||
0x01000000);
|
||||
SDMA0_UTCL1_PAGE__LLC_NOALLOC_MASK);
|
||||
WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE), temp);
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
|
@ -1169,8 +1180,12 @@ static int sdma_v5_2_early_init(void *handle)
|
|||
adev->sdma.num_instances = 4;
|
||||
break;
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
adev->sdma.num_instances = 2;
|
||||
break;
|
||||
case CHIP_VANGOGH:
|
||||
adev->sdma.num_instances = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1567,6 +1582,8 @@ static int sdma_v5_2_set_clockgating_state(void *handle,
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
sdma_v5_2_update_medium_grain_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE ? true : false);
|
||||
sdma_v5_2_update_medium_grain_light_sleep(adev,
|
||||
|
|
|
@ -1350,7 +1350,7 @@ static void si_vga_set_state(struct amdgpu_device *adev, bool state)
|
|||
|
||||
static u32 si_get_xclk(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 reference_clock = adev->clock.spll.reference_freq;
|
||||
u32 reference_clock = adev->clock.spll.reference_freq;
|
||||
u32 tmp;
|
||||
|
||||
tmp = RREG32(CG_CLKPIN_CNTL_2);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue