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:
Dave Airlie 2024-04-30 14:42:54 +10:00
commit 4a56c0ed5a
185 changed files with 1650 additions and 286 deletions

View File

@ -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

View File

@ -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);

View File

@ -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 = {

View File

@ -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,

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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++) {

View File

@ -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 */

View File

@ -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

View File

@ -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) {

View File

@ -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 {

View File

@ -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,

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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;
}

View File

@ -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

View File

@ -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 = {

View File

@ -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;

View File

@ -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 {

View File

@ -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

View File

@ -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 = {

View File

@ -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;

View File

@ -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;

View File

@ -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 =

View File

@ -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 = {

View File

@ -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;

View File

@ -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 = {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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,
};

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 =

View File

@ -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);

View File

@ -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 = {

View File

@ -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

View File

@ -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,
};

View File

@ -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)

View File

@ -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,
};

View File

@ -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 = {

View File

@ -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,
};

View File

@ -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);

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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,
};
/*

View File

@ -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 = {

View File

@ -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 =

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 =

View File

@ -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) {

View File

@ -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