Merge tag 'amd-drm-next-5.18-2022-02-11-1' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-next-5.18-2022-02-11-1:

amdgpu:
- Clean up of power management code
- Enable freesync video mode by default
- Clean up of RAS code
- Improve VRAM access for debug using SDMA
- Coding style cleanups
- SR-IOV fixes
- More display FP reorg
- TLB flush fixes for Arcuturus, Vega20
- Misc display fixes
- Rework special register access methods for SR-IOV
- DP2 fixes
- DP tunneling fixes
- DSC fixes
- More IP discovery cleanups
- Misc RAS fixes
- Enable both SMU i2c buses where applicable
- s2idle improvements
- DPCS header cleanup
- Add new CAP firmware support for SR-IOV

amdkfd:
- Misc cleanups
- SVM fixes
- CRIU support
- Clean up MQD manager

UAPI:
- Add interface to amdgpu CTX ioctl to request a stable power state for profiling
  https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/207
- Add amdkfd support for CRIU
  https://github.com/checkpoint-restore/criu/pull/1709
- Remove old unused amdkfd debugger interface
  Was only implemented for Kaveri and was only ever used by an old HSA tool that was never open sourced

radeon:
- Fix error handling in radeon_driver_open_kms
- UVD suspend fix
- Misc fixes

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220211220706.5803-1-alexander.deucher@amd.com
This commit is contained in:
Dave Airlie 2022-02-14 10:31:51 +10:00
commit 123db17ddf
394 changed files with 13697 additions and 10936 deletions

View File

@ -260,7 +260,7 @@ static int aldebaran_mode2_restore_ip(struct amdgpu_device *adev)
adev->gfx.rlc.funcs->resume(adev);
/* Wait for FW reset event complete */
r = smu_wait_for_event(adev, SMU_EVENT_RESET_COMPLETE, 0);
r = amdgpu_dpm_wait_for_event(adev, SMU_EVENT_RESET_COMPLETE, 0);
if (r) {
dev_err(adev->dev,
"Failed to get response from firmware after reset\n");

View File

@ -99,7 +99,6 @@
#include "amdgpu_gem.h"
#include "amdgpu_doorbell.h"
#include "amdgpu_amdkfd.h"
#include "amdgpu_smu.h"
#include "amdgpu_discovery.h"
#include "amdgpu_mes.h"
#include "amdgpu_umc.h"
@ -109,6 +108,7 @@
#include "amdgpu_smuio.h"
#include "amdgpu_fdinfo.h"
#include "amdgpu_mca.h"
#include "amdgpu_ras.h"
#define MAX_GPU_INSTANCE 16
@ -197,7 +197,6 @@ extern int amdgpu_emu_mode;
extern uint amdgpu_smu_memory_pool_size;
extern int amdgpu_smu_pptable_id;
extern uint amdgpu_dc_feature_mask;
extern uint amdgpu_freesync_vid_mode;
extern uint amdgpu_dc_debug_mask;
extern uint amdgpu_dm_abm_level;
extern int amdgpu_backlight;
@ -373,7 +372,8 @@ int amdgpu_device_ip_block_add(struct amdgpu_device *adev,
*/
bool amdgpu_get_bios(struct amdgpu_device *adev);
bool amdgpu_read_bios(struct amdgpu_device *adev);
bool amdgpu_soc15_read_bios_from_rom(struct amdgpu_device *adev,
u8 *bios, u32 length_bytes);
/*
* Clocks
*/
@ -950,12 +950,6 @@ struct amdgpu_device {
/* powerplay */
struct amd_powerplay powerplay;
bool pp_force_state_enabled;
/* smu */
struct smu_context smu;
/* dpm */
struct amdgpu_pm pm;
u32 cg_flags;
u32 pg_flags;
@ -1100,6 +1094,8 @@ struct amdgpu_device {
uint32_t ip_versions[MAX_HWIP][HWIP_MAX_INSTANCE];
bool ram_is_direct_mapped;
struct list_head ras_list;
};
static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)
@ -1321,6 +1317,10 @@ void amdgpu_device_invalidate_hdp(struct amdgpu_device *adev,
struct amdgpu_ring *ring);
void amdgpu_device_halt(struct amdgpu_device *adev);
u32 amdgpu_device_pcie_port_rreg(struct amdgpu_device *adev,
u32 reg);
void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev,
u32 reg, u32 v);
/* atpx handler */
#if defined(CONFIG_VGA_SWITCHEROO)
@ -1408,12 +1408,10 @@ int amdgpu_acpi_smart_shift_update(struct drm_device *dev, enum amdgpu_ss ss_sta
int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev);
void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps);
bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev);
void amdgpu_acpi_detect(void);
#else
static inline int amdgpu_acpi_init(struct amdgpu_device *adev) { return 0; }
static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { }
static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; }
static inline void amdgpu_acpi_detect(void) { }
static inline bool amdgpu_acpi_is_power_shift_control_supported(void) { return false; }
static inline int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
@ -1422,6 +1420,14 @@ static inline int amdgpu_acpi_smart_shift_update(struct drm_device *dev,
enum amdgpu_ss ss_state) { return 0; }
#endif
#if defined(CONFIG_ACPI) && defined(CONFIG_SUSPEND)
bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev);
bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev);
#else
static inline bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev) { return false; }
static inline bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev) { return false; }
#endif
int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
uint64_t addr, struct amdgpu_bo **bo,
struct amdgpu_bo_va_mapping **mapping);
@ -1452,6 +1458,15 @@ int amdgpu_device_set_cg_state(struct amdgpu_device *adev,
int amdgpu_device_set_pg_state(struct amdgpu_device *adev,
enum amd_powergating_state state);
static inline bool amdgpu_device_has_timeouts_enabled(struct amdgpu_device *adev)
{
return amdgpu_gpu_recovery != 0 &&
adev->gfx_timeout != MAX_SCHEDULE_TIMEOUT &&
adev->compute_timeout != MAX_SCHEDULE_TIMEOUT &&
adev->sdma_timeout != MAX_SCHEDULE_TIMEOUT &&
adev->video_timeout != MAX_SCHEDULE_TIMEOUT;
}
#include "amdgpu_object.h"
static inline bool amdgpu_is_tmz(struct amdgpu_device *adev)

View File

@ -1031,6 +1031,20 @@ void amdgpu_acpi_detect(void)
}
}
#if IS_ENABLED(CONFIG_SUSPEND)
/**
* amdgpu_acpi_is_s3_active
*
* @adev: amdgpu_device_pointer
*
* returns true if supported, false if not.
*/
bool amdgpu_acpi_is_s3_active(struct amdgpu_device *adev)
{
return !(adev->flags & AMD_IS_APU) ||
(pm_suspend_target_state == PM_SUSPEND_MEM);
}
/**
* amdgpu_acpi_is_s0ix_active
*
@ -1040,11 +1054,24 @@ void amdgpu_acpi_detect(void)
*/
bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev)
{
#if IS_ENABLED(CONFIG_AMD_PMC) && IS_ENABLED(CONFIG_SUSPEND)
if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) {
if (adev->flags & AMD_IS_APU)
return pm_suspend_target_state == PM_SUSPEND_TO_IDLE;
if (!(adev->flags & AMD_IS_APU) ||
(pm_suspend_target_state != PM_SUSPEND_TO_IDLE))
return false;
if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) {
dev_warn_once(adev->dev,
"Power consumption will be higher as BIOS has not been configured for suspend-to-idle.\n"
"To use suspend-to-idle change the sleep mode in BIOS setup.\n");
return false;
}
#endif
#if !IS_ENABLED(CONFIG_AMD_PMC)
dev_warn_once(adev->dev,
"Power consumption will be higher as the kernel has not been compiled with CONFIG_AMD_PMC.\n");
return false;
#else
return true;
#endif /* CONFIG_AMD_PMC */
}
#endif /* CONFIG_SUSPEND */

View File

@ -131,6 +131,7 @@ struct amdkfd_process_info {
atomic_t evicted_bos;
struct delayed_work restore_userptr_work;
struct pid *pid;
bool block_mmu_notifications;
};
int amdgpu_amdkfd_init(void);
@ -268,7 +269,7 @@ uint64_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *drm_priv);
int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
struct amdgpu_device *adev, uint64_t va, uint64_t size,
void *drm_priv, struct kgd_mem **mem,
uint64_t *offset, uint32_t flags);
uint64_t *offset, uint32_t flags, bool criu_resume);
int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv,
uint64_t *size);
@ -297,6 +298,10 @@ int amdgpu_amdkfd_get_tile_config(struct amdgpu_device *adev,
struct tile_config *config);
void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev,
bool reset);
bool amdgpu_amdkfd_bo_mapped_to_dev(struct amdgpu_device *adev, struct kgd_mem *mem);
void amdgpu_amdkfd_block_mmu_notifications(void *p);
int amdgpu_amdkfd_criu_resume(void *p);
#if IS_ENABLED(CONFIG_HSA_AMD)
void amdgpu_amdkfd_gpuvm_init_mem_limits(void);
void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,

View File

@ -37,10 +37,7 @@ const struct kfd2kgd_calls aldebaran_kfd2kgd = {
.hqd_sdma_is_occupied = kgd_arcturus_hqd_sdma_is_occupied,
.hqd_destroy = kgd_gfx_v9_hqd_destroy,
.hqd_sdma_destroy = kgd_arcturus_hqd_sdma_destroy,
.address_watch_disable = kgd_gfx_v9_address_watch_disable,
.address_watch_execute = kgd_gfx_v9_address_watch_execute,
.wave_control_execute = kgd_gfx_v9_wave_control_execute,
.address_watch_get_offset = kgd_gfx_v9_address_watch_get_offset,
.get_atc_vmid_pasid_mapping_info =
kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
.set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base,

View File

@ -289,10 +289,7 @@ const struct kfd2kgd_calls arcturus_kfd2kgd = {
.hqd_sdma_is_occupied = kgd_arcturus_hqd_sdma_is_occupied,
.hqd_destroy = kgd_gfx_v9_hqd_destroy,
.hqd_sdma_destroy = kgd_arcturus_hqd_sdma_destroy,
.address_watch_disable = kgd_gfx_v9_address_watch_disable,
.address_watch_execute = kgd_gfx_v9_address_watch_execute,
.wave_control_execute = kgd_gfx_v9_wave_control_execute,
.address_watch_get_offset = kgd_gfx_v9_address_watch_get_offset,
.get_atc_vmid_pasid_mapping_info =
kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
.set_vm_context_page_table_base =

View File

@ -671,20 +671,6 @@ static bool get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
}
static int kgd_address_watch_disable(struct amdgpu_device *adev)
{
return 0;
}
static int kgd_address_watch_execute(struct amdgpu_device *adev,
unsigned int watch_point_id,
uint32_t cntl_val,
uint32_t addr_hi,
uint32_t addr_lo)
{
return 0;
}
static int kgd_wave_control_execute(struct amdgpu_device *adev,
uint32_t gfx_index_val,
uint32_t sq_cmd)
@ -709,13 +695,6 @@ static int kgd_wave_control_execute(struct amdgpu_device *adev,
return 0;
}
static uint32_t kgd_address_watch_get_offset(struct amdgpu_device *adev,
unsigned int watch_point_id,
unsigned int reg_offset)
{
return 0;
}
static void set_vm_context_page_table_base(struct amdgpu_device *adev,
uint32_t vmid, uint64_t page_table_base)
{
@ -767,10 +746,7 @@ const struct kfd2kgd_calls gfx_v10_kfd2kgd = {
.hqd_sdma_is_occupied = kgd_hqd_sdma_is_occupied,
.hqd_destroy = kgd_hqd_destroy,
.hqd_sdma_destroy = kgd_hqd_sdma_destroy,
.address_watch_disable = kgd_address_watch_disable,
.address_watch_execute = kgd_address_watch_execute,
.wave_control_execute = kgd_wave_control_execute,
.address_watch_get_offset = kgd_address_watch_get_offset,
.get_atc_vmid_pasid_mapping_info =
get_atc_vmid_pasid_mapping_info,
.set_vm_context_page_table_base = set_vm_context_page_table_base,

View File

@ -582,21 +582,6 @@ static int hqd_sdma_destroy_v10_3(struct amdgpu_device *adev, void *mqd,
return 0;
}
static int address_watch_disable_v10_3(struct amdgpu_device *adev)
{
return 0;
}
static int address_watch_execute_v10_3(struct amdgpu_device *adev,
unsigned int watch_point_id,
uint32_t cntl_val,
uint32_t addr_hi,
uint32_t addr_lo)
{
return 0;
}
static int wave_control_execute_v10_3(struct amdgpu_device *adev,
uint32_t gfx_index_val,
uint32_t sq_cmd)
@ -621,13 +606,6 @@ static int wave_control_execute_v10_3(struct amdgpu_device *adev,
return 0;
}
static uint32_t address_watch_get_offset_v10_3(struct amdgpu_device *adev,
unsigned int watch_point_id,
unsigned int reg_offset)
{
return 0;
}
static void set_vm_context_page_table_base_v10_3(struct amdgpu_device *adev,
uint32_t vmid, uint64_t page_table_base)
{
@ -809,10 +787,7 @@ const struct kfd2kgd_calls gfx_v10_3_kfd2kgd = {
.hqd_sdma_is_occupied = hqd_sdma_is_occupied_v10_3,
.hqd_destroy = hqd_destroy_v10_3,
.hqd_sdma_destroy = hqd_sdma_destroy_v10_3,
.address_watch_disable = address_watch_disable_v10_3,
.address_watch_execute = address_watch_execute_v10_3,
.wave_control_execute = wave_control_execute_v10_3,
.address_watch_get_offset = address_watch_get_offset_v10_3,
.get_atc_vmid_pasid_mapping_info = NULL,
.set_vm_context_page_table_base = set_vm_context_page_table_base_v10_3,
.program_trap_handler_settings = program_trap_handler_settings_v10_3,

View File

@ -45,43 +45,6 @@ enum {
MAX_WATCH_ADDRESSES = 4
};
enum {
ADDRESS_WATCH_REG_ADDR_HI = 0,
ADDRESS_WATCH_REG_ADDR_LO,
ADDRESS_WATCH_REG_CNTL,
ADDRESS_WATCH_REG_MAX
};
/* not defined in the CI/KV reg file */
enum {
ADDRESS_WATCH_REG_CNTL_ATC_BIT = 0x10000000UL,
ADDRESS_WATCH_REG_CNTL_DEFAULT_MASK = 0x00FFFFFF,
ADDRESS_WATCH_REG_ADDLOW_MASK_EXTENSION = 0x03000000,
/* extend the mask to 26 bits to match the low address field */
ADDRESS_WATCH_REG_ADDLOW_SHIFT = 6,
ADDRESS_WATCH_REG_ADDHIGH_MASK = 0xFFFF
};
static const uint32_t watchRegs[MAX_WATCH_ADDRESSES * ADDRESS_WATCH_REG_MAX] = {
mmTCP_WATCH0_ADDR_H, mmTCP_WATCH0_ADDR_L, mmTCP_WATCH0_CNTL,
mmTCP_WATCH1_ADDR_H, mmTCP_WATCH1_ADDR_L, mmTCP_WATCH1_CNTL,
mmTCP_WATCH2_ADDR_H, mmTCP_WATCH2_ADDR_L, mmTCP_WATCH2_CNTL,
mmTCP_WATCH3_ADDR_H, mmTCP_WATCH3_ADDR_L, mmTCP_WATCH3_CNTL
};
union TCP_WATCH_CNTL_BITS {
struct {
uint32_t mask:24;
uint32_t vmid:4;
uint32_t atc:1;
uint32_t mode:2;
uint32_t valid:1;
} bitfields, bits;
uint32_t u32All;
signed int i32All;
float f32All;
};
static void lock_srbm(struct amdgpu_device *adev, uint32_t mec, uint32_t pipe,
uint32_t queue, uint32_t vmid)
{
@ -529,55 +492,6 @@ static int kgd_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd,
return 0;
}
static int kgd_address_watch_disable(struct amdgpu_device *adev)
{
union TCP_WATCH_CNTL_BITS cntl;
unsigned int i;
cntl.u32All = 0;
cntl.bitfields.valid = 0;
cntl.bitfields.mask = ADDRESS_WATCH_REG_CNTL_DEFAULT_MASK;
cntl.bitfields.atc = 1;
/* Turning off this address until we set all the registers */
for (i = 0; i < MAX_WATCH_ADDRESSES; i++)
WREG32(watchRegs[i * ADDRESS_WATCH_REG_MAX +
ADDRESS_WATCH_REG_CNTL], cntl.u32All);
return 0;
}
static int kgd_address_watch_execute(struct amdgpu_device *adev,
unsigned int watch_point_id,
uint32_t cntl_val,
uint32_t addr_hi,
uint32_t addr_lo)
{
union TCP_WATCH_CNTL_BITS cntl;
cntl.u32All = cntl_val;
/* Turning off this watch point until we set all the registers */
cntl.bitfields.valid = 0;
WREG32(watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX +
ADDRESS_WATCH_REG_CNTL], cntl.u32All);
WREG32(watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX +
ADDRESS_WATCH_REG_ADDR_HI], addr_hi);
WREG32(watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX +
ADDRESS_WATCH_REG_ADDR_LO], addr_lo);
/* Enable the watch point */
cntl.bitfields.valid = 1;
WREG32(watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX +
ADDRESS_WATCH_REG_CNTL], cntl.u32All);
return 0;
}
static int kgd_wave_control_execute(struct amdgpu_device *adev,
uint32_t gfx_index_val,
uint32_t sq_cmd)
@ -602,13 +516,6 @@ static int kgd_wave_control_execute(struct amdgpu_device *adev,
return 0;
}
static uint32_t kgd_address_watch_get_offset(struct amdgpu_device *adev,
unsigned int watch_point_id,
unsigned int reg_offset)
{
return watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX + reg_offset];
}
static bool get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
uint8_t vmid, uint16_t *p_pasid)
{
@ -665,10 +572,7 @@ const struct kfd2kgd_calls gfx_v7_kfd2kgd = {
.hqd_sdma_is_occupied = kgd_hqd_sdma_is_occupied,
.hqd_destroy = kgd_hqd_destroy,
.hqd_sdma_destroy = kgd_hqd_sdma_destroy,
.address_watch_disable = kgd_address_watch_disable,
.address_watch_execute = kgd_address_watch_execute,
.wave_control_execute = kgd_wave_control_execute,
.address_watch_get_offset = kgd_address_watch_get_offset,
.get_atc_vmid_pasid_mapping_info = get_atc_vmid_pasid_mapping_info,
.set_scratch_backing_va = set_scratch_backing_va,
.set_vm_context_page_table_base = set_vm_context_page_table_base,

View File

@ -538,20 +538,6 @@ static bool get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
}
static int kgd_address_watch_disable(struct amdgpu_device *adev)
{
return 0;
}
static int kgd_address_watch_execute(struct amdgpu_device *adev,
unsigned int watch_point_id,
uint32_t cntl_val,
uint32_t addr_hi,
uint32_t addr_lo)
{
return 0;
}
static int kgd_wave_control_execute(struct amdgpu_device *adev,
uint32_t gfx_index_val,
uint32_t sq_cmd)
@ -576,13 +562,6 @@ static int kgd_wave_control_execute(struct amdgpu_device *adev,
return 0;
}
static uint32_t kgd_address_watch_get_offset(struct amdgpu_device *adev,
unsigned int watch_point_id,
unsigned int reg_offset)
{
return 0;
}
static void set_scratch_backing_va(struct amdgpu_device *adev,
uint64_t va, uint32_t vmid)
{
@ -614,10 +593,7 @@ const struct kfd2kgd_calls gfx_v8_kfd2kgd = {
.hqd_sdma_is_occupied = kgd_hqd_sdma_is_occupied,
.hqd_destroy = kgd_hqd_destroy,
.hqd_sdma_destroy = kgd_hqd_sdma_destroy,
.address_watch_disable = kgd_address_watch_disable,
.address_watch_execute = kgd_address_watch_execute,
.wave_control_execute = kgd_wave_control_execute,
.address_watch_get_offset = kgd_address_watch_get_offset,
.get_atc_vmid_pasid_mapping_info =
get_atc_vmid_pasid_mapping_info,
.set_scratch_backing_va = set_scratch_backing_va,

View File

@ -622,20 +622,6 @@ bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK);
}
int kgd_gfx_v9_address_watch_disable(struct amdgpu_device *adev)
{
return 0;
}
int kgd_gfx_v9_address_watch_execute(struct amdgpu_device *adev,
unsigned int watch_point_id,
uint32_t cntl_val,
uint32_t addr_hi,
uint32_t addr_lo)
{
return 0;
}
int kgd_gfx_v9_wave_control_execute(struct amdgpu_device *adev,
uint32_t gfx_index_val,
uint32_t sq_cmd)
@ -660,13 +646,6 @@ int kgd_gfx_v9_wave_control_execute(struct amdgpu_device *adev,
return 0;
}
uint32_t kgd_gfx_v9_address_watch_get_offset(struct amdgpu_device *adev,
unsigned int watch_point_id,
unsigned int reg_offset)
{
return 0;
}
void kgd_gfx_v9_set_vm_context_page_table_base(struct amdgpu_device *adev,
uint32_t vmid, uint64_t page_table_base)
{
@ -888,10 +867,7 @@ const struct kfd2kgd_calls gfx_v9_kfd2kgd = {
.hqd_sdma_is_occupied = kgd_hqd_sdma_is_occupied,
.hqd_destroy = kgd_gfx_v9_hqd_destroy,
.hqd_sdma_destroy = kgd_hqd_sdma_destroy,
.address_watch_disable = kgd_gfx_v9_address_watch_disable,
.address_watch_execute = kgd_gfx_v9_address_watch_execute,
.wave_control_execute = kgd_gfx_v9_wave_control_execute,
.address_watch_get_offset = kgd_gfx_v9_address_watch_get_offset,
.get_atc_vmid_pasid_mapping_info =
kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
.set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base,

View File

@ -46,19 +46,9 @@ int kgd_gfx_v9_hqd_destroy(struct amdgpu_device *adev, void *mqd,
enum kfd_preempt_type reset_type,
unsigned int utimeout, uint32_t pipe_id,
uint32_t queue_id);
int kgd_gfx_v9_address_watch_disable(struct amdgpu_device *adev);
int kgd_gfx_v9_address_watch_execute(struct amdgpu_device *adev,
unsigned int watch_point_id,
uint32_t cntl_val,
uint32_t addr_hi,
uint32_t addr_lo);
int kgd_gfx_v9_wave_control_execute(struct amdgpu_device *adev,
uint32_t gfx_index_val,
uint32_t sq_cmd);
uint32_t kgd_gfx_v9_address_watch_get_offset(struct amdgpu_device *adev,
unsigned int watch_point_id,
unsigned int reg_offset);
bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev,
uint8_t vmid, uint16_t *p_pasid);

View File

@ -778,7 +778,7 @@ unwind:
continue;
if (attachment[i]->bo_va) {
amdgpu_bo_reserve(bo[i], true);
amdgpu_vm_bo_rmv(adev, attachment[i]->bo_va);
amdgpu_vm_bo_del(adev, attachment[i]->bo_va);
amdgpu_bo_unreserve(bo[i]);
list_del(&attachment[i]->list);
}
@ -795,7 +795,7 @@ static void kfd_mem_detach(struct kfd_mem_attachment *attachment)
pr_debug("\t remove VA 0x%llx in entry %p\n",
attachment->va, attachment);
amdgpu_vm_bo_rmv(attachment->adev, attachment->bo_va);
amdgpu_vm_bo_del(attachment->adev, attachment->bo_va);
drm_gem_object_put(&bo->tbo.base);
list_del(&attachment->list);
kfree(attachment);
@ -842,7 +842,8 @@ static void remove_kgd_mem_from_kfd_bo_list(struct kgd_mem *mem,
*
* Returns 0 for success, negative errno for errors.
*/
static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr)
static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr,
bool criu_resume)
{
struct amdkfd_process_info *process_info = mem->process_info;
struct amdgpu_bo *bo = mem->bo;
@ -864,6 +865,18 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr)
goto out;
}
if (criu_resume) {
/*
* During a CRIU restore operation, the userptr buffer objects
* will be validated in the restore_userptr_work worker at a
* later stage when it is scheduled by another ioctl called by
* CRIU master process for the target pid for restore.
*/
atomic_inc(&mem->invalid);
mutex_unlock(&process_info->lock);
return 0;
}
ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
if (ret) {
pr_err("%s: Failed to get user pages: %d\n", __func__, ret);
@ -1452,10 +1465,39 @@ uint64_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *drm_priv)
return avm->pd_phys_addr;
}
void amdgpu_amdkfd_block_mmu_notifications(void *p)
{
struct amdkfd_process_info *pinfo = (struct amdkfd_process_info *)p;
mutex_lock(&pinfo->lock);
WRITE_ONCE(pinfo->block_mmu_notifications, true);
mutex_unlock(&pinfo->lock);
}
int amdgpu_amdkfd_criu_resume(void *p)
{
int ret = 0;
struct amdkfd_process_info *pinfo = (struct amdkfd_process_info *)p;
mutex_lock(&pinfo->lock);
pr_debug("scheduling work\n");
atomic_inc(&pinfo->evicted_bos);
if (!READ_ONCE(pinfo->block_mmu_notifications)) {
ret = -EINVAL;
goto out_unlock;
}
WRITE_ONCE(pinfo->block_mmu_notifications, false);
schedule_delayed_work(&pinfo->restore_userptr_work, 0);
out_unlock:
mutex_unlock(&pinfo->lock);
return ret;
}
int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
struct amdgpu_device *adev, uint64_t va, uint64_t size,
void *drm_priv, struct kgd_mem **mem,
uint64_t *offset, uint32_t flags)
uint64_t *offset, uint32_t flags, bool criu_resume)
{
struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv);
enum ttm_bo_type bo_type = ttm_bo_type_device;
@ -1558,7 +1600,8 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
add_kgd_mem_to_kfd_bo_list(*mem, avm->process_info, user_addr);
if (user_addr) {
ret = init_user_pages(*mem, user_addr);
pr_debug("creating userptr BO for user_addr = %llu\n", user_addr);
ret = init_user_pages(*mem, user_addr, criu_resume);
if (ret)
goto allocate_init_user_pages_failed;
} else if (flags & (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL |
@ -1813,12 +1856,6 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
true);
ret = unreserve_bo_and_vms(&ctx, false, false);
/* Only apply no TLB flush on Aldebaran to
* workaround regressions on other Asics.
*/
if (table_freed && (adev->asic_type != CHIP_ALDEBARAN))
*table_freed = true;
goto out;
out_unreserve:
@ -2068,6 +2105,10 @@ int amdgpu_amdkfd_evict_userptr(struct kgd_mem *mem,
int evicted_bos;
int r = 0;
/* Do not process MMU notifications until stage-4 IOCTL is received */
if (READ_ONCE(process_info->block_mmu_notifications))
return 0;
atomic_inc(&mem->invalid);
evicted_bos = atomic_inc_return(&process_info->evicted_bos);
if (evicted_bos == 1) {
@ -2635,3 +2676,14 @@ int amdgpu_amdkfd_get_tile_config(struct amdgpu_device *adev,
return 0;
}
bool amdgpu_amdkfd_bo_mapped_to_dev(struct amdgpu_device *adev, struct kgd_mem *mem)
{
struct kfd_mem_attachment *entry;
list_for_each_entry(entry, &mem->attachments, list) {
if (entry->is_mapped && entry->adev == adev)
return true;
}
return false;
}

View File

@ -1083,6 +1083,7 @@ int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,
return 0;
}
#ifdef CONFIG_DRM_AMDGPU_SI
int amdgpu_atombios_get_memory_pll_dividers(struct amdgpu_device *adev,
u32 clock,
bool strobe_mode,
@ -1503,6 +1504,7 @@ int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev,
}
return -EINVAL;
}
#endif
bool amdgpu_atombios_has_gpu_virtualization_table(struct amdgpu_device *adev)
{

View File

@ -160,6 +160,7 @@ int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,
bool strobe_mode,
struct atom_clock_dividers *dividers);
#ifdef CONFIG_DRM_AMDGPU_SI
int amdgpu_atombios_get_memory_pll_dividers(struct amdgpu_device *adev,
u32 clock,
bool strobe_mode,
@ -179,6 +180,17 @@ int amdgpu_atombios_get_voltage_table(struct amdgpu_device *adev,
int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev,
u8 module_index,
struct atom_mc_reg_table *reg_table);
int amdgpu_atombios_get_max_vddc(struct amdgpu_device *adev, u8 voltage_type,
u16 voltage_id, u16 *voltage);
int amdgpu_atombios_get_leakage_vddc_based_on_leakage_idx(struct amdgpu_device *adev,
u16 *voltage,
u16 leakage_idx);
void amdgpu_atombios_get_default_voltages(struct amdgpu_device *adev,
u16 *vddc, u16 *vddci, u16 *mvdd);
int amdgpu_atombios_get_svi2_info(struct amdgpu_device *adev,
u8 voltage_type,
u8 *svd_gpio_id, u8 *svc_gpio_id);
#endif
bool amdgpu_atombios_has_gpu_virtualization_table(struct amdgpu_device *adev);
@ -190,21 +202,11 @@ void amdgpu_atombios_scratch_regs_set_backlight_level(struct amdgpu_device *adev
bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev);
void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le);
int amdgpu_atombios_get_max_vddc(struct amdgpu_device *adev, u8 voltage_type,
u16 voltage_id, u16 *voltage);
int amdgpu_atombios_get_leakage_vddc_based_on_leakage_idx(struct amdgpu_device *adev,
u16 *voltage,
u16 leakage_idx);
void amdgpu_atombios_get_default_voltages(struct amdgpu_device *adev,
u16 *vddc, u16 *vddci, u16 *mvdd);
int amdgpu_atombios_get_clock_dividers(struct amdgpu_device *adev,
u8 clock_type,
u32 clock,
bool strobe_mode,
struct atom_clock_dividers *dividers);
int amdgpu_atombios_get_svi2_info(struct amdgpu_device *adev,
u8 voltage_type,
u8 *svd_gpio_id, u8 *svc_gpio_id);
int amdgpu_atombios_get_data_table(struct amdgpu_device *adev,
uint32_t table,

View File

@ -464,3 +464,41 @@ success:
adev->is_atom_fw = (adev->asic_type >= CHIP_VEGA10) ? true : false;
return true;
}
/* helper function for soc15 and onwards to read bios from rom */
bool amdgpu_soc15_read_bios_from_rom(struct amdgpu_device *adev,
u8 *bios, u32 length_bytes)
{
u32 *dw_ptr;
u32 i, length_dw;
u32 rom_index_offset;
u32 rom_data_offset;
if (bios == NULL)
return false;
if (length_bytes == 0)
return false;
/* APU vbios image is part of sbios image */
if (adev->flags & AMD_IS_APU)
return false;
if (!adev->smuio.funcs ||
!adev->smuio.funcs->get_rom_index_offset ||
!adev->smuio.funcs->get_rom_data_offset)
return false;
dw_ptr = (u32 *)bios;
length_dw = ALIGN(length_bytes, 4) / 4;
rom_index_offset =
adev->smuio.funcs->get_rom_index_offset(adev);
rom_data_offset =
adev->smuio.funcs->get_rom_data_offset(adev);
/* set rom index to 0 */
WREG32(rom_index_offset, 0);
/* read out the rom data */
for (i = 0; i < length_dw; i++)
dw_ptr[i] = RREG32(rom_data_offset);
return true;
}

View File

@ -127,8 +127,6 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs
goto free_chunk;
}
mutex_lock(&p->ctx->lock);
/* skip guilty context job */
if (atomic_read(&p->ctx->guilty) == 1) {
ret = -ECANCELED;
@ -585,6 +583,16 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
}
}
/* Move fence waiting after getting reservation lock of
* PD root. Then there is no need on a ctx mutex lock.
*/
r = amdgpu_ctx_wait_prev_fence(p->ctx, p->entity);
if (unlikely(r != 0)) {
if (r != -ERESTARTSYS)
DRM_ERROR("amdgpu_ctx_wait_prev_fence failed.\n");
goto error_validate;
}
amdgpu_cs_get_threshold_for_moves(p->adev, &p->bytes_moved_threshold,
&p->bytes_moved_vis_threshold);
p->bytes_moved = 0;
@ -700,7 +708,6 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error,
dma_fence_put(parser->fence);
if (parser->ctx) {
mutex_unlock(&parser->ctx->lock);
amdgpu_ctx_put(parser->ctx);
}
if (parser->bo_list)
@ -944,7 +951,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
if (parser->job->uf_addr && ring->funcs->no_user_fence)
return -EINVAL;
return amdgpu_ctx_wait_prev_fence(parser->ctx, parser->entity);
return 0;
}
static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p,
@ -1360,7 +1367,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
goto out;
r = amdgpu_cs_submit(&parser, cs);
out:
amdgpu_cs_parser_fini(&parser, r, reserved_buffers);
@ -1506,6 +1512,7 @@ int amdgpu_cs_fence_to_handle_ioctl(struct drm_device *dev, void *data,
return 0;
default:
dma_fence_put(fence);
return -EINVAL;
}
}

