amd-drm-next-6.10-2024-04-26:
amdgpu: - Misc code cleanups and refactors - Support setting reset method at runtime - Report OD status - SMU 14.0.1 fixes - SDMA 4.4.2 fixes - VPE fixes - MES fixes - Update BO eviction priorities - UMSCH fixes - Reset fixes - Freesync fixes - GFXIP 9.4.3 fixes - SDMA 5.2 fixes - MES UAF fix - RAS updates - Devcoredump updates for dumping IP state - DSC fixes - JPEG fix - Fix VRAM memory accounting - VCN 5.0 fixes - MES fixes - UMC 12.0 updates - Modify contiguous flags handling - Initial support for mapping kernel queues via MES amdkfd: - Fix rescheduling of restore worker - VRAM accounting for SVM migrations - mGPU fix - Enable SQ watchpoint for gfx10 -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCZiwmAQAKCRC93/aFa7yZ 2Hp0AP9SOxHrKDPErqCQbenkZXNoPFtLJWAhhKZ9zEb7YgjufwD/Zpk31mO0FpVu kUYSAQ4OFXinVVLtmVH3fE/vK+1ccwM= =oFW7 -----END PGP SIGNATURE----- Merge tag 'amd-drm-next-6.10-2024-04-26' of https://gitlab.freedesktop.org/agd5f/linux into drm-next amd-drm-next-6.10-2024-04-26: amdgpu: - Misc code cleanups and refactors - Support setting reset method at runtime - Report OD status - SMU 14.0.1 fixes - SDMA 4.4.2 fixes - VPE fixes - MES fixes - Update BO eviction priorities - UMSCH fixes - Reset fixes - Freesync fixes - GFXIP 9.4.3 fixes - SDMA 5.2 fixes - MES UAF fix - RAS updates - Devcoredump updates for dumping IP state - DSC fixes - JPEG fix - Fix VRAM memory accounting - VCN 5.0 fixes - MES fixes - UMC 12.0 updates - Modify contiguous flags handling - Initial support for mapping kernel queues via MES amdkfd: - Fix rescheduling of restore worker - VRAM accounting for SVM migrations - mGPU fix - Enable SQ watchpoint for gfx10 Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240426221245.1613332-1-alexander.deucher@amd.com
This commit is contained in:
commit
4a56c0ed5a
@ -97,7 +97,7 @@ static int aldebaran_mode2_suspend_ip(struct amdgpu_device *adev)
|
||||
adev->ip_blocks[i].status.hw = false;
|
||||
}
|
||||
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -139,6 +139,14 @@ enum amdgpu_ss {
|
||||
AMDGPU_SS_DRV_UNLOAD
|
||||
};
|
||||
|
||||
struct amdgpu_hwip_reg_entry {
|
||||
u32 hwip;
|
||||
u32 inst;
|
||||
u32 seg;
|
||||
u32 reg_offset;
|
||||
const char *reg_name;
|
||||
};
|
||||
|
||||
struct amdgpu_watchdog_timer {
|
||||
bool timeout_fatal_disable;
|
||||
uint32_t period; /* maxCycles = (1 << period), the number of cycles before a timeout */
|
||||
@ -494,6 +502,7 @@ struct amdgpu_wb {
|
||||
uint64_t gpu_addr;
|
||||
u32 num_wb; /* Number of wb slots actually reserved for amdgpu. */
|
||||
unsigned long used[DIV_ROUND_UP(AMDGPU_MAX_WB, BITS_PER_LONG)];
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb);
|
||||
|
@ -637,6 +637,8 @@ static const struct amd_ip_funcs acp_ip_funcs = {
|
||||
.soft_reset = acp_soft_reset,
|
||||
.set_clockgating_state = acp_set_clockgating_state,
|
||||
.set_powergating_state = acp_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
const struct amdgpu_ip_block_version acp_ip_block = {
|
||||
|
@ -747,10 +747,17 @@ bool amdgpu_amdkfd_is_fed(struct amdgpu_device *adev)
|
||||
return amdgpu_ras_get_fed_status(adev);
|
||||
}
|
||||
|
||||
void amdgpu_amdkfd_ras_pasid_poison_consumption_handler(struct amdgpu_device *adev,
|
||||
enum amdgpu_ras_block block, uint16_t pasid,
|
||||
pasid_notify pasid_fn, void *data, uint32_t reset)
|
||||
{
|
||||
amdgpu_umc_pasid_poison_handler(adev, block, pasid, pasid_fn, data, reset);
|
||||
}
|
||||
|
||||
void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev,
|
||||
enum amdgpu_ras_block block, uint32_t reset)
|
||||
{
|
||||
amdgpu_umc_poison_handler(adev, block, reset);
|
||||
amdgpu_umc_pasid_poison_handler(adev, block, 0, NULL, NULL, reset);
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_send_close_event_drain_irq(struct amdgpu_device *adev,
|
||||
|
@ -337,6 +337,11 @@ 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,
|
||||
enum amdgpu_ras_block block, uint32_t reset);
|
||||
|
||||
void amdgpu_amdkfd_ras_pasid_poison_consumption_handler(struct amdgpu_device *adev,
|
||||
enum amdgpu_ras_block block, uint16_t pasid,
|
||||
pasid_notify pasid_fn, void *data, uint32_t reset);
|
||||
|
||||
bool amdgpu_amdkfd_is_fed(struct amdgpu_device *adev);
|
||||
bool amdgpu_amdkfd_bo_mapped_to_dev(struct amdgpu_device *adev, struct kgd_mem *mem);
|
||||
void amdgpu_amdkfd_block_mmu_notifications(void *p);
|
||||
|
@ -881,6 +881,7 @@ uint32_t kgd_gfx_v10_set_wave_launch_mode(struct amdgpu_device *adev,
|
||||
}
|
||||
|
||||
#define TCP_WATCH_STRIDE (mmTCP_WATCH1_ADDR_H - mmTCP_WATCH0_ADDR_H)
|
||||
#define SQ_WATCH_STRIDE (mmSQ_WATCH1_ADDR_H - mmSQ_WATCH0_ADDR_H)
|
||||
uint32_t kgd_gfx_v10_set_address_watch(struct amdgpu_device *adev,
|
||||
uint64_t watch_address,
|
||||
uint32_t watch_address_mask,
|
||||
@ -889,55 +890,93 @@ uint32_t kgd_gfx_v10_set_address_watch(struct amdgpu_device *adev,
|
||||
uint32_t debug_vmid,
|
||||
uint32_t inst)
|
||||
{
|
||||
/* SQ_WATCH?_ADDR_* and TCP_WATCH?_ADDR_* are programmed with the
|
||||
* same values.
|
||||
*/
|
||||
uint32_t watch_address_high;
|
||||
uint32_t watch_address_low;
|
||||
uint32_t watch_address_cntl;
|
||||
|
||||
watch_address_cntl = 0;
|
||||
uint32_t tcp_watch_address_cntl;
|
||||
uint32_t sq_watch_address_cntl;
|
||||
|
||||
watch_address_low = lower_32_bits(watch_address);
|
||||
watch_address_high = upper_32_bits(watch_address) & 0xffff;
|
||||
|
||||
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
|
||||
tcp_watch_address_cntl = 0;
|
||||
tcp_watch_address_cntl = REG_SET_FIELD(tcp_watch_address_cntl,
|
||||
TCP_WATCH0_CNTL,
|
||||
VMID,
|
||||
debug_vmid);
|
||||
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
|
||||
tcp_watch_address_cntl = REG_SET_FIELD(tcp_watch_address_cntl,
|
||||
TCP_WATCH0_CNTL,
|
||||
MODE,
|
||||
watch_mode);
|
||||
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
|
||||
tcp_watch_address_cntl = REG_SET_FIELD(tcp_watch_address_cntl,
|
||||
TCP_WATCH0_CNTL,
|
||||
MASK,
|
||||
watch_address_mask >> 7);
|
||||
|
||||
sq_watch_address_cntl = 0;
|
||||
sq_watch_address_cntl = REG_SET_FIELD(sq_watch_address_cntl,
|
||||
SQ_WATCH0_CNTL,
|
||||
VMID,
|
||||
debug_vmid);
|
||||
sq_watch_address_cntl = REG_SET_FIELD(sq_watch_address_cntl,
|
||||
SQ_WATCH0_CNTL,
|
||||
MODE,
|
||||
watch_mode);
|
||||
sq_watch_address_cntl = REG_SET_FIELD(sq_watch_address_cntl,
|
||||
SQ_WATCH0_CNTL,
|
||||
MASK,
|
||||
watch_address_mask >> 6);
|
||||
|
||||
/* Turning off this watch point until we set all the registers */
|
||||
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
|
||||
tcp_watch_address_cntl = REG_SET_FIELD(tcp_watch_address_cntl,
|
||||
TCP_WATCH0_CNTL,
|
||||
VALID,
|
||||
0);
|
||||
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmTCP_WATCH0_CNTL) +
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_cntl);
|
||||
tcp_watch_address_cntl);
|
||||
|
||||
sq_watch_address_cntl = REG_SET_FIELD(sq_watch_address_cntl,
|
||||
SQ_WATCH0_CNTL,
|
||||
VALID,
|
||||
0);
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmSQ_WATCH0_CNTL) +
|
||||
(watch_id * SQ_WATCH_STRIDE)),
|
||||
sq_watch_address_cntl);
|
||||
|
||||
/* Program {TCP,SQ}_WATCH?_ADDR* */
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmTCP_WATCH0_ADDR_H) +
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_high);
|
||||
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmTCP_WATCH0_ADDR_L) +
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_low);
|
||||
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmSQ_WATCH0_ADDR_H) +
|
||||
(watch_id * SQ_WATCH_STRIDE)),
|
||||
watch_address_high);
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmSQ_WATCH0_ADDR_L) +
|
||||
(watch_id * SQ_WATCH_STRIDE)),
|
||||
watch_address_low);
|
||||
|
||||
/* Enable the watch point */
|
||||
watch_address_cntl = REG_SET_FIELD(watch_address_cntl,
|
||||
tcp_watch_address_cntl = REG_SET_FIELD(tcp_watch_address_cntl,
|
||||
TCP_WATCH0_CNTL,
|
||||
VALID,
|
||||
1);
|
||||
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmTCP_WATCH0_CNTL) +
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_cntl);
|
||||
tcp_watch_address_cntl);
|
||||
|
||||
sq_watch_address_cntl = REG_SET_FIELD(sq_watch_address_cntl,
|
||||
SQ_WATCH0_CNTL,
|
||||
VALID,
|
||||
1);
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmSQ_WATCH0_CNTL) +
|
||||
(watch_id * SQ_WATCH_STRIDE)),
|
||||
sq_watch_address_cntl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -953,8 +992,14 @@ uint32_t kgd_gfx_v10_clear_address_watch(struct amdgpu_device *adev,
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_cntl);
|
||||
|
||||
WREG32((SOC15_REG_OFFSET(GC, 0, mmSQ_WATCH0_CNTL) +
|
||||
(watch_id * SQ_WATCH_STRIDE)),
|
||||
watch_address_cntl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#undef TCP_WATCH_STRIDE
|
||||
#undef SQ_WATCH_STRIDE
|
||||
|
||||
|
||||
/* kgd_gfx_v10_get_iq_wait_times: Returns the mmCP_IQ_WAIT_TIME1/2 values
|
||||
|
@ -220,7 +220,7 @@ int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
|
||||
(kfd_mem_limit.ttm_mem_used + ttm_mem_needed >
|
||||
kfd_mem_limit.max_ttm_mem_limit) ||
|
||||
(adev && xcp_id >= 0 && adev->kfd.vram_used[xcp_id] + vram_needed >
|
||||
vram_size - reserved_for_pt)) {
|
||||
vram_size - reserved_for_pt - atomic64_read(&adev->vram_pin_size))) {
|
||||
ret = -ENOMEM;
|
||||
goto release;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ static int amdgpu_benchmark_do_move(struct amdgpu_device *adev, unsigned size,
|
||||
for (i = 0; i < n; i++) {
|
||||
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
|
||||
r = amdgpu_copy_buffer(ring, saddr, daddr, size, NULL, &fence,
|
||||
false, false, false);
|
||||
false, false, 0);
|
||||
if (r)
|
||||
goto exit_do_move;
|
||||
r = dma_fence_wait(fence, false);
|
||||
|
@ -2065,12 +2065,13 @@ static ssize_t amdgpu_reset_dump_register_list_write(struct file *f,
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
|
||||
char reg_offset[11];
|
||||
uint32_t *new = NULL, *tmp = NULL;
|
||||
int ret, i = 0, len = 0;
|
||||
unsigned int len = 0;
|
||||
int ret, i = 0;
|
||||
|
||||
do {
|
||||
memset(reg_offset, 0, 11);
|
||||
if (copy_from_user(reg_offset, buf + len,
|
||||
min(10, ((int)size-len)))) {
|
||||
min(10, (size-len)))) {
|
||||
ret = -EFAULT;
|
||||
goto error_free;
|
||||
}
|
||||
|
@ -262,6 +262,20 @@ amdgpu_devcoredump_read(char *buffer, loff_t offset, size_t count,
|
||||
drm_printf(&p, "Faulty page starting at address: 0x%016llx\n", fault_info->addr);
|
||||
drm_printf(&p, "Protection fault status register: 0x%x\n\n", fault_info->status);
|
||||
|
||||
/* dump the ip state for each ip */
|
||||
drm_printf(&p, "IP Dump\n");
|
||||
for (int i = 0; i < coredump->adev->num_ip_blocks; i++) {
|
||||
if (coredump->adev->ip_blocks[i].version->funcs->print_ip_state) {
|
||||
drm_printf(&p, "IP: %s\n",
|
||||
coredump->adev->ip_blocks[i]
|
||||
.version->funcs->name);
|
||||
coredump->adev->ip_blocks[i]
|
||||
.version->funcs->print_ip_state(
|
||||
(void *)coredump->adev, &p);
|
||||
drm_printf(&p, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Add ring buffer information */
|
||||
drm_printf(&p, "Ring buffer information\n");
|
||||
for (int i = 0; i < coredump->adev->num_rings; i++) {
|
||||
|
@ -1482,13 +1482,17 @@ static int amdgpu_device_wb_init(struct amdgpu_device *adev)
|
||||
*/
|
||||
int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb)
|
||||
{
|
||||
unsigned long offset = find_first_zero_bit(adev->wb.used, adev->wb.num_wb);
|
||||
unsigned long flags, offset;
|
||||
|
||||
spin_lock_irqsave(&adev->wb.lock, flags);
|
||||
offset = find_first_zero_bit(adev->wb.used, adev->wb.num_wb);
|
||||
if (offset < adev->wb.num_wb) {
|
||||
__set_bit(offset, adev->wb.used);
|
||||
spin_unlock_irqrestore(&adev->wb.lock, flags);
|
||||
*wb = offset << 3; /* convert to dw offset */
|
||||
return 0;
|
||||
} else {
|
||||
spin_unlock_irqrestore(&adev->wb.lock, flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@ -1503,9 +1507,13 @@ int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb)
|
||||
*/
|
||||
void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
wb >>= 3;
|
||||
spin_lock_irqsave(&adev->wb.lock, flags);
|
||||
if (wb < adev->wb.num_wb)
|
||||
__clear_bit(wb, adev->wb.used);
|
||||
spin_unlock_irqrestore(&adev->wb.lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4061,6 +4069,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||
spin_lock_init(&adev->se_cac_idx_lock);
|
||||
spin_lock_init(&adev->audio_endpt_idx_lock);
|
||||
spin_lock_init(&adev->mm_stats.lock);
|
||||
spin_lock_init(&adev->wb.lock);
|
||||
|
||||
INIT_LIST_HEAD(&adev->shadow_list);
|
||||
mutex_init(&adev->shadow_list_lock);
|
||||
@ -5353,14 +5362,22 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
|
||||
struct amdgpu_device *tmp_adev = NULL;
|
||||
bool need_full_reset, skip_hw_reset, vram_lost = false;
|
||||
int r = 0;
|
||||
uint32_t i;
|
||||
|
||||
/* Try reset handler method first */
|
||||
tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
|
||||
reset_list);
|
||||
|
||||
if (!test_bit(AMDGPU_SKIP_COREDUMP, &reset_context->flags))
|
||||
if (!test_bit(AMDGPU_SKIP_COREDUMP, &reset_context->flags)) {
|
||||
amdgpu_reset_reg_dumps(tmp_adev);
|
||||
|
||||
/* Trigger ip dump before we reset the asic */
|
||||
for (i = 0; i < tmp_adev->num_ip_blocks; i++)
|
||||
if (tmp_adev->ip_blocks[i].version->funcs->dump_ip_state)
|
||||
tmp_adev->ip_blocks[i].version->funcs
|
||||
->dump_ip_state((void *)tmp_adev);
|
||||
}
|
||||
|
||||
reset_context->reset_device_list = device_list_handle;
|
||||
r = amdgpu_reset_perform_reset(tmp_adev, reset_context);
|
||||
/* If reset handler not implemented, continue; otherwise return */
|
||||
|
@ -925,7 +925,7 @@ module_param_named(freesync_video, amdgpu_freesync_vid_mode, uint, 0444);
|
||||
* GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco)
|
||||
*/
|
||||
MODULE_PARM_DESC(reset_method, "GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco/bamaco)");
|
||||
module_param_named(reset_method, amdgpu_reset_method, int, 0444);
|
||||
module_param_named(reset_method, amdgpu_reset_method, int, 0644);
|
||||
|
||||
/**
|
||||
* DOC: bad_page_threshold (int) Bad page threshold is specifies the
|
||||
|
@ -1206,7 +1206,8 @@ void amdgpu_gfx_cp_init_microcode(struct amdgpu_device *adev,
|
||||
fw_size = le32_to_cpu(cp_hdr_v2_0->data_size_bytes);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
dev_err(adev->dev, "Invalid ucode id %u\n", ucode_id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
|
@ -433,6 +433,10 @@ struct amdgpu_gfx {
|
||||
uint32_t num_xcc_per_xcp;
|
||||
struct mutex partition_mutex;
|
||||
bool mcbp; /* mid command buffer preemption */
|
||||
|
||||
/* IP reg dump */
|
||||
uint32_t *ip_dump;
|
||||
uint32_t reg_count;
|
||||
};
|
||||
|
||||
struct amdgpu_gfx_ras_reg_entry {
|
||||
|
@ -279,7 +279,7 @@ amdgpu_i2c_lookup(struct amdgpu_device *adev,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void amdgpu_i2c_get_byte(struct amdgpu_i2c_chan *i2c_bus,
|
||||
static int amdgpu_i2c_get_byte(struct amdgpu_i2c_chan *i2c_bus,
|
||||
u8 slave_addr,
|
||||
u8 addr,
|
||||
u8 *val)
|
||||
@ -304,16 +304,18 @@ static void amdgpu_i2c_get_byte(struct amdgpu_i2c_chan *i2c_bus,
|
||||
out_buf[0] = addr;
|
||||
out_buf[1] = 0;
|
||||
|
||||
if (i2c_transfer(&i2c_bus->adapter, msgs, 2) == 2) {
|
||||
*val = in_buf[0];
|
||||
DRM_DEBUG("val = 0x%02x\n", *val);
|
||||
} else {
|
||||
DRM_DEBUG("i2c 0x%02x 0x%02x read failed\n",
|
||||
addr, *val);
|
||||
if (i2c_transfer(&i2c_bus->adapter, msgs, 2) != 2) {
|
||||
DRM_DEBUG("i2c 0x%02x read failed\n", addr);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
*val = in_buf[0];
|
||||
DRM_DEBUG("val = 0x%02x\n", *val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void amdgpu_i2c_put_byte(struct amdgpu_i2c_chan *i2c_bus,
|
||||
static int amdgpu_i2c_put_byte(struct amdgpu_i2c_chan *i2c_bus,
|
||||
u8 slave_addr,
|
||||
u8 addr,
|
||||
u8 val)
|
||||
@ -329,9 +331,12 @@ static void amdgpu_i2c_put_byte(struct amdgpu_i2c_chan *i2c_bus,
|
||||
out_buf[0] = addr;
|
||||
out_buf[1] = val;
|
||||
|
||||
if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1)
|
||||
DRM_DEBUG("i2c 0x%02x 0x%02x write failed\n",
|
||||
addr, val);
|
||||
if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1) {
|
||||
DRM_DEBUG("i2c 0x%02x 0x%02x write failed\n", addr, val);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ddc router switching */
|
||||
@ -346,16 +351,18 @@ amdgpu_i2c_router_select_ddc_port(const struct amdgpu_connector *amdgpu_connecto
|
||||
if (!amdgpu_connector->router_bus)
|
||||
return;
|
||||
|
||||
amdgpu_i2c_get_byte(amdgpu_connector->router_bus,
|
||||
if (amdgpu_i2c_get_byte(amdgpu_connector->router_bus,
|
||||
amdgpu_connector->router.i2c_addr,
|
||||
0x3, &val);
|
||||
0x3, &val))
|
||||
return;
|
||||
val &= ~amdgpu_connector->router.ddc_mux_control_pin;
|
||||
amdgpu_i2c_put_byte(amdgpu_connector->router_bus,
|
||||
amdgpu_connector->router.i2c_addr,
|
||||
0x3, val);
|
||||
amdgpu_i2c_get_byte(amdgpu_connector->router_bus,
|
||||
if (amdgpu_i2c_get_byte(amdgpu_connector->router_bus,
|
||||
amdgpu_connector->router.i2c_addr,
|
||||
0x1, &val);
|
||||
0x1, &val))
|
||||
return;
|
||||
val &= ~amdgpu_connector->router.ddc_mux_control_pin;
|
||||
val |= amdgpu_connector->router.ddc_mux_state;
|
||||
amdgpu_i2c_put_byte(amdgpu_connector->router_bus,
|
||||
@ -375,16 +382,18 @@ amdgpu_i2c_router_select_cd_port(const struct amdgpu_connector *amdgpu_connector
|
||||
if (!amdgpu_connector->router_bus)
|
||||
return;
|
||||
|
||||
amdgpu_i2c_get_byte(amdgpu_connector->router_bus,
|
||||
if (amdgpu_i2c_get_byte(amdgpu_connector->router_bus,
|
||||
amdgpu_connector->router.i2c_addr,
|
||||
0x3, &val);
|
||||
0x3, &val))
|
||||
return;
|
||||
val &= ~amdgpu_connector->router.cd_mux_control_pin;
|
||||
amdgpu_i2c_put_byte(amdgpu_connector->router_bus,
|
||||
amdgpu_connector->router.i2c_addr,
|
||||
0x3, val);
|
||||
amdgpu_i2c_get_byte(amdgpu_connector->router_bus,
|
||||
if (amdgpu_i2c_get_byte(amdgpu_connector->router_bus,
|
||||
amdgpu_connector->router.i2c_addr,
|
||||
0x1, &val);
|
||||
0x1, &val))
|
||||
return;
|
||||
val &= ~amdgpu_connector->router.cd_mux_control_pin;
|
||||
val |= amdgpu_connector->router.cd_mux_state;
|
||||
amdgpu_i2c_put_byte(amdgpu_connector->router_bus,
|
||||
|
@ -445,6 +445,14 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
|
||||
|
||||
entry.ih = ih;
|
||||
entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
|
||||
|
||||
/*
|
||||
* timestamp is not supported on some legacy SOCs (cik, cz, iceland,
|
||||
* si and tonga), so initialize timestamp and timestamp_src to 0
|
||||
*/
|
||||
entry.timestamp = 0;
|
||||
entry.timestamp_src = 0;
|
||||
|
||||
amdgpu_ih_decode_iv(adev, &entry);
|
||||
|
||||
trace_amdgpu_iv(ih - &adev->irq.ih, &entry);
|
||||
|
@ -32,6 +32,18 @@
|
||||
#define AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS 1024
|
||||
#define AMDGPU_ONE_DOORBELL_SIZE 8
|
||||
|
||||
signed long amdgpu_mes_fence_wait_polling(u64 *fence,
|
||||
u64 wait_seq,
|
||||
signed long timeout)
|
||||
{
|
||||
|
||||
while ((s64)(wait_seq - *fence) > 0 && timeout > 0) {
|
||||
udelay(2);
|
||||
timeout -= 2;
|
||||
}
|
||||
return timeout > 0 ? timeout : 0;
|
||||
}
|
||||
|
||||
int amdgpu_mes_doorbell_process_slice(struct amdgpu_device *adev)
|
||||
{
|
||||
return roundup(AMDGPU_ONE_DOORBELL_SIZE *
|
||||
@ -774,6 +786,28 @@ int amdgpu_mes_remove_hw_queue(struct amdgpu_device *adev, int queue_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_mes_map_legacy_queue(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring)
|
||||
{
|
||||
struct mes_map_legacy_queue_input queue_input;
|
||||
int r;
|
||||
|
||||
memset(&queue_input, 0, sizeof(queue_input));
|
||||
|
||||
queue_input.queue_type = ring->funcs->type;
|
||||
queue_input.doorbell_offset = ring->doorbell_index;
|
||||
queue_input.pipe_id = ring->pipe;
|
||||
queue_input.queue_id = ring->queue;
|
||||
queue_input.mqd_addr = amdgpu_bo_gpu_offset(ring->mqd_obj);
|
||||
queue_input.wptr_addr = ring->wptr_gpu_addr;
|
||||
|
||||
r = adev->mes.funcs->map_legacy_queue(&adev->mes, &queue_input);
|
||||
if (r)
|
||||
DRM_ERROR("failed to map legacy queue\n");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int amdgpu_mes_unmap_legacy_queue(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring,
|
||||
enum amdgpu_unmap_queues_action action,
|
||||
|
@ -248,6 +248,15 @@ struct mes_remove_queue_input {
|
||||
uint64_t gang_context_addr;
|
||||
};
|
||||
|
||||
struct mes_map_legacy_queue_input {
|
||||
uint32_t queue_type;
|
||||
uint32_t doorbell_offset;
|
||||
uint32_t pipe_id;
|
||||
uint32_t queue_id;
|
||||
uint64_t mqd_addr;
|
||||
uint64_t wptr_addr;
|
||||
};
|
||||
|
||||
struct mes_unmap_legacy_queue_input {
|
||||
enum amdgpu_unmap_queues_action action;
|
||||
uint32_t queue_type;
|
||||
@ -324,6 +333,9 @@ struct amdgpu_mes_funcs {
|
||||
int (*remove_hw_queue)(struct amdgpu_mes *mes,
|
||||
struct mes_remove_queue_input *input);
|
||||
|
||||
int (*map_legacy_queue)(struct amdgpu_mes *mes,
|
||||
struct mes_map_legacy_queue_input *input);
|
||||
|
||||
int (*unmap_legacy_queue)(struct amdgpu_mes *mes,
|
||||
struct mes_unmap_legacy_queue_input *input);
|
||||
|
||||
@ -340,6 +352,10 @@ struct amdgpu_mes_funcs {
|
||||
#define amdgpu_mes_kiq_hw_init(adev) (adev)->mes.kiq_hw_init((adev))
|
||||
#define amdgpu_mes_kiq_hw_fini(adev) (adev)->mes.kiq_hw_fini((adev))
|
||||
|
||||
signed long amdgpu_mes_fence_wait_polling(u64 *fence,
|
||||
u64 wait_seq,
|
||||
signed long timeout);
|
||||
|
||||
int amdgpu_mes_ctx_get_offs(struct amdgpu_ring *ring, unsigned int id_offs);
|
||||
|
||||
int amdgpu_mes_init_microcode(struct amdgpu_device *adev, int pipe);
|
||||
@ -363,6 +379,8 @@ int amdgpu_mes_add_hw_queue(struct amdgpu_device *adev, int gang_id,
|
||||
int *queue_id);
|
||||
int amdgpu_mes_remove_hw_queue(struct amdgpu_device *adev, int queue_id);
|
||||
|
||||
int amdgpu_mes_map_legacy_queue(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring);
|
||||
int amdgpu_mes_unmap_legacy_queue(struct amdgpu_device *adev,
|
||||
struct amdgpu_ring *ring,
|
||||
enum amdgpu_unmap_queues_action action,
|
||||
|
@ -154,8 +154,10 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain)
|
||||
else
|
||||
places[c].flags |= TTM_PL_FLAG_TOPDOWN;
|
||||
|
||||
if (flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)
|
||||
if (abo->tbo.type == ttm_bo_type_kernel &&
|
||||
flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)
|
||||
places[c].flags |= TTM_PL_FLAG_CONTIGUOUS;
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
@ -765,7 +767,7 @@ int amdgpu_bo_restore_shadow(struct amdgpu_bo *shadow, struct dma_fence **fence)
|
||||
|
||||
return amdgpu_copy_buffer(ring, shadow_addr, parent_addr,
|
||||
amdgpu_bo_size(shadow), NULL, fence,
|
||||
true, false, false);
|
||||
true, false, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -967,6 +969,10 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
|
||||
if (!bo->placements[i].lpfn ||
|
||||
(lpfn && lpfn < bo->placements[i].lpfn))
|
||||
bo->placements[i].lpfn = lpfn;
|
||||
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS &&
|
||||
bo->placements[i].mem_type == TTM_PL_VRAM)
|
||||
bo->placements[i].flags |= TTM_PL_FLAG_CONTIGUOUS;
|
||||
}
|
||||
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
|
@ -122,6 +122,8 @@ const char *get_ras_block_str(struct ras_common_if *ras_block)
|
||||
|
||||
#define MAX_UMC_POISON_POLLING_TIME_ASYNC 100 //ms
|
||||
|
||||
#define AMDGPU_RAS_RETIRE_PAGE_INTERVAL 100 //ms
|
||||
|
||||
enum amdgpu_ras_retire_page_reservation {
|
||||
AMDGPU_RAS_RETIRE_PAGE_RESERVED,
|
||||
AMDGPU_RAS_RETIRE_PAGE_PENDING,
|
||||
@ -1248,6 +1250,10 @@ int amdgpu_ras_bind_aca(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
{
|
||||
struct ras_manager *obj;
|
||||
|
||||
/* in resume phase, no need to create aca fs node */
|
||||
if (adev->in_suspend || amdgpu_in_reset(adev))
|
||||
return 0;
|
||||
|
||||
obj = get_ras_manager(adev, blk);
|
||||
if (!obj)
|
||||
return -EINVAL;
|
||||
@ -2076,6 +2082,17 @@ static void amdgpu_ras_interrupt_poison_creation_handler(struct ras_manager *obj
|
||||
{
|
||||
dev_info(obj->adev->dev,
|
||||
"Poison is created\n");
|
||||
|
||||
if (amdgpu_ip_version(obj->adev, UMC_HWIP, 0) >= IP_VERSION(12, 0, 0)) {
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(obj->adev);
|
||||
|
||||
amdgpu_ras_put_poison_req(obj->adev,
|
||||
AMDGPU_RAS_BLOCK__UMC, 0, NULL, NULL, false);
|
||||
|
||||
atomic_inc(&con->page_retirement_req_cnt);
|
||||
|
||||
wake_up(&con->page_retirement_wq);
|
||||
}
|
||||
}
|
||||
|
||||
static void amdgpu_ras_interrupt_umc_handler(struct ras_manager *obj,
|
||||
@ -2386,7 +2403,7 @@ static int amdgpu_ras_badpages_read(struct amdgpu_device *adev,
|
||||
.flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED,
|
||||
};
|
||||
status = amdgpu_vram_mgr_query_page_status(&adev->mman.vram_mgr,
|
||||
data->bps[i].retired_page);
|
||||
data->bps[i].retired_page << AMDGPU_GPU_PAGE_SHIFT);
|
||||
if (status == -EBUSY)
|
||||
(*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_PENDING;
|
||||
else if (status == -ENOENT)
|
||||
@ -2545,9 +2562,7 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev,
|
||||
goto out;
|
||||
}
|
||||
|
||||
amdgpu_vram_mgr_reserve_range(&adev->mman.vram_mgr,
|
||||
bps[i].retired_page << AMDGPU_GPU_PAGE_SHIFT,
|
||||
AMDGPU_GPU_PAGE_SIZE);
|
||||
amdgpu_ras_reserve_page(adev, bps[i].retired_page);
|
||||
|
||||
memcpy(&data->bps[data->count], &bps[i], sizeof(*data->bps));
|
||||
data->count++;
|
||||
@ -2703,10 +2718,167 @@ static void amdgpu_ras_validate_threshold(struct amdgpu_device *adev,
|
||||
}
|
||||
}
|
||||
|
||||
int amdgpu_ras_put_poison_req(struct amdgpu_device *adev,
|
||||
enum amdgpu_ras_block block, uint16_t pasid,
|
||||
pasid_notify pasid_fn, void *data, uint32_t reset)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ras_poison_msg poison_msg;
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
|
||||
memset(&poison_msg, 0, sizeof(poison_msg));
|
||||
poison_msg.block = block;
|
||||
poison_msg.pasid = pasid;
|
||||
poison_msg.reset = reset;
|
||||
poison_msg.pasid_fn = pasid_fn;
|
||||
poison_msg.data = data;
|
||||
|
||||
ret = kfifo_put(&con->poison_fifo, poison_msg);
|
||||
if (!ret) {
|
||||
dev_err(adev->dev, "Poison message fifo is full!\n");
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_ras_get_poison_req(struct amdgpu_device *adev,
|
||||
struct ras_poison_msg *poison_msg)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
|
||||
return kfifo_get(&con->poison_fifo, poison_msg);
|
||||
}
|
||||
|
||||
static void amdgpu_ras_ecc_log_init(struct ras_ecc_log_info *ecc_log)
|
||||
{
|
||||
mutex_init(&ecc_log->lock);
|
||||
|
||||
/* Set any value as siphash key */
|
||||
memset(&ecc_log->ecc_key, 0xad, sizeof(ecc_log->ecc_key));
|
||||
|
||||
INIT_RADIX_TREE(&ecc_log->de_page_tree, GFP_KERNEL);
|
||||
ecc_log->de_updated = false;
|
||||
}
|
||||
|
||||
static void amdgpu_ras_ecc_log_fini(struct ras_ecc_log_info *ecc_log)
|
||||
{
|
||||
struct radix_tree_iter iter;
|
||||
void __rcu **slot;
|
||||
struct ras_ecc_err *ecc_err;
|
||||
|
||||
mutex_lock(&ecc_log->lock);
|
||||
radix_tree_for_each_slot(slot, &ecc_log->de_page_tree, &iter, 0) {
|
||||
ecc_err = radix_tree_deref_slot(slot);
|
||||
kfree(ecc_err->err_pages.pfn);
|
||||
kfree(ecc_err);
|
||||
radix_tree_iter_delete(&ecc_log->de_page_tree, &iter, slot);
|
||||
}
|
||||
mutex_unlock(&ecc_log->lock);
|
||||
|
||||
mutex_destroy(&ecc_log->lock);
|
||||
ecc_log->de_updated = false;
|
||||
}
|
||||
|
||||
static void amdgpu_ras_do_page_retirement(struct work_struct *work)
|
||||
{
|
||||
struct amdgpu_ras *con = container_of(work, struct amdgpu_ras,
|
||||
page_retirement_dwork.work);
|
||||
struct amdgpu_device *adev = con->adev;
|
||||
struct ras_err_data err_data;
|
||||
|
||||
if (amdgpu_in_reset(adev) || atomic_read(&con->in_recovery))
|
||||
return;
|
||||
|
||||
amdgpu_ras_error_data_init(&err_data);
|
||||
|
||||
amdgpu_umc_handle_bad_pages(adev, &err_data);
|
||||
|
||||
amdgpu_ras_error_data_fini(&err_data);
|
||||
|
||||
mutex_lock(&con->umc_ecc_log.lock);
|
||||
if (radix_tree_tagged(&con->umc_ecc_log.de_page_tree,
|
||||
UMC_ECC_NEW_DETECTED_TAG))
|
||||
schedule_delayed_work(&con->page_retirement_dwork,
|
||||
msecs_to_jiffies(AMDGPU_RAS_RETIRE_PAGE_INTERVAL));
|
||||
mutex_unlock(&con->umc_ecc_log.lock);
|
||||
}
|
||||
|
||||
static int amdgpu_ras_query_ecc_status(struct amdgpu_device *adev,
|
||||
enum amdgpu_ras_block ras_block, uint32_t timeout_ms)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ras_ecc_log_info *ecc_log;
|
||||
struct ras_query_if info;
|
||||
uint32_t timeout = timeout_ms;
|
||||
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.head.block = ras_block;
|
||||
|
||||
ecc_log = &ras->umc_ecc_log;
|
||||
ecc_log->de_updated = false;
|
||||
do {
|
||||
ret = amdgpu_ras_query_error_status(adev, &info);
|
||||
if (ret) {
|
||||
dev_err(adev->dev, "Failed to query ras error! ret:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (timeout && !ecc_log->de_updated) {
|
||||
msleep(1);
|
||||
timeout--;
|
||||
}
|
||||
} while (timeout && !ecc_log->de_updated);
|
||||
|
||||
if (timeout_ms && !timeout) {
|
||||
dev_warn(adev->dev, "Can't find deferred error\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void amdgpu_ras_poison_creation_handler(struct amdgpu_device *adev,
|
||||
uint32_t timeout)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
int ret;
|
||||
|
||||
ret = amdgpu_ras_query_ecc_status(adev, AMDGPU_RAS_BLOCK__UMC, timeout);
|
||||
if (!ret)
|
||||
schedule_delayed_work(&con->page_retirement_dwork, 0);
|
||||
}
|
||||
|
||||
static int amdgpu_ras_poison_consumption_handler(struct amdgpu_device *adev,
|
||||
struct ras_poison_msg *poison_msg)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
uint32_t reset = poison_msg->reset;
|
||||
uint16_t pasid = poison_msg->pasid;
|
||||
|
||||
kgd2kfd_set_sram_ecc_flag(adev->kfd.dev);
|
||||
|
||||
if (poison_msg->pasid_fn)
|
||||
poison_msg->pasid_fn(adev, pasid, poison_msg->data);
|
||||
|
||||
if (reset) {
|
||||
flush_delayed_work(&con->page_retirement_dwork);
|
||||
|
||||
con->gpu_reset_flags |= reset;
|
||||
amdgpu_ras_reset_gpu(adev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_ras_page_retirement_thread(void *param)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)param;
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
struct ras_poison_msg poison_msg;
|
||||
enum amdgpu_ras_block ras_block;
|
||||
bool poison_creation_is_handled = false;
|
||||
|
||||
while (!kthread_should_stop()) {
|
||||
|
||||
@ -2717,13 +2889,34 @@ static int amdgpu_ras_page_retirement_thread(void *param)
|
||||
if (kthread_should_stop())
|
||||
break;
|
||||
|
||||
dev_info(adev->dev, "Start processing page retirement. request:%d\n",
|
||||
atomic_read(&con->page_retirement_req_cnt));
|
||||
|
||||
atomic_dec(&con->page_retirement_req_cnt);
|
||||
|
||||
amdgpu_umc_bad_page_polling_timeout(adev,
|
||||
0, MAX_UMC_POISON_POLLING_TIME_ASYNC);
|
||||
if (!amdgpu_ras_get_poison_req(adev, &poison_msg))
|
||||
continue;
|
||||
|
||||
ras_block = poison_msg.block;
|
||||
|
||||
dev_info(adev->dev, "Start processing ras block %s(%d)\n",
|
||||
ras_block_str(ras_block), ras_block);
|
||||
|
||||
if (ras_block == AMDGPU_RAS_BLOCK__UMC) {
|
||||
amdgpu_ras_poison_creation_handler(adev,
|
||||
MAX_UMC_POISON_POLLING_TIME_ASYNC);
|
||||
poison_creation_is_handled = true;
|
||||
} else {
|
||||
/* poison_creation_is_handled:
|
||||
* false: no poison creation interrupt, but it has poison
|
||||
* consumption interrupt.
|
||||
* true: It has poison creation interrupt at the beginning,
|
||||
* but it has no poison creation interrupt later.
|
||||
*/
|
||||
amdgpu_ras_poison_creation_handler(adev,
|
||||
poison_creation_is_handled ?
|
||||
0 : MAX_UMC_POISON_POLLING_TIME_ASYNC);
|
||||
|
||||
amdgpu_ras_poison_consumption_handler(adev, &poison_msg);
|
||||
poison_creation_is_handled = false;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -2792,6 +2985,8 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
mutex_init(&con->page_rsv_lock);
|
||||
INIT_KFIFO(con->poison_fifo);
|
||||
mutex_init(&con->page_retirement_lock);
|
||||
init_waitqueue_head(&con->page_retirement_wq);
|
||||
atomic_set(&con->page_retirement_req_cnt, 0);
|
||||
@ -2802,6 +2997,8 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev)
|
||||
dev_warn(adev->dev, "Failed to create umc_page_retirement thread!!!\n");
|
||||
}
|
||||
|
||||
INIT_DELAYED_WORK(&con->page_retirement_dwork, amdgpu_ras_do_page_retirement);
|
||||
amdgpu_ras_ecc_log_init(&con->umc_ecc_log);
|
||||
#ifdef CONFIG_X86_MCE_AMD
|
||||
if ((adev->asic_type == CHIP_ALDEBARAN) &&
|
||||
(adev->gmc.xgmi.connected_to_cpu))
|
||||
@ -2842,8 +3039,14 @@ static int amdgpu_ras_recovery_fini(struct amdgpu_device *adev)
|
||||
|
||||
atomic_set(&con->page_retirement_req_cnt, 0);
|
||||
|
||||
mutex_destroy(&con->page_rsv_lock);
|
||||
|
||||
cancel_work_sync(&con->recovery_work);
|
||||
|
||||
cancel_delayed_work_sync(&con->page_retirement_dwork);
|
||||
|
||||
amdgpu_ras_ecc_log_fini(&con->umc_ecc_log);
|
||||
|
||||
mutex_lock(&con->recovery_lock);
|
||||
con->eh_data = NULL;
|
||||
kfree(data->bps);
|
||||
@ -4083,6 +4286,8 @@ void amdgpu_ras_add_mca_err_addr(struct ras_err_info *err_info, struct ras_err_a
|
||||
{
|
||||
struct ras_err_addr *mca_err_addr;
|
||||
|
||||
/* This function will be retired. */
|
||||
return;
|
||||
mca_err_addr = kzalloc(sizeof(*mca_err_addr), GFP_KERNEL);
|
||||
if (!mca_err_addr)
|
||||
return;
|
||||
@ -4280,3 +4485,19 @@ void amdgpu_ras_query_boot_status(struct amdgpu_device *adev, u32 num_instances)
|
||||
amdgpu_ras_boot_time_error_reporting(adev, i, boot_error);
|
||||
}
|
||||
}
|
||||
|
||||
int amdgpu_ras_reserve_page(struct amdgpu_device *adev, uint64_t pfn)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
struct amdgpu_vram_mgr *mgr = &adev->mman.vram_mgr;
|
||||
uint64_t start = pfn << AMDGPU_GPU_PAGE_SHIFT;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&con->page_rsv_lock);
|
||||
ret = amdgpu_vram_mgr_query_page_status(mgr, start);
|
||||
if (ret == -ENOENT)
|
||||
ret = amdgpu_vram_mgr_reserve_range(mgr, start, AMDGPU_GPU_PAGE_SIZE);
|
||||
mutex_unlock(&con->page_rsv_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -26,6 +26,9 @@
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/kfifo.h>
|
||||
#include <linux/radix-tree.h>
|
||||
#include <linux/siphash.h>
|
||||
#include "ta_ras_if.h"
|
||||
#include "amdgpu_ras_eeprom.h"
|
||||
#include "amdgpu_smuio.h"
|
||||
@ -442,6 +445,37 @@ struct ras_query_context {
|
||||
u64 event_id;
|
||||
};
|
||||
|
||||
typedef int (*pasid_notify)(struct amdgpu_device *adev,
|
||||
uint16_t pasid, void *data);
|
||||
|
||||
struct ras_poison_msg {
|
||||
enum amdgpu_ras_block block;
|
||||
uint16_t pasid;
|
||||
uint32_t reset;
|
||||
pasid_notify pasid_fn;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct ras_err_pages {
|
||||
uint32_t count;
|
||||
uint64_t *pfn;
|
||||
};
|
||||
|
||||
struct ras_ecc_err {
|
||||
u64 hash_index;
|
||||
uint64_t status;
|
||||
uint64_t ipid;
|
||||
uint64_t addr;
|
||||
struct ras_err_pages err_pages;
|
||||
};
|
||||
|
||||
struct ras_ecc_log_info {
|
||||
struct mutex lock;
|
||||
siphash_key_t ecc_key;
|
||||
struct radix_tree_root de_page_tree;
|
||||
bool de_updated;
|
||||
};
|
||||
|
||||
struct amdgpu_ras {
|
||||
/* ras infrastructure */
|
||||
/* for ras itself. */
|
||||
@ -500,6 +534,11 @@ struct amdgpu_ras {
|
||||
wait_queue_head_t page_retirement_wq;
|
||||
struct mutex page_retirement_lock;
|
||||
atomic_t page_retirement_req_cnt;
|
||||
struct mutex page_rsv_lock;
|
||||
DECLARE_KFIFO(poison_fifo, struct ras_poison_msg, 128);
|
||||
struct ras_ecc_log_info umc_ecc_log;
|
||||
struct delayed_work page_retirement_dwork;
|
||||
|
||||
/* Fatal error detected flag */
|
||||
atomic_t fed;
|
||||
|
||||
@ -540,6 +579,7 @@ struct ras_err_data {
|
||||
unsigned long de_count;
|
||||
unsigned long err_addr_cnt;
|
||||
struct eeprom_table_record *err_addr;
|
||||
unsigned long err_addr_len;
|
||||
u32 err_list_count;
|
||||
struct list_head err_node_list;
|
||||
};
|
||||
@ -909,4 +949,11 @@ bool amdgpu_ras_get_fed_status(struct amdgpu_device *adev);
|
||||
|
||||
bool amdgpu_ras_event_id_is_valid(struct amdgpu_device *adev, u64 id);
|
||||
u64 amdgpu_ras_acquire_event_id(struct amdgpu_device *adev, enum ras_event_type type);
|
||||
|
||||
int amdgpu_ras_reserve_page(struct amdgpu_device *adev, uint64_t pfn);
|
||||
|
||||
int amdgpu_ras_put_poison_req(struct amdgpu_device *adev,
|
||||
enum amdgpu_ras_block block, uint16_t pasid,
|
||||
pasid_notify pasid_fn, void *data, uint32_t reset);
|
||||
|
||||
#endif
|
||||
|
@ -132,7 +132,7 @@ struct amdgpu_buffer_funcs {
|
||||
uint64_t dst_offset,
|
||||
/* number of byte to transfer */
|
||||
uint32_t byte_count,
|
||||
bool tmz);
|
||||
uint32_t copy_flags);
|
||||
|
||||
/* maximum bytes in a single operation */
|
||||
uint32_t fill_max_bytes;
|
||||
|
@ -236,7 +236,7 @@ static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
|
||||
dst_addr = amdgpu_bo_gpu_offset(adev->gart.bo);
|
||||
dst_addr += window * AMDGPU_GTT_MAX_TRANSFER_SIZE * 8;
|
||||
amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr,
|
||||
dst_addr, num_bytes, false);
|
||||
dst_addr, num_bytes, 0);
|
||||
|
||||
amdgpu_ring_pad_ib(ring, &job->ibs[0]);
|
||||
WARN_ON(job->ibs[0].length_dw > num_dw);
|
||||
@ -296,6 +296,8 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
|
||||
struct dma_fence *fence = NULL;
|
||||
int r = 0;
|
||||
|
||||
uint32_t copy_flags = 0;
|
||||
|
||||
if (!adev->mman.buffer_funcs_enabled) {
|
||||
DRM_ERROR("Trying to move memory with ring turned off.\n");
|
||||
return -EINVAL;
|
||||
@ -323,8 +325,11 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
r = amdgpu_copy_buffer(ring, from, to, cur_size,
|
||||
resv, &next, false, true, tmz);
|
||||
if (tmz)
|
||||
copy_flags |= AMDGPU_COPY_FLAGS_TMZ;
|
||||
|
||||
r = amdgpu_copy_buffer(ring, from, to, cur_size, resv,
|
||||
&next, false, true, copy_flags);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
@ -1489,7 +1494,7 @@ static int amdgpu_ttm_access_memory_sdma(struct ttm_buffer_object *bo,
|
||||
swap(src_addr, dst_addr);
|
||||
|
||||
amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr, dst_addr,
|
||||
PAGE_SIZE, false);
|
||||
PAGE_SIZE, 0);
|
||||
|
||||
amdgpu_ring_pad_ib(adev->mman.buffer_funcs_ring, &job->ibs[0]);
|
||||
WARN_ON(job->ibs[0].length_dw > num_dw);
|
||||
@ -2140,7 +2145,7 @@ 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)
|
||||
bool vm_needs_flush, uint32_t copy_flags)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
unsigned int num_loops, num_dw;
|
||||
@ -2166,8 +2171,7 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
|
||||
uint32_t cur_size_in_bytes = min(byte_count, max_bytes);
|
||||
|
||||
amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_offset,
|
||||
dst_offset, cur_size_in_bytes, tmz);
|
||||
|
||||
dst_offset, cur_size_in_bytes, copy_flags);
|
||||
src_offset += cur_size_in_bytes;
|
||||
dst_offset += cur_size_in_bytes;
|
||||
byte_count -= cur_size_in_bytes;
|
||||
|
@ -109,6 +109,8 @@ struct amdgpu_copy_mem {
|
||||
unsigned long offset;
|
||||
};
|
||||
|
||||
#define AMDGPU_COPY_FLAGS_TMZ (1 << 0)
|
||||
|
||||
int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size);
|
||||
void amdgpu_gtt_mgr_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_preempt_mgr_init(struct amdgpu_device *adev);
|
||||
@ -149,7 +151,7 @@ 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);
|
||||
bool vm_needs_flush, uint32_t copy_flags);
|
||||
int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
|
||||
const struct amdgpu_copy_mem *src,
|
||||
const struct amdgpu_copy_mem *dst,
|
||||
|
@ -21,10 +21,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/sort.h>
|
||||
#include "amdgpu.h"
|
||||
#include "umc_v6_7.h"
|
||||
#define MAX_UMC_POISON_POLLING_TIME_SYNC 20 //ms
|
||||
|
||||
#define MAX_UMC_HASH_STRING_SIZE 256
|
||||
|
||||
static int amdgpu_umc_convert_error_address(struct amdgpu_device *adev,
|
||||
struct ras_err_data *err_data, uint64_t err_addr,
|
||||
uint32_t ch_inst, uint32_t umc_inst)
|
||||
@ -63,6 +66,8 @@ int amdgpu_umc_page_retirement_mca(struct amdgpu_device *adev,
|
||||
goto out_fini_err_data;
|
||||
}
|
||||
|
||||
err_data.err_addr_len = adev->umc.max_ras_err_cnt_per_query;
|
||||
|
||||
/*
|
||||
* Translate UMC channel address to Physical address
|
||||
*/
|
||||
@ -86,7 +91,7 @@ out_fini_err_data:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void amdgpu_umc_handle_bad_pages(struct amdgpu_device *adev,
|
||||
void amdgpu_umc_handle_bad_pages(struct amdgpu_device *adev,
|
||||
void *ras_error_status)
|
||||
{
|
||||
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
|
||||
@ -118,6 +123,8 @@ static void amdgpu_umc_handle_bad_pages(struct amdgpu_device *adev,
|
||||
if(!err_data->err_addr)
|
||||
dev_warn(adev->dev, "Failed to alloc memory for "
|
||||
"umc error address record!\n");
|
||||
else
|
||||
err_data->err_addr_len = adev->umc.max_ras_err_cnt_per_query;
|
||||
|
||||
/* umc query_ras_error_address is also responsible for clearing
|
||||
* error status
|
||||
@ -143,6 +150,8 @@ static void amdgpu_umc_handle_bad_pages(struct amdgpu_device *adev,
|
||||
if(!err_data->err_addr)
|
||||
dev_warn(adev->dev, "Failed to alloc memory for "
|
||||
"umc error address record!\n");
|
||||
else
|
||||
err_data->err_addr_len = adev->umc.max_ras_err_cnt_per_query;
|
||||
|
||||
/* umc query_ras_error_address is also responsible for clearing
|
||||
* error status
|
||||
@ -170,6 +179,7 @@ static void amdgpu_umc_handle_bad_pages(struct amdgpu_device *adev,
|
||||
}
|
||||
|
||||
kfree(err_data->err_addr);
|
||||
err_data->err_addr = NULL;
|
||||
|
||||
mutex_unlock(&con->page_retirement_lock);
|
||||
}
|
||||
@ -243,8 +253,9 @@ int amdgpu_umc_bad_page_polling_timeout(struct amdgpu_device *adev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_umc_poison_handler(struct amdgpu_device *adev,
|
||||
enum amdgpu_ras_block block, uint32_t reset)
|
||||
int amdgpu_umc_pasid_poison_handler(struct amdgpu_device *adev,
|
||||
enum amdgpu_ras_block block, uint16_t pasid,
|
||||
pasid_notify pasid_fn, void *data, uint32_t reset)
|
||||
{
|
||||
int ret = AMDGPU_RAS_SUCCESS;
|
||||
|
||||
@ -282,16 +293,14 @@ int amdgpu_umc_poison_handler(struct amdgpu_device *adev,
|
||||
|
||||
amdgpu_ras_error_data_fini(&err_data);
|
||||
} else {
|
||||
if (reset) {
|
||||
amdgpu_umc_bad_page_polling_timeout(adev,
|
||||
reset, MAX_UMC_POISON_POLLING_TIME_SYNC);
|
||||
} else {
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
|
||||
amdgpu_ras_put_poison_req(adev,
|
||||
block, pasid, pasid_fn, data, reset);
|
||||
|
||||
atomic_inc(&con->page_retirement_req_cnt);
|
||||
|
||||
wake_up(&con->page_retirement_wq);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (adev->virt.ops && adev->virt.ops->ras_poison_handler)
|
||||
@ -304,6 +313,13 @@ int amdgpu_umc_poison_handler(struct amdgpu_device *adev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_umc_poison_handler(struct amdgpu_device *adev,
|
||||
enum amdgpu_ras_block block, uint32_t reset)
|
||||
{
|
||||
return amdgpu_umc_pasid_poison_handler(adev,
|
||||
block, 0, NULL, NULL, reset);
|
||||
}
|
||||
|
||||
int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev,
|
||||
void *ras_error_status,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
@ -386,14 +402,20 @@ int amdgpu_umc_process_ecc_irq(struct amdgpu_device *adev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void amdgpu_umc_fill_error_record(struct ras_err_data *err_data,
|
||||
int 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];
|
||||
struct eeprom_table_record *err_rec;
|
||||
|
||||
if (!err_data ||
|
||||
!err_data->err_addr ||
|
||||
(err_data->err_addr_cnt >= err_data->err_addr_len))
|
||||
return -EINVAL;
|
||||
|
||||
err_rec = &err_data->err_addr[err_data->err_addr_cnt];
|
||||
|
||||
err_rec->address = err_addr;
|
||||
/* page frame address is saved */
|
||||
@ -405,6 +427,8 @@ void amdgpu_umc_fill_error_record(struct ras_err_data *err_data,
|
||||
err_rec->mcumc_id = umc_inst;
|
||||
|
||||
err_data->err_addr_cnt++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_umc_loop_channels(struct amdgpu_device *adev,
|
||||
@ -437,3 +461,76 @@ int amdgpu_umc_loop_channels(struct amdgpu_device *adev,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_umc_update_ecc_status(struct amdgpu_device *adev,
|
||||
uint64_t status, uint64_t ipid, uint64_t addr)
|
||||
{
|
||||
if (adev->umc.ras->update_ecc_status)
|
||||
return adev->umc.ras->update_ecc_status(adev,
|
||||
status, ipid, addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_umc_uint64_cmp(const void *a, const void *b)
|
||||
{
|
||||
uint64_t *addr_a = (uint64_t *)a;
|
||||
uint64_t *addr_b = (uint64_t *)b;
|
||||
|
||||
if (*addr_a > *addr_b)
|
||||
return 1;
|
||||
else if (*addr_a < *addr_b)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use string hash to avoid logging the same bad pages repeatedly */
|
||||
int amdgpu_umc_build_pages_hash(struct amdgpu_device *adev,
|
||||
uint64_t *pfns, int len, uint64_t *val)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
char buf[MAX_UMC_HASH_STRING_SIZE] = {0};
|
||||
int offset = 0, i = 0;
|
||||
uint64_t hash_val;
|
||||
|
||||
if (!pfns || !len)
|
||||
return -EINVAL;
|
||||
|
||||
sort(pfns, len, sizeof(uint64_t), amdgpu_umc_uint64_cmp, NULL);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
offset += snprintf(&buf[offset], sizeof(buf) - offset, "%llx", pfns[i]);
|
||||
|
||||
hash_val = siphash(buf, offset, &con->umc_ecc_log.ecc_key);
|
||||
|
||||
*val = hash_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_umc_logs_ecc_err(struct amdgpu_device *adev,
|
||||
struct radix_tree_root *ecc_tree, struct ras_ecc_err *ecc_err)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
struct ras_ecc_log_info *ecc_log;
|
||||
int ret;
|
||||
|
||||
ecc_log = &con->umc_ecc_log;
|
||||
|
||||
mutex_lock(&ecc_log->lock);
|
||||
ret = radix_tree_insert(ecc_tree, ecc_err->hash_index, ecc_err);
|
||||
if (!ret) {
|
||||
struct ras_err_pages *err_pages = &ecc_err->err_pages;
|
||||
int i;
|
||||
|
||||
/* Reserve memory */
|
||||
for (i = 0; i < err_pages->count; i++)
|
||||
amdgpu_ras_reserve_page(adev, err_pages->pfn[i]);
|
||||
|
||||
radix_tree_tag_set(ecc_tree,
|
||||
ecc_err->hash_index, UMC_ECC_NEW_DETECTED_TAG);
|
||||
}
|
||||
mutex_unlock(&ecc_log->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -52,6 +52,8 @@
|
||||
#define LOOP_UMC_EACH_NODE_INST_AND_CH(node_inst, umc_inst, ch_inst) \
|
||||
LOOP_UMC_NODE_INST((node_inst)) LOOP_UMC_INST_AND_CH((umc_inst), (ch_inst))
|
||||
|
||||
/* Page retirement tag */
|
||||
#define UMC_ECC_NEW_DETECTED_TAG 0x1
|
||||
|
||||
typedef int (*umc_func)(struct amdgpu_device *adev, uint32_t node_inst,
|
||||
uint32_t umc_inst, uint32_t ch_inst, void *data);
|
||||
@ -66,6 +68,8 @@ struct amdgpu_umc_ras {
|
||||
void *ras_error_status);
|
||||
bool (*check_ecc_err_status)(struct amdgpu_device *adev,
|
||||
enum amdgpu_mca_error_type type, void *ras_error_status);
|
||||
int (*update_ecc_status)(struct amdgpu_device *adev,
|
||||
uint64_t status, uint64_t ipid, uint64_t addr);
|
||||
};
|
||||
|
||||
struct amdgpu_umc_funcs {
|
||||
@ -102,10 +106,13 @@ int amdgpu_umc_ras_sw_init(struct amdgpu_device *adev);
|
||||
int amdgpu_umc_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
|
||||
int amdgpu_umc_poison_handler(struct amdgpu_device *adev,
|
||||
enum amdgpu_ras_block block, uint32_t reset);
|
||||
int amdgpu_umc_pasid_poison_handler(struct amdgpu_device *adev,
|
||||
enum amdgpu_ras_block block, uint16_t pasid,
|
||||
pasid_notify pasid_fn, void *data, uint32_t reset);
|
||||
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,
|
||||
int amdgpu_umc_fill_error_record(struct ras_err_data *err_data,
|
||||
uint64_t err_addr,
|
||||
uint64_t retired_page,
|
||||
uint32_t channel_index,
|
||||
@ -122,4 +129,14 @@ int amdgpu_umc_loop_channels(struct amdgpu_device *adev,
|
||||
|
||||
int amdgpu_umc_bad_page_polling_timeout(struct amdgpu_device *adev,
|
||||
uint32_t reset, uint32_t timeout_ms);
|
||||
|
||||
int amdgpu_umc_update_ecc_status(struct amdgpu_device *adev,
|
||||
uint64_t status, uint64_t ipid, uint64_t addr);
|
||||
int amdgpu_umc_build_pages_hash(struct amdgpu_device *adev,
|
||||
uint64_t *pfns, int len, uint64_t *val);
|
||||
int amdgpu_umc_logs_ecc_err(struct amdgpu_device *adev,
|
||||
struct radix_tree_root *ecc_tree, struct ras_ecc_err *ecc_err);
|
||||
|
||||
void amdgpu_umc_handle_bad_pages(struct amdgpu_device *adev,
|
||||
void *ras_error_status);
|
||||
#endif
|
||||
|
@ -878,6 +878,8 @@ static const struct amd_ip_funcs umsch_mm_v4_0_ip_funcs = {
|
||||
.hw_fini = umsch_mm_hw_fini,
|
||||
.suspend = umsch_mm_suspend,
|
||||
.resume = umsch_mm_resume,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
const struct amdgpu_ip_block_version umsch_mm_v4_0_ip_block = {
|
||||
|
@ -743,7 +743,8 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p,
|
||||
uint32_t created = 0;
|
||||
uint32_t allocated = 0;
|
||||
uint32_t tmp, handle = 0;
|
||||
uint32_t *size = &tmp;
|
||||
uint32_t dummy = 0xffffffff;
|
||||
uint32_t *size = &dummy;
|
||||
unsigned int idx;
|
||||
int i, r = 0;
|
||||
|
||||
|
@ -185,7 +185,10 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
||||
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
|
||||
bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
|
||||
|
||||
if (amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0)) {
|
||||
if (amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(5, 0, 0)) {
|
||||
fw_shared_size = AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn5_fw_shared));
|
||||
log_offset = offsetof(struct amdgpu_vcn5_fw_shared, fw_log);
|
||||
} else if (amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0)) {
|
||||
fw_shared_size = AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared));
|
||||
log_offset = offsetof(struct amdgpu_vcn4_fw_shared, fw_log);
|
||||
} else {
|
||||
|
@ -454,6 +454,16 @@ struct amdgpu_vcn_rb_metadata {
|
||||
uint8_t pad[26];
|
||||
};
|
||||
|
||||
struct amdgpu_vcn5_fw_shared {
|
||||
uint32_t present_flag_0;
|
||||
uint8_t pad[12];
|
||||
struct amdgpu_fw_shared_unified_queue_struct sq;
|
||||
uint8_t pad1[8];
|
||||
struct amdgpu_fw_shared_fw_logging fw_log;
|
||||
struct amdgpu_fw_shared_rb_setup rb_setup;
|
||||
uint8_t pad2[4];
|
||||
};
|
||||
|
||||
#define VCN_BLOCK_ENCODE_DISABLE_MASK 0x80
|
||||
#define VCN_BLOCK_DECODE_DISABLE_MASK 0x40
|
||||
#define VCN_BLOCK_QUEUE_DISABLE_MASK 0xC0
|
||||
|
@ -658,6 +658,8 @@ static const struct amd_ip_funcs amdgpu_vkms_ip_funcs = {
|
||||
.soft_reset = amdgpu_vkms_soft_reset,
|
||||
.set_clockgating_state = amdgpu_vkms_set_clockgating_state,
|
||||
.set_powergating_state = amdgpu_vkms_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
const struct amdgpu_ip_block_version amdgpu_vkms_ip_block = {
|
||||
|
@ -469,7 +469,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
if (tbo->type != ttm_bo_type_kernel)
|
||||
max_bytes -= AMDGPU_VM_RESERVED_VRAM;
|
||||
|
||||
if (place->flags & TTM_PL_FLAG_CONTIGUOUS) {
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS) {
|
||||
pages_per_block = ~0ul;
|
||||
} else {
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
@ -478,7 +478,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
/* default to 2MB */
|
||||
pages_per_block = 2UL << (20UL - PAGE_SHIFT);
|
||||
#endif
|
||||
pages_per_block = max_t(uint32_t, pages_per_block,
|
||||
pages_per_block = max_t(u32, pages_per_block,
|
||||
tbo->page_alignment);
|
||||
}
|
||||
|
||||
@ -499,7 +499,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
if (place->flags & TTM_PL_FLAG_TOPDOWN)
|
||||
vres->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION;
|
||||
|
||||
if (place->flags & TTM_PL_FLAG_CONTIGUOUS)
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)
|
||||
vres->flags |= DRM_BUDDY_CONTIGUOUS_ALLOCATION;
|
||||
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CLEARED)
|
||||
@ -518,21 +518,31 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
|
||||
else
|
||||
min_block_size = mgr->default_page_size;
|
||||
|
||||
BUG_ON(min_block_size < mm->chunk_size);
|
||||
|
||||
/* Limit maximum size to 2GiB due to SG table limitations */
|
||||
size = min(remaining_size, 2ULL << 30);
|
||||
|
||||
if ((size >= (u64)pages_per_block << PAGE_SHIFT) &&
|
||||
!(size & (((u64)pages_per_block << PAGE_SHIFT) - 1)))
|
||||
!(size & (((u64)pages_per_block << PAGE_SHIFT) - 1)))
|
||||
min_block_size = (u64)pages_per_block << PAGE_SHIFT;
|
||||
|
||||
BUG_ON(min_block_size < mm->chunk_size);
|
||||
|
||||
r = drm_buddy_alloc_blocks(mm, fpfn,
|
||||
lpfn,
|
||||
size,
|
||||
min_block_size,
|
||||
&vres->blocks,
|
||||
vres->flags);
|
||||
|
||||
if (unlikely(r == -ENOSPC) && pages_per_block == ~0ul &&
|
||||
!(place->flags & TTM_PL_FLAG_CONTIGUOUS)) {
|
||||
vres->flags &= ~DRM_BUDDY_CONTIGUOUS_ALLOCATION;
|
||||
pages_per_block = max_t(u32, 2UL << (20UL - PAGE_SHIFT),
|
||||
tbo->page_alignment);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (unlikely(r))
|
||||
goto error_free_blocks;
|
||||
|
||||
|
@ -1243,6 +1243,7 @@ static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index,
|
||||
ectx.ps_size = params_size;
|
||||
ectx.abort = false;
|
||||
ectx.last_jump = 0;
|
||||
ectx.last_jump_jiffies = 0;
|
||||
if (ws) {
|
||||
ectx.ws = kcalloc(4, ws, GFP_KERNEL);
|
||||
ectx.ws_size = ws;
|
||||
|
@ -2210,6 +2210,8 @@ static const struct amd_ip_funcs cik_common_ip_funcs = {
|
||||
.soft_reset = cik_common_soft_reset,
|
||||
.set_clockgating_state = cik_common_set_clockgating_state,
|
||||
.set_powergating_state = cik_common_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ip_block_version cik_common_ip_block =
|
||||
|
@ -435,6 +435,8 @@ static const struct amd_ip_funcs cik_ih_ip_funcs = {
|
||||
.soft_reset = cik_ih_soft_reset,
|
||||
.set_clockgating_state = cik_ih_set_clockgating_state,
|
||||
.set_powergating_state = cik_ih_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ih_funcs cik_ih_funcs = {
|
||||
|
@ -1228,6 +1228,8 @@ static const struct amd_ip_funcs cik_sdma_ip_funcs = {
|
||||
.soft_reset = cik_sdma_soft_reset,
|
||||
.set_clockgating_state = cik_sdma_set_clockgating_state,
|
||||
.set_powergating_state = cik_sdma_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs cik_sdma_ring_funcs = {
|
||||
@ -1290,7 +1292,7 @@ static void cik_sdma_set_irq_funcs(struct amdgpu_device *adev)
|
||||
* @src_offset: src GPU address
|
||||
* @dst_offset: dst GPU address
|
||||
* @byte_count: number of bytes to xfer
|
||||
* @tmz: is this a secure operation
|
||||
* @copy_flags: unused
|
||||
*
|
||||
* Copy GPU buffers using the DMA engine (CIK).
|
||||
* Used by the amdgpu ttm implementation to move pages if
|
||||
@ -1300,7 +1302,7 @@ static void cik_sdma_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
uint64_t src_offset,
|
||||
uint64_t dst_offset,
|
||||
uint32_t byte_count,
|
||||
bool tmz)
|
||||
uint32_t copy_flags)
|
||||
{
|
||||
ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_LINEAR, 0);
|
||||
ib->ptr[ib->length_dw++] = byte_count;
|
||||
|
@ -433,6 +433,8 @@ static const struct amd_ip_funcs cz_ih_ip_funcs = {
|
||||
.soft_reset = cz_ih_soft_reset,
|
||||
.set_clockgating_state = cz_ih_set_clockgating_state,
|
||||
.set_powergating_state = cz_ih_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ih_funcs cz_ih_funcs = {
|
||||
|
@ -3333,6 +3333,8 @@ static const struct amd_ip_funcs dce_v10_0_ip_funcs = {
|
||||
.soft_reset = dce_v10_0_soft_reset,
|
||||
.set_clockgating_state = dce_v10_0_set_clockgating_state,
|
||||
.set_powergating_state = dce_v10_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -3464,6 +3464,8 @@ static const struct amd_ip_funcs dce_v11_0_ip_funcs = {
|
||||
.soft_reset = dce_v11_0_soft_reset,
|
||||
.set_clockgating_state = dce_v11_0_set_clockgating_state,
|
||||
.set_powergating_state = dce_v11_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -3154,6 +3154,8 @@ static const struct amd_ip_funcs dce_v6_0_ip_funcs = {
|
||||
.soft_reset = dce_v6_0_soft_reset,
|
||||
.set_clockgating_state = dce_v6_0_set_clockgating_state,
|
||||
.set_powergating_state = dce_v6_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -3242,6 +3242,8 @@ static const struct amd_ip_funcs dce_v8_0_ip_funcs = {
|
||||
.soft_reset = dce_v8_0_soft_reset,
|
||||
.set_clockgating_state = dce_v8_0_set_clockgating_state,
|
||||
.set_powergating_state = dce_v8_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -276,6 +276,99 @@ MODULE_FIRMWARE("amdgpu/gc_10_3_7_mec.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_10_3_7_mec2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_10_3_7_rlc.bin");
|
||||
|
||||
static const struct amdgpu_hwip_reg_entry gc_reg_list_10_1[] = {
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmGRBM_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmGRBM_STATUS2),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmGRBM_STATUS3),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_STALLED_STAT1),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_STALLED_STAT2),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CPC_STALLED_STAT1),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CPF_STALLED_STAT1),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_BUSY_STAT),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CPC_BUSY_STAT),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CPF_BUSY_STAT),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CPC_BUSY_STAT2),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CPF_BUSY_STAT2),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CPF_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_GFX_ERROR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_GFX_HPD_STATUS0),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_RB_BASE),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_RB0_BASE),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_RB0_RPTR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_RB0_WPTR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_RB1_BASE),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_RB1_RPTR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_RB1_WPTR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_RB2_BASE),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_RB2_WPTR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_RB2_WPTR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CE_IB1_CMD_BUFSZ),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CE_IB2_CMD_BUFSZ),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_IB1_CMD_BUFSZ),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_IB2_CMD_BUFSZ),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CE_IB1_BASE_LO),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CE_IB1_BASE_HI),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CE_IB1_BUFSZ),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CE_IB2_BASE_LO),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CE_IB2_BASE_HI),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CE_IB2_BUFSZ),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_IB1_BASE_LO),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_IB1_BASE_HI),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_IB1_BUFSZ),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_IB2_BASE_LO),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_IB2_BASE_HI),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_IB2_BUFSZ),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCPF_UTCL1_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCPC_UTCL1_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCPG_UTCL1_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmGDS_PROTECTION_FAULT),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmGDS_VM_PROTECTION_FAULT),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmIA_UTCL1_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmIA_UTCL1_STATUS_2),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmPA_CL_CNTL_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_UTCL1_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRMI_UTCL1_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmSQC_DCACHE_UTCL0_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmSQC_ICACHE_UTCL0_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmSQG_UTCL0_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmTCP_UTCL0_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmWD_UTCL1_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmGCVM_L2_PROTECTION_FAULT_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_DEBUG),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_MEC_CNTL),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_MES_CNTL),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CE_INSTR_PNTR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_MEC1_INSTR_PNTR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_MEC2_INSTR_PNTR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_MES_DEBUG_INTERRUPT_INSTR_PNTR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_MES_INSTR_PNTR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_ME_INSTR_PNTR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_PFP_INSTR_PNTR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmCP_CPC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_STAT),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_SMU_COMMAND),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_SMU_MESSAGE),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_SMU_ARGUMENT_1),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_SMU_ARGUMENT_2),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_SMU_ARGUMENT_3),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_SMU_ARGUMENT_4),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmSMU_RLC_RESPONSE),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_SAFE_MODE),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_SMU_SAFE_MODE),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_RLCS_GPM_STAT_2),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_SPP_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_RLCS_BOOTLOAD_STATUS),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_INT_STAT),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_GPM_GENERAL_6),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_GPM_DEBUG_INST_A),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_GPM_DEBUG_INST_B),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_GPM_DEBUG_INST_ADDR),
|
||||
SOC15_REG_ENTRY_STR(GC, 0, mmRLC_LX6_CORE_PDEBUG_INST)
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_gc_10_1[] = {
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x00400014),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_CPF_CLK_CTRL, 0xfcff8fff, 0xf8000100),
|
||||
@ -4490,6 +4583,22 @@ static int gfx_v10_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
|
||||
hw_prio, NULL);
|
||||
}
|
||||
|
||||
static void gfx_v10_0_alloc_dump_mem(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t reg_count = ARRAY_SIZE(gc_reg_list_10_1);
|
||||
uint32_t *ptr;
|
||||
|
||||
ptr = kcalloc(reg_count, sizeof(uint32_t), GFP_KERNEL);
|
||||
if (ptr == NULL) {
|
||||
DRM_ERROR("Failed to allocate memory for IP Dump\n");
|
||||
adev->gfx.ip_dump = NULL;
|
||||
adev->gfx.reg_count = 0;
|
||||
} else {
|
||||
adev->gfx.ip_dump = ptr;
|
||||
adev->gfx.reg_count = reg_count;
|
||||
}
|
||||
}
|
||||
|
||||
static int gfx_v10_0_sw_init(void *handle)
|
||||
{
|
||||
int i, j, k, r, ring_id = 0;
|
||||
@ -4642,6 +4751,8 @@ static int gfx_v10_0_sw_init(void *handle)
|
||||
|
||||
gfx_v10_0_gpu_early_init(adev);
|
||||
|
||||
gfx_v10_0_alloc_dump_mem(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4694,6 +4805,8 @@ static int gfx_v10_0_sw_fini(void *handle)
|
||||
|
||||
gfx_v10_0_free_microcode(adev);
|
||||
|
||||
kfree(adev->gfx.ip_dump);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -9154,6 +9267,36 @@ static void gfx_v10_0_emit_mem_sync(struct amdgpu_ring *ring)
|
||||
amdgpu_ring_write(ring, gcr_cntl); /* GCR_CNTL */
|
||||
}
|
||||
|
||||
static void gfx_v10_ip_print(void *handle, struct drm_printer *p)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
uint32_t i;
|
||||
uint32_t reg_count = ARRAY_SIZE(gc_reg_list_10_1);
|
||||
|
||||
if (!adev->gfx.ip_dump)
|
||||
return;
|
||||
|
||||
for (i = 0; i < reg_count; i++)
|
||||
drm_printf(p, "%-50s \t 0x%08x\n",
|
||||
gc_reg_list_10_1[i].reg_name,
|
||||
adev->gfx.ip_dump[i]);
|
||||
}
|
||||
|
||||
static void gfx_v10_ip_dump(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
uint32_t i;
|
||||
uint32_t reg_count = ARRAY_SIZE(gc_reg_list_10_1);
|
||||
|
||||
if (!adev->gfx.ip_dump)
|
||||
return;
|
||||
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
for (i = 0; i < reg_count; i++)
|
||||
adev->gfx.ip_dump[i] = RREG32(SOC15_REG_ENTRY_OFFSET(gc_reg_list_10_1[i]));
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
}
|
||||
|
||||
static const struct amd_ip_funcs gfx_v10_0_ip_funcs = {
|
||||
.name = "gfx_v10_0",
|
||||
.early_init = gfx_v10_0_early_init,
|
||||
@ -9170,6 +9313,8 @@ static const struct amd_ip_funcs gfx_v10_0_ip_funcs = {
|
||||
.set_clockgating_state = gfx_v10_0_set_clockgating_state,
|
||||
.set_powergating_state = gfx_v10_0_set_powergating_state,
|
||||
.get_clockgating_state = gfx_v10_0_get_clockgating_state,
|
||||
.dump_ip_state = gfx_v10_ip_dump,
|
||||
.print_ip_state = gfx_v10_ip_print,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {
|
||||
|
@ -6169,6 +6169,8 @@ static const struct amd_ip_funcs gfx_v11_0_ip_funcs = {
|
||||
.set_clockgating_state = gfx_v11_0_set_clockgating_state,
|
||||
.set_powergating_state = gfx_v11_0_set_powergating_state,
|
||||
.get_clockgating_state = gfx_v11_0_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_gfx = {
|
||||
|
@ -3457,6 +3457,8 @@ static const struct amd_ip_funcs gfx_v6_0_ip_funcs = {
|
||||
.soft_reset = gfx_v6_0_soft_reset,
|
||||
.set_clockgating_state = gfx_v6_0_set_clockgating_state,
|
||||
.set_powergating_state = gfx_v6_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v6_0_ring_funcs_gfx = {
|
||||
|
@ -4977,6 +4977,8 @@ static const struct amd_ip_funcs gfx_v7_0_ip_funcs = {
|
||||
.soft_reset = gfx_v7_0_soft_reset,
|
||||
.set_clockgating_state = gfx_v7_0_set_clockgating_state,
|
||||
.set_powergating_state = gfx_v7_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v7_0_ring_funcs_gfx = {
|
||||
|
@ -6878,6 +6878,8 @@ static const struct amd_ip_funcs gfx_v8_0_ip_funcs = {
|
||||
.set_clockgating_state = gfx_v8_0_set_clockgating_state,
|
||||
.set_powergating_state = gfx_v8_0_set_powergating_state,
|
||||
.get_clockgating_state = gfx_v8_0_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_gfx = {
|
||||
|
@ -6856,6 +6856,8 @@ static const struct amd_ip_funcs gfx_v9_0_ip_funcs = {
|
||||
.set_clockgating_state = gfx_v9_0_set_clockgating_state,
|
||||
.set_powergating_state = gfx_v9_0_set_powergating_state,
|
||||
.get_clockgating_state = gfx_v9_0_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_gfx = {
|
||||
|
@ -431,16 +431,16 @@ out:
|
||||
|
||||
static int gfx_v9_4_3_init_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const char *chip_name;
|
||||
char ucode_prefix[15];
|
||||
int r;
|
||||
|
||||
chip_name = "gc_9_4_3";
|
||||
amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix));
|
||||
|
||||
r = gfx_v9_4_3_init_rlc_microcode(adev, chip_name);
|
||||
r = gfx_v9_4_3_init_rlc_microcode(adev, ucode_prefix);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = gfx_v9_4_3_init_cp_compute_microcode(adev, chip_name);
|
||||
r = gfx_v9_4_3_init_cp_compute_microcode(adev, ucode_prefix);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@ -2404,10 +2404,10 @@ gfx_v9_4_3_xcc_update_coarse_grain_clock_gating(struct amdgpu_device *adev,
|
||||
if (def != data)
|
||||
WREG32_SOC15(GC, GET_INST(GC, xcc_id), regRLC_CGTT_MGCG_OVERRIDE, data);
|
||||
|
||||
/* enable cgcg FSM(0x0000363F) */
|
||||
/* CGCG Hysteresis: 400us */
|
||||
def = RREG32_SOC15(GC, GET_INST(GC, xcc_id), regRLC_CGCG_CGLS_CTRL);
|
||||
|
||||
data = (0x36
|
||||
data = (0x2710
|
||||
<< RLC_CGCG_CGLS_CTRL__CGCG_GFX_IDLE_THRESHOLD__SHIFT) |
|
||||
RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK;
|
||||
if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGLS)
|
||||
@ -2416,10 +2416,10 @@ gfx_v9_4_3_xcc_update_coarse_grain_clock_gating(struct amdgpu_device *adev,
|
||||
if (def != data)
|
||||
WREG32_SOC15(GC, GET_INST(GC, xcc_id), regRLC_CGCG_CGLS_CTRL, data);
|
||||
|
||||
/* set IDLE_POLL_COUNT(0x00900100) */
|
||||
/* set IDLE_POLL_COUNT(0x33450100)*/
|
||||
def = RREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_RB_WPTR_POLL_CNTL);
|
||||
data = (0x0100 << CP_RB_WPTR_POLL_CNTL__POLL_FREQUENCY__SHIFT) |
|
||||
(0x0090 << CP_RB_WPTR_POLL_CNTL__IDLE_POLL_COUNT__SHIFT);
|
||||
(0x3345 << CP_RB_WPTR_POLL_CNTL__IDLE_POLL_COUNT__SHIFT);
|
||||
if (def != data)
|
||||
WREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_RB_WPTR_POLL_CNTL, data);
|
||||
} else {
|
||||
@ -4016,6 +4016,8 @@ static const struct amd_ip_funcs gfx_v9_4_3_ip_funcs = {
|
||||
.set_clockgating_state = gfx_v9_4_3_set_clockgating_state,
|
||||
.set_powergating_state = gfx_v9_4_3_set_powergating_state,
|
||||
.get_clockgating_state = gfx_v9_4_3_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v9_4_3_ring_funcs_compute = {
|
||||
|
@ -1115,6 +1115,8 @@ static const struct amd_ip_funcs gmc_v6_0_ip_funcs = {
|
||||
.soft_reset = gmc_v6_0_soft_reset,
|
||||
.set_clockgating_state = gmc_v6_0_set_clockgating_state,
|
||||
.set_powergating_state = gmc_v6_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_gmc_funcs gmc_v6_0_gmc_funcs = {
|
||||
|
@ -1354,6 +1354,8 @@ static const struct amd_ip_funcs gmc_v7_0_ip_funcs = {
|
||||
.soft_reset = gmc_v7_0_soft_reset,
|
||||
.set_clockgating_state = gmc_v7_0_set_clockgating_state,
|
||||
.set_powergating_state = gmc_v7_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_gmc_funcs gmc_v7_0_gmc_funcs = {
|
||||
|
@ -1717,6 +1717,8 @@ static const struct amd_ip_funcs gmc_v8_0_ip_funcs = {
|
||||
.set_clockgating_state = gmc_v8_0_set_clockgating_state,
|
||||
.set_powergating_state = gmc_v8_0_set_powergating_state,
|
||||
.get_clockgating_state = gmc_v8_0_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_gmc_funcs gmc_v8_0_gmc_funcs = {
|
||||
|
@ -425,6 +425,8 @@ static const struct amd_ip_funcs iceland_ih_ip_funcs = {
|
||||
.soft_reset = iceland_ih_soft_reset,
|
||||
.set_clockgating_state = iceland_ih_set_clockgating_state,
|
||||
.set_powergating_state = iceland_ih_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ih_funcs iceland_ih_funcs = {
|
||||
|
@ -770,6 +770,8 @@ static const struct amd_ip_funcs ih_v6_0_ip_funcs = {
|
||||
.set_clockgating_state = ih_v6_0_set_clockgating_state,
|
||||
.set_powergating_state = ih_v6_0_set_powergating_state,
|
||||
.get_clockgating_state = ih_v6_0_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ih_funcs ih_v6_0_funcs = {
|
||||
|
@ -775,6 +775,8 @@ static const struct amd_ip_funcs ih_v6_1_ip_funcs = {
|
||||
.set_clockgating_state = ih_v6_1_set_clockgating_state,
|
||||
.set_powergating_state = ih_v6_1_set_powergating_state,
|
||||
.get_clockgating_state = ih_v6_1_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ih_funcs ih_v6_1_funcs = {
|
||||
|
@ -749,6 +749,8 @@ static const struct amd_ip_funcs ih_v7_0_ip_funcs = {
|
||||
.set_clockgating_state = ih_v7_0_set_clockgating_state,
|
||||
.set_powergating_state = ih_v7_0_set_powergating_state,
|
||||
.get_clockgating_state = ih_v7_0_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ih_funcs ih_v7_0_funcs = {
|
||||
|
@ -759,6 +759,8 @@ static const struct amd_ip_funcs jpeg_v2_0_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = jpeg_v2_0_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v2_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v2_0_dec_ring_vm_funcs = {
|
||||
|
@ -632,6 +632,8 @@ static const struct amd_ip_funcs jpeg_v2_5_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = jpeg_v2_5_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v2_5_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amd_ip_funcs jpeg_v2_6_ip_funcs = {
|
||||
@ -652,6 +654,8 @@ static const struct amd_ip_funcs jpeg_v2_6_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = jpeg_v2_5_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v2_5_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v2_5_dec_ring_vm_funcs = {
|
||||
|
@ -557,6 +557,8 @@ static const struct amd_ip_funcs jpeg_v3_0_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = jpeg_v3_0_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v3_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v3_0_dec_ring_vm_funcs = {
|
||||
|
@ -719,6 +719,8 @@ static const struct amd_ip_funcs jpeg_v4_0_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = jpeg_v4_0_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v4_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v4_0_dec_ring_vm_funcs = {
|
||||
|
@ -1053,6 +1053,8 @@ static const struct amd_ip_funcs jpeg_v4_0_3_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = jpeg_v4_0_3_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v4_0_3_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v4_0_3_dec_ring_vm_funcs = {
|
||||
|
@ -762,6 +762,8 @@ static const struct amd_ip_funcs jpeg_v4_0_5_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = jpeg_v4_0_5_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v4_0_5_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v4_0_5_dec_ring_vm_funcs = {
|
||||
|
@ -513,6 +513,8 @@ static const struct amd_ip_funcs jpeg_v5_0_0_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = jpeg_v5_0_0_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v5_0_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v5_0_0_dec_ring_vm_funcs = {
|
||||
|
@ -1176,6 +1176,8 @@ static const struct amd_ip_funcs mes_v10_1_ip_funcs = {
|
||||
.hw_fini = mes_v10_1_hw_fini,
|
||||
.suspend = mes_v10_1_suspend,
|
||||
.resume = mes_v10_1_resume,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
const struct amdgpu_ip_block_version mes_v10_1_ip_block = {
|
||||
|
@ -100,18 +100,76 @@ static const struct amdgpu_ring_funcs mes_v11_0_ring_funcs = {
|
||||
.insert_nop = amdgpu_ring_insert_nop,
|
||||
};
|
||||
|
||||
static const char *mes_v11_0_opcodes[] = {
|
||||
"SET_HW_RSRC",
|
||||
"SET_SCHEDULING_CONFIG",
|
||||
"ADD_QUEUE",
|
||||
"REMOVE_QUEUE",
|
||||
"PERFORM_YIELD",
|
||||
"SET_GANG_PRIORITY_LEVEL",
|
||||
"SUSPEND",
|
||||
"RESUME",
|
||||
"RESET",
|
||||
"SET_LOG_BUFFER",
|
||||
"CHANGE_GANG_PRORITY",
|
||||
"QUERY_SCHEDULER_STATUS",
|
||||
"PROGRAM_GDS",
|
||||
"SET_DEBUG_VMID",
|
||||
"MISC",
|
||||
"UPDATE_ROOT_PAGE_TABLE",
|
||||
"AMD_LOG",
|
||||
};
|
||||
|
||||
static const char *mes_v11_0_misc_opcodes[] = {
|
||||
"WRITE_REG",
|
||||
"INV_GART",
|
||||
"QUERY_STATUS",
|
||||
"READ_REG",
|
||||
"WAIT_REG_MEM",
|
||||
"SET_SHADER_DEBUGGER",
|
||||
};
|
||||
|
||||
static const char *mes_v11_0_get_op_string(union MESAPI__MISC *x_pkt)
|
||||
{
|
||||
const char *op_str = NULL;
|
||||
|
||||
if (x_pkt->header.opcode < ARRAY_SIZE(mes_v11_0_opcodes))
|
||||
op_str = mes_v11_0_opcodes[x_pkt->header.opcode];
|
||||
|
||||
return op_str;
|
||||
}
|
||||
|
||||
static const char *mes_v11_0_get_misc_op_string(union MESAPI__MISC *x_pkt)
|
||||
{
|
||||
const char *op_str = NULL;
|
||||
|
||||
if ((x_pkt->header.opcode == MES_SCH_API_MISC) &&
|
||||
(x_pkt->opcode < ARRAY_SIZE(mes_v11_0_misc_opcodes)))
|
||||
op_str = mes_v11_0_misc_opcodes[x_pkt->opcode];
|
||||
|
||||
return op_str;
|
||||
}
|
||||
|
||||
static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
||||
void *pkt, int size,
|
||||
int api_status_off)
|
||||
{
|
||||
int ndw = size / 4;
|
||||
signed long r;
|
||||
union MESAPI__ADD_QUEUE *x_pkt = pkt;
|
||||
union MESAPI__MISC *x_pkt = pkt;
|
||||
struct MES_API_STATUS *api_status;
|
||||
struct amdgpu_device *adev = mes->adev;
|
||||
struct amdgpu_ring *ring = &mes->ring;
|
||||
unsigned long flags;
|
||||
signed long timeout = 3000000; /* 3000 ms */
|
||||
const char *op_str, *misc_op_str;
|
||||
u32 fence_offset;
|
||||
u64 fence_gpu_addr;
|
||||
u64 *fence_ptr;
|
||||
int ret;
|
||||
|
||||
if (x_pkt->header.opcode >= MES_SCH_API_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if (amdgpu_emu_mode) {
|
||||
timeout *= 100;
|
||||
@ -121,27 +179,52 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
|
||||
}
|
||||
BUG_ON(size % 4 != 0);
|
||||
|
||||
ret = amdgpu_device_wb_get(adev, &fence_offset);
|
||||
if (ret)
|
||||
return ret;
|
||||
fence_gpu_addr =
|
||||
adev->wb.gpu_addr + (fence_offset * 4);
|
||||
fence_ptr = (u64 *)&adev->wb.wb[fence_offset];
|
||||
*fence_ptr = 0;
|
||||
|
||||
spin_lock_irqsave(&mes->ring_lock, flags);
|
||||
if (amdgpu_ring_alloc(ring, ndw)) {
|
||||
spin_unlock_irqrestore(&mes->ring_lock, flags);
|
||||
amdgpu_device_wb_free(adev, fence_offset);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
api_status = (struct MES_API_STATUS *)((char *)pkt + api_status_off);
|
||||
api_status->api_completion_fence_addr = mes->ring.fence_drv.gpu_addr;
|
||||
api_status->api_completion_fence_value = ++mes->ring.fence_drv.sync_seq;
|
||||
api_status->api_completion_fence_addr = fence_gpu_addr;
|
||||
api_status->api_completion_fence_value = 1;
|
||||
|
||||
amdgpu_ring_write_multiple(ring, pkt, ndw);
|
||||
amdgpu_ring_commit(ring);
|
||||
spin_unlock_irqrestore(&mes->ring_lock, flags);
|
||||
|
||||
DRM_DEBUG("MES msg=%d was emitted\n", x_pkt->header.opcode);
|
||||
op_str = mes_v11_0_get_op_string(x_pkt);
|
||||
misc_op_str = mes_v11_0_get_misc_op_string(x_pkt);
|
||||
|
||||
r = amdgpu_fence_wait_polling(ring, ring->fence_drv.sync_seq,
|
||||
timeout);
|
||||
if (misc_op_str)
|
||||
dev_dbg(adev->dev, "MES msg=%s (%s) was emitted\n", op_str, misc_op_str);
|
||||
else if (op_str)
|
||||
dev_dbg(adev->dev, "MES msg=%s was emitted\n", op_str);
|
||||
else
|
||||
dev_dbg(adev->dev, "MES msg=%d was emitted\n", x_pkt->header.opcode);
|
||||
|
||||
r = amdgpu_mes_fence_wait_polling(fence_ptr, (u64)1, timeout);
|
||||
amdgpu_device_wb_free(adev, fence_offset);
|
||||
if (r < 1) {
|
||||
DRM_ERROR("MES failed to response msg=%d\n",
|
||||
x_pkt->header.opcode);
|
||||
|
||||
if (misc_op_str)
|
||||
dev_err(adev->dev, "MES failed to respond to msg=%s (%s)\n",
|
||||
op_str, misc_op_str);
|
||||
else if (op_str)
|
||||
dev_err(adev->dev, "MES failed to respond to msg=%s\n",
|
||||
op_str);
|
||||
else
|
||||
dev_err(adev->dev, "MES failed to respond to msg=%d\n",
|
||||
x_pkt->header.opcode);
|
||||
|
||||
while (halt_if_hws_hang)
|
||||
schedule();
|
||||
@ -1334,6 +1417,8 @@ static const struct amd_ip_funcs mes_v11_0_ip_funcs = {
|
||||
.hw_fini = mes_v11_0_hw_fini,
|
||||
.suspend = mes_v11_0_suspend,
|
||||
.resume = mes_v11_0_resume,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
const struct amdgpu_ip_block_version mes_v11_0_ip_block = {
|
||||
|
@ -713,6 +713,8 @@ static const struct amd_ip_funcs navi10_ih_ip_funcs = {
|
||||
.set_clockgating_state = navi10_ih_set_clockgating_state,
|
||||
.set_powergating_state = navi10_ih_set_powergating_state,
|
||||
.get_clockgating_state = navi10_ih_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ih_funcs navi10_ih_funcs = {
|
||||
|
@ -110,7 +110,7 @@ static const struct amdgpu_video_codec_info sc_video_codecs_decode_array_vcn0[]
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 16384, 16384, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
|
||||
};
|
||||
@ -121,7 +121,7 @@ static const struct amdgpu_video_codec_info sc_video_codecs_decode_array_vcn1[]
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 16384, 16384, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
|
||||
};
|
||||
|
||||
@ -199,7 +199,7 @@ static const struct amdgpu_video_codec_info yc_video_codecs_decode_array[] = {
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 16384, 16384, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
|
||||
};
|
||||
|
||||
@ -1131,4 +1131,6 @@ static const struct amd_ip_funcs nv_common_ip_funcs = {
|
||||
.set_clockgating_state = nv_common_set_clockgating_state,
|
||||
.set_powergating_state = nv_common_set_powergating_state,
|
||||
.get_clockgating_state = nv_common_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
@ -1113,6 +1113,8 @@ static const struct amd_ip_funcs sdma_v2_4_ip_funcs = {
|
||||
.soft_reset = sdma_v2_4_soft_reset,
|
||||
.set_clockgating_state = sdma_v2_4_set_clockgating_state,
|
||||
.set_powergating_state = sdma_v2_4_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs sdma_v2_4_ring_funcs = {
|
||||
@ -1176,7 +1178,7 @@ static void sdma_v2_4_set_irq_funcs(struct amdgpu_device *adev)
|
||||
* @src_offset: src GPU address
|
||||
* @dst_offset: dst GPU address
|
||||
* @byte_count: number of bytes to xfer
|
||||
* @tmz: unused
|
||||
* @copy_flags: unused
|
||||
*
|
||||
* Copy GPU buffers using the DMA engine (VI).
|
||||
* Used by the amdgpu ttm implementation to move pages if
|
||||
@ -1186,7 +1188,7 @@ static void sdma_v2_4_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
uint64_t src_offset,
|
||||
uint64_t dst_offset,
|
||||
uint32_t byte_count,
|
||||
bool tmz)
|
||||
uint32_t copy_flags)
|
||||
{
|
||||
ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
|
||||
SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR);
|
||||
|
@ -1553,6 +1553,8 @@ static const struct amd_ip_funcs sdma_v3_0_ip_funcs = {
|
||||
.set_clockgating_state = sdma_v3_0_set_clockgating_state,
|
||||
.set_powergating_state = sdma_v3_0_set_powergating_state,
|
||||
.get_clockgating_state = sdma_v3_0_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs sdma_v3_0_ring_funcs = {
|
||||
@ -1616,7 +1618,7 @@ static void sdma_v3_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
* @src_offset: src GPU address
|
||||
* @dst_offset: dst GPU address
|
||||
* @byte_count: number of bytes to xfer
|
||||
* @tmz: unused
|
||||
* @copy_flags: unused
|
||||
*
|
||||
* Copy GPU buffers using the DMA engine (VI).
|
||||
* Used by the amdgpu ttm implementation to move pages if
|
||||
@ -1626,7 +1628,7 @@ static void sdma_v3_0_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
uint64_t src_offset,
|
||||
uint64_t dst_offset,
|
||||
uint32_t byte_count,
|
||||
bool tmz)
|
||||
uint32_t copy_flags)
|
||||
{
|
||||
ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
|
||||
SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR);
|
||||
|
@ -2021,6 +2021,9 @@ static int sdma_v4_0_process_trap_irq(struct amdgpu_device *adev,
|
||||
|
||||
DRM_DEBUG("IH: SDMA trap\n");
|
||||
instance = sdma_v4_0_irq_id_to_seq(entry->client_id);
|
||||
if (instance < 0)
|
||||
return instance;
|
||||
|
||||
switch (entry->ring_id) {
|
||||
case 0:
|
||||
amdgpu_fence_process(&adev->sdma.instance[instance].ring);
|
||||
@ -2448,7 +2451,7 @@ static void sdma_v4_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
* @src_offset: src GPU address
|
||||
* @dst_offset: dst GPU address
|
||||
* @byte_count: number of bytes to xfer
|
||||
* @tmz: if a secure copy should be used
|
||||
* @copy_flags: copy flags for the buffers
|
||||
*
|
||||
* Copy GPU buffers using the DMA engine (VEGA10/12).
|
||||
* Used by the amdgpu ttm implementation to move pages if
|
||||
@ -2458,11 +2461,11 @@ static void sdma_v4_0_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
uint64_t src_offset,
|
||||
uint64_t dst_offset,
|
||||
uint32_t byte_count,
|
||||
bool tmz)
|
||||
uint32_t copy_flags)
|
||||
{
|
||||
ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
|
||||
SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR) |
|
||||
SDMA_PKT_COPY_LINEAR_HEADER_TMZ(tmz ? 1 : 0);
|
||||
SDMA_PKT_COPY_LINEAR_HEADER_TMZ((copy_flags & AMDGPU_COPY_FLAGS_TMZ) ? 1 : 0);
|
||||
ib->ptr[ib->length_dw++] = byte_count - 1;
|
||||
ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
|
||||
ib->ptr[ib->length_dw++] = lower_32_bits(src_offset);
|
||||
|
@ -1945,7 +1945,7 @@ static void sdma_v4_4_2_set_irq_funcs(struct amdgpu_device *adev)
|
||||
* @src_offset: src GPU address
|
||||
* @dst_offset: dst GPU address
|
||||
* @byte_count: number of bytes to xfer
|
||||
* @tmz: if a secure copy should be used
|
||||
* @copy_flags: copy flags for the buffers
|
||||
*
|
||||
* Copy GPU buffers using the DMA engine.
|
||||
* Used by the amdgpu ttm implementation to move pages if
|
||||
@ -1955,11 +1955,11 @@ static void sdma_v4_4_2_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
uint64_t src_offset,
|
||||
uint64_t dst_offset,
|
||||
uint32_t byte_count,
|
||||
bool tmz)
|
||||
uint32_t copy_flags)
|
||||
{
|
||||
ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
|
||||
SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR) |
|
||||
SDMA_PKT_COPY_LINEAR_HEADER_TMZ(tmz ? 1 : 0);
|
||||
SDMA_PKT_COPY_LINEAR_HEADER_TMZ((copy_flags & AMDGPU_COPY_FLAGS_TMZ) ? 1 : 0);
|
||||
ib->ptr[ib->length_dw++] = byte_count - 1;
|
||||
ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
|
||||
ib->ptr[ib->length_dw++] = lower_32_bits(src_offset);
|
||||
|
@ -999,7 +999,8 @@ static int sdma_v5_0_ring_test_ring(struct amdgpu_ring *ring)
|
||||
r = amdgpu_ring_alloc(ring, 20);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu: dma failed to lock ring %d (%d).\n", ring->idx, r);
|
||||
amdgpu_device_wb_free(adev, index);
|
||||
if (!ring->is_mes_queue)
|
||||
amdgpu_device_wb_free(adev, index);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -1805,7 +1806,7 @@ static void sdma_v5_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
* @src_offset: src GPU address
|
||||
* @dst_offset: dst GPU address
|
||||
* @byte_count: number of bytes to xfer
|
||||
* @tmz: if a secure copy should be used
|
||||
* @copy_flags: copy flags for the buffers
|
||||
*
|
||||
* Copy GPU buffers using the DMA engine (NAVI10).
|
||||
* Used by the amdgpu ttm implementation to move pages if
|
||||
@ -1815,11 +1816,11 @@ static void sdma_v5_0_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
uint64_t src_offset,
|
||||
uint64_t dst_offset,
|
||||
uint32_t byte_count,
|
||||
bool tmz)
|
||||
uint32_t copy_flags)
|
||||
{
|
||||
ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
|
||||
SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR) |
|
||||
SDMA_PKT_COPY_LINEAR_HEADER_TMZ(tmz ? 1 : 0);
|
||||
SDMA_PKT_COPY_LINEAR_HEADER_TMZ((copy_flags & AMDGPU_COPY_FLAGS_TMZ) ? 1 : 0);
|
||||
ib->ptr[ib->length_dw++] = byte_count - 1;
|
||||
ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
|
||||
ib->ptr[ib->length_dw++] = lower_32_bits(src_offset);
|
||||
|
@ -839,7 +839,8 @@ static int sdma_v5_2_ring_test_ring(struct amdgpu_ring *ring)
|
||||
r = amdgpu_ring_alloc(ring, 20);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu: dma failed to lock ring %d (%d).\n", ring->idx, r);
|
||||
amdgpu_device_wb_free(adev, index);
|
||||
if (!ring->is_mes_queue)
|
||||
amdgpu_device_wb_free(adev, index);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -1751,7 +1752,7 @@ static void sdma_v5_2_set_irq_funcs(struct amdgpu_device *adev)
|
||||
* @src_offset: src GPU address
|
||||
* @dst_offset: dst GPU address
|
||||
* @byte_count: number of bytes to xfer
|
||||
* @tmz: if a secure copy should be used
|
||||
* @copy_flags: copy flags for the buffers
|
||||
*
|
||||
* Copy GPU buffers using the DMA engine.
|
||||
* Used by the amdgpu ttm implementation to move pages if
|
||||
@ -1761,11 +1762,11 @@ static void sdma_v5_2_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
uint64_t src_offset,
|
||||
uint64_t dst_offset,
|
||||
uint32_t byte_count,
|
||||
bool tmz)
|
||||
uint32_t copy_flags)
|
||||
{
|
||||
ib->ptr[ib->length_dw++] = SDMA_PKT_HEADER_OP(SDMA_OP_COPY) |
|
||||
SDMA_PKT_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR) |
|
||||
SDMA_PKT_COPY_LINEAR_HEADER_TMZ(tmz ? 1 : 0);
|
||||
SDMA_PKT_COPY_LINEAR_HEADER_TMZ((copy_flags & AMDGPU_COPY_FLAGS_TMZ) ? 1 : 0);
|
||||
ib->ptr[ib->length_dw++] = byte_count - 1;
|
||||
ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
|
||||
ib->ptr[ib->length_dw++] = lower_32_bits(src_offset);
|
||||
|
@ -861,7 +861,8 @@ static int sdma_v6_0_ring_test_ring(struct amdgpu_ring *ring)
|
||||
r = amdgpu_ring_alloc(ring, 5);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu: dma failed to lock ring %d (%d).\n", ring->idx, r);
|
||||
amdgpu_device_wb_free(adev, index);
|
||||
if (!ring->is_mes_queue)
|
||||
amdgpu_device_wb_free(adev, index);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -1574,7 +1575,7 @@ static void sdma_v6_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
* @src_offset: src GPU address
|
||||
* @dst_offset: dst GPU address
|
||||
* @byte_count: number of bytes to xfer
|
||||
* @tmz: if a secure copy should be used
|
||||
* @copy_flags: copy flags for the buffers
|
||||
*
|
||||
* Copy GPU buffers using the DMA engine.
|
||||
* Used by the amdgpu ttm implementation to move pages if
|
||||
@ -1584,11 +1585,11 @@ static void sdma_v6_0_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
uint64_t src_offset,
|
||||
uint64_t dst_offset,
|
||||
uint32_t byte_count,
|
||||
bool tmz)
|
||||
uint32_t copy_flags)
|
||||
{
|
||||
ib->ptr[ib->length_dw++] = SDMA_PKT_COPY_LINEAR_HEADER_OP(SDMA_OP_COPY) |
|
||||
SDMA_PKT_COPY_LINEAR_HEADER_SUB_OP(SDMA_SUBOP_COPY_LINEAR) |
|
||||
SDMA_PKT_COPY_LINEAR_HEADER_TMZ(tmz ? 1 : 0);
|
||||
SDMA_PKT_COPY_LINEAR_HEADER_TMZ((copy_flags & AMDGPU_COPY_FLAGS_TMZ) ? 1 : 0);
|
||||
ib->ptr[ib->length_dw++] = byte_count - 1;
|
||||
ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
|
||||
ib->ptr[ib->length_dw++] = lower_32_bits(src_offset);
|
||||
|
@ -2706,6 +2706,8 @@ static const struct amd_ip_funcs si_common_ip_funcs = {
|
||||
.soft_reset = si_common_soft_reset,
|
||||
.set_clockgating_state = si_common_set_clockgating_state,
|
||||
.set_powergating_state = si_common_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ip_block_version si_common_ip_block =
|
||||
|
@ -708,6 +708,8 @@ static const struct amd_ip_funcs si_dma_ip_funcs = {
|
||||
.soft_reset = si_dma_soft_reset,
|
||||
.set_clockgating_state = si_dma_set_clockgating_state,
|
||||
.set_powergating_state = si_dma_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs si_dma_ring_funcs = {
|
||||
@ -761,7 +763,7 @@ static void si_dma_set_irq_funcs(struct amdgpu_device *adev)
|
||||
* @src_offset: src GPU address
|
||||
* @dst_offset: dst GPU address
|
||||
* @byte_count: number of bytes to xfer
|
||||
* @tmz: is this a secure operation
|
||||
* @copy_flags: unused
|
||||
*
|
||||
* Copy GPU buffers using the DMA engine (VI).
|
||||
* Used by the amdgpu ttm implementation to move pages if
|
||||
@ -771,7 +773,7 @@ static void si_dma_emit_copy_buffer(struct amdgpu_ib *ib,
|
||||
uint64_t src_offset,
|
||||
uint64_t dst_offset,
|
||||
uint32_t byte_count,
|
||||
bool tmz)
|
||||
uint32_t copy_flags)
|
||||
{
|
||||
ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_COPY,
|
||||
1, 0, 0, byte_count);
|
||||
|
@ -296,6 +296,8 @@ static const struct amd_ip_funcs si_ih_ip_funcs = {
|
||||
.soft_reset = si_ih_soft_reset,
|
||||
.set_clockgating_state = si_ih_set_clockgating_state,
|
||||
.set_powergating_state = si_ih_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ih_funcs si_ih_funcs = {
|
||||
|
@ -92,7 +92,7 @@ static int sienna_cichlid_mode2_suspend_ip(struct amdgpu_device *adev)
|
||||
adev->ip_blocks[i].status.hw = false;
|
||||
}
|
||||
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -143,7 +143,7 @@ static const struct amdgpu_video_codec_info rn_video_codecs_decode_array[] =
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 16384, 16384, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
|
||||
};
|
||||
|
||||
@ -156,7 +156,7 @@ static const struct amdgpu_video_codecs rn_video_codecs_decode =
|
||||
static const struct amdgpu_video_codec_info vcn_4_0_3_video_codecs_decode_array[] = {
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 16384, 16384, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
|
||||
};
|
||||
@ -1501,4 +1501,6 @@ static const struct amd_ip_funcs soc15_common_ip_funcs = {
|
||||
.set_clockgating_state = soc15_common_set_clockgating_state,
|
||||
.set_powergating_state = soc15_common_set_powergating_state,
|
||||
.get_clockgating_state= soc15_common_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
@ -88,6 +88,8 @@ struct soc15_ras_field_entry {
|
||||
};
|
||||
|
||||
#define SOC15_REG_ENTRY(ip, inst, reg) ip##_HWIP, inst, reg##_BASE_IDX, reg
|
||||
#define SOC15_REG_ENTRY_STR(ip, inst, reg) \
|
||||
{ ip##_HWIP, inst, reg##_BASE_IDX, reg, #reg }
|
||||
|
||||
#define SOC15_REG_ENTRY_OFFSET(entry) (adev->reg_offset[entry.hwip][entry.inst][entry.seg] + entry.reg_offset)
|
||||
|
||||
|
@ -72,7 +72,7 @@ static const struct amdgpu_video_codecs vcn_4_0_0_video_codecs_encode_vcn1 = {
|
||||
static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_decode_array_vcn0[] = {
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 16384, 16384, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
|
||||
};
|
||||
@ -80,7 +80,7 @@ static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_decode_array_
|
||||
static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_decode_array_vcn1[] = {
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 16384, 16384, 0)},
|
||||
{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
|
||||
};
|
||||
|
||||
@ -985,4 +985,6 @@ static const struct amd_ip_funcs soc21_common_ip_funcs = {
|
||||
.set_clockgating_state = soc21_common_set_clockgating_state,
|
||||
.set_powergating_state = soc21_common_set_powergating_state,
|
||||
.get_clockgating_state = soc21_common_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
@ -486,6 +486,8 @@ static const struct amd_ip_funcs tonga_ih_ip_funcs = {
|
||||
.post_soft_reset = tonga_ih_post_soft_reset,
|
||||
.set_clockgating_state = tonga_ih_set_clockgating_state,
|
||||
.set_powergating_state = tonga_ih_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ih_funcs tonga_ih_funcs = {
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "umc/umc_12_0_0_sh_mask.h"
|
||||
#include "mp/mp_13_0_6_sh_mask.h"
|
||||
|
||||
#define MAX_ECC_NUM_PER_RETIREMENT 32
|
||||
|
||||
static inline uint64_t get_umc_v12_0_reg_offset(struct amdgpu_device *adev,
|
||||
uint32_t node_inst,
|
||||
uint32_t umc_inst,
|
||||
@ -222,6 +224,66 @@ static void umc_v12_0_convert_error_address(struct amdgpu_device *adev,
|
||||
}
|
||||
}
|
||||
|
||||
static int umc_v12_0_convert_err_addr(struct amdgpu_device *adev,
|
||||
struct ta_ras_query_address_input *addr_in,
|
||||
uint64_t *pfns, int len)
|
||||
{
|
||||
uint32_t col, row, row_xor, bank, channel_index;
|
||||
uint64_t soc_pa, retired_page, column, err_addr;
|
||||
struct ta_ras_query_address_output addr_out;
|
||||
uint32_t pos = 0;
|
||||
|
||||
err_addr = addr_in->ma.err_addr;
|
||||
addr_in->addr_type = TA_RAS_MCA_TO_PA;
|
||||
if (psp_ras_query_address(&adev->psp, addr_in, &addr_out)) {
|
||||
dev_warn(adev->dev, "Failed to query RAS physical address for 0x%llx",
|
||||
err_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
soc_pa = addr_out.pa.pa;
|
||||
bank = addr_out.pa.bank;
|
||||
channel_index = addr_out.pa.channel_idx;
|
||||
|
||||
col = (err_addr >> 1) & 0x1fULL;
|
||||
row = (err_addr >> 10) & 0x3fffULL;
|
||||
row_xor = row ^ (0x1ULL << 13);
|
||||
/* clear [C3 C2] in soc physical address */
|
||||
soc_pa &= ~(0x3ULL << UMC_V12_0_PA_C2_BIT);
|
||||
/* clear [C4] in soc physical address */
|
||||
soc_pa &= ~(0x1ULL << UMC_V12_0_PA_C4_BIT);
|
||||
|
||||
/* loop for all possibilities of [C4 C3 C2] */
|
||||
for (column = 0; column < UMC_V12_0_NA_MAP_PA_NUM; column++) {
|
||||
retired_page = soc_pa | ((column & 0x3) << UMC_V12_0_PA_C2_BIT);
|
||||
retired_page |= (((column & 0x4) >> 2) << UMC_V12_0_PA_C4_BIT);
|
||||
|
||||
if (pos >= len)
|
||||
return 0;
|
||||
pfns[pos++] = retired_page >> AMDGPU_GPU_PAGE_SHIFT;
|
||||
|
||||
/* include column bit 0 and 1 */
|
||||
col &= 0x3;
|
||||
col |= (column << 2);
|
||||
dev_info(adev->dev,
|
||||
"Error Address(PA):0x%-10llx Row:0x%-4x Col:0x%-2x Bank:0x%x Channel:0x%x\n",
|
||||
retired_page, row, col, bank, channel_index);
|
||||
|
||||
/* shift R13 bit */
|
||||
retired_page ^= (0x1ULL << UMC_V12_0_PA_R13_BIT);
|
||||
|
||||
if (pos >= len)
|
||||
return 0;
|
||||
pfns[pos++] = retired_page >> AMDGPU_GPU_PAGE_SHIFT;
|
||||
|
||||
dev_info(adev->dev,
|
||||
"Error Address(PA):0x%-10llx Row:0x%-4x Col:0x%-2x Bank:0x%x Channel:0x%x\n",
|
||||
retired_page, row_xor, col, bank, channel_index);
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
static int umc_v12_0_query_error_address(struct amdgpu_device *adev,
|
||||
uint32_t node_inst, uint32_t umc_inst,
|
||||
uint32_t ch_inst, void *data)
|
||||
@ -314,6 +376,7 @@ static int umc_v12_0_err_cnt_init_per_channel(struct amdgpu_device *adev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef TO_BE_REMOVED
|
||||
static void umc_v12_0_ecc_info_query_ras_error_count(struct amdgpu_device *adev,
|
||||
void *ras_error_status)
|
||||
{
|
||||
@ -382,6 +445,7 @@ static void umc_v12_0_ecc_info_query_ras_error_address(struct amdgpu_device *ade
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool umc_v12_0_check_ecc_err_status(struct amdgpu_device *adev,
|
||||
enum amdgpu_mca_error_type type, void *ras_error_status)
|
||||
@ -446,6 +510,11 @@ static int umc_v12_0_aca_bank_parser(struct aca_handle *handle, struct aca_bank
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
amdgpu_umc_update_ecc_status(adev,
|
||||
bank->regs[ACA_REG_IDX_STATUS],
|
||||
bank->regs[ACA_REG_IDX_IPID],
|
||||
bank->regs[ACA_REG_IDX_ADDR]);
|
||||
|
||||
ext_error_code = ACA_REG__STATUS__ERRORCODEEXT(status);
|
||||
count = ext_error_code == 0 ?
|
||||
ACA_REG__MISC0__ERRCNT(bank->regs[ACA_REG_IDX_MISC0]) : 1ULL;
|
||||
@ -479,6 +548,152 @@ static int umc_v12_0_ras_late_init(struct amdgpu_device *adev, struct ras_common
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int umc_v12_0_update_ecc_status(struct amdgpu_device *adev,
|
||||
uint64_t status, uint64_t ipid, uint64_t addr)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
uint16_t hwid, mcatype;
|
||||
struct ta_ras_query_address_input addr_in;
|
||||
uint64_t page_pfn[UMC_V12_0_BAD_PAGE_NUM_PER_CHANNEL];
|
||||
uint64_t err_addr, hash_val = 0;
|
||||
struct ras_ecc_err *ecc_err;
|
||||
int count;
|
||||
int ret;
|
||||
|
||||
hwid = REG_GET_FIELD(ipid, MCMP1_IPIDT0, HardwareID);
|
||||
mcatype = REG_GET_FIELD(ipid, MCMP1_IPIDT0, McaType);
|
||||
|
||||
if ((hwid != MCA_UMC_HWID_V12_0) || (mcatype != MCA_UMC_MCATYPE_V12_0))
|
||||
return 0;
|
||||
|
||||
if (!status)
|
||||
return 0;
|
||||
|
||||
if (!umc_v12_0_is_deferred_error(adev, status))
|
||||
return 0;
|
||||
|
||||
err_addr = REG_GET_FIELD(addr,
|
||||
MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
|
||||
|
||||
dev_info(adev->dev,
|
||||
"UMC:IPID:0x%llx, socket:%llu, aid:%llu, inst:%llu, ch:%llu, err_addr:0x%llx\n",
|
||||
ipid,
|
||||
MCA_IPID_2_SOCKET_ID(ipid),
|
||||
MCA_IPID_2_DIE_ID(ipid),
|
||||
MCA_IPID_2_UMC_INST(ipid),
|
||||
MCA_IPID_2_UMC_CH(ipid),
|
||||
err_addr);
|
||||
|
||||
memset(page_pfn, 0, sizeof(page_pfn));
|
||||
|
||||
memset(&addr_in, 0, sizeof(addr_in));
|
||||
addr_in.ma.err_addr = err_addr;
|
||||
addr_in.ma.ch_inst = MCA_IPID_2_UMC_CH(ipid);
|
||||
addr_in.ma.umc_inst = MCA_IPID_2_UMC_INST(ipid);
|
||||
addr_in.ma.node_inst = MCA_IPID_2_DIE_ID(ipid);
|
||||
addr_in.ma.socket_id = MCA_IPID_2_SOCKET_ID(ipid);
|
||||
|
||||
count = umc_v12_0_convert_err_addr(adev,
|
||||
&addr_in, page_pfn, ARRAY_SIZE(page_pfn));
|
||||
if (count <= 0) {
|
||||
dev_warn(adev->dev, "Fail to convert error address! count:%d\n", count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = amdgpu_umc_build_pages_hash(adev,
|
||||
page_pfn, count, &hash_val);
|
||||
if (ret) {
|
||||
dev_err(adev->dev, "Fail to build error pages hash\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ecc_err = kzalloc(sizeof(*ecc_err), GFP_KERNEL);
|
||||
if (!ecc_err)
|
||||
return -ENOMEM;
|
||||
|
||||
ecc_err->err_pages.pfn = kcalloc(count, sizeof(*ecc_err->err_pages.pfn), GFP_KERNEL);
|
||||
if (!ecc_err->err_pages.pfn) {
|
||||
kfree(ecc_err);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(ecc_err->err_pages.pfn, page_pfn, count * sizeof(*ecc_err->err_pages.pfn));
|
||||
ecc_err->err_pages.count = count;
|
||||
|
||||
ecc_err->hash_index = hash_val;
|
||||
ecc_err->status = status;
|
||||
ecc_err->ipid = ipid;
|
||||
ecc_err->addr = addr;
|
||||
|
||||
ret = amdgpu_umc_logs_ecc_err(adev, &con->umc_ecc_log.de_page_tree, ecc_err);
|
||||
if (ret) {
|
||||
if (ret == -EEXIST)
|
||||
con->umc_ecc_log.de_updated = true;
|
||||
else
|
||||
dev_err(adev->dev, "Fail to log ecc error! ret:%d\n", ret);
|
||||
|
||||
kfree(ecc_err->err_pages.pfn);
|
||||
kfree(ecc_err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
con->umc_ecc_log.de_updated = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int umc_v12_0_fill_error_record(struct amdgpu_device *adev,
|
||||
struct ras_ecc_err *ecc_err, void *ras_error_status)
|
||||
{
|
||||
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
|
||||
uint32_t i = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!err_data || !ecc_err)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < ecc_err->err_pages.count; i++) {
|
||||
ret = amdgpu_umc_fill_error_record(err_data,
|
||||
ecc_err->addr,
|
||||
ecc_err->err_pages.pfn[i] << AMDGPU_GPU_PAGE_SHIFT,
|
||||
MCA_IPID_2_UMC_CH(ecc_err->ipid),
|
||||
MCA_IPID_2_UMC_INST(ecc_err->ipid));
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
err_data->de_count++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void umc_v12_0_query_ras_ecc_err_addr(struct amdgpu_device *adev,
|
||||
void *ras_error_status)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
struct ras_ecc_err *entries[MAX_ECC_NUM_PER_RETIREMENT];
|
||||
struct radix_tree_root *ecc_tree;
|
||||
int new_detected, ret, i;
|
||||
|
||||
ecc_tree = &con->umc_ecc_log.de_page_tree;
|
||||
|
||||
mutex_lock(&con->umc_ecc_log.lock);
|
||||
new_detected = radix_tree_gang_lookup_tag(ecc_tree, (void **)entries,
|
||||
0, ARRAY_SIZE(entries), UMC_ECC_NEW_DETECTED_TAG);
|
||||
for (i = 0; i < new_detected; i++) {
|
||||
if (!entries[i])
|
||||
continue;
|
||||
|
||||
ret = umc_v12_0_fill_error_record(adev, entries[i], ras_error_status);
|
||||
if (ret) {
|
||||
dev_err(adev->dev, "Fail to fill umc error record, ret:%d\n", ret);
|
||||
break;
|
||||
}
|
||||
radix_tree_tag_clear(ecc_tree, entries[i]->hash_index, UMC_ECC_NEW_DETECTED_TAG);
|
||||
}
|
||||
mutex_unlock(&con->umc_ecc_log.lock);
|
||||
}
|
||||
|
||||
struct amdgpu_umc_ras umc_v12_0_ras = {
|
||||
.ras_block = {
|
||||
.hw_ops = &umc_v12_0_ras_hw_ops,
|
||||
@ -486,8 +701,8 @@ struct amdgpu_umc_ras umc_v12_0_ras = {
|
||||
},
|
||||
.err_cnt_init = umc_v12_0_err_cnt_init,
|
||||
.query_ras_poison_mode = umc_v12_0_query_ras_poison_mode,
|
||||
.ecc_info_query_ras_error_count = umc_v12_0_ecc_info_query_ras_error_count,
|
||||
.ecc_info_query_ras_error_address = umc_v12_0_ecc_info_query_ras_error_address,
|
||||
.ecc_info_query_ras_error_address = umc_v12_0_query_ras_ecc_err_addr,
|
||||
.check_ecc_err_status = umc_v12_0_check_ecc_err_status,
|
||||
.update_ecc_status = umc_v12_0_update_ecc_status,
|
||||
};
|
||||
|
||||
|
@ -62,10 +62,25 @@
|
||||
/* row bits in SOC physical address */
|
||||
#define UMC_V12_0_PA_R13_BIT 35
|
||||
|
||||
#define MCA_UMC_HWID_V12_0 0x96
|
||||
#define MCA_UMC_MCATYPE_V12_0 0x0
|
||||
|
||||
#define MCA_IPID_LO_2_UMC_CH(_ipid_lo) (((((_ipid_lo) >> 20) & 0x1) * 4) + \
|
||||
(((_ipid_lo) >> 12) & 0xF))
|
||||
#define MCA_IPID_LO_2_UMC_INST(_ipid_lo) (((_ipid_lo) >> 21) & 0x7)
|
||||
|
||||
#define MCA_IPID_2_DIE_ID(ipid) ((REG_GET_FIELD(ipid, MCMP1_IPIDT0, InstanceIdHi) >> 2) & 0x03)
|
||||
|
||||
#define MCA_IPID_2_UMC_CH(ipid) \
|
||||
(MCA_IPID_LO_2_UMC_CH(REG_GET_FIELD(ipid, MCMP1_IPIDT0, InstanceIdLo)))
|
||||
|
||||
#define MCA_IPID_2_UMC_INST(ipid) \
|
||||
(MCA_IPID_LO_2_UMC_INST(REG_GET_FIELD(ipid, MCMP1_IPIDT0, InstanceIdLo)))
|
||||
|
||||
#define MCA_IPID_2_SOCKET_ID(ipid) \
|
||||
(((REG_GET_FIELD(ipid, MCMP1_IPIDT0, InstanceIdLo) & 0x1) << 2) | \
|
||||
(REG_GET_FIELD(ipid, MCMP1_IPIDT0, InstanceIdHi) & 0x03))
|
||||
|
||||
bool umc_v12_0_is_deferred_error(struct amdgpu_device *adev, uint64_t mc_umc_status);
|
||||
bool umc_v12_0_is_uncorrectable_error(struct amdgpu_device *adev, uint64_t mc_umc_status);
|
||||
bool umc_v12_0_is_correctable_error(struct amdgpu_device *adev, uint64_t mc_umc_status);
|
||||
|
@ -819,6 +819,8 @@ static const struct amd_ip_funcs uvd_v3_1_ip_funcs = {
|
||||
.soft_reset = uvd_v3_1_soft_reset,
|
||||
.set_clockgating_state = uvd_v3_1_set_clockgating_state,
|
||||
.set_powergating_state = uvd_v3_1_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
const struct amdgpu_ip_block_version uvd_v3_1_ip_block = {
|
||||
|
@ -769,6 +769,8 @@ static const struct amd_ip_funcs uvd_v4_2_ip_funcs = {
|
||||
.soft_reset = uvd_v4_2_soft_reset,
|
||||
.set_clockgating_state = uvd_v4_2_set_clockgating_state,
|
||||
.set_powergating_state = uvd_v4_2_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs uvd_v4_2_ring_funcs = {
|
||||
|
@ -877,6 +877,8 @@ static const struct amd_ip_funcs uvd_v5_0_ip_funcs = {
|
||||
.set_clockgating_state = uvd_v5_0_set_clockgating_state,
|
||||
.set_powergating_state = uvd_v5_0_set_powergating_state,
|
||||
.get_clockgating_state = uvd_v5_0_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs uvd_v5_0_ring_funcs = {
|
||||
|
@ -1545,6 +1545,8 @@ static const struct amd_ip_funcs uvd_v6_0_ip_funcs = {
|
||||
.set_clockgating_state = uvd_v6_0_set_clockgating_state,
|
||||
.set_powergating_state = uvd_v6_0_set_powergating_state,
|
||||
.get_clockgating_state = uvd_v6_0_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs uvd_v6_0_ring_phys_funcs = {
|
||||
|
@ -626,6 +626,8 @@ static const struct amd_ip_funcs vce_v2_0_ip_funcs = {
|
||||
.soft_reset = vce_v2_0_soft_reset,
|
||||
.set_clockgating_state = vce_v2_0_set_clockgating_state,
|
||||
.set_powergating_state = vce_v2_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs vce_v2_0_ring_funcs = {
|
||||
|
@ -913,6 +913,8 @@ static const struct amd_ip_funcs vce_v3_0_ip_funcs = {
|
||||
.set_clockgating_state = vce_v3_0_set_clockgating_state,
|
||||
.set_powergating_state = vce_v3_0_set_powergating_state,
|
||||
.get_clockgating_state = vce_v3_0_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs vce_v3_0_ring_phys_funcs = {
|
||||
|
@ -1902,6 +1902,8 @@ static const struct amd_ip_funcs vcn_v1_0_ip_funcs = {
|
||||
.post_soft_reset = NULL /* vcn_v1_0_post_soft_reset */,
|
||||
.set_clockgating_state = vcn_v1_0_set_clockgating_state,
|
||||
.set_powergating_state = vcn_v1_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -2008,6 +2008,8 @@ static const struct amd_ip_funcs vcn_v2_0_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = vcn_v2_0_set_clockgating_state,
|
||||
.set_powergating_state = vcn_v2_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs vcn_v2_0_dec_ring_vm_funcs = {
|
||||
|
@ -1901,6 +1901,8 @@ static const struct amd_ip_funcs vcn_v2_5_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = vcn_v2_5_set_clockgating_state,
|
||||
.set_powergating_state = vcn_v2_5_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amd_ip_funcs vcn_v2_6_ip_funcs = {
|
||||
@ -1921,6 +1923,8 @@ static const struct amd_ip_funcs vcn_v2_6_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = vcn_v2_5_set_clockgating_state,
|
||||
.set_powergating_state = vcn_v2_5_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
const struct amdgpu_ip_block_version vcn_v2_5_ip_block =
|
||||
|
@ -359,6 +359,7 @@ static int vcn_v3_0_hw_init(void *handle)
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
done:
|
||||
if (!r)
|
||||
DRM_INFO("VCN decode and encode initialized successfully(under %s).\n",
|
||||
@ -2230,6 +2231,8 @@ static const struct amd_ip_funcs vcn_v3_0_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = vcn_v3_0_set_clockgating_state,
|
||||
.set_powergating_state = vcn_v3_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
const struct amdgpu_ip_block_version vcn_v3_0_ip_block = {
|
||||
|
@ -288,6 +288,7 @@ static int vcn_v4_0_hw_init(void *handle)
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
done:
|
||||
if (!r)
|
||||
DRM_INFO("VCN decode and encode initialized successfully(under %s).\n",
|
||||
@ -2130,6 +2131,8 @@ static const struct amd_ip_funcs vcn_v4_0_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = vcn_v4_0_set_clockgating_state,
|
||||
.set_powergating_state = vcn_v4_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
const struct amdgpu_ip_block_version vcn_v4_0_ip_block = {
|
||||
|
@ -1660,6 +1660,8 @@ static const struct amd_ip_funcs vcn_v4_0_3_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = vcn_v4_0_3_set_clockgating_state,
|
||||
.set_powergating_state = vcn_v4_0_3_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
const struct amdgpu_ip_block_version vcn_v4_0_3_ip_block = {
|
||||
|
@ -237,6 +237,7 @@ static int vcn_v4_0_5_hw_init(void *handle)
|
||||
goto done;
|
||||
}
|
||||
|
||||
return 0;
|
||||
done:
|
||||
if (!r)
|
||||
DRM_INFO("VCN decode and encode initialized successfully(under %s).\n",
|
||||
@ -1752,6 +1753,8 @@ static const struct amd_ip_funcs vcn_v4_0_5_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = vcn_v4_0_5_set_clockgating_state,
|
||||
.set_powergating_state = vcn_v4_0_5_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
const struct amdgpu_ip_block_version vcn_v4_0_5_ip_block = {
|
||||
|
@ -95,7 +95,7 @@ static int vcn_v5_0_0_sw_init(void *handle)
|
||||
return r;
|
||||
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
|
||||
volatile struct amdgpu_vcn4_fw_shared *fw_shared;
|
||||
volatile struct amdgpu_vcn5_fw_shared *fw_shared;
|
||||
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
@ -154,7 +154,7 @@ static int vcn_v5_0_0_sw_fini(void *handle)
|
||||
|
||||
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
|
||||
volatile struct amdgpu_vcn4_fw_shared *fw_shared;
|
||||
volatile struct amdgpu_vcn5_fw_shared *fw_shared;
|
||||
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
@ -203,6 +203,7 @@ static int vcn_v5_0_0_hw_init(void *handle)
|
||||
goto done;
|
||||
}
|
||||
|
||||
return 0;
|
||||
done:
|
||||
if (!r)
|
||||
DRM_INFO("VCN decode and encode initialized successfully(under %s).\n",
|
||||
@ -334,7 +335,7 @@ static void vcn_v5_0_0_mc_resume(struct amdgpu_device *adev, int inst)
|
||||
upper_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr));
|
||||
WREG32_SOC15(VCN, inst, regUVD_VCPU_NONCACHE_OFFSET0, 0);
|
||||
WREG32_SOC15(VCN, inst, regUVD_VCPU_NONCACHE_SIZE0,
|
||||
AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)));
|
||||
AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn5_fw_shared)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -438,7 +439,7 @@ static void vcn_v5_0_0_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_i
|
||||
VCN, inst_idx, regUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
|
||||
WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
|
||||
VCN, inst_idx, regUVD_VCPU_NONCACHE_SIZE0),
|
||||
AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)), 0, indirect);
|
||||
AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn5_fw_shared)), 0, indirect);
|
||||
|
||||
/* VCN global tiling registers */
|
||||
WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
|
||||
@ -615,7 +616,7 @@ static void vcn_v5_0_0_enable_clock_gating(struct amdgpu_device *adev, int inst)
|
||||
*/
|
||||
static int vcn_v5_0_0_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
|
||||
{
|
||||
volatile struct amdgpu_vcn4_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
|
||||
volatile struct amdgpu_vcn5_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
|
||||
struct amdgpu_ring *ring;
|
||||
uint32_t tmp;
|
||||
|
||||
@ -712,7 +713,7 @@ static int vcn_v5_0_0_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, b
|
||||
*/
|
||||
static int vcn_v5_0_0_start(struct amdgpu_device *adev)
|
||||
{
|
||||
volatile struct amdgpu_vcn4_fw_shared *fw_shared;
|
||||
volatile struct amdgpu_vcn5_fw_shared *fw_shared;
|
||||
struct amdgpu_ring *ring;
|
||||
uint32_t tmp;
|
||||
int i, j, k, r;
|
||||
@ -893,7 +894,7 @@ static void vcn_v5_0_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
|
||||
*/
|
||||
static int vcn_v5_0_0_stop(struct amdgpu_device *adev)
|
||||
{
|
||||
volatile struct amdgpu_vcn4_fw_shared *fw_shared;
|
||||
volatile struct amdgpu_vcn5_fw_shared *fw_shared;
|
||||
uint32_t tmp;
|
||||
int i, r = 0;
|
||||
|
||||
@ -1328,6 +1329,8 @@ static const struct amd_ip_funcs vcn_v5_0_0_ip_funcs = {
|
||||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = vcn_v5_0_0_set_clockgating_state,
|
||||
.set_powergating_state = vcn_v5_0_0_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
const struct amdgpu_ip_block_version vcn_v5_0_0_ip_block = {
|
||||
|
@ -2058,6 +2058,8 @@ static const struct amd_ip_funcs vi_common_ip_funcs = {
|
||||
.set_clockgating_state = vi_common_set_clockgating_state,
|
||||
.set_powergating_state = vi_common_set_powergating_state,
|
||||
.get_clockgating_state = vi_common_get_clockgating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ip_block_version vi_common_ip_block =
|
||||
|
@ -371,6 +371,11 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
|
||||
err = -EINVAL;
|
||||
goto err_wptr_map_gart;
|
||||
}
|
||||
if (dev->adev != amdgpu_ttm_adev(wptr_bo->tbo.bdev)) {
|
||||
pr_err("Queue memory allocated to wrong device\n");
|
||||
err = -EINVAL;
|
||||
goto err_wptr_map_gart;
|
||||
}
|
||||
|
||||
err = amdgpu_amdkfd_map_gtt_bo_to_gart(wptr_bo);
|
||||
if (err) {
|
||||
|
@ -435,12 +435,12 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
|
||||
|
||||
if (!f2g) {
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0))
|
||||
dev_err(kfd_device,
|
||||
dev_info(kfd_device,
|
||||
"GC IP %06x %s not supported in kfd\n",
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0),
|
||||
vf ? "VF" : "");
|
||||
else
|
||||
dev_err(kfd_device, "%s %s not supported in kfd\n",
|
||||
dev_info(kfd_device, "%s %s not supported in kfd\n",
|
||||
amdgpu_asic_name[adev->asic_type], vf ? "VF" : "");
|
||||
return NULL;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user