mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-21 04:53:46 -04:00
Merge tag 'amd-drm-next-6.7-2023-11-10' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-6.7-2023-11-10: amdgpu: - SR-IOV fixes - DMCUB fixes - DCN3.5 fixes - DP2 fixes - SubVP fixes - SMU14 fixes - SDMA4.x fixes - Suspend/resume fixes - AGP regression fix - UAF fixes for some error cases - SMU 13.0.6 fixes - Documentation fixes - RAS fixes - Hotplug fixes - Scheduling entity ordering fix - GPUVM fixes Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231110190703.4741-1-alexander.deucher@amd.com
This commit is contained in:
@@ -1159,11 +1159,18 @@ uint32_t amdgpu_device_rreg(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t acc_flags);
|
||||
u32 amdgpu_device_indirect_rreg_ext(struct amdgpu_device *adev,
|
||||
u64 reg_addr);
|
||||
uint32_t amdgpu_device_xcc_rreg(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t acc_flags,
|
||||
uint32_t xcc_id);
|
||||
void amdgpu_device_wreg(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t v,
|
||||
uint32_t acc_flags);
|
||||
void amdgpu_device_indirect_wreg_ext(struct amdgpu_device *adev,
|
||||
u64 reg_addr, u32 reg_data);
|
||||
void amdgpu_device_xcc_wreg(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t v,
|
||||
uint32_t acc_flags,
|
||||
uint32_t xcc_id);
|
||||
void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t v, uint32_t xcc_id);
|
||||
void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value);
|
||||
@@ -1204,8 +1211,8 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
|
||||
#define RREG32_NO_KIQ(reg) amdgpu_device_rreg(adev, (reg), AMDGPU_REGS_NO_KIQ)
|
||||
#define WREG32_NO_KIQ(reg, v) amdgpu_device_wreg(adev, (reg), (v), AMDGPU_REGS_NO_KIQ)
|
||||
|
||||
#define RREG32_KIQ(reg) amdgpu_kiq_rreg(adev, (reg))
|
||||
#define WREG32_KIQ(reg, v) amdgpu_kiq_wreg(adev, (reg), (v))
|
||||
#define RREG32_KIQ(reg) amdgpu_kiq_rreg(adev, (reg), 0)
|
||||
#define WREG32_KIQ(reg, v) amdgpu_kiq_wreg(adev, (reg), (v), 0)
|
||||
|
||||
#define RREG8(reg) amdgpu_mm_rreg8(adev, (reg))
|
||||
#define WREG8(reg, v) amdgpu_mm_wreg8(adev, (reg), (v))
|
||||
@@ -1215,6 +1222,8 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
|
||||
#define WREG32(reg, v) amdgpu_device_wreg(adev, (reg), (v), 0)
|
||||
#define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
|
||||
#define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
|
||||
#define RREG32_XCC(reg, inst) amdgpu_device_xcc_rreg(adev, (reg), 0, inst)
|
||||
#define WREG32_XCC(reg, v, inst) amdgpu_device_xcc_wreg(adev, (reg), (v), 0, inst)
|
||||
#define RREG32_PCIE(reg) adev->pcie_rreg(adev, (reg))
|
||||
#define WREG32_PCIE(reg, v) adev->pcie_wreg(adev, (reg), (v))
|
||||
#define RREG32_PCIE_PORT(reg) adev->pciep_rreg(adev, (reg))
|
||||
|
||||
@@ -1497,6 +1497,9 @@ bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev)
|
||||
if (adev->asic_type < CHIP_RAVEN)
|
||||
return false;
|
||||
|
||||
if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If ACPI_FADT_LOW_POWER_S0 is not set in the FADT, it is generally
|
||||
* risky to do any special firmware-related preparations for entering
|
||||
|
||||
@@ -300,14 +300,13 @@ static int kgd_gfx_v9_4_3_hqd_load(struct amdgpu_device *adev, void *mqd,
|
||||
hqd_end = SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_HQD_AQL_DISPATCH_ID_HI);
|
||||
|
||||
for (reg = hqd_base; reg <= hqd_end; reg++)
|
||||
WREG32_RLC(reg, mqd_hqd[reg - hqd_base]);
|
||||
WREG32_XCC(reg, mqd_hqd[reg - hqd_base], inst);
|
||||
|
||||
|
||||
/* Activate doorbell logic before triggering WPTR poll. */
|
||||
data = REG_SET_FIELD(m->cp_hqd_pq_doorbell_control,
|
||||
CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1);
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_HQD_PQ_DOORBELL_CONTROL),
|
||||
data);
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_HQD_PQ_DOORBELL_CONTROL, data);
|
||||
|
||||
if (wptr) {
|
||||
/* Don't read wptr with get_user because the user
|
||||
@@ -336,27 +335,24 @@ static int kgd_gfx_v9_4_3_hqd_load(struct amdgpu_device *adev, void *mqd,
|
||||
guessed_wptr += m->cp_hqd_pq_wptr_lo & ~(queue_size - 1);
|
||||
guessed_wptr += (uint64_t)m->cp_hqd_pq_wptr_hi << 32;
|
||||
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_HQD_PQ_WPTR_LO),
|
||||
lower_32_bits(guessed_wptr));
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_HQD_PQ_WPTR_HI),
|
||||
upper_32_bits(guessed_wptr));
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_HQD_PQ_WPTR_POLL_ADDR),
|
||||
lower_32_bits((uintptr_t)wptr));
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst),
|
||||
regCP_HQD_PQ_WPTR_POLL_ADDR_HI),
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_HQD_PQ_WPTR_LO,
|
||||
lower_32_bits(guessed_wptr));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_HQD_PQ_WPTR_HI,
|
||||
upper_32_bits(guessed_wptr));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_HQD_PQ_WPTR_POLL_ADDR,
|
||||
lower_32_bits((uintptr_t)wptr));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_HQD_PQ_WPTR_POLL_ADDR_HI,
|
||||
upper_32_bits((uintptr_t)wptr));
|
||||
WREG32(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_PQ_WPTR_POLL_CNTL1),
|
||||
(uint32_t)kgd_gfx_v9_get_queue_mask(adev, pipe_id,
|
||||
queue_id));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_PQ_WPTR_POLL_CNTL1,
|
||||
(uint32_t)kgd_gfx_v9_get_queue_mask(adev, pipe_id, queue_id));
|
||||
}
|
||||
|
||||
/* Start the EOP fetcher */
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_HQD_EOP_RPTR),
|
||||
REG_SET_FIELD(m->cp_hqd_eop_rptr,
|
||||
CP_HQD_EOP_RPTR, INIT_FETCHER, 1));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_HQD_EOP_RPTR,
|
||||
REG_SET_FIELD(m->cp_hqd_eop_rptr, CP_HQD_EOP_RPTR, INIT_FETCHER, 1));
|
||||
|
||||
data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1);
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), regCP_HQD_ACTIVE), data);
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), regCP_HQD_ACTIVE, data);
|
||||
|
||||
kgd_gfx_v9_release_queue(adev, inst);
|
||||
|
||||
@@ -494,15 +490,15 @@ static uint32_t kgd_gfx_v9_4_3_set_address_watch(
|
||||
VALID,
|
||||
1);
|
||||
|
||||
WREG32_RLC((SOC15_REG_OFFSET(GC, GET_INST(GC, inst),
|
||||
WREG32_XCC((SOC15_REG_OFFSET(GC, GET_INST(GC, inst),
|
||||
regTCP_WATCH0_ADDR_H) +
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_high);
|
||||
watch_address_high, inst);
|
||||
|
||||
WREG32_RLC((SOC15_REG_OFFSET(GC, GET_INST(GC, inst),
|
||||
WREG32_XCC((SOC15_REG_OFFSET(GC, GET_INST(GC, inst),
|
||||
regTCP_WATCH0_ADDR_L) +
|
||||
(watch_id * TCP_WATCH_STRIDE)),
|
||||
watch_address_low);
|
||||
watch_address_low, inst);
|
||||
|
||||
return watch_address_cntl;
|
||||
}
|
||||
|
||||
@@ -91,8 +91,8 @@ void kgd_gfx_v9_program_sh_mem_settings(struct amdgpu_device *adev, uint32_t vmi
|
||||
{
|
||||
kgd_gfx_v9_lock_srbm(adev, 0, 0, 0, vmid, inst);
|
||||
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmSH_MEM_CONFIG), sh_mem_config);
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmSH_MEM_BASES), sh_mem_bases);
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmSH_MEM_CONFIG, sh_mem_config);
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmSH_MEM_BASES, sh_mem_bases);
|
||||
/* APE1 no longer exists on GFX9 */
|
||||
|
||||
kgd_gfx_v9_unlock_srbm(adev, inst);
|
||||
@@ -239,14 +239,13 @@ int kgd_gfx_v9_hqd_load(struct amdgpu_device *adev, void *mqd,
|
||||
|
||||
for (reg = hqd_base;
|
||||
reg <= SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_HI); reg++)
|
||||
WREG32_RLC(reg, mqd_hqd[reg - hqd_base]);
|
||||
WREG32_XCC(reg, mqd_hqd[reg - hqd_base], inst);
|
||||
|
||||
|
||||
/* Activate doorbell logic before triggering WPTR poll. */
|
||||
data = REG_SET_FIELD(m->cp_hqd_pq_doorbell_control,
|
||||
CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1);
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_PQ_DOORBELL_CONTROL),
|
||||
data);
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_PQ_DOORBELL_CONTROL, data);
|
||||
|
||||
if (wptr) {
|
||||
/* Don't read wptr with get_user because the user
|
||||
@@ -275,25 +274,24 @@ int kgd_gfx_v9_hqd_load(struct amdgpu_device *adev, void *mqd,
|
||||
guessed_wptr += m->cp_hqd_pq_wptr_lo & ~(queue_size - 1);
|
||||
guessed_wptr += (uint64_t)m->cp_hqd_pq_wptr_hi << 32;
|
||||
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_LO),
|
||||
lower_32_bits(guessed_wptr));
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_HI),
|
||||
upper_32_bits(guessed_wptr));
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_POLL_ADDR),
|
||||
lower_32_bits((uintptr_t)wptr));
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_POLL_ADDR_HI),
|
||||
upper_32_bits((uintptr_t)wptr));
|
||||
WREG32_SOC15(GC, GET_INST(GC, inst), mmCP_PQ_WPTR_POLL_CNTL1,
|
||||
(uint32_t)kgd_gfx_v9_get_queue_mask(adev, pipe_id, queue_id));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_LO,
|
||||
lower_32_bits(guessed_wptr));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_HI,
|
||||
upper_32_bits(guessed_wptr));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_POLL_ADDR,
|
||||
lower_32_bits((uintptr_t)wptr));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_PQ_WPTR_POLL_ADDR_HI,
|
||||
upper_32_bits((uintptr_t)wptr));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_PQ_WPTR_POLL_CNTL1,
|
||||
(uint32_t)kgd_gfx_v9_get_queue_mask(adev, pipe_id, queue_id));
|
||||
}
|
||||
|
||||
/* Start the EOP fetcher */
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_EOP_RPTR),
|
||||
REG_SET_FIELD(m->cp_hqd_eop_rptr,
|
||||
CP_HQD_EOP_RPTR, INIT_FETCHER, 1));
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_EOP_RPTR,
|
||||
REG_SET_FIELD(m->cp_hqd_eop_rptr, CP_HQD_EOP_RPTR, INIT_FETCHER, 1));
|
||||
|
||||
data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1);
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_ACTIVE), data);
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_ACTIVE, data);
|
||||
|
||||
kgd_gfx_v9_release_queue(adev, inst);
|
||||
|
||||
@@ -556,7 +554,7 @@ int kgd_gfx_v9_hqd_destroy(struct amdgpu_device *adev, void *mqd,
|
||||
break;
|
||||
}
|
||||
|
||||
WREG32_RLC(SOC15_REG_OFFSET(GC, GET_INST(GC, inst), mmCP_HQD_DEQUEUE_REQUEST), type);
|
||||
WREG32_SOC15_RLC(GC, GET_INST(GC, inst), mmCP_HQD_DEQUEUE_REQUEST, type);
|
||||
|
||||
end_jiffies = (utimeout * HZ / 1000) + jiffies;
|
||||
while (true) {
|
||||
@@ -908,8 +906,8 @@ void kgd_gfx_v9_get_iq_wait_times(struct amdgpu_device *adev,
|
||||
uint32_t inst)
|
||||
|
||||
{
|
||||
*wait_times = RREG32(SOC15_REG_OFFSET(GC, GET_INST(GC, inst),
|
||||
mmCP_IQ_WAIT_TIME2));
|
||||
*wait_times = RREG32_SOC15_RLC(GC, GET_INST(GC, inst),
|
||||
mmCP_IQ_WAIT_TIME2);
|
||||
}
|
||||
|
||||
void kgd_gfx_v9_set_vm_context_page_table_base(struct amdgpu_device *adev,
|
||||
|
||||
@@ -172,6 +172,7 @@ int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
*result = NULL;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
||||
@@ -1415,7 +1415,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
if (r == -ENOMEM)
|
||||
DRM_ERROR("Not enough memory for command submission!\n");
|
||||
else if (r != -ERESTARTSYS && r != -EAGAIN)
|
||||
DRM_ERROR("Failed to process the buffer list %d!\n", r);
|
||||
DRM_DEBUG("Failed to process the buffer list %d!\n", r);
|
||||
goto error_fini;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
#include "amdgpu_pmu.h"
|
||||
#include "amdgpu_fru_eeprom.h"
|
||||
#include "amdgpu_reset.h"
|
||||
#include "amdgpu_virt.h"
|
||||
|
||||
#include <linux/suspend.h>
|
||||
#include <drm/task_barrier.h>
|
||||
@@ -472,7 +473,7 @@ uint32_t amdgpu_device_rreg(struct amdgpu_device *adev,
|
||||
if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
|
||||
amdgpu_sriov_runtime(adev) &&
|
||||
down_read_trylock(&adev->reset_domain->sem)) {
|
||||
ret = amdgpu_kiq_rreg(adev, reg);
|
||||
ret = amdgpu_kiq_rreg(adev, reg, 0);
|
||||
up_read(&adev->reset_domain->sem);
|
||||
} else {
|
||||
ret = readl(((void __iomem *)adev->rmmio) + (reg * 4));
|
||||
@@ -509,6 +510,49 @@ uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset)
|
||||
BUG();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* amdgpu_device_xcc_rreg - read a memory mapped IO or indirect register with specific XCC
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @reg: dword aligned register offset
|
||||
* @acc_flags: access flags which require special behavior
|
||||
* @xcc_id: xcc accelerated compute core id
|
||||
*
|
||||
* Returns the 32 bit value from the offset specified.
|
||||
*/
|
||||
uint32_t amdgpu_device_xcc_rreg(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t acc_flags,
|
||||
uint32_t xcc_id)
|
||||
{
|
||||
uint32_t ret, rlcg_flag;
|
||||
|
||||
if (amdgpu_device_skip_hw_access(adev))
|
||||
return 0;
|
||||
|
||||
if ((reg * 4) < adev->rmmio_size) {
|
||||
if (amdgpu_sriov_vf(adev) &&
|
||||
!amdgpu_sriov_runtime(adev) &&
|
||||
adev->gfx.rlc.rlcg_reg_access_supported &&
|
||||
amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags,
|
||||
GC_HWIP, false,
|
||||
&rlcg_flag)) {
|
||||
ret = amdgpu_virt_rlcg_reg_rw(adev, reg, 0, rlcg_flag, xcc_id);
|
||||
} else if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
|
||||
amdgpu_sriov_runtime(adev) &&
|
||||
down_read_trylock(&adev->reset_domain->sem)) {
|
||||
ret = amdgpu_kiq_rreg(adev, reg, xcc_id);
|
||||
up_read(&adev->reset_domain->sem);
|
||||
} else {
|
||||
ret = readl(((void __iomem *)adev->rmmio) + (reg * 4));
|
||||
}
|
||||
} else {
|
||||
ret = adev->pcie_rreg(adev, reg * 4);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* MMIO register write with bytes helper functions
|
||||
* @offset:bytes offset from MMIO start
|
||||
@@ -556,7 +600,7 @@ void amdgpu_device_wreg(struct amdgpu_device *adev,
|
||||
if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
|
||||
amdgpu_sriov_runtime(adev) &&
|
||||
down_read_trylock(&adev->reset_domain->sem)) {
|
||||
amdgpu_kiq_wreg(adev, reg, v);
|
||||
amdgpu_kiq_wreg(adev, reg, v, 0);
|
||||
up_read(&adev->reset_domain->sem);
|
||||
} else {
|
||||
writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
|
||||
@@ -597,6 +641,47 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_xcc_wreg - write to a memory mapped IO or indirect register with specific XCC
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @reg: dword aligned register offset
|
||||
* @v: 32 bit value to write to the register
|
||||
* @acc_flags: access flags which require special behavior
|
||||
* @xcc_id: xcc accelerated compute core id
|
||||
*
|
||||
* Writes the value specified to the offset specified.
|
||||
*/
|
||||
void amdgpu_device_xcc_wreg(struct amdgpu_device *adev,
|
||||
uint32_t reg, uint32_t v,
|
||||
uint32_t acc_flags, uint32_t xcc_id)
|
||||
{
|
||||
uint32_t rlcg_flag;
|
||||
|
||||
if (amdgpu_device_skip_hw_access(adev))
|
||||
return;
|
||||
|
||||
if ((reg * 4) < adev->rmmio_size) {
|
||||
if (amdgpu_sriov_vf(adev) &&
|
||||
!amdgpu_sriov_runtime(adev) &&
|
||||
adev->gfx.rlc.rlcg_reg_access_supported &&
|
||||
amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags,
|
||||
GC_HWIP, true,
|
||||
&rlcg_flag)) {
|
||||
amdgpu_virt_rlcg_reg_rw(adev, reg, v, rlcg_flag, xcc_id);
|
||||
} else if (!(acc_flags & AMDGPU_REGS_NO_KIQ) &&
|
||||
amdgpu_sriov_runtime(adev) &&
|
||||
down_read_trylock(&adev->reset_domain->sem)) {
|
||||
amdgpu_kiq_wreg(adev, reg, v, xcc_id);
|
||||
up_read(&adev->reset_domain->sem);
|
||||
} else {
|
||||
writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
|
||||
}
|
||||
} else {
|
||||
adev->pcie_wreg(adev, reg * 4, v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_indirect_rreg - read an indirect register
|
||||
*
|
||||
@@ -2499,6 +2584,18 @@ static int amdgpu_device_init_schedulers(struct amdgpu_device *adev)
|
||||
ring->name);
|
||||
return r;
|
||||
}
|
||||
r = amdgpu_uvd_entity_init(adev, ring);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to create UVD scheduling entity on ring %s.\n",
|
||||
ring->name);
|
||||
return r;
|
||||
}
|
||||
r = amdgpu_vce_entity_init(adev, ring);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to create VCE scheduling entity on ring %s.\n",
|
||||
ring->name);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
amdgpu_xcp_update_partition_sched_list(adev);
|
||||
@@ -4486,19 +4583,18 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
||||
}
|
||||
amdgpu_fence_driver_hw_init(adev);
|
||||
|
||||
r = amdgpu_device_ip_late_init(adev);
|
||||
if (r)
|
||||
goto exit;
|
||||
|
||||
queue_delayed_work(system_wq, &adev->delayed_init_work,
|
||||
msecs_to_jiffies(AMDGPU_RESUME_MS));
|
||||
|
||||
if (!adev->in_s0ix) {
|
||||
r = amdgpu_amdkfd_resume(adev, adev->in_runpm);
|
||||
if (r)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
r = amdgpu_device_ip_late_init(adev);
|
||||
if (r)
|
||||
goto exit;
|
||||
|
||||
queue_delayed_work(system_wq, &adev->delayed_init_work,
|
||||
msecs_to_jiffies(AMDGPU_RESUME_MS));
|
||||
exit:
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
amdgpu_virt_init_data_exchange(adev);
|
||||
|
||||
@@ -931,12 +931,12 @@ void amdgpu_gfx_ras_error_func(struct amdgpu_device *adev,
|
||||
func(adev, ras_error_status, i);
|
||||
}
|
||||
|
||||
uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg)
|
||||
uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_id)
|
||||
{
|
||||
signed long r, cnt = 0;
|
||||
unsigned long flags;
|
||||
uint32_t seq, reg_val_offs = 0, value = 0;
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[0];
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
|
||||
struct amdgpu_ring *ring = &kiq->ring;
|
||||
|
||||
if (amdgpu_device_skip_hw_access(adev))
|
||||
@@ -999,12 +999,12 @@ failed_kiq_read:
|
||||
return ~0;
|
||||
}
|
||||
|
||||
void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
|
||||
void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint32_t xcc_id)
|
||||
{
|
||||
signed long r, cnt = 0;
|
||||
unsigned long flags;
|
||||
uint32_t seq;
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[0];
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
|
||||
struct amdgpu_ring *ring = &kiq->ring;
|
||||
|
||||
BUG_ON(!ring->funcs->emit_wreg);
|
||||
|
||||
@@ -521,8 +521,8 @@ int amdgpu_gfx_process_ras_data_cb(struct amdgpu_device *adev,
|
||||
int amdgpu_gfx_cp_ecc_error_irq(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry);
|
||||
uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg);
|
||||
void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
|
||||
uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t xcc_id);
|
||||
void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint32_t xcc_id);
|
||||
int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev);
|
||||
void amdgpu_gfx_cp_init_microcode(struct amdgpu_device *adev, uint32_t ucode_id);
|
||||
|
||||
|
||||
@@ -826,7 +826,10 @@ void amdgpu_gmc_noretry_set(struct amdgpu_device *adev)
|
||||
gc_ver == IP_VERSION(9, 4, 3) ||
|
||||
gc_ver >= IP_VERSION(10, 3, 0));
|
||||
|
||||
gmc->noretry = (amdgpu_noretry == -1) ? noretry_default : amdgpu_noretry;
|
||||
if (!amdgpu_sriov_xnack_support(adev))
|
||||
gmc->noretry = 1;
|
||||
else
|
||||
gmc->noretry = (amdgpu_noretry == -1) ? noretry_default : amdgpu_noretry;
|
||||
}
|
||||
|
||||
void amdgpu_gmc_set_vm_fault_masks(struct amdgpu_device *adev, int hub_type,
|
||||
|
||||
@@ -143,6 +143,46 @@ int amdgpu_mca_mpio_ras_sw_init(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void amdgpu_mca_bank_set_init(struct mca_bank_set *mca_set)
|
||||
{
|
||||
if (!mca_set)
|
||||
return;
|
||||
|
||||
memset(mca_set, 0, sizeof(*mca_set));
|
||||
INIT_LIST_HEAD(&mca_set->list);
|
||||
}
|
||||
|
||||
int amdgpu_mca_bank_set_add_entry(struct mca_bank_set *mca_set, struct mca_bank_entry *entry)
|
||||
{
|
||||
struct mca_bank_node *node;
|
||||
|
||||
if (!entry)
|
||||
return -EINVAL;
|
||||
|
||||
node = kvzalloc(sizeof(*node), GFP_KERNEL);
|
||||
if (!node)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(&node->entry, entry, sizeof(*entry));
|
||||
|
||||
INIT_LIST_HEAD(&node->node);
|
||||
list_add_tail(&node->node, &mca_set->list);
|
||||
|
||||
mca_set->nr_entries++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void amdgpu_mca_bank_set_release(struct mca_bank_set *mca_set)
|
||||
{
|
||||
struct mca_bank_node *node, *tmp;
|
||||
|
||||
list_for_each_entry_safe(node, tmp, &mca_set->list, node) {
|
||||
list_del(&node->node);
|
||||
kvfree(node);
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_mca_smu_init_funcs(struct amdgpu_device *adev, const struct amdgpu_mca_smu_funcs *mca_funcs)
|
||||
{
|
||||
struct amdgpu_mca *mca = &adev->mca;
|
||||
@@ -160,6 +200,65 @@ int amdgpu_mca_smu_set_debug_mode(struct amdgpu_device *adev, bool enable)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static void amdgpu_mca_smu_mca_bank_dump(struct amdgpu_device *adev, int idx, struct mca_bank_entry *entry)
|
||||
{
|
||||
dev_info(adev->dev, "[Hardware error] Accelerator Check Architecture events logged\n");
|
||||
dev_info(adev->dev, "[Hardware error] aca entry[%02d].STATUS=0x%016llx\n",
|
||||
idx, entry->regs[MCA_REG_IDX_STATUS]);
|
||||
dev_info(adev->dev, "[Hardware error] aca entry[%02d].ADDR=0x%016llx\n",
|
||||
idx, entry->regs[MCA_REG_IDX_ADDR]);
|
||||
dev_info(adev->dev, "[Hardware error] aca entry[%02d].MISC0=0x%016llx\n",
|
||||
idx, entry->regs[MCA_REG_IDX_MISC0]);
|
||||
dev_info(adev->dev, "[Hardware error] aca entry[%02d].IPID=0x%016llx\n",
|
||||
idx, entry->regs[MCA_REG_IDX_IPID]);
|
||||
dev_info(adev->dev, "[Hardware error] aca entry[%02d].SYND=0x%016llx\n",
|
||||
idx, entry->regs[MCA_REG_IDX_SYND]);
|
||||
}
|
||||
|
||||
int amdgpu_mca_smu_log_ras_error(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type, struct ras_err_data *err_data)
|
||||
{
|
||||
struct amdgpu_smuio_mcm_config_info mcm_info;
|
||||
struct mca_bank_set mca_set;
|
||||
struct mca_bank_node *node;
|
||||
struct mca_bank_entry *entry;
|
||||
uint32_t count;
|
||||
int ret, i = 0;
|
||||
|
||||
amdgpu_mca_bank_set_init(&mca_set);
|
||||
|
||||
ret = amdgpu_mca_smu_get_mca_set(adev, blk, type, &mca_set);
|
||||
if (ret)
|
||||
goto out_mca_release;
|
||||
|
||||
list_for_each_entry(node, &mca_set.list, node) {
|
||||
entry = &node->entry;
|
||||
|
||||
amdgpu_mca_smu_mca_bank_dump(adev, i++, entry);
|
||||
|
||||
count = 0;
|
||||
ret = amdgpu_mca_smu_parse_mca_error_count(adev, blk, type, entry, &count);
|
||||
if (ret)
|
||||
goto out_mca_release;
|
||||
|
||||
if (!count)
|
||||
continue;
|
||||
|
||||
mcm_info.socket_id = entry->info.socket_id;
|
||||
mcm_info.die_id = entry->info.aid;
|
||||
|
||||
if (type == AMDGPU_MCA_ERROR_TYPE_UE)
|
||||
amdgpu_ras_error_statistic_ue_count(err_data, &mcm_info, (uint64_t)count);
|
||||
else
|
||||
amdgpu_ras_error_statistic_ce_count(err_data, &mcm_info, (uint64_t)count);
|
||||
}
|
||||
|
||||
out_mca_release:
|
||||
amdgpu_mca_bank_set_release(&mca_set);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int amdgpu_mca_smu_get_valid_mca_count(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, uint32_t *count)
|
||||
{
|
||||
const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
|
||||
@@ -173,17 +272,77 @@ int amdgpu_mca_smu_get_valid_mca_count(struct amdgpu_device *adev, enum amdgpu_m
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int amdgpu_mca_smu_get_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, uint32_t *count)
|
||||
int amdgpu_mca_smu_get_mca_set_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, uint32_t *total)
|
||||
{
|
||||
const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
|
||||
if (!count)
|
||||
struct mca_bank_set mca_set;
|
||||
struct mca_bank_node *node;
|
||||
struct mca_bank_entry *entry;
|
||||
uint32_t count;
|
||||
int ret;
|
||||
|
||||
if (!total)
|
||||
return -EINVAL;
|
||||
|
||||
if (mca_funcs && mca_funcs->mca_get_error_count)
|
||||
return mca_funcs->mca_get_error_count(adev, blk, type, count);
|
||||
if (!mca_funcs)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
if (!mca_funcs->mca_get_ras_mca_set || !mca_funcs->mca_get_valid_mca_count)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
amdgpu_mca_bank_set_init(&mca_set);
|
||||
|
||||
ret = mca_funcs->mca_get_ras_mca_set(adev, blk, type, &mca_set);
|
||||
if (ret)
|
||||
goto err_mca_set_release;
|
||||
|
||||
*total = 0;
|
||||
list_for_each_entry(node, &mca_set.list, node) {
|
||||
entry = &node->entry;
|
||||
|
||||
count = 0;
|
||||
ret = mca_funcs->mca_parse_mca_error_count(adev, blk, type, entry, &count);
|
||||
if (ret)
|
||||
goto err_mca_set_release;
|
||||
|
||||
*total += count;
|
||||
}
|
||||
|
||||
err_mca_set_release:
|
||||
amdgpu_mca_bank_set_release(&mca_set);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_mca_smu_parse_mca_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, struct mca_bank_entry *entry, uint32_t *count)
|
||||
{
|
||||
const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
|
||||
if (!count || !entry)
|
||||
return -EINVAL;
|
||||
|
||||
if (!mca_funcs || !mca_funcs->mca_parse_mca_error_count)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
|
||||
return mca_funcs->mca_parse_mca_error_count(adev, blk, type, entry, count);
|
||||
}
|
||||
|
||||
int amdgpu_mca_smu_get_mca_set(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, struct mca_bank_set *mca_set)
|
||||
{
|
||||
const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
|
||||
|
||||
if (!mca_set)
|
||||
return -EINVAL;
|
||||
|
||||
if (!mca_funcs || !mca_funcs->mca_get_ras_mca_set)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
WARN_ON(!list_empty(&mca_set->list));
|
||||
|
||||
return mca_funcs->mca_get_ras_mca_set(adev, blk, type, mca_set);
|
||||
}
|
||||
|
||||
int amdgpu_mca_smu_get_mca_entry(struct amdgpu_device *adev, enum amdgpu_mca_error_type type,
|
||||
@@ -230,14 +389,21 @@ static int amdgpu_mca_smu_debug_mode_set(void *data, u64 val)
|
||||
static void mca_dump_entry(struct seq_file *m, struct mca_bank_entry *entry)
|
||||
{
|
||||
int i, idx = entry->idx;
|
||||
int reg_idx_array[] = {
|
||||
MCA_REG_IDX_STATUS,
|
||||
MCA_REG_IDX_ADDR,
|
||||
MCA_REG_IDX_MISC0,
|
||||
MCA_REG_IDX_IPID,
|
||||
MCA_REG_IDX_SYND,
|
||||
};
|
||||
|
||||
seq_printf(m, "mca entry[%d].type: %s\n", idx, entry->type == AMDGPU_MCA_ERROR_TYPE_UE ? "UE" : "CE");
|
||||
seq_printf(m, "mca entry[%d].ip: %d\n", idx, entry->ip);
|
||||
seq_printf(m, "mca entry[%d].info: socketid:%d aid:%d hwid:0x%03x mcatype:0x%04x\n",
|
||||
idx, entry->info.socket_id, entry->info.aid, entry->info.hwid, entry->info.mcatype);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(entry->regs); i++)
|
||||
seq_printf(m, "mca entry[%d].regs[%d]: 0x%016llx\n", idx, i, entry->regs[i]);
|
||||
for (i = 0; i < ARRAY_SIZE(reg_idx_array); i++)
|
||||
seq_printf(m, "mca entry[%d].regs[%d]: 0x%016llx\n", idx, reg_idx_array[i], entry->regs[reg_idx_array[i]]);
|
||||
}
|
||||
|
||||
static int mca_dump_show(struct seq_file *m, enum amdgpu_mca_error_type type)
|
||||
|
||||
@@ -25,6 +25,27 @@
|
||||
|
||||
#define MCA_MAX_REGS_COUNT (16)
|
||||
|
||||
#define MCA_REG_FIELD(x, h, l) (((x) & GENMASK_ULL(h, l)) >> l)
|
||||
#define MCA_REG__STATUS__VAL(x) MCA_REG_FIELD(x, 63, 63)
|
||||
#define MCA_REG__STATUS__OVERFLOW(x) MCA_REG_FIELD(x, 62, 62)
|
||||
#define MCA_REG__STATUS__UC(x) MCA_REG_FIELD(x, 61, 61)
|
||||
#define MCA_REG__STATUS__EN(x) MCA_REG_FIELD(x, 60, 60)
|
||||
#define MCA_REG__STATUS__MISCV(x) MCA_REG_FIELD(x, 59, 59)
|
||||
#define MCA_REG__STATUS__ADDRV(x) MCA_REG_FIELD(x, 58, 58)
|
||||
#define MCA_REG__STATUS__PCC(x) MCA_REG_FIELD(x, 57, 57)
|
||||
#define MCA_REG__STATUS__ERRCOREIDVAL(x) MCA_REG_FIELD(x, 56, 56)
|
||||
#define MCA_REG__STATUS__TCC(x) MCA_REG_FIELD(x, 55, 55)
|
||||
#define MCA_REG__STATUS__SYNDV(x) MCA_REG_FIELD(x, 53, 53)
|
||||
#define MCA_REG__STATUS__CECC(x) MCA_REG_FIELD(x, 46, 46)
|
||||
#define MCA_REG__STATUS__UECC(x) MCA_REG_FIELD(x, 45, 45)
|
||||
#define MCA_REG__STATUS__DEFERRED(x) MCA_REG_FIELD(x, 44, 44)
|
||||
#define MCA_REG__STATUS__POISON(x) MCA_REG_FIELD(x, 43, 43)
|
||||
#define MCA_REG__STATUS__SCRUB(x) MCA_REG_FIELD(x, 40, 40)
|
||||
#define MCA_REG__STATUS__ERRCOREID(x) MCA_REG_FIELD(x, 37, 32)
|
||||
#define MCA_REG__STATUS__ADDRLSB(x) MCA_REG_FIELD(x, 29, 24)
|
||||
#define MCA_REG__STATUS__ERRORCODEEXT(x) MCA_REG_FIELD(x, 21, 16)
|
||||
#define MCA_REG__STATUS__ERRORCODE(x) MCA_REG_FIELD(x, 15, 0)
|
||||
|
||||
enum amdgpu_mca_ip {
|
||||
AMDGPU_MCA_IP_UNKNOW = -1,
|
||||
AMDGPU_MCA_IP_PSP = 0,
|
||||
@@ -33,6 +54,7 @@ enum amdgpu_mca_ip {
|
||||
AMDGPU_MCA_IP_SMU,
|
||||
AMDGPU_MCA_IP_MP5,
|
||||
AMDGPU_MCA_IP_UMC,
|
||||
AMDGPU_MCA_IP_PCS_XGMI,
|
||||
AMDGPU_MCA_IP_COUNT,
|
||||
};
|
||||
|
||||
@@ -57,6 +79,15 @@ struct amdgpu_mca {
|
||||
const struct amdgpu_mca_smu_funcs *mca_funcs;
|
||||
};
|
||||
|
||||
enum mca_reg_idx {
|
||||
MCA_REG_IDX_STATUS = 1,
|
||||
MCA_REG_IDX_ADDR = 2,
|
||||
MCA_REG_IDX_MISC0 = 3,
|
||||
MCA_REG_IDX_IPID = 5,
|
||||
MCA_REG_IDX_SYND = 6,
|
||||
MCA_REG_IDX_COUNT = 16,
|
||||
};
|
||||
|
||||
struct mca_bank_info {
|
||||
int socket_id;
|
||||
int aid;
|
||||
@@ -72,18 +103,28 @@ struct mca_bank_entry {
|
||||
uint64_t regs[MCA_MAX_REGS_COUNT];
|
||||
};
|
||||
|
||||
struct mca_bank_node {
|
||||
struct mca_bank_entry entry;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
struct mca_bank_set {
|
||||
int nr_entries;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct amdgpu_mca_smu_funcs {
|
||||
int max_ue_count;
|
||||
int max_ce_count;
|
||||
int (*mca_set_debug_mode)(struct amdgpu_device *adev, bool enable);
|
||||
int (*mca_get_error_count)(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, uint32_t *count);
|
||||
int (*mca_get_ras_mca_set)(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type,
|
||||
struct mca_bank_set *mca_set);
|
||||
int (*mca_parse_mca_error_count)(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type,
|
||||
struct mca_bank_entry *entry, uint32_t *count);
|
||||
int (*mca_get_valid_mca_count)(struct amdgpu_device *adev, enum amdgpu_mca_error_type type,
|
||||
uint32_t *count);
|
||||
int (*mca_get_mca_entry)(struct amdgpu_device *adev, enum amdgpu_mca_error_type type,
|
||||
int idx, struct mca_bank_entry *entry);
|
||||
int (*mca_get_ras_mca_idx_array)(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, int *idx_array, int *idx_array_size);
|
||||
};
|
||||
|
||||
void amdgpu_mca_query_correctable_error_count(struct amdgpu_device *adev,
|
||||
@@ -107,11 +148,22 @@ int amdgpu_mca_mpio_ras_sw_init(struct amdgpu_device *adev);
|
||||
void amdgpu_mca_smu_init_funcs(struct amdgpu_device *adev, const struct amdgpu_mca_smu_funcs *mca_funcs);
|
||||
int amdgpu_mca_smu_set_debug_mode(struct amdgpu_device *adev, bool enable);
|
||||
int amdgpu_mca_smu_get_valid_mca_count(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, uint32_t *count);
|
||||
int amdgpu_mca_smu_get_mca_set_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, uint32_t *total);
|
||||
int amdgpu_mca_smu_get_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, uint32_t *count);
|
||||
int amdgpu_mca_smu_parse_mca_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, struct mca_bank_entry *entry, uint32_t *count);
|
||||
int amdgpu_mca_smu_get_mca_set(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
|
||||
enum amdgpu_mca_error_type type, struct mca_bank_set *mca_set);
|
||||
int amdgpu_mca_smu_get_mca_entry(struct amdgpu_device *adev, enum amdgpu_mca_error_type type,
|
||||
int idx, struct mca_bank_entry *entry);
|
||||
|
||||
void amdgpu_mca_smu_debugfs_init(struct amdgpu_device *adev, struct dentry *root);
|
||||
|
||||
void amdgpu_mca_bank_set_init(struct mca_bank_set *mca_set);
|
||||
int amdgpu_mca_bank_set_add_entry(struct mca_bank_set *mca_set, struct mca_bank_entry *entry);
|
||||
void amdgpu_mca_bank_set_release(struct mca_bank_set *mca_set);
|
||||
int amdgpu_mca_smu_log_ras_error(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type, struct ras_err_data *err_data);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1062,9 +1062,6 @@ static const char * const amdgpu_vram_names[] = {
|
||||
*/
|
||||
int amdgpu_bo_init(struct amdgpu_device *adev)
|
||||
{
|
||||
/* set the default AGP aperture state */
|
||||
amdgpu_gmc_set_agp_default(adev, &adev->gmc);
|
||||
|
||||
/* On A+A platform, VRAM can be mapped as WB */
|
||||
if (!adev->gmc.xgmi.connected_to_cpu && !adev->gmc.is_app_apu) {
|
||||
/* reserve PAT memory space to WC for VRAM */
|
||||
|
||||
@@ -1165,13 +1165,53 @@ static void amdgpu_rasmgr_error_data_statistic_update(struct ras_manager *obj, s
|
||||
}
|
||||
}
|
||||
|
||||
/* query/inject/cure begin */
|
||||
int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
|
||||
struct ras_query_if *info)
|
||||
static int amdgpu_ras_query_error_status_helper(struct amdgpu_device *adev,
|
||||
struct ras_query_if *info,
|
||||
struct ras_err_data *err_data,
|
||||
unsigned int error_query_mode)
|
||||
{
|
||||
enum amdgpu_ras_block blk = info ? info->head.block : AMDGPU_RAS_BLOCK_COUNT;
|
||||
struct amdgpu_ras_block_object *block_obj = NULL;
|
||||
|
||||
if (error_query_mode == AMDGPU_RAS_INVALID_ERROR_QUERY)
|
||||
return -EINVAL;
|
||||
|
||||
if (error_query_mode == AMDGPU_RAS_DIRECT_ERROR_QUERY) {
|
||||
if (info->head.block == AMDGPU_RAS_BLOCK__UMC) {
|
||||
amdgpu_ras_get_ecc_info(adev, err_data);
|
||||
} else {
|
||||
block_obj = amdgpu_ras_get_ras_block(adev, info->head.block, 0);
|
||||
if (!block_obj || !block_obj->hw_ops) {
|
||||
dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
|
||||
get_ras_block_str(&info->head));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (block_obj->hw_ops->query_ras_error_count)
|
||||
block_obj->hw_ops->query_ras_error_count(adev, &err_data);
|
||||
|
||||
if ((info->head.block == AMDGPU_RAS_BLOCK__SDMA) ||
|
||||
(info->head.block == AMDGPU_RAS_BLOCK__GFX) ||
|
||||
(info->head.block == AMDGPU_RAS_BLOCK__MMHUB)) {
|
||||
if (block_obj->hw_ops->query_ras_error_status)
|
||||
block_obj->hw_ops->query_ras_error_status(adev);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* FIXME: add code to check return value later */
|
||||
amdgpu_mca_smu_log_ras_error(adev, blk, AMDGPU_MCA_ERROR_TYPE_UE, err_data);
|
||||
amdgpu_mca_smu_log_ras_error(adev, blk, AMDGPU_MCA_ERROR_TYPE_CE, err_data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* query/inject/cure begin */
|
||||
int amdgpu_ras_query_error_status(struct amdgpu_device *adev, struct ras_query_if *info)
|
||||
{
|
||||
struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head);
|
||||
struct ras_err_data err_data;
|
||||
unsigned int error_query_mode;
|
||||
int ret;
|
||||
|
||||
if (!obj)
|
||||
@@ -1181,27 +1221,14 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (info->head.block == AMDGPU_RAS_BLOCK__UMC) {
|
||||
amdgpu_ras_get_ecc_info(adev, &err_data);
|
||||
} else {
|
||||
block_obj = amdgpu_ras_get_ras_block(adev, info->head.block, 0);
|
||||
if (!block_obj || !block_obj->hw_ops) {
|
||||
dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
|
||||
get_ras_block_str(&info->head));
|
||||
ret = -EINVAL;
|
||||
goto out_fini_err_data;
|
||||
}
|
||||
if (!amdgpu_ras_get_error_query_mode(adev, &error_query_mode))
|
||||
return -EINVAL;
|
||||
|
||||
if (block_obj->hw_ops->query_ras_error_count)
|
||||
block_obj->hw_ops->query_ras_error_count(adev, &err_data);
|
||||
|
||||
if ((info->head.block == AMDGPU_RAS_BLOCK__SDMA) ||
|
||||
(info->head.block == AMDGPU_RAS_BLOCK__GFX) ||
|
||||
(info->head.block == AMDGPU_RAS_BLOCK__MMHUB)) {
|
||||
if (block_obj->hw_ops->query_ras_error_status)
|
||||
block_obj->hw_ops->query_ras_error_status(adev);
|
||||
}
|
||||
}
|
||||
ret = amdgpu_ras_query_error_status_helper(adev, info,
|
||||
&err_data,
|
||||
error_query_mode);
|
||||
if (ret)
|
||||
goto out_fini_err_data;
|
||||
|
||||
amdgpu_rasmgr_error_data_statistic_update(obj, &err_data);
|
||||
|
||||
@@ -1537,7 +1564,8 @@ static void amdgpu_ras_sysfs_remove_bad_page_node(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
|
||||
sysfs_remove_file_from_group(&adev->dev->kobj,
|
||||
if (adev->dev->kobj.sd)
|
||||
sysfs_remove_file_from_group(&adev->dev->kobj,
|
||||
&con->badpages_attr.attr,
|
||||
RAS_FS_NAME);
|
||||
}
|
||||
@@ -1556,7 +1584,8 @@ static int amdgpu_ras_sysfs_remove_dev_attr_node(struct amdgpu_device *adev)
|
||||
.attrs = attrs,
|
||||
};
|
||||
|
||||
sysfs_remove_group(&adev->dev->kobj, &group);
|
||||
if (adev->dev->kobj.sd)
|
||||
sysfs_remove_group(&adev->dev->kobj, &group);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1603,7 +1632,8 @@ int amdgpu_ras_sysfs_remove(struct amdgpu_device *adev,
|
||||
if (!obj || !obj->attr_inuse)
|
||||
return -EINVAL;
|
||||
|
||||
sysfs_remove_file_from_group(&adev->dev->kobj,
|
||||
if (adev->dev->kobj.sd)
|
||||
sysfs_remove_file_from_group(&adev->dev->kobj,
|
||||
&obj->sysfs_attr.attr,
|
||||
RAS_FS_NAME);
|
||||
obj->attr_inuse = 0;
|
||||
@@ -3397,6 +3427,26 @@ bool amdgpu_ras_get_mca_debug_mode(struct amdgpu_device *adev)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool amdgpu_ras_get_error_query_mode(struct amdgpu_device *adev,
|
||||
unsigned int *error_query_mode)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
|
||||
|
||||
if (!con) {
|
||||
*error_query_mode = AMDGPU_RAS_INVALID_ERROR_QUERY;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mca_funcs && mca_funcs->mca_set_debug_mode)
|
||||
*error_query_mode =
|
||||
(con->is_mca_debug_mode) ? AMDGPU_RAS_DIRECT_ERROR_QUERY : AMDGPU_RAS_FIRMWARE_ERROR_QUERY;
|
||||
else
|
||||
*error_query_mode = AMDGPU_RAS_DIRECT_ERROR_QUERY;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Register each ip ras block into amdgpu ras */
|
||||
int amdgpu_ras_register_ras_block(struct amdgpu_device *adev,
|
||||
struct amdgpu_ras_block_object *ras_block_obj)
|
||||
|
||||
@@ -320,6 +320,12 @@ enum amdgpu_ras_ret {
|
||||
AMDGPU_RAS_PT,
|
||||
};
|
||||
|
||||
enum amdgpu_ras_error_query_mode {
|
||||
AMDGPU_RAS_INVALID_ERROR_QUERY = 0,
|
||||
AMDGPU_RAS_DIRECT_ERROR_QUERY = 1,
|
||||
AMDGPU_RAS_FIRMWARE_ERROR_QUERY = 2,
|
||||
};
|
||||
|
||||
/* ras error status reisger fields */
|
||||
#define ERR_STATUS_LO__ERR_STATUS_VALID_FLAG__SHIFT 0x0
|
||||
#define ERR_STATUS_LO__ERR_STATUS_VALID_FLAG_MASK 0x00000001L
|
||||
@@ -769,6 +775,8 @@ int amdgpu_ras_set_context(struct amdgpu_device *adev, struct amdgpu_ras *ras_co
|
||||
|
||||
void amdgpu_ras_set_mca_debug_mode(struct amdgpu_device *adev, bool enable);
|
||||
bool amdgpu_ras_get_mca_debug_mode(struct amdgpu_device *adev);
|
||||
bool amdgpu_ras_get_error_query_mode(struct amdgpu_device *adev,
|
||||
unsigned int *mode);
|
||||
|
||||
int amdgpu_ras_register_ras_block(struct amdgpu_device *adev,
|
||||
struct amdgpu_ras_block_object *ras_block_obj);
|
||||
|
||||
@@ -399,20 +399,20 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Initialize the entity used for handle management in the kernel driver.
|
||||
*/
|
||||
int amdgpu_uvd_entity_init(struct amdgpu_device *adev)
|
||||
int amdgpu_uvd_entity_init(struct amdgpu_device *adev, struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_ring *ring;
|
||||
struct drm_gpu_scheduler *sched;
|
||||
int r;
|
||||
if (ring == &adev->uvd.inst[0].ring) {
|
||||
struct drm_gpu_scheduler *sched = &ring->sched;
|
||||
int r;
|
||||
|
||||
ring = &adev->uvd.inst[0].ring;
|
||||
sched = &ring->sched;
|
||||
r = drm_sched_entity_init(&adev->uvd.entity, DRM_SCHED_PRIORITY_NORMAL,
|
||||
&sched, 1, NULL);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed setting up UVD kernel entity.\n");
|
||||
return r;
|
||||
r = drm_sched_entity_init(&adev->uvd.entity, DRM_SCHED_PRIORITY_NORMAL,
|
||||
&sched, 1, NULL);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed setting up UVD kernel entity.\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -73,7 +73,7 @@ struct amdgpu_uvd {
|
||||
|
||||
int amdgpu_uvd_sw_init(struct amdgpu_device *adev);
|
||||
int amdgpu_uvd_sw_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_uvd_entity_init(struct amdgpu_device *adev);
|
||||
int amdgpu_uvd_entity_init(struct amdgpu_device *adev, struct amdgpu_ring *ring);
|
||||
int amdgpu_uvd_prepare_suspend(struct amdgpu_device *adev);
|
||||
int amdgpu_uvd_suspend(struct amdgpu_device *adev);
|
||||
int amdgpu_uvd_resume(struct amdgpu_device *adev);
|
||||
|
||||
@@ -231,20 +231,20 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev)
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Initialize the entity used for handle management in the kernel driver.
|
||||
*/
|
||||
int amdgpu_vce_entity_init(struct amdgpu_device *adev)
|
||||
int amdgpu_vce_entity_init(struct amdgpu_device *adev, struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_ring *ring;
|
||||
struct drm_gpu_scheduler *sched;
|
||||
int r;
|
||||
if (ring == &adev->vce.ring[0]) {
|
||||
struct drm_gpu_scheduler *sched = &ring->sched;
|
||||
int r;
|
||||
|
||||
ring = &adev->vce.ring[0];
|
||||
sched = &ring->sched;
|
||||
r = drm_sched_entity_init(&adev->vce.entity, DRM_SCHED_PRIORITY_NORMAL,
|
||||
&sched, 1, NULL);
|
||||
if (r != 0) {
|
||||
DRM_ERROR("Failed setting up VCE run queue.\n");
|
||||
return r;
|
||||
r = drm_sched_entity_init(&adev->vce.entity, DRM_SCHED_PRIORITY_NORMAL,
|
||||
&sched, 1, NULL);
|
||||
if (r != 0) {
|
||||
DRM_ERROR("Failed setting up VCE run queue.\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -55,7 +55,7 @@ struct amdgpu_vce {
|
||||
|
||||
int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size);
|
||||
int amdgpu_vce_sw_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_vce_entity_init(struct amdgpu_device *adev);
|
||||
int amdgpu_vce_entity_init(struct amdgpu_device *adev, struct amdgpu_ring *ring);
|
||||
int amdgpu_vce_suspend(struct amdgpu_device *adev);
|
||||
int amdgpu_vce_resume(struct amdgpu_device *adev);
|
||||
void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp);
|
||||
|
||||
@@ -73,9 +73,10 @@ void amdgpu_virt_init_setting(struct amdgpu_device *adev)
|
||||
|
||||
void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
|
||||
uint32_t reg0, uint32_t reg1,
|
||||
uint32_t ref, uint32_t mask)
|
||||
uint32_t ref, uint32_t mask,
|
||||
uint32_t xcc_inst)
|
||||
{
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[0];
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_inst];
|
||||
struct amdgpu_ring *ring = &kiq->ring;
|
||||
signed long r, cnt = 0;
|
||||
unsigned long flags;
|
||||
@@ -942,7 +943,7 @@ void amdgpu_virt_update_sriov_video_codec(struct amdgpu_device *adev,
|
||||
}
|
||||
}
|
||||
|
||||
static bool amdgpu_virt_get_rlcg_reg_access_flag(struct amdgpu_device *adev,
|
||||
bool amdgpu_virt_get_rlcg_reg_access_flag(struct amdgpu_device *adev,
|
||||
u32 acc_flags, u32 hwip,
|
||||
bool write, u32 *rlcg_flag)
|
||||
{
|
||||
@@ -975,7 +976,7 @@ static bool amdgpu_virt_get_rlcg_reg_access_flag(struct amdgpu_device *adev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag, u32 xcc_id)
|
||||
u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag, u32 xcc_id)
|
||||
{
|
||||
struct amdgpu_rlcg_reg_access_ctrl *reg_access_ctrl;
|
||||
uint32_t timeout = 50000;
|
||||
@@ -1093,3 +1094,13 @@ u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
|
||||
else
|
||||
return RREG32(offset);
|
||||
}
|
||||
|
||||
bool amdgpu_sriov_xnack_support(struct amdgpu_device *adev)
|
||||
{
|
||||
bool xnack_mode = true;
|
||||
|
||||
if (amdgpu_sriov_vf(adev) && adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2))
|
||||
xnack_mode = false;
|
||||
|
||||
return xnack_mode;
|
||||
}
|
||||
|
||||
@@ -334,7 +334,8 @@ bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);
|
||||
void amdgpu_virt_init_setting(struct amdgpu_device *adev);
|
||||
void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
|
||||
uint32_t reg0, uint32_t rreg1,
|
||||
uint32_t ref, uint32_t mask);
|
||||
uint32_t ref, uint32_t mask,
|
||||
uint32_t xcc_inst);
|
||||
int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init);
|
||||
int amdgpu_virt_release_full_gpu(struct amdgpu_device *adev, bool init);
|
||||
int amdgpu_virt_reset_gpu(struct amdgpu_device *adev);
|
||||
@@ -365,4 +366,9 @@ u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
|
||||
bool amdgpu_virt_fw_load_skip_check(struct amdgpu_device *adev,
|
||||
uint32_t ucode_id);
|
||||
void amdgpu_virt_post_reset(struct amdgpu_device *adev);
|
||||
bool amdgpu_sriov_xnack_support(struct amdgpu_device *adev);
|
||||
bool amdgpu_virt_get_rlcg_reg_access_flag(struct amdgpu_device *adev,
|
||||
u32 acc_flags, u32 hwip,
|
||||
bool write, u32 *rlcg_flag);
|
||||
u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag, u32 xcc_id);
|
||||
#endif
|
||||
|
||||
@@ -1098,8 +1098,8 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
|
||||
bo = gem_to_amdgpu_bo(gobj);
|
||||
}
|
||||
mem = bo->tbo.resource;
|
||||
if (mem->mem_type == TTM_PL_TT ||
|
||||
mem->mem_type == AMDGPU_PL_PREEMPT)
|
||||
if (mem && (mem->mem_type == TTM_PL_TT ||
|
||||
mem->mem_type == AMDGPU_PL_PREEMPT))
|
||||
pages_addr = bo->tbo.ttm->dma_address;
|
||||
}
|
||||
|
||||
@@ -2139,7 +2139,8 @@ long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout)
|
||||
* Returns:
|
||||
* 0 for success, error for failure.
|
||||
*/
|
||||
int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp_id)
|
||||
int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
int32_t xcp_id)
|
||||
{
|
||||
struct amdgpu_bo *root_bo;
|
||||
struct amdgpu_bo_vm *root;
|
||||
@@ -2158,6 +2159,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp
|
||||
INIT_LIST_HEAD(&vm->done);
|
||||
INIT_LIST_HEAD(&vm->pt_freed);
|
||||
INIT_WORK(&vm->pt_free_work, amdgpu_vm_pt_free_work);
|
||||
INIT_KFIFO(vm->faults);
|
||||
|
||||
r = amdgpu_vm_init_entities(adev, vm);
|
||||
if (r)
|
||||
@@ -2192,34 +2194,33 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp
|
||||
false, &root, xcp_id);
|
||||
if (r)
|
||||
goto error_free_delayed;
|
||||
root_bo = &root->bo;
|
||||
|
||||
root_bo = amdgpu_bo_ref(&root->bo);
|
||||
r = amdgpu_bo_reserve(root_bo, true);
|
||||
if (r) {
|
||||
amdgpu_bo_unref(&root->shadow);
|
||||
amdgpu_bo_unref(&root_bo);
|
||||
goto error_free_delayed;
|
||||
}
|
||||
|
||||
amdgpu_vm_bo_base_init(&vm->root, vm, root_bo);
|
||||
r = dma_resv_reserve_fences(root_bo->tbo.base.resv, 1);
|
||||
if (r)
|
||||
goto error_free_root;
|
||||
|
||||
r = dma_resv_reserve_fences(root_bo->tbo.base.resv, 1);
|
||||
if (r)
|
||||
goto error_unreserve;
|
||||
|
||||
amdgpu_vm_bo_base_init(&vm->root, vm, root_bo);
|
||||
|
||||
r = amdgpu_vm_pt_clear(adev, vm, root, false);
|
||||
if (r)
|
||||
goto error_unreserve;
|
||||
goto error_free_root;
|
||||
|
||||
amdgpu_bo_unreserve(vm->root.bo);
|
||||
|
||||
INIT_KFIFO(vm->faults);
|
||||
amdgpu_bo_unref(&root_bo);
|
||||
|
||||
return 0;
|
||||
|
||||
error_unreserve:
|
||||
amdgpu_bo_unreserve(vm->root.bo);
|
||||
|
||||
error_free_root:
|
||||
amdgpu_bo_unref(&root->shadow);
|
||||
amdgpu_vm_pt_free_root(adev, vm);
|
||||
amdgpu_bo_unreserve(vm->root.bo);
|
||||
amdgpu_bo_unref(&root_bo);
|
||||
vm->root.bo = NULL;
|
||||
|
||||
error_free_delayed:
|
||||
dma_fence_put(vm->last_tlb_flush);
|
||||
|
||||
@@ -103,6 +103,53 @@ static const int walf_pcs_err_noncorrectable_mask_reg_aldebaran[] = {
|
||||
smnPCS_GOPX1_PCS_ERROR_NONCORRECTABLE_MASK + 0x100000
|
||||
};
|
||||
|
||||
static const int xgmi3x16_pcs_err_status_reg_v6_4[] = {
|
||||
smnPCS_XGMI3X16_PCS_ERROR_STATUS,
|
||||
smnPCS_XGMI3X16_PCS_ERROR_STATUS + 0x100000
|
||||
};
|
||||
|
||||
static const int xgmi3x16_pcs_err_noncorrectable_mask_reg_v6_4[] = {
|
||||
smnPCS_XGMI3X16_PCS_ERROR_NONCORRECTABLE_MASK,
|
||||
smnPCS_XGMI3X16_PCS_ERROR_NONCORRECTABLE_MASK + 0x100000
|
||||
};
|
||||
|
||||
static const u64 xgmi_v6_4_0_mca_base_array[] = {
|
||||
0x11a09200,
|
||||
0x11b09200,
|
||||
};
|
||||
|
||||
static const char *xgmi_v6_4_0_ras_error_code_ext[32] = {
|
||||
[0x00] = "XGMI PCS DataLossErr",
|
||||
[0x01] = "XGMI PCS TrainingErr",
|
||||
[0x02] = "XGMI PCS FlowCtrlAckErr",
|
||||
[0x03] = "XGMI PCS RxFifoUnderflowErr",
|
||||
[0x04] = "XGMI PCS RxFifoOverflowErr",
|
||||
[0x05] = "XGMI PCS CRCErr",
|
||||
[0x06] = "XGMI PCS BERExceededErr",
|
||||
[0x07] = "XGMI PCS TxMetaDataErr",
|
||||
[0x08] = "XGMI PCS ReplayBufParityErr",
|
||||
[0x09] = "XGMI PCS DataParityErr",
|
||||
[0x0a] = "XGMI PCS ReplayFifoOverflowErr",
|
||||
[0x0b] = "XGMI PCS ReplayFifoUnderflowErr",
|
||||
[0x0c] = "XGMI PCS ElasticFifoOverflowErr",
|
||||
[0x0d] = "XGMI PCS DeskewErr",
|
||||
[0x0e] = "XGMI PCS FlowCtrlCRCErr",
|
||||
[0x0f] = "XGMI PCS DataStartupLimitErr",
|
||||
[0x10] = "XGMI PCS FCInitTimeoutErr",
|
||||
[0x11] = "XGMI PCS RecoveryTimeoutErr",
|
||||
[0x12] = "XGMI PCS ReadySerialTimeoutErr",
|
||||
[0x13] = "XGMI PCS ReadySerialAttemptErr",
|
||||
[0x14] = "XGMI PCS RecoveryAttemptErr",
|
||||
[0x15] = "XGMI PCS RecoveryRelockAttemptErr",
|
||||
[0x16] = "XGMI PCS ReplayAttemptErr",
|
||||
[0x17] = "XGMI PCS SyncHdrErr",
|
||||
[0x18] = "XGMI PCS TxReplayTimeoutErr",
|
||||
[0x19] = "XGMI PCS RxReplayTimeoutErr",
|
||||
[0x1a] = "XGMI PCS LinkSubTxTimeoutErr",
|
||||
[0x1b] = "XGMI PCS LinkSubRxTimeoutErr",
|
||||
[0x1c] = "XGMI PCS RxCMDPktErr",
|
||||
};
|
||||
|
||||
static const struct amdgpu_pcs_ras_field xgmi_pcs_ras_fields[] = {
|
||||
{"XGMI PCS DataLossErr",
|
||||
SOC15_REG_FIELD(XGMI0_PCS_GOPX16_PCS_ERROR_STATUS, DataLossErr)},
|
||||
@@ -926,7 +973,7 @@ static void pcs_clear_status(struct amdgpu_device *adev, uint32_t pcs_status_reg
|
||||
WREG32_PCIE(pcs_status_reg, 0);
|
||||
}
|
||||
|
||||
static void amdgpu_xgmi_reset_ras_error_count(struct amdgpu_device *adev)
|
||||
static void amdgpu_xgmi_legacy_reset_ras_error_count(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
@@ -952,6 +999,49 @@ static void amdgpu_xgmi_reset_ras_error_count(struct amdgpu_device *adev)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (amdgpu_ip_version(adev, XGMI_HWIP, 0)) {
|
||||
case IP_VERSION(6, 4, 0):
|
||||
for (i = 0; i < ARRAY_SIZE(xgmi3x16_pcs_err_status_reg_v6_4); i++)
|
||||
pcs_clear_status(adev,
|
||||
xgmi3x16_pcs_err_status_reg_v6_4[i]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void __xgmi_v6_4_0_reset_error_count(struct amdgpu_device *adev, int xgmi_inst, u64 mca_base)
|
||||
{
|
||||
WREG64_MCA(xgmi_inst, mca_base, MCA_REG_IDX_STATUS, 0ULL);
|
||||
}
|
||||
|
||||
static void xgmi_v6_4_0_reset_error_count(struct amdgpu_device *adev, int xgmi_inst)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(xgmi_v6_4_0_mca_base_array); i++)
|
||||
__xgmi_v6_4_0_reset_error_count(adev, xgmi_inst, xgmi_v6_4_0_mca_base_array[i]);
|
||||
}
|
||||
|
||||
static void xgmi_v6_4_0_reset_ras_error_count(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for_each_inst(i, adev->aid_mask)
|
||||
xgmi_v6_4_0_reset_error_count(adev, i);
|
||||
}
|
||||
|
||||
static void amdgpu_xgmi_reset_ras_error_count(struct amdgpu_device *adev)
|
||||
{
|
||||
switch (amdgpu_ip_version(adev, XGMI_HWIP, 0)) {
|
||||
case IP_VERSION(6, 4, 0):
|
||||
xgmi_v6_4_0_reset_ras_error_count(adev);
|
||||
break;
|
||||
default:
|
||||
amdgpu_xgmi_legacy_reset_ras_error_count(adev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int amdgpu_xgmi_query_pcs_error_status(struct amdgpu_device *adev,
|
||||
@@ -969,7 +1059,9 @@ static int amdgpu_xgmi_query_pcs_error_status(struct amdgpu_device *adev,
|
||||
|
||||
if (is_xgmi_pcs) {
|
||||
if (amdgpu_ip_version(adev, XGMI_HWIP, 0) ==
|
||||
IP_VERSION(6, 1, 0)) {
|
||||
IP_VERSION(6, 1, 0) ||
|
||||
amdgpu_ip_version(adev, XGMI_HWIP, 0) ==
|
||||
IP_VERSION(6, 4, 0)) {
|
||||
pcs_ras_fields = &xgmi3x16_pcs_ras_fields[0];
|
||||
field_array_size = ARRAY_SIZE(xgmi3x16_pcs_ras_fields);
|
||||
} else {
|
||||
@@ -1003,11 +1095,11 @@ static int amdgpu_xgmi_query_pcs_error_status(struct amdgpu_device *adev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
|
||||
void *ras_error_status)
|
||||
static void amdgpu_xgmi_legacy_query_ras_error_count(struct amdgpu_device *adev,
|
||||
void *ras_error_status)
|
||||
{
|
||||
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
|
||||
int i;
|
||||
int i, supported = 1;
|
||||
uint32_t data, mask_data = 0;
|
||||
uint32_t ue_cnt = 0, ce_cnt = 0;
|
||||
|
||||
@@ -1071,7 +1163,25 @@ static void amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dev_warn(adev->dev, "XGMI RAS error query not supported");
|
||||
supported = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (amdgpu_ip_version(adev, XGMI_HWIP, 0)) {
|
||||
case IP_VERSION(6, 4, 0):
|
||||
/* check xgmi3x16 pcs error */
|
||||
for (i = 0; i < ARRAY_SIZE(xgmi3x16_pcs_err_status_reg_v6_4); i++) {
|
||||
data = RREG32_PCIE(xgmi3x16_pcs_err_status_reg_v6_4[i]);
|
||||
mask_data =
|
||||
RREG32_PCIE(xgmi3x16_pcs_err_noncorrectable_mask_reg_v6_4[i]);
|
||||
if (data)
|
||||
amdgpu_xgmi_query_pcs_error_status(adev, data,
|
||||
mask_data, &ue_cnt, &ce_cnt, true, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!supported)
|
||||
dev_warn(adev->dev, "XGMI RAS error query not supported");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1081,32 +1191,116 @@ static void amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
|
||||
err_data->ce_count += ce_cnt;
|
||||
}
|
||||
|
||||
static enum amdgpu_mca_error_type xgmi_v6_4_0_pcs_mca_get_error_type(struct amdgpu_device *adev, u64 status)
|
||||
{
|
||||
const char *error_str;
|
||||
int ext_error_code;
|
||||
|
||||
ext_error_code = MCA_REG__STATUS__ERRORCODEEXT(status);
|
||||
|
||||
error_str = ext_error_code < ARRAY_SIZE(xgmi_v6_4_0_ras_error_code_ext) ?
|
||||
xgmi_v6_4_0_ras_error_code_ext[ext_error_code] : NULL;
|
||||
if (error_str)
|
||||
dev_info(adev->dev, "%s detected\n", error_str);
|
||||
|
||||
switch (ext_error_code) {
|
||||
case 0:
|
||||
return AMDGPU_MCA_ERROR_TYPE_UE;
|
||||
case 6:
|
||||
return AMDGPU_MCA_ERROR_TYPE_CE;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void __xgmi_v6_4_0_query_error_count(struct amdgpu_device *adev, struct amdgpu_smuio_mcm_config_info *mcm_info,
|
||||
u64 mca_base, struct ras_err_data *err_data)
|
||||
{
|
||||
int xgmi_inst = mcm_info->die_id;
|
||||
u64 status = 0;
|
||||
|
||||
status = RREG64_MCA(xgmi_inst, mca_base, MCA_REG_IDX_STATUS);
|
||||
if (!MCA_REG__STATUS__VAL(status))
|
||||
return;
|
||||
|
||||
switch (xgmi_v6_4_0_pcs_mca_get_error_type(adev, status)) {
|
||||
case AMDGPU_MCA_ERROR_TYPE_UE:
|
||||
amdgpu_ras_error_statistic_ue_count(err_data, mcm_info, 1ULL);
|
||||
break;
|
||||
case AMDGPU_MCA_ERROR_TYPE_CE:
|
||||
amdgpu_ras_error_statistic_ce_count(err_data, mcm_info, 1ULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
WREG64_MCA(xgmi_inst, mca_base, MCA_REG_IDX_STATUS, 0ULL);
|
||||
}
|
||||
|
||||
static void xgmi_v6_4_0_query_error_count(struct amdgpu_device *adev, int xgmi_inst, struct ras_err_data *err_data)
|
||||
{
|
||||
struct amdgpu_smuio_mcm_config_info mcm_info = {
|
||||
.socket_id = adev->smuio.funcs->get_socket_id(adev),
|
||||
.die_id = xgmi_inst,
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(xgmi_v6_4_0_mca_base_array); i++)
|
||||
__xgmi_v6_4_0_query_error_count(adev, &mcm_info, xgmi_v6_4_0_mca_base_array[i], err_data);
|
||||
}
|
||||
|
||||
static void xgmi_v6_4_0_query_ras_error_count(struct amdgpu_device *adev, void *ras_error_status)
|
||||
{
|
||||
struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
|
||||
int i;
|
||||
|
||||
for_each_inst(i, adev->aid_mask)
|
||||
xgmi_v6_4_0_query_error_count(adev, i, err_data);
|
||||
}
|
||||
|
||||
static void amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
|
||||
void *ras_error_status)
|
||||
{
|
||||
switch (amdgpu_ip_version(adev, XGMI_HWIP, 0)) {
|
||||
case IP_VERSION(6, 4, 0):
|
||||
xgmi_v6_4_0_query_ras_error_count(adev, ras_error_status);
|
||||
break;
|
||||
default:
|
||||
amdgpu_xgmi_legacy_query_ras_error_count(adev, ras_error_status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Trigger XGMI/WAFL error */
|
||||
static int amdgpu_ras_error_inject_xgmi(struct amdgpu_device *adev,
|
||||
void *inject_if, uint32_t instance_mask)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret1, ret2;
|
||||
struct ta_ras_trigger_error_input *block_info =
|
||||
(struct ta_ras_trigger_error_input *)inject_if;
|
||||
|
||||
if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_DISALLOW))
|
||||
dev_warn(adev->dev, "Failed to disallow df cstate");
|
||||
|
||||
if (amdgpu_dpm_set_xgmi_plpd_mode(adev, XGMI_PLPD_DISALLOW))
|
||||
ret1 = amdgpu_dpm_set_xgmi_plpd_mode(adev, XGMI_PLPD_DISALLOW);
|
||||
if (ret1 && ret1 != -EOPNOTSUPP)
|
||||
dev_warn(adev->dev, "Failed to disallow XGMI power down");
|
||||
|
||||
ret = psp_ras_trigger_error(&adev->psp, block_info, instance_mask);
|
||||
ret2 = psp_ras_trigger_error(&adev->psp, block_info, instance_mask);
|
||||
|
||||
if (amdgpu_ras_intr_triggered())
|
||||
return ret;
|
||||
return ret2;
|
||||
|
||||
if (amdgpu_dpm_set_xgmi_plpd_mode(adev, XGMI_PLPD_DEFAULT))
|
||||
ret1 = amdgpu_dpm_set_xgmi_plpd_mode(adev, XGMI_PLPD_DEFAULT);
|
||||
if (ret1 && ret1 != -EOPNOTSUPP)
|
||||
dev_warn(adev->dev, "Failed to allow XGMI power down");
|
||||
|
||||
if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_ALLOW))
|
||||
dev_warn(adev->dev, "Failed to allow df cstate");
|
||||
|
||||
return ret;
|
||||
return ret2;
|
||||
}
|
||||
|
||||
struct amdgpu_ras_block_hw_ops xgmi_ras_hw_ops = {
|
||||
|
||||
@@ -1102,6 +1102,7 @@ static void gfx_v9_4_3_init_rlcg_reg_access_ctrl(struct amdgpu_device *adev)
|
||||
reg_access_ctrl->grbm_idx = SOC15_REG_OFFSET(GC, GET_INST(GC, xcc_id), regGRBM_GFX_INDEX);
|
||||
reg_access_ctrl->spare_int = SOC15_REG_OFFSET(GC, GET_INST(GC, xcc_id), regRLC_SPARE_INT);
|
||||
}
|
||||
adev->gfx.rlc.rlcg_reg_access_supported = true;
|
||||
}
|
||||
|
||||
static int gfx_v9_4_3_rlc_init(struct amdgpu_device *adev)
|
||||
@@ -2738,16 +2739,16 @@ static void gfx_v9_4_3_xcc_set_compute_eop_interrupt_state(
|
||||
|
||||
switch (state) {
|
||||
case AMDGPU_IRQ_STATE_DISABLE:
|
||||
mec_int_cntl = RREG32(mec_int_cntl_reg);
|
||||
mec_int_cntl = RREG32_XCC(mec_int_cntl_reg, xcc_id);
|
||||
mec_int_cntl = REG_SET_FIELD(mec_int_cntl, CP_ME1_PIPE0_INT_CNTL,
|
||||
TIME_STAMP_INT_ENABLE, 0);
|
||||
WREG32(mec_int_cntl_reg, mec_int_cntl);
|
||||
WREG32_XCC(mec_int_cntl_reg, mec_int_cntl, xcc_id);
|
||||
break;
|
||||
case AMDGPU_IRQ_STATE_ENABLE:
|
||||
mec_int_cntl = RREG32(mec_int_cntl_reg);
|
||||
mec_int_cntl = RREG32_XCC(mec_int_cntl_reg, xcc_id);
|
||||
mec_int_cntl = REG_SET_FIELD(mec_int_cntl, CP_ME1_PIPE0_INT_CNTL,
|
||||
TIME_STAMP_INT_ENABLE, 1);
|
||||
WREG32(mec_int_cntl_reg, mec_int_cntl);
|
||||
WREG32_XCC(mec_int_cntl_reg, mec_int_cntl, xcc_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -3799,6 +3800,27 @@ static void gfx_v9_4_3_inst_query_ras_err_count(struct amdgpu_device *adev,
|
||||
}
|
||||
}
|
||||
|
||||
/* handle extra register entries of UE */
|
||||
for (; i < ARRAY_SIZE(gfx_v9_4_3_ue_reg_list); i++) {
|
||||
for (j = 0; j < gfx_v9_4_3_ue_reg_list[i].se_num; j++) {
|
||||
for (k = 0; k < gfx_v9_4_3_ue_reg_list[i].reg_entry.reg_inst; k++) {
|
||||
/* no need to select if instance number is 1 */
|
||||
if (gfx_v9_4_3_ue_reg_list[i].se_num > 1 ||
|
||||
gfx_v9_4_3_ue_reg_list[i].reg_entry.reg_inst > 1)
|
||||
gfx_v9_4_3_xcc_select_se_sh(adev, j, 0, k, xcc_id);
|
||||
|
||||
amdgpu_ras_inst_query_ras_error_count(adev,
|
||||
&(gfx_v9_4_3_ue_reg_list[i].reg_entry),
|
||||
1,
|
||||
gfx_v9_4_3_ras_mem_list_array[gfx_v9_4_3_ue_reg_list[i].mem_id_type].mem_id_ent,
|
||||
gfx_v9_4_3_ras_mem_list_array[gfx_v9_4_3_ue_reg_list[i].mem_id_type].size,
|
||||
GET_INST(GC, xcc_id),
|
||||
AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE,
|
||||
&ue_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gfx_v9_4_3_xcc_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
xcc_id);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
@@ -3838,6 +3860,23 @@ static void gfx_v9_4_3_inst_reset_ras_err_count(struct amdgpu_device *adev,
|
||||
}
|
||||
}
|
||||
|
||||
/* handle extra register entries of UE */
|
||||
for (; i < ARRAY_SIZE(gfx_v9_4_3_ue_reg_list); i++) {
|
||||
for (j = 0; j < gfx_v9_4_3_ue_reg_list[i].se_num; j++) {
|
||||
for (k = 0; k < gfx_v9_4_3_ue_reg_list[i].reg_entry.reg_inst; k++) {
|
||||
/* no need to select if instance number is 1 */
|
||||
if (gfx_v9_4_3_ue_reg_list[i].se_num > 1 ||
|
||||
gfx_v9_4_3_ue_reg_list[i].reg_entry.reg_inst > 1)
|
||||
gfx_v9_4_3_xcc_select_se_sh(adev, j, 0, k, xcc_id);
|
||||
|
||||
amdgpu_ras_inst_reset_ras_error_count(adev,
|
||||
&(gfx_v9_4_3_ue_reg_list[i].reg_entry),
|
||||
1,
|
||||
GET_INST(GC, xcc_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gfx_v9_4_3_xcc_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff,
|
||||
xcc_id);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
@@ -4300,7 +4339,7 @@ const struct amdgpu_ip_block_version gfx_v9_4_3_ip_block = {
|
||||
.type = AMD_IP_BLOCK_TYPE_GFX,
|
||||
.major = 9,
|
||||
.minor = 4,
|
||||
.rev = 0,
|
||||
.rev = 3,
|
||||
.funcs = &gfx_v9_4_3_ip_funcs,
|
||||
};
|
||||
|
||||
|
||||
@@ -268,7 +268,7 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
if (adev->gfx.kiq[0].ring.sched.ready && !adev->enable_mes &&
|
||||
(amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) {
|
||||
amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
|
||||
1 << vmid);
|
||||
1 << vmid, GET_INST(GC, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -672,6 +672,7 @@ static void gmc_v10_0_vram_gtt_location(struct amdgpu_device *adev,
|
||||
/* add the xgmi offset of the physical node */
|
||||
base += adev->gmc.xgmi.physical_node_id * adev->gmc.xgmi.node_segment_size;
|
||||
|
||||
amdgpu_gmc_set_agp_default(adev, mc);
|
||||
amdgpu_gmc_vram_location(adev, &adev->gmc, base);
|
||||
amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_BEST_FIT);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
|
||||
@@ -229,7 +229,7 @@ static void gmc_v11_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
if ((adev->gfx.kiq[0].ring.sched.ready || adev->mes.ring.sched.ready) &&
|
||||
(amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) {
|
||||
amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
|
||||
1 << vmid);
|
||||
1 << vmid, GET_INST(GC, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -637,6 +637,7 @@ static void gmc_v11_0_vram_gtt_location(struct amdgpu_device *adev,
|
||||
|
||||
base = adev->mmhub.funcs->get_fb_location(adev);
|
||||
|
||||
amdgpu_gmc_set_agp_default(adev, mc);
|
||||
amdgpu_gmc_vram_location(adev, &adev->gmc, base);
|
||||
amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_HIGH);
|
||||
if (!amdgpu_sriov_vf(adev) ||
|
||||
|
||||
@@ -211,6 +211,7 @@ static void gmc_v6_0_vram_gtt_location(struct amdgpu_device *adev,
|
||||
|
||||
base <<= 24;
|
||||
|
||||
amdgpu_gmc_set_agp_default(adev, mc);
|
||||
amdgpu_gmc_vram_location(adev, mc, base);
|
||||
amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_BEST_FIT);
|
||||
}
|
||||
|
||||
@@ -239,6 +239,7 @@ static void gmc_v7_0_vram_gtt_location(struct amdgpu_device *adev,
|
||||
|
||||
base <<= 24;
|
||||
|
||||
amdgpu_gmc_set_agp_default(adev, mc);
|
||||
amdgpu_gmc_vram_location(adev, mc, base);
|
||||
amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_BEST_FIT);
|
||||
}
|
||||
|
||||
@@ -413,6 +413,7 @@ static void gmc_v8_0_vram_gtt_location(struct amdgpu_device *adev,
|
||||
base = RREG32(mmMC_VM_FB_LOCATION) & 0xFFFF;
|
||||
base <<= 24;
|
||||
|
||||
amdgpu_gmc_set_agp_default(adev, mc);
|
||||
amdgpu_gmc_vram_location(adev, mc, base);
|
||||
amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_BEST_FIT);
|
||||
}
|
||||
|
||||
@@ -817,7 +817,7 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
uint32_t vmhub, uint32_t flush_type)
|
||||
{
|
||||
bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(adev, vmhub);
|
||||
u32 j, inv_req, tmp, sem, req, ack;
|
||||
u32 j, inv_req, tmp, sem, req, ack, inst;
|
||||
const unsigned int eng = 17;
|
||||
struct amdgpu_vmhub *hub;
|
||||
|
||||
@@ -832,13 +832,17 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
/* This is necessary for a HW workaround under SRIOV as well
|
||||
* as GFXOFF under bare metal
|
||||
*/
|
||||
if (adev->gfx.kiq[0].ring.sched.ready &&
|
||||
if (vmhub >= AMDGPU_MMHUB0(0))
|
||||
inst = GET_INST(GC, 0);
|
||||
else
|
||||
inst = vmhub;
|
||||
if (adev->gfx.kiq[inst].ring.sched.ready &&
|
||||
(amdgpu_sriov_runtime(adev) || !amdgpu_sriov_vf(adev))) {
|
||||
uint32_t req = hub->vm_inv_eng0_req + hub->eng_distance * eng;
|
||||
uint32_t ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng;
|
||||
|
||||
amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
|
||||
1 << vmid);
|
||||
1 << vmid, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -856,9 +860,9 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
for (j = 0; j < adev->usec_timeout; j++) {
|
||||
/* a read return value of 1 means semaphore acquire */
|
||||
if (vmhub >= AMDGPU_MMHUB0(0))
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, sem);
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, sem, inst);
|
||||
else
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(GC, sem);
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(GC, sem, inst);
|
||||
if (tmp & 0x1)
|
||||
break;
|
||||
udelay(1);
|
||||
@@ -869,9 +873,9 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
}
|
||||
|
||||
if (vmhub >= AMDGPU_MMHUB0(0))
|
||||
WREG32_SOC15_IP_NO_KIQ(MMHUB, req, inv_req);
|
||||
WREG32_SOC15_IP_NO_KIQ(MMHUB, req, inv_req, inst);
|
||||
else
|
||||
WREG32_SOC15_IP_NO_KIQ(GC, req, inv_req);
|
||||
WREG32_SOC15_IP_NO_KIQ(GC, req, inv_req, inst);
|
||||
|
||||
/*
|
||||
* Issue a dummy read to wait for the ACK register to
|
||||
@@ -884,9 +888,9 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
|
||||
for (j = 0; j < adev->usec_timeout; j++) {
|
||||
if (vmhub >= AMDGPU_MMHUB0(0))
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, ack);
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, ack, inst);
|
||||
else
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(GC, ack);
|
||||
tmp = RREG32_SOC15_IP_NO_KIQ(GC, ack, inst);
|
||||
if (tmp & (1 << vmid))
|
||||
break;
|
||||
udelay(1);
|
||||
@@ -899,9 +903,9 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
||||
* write with 0 means semaphore release
|
||||
*/
|
||||
if (vmhub >= AMDGPU_MMHUB0(0))
|
||||
WREG32_SOC15_IP_NO_KIQ(MMHUB, sem, 0);
|
||||
WREG32_SOC15_IP_NO_KIQ(MMHUB, sem, 0, inst);
|
||||
else
|
||||
WREG32_SOC15_IP_NO_KIQ(GC, sem, 0);
|
||||
WREG32_SOC15_IP_NO_KIQ(GC, sem, 0, inst);
|
||||
}
|
||||
|
||||
spin_unlock(&adev->gmc.invalidate_lock);
|
||||
@@ -1176,7 +1180,10 @@ static void gmc_v9_0_get_coherence_flags(struct amdgpu_device *adev,
|
||||
if (uncached) {
|
||||
mtype = MTYPE_UC;
|
||||
} else if (ext_coherent) {
|
||||
mtype = is_local ? MTYPE_CC : MTYPE_UC;
|
||||
if (adev->rev_id)
|
||||
mtype = is_local ? MTYPE_CC : MTYPE_UC;
|
||||
else
|
||||
mtype = MTYPE_UC;
|
||||
} else if (adev->flags & AMD_IS_APU) {
|
||||
mtype = is_local ? mtype_local : MTYPE_NC;
|
||||
} else {
|
||||
@@ -1297,7 +1304,7 @@ static void gmc_v9_0_override_vm_pte_flags(struct amdgpu_device *adev,
|
||||
|
||||
*flags = (*flags & ~AMDGPU_PTE_MTYPE_VG10_MASK) |
|
||||
AMDGPU_PTE_MTYPE_VG10(mtype_local);
|
||||
} else {
|
||||
} else if (adev->rev_id) {
|
||||
/* MTYPE_UC case */
|
||||
*flags = (*flags & ~AMDGPU_PTE_MTYPE_VG10_MASK) |
|
||||
AMDGPU_PTE_MTYPE_VG10(MTYPE_CC);
|
||||
@@ -1614,6 +1621,8 @@ static void gmc_v9_0_vram_gtt_location(struct amdgpu_device *adev,
|
||||
{
|
||||
u64 base = adev->mmhub.funcs->get_fb_location(adev);
|
||||
|
||||
amdgpu_gmc_set_agp_default(adev, mc);
|
||||
|
||||
/* add the xgmi offset of the physical node */
|
||||
base += adev->gmc.xgmi.physical_node_id * adev->gmc.xgmi.node_segment_size;
|
||||
if (adev->gmc.xgmi.connected_to_cpu) {
|
||||
|
||||
@@ -145,6 +145,10 @@ static void hdp_v4_0_init_registers(struct amdgpu_device *adev)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Do not program registers if VF */
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return;
|
||||
|
||||
WREG32_FIELD15(HDP, 0, HDP_MISC_CNTL, FLUSH_INVALIDATE_CACHE, 1);
|
||||
|
||||
if (amdgpu_ip_version(adev, HDP_HWIP, 0) == IP_VERSION(4, 4, 0))
|
||||
|
||||
@@ -654,9 +654,11 @@ static void jpeg_v4_0_3_dec_ring_set_wptr(struct amdgpu_ring *ring)
|
||||
*/
|
||||
static void jpeg_v4_0_3_dec_ring_insert_start(struct amdgpu_ring *ring)
|
||||
{
|
||||
amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
amdgpu_ring_write(ring, 0x62a04); /* PCTL0_MMHUB_DEEPSLEEP_IB */
|
||||
if (!amdgpu_sriov_vf(ring->adev)) {
|
||||
amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
amdgpu_ring_write(ring, 0x62a04); /* PCTL0_MMHUB_DEEPSLEEP_IB */
|
||||
}
|
||||
|
||||
amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
@@ -672,9 +674,11 @@ static void jpeg_v4_0_3_dec_ring_insert_start(struct amdgpu_ring *ring)
|
||||
*/
|
||||
static void jpeg_v4_0_3_dec_ring_insert_end(struct amdgpu_ring *ring)
|
||||
{
|
||||
amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
amdgpu_ring_write(ring, 0x62a04);
|
||||
if (!amdgpu_sriov_vf(ring->adev)) {
|
||||
amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
amdgpu_ring_write(ring, 0x62a04);
|
||||
}
|
||||
|
||||
amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
|
||||
0, 0, PACKETJ_TYPE0));
|
||||
|
||||
@@ -427,6 +427,7 @@ static void sdma_v4_4_2_inst_gfx_stop(struct amdgpu_device *adev,
|
||||
uint32_t inst_mask)
|
||||
{
|
||||
struct amdgpu_ring *sdma[AMDGPU_MAX_SDMA_INSTANCES];
|
||||
u32 doorbell_offset, doorbell;
|
||||
u32 rb_cntl, ib_cntl;
|
||||
int i, unset = 0;
|
||||
|
||||
@@ -444,6 +445,18 @@ static void sdma_v4_4_2_inst_gfx_stop(struct amdgpu_device *adev,
|
||||
ib_cntl = RREG32_SDMA(i, regSDMA_GFX_IB_CNTL);
|
||||
ib_cntl = REG_SET_FIELD(ib_cntl, SDMA_GFX_IB_CNTL, IB_ENABLE, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_IB_CNTL, ib_cntl);
|
||||
|
||||
if (sdma[i]->use_doorbell) {
|
||||
doorbell = RREG32_SDMA(i, regSDMA_GFX_DOORBELL);
|
||||
doorbell_offset = RREG32_SDMA(i, regSDMA_GFX_DOORBELL_OFFSET);
|
||||
|
||||
doorbell = REG_SET_FIELD(doorbell, SDMA_GFX_DOORBELL, ENABLE, 0);
|
||||
doorbell_offset = REG_SET_FIELD(doorbell_offset,
|
||||
SDMA_GFX_DOORBELL_OFFSET,
|
||||
OFFSET, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_DOORBELL, doorbell);
|
||||
WREG32_SDMA(i, regSDMA_GFX_DOORBELL_OFFSET, doorbell_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,12 +644,6 @@ static void sdma_v4_4_2_gfx_resume(struct amdgpu_device *adev, unsigned int i)
|
||||
rb_cntl = sdma_v4_4_2_rb_cntl(ring, rb_cntl);
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_CNTL, rb_cntl);
|
||||
|
||||
/* Initialize the ring buffer's read and write pointers */
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_RPTR, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_RPTR_HI, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_WPTR, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_WPTR_HI, 0);
|
||||
|
||||
/* set the wb address whether it's enabled or not */
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_RPTR_ADDR_HI,
|
||||
upper_32_bits(adev->wb.gpu_addr + wb_offset) & 0xFFFFFFFF);
|
||||
@@ -654,6 +661,12 @@ static void sdma_v4_4_2_gfx_resume(struct amdgpu_device *adev, unsigned int i)
|
||||
/* before programing wptr to a less value, need set minor_ptr_update first */
|
||||
WREG32_SDMA(i, regSDMA_GFX_MINOR_PTR_UPDATE, 1);
|
||||
|
||||
/* Initialize the ring buffer's read and write pointers */
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_RPTR, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_RPTR_HI, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_WPTR, 0);
|
||||
WREG32_SDMA(i, regSDMA_GFX_RB_WPTR_HI, 0);
|
||||
|
||||
doorbell = RREG32_SDMA(i, regSDMA_GFX_DOORBELL);
|
||||
doorbell_offset = RREG32_SDMA(i, regSDMA_GFX_DOORBELL_OFFSET);
|
||||
|
||||
@@ -2048,7 +2061,7 @@ const struct amdgpu_ip_block_version sdma_v4_4_2_ip_block = {
|
||||
.type = AMD_IP_BLOCK_TYPE_SDMA,
|
||||
.major = 4,
|
||||
.minor = 4,
|
||||
.rev = 0,
|
||||
.rev = 2,
|
||||
.funcs = &sdma_v4_4_2_ip_funcs,
|
||||
};
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
|
||||
#define RREG32_SOC15_IP(ip, reg) __RREG32_SOC15_RLC__(reg, 0, ip##_HWIP, 0)
|
||||
|
||||
#define RREG32_SOC15_IP_NO_KIQ(ip, reg) __RREG32_SOC15_RLC__(reg, AMDGPU_REGS_NO_KIQ, ip##_HWIP, 0)
|
||||
#define RREG32_SOC15_IP_NO_KIQ(ip, reg, inst) __RREG32_SOC15_RLC__(reg, AMDGPU_REGS_NO_KIQ, ip##_HWIP, inst)
|
||||
|
||||
#define RREG32_SOC15_NO_KIQ(ip, inst, reg) \
|
||||
__RREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg, \
|
||||
@@ -86,8 +86,8 @@
|
||||
#define WREG32_SOC15_IP(ip, reg, value) \
|
||||
__WREG32_SOC15_RLC__(reg, value, 0, ip##_HWIP, 0)
|
||||
|
||||
#define WREG32_SOC15_IP_NO_KIQ(ip, reg, value) \
|
||||
__WREG32_SOC15_RLC__(reg, value, AMDGPU_REGS_NO_KIQ, ip##_HWIP, 0)
|
||||
#define WREG32_SOC15_IP_NO_KIQ(ip, reg, value, inst) \
|
||||
__WREG32_SOC15_RLC__(reg, value, AMDGPU_REGS_NO_KIQ, ip##_HWIP, inst)
|
||||
|
||||
#define WREG32_SOC15_NO_KIQ(ip, inst, reg, value) \
|
||||
__WREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg, \
|
||||
@@ -140,7 +140,7 @@
|
||||
|
||||
/* for GC only */
|
||||
#define RREG32_RLC(reg) \
|
||||
__RREG32_SOC15_RLC__(reg, AMDGPU_REGS_RLC, GC_HWIP)
|
||||
__RREG32_SOC15_RLC__(reg, AMDGPU_REGS_RLC, GC_HWIP, 0)
|
||||
|
||||
#define WREG32_RLC_NO_KIQ(reg, value, hwip) \
|
||||
__WREG32_SOC15_RLC__(reg, value, AMDGPU_REGS_NO_KIQ | AMDGPU_REGS_RLC, hwip, 0)
|
||||
@@ -204,4 +204,10 @@
|
||||
+ adev->asic_funcs->encode_ext_smn_addressing(ext), \
|
||||
value) \
|
||||
|
||||
#define RREG64_MCA(ext, mca_base, idx) \
|
||||
RREG64_PCIE_EXT(adev->asic_funcs->encode_ext_smn_addressing(ext) + mca_base + (idx * 8))
|
||||
|
||||
#define WREG64_MCA(ext, mca_base, idx, val) \
|
||||
WREG64_PCIE_EXT(adev->asic_funcs->encode_ext_smn_addressing(ext) + mca_base + (idx * 8), val)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -381,6 +381,7 @@ soc21_asic_reset_method(struct amdgpu_device *adev)
|
||||
return AMD_RESET_METHOD_MODE1;
|
||||
case IP_VERSION(13, 0, 4):
|
||||
case IP_VERSION(13, 0, 11):
|
||||
case IP_VERSION(14, 0, 0):
|
||||
return AMD_RESET_METHOD_MODE2;
|
||||
default:
|
||||
if (amdgpu_dpm_is_baco_supported(adev))
|
||||
|
||||
@@ -88,7 +88,7 @@ static void umc_v12_0_reset_error_count(struct amdgpu_device *adev)
|
||||
umc_v12_0_reset_error_count_per_channel, NULL);
|
||||
}
|
||||
|
||||
static bool umc_v12_0_is_uncorrectable_error(uint64_t mc_umc_status)
|
||||
bool umc_v12_0_is_uncorrectable_error(uint64_t mc_umc_status)
|
||||
{
|
||||
return ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) &&
|
||||
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, PCC) == 1 ||
|
||||
@@ -96,7 +96,7 @@ static bool umc_v12_0_is_uncorrectable_error(uint64_t mc_umc_status)
|
||||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, TCC) == 1));
|
||||
}
|
||||
|
||||
static bool umc_v12_0_is_correctable_error(uint64_t mc_umc_status)
|
||||
bool umc_v12_0_is_correctable_error(uint64_t mc_umc_status)
|
||||
{
|
||||
return (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
|
||||
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1 ||
|
||||
|
||||
@@ -117,6 +117,9 @@
|
||||
(pa) |= (UMC_V12_0_CHANNEL_HASH_CH6(channel_idx, pa) << UMC_V12_0_PA_CH6_BIT); \
|
||||
} while (0)
|
||||
|
||||
bool umc_v12_0_is_uncorrectable_error(uint64_t mc_umc_status);
|
||||
bool umc_v12_0_is_correctable_error(uint64_t mc_umc_status);
|
||||
|
||||
extern const uint32_t
|
||||
umc_v12_0_channel_idx_tbl[]
|
||||
[UMC_V12_0_UMC_INSTANCE_NUM]
|
||||
|
||||
@@ -577,8 +577,6 @@ static int uvd_v3_1_sw_init(void *handle)
|
||||
ptr += ucode_len;
|
||||
memcpy(&adev->uvd.keyselect, ptr, 4);
|
||||
|
||||
r = amdgpu_uvd_entity_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -127,8 +127,6 @@ static int uvd_v4_2_sw_init(void *handle)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_uvd_entity_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -125,8 +125,6 @@ static int uvd_v5_0_sw_init(void *handle)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_uvd_entity_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -432,8 +432,6 @@ static int uvd_v6_0_sw_init(void *handle)
|
||||
}
|
||||
}
|
||||
|
||||
r = amdgpu_uvd_entity_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -480,10 +480,6 @@ static int uvd_v7_0_sw_init(void *handle)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_uvd_entity_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_virt_alloc_mm_table(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -441,8 +441,6 @@ static int vce_v2_0_sw_init(void *handle)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_vce_entity_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -450,8 +450,6 @@ static int vce_v3_0_sw_init(void *handle)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_vce_entity_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -486,11 +486,6 @@ static int vce_v4_0_sw_init(void *handle)
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
r = amdgpu_vce_entity_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_virt_alloc_mm_table(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
Reference in New Issue
Block a user