View File

@ -98,7 +98,7 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
if (r) {
DRM_ERROR("failed to do bo_map on static CSA, err=%d\n", r);
amdgpu_vm_bo_rmv(adev, *bo_va);
amdgpu_vm_bo_del(adev, *bo_va);
ttm_eu_backoff_reservation(&ticket, &list);
return r;
}

View File

@ -230,13 +230,13 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev,
kref_init(&ctx->refcount);
spin_lock_init(&ctx->ring_lock);
mutex_init(&ctx->lock);
ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);
ctx->reset_counter_query = ctx->reset_counter;
ctx->vram_lost_counter = atomic_read(&adev->vram_lost_counter);
ctx->init_priority = priority;
ctx->override_priority = AMDGPU_CTX_PRIORITY_UNSET;
ctx->stable_pstate = AMDGPU_CTX_STABLE_PSTATE_NONE;
return 0;
}
@ -255,6 +255,86 @@ static void amdgpu_ctx_fini_entity(struct amdgpu_ctx_entity *entity)
kfree(entity);
}
static int amdgpu_ctx_get_stable_pstate(struct amdgpu_ctx *ctx,
u32 *stable_pstate)
{
struct amdgpu_device *adev = ctx->adev;
enum amd_dpm_forced_level current_level;
if (!ctx)
return -EINVAL;
current_level = amdgpu_dpm_get_performance_level(adev);
switch (current_level) {
case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
*stable_pstate = AMDGPU_CTX_STABLE_PSTATE_STANDARD;
break;
case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
*stable_pstate = AMDGPU_CTX_STABLE_PSTATE_MIN_SCLK;
break;
case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
*stable_pstate = AMDGPU_CTX_STABLE_PSTATE_MIN_MCLK;
break;
case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
*stable_pstate = AMDGPU_CTX_STABLE_PSTATE_PEAK;
break;
default:
*stable_pstate = AMDGPU_CTX_STABLE_PSTATE_NONE;
break;
}
return 0;
}
static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx,
u32 stable_pstate)
{
struct amdgpu_device *adev = ctx->adev;
enum amd_dpm_forced_level level;
int r;
if (!ctx)
return -EINVAL;
mutex_lock(&adev->pm.stable_pstate_ctx_lock);
if (adev->pm.stable_pstate_ctx && adev->pm.stable_pstate_ctx != ctx) {
r = -EBUSY;
goto done;
}
switch (stable_pstate) {
case AMDGPU_CTX_STABLE_PSTATE_NONE:
level = AMD_DPM_FORCED_LEVEL_AUTO;
break;
case AMDGPU_CTX_STABLE_PSTATE_STANDARD:
level = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD;
break;
case AMDGPU_CTX_STABLE_PSTATE_MIN_SCLK:
level = AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK;
break;
case AMDGPU_CTX_STABLE_PSTATE_MIN_MCLK:
level = AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK;
break;
case AMDGPU_CTX_STABLE_PSTATE_PEAK:
level = AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
break;
default:
r = -EINVAL;
goto done;
}
r = amdgpu_dpm_force_performance_level(adev, level);
if (level == AMD_DPM_FORCED_LEVEL_AUTO)
adev->pm.stable_pstate_ctx = NULL;
else
adev->pm.stable_pstate_ctx = ctx;
done:
mutex_unlock(&adev->pm.stable_pstate_ctx_lock);
return r;
}
static void amdgpu_ctx_fini(struct kref *ref)
{
struct amdgpu_ctx *ctx = container_of(ref, struct amdgpu_ctx, refcount);
@ -270,8 +350,7 @@ static void amdgpu_ctx_fini(struct kref *ref)
ctx->entities[i][j] = NULL;
}
}
mutex_destroy(&ctx->lock);
amdgpu_ctx_set_stable_pstate(ctx, AMDGPU_CTX_STABLE_PSTATE_NONE);
kfree(ctx);
}
@ -467,11 +546,41 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev,
return 0;
}
static int amdgpu_ctx_stable_pstate(struct amdgpu_device *adev,
struct amdgpu_fpriv *fpriv, uint32_t id,
bool set, u32 *stable_pstate)
{
struct amdgpu_ctx *ctx;
struct amdgpu_ctx_mgr *mgr;
int r;
if (!fpriv)
return -EINVAL;
mgr = &fpriv->ctx_mgr;
mutex_lock(&mgr->lock);
ctx = idr_find(&mgr->ctx_handles, id);
if (!ctx) {
mutex_unlock(&mgr->lock);
return -EINVAL;
}
if (set)
r = amdgpu_ctx_set_stable_pstate(ctx, *stable_pstate);
else
r = amdgpu_ctx_get_stable_pstate(ctx, stable_pstate);
mutex_unlock(&mgr->lock);
return r;
}
int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
{
int r;
uint32_t id;
uint32_t id, stable_pstate;
int32_t priority;
union drm_amdgpu_ctx *args = data;
@ -500,6 +609,20 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
case AMDGPU_CTX_OP_QUERY_STATE2:
r = amdgpu_ctx_query2(adev, fpriv, id, &args->out);
break;
case AMDGPU_CTX_OP_GET_STABLE_PSTATE:
if (args->in.flags)
return -EINVAL;
r = amdgpu_ctx_stable_pstate(adev, fpriv, id, false, &stable_pstate);
args->out.pstate.flags = stable_pstate;
break;
case AMDGPU_CTX_OP_SET_STABLE_PSTATE:
if (args->in.flags & ~AMDGPU_CTX_STABLE_PSTATE_FLAGS_MASK)
return -EINVAL;
stable_pstate = args->in.flags & AMDGPU_CTX_STABLE_PSTATE_FLAGS_MASK;
if (stable_pstate > AMDGPU_CTX_STABLE_PSTATE_PEAK)
return -EINVAL;
r = amdgpu_ctx_stable_pstate(adev, fpriv, id, true, &stable_pstate);
break;
default:
return -EINVAL;
}

View File

@ -49,10 +49,10 @@ struct amdgpu_ctx {
bool preamble_presented;
int32_t init_priority;
int32_t override_priority;
struct mutex lock;
atomic_t guilty;
unsigned long ras_counter_ce;
unsigned long ras_counter_ue;
uint32_t stable_pstate;
};
struct amdgpu_ctx_mgr {

View File

@ -1120,8 +1120,10 @@ static ssize_t amdgpu_debugfs_gfxoff_read(struct file *f, char __user *buf,
return -EINVAL;
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0)
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
while (size) {
uint32_t value;
@ -1585,22 +1587,25 @@ static int amdgpu_debugfs_sclk_set(void *data, u64 val)
return ret;
}
if (is_support_sw_smu(adev)) {
ret = smu_get_dpm_freq_range(&adev->smu, SMU_SCLK, &min_freq, &max_freq);
if (ret || val > max_freq || val < min_freq)
return -EINVAL;
ret = smu_set_soft_freq_range(&adev->smu, SMU_SCLK, (uint32_t)val, (uint32_t)val);
} else {
return 0;
ret = amdgpu_dpm_get_dpm_freq_range(adev, PP_SCLK, &min_freq, &max_freq);
if (ret == -EOPNOTSUPP) {
ret = 0;
goto out;
}
if (ret || val > max_freq || val < min_freq) {
ret = -EINVAL;
goto out;
}
ret = amdgpu_dpm_set_soft_freq_range(adev, PP_SCLK, (uint32_t)val, (uint32_t)val);
if (ret)
ret = -EINVAL;
out:
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
if (ret)
return -EINVAL;
return 0;
return ret;
}
DEFINE_DEBUGFS_ATTRIBUTE(fops_ib_preempt, NULL,

View File

@ -31,6 +31,7 @@
#include <linux/console.h>
#include <linux/slab.h>
#include <linux/iommu.h>
#include <linux/pci.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_probe_helper.h>
@ -55,7 +56,6 @@
#include "soc15.h"
#include "nv.h"
#include "bif/bif_4_1_d.h"
#include <linux/pci.h>
#include <linux/firmware.h>
#include "amdgpu_vf_error.h"
@ -566,7 +566,7 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
adev->gfx.rlc.funcs &&
adev->gfx.rlc.funcs->is_rlcg_access_range) {
if (adev->gfx.rlc.funcs->is_rlcg_access_range(adev, reg))
return adev->gfx.rlc.funcs->sriov_wreg(adev, reg, v, 0, 0);
return amdgpu_sriov_wreg(adev, reg, v, 0, 0);
} else if ((reg * 4) >= adev->rmmio_size) {
adev->pcie_wreg(adev, reg * 4, v);
} else {
@ -2073,6 +2073,8 @@ out:
*/
static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
{
struct drm_device *dev = adev_to_drm(adev);
struct pci_dev *parent;
int i, r;
amdgpu_device_enable_virtual_display(adev);
@ -2137,6 +2139,16 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
break;
}
if (amdgpu_has_atpx() &&
(amdgpu_is_atpx_hybrid() ||
amdgpu_has_atpx_dgpu_power_cntl()) &&
((adev->flags & AMD_IS_APU) == 0) &&
!pci_is_thunderbolt_attached(to_pci_dev(dev->dev)))
adev->flags |= AMD_IS_PX;
parent = pci_upstream_bridge(adev->pdev);
adev->has_pr3 = parent ? pci_pr3_present(parent) : false;
amdgpu_amdkfd_device_probe(adev);
adev->pm.pp_feature = amdgpu_pp_feature_mask;
@ -2624,7 +2636,7 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev)
/* For passthrough configuration on arcturus and aldebaran, enable special handling SBR */
if (amdgpu_passthrough(adev) && ((adev->asic_type == CHIP_ARCTURUS && adev->gmc.xgmi.num_physical_nodes > 1)||
adev->asic_type == CHIP_ALDEBARAN ))
smu_handle_passthrough_sbr(&adev->smu, true);
amdgpu_dpm_handle_passthrough_sbr(adev, true);
if (adev->gmc.xgmi.num_physical_nodes > 1) {
mutex_lock(&mgpu_info.mutex);
@ -2708,11 +2720,11 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev)
}
}
amdgpu_amdkfd_suspend(adev, false);
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
amdgpu_amdkfd_suspend(adev, false);
/* Workaroud for ASICs need to disable SMC first */
amdgpu_device_smu_fini_early(adev);
@ -2881,7 +2893,7 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
int i, r;
if (adev->in_s0ix)
amdgpu_gfx_state_change_set(adev, sGpuChangeState_D3Entry);
amdgpu_dpm_gfx_state_change(adev, sGpuChangeState_D3Entry);
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (!adev->ip_blocks[i].status.valid)
@ -3307,9 +3319,9 @@ static void amdgpu_device_xgmi_reset_func(struct work_struct *__work)
if (adev->asic_reset_res)
goto fail;
if (adev->mmhub.ras_funcs &&
adev->mmhub.ras_funcs->reset_ras_error_count)
adev->mmhub.ras_funcs->reset_ras_error_count(adev);
if (adev->mmhub.ras && adev->mmhub.ras->ras_block.hw_ops &&
adev->mmhub.ras->ras_block.hw_ops->reset_ras_error_count)
adev->mmhub.ras->ras_block.hw_ops->reset_ras_error_count(adev);
} else {
task_barrier_full(&hive->tb);
@ -3497,8 +3509,9 @@ int amdgpu_device_init(struct amdgpu_device *adev,
init_rwsem(&adev->reset_sem);
mutex_init(&adev->psp.mutex);
mutex_init(&adev->notifier_lock);
mutex_init(&adev->pm.stable_pstate_ctx_lock);
amdgpu_device_init_apu_flags(adev);
amdgpu_device_init_apu_flags(adev);
r = amdgpu_device_check_arguments(adev);
if (r)
@ -3519,6 +3532,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
INIT_LIST_HEAD(&adev->reset_list);
INIT_LIST_HEAD(&adev->ras_list);
INIT_DELAYED_WORK(&adev->delayed_init_work,
amdgpu_device_delayed_init_work_handler);
INIT_DELAYED_WORK(&adev->gfx.gfx_off_delay_work,
@ -4044,7 +4059,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
return 0;
if (adev->in_s0ix)
amdgpu_gfx_state_change_set(adev, sGpuChangeState_D0Entry);
amdgpu_dpm_gfx_state_change(adev, sGpuChangeState_D0Entry);
/* post card */
if (amdgpu_device_need_post(adev)) {
@ -4645,9 +4660,9 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
if (!r && amdgpu_ras_intr_triggered()) {
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
if (tmp_adev->mmhub.ras_funcs &&
tmp_adev->mmhub.ras_funcs->reset_ras_error_count)
tmp_adev->mmhub.ras_funcs->reset_ras_error_count(tmp_adev);
if (tmp_adev->mmhub.ras && tmp_adev->mmhub.ras->ras_block.hw_ops &&
tmp_adev->mmhub.ras->ras_block.hw_ops->reset_ras_error_count)
tmp_adev->mmhub.ras->ras_block.hw_ops->reset_ras_error_count(tmp_adev);
}
amdgpu_ras_intr_cleared();
@ -5726,3 +5741,36 @@ void amdgpu_device_halt(struct amdgpu_device *adev)
pci_disable_device(pdev);
pci_wait_for_pending_transaction(pdev);
}
u32 amdgpu_device_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;
}
void amdgpu_device_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);
}

View File

@ -674,6 +674,7 @@ static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 3):
case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 3, 0):
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 2):
@ -709,6 +710,7 @@ static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 3):
case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 3, 0):
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 2):
@ -846,8 +848,14 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
{
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) {
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
return 0;
}
if (!amdgpu_device_has_dc_support(adev))
return 0;
#if defined(CONFIG_DRM_AMD_DC)
} else if (adev->ip_versions[DCE_HWIP][0]) {
if (adev->ip_versions[DCE_HWIP][0]) {
switch (adev->ip_versions[DCE_HWIP][0]) {
case IP_VERSION(1, 0, 0):
case IP_VERSION(1, 0, 1):
@ -882,8 +890,8 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
adev->ip_versions[DCI_HWIP][0]);
return -EINVAL;
}
#endif
}
#endif
return 0;
}
@ -904,6 +912,7 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 3):
case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 3, 0):
case IP_VERSION(10, 3, 2):
case IP_VERSION(10, 3, 1):
@ -1038,6 +1047,7 @@ static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 3):
case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 3, 0):
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 2):
@ -1217,11 +1227,6 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
return -EINVAL;
amdgpu_discovery_harvest_ip(adev);
if (!adev->mman.discovery_bin) {
DRM_ERROR("ip discovery uninitialized\n");
return -EINVAL;
}
break;
}
@ -1242,6 +1247,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 3):
case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 3, 0):
case IP_VERSION(10, 3, 2):
case IP_VERSION(10, 3, 4):
@ -1258,6 +1264,20 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
return -EINVAL;
}
switch (adev->ip_versions[GC_HWIP][0]) {
case IP_VERSION(9, 1, 0):
case IP_VERSION(9, 2, 2):
case IP_VERSION(9, 3, 0):
case IP_VERSION(10, 1, 3):
case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 3):
adev->flags |= AMD_IS_APU;
break;
default:
break;
}
if (adev->ip_versions[XGMI_HWIP][0] == IP_VERSION(4, 8, 0))
adev->gmc.xgmi.supported = true;

View File

@ -512,19 +512,24 @@ uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
case CHIP_STONEY:
domain |= AMDGPU_GEM_DOMAIN_GTT;
break;
case CHIP_RAVEN:
/* enable S/G on PCO and RV2 */
if ((adev->apu_flags & AMD_APU_IS_RAVEN2) ||
(adev->apu_flags & AMD_APU_IS_PICASSO))
domain |= AMDGPU_GEM_DOMAIN_GTT;
break;
case CHIP_RENOIR:
case CHIP_VANGOGH:
case CHIP_YELLOW_CARP:
domain |= AMDGPU_GEM_DOMAIN_GTT;
break;
default:
switch (adev->ip_versions[DCE_HWIP][0]) {
case IP_VERSION(1, 0, 0):
case IP_VERSION(1, 0, 1):
/* enable S/G on PCO and RV2 */
if ((adev->apu_flags & AMD_APU_IS_RAVEN2) ||
(adev->apu_flags & AMD_APU_IS_PICASSO))
domain |= AMDGPU_GEM_DOMAIN_GTT;
break;
case IP_VERSION(2, 1, 0):
case IP_VERSION(3, 0, 1):
case IP_VERSION(3, 1, 2):
case IP_VERSION(3, 1, 3):
domain |= AMDGPU_GEM_DOMAIN_GTT;
break;
default:
break;
}
break;
}
}

View File

@ -99,9 +99,10 @@
* - 3.42.0 - Add 16bpc fixed point display support
* - 3.43.0 - Add device hot plug/unplug support
* - 3.44.0 - DCN3 supports DCC independent block settings: !64B && 128B, 64B && 128B
* - 3.45.0 - Add context ioctl stable pstate interface
*/
#define KMS_DRIVER_MAJOR 3
#define KMS_DRIVER_MINOR 44
#define KMS_DRIVER_MINOR 45
#define KMS_DRIVER_PATCHLEVEL 0
int amdgpu_vram_limit;
@ -174,7 +175,6 @@ int amdgpu_mes;
int amdgpu_noretry = -1;
int amdgpu_force_asic_type = -1;
int amdgpu_tmz = -1; /* auto */
uint amdgpu_freesync_vid_mode;
int amdgpu_reset_method = -1; /* auto */
int amdgpu_num_kcq = -1;
int amdgpu_smartshift_bias;
@ -843,32 +843,6 @@ module_param_named(backlight, amdgpu_backlight, bint, 0444);
MODULE_PARM_DESC(tmz, "Enable TMZ feature (-1 = auto (default), 0 = off, 1 = on)");
module_param_named(tmz, amdgpu_tmz, int, 0444);
/**
* DOC: freesync_video (uint)
* Enable the optimization to adjust front porch timing to achieve seamless
* mode change experience when setting a freesync supported mode for which full
* modeset is not needed.
*
* The Display Core will add a set of modes derived from the base FreeSync
* video mode into the corresponding connector's mode list based on commonly
* used refresh rates and VRR range of the connected display, when users enable
* this feature. From the userspace perspective, they can see a seamless mode
* change experience when the change between different refresh rates under the
* same resolution. Additionally, userspace applications such as Video playback
* can read this modeset list and change the refresh rate based on the video
* frame rate. Finally, the userspace can also derive an appropriate mode for a
* particular refresh rate based on the FreeSync Mode and add it to the
* connector's mode list.
*
* Note: This is an experimental feature.
*
* The default value: 0 (off).
*/
MODULE_PARM_DESC(
freesync_video,
"Enable freesync modesetting optimization feature (0 = off (default), 1 = on)");
module_param_named(freesync_video, amdgpu_freesync_vid_mode, uint, 0444);
/**
* DOC: reset_method (int)
* GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco, 5 = pci)
@ -1942,10 +1916,10 @@ static const struct pci_device_id pciidlist[] = {
{0x1002, 0x73FF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_DIMGREY_CAVEFISH},
/* Aldebaran */
{0x1002, 0x7408, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN|AMD_EXP_HW_SUPPORT},
{0x1002, 0x740C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN|AMD_EXP_HW_SUPPORT},
{0x1002, 0x740F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN|AMD_EXP_HW_SUPPORT},
{0x1002, 0x7410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN|AMD_EXP_HW_SUPPORT},
{0x1002, 0x7408, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN},
{0x1002, 0x740C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN},
{0x1002, 0x740F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN},
{0x1002, 0x7410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ALDEBARAN},
/* CYAN_SKILLFISH */
{0x1002, 0x13FE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYAN_SKILLFISH|AMD_IS_APU},
@ -1994,6 +1968,28 @@ static bool amdgpu_is_fw_framebuffer(resource_size_t base,
return found;
}
static void amdgpu_get_secondary_funcs(struct amdgpu_device *adev)
{
struct pci_dev *p = NULL;
int i;
/* 0 - GPU
* 1 - audio
* 2 - USB
* 3 - UCSI
*/
for (i = 1; i < 4; i++) {
p = pci_get_domain_bus_and_slot(pci_domain_nr(adev->pdev->bus),
adev->pdev->bus->number, i);
if (p) {
pm_runtime_get_sync(&p->dev);
pm_runtime_mark_last_busy(&p->dev);
pm_runtime_put_autosuspend(&p->dev);
pci_dev_put(p);
}
}
}
static int amdgpu_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@ -2126,6 +2122,48 @@ retry_init:
if (ret)
DRM_ERROR("Creating debugfs files failed (%d).\n", ret);
if (adev->runpm) {
/* only need to skip on ATPX */
if (amdgpu_device_supports_px(ddev))
dev_pm_set_driver_flags(ddev->dev, DPM_FLAG_NO_DIRECT_COMPLETE);
/* we want direct complete for BOCO */
if (amdgpu_device_supports_boco(ddev))
dev_pm_set_driver_flags(ddev->dev, DPM_FLAG_SMART_PREPARE |
DPM_FLAG_SMART_SUSPEND |
DPM_FLAG_MAY_SKIP_RESUME);
pm_runtime_use_autosuspend(ddev->dev);
pm_runtime_set_autosuspend_delay(ddev->dev, 5000);
pm_runtime_allow(ddev->dev);
pm_runtime_mark_last_busy(ddev->dev);
pm_runtime_put_autosuspend(ddev->dev);
/*
* For runpm implemented via BACO, PMFW will handle the
* timing for BACO in and out:
* - put ASIC into BACO state only when both video and
* audio functions are in D3 state.
* - pull ASIC out of BACO state when either video or
* audio function is in D0 state.
* Also, at startup, PMFW assumes both functions are in
* D0 state.
*
* So if snd driver was loaded prior to amdgpu driver
* and audio function was put into D3 state, there will
* be no PMFW-aware D-state transition(D0->D3) on runpm
* suspend. Thus the BACO will be not correctly kicked in.
*
* Via amdgpu_get_secondary_funcs(), the audio dev is put
* into D0 state. Then there will be a PMFW-aware D-state
* transition(D0->D3) on runpm suspend.
*/
if (amdgpu_device_supports_baco(ddev) &&
!(adev->flags & AMD_IS_APU) &&
(adev->asic_type >= CHIP_NAVI10))
amdgpu_get_secondary_funcs(adev);
}
return 0;
err_pci:
@ -2137,8 +2175,15 @@ static void
amdgpu_pci_remove(struct pci_dev *pdev)
{
struct drm_device *dev = pci_get_drvdata(pdev);
struct amdgpu_device *adev = drm_to_adev(dev);
drm_dev_unplug(dev);
if (adev->runpm) {
pm_runtime_get_sync(dev->dev);
pm_runtime_forbid(dev->dev);
}
amdgpu_driver_unload_kms(dev);
/*
@ -2246,13 +2291,20 @@ static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work)
static int amdgpu_pmops_prepare(struct device *dev)
{
struct drm_device *drm_dev = dev_get_drvdata(dev);
struct amdgpu_device *adev = drm_to_adev(drm_dev);
/* Return a positive number here so
* DPM_FLAG_SMART_SUSPEND works properly
*/
if (amdgpu_device_supports_boco(drm_dev))
return pm_runtime_suspended(dev) &&
pm_suspend_via_firmware();
return pm_runtime_suspended(dev);
/* if we will not support s3 or s2i for the device
* then skip suspend
*/
if (!amdgpu_acpi_is_s0ix_active(adev) &&
!amdgpu_acpi_is_s3_active(adev))
return 1;
return 0;
}

View File

@ -30,7 +30,6 @@
#include "amdgpu_eeprom.h"
#define FRU_EEPROM_MADDR 0x60000
#define I2C_PRODUCT_INFO_OFFSET 0xC0
static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
{
@ -40,7 +39,13 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
*/
struct atom_context *atom_ctx = adev->mode_info.atom_context;
/* VBIOS is of the format ###-DXXXYY-##. For SKU identification,
/* The i2c access is blocked on VF
* TODO: Need other way to get the info
*/
if (amdgpu_sriov_vf(adev))
return false;
/* VBIOS is of the format ###-DXXXYYYY-##. For SKU identification,
* we can use just the "DXXX" portion. If there were more models, we
* could convert the 3 characters to a hex integer and use a switch
* for ease/speed/readability. For now, 2 string comparisons are
@ -59,17 +64,24 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
case CHIP_ALDEBARAN:
/* All Aldebaran SKUs have the FRU */
return true;
case CHIP_SIENNA_CICHLID:
if (strnstr(atom_ctx->vbios_version, "D603",
sizeof(atom_ctx->vbios_version)))
return true;
else
return false;
default:
return false;
}
}
static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
unsigned char *buff)
unsigned char *buf, size_t buf_size)
{
int ret, size;
int ret;
u8 size;
ret = amdgpu_eeprom_read(&adev->pm.smu_i2c, addrptr, buff, 1);
ret = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, addrptr, buf, 1);
if (ret < 1) {
DRM_WARN("FRU: Failed to get size field");
return ret;
@ -78,9 +90,11 @@ static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
/* The size returned by the i2c requires subtraction of 0xC0 since the
* size apparently always reports as 0xC0+actual size.
*/
size = buff[0] - I2C_PRODUCT_INFO_OFFSET;
size = buf[0] & 0x3F;
size = min_t(size_t, size, buf_size);
ret = amdgpu_eeprom_read(&adev->pm.smu_i2c, addrptr + 1, buff, size);
ret = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, addrptr + 1,
buf, size);
if (ret < 1) {
DRM_WARN("FRU: Failed to get data field");
return ret;
@ -91,19 +105,15 @@ static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
{
unsigned char buff[AMDGPU_PRODUCT_NAME_LEN+2];
unsigned char buf[AMDGPU_PRODUCT_NAME_LEN];
u32 addrptr;
int size, len;
int offset = 2;
if (!is_fru_eeprom_supported(adev))
return 0;
if (adev->asic_type == CHIP_ALDEBARAN)
offset = 0;
/* If algo exists, it means that the i2c_adapter's initialized */
if (!adev->pm.smu_i2c.algo) {
if (!adev->pm.fru_eeprom_i2c_bus || !adev->pm.fru_eeprom_i2c_bus->algo) {
DRM_WARN("Cannot access FRU, EEPROM accessor not initialized");
return -ENODEV;
}
@ -121,7 +131,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
* and the language field, so just start from 0xb, manufacturer size
*/
addrptr = FRU_EEPROM_MADDR + 0xb;
size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
if (size < 1) {
DRM_ERROR("Failed to read FRU Manufacturer, ret:%d", size);
return -EINVAL;
@ -131,7 +141,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
* size field being 1 byte. This pattern continues below.
*/
addrptr += size + 1;
size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
if (size < 1) {
DRM_ERROR("Failed to read FRU product name, ret:%d", size);
return -EINVAL;
@ -143,12 +153,11 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
AMDGPU_PRODUCT_NAME_LEN);
len = AMDGPU_PRODUCT_NAME_LEN - 1;
}
/* Start at 2 due to buff using fields 0 and 1 for the address */
memcpy(adev->product_name, &buff[offset], len);
memcpy(adev->product_name, buf, len);
adev->product_name[len] = '\0';
addrptr += size + 1;
size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
if (size < 1) {
DRM_ERROR("Failed to read FRU product number, ret:%d", size);
return -EINVAL;
@ -162,11 +171,11 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
DRM_WARN("FRU Product Number is larger than 16 characters. This is likely a mistake");
len = sizeof(adev->product_number) - 1;
}
memcpy(adev->product_number, &buff[offset], len);
memcpy(adev->product_number, buf, len);
adev->product_number[len] = '\0';
addrptr += size + 1;
size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
if (size < 1) {
DRM_ERROR("Failed to read FRU product version, ret:%d", size);
@ -174,7 +183,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
}
addrptr += size + 1;
size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
if (size < 1) {
DRM_ERROR("Failed to read FRU serial number, ret:%d", size);
@ -189,7 +198,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
DRM_WARN("FRU Serial Number is larger than 16 characters. This is likely a mistake");
len = sizeof(adev->serial) - 1;
}
memcpy(adev->serial, &buff[offset], len);
memcpy(adev->serial, buf, len);
adev->serial[len] = '\0';
return 0;

View File

@ -150,7 +150,7 @@ void amdgpu_gart_table_vram_free(struct amdgpu_device *adev)
* replaces them with the dummy page (all asics).
* Returns 0 for success, -EINVAL for failure.
*/
int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
void amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
int pages)
{
unsigned t;
@ -161,13 +161,11 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
uint64_t flags = 0;
int idx;
if (!adev->gart.ready) {
WARN(1, "trying to unbind memory from uninitialized GART !\n");
return -EINVAL;
}
if (!adev->gart.ptr)
return;
if (!drm_dev_enter(adev_to_drm(adev), &idx))
return 0;
return;
t = offset / AMDGPU_GPU_PAGE_SIZE;
p = t / AMDGPU_GPU_PAGES_IN_CPU_PAGE;
@ -188,7 +186,6 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0);
drm_dev_exit(idx);
return 0;
}
/**
@ -204,7 +201,7 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
* Map the dma_addresses into GART entries (all asics).
* Returns 0 for success, -EINVAL for failure.
*/
int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
void amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
int pages, dma_addr_t *dma_addr, uint64_t flags,
void *dst)
{
@ -212,13 +209,8 @@ int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
unsigned i, j, t;
int idx;
if (!adev->gart.ready) {
WARN(1, "trying to bind memory to uninitialized GART !\n");
return -EINVAL;
}
if (!drm_dev_enter(adev_to_drm(adev), &idx))
return 0;
return;
t = offset / AMDGPU_GPU_PAGE_SIZE;
@ -230,7 +222,6 @@ int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
}
}
drm_dev_exit(idx);
return 0;
}
/**
@ -246,20 +237,14 @@ int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
* (all asics).
* Returns 0 for success, -EINVAL for failure.
*/
int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
void amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
int pages, dma_addr_t *dma_addr,
uint64_t flags)
{
if (!adev->gart.ready) {
WARN(1, "trying to bind memory to uninitialized GART !\n");
return -EINVAL;
}
if (!adev->gart.ptr)
return 0;
return;
return amdgpu_gart_map(adev, offset, pages, dma_addr, flags,
adev->gart.ptr);
amdgpu_gart_map(adev, offset, pages, dma_addr, flags, adev->gart.ptr);
}
/**
@ -274,6 +259,9 @@ void amdgpu_gart_invalidate_tlb(struct amdgpu_device *adev)
{
int i;
if (!adev->gart.ptr)
return;
mb();
amdgpu_device_flush_hdp(adev, NULL);
for (i = 0; i < adev->num_vmhubs; i++)

View File

@ -46,7 +46,6 @@ struct amdgpu_gart {
unsigned num_gpu_pages;
unsigned num_cpu_pages;
unsigned table_size;
bool ready;
/* Asic default pte flags */
uint64_t gart_pte_flags;
@ -58,12 +57,12 @@ int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev);
void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev);
int amdgpu_gart_init(struct amdgpu_device *adev);
void amdgpu_gart_dummy_page_fini(struct amdgpu_device *adev);
int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
int pages);
int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
int pages, dma_addr_t *dma_addr, uint64_t flags,
void *dst);
int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
int pages, dma_addr_t *dma_addr, uint64_t flags);
void amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
int pages);
void amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
int pages, dma_addr_t *dma_addr, uint64_t flags,
void *dst);
void amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
int pages, dma_addr_t *dma_addr, uint64_t flags);
void amdgpu_gart_invalidate_tlb(struct amdgpu_device *adev);
#endif

View File

@ -222,7 +222,7 @@ static void amdgpu_gem_object_close(struct drm_gem_object *obj,
if (!bo_va || --bo_va->ref_count)
goto out_unlock;
amdgpu_vm_bo_rmv(adev, bo_va);
amdgpu_vm_bo_del(adev, bo_va);
if (!amdgpu_vm_ready(vm))
goto out_unlock;

View File

@ -615,14 +615,14 @@ int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value)
mutex_lock(&adev->gfx.gfx_off_mutex);
r = smu_get_status_gfxoff(adev, value);
r = amdgpu_dpm_get_status_gfxoff(adev, value);
mutex_unlock(&adev->gfx.gfx_off_mutex);
return r;
}
int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev)
int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, void *ras_info)
{
int r;
struct ras_fs_if fs_info = {
@ -695,9 +695,9 @@ int amdgpu_gfx_process_ras_data_cb(struct amdgpu_device *adev,
*/
if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX)) {
kgd2kfd_set_sram_ecc_flag(adev->kfd.dev);
if (adev->gfx.ras_funcs &&
adev->gfx.ras_funcs->query_ras_error_count)
adev->gfx.ras_funcs->query_ras_error_count(adev, err_data);
if (adev->gfx.ras && adev->gfx.ras->ras_block.hw_ops &&
adev->gfx.ras->ras_block.hw_ops->query_ras_error_count)
adev->gfx.ras->ras_block.hw_ops->query_ras_error_count(adev, err_data);
amdgpu_ras_reset_gpu(adev);
}
return AMDGPU_RAS_SUCCESS;
@ -852,19 +852,3 @@ int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev)
}
return amdgpu_num_kcq;
}
/* amdgpu_gfx_state_change_set - Handle gfx power state change set
* @adev: amdgpu_device pointer
* @state: gfx power state(1 -sGpuChangeState_D0Entry and 2 -sGpuChangeState_D3Entry)
*
*/
void amdgpu_gfx_state_change_set(struct amdgpu_device *adev, enum gfx_change_state state)
{
mutex_lock(&adev->pm.mutex);
if (adev->powerplay.pp_funcs &&
adev->powerplay.pp_funcs->gfx_state_change_set)
((adev)->powerplay.pp_funcs->gfx_state_change_set(
(adev)->powerplay.pp_handle, state));
mutex_unlock(&adev->pm.mutex);
}

View File

@ -31,6 +31,7 @@
#include "amdgpu_ring.h"
#include "amdgpu_rlc.h"
#include "soc15.h"
#include "amdgpu_ras.h"
/* GFX current status */
#define AMDGPU_GFX_NORMAL_MODE 0x00000000L
@ -47,12 +48,6 @@ enum amdgpu_gfx_pipe_priority {
AMDGPU_GFX_PIPE_PRIO_HIGH = AMDGPU_RING_PRIO_2
};
/* Argument for PPSMC_MSG_GpuChangeState */
enum gfx_change_state {
sGpuChangeState_D0Entry = 1,
sGpuChangeState_D3Entry,
};
#define AMDGPU_GFX_QUEUE_PRIORITY_MINIMUM 0
#define AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM 15
@ -204,16 +199,8 @@ struct amdgpu_cu_info {
uint32_t bitmap[4][4];
};
struct amdgpu_gfx_ras_funcs {
int (*ras_late_init)(struct amdgpu_device *adev);
void (*ras_fini)(struct amdgpu_device *adev);
int (*ras_error_inject)(struct amdgpu_device *adev,
void *inject_if);
int (*query_ras_error_count)(struct amdgpu_device *adev,
void *ras_error_status);
void (*reset_ras_error_count)(struct amdgpu_device *adev);
void (*query_ras_error_status)(struct amdgpu_device *adev);
void (*reset_ras_error_status)(struct amdgpu_device *adev);
struct amdgpu_gfx_ras {
struct amdgpu_ras_block_object ras_block;
void (*enable_watchdog_timer)(struct amdgpu_device *adev);
};
@ -337,7 +324,7 @@ struct amdgpu_gfx {
/*ras */
struct ras_common_if *ras_if;
const struct amdgpu_gfx_ras_funcs *ras_funcs;
struct amdgpu_gfx_ras *ras;
};
#define amdgpu_gfx_get_gpu_clock_counter(adev) (adev)->gfx.funcs->get_gpu_clock_counter((adev))
@ -399,7 +386,7 @@ bool amdgpu_gfx_is_me_queue_enabled(struct amdgpu_device *adev, int me,
int pipe, int queue);
void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable);
int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value);
int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev);
int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, void *ras_info);
void amdgpu_gfx_ras_fini(struct amdgpu_device *adev);
int amdgpu_gfx_process_ras_data_cb(struct amdgpu_device *adev,
void *err_data,
@ -410,5 +397,4 @@ int amdgpu_gfx_cp_ecc_error_irq(struct amdgpu_device *adev,
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);
void amdgpu_gfx_state_change_set(struct amdgpu_device *adev, enum gfx_change_state state);
#endif

View File

@ -436,58 +436,58 @@ void amdgpu_gmc_filter_faults_remove(struct amdgpu_device *adev, uint64_t addr,
} while (fault->timestamp < tmp);
}
int amdgpu_gmc_ras_early_init(struct amdgpu_device *adev)
{
if (!adev->gmc.xgmi.connected_to_cpu) {
adev->gmc.xgmi.ras = &xgmi_ras;
amdgpu_ras_register_ras_block(adev, &adev->gmc.xgmi.ras->ras_block);
}
return 0;
}
int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev)
{
int r;
if (adev->umc.ras_funcs &&
adev->umc.ras_funcs->ras_late_init) {
r = adev->umc.ras_funcs->ras_late_init(adev);
if (adev->umc.ras && adev->umc.ras->ras_block.ras_late_init) {
r = adev->umc.ras->ras_block.ras_late_init(adev, NULL);
if (r)
return r;
}
if (adev->mmhub.ras_funcs &&
adev->mmhub.ras_funcs->ras_late_init) {
r = adev->mmhub.ras_funcs->ras_late_init(adev);
if (adev->mmhub.ras && adev->mmhub.ras->ras_block.ras_late_init) {
r = adev->mmhub.ras->ras_block.ras_late_init(adev, NULL);
if (r)
return r;
}
if (!adev->gmc.xgmi.connected_to_cpu)
adev->gmc.xgmi.ras_funcs = &xgmi_ras_funcs;
if (adev->gmc.xgmi.ras_funcs &&
adev->gmc.xgmi.ras_funcs->ras_late_init) {
r = adev->gmc.xgmi.ras_funcs->ras_late_init(adev);
if (adev->gmc.xgmi.ras && adev->gmc.xgmi.ras->ras_block.ras_late_init) {
r = adev->gmc.xgmi.ras->ras_block.ras_late_init(adev, NULL);
if (r)
return r;
}
if (adev->hdp.ras_funcs &&
adev->hdp.ras_funcs->ras_late_init) {
r = adev->hdp.ras_funcs->ras_late_init(adev);
if (adev->hdp.ras && adev->hdp.ras->ras_block.ras_late_init) {
r = adev->hdp.ras->ras_block.ras_late_init(adev, NULL);
if (r)
return r;
}
if (adev->mca.mp0.ras_funcs &&
adev->mca.mp0.ras_funcs->ras_late_init) {
r = adev->mca.mp0.ras_funcs->ras_late_init(adev);
if (adev->mca.mp0.ras && adev->mca.mp0.ras->ras_block.ras_late_init) {
r = adev->mca.mp0.ras->ras_block.ras_late_init(adev, NULL);
if (r)
return r;
}
if (adev->mca.mp1.ras_funcs &&
adev->mca.mp1.ras_funcs->ras_late_init) {
r = adev->mca.mp1.ras_funcs->ras_late_init(adev);
if (adev->mca.mp1.ras && adev->mca.mp1.ras->ras_block.ras_late_init) {
r = adev->mca.mp1.ras->ras_block.ras_late_init(adev, NULL);
if (r)
return r;
}
if (adev->mca.mpio.ras_funcs &&
adev->mca.mpio.ras_funcs->ras_late_init) {
r = adev->mca.mpio.ras_funcs->ras_late_init(adev);
if (adev->mca.mpio.ras && adev->mca.mpio.ras->ras_block.ras_late_init) {
r = adev->mca.mpio.ras->ras_block.ras_late_init(adev, NULL);
if (r)
return r;
}
@ -497,21 +497,17 @@ int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev)
void amdgpu_gmc_ras_fini(struct amdgpu_device *adev)
{
if (adev->umc.ras_funcs &&
adev->umc.ras_funcs->ras_fini)
adev->umc.ras_funcs->ras_fini(adev);
if (adev->umc.ras && adev->umc.ras->ras_block.ras_fini)
adev->umc.ras->ras_block.ras_fini(adev);
if (adev->mmhub.ras_funcs &&
adev->mmhub.ras_funcs->ras_fini)
adev->mmhub.ras_funcs->ras_fini(adev);
if (adev->mmhub.ras && adev->mmhub.ras->ras_block.ras_fini)
adev->mmhub.ras->ras_block.ras_fini(adev);
if (adev->gmc.xgmi.ras_funcs &&
adev->gmc.xgmi.ras_funcs->ras_fini)
adev->gmc.xgmi.ras_funcs->ras_fini(adev);
if (adev->gmc.xgmi.ras && adev->gmc.xgmi.ras->ras_block.ras_fini)
adev->gmc.xgmi.ras->ras_block.ras_fini(adev);
if (adev->hdp.ras_funcs &&
adev->hdp.ras_funcs->ras_fini)
adev->hdp.ras_funcs->ras_fini(adev);
if (adev->hdp.ras && adev->hdp.ras->ras_block.ras_fini)
adev->hdp.ras->ras_block.ras_fini(adev);
}
/*
@ -831,3 +827,49 @@ void amdgpu_gmc_get_reserved_allocation(struct amdgpu_device *adev)
break;
}
}
int amdgpu_gmc_vram_checking(struct amdgpu_device *adev)
{
struct amdgpu_bo *vram_bo = NULL;
uint64_t vram_gpu = 0;
void *vram_ptr = NULL;
int ret, size = 0x100000;
uint8_t cptr[10];
ret = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
AMDGPU_GEM_DOMAIN_VRAM,
&vram_bo,
&vram_gpu,
&vram_ptr);
if (ret)
return ret;
memset(vram_ptr, 0x86, size);
memset(cptr, 0x86, 10);
/**
* Check the start, the mid, and the end of the memory if the content of
* each byte is the pattern "0x86". If yes, we suppose the vram bo is
* workable.
*
* Note: If check the each byte of whole 1M bo, it will cost too many
* seconds, so here, we just pick up three parts for emulation.
*/
ret = memcmp(vram_ptr, cptr, 10);
if (ret)
return ret;
ret = memcmp(vram_ptr + (size / 2), cptr, 10);
if (ret)
return ret;
ret = memcmp(vram_ptr + size - 10, cptr, 10);
if (ret)
return ret;
amdgpu_bo_free_kernel(&vram_bo, &vram_gpu,
&vram_ptr);
return 0;
}

View File

@ -29,6 +29,7 @@
#include <linux/types.h>
#include "amdgpu_irq.h"
#include "amdgpu_ras.h"
/* VA hole for 48bit addresses on Vega10 */
#define AMDGPU_GMC_HOLE_START 0x0000800000000000ULL
@ -135,12 +136,8 @@ struct amdgpu_gmc_funcs {
unsigned int (*get_vbios_fb_size)(struct amdgpu_device *adev);
};
struct amdgpu_xgmi_ras_funcs {
int (*ras_late_init)(struct amdgpu_device *adev);
void (*ras_fini)(struct amdgpu_device *adev);
int (*query_ras_error_count)(struct amdgpu_device *adev,
void *ras_error_status);
void (*reset_ras_error_count)(struct amdgpu_device *adev);
struct amdgpu_xgmi_ras {
struct amdgpu_ras_block_object ras_block;
};
struct amdgpu_xgmi {
@ -159,7 +156,7 @@ struct amdgpu_xgmi {
struct ras_common_if *ras_if;
bool connected_to_cpu;
bool pending_reset;
const struct amdgpu_xgmi_ras_funcs *ras_funcs;
struct amdgpu_xgmi_ras *ras;
};
struct amdgpu_gmc {
@ -321,6 +318,7 @@ bool amdgpu_gmc_filter_faults(struct amdgpu_device *adev,
uint16_t pasid, uint64_t timestamp);
void amdgpu_gmc_filter_faults_remove(struct amdgpu_device *adev, uint64_t addr,
uint16_t pasid);
int amdgpu_gmc_ras_early_init(struct amdgpu_device *adev);
int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev);
void amdgpu_gmc_ras_fini(struct amdgpu_device *adev);
int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev);
@ -339,4 +337,5 @@ void amdgpu_gmc_init_pdb0(struct amdgpu_device *adev);
uint64_t amdgpu_gmc_vram_mc2pa(struct amdgpu_device *adev, uint64_t mc_addr);
uint64_t amdgpu_gmc_vram_pa(struct amdgpu_device *adev, struct amdgpu_bo *bo);
uint64_t amdgpu_gmc_vram_cpu_pa(struct amdgpu_device *adev, struct amdgpu_bo *bo);
int amdgpu_gmc_vram_checking(struct amdgpu_device *adev);
#endif

View File

@ -222,26 +222,21 @@ uint64_t amdgpu_gtt_mgr_usage(struct amdgpu_gtt_mgr *mgr)
*
* Re-init the gart for each known BO in the GTT.
*/
int amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr)
void amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr)
{
struct amdgpu_gtt_node *node;
struct drm_mm_node *mm_node;
struct amdgpu_device *adev;
int r = 0;
adev = container_of(mgr, typeof(*adev), mman.gtt_mgr);
spin_lock(&mgr->lock);
drm_mm_for_each_node(mm_node, &mgr->mm) {
node = container_of(mm_node, typeof(*node), base.mm_nodes[0]);
r = amdgpu_ttm_recover_gart(node->tbo);
if (r)
break;
amdgpu_ttm_recover_gart(node->tbo);
}
spin_unlock(&mgr->lock);
amdgpu_gart_invalidate_tlb(adev);
return r;
}
/**

View File

@ -24,7 +24,7 @@
#include "amdgpu.h"
#include "amdgpu_ras.h"
int amdgpu_hdp_ras_late_init(struct amdgpu_device *adev)
int amdgpu_hdp_ras_late_init(struct amdgpu_device *adev, void *ras_info)
{
int r;
struct ras_ih_if ih_info = {

View File

@ -22,13 +22,10 @@
*/
#ifndef __AMDGPU_HDP_H__
#define __AMDGPU_HDP_H__
#include "amdgpu_ras.h"
struct amdgpu_hdp_ras_funcs {
int (*ras_late_init)(struct amdgpu_device *adev);
void (*ras_fini)(struct amdgpu_device *adev);
void (*query_ras_error_count)(struct amdgpu_device *adev,
void *ras_error_status);
void (*reset_ras_error_count)(struct amdgpu_device *adev);
struct amdgpu_hdp_ras {
struct amdgpu_ras_block_object ras_block;
};
struct amdgpu_hdp_funcs {
@ -43,9 +40,9 @@ struct amdgpu_hdp_funcs {
struct amdgpu_hdp {
struct ras_common_if *ras_if;
const struct amdgpu_hdp_funcs *funcs;
const struct amdgpu_hdp_ras_funcs *ras_funcs;
struct amdgpu_hdp_ras *ras;
};
int amdgpu_hdp_ras_late_init(struct amdgpu_device *adev);
int amdgpu_hdp_ras_late_init(struct amdgpu_device *adev, void *ras_info);
void amdgpu_hdp_ras_fini(struct amdgpu_device *adev);
#endif /* __AMDGPU_HDP_H__ */

View File

@ -199,13 +199,13 @@ static irqreturn_t amdgpu_irq_handler(int irq, void *arg)
* ack the interrupt if it is there
*/
if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__PCIE_BIF)) {
if (adev->nbio.ras_funcs &&
adev->nbio.ras_funcs->handle_ras_controller_intr_no_bifring)
adev->nbio.ras_funcs->handle_ras_controller_intr_no_bifring(adev);
if (adev->nbio.ras &&
adev->nbio.ras->handle_ras_controller_intr_no_bifring)
adev->nbio.ras->handle_ras_controller_intr_no_bifring(adev);
if (adev->nbio.ras_funcs &&
adev->nbio.ras_funcs->handle_ras_err_event_athub_intr_no_bifring)
adev->nbio.ras_funcs->handle_ras_err_event_athub_intr_no_bifring(adev);
if (adev->nbio.ras &&
adev->nbio.ras->handle_ras_err_event_athub_intr_no_bifring)
adev->nbio.ras->handle_ras_err_event_athub_intr_no_bifring(adev);
}
return ret;

View File

@ -87,11 +87,6 @@ void amdgpu_driver_unload_kms(struct drm_device *dev)
if (adev->rmmio == NULL)
return;
if (adev->runpm) {
pm_runtime_get_sync(dev->dev);
pm_runtime_forbid(dev->dev);
}
if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DRV_UNLOAD))
DRM_WARN("smart shift update failed\n");
@ -124,22 +119,6 @@ void amdgpu_register_gpu_instance(struct amdgpu_device *adev)
mutex_unlock(&mgpu_info.mutex);
}
static void amdgpu_get_audio_func(struct amdgpu_device *adev)
{
struct pci_dev *p = NULL;
p = pci_get_domain_bus_and_slot(pci_domain_nr(adev->pdev->bus),
adev->pdev->bus->number, 1);
if (p) {
pm_runtime_get_sync(&p->dev);
pm_runtime_mark_last_busy(&p->dev);
pm_runtime_put_autosuspend(&p->dev);
pci_dev_put(p);
}
}
/**
* amdgpu_driver_load_kms - Main load function for KMS.
*
@ -152,21 +131,10 @@ static void amdgpu_get_audio_func(struct amdgpu_device *adev)
int amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags)
{
struct drm_device *dev;
struct pci_dev *parent;
int r, acpi_status;
dev = adev_to_drm(adev);
if (amdgpu_has_atpx() &&
(amdgpu_is_atpx_hybrid() ||
amdgpu_has_atpx_dgpu_power_cntl()) &&
((flags & AMD_IS_APU) == 0) &&
!pci_is_thunderbolt_attached(to_pci_dev(dev->dev)))
flags |= AMD_IS_PX;
parent = pci_upstream_bridge(adev->pdev);
adev->has_pr3 = parent ? pci_pr3_present(parent) : false;
/* amdgpu_device_init should report only fatal error
* like memory allocation failure or iomapping failure,
* or memory manager initialization failure, it must
@ -224,58 +192,12 @@ int amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags)
if (acpi_status)
dev_dbg(dev->dev, "Error during ACPI methods call\n");
if (adev->runpm) {
/* only need to skip on ATPX */
if (amdgpu_device_supports_px(dev))
dev_pm_set_driver_flags(dev->dev, DPM_FLAG_NO_DIRECT_COMPLETE);
/* we want direct complete for BOCO */
if (amdgpu_device_supports_boco(dev))
dev_pm_set_driver_flags(dev->dev, DPM_FLAG_SMART_PREPARE |
DPM_FLAG_SMART_SUSPEND |
DPM_FLAG_MAY_SKIP_RESUME);
pm_runtime_use_autosuspend(dev->dev);
pm_runtime_set_autosuspend_delay(dev->dev, 5000);
pm_runtime_allow(dev->dev);
pm_runtime_mark_last_busy(dev->dev);
pm_runtime_put_autosuspend(dev->dev);
/*
* For runpm implemented via BACO, PMFW will handle the
* timing for BACO in and out:
* - put ASIC into BACO state only when both video and
* audio functions are in D3 state.
* - pull ASIC out of BACO state when either video or
* audio function is in D0 state.
* Also, at startup, PMFW assumes both functions are in
* D0 state.
*
* So if snd driver was loaded prior to amdgpu driver
* and audio function was put into D3 state, there will
* be no PMFW-aware D-state transition(D0->D3) on runpm
* suspend. Thus the BACO will be not correctly kicked in.
*
* Via amdgpu_get_audio_func(), the audio dev is put
* into D0 state. Then there will be a PMFW-aware D-state
* transition(D0->D3) on runpm suspend.
*/
if (amdgpu_device_supports_baco(dev) &&
!(adev->flags & AMD_IS_APU) &&
(adev->asic_type >= CHIP_NAVI10))
amdgpu_get_audio_func(adev);
}
if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DRV_LOAD))
DRM_WARN("smart shift update failed\n");
out:
if (r) {
/* balance pm_runtime_get_sync in amdgpu_driver_unload_kms */
if (adev->rmmio && adev->runpm)
pm_runtime_put_noidle(dev->dev);
if (r)
amdgpu_driver_unload_kms(dev);
}
return r;
}
@ -406,6 +328,10 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
fw_info->ver = adev->psp.toc.fw_version;
fw_info->feature = adev->psp.toc.feature_version;
break;
case AMDGPU_INFO_FW_CAP:
fw_info->ver = adev->psp.cap_fw_version;
fw_info->feature = adev->psp.cap_feature_version;
break;
default:
return -EINVAL;
}
@ -1268,18 +1194,20 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_VCE) != NULL)
amdgpu_vce_free_handles(adev, file_priv);
amdgpu_vm_bo_rmv(adev, fpriv->prt_va);
if (amdgpu_mcbp || amdgpu_sriov_vf(adev)) {
/* TODO: how to handle reserve failure */
BUG_ON(amdgpu_bo_reserve(adev->virt.csa_obj, true));
amdgpu_vm_bo_rmv(adev, fpriv->csa_va);
amdgpu_vm_bo_del(adev, fpriv->csa_va);
fpriv->csa_va = NULL;
amdgpu_bo_unreserve(adev->virt.csa_obj);
}
pasid = fpriv->vm.pasid;
pd = amdgpu_bo_ref(fpriv->vm.root.bo);
if (!WARN_ON(amdgpu_bo_reserve(pd, true))) {
amdgpu_vm_bo_del(adev, fpriv->prt_va);
amdgpu_bo_unreserve(pd);
}
amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr);
amdgpu_vm_fini(adev, &fpriv->vm);
@ -1427,8 +1355,7 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
struct drm_amdgpu_info_firmware fw_info;
struct drm_amdgpu_query_fw query_fw;
struct atom_context *ctx = adev->mode_info.atom_context;
uint8_t smu_minor, smu_debug;
uint16_t smu_major;
uint8_t smu_program, smu_major, smu_minor, smu_debug;
int ret, i;
static const char *ta_fw_name[TA_FW_TYPE_MAX_INDEX] = {
@ -1574,11 +1501,12 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
if (ret)
return ret;
smu_major = (fw_info.ver >> 16) & 0xffff;
smu_program = (fw_info.ver >> 24) & 0xff;
smu_major = (fw_info.ver >> 16) & 0xff;
smu_minor = (fw_info.ver >> 8) & 0xff;
smu_debug = (fw_info.ver >> 0) & 0xff;
seq_printf(m, "SMC feature version: %u, firmware version: 0x%08x (%d.%d.%d)\n",
fw_info.feature, fw_info.ver, smu_major, smu_minor, smu_debug);
seq_printf(m, "SMC feature version: %u, program: %d, firmware version: 0x%08x (%d.%d.%d)\n",
fw_info.feature, smu_program, fw_info.ver, smu_major, smu_minor, smu_debug);
/* SDMA */
query_fw.fw_type = AMDGPU_INFO_FW_SDMA;
@ -1623,6 +1551,16 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
seq_printf(m, "TOC feature version: %u, firmware version: 0x%08x\n",
fw_info.feature, fw_info.ver);
/* CAP */
if (adev->psp.cap_fw) {
query_fw.fw_type = AMDGPU_INFO_FW_CAP;
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
if (ret)
return ret;
seq_printf(m, "CAP feature version: %u, firmware version: 0x%08x\n",
fw_info.feature, fw_info.ver);
}
seq_printf(m, "VBIOS version: %s\n", ctx->vbios_version);
return 0;

View File

@ -74,20 +74,23 @@ void amdgpu_mca_query_ras_error_count(struct amdgpu_device *adev,
int amdgpu_mca_ras_late_init(struct amdgpu_device *adev,
struct amdgpu_mca_ras *mca_dev)
{
char sysfs_name[32] = {0};
int r;
struct ras_ih_if ih_info = {
.cb = NULL,
};
struct ras_fs_if fs_info = {
.sysfs_name = mca_dev->ras_funcs->sysfs_name,
struct ras_fs_if fs_info= {
.sysfs_name = sysfs_name,
};
snprintf(sysfs_name, sizeof(sysfs_name), "%s_err_count", mca_dev->ras->ras_block.name);
if (!mca_dev->ras_if) {
mca_dev->ras_if = kmalloc(sizeof(struct ras_common_if), GFP_KERNEL);
if (!mca_dev->ras_if)
return -ENOMEM;
mca_dev->ras_if->block = mca_dev->ras_funcs->ras_block;
mca_dev->ras_if->sub_block_index = mca_dev->ras_funcs->ras_sub_block;
mca_dev->ras_if->block = mca_dev->ras->ras_block.block;
mca_dev->ras_if->sub_block_index = mca_dev->ras->ras_block.sub_block_index;
mca_dev->ras_if->type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
}
ih_info.head = fs_info.head = *mca_dev->ras_if;

View File

@ -21,21 +21,13 @@
#ifndef __AMDGPU_MCA_H__
#define __AMDGPU_MCA_H__
struct amdgpu_mca_ras_funcs {
int (*ras_late_init)(struct amdgpu_device *adev);
void (*ras_fini)(struct amdgpu_device *adev);
void (*query_ras_error_count)(struct amdgpu_device *adev,
void *ras_error_status);
void (*query_ras_error_address)(struct amdgpu_device *adev,
void *ras_error_status);
uint32_t ras_block;
uint32_t ras_sub_block;
const char* sysfs_name;
struct amdgpu_mca_ras_block {
struct amdgpu_ras_block_object ras_block;
};
struct amdgpu_mca_ras {
struct ras_common_if *ras_if;
const struct amdgpu_mca_ras_funcs *ras_funcs;
struct amdgpu_mca_ras_block *ras;
};
struct amdgpu_mca_funcs {

View File

@ -24,7 +24,7 @@
#include "amdgpu.h"
#include "amdgpu_ras.h"
int amdgpu_mmhub_ras_late_init(struct amdgpu_device *adev)
int amdgpu_mmhub_ras_late_init(struct amdgpu_device *adev, void *ras_info)
{
int r;
struct ras_ih_if ih_info = {

View File

@ -21,14 +21,8 @@
#ifndef __AMDGPU_MMHUB_H__
#define __AMDGPU_MMHUB_H__
struct amdgpu_mmhub_ras_funcs {
int (*ras_late_init)(struct amdgpu_device *adev);
void (*ras_fini)(struct amdgpu_device *adev);
void (*query_ras_error_count)(struct amdgpu_device *adev,
void *ras_error_status);
void (*query_ras_error_status)(struct amdgpu_device *adev);
void (*reset_ras_error_count)(struct amdgpu_device *adev);
void (*reset_ras_error_status)(struct amdgpu_device *adev);
struct amdgpu_mmhub_ras {
struct amdgpu_ras_block_object ras_block;
};
struct amdgpu_mmhub_funcs {
@ -50,10 +44,10 @@ struct amdgpu_mmhub_funcs {
struct amdgpu_mmhub {
struct ras_common_if *ras_if;
const struct amdgpu_mmhub_funcs *funcs;
const struct amdgpu_mmhub_ras_funcs *ras_funcs;
struct amdgpu_mmhub_ras *ras;
};
int amdgpu_mmhub_ras_late_init(struct amdgpu_device *adev);
int amdgpu_mmhub_ras_late_init(struct amdgpu_device *adev, void *ras_info);
void amdgpu_mmhub_ras_fini(struct amdgpu_device *adev);
#endif

View File

@ -22,7 +22,7 @@
#include "amdgpu.h"
#include "amdgpu_ras.h"
int amdgpu_nbio_ras_late_init(struct amdgpu_device *adev)
int amdgpu_nbio_ras_late_init(struct amdgpu_device *adev, void *ras_info)
{
int r;
struct ras_ih_if ih_info = {

View File

@ -47,15 +47,12 @@ struct nbio_hdp_flush_reg {
u32 ref_and_mask_sdma7;
};
struct amdgpu_nbio_ras_funcs {
struct amdgpu_nbio_ras {
struct amdgpu_ras_block_object ras_block;
void (*handle_ras_controller_intr_no_bifring)(struct amdgpu_device *adev);
void (*handle_ras_err_event_athub_intr_no_bifring)(struct amdgpu_device *adev);
int (*init_ras_controller_interrupt)(struct amdgpu_device *adev);
int (*init_ras_err_event_athub_interrupt)(struct amdgpu_device *adev);
void (*query_ras_error_count)(struct amdgpu_device *adev,
void *ras_error_status);
int (*ras_late_init)(struct amdgpu_device *adev);
void (*ras_fini)(struct amdgpu_device *adev);
};
struct amdgpu_nbio_funcs {
@ -104,9 +101,9 @@ struct amdgpu_nbio {
struct amdgpu_irq_src ras_err_event_athub_irq;
struct ras_common_if *ras_if;
const struct amdgpu_nbio_funcs *funcs;
const struct amdgpu_nbio_ras_funcs *ras_funcs;
struct amdgpu_nbio_ras *ras;
};
int amdgpu_nbio_ras_late_init(struct amdgpu_device *adev);
int amdgpu_nbio_ras_late_init(struct amdgpu_device *adev, void *ras_info);
void amdgpu_nbio_ras_fini(struct amdgpu_device *adev);
#endif

View File

@ -575,6 +575,9 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
if (!amdgpu_bo_support_uswc(bo->flags))
bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC;
if (adev->ras_enabled)
bo->flags |= AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE;
bo->tbo.bdev = &adev->mman.bdev;
if (bp->domain & (AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA |
AMDGPU_GEM_DOMAIN_GDS))
@ -1303,7 +1306,8 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
!(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE))
return;
dma_resv_lock(bo->base.resv, NULL);
if (WARN_ON_ONCE(!dma_resv_trylock(bo->base.resv)))
return;
r = amdgpu_fill_buffer(abo, AMDGPU_POISON, bo->base.resv, &fence);
if (!WARN_ON(r)) {

View File

@ -137,7 +137,8 @@ static int psp_early_init(void *handle)
psp->autoload_supported = true;
break;
case IP_VERSION(11, 0, 8):
if (adev->apu_flags & AMD_APU_IS_CYAN_SKILLFISH2) {
if (adev->apu_flags & AMD_APU_IS_CYAN_SKILLFISH2 ||
adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 4)) {
psp_v11_0_8_set_psp_funcs(psp);
psp->autoload_supported = false;
}
@ -259,6 +260,32 @@ static bool psp_get_runtime_db_entry(struct amdgpu_device *adev,
return ret;
}
static int psp_init_sriov_microcode(struct psp_context *psp)
{
struct amdgpu_device *adev = psp->adev;
int ret = 0;
switch (adev->ip_versions[MP0_HWIP][0]) {
case IP_VERSION(9, 0, 0):
ret = psp_init_cap_microcode(psp, "vega10");
break;
case IP_VERSION(11, 0, 9):
ret = psp_init_cap_microcode(psp, "navi12");
break;
case IP_VERSION(11, 0, 7):
ret = psp_init_cap_microcode(psp, "sienna_cichlid");
break;
case IP_VERSION(13, 0, 2):
ret = psp_init_ta_microcode(psp, "aldebaran");
break;
default:
BUG();
break;
}
return ret;
}
static int psp_sw_init(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
@ -273,19 +300,13 @@ static int psp_sw_init(void *handle)
ret = -ENOMEM;
}
if (!amdgpu_sriov_vf(adev)) {
if (amdgpu_sriov_vf(adev))
ret = psp_init_sriov_microcode(psp);
else
ret = psp_init_microcode(psp);
if (ret) {
DRM_ERROR("Failed to load psp firmware!\n");
return ret;
}
} else if (amdgpu_sriov_vf(adev) &&
adev->ip_versions[MP0_HWIP][0] == IP_VERSION(13, 0, 2)) {
ret = psp_init_ta_microcode(psp, "aldebaran");
if (ret) {
DRM_ERROR("Failed to initialize ta microcode!\n");
return ret;
}
if (ret) {
DRM_ERROR("Failed to load psp firmware!\n");
return ret;
}
memset(&boot_cfg_entry, 0, sizeof(boot_cfg_entry));
@ -353,6 +374,10 @@ static int psp_sw_fini(void *handle)
release_firmware(psp->ta_fw);
psp->ta_fw = NULL;
}
if (adev->psp.cap_fw) {
release_firmware(psp->cap_fw);
psp->cap_fw = NULL;
}
if (adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 0) ||
adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 7))
@ -491,7 +516,10 @@ psp_cmd_submit_buf(struct psp_context *psp,
DRM_WARN("psp gfx command %s(0x%X) failed and response status is (0x%X)\n",
psp_gfx_cmd_name(psp->cmd_buf_mem->cmd_id), psp->cmd_buf_mem->cmd_id,
psp->cmd_buf_mem->resp.status);
if (!timeout) {
/* If we load CAP FW, PSP must return 0 under SRIOV
* also return failure in case of timeout
*/
if ((ucode && (ucode->ucode_id == AMDGPU_UCODE_ID_CAP)) || !timeout) {
ret = -EINVAL;
goto exit;
}
@ -914,19 +942,15 @@ static void psp_prep_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
static int psp_ta_init_shared_buf(struct psp_context *psp,
struct ta_mem_context *mem_ctx)
{
int ret;
/*
* Allocate 16k memory aligned to 4k from Frame Buffer (local
* physical) for ta to host memory
*/
ret = amdgpu_bo_create_kernel(psp->adev, mem_ctx->shared_mem_size,
return amdgpu_bo_create_kernel(psp->adev, mem_ctx->shared_mem_size,
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
&mem_ctx->shared_bo,
&mem_ctx->shared_mc_addr,
&mem_ctx->shared_buf);
return ret;
}
static void psp_ta_free_shared_buf(struct ta_mem_context *mem_ctx)
@ -1308,6 +1332,11 @@ static void psp_ras_ta_check_status(struct psp_context *psp)
break;
case TA_RAS_STATUS__SUCCESS:
break;
case TA_RAS_STATUS__TEE_ERROR_ACCESS_DENIED:
if (ras_cmd->cmd_id == TA_RAS_COMMAND__TRIGGER_ERROR)
dev_warn(psp->adev->dev,
"RAS WARNING: Inject error to critical region is not allowed\n");
break;
default:
dev_warn(psp->adev->dev,
"RAS WARNING: ras status = 0x%X\n", ras_cmd->ras_status);
@ -1520,7 +1549,9 @@ int psp_ras_trigger_error(struct psp_context *psp,
if (amdgpu_ras_intr_triggered())
return 0;
if (ras_cmd->ras_status)
if (ras_cmd->ras_status == TA_RAS_STATUS__TEE_ERROR_ACCESS_DENIED)
return -EACCES;
else if (ras_cmd->ras_status)
return -EINVAL;
return 0;
@ -2051,6 +2082,9 @@ static int psp_get_fw_type(struct amdgpu_firmware_info *ucode,
enum psp_gfx_fw_type *type)
{
switch (ucode->ucode_id) {
case AMDGPU_UCODE_ID_CAP:
*type = GFX_FW_TYPE_CAP;
break;
case AMDGPU_UCODE_ID_SDMA0:
*type = GFX_FW_TYPE_SDMA0;
break;
@ -3217,6 +3251,58 @@ out:
return err;
}
int psp_init_cap_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 *cap_hdr_v1_0;
struct amdgpu_firmware_info *info = NULL;
int err = 0;
if (!chip_name) {
dev_err(adev->dev, "invalid chip name for cap microcode\n");
return -EINVAL;
}
if (!amdgpu_sriov_vf(adev)) {
dev_err(adev->dev, "cap microcode should only be loaded under SRIOV\n");
return -EINVAL;
}
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_cap.bin", chip_name);
err = request_firmware(&adev->psp.cap_fw, fw_name, adev->dev);
if (err) {
dev_warn(adev->dev, "cap microcode does not exist, skip\n");
err = 0;
goto out;
}
err = amdgpu_ucode_validate(adev->psp.cap_fw);
if (err) {
dev_err(adev->dev, "fail to initialize cap microcode\n");
goto out;
}
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_CAP];
info->ucode_id = AMDGPU_UCODE_ID_CAP;
info->fw = adev->psp.cap_fw;
cap_hdr_v1_0 = (const struct psp_firmware_header_v1_0 *)
adev->psp.cap_fw->data;
adev->firmware.fw_size += ALIGN(
le32_to_cpu(cap_hdr_v1_0->header.ucode_size_bytes), PAGE_SIZE);
adev->psp.cap_fw_version = le32_to_cpu(cap_hdr_v1_0->header.ucode_version);
adev->psp.cap_feature_version = le32_to_cpu(cap_hdr_v1_0->sos.fw_version);
adev->psp.cap_ucode_size = le32_to_cpu(cap_hdr_v1_0->header.ucode_size_bytes);
return 0;
out:
release_firmware(adev->psp.cap_fw);
adev->psp.cap_fw = NULL;
return err;
}
static int psp_set_clockgating_state(void *handle,
enum amd_clockgating_state state)
{

View File

@ -306,6 +306,9 @@ struct psp_context
/* toc firmware */
const struct firmware *toc_fw;
/* cap firmware */
const struct firmware *cap_fw;
/* fence buffer */
struct amdgpu_bo *fence_buf_bo;
uint64_t fence_buf_mc_addr;
@ -327,6 +330,10 @@ struct psp_context
const struct firmware *ta_fw;
uint32_t ta_fw_version;
uint32_t cap_fw_version;
uint32_t cap_feature_version;
uint32_t cap_ucode_size;
struct ta_context asd_context;
struct psp_xgmi_context xgmi_context;
struct psp_ras_context ras_context;
@ -440,6 +447,8 @@ 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_init_cap_microcode(struct psp_context *psp,
const char *chip_name);
int psp_get_fw_attestation_records_addr(struct psp_context *psp,
uint64_t *output_ptr);

View File

@ -75,6 +75,13 @@ const char *ras_mca_block_string[] = {
"mca_iohc",
};
struct amdgpu_ras_block_list {
/* ras block link */
struct list_head node;
struct amdgpu_ras_block_object *ras_obj;
};
const char *get_ras_block_str(struct ras_common_if *ras_block)
{
if (!ras_block)
@ -89,6 +96,9 @@ const char *get_ras_block_str(struct ras_common_if *ras_block)
return ras_block_string[ras_block->block];
}
#define ras_block_str(_BLOCK_) \
(((_BLOCK_) < ARRAY_SIZE(ras_block_string)) ? ras_block_string[_BLOCK_] : "Out Of Range")
#define ras_err_str(i) (ras_error_string[ffs(i)])
#define RAS_DEFAULT_FLAGS (AMDGPU_RAS_FLAG_INIT_BY_VBIOS)
@ -155,14 +165,9 @@ static int amdgpu_reserve_page_direct(struct amdgpu_device *adev, uint64_t addre
}
memset(&err_rec, 0x0, sizeof(struct eeprom_table_record));
err_rec.address = address;
err_rec.retired_page = address >> AMDGPU_GPU_PAGE_SHIFT;
err_rec.ts = (uint64_t)ktime_get_real_seconds();
err_rec.err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE;
err_data.err_addr = &err_rec;
err_data.err_addr_cnt = 1;
amdgpu_umc_fill_error_record(&err_data, address,
(address >> AMDGPU_GPU_PAGE_SHIFT), 0, 0);
if (amdgpu_bad_page_threshold != 0) {
amdgpu_ras_add_bad_pages(adev, err_data.err_addr,
@ -452,7 +457,7 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f,
}
if (ret)
return -EINVAL;
return ret;
return size;
}
@ -866,30 +871,47 @@ static int amdgpu_ras_enable_all_features(struct amdgpu_device *adev,
}
/* feature ctl end */
static void amdgpu_ras_mca_query_error_status(struct amdgpu_device *adev,
struct ras_common_if *ras_block,
struct ras_err_data *err_data)
static int amdgpu_ras_block_match_default(struct amdgpu_ras_block_object *block_obj,
enum amdgpu_ras_block block)
{
switch (ras_block->sub_block_index) {
case AMDGPU_RAS_MCA_BLOCK__MP0:
if (adev->mca.mp0.ras_funcs &&
adev->mca.mp0.ras_funcs->query_ras_error_count)
adev->mca.mp0.ras_funcs->query_ras_error_count(adev, &err_data);
break;
case AMDGPU_RAS_MCA_BLOCK__MP1:
if (adev->mca.mp1.ras_funcs &&
adev->mca.mp1.ras_funcs->query_ras_error_count)
adev->mca.mp1.ras_funcs->query_ras_error_count(adev, &err_data);
break;
case AMDGPU_RAS_MCA_BLOCK__MPIO:
if (adev->mca.mpio.ras_funcs &&
adev->mca.mpio.ras_funcs->query_ras_error_count)
adev->mca.mpio.ras_funcs->query_ras_error_count(adev, &err_data);
break;
default:
break;
if (!block_obj)
return -EINVAL;
if (block_obj->block == block)
return 0;
return -EINVAL;
}
static struct amdgpu_ras_block_object *amdgpu_ras_get_ras_block(struct amdgpu_device *adev,
enum amdgpu_ras_block block, uint32_t sub_block_index)
{
struct amdgpu_ras_block_list *node, *tmp;
struct amdgpu_ras_block_object *obj;
if (block >= AMDGPU_RAS_BLOCK__LAST)
return NULL;
if (!amdgpu_ras_is_supported(adev, block))
return NULL;
list_for_each_entry_safe(node, tmp, &adev->ras_list, node) {
if (!node->ras_obj) {
dev_warn(adev->dev, "Warning: abnormal ras list node.\n");
continue;
}
obj = node->ras_obj;
if (obj->ras_block_match) {
if (obj->ras_block_match(obj, block, sub_block_index) == 0)
return obj;
} else {
if (amdgpu_ras_block_match_default(obj, block) == 0)
return obj;
}
}
return NULL;
}
static void amdgpu_ras_get_ecc_info(struct amdgpu_device *adev, struct ras_err_data *err_data)
@ -901,26 +923,26 @@ static void amdgpu_ras_get_ecc_info(struct amdgpu_device *adev, struct ras_err_d
* choosing right query method according to
* whether smu support query error information
*/
ret = smu_get_ecc_info(&adev->smu, (void *)&(ras->umc_ecc));
ret = amdgpu_dpm_get_ecc_info(adev, (void *)&(ras->umc_ecc));
if (ret == -EOPNOTSUPP) {
if (adev->umc.ras_funcs &&
adev->umc.ras_funcs->query_ras_error_count)
adev->umc.ras_funcs->query_ras_error_count(adev, err_data);
if (adev->umc.ras && adev->umc.ras->ras_block.hw_ops &&
adev->umc.ras->ras_block.hw_ops->query_ras_error_count)
adev->umc.ras->ras_block.hw_ops->query_ras_error_count(adev, err_data);
/* umc query_ras_error_address is also responsible for clearing
* error status
*/
if (adev->umc.ras_funcs &&
adev->umc.ras_funcs->query_ras_error_address)
adev->umc.ras_funcs->query_ras_error_address(adev, err_data);
if (adev->umc.ras && adev->umc.ras->ras_block.hw_ops &&
adev->umc.ras->ras_block.hw_ops->query_ras_error_address)
adev->umc.ras->ras_block.hw_ops->query_ras_error_address(adev, err_data);
} else if (!ret) {
if (adev->umc.ras_funcs &&
adev->umc.ras_funcs->ecc_info_query_ras_error_count)
adev->umc.ras_funcs->ecc_info_query_ras_error_count(adev, err_data);
if (adev->umc.ras &&
adev->umc.ras->ecc_info_query_ras_error_count)
adev->umc.ras->ecc_info_query_ras_error_count(adev, err_data);
if (adev->umc.ras_funcs &&
adev->umc.ras_funcs->ecc_info_query_ras_error_address)
adev->umc.ras_funcs->ecc_info_query_ras_error_address(adev, err_data);
if (adev->umc.ras &&
adev->umc.ras->ecc_info_query_ras_error_address)
adev->umc.ras->ecc_info_query_ras_error_address(adev, err_data);
}
}
@ -928,62 +950,32 @@ static void amdgpu_ras_get_ecc_info(struct amdgpu_device *adev, struct ras_err_d
int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
struct ras_query_if *info)
{
struct amdgpu_ras_block_object *block_obj = NULL;
struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head);
struct ras_err_data err_data = {0, 0, 0, NULL};
int i;
if (!obj)
return -EINVAL;
switch (info->head.block) {
case AMDGPU_RAS_BLOCK__UMC:
if (info->head.block == AMDGPU_RAS_BLOCK__UMC) {
amdgpu_ras_get_ecc_info(adev, &err_data);
break;
case AMDGPU_RAS_BLOCK__SDMA:
if (adev->sdma.funcs->query_ras_error_count) {
for (i = 0; i < adev->sdma.num_instances; i++)
adev->sdma.funcs->query_ras_error_count(adev, i,
&err_data);
} else {
block_obj = amdgpu_ras_get_ras_block(adev, info->head.block, 0);
if (!block_obj || !block_obj->hw_ops) {
dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
get_ras_block_str(&info->head));
return -EINVAL;
}
break;
case AMDGPU_RAS_BLOCK__GFX:
if (adev->gfx.ras_funcs &&
adev->gfx.ras_funcs->query_ras_error_count)
adev->gfx.ras_funcs->query_ras_error_count(adev, &err_data);
if (adev->gfx.ras_funcs &&
adev->gfx.ras_funcs->query_ras_error_status)
adev->gfx.ras_funcs->query_ras_error_status(adev);
break;
case AMDGPU_RAS_BLOCK__MMHUB:
if (adev->mmhub.ras_funcs &&
adev->mmhub.ras_funcs->query_ras_error_count)
adev->mmhub.ras_funcs->query_ras_error_count(adev, &err_data);
if (block_obj->hw_ops->query_ras_error_count)
block_obj->hw_ops->query_ras_error_count(adev, &err_data);
if (adev->mmhub.ras_funcs &&
adev->mmhub.ras_funcs->query_ras_error_status)
adev->mmhub.ras_funcs->query_ras_error_status(adev);
break;
case AMDGPU_RAS_BLOCK__PCIE_BIF:
if (adev->nbio.ras_funcs &&
adev->nbio.ras_funcs->query_ras_error_count)
adev->nbio.ras_funcs->query_ras_error_count(adev, &err_data);
break;
case AMDGPU_RAS_BLOCK__XGMI_WAFL:
if (adev->gmc.xgmi.ras_funcs &&
adev->gmc.xgmi.ras_funcs->query_ras_error_count)
adev->gmc.xgmi.ras_funcs->query_ras_error_count(adev, &err_data);
break;
case AMDGPU_RAS_BLOCK__HDP:
if (adev->hdp.ras_funcs &&
adev->hdp.ras_funcs->query_ras_error_count)
adev->hdp.ras_funcs->query_ras_error_count(adev, &err_data);
break;
case AMDGPU_RAS_BLOCK__MCA:
amdgpu_ras_mca_query_error_status(adev, &info->head, &err_data);
break;
default:
break;
if ((info->head.block == AMDGPU_RAS_BLOCK__SDMA) ||
(info->head.block == AMDGPU_RAS_BLOCK__GFX) ||
(info->head.block == AMDGPU_RAS_BLOCK__MMHUB)) {
if (block_obj->hw_ops->query_ras_error_status)
block_obj->hw_ops->query_ras_error_status(adev);
}
}
obj->err_data.ue_count += err_data.ue_count;
@ -1040,70 +1032,29 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
int amdgpu_ras_reset_error_status(struct amdgpu_device *adev,
enum amdgpu_ras_block block)
{
struct amdgpu_ras_block_object *block_obj = amdgpu_ras_get_ras_block(adev, block, 0);
if (!amdgpu_ras_is_supported(adev, block))
return -EINVAL;
switch (block) {
case AMDGPU_RAS_BLOCK__GFX:
if (adev->gfx.ras_funcs &&
adev->gfx.ras_funcs->reset_ras_error_count)
adev->gfx.ras_funcs->reset_ras_error_count(adev);
if (!block_obj || !block_obj->hw_ops) {
dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
ras_block_str(block));
return -EINVAL;
}
if (adev->gfx.ras_funcs &&
adev->gfx.ras_funcs->reset_ras_error_status)
adev->gfx.ras_funcs->reset_ras_error_status(adev);
break;
case AMDGPU_RAS_BLOCK__MMHUB:
if (adev->mmhub.ras_funcs &&
adev->mmhub.ras_funcs->reset_ras_error_count)
adev->mmhub.ras_funcs->reset_ras_error_count(adev);
if (block_obj->hw_ops->reset_ras_error_count)
block_obj->hw_ops->reset_ras_error_count(adev);
if (adev->mmhub.ras_funcs &&
adev->mmhub.ras_funcs->reset_ras_error_status)
adev->mmhub.ras_funcs->reset_ras_error_status(adev);
break;
case AMDGPU_RAS_BLOCK__SDMA:
if (adev->sdma.funcs->reset_ras_error_count)
adev->sdma.funcs->reset_ras_error_count(adev);
break;
case AMDGPU_RAS_BLOCK__HDP:
if (adev->hdp.ras_funcs &&
adev->hdp.ras_funcs->reset_ras_error_count)
adev->hdp.ras_funcs->reset_ras_error_count(adev);
break;
default:
break;
if ((block == AMDGPU_RAS_BLOCK__GFX) ||
(block == AMDGPU_RAS_BLOCK__MMHUB)) {
if (block_obj->hw_ops->reset_ras_error_status)
block_obj->hw_ops->reset_ras_error_status(adev);
}
return 0;
}
/* Trigger XGMI/WAFL error */
static int amdgpu_ras_error_inject_xgmi(struct amdgpu_device *adev,
struct ta_ras_trigger_error_input *block_info)
{
int ret;
if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_DISALLOW))
dev_warn(adev->dev, "Failed to disallow df cstate");
if (amdgpu_dpm_allow_xgmi_power_down(adev, false))
dev_warn(adev->dev, "Failed to disallow XGMI power down");
ret = psp_ras_trigger_error(&adev->psp, block_info);
if (amdgpu_ras_intr_triggered())
return ret;
if (amdgpu_dpm_allow_xgmi_power_down(adev, true))
dev_warn(adev->dev, "Failed to allow XGMI power down");
if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_ALLOW))
dev_warn(adev->dev, "Failed to allow df cstate");
return ret;
}
/* wrapper of psp_ras_trigger_error */
int amdgpu_ras_error_inject(struct amdgpu_device *adev,
struct ras_inject_if *info)
@ -1116,11 +1067,20 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
.address = info->address,
.value = info->value,
};
int ret = 0;
int ret = -EINVAL;
struct amdgpu_ras_block_object *block_obj = amdgpu_ras_get_ras_block(adev,
info->head.block,
info->head.sub_block_index);
if (!obj)
return -EINVAL;
if (!block_obj || !block_obj->hw_ops) {
dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
get_ras_block_str(&info->head));
return -EINVAL;
}
/* Calculate XGMI relative offset */
if (adev->gmc.xgmi.num_physical_nodes > 1) {
block_info.address =
@ -1128,28 +1088,15 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
block_info.address);
}
switch (info->head.block) {
case AMDGPU_RAS_BLOCK__GFX:
if (adev->gfx.ras_funcs &&
adev->gfx.ras_funcs->ras_error_inject)
ret = adev->gfx.ras_funcs->ras_error_inject(adev, info);
else
ret = -EINVAL;
break;
case AMDGPU_RAS_BLOCK__UMC:
case AMDGPU_RAS_BLOCK__SDMA:
case AMDGPU_RAS_BLOCK__MMHUB:
case AMDGPU_RAS_BLOCK__PCIE_BIF:
case AMDGPU_RAS_BLOCK__MCA:
ret = psp_ras_trigger_error(&adev->psp, &block_info);
break;
case AMDGPU_RAS_BLOCK__XGMI_WAFL:
ret = amdgpu_ras_error_inject_xgmi(adev, &block_info);
break;
default:
dev_info(adev->dev, "%s error injection is not supported yet\n",
get_ras_block_str(&info->head));
ret = -EINVAL;
if (info->head.block == AMDGPU_RAS_BLOCK__GFX) {
if (block_obj->hw_ops->ras_error_inject)
ret = block_obj->hw_ops->ras_error_inject(adev, info);
} else {
/* If defined special ras_error_inject(e.g: xgmi), implement special ras_error_inject */
if (block_obj->hw_ops->ras_error_inject)
ret = block_obj->hw_ops->ras_error_inject(adev, &block_info);
else /*If not defined .ras_error_inject, use default ras_error_inject*/
ret = psp_ras_trigger_error(&adev->psp, &block_info);
}
if (ret)
@ -1766,24 +1713,28 @@ static void amdgpu_ras_log_on_err_counter(struct amdgpu_device *adev)
static void amdgpu_ras_error_status_query(struct amdgpu_device *adev,
struct ras_query_if *info)
{
struct amdgpu_ras_block_object *block_obj;
/*
* Only two block need to query read/write
* RspStatus at current state
*/
switch (info->head.block) {
case AMDGPU_RAS_BLOCK__GFX:
if (adev->gfx.ras_funcs &&
adev->gfx.ras_funcs->query_ras_error_status)
adev->gfx.ras_funcs->query_ras_error_status(adev);
break;
case AMDGPU_RAS_BLOCK__MMHUB:
if (adev->mmhub.ras_funcs &&
adev->mmhub.ras_funcs->query_ras_error_status)
adev->mmhub.ras_funcs->query_ras_error_status(adev);
break;
default:
break;
if ((info->head.block != AMDGPU_RAS_BLOCK__GFX) &&
(info->head.block != AMDGPU_RAS_BLOCK__MMHUB))
return;
block_obj = amdgpu_ras_get_ras_block(adev,
info->head.block,
info->head.sub_block_index);
if (!block_obj || !block_obj->hw_ops) {
dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
get_ras_block_str(&info->head));
return;
}
if (block_obj->hw_ops->query_ras_error_status)
block_obj->hw_ops->query_ras_error_status(adev);
}
static void amdgpu_ras_query_err_status(struct amdgpu_device *adev)
@ -2141,8 +2092,7 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev)
if (ret)
goto free;
if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->send_hbm_bad_pages_num)
adev->smu.ppt_funcs->send_hbm_bad_pages_num(&adev->smu, con->eeprom_control.ras_num_recs);
amdgpu_dpm_send_hbm_bad_pages_num(adev, con->eeprom_control.ras_num_recs);
}
#ifdef CONFIG_X86_MCE_AMD
@ -2348,24 +2298,26 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
case CHIP_VEGA20:
case CHIP_ARCTURUS:
case CHIP_ALDEBARAN:
if (!adev->gmc.xgmi.connected_to_cpu)
adev->nbio.ras_funcs = &nbio_v7_4_ras_funcs;
if (!adev->gmc.xgmi.connected_to_cpu) {
adev->nbio.ras = &nbio_v7_4_ras;
amdgpu_ras_register_ras_block(adev, &adev->nbio.ras->ras_block);
}
break;
default:
/* nbio ras is not available */
break;
}
if (adev->nbio.ras_funcs &&
adev->nbio.ras_funcs->init_ras_controller_interrupt) {
r = adev->nbio.ras_funcs->init_ras_controller_interrupt(adev);
if (adev->nbio.ras &&
adev->nbio.ras->init_ras_controller_interrupt) {
r = adev->nbio.ras->init_ras_controller_interrupt(adev);
if (r)
goto release_con;
}
if (adev->nbio.ras_funcs &&
adev->nbio.ras_funcs->init_ras_err_event_athub_interrupt) {
r = adev->nbio.ras_funcs->init_ras_err_event_athub_interrupt(adev);
if (adev->nbio.ras &&
adev->nbio.ras->init_ras_err_event_athub_interrupt) {
r = adev->nbio.ras->init_ras_err_event_athub_interrupt(adev);
if (r)
goto release_con;
}
@ -2377,12 +2329,12 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
}
else if (adev->df.funcs &&
adev->df.funcs->query_ras_poison_mode &&
adev->umc.ras_funcs &&
adev->umc.ras_funcs->query_ras_poison_mode) {
adev->umc.ras &&
adev->umc.ras->query_ras_poison_mode) {
df_poison =
adev->df.funcs->query_ras_poison_mode(adev);
umc_poison =
adev->umc.ras_funcs->query_ras_poison_mode(adev);
adev->umc.ras->query_ras_poison_mode(adev);
/* Only poison is set in both DF and UMC, we can support it */
if (df_poison && umc_poison)
con->poison_supported = true;
@ -2585,6 +2537,7 @@ int amdgpu_ras_pre_fini(struct amdgpu_device *adev)
int amdgpu_ras_fini(struct amdgpu_device *adev)
{
struct amdgpu_ras_block_list *ras_node, *tmp;
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
if (!adev->ras_enabled || !con)
@ -2603,6 +2556,12 @@ int amdgpu_ras_fini(struct amdgpu_device *adev)
amdgpu_ras_set_context(adev, NULL);
kfree(con);
/* Clear ras blocks from ras_list and free ras block list node */
list_for_each_entry_safe(ras_node, tmp, &adev->ras_list, node) {
list_del(&ras_node->node);
kfree(ras_node);
}
return 0;
}
@ -2717,8 +2676,6 @@ static int amdgpu_bad_page_notifier(struct notifier_block *nb,
dev_info(adev->dev, "Uncorrectable error detected in UMC inst: %d, chan_idx: %d",
umc_inst, ch_inst);
memset(&err_rec, 0x0, sizeof(struct eeprom_table_record));
/*
* Translate UMC channel address to Physical address
*/
@ -2730,16 +2687,10 @@ static int amdgpu_bad_page_notifier(struct notifier_block *nb,
ADDR_OF_256B_BLOCK(channel_index) |
OFFSET_IN_256B_BLOCK(m->addr);
err_rec.address = m->addr;
err_rec.retired_page = retired_page >> AMDGPU_GPU_PAGE_SHIFT;
err_rec.ts = (uint64_t)ktime_get_real_seconds();
err_rec.err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE;
err_rec.cu = 0;
err_rec.mem_channel = channel_index;
err_rec.mcumc_id = umc_inst;
memset(&err_rec, 0x0, sizeof(struct eeprom_table_record));
err_data.err_addr = &err_rec;
err_data.err_addr_cnt = 1;
amdgpu_umc_fill_error_record(&err_data, m->addr,
retired_page, channel_index, umc_inst);
if (amdgpu_bad_page_threshold != 0) {
amdgpu_ras_add_bad_pages(adev, err_data.err_addr,
@ -2777,3 +2728,63 @@ static void amdgpu_register_bad_pages_mca_notifier(struct amdgpu_device *adev)
}
}
#endif
struct amdgpu_ras *amdgpu_ras_get_context(struct amdgpu_device *adev)
{
if (!adev)
return NULL;
return adev->psp.ras_context.ras;
}
int amdgpu_ras_set_context(struct amdgpu_device *adev, struct amdgpu_ras *ras_con)
{
if (!adev)
return -EINVAL;
adev->psp.ras_context.ras = ras_con;
return 0;
}
/* check if ras is supported on block, say, sdma, gfx */
int amdgpu_ras_is_supported(struct amdgpu_device *adev,
unsigned int block)
{
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
if (block >= AMDGPU_RAS_BLOCK_COUNT)
return 0;
return ras && (adev->ras_enabled & (1 << block));
}
int amdgpu_ras_reset_gpu(struct amdgpu_device *adev)
{
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
if (atomic_cmpxchg(&ras->in_recovery, 0, 1) == 0)
schedule_work(&ras->recovery_work);
return 0;
}
/* Register each ip ras block into amdgpu ras */
int amdgpu_ras_register_ras_block(struct amdgpu_device *adev,
struct amdgpu_ras_block_object *ras_block_obj)
{
struct amdgpu_ras_block_list *ras_node;
if (!adev || !ras_block_obj)
return -EINVAL;
if (!amdgpu_ras_asic_supported(adev))
return 0;
ras_node = kzalloc(sizeof(*ras_node), GFP_KERNEL);
if (!ras_node)
return -ENOMEM;
INIT_LIST_HEAD(&ras_node->node);
ras_node->ras_obj = ras_block_obj;
list_add_tail(&ras_node->node, &adev->ras_list);
return 0;
}

View File

@ -26,11 +26,11 @@
#include <linux/debugfs.h>
#include <linux/list.h>
#include "amdgpu.h"
#include "amdgpu_psp.h"
#include "ta_ras_if.h"
#include "amdgpu_ras_eeprom.h"
struct amdgpu_iv_entry;
#define AMDGPU_RAS_FLAG_INIT_BY_VBIOS (0x1 << 0)
enum amdgpu_ras_block {
@ -484,6 +484,31 @@ struct ras_debug_if {
};
int op;
};
struct amdgpu_ras_block_object {
/* block name */
char name[32];
enum amdgpu_ras_block block;
uint32_t sub_block_index;
int (*ras_block_match)(struct amdgpu_ras_block_object *block_obj,
enum amdgpu_ras_block block, uint32_t sub_block_index);
int (*ras_late_init)(struct amdgpu_device *adev, void *ras_info);
void (*ras_fini)(struct amdgpu_device *adev);
const struct amdgpu_ras_block_hw_ops *hw_ops;
};
struct amdgpu_ras_block_hw_ops {
int (*ras_error_inject)(struct amdgpu_device *adev, void *inject_if);
void (*query_ras_error_count)(struct amdgpu_device *adev, void *ras_error_status);
void (*query_ras_error_status)(struct amdgpu_device *adev);
void (*query_ras_error_address)(struct amdgpu_device *adev, void *ras_error_status);
void (*reset_ras_error_count)(struct amdgpu_device *adev);
void (*reset_ras_error_status)(struct amdgpu_device *adev);
};
/* work flow
* vbios
* 1: ras feature enable (enabled by default)
@ -498,19 +523,6 @@ struct ras_debug_if {
* 8: feature disable
*/
#define amdgpu_ras_get_context(adev) ((adev)->psp.ras_context.ras)
#define amdgpu_ras_set_context(adev, ras_con) ((adev)->psp.ras_context.ras = (ras_con))
/* check if ras is supported on block, say, sdma, gfx */
static inline int amdgpu_ras_is_supported(struct amdgpu_device *adev,
unsigned int block)
{
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
if (block >= AMDGPU_RAS_BLOCK_COUNT)
return 0;
return ras && (adev->ras_enabled & (1 << block));
}
int amdgpu_ras_recovery_init(struct amdgpu_device *adev);
@ -527,15 +539,6 @@ int amdgpu_ras_add_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);
if (atomic_cmpxchg(&ras->in_recovery, 0, 1) == 0)
schedule_work(&ras->recovery_work);
return 0;
}
static inline enum ta_ras_block
amdgpu_ras_block_to_ta(enum amdgpu_ras_block block) {
switch (block) {
@ -667,4 +670,14 @@ const char *get_ras_block_str(struct ras_common_if *ras_block);
bool amdgpu_ras_is_poison_mode_supported(struct amdgpu_device *adev);
int amdgpu_ras_is_supported(struct amdgpu_device *adev, unsigned int block);
int amdgpu_ras_reset_gpu(struct amdgpu_device *adev);
struct amdgpu_ras* amdgpu_ras_get_context(struct amdgpu_device *adev);
int amdgpu_ras_set_context(struct amdgpu_device *adev, struct amdgpu_ras *ras_con);
int amdgpu_ras_register_ras_block(struct amdgpu_device *adev,
struct amdgpu_ras_block_object *ras_block_obj);
#endif

View File

@ -194,7 +194,7 @@ static int __write_table_header(struct amdgpu_ras_eeprom_control *control)
/* i2c may be unstable in gpu reset */
down_read(&adev->reset_sem);
res = amdgpu_eeprom_write(&adev->pm.smu_i2c,
res = amdgpu_eeprom_write(adev->pm.ras_eeprom_i2c_bus,
control->i2c_address +
control->ras_header_offset,
buf, RAS_TABLE_HEADER_SIZE);
@ -263,6 +263,7 @@ static int amdgpu_ras_eeprom_correct_header_tag(
*/
int amdgpu_ras_eeprom_reset_table(struct amdgpu_ras_eeprom_control *control)
{
struct amdgpu_device *adev = to_amdgpu_device(control);
struct amdgpu_ras_eeprom_table_header *hdr = &control->tbl_hdr;
u8 csum;
int res;
@ -282,6 +283,8 @@ int amdgpu_ras_eeprom_reset_table(struct amdgpu_ras_eeprom_control *control)
control->ras_num_recs = 0;
control->ras_fri = 0;
amdgpu_dpm_send_hbm_bad_pages_num(adev, control->ras_num_recs);
amdgpu_ras_debugfs_set_ret_size(control);
mutex_unlock(&control->ras_tbl_mutex);
@ -389,7 +392,7 @@ static int __amdgpu_ras_eeprom_write(struct amdgpu_ras_eeprom_control *control,
/* i2c may be unstable in gpu reset */
down_read(&adev->reset_sem);
buf_size = num * RAS_TABLE_RECORD_SIZE;
res = amdgpu_eeprom_write(&adev->pm.smu_i2c,
res = amdgpu_eeprom_write(adev->pm.ras_eeprom_i2c_bus,
control->i2c_address +
RAS_INDEX_TO_OFFSET(control, fri),
buf, buf_size);
@ -548,7 +551,7 @@ amdgpu_ras_eeprom_update_header(struct amdgpu_ras_eeprom_control *control)
}
down_read(&adev->reset_sem);
res = amdgpu_eeprom_read(&adev->pm.smu_i2c,
res = amdgpu_eeprom_read(adev->pm.ras_eeprom_i2c_bus,
control->i2c_address +
control->ras_record_offset,
buf, buf_size);
@ -644,7 +647,7 @@ static int __amdgpu_ras_eeprom_read(struct amdgpu_ras_eeprom_control *control,
/* i2c may be unstable in gpu reset */
down_read(&adev->reset_sem);
buf_size = num * RAS_TABLE_RECORD_SIZE;
res = amdgpu_eeprom_read(&adev->pm.smu_i2c,
res = amdgpu_eeprom_read(adev->pm.ras_eeprom_i2c_bus,
control->i2c_address +
RAS_INDEX_TO_OFFSET(control, fri),
buf, buf_size);
@ -1009,7 +1012,7 @@ static int __verify_ras_table_checksum(struct amdgpu_ras_eeprom_control *control
return -ENOMEM;
}
res = amdgpu_eeprom_read(&adev->pm.smu_i2c,
res = amdgpu_eeprom_read(adev->pm.ras_eeprom_i2c_bus,
control->i2c_address +
control->ras_header_offset,
buf, buf_size);
@ -1045,7 +1048,7 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control,
return 0;
/* Verify i2c adapter is initialized */
if (!adev->pm.smu_i2c.algo)
if (!adev->pm.ras_eeprom_i2c_bus || !adev->pm.ras_eeprom_i2c_bus->algo)
return -ENOENT;
if (!__get_eeprom_i2c_addr(adev, control))
@ -1057,7 +1060,7 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control,
mutex_init(&control->ras_tbl_mutex);
/* Read the table header from EEPROM address */
res = amdgpu_eeprom_read(&adev->pm.smu_i2c,
res = amdgpu_eeprom_read(adev->pm.ras_eeprom_i2c_bus,
control->i2c_address + control->ras_header_offset,
buf, RAS_TABLE_HEADER_SIZE);
if (res < RAS_TABLE_HEADER_SIZE) {

View File

@ -127,11 +127,19 @@ struct amdgpu_rlc_funcs {
void (*reset)(struct amdgpu_device *adev);
void (*start)(struct amdgpu_device *adev);
void (*update_spm_vmid)(struct amdgpu_device *adev, unsigned vmid);
void (*sriov_wreg)(struct amdgpu_device *adev, u32 offset, u32 v, u32 acc_flags, u32 hwip);
u32 (*sriov_rreg)(struct amdgpu_device *adev, u32 offset, u32 acc_flags, u32 hwip);
bool (*is_rlcg_access_range)(struct amdgpu_device *adev, uint32_t reg);
};
struct amdgpu_rlcg_reg_access_ctrl {
uint32_t scratch_reg0;
uint32_t scratch_reg1;
uint32_t scratch_reg2;
uint32_t scratch_reg3;
uint32_t grbm_cntl;
uint32_t grbm_idx;
uint32_t spare_int;
};
struct amdgpu_rlc {
/* for power gating */
struct amdgpu_bo *save_restore_obj;
@ -191,6 +199,10 @@ struct amdgpu_rlc {
struct amdgpu_bo *rlc_toc_bo;
uint64_t rlc_toc_gpu_addr;
void *rlc_toc_buf;
bool rlcg_reg_access_supported;
/* registers for rlcg indirect reg access */
struct amdgpu_rlcg_reg_access_ctrl reg_access_ctrl;
};
void amdgpu_gfx_rlc_enter_safe_mode(struct amdgpu_device *adev);

View File

@ -23,6 +23,7 @@
#ifndef __AMDGPU_SDMA_H__
#define __AMDGPU_SDMA_H__
#include "amdgpu_ras.h"
/* max number of IP instances */
#define AMDGPU_MAX_SDMA_INSTANCES 8
@ -50,13 +51,8 @@ struct amdgpu_sdma_instance {
bool burst_nop;
};
struct amdgpu_sdma_ras_funcs {
int (*ras_late_init)(struct amdgpu_device *adev,
void *ras_ih_info);
void (*ras_fini)(struct amdgpu_device *adev);
int (*query_ras_error_count)(struct amdgpu_device *adev,
uint32_t instance, void *ras_error_status);
void (*reset_ras_error_count)(struct amdgpu_device *adev);
struct amdgpu_sdma_ras {
struct amdgpu_ras_block_object ras_block;
};
struct amdgpu_sdma {
@ -73,7 +69,7 @@ struct amdgpu_sdma {
uint32_t srbm_soft_reset;
bool has_page_queue;
struct ras_common_if *ras_if;
const struct amdgpu_sdma_ras_funcs *funcs;
struct amdgpu_sdma_ras *ras;
};
/*

View File

@ -358,11 +358,10 @@ TRACE_EVENT(amdgpu_vm_update_ptes,
}
),
TP_printk("pid:%u vm_ctx:0x%llx start:0x%010llx end:0x%010llx,"
" flags:0x%llx, incr:%llu, dst:\n%s%s", __entry->pid,
" flags:0x%llx, incr:%llu, dst:\n%s", __entry->pid,
__entry->vm_ctx, __entry->start, __entry->end,
__entry->flags, __entry->incr, __print_array(
__get_dynamic_array(dst), min(__entry->nptes, 32u), 8),
__entry->nptes > 32 ? "..." : "")
__get_dynamic_array(dst), __entry->nptes, 8))
);
TRACE_EVENT(amdgpu_vm_set_ptes,

View File

@ -50,6 +50,7 @@
#include <drm/ttm/ttm_range_manager.h>
#include <drm/amdgpu_drm.h>
#include <drm/drm_drv.h>
#include "amdgpu.h"
#include "amdgpu_object.h"
@ -170,10 +171,10 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
* @bo: buffer object to map
* @mem: memory object to map
* @mm_cur: range to map
* @num_pages: number of pages to map
* @window: which GART window to use
* @ring: DMA ring to use for the copy
* @tmz: if we should setup a TMZ enabled mapping
* @size: in number of bytes to map, out number of bytes mapped
* @addr: resulting address inside the MC address space
*
* Setup one of the GART windows to access a specific piece of memory or return
@ -182,15 +183,14 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
struct ttm_resource *mem,
struct amdgpu_res_cursor *mm_cur,
unsigned num_pages, unsigned window,
struct amdgpu_ring *ring, bool tmz,
uint64_t *addr)
unsigned window, struct amdgpu_ring *ring,
bool tmz, uint64_t *size, uint64_t *addr)
{
struct amdgpu_device *adev = ring->adev;
struct amdgpu_job *job;
unsigned num_dw, num_bytes;
struct dma_fence *fence;
unsigned offset, num_pages, num_dw, num_bytes;
uint64_t src_addr, dst_addr;
struct dma_fence *fence;
struct amdgpu_job *job;
void *cpu_addr;
uint64_t flags;
unsigned int i;
@ -198,7 +198,9 @@ static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
BUG_ON(adev->mman.buffer_funcs->copy_max_bytes <
AMDGPU_GTT_MAX_TRANSFER_SIZE * 8);
BUG_ON(mem->mem_type == AMDGPU_PL_PREEMPT);
if (WARN_ON(mem->mem_type == AMDGPU_PL_PREEMPT))
return -EINVAL;
/* Map only what can't be accessed directly */
if (!tmz && mem->start != AMDGPU_BO_INVALID_OFFSET) {
@ -207,10 +209,22 @@ static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
return 0;
}
/*
* If start begins at an offset inside the page, then adjust the size
* and addr accordingly
*/
offset = mm_cur->start & ~PAGE_MASK;
num_pages = PFN_UP(*size + offset);
num_pages = min_t(uint32_t, num_pages, AMDGPU_GTT_MAX_TRANSFER_SIZE);
*size = min(*size, (uint64_t)num_pages * PAGE_SIZE - offset);
*addr = adev->gmc.gart_start;
*addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE *
AMDGPU_GPU_PAGE_SIZE;
*addr += mm_cur->start & ~PAGE_MASK;
*addr += offset;
num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
num_bytes = num_pages * 8 * AMDGPU_GPU_PAGES_IN_CPU_PAGE;
@ -241,10 +255,7 @@ static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
dma_addr_t *dma_addr;
dma_addr = &bo->ttm->dma_address[mm_cur->start >> PAGE_SHIFT];
r = amdgpu_gart_map(adev, 0, num_pages, dma_addr, flags,
cpu_addr);
if (r)
goto error_free;
amdgpu_gart_map(adev, 0, num_pages, dma_addr, flags, cpu_addr);
} else {
dma_addr_t dma_address;
@ -252,11 +263,8 @@ static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
dma_address += adev->vm_manager.vram_base_offset;
for (i = 0; i < num_pages; ++i) {
r = amdgpu_gart_map(adev, i << PAGE_SHIFT, 1,
&dma_address, flags, cpu_addr);
if (r)
goto error_free;
amdgpu_gart_map(adev, i << PAGE_SHIFT, 1, &dma_address,
flags, cpu_addr);
dma_address += PAGE_SIZE;
}
}
@ -297,9 +305,6 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
struct dma_resv *resv,
struct dma_fence **f)
{
const uint32_t GTT_MAX_BYTES = (AMDGPU_GTT_MAX_TRANSFER_SIZE *
AMDGPU_GPU_PAGE_SIZE);
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
struct amdgpu_res_cursor src_mm, dst_mm;
struct dma_fence *fence = NULL;
@ -315,29 +320,20 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
mutex_lock(&adev->mman.gtt_window_lock);
while (src_mm.remaining) {
uint32_t src_page_offset = src_mm.start & ~PAGE_MASK;
uint32_t dst_page_offset = dst_mm.start & ~PAGE_MASK;
uint64_t from, to, cur_size;
struct dma_fence *next;
uint32_t cur_size;
uint64_t from, to;
/* Copy size cannot exceed GTT_MAX_BYTES. So if src or dst
* begins at an offset, then adjust the size accordingly
*/
cur_size = max(src_page_offset, dst_page_offset);
cur_size = min(min3(src_mm.size, dst_mm.size, size),
(uint64_t)(GTT_MAX_BYTES - cur_size));
/* Never copy more than 256MiB at once to avoid a timeout */
cur_size = min3(src_mm.size, dst_mm.size, 256ULL << 20);
/* Map src to window 0 and dst to window 1. */
r = amdgpu_ttm_map_buffer(src->bo, src->mem, &src_mm,
PFN_UP(cur_size + src_page_offset),
0, ring, tmz, &from);
0, ring, tmz, &cur_size, &from);
if (r)
goto error;
r = amdgpu_ttm_map_buffer(dst->bo, dst->mem, &dst_mm,
PFN_UP(cur_size + dst_page_offset),
1, ring, tmz, &to);
1, ring, tmz, &cur_size, &to);
if (r)
goto error;
@ -396,8 +392,7 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
struct dma_fence *wipe_fence = NULL;
r = amdgpu_fill_buffer(ttm_to_amdgpu_bo(bo), AMDGPU_POISON,
NULL, &wipe_fence);
r = amdgpu_fill_buffer(abo, AMDGPU_POISON, NULL, &wipe_fence);
if (r) {
goto error;
} else if (wipe_fence) {
@ -821,14 +816,13 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_device *bdev,
#endif
}
static int amdgpu_ttm_gart_bind(struct amdgpu_device *adev,
struct ttm_buffer_object *tbo,
uint64_t flags)
static void amdgpu_ttm_gart_bind(struct amdgpu_device *adev,
struct ttm_buffer_object *tbo,
uint64_t flags)
{
struct amdgpu_bo *abo = ttm_to_amdgpu_bo(tbo);
struct ttm_tt *ttm = tbo->ttm;
struct amdgpu_ttm_tt *gtt = (void *)ttm;
int r;
if (amdgpu_bo_encrypted(abo))
flags |= AMDGPU_PTE_TMZ;
@ -836,10 +830,8 @@ static int amdgpu_ttm_gart_bind(struct amdgpu_device *adev,
if (abo->flags & AMDGPU_GEM_CREATE_CP_MQD_GFX9) {
uint64_t page_idx = 1;
r = amdgpu_gart_bind(adev, gtt->offset, page_idx,
gtt->ttm.dma_address, flags);
if (r)
goto gart_bind_fail;
amdgpu_gart_bind(adev, gtt->offset, page_idx,
gtt->ttm.dma_address, flags);
/* The memory type of the first page defaults to UC. Now
* modify the memory type to NC from the second page of
@ -848,21 +840,13 @@ static int amdgpu_ttm_gart_bind(struct amdgpu_device *adev,
flags &= ~AMDGPU_PTE_MTYPE_VG10_MASK;
flags |= AMDGPU_PTE_MTYPE_VG10(AMDGPU_MTYPE_NC);
r = amdgpu_gart_bind(adev,
gtt->offset + (page_idx << PAGE_SHIFT),
ttm->num_pages - page_idx,
&(gtt->ttm.dma_address[page_idx]), flags);
amdgpu_gart_bind(adev, gtt->offset + (page_idx << PAGE_SHIFT),
ttm->num_pages - page_idx,
&(gtt->ttm.dma_address[page_idx]), flags);
} else {
r = amdgpu_gart_bind(adev, gtt->offset, ttm->num_pages,
gtt->ttm.dma_address, flags);
amdgpu_gart_bind(adev, gtt->offset, ttm->num_pages,
gtt->ttm.dma_address, flags);
}
gart_bind_fail:
if (r)
DRM_ERROR("failed to bind %u pages at 0x%08llX\n",
ttm->num_pages, gtt->offset);
return r;
}
/*
@ -878,7 +862,7 @@ static int amdgpu_ttm_backend_bind(struct ttm_device *bdev,
struct amdgpu_device *adev = amdgpu_ttm_adev(bdev);
struct amdgpu_ttm_tt *gtt = (void*)ttm;
uint64_t flags;
int r = 0;
int r;
if (!bo_mem)
return -EINVAL;
@ -925,14 +909,10 @@ static int amdgpu_ttm_backend_bind(struct ttm_device *bdev,
/* bind pages into GART page tables */
gtt->offset = (u64)bo_mem->start << PAGE_SHIFT;
r = amdgpu_gart_bind(adev, gtt->offset, ttm->num_pages,
gtt->ttm.dma_address, flags);
if (r)
DRM_ERROR("failed to bind %u pages at 0x%08llX\n",
ttm->num_pages, gtt->offset);
amdgpu_gart_bind(adev, gtt->offset, ttm->num_pages,
gtt->ttm.dma_address, flags);
gtt->bound = true;
return r;
return 0;
}
/*
@ -982,12 +962,7 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)
/* Bind pages */
gtt->offset = (u64)tmp->start << PAGE_SHIFT;
r = amdgpu_ttm_gart_bind(adev, bo, flags);
if (unlikely(r)) {
ttm_resource_free(bo, &tmp);
return r;
}
amdgpu_ttm_gart_bind(adev, bo, flags);
amdgpu_gart_invalidate_tlb(adev);
ttm_resource_free(bo, &bo->resource);
ttm_bo_assign_mem(bo, tmp);
@ -1001,19 +976,16 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)
* Called by amdgpu_gtt_mgr_recover() from amdgpu_device_reset() to
* rebind GTT pages during a GPU reset.
*/
int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo)
void amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev);
uint64_t flags;
int r;
if (!tbo->ttm)
return 0;
return;
flags = amdgpu_ttm_tt_pte_flags(adev, tbo->ttm, tbo->resource);
r = amdgpu_ttm_gart_bind(adev, tbo, flags);
return r;
amdgpu_ttm_gart_bind(adev, tbo, flags);
}
/*
@ -1027,7 +999,6 @@ static void amdgpu_ttm_backend_unbind(struct ttm_device *bdev,
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bdev);
struct amdgpu_ttm_tt *gtt = (void *)ttm;
int r;
/* if the pages have userptr pinning then clear that first */
if (gtt->userptr) {
@ -1047,10 +1018,7 @@ static void amdgpu_ttm_backend_unbind(struct ttm_device *bdev,
return;
/* unbind shouldn't be done for GDS/GWS/OA in ttm_bo_clean_mm */
r = amdgpu_gart_unbind(adev, gtt->offset, ttm->num_pages);
if (r)
DRM_ERROR("failed to unbind %u pages at 0x%08llX\n",
gtt->ttm.num_pages, gtt->offset);
amdgpu_gart_unbind(adev, gtt->offset, ttm->num_pages);
gtt->bound = false;
}
@ -1168,6 +1136,26 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev,
return ttm_pool_free(&adev->mman.bdev.pool, ttm);
}
/**
* amdgpu_ttm_tt_get_userptr - Return the userptr GTT ttm_tt for the current
* task
*
* @tbo: The ttm_buffer_object that contains the userptr
* @user_addr: The returned value
*/
int amdgpu_ttm_tt_get_userptr(const struct ttm_buffer_object *tbo,
uint64_t *user_addr)
{
struct amdgpu_ttm_tt *gtt;
if (!tbo->ttm)
return -EINVAL;
gtt = (void *)tbo->ttm;
*user_addr = gtt->userptr;
return 0;
}
/**
* amdgpu_ttm_tt_set_userptr - Initialize userptr GTT ttm_tt for the current
* task
@ -1433,6 +1421,63 @@ static void amdgpu_ttm_vram_mm_access(struct amdgpu_device *adev, loff_t pos,
}
}
static int amdgpu_ttm_access_memory_sdma(struct ttm_buffer_object *bo,
unsigned long offset, void *buf, int len, int write)
{
struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo);
struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev);
struct amdgpu_res_cursor src_mm;
struct amdgpu_job *job;
struct dma_fence *fence;
uint64_t src_addr, dst_addr;
unsigned int num_dw;
int r, idx;
if (len != PAGE_SIZE)
return -EINVAL;
if (!adev->mman.sdma_access_ptr)
return -EACCES;
if (!drm_dev_enter(adev_to_drm(adev), &idx))
return -ENODEV;
if (write)
memcpy(adev->mman.sdma_access_ptr, buf, len);
num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, AMDGPU_IB_POOL_DELAYED, &job);
if (r)
goto out;
amdgpu_res_first(abo->tbo.resource, offset, len, &src_mm);
src_addr = amdgpu_ttm_domain_start(adev, bo->resource->mem_type) + src_mm.start;
dst_addr = amdgpu_bo_gpu_offset(adev->mman.sdma_access_bo);
if (write)
swap(src_addr, dst_addr);
amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr, dst_addr, PAGE_SIZE, false);
amdgpu_ring_pad_ib(adev->mman.buffer_funcs_ring, &job->ibs[0]);
WARN_ON(job->ibs[0].length_dw > num_dw);
r = amdgpu_job_submit(job, &adev->mman.entity, AMDGPU_FENCE_OWNER_UNDEFINED, &fence);
if (r) {
amdgpu_job_free(job);
goto out;
}
if (!dma_fence_wait_timeout(fence, false, adev->sdma_timeout))
r = -ETIMEDOUT;
dma_fence_put(fence);
if (!(r || write))
memcpy(buf, adev->mman.sdma_access_ptr, len);
out:
drm_dev_exit(idx);
return r;
}
/**
* amdgpu_ttm_access_memory - Read or Write memory that backs a buffer object.
*
@ -1457,6 +1502,10 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo,
if (bo->resource->mem_type != TTM_PL_VRAM)
return -EIO;
if (amdgpu_device_has_timeouts_enabled(adev) &&
!amdgpu_ttm_access_memory_sdma(bo, offset, buf, len, write))
return len;
amdgpu_res_first(bo->resource, offset, len, &cursor);
while (cursor.remaining) {
size_t count, size = cursor.size;
@ -1797,6 +1846,12 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
return r;
}
if (amdgpu_bo_create_kernel(adev, PAGE_SIZE, PAGE_SIZE,
AMDGPU_GEM_DOMAIN_GTT,
&adev->mman.sdma_access_bo, NULL,
&adev->mman.sdma_access_ptr))
DRM_WARN("Debug VRAM access will use slowpath MM access\n");
return 0;
}
@ -1818,6 +1873,8 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
if (adev->mman.stolen_reserved_size)
amdgpu_bo_free_kernel(&adev->mman.stolen_reserved_memory,
NULL, NULL);
amdgpu_bo_free_kernel(&adev->mman.sdma_access_bo, NULL,
&adev->mman.sdma_access_ptr);
amdgpu_ttm_fw_reserve_vram_fini(adev);
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
@ -1888,23 +1945,55 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
adev->mman.buffer_funcs_enabled = enable;
}
static int amdgpu_ttm_prepare_job(struct amdgpu_device *adev,
bool direct_submit,
unsigned int num_dw,
struct dma_resv *resv,
bool vm_needs_flush,
struct amdgpu_job **job)
{
enum amdgpu_ib_pool_type pool = direct_submit ?
AMDGPU_IB_POOL_DIRECT :
AMDGPU_IB_POOL_DELAYED;
int r;
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, pool, job);
if (r)
return r;
if (vm_needs_flush) {
(*job)->vm_pd_addr = amdgpu_gmc_pd_addr(adev->gmc.pdb0_bo ?
adev->gmc.pdb0_bo :
adev->gart.bo);
(*job)->vm_needs_flush = true;
}
if (resv) {
r = amdgpu_sync_resv(adev, &(*job)->sync, resv,
AMDGPU_SYNC_ALWAYS,
AMDGPU_FENCE_OWNER_UNDEFINED);
if (r) {
DRM_ERROR("sync failed (%d).\n", r);
amdgpu_job_free(*job);
return r;
}
}
return 0;
}
int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
uint64_t dst_offset, uint32_t byte_count,
struct dma_resv *resv,
struct dma_fence **fence, bool direct_submit,
bool vm_needs_flush, bool tmz)
{
enum amdgpu_ib_pool_type pool = direct_submit ? AMDGPU_IB_POOL_DIRECT :
AMDGPU_IB_POOL_DELAYED;
struct amdgpu_device *adev = ring->adev;
struct amdgpu_job *job;
uint32_t max_bytes;
unsigned num_loops, num_dw;
struct amdgpu_job *job;
uint32_t max_bytes;
unsigned i;
int r;
if (direct_submit && !ring->sched.ready) {
if (!direct_submit && !ring->sched.ready) {
DRM_ERROR("Trying to move memory with ring turned off.\n");
return -EINVAL;
}
@ -1912,26 +2001,11 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
max_bytes = adev->mman.buffer_funcs->copy_max_bytes;
num_loops = DIV_ROUND_UP(byte_count, max_bytes);
num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->copy_num_dw, 8);
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, pool, &job);
r = amdgpu_ttm_prepare_job(adev, direct_submit, num_dw,
resv, vm_needs_flush, &job);
if (r)
return r;
if (vm_needs_flush) {
job->vm_pd_addr = amdgpu_gmc_pd_addr(adev->gmc.pdb0_bo ?
adev->gmc.pdb0_bo : adev->gart.bo);
job->vm_needs_flush = true;
}
if (resv) {
r = amdgpu_sync_resv(adev, &job->sync, resv,
AMDGPU_SYNC_ALWAYS,
AMDGPU_FENCE_OWNER_UNDEFINED);
if (r) {
DRM_ERROR("sync failed (%d).\n", r);
goto error_free;
}
}
for (i = 0; i < num_loops; i++) {
uint32_t cur_size_in_bytes = min(byte_count, max_bytes);
@ -1961,77 +2035,35 @@ error_free:
return r;
}
int amdgpu_fill_buffer(struct amdgpu_bo *bo,
uint32_t src_data,
struct dma_resv *resv,
struct dma_fence **fence)
static int amdgpu_ttm_fill_mem(struct amdgpu_ring *ring, uint32_t src_data,
uint64_t dst_addr, uint32_t byte_count,
struct dma_resv *resv,
struct dma_fence **fence,
bool vm_needs_flush)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
uint32_t max_bytes = adev->mman.buffer_funcs->fill_max_bytes;
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
struct amdgpu_res_cursor cursor;
struct amdgpu_device *adev = ring->adev;
unsigned int num_loops, num_dw;
uint64_t num_bytes;
struct amdgpu_job *job;
uint32_t max_bytes;
unsigned int i;
int r;
if (!adev->mman.buffer_funcs_enabled) {
DRM_ERROR("Trying to clear memory with ring turned off.\n");
return -EINVAL;
}
if (bo->tbo.resource->mem_type == AMDGPU_PL_PREEMPT) {
DRM_ERROR("Trying to clear preemptible memory.\n");
return -EINVAL;
}
if (bo->tbo.resource->mem_type == TTM_PL_TT) {
r = amdgpu_ttm_alloc_gart(&bo->tbo);
if (r)
return r;
}
num_bytes = bo->tbo.resource->num_pages << PAGE_SHIFT;
num_loops = 0;
amdgpu_res_first(bo->tbo.resource, 0, num_bytes, &cursor);
while (cursor.remaining) {
num_loops += DIV_ROUND_UP_ULL(cursor.size, max_bytes);
amdgpu_res_next(&cursor, cursor.size);
}
num_dw = num_loops * adev->mman.buffer_funcs->fill_num_dw;
/* for IB padding */
num_dw += 64;
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, AMDGPU_IB_POOL_DELAYED,
&job);
max_bytes = adev->mman.buffer_funcs->fill_max_bytes;
num_loops = DIV_ROUND_UP_ULL(byte_count, max_bytes);
num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->fill_num_dw, 8);
r = amdgpu_ttm_prepare_job(adev, false, num_dw, resv, vm_needs_flush,
&job);
if (r)
return r;
if (resv) {
r = amdgpu_sync_resv(adev, &job->sync, resv,
AMDGPU_SYNC_ALWAYS,
AMDGPU_FENCE_OWNER_UNDEFINED);
if (r) {
DRM_ERROR("sync failed (%d).\n", r);
goto error_free;
}
}
for (i = 0; i < num_loops; i++) {
uint32_t cur_size = min(byte_count, max_bytes);
amdgpu_res_first(bo->tbo.resource, 0, num_bytes, &cursor);
while (cursor.remaining) {
uint32_t cur_size = min_t(uint64_t, cursor.size, max_bytes);
uint64_t dst_addr = cursor.start;
dst_addr += amdgpu_ttm_domain_start(adev,
bo->tbo.resource->mem_type);
amdgpu_emit_fill_buffer(adev, &job->ibs[0], src_data, dst_addr,
cur_size);
amdgpu_res_next(&cursor, cur_size);
dst_addr += cur_size;
byte_count -= cur_size;
}
amdgpu_ring_pad_ib(ring, &job->ibs[0]);
@ -2048,6 +2080,55 @@ error_free:
return r;
}
int amdgpu_fill_buffer(struct amdgpu_bo *bo,
uint32_t src_data,
struct dma_resv *resv,
struct dma_fence **f)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
struct dma_fence *fence = NULL;
struct amdgpu_res_cursor dst;
int r;
if (!adev->mman.buffer_funcs_enabled) {
DRM_ERROR("Trying to clear memory with ring turned off.\n");
return -EINVAL;
}
amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &dst);
mutex_lock(&adev->mman.gtt_window_lock);
while (dst.remaining) {
struct dma_fence *next;
uint64_t cur_size, to;
/* Never fill more than 256MiB at once to avoid timeouts */
cur_size = min(dst.size, 256ULL << 20);
r = amdgpu_ttm_map_buffer(&bo->tbo, bo->tbo.resource, &dst,
1, ring, false, &cur_size, &to);
if (r)
goto error;
r = amdgpu_ttm_fill_mem(ring, src_data, to, cur_size, resv,
&next, true);
if (r)
goto error;
dma_fence_put(fence);
fence = next;
amdgpu_res_next(&dst, cur_size);
}
error:
mutex_unlock(&adev->mman.gtt_window_lock);
if (f)
*f = dma_fence_get(fence);
dma_fence_put(fence);
return r;
}
/**
* amdgpu_ttm_evict_resources - evict memory buffers
* @adev: amdgpu device object

View File

@ -98,6 +98,10 @@ struct amdgpu_mman {
u64 fw_vram_usage_size;
struct amdgpu_bo *fw_vram_usage_reserved_bo;
void *fw_vram_usage_va;
/* PAGE_SIZE'd BO for process memory r/w over SDMA. */
struct amdgpu_bo *sdma_access_bo;
void *sdma_access_ptr;
};
struct amdgpu_copy_mem {
@ -115,7 +119,7 @@ void amdgpu_vram_mgr_fini(struct amdgpu_device *adev);
bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_resource *mem);
uint64_t amdgpu_gtt_mgr_usage(struct amdgpu_gtt_mgr *mgr);
int amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr);
void amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr);
uint64_t amdgpu_preempt_mgr_usage(struct ttm_resource_manager *man);
@ -158,7 +162,7 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
struct dma_fence **fence);
int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo);
int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo);
void amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo);
uint64_t amdgpu_ttm_domain_start(struct amdgpu_device *adev, uint32_t type);
#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
@ -177,6 +181,8 @@ static inline bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm)
#endif
void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages);
int amdgpu_ttm_tt_get_userptr(const struct ttm_buffer_object *tbo,
uint64_t *user_addr);
int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo,
uint64_t addr, uint32_t flags);
bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm);

View File

@ -378,6 +378,7 @@ enum AMDGPU_UCODE_ID {
AMDGPU_UCODE_ID_VCN0_RAM,
AMDGPU_UCODE_ID_VCN1_RAM,
AMDGPU_UCODE_ID_DMCUB,
AMDGPU_UCODE_ID_CAP,
AMDGPU_UCODE_ID_MAXIMUM,
};

View File

@ -21,7 +21,7 @@
*
*/
#include "amdgpu_ras.h"
#include "amdgpu.h"
static int amdgpu_umc_do_page_retirement(struct amdgpu_device *adev,
void *ras_error_status,
@ -33,14 +33,14 @@ static int amdgpu_umc_do_page_retirement(struct amdgpu_device *adev,
int ret = 0;
kgd2kfd_set_sram_ecc_flag(adev->kfd.dev);
ret = smu_get_ecc_info(&adev->smu, (void *)&(con->umc_ecc));
ret = amdgpu_dpm_get_ecc_info(adev, (void *)&(con->umc_ecc));
if (ret == -EOPNOTSUPP) {
if (adev->umc.ras_funcs &&
adev->umc.ras_funcs->query_ras_error_count)
adev->umc.ras_funcs->query_ras_error_count(adev, ras_error_status);
if (adev->umc.ras && adev->umc.ras->ras_block.hw_ops &&
adev->umc.ras->ras_block.hw_ops->query_ras_error_count)
adev->umc.ras->ras_block.hw_ops->query_ras_error_count(adev, ras_error_status);
if (adev->umc.ras_funcs &&
adev->umc.ras_funcs->query_ras_error_address &&
if (adev->umc.ras && adev->umc.ras->ras_block.hw_ops &&
adev->umc.ras->ras_block.hw_ops->query_ras_error_address &&
adev->umc.max_ras_err_cnt_per_query) {
err_data->err_addr =
kcalloc(adev->umc.max_ras_err_cnt_per_query,
@ -56,15 +56,15 @@ static int amdgpu_umc_do_page_retirement(struct amdgpu_device *adev,
/* umc query_ras_error_address is also responsible for clearing
* error status
*/
adev->umc.ras_funcs->query_ras_error_address(adev, ras_error_status);
adev->umc.ras->ras_block.hw_ops->query_ras_error_address(adev, ras_error_status);
}
} else if (!ret) {
if (adev->umc.ras_funcs &&
adev->umc.ras_funcs->ecc_info_query_ras_error_count)
adev->umc.ras_funcs->ecc_info_query_ras_error_count(adev, ras_error_status);
if (adev->umc.ras &&
adev->umc.ras->ecc_info_query_ras_error_count)
adev->umc.ras->ecc_info_query_ras_error_count(adev, ras_error_status);
if (adev->umc.ras_funcs &&
adev->umc.ras_funcs->ecc_info_query_ras_error_address &&
if (adev->umc.ras &&
adev->umc.ras->ecc_info_query_ras_error_address &&
adev->umc.max_ras_err_cnt_per_query) {
err_data->err_addr =
kcalloc(adev->umc.max_ras_err_cnt_per_query,
@ -80,7 +80,7 @@ static int amdgpu_umc_do_page_retirement(struct amdgpu_device *adev,
/* umc query_ras_error_address is also responsible for clearing
* error status
*/
adev->umc.ras_funcs->ecc_info_query_ras_error_address(adev, ras_error_status);
adev->umc.ras->ecc_info_query_ras_error_address(adev, ras_error_status);
}
}
@ -96,8 +96,7 @@ static int amdgpu_umc_do_page_retirement(struct amdgpu_device *adev,
err_data->err_addr_cnt);
amdgpu_ras_save_bad_pages(adev);
if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->send_hbm_bad_pages_num)
adev->smu.ppt_funcs->send_hbm_bad_pages_num(&adev->smu, con->eeprom_control.ras_num_recs);
amdgpu_dpm_send_hbm_bad_pages_num(adev, con->eeprom_control.ras_num_recs);
}
if (reset)
@ -137,7 +136,7 @@ static int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev,
return amdgpu_umc_do_page_retirement(adev, ras_error_status, entry, true);
}
int amdgpu_umc_ras_late_init(struct amdgpu_device *adev)
int amdgpu_umc_ras_late_init(struct amdgpu_device *adev, void *ras_info)
{
int r;
struct ras_fs_if fs_info = {
@ -173,9 +172,9 @@ int amdgpu_umc_ras_late_init(struct amdgpu_device *adev)
}
/* ras init of specific umc version */
if (adev->umc.ras_funcs &&
adev->umc.ras_funcs->err_cnt_init)
adev->umc.ras_funcs->err_cnt_init(adev);
if (adev->umc.ras &&
adev->umc.ras->err_cnt_init)
adev->umc.ras->err_cnt_init(adev);
return 0;
@ -219,3 +218,24 @@ int amdgpu_umc_process_ecc_irq(struct amdgpu_device *adev,
amdgpu_ras_interrupt_dispatch(adev, &ih_data);
return 0;
}
void amdgpu_umc_fill_error_record(struct ras_err_data *err_data,
uint64_t err_addr,
uint64_t retired_page,
uint32_t channel_index,
uint32_t umc_inst)
{
struct eeprom_table_record *err_rec =
&err_data->err_addr[err_data->err_addr_cnt];
err_rec->address = err_addr;
/* page frame address is saved */
err_rec->retired_page = retired_page >> AMDGPU_GPU_PAGE_SHIFT;
err_rec->ts = (uint64_t)ktime_get_real_seconds();
err_rec->err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE;
err_rec->cu = 0;
err_rec->mem_channel = channel_index;
err_rec->mcumc_id = umc_inst;
err_data->err_addr_cnt++;
}

View File

@ -20,6 +20,7 @@
*/
#ifndef __AMDGPU_UMC_H__
#define __AMDGPU_UMC_H__
#include "amdgpu_ras.h"
/*
* (addr / 256) * 4096, the higher 26 bits in ErrorAddr
@ -40,14 +41,9 @@
#define LOOP_UMC_CH_INST(ch_inst) for ((ch_inst) = 0; (ch_inst) < adev->umc.channel_inst_num; (ch_inst)++)
#define LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) LOOP_UMC_INST((umc_inst)) LOOP_UMC_CH_INST((ch_inst))
struct amdgpu_umc_ras_funcs {
struct amdgpu_umc_ras {
struct amdgpu_ras_block_object ras_block;
void (*err_cnt_init)(struct amdgpu_device *adev);
int (*ras_late_init)(struct amdgpu_device *adev);
void (*ras_fini)(struct amdgpu_device *adev);
void (*query_ras_error_count)(struct amdgpu_device *adev,
void *ras_error_status);
void (*query_ras_error_address)(struct amdgpu_device *adev,
void *ras_error_status);
bool (*query_ras_poison_mode)(struct amdgpu_device *adev);
void (*ecc_info_query_ras_error_count)(struct amdgpu_device *adev,
void *ras_error_status);
@ -73,10 +69,10 @@ struct amdgpu_umc {
struct ras_common_if *ras_if;
const struct amdgpu_umc_funcs *funcs;
const struct amdgpu_umc_ras_funcs *ras_funcs;
struct amdgpu_umc_ras *ras;
};
int amdgpu_umc_ras_late_init(struct amdgpu_device *adev);
int amdgpu_umc_ras_late_init(struct amdgpu_device *adev, void *ras_info);
void amdgpu_umc_ras_fini(struct amdgpu_device *adev);
int amdgpu_umc_poison_handler(struct amdgpu_device *adev,
void *ras_error_status,
@ -84,4 +80,9 @@ int amdgpu_umc_poison_handler(struct amdgpu_device *adev,
int amdgpu_umc_process_ecc_irq(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry);
void amdgpu_umc_fill_error_record(struct ras_err_data *err_data,
uint64_t err_addr,
uint64_t retired_page,
uint32_t channel_index,
uint32_t umc_inst);
#endif

View File

@ -834,6 +834,7 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
handle = msg[2];
if (handle == 0) {
amdgpu_bo_kunmap(bo);
DRM_ERROR("Invalid UVD handle!\n");
return -EINVAL;
}
@ -892,6 +893,7 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
}
amdgpu_bo_kunmap(bo);
return -EINVAL;
}

View File

@ -820,3 +820,148 @@ void amdgpu_virt_update_sriov_video_codec(struct amdgpu_device *adev,
}
}
}
static bool amdgpu_virt_get_rlcg_reg_access_flag(struct amdgpu_device *adev,
u32 acc_flags, u32 hwip,
bool write, u32 *rlcg_flag)
{
bool ret = false;
switch (hwip) {
case GC_HWIP:
if (amdgpu_sriov_reg_indirect_gc(adev)) {
*rlcg_flag =
write ? AMDGPU_RLCG_GC_WRITE : AMDGPU_RLCG_GC_READ;
ret = true;
/* only in new version, AMDGPU_REGS_NO_KIQ and
* AMDGPU_REGS_RLC are enabled simultaneously */
} else if ((acc_flags & AMDGPU_REGS_RLC) &&
!(acc_flags & AMDGPU_REGS_NO_KIQ)) {
*rlcg_flag = AMDGPU_RLCG_GC_WRITE_LEGACY;
ret = true;
}
break;
case MMHUB_HWIP:
if (amdgpu_sriov_reg_indirect_mmhub(adev) &&
(acc_flags & AMDGPU_REGS_RLC) && write) {
*rlcg_flag = AMDGPU_RLCG_MMHUB_WRITE;
ret = true;
}
break;
default:
break;
}
return ret;
}
static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag)
{
struct amdgpu_rlcg_reg_access_ctrl *reg_access_ctrl;
uint32_t timeout = 50000;
uint32_t i, tmp;
uint32_t ret = 0;
static void *scratch_reg0;
static void *scratch_reg1;
static void *scratch_reg2;
static void *scratch_reg3;
static void *spare_int;
if (!adev->gfx.rlc.rlcg_reg_access_supported) {
dev_err(adev->dev,
"indirect registers access through rlcg is not available\n");
return 0;
}
reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl;
scratch_reg0 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg0;
scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1;
scratch_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2;
scratch_reg3 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg3;
if (reg_access_ctrl->spare_int)
spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int;
if (offset == reg_access_ctrl->grbm_cntl) {
/* if the target reg offset is grbm_cntl, write to scratch_reg2 */
writel(v, scratch_reg2);
writel(v, ((void __iomem *)adev->rmmio) + (offset * 4));
} else if (offset == reg_access_ctrl->grbm_idx) {
/* if the target reg offset is grbm_idx, write to scratch_reg3 */
writel(v, scratch_reg3);
writel(v, ((void __iomem *)adev->rmmio) + (offset * 4));
} else {
/*
* SCRATCH_REG0 = read/write value
* SCRATCH_REG1[30:28] = command
* SCRATCH_REG1[19:0] = address in dword
* SCRATCH_REG1[26:24] = Error reporting
*/
writel(v, scratch_reg0);
writel((offset | flag), scratch_reg1);
if (reg_access_ctrl->spare_int)
writel(1, spare_int);
for (i = 0; i < timeout; i++) {
tmp = readl(scratch_reg1);
if (!(tmp & flag))
break;
udelay(10);
}
if (i >= timeout) {
if (amdgpu_sriov_rlcg_error_report_enabled(adev)) {
if (tmp & AMDGPU_RLCG_VFGATE_DISABLED) {
dev_err(adev->dev,
"vfgate is disabled, rlcg failed to program reg: 0x%05x\n", offset);
} else if (tmp & AMDGPU_RLCG_WRONG_OPERATION_TYPE) {
dev_err(adev->dev,
"wrong operation type, rlcg failed to program reg: 0x%05x\n", offset);
} else if (tmp & AMDGPU_RLCG_REG_NOT_IN_RANGE) {
dev_err(adev->dev,
"regiser is not in range, rlcg failed to program reg: 0x%05x\n", offset);
} else {
dev_err(adev->dev,
"unknown error type, rlcg failed to program reg: 0x%05x\n", offset);
}
} else {
dev_err(adev->dev,
"timeout: rlcg faled to program reg: 0x%05x\n", offset);
}
}
}
ret = readl(scratch_reg0);
return ret;
}
void amdgpu_sriov_wreg(struct amdgpu_device *adev,
u32 offset, u32 value,
u32 acc_flags, u32 hwip)
{
u32 rlcg_flag;
if (!amdgpu_sriov_runtime(adev) &&
amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, true, &rlcg_flag)) {
amdgpu_virt_rlcg_reg_rw(adev, offset, value, rlcg_flag);
return;
}
if (acc_flags & AMDGPU_REGS_NO_KIQ)
WREG32_NO_KIQ(offset, value);
else
WREG32(offset, value);
}
u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
u32 offset, u32 acc_flags, u32 hwip)
{
u32 rlcg_flag;
if (!amdgpu_sriov_runtime(adev) &&
amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, false, &rlcg_flag))
return amdgpu_virt_rlcg_reg_rw(adev, offset, 0, rlcg_flag);
if (acc_flags & AMDGPU_REGS_NO_KIQ)
return RREG32_NO_KIQ(offset);
else
return RREG32(offset);
}

View File

@ -32,6 +32,17 @@
#define AMDGPU_PASSTHROUGH_MODE (1 << 3) /* thw whole GPU is pass through for VM */
#define AMDGPU_SRIOV_CAPS_RUNTIME (1 << 4) /* is out of full access mode */
/* flags for indirect register access path supported by rlcg for sriov */
#define AMDGPU_RLCG_GC_WRITE_LEGACY (0x8 << 28)
#define AMDGPU_RLCG_GC_WRITE (0x0 << 28)
#define AMDGPU_RLCG_GC_READ (0x1 << 28)
#define AMDGPU_RLCG_MMHUB_WRITE (0x2 << 28)
/* error code for indirect register access path supported by rlcg for sriov */
#define AMDGPU_RLCG_VFGATE_DISABLED 0x4000000
#define AMDGPU_RLCG_WRONG_OPERATION_TYPE 0x2000000
#define AMDGPU_RLCG_REG_NOT_IN_RANGE 0x1000000
/* all asic after AI use this offset */
#define mmRCC_IOV_FUNC_IDENTIFIER 0xDE5
/* tonga/fiji use this offset */
@ -275,13 +286,18 @@ struct amdgpu_video_codec_info;
(amdgpu_sriov_vf((adev)) && \
((adev)->virt.reg_access & (AMDGIM_FEATURE_GC_REG_RLC_EN)))
#define amdgpu_sriov_rlcg_error_report_enabled(adev) \
(amdgpu_sriov_reg_indirect_mmhub(adev) || amdgpu_sriov_reg_indirect_gc(adev))
#define amdgpu_passthrough(adev) \
((adev)->virt.caps & AMDGPU_PASSTHROUGH_MODE)
static inline bool is_virtual_machine(void)
{
#ifdef CONFIG_X86
#if defined(CONFIG_X86)
return boot_cpu_has(X86_FEATURE_HYPERVISOR);
#elif defined(CONFIG_ARM64)
return !is_kernel_in_hyp_mode();
#else
return false;
#endif
@ -293,7 +309,6 @@ static inline bool is_virtual_machine(void)
((!amdgpu_in_reset(adev)) && adev->virt.tdr_debug)
#define amdgpu_sriov_is_normal(adev) \
((!amdgpu_in_reset(adev)) && (!adev->virt.tdr_debug))
bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);
void amdgpu_virt_init_setting(struct amdgpu_device *adev);
void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
@ -321,4 +336,9 @@ enum amdgpu_sriov_vf_mode amdgpu_virt_get_sriov_vf_mode(struct amdgpu_device *ad
void amdgpu_virt_update_sriov_video_codec(struct amdgpu_device *adev,
struct amdgpu_video_codec_info *encode, uint32_t encode_array_size,
struct amdgpu_video_codec_info *decode, uint32_t decode_array_size);
void amdgpu_sriov_wreg(struct amdgpu_device *adev,
u32 offset, u32 value,
u32 acc_flags, u32 hwip);
u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
u32 offset, u32 acc_flags, u32 hwip);
#endif

View File

@ -375,6 +375,8 @@ static void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,
if (bo->tbo.base.resv != vm->root.bo->tbo.base.resv)
return;
dma_resv_assert_held(vm->root.bo->tbo.base.resv);
vm->bulk_moveable = false;
if (bo->tbo.type == ttm_bo_type_kernel && bo->parent)
amdgpu_vm_bo_relocated(base);
@ -1634,7 +1636,7 @@ static int amdgpu_vm_update_ptes(struct amdgpu_vm_update_params *params,
nptes = max(nptes, 1u);
trace_amdgpu_vm_update_ptes(params, frag_start, upd_end,
nptes, dst, incr, upd_flags,
min(nptes, 32u), dst, incr, upd_flags,
vm->task_info.pid,
vm->immediate.fence_context);
amdgpu_vm_update_flags(params, to_amdgpu_bo_vm(pt),
@ -2257,6 +2259,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
if (!bo)
return bo_va;
dma_resv_assert_held(bo->tbo.base.resv);
if (amdgpu_dmabuf_is_xgmi_accessible(adev, bo)) {
bo_va->is_xgmi = true;
/* Power up XGMI if it can be potentially used */
@ -2634,7 +2637,7 @@ void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket)
}
/**
* amdgpu_vm_bo_rmv - remove a bo to a specific vm
* amdgpu_vm_bo_del - remove a bo from a specific vm
*
* @adev: amdgpu_device pointer
* @bo_va: requested bo_va
@ -2643,7 +2646,7 @@ void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket)
*
* Object have to be reserved!
*/
void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
void amdgpu_vm_bo_del(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va)
{
struct amdgpu_bo_va_mapping *mapping, *next;
@ -2651,7 +2654,10 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
struct amdgpu_vm *vm = bo_va->base.vm;
struct amdgpu_vm_bo_base **base;
dma_resv_assert_held(vm->root.bo->tbo.base.resv);
if (bo) {
dma_resv_assert_held(bo->tbo.base.resv);
if (bo->tbo.base.resv == vm->root.bo->tbo.base.resv)
vm->bulk_moveable = false;

View File

@ -435,7 +435,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm,
uint64_t addr);
void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket);
void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
void amdgpu_vm_bo_del(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va);
void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,
uint32_t fragment_size_default, unsigned max_level,

View File

@ -281,7 +281,7 @@ int amdgpu_vram_mgr_reserve_range(struct amdgpu_vram_mgr *mgr,
rsv->mm_node.size = size >> PAGE_SHIFT;
spin_lock(&mgr->lock);
list_add_tail(&mgr->reservations_pending, &rsv->node);
list_add_tail(&rsv->node, &mgr->reservations_pending);
amdgpu_vram_mgr_do_reserve(&mgr->manager);
spin_unlock(&mgr->lock);

View File

@ -732,7 +732,7 @@ int amdgpu_xgmi_remove_device(struct amdgpu_device *adev)
return psp_xgmi_terminate(&adev->psp);
}
static int amdgpu_xgmi_ras_late_init(struct amdgpu_device *adev)
static int amdgpu_xgmi_ras_late_init(struct amdgpu_device *adev, void *ras_info)
{
int r;
struct ras_ih_if ih_info = {
@ -746,7 +746,7 @@ static int amdgpu_xgmi_ras_late_init(struct amdgpu_device *adev)
adev->gmc.xgmi.num_physical_nodes == 0)
return 0;
adev->gmc.xgmi.ras_funcs->reset_ras_error_count(adev);
adev->gmc.xgmi.ras->ras_block.hw_ops->reset_ras_error_count(adev);
if (!adev->gmc.xgmi.ras_if) {
adev->gmc.xgmi.ras_if = kmalloc(sizeof(struct ras_common_if), GFP_KERNEL);
@ -865,7 +865,7 @@ static int amdgpu_xgmi_query_pcs_error_status(struct amdgpu_device *adev,
return 0;
}
static int amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
static void amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
void *ras_error_status)
{
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
@ -874,7 +874,7 @@ static int amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
uint32_t ue_cnt = 0, ce_cnt = 0;
if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__XGMI_WAFL))
return -EINVAL;
return ;
err_data->ue_count = 0;
err_data->ce_count = 0;
@ -940,17 +940,51 @@ static int amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
break;
}
adev->gmc.xgmi.ras_funcs->reset_ras_error_count(adev);
adev->gmc.xgmi.ras->ras_block.hw_ops->reset_ras_error_count(adev);
err_data->ue_count += ue_cnt;
err_data->ce_count += ce_cnt;
return 0;
}
const struct amdgpu_xgmi_ras_funcs xgmi_ras_funcs = {
.ras_late_init = amdgpu_xgmi_ras_late_init,
.ras_fini = amdgpu_xgmi_ras_fini,
/* Trigger XGMI/WAFL error */
static int amdgpu_ras_error_inject_xgmi(struct amdgpu_device *adev, void *inject_if)
{
int ret = 0;
struct ta_ras_trigger_error_input *block_info =
(struct ta_ras_trigger_error_input *)inject_if;
if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_DISALLOW))
dev_warn(adev->dev, "Failed to disallow df cstate");
if (amdgpu_dpm_allow_xgmi_power_down(adev, false))
dev_warn(adev->dev, "Failed to disallow XGMI power down");
ret = psp_ras_trigger_error(&adev->psp, block_info);
if (amdgpu_ras_intr_triggered())
return ret;
if (amdgpu_dpm_allow_xgmi_power_down(adev, true))
dev_warn(adev->dev, "Failed to allow XGMI power down");
if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_ALLOW))
dev_warn(adev->dev, "Failed to allow df cstate");
return ret;
}
struct amdgpu_ras_block_hw_ops xgmi_ras_hw_ops = {
.query_ras_error_count = amdgpu_xgmi_query_ras_error_count,
.reset_ras_error_count = amdgpu_xgmi_reset_ras_error_count,
.ras_error_inject = amdgpu_ras_error_inject_xgmi,
};
struct amdgpu_xgmi_ras xgmi_ras = {
.ras_block = {
.name = "xgmi",
.block = AMDGPU_RAS_BLOCK__XGMI_WAFL,
.hw_ops = &xgmi_ras_hw_ops,
.ras_late_init = amdgpu_xgmi_ras_late_init,
.ras_fini = amdgpu_xgmi_ras_fini,
},
};

View File

@ -24,7 +24,7 @@
#include <drm/task_barrier.h>
#include "amdgpu_psp.h"
#include "amdgpu_ras.h"
struct amdgpu_hive_info {
struct kobject kobj;
@ -50,7 +50,7 @@ struct amdgpu_pcs_ras_field {
uint32_t pcs_err_shift;
};
extern const struct amdgpu_xgmi_ras_funcs xgmi_ras_funcs;
extern struct amdgpu_xgmi_ras xgmi_ras;
struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev);
void amdgpu_put_xgmi_hive(struct amdgpu_hive_info *hive);
int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_device *adev);

View File

@ -68,12 +68,13 @@ int athub_v1_0_set_clockgating(struct amdgpu_device *adev,
if (amdgpu_sriov_vf(adev))
return 0;
switch (adev->asic_type) {
case CHIP_VEGA10:
case CHIP_VEGA12:
case CHIP_VEGA20:
case CHIP_RAVEN:
case CHIP_RENOIR:
switch (adev->ip_versions[ATHUB_HWIP][0]) {
case IP_VERSION(9, 0, 0):
case IP_VERSION(9, 1, 0):
case IP_VERSION(9, 2, 0):
case IP_VERSION(9, 3, 0):
case IP_VERSION(9, 4, 0):
case IP_VERSION(1, 5, 0):
athub_update_medium_grain_clock_gating(adev,
state == AMD_CG_STATE_GATE);
athub_update_medium_grain_light_sleep(adev,

View File

@ -78,6 +78,7 @@ int athub_v2_0_set_clockgating(struct amdgpu_device *adev,
return 0;
switch (adev->ip_versions[ATHUB_HWIP][0]) {
case IP_VERSION(1, 3, 1):
case IP_VERSION(2, 0, 0):
case IP_VERSION(2, 0, 2):
athub_v2_0_update_medium_grain_clock_gating(adev,

View File

@ -74,6 +74,7 @@ int athub_v2_1_set_clockgating(struct amdgpu_device *adev,
case IP_VERSION(2, 1, 0):
case IP_VERSION(2, 1, 1):
case IP_VERSION(2, 1, 2):
case IP_VERSION(2, 4, 0):
athub_v2_1_update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE);
athub_v2_1_update_medium_grain_light_sleep(adev, state == AMD_CG_STATE_GATE);
break;

View File

@ -2532,7 +2532,7 @@ static void dce_v10_0_crtc_dpms(struct drm_crtc *crtc, int mode)
break;
}
/* adjust pm to dpms */
amdgpu_pm_compute_clocks(adev);
amdgpu_dpm_compute_clocks(adev);
}
static void dce_v10_0_crtc_prepare(struct drm_crtc *crtc)

View File

@ -2608,7 +2608,7 @@ static void dce_v11_0_crtc_dpms(struct drm_crtc *crtc, int mode)
break;
}
/* adjust pm to dpms */
amdgpu_pm_compute_clocks(adev);
amdgpu_dpm_compute_clocks(adev);
}
static void dce_v11_0_crtc_prepare(struct drm_crtc *crtc)

View File

@ -2424,7 +2424,7 @@ static void dce_v6_0_crtc_dpms(struct drm_crtc *crtc, int mode)
break;
}
/* adjust pm to dpms */
amdgpu_pm_compute_clocks(adev);
amdgpu_dpm_compute_clocks(adev);
}
static void dce_v6_0_crtc_prepare(struct drm_crtc *crtc)

View File

@ -2433,7 +2433,7 @@ static void dce_v8_0_crtc_dpms(struct drm_crtc *crtc, int mode)
break;
}
/* adjust pm to dpms */
amdgpu_pm_compute_clocks(adev);
amdgpu_dpm_compute_clocks(adev);
}
static void dce_v8_0_crtc_prepare(struct drm_crtc *crtc)

View File

@ -458,7 +458,7 @@ 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,
int counter_idx, uint64_t config,
uint64_t config, int counter_idx,
bool is_deferred)
{
@ -476,8 +476,8 @@ static int df_v3_6_pmc_set_deferred(struct amdgpu_device *adev,
}
static bool df_v3_6_pmc_is_deferred(struct amdgpu_device *adev,
int counter_idx,
uint64_t config)
uint64_t config,
int counter_idx)
{
return (df_v3_6_pmc_has_counter(adev, config, counter_idx) &&
(adev->df_perfmon_config_assign_mask[counter_idx]

View File

@ -56,10 +56,6 @@
#define GFX10_NUM_GFX_RINGS_Sienna_Cichlid 1
#define GFX10_MEC_HPD_SIZE 2048
#define RLCG_VFGATE_DISABLED 0x4000000
#define RLCG_WRONG_OPERATION_TYPE 0x2000000
#define RLCG_NOT_IN_RANGE 0x1000000
#define F32_CE_PROGRAM_RAM_SIZE 65536
#define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L
@ -180,14 +176,6 @@
#define mmRLC_SPARE_INT_0_Sienna_Cichlid 0x4ca5
#define mmRLC_SPARE_INT_0_Sienna_Cichlid_BASE_IDX 1
#define GFX_RLCG_GC_WRITE_OLD (0x8 << 28)
#define GFX_RLCG_GC_WRITE (0x0 << 28)
#define GFX_RLCG_GC_READ (0x1 << 28)
#define GFX_RLCG_MMHUB_WRITE (0x2 << 28)
#define RLCG_ERROR_REPORT_ENABLED(adev) \
(amdgpu_sriov_reg_indirect_mmhub(adev) || amdgpu_sriov_reg_indirect_gc(adev))
MODULE_FIRMWARE("amdgpu/navi10_ce.bin");
MODULE_FIRMWARE("amdgpu/navi10_pfp.bin");
MODULE_FIRMWARE("amdgpu/navi10_me.bin");
@ -1463,143 +1451,6 @@ static const struct soc15_reg_golden golden_settings_gc_10_1_2[] =
SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, 0x00c00000)
};
static bool gfx_v10_get_rlcg_flag(struct amdgpu_device *adev, u32 acc_flags, u32 hwip,
int write, u32 *rlcg_flag)
{
switch (hwip) {
case GC_HWIP:
if (amdgpu_sriov_reg_indirect_gc(adev)) {
*rlcg_flag = write ? GFX_RLCG_GC_WRITE : GFX_RLCG_GC_READ;
return true;
/* only in new version, AMDGPU_REGS_NO_KIQ and AMDGPU_REGS_RLC enabled simultaneously */
} else if ((acc_flags & AMDGPU_REGS_RLC) && !(acc_flags & AMDGPU_REGS_NO_KIQ)) {
*rlcg_flag = GFX_RLCG_GC_WRITE_OLD;
return true;
}
break;
case MMHUB_HWIP:
if (amdgpu_sriov_reg_indirect_mmhub(adev) &&
(acc_flags & AMDGPU_REGS_RLC) && write) {
*rlcg_flag = GFX_RLCG_MMHUB_WRITE;
return true;
}
break;
default:
DRM_DEBUG("Not program register by RLCG\n");
}
return false;
}
static u32 gfx_v10_rlcg_rw(struct amdgpu_device *adev, u32 offset, u32 v, uint32_t flag)
{
static void *scratch_reg0;
static void *scratch_reg1;
static void *scratch_reg2;
static void *scratch_reg3;
static void *spare_int;
static uint32_t grbm_cntl;
static uint32_t grbm_idx;
uint32_t i = 0;
uint32_t retries = 50000;
u32 ret = 0;
u32 tmp;
scratch_reg0 = adev->rmmio +
(adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG0_BASE_IDX] + mmSCRATCH_REG0) * 4;
scratch_reg1 = adev->rmmio +
(adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG1) * 4;
scratch_reg2 = adev->rmmio +
(adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG0_BASE_IDX] + mmSCRATCH_REG2) * 4;
scratch_reg3 = adev->rmmio +
(adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG3) * 4;
if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0)) {
spare_int = adev->rmmio +
(adev->reg_offset[GC_HWIP][0][mmRLC_SPARE_INT_0_Sienna_Cichlid_BASE_IDX]
+ mmRLC_SPARE_INT_0_Sienna_Cichlid) * 4;
} else {
spare_int = adev->rmmio +
(adev->reg_offset[GC_HWIP][0][mmRLC_SPARE_INT_BASE_IDX] + mmRLC_SPARE_INT) * 4;
}
grbm_cntl = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_CNTL_BASE_IDX] + mmGRBM_GFX_CNTL;
grbm_idx = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_INDEX_BASE_IDX] + mmGRBM_GFX_INDEX;
if (offset == grbm_cntl || offset == grbm_idx) {
if (offset == grbm_cntl)
writel(v, scratch_reg2);
else if (offset == grbm_idx)
writel(v, scratch_reg3);
writel(v, ((void __iomem *)adev->rmmio) + (offset * 4));
} else {
writel(v, scratch_reg0);
writel(offset | flag, scratch_reg1);
writel(1, spare_int);
for (i = 0; i < retries; i++) {
tmp = readl(scratch_reg1);
if (!(tmp & flag))
break;
udelay(10);
}
if (i >= retries) {
if (RLCG_ERROR_REPORT_ENABLED(adev)) {
if (tmp & RLCG_VFGATE_DISABLED)
pr_err("The vfgate is disabled, program reg:0x%05x failed!\n", offset);
else if (tmp & RLCG_WRONG_OPERATION_TYPE)
pr_err("Wrong operation type, program reg:0x%05x failed!\n", offset);
else if (tmp & RLCG_NOT_IN_RANGE)
pr_err("The register is not in range, program reg:0x%05x failed!\n", offset);
else
pr_err("Unknown error type, program reg:0x%05x failed!\n", offset);
} else
pr_err("timeout: rlcg program reg:0x%05x failed!\n", offset);
}
}
ret = readl(scratch_reg0);
return ret;
}
static void gfx_v10_sriov_wreg(struct amdgpu_device *adev, u32 offset, u32 value, u32 acc_flags, u32 hwip)
{
u32 rlcg_flag;
if (!amdgpu_sriov_runtime(adev) &&
gfx_v10_get_rlcg_flag(adev, acc_flags, hwip, 1, &rlcg_flag)) {
gfx_v10_rlcg_rw(adev, offset, value, rlcg_flag);
return;
}
if (acc_flags & AMDGPU_REGS_NO_KIQ)
WREG32_NO_KIQ(offset, value);
else
WREG32(offset, value);
}
static u32 gfx_v10_sriov_rreg(struct amdgpu_device *adev, u32 offset, u32 acc_flags, u32 hwip)
{
u32 rlcg_flag;
if (!amdgpu_sriov_runtime(adev) &&
gfx_v10_get_rlcg_flag(adev, acc_flags, hwip, 0, &rlcg_flag))
return gfx_v10_rlcg_rw(adev, offset, 0, rlcg_flag);
if (acc_flags & AMDGPU_REGS_NO_KIQ)
return RREG32_NO_KIQ(offset);
else
return RREG32(offset);
}
static const struct soc15_reg_golden golden_settings_gc_10_1_nv14[] =
{
/* Pending on emulation bring up */
@ -3790,6 +3641,7 @@ static void gfx_v10_0_init_golden_registers(struct amdgpu_device *adev)
(const u32)ARRAY_SIZE(golden_settings_gc_10_3_5));
break;
case IP_VERSION(10, 1, 3):
case IP_VERSION(10, 1, 4):
soc15_program_register_sequence(adev,
golden_settings_gc_10_0_cyan_skillfish,
(const u32)ARRAY_SIZE(golden_settings_gc_10_0_cyan_skillfish));
@ -3968,6 +3820,7 @@ static void gfx_v10_0_check_fw_write_wait(struct amdgpu_device *adev)
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 3):
case IP_VERSION(10, 1, 4):
if ((adev->gfx.me_fw_version >= 0x00000046) &&
(adev->gfx.me_feature_version >= 27) &&
(adev->gfx.pfp_fw_version >= 0x00000068) &&
@ -4108,6 +3961,9 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
else
chip_name = "cyan_skillfish";
break;
case IP_VERSION(10, 1, 4):
chip_name = "cyan_skillfish2";
break;
default:
BUG();
}
@ -4448,6 +4304,30 @@ static void gfx_v10_0_rlc_fini(struct amdgpu_device *adev)
(void **)&adev->gfx.rlc.cp_table_ptr);
}
static void gfx_v10_0_init_rlcg_reg_access_ctrl(struct amdgpu_device *adev)
{
struct amdgpu_rlcg_reg_access_ctrl *reg_access_ctrl;
reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl;
reg_access_ctrl->scratch_reg0 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG0);
reg_access_ctrl->scratch_reg1 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG1);
reg_access_ctrl->scratch_reg2 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG2);
reg_access_ctrl->scratch_reg3 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG3);
reg_access_ctrl->grbm_cntl = SOC15_REG_OFFSET(GC, 0, mmGRBM_GFX_CNTL);
reg_access_ctrl->grbm_idx = SOC15_REG_OFFSET(GC, 0, mmGRBM_GFX_INDEX);
switch (adev->ip_versions[GC_HWIP][0]) {
case IP_VERSION(10, 3, 0):
reg_access_ctrl->spare_int =
SOC15_REG_OFFSET(GC, 0, mmRLC_SPARE_INT_0_Sienna_Cichlid);
break;
default:
reg_access_ctrl->spare_int =
SOC15_REG_OFFSET(GC, 0, mmRLC_SPARE_INT);
break;
}
adev->gfx.rlc.rlcg_reg_access_supported = true;
}
static int gfx_v10_0_rlc_init(struct amdgpu_device *adev)
{
const struct cs_section_def *cs_data;
@ -4468,6 +4348,7 @@ static int gfx_v10_0_rlc_init(struct amdgpu_device *adev)
if (adev->gfx.rlc.funcs->update_spm_vmid)
adev->gfx.rlc.funcs->update_spm_vmid(adev, 0xf);
return 0;
}
@ -4689,6 +4570,7 @@ static void gfx_v10_0_gpu_early_init(struct amdgpu_device *adev)
1 << REG_GET_FIELD(gb_addr_config, GB_ADDR_CONFIG, NUM_PKRS);
break;
case IP_VERSION(10, 1, 3):
case IP_VERSION(10, 1, 4):
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;
@ -4801,6 +4683,7 @@ static int gfx_v10_0_sw_init(void *handle)
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 3):
case IP_VERSION(10, 1, 4):
adev->gfx.me.num_me = 1;
adev->gfx.me.num_pipe_per_me = 1;
adev->gfx.me.num_queue_per_pipe = 1;
@ -4865,10 +4748,14 @@ static int gfx_v10_0_sw_init(void *handle)
if (r)
return r;
r = gfx_v10_0_rlc_init(adev);
if (r) {
DRM_ERROR("Failed to init rlc BOs!\n");
return r;
if (adev->gfx.rlc.funcs) {
if (adev->gfx.rlc.funcs->init) {
r = adev->gfx.rlc.funcs->init(adev);
if (r) {
dev_err(adev->dev, "Failed to init rlc BOs!\n");
return r;
}
}
}
r = gfx_v10_0_mec_init(adev);
@ -7778,6 +7665,7 @@ static int gfx_v10_0_early_init(void *handle)
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 3):
case IP_VERSION(10, 1, 4):
adev->gfx.num_gfx_rings = GFX10_NUM_GFX_RINGS_NV1X;
break;
case IP_VERSION(10, 3, 0):
@ -7801,6 +7689,9 @@ static int gfx_v10_0_early_init(void *handle)
gfx_v10_0_set_gds_init(adev);
gfx_v10_0_set_rlc_funcs(adev);
/* init rlcg reg access ctrl */
gfx_v10_0_init_rlcg_reg_access_ctrl(adev);
return 0;
}
@ -8377,8 +8268,6 @@ static const struct amdgpu_rlc_funcs gfx_v10_0_rlc_funcs_sriov = {
.reset = gfx_v10_0_rlc_reset,
.start = gfx_v10_0_rlc_start,
.update_spm_vmid = gfx_v10_0_update_spm_vmid,
.sriov_wreg = gfx_v10_sriov_wreg,
.sriov_rreg = gfx_v10_sriov_rreg,
.is_rlcg_access_range = gfx_v10_0_is_rlcg_access_range,
};
@ -9537,6 +9426,7 @@ static void gfx_v10_0_set_rlc_funcs(struct amdgpu_device *adev)
case IP_VERSION(10, 1, 10):
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 3):
case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 3, 2):
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 4):

View File

@ -63,13 +63,6 @@
#define mmGCEA_PROBE_MAP 0x070c
#define mmGCEA_PROBE_MAP_BASE_IDX 0
#define GFX9_RLCG_GC_WRITE_OLD (0x8 << 28)
#define GFX9_RLCG_GC_WRITE (0x0 << 28)
#define GFX9_RLCG_GC_READ (0x1 << 28)
#define GFX9_RLCG_VFGATE_DISABLED 0x4000000
#define GFX9_RLCG_WRONG_OPERATION_TYPE 0x2000000
#define GFX9_RLCG_NOT_IN_RANGE 0x1000000
MODULE_FIRMWARE("amdgpu/vega10_ce.bin");
MODULE_FIRMWARE("amdgpu/vega10_pfp.bin");
MODULE_FIRMWARE("amdgpu/vega10_me.bin");
@ -746,128 +739,6 @@ static const u32 GFX_RLC_SRM_INDEX_CNTL_DATA_OFFSETS[] =
mmRLC_SRM_INDEX_CNTL_DATA_7 - mmRLC_SRM_INDEX_CNTL_DATA_0,
};
static u32 gfx_v9_0_rlcg_rw(struct amdgpu_device *adev, u32 offset, u32 v, uint32_t flag)
{
static void *scratch_reg0;
static void *scratch_reg1;
static void *scratch_reg2;
static void *scratch_reg3;
static void *spare_int;
static uint32_t grbm_cntl;
static uint32_t grbm_idx;
uint32_t i = 0;
uint32_t retries = 50000;
u32 ret = 0;
u32 tmp;
scratch_reg0 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG0_BASE_IDX] + mmSCRATCH_REG0)*4;
scratch_reg1 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG1)*4;
scratch_reg2 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG2_BASE_IDX] + mmSCRATCH_REG2)*4;
scratch_reg3 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG3_BASE_IDX] + mmSCRATCH_REG3)*4;
spare_int = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmRLC_SPARE_INT_BASE_IDX] + mmRLC_SPARE_INT)*4;
grbm_cntl = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_CNTL_BASE_IDX] + mmGRBM_GFX_CNTL;
grbm_idx = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_INDEX_BASE_IDX] + mmGRBM_GFX_INDEX;
if (offset == grbm_cntl || offset == grbm_idx) {
if (offset == grbm_cntl)
writel(v, scratch_reg2);
else if (offset == grbm_idx)
writel(v, scratch_reg3);
writel(v, ((void __iomem *)adev->rmmio) + (offset * 4));
} else {
/*
* SCRATCH_REG0 = read/write value
* SCRATCH_REG1[30:28] = command
* SCRATCH_REG1[19:0] = address in dword
* SCRATCH_REG1[26:24] = Error reporting
*/
writel(v, scratch_reg0);
writel(offset | flag, scratch_reg1);
writel(1, spare_int);
for (i = 0; i < retries; i++) {
tmp = readl(scratch_reg1);
if (!(tmp & flag))
break;
udelay(10);
}
if (i >= retries) {
if (amdgpu_sriov_reg_indirect_gc(adev)) {
if (tmp & GFX9_RLCG_VFGATE_DISABLED)
pr_err("The vfgate is disabled, program reg:0x%05x failed!\n", offset);
else if (tmp & GFX9_RLCG_WRONG_OPERATION_TYPE)
pr_err("Wrong operation type, program reg:0x%05x failed!\n", offset);
else if (tmp & GFX9_RLCG_NOT_IN_RANGE)
pr_err("The register is not in range, program reg:0x%05x failed!\n", offset);
else
pr_err("Unknown error type, program reg:0x%05x failed!\n", offset);
} else
pr_err("timeout: rlcg program reg:0x%05x failed!\n", offset);
}
}
ret = readl(scratch_reg0);
return ret;
}
static bool gfx_v9_0_get_rlcg_flag(struct amdgpu_device *adev, u32 acc_flags, u32 hwip,
int write, u32 *rlcg_flag)
{
switch (hwip) {
case GC_HWIP:
if (amdgpu_sriov_reg_indirect_gc(adev)) {
*rlcg_flag = write ? GFX9_RLCG_GC_WRITE : GFX9_RLCG_GC_READ;
return true;
/* only in new version, AMDGPU_REGS_NO_KIQ and AMDGPU_REGS_RLC enabled simultaneously */
} else if ((acc_flags & AMDGPU_REGS_RLC) && !(acc_flags & AMDGPU_REGS_NO_KIQ) && write) {
*rlcg_flag = GFX9_RLCG_GC_WRITE_OLD;
return true;
}
break;
default:
return false;
}
return false;
}
static u32 gfx_v9_0_sriov_rreg(struct amdgpu_device *adev, u32 offset, u32 acc_flags, u32 hwip)
{
u32 rlcg_flag;
if (!amdgpu_sriov_runtime(adev) && gfx_v9_0_get_rlcg_flag(adev, acc_flags, hwip, 0, &rlcg_flag))
return gfx_v9_0_rlcg_rw(adev, offset, 0, rlcg_flag);
if (acc_flags & AMDGPU_REGS_NO_KIQ)
return RREG32_NO_KIQ(offset);
else
return RREG32(offset);
}
static void gfx_v9_0_sriov_wreg(struct amdgpu_device *adev, u32 offset,
u32 value, u32 acc_flags, u32 hwip)
{
u32 rlcg_flag;
if (!amdgpu_sriov_runtime(adev) && gfx_v9_0_get_rlcg_flag(adev, acc_flags, hwip, 1, &rlcg_flag)) {
gfx_v9_0_rlcg_rw(adev, offset, value, rlcg_flag);
return;
}
if (acc_flags & AMDGPU_REGS_NO_KIQ)
WREG32_NO_KIQ(offset, value);
else
WREG32(offset, value);
}
#define VEGA10_GB_ADDR_CONFIG_GOLDEN 0x2a114042
#define VEGA12_GB_ADDR_CONFIG_GOLDEN 0x24104041
#define RAVEN_GB_ADDR_CONFIG_GOLDEN 0x24000042
@ -882,7 +753,7 @@ static int gfx_v9_0_get_cu_info(struct amdgpu_device *adev,
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);
static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
static void gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
void *ras_error_status);
static int gfx_v9_0_ras_error_inject(struct amdgpu_device *adev,
void *inject_if);
@ -2008,6 +1879,21 @@ static int gfx_v9_0_cp_jump_table_num(struct amdgpu_device *adev)
return 4;
}
static void gfx_v9_0_init_rlcg_reg_access_ctrl(struct amdgpu_device *adev)
{
struct amdgpu_rlcg_reg_access_ctrl *reg_access_ctrl;
reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl;
reg_access_ctrl->scratch_reg0 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG0);
reg_access_ctrl->scratch_reg1 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG1);
reg_access_ctrl->scratch_reg2 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG2);
reg_access_ctrl->scratch_reg3 = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG3);
reg_access_ctrl->grbm_cntl = SOC15_REG_OFFSET(GC, 0, mmGRBM_GFX_CNTL);
reg_access_ctrl->grbm_idx = SOC15_REG_OFFSET(GC, 0, mmGRBM_GFX_INDEX);
reg_access_ctrl->spare_int = SOC15_REG_OFFSET(GC, 0, mmRLC_SPARE_INT);
adev->gfx.rlc.rlcg_reg_access_supported = true;
}
static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
{
const struct cs_section_def *cs_data;
@ -2197,12 +2083,16 @@ static const struct amdgpu_gfx_funcs gfx_v9_0_gfx_funcs = {
.select_me_pipe_q = &gfx_v9_0_select_me_pipe_q,
};
static const struct amdgpu_gfx_ras_funcs gfx_v9_0_ras_funcs = {
.ras_late_init = amdgpu_gfx_ras_late_init,
.ras_fini = amdgpu_gfx_ras_fini,
.ras_error_inject = &gfx_v9_0_ras_error_inject,
.query_ras_error_count = &gfx_v9_0_query_ras_error_count,
.reset_ras_error_count = &gfx_v9_0_reset_ras_error_count,
const struct amdgpu_ras_block_hw_ops gfx_v9_0_ras_ops = {
.ras_error_inject = &gfx_v9_0_ras_error_inject,
.query_ras_error_count = &gfx_v9_0_query_ras_error_count,
.reset_ras_error_count = &gfx_v9_0_reset_ras_error_count,
};
static struct amdgpu_gfx_ras gfx_v9_0_ras = {
.ras_block = {
.hw_ops = &gfx_v9_0_ras_ops,
},
};
static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
@ -2231,7 +2121,7 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
DRM_INFO("fix gfx.config for vega12\n");
break;
case IP_VERSION(9, 4, 0):
adev->gfx.ras_funcs = &gfx_v9_0_ras_funcs;
adev->gfx.ras = &gfx_v9_0_ras;
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;
@ -2258,7 +2148,7 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
gb_addr_config = RAVEN_GB_ADDR_CONFIG_GOLDEN;
break;
case IP_VERSION(9, 4, 1):
adev->gfx.ras_funcs = &gfx_v9_4_ras_funcs;
adev->gfx.ras = &gfx_v9_4_ras;
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;
@ -2279,7 +2169,7 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
gb_addr_config |= 0x22010042;
break;
case IP_VERSION(9, 4, 2):
adev->gfx.ras_funcs = &gfx_v9_4_2_ras_funcs;
adev->gfx.ras = &gfx_v9_4_2_ras;
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;
@ -2298,6 +2188,25 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
break;
}
if (adev->gfx.ras) {
err = amdgpu_ras_register_ras_block(adev, &adev->gfx.ras->ras_block);
if (err) {
DRM_ERROR("Failed to register gfx ras block!\n");
return err;
}
strcpy(adev->gfx.ras->ras_block.name,"gfx");
adev->gfx.ras->ras_block.block = AMDGPU_RAS_BLOCK__GFX;
/* If not define special ras_late_init function, use gfx default ras_late_init */
if (!adev->gfx.ras->ras_block.ras_late_init)
adev->gfx.ras->ras_block.ras_late_init = amdgpu_gfx_ras_late_init;
/* If not define special ras_fini function, use gfx default ras_fini */
if (!adev->gfx.ras->ras_block.ras_fini)
adev->gfx.ras->ras_block.ras_fini = amdgpu_gfx_ras_fini;
}
adev->gfx.config.gb_addr_config = gb_addr_config;
adev->gfx.config.gb_addr_config_fields.num_pipes = 1 <<
@ -2434,10 +2343,14 @@ static int gfx_v9_0_sw_init(void *handle)
return r;
}
r = adev->gfx.rlc.funcs->init(adev);
if (r) {
DRM_ERROR("Failed to init rlc BOs!\n");
return r;
if (adev->gfx.rlc.funcs) {
if (adev->gfx.rlc.funcs->init) {
r = adev->gfx.rlc.funcs->init(adev);
if (r) {
dev_err(adev->dev, "Failed to init rlc BOs!\n");
return r;
}
}
}
r = gfx_v9_0_mec_init(adev);
@ -2513,9 +2426,8 @@ static int gfx_v9_0_sw_fini(void *handle)
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (adev->gfx.ras_funcs &&
adev->gfx.ras_funcs->ras_fini)
adev->gfx.ras_funcs->ras_fini(adev);
if (adev->gfx.ras && adev->gfx.ras->ras_block.ras_fini)
adev->gfx.ras->ras_block.ras_fini(adev);
for (i = 0; i < adev->gfx.num_gfx_rings; i++)
amdgpu_ring_fini(&adev->gfx.gfx_ring[i]);
@ -4840,6 +4752,9 @@ static int gfx_v9_0_early_init(void *handle)
gfx_v9_0_set_gds_init(adev);
gfx_v9_0_set_rlc_funcs(adev);
/* init rlcg reg access ctrl */
gfx_v9_0_init_rlcg_reg_access_ctrl(adev);
return 0;
}
@ -4870,16 +4785,15 @@ static int gfx_v9_0_ecc_late_init(void *handle)
if (r)
return r;
if (adev->gfx.ras_funcs &&
adev->gfx.ras_funcs->ras_late_init) {
r = adev->gfx.ras_funcs->ras_late_init(adev);
if (adev->gfx.ras && adev->gfx.ras->ras_block.ras_late_init) {
r = adev->gfx.ras->ras_block.ras_late_init(adev, NULL);
if (r)
return r;
}
if (adev->gfx.ras_funcs &&
adev->gfx.ras_funcs->enable_watchdog_timer)
adev->gfx.ras_funcs->enable_watchdog_timer(adev);
if (adev->gfx.ras &&
adev->gfx.ras->enable_watchdog_timer)
adev->gfx.ras->enable_watchdog_timer(adev);
return 0;
}
@ -5250,8 +5164,6 @@ static const struct amdgpu_rlc_funcs gfx_v9_0_rlc_funcs = {
.reset = gfx_v9_0_rlc_reset,
.start = gfx_v9_0_rlc_start,
.update_spm_vmid = gfx_v9_0_update_spm_vmid,
.sriov_wreg = gfx_v9_0_sriov_wreg,
.sriov_rreg = gfx_v9_0_sriov_rreg,
.is_rlcg_access_range = gfx_v9_0_is_rlcg_access_range,
};
@ -6819,7 +6731,7 @@ static void gfx_v9_0_reset_ras_error_count(struct amdgpu_device *adev)
WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, 255);
}
static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
static void gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
void *ras_error_status)
{
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
@ -6828,7 +6740,7 @@ static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
uint32_t reg_value;
if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
return -EINVAL;
return;
err_data->ue_count = 0;
err_data->ce_count = 0;
@ -6857,8 +6769,6 @@ static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
mutex_unlock(&adev->grbm_idx_mutex);
gfx_v9_0_query_utc_edc_status(adev, err_data);
return 0;
}
static void gfx_v9_0_emit_mem_sync(struct amdgpu_ring *ring)

View File

@ -863,7 +863,7 @@ static int gfx_v9_4_ras_error_count(struct amdgpu_device *adev,
return 0;
}
static int gfx_v9_4_query_ras_error_count(struct amdgpu_device *adev,
static void gfx_v9_4_query_ras_error_count(struct amdgpu_device *adev,
void *ras_error_status)
{
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
@ -872,7 +872,7 @@ static int gfx_v9_4_query_ras_error_count(struct amdgpu_device *adev,
uint32_t reg_value;
if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
return -EINVAL;
return;
err_data->ue_count = 0;
err_data->ce_count = 0;
@ -903,7 +903,6 @@ static int gfx_v9_4_query_ras_error_count(struct amdgpu_device *adev,
gfx_v9_4_query_utc_edc_status(adev, err_data);
return 0;
}
static void gfx_v9_4_reset_ras_error_count(struct amdgpu_device *adev)
@ -1029,11 +1028,16 @@ static void gfx_v9_4_query_ras_error_status(struct amdgpu_device *adev)
mutex_unlock(&adev->grbm_idx_mutex);
}
const struct amdgpu_gfx_ras_funcs gfx_v9_4_ras_funcs = {
.ras_late_init = amdgpu_gfx_ras_late_init,
.ras_fini = amdgpu_gfx_ras_fini,
.ras_error_inject = &gfx_v9_4_ras_error_inject,
.query_ras_error_count = &gfx_v9_4_query_ras_error_count,
.reset_ras_error_count = &gfx_v9_4_reset_ras_error_count,
.query_ras_error_status = &gfx_v9_4_query_ras_error_status,
const struct amdgpu_ras_block_hw_ops gfx_v9_4_ras_ops = {
.ras_error_inject = &gfx_v9_4_ras_error_inject,
.query_ras_error_count = &gfx_v9_4_query_ras_error_count,
.reset_ras_error_count = &gfx_v9_4_reset_ras_error_count,
.query_ras_error_status = &gfx_v9_4_query_ras_error_status,
};
struct amdgpu_gfx_ras gfx_v9_4_ras = {
.ras_block = {
.hw_ops = &gfx_v9_4_ras_ops,
},
};

View File

@ -24,6 +24,6 @@
#ifndef __GFX_V9_4_H__
#define __GFX_V9_4_H__
extern const struct amdgpu_gfx_ras_funcs gfx_v9_4_ras_funcs;
extern struct amdgpu_gfx_ras gfx_v9_4_ras;
#endif /* __GFX_V9_4_H__ */

View File

@ -1641,14 +1641,14 @@ static int gfx_v9_4_2_query_utc_edc_count(struct amdgpu_device *adev,
return 0;
}
static int gfx_v9_4_2_query_ras_error_count(struct amdgpu_device *adev,
static void gfx_v9_4_2_query_ras_error_count(struct amdgpu_device *adev,
void *ras_error_status)
{
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
uint32_t sec_count = 0, ded_count = 0;
if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
return -EINVAL;
return;
err_data->ue_count = 0;
err_data->ce_count = 0;
@ -1661,7 +1661,6 @@ static int gfx_v9_4_2_query_ras_error_count(struct amdgpu_device *adev,
err_data->ce_count += sec_count;
err_data->ue_count += ded_count;
return 0;
}
static void gfx_v9_4_2_reset_utc_err_status(struct amdgpu_device *adev)
@ -1931,13 +1930,17 @@ static void gfx_v9_4_2_reset_sq_timeout_status(struct amdgpu_device *adev)
mutex_unlock(&adev->grbm_idx_mutex);
}
const struct amdgpu_gfx_ras_funcs gfx_v9_4_2_ras_funcs = {
.ras_late_init = amdgpu_gfx_ras_late_init,
.ras_fini = amdgpu_gfx_ras_fini,
.ras_error_inject = &gfx_v9_4_2_ras_error_inject,
.query_ras_error_count = &gfx_v9_4_2_query_ras_error_count,
.reset_ras_error_count = &gfx_v9_4_2_reset_ras_error_count,
.query_ras_error_status = &gfx_v9_4_2_query_ras_error_status,
.reset_ras_error_status = &gfx_v9_4_2_reset_ras_error_status,
struct amdgpu_ras_block_hw_ops gfx_v9_4_2_ras_ops = {
.ras_error_inject = &gfx_v9_4_2_ras_error_inject,
.query_ras_error_count = &gfx_v9_4_2_query_ras_error_count,
.reset_ras_error_count = &gfx_v9_4_2_reset_ras_error_count,
.query_ras_error_status = &gfx_v9_4_2_query_ras_error_status,
.reset_ras_error_status = &gfx_v9_4_2_reset_ras_error_status,
};
struct amdgpu_gfx_ras gfx_v9_4_2_ras = {
.ras_block = {
.hw_ops = &gfx_v9_4_2_ras_ops,
},
.enable_watchdog_timer = &gfx_v9_4_2_enable_watchdog_timer,
};

View File

@ -31,6 +31,6 @@ void gfx_v9_4_2_init_golden_registers(struct amdgpu_device *adev,
void gfx_v9_4_2_set_power_brake_sequence(struct amdgpu_device *adev);
int gfx_v9_4_2_do_edc_gpr_workarounds(struct amdgpu_device *adev);
extern const struct amdgpu_gfx_ras_funcs gfx_v9_4_2_ras_funcs;
extern struct amdgpu_gfx_ras gfx_v9_4_2_ras;
#endif /* __GFX_V9_4_2_H__ */

View File

@ -543,7 +543,9 @@ static void gfxhub_v2_1_utcl2_harvest(struct amdgpu_device *adev)
adev->gfx.config.max_sh_per_se *
adev->gfx.config.max_shader_engines);
if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 3)) {
switch (adev->ip_versions[GC_HWIP][0]) {
case IP_VERSION(10, 3, 1):
case IP_VERSION(10, 3, 3):
/* Get SA disabled bitmap from eFuse setting */
efuse_setting = RREG32_SOC15(GC, 0, mmCC_GC_SA_UNIT_DISABLE);
efuse_setting &= CC_GC_SA_UNIT_DISABLE__SA_DISABLE_MASK;
@ -566,6 +568,9 @@ static void gfxhub_v2_1_utcl2_harvest(struct amdgpu_device *adev)
disabled_sa = tmp;
WREG32_SOC15(GC, 0, mmGCUTCL2_HARVEST_BYPASS_GROUPS_YELLOW_CARP, disabled_sa);
break;
default:
break;
}
}

View File

@ -664,11 +664,25 @@ static void gmc_v10_0_set_umc_funcs(struct amdgpu_device *adev)
adev->umc.umc_inst_num = UMC_V8_7_UMC_INSTANCE_NUM;
adev->umc.channel_offs = UMC_V8_7_PER_CHANNEL_OFFSET_SIENNA;
adev->umc.channel_idx_tbl = &umc_v8_7_channel_idx_tbl[0][0];
adev->umc.ras_funcs = &umc_v8_7_ras_funcs;
adev->umc.ras = &umc_v8_7_ras;
break;
default:
break;
}
if (adev->umc.ras) {
amdgpu_ras_register_ras_block(adev, &adev->umc.ras->ras_block);
strcpy(adev->umc.ras->ras_block.name, "umc");
adev->umc.ras->ras_block.block = AMDGPU_RAS_BLOCK__UMC;
/* If don't define special ras_late_init function, use default ras_late_init */
if (!adev->umc.ras->ras_block.ras_late_init)
adev->umc.ras->ras_block.ras_late_init = amdgpu_umc_ras_late_init;
/* If don't define special ras_fini function, use default ras_fini */
if (!adev->umc.ras->ras_block.ras_fini)
adev->umc.ras->ras_block.ras_fini = amdgpu_umc_ras_fini;
}
}
@ -705,6 +719,7 @@ static void gmc_v10_0_set_gfxhub_funcs(struct amdgpu_device *adev)
static int gmc_v10_0_early_init(void *handle)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
gmc_v10_0_set_mmhub_funcs(adev);
@ -720,6 +735,10 @@ static int gmc_v10_0_early_init(void *handle)
adev->gmc.private_aperture_end =
adev->gmc.private_aperture_start + (4ULL << 30) - 1;
r = amdgpu_gmc_ras_early_init(adev);
if (r)
return r;
return 0;
}
@ -862,6 +881,7 @@ static int gmc_v10_0_sw_init(void *handle)
case IP_VERSION(10, 1, 1):
case IP_VERSION(10, 1, 2):
case IP_VERSION(10, 1, 3):
case IP_VERSION(10, 1, 4):
case IP_VERSION(10, 3, 0):
case IP_VERSION(10, 3, 2):
case IP_VERSION(10, 3, 1):
@ -986,14 +1006,7 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev)
return -EINVAL;
}
if (amdgpu_sriov_vf(adev) && amdgpu_in_reset(adev))
goto skip_pin_bo;
r = amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
if (r)
return r;
skip_pin_bo:
amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
r = adev->gfxhub.funcs->gart_enable(adev);
if (r)
return r;
@ -1019,8 +1032,6 @@ skip_pin_bo:
(unsigned)(adev->gmc.gart_size >> 20),
(unsigned long long)amdgpu_bo_gpu_offset(adev->gart.bo));
adev->gart.ready = true;
return 0;
}
@ -1043,6 +1054,12 @@ static int gmc_v10_0_hw_init(void *handle)
if (r)
return r;
if (amdgpu_emu_mode == 1) {
r = amdgpu_gmc_vram_checking(adev);
if (r)
return r;
}
if (adev->umc.funcs && adev->umc.funcs->init_registers)
adev->umc.funcs->init_registers(adev);
@ -1140,6 +1157,10 @@ static void gmc_v10_0_get_clockgating_state(void *handle, u32 *flags)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 3) ||
adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 4))
return;
adev->mmhub.funcs->get_clockgating(adev, flags);
if (adev->ip_versions[ATHUB_HWIP][0] >= IP_VERSION(2, 1, 0))

View File

@ -469,16 +469,14 @@ static void gmc_v6_0_set_prt(struct amdgpu_device *adev, bool enable)
static int gmc_v6_0_gart_enable(struct amdgpu_device *adev)
{
uint64_t table_addr;
int r, i;
u32 field;
int i;
if (adev->gart.bo == NULL) {
dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
return -EINVAL;
}
r = amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
if (r)
return r;
amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
table_addr = amdgpu_bo_gpu_offset(adev->gart.bo);
@ -558,7 +556,6 @@ static int gmc_v6_0_gart_enable(struct amdgpu_device *adev)
dev_info(adev->dev, "PCIE GART of %uM enabled (table at 0x%016llX).\n",
(unsigned)(adev->gmc.gart_size >> 20),
(unsigned long long)table_addr);
adev->gart.ready = true;
return 0;
}
@ -922,7 +919,10 @@ static int gmc_v6_0_hw_init(void *handle)
if (r)
return r;
return r;
if (amdgpu_emu_mode == 1)
return amdgpu_gmc_vram_checking(adev);
else
return r;
}
static int gmc_v6_0_hw_fini(void *handle)

View File

@ -613,17 +613,14 @@ static void gmc_v7_0_set_prt(struct amdgpu_device *adev, bool enable)
static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
{
uint64_t table_addr;
int r, i;
u32 tmp, field;
int i;
if (adev->gart.bo == NULL) {
dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
return -EINVAL;
}
r = amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
if (r)
return r;
amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
table_addr = amdgpu_bo_gpu_offset(adev->gart.bo);
/* Setup TLB control */
@ -712,7 +709,6 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
(unsigned)(adev->gmc.gart_size >> 20),
(unsigned long long)table_addr);
adev->gart.ready = true;
return 0;
}
@ -1111,7 +1107,10 @@ static int gmc_v7_0_hw_init(void *handle)
if (r)
return r;
return r;
if (amdgpu_emu_mode == 1)
return amdgpu_gmc_vram_checking(adev);
else
return r;
}
static int gmc_v7_0_hw_fini(void *handle)

View File

@ -837,17 +837,14 @@ static void gmc_v8_0_set_prt(struct amdgpu_device *adev, bool enable)
static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
{
uint64_t table_addr;
int r, i;
u32 tmp, field;
int i;
if (adev->gart.bo == NULL) {
dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
return -EINVAL;
}
r = amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
if (r)
return r;
amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
table_addr = amdgpu_bo_gpu_offset(adev->gart.bo);
/* Setup TLB control */
@ -953,7 +950,6 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
(unsigned)(adev->gmc.gart_size >> 20),
(unsigned long long)table_addr);
adev->gart.ready = true;
return 0;
}
@ -1242,7 +1238,10 @@ static int gmc_v8_0_hw_init(void *handle)
if (r)
return r;
return r;
if (amdgpu_emu_mode == 1)
return amdgpu_gmc_vram_checking(adev);
else
return r;
}
static int gmc_v8_0_hw_fini(void *handle)

View File

@ -1202,7 +1202,7 @@ static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev)
adev->umc.umc_inst_num = UMC_V6_1_UMC_INSTANCE_NUM;
adev->umc.channel_offs = UMC_V6_1_PER_CHANNEL_OFFSET_VG20;
adev->umc.channel_idx_tbl = &umc_v6_1_channel_idx_tbl[0][0];
adev->umc.ras_funcs = &umc_v6_1_ras_funcs;
adev->umc.ras = &umc_v6_1_ras;
break;
case IP_VERSION(6, 1, 2):
adev->umc.max_ras_err_cnt_per_query = UMC_V6_1_TOTAL_CHANNEL_NUM;
@ -1210,15 +1210,16 @@ static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev)
adev->umc.umc_inst_num = UMC_V6_1_UMC_INSTANCE_NUM;
adev->umc.channel_offs = UMC_V6_1_PER_CHANNEL_OFFSET_ARCT;
adev->umc.channel_idx_tbl = &umc_v6_1_channel_idx_tbl[0][0];
adev->umc.ras_funcs = &umc_v6_1_ras_funcs;
adev->umc.ras = &umc_v6_1_ras;
break;
case IP_VERSION(6, 7, 0):
adev->umc.max_ras_err_cnt_per_query = UMC_V6_7_TOTAL_CHANNEL_NUM;
adev->umc.max_ras_err_cnt_per_query =
UMC_V6_7_TOTAL_CHANNEL_NUM * UMC_V6_7_BAD_PAGE_NUM_PER_CHANNEL;
adev->umc.channel_inst_num = UMC_V6_7_CHANNEL_INSTANCE_NUM;
adev->umc.umc_inst_num = UMC_V6_7_UMC_INSTANCE_NUM;
adev->umc.channel_offs = UMC_V6_7_PER_CHANNEL_OFFSET;
if (!adev->gmc.xgmi.connected_to_cpu)
adev->umc.ras_funcs = &umc_v6_7_ras_funcs;
adev->umc.ras = &umc_v6_7_ras;
if (1 & adev->smuio.funcs->get_die_id(adev))
adev->umc.channel_idx_tbl = &umc_v6_7_channel_idx_tbl_first[0][0];
else
@ -1227,6 +1228,21 @@ static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev)
default:
break;
}
if (adev->umc.ras) {
amdgpu_ras_register_ras_block(adev, &adev->umc.ras->ras_block);
strcpy(adev->umc.ras->ras_block.name, "umc");
adev->umc.ras->ras_block.block = AMDGPU_RAS_BLOCK__UMC;
/* If don't define special ras_late_init function, use default ras_late_init */
if (!adev->umc.ras->ras_block.ras_late_init)
adev->umc.ras->ras_block.ras_late_init = amdgpu_umc_ras_late_init;
/* If don't define special ras_fini function, use default ras_fini */
if (!adev->umc.ras->ras_block.ras_fini)
adev->umc.ras->ras_block.ras_fini = amdgpu_umc_ras_fini;
}
}
static void gmc_v9_0_set_mmhub_funcs(struct amdgpu_device *adev)
@ -1248,18 +1264,33 @@ static void gmc_v9_0_set_mmhub_ras_funcs(struct amdgpu_device *adev)
{
switch (adev->ip_versions[MMHUB_HWIP][0]) {
case IP_VERSION(9, 4, 0):
adev->mmhub.ras_funcs = &mmhub_v1_0_ras_funcs;
adev->mmhub.ras = &mmhub_v1_0_ras;
break;
case IP_VERSION(9, 4, 1):
adev->mmhub.ras_funcs = &mmhub_v9_4_ras_funcs;
adev->mmhub.ras = &mmhub_v9_4_ras;
break;
case IP_VERSION(9, 4, 2):
adev->mmhub.ras_funcs = &mmhub_v1_7_ras_funcs;
adev->mmhub.ras = &mmhub_v1_7_ras;
break;
default:
/* mmhub ras is not available */
break;
}
if (adev->mmhub.ras) {
amdgpu_ras_register_ras_block(adev, &adev->mmhub.ras->ras_block);
strcpy(adev->mmhub.ras->ras_block.name,"mmhub");
adev->mmhub.ras->ras_block.block = AMDGPU_RAS_BLOCK__MMHUB;
/* If don't define special ras_late_init function, use default ras_late_init */
if (!adev->mmhub.ras->ras_block.ras_late_init)
adev->mmhub.ras->ras_block.ras_late_init = amdgpu_mmhub_ras_late_init;
/* If don't define special ras_fini function, use default ras_fini */
if (!adev->mmhub.ras->ras_block.ras_fini)
adev->mmhub.ras->ras_block.ras_fini = amdgpu_mmhub_ras_fini;
}
}
static void gmc_v9_0_set_gfxhub_funcs(struct amdgpu_device *adev)
@ -1269,7 +1300,8 @@ static void gmc_v9_0_set_gfxhub_funcs(struct amdgpu_device *adev)
static void gmc_v9_0_set_hdp_ras_funcs(struct amdgpu_device *adev)
{
adev->hdp.ras_funcs = &hdp_v4_0_ras_funcs;
adev->hdp.ras = &hdp_v4_0_ras;
amdgpu_ras_register_ras_block(adev, &adev->hdp.ras->ras_block);
}
static void gmc_v9_0_set_mca_funcs(struct amdgpu_device *adev)
@ -1287,6 +1319,7 @@ static void gmc_v9_0_set_mca_funcs(struct amdgpu_device *adev)
static int gmc_v9_0_early_init(void *handle)
{
int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
/* ARCT and VEGA20 don't have XGMI defined in their IP discovery tables */
@ -1316,6 +1349,10 @@ static int gmc_v9_0_early_init(void *handle)
adev->gmc.private_aperture_end =
adev->gmc.private_aperture_start + (4ULL << 30) - 1;
r = amdgpu_gmc_ras_early_init(adev);
if (r)
return r;
return 0;
}
@ -1342,13 +1379,13 @@ static int gmc_v9_0_late_init(void *handle)
}
if (!amdgpu_persistent_edc_harvesting_supported(adev)) {
if (adev->mmhub.ras_funcs &&
adev->mmhub.ras_funcs->reset_ras_error_count)
adev->mmhub.ras_funcs->reset_ras_error_count(adev);
if (adev->mmhub.ras && adev->mmhub.ras->ras_block.hw_ops &&
adev->mmhub.ras->ras_block.hw_ops->reset_ras_error_count)
adev->mmhub.ras->ras_block.hw_ops->reset_ras_error_count(adev);
if (adev->hdp.ras_funcs &&
adev->hdp.ras_funcs->reset_ras_error_count)
adev->hdp.ras_funcs->reset_ras_error_count(adev);
if (adev->hdp.ras && adev->hdp.ras->ras_block.hw_ops &&
adev->hdp.ras->ras_block.hw_ops->reset_ras_error_count)
adev->hdp.ras->ras_block.hw_ops->reset_ras_error_count(adev);
}
r = amdgpu_gmc_ras_late_init(adev);
@ -1752,14 +1789,7 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev)
return -EINVAL;
}
if (amdgpu_sriov_vf(adev) && amdgpu_in_reset(adev))
goto skip_pin_bo;
r = amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
if (r)
return r;
skip_pin_bo:
amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr);
r = adev->gfxhub.funcs->gart_enable(adev);
if (r)
return r;
@ -1776,7 +1806,6 @@ skip_pin_bo:
DRM_INFO("PTB located at 0x%016llX\n",
(unsigned long long)amdgpu_bo_gpu_offset(adev->gart.bo));
adev->gart.ready = true;
return 0;
}
@ -1784,7 +1813,7 @@ static int gmc_v9_0_hw_init(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
bool value;
int i;
int i, r;
/* The sequence of these two function calls matters.*/
gmc_v9_0_init_golden_registers(adev);
@ -1819,7 +1848,14 @@ static int gmc_v9_0_hw_init(void *handle)
if (adev->umc.funcs && adev->umc.funcs->init_registers)
adev->umc.funcs->init_registers(adev);
return gmc_v9_0_gart_enable(adev);
r = gmc_v9_0_gart_enable(adev);
if (r)
return r;
if (amdgpu_emu_mode == 1)
return amdgpu_gmc_vram_checking(adev);
else
return r;
}
/**

View File

@ -150,13 +150,21 @@ static void hdp_v4_0_init_registers(struct amdgpu_device *adev)
WREG32_SOC15(HDP, 0, mmHDP_NONSURFACE_BASE_HI, (adev->gmc.vram_start >> 40));
}
const struct amdgpu_hdp_ras_funcs hdp_v4_0_ras_funcs = {
.ras_late_init = amdgpu_hdp_ras_late_init,
.ras_fini = amdgpu_hdp_ras_fini,
struct amdgpu_ras_block_hw_ops hdp_v4_0_ras_hw_ops = {
.query_ras_error_count = hdp_v4_0_query_ras_error_count,
.reset_ras_error_count = hdp_v4_0_reset_ras_error_count,
};
struct amdgpu_hdp_ras hdp_v4_0_ras = {
.ras_block = {
.name = "hdp",
.block = AMDGPU_RAS_BLOCK__HDP,
.hw_ops = &hdp_v4_0_ras_hw_ops,
.ras_late_init = amdgpu_hdp_ras_late_init,
.ras_fini = amdgpu_hdp_ras_fini,
},
};
const struct amdgpu_hdp_funcs hdp_v4_0_funcs = {
.flush_hdp = hdp_v4_0_flush_hdp,
.invalidate_hdp = hdp_v4_0_invalidate_hdp,

View File

@ -27,6 +27,6 @@
#include "soc15_common.h"
extern const struct amdgpu_hdp_funcs hdp_v4_0_funcs;
extern const struct amdgpu_hdp_ras_funcs hdp_v4_0_ras_funcs;
extern struct amdgpu_hdp_ras hdp_v4_0_ras;
#endif

View File

@ -50,11 +50,16 @@ static int jpeg_v3_0_early_init(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (adev->asic_type != CHIP_YELLOW_CARP) {
u32 harvest = RREG32_SOC15(JPEG, 0, mmCC_UVD_HARVESTING);
u32 harvest;
switch (adev->ip_versions[UVD_HWIP][0]) {
case IP_VERSION(3, 1, 1):
break;
default:
harvest = RREG32_SOC15(JPEG, 0, mmCC_UVD_HARVESTING);
if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK)
return -ENOENT;
break;
}
adev->jpeg.num_jpeg_inst = 1;

View File

@ -37,7 +37,7 @@ static void mca_v3_0_mp0_query_ras_error_count(struct amdgpu_device *adev,
ras_error_status);
}
static int mca_v3_0_mp0_ras_late_init(struct amdgpu_device *adev)
static int mca_v3_0_mp0_ras_late_init(struct amdgpu_device *adev, void *ras_info)
{
return amdgpu_mca_ras_late_init(adev, &adev->mca.mp0);
}
@ -47,14 +47,35 @@ static void mca_v3_0_mp0_ras_fini(struct amdgpu_device *adev)
amdgpu_mca_ras_fini(adev, &adev->mca.mp0);
}
const struct amdgpu_mca_ras_funcs mca_v3_0_mp0_ras_funcs = {
.ras_late_init = mca_v3_0_mp0_ras_late_init,
.ras_fini = mca_v3_0_mp0_ras_fini,
static int mca_v3_0_ras_block_match(struct amdgpu_ras_block_object *block_obj,
enum amdgpu_ras_block block, uint32_t sub_block_index)
{
if (!block_obj)
return -EINVAL;
if ((block_obj->block == block) &&
(block_obj->sub_block_index == sub_block_index)) {
return 0;
}
return -EINVAL;
}
const struct amdgpu_ras_block_hw_ops mca_v3_0_mp0_hw_ops = {
.query_ras_error_count = mca_v3_0_mp0_query_ras_error_count,
.query_ras_error_address = NULL,
.ras_block = AMDGPU_RAS_BLOCK__MCA,
.ras_sub_block = AMDGPU_RAS_MCA_BLOCK__MP0,
.sysfs_name = "mp0_err_count",
};
struct amdgpu_mca_ras_block mca_v3_0_mp0_ras = {
.ras_block = {
.block = AMDGPU_RAS_BLOCK__MCA,
.sub_block_index = AMDGPU_RAS_MCA_BLOCK__MP0,
.name = "mp0",
.hw_ops = &mca_v3_0_mp0_hw_ops,
.ras_block_match = mca_v3_0_ras_block_match,
.ras_late_init = mca_v3_0_mp0_ras_late_init,
.ras_fini = mca_v3_0_mp0_ras_fini,
},
};
static void mca_v3_0_mp1_query_ras_error_count(struct amdgpu_device *adev,
@ -65,7 +86,7 @@ static void mca_v3_0_mp1_query_ras_error_count(struct amdgpu_device *adev,
ras_error_status);
}
static int mca_v3_0_mp1_ras_late_init(struct amdgpu_device *adev)
static int mca_v3_0_mp1_ras_late_init(struct amdgpu_device *adev, void *ras_info)
{
return amdgpu_mca_ras_late_init(adev, &adev->mca.mp1);
}
@ -75,14 +96,21 @@ static void mca_v3_0_mp1_ras_fini(struct amdgpu_device *adev)
amdgpu_mca_ras_fini(adev, &adev->mca.mp1);
}
const struct amdgpu_mca_ras_funcs mca_v3_0_mp1_ras_funcs = {
.ras_late_init = mca_v3_0_mp1_ras_late_init,
.ras_fini = mca_v3_0_mp1_ras_fini,
const struct amdgpu_ras_block_hw_ops mca_v3_0_mp1_hw_ops = {
.query_ras_error_count = mca_v3_0_mp1_query_ras_error_count,
.query_ras_error_address = NULL,
.ras_block = AMDGPU_RAS_BLOCK__MCA,
.ras_sub_block = AMDGPU_RAS_MCA_BLOCK__MP1,
.sysfs_name = "mp1_err_count",
};
struct amdgpu_mca_ras_block mca_v3_0_mp1_ras = {
.ras_block = {
.block = AMDGPU_RAS_BLOCK__MCA,
.sub_block_index = AMDGPU_RAS_MCA_BLOCK__MP1,
.name = "mp1",
.hw_ops = &mca_v3_0_mp1_hw_ops,
.ras_block_match = mca_v3_0_ras_block_match,
.ras_late_init = mca_v3_0_mp1_ras_late_init,
.ras_fini = mca_v3_0_mp1_ras_fini,
},
};
static void mca_v3_0_mpio_query_ras_error_count(struct amdgpu_device *adev,
@ -93,7 +121,7 @@ static void mca_v3_0_mpio_query_ras_error_count(struct amdgpu_device *adev,
ras_error_status);
}
static int mca_v3_0_mpio_ras_late_init(struct amdgpu_device *adev)
static int mca_v3_0_mpio_ras_late_init(struct amdgpu_device *adev, void *ras_info)
{
return amdgpu_mca_ras_late_init(adev, &adev->mca.mpio);
}
@ -103,14 +131,21 @@ static void mca_v3_0_mpio_ras_fini(struct amdgpu_device *adev)
amdgpu_mca_ras_fini(adev, &adev->mca.mpio);
}
const struct amdgpu_mca_ras_funcs mca_v3_0_mpio_ras_funcs = {
.ras_late_init = mca_v3_0_mpio_ras_late_init,
.ras_fini = mca_v3_0_mpio_ras_fini,
const struct amdgpu_ras_block_hw_ops mca_v3_0_mpio_hw_ops = {
.query_ras_error_count = mca_v3_0_mpio_query_ras_error_count,
.query_ras_error_address = NULL,
.ras_block = AMDGPU_RAS_BLOCK__MCA,
.ras_sub_block = AMDGPU_RAS_MCA_BLOCK__MPIO,
.sysfs_name = "mpio_err_count",
};
struct amdgpu_mca_ras_block mca_v3_0_mpio_ras = {
.ras_block = {
.block = AMDGPU_RAS_BLOCK__MCA,
.sub_block_index = AMDGPU_RAS_MCA_BLOCK__MPIO,
.name = "mpio",
.hw_ops = &mca_v3_0_mpio_hw_ops,
.ras_block_match = mca_v3_0_ras_block_match,
.ras_late_init = mca_v3_0_mpio_ras_late_init,
.ras_fini = mca_v3_0_mpio_ras_fini,
},
};
@ -118,9 +153,12 @@ static void mca_v3_0_init(struct amdgpu_device *adev)
{
struct amdgpu_mca *mca = &adev->mca;
mca->mp0.ras_funcs = &mca_v3_0_mp0_ras_funcs;
mca->mp1.ras_funcs = &mca_v3_0_mp1_ras_funcs;
mca->mpio.ras_funcs = &mca_v3_0_mpio_ras_funcs;
mca->mp0.ras = &mca_v3_0_mp0_ras;
mca->mp1.ras = &mca_v3_0_mp1_ras;
mca->mpio.ras = &mca_v3_0_mpio_ras;
amdgpu_ras_register_ras_block(adev, &mca->mp0.ras->ras_block);
amdgpu_ras_register_ras_block(adev, &mca->mp1.ras->ras_block);
amdgpu_ras_register_ras_block(adev, &mca->mpio.ras->ras_block);
}
const struct amdgpu_mca_funcs mca_v3_0_funcs = {

View File

@ -774,13 +774,17 @@ static void mmhub_v1_0_reset_ras_error_count(struct amdgpu_device *adev)
}
}
const struct amdgpu_mmhub_ras_funcs mmhub_v1_0_ras_funcs = {
.ras_late_init = amdgpu_mmhub_ras_late_init,
.ras_fini = amdgpu_mmhub_ras_fini,
struct amdgpu_ras_block_hw_ops mmhub_v1_0_ras_hw_ops = {
.query_ras_error_count = mmhub_v1_0_query_ras_error_count,
.reset_ras_error_count = mmhub_v1_0_reset_ras_error_count,
};
struct amdgpu_mmhub_ras mmhub_v1_0_ras = {
.ras_block = {
.hw_ops = &mmhub_v1_0_ras_hw_ops,
},
};
const struct amdgpu_mmhub_funcs mmhub_v1_0_funcs = {
.get_fb_location = mmhub_v1_0_get_fb_location,
.init = mmhub_v1_0_init,

View File

@ -24,6 +24,6 @@
#define __MMHUB_V1_0_H__
extern const struct amdgpu_mmhub_funcs mmhub_v1_0_funcs;
extern const struct amdgpu_mmhub_ras_funcs mmhub_v1_0_ras_funcs;
extern struct amdgpu_mmhub_ras mmhub_v1_0_ras;
#endif

View File

@ -1321,15 +1321,19 @@ static void mmhub_v1_7_reset_ras_error_status(struct amdgpu_device *adev)
}
}
const struct amdgpu_mmhub_ras_funcs mmhub_v1_7_ras_funcs = {
.ras_late_init = amdgpu_mmhub_ras_late_init,
.ras_fini = amdgpu_mmhub_ras_fini,
struct amdgpu_ras_block_hw_ops mmhub_v1_7_ras_hw_ops = {
.query_ras_error_count = mmhub_v1_7_query_ras_error_count,
.reset_ras_error_count = mmhub_v1_7_reset_ras_error_count,
.query_ras_error_status = mmhub_v1_7_query_ras_error_status,
.reset_ras_error_status = mmhub_v1_7_reset_ras_error_status,
};
struct amdgpu_mmhub_ras mmhub_v1_7_ras = {
.ras_block = {
.hw_ops = &mmhub_v1_7_ras_hw_ops,
},
};
const struct amdgpu_mmhub_funcs mmhub_v1_7_funcs = {
.get_fb_location = mmhub_v1_7_get_fb_location,
.init = mmhub_v1_7_init,

View File

@ -24,6 +24,6 @@
#define __MMHUB_V1_7_H__
extern const struct amdgpu_mmhub_funcs mmhub_v1_7_funcs;
extern const struct amdgpu_mmhub_ras_funcs mmhub_v1_7_ras_funcs;
extern struct amdgpu_mmhub_ras mmhub_v1_7_ras;
#endif

View File

@ -1655,14 +1655,18 @@ static void mmhub_v9_4_query_ras_error_status(struct amdgpu_device *adev)
}
}
const struct amdgpu_mmhub_ras_funcs mmhub_v9_4_ras_funcs = {
.ras_late_init = amdgpu_mmhub_ras_late_init,
.ras_fini = amdgpu_mmhub_ras_fini,
const struct amdgpu_ras_block_hw_ops mmhub_v9_4_ras_hw_ops = {
.query_ras_error_count = mmhub_v9_4_query_ras_error_count,
.reset_ras_error_count = mmhub_v9_4_reset_ras_error_count,
.query_ras_error_status = mmhub_v9_4_query_ras_error_status,
};
struct amdgpu_mmhub_ras mmhub_v9_4_ras = {
.ras_block = {
.hw_ops = &mmhub_v9_4_ras_hw_ops,
},
};
const struct amdgpu_mmhub_funcs mmhub_v9_4_funcs = {
.get_fb_location = mmhub_v9_4_get_fb_location,
.init = mmhub_v9_4_init,

View File

@ -24,6 +24,6 @@
#define __MMHUB_V9_4_H__
extern const struct amdgpu_mmhub_funcs mmhub_v9_4_funcs;
extern const struct amdgpu_mmhub_ras_funcs mmhub_v9_4_ras_funcs;
extern struct amdgpu_mmhub_ras mmhub_v9_4_ras;
#endif

View File

@ -544,7 +544,7 @@ static int xgpu_vi_mailbox_rcv_irq(struct amdgpu_device *adev,
{
int r;
/* trigger gpu-reset by hypervisor only if TDR disbaled */
/* trigger gpu-reset by hypervisor only if TDR disabled */
if (!amdgpu_gpu_recovery) {
/* see what event we get */
r = xgpu_vi_mailbox_rcv_msg(adev, IDH_FLR_NOTIFICATION);

View File

@ -59,10 +59,15 @@ static u32 nbio_v7_2_get_rev_id(struct amdgpu_device *adev)
{
u32 tmp;
if (adev->asic_type == CHIP_YELLOW_CARP)
switch (adev->ip_versions[NBIO_HWIP][0]) {
case IP_VERSION(7, 2, 1):
case IP_VERSION(7, 5, 0):
tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_YC);
else
break;
default:
tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0);
break;
}
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;
@ -72,20 +77,25 @@ static u32 nbio_v7_2_get_rev_id(struct amdgpu_device *adev)
static void nbio_v7_2_mc_access_enable(struct amdgpu_device *adev, bool enable)
{
if (enable)
if (adev->asic_type == CHIP_YELLOW_CARP)
switch (adev->ip_versions[NBIO_HWIP][0]) {
case IP_VERSION(7, 2, 1):
case IP_VERSION(7, 5, 0):
if (enable)
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN_YC,
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_YC, 0);
break;
default:
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
if (adev->asic_type == CHIP_YELLOW_CARP)
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN_YC, 0);
else
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_FB_EN, 0);
break;
}
}
static u32 nbio_v7_2_get_memsize(struct amdgpu_device *adev)
@ -250,7 +260,9 @@ static void nbio_v7_2_update_medium_grain_light_sleep(struct amdgpu_device *adev
{
uint32_t def, data;
if (adev->asic_type == CHIP_YELLOW_CARP) {
switch (adev->ip_versions[NBIO_HWIP][0]) {
case IP_VERSION(7, 2, 1):
case IP_VERSION(7, 5, 0):
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;
@ -260,8 +272,8 @@ static void nbio_v7_2_update_medium_grain_light_sleep(struct amdgpu_device *adev
if (def != data)
WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CNTL2), data);
data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regBIF1_PCIE_TX_POWER_CTRL_1));
def = data;
def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0,
regBIF1_PCIE_TX_POWER_CTRL_1));
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_BIF_LS))
data |= (BIF1_PCIE_TX_POWER_CTRL_1__MST_MEM_LS_EN_MASK |
BIF1_PCIE_TX_POWER_CTRL_1__REPLAY_MEM_LS_EN_MASK);
@ -272,7 +284,8 @@ static void nbio_v7_2_update_medium_grain_light_sleep(struct amdgpu_device *adev
if (def != data)
WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regBIF1_PCIE_TX_POWER_CTRL_1),
data);
} else {
break;
default:
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 |
@ -285,6 +298,7 @@ static void nbio_v7_2_update_medium_grain_light_sleep(struct amdgpu_device *adev
if (def != data)
WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CNTL2), data);
break;
}
}
@ -352,7 +366,9 @@ const struct nbio_hdp_flush_reg nbio_v7_2_hdp_flush_reg = {
static void nbio_v7_2_init_registers(struct amdgpu_device *adev)
{
uint32_t def, data;
if (adev->asic_type == CHIP_YELLOW_CARP) {
switch (adev->ip_versions[NBIO_HWIP][0]) {
case IP_VERSION(7, 2, 1):
case IP_VERSION(7, 5, 0):
def = data = RREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regBIF1_PCIE_MST_CTRL_3));
data = REG_SET_FIELD(data, BIF1_PCIE_MST_CTRL_3,
CI_SWUS_MAX_READ_REQUEST_SIZE_MODE, 1);
@ -361,7 +377,8 @@ static void nbio_v7_2_init_registers(struct amdgpu_device *adev)
if (def != data)
WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regBIF1_PCIE_MST_CTRL_3), data);
} else {
break;
default:
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);
@ -370,6 +387,7 @@ static void nbio_v7_2_init_registers(struct amdgpu_device *adev)
if (def != data)
WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CONFIG_CNTL), data);
break;
}
if (amdgpu_sriov_vf(adev))

View File

@ -658,16 +658,25 @@ static void nbio_v7_4_enable_doorbell_interrupt(struct amdgpu_device *adev,
DOORBELL_INTERRUPT_DISABLE, enable ? 0 : 1);
}
const struct amdgpu_nbio_ras_funcs nbio_v7_4_ras_funcs = {
const struct amdgpu_ras_block_hw_ops nbio_v7_4_ras_hw_ops = {
.query_ras_error_count = nbio_v7_4_query_ras_error_count,
};
struct amdgpu_nbio_ras nbio_v7_4_ras = {
.ras_block = {
.name = "pcie_bif",
.block = AMDGPU_RAS_BLOCK__PCIE_BIF,
.hw_ops = &nbio_v7_4_ras_hw_ops,
.ras_late_init = amdgpu_nbio_ras_late_init,
.ras_fini = amdgpu_nbio_ras_fini,
},
.handle_ras_controller_intr_no_bifring = nbio_v7_4_handle_ras_controller_intr_no_bifring,
.handle_ras_err_event_athub_intr_no_bifring = nbio_v7_4_handle_ras_err_event_athub_intr_no_bifring,
.init_ras_controller_interrupt = nbio_v7_4_init_ras_controller_interrupt,
.init_ras_err_event_athub_interrupt = nbio_v7_4_init_ras_err_event_athub_interrupt,
.query_ras_error_count = nbio_v7_4_query_ras_error_count,
.ras_late_init = amdgpu_nbio_ras_late_init,
.ras_fini = amdgpu_nbio_ras_fini,
};
static void nbio_v7_4_program_ltr(struct amdgpu_device *adev)
{
uint32_t def, data;

View File

@ -29,6 +29,6 @@
extern const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg;
extern const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg_ald;
extern const struct amdgpu_nbio_funcs nbio_v7_4_funcs;
extern const struct amdgpu_nbio_ras_funcs nbio_v7_4_ras_funcs;
extern struct amdgpu_nbio_ras nbio_v7_4_ras;
#endif

Some files were not shown because too many files have changed in this diff Show More