Merge tag 'amd-drm-next-5.8-2020-04-24' of git://people.freedesktop.org/~agd5f/linux into drm-next
amd-drm-next-5.8-2020-04-24: amdgpu: - Documentation improvements - Enable FRU chip access on boards that support it - RAS updates - SR-IOV updates - Powerplay locking fixes for older SMU versions - VCN DPG (dynamic powergating) cleanup - VCN 2.5 DPG enablement - Rework GPU scheduler handling - Improve scheduler priority handling - Add SPM (streaming performance monitor) golden settings for navi - GFX10 clockgating fixes - DC ABM (automatic backlight modulation) fixes - DC cursor and plane fixes - DC watermark fixes - DC clock handling fixes - DC color management fixes - GPU reset fixes - Clean up MMIO access macros - EEPROM access fixes - Misc code cleanups amdkfd: - Misc code cleanups radeon: - Clean up safe reg list generation - Misc code cleanups From: Alex Deucher <alexdeucher@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200424190827.4542-1-alexander.deucher@amd.com
This commit is contained in:
commit
937eea297e
|
@ -202,3 +202,91 @@ busy_percent
|
|||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
|
||||
:doc: busy_percent
|
||||
|
||||
GPU Product Information
|
||||
=======================
|
||||
|
||||
Information about the GPU can be obtained on certain cards
|
||||
via sysfs
|
||||
|
||||
product_name
|
||||
------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
||||
:doc: product_name
|
||||
|
||||
product_number
|
||||
--------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
||||
:doc: product_name
|
||||
|
||||
serial_number
|
||||
-------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
||||
:doc: serial_number
|
||||
|
||||
unique_id
|
||||
---------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
|
||||
:doc: unique_id
|
||||
|
||||
GPU Memory Usage Information
|
||||
============================
|
||||
|
||||
Various memory accounting can be accessed via sysfs
|
||||
|
||||
mem_info_vram_total
|
||||
-------------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
|
||||
:doc: mem_info_vram_total
|
||||
|
||||
mem_info_vram_used
|
||||
------------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
|
||||
:doc: mem_info_vram_used
|
||||
|
||||
mem_info_vis_vram_total
|
||||
-----------------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
|
||||
:doc: mem_info_vis_vram_total
|
||||
|
||||
mem_info_vis_vram_used
|
||||
----------------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
|
||||
:doc: mem_info_vis_vram_used
|
||||
|
||||
mem_info_gtt_total
|
||||
------------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
|
||||
:doc: mem_info_gtt_total
|
||||
|
||||
mem_info_gtt_used
|
||||
-----------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
|
||||
:doc: mem_info_gtt_used
|
||||
|
||||
PCIe Accounting Information
|
||||
===========================
|
||||
|
||||
pcie_bw
|
||||
-------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
|
||||
:doc: pcie_bw
|
||||
|
||||
pcie_replay_count
|
||||
-----------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
||||
:doc: pcie_replay_count
|
||||
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
|
|||
amdgpu_vf_error.o amdgpu_sched.o amdgpu_debugfs.o amdgpu_ids.o \
|
||||
amdgpu_gmc.o amdgpu_mmhub.o amdgpu_xgmi.o amdgpu_csa.o amdgpu_ras.o amdgpu_vm_cpu.o \
|
||||
amdgpu_vm_sdma.o amdgpu_discovery.o amdgpu_ras_eeprom.o amdgpu_nbio.o \
|
||||
amdgpu_umc.o smu_v11_0_i2c.o
|
||||
amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o
|
||||
|
||||
amdgpu-$(CONFIG_PERF_EVENTS) += amdgpu_pmu.o
|
||||
|
||||
|
|
|
@ -28,6 +28,18 @@
|
|||
#ifndef __AMDGPU_H__
|
||||
#define __AMDGPU_H__
|
||||
|
||||
#ifdef pr_fmt
|
||||
#undef pr_fmt
|
||||
#endif
|
||||
|
||||
#define pr_fmt(fmt) "amdgpu: " fmt
|
||||
|
||||
#ifdef dev_fmt
|
||||
#undef dev_fmt
|
||||
#endif
|
||||
|
||||
#define dev_fmt(fmt) "amdgpu: " fmt
|
||||
|
||||
#include "amdgpu_ctx.h"
|
||||
|
||||
#include <linux/atomic.h>
|
||||
|
@ -388,6 +400,13 @@ struct amdgpu_sa_bo {
|
|||
int amdgpu_fence_slab_init(void);
|
||||
void amdgpu_fence_slab_fini(void);
|
||||
|
||||
enum amdgpu_ib_pool_type {
|
||||
AMDGPU_IB_POOL_NORMAL = 0,
|
||||
AMDGPU_IB_POOL_VM,
|
||||
AMDGPU_IB_POOL_DIRECT,
|
||||
|
||||
AMDGPU_IB_POOL_MAX
|
||||
};
|
||||
/*
|
||||
* IRQS.
|
||||
*/
|
||||
|
@ -439,7 +458,9 @@ struct amdgpu_fpriv {
|
|||
int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv);
|
||||
|
||||
int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
unsigned size, struct amdgpu_ib *ib);
|
||||
unsigned size,
|
||||
enum amdgpu_ib_pool_type pool,
|
||||
struct amdgpu_ib *ib);
|
||||
void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib,
|
||||
struct dma_fence *f);
|
||||
int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
||||
|
@ -512,7 +533,7 @@ static inline void amdgpu_set_ib_value(struct amdgpu_cs_parser *p,
|
|||
/*
|
||||
* Writeback
|
||||
*/
|
||||
#define AMDGPU_MAX_WB 128 /* Reserve at most 128 WB slots for amdgpu-owned rings. */
|
||||
#define AMDGPU_MAX_WB 256 /* Reserve at most 256 WB slots for amdgpu-owned rings. */
|
||||
|
||||
struct amdgpu_wb {
|
||||
struct amdgpu_bo *wb_obj;
|
||||
|
@ -843,7 +864,8 @@ struct amdgpu_device {
|
|||
unsigned num_rings;
|
||||
struct amdgpu_ring *rings[AMDGPU_MAX_RINGS];
|
||||
bool ib_pool_ready;
|
||||
struct amdgpu_sa_manager ring_tmp_bo;
|
||||
struct amdgpu_sa_manager ring_tmp_bo[AMDGPU_IB_POOL_MAX];
|
||||
struct amdgpu_sched gpu_sched[AMDGPU_HW_IP_NUM][AMDGPU_RING_PRIO_MAX];
|
||||
|
||||
/* interrupts */
|
||||
struct amdgpu_irq irq;
|
||||
|
@ -935,9 +957,6 @@ struct amdgpu_device {
|
|||
/* link all shadow bo */
|
||||
struct list_head shadow_list;
|
||||
struct mutex shadow_list_lock;
|
||||
/* keep an lru list of rings by HW IP */
|
||||
struct list_head ring_lru_list;
|
||||
spinlock_t ring_lru_list_lock;
|
||||
|
||||
/* record hw reset is performed */
|
||||
bool has_hw_reset;
|
||||
|
@ -946,8 +965,6 @@ struct amdgpu_device {
|
|||
/* s3/s4 mask */
|
||||
bool in_suspend;
|
||||
|
||||
/* record last mm index being written through WREG32*/
|
||||
unsigned long last_mm_index;
|
||||
bool in_gpu_reset;
|
||||
enum pp_mp1_state mp1_state;
|
||||
struct mutex lock_reset;
|
||||
|
@ -966,14 +983,17 @@ struct amdgpu_device {
|
|||
uint64_t unique_id;
|
||||
uint64_t df_perfmon_config_assign_mask[AMDGPU_MAX_DF_PERFMONS];
|
||||
|
||||
/* device pstate */
|
||||
int pstate;
|
||||
/* enable runtime pm on the device */
|
||||
bool runpm;
|
||||
bool in_runpm;
|
||||
|
||||
bool pm_sysfs_en;
|
||||
bool ucode_sysfs_en;
|
||||
|
||||
/* Chip product information */
|
||||
char product_number[16];
|
||||
char product_name[32];
|
||||
char serial[16];
|
||||
};
|
||||
|
||||
static inline struct amdgpu_device *amdgpu_ttm_adev(struct ttm_bo_device *bdev)
|
||||
|
@ -990,10 +1010,10 @@ int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev);
|
|||
|
||||
void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
|
||||
uint32_t *buf, size_t size, bool write);
|
||||
uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
|
||||
uint32_t amdgpu_device_rreg(struct amdgpu_device *adev, uint32_t reg,
|
||||
uint32_t acc_flags);
|
||||
void amdgpu_device_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
|
||||
uint32_t acc_flags);
|
||||
void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
|
||||
uint32_t acc_flags);
|
||||
void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
|
||||
uint32_t acc_flags);
|
||||
void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value);
|
||||
|
@ -1010,25 +1030,20 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
|
|||
/*
|
||||
* Registers read & write functions.
|
||||
*/
|
||||
|
||||
#define AMDGPU_REGS_IDX (1<<0)
|
||||
#define AMDGPU_REGS_NO_KIQ (1<<1)
|
||||
#define AMDGPU_REGS_KIQ (1<<2)
|
||||
|
||||
#define RREG32_NO_KIQ(reg) amdgpu_mm_rreg(adev, (reg), AMDGPU_REGS_NO_KIQ)
|
||||
#define WREG32_NO_KIQ(reg, v) amdgpu_mm_wreg(adev, (reg), (v), AMDGPU_REGS_NO_KIQ)
|
||||
#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_mm_rreg(adev, (reg), AMDGPU_REGS_KIQ)
|
||||
#define WREG32_KIQ(reg, v) amdgpu_mm_wreg(adev, (reg), (v), AMDGPU_REGS_KIQ)
|
||||
#define RREG32_KIQ(reg) amdgpu_kiq_rreg(adev, (reg))
|
||||
#define WREG32_KIQ(reg, v) amdgpu_kiq_wreg(adev, (reg), (v))
|
||||
|
||||
#define RREG8(reg) amdgpu_mm_rreg8(adev, (reg))
|
||||
#define WREG8(reg, v) amdgpu_mm_wreg8(adev, (reg), (v))
|
||||
|
||||
#define RREG32(reg) amdgpu_mm_rreg(adev, (reg), 0)
|
||||
#define RREG32_IDX(reg) amdgpu_mm_rreg(adev, (reg), AMDGPU_REGS_IDX)
|
||||
#define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", amdgpu_mm_rreg(adev, (reg), 0))
|
||||
#define WREG32(reg, v) amdgpu_mm_wreg(adev, (reg), (v), 0)
|
||||
#define WREG32_IDX(reg, v) amdgpu_mm_wreg(adev, (reg), (v), AMDGPU_REGS_IDX)
|
||||
#define RREG32(reg) amdgpu_device_rreg(adev, (reg), 0)
|
||||
#define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", amdgpu_device_rreg(adev, (reg), 0))
|
||||
#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_PCIE(reg) adev->pcie_rreg(adev, (reg))
|
||||
|
@ -1065,7 +1080,7 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
|
|||
tmp_ |= ((val) & ~(mask)); \
|
||||
WREG32_PLL(reg, tmp_); \
|
||||
} while (0)
|
||||
#define DREG32_SYS(sqf, adev, reg) seq_printf((sqf), #reg " : 0x%08X\n", amdgpu_mm_rreg((adev), (reg), false))
|
||||
#define DREG32_SYS(sqf, adev, reg) seq_printf((sqf), #reg " : 0x%08X\n", amdgpu_device_rreg((adev), (reg), false))
|
||||
#define RREG32_IO(reg) amdgpu_io_rreg(adev, (reg))
|
||||
#define WREG32_IO(reg, v) amdgpu_io_wreg(adev, (reg), (v))
|
||||
|
||||
|
|
|
@ -543,6 +543,9 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
|
|||
uint32_t temp;
|
||||
struct v10_compute_mqd *m = get_mqd(mqd);
|
||||
|
||||
if (adev->in_gpu_reset)
|
||||
return -EIO;
|
||||
|
||||
#if 0
|
||||
unsigned long flags;
|
||||
int retry;
|
||||
|
|
|
@ -362,13 +362,13 @@ static int vm_validate_pt_pd_bos(struct amdgpu_vm *vm)
|
|||
ret = amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_amdkfd_validate,
|
||||
¶m);
|
||||
if (ret) {
|
||||
pr_err("amdgpu: failed to validate PT BOs\n");
|
||||
pr_err("failed to validate PT BOs\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = amdgpu_amdkfd_validate(¶m, pd);
|
||||
if (ret) {
|
||||
pr_err("amdgpu: failed to validate PD\n");
|
||||
pr_err("failed to validate PD\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -377,7 +377,7 @@ static int vm_validate_pt_pd_bos(struct amdgpu_vm *vm)
|
|||
if (vm->use_cpu_for_update) {
|
||||
ret = amdgpu_bo_kmap(pd, NULL);
|
||||
if (ret) {
|
||||
pr_err("amdgpu: failed to kmap PD, ret=%d\n", ret);
|
||||
pr_err("failed to kmap PD, ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -660,15 +660,15 @@ static int reserve_bo_and_vm(struct kgd_mem *mem,
|
|||
|
||||
ret = ttm_eu_reserve_buffers(&ctx->ticket, &ctx->list,
|
||||
false, &ctx->duplicates);
|
||||
if (!ret)
|
||||
ctx->reserved = true;
|
||||
else {
|
||||
pr_err("Failed to reserve buffers in ttm\n");
|
||||
if (ret) {
|
||||
pr_err("Failed to reserve buffers in ttm.\n");
|
||||
kfree(ctx->vm_pd);
|
||||
ctx->vm_pd = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
ctx->reserved = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -733,17 +733,15 @@ static int reserve_bo_and_cond_vms(struct kgd_mem *mem,
|
|||
|
||||
ret = ttm_eu_reserve_buffers(&ctx->ticket, &ctx->list,
|
||||
false, &ctx->duplicates);
|
||||
if (!ret)
|
||||
ctx->reserved = true;
|
||||
else
|
||||
pr_err("Failed to reserve buffers in ttm.\n");
|
||||
|
||||
if (ret) {
|
||||
pr_err("Failed to reserve buffers in ttm.\n");
|
||||
kfree(ctx->vm_pd);
|
||||
ctx->vm_pd = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
ctx->reserved = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1286,22 +1284,22 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
|
|||
struct kfd_bo_va_list *entry, *tmp;
|
||||
struct bo_vm_reservation_context ctx;
|
||||
struct ttm_validate_buffer *bo_list_entry;
|
||||
unsigned int mapped_to_gpu_memory;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&mem->lock);
|
||||
|
||||
if (mem->mapped_to_gpu_memory > 0) {
|
||||
pr_debug("BO VA 0x%llx size 0x%lx is still mapped.\n",
|
||||
mem->va, bo_size);
|
||||
mutex_unlock(&mem->lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
mapped_to_gpu_memory = mem->mapped_to_gpu_memory;
|
||||
mutex_unlock(&mem->lock);
|
||||
/* lock is not needed after this, since mem is unused and will
|
||||
* be freed anyway
|
||||
*/
|
||||
|
||||
if (mapped_to_gpu_memory > 0) {
|
||||
pr_debug("BO VA 0x%llx size 0x%lx is still mapped.\n",
|
||||
mem->va, bo_size);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* No more MMU notifiers */
|
||||
amdgpu_mn_unregister(mem->bo);
|
||||
|
||||
|
|
|
@ -60,8 +60,6 @@ static uint32_t amdgpu_cgs_read_ind_register(struct cgs_device *cgs_device,
|
|||
{
|
||||
CGS_FUNC_ADEV;
|
||||
switch (space) {
|
||||
case CGS_IND_REG__MMIO:
|
||||
return RREG32_IDX(index);
|
||||
case CGS_IND_REG__PCIE:
|
||||
return RREG32_PCIE(index);
|
||||
case CGS_IND_REG__SMC:
|
||||
|
@ -77,6 +75,8 @@ static uint32_t amdgpu_cgs_read_ind_register(struct cgs_device *cgs_device,
|
|||
case CGS_IND_REG__AUDIO_ENDPT:
|
||||
DRM_ERROR("audio endpt register access not implemented.\n");
|
||||
return 0;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
WARN(1, "Invalid indirect register space");
|
||||
return 0;
|
||||
|
@ -88,8 +88,6 @@ static void amdgpu_cgs_write_ind_register(struct cgs_device *cgs_device,
|
|||
{
|
||||
CGS_FUNC_ADEV;
|
||||
switch (space) {
|
||||
case CGS_IND_REG__MMIO:
|
||||
return WREG32_IDX(index, value);
|
||||
case CGS_IND_REG__PCIE:
|
||||
return WREG32_PCIE(index, value);
|
||||
case CGS_IND_REG__SMC:
|
||||
|
@ -105,6 +103,8 @@ static void amdgpu_cgs_write_ind_register(struct cgs_device *cgs_device,
|
|||
case CGS_IND_REG__AUDIO_ENDPT:
|
||||
DRM_ERROR("audio endpt register access not implemented.\n");
|
||||
return;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
WARN(1, "Invalid indirect register space");
|
||||
}
|
||||
|
|
|
@ -924,7 +924,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
|
|||
|
||||
ring = to_amdgpu_ring(entity->rq->sched);
|
||||
r = amdgpu_ib_get(adev, vm, ring->funcs->parse_cs ?
|
||||
chunk_ib->ib_bytes : 0, ib);
|
||||
chunk_ib->ib_bytes : 0, AMDGPU_IB_POOL_NORMAL, ib);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to get ib !\n");
|
||||
return r;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "amdgpu.h"
|
||||
#include "amdgpu_sched.h"
|
||||
#include "amdgpu_ras.h"
|
||||
#include <linux/nospec.h>
|
||||
|
||||
#define to_amdgpu_ctx_entity(e) \
|
||||
container_of((e), struct amdgpu_ctx_entity, entity)
|
||||
|
@ -72,13 +73,30 @@ static enum gfx_pipe_priority amdgpu_ctx_sched_prio_to_compute_prio(enum drm_sch
|
|||
}
|
||||
}
|
||||
|
||||
static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, const u32 hw_ip, const u32 ring)
|
||||
static unsigned int amdgpu_ctx_prio_sched_to_hw(struct amdgpu_device *adev,
|
||||
enum drm_sched_priority prio,
|
||||
u32 hw_ip)
|
||||
{
|
||||
unsigned int hw_prio;
|
||||
|
||||
hw_prio = (hw_ip == AMDGPU_HW_IP_COMPUTE) ?
|
||||
amdgpu_ctx_sched_prio_to_compute_prio(prio) :
|
||||
AMDGPU_RING_PRIO_DEFAULT;
|
||||
hw_ip = array_index_nospec(hw_ip, AMDGPU_HW_IP_NUM);
|
||||
if (adev->gpu_sched[hw_ip][hw_prio].num_scheds == 0)
|
||||
hw_prio = AMDGPU_RING_PRIO_DEFAULT;
|
||||
|
||||
return hw_prio;
|
||||
}
|
||||
|
||||
static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
|
||||
const u32 ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ctx->adev;
|
||||
struct amdgpu_ctx_entity *entity;
|
||||
struct drm_gpu_scheduler **scheds = NULL, *sched = NULL;
|
||||
unsigned num_scheds = 0;
|
||||
enum gfx_pipe_priority hw_prio;
|
||||
unsigned int hw_prio;
|
||||
enum drm_sched_priority priority;
|
||||
int r;
|
||||
|
||||
|
@ -90,52 +108,16 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, const u32 hw_ip, const
|
|||
entity->sequence = 1;
|
||||
priority = (ctx->override_priority == DRM_SCHED_PRIORITY_UNSET) ?
|
||||
ctx->init_priority : ctx->override_priority;
|
||||
switch (hw_ip) {
|
||||
case AMDGPU_HW_IP_GFX:
|
||||
sched = &adev->gfx.gfx_ring[0].sched;
|
||||
hw_prio = amdgpu_ctx_prio_sched_to_hw(adev, priority, hw_ip);
|
||||
|
||||
hw_ip = array_index_nospec(hw_ip, AMDGPU_HW_IP_NUM);
|
||||
scheds = adev->gpu_sched[hw_ip][hw_prio].sched;
|
||||
num_scheds = adev->gpu_sched[hw_ip][hw_prio].num_scheds;
|
||||
|
||||
if (hw_ip == AMDGPU_HW_IP_VCN_ENC || hw_ip == AMDGPU_HW_IP_VCN_DEC) {
|
||||
sched = drm_sched_pick_best(scheds, num_scheds);
|
||||
scheds = &sched;
|
||||
num_scheds = 1;
|
||||
break;
|
||||
case AMDGPU_HW_IP_COMPUTE:
|
||||
hw_prio = amdgpu_ctx_sched_prio_to_compute_prio(priority);
|
||||
scheds = adev->gfx.compute_prio_sched[hw_prio];
|
||||
num_scheds = adev->gfx.num_compute_sched[hw_prio];
|
||||
break;
|
||||
case AMDGPU_HW_IP_DMA:
|
||||
scheds = adev->sdma.sdma_sched;
|
||||
num_scheds = adev->sdma.num_sdma_sched;
|
||||
break;
|
||||
case AMDGPU_HW_IP_UVD:
|
||||
sched = &adev->uvd.inst[0].ring.sched;
|
||||
scheds = &sched;
|
||||
num_scheds = 1;
|
||||
break;
|
||||
case AMDGPU_HW_IP_VCE:
|
||||
sched = &adev->vce.ring[0].sched;
|
||||
scheds = &sched;
|
||||
num_scheds = 1;
|
||||
break;
|
||||
case AMDGPU_HW_IP_UVD_ENC:
|
||||
sched = &adev->uvd.inst[0].ring_enc[0].sched;
|
||||
scheds = &sched;
|
||||
num_scheds = 1;
|
||||
break;
|
||||
case AMDGPU_HW_IP_VCN_DEC:
|
||||
sched = drm_sched_pick_best(adev->vcn.vcn_dec_sched,
|
||||
adev->vcn.num_vcn_dec_sched);
|
||||
scheds = &sched;
|
||||
num_scheds = 1;
|
||||
break;
|
||||
case AMDGPU_HW_IP_VCN_ENC:
|
||||
sched = drm_sched_pick_best(adev->vcn.vcn_enc_sched,
|
||||
adev->vcn.num_vcn_enc_sched);
|
||||
scheds = &sched;
|
||||
num_scheds = 1;
|
||||
break;
|
||||
case AMDGPU_HW_IP_VCN_JPEG:
|
||||
scheds = adev->jpeg.jpeg_sched;
|
||||
num_scheds = adev->jpeg.num_jpeg_sched;
|
||||
break;
|
||||
}
|
||||
|
||||
r = drm_sched_entity_init(&entity->entity, priority, scheds, num_scheds,
|
||||
|
@ -178,7 +160,6 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev,
|
|||
ctx->override_priority = DRM_SCHED_PRIORITY_UNSET;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static void amdgpu_ctx_fini_entity(struct amdgpu_ctx_entity *entity)
|
||||
|
@ -525,7 +506,7 @@ static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx,
|
|||
enum drm_sched_priority priority)
|
||||
{
|
||||
struct amdgpu_device *adev = ctx->adev;
|
||||
enum gfx_pipe_priority hw_prio;
|
||||
unsigned int hw_prio;
|
||||
struct drm_gpu_scheduler **scheds = NULL;
|
||||
unsigned num_scheds;
|
||||
|
||||
|
@ -534,9 +515,11 @@ static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx,
|
|||
|
||||
/* set hw priority */
|
||||
if (hw_ip == AMDGPU_HW_IP_COMPUTE) {
|
||||
hw_prio = amdgpu_ctx_sched_prio_to_compute_prio(priority);
|
||||
scheds = adev->gfx.compute_prio_sched[hw_prio];
|
||||
num_scheds = adev->gfx.num_compute_sched[hw_prio];
|
||||
hw_prio = amdgpu_ctx_prio_sched_to_hw(adev, priority,
|
||||
AMDGPU_HW_IP_COMPUTE);
|
||||
hw_prio = array_index_nospec(hw_prio, AMDGPU_RING_PRIO_MAX);
|
||||
scheds = adev->gpu_sched[hw_ip][hw_prio].sched;
|
||||
num_scheds = adev->gpu_sched[hw_ip][hw_prio].num_scheds;
|
||||
drm_sched_entity_modify_sched(&aentity->entity, scheds,
|
||||
num_scheds);
|
||||
}
|
||||
|
@ -665,78 +648,3 @@ void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr)
|
|||
idr_destroy(&mgr->ctx_handles);
|
||||
mutex_destroy(&mgr->lock);
|
||||
}
|
||||
|
||||
|
||||
static void amdgpu_ctx_init_compute_sched(struct amdgpu_device *adev)
|
||||
{
|
||||
int num_compute_sched_normal = 0;
|
||||
int num_compute_sched_high = AMDGPU_MAX_COMPUTE_RINGS - 1;
|
||||
int i;
|
||||
|
||||
/* use one drm sched array, gfx.compute_sched to store both high and
|
||||
* normal priority drm compute schedulers */
|
||||
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
|
||||
if (!adev->gfx.compute_ring[i].has_high_prio)
|
||||
adev->gfx.compute_sched[num_compute_sched_normal++] =
|
||||
&adev->gfx.compute_ring[i].sched;
|
||||
else
|
||||
adev->gfx.compute_sched[num_compute_sched_high--] =
|
||||
&adev->gfx.compute_ring[i].sched;
|
||||
}
|
||||
|
||||
/* compute ring only has two priority for now */
|
||||
i = AMDGPU_GFX_PIPE_PRIO_NORMAL;
|
||||
adev->gfx.compute_prio_sched[i] = &adev->gfx.compute_sched[0];
|
||||
adev->gfx.num_compute_sched[i] = num_compute_sched_normal;
|
||||
|
||||
i = AMDGPU_GFX_PIPE_PRIO_HIGH;
|
||||
if (num_compute_sched_high == (AMDGPU_MAX_COMPUTE_RINGS - 1)) {
|
||||
/* When compute has no high priority rings then use */
|
||||
/* normal priority sched array */
|
||||
adev->gfx.compute_prio_sched[i] = &adev->gfx.compute_sched[0];
|
||||
adev->gfx.num_compute_sched[i] = num_compute_sched_normal;
|
||||
} else {
|
||||
adev->gfx.compute_prio_sched[i] =
|
||||
&adev->gfx.compute_sched[num_compute_sched_high - 1];
|
||||
adev->gfx.num_compute_sched[i] =
|
||||
adev->gfx.num_compute_rings - num_compute_sched_normal;
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_ctx_init_sched(struct amdgpu_device *adev)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
amdgpu_ctx_init_compute_sched(adev);
|
||||
for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
|
||||
adev->gfx.gfx_sched[i] = &adev->gfx.gfx_ring[i].sched;
|
||||
adev->gfx.num_gfx_sched++;
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
adev->sdma.sdma_sched[i] = &adev->sdma.instance[i].ring.sched;
|
||||
adev->sdma.num_sdma_sched++;
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
adev->vcn.vcn_dec_sched[adev->vcn.num_vcn_dec_sched++] =
|
||||
&adev->vcn.inst[i].ring_dec.sched;
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
for (j = 0; j < adev->vcn.num_enc_rings; ++j)
|
||||
adev->vcn.vcn_enc_sched[adev->vcn.num_vcn_enc_sched++] =
|
||||
&adev->vcn.inst[i].ring_enc[j].sched;
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
if (adev->jpeg.harvest_config & (1 << i))
|
||||
continue;
|
||||
adev->jpeg.jpeg_sched[adev->jpeg.num_jpeg_sched++] =
|
||||
&adev->jpeg.inst[i].ring_dec.sched;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,4 @@ void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr);
|
|||
long amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr, long timeout);
|
||||
void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr);
|
||||
|
||||
void amdgpu_ctx_init_sched(struct amdgpu_device *adev);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -152,11 +152,16 @@ static int amdgpu_debugfs_process_reg_op(bool read, struct file *f,
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = amdgpu_virt_enable_access_debugfs(adev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (use_bank) {
|
||||
if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||
|
||||
(se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines)) {
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return -EINVAL;
|
||||
}
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
|
@ -207,6 +212,7 @@ end:
|
|||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -255,6 +261,10 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = amdgpu_virt_enable_access_debugfs(adev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
|
||||
|
@ -263,6 +273,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
|
|||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -275,6 +286,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
|
|||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -304,6 +316,10 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = amdgpu_virt_enable_access_debugfs(adev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
|
||||
|
@ -311,6 +327,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user
|
|||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -325,6 +342,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user
|
|||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -354,6 +372,10 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = amdgpu_virt_enable_access_debugfs(adev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
|
||||
|
@ -362,6 +384,7 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
|
|||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -374,6 +397,7 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
|
|||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -403,6 +427,10 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = amdgpu_virt_enable_access_debugfs(adev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
|
||||
|
@ -410,6 +438,7 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user
|
|||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -424,6 +453,7 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user
|
|||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -453,6 +483,10 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = amdgpu_virt_enable_access_debugfs(adev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
|
||||
|
@ -461,6 +495,7 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
|
|||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -473,6 +508,7 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
|
|||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -502,6 +538,10 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = amdgpu_virt_enable_access_debugfs(adev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
|
||||
|
@ -509,6 +549,7 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *
|
|||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -523,6 +564,7 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *
|
|||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -651,16 +693,24 @@ static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = amdgpu_virt_enable_access_debugfs(adev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = amdgpu_dpm_read_sensor(adev, idx, &values[0], &valuesize);
|
||||
|
||||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
if (r)
|
||||
if (r) {
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (size > valuesize)
|
||||
if (size > valuesize) {
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
outsize = 0;
|
||||
x = 0;
|
||||
|
@ -673,6 +723,7 @@ static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
|
|||
}
|
||||
}
|
||||
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return !r ? outsize : r;
|
||||
}
|
||||
|
||||
|
@ -720,6 +771,10 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = amdgpu_virt_enable_access_debugfs(adev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* switch to the specific se/sh/cu */
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
amdgpu_gfx_select_se_sh(adev, se, sh, cu);
|
||||
|
@ -734,16 +789,20 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
|
|||
pm_runtime_mark_last_busy(adev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(adev->ddev->dev);
|
||||
|
||||
if (!x)
|
||||
if (!x) {
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
while (size && (offset < x * 4)) {
|
||||
uint32_t value;
|
||||
|
||||
value = data[offset >> 2];
|
||||
r = put_user(value, (uint32_t *)buf);
|
||||
if (r)
|
||||
if (r) {
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return r;
|
||||
}
|
||||
|
||||
result += 4;
|
||||
buf += 4;
|
||||
|
@ -751,6 +810,7 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
|
|||
size -= 4;
|
||||
}
|
||||
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -805,6 +865,10 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = amdgpu_virt_enable_access_debugfs(adev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* switch to the specific se/sh/cu */
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
amdgpu_gfx_select_se_sh(adev, se, sh, cu);
|
||||
|
@ -840,6 +904,7 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
|
|||
|
||||
err:
|
||||
kfree(data);
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
#include "amdgpu_xgmi.h"
|
||||
#include "amdgpu_ras.h"
|
||||
#include "amdgpu_pmu.h"
|
||||
#include "amdgpu_fru_eeprom.h"
|
||||
|
||||
#include <linux/suspend.h>
|
||||
#include <drm/task_barrier.h>
|
||||
|
@ -137,6 +138,72 @@ static DEVICE_ATTR(pcie_replay_count, S_IRUGO,
|
|||
|
||||
static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev);
|
||||
|
||||
/**
|
||||
* DOC: product_name
|
||||
*
|
||||
* The amdgpu driver provides a sysfs API for reporting the product name
|
||||
* for the device
|
||||
* The file serial_number is used for this and returns the product name
|
||||
* as returned from the FRU.
|
||||
* NOTE: This is only available for certain server cards
|
||||
*/
|
||||
|
||||
static ssize_t amdgpu_device_get_product_name(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = ddev->dev_private;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", adev->product_name);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(product_name, S_IRUGO,
|
||||
amdgpu_device_get_product_name, NULL);
|
||||
|
||||
/**
|
||||
* DOC: product_number
|
||||
*
|
||||
* The amdgpu driver provides a sysfs API for reporting the part number
|
||||
* for the device
|
||||
* The file serial_number is used for this and returns the part number
|
||||
* as returned from the FRU.
|
||||
* NOTE: This is only available for certain server cards
|
||||
*/
|
||||
|
||||
static ssize_t amdgpu_device_get_product_number(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = ddev->dev_private;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", adev->product_number);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(product_number, S_IRUGO,
|
||||
amdgpu_device_get_product_number, NULL);
|
||||
|
||||
/**
|
||||
* DOC: serial_number
|
||||
*
|
||||
* The amdgpu driver provides a sysfs API for reporting the serial number
|
||||
* for the device
|
||||
* The file serial_number is used for this and returns the serial number
|
||||
* as returned from the FRU.
|
||||
* NOTE: This is only available for certain server cards
|
||||
*/
|
||||
|
||||
static ssize_t amdgpu_device_get_serial_number(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct drm_device *ddev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = ddev->dev_private;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", adev->serial);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(serial_number, S_IRUGO,
|
||||
amdgpu_device_get_serial_number, NULL);
|
||||
|
||||
/**
|
||||
* amdgpu_device_supports_boco - Is the device a dGPU with HG/PX power control
|
||||
*
|
||||
|
@ -187,32 +254,6 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
|
|||
uint32_t hi = ~0;
|
||||
uint64_t last;
|
||||
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
last = min(pos + size, adev->gmc.visible_vram_size);
|
||||
if (last > pos) {
|
||||
void __iomem *addr = adev->mman.aper_base_kaddr + pos;
|
||||
size_t count = last - pos;
|
||||
|
||||
if (write) {
|
||||
memcpy_toio(addr, buf, count);
|
||||
mb();
|
||||
amdgpu_asic_flush_hdp(adev, NULL);
|
||||
} else {
|
||||
amdgpu_asic_invalidate_hdp(adev, NULL);
|
||||
mb();
|
||||
memcpy_fromio(buf, addr, count);
|
||||
}
|
||||
|
||||
if (count == size)
|
||||
return;
|
||||
|
||||
pos += count;
|
||||
buf += count / 4;
|
||||
size -= count;
|
||||
}
|
||||
#endif
|
||||
|
||||
spin_lock_irqsave(&adev->mmio_idx_lock, flags);
|
||||
for (last = pos + size; pos < last; pos += 4) {
|
||||
uint32_t tmp = pos >> 31;
|
||||
|
@ -231,10 +272,10 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
|
|||
}
|
||||
|
||||
/*
|
||||
* MMIO register access helper functions.
|
||||
* device register access helper functions.
|
||||
*/
|
||||
/**
|
||||
* amdgpu_mm_rreg - read a memory mapped IO register
|
||||
* amdgpu_device_rreg - read a register
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @reg: dword aligned register offset
|
||||
|
@ -242,25 +283,19 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
|
|||
*
|
||||
* Returns the 32 bit value from the offset specified.
|
||||
*/
|
||||
uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
|
||||
uint32_t acc_flags)
|
||||
uint32_t amdgpu_device_rreg(struct amdgpu_device *adev, uint32_t reg,
|
||||
uint32_t acc_flags)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
if ((acc_flags & AMDGPU_REGS_KIQ) || (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)))
|
||||
if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev))
|
||||
return amdgpu_kiq_rreg(adev, reg);
|
||||
|
||||
if ((reg * 4) < adev->rmmio_size && !(acc_flags & AMDGPU_REGS_IDX))
|
||||
if ((reg * 4) < adev->rmmio_size)
|
||||
ret = readl(((void __iomem *)adev->rmmio) + (reg * 4));
|
||||
else {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&adev->mmio_idx_lock, flags);
|
||||
writel((reg * 4), ((void __iomem *)adev->rmmio) + (mmMM_INDEX * 4));
|
||||
ret = readl(((void __iomem *)adev->rmmio) + (mmMM_DATA * 4));
|
||||
spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
|
||||
}
|
||||
trace_amdgpu_mm_rreg(adev->pdev->device, reg, ret);
|
||||
else
|
||||
ret = adev->pcie_rreg(adev, (reg * 4));
|
||||
trace_amdgpu_device_rreg(adev->pdev->device, reg, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -306,28 +341,19 @@ void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value)
|
|||
BUG();
|
||||
}
|
||||
|
||||
void static inline amdgpu_mm_wreg_mmio(struct amdgpu_device *adev, uint32_t reg, uint32_t v, uint32_t acc_flags)
|
||||
void static inline amdgpu_device_wreg_no_kiq(struct amdgpu_device *adev, uint32_t reg,
|
||||
uint32_t v, uint32_t acc_flags)
|
||||
{
|
||||
trace_amdgpu_mm_wreg(adev->pdev->device, reg, v);
|
||||
trace_amdgpu_device_wreg(adev->pdev->device, reg, v);
|
||||
|
||||
if ((reg * 4) < adev->rmmio_size && !(acc_flags & AMDGPU_REGS_IDX))
|
||||
if ((reg * 4) < adev->rmmio_size)
|
||||
writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
|
||||
else {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&adev->mmio_idx_lock, flags);
|
||||
writel((reg * 4), ((void __iomem *)adev->rmmio) + (mmMM_INDEX * 4));
|
||||
writel(v, ((void __iomem *)adev->rmmio) + (mmMM_DATA * 4));
|
||||
spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
|
||||
}
|
||||
|
||||
if (adev->asic_type >= CHIP_VEGA10 && reg == 1 && adev->last_mm_index == 0x5702C) {
|
||||
udelay(500);
|
||||
}
|
||||
else
|
||||
adev->pcie_wreg(adev, (reg * 4), v);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_mm_wreg - write to a memory mapped IO register
|
||||
* amdgpu_device_wreg - write to a register
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @reg: dword aligned register offset
|
||||
|
@ -336,17 +362,13 @@ void static inline amdgpu_mm_wreg_mmio(struct amdgpu_device *adev, uint32_t reg,
|
|||
*
|
||||
* Writes the value specified to the offset specified.
|
||||
*/
|
||||
void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
|
||||
uint32_t acc_flags)
|
||||
void amdgpu_device_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
|
||||
uint32_t acc_flags)
|
||||
{
|
||||
if (adev->asic_type >= CHIP_VEGA10 && reg == 0) {
|
||||
adev->last_mm_index = v;
|
||||
}
|
||||
|
||||
if ((acc_flags & AMDGPU_REGS_KIQ) || (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)))
|
||||
if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev))
|
||||
return amdgpu_kiq_wreg(adev, reg, v);
|
||||
|
||||
amdgpu_mm_wreg_mmio(adev, reg, v, acc_flags);
|
||||
amdgpu_device_wreg_no_kiq(adev, reg, v, acc_flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -365,7 +387,7 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev, uint32_t reg, uint32_t
|
|||
return adev->gfx.rlc.funcs->rlcg_wreg(adev, reg, v);
|
||||
}
|
||||
|
||||
amdgpu_mm_wreg_mmio(adev, reg, v, acc_flags);
|
||||
amdgpu_device_wreg_no_kiq(adev, reg, v, acc_flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -397,20 +419,12 @@ u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg)
|
|||
*/
|
||||
void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
|
||||
{
|
||||
if (adev->asic_type >= CHIP_VEGA10 && reg == 0) {
|
||||
adev->last_mm_index = v;
|
||||
}
|
||||
|
||||
if ((reg * 4) < adev->rio_mem_size)
|
||||
iowrite32(v, adev->rio_mem + (reg * 4));
|
||||
else {
|
||||
iowrite32((reg * 4), adev->rio_mem + (mmMM_INDEX * 4));
|
||||
iowrite32(v, adev->rio_mem + (mmMM_DATA * 4));
|
||||
}
|
||||
|
||||
if (adev->asic_type >= CHIP_VEGA10 && reg == 1 && adev->last_mm_index == 0x5702C) {
|
||||
udelay(500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1147,7 +1161,7 @@ static void amdgpu_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
|
|||
return;
|
||||
|
||||
if (state == VGA_SWITCHEROO_ON) {
|
||||
pr_info("amdgpu: switched on\n");
|
||||
pr_info("switched on\n");
|
||||
/* don't suspend or resume card normally */
|
||||
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
|
||||
|
||||
|
@ -1161,7 +1175,7 @@ static void amdgpu_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
|
|||
dev->switch_power_state = DRM_SWITCH_POWER_ON;
|
||||
drm_kms_helper_poll_enable(dev);
|
||||
} else {
|
||||
pr_info("amdgpu: switched off\n");
|
||||
pr_info("switched off\n");
|
||||
drm_kms_helper_poll_disable(dev);
|
||||
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
|
||||
amdgpu_device_suspend(dev, true);
|
||||
|
@ -1731,9 +1745,28 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
|
|||
amdgpu_amdkfd_device_probe(adev);
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
/* handle vbios stuff prior full access mode for new handshake */
|
||||
if (adev->virt.req_init_data_ver == 1) {
|
||||
if (!amdgpu_get_bios(adev)) {
|
||||
DRM_ERROR("failed to get vbios\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = amdgpu_atombios_init(adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "amdgpu_atombios_init failed\n");
|
||||
amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_ATOMBIOS_INIT_FAIL, 0, 0);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* we need to send REQ_GPU here for legacy handshaker otherwise the vbios
|
||||
* will not be prepared by host for this VF */
|
||||
if (amdgpu_sriov_vf(adev) && adev->virt.req_init_data_ver < 1) {
|
||||
r = amdgpu_virt_request_full_gpu(adev, true);
|
||||
if (r)
|
||||
return -EAGAIN;
|
||||
return r;
|
||||
}
|
||||
|
||||
adev->pm.pp_feature = amdgpu_pp_feature_mask;
|
||||
|
@ -1763,6 +1796,10 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
|
|||
}
|
||||
/* get the vbios after the asic_funcs are set up */
|
||||
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_COMMON) {
|
||||
/* skip vbios handling for new handshake */
|
||||
if (amdgpu_sriov_vf(adev) && adev->virt.req_init_data_ver == 1)
|
||||
continue;
|
||||
|
||||
/* Read BIOS */
|
||||
if (!amdgpu_get_bios(adev))
|
||||
return -EINVAL;
|
||||
|
@ -1889,6 +1926,12 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
if (amdgpu_sriov_vf(adev) && adev->virt.req_init_data_ver > 0) {
|
||||
r = amdgpu_virt_request_full_gpu(adev, true);
|
||||
if (r)
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->num_ip_blocks; i++) {
|
||||
if (!adev->ip_blocks[i].status.valid)
|
||||
continue;
|
||||
|
@ -1975,6 +2018,8 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
|||
amdgpu_xgmi_add_device(adev);
|
||||
amdgpu_amdkfd_device_init(adev);
|
||||
|
||||
amdgpu_fru_get_product_info(adev);
|
||||
|
||||
init_failed:
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
amdgpu_virt_release_full_gpu(adev, true);
|
||||
|
@ -2171,6 +2216,8 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev)
|
|||
adev->ip_blocks[i].status.late_initialized = true;
|
||||
}
|
||||
|
||||
amdgpu_ras_set_error_query_ready(adev, true);
|
||||
|
||||
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_GATE);
|
||||
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_GATE);
|
||||
|
||||
|
@ -2203,7 +2250,8 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev)
|
|||
if (gpu_instance->adev->flags & AMD_IS_APU)
|
||||
continue;
|
||||
|
||||
r = amdgpu_xgmi_set_pstate(gpu_instance->adev, 0);
|
||||
r = amdgpu_xgmi_set_pstate(gpu_instance->adev,
|
||||
AMDGPU_XGMI_PSTATE_MIN);
|
||||
if (r) {
|
||||
DRM_ERROR("pstate setting failed (%d).\n", r);
|
||||
break;
|
||||
|
@ -2785,12 +2833,12 @@ static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev)
|
|||
* By default timeout for non compute jobs is 10000.
|
||||
* And there is no timeout enforced on compute jobs.
|
||||
* In SR-IOV or passthrough mode, timeout for compute
|
||||
* jobs are 10000 by default.
|
||||
* jobs are 60000 by default.
|
||||
*/
|
||||
adev->gfx_timeout = msecs_to_jiffies(10000);
|
||||
adev->sdma_timeout = adev->video_timeout = adev->gfx_timeout;
|
||||
if (amdgpu_sriov_vf(adev) || amdgpu_passthrough(adev))
|
||||
adev->compute_timeout = adev->gfx_timeout;
|
||||
adev->compute_timeout = msecs_to_jiffies(60000);
|
||||
else
|
||||
adev->compute_timeout = MAX_SCHEDULE_TIMEOUT;
|
||||
|
||||
|
@ -2942,9 +2990,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
INIT_LIST_HEAD(&adev->shadow_list);
|
||||
mutex_init(&adev->shadow_list_lock);
|
||||
|
||||
INIT_LIST_HEAD(&adev->ring_lru_list);
|
||||
spin_lock_init(&adev->ring_lru_list_lock);
|
||||
|
||||
INIT_DELAYED_WORK(&adev->delayed_init_work,
|
||||
amdgpu_device_delayed_init_work_handler);
|
||||
INIT_DELAYED_WORK(&adev->gfx.gfx_off_delay_work,
|
||||
|
@ -3002,18 +3047,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
if (amdgpu_mes && adev->asic_type >= CHIP_NAVI10)
|
||||
adev->enable_mes = true;
|
||||
|
||||
if (amdgpu_discovery && adev->asic_type >= CHIP_NAVI10) {
|
||||
r = amdgpu_discovery_init(adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "amdgpu_discovery_init failed\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/* early init functions */
|
||||
r = amdgpu_device_ip_early_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
/* detect hw virtualization here */
|
||||
amdgpu_detect_virtualization(adev);
|
||||
|
||||
r = amdgpu_device_get_job_timeout_settings(adev);
|
||||
if (r) {
|
||||
|
@ -3021,6 +3056,11 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
return r;
|
||||
}
|
||||
|
||||
/* early init functions */
|
||||
r = amdgpu_device_ip_early_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* doorbell bar mapping and doorbell index init*/
|
||||
amdgpu_device_doorbell_init(adev);
|
||||
|
||||
|
@ -3127,14 +3167,13 @@ fence_driver_init:
|
|||
goto failed;
|
||||
}
|
||||
|
||||
DRM_DEBUG("SE %d, SH per SE %d, CU per SH %d, active_cu_number %d\n",
|
||||
dev_info(adev->dev,
|
||||
"SE %d, SH per SE %d, CU per SH %d, active_cu_number %d\n",
|
||||
adev->gfx.config.max_shader_engines,
|
||||
adev->gfx.config.max_sh_per_se,
|
||||
adev->gfx.config.max_cu_per_sh,
|
||||
adev->gfx.cu_info.number);
|
||||
|
||||
amdgpu_ctx_init_sched(adev);
|
||||
|
||||
adev->accel_working = true;
|
||||
|
||||
amdgpu_vm_check_compute_bug(adev);
|
||||
|
@ -3205,6 +3244,24 @@ fence_driver_init:
|
|||
return r;
|
||||
}
|
||||
|
||||
r = device_create_file(adev->dev, &dev_attr_product_name);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "Could not create product_name");
|
||||
return r;
|
||||
}
|
||||
|
||||
r = device_create_file(adev->dev, &dev_attr_product_number);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "Could not create product_number");
|
||||
return r;
|
||||
}
|
||||
|
||||
r = device_create_file(adev->dev, &dev_attr_serial_number);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "Could not create serial_number");
|
||||
return r;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_PERF_EVENTS))
|
||||
r = amdgpu_pmu_init(adev);
|
||||
if (r)
|
||||
|
@ -3287,6 +3344,9 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
|
|||
device_remove_file(adev->dev, &dev_attr_pcie_replay_count);
|
||||
if (adev->ucode_sysfs_en)
|
||||
amdgpu_ucode_sysfs_fini(adev);
|
||||
device_remove_file(adev->dev, &dev_attr_product_name);
|
||||
device_remove_file(adev->dev, &dev_attr_product_number);
|
||||
device_remove_file(adev->dev, &dev_attr_serial_number);
|
||||
if (IS_ENABLED(CONFIG_PERF_EVENTS))
|
||||
amdgpu_pmu_fini(adev);
|
||||
if (amdgpu_discovery && adev->asic_type >= CHIP_NAVI10)
|
||||
|
@ -3757,6 +3817,8 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
amdgpu_amdkfd_pre_reset(adev);
|
||||
|
||||
/* Resume IP prior to SMC */
|
||||
r = amdgpu_device_ip_reinit_early_sriov(adev);
|
||||
if (r)
|
||||
|
@ -4070,7 +4132,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
struct amdgpu_job *job)
|
||||
{
|
||||
struct list_head device_list, *device_list_handle = NULL;
|
||||
bool need_full_reset, job_signaled;
|
||||
bool need_full_reset = false;
|
||||
bool job_signaled = false;
|
||||
struct amdgpu_hive_info *hive = NULL;
|
||||
struct amdgpu_device *tmp_adev = NULL;
|
||||
int i, r = 0;
|
||||
|
@ -4091,16 +4154,9 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
emergency_restart();
|
||||
}
|
||||
|
||||
need_full_reset = job_signaled = false;
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
|
||||
dev_info(adev->dev, "GPU %s begin!\n",
|
||||
(in_ras_intr && !use_baco) ? "jobs stop":"reset");
|
||||
|
||||
cancel_delayed_work_sync(&adev->delayed_init_work);
|
||||
|
||||
hive = amdgpu_get_xgmi_hive(adev, false);
|
||||
|
||||
/*
|
||||
* Here we trylock to avoid chain of resets executing from
|
||||
* either trigger by jobs on different adevs in XGMI hive or jobs on
|
||||
|
@ -4108,39 +4164,25 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
* We always reset all schedulers for device and all devices for XGMI
|
||||
* hive so that should take care of them too.
|
||||
*/
|
||||
|
||||
hive = amdgpu_get_xgmi_hive(adev, true);
|
||||
if (hive && !mutex_trylock(&hive->reset_lock)) {
|
||||
DRM_INFO("Bailing on TDR for s_job:%llx, hive: %llx as another already in progress",
|
||||
job ? job->base.id : -1, hive->hive_id);
|
||||
mutex_unlock(&hive->hive_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Start with adev pre asic reset first for soft reset check.*/
|
||||
if (!amdgpu_device_lock_adev(adev, !hive)) {
|
||||
DRM_INFO("Bailing on TDR for s_job:%llx, as another already in progress",
|
||||
job ? job->base.id : -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Block kfd: SRIOV would do it separately */
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
amdgpu_amdkfd_pre_reset(adev);
|
||||
|
||||
/* Build list of devices to reset */
|
||||
if (adev->gmc.xgmi.num_physical_nodes > 1) {
|
||||
if (!hive) {
|
||||
/*unlock kfd: SRIOV would do it separately */
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
amdgpu_amdkfd_post_reset(adev);
|
||||
amdgpu_device_unlock_adev(adev);
|
||||
/*
|
||||
* Build list of devices to reset.
|
||||
* In case we are in XGMI hive mode, resort the device list
|
||||
* to put adev in the 1st position.
|
||||
*/
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
if (adev->gmc.xgmi.num_physical_nodes > 1) {
|
||||
if (!hive)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* In case we are in XGMI hive mode device reset is done for all the
|
||||
* nodes in the hive to retrain all XGMI links and hence the reset
|
||||
* sequence is executed in loop on all nodes.
|
||||
*/
|
||||
if (!list_is_first(&adev->gmc.xgmi.head, &hive->device_list))
|
||||
list_rotate_to_front(&adev->gmc.xgmi.head, &hive->device_list);
|
||||
device_list_handle = &hive->device_list;
|
||||
} else {
|
||||
list_add_tail(&adev->gmc.xgmi.head, &device_list);
|
||||
|
@ -4149,19 +4191,27 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
|
||||
/* block all schedulers and reset given job's ring */
|
||||
list_for_each_entry(tmp_adev, device_list_handle, gmc.xgmi.head) {
|
||||
if (tmp_adev != adev) {
|
||||
amdgpu_device_lock_adev(tmp_adev, false);
|
||||
if (!amdgpu_sriov_vf(tmp_adev))
|
||||
amdgpu_amdkfd_pre_reset(tmp_adev);
|
||||
if (!amdgpu_device_lock_adev(tmp_adev, !hive)) {
|
||||
DRM_INFO("Bailing on TDR for s_job:%llx, as another already in progress",
|
||||
job ? job->base.id : -1);
|
||||
mutex_unlock(&hive->hive_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
amdgpu_ras_set_error_query_ready(tmp_adev, false);
|
||||
|
||||
cancel_delayed_work_sync(&tmp_adev->delayed_init_work);
|
||||
|
||||
if (!amdgpu_sriov_vf(tmp_adev))
|
||||
amdgpu_amdkfd_pre_reset(tmp_adev);
|
||||
|
||||
/*
|
||||
* Mark these ASICs to be reseted as untracked first
|
||||
* And add them back after reset completed
|
||||
*/
|
||||
amdgpu_unregister_gpu_instance(tmp_adev);
|
||||
|
||||
amdgpu_fbdev_set_suspend(adev, 1);
|
||||
amdgpu_fbdev_set_suspend(tmp_adev, 1);
|
||||
|
||||
/* disable ras on ALL IPs */
|
||||
if (!(in_ras_intr && !use_baco) &&
|
||||
|
@ -4181,7 +4231,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (in_ras_intr && !use_baco)
|
||||
goto skip_sched_resume;
|
||||
|
||||
|
@ -4192,30 +4241,14 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
* job->base holds a reference to parent fence
|
||||
*/
|
||||
if (job && job->base.s_fence->parent &&
|
||||
dma_fence_is_signaled(job->base.s_fence->parent))
|
||||
dma_fence_is_signaled(job->base.s_fence->parent)) {
|
||||
job_signaled = true;
|
||||
|
||||
if (job_signaled) {
|
||||
dev_info(adev->dev, "Guilty job already signaled, skipping HW reset");
|
||||
goto skip_hw_reset;
|
||||
}
|
||||
|
||||
|
||||
/* Guilty job will be freed after this*/
|
||||
r = amdgpu_device_pre_asic_reset(adev, job, &need_full_reset);
|
||||
if (r) {
|
||||
/*TODO Should we stop ?*/
|
||||
DRM_ERROR("GPU pre asic reset failed with err, %d for drm dev, %s ",
|
||||
r, adev->ddev->unique);
|
||||
adev->asic_reset_res = r;
|
||||
}
|
||||
|
||||
retry: /* Rest of adevs pre asic reset from XGMI hive. */
|
||||
list_for_each_entry(tmp_adev, device_list_handle, gmc.xgmi.head) {
|
||||
|
||||
if (tmp_adev == adev)
|
||||
continue;
|
||||
|
||||
r = amdgpu_device_pre_asic_reset(tmp_adev,
|
||||
NULL,
|
||||
&need_full_reset);
|
||||
|
@ -4280,8 +4313,10 @@ skip_sched_resume:
|
|||
amdgpu_device_unlock_adev(tmp_adev);
|
||||
}
|
||||
|
||||
if (hive)
|
||||
if (hive) {
|
||||
mutex_unlock(&hive->reset_lock);
|
||||
mutex_unlock(&hive->hive_lock);
|
||||
}
|
||||
|
||||
if (r)
|
||||
dev_info(adev->dev, "GPU reset end with ret = %d\n", r);
|
||||
|
|
|
@ -23,9 +23,7 @@
|
|||
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_discovery.h"
|
||||
#include "soc15_common.h"
|
||||
#include "soc15_hw_ip.h"
|
||||
#include "nbio/nbio_2_3_offset.h"
|
||||
#include "discovery.h"
|
||||
|
||||
#define mmRCC_CONFIG_MEMSIZE 0xde3
|
||||
|
@ -158,7 +156,7 @@ static inline bool amdgpu_discovery_verify_checksum(uint8_t *data, uint32_t size
|
|||
return !!(amdgpu_discovery_calculate_checksum(data, size) == expected);
|
||||
}
|
||||
|
||||
int amdgpu_discovery_init(struct amdgpu_device *adev)
|
||||
static int amdgpu_discovery_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct table_info *info;
|
||||
struct binary_header *bhdr;
|
||||
|
@ -257,10 +255,12 @@ int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
|
|||
uint8_t num_base_address;
|
||||
int hw_ip;
|
||||
int i, j, k;
|
||||
int r;
|
||||
|
||||
if (!adev->discovery) {
|
||||
DRM_ERROR("ip discovery uninitialized\n");
|
||||
return -EINVAL;
|
||||
r = amdgpu_discovery_init(adev);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu_discovery_init failed\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
bhdr = (struct binary_header *)adev->discovery;
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#define DISCOVERY_TMR_SIZE (64 << 10)
|
||||
|
||||
int amdgpu_discovery_init(struct amdgpu_device *adev);
|
||||
void amdgpu_discovery_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev);
|
||||
int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id,
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright 2019 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_i2c.h"
|
||||
#include "smu_v11_0_i2c.h"
|
||||
#include "atom.h"
|
||||
|
||||
#define I2C_PRODUCT_INFO_ADDR 0xAC
|
||||
#define I2C_PRODUCT_INFO_ADDR_SIZE 0x2
|
||||
#define I2C_PRODUCT_INFO_OFFSET 0xC0
|
||||
|
||||
bool is_fru_eeprom_supported(struct amdgpu_device *adev)
|
||||
{
|
||||
/* TODO: Gaming SKUs don't have the FRU EEPROM.
|
||||
* Use this hack to address hangs on modprobe on gaming SKUs
|
||||
* until a proper solution can be implemented by only supporting
|
||||
* the explicit chip IDs for VG20 Server cards
|
||||
*
|
||||
* TODO: Add list of supported Arcturus DIDs once confirmed
|
||||
*/
|
||||
if ((adev->asic_type == CHIP_VEGA20 && adev->pdev->device == 0x66a0) ||
|
||||
(adev->asic_type == CHIP_VEGA20 && adev->pdev->device == 0x66a1) ||
|
||||
(adev->asic_type == CHIP_VEGA20 && adev->pdev->device == 0x66a4))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
|
||||
unsigned char *buff)
|
||||
{
|
||||
int ret, size;
|
||||
struct i2c_msg msg = {
|
||||
.addr = I2C_PRODUCT_INFO_ADDR,
|
||||
.flags = I2C_M_RD,
|
||||
.buf = buff,
|
||||
};
|
||||
buff[0] = 0;
|
||||
buff[1] = addrptr;
|
||||
msg.len = I2C_PRODUCT_INFO_ADDR_SIZE + 1;
|
||||
ret = i2c_transfer(&adev->pm.smu_i2c, &msg, 1);
|
||||
|
||||
if (ret < 1) {
|
||||
DRM_WARN("FRU: Failed to get size field");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The size returned by the i2c requires subtraction of 0xC0 since the
|
||||
* size apparently always reports as 0xC0+actual size.
|
||||
*/
|
||||
size = buff[2] - I2C_PRODUCT_INFO_OFFSET;
|
||||
/* Add 1 since address field was 1 byte */
|
||||
buff[1] = addrptr + 1;
|
||||
|
||||
msg.len = I2C_PRODUCT_INFO_ADDR_SIZE + size;
|
||||
ret = i2c_transfer(&adev->pm.smu_i2c, &msg, 1);
|
||||
|
||||
if (ret < 1) {
|
||||
DRM_WARN("FRU: Failed to get data field");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
|
||||
{
|
||||
unsigned char buff[34];
|
||||
int addrptr = 0, size = 0;
|
||||
|
||||
if (!is_fru_eeprom_supported(adev))
|
||||
return 0;
|
||||
|
||||
/* If algo exists, it means that the i2c_adapter's initialized */
|
||||
if (!adev->pm.smu_i2c.algo) {
|
||||
DRM_WARN("Cannot access FRU, EEPROM accessor not initialized");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* There's a lot of repetition here. This is due to the FRU having
|
||||
* variable-length fields. To get the information, we have to find the
|
||||
* size of each field, and then keep reading along and reading along
|
||||
* until we get all of the data that we want. We use addrptr to track
|
||||
* the address as we go
|
||||
*/
|
||||
|
||||
/* The first fields are all of size 1-byte, from 0-7 are offsets that
|
||||
* contain information that isn't useful to us.
|
||||
* Bytes 8-a are all 1-byte and refer to the size of the entire struct,
|
||||
* and the language field, so just start from 0xb, manufacturer size
|
||||
*/
|
||||
addrptr = 0xb;
|
||||
size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
|
||||
if (size < 1) {
|
||||
DRM_ERROR("Failed to read FRU Manufacturer, ret:%d", size);
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Increment the addrptr by the size of the field, and 1 due to the
|
||||
* size field being 1 byte. This pattern continues below.
|
||||
*/
|
||||
addrptr += size + 1;
|
||||
size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
|
||||
if (size < 1) {
|
||||
DRM_ERROR("Failed to read FRU product name, ret:%d", size);
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Product name should only be 32 characters. Any more,
|
||||
* and something could be wrong. Cap it at 32 to be safe
|
||||
*/
|
||||
if (size > 32) {
|
||||
DRM_WARN("FRU Product Number is larger than 32 characters. This is likely a mistake");
|
||||
size = 32;
|
||||
}
|
||||
/* Start at 2 due to buff using fields 0 and 1 for the address */
|
||||
memcpy(adev->product_name, &buff[2], size);
|
||||
adev->product_name[size] = '\0';
|
||||
|
||||
addrptr += size + 1;
|
||||
size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
|
||||
if (size < 1) {
|
||||
DRM_ERROR("Failed to read FRU product number, ret:%d", size);
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Product number should only be 16 characters. Any more,
|
||||
* and something could be wrong. Cap it at 16 to be safe
|
||||
*/
|
||||
if (size > 16) {
|
||||
DRM_WARN("FRU Product Number is larger than 16 characters. This is likely a mistake");
|
||||
size = 16;
|
||||
}
|
||||
memcpy(adev->product_number, &buff[2], size);
|
||||
adev->product_number[size] = '\0';
|
||||
|
||||
addrptr += size + 1;
|
||||
size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
|
||||
|
||||
if (size < 1) {
|
||||
DRM_ERROR("Failed to read FRU product version, ret:%d", size);
|
||||
return size;
|
||||
}
|
||||
|
||||
addrptr += size + 1;
|
||||
size = amdgpu_fru_read_eeprom(adev, addrptr, buff);
|
||||
|
||||
if (size < 1) {
|
||||
DRM_ERROR("Failed to read FRU serial number, ret:%d", size);
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Serial number should only be 16 characters. Any more,
|
||||
* and something could be wrong. Cap it at 16 to be safe
|
||||
*/
|
||||
if (size > 16) {
|
||||
DRM_WARN("FRU Serial Number is larger than 16 characters. This is likely a mistake");
|
||||
size = 16;
|
||||
}
|
||||
memcpy(adev->serial, &buff[2], size);
|
||||
adev->serial[size] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2020 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __AMDGPU_PRODINFO_H__
|
||||
#define __AMDGPU_PRODINFO_H__
|
||||
|
||||
int amdgpu_fru_get_product_info(struct amdgpu_device *adev);
|
||||
|
||||
#endif // __AMDGPU_PRODINFO_H__
|
|
@ -162,16 +162,17 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
|
|||
|
||||
struct amdgpu_bo_list_entry vm_pd;
|
||||
struct list_head list, duplicates;
|
||||
struct dma_fence *fence = NULL;
|
||||
struct ttm_validate_buffer tv;
|
||||
struct ww_acquire_ctx ticket;
|
||||
struct amdgpu_bo_va *bo_va;
|
||||
int r;
|
||||
long r;
|
||||
|
||||
INIT_LIST_HEAD(&list);
|
||||
INIT_LIST_HEAD(&duplicates);
|
||||
|
||||
tv.bo = &bo->tbo;
|
||||
tv.num_shared = 1;
|
||||
tv.num_shared = 2;
|
||||
list_add(&tv.head, &list);
|
||||
|
||||
amdgpu_vm_get_pd_bo(vm, &list, &vm_pd);
|
||||
|
@ -179,28 +180,34 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
|
|||
r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "leaking bo va because "
|
||||
"we fail to reserve bo (%d)\n", r);
|
||||
"we fail to reserve bo (%ld)\n", r);
|
||||
return;
|
||||
}
|
||||
bo_va = amdgpu_vm_bo_find(vm, bo);
|
||||
if (bo_va && --bo_va->ref_count == 0) {
|
||||
amdgpu_vm_bo_rmv(adev, bo_va);
|
||||
if (!bo_va || --bo_va->ref_count)
|
||||
goto out_unlock;
|
||||
|
||||
if (amdgpu_vm_ready(vm)) {
|
||||
struct dma_fence *fence = NULL;
|
||||
amdgpu_vm_bo_rmv(adev, bo_va);
|
||||
if (!amdgpu_vm_ready(vm))
|
||||
goto out_unlock;
|
||||
|
||||
r = amdgpu_vm_clear_freed(adev, vm, &fence);
|
||||
if (unlikely(r)) {
|
||||
dev_err(adev->dev, "failed to clear page "
|
||||
"tables on GEM object close (%d)\n", r);
|
||||
}
|
||||
|
||||
if (fence) {
|
||||
amdgpu_bo_fence(bo, fence, true);
|
||||
dma_fence_put(fence);
|
||||
}
|
||||
}
|
||||
fence = dma_resv_get_excl(bo->tbo.base.resv);
|
||||
if (fence) {
|
||||
amdgpu_bo_fence(bo, fence, true);
|
||||
fence = NULL;
|
||||
}
|
||||
|
||||
r = amdgpu_vm_clear_freed(adev, vm, &fence);
|
||||
if (r || !fence)
|
||||
goto out_unlock;
|
||||
|
||||
amdgpu_bo_fence(bo, fence, true);
|
||||
dma_fence_put(fence);
|
||||
|
||||
out_unlock:
|
||||
if (unlikely(r < 0))
|
||||
dev_err(adev->dev, "failed to clear page "
|
||||
"tables on GEM object close (%ld)\n", r);
|
||||
ttm_eu_backoff_reservation(&ticket, &list);
|
||||
}
|
||||
|
||||
|
|
|
@ -304,10 +304,6 @@ int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev,
|
|||
|
||||
spin_lock_init(&kiq->ring_lock);
|
||||
|
||||
r = amdgpu_device_wb_get(adev, &kiq->reg_val_offs);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ring->adev = NULL;
|
||||
ring->ring_obj = NULL;
|
||||
ring->use_doorbell = true;
|
||||
|
@ -318,9 +314,11 @@ int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev,
|
|||
return r;
|
||||
|
||||
ring->eop_gpu_addr = kiq->eop_gpu_addr;
|
||||
ring->no_scheduler = true;
|
||||
sprintf(ring->name, "kiq_%d.%d.%d", ring->me, ring->pipe, ring->queue);
|
||||
r = amdgpu_ring_init(adev, ring, 1024,
|
||||
irq, AMDGPU_CP_KIQ_IRQ_DRIVER0);
|
||||
irq, AMDGPU_CP_KIQ_IRQ_DRIVER0,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
dev_warn(adev->dev, "(%d) failed to init kiq ring\n", r);
|
||||
|
||||
|
@ -329,7 +327,6 @@ int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev,
|
|||
|
||||
void amdgpu_gfx_kiq_free_ring(struct amdgpu_ring *ring)
|
||||
{
|
||||
amdgpu_device_wb_free(ring->adev, ring->adev->gfx.kiq.reg_val_offs);
|
||||
amdgpu_ring_fini(ring);
|
||||
}
|
||||
|
||||
|
@ -670,15 +667,20 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg)
|
|||
{
|
||||
signed long r, cnt = 0;
|
||||
unsigned long flags;
|
||||
uint32_t seq;
|
||||
uint32_t seq, reg_val_offs = 0, value = 0;
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq;
|
||||
struct amdgpu_ring *ring = &kiq->ring;
|
||||
|
||||
BUG_ON(!ring->funcs->emit_rreg);
|
||||
|
||||
spin_lock_irqsave(&kiq->ring_lock, flags);
|
||||
if (amdgpu_device_wb_get(adev, ®_val_offs)) {
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
pr_err("critical bug! too many kiq readers\n");
|
||||
goto failed_kiq_read;
|
||||
}
|
||||
amdgpu_ring_alloc(ring, 32);
|
||||
amdgpu_ring_emit_rreg(ring, reg);
|
||||
amdgpu_ring_emit_rreg(ring, reg, reg_val_offs);
|
||||
amdgpu_fence_emit_polling(ring, &seq);
|
||||
amdgpu_ring_commit(ring);
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
|
@ -705,7 +707,10 @@ uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg)
|
|||
if (cnt > MAX_KIQ_REG_TRY)
|
||||
goto failed_kiq_read;
|
||||
|
||||
return adev->wb.wb[kiq->reg_val_offs];
|
||||
mb();
|
||||
value = adev->wb.wb[reg_val_offs];
|
||||
amdgpu_device_wb_free(adev, reg_val_offs);
|
||||
return value;
|
||||
|
||||
failed_kiq_read:
|
||||
pr_err("failed to read reg:%x\n", reg);
|
||||
|
|
|
@ -103,7 +103,6 @@ struct amdgpu_kiq {
|
|||
struct amdgpu_ring ring;
|
||||
struct amdgpu_irq_src irq;
|
||||
const struct kiq_pm4_funcs *pmf;
|
||||
uint32_t reg_val_offs;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -286,13 +285,8 @@ struct amdgpu_gfx {
|
|||
bool me_fw_write_wait;
|
||||
bool cp_fw_write_wait;
|
||||
struct amdgpu_ring gfx_ring[AMDGPU_MAX_GFX_RINGS];
|
||||
struct drm_gpu_scheduler *gfx_sched[AMDGPU_MAX_GFX_RINGS];
|
||||
uint32_t num_gfx_sched;
|
||||
unsigned num_gfx_rings;
|
||||
struct amdgpu_ring compute_ring[AMDGPU_MAX_COMPUTE_RINGS];
|
||||
struct drm_gpu_scheduler **compute_prio_sched[AMDGPU_GFX_PIPE_PRIO_MAX];
|
||||
struct drm_gpu_scheduler *compute_sched[AMDGPU_MAX_COMPUTE_RINGS];
|
||||
uint32_t num_compute_sched[AMDGPU_GFX_PIPE_PRIO_MAX];
|
||||
unsigned num_compute_rings;
|
||||
struct amdgpu_irq_src eop_irq;
|
||||
struct amdgpu_irq_src priv_reg_irq;
|
||||
|
|
|
@ -136,8 +136,8 @@ uint64_t amdgpu_gmc_agp_addr(struct ttm_buffer_object *bo)
|
|||
/**
|
||||
* amdgpu_gmc_vram_location - try to find VRAM location
|
||||
*
|
||||
* @adev: amdgpu device structure holding all necessary informations
|
||||
* @mc: memory controller structure holding memory informations
|
||||
* @adev: amdgpu device structure holding all necessary information
|
||||
* @mc: memory controller structure holding memory information
|
||||
* @base: base address at which to put VRAM
|
||||
*
|
||||
* Function will try to place VRAM at base address provided
|
||||
|
@ -165,8 +165,8 @@ void amdgpu_gmc_vram_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc,
|
|||
/**
|
||||
* amdgpu_gmc_gart_location - try to find GART location
|
||||
*
|
||||
* @adev: amdgpu device structure holding all necessary informations
|
||||
* @mc: memory controller structure holding memory informations
|
||||
* @adev: amdgpu device structure holding all necessary information
|
||||
* @mc: memory controller structure holding memory information
|
||||
*
|
||||
* Function will place try to place GART before or after VRAM.
|
||||
*
|
||||
|
@ -207,8 +207,8 @@ void amdgpu_gmc_gart_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc)
|
|||
|
||||
/**
|
||||
* amdgpu_gmc_agp_location - try to find AGP location
|
||||
* @adev: amdgpu device structure holding all necessary informations
|
||||
* @mc: memory controller structure holding memory informations
|
||||
* @adev: amdgpu device structure holding all necessary information
|
||||
* @mc: memory controller structure holding memory information
|
||||
*
|
||||
* Function will place try to find a place for the AGP BAR in the MC address
|
||||
* space.
|
||||
|
|
|
@ -61,12 +61,14 @@
|
|||
* Returns 0 on success, error on failure.
|
||||
*/
|
||||
int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
unsigned size, struct amdgpu_ib *ib)
|
||||
unsigned size,
|
||||
enum amdgpu_ib_pool_type pool_type,
|
||||
struct amdgpu_ib *ib)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (size) {
|
||||
r = amdgpu_sa_bo_new(&adev->ring_tmp_bo,
|
||||
r = amdgpu_sa_bo_new(&adev->ring_tmp_bo[pool_type],
|
||||
&ib->sa_bo, size, 256);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "failed to get a new IB (%d)\n", r);
|
||||
|
@ -280,19 +282,27 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
|||
*/
|
||||
int amdgpu_ib_pool_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int r;
|
||||
int r, i;
|
||||
unsigned size;
|
||||
|
||||
if (adev->ib_pool_ready) {
|
||||
return 0;
|
||||
}
|
||||
r = amdgpu_sa_bo_manager_init(adev, &adev->ring_tmp_bo,
|
||||
AMDGPU_IB_POOL_SIZE*64*1024,
|
||||
AMDGPU_GPU_PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_GTT);
|
||||
if (r) {
|
||||
return r;
|
||||
for (i = 0; i < AMDGPU_IB_POOL_MAX; i++) {
|
||||
if (i == AMDGPU_IB_POOL_DIRECT)
|
||||
size = PAGE_SIZE * 2;
|
||||
else
|
||||
size = AMDGPU_IB_POOL_SIZE*64*1024;
|
||||
r = amdgpu_sa_bo_manager_init(adev, &adev->ring_tmp_bo[i],
|
||||
size,
|
||||
AMDGPU_GPU_PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_GTT);
|
||||
if (r) {
|
||||
for (i--; i >= 0; i--)
|
||||
amdgpu_sa_bo_manager_fini(adev, &adev->ring_tmp_bo[i]);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
adev->ib_pool_ready = true;
|
||||
|
||||
return 0;
|
||||
|
@ -308,8 +318,11 @@ int amdgpu_ib_pool_init(struct amdgpu_device *adev)
|
|||
*/
|
||||
void amdgpu_ib_pool_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (adev->ib_pool_ready) {
|
||||
amdgpu_sa_bo_manager_fini(adev, &adev->ring_tmp_bo);
|
||||
for (i = 0; i < AMDGPU_IB_POOL_MAX; i++)
|
||||
amdgpu_sa_bo_manager_fini(adev, &adev->ring_tmp_bo[i]);
|
||||
adev->ib_pool_ready = false;
|
||||
}
|
||||
}
|
||||
|
@ -406,7 +419,12 @@ static int amdgpu_debugfs_sa_info(struct seq_file *m, void *data)
|
|||
struct drm_device *dev = node->minor->dev;
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
|
||||
amdgpu_sa_bo_dump_debug_info(&adev->ring_tmp_bo, m);
|
||||
seq_printf(m, "-------------------- NORMAL -------------------- \n");
|
||||
amdgpu_sa_bo_dump_debug_info(&adev->ring_tmp_bo[AMDGPU_IB_POOL_NORMAL], m);
|
||||
seq_printf(m, "---------------------- VM ---------------------- \n");
|
||||
amdgpu_sa_bo_dump_debug_info(&adev->ring_tmp_bo[AMDGPU_IB_POOL_VM], m);
|
||||
seq_printf(m, "-------------------- DIRECT--------------------- \n");
|
||||
amdgpu_sa_bo_dump_debug_info(&adev->ring_tmp_bo[AMDGPU_IB_POOL_DIRECT], m);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -260,7 +260,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
|
|||
nvec = pci_alloc_irq_vectors(adev->pdev, 1, 1, flags);
|
||||
if (nvec > 0) {
|
||||
adev->irq.msi_enabled = true;
|
||||
dev_dbg(adev->dev, "amdgpu: using MSI/MSI-X.\n");
|
||||
dev_dbg(adev->dev, "using MSI/MSI-X.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ static void amdgpu_job_timedout(struct drm_sched_job *s_job)
|
|||
struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched);
|
||||
struct amdgpu_job *job = to_amdgpu_job(s_job);
|
||||
struct amdgpu_task_info ti;
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
|
||||
memset(&ti, 0, sizeof(struct amdgpu_task_info));
|
||||
|
||||
|
@ -49,10 +50,13 @@ static void amdgpu_job_timedout(struct drm_sched_job *s_job)
|
|||
DRM_ERROR("Process information: process %s pid %d thread %s pid %d\n",
|
||||
ti.process_name, ti.tgid, ti.task_name, ti.pid);
|
||||
|
||||
if (amdgpu_device_should_recover_gpu(ring->adev))
|
||||
if (amdgpu_device_should_recover_gpu(ring->adev)) {
|
||||
amdgpu_device_gpu_recover(ring->adev, job);
|
||||
else
|
||||
} else {
|
||||
drm_sched_suspend_timeout(&ring->sched);
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
adev->virt.tdr_debug = true;
|
||||
}
|
||||
}
|
||||
|
||||
int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
|
||||
|
@ -87,7 +91,8 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
|
|||
}
|
||||
|
||||
int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
|
||||
struct amdgpu_job **job)
|
||||
enum amdgpu_ib_pool_type pool_type,
|
||||
struct amdgpu_job **job)
|
||||
{
|
||||
int r;
|
||||
|
||||
|
@ -95,7 +100,7 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_ib_get(adev, NULL, size, &(*job)->ibs[0]);
|
||||
r = amdgpu_ib_get(adev, NULL, size, pool_type, &(*job)->ibs[0]);
|
||||
if (r)
|
||||
kfree(*job);
|
||||
|
||||
|
@ -140,7 +145,6 @@ void amdgpu_job_free(struct amdgpu_job *job)
|
|||
int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
|
||||
void *owner, struct dma_fence **f)
|
||||
{
|
||||
enum drm_sched_priority priority;
|
||||
int r;
|
||||
|
||||
if (!f)
|
||||
|
@ -152,7 +156,6 @@ int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
|
|||
|
||||
*f = dma_fence_get(&job->base.s_fence->finished);
|
||||
amdgpu_job_free_resources(job);
|
||||
priority = job->base.s_priority;
|
||||
drm_sched_entity_push_job(&job->base, entity);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#define AMDGPU_JOB_GET_VMID(job) ((job) ? (job)->vmid : 0)
|
||||
|
||||
struct amdgpu_fence;
|
||||
enum amdgpu_ib_pool_type;
|
||||
|
||||
struct amdgpu_job {
|
||||
struct drm_sched_job base;
|
||||
|
@ -67,8 +68,7 @@ struct amdgpu_job {
|
|||
int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
|
||||
struct amdgpu_job **job, struct amdgpu_vm *vm);
|
||||
int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
|
||||
struct amdgpu_job **job);
|
||||
|
||||
enum amdgpu_ib_pool_type pool, struct amdgpu_job **job);
|
||||
void amdgpu_job_free_resources(struct amdgpu_job *job);
|
||||
void amdgpu_job_free(struct amdgpu_job *job);
|
||||
int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
|
||||
|
|
|
@ -144,7 +144,8 @@ static int amdgpu_jpeg_dec_set_reg(struct amdgpu_ring *ring, uint32_t handle,
|
|||
const unsigned ib_size_dw = 16;
|
||||
int i, r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
|
||||
AMDGPU_IB_POOL_DIRECT, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -43,8 +43,6 @@ struct amdgpu_jpeg {
|
|||
uint8_t num_jpeg_inst;
|
||||
struct amdgpu_jpeg_inst inst[AMDGPU_MAX_JPEG_INSTANCES];
|
||||
struct amdgpu_jpeg_reg internal;
|
||||
struct drm_gpu_scheduler *jpeg_sched[AMDGPU_MAX_JPEG_INSTANCES];
|
||||
uint32_t num_jpeg_sched;
|
||||
unsigned harvest_config;
|
||||
struct delayed_work idle_work;
|
||||
enum amd_powergating_state cur_state;
|
||||
|
|
|
@ -183,12 +183,10 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)
|
|||
/* Call ACPI methods: require modeset init
|
||||
* but failure is not fatal
|
||||
*/
|
||||
if (!r) {
|
||||
acpi_status = amdgpu_acpi_init(adev);
|
||||
if (acpi_status)
|
||||
dev_dbg(&dev->pdev->dev,
|
||||
"Error during ACPI methods call\n");
|
||||
}
|
||||
|
||||
acpi_status = amdgpu_acpi_init(adev);
|
||||
if (acpi_status)
|
||||
dev_dbg(&dev->pdev->dev, "Error during ACPI methods call\n");
|
||||
|
||||
if (adev->runpm) {
|
||||
dev_pm_set_driver_flags(dev->dev, DPM_FLAG_NEVER_SKIP);
|
||||
|
|
|
@ -77,7 +77,6 @@ struct amdgpu_nbio_funcs {
|
|||
u32 *flags);
|
||||
void (*ih_control)(struct amdgpu_device *adev);
|
||||
void (*init_registers)(struct amdgpu_device *adev);
|
||||
void (*detect_hw_virt)(struct amdgpu_device *adev);
|
||||
void (*remap_hdp_registers)(struct amdgpu_device *adev);
|
||||
void (*handle_ras_controller_intr_no_bifring)(struct amdgpu_device *adev);
|
||||
void (*handle_ras_err_event_athub_intr_no_bifring)(struct amdgpu_device *adev);
|
||||
|
|
|
@ -444,8 +444,11 @@ static ssize_t amdgpu_get_pp_num_states(struct device *dev,
|
|||
ret = smu_get_power_num_states(&adev->smu, &data);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else if (adev->powerplay.pp_funcs->get_pp_num_states)
|
||||
} else if (adev->powerplay.pp_funcs->get_pp_num_states) {
|
||||
amdgpu_dpm_get_pp_num_states(adev, &data);
|
||||
} else {
|
||||
memset(&data, 0, sizeof(data));
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(ddev->dev);
|
||||
pm_runtime_put_autosuspend(ddev->dev);
|
||||
|
|
|
@ -37,11 +37,11 @@
|
|||
|
||||
#include "amdgpu_ras.h"
|
||||
|
||||
static void psp_set_funcs(struct amdgpu_device *adev);
|
||||
|
||||
static int psp_sysfs_init(struct amdgpu_device *adev);
|
||||
static void psp_sysfs_fini(struct amdgpu_device *adev);
|
||||
|
||||
static int psp_load_smu_fw(struct psp_context *psp);
|
||||
|
||||
/*
|
||||
* Due to DF Cstate management centralized to PMFW, the firmware
|
||||
* loading sequence will be updated as below:
|
||||
|
@ -80,8 +80,6 @@ static int psp_early_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
|
||||
psp_set_funcs(adev);
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA12:
|
||||
|
@ -201,6 +199,7 @@ psp_cmd_submit_buf(struct psp_context *psp,
|
|||
int index;
|
||||
int timeout = 2000;
|
||||
bool ras_intr = false;
|
||||
bool skip_unsupport = false;
|
||||
|
||||
mutex_lock(&psp->mutex);
|
||||
|
||||
|
@ -232,6 +231,9 @@ psp_cmd_submit_buf(struct psp_context *psp,
|
|||
amdgpu_asic_invalidate_hdp(psp->adev, NULL);
|
||||
}
|
||||
|
||||
/* We allow TEE_ERROR_NOT_SUPPORTED for VMR command in SRIOV */
|
||||
skip_unsupport = (psp->cmd_buf_mem->resp.status == 0xffff000a) && amdgpu_sriov_vf(psp->adev);
|
||||
|
||||
/* In some cases, psp response status is not 0 even there is no
|
||||
* problem while the command is submitted. Some version of PSP FW
|
||||
* doesn't write 0 to that field.
|
||||
|
@ -239,7 +241,7 @@ psp_cmd_submit_buf(struct psp_context *psp,
|
|||
* during psp initialization to avoid breaking hw_init and it doesn't
|
||||
* return -EINVAL.
|
||||
*/
|
||||
if ((psp->cmd_buf_mem->resp.status || !timeout) && !ras_intr) {
|
||||
if (!skip_unsupport && (psp->cmd_buf_mem->resp.status || !timeout) && !ras_intr) {
|
||||
if (ucode)
|
||||
DRM_WARN("failed to load ucode id (%d) ",
|
||||
ucode->ucode_id);
|
||||
|
@ -268,7 +270,7 @@ static void psp_prep_tmr_cmd_buf(struct psp_context *psp,
|
|||
struct psp_gfx_cmd_resp *cmd,
|
||||
uint64_t tmr_mc, uint32_t size)
|
||||
{
|
||||
if (psp_support_vmr_ring(psp))
|
||||
if (amdgpu_sriov_vf(psp->adev))
|
||||
cmd->cmd_id = GFX_CMD_ID_SETUP_VMR;
|
||||
else
|
||||
cmd->cmd_id = GFX_CMD_ID_SETUP_TMR;
|
||||
|
@ -884,6 +886,7 @@ static int psp_hdcp_load(struct psp_context *psp)
|
|||
if (!ret) {
|
||||
psp->hdcp_context.hdcp_initialized = true;
|
||||
psp->hdcp_context.session_id = cmd->resp.session_id;
|
||||
mutex_init(&psp->hdcp_context.mutex);
|
||||
}
|
||||
|
||||
kfree(cmd);
|
||||
|
@ -1029,6 +1032,7 @@ static int psp_dtm_load(struct psp_context *psp)
|
|||
if (!ret) {
|
||||
psp->dtm_context.dtm_initialized = true;
|
||||
psp->dtm_context.session_id = cmd->resp.session_id;
|
||||
mutex_init(&psp->dtm_context.mutex);
|
||||
}
|
||||
|
||||
kfree(cmd);
|
||||
|
@ -1169,16 +1173,20 @@ static int psp_hw_start(struct psp_context *psp)
|
|||
}
|
||||
|
||||
/*
|
||||
* For those ASICs with DF Cstate management centralized
|
||||
* For ASICs with DF Cstate management centralized
|
||||
* to PMFW, TMR setup should be performed after PMFW
|
||||
* loaded and before other non-psp firmware loaded.
|
||||
*/
|
||||
if (!psp->pmfw_centralized_cstate_management) {
|
||||
ret = psp_tmr_load(psp);
|
||||
if (ret) {
|
||||
DRM_ERROR("PSP load tmr failed!\n");
|
||||
if (psp->pmfw_centralized_cstate_management) {
|
||||
ret = psp_load_smu_fw(psp);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = psp_tmr_load(psp);
|
||||
if (ret) {
|
||||
DRM_ERROR("PSP load tmr failed!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1355,7 +1363,7 @@ static int psp_prep_load_ip_fw_cmd_buf(struct amdgpu_firmware_info *ucode,
|
|||
}
|
||||
|
||||
static int psp_execute_np_fw_load(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *ucode)
|
||||
struct amdgpu_firmware_info *ucode)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -1369,64 +1377,95 @@ static int psp_execute_np_fw_load(struct psp_context *psp,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int psp_load_smu_fw(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
struct amdgpu_device* adev = psp->adev;
|
||||
struct amdgpu_firmware_info *ucode =
|
||||
&adev->firmware.ucode[AMDGPU_UCODE_ID_SMC];
|
||||
|
||||
if (!ucode->fw || amdgpu_sriov_vf(psp->adev))
|
||||
return 0;
|
||||
|
||||
|
||||
if (adev->in_gpu_reset) {
|
||||
ret = amdgpu_dpm_set_mp1_state(adev, PP_MP1_STATE_UNLOAD);
|
||||
if (ret) {
|
||||
DRM_WARN("Failed to set MP1 state prepare for reload\n");
|
||||
}
|
||||
}
|
||||
|
||||
ret = psp_execute_np_fw_load(psp, ucode);
|
||||
|
||||
if (ret)
|
||||
DRM_ERROR("PSP load smu failed!\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool fw_load_skip_check(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *ucode)
|
||||
{
|
||||
if (!ucode->fw)
|
||||
return true;
|
||||
|
||||
if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC &&
|
||||
(psp_smu_reload_quirk(psp) ||
|
||||
psp->autoload_supported ||
|
||||
psp->pmfw_centralized_cstate_management))
|
||||
return true;
|
||||
|
||||
if (amdgpu_sriov_vf(psp->adev) &&
|
||||
(ucode->ucode_id == AMDGPU_UCODE_ID_SDMA0
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA4
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA5
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA6
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA7
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_G
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SMC))
|
||||
/*skip ucode loading in SRIOV VF */
|
||||
return true;
|
||||
|
||||
if (psp->autoload_supported &&
|
||||
(ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC1_JT ||
|
||||
ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC2_JT))
|
||||
/* skip mec JT when autoload is enabled */
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int psp_np_fw_load(struct psp_context *psp)
|
||||
{
|
||||
int i, ret;
|
||||
struct amdgpu_firmware_info *ucode;
|
||||
struct amdgpu_device* adev = psp->adev;
|
||||
|
||||
if (psp->autoload_supported ||
|
||||
psp->pmfw_centralized_cstate_management) {
|
||||
ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC];
|
||||
if (!ucode->fw || amdgpu_sriov_vf(adev))
|
||||
goto out;
|
||||
|
||||
ret = psp_execute_np_fw_load(psp, ucode);
|
||||
if (psp->autoload_supported &&
|
||||
!psp->pmfw_centralized_cstate_management) {
|
||||
ret = psp_load_smu_fw(psp);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (psp->pmfw_centralized_cstate_management) {
|
||||
ret = psp_tmr_load(psp);
|
||||
if (ret) {
|
||||
DRM_ERROR("PSP load tmr failed!\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
for (i = 0; i < adev->firmware.max_ucodes; i++) {
|
||||
ucode = &adev->firmware.ucode[i];
|
||||
if (!ucode->fw)
|
||||
continue;
|
||||
|
||||
if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC &&
|
||||
(psp_smu_reload_quirk(psp) ||
|
||||
psp->autoload_supported ||
|
||||
psp->pmfw_centralized_cstate_management))
|
||||
!fw_load_skip_check(psp, ucode)) {
|
||||
ret = psp_load_smu_fw(psp);
|
||||
if (ret)
|
||||
return ret;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (amdgpu_sriov_vf(adev) &&
|
||||
(ucode->ucode_id == AMDGPU_UCODE_ID_SDMA0
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA4
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA5
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA6
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA7
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_G
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM
|
||||
|| ucode->ucode_id == AMDGPU_UCODE_ID_SMC))
|
||||
/*skip ucode loading in SRIOV VF */
|
||||
continue;
|
||||
|
||||
if (psp->autoload_supported &&
|
||||
(ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC1_JT ||
|
||||
ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC2_JT))
|
||||
/* skip mec JT when autoload is enabled */
|
||||
if (fw_load_skip_check(psp, ucode))
|
||||
continue;
|
||||
|
||||
psp_print_fw_hdr(psp, ucode);
|
||||
|
@ -1444,11 +1483,6 @@ out:
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
/* check if firmware loaded sucessfully */
|
||||
if (!amdgpu_psp_check_fw_loading_status(adev, i))
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1806,19 +1840,110 @@ int psp_ring_cmd_submit(struct psp_context *psp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool psp_check_fw_loading_status(struct amdgpu_device *adev,
|
||||
enum AMDGPU_UCODE_ID ucode_type)
|
||||
int psp_init_asd_microcode(struct psp_context *psp,
|
||||
const char *chip_name)
|
||||
{
|
||||
struct amdgpu_firmware_info *ucode = NULL;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
char fw_name[30];
|
||||
const struct psp_firmware_header_v1_0 *asd_hdr;
|
||||
int err = 0;
|
||||
|
||||
if (!adev->firmware.fw_size)
|
||||
return false;
|
||||
if (!chip_name) {
|
||||
dev_err(adev->dev, "invalid chip name for asd microcode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ucode = &adev->firmware.ucode[ucode_type];
|
||||
if (!ucode->fw || !ucode->ucode_size)
|
||||
return false;
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_asd.bin", chip_name);
|
||||
err = request_firmware(&adev->psp.asd_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
return psp_compare_sram_data(&adev->psp, ucode, ucode_type);
|
||||
err = amdgpu_ucode_validate(adev->psp.asd_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
asd_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.asd_fw->data;
|
||||
adev->psp.asd_fw_version = le32_to_cpu(asd_hdr->header.ucode_version);
|
||||
adev->psp.asd_feature_version = le32_to_cpu(asd_hdr->ucode_feature_version);
|
||||
adev->psp.asd_ucode_size = le32_to_cpu(asd_hdr->header.ucode_size_bytes);
|
||||
adev->psp.asd_start_addr = (uint8_t *)asd_hdr +
|
||||
le32_to_cpu(asd_hdr->header.ucode_array_offset_bytes);
|
||||
return 0;
|
||||
out:
|
||||
dev_err(adev->dev, "fail to initialize asd microcode\n");
|
||||
release_firmware(adev->psp.asd_fw);
|
||||
adev->psp.asd_fw = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
int psp_init_sos_microcode(struct psp_context *psp,
|
||||
const char *chip_name)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
char fw_name[30];
|
||||
const struct psp_firmware_header_v1_0 *sos_hdr;
|
||||
const struct psp_firmware_header_v1_1 *sos_hdr_v1_1;
|
||||
const struct psp_firmware_header_v1_2 *sos_hdr_v1_2;
|
||||
int err = 0;
|
||||
|
||||
if (!chip_name) {
|
||||
dev_err(adev->dev, "invalid chip name for sos microcode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sos.bin", chip_name);
|
||||
err = request_firmware(&adev->psp.sos_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = amdgpu_ucode_validate(adev->psp.sos_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
sos_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.sos_fw->data;
|
||||
amdgpu_ucode_print_psp_hdr(&sos_hdr->header);
|
||||
|
||||
switch (sos_hdr->header.header_version_major) {
|
||||
case 1:
|
||||
adev->psp.sos_fw_version = le32_to_cpu(sos_hdr->header.ucode_version);
|
||||
adev->psp.sos_feature_version = le32_to_cpu(sos_hdr->ucode_feature_version);
|
||||
adev->psp.sos_bin_size = le32_to_cpu(sos_hdr->sos_size_bytes);
|
||||
adev->psp.sys_bin_size = le32_to_cpu(sos_hdr->sos_offset_bytes);
|
||||
adev->psp.sys_start_addr = (uint8_t *)sos_hdr +
|
||||
le32_to_cpu(sos_hdr->header.ucode_array_offset_bytes);
|
||||
adev->psp.sos_start_addr = (uint8_t *)adev->psp.sys_start_addr +
|
||||
le32_to_cpu(sos_hdr->sos_offset_bytes);
|
||||
if (sos_hdr->header.header_version_minor == 1) {
|
||||
sos_hdr_v1_1 = (const struct psp_firmware_header_v1_1 *)adev->psp.sos_fw->data;
|
||||
adev->psp.toc_bin_size = le32_to_cpu(sos_hdr_v1_1->toc_size_bytes);
|
||||
adev->psp.toc_start_addr = (uint8_t *)adev->psp.sys_start_addr +
|
||||
le32_to_cpu(sos_hdr_v1_1->toc_offset_bytes);
|
||||
adev->psp.kdb_bin_size = le32_to_cpu(sos_hdr_v1_1->kdb_size_bytes);
|
||||
adev->psp.kdb_start_addr = (uint8_t *)adev->psp.sys_start_addr +
|
||||
le32_to_cpu(sos_hdr_v1_1->kdb_offset_bytes);
|
||||
}
|
||||
if (sos_hdr->header.header_version_minor == 2) {
|
||||
sos_hdr_v1_2 = (const struct psp_firmware_header_v1_2 *)adev->psp.sos_fw->data;
|
||||
adev->psp.kdb_bin_size = le32_to_cpu(sos_hdr_v1_2->kdb_size_bytes);
|
||||
adev->psp.kdb_start_addr = (uint8_t *)adev->psp.sys_start_addr +
|
||||
le32_to_cpu(sos_hdr_v1_2->kdb_offset_bytes);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"unsupported psp sos firmware\n");
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
dev_err(adev->dev,
|
||||
"failed to init sos firmware\n");
|
||||
release_firmware(adev->psp.sos_fw);
|
||||
adev->psp.sos_fw = NULL;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int psp_set_clockgating_state(void *handle,
|
||||
|
@ -1957,16 +2082,6 @@ static void psp_sysfs_fini(struct amdgpu_device *adev)
|
|||
device_remove_file(adev->dev, &dev_attr_usbc_pd_fw);
|
||||
}
|
||||
|
||||
static const struct amdgpu_psp_funcs psp_funcs = {
|
||||
.check_fw_loading_status = psp_check_fw_loading_status,
|
||||
};
|
||||
|
||||
static void psp_set_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (NULL == adev->firmware.funcs)
|
||||
adev->firmware.funcs = &psp_funcs;
|
||||
}
|
||||
|
||||
const struct amdgpu_ip_block_version psp_v3_1_ip_block =
|
||||
{
|
||||
.type = AMD_IP_BLOCK_TYPE_PSP,
|
||||
|
|
|
@ -93,9 +93,6 @@ struct psp_funcs
|
|||
enum psp_ring_type ring_type);
|
||||
int (*ring_destroy)(struct psp_context *psp,
|
||||
enum psp_ring_type ring_type);
|
||||
bool (*compare_sram_data)(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *ucode,
|
||||
enum AMDGPU_UCODE_ID ucode_type);
|
||||
bool (*smu_reload_quirk)(struct psp_context *psp);
|
||||
int (*mode1_reset)(struct psp_context *psp);
|
||||
int (*xgmi_get_node_id)(struct psp_context *psp, uint64_t *node_id);
|
||||
|
@ -104,7 +101,6 @@ struct psp_funcs
|
|||
struct psp_xgmi_topology_info *topology);
|
||||
int (*xgmi_set_topology_info)(struct psp_context *psp, int number_devices,
|
||||
struct psp_xgmi_topology_info *topology);
|
||||
bool (*support_vmr_ring)(struct psp_context *psp);
|
||||
int (*ras_trigger_error)(struct psp_context *psp,
|
||||
struct ta_ras_trigger_error_input *info);
|
||||
int (*ras_cure_posion)(struct psp_context *psp, uint64_t *mode_ptr);
|
||||
|
@ -161,6 +157,7 @@ struct psp_hdcp_context {
|
|||
struct amdgpu_bo *hdcp_shared_bo;
|
||||
uint64_t hdcp_shared_mc_addr;
|
||||
void *hdcp_shared_buf;
|
||||
struct mutex mutex;
|
||||
};
|
||||
|
||||
struct psp_dtm_context {
|
||||
|
@ -169,6 +166,7 @@ struct psp_dtm_context {
|
|||
struct amdgpu_bo *dtm_shared_bo;
|
||||
uint64_t dtm_shared_mc_addr;
|
||||
void *dtm_shared_buf;
|
||||
struct mutex mutex;
|
||||
};
|
||||
|
||||
#define MEM_TRAIN_SYSTEM_SIGNATURE 0x54534942
|
||||
|
@ -306,8 +304,6 @@ struct amdgpu_psp_funcs {
|
|||
#define psp_ring_create(psp, type) (psp)->funcs->ring_create((psp), (type))
|
||||
#define psp_ring_stop(psp, type) (psp)->funcs->ring_stop((psp), (type))
|
||||
#define psp_ring_destroy(psp, type) ((psp)->funcs->ring_destroy((psp), (type)))
|
||||
#define psp_compare_sram_data(psp, ucode, type) \
|
||||
(psp)->funcs->compare_sram_data((psp), (ucode), (type))
|
||||
#define psp_init_microcode(psp) \
|
||||
((psp)->funcs->init_microcode ? (psp)->funcs->init_microcode((psp)) : 0)
|
||||
#define psp_bootloader_load_kdb(psp) \
|
||||
|
@ -318,8 +314,6 @@ struct amdgpu_psp_funcs {
|
|||
((psp)->funcs->bootloader_load_sos ? (psp)->funcs->bootloader_load_sos((psp)) : 0)
|
||||
#define psp_smu_reload_quirk(psp) \
|
||||
((psp)->funcs->smu_reload_quirk ? (psp)->funcs->smu_reload_quirk((psp)) : false)
|
||||
#define psp_support_vmr_ring(psp) \
|
||||
((psp)->funcs->support_vmr_ring ? (psp)->funcs->support_vmr_ring((psp)) : false)
|
||||
#define psp_mode1_reset(psp) \
|
||||
((psp)->funcs->mode1_reset ? (psp)->funcs->mode1_reset((psp)) : false)
|
||||
#define psp_xgmi_get_node_id(psp, node_id) \
|
||||
|
@ -341,8 +335,6 @@ struct amdgpu_psp_funcs {
|
|||
#define psp_mem_training(psp, ops) \
|
||||
((psp)->funcs->mem_training ? (psp)->funcs->mem_training((psp), (ops)) : 0)
|
||||
|
||||
#define amdgpu_psp_check_fw_loading_status(adev, i) (adev)->firmware.funcs->check_fw_loading_status((adev), (i))
|
||||
|
||||
#define psp_ras_trigger_error(psp, info) \
|
||||
((psp)->funcs->ras_trigger_error ? \
|
||||
(psp)->funcs->ras_trigger_error((psp), (info)) : -EINVAL)
|
||||
|
@ -393,4 +385,8 @@ int psp_ring_cmd_submit(struct psp_context *psp,
|
|||
uint64_t cmd_buf_mc_addr,
|
||||
uint64_t fence_mc_addr,
|
||||
int index);
|
||||
int psp_init_asd_microcode(struct psp_context *psp,
|
||||
const char *chip_name);
|
||||
int psp_init_sos_microcode(struct psp_context *psp,
|
||||
const char *chip_name);
|
||||
#endif
|
||||
|
|
|
@ -80,6 +80,20 @@ atomic_t amdgpu_ras_in_intr = ATOMIC_INIT(0);
|
|||
static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev,
|
||||
uint64_t addr);
|
||||
|
||||
void amdgpu_ras_set_error_query_ready(struct amdgpu_device *adev, bool ready)
|
||||
{
|
||||
if (adev && amdgpu_ras_get_context(adev))
|
||||
amdgpu_ras_get_context(adev)->error_query_ready = ready;
|
||||
}
|
||||
|
||||
bool amdgpu_ras_get_error_query_ready(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev && amdgpu_ras_get_context(adev))
|
||||
return amdgpu_ras_get_context(adev)->error_query_ready;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static ssize_t amdgpu_ras_debugfs_read(struct file *f, char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
|
@ -281,8 +295,9 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f, const char __user *
|
|||
struct ras_debug_if data;
|
||||
int ret = 0;
|
||||
|
||||
if (amdgpu_ras_intr_triggered()) {
|
||||
DRM_WARN("RAS WARN: error injection currently inaccessible\n");
|
||||
if (!amdgpu_ras_get_error_query_ready(adev)) {
|
||||
dev_warn(adev->dev, "RAS WARN: error injection "
|
||||
"currently inaccessible\n");
|
||||
return size;
|
||||
}
|
||||
|
||||
|
@ -310,7 +325,8 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f, const char __user *
|
|||
/* umc ce/ue error injection for a bad page is not allowed */
|
||||
if ((data.head.block == AMDGPU_RAS_BLOCK__UMC) &&
|
||||
amdgpu_ras_check_bad_page(adev, data.inject.address)) {
|
||||
DRM_WARN("RAS WARN: 0x%llx has been marked as bad before error injection!\n",
|
||||
dev_warn(adev->dev, "RAS WARN: 0x%llx has been marked "
|
||||
"as bad before error injection!\n",
|
||||
data.inject.address);
|
||||
break;
|
||||
}
|
||||
|
@ -399,7 +415,7 @@ static ssize_t amdgpu_ras_sysfs_read(struct device *dev,
|
|||
.head = obj->head,
|
||||
};
|
||||
|
||||
if (amdgpu_ras_intr_triggered())
|
||||
if (!amdgpu_ras_get_error_query_ready(obj->adev))
|
||||
return snprintf(buf, PAGE_SIZE,
|
||||
"Query currently inaccessible\n");
|
||||
|
||||
|
@ -576,7 +592,8 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev,
|
|||
if (!amdgpu_ras_intr_triggered()) {
|
||||
ret = psp_ras_enable_features(&adev->psp, &info, enable);
|
||||
if (ret) {
|
||||
DRM_ERROR("RAS ERROR: %s %s feature failed ret %d\n",
|
||||
dev_err(adev->dev, "RAS ERROR: %s %s feature "
|
||||
"failed ret %d\n",
|
||||
enable ? "enable":"disable",
|
||||
ras_block_str(head->block),
|
||||
ret);
|
||||
|
@ -618,7 +635,8 @@ int amdgpu_ras_feature_enable_on_boot(struct amdgpu_device *adev,
|
|||
if (ret == -EINVAL) {
|
||||
ret = __amdgpu_ras_feature_enable(adev, head, 1);
|
||||
if (!ret)
|
||||
DRM_INFO("RAS INFO: %s setup object\n",
|
||||
dev_info(adev->dev,
|
||||
"RAS INFO: %s setup object\n",
|
||||
ras_block_str(head->block));
|
||||
}
|
||||
} else {
|
||||
|
@ -744,12 +762,17 @@ int amdgpu_ras_error_query(struct amdgpu_device *adev,
|
|||
info->ce_count = obj->err_data.ce_count;
|
||||
|
||||
if (err_data.ce_count) {
|
||||
dev_info(adev->dev, "%ld correctable errors detected in %s block\n",
|
||||
obj->err_data.ce_count, ras_block_str(info->head.block));
|
||||
dev_info(adev->dev, "%ld correctable hardware errors "
|
||||
"detected in %s block, no user "
|
||||
"action is needed.\n",
|
||||
obj->err_data.ce_count,
|
||||
ras_block_str(info->head.block));
|
||||
}
|
||||
if (err_data.ue_count) {
|
||||
dev_info(adev->dev, "%ld uncorrectable errors detected in %s block\n",
|
||||
obj->err_data.ue_count, ras_block_str(info->head.block));
|
||||
dev_info(adev->dev, "%ld uncorrectable hardware errors "
|
||||
"detected in %s block\n",
|
||||
obj->err_data.ue_count,
|
||||
ras_block_str(info->head.block));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -793,13 +816,13 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
|
|||
ret = psp_ras_trigger_error(&adev->psp, &block_info);
|
||||
break;
|
||||
default:
|
||||
DRM_INFO("%s error injection is not supported yet\n",
|
||||
dev_info(adev->dev, "%s error injection is not supported yet\n",
|
||||
ras_block_str(info->head.block));
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
DRM_ERROR("RAS ERROR: inject %s error failed ret %d\n",
|
||||
dev_err(adev->dev, "RAS ERROR: inject %s error failed ret %d\n",
|
||||
ras_block_str(info->head.block),
|
||||
ret);
|
||||
|
||||
|
@ -1430,9 +1453,10 @@ static void amdgpu_ras_do_recovery(struct work_struct *work)
|
|||
struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev, false);
|
||||
|
||||
/* Build list of devices to query RAS related errors */
|
||||
if (hive && adev->gmc.xgmi.num_physical_nodes > 1) {
|
||||
if (hive && adev->gmc.xgmi.num_physical_nodes > 1)
|
||||
device_list_handle = &hive->device_list;
|
||||
} else {
|
||||
else {
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
list_add_tail(&adev->gmc.xgmi.head, &device_list);
|
||||
device_list_handle = &device_list;
|
||||
}
|
||||
|
@ -1535,7 +1559,7 @@ static int amdgpu_ras_save_bad_pages(struct amdgpu_device *adev)
|
|||
&data->bps[control->num_recs],
|
||||
true,
|
||||
save_count)) {
|
||||
DRM_ERROR("Failed to save EEPROM table data!");
|
||||
dev_err(adev->dev, "Failed to save EEPROM table data!");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -1563,7 +1587,7 @@ static int amdgpu_ras_load_bad_pages(struct amdgpu_device *adev)
|
|||
|
||||
if (amdgpu_ras_eeprom_process_recods(control, bps, false,
|
||||
control->num_recs)) {
|
||||
DRM_ERROR("Failed to load EEPROM table records!");
|
||||
dev_err(adev->dev, "Failed to load EEPROM table records!");
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
@ -1637,7 +1661,8 @@ int amdgpu_ras_reserve_bad_pages(struct amdgpu_device *adev)
|
|||
AMDGPU_GPU_PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&bo, NULL))
|
||||
DRM_WARN("RAS WARN: reserve vram for retired page %llx fail\n", bp);
|
||||
dev_warn(adev->dev, "RAS WARN: reserve vram for "
|
||||
"retired page %llx fail\n", bp);
|
||||
|
||||
data->bps_bo[i] = bo;
|
||||
data->last_reserved = i + 1;
|
||||
|
@ -1725,7 +1750,7 @@ free:
|
|||
kfree(*data);
|
||||
con->eh_data = NULL;
|
||||
out:
|
||||
DRM_WARN("Failed to initialize ras recovery!\n");
|
||||
dev_warn(adev->dev, "Failed to initialize ras recovery!\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1787,18 +1812,18 @@ static void amdgpu_ras_check_supported(struct amdgpu_device *adev,
|
|||
return;
|
||||
|
||||
if (amdgpu_atomfirmware_mem_ecc_supported(adev)) {
|
||||
DRM_INFO("HBM ECC is active.\n");
|
||||
dev_info(adev->dev, "HBM ECC is active.\n");
|
||||
*hw_supported |= (1 << AMDGPU_RAS_BLOCK__UMC |
|
||||
1 << AMDGPU_RAS_BLOCK__DF);
|
||||
} else
|
||||
DRM_INFO("HBM ECC is not presented.\n");
|
||||
dev_info(adev->dev, "HBM ECC is not presented.\n");
|
||||
|
||||
if (amdgpu_atomfirmware_sram_ecc_supported(adev)) {
|
||||
DRM_INFO("SRAM ECC is active.\n");
|
||||
dev_info(adev->dev, "SRAM ECC is active.\n");
|
||||
*hw_supported |= ~(1 << AMDGPU_RAS_BLOCK__UMC |
|
||||
1 << AMDGPU_RAS_BLOCK__DF);
|
||||
} else
|
||||
DRM_INFO("SRAM ECC is not presented.\n");
|
||||
dev_info(adev->dev, "SRAM ECC is not presented.\n");
|
||||
|
||||
/* hw_supported needs to be aligned with RAS block mask. */
|
||||
*hw_supported &= AMDGPU_RAS_BLOCK_MASK;
|
||||
|
@ -1855,7 +1880,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
|
|||
if (amdgpu_ras_fs_init(adev))
|
||||
goto fs_out;
|
||||
|
||||
DRM_INFO("RAS INFO: ras initialized successfully, "
|
||||
dev_info(adev->dev, "RAS INFO: ras initialized successfully, "
|
||||
"hardware ability[%x] ras_mask[%x]\n",
|
||||
con->hw_supported, con->supported);
|
||||
return 0;
|
||||
|
@ -2037,7 +2062,8 @@ void amdgpu_ras_global_ras_isr(struct amdgpu_device *adev)
|
|||
return;
|
||||
|
||||
if (atomic_cmpxchg(&amdgpu_ras_in_intr, 0, 1) == 0) {
|
||||
DRM_WARN("RAS event of type ERREVENT_ATHUB_INTERRUPT detected!\n");
|
||||
dev_info(adev->dev, "uncorrectable hardware error"
|
||||
"(ERREVENT_ATHUB_INTERRUPT) detected!\n");
|
||||
|
||||
amdgpu_ras_reset_gpu(adev);
|
||||
}
|
||||
|
|
|
@ -334,6 +334,8 @@ struct amdgpu_ras {
|
|||
uint32_t flags;
|
||||
bool reboot;
|
||||
struct amdgpu_ras_eeprom_control eeprom_control;
|
||||
|
||||
bool error_query_ready;
|
||||
};
|
||||
|
||||
struct ras_fs_data {
|
||||
|
@ -629,4 +631,6 @@ static inline void amdgpu_ras_intr_cleared(void)
|
|||
|
||||
void amdgpu_ras_global_ras_isr(struct amdgpu_device *adev);
|
||||
|
||||
void amdgpu_ras_set_error_query_ready(struct amdgpu_device *adev, bool ready);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -162,11 +162,13 @@ void amdgpu_ring_undo(struct amdgpu_ring *ring)
|
|||
* Returns 0 on success, error on failure.
|
||||
*/
|
||||
int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
|
||||
unsigned max_dw, struct amdgpu_irq_src *irq_src,
|
||||
unsigned irq_type)
|
||||
unsigned int max_dw, struct amdgpu_irq_src *irq_src,
|
||||
unsigned int irq_type, unsigned int hw_prio)
|
||||
{
|
||||
int r, i;
|
||||
int sched_hw_submission = amdgpu_sched_hw_submission;
|
||||
u32 *num_sched;
|
||||
u32 hw_ip;
|
||||
|
||||
/* Set the hw submission limit higher for KIQ because
|
||||
* it's used for a number of gfx/compute tasks by both
|
||||
|
@ -258,6 +260,13 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
|
|||
ring->priority = DRM_SCHED_PRIORITY_NORMAL;
|
||||
mutex_init(&ring->priority_mutex);
|
||||
|
||||
if (!ring->no_scheduler) {
|
||||
hw_ip = ring->funcs->type;
|
||||
num_sched = &adev->gpu_sched[hw_ip][hw_prio].num_scheds;
|
||||
adev->gpu_sched[hw_ip][hw_prio].sched[(*num_sched)++] =
|
||||
&ring->sched;
|
||||
}
|
||||
|
||||
for (i = 0; i < DRM_SCHED_PRIORITY_MAX; ++i)
|
||||
atomic_set(&ring->num_jobs[i], 0);
|
||||
|
||||
|
|
|
@ -30,11 +30,15 @@
|
|||
|
||||
/* max number of rings */
|
||||
#define AMDGPU_MAX_RINGS 28
|
||||
#define AMDGPU_MAX_HWIP_RINGS 8
|
||||
#define AMDGPU_MAX_GFX_RINGS 2
|
||||
#define AMDGPU_MAX_COMPUTE_RINGS 8
|
||||
#define AMDGPU_MAX_VCE_RINGS 3
|
||||
#define AMDGPU_MAX_UVD_ENC_RINGS 2
|
||||
|
||||
#define AMDGPU_RING_PRIO_DEFAULT 1
|
||||
#define AMDGPU_RING_PRIO_MAX AMDGPU_GFX_PIPE_PRIO_MAX
|
||||
|
||||
/* some special values for the owner field */
|
||||
#define AMDGPU_FENCE_OWNER_UNDEFINED ((void *)0ul)
|
||||
#define AMDGPU_FENCE_OWNER_VM ((void *)1ul)
|
||||
|
@ -47,16 +51,16 @@
|
|||
#define to_amdgpu_ring(s) container_of((s), struct amdgpu_ring, sched)
|
||||
|
||||
enum amdgpu_ring_type {
|
||||
AMDGPU_RING_TYPE_GFX,
|
||||
AMDGPU_RING_TYPE_COMPUTE,
|
||||
AMDGPU_RING_TYPE_SDMA,
|
||||
AMDGPU_RING_TYPE_UVD,
|
||||
AMDGPU_RING_TYPE_VCE,
|
||||
AMDGPU_RING_TYPE_KIQ,
|
||||
AMDGPU_RING_TYPE_UVD_ENC,
|
||||
AMDGPU_RING_TYPE_VCN_DEC,
|
||||
AMDGPU_RING_TYPE_VCN_ENC,
|
||||
AMDGPU_RING_TYPE_VCN_JPEG
|
||||
AMDGPU_RING_TYPE_GFX = AMDGPU_HW_IP_GFX,
|
||||
AMDGPU_RING_TYPE_COMPUTE = AMDGPU_HW_IP_COMPUTE,
|
||||
AMDGPU_RING_TYPE_SDMA = AMDGPU_HW_IP_DMA,
|
||||
AMDGPU_RING_TYPE_UVD = AMDGPU_HW_IP_UVD,
|
||||
AMDGPU_RING_TYPE_VCE = AMDGPU_HW_IP_VCE,
|
||||
AMDGPU_RING_TYPE_UVD_ENC = AMDGPU_HW_IP_UVD_ENC,
|
||||
AMDGPU_RING_TYPE_VCN_DEC = AMDGPU_HW_IP_VCN_DEC,
|
||||
AMDGPU_RING_TYPE_VCN_ENC = AMDGPU_HW_IP_VCN_ENC,
|
||||
AMDGPU_RING_TYPE_VCN_JPEG = AMDGPU_HW_IP_VCN_JPEG,
|
||||
AMDGPU_RING_TYPE_KIQ
|
||||
};
|
||||
|
||||
struct amdgpu_device;
|
||||
|
@ -65,6 +69,11 @@ struct amdgpu_ib;
|
|||
struct amdgpu_cs_parser;
|
||||
struct amdgpu_job;
|
||||
|
||||
struct amdgpu_sched {
|
||||
u32 num_scheds;
|
||||
struct drm_gpu_scheduler *sched[AMDGPU_MAX_HWIP_RINGS];
|
||||
};
|
||||
|
||||
/*
|
||||
* Fences.
|
||||
*/
|
||||
|
@ -159,7 +168,8 @@ struct amdgpu_ring_funcs {
|
|||
void (*end_use)(struct amdgpu_ring *ring);
|
||||
void (*emit_switch_buffer) (struct amdgpu_ring *ring);
|
||||
void (*emit_cntxcntl) (struct amdgpu_ring *ring, uint32_t flags);
|
||||
void (*emit_rreg)(struct amdgpu_ring *ring, uint32_t reg);
|
||||
void (*emit_rreg)(struct amdgpu_ring *ring, uint32_t reg,
|
||||
uint32_t reg_val_offs);
|
||||
void (*emit_wreg)(struct amdgpu_ring *ring, uint32_t reg, uint32_t val);
|
||||
void (*emit_reg_wait)(struct amdgpu_ring *ring, uint32_t reg,
|
||||
uint32_t val, uint32_t mask);
|
||||
|
@ -214,12 +224,12 @@ struct amdgpu_ring {
|
|||
unsigned vm_inv_eng;
|
||||
struct dma_fence *vmid_wait;
|
||||
bool has_compute_vm_bug;
|
||||
bool no_scheduler;
|
||||
|
||||
atomic_t num_jobs[DRM_SCHED_PRIORITY_MAX];
|
||||
struct mutex priority_mutex;
|
||||
/* protected by priority_mutex */
|
||||
int priority;
|
||||
bool has_high_prio;
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
struct dentry *ent;
|
||||
|
@ -241,7 +251,7 @@ struct amdgpu_ring {
|
|||
#define amdgpu_ring_emit_hdp_flush(r) (r)->funcs->emit_hdp_flush((r))
|
||||
#define amdgpu_ring_emit_switch_buffer(r) (r)->funcs->emit_switch_buffer((r))
|
||||
#define amdgpu_ring_emit_cntxcntl(r, d) (r)->funcs->emit_cntxcntl((r), (d))
|
||||
#define amdgpu_ring_emit_rreg(r, d) (r)->funcs->emit_rreg((r), (d))
|
||||
#define amdgpu_ring_emit_rreg(r, d, o) (r)->funcs->emit_rreg((r), (d), (o))
|
||||
#define amdgpu_ring_emit_wreg(r, d, v) (r)->funcs->emit_wreg((r), (d), (v))
|
||||
#define amdgpu_ring_emit_reg_wait(r, d, v, m) (r)->funcs->emit_reg_wait((r), (d), (v), (m))
|
||||
#define amdgpu_ring_emit_reg_write_reg_wait(r, d0, d1, v, m) (r)->funcs->emit_reg_write_reg_wait((r), (d0), (d1), (v), (m))
|
||||
|
@ -257,8 +267,8 @@ void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib);
|
|||
void amdgpu_ring_commit(struct amdgpu_ring *ring);
|
||||
void amdgpu_ring_undo(struct amdgpu_ring *ring);
|
||||
int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
|
||||
unsigned ring_size, struct amdgpu_irq_src *irq_src,
|
||||
unsigned irq_type);
|
||||
unsigned int ring_size, struct amdgpu_irq_src *irq_src,
|
||||
unsigned int irq_type, unsigned int prio);
|
||||
void amdgpu_ring_fini(struct amdgpu_ring *ring);
|
||||
void amdgpu_ring_emit_reg_write_reg_wait_helper(struct amdgpu_ring *ring,
|
||||
uint32_t reg0, uint32_t val0,
|
||||
|
|
|
@ -61,8 +61,6 @@ struct amdgpu_sdma_ras_funcs {
|
|||
|
||||
struct amdgpu_sdma {
|
||||
struct amdgpu_sdma_instance instance[AMDGPU_MAX_SDMA_INSTANCES];
|
||||
struct drm_gpu_scheduler *sdma_sched[AMDGPU_MAX_SDMA_INSTANCES];
|
||||
uint32_t num_sdma_sched;
|
||||
struct amdgpu_irq_src trap_irq;
|
||||
struct amdgpu_irq_src illegal_inst_irq;
|
||||
struct amdgpu_irq_src ecc_irq;
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define AMDGPU_JOB_GET_TIMELINE_NAME(job) \
|
||||
job->base.s_fence->finished.ops->get_timeline_name(&job->base.s_fence->finished)
|
||||
|
||||
TRACE_EVENT(amdgpu_mm_rreg,
|
||||
TRACE_EVENT(amdgpu_device_rreg,
|
||||
TP_PROTO(unsigned did, uint32_t reg, uint32_t value),
|
||||
TP_ARGS(did, reg, value),
|
||||
TP_STRUCT__entry(
|
||||
|
@ -54,7 +54,7 @@ TRACE_EVENT(amdgpu_mm_rreg,
|
|||
(unsigned long)__entry->value)
|
||||
);
|
||||
|
||||
TRACE_EVENT(amdgpu_mm_wreg,
|
||||
TRACE_EVENT(amdgpu_device_wreg,
|
||||
TP_PROTO(unsigned did, uint32_t reg, uint32_t value),
|
||||
TP_ARGS(did, reg, value),
|
||||
TP_STRUCT__entry(
|
||||
|
|
|
@ -2042,7 +2042,8 @@ static int amdgpu_map_buffer(struct ttm_buffer_object *bo,
|
|||
num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8);
|
||||
num_bytes = num_pages * 8;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4 + num_bytes, &job);
|
||||
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4 + num_bytes,
|
||||
AMDGPU_IB_POOL_NORMAL, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -2101,7 +2102,8 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
|
|||
num_loops = DIV_ROUND_UP(byte_count, max_bytes);
|
||||
num_dw = ALIGN(num_loops * adev->mman.buffer_funcs->copy_num_dw, 8);
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, &job);
|
||||
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4,
|
||||
direct_submit ? AMDGPU_IB_POOL_DIRECT : AMDGPU_IB_POOL_NORMAL, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -2190,7 +2192,7 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
|
|||
/* for IB padding */
|
||||
num_dw += 64;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, &job);
|
||||
r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, AMDGPU_IB_POOL_NORMAL, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -403,8 +403,8 @@ FW_VERSION_ATTR(mec_fw_version, 0444, gfx.mec_fw_version);
|
|||
FW_VERSION_ATTR(mec2_fw_version, 0444, gfx.mec2_fw_version);
|
||||
FW_VERSION_ATTR(sos_fw_version, 0444, psp.sos_fw_version);
|
||||
FW_VERSION_ATTR(asd_fw_version, 0444, psp.asd_fw_version);
|
||||
FW_VERSION_ATTR(ta_ras_fw_version, 0444, psp.ta_fw_version);
|
||||
FW_VERSION_ATTR(ta_xgmi_fw_version, 0444, psp.ta_fw_version);
|
||||
FW_VERSION_ATTR(ta_ras_fw_version, 0444, psp.ta_ras_ucode_version);
|
||||
FW_VERSION_ATTR(ta_xgmi_fw_version, 0444, psp.ta_xgmi_ucode_version);
|
||||
FW_VERSION_ATTR(smc_fw_version, 0444, pm.fw_version);
|
||||
FW_VERSION_ATTR(sdma_fw_version, 0444, sdma.instance[0].fw_version);
|
||||
FW_VERSION_ATTR(sdma2_fw_version, 0444, sdma.instance[1].fw_version);
|
||||
|
|
|
@ -110,7 +110,8 @@ int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev,
|
|||
* even NOMEM error is encountered
|
||||
*/
|
||||
if(!err_data->err_addr)
|
||||
DRM_WARN("Failed to alloc memory for umc error address record!\n");
|
||||
dev_warn(adev->dev, "Failed to alloc memory for "
|
||||
"umc error address record!\n");
|
||||
|
||||
/* umc query_ras_error_address is also responsible for clearing
|
||||
* error status
|
||||
|
@ -120,10 +121,14 @@ int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev,
|
|||
|
||||
/* only uncorrectable error needs gpu reset */
|
||||
if (err_data->ue_count) {
|
||||
dev_info(adev->dev, "%ld uncorrectable hardware errors "
|
||||
"detected in UMC block\n",
|
||||
err_data->ue_count);
|
||||
|
||||
if (err_data->err_addr_cnt &&
|
||||
amdgpu_ras_add_bad_pages(adev, err_data->err_addr,
|
||||
err_data->err_addr_cnt))
|
||||
DRM_WARN("Failed to add ras bad page!\n");
|
||||
dev_warn(adev->dev, "Failed to add ras bad page!\n");
|
||||
|
||||
amdgpu_ras_reset_gpu(adev);
|
||||
}
|
||||
|
|
|
@ -1056,7 +1056,8 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
|
|||
goto err;
|
||||
}
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(adev, 64, &job);
|
||||
r = amdgpu_job_alloc_with_ib(adev, 64,
|
||||
direct ? AMDGPU_IB_POOL_DIRECT : AMDGPU_IB_POOL_NORMAL, &job);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
|
|
|
@ -446,7 +446,8 @@ static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
|
|||
uint64_t addr;
|
||||
int i, r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
|
||||
AMDGPU_IB_POOL_DIRECT, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -524,7 +525,8 @@ static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
|||
struct dma_fence *f = NULL;
|
||||
int i, r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
|
||||
direct ? AMDGPU_IB_POOL_DIRECT : AMDGPU_IB_POOL_NORMAL, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -56,13 +56,17 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work);
|
|||
|
||||
int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
unsigned long bo_size;
|
||||
unsigned long bo_size, fw_shared_bo_size;
|
||||
const char *fw_name;
|
||||
const struct common_firmware_header *hdr;
|
||||
unsigned char fw_check;
|
||||
int i, r;
|
||||
|
||||
INIT_DELAYED_WORK(&adev->vcn.idle_work, amdgpu_vcn_idle_work_handler);
|
||||
mutex_init(&adev->vcn.vcn_pg_lock);
|
||||
atomic_set(&adev->vcn.total_submission_cnt, 0);
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; i++)
|
||||
atomic_set(&adev->vcn.inst[i].dpg_enc_submission_cnt, 0);
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RAVEN:
|
||||
|
@ -178,6 +182,17 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
|||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
r = amdgpu_bo_create_kernel(adev, AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)),
|
||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].fw_shared_bo,
|
||||
&adev->vcn.inst[i].fw_shared_gpu_addr, &adev->vcn.inst[i].fw_shared_cpu_addr);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "VCN %d (%d) failed to allocate firmware shared bo\n", i, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
fw_shared_bo_size = amdgpu_bo_size(adev->vcn.inst[i].fw_shared_bo);
|
||||
adev->vcn.inst[i].saved_shm_bo = kvmalloc(fw_shared_bo_size, GFP_KERNEL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -192,6 +207,12 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
|
|||
for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
|
||||
if (adev->vcn.harvest_config & (1 << j))
|
||||
continue;
|
||||
|
||||
kvfree(adev->vcn.inst[j].saved_shm_bo);
|
||||
amdgpu_bo_free_kernel(&adev->vcn.inst[j].fw_shared_bo,
|
||||
&adev->vcn.inst[j].fw_shared_gpu_addr,
|
||||
(void **)&adev->vcn.inst[j].fw_shared_cpu_addr);
|
||||
|
||||
if (adev->vcn.indirect_sram) {
|
||||
amdgpu_bo_free_kernel(&adev->vcn.inst[j].dpg_sram_bo,
|
||||
&adev->vcn.inst[j].dpg_sram_gpu_addr,
|
||||
|
@ -210,6 +231,7 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
release_firmware(adev->vcn.fw);
|
||||
mutex_destroy(&adev->vcn.vcn_pg_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -236,6 +258,17 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)
|
|||
return -ENOMEM;
|
||||
|
||||
memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size);
|
||||
|
||||
if (adev->vcn.inst[i].fw_shared_bo == NULL)
|
||||
return 0;
|
||||
|
||||
if (!adev->vcn.inst[i].saved_shm_bo)
|
||||
return -ENOMEM;
|
||||
|
||||
size = amdgpu_bo_size(adev->vcn.inst[i].fw_shared_bo);
|
||||
ptr = adev->vcn.inst[i].fw_shared_cpu_addr;
|
||||
|
||||
memcpy_fromio(adev->vcn.inst[i].saved_shm_bo, ptr, size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -273,6 +306,17 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)
|
|||
}
|
||||
memset_io(ptr, 0, size);
|
||||
}
|
||||
|
||||
if (adev->vcn.inst[i].fw_shared_bo == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
size = amdgpu_bo_size(adev->vcn.inst[i].fw_shared_bo);
|
||||
ptr = adev->vcn.inst[i].fw_shared_cpu_addr;
|
||||
|
||||
if (adev->vcn.inst[i].saved_shm_bo != NULL)
|
||||
memcpy_toio(ptr, adev->vcn.inst[i].saved_shm_bo, size);
|
||||
else
|
||||
memset_io(ptr, 0, size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -295,7 +339,8 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
|
|||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
|
||||
struct dpg_pause_state new_state;
|
||||
|
||||
if (fence[j])
|
||||
if (fence[j] ||
|
||||
unlikely(atomic_read(&adev->vcn.inst[j].dpg_enc_submission_cnt)))
|
||||
new_state.fw_based = VCN_DPG_STATE__PAUSE;
|
||||
else
|
||||
new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
|
||||
|
@ -307,8 +352,7 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
|
|||
fences += fence[j];
|
||||
}
|
||||
|
||||
if (fences == 0) {
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
if (!fences && !atomic_read(&adev->vcn.total_submission_cnt)) {
|
||||
amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
|
||||
AMD_PG_STATE_GATE);
|
||||
} else {
|
||||
|
@ -319,36 +363,46 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
|
|||
void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
|
||||
|
||||
if (set_clocks) {
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
|
||||
AMD_PG_STATE_UNGATE);
|
||||
}
|
||||
atomic_inc(&adev->vcn.total_submission_cnt);
|
||||
cancel_delayed_work_sync(&adev->vcn.idle_work);
|
||||
|
||||
mutex_lock(&adev->vcn.vcn_pg_lock);
|
||||
amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
|
||||
AMD_PG_STATE_UNGATE);
|
||||
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
|
||||
struct dpg_pause_state new_state;
|
||||
unsigned int fences = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
|
||||
fences += amdgpu_fence_count_emitted(&adev->vcn.inst[ring->me].ring_enc[i]);
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) {
|
||||
atomic_inc(&adev->vcn.inst[ring->me].dpg_enc_submission_cnt);
|
||||
new_state.fw_based = VCN_DPG_STATE__PAUSE;
|
||||
} else {
|
||||
unsigned int fences = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < adev->vcn.num_enc_rings; ++i)
|
||||
fences += amdgpu_fence_count_emitted(&adev->vcn.inst[ring->me].ring_enc[i]);
|
||||
|
||||
if (fences || atomic_read(&adev->vcn.inst[ring->me].dpg_enc_submission_cnt))
|
||||
new_state.fw_based = VCN_DPG_STATE__PAUSE;
|
||||
else
|
||||
new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
|
||||
}
|
||||
if (fences)
|
||||
new_state.fw_based = VCN_DPG_STATE__PAUSE;
|
||||
else
|
||||
new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
|
||||
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
|
||||
new_state.fw_based = VCN_DPG_STATE__PAUSE;
|
||||
|
||||
adev->vcn.pause_dpg_mode(adev, ring->me, &new_state);
|
||||
}
|
||||
mutex_unlock(&adev->vcn.vcn_pg_lock);
|
||||
}
|
||||
|
||||
void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
if (ring->adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
|
||||
ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
|
||||
atomic_dec(&ring->adev->vcn.inst[ring->me].dpg_enc_submission_cnt);
|
||||
|
||||
atomic_dec(&ring->adev->vcn.total_submission_cnt);
|
||||
|
||||
schedule_delayed_work(&ring->adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
|
||||
}
|
||||
|
||||
|
@ -390,7 +444,8 @@ static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,
|
|||
uint64_t addr;
|
||||
int i, r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(adev, 64, &job);
|
||||
r = amdgpu_job_alloc_with_ib(adev, 64,
|
||||
AMDGPU_IB_POOL_DIRECT, &job);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
|
@ -557,7 +612,8 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t hand
|
|||
uint64_t addr;
|
||||
int i, r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
|
||||
AMDGPU_IB_POOL_DIRECT, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -610,7 +666,8 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han
|
|||
uint64_t addr;
|
||||
int i, r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
|
||||
AMDGPU_IB_POOL_DIRECT, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -132,6 +132,13 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define AMDGPU_VCN_MULTI_QUEUE_FLAG (1 << 8)
|
||||
|
||||
enum fw_queue_mode {
|
||||
FW_QUEUE_RING_RESET = 1,
|
||||
FW_QUEUE_DPG_HOLD_OFF = 2,
|
||||
};
|
||||
|
||||
enum engine_status_constants {
|
||||
UVD_PGFSM_STATUS__UVDM_UVDU_PWR_ON = 0x2AAAA0,
|
||||
UVD_PGFSM_STATUS__UVDM_UVDU_PWR_ON_2_0 = 0xAAAA0,
|
||||
|
@ -179,10 +186,15 @@ struct amdgpu_vcn_inst {
|
|||
struct amdgpu_irq_src irq;
|
||||
struct amdgpu_vcn_reg external;
|
||||
struct amdgpu_bo *dpg_sram_bo;
|
||||
struct amdgpu_bo *fw_shared_bo;
|
||||
struct dpg_pause_state pause_state;
|
||||
void *dpg_sram_cpu_addr;
|
||||
uint64_t dpg_sram_gpu_addr;
|
||||
uint32_t *dpg_sram_curr_addr;
|
||||
atomic_t dpg_enc_submission_cnt;
|
||||
void *fw_shared_cpu_addr;
|
||||
uint64_t fw_shared_gpu_addr;
|
||||
void *saved_shm_bo;
|
||||
};
|
||||
|
||||
struct amdgpu_vcn {
|
||||
|
@ -196,16 +208,28 @@ struct amdgpu_vcn {
|
|||
uint8_t num_vcn_inst;
|
||||
struct amdgpu_vcn_inst inst[AMDGPU_MAX_VCN_INSTANCES];
|
||||
struct amdgpu_vcn_reg internal;
|
||||
struct drm_gpu_scheduler *vcn_enc_sched[AMDGPU_MAX_VCN_ENC_RINGS];
|
||||
struct drm_gpu_scheduler *vcn_dec_sched[AMDGPU_MAX_VCN_INSTANCES];
|
||||
uint32_t num_vcn_enc_sched;
|
||||
uint32_t num_vcn_dec_sched;
|
||||
struct mutex vcn_pg_lock;
|
||||
atomic_t total_submission_cnt;
|
||||
|
||||
unsigned harvest_config;
|
||||
int (*pause_dpg_mode)(struct amdgpu_device *adev,
|
||||
int inst_idx, struct dpg_pause_state *new_state);
|
||||
};
|
||||
|
||||
struct amdgpu_fw_shared_multi_queue {
|
||||
uint8_t decode_queue_mode;
|
||||
uint8_t encode_generalpurpose_queue_mode;
|
||||
uint8_t encode_lowlatency_queue_mode;
|
||||
uint8_t encode_realtime_queue_mode;
|
||||
uint8_t padding[4];
|
||||
};
|
||||
|
||||
struct amdgpu_fw_shared {
|
||||
uint32_t present_flag_0;
|
||||
uint8_t pad[53];
|
||||
struct amdgpu_fw_shared_multi_queue multi_queue;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
int amdgpu_vcn_sw_init(struct amdgpu_device *adev);
|
||||
int amdgpu_vcn_sw_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_vcn_suspend(struct amdgpu_device *adev);
|
||||
|
|
|
@ -38,7 +38,8 @@ bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev)
|
|||
void amdgpu_virt_init_setting(struct amdgpu_device *adev)
|
||||
{
|
||||
/* enable virtual display */
|
||||
adev->mode_info.num_crtc = 1;
|
||||
if (adev->mode_info.num_crtc == 0)
|
||||
adev->mode_info.num_crtc = 1;
|
||||
adev->enable_virtual_display = true;
|
||||
adev->ddev->driver->driver_features &= ~DRIVER_ATOMIC;
|
||||
adev->cg_flags = 0;
|
||||
|
@ -152,6 +153,19 @@ int amdgpu_virt_reset_gpu(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void amdgpu_virt_request_init_data(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_virt *virt = &adev->virt;
|
||||
|
||||
if (virt->ops && virt->ops->req_init_data)
|
||||
virt->ops->req_init_data(adev);
|
||||
|
||||
if (adev->virt.req_init_data_ver > 0)
|
||||
DRM_INFO("host supports REQ_INIT_DATA handshake\n");
|
||||
else
|
||||
DRM_WARN("host doesn't support REQ_INIT_DATA handshake\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_virt_wait_reset() - wait for reset gpu completed
|
||||
* @amdgpu: amdgpu device.
|
||||
|
@ -287,3 +301,66 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_detect_virtualization(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_TONGA:
|
||||
case CHIP_FIJI:
|
||||
reg = RREG32(mmBIF_IOV_FUNC_IDENTIFIER);
|
||||
break;
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI12:
|
||||
case CHIP_ARCTURUS:
|
||||
reg = RREG32(mmRCC_IOV_FUNC_IDENTIFIER);
|
||||
break;
|
||||
default: /* other chip doesn't support SRIOV */
|
||||
reg = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (reg & 1)
|
||||
adev->virt.caps |= AMDGPU_SRIOV_CAPS_IS_VF;
|
||||
|
||||
if (reg & 0x80000000)
|
||||
adev->virt.caps |= AMDGPU_SRIOV_CAPS_ENABLE_IOV;
|
||||
|
||||
if (!reg) {
|
||||
if (is_virtual_machine()) /* passthrough mode exclus sriov mod */
|
||||
adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
bool amdgpu_virt_access_debugfs_is_mmio(struct amdgpu_device *adev)
|
||||
{
|
||||
return amdgpu_sriov_is_debug(adev) ? true : false;
|
||||
}
|
||||
|
||||
bool amdgpu_virt_access_debugfs_is_kiq(struct amdgpu_device *adev)
|
||||
{
|
||||
return amdgpu_sriov_is_normal(adev) ? true : false;
|
||||
}
|
||||
|
||||
int amdgpu_virt_enable_access_debugfs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (!amdgpu_sriov_vf(adev) ||
|
||||
amdgpu_virt_access_debugfs_is_kiq(adev))
|
||||
return 0;
|
||||
|
||||
if (amdgpu_virt_access_debugfs_is_mmio(adev))
|
||||
adev->virt.caps &= ~AMDGPU_SRIOV_CAPS_RUNTIME;
|
||||
else
|
||||
return -EPERM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void amdgpu_virt_disable_access_debugfs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
adev->virt.caps |= AMDGPU_SRIOV_CAPS_RUNTIME;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,11 @@
|
|||
#define AMDGPU_PASSTHROUGH_MODE (1 << 3) /* thw whole GPU is pass through for VM */
|
||||
#define AMDGPU_SRIOV_CAPS_RUNTIME (1 << 4) /* is out of full access mode */
|
||||
|
||||
/* all asic after AI use this offset */
|
||||
#define mmRCC_IOV_FUNC_IDENTIFIER 0xDE5
|
||||
/* tonga/fiji use this offset */
|
||||
#define mmBIF_IOV_FUNC_IDENTIFIER 0x1503
|
||||
|
||||
struct amdgpu_mm_table {
|
||||
struct amdgpu_bo *bo;
|
||||
uint32_t *cpu_addr;
|
||||
|
@ -54,6 +59,7 @@ struct amdgpu_vf_error_buffer {
|
|||
struct amdgpu_virt_ops {
|
||||
int (*req_full_gpu)(struct amdgpu_device *adev, bool init);
|
||||
int (*rel_full_gpu)(struct amdgpu_device *adev, bool init);
|
||||
int (*req_init_data)(struct amdgpu_device *adev);
|
||||
int (*reset_gpu)(struct amdgpu_device *adev);
|
||||
int (*wait_reset)(struct amdgpu_device *adev);
|
||||
void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3);
|
||||
|
@ -83,6 +89,8 @@ enum AMDGIM_FEATURE_FLAG {
|
|||
AMDGIM_FEATURE_GIM_LOAD_UCODES = 0x2,
|
||||
/* VRAM LOST by GIM */
|
||||
AMDGIM_FEATURE_GIM_FLR_VRAMLOST = 0x4,
|
||||
/* MM bandwidth */
|
||||
AMDGIM_FEATURE_GIM_MM_BW_MGR = 0x8,
|
||||
/* PP ONE VF MODE in GIM */
|
||||
AMDGIM_FEATURE_PP_ONE_VF = (1 << 4),
|
||||
};
|
||||
|
@ -256,6 +264,8 @@ struct amdgpu_virt {
|
|||
struct amdgpu_virt_fw_reserve fw_reserve;
|
||||
uint32_t gim_feature;
|
||||
uint32_t reg_access_mode;
|
||||
int req_init_data_ver;
|
||||
bool tdr_debug;
|
||||
};
|
||||
|
||||
#define amdgpu_sriov_enabled(adev) \
|
||||
|
@ -287,6 +297,10 @@ static inline bool is_virtual_machine(void)
|
|||
|
||||
#define amdgpu_sriov_is_pp_one_vf(adev) \
|
||||
((adev)->virt.gim_feature & AMDGIM_FEATURE_PP_ONE_VF)
|
||||
#define amdgpu_sriov_is_debug(adev) \
|
||||
((!adev->in_gpu_reset) && adev->virt.tdr_debug)
|
||||
#define amdgpu_sriov_is_normal(adev) \
|
||||
((!adev->in_gpu_reset) && (!adev->virt.tdr_debug))
|
||||
|
||||
bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);
|
||||
void amdgpu_virt_init_setting(struct amdgpu_device *adev);
|
||||
|
@ -296,6 +310,7 @@ void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
|
|||
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);
|
||||
void amdgpu_virt_request_init_data(struct amdgpu_device *adev);
|
||||
int amdgpu_virt_wait_reset(struct amdgpu_device *adev);
|
||||
int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev);
|
||||
void amdgpu_virt_free_mm_table(struct amdgpu_device *adev);
|
||||
|
@ -303,4 +318,9 @@ int amdgpu_virt_fw_reserve_get_checksum(void *obj, unsigned long obj_size,
|
|||
unsigned int key,
|
||||
unsigned int chksum);
|
||||
void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev);
|
||||
void amdgpu_detect_virtualization(struct amdgpu_device *adev);
|
||||
|
||||
bool amdgpu_virt_can_access_debugfs(struct amdgpu_device *adev);
|
||||
int amdgpu_virt_enable_access_debugfs(struct amdgpu_device *adev);
|
||||
void amdgpu_virt_disable_access_debugfs(struct amdgpu_device *adev);
|
||||
#endif
|
||||
|
|
|
@ -82,7 +82,7 @@ struct amdgpu_prt_cb {
|
|||
struct dma_fence_cb cb;
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* vm eviction_lock can be taken in MMU notifiers. Make sure no reclaim-FS
|
||||
* happens while holding this lock anywhere to prevent deadlocks when
|
||||
* an MMU notifier runs in reclaim-FS context.
|
||||
|
@ -2124,11 +2124,8 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
|
|||
if (bo && amdgpu_xgmi_same_hive(adev, amdgpu_ttm_adev(bo->tbo.bdev)) &&
|
||||
(bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM)) {
|
||||
bo_va->is_xgmi = true;
|
||||
mutex_lock(&adev->vm_manager.lock_pstate);
|
||||
/* Power up XGMI if it can be potentially used */
|
||||
if (++adev->vm_manager.xgmi_map_counter == 1)
|
||||
amdgpu_xgmi_set_pstate(adev, 1);
|
||||
mutex_unlock(&adev->vm_manager.lock_pstate);
|
||||
amdgpu_xgmi_set_pstate(adev, AMDGPU_XGMI_PSTATE_MAX_VEGA20);
|
||||
}
|
||||
|
||||
return bo_va;
|
||||
|
@ -2551,12 +2548,8 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
|
|||
|
||||
dma_fence_put(bo_va->last_pt_update);
|
||||
|
||||
if (bo && bo_va->is_xgmi) {
|
||||
mutex_lock(&adev->vm_manager.lock_pstate);
|
||||
if (--adev->vm_manager.xgmi_map_counter == 0)
|
||||
amdgpu_xgmi_set_pstate(adev, 0);
|
||||
mutex_unlock(&adev->vm_manager.lock_pstate);
|
||||
}
|
||||
if (bo && bo_va->is_xgmi)
|
||||
amdgpu_xgmi_set_pstate(adev, AMDGPU_XGMI_PSTATE_MIN);
|
||||
|
||||
kfree(bo_va);
|
||||
}
|
||||
|
@ -3166,9 +3159,6 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev)
|
|||
|
||||
idr_init(&adev->vm_manager.pasid_idr);
|
||||
spin_lock_init(&adev->vm_manager.pasid_lock);
|
||||
|
||||
adev->vm_manager.xgmi_map_counter = 0;
|
||||
mutex_init(&adev->vm_manager.lock_pstate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -349,10 +349,6 @@ struct amdgpu_vm_manager {
|
|||
*/
|
||||
struct idr pasid_idr;
|
||||
spinlock_t pasid_lock;
|
||||
|
||||
/* counter of mapped memory through xgmi */
|
||||
uint32_t xgmi_map_counter;
|
||||
struct mutex lock_pstate;
|
||||
};
|
||||
|
||||
#define amdgpu_vm_copy_pte(adev, ib, pe, src, count) ((adev)->vm_manager.vm_pte_funcs->copy_pte((ib), (pe), (src), (count)))
|
||||
|
|
|
@ -64,7 +64,8 @@ static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p,
|
|||
unsigned int ndw = AMDGPU_VM_SDMA_MIN_NUM_DW;
|
||||
int r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4, &p->job);
|
||||
r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4,
|
||||
p->direct ? AMDGPU_IB_POOL_VM : AMDGPU_IB_POOL_NORMAL, &p->job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -223,7 +224,8 @@ static int amdgpu_vm_sdma_update(struct amdgpu_vm_update_params *p,
|
|||
ndw = max(ndw, AMDGPU_VM_SDMA_MIN_NUM_DW);
|
||||
ndw = min(ndw, AMDGPU_VM_SDMA_MAX_NUM_DW);
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4, &p->job);
|
||||
r = amdgpu_job_alloc_with_ib(p->adev, ndw * 4,
|
||||
p->direct ? AMDGPU_IB_POOL_VM : AMDGPU_IB_POOL_NORMAL, &p->job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -373,7 +373,13 @@ struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev, int lo
|
|||
|
||||
if (lock)
|
||||
mutex_lock(&tmp->hive_lock);
|
||||
tmp->pstate = -1;
|
||||
tmp->pstate = AMDGPU_XGMI_PSTATE_UNKNOWN;
|
||||
tmp->hi_req_gpu = NULL;
|
||||
/*
|
||||
* hive pstate on boot is high in vega20 so we have to go to low
|
||||
* pstate on after boot.
|
||||
*/
|
||||
tmp->hi_req_count = AMDGPU_MAX_XGMI_DEVICE_PER_HIVE;
|
||||
mutex_unlock(&xgmi_mutex);
|
||||
|
||||
return tmp;
|
||||
|
@ -383,50 +389,51 @@ int amdgpu_xgmi_set_pstate(struct amdgpu_device *adev, int pstate)
|
|||
{
|
||||
int ret = 0;
|
||||
struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev, 0);
|
||||
struct amdgpu_device *tmp_adev;
|
||||
bool update_hive_pstate = true;
|
||||
bool is_high_pstate = pstate && adev->asic_type == CHIP_VEGA20;
|
||||
struct amdgpu_device *request_adev = hive->hi_req_gpu ?
|
||||
hive->hi_req_gpu : adev;
|
||||
bool is_hi_req = pstate == AMDGPU_XGMI_PSTATE_MAX_VEGA20;
|
||||
bool init_low = hive->pstate == AMDGPU_XGMI_PSTATE_UNKNOWN;
|
||||
|
||||
if (!hive)
|
||||
/* fw bug so temporarily disable pstate switching */
|
||||
if (!hive || adev->asic_type == CHIP_VEGA20)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&hive->hive_lock);
|
||||
|
||||
if (hive->pstate == pstate) {
|
||||
adev->pstate = is_high_pstate ? pstate : adev->pstate;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev_dbg(adev->dev, "Set xgmi pstate %d.\n", pstate);
|
||||
|
||||
ret = amdgpu_dpm_set_xgmi_pstate(adev, pstate);
|
||||
if (ret) {
|
||||
dev_err(adev->dev,
|
||||
"XGMI: Set pstate failure on device %llx, hive %llx, ret %d",
|
||||
adev->gmc.xgmi.node_id,
|
||||
adev->gmc.xgmi.hive_id, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Update device pstate */
|
||||
adev->pstate = pstate;
|
||||
if (is_hi_req)
|
||||
hive->hi_req_count++;
|
||||
else
|
||||
hive->hi_req_count--;
|
||||
|
||||
/*
|
||||
* Update the hive pstate only all devices of the hive
|
||||
* are in the same pstate
|
||||
* Vega20 only needs single peer to request pstate high for the hive to
|
||||
* go high but all peers must request pstate low for the hive to go low
|
||||
*/
|
||||
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
|
||||
if (tmp_adev->pstate != adev->pstate) {
|
||||
update_hive_pstate = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (update_hive_pstate || is_high_pstate)
|
||||
hive->pstate = pstate;
|
||||
if (hive->pstate == pstate ||
|
||||
(!is_hi_req && hive->hi_req_count && !init_low))
|
||||
goto out;
|
||||
|
||||
dev_dbg(request_adev->dev, "Set xgmi pstate %d.\n", pstate);
|
||||
|
||||
ret = amdgpu_dpm_set_xgmi_pstate(request_adev, pstate);
|
||||
if (ret) {
|
||||
dev_err(request_adev->dev,
|
||||
"XGMI: Set pstate failure on device %llx, hive %llx, ret %d",
|
||||
request_adev->gmc.xgmi.node_id,
|
||||
request_adev->gmc.xgmi.hive_id, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (init_low)
|
||||
hive->pstate = hive->hi_req_count ?
|
||||
hive->pstate : AMDGPU_XGMI_PSTATE_MIN;
|
||||
else {
|
||||
hive->pstate = pstate;
|
||||
hive->hi_req_gpu = pstate != AMDGPU_XGMI_PSTATE_MIN ?
|
||||
adev : NULL;
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&hive->hive_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -507,9 +514,6 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev)
|
|||
goto exit;
|
||||
}
|
||||
|
||||
/* Set default device pstate */
|
||||
adev->pstate = -1;
|
||||
|
||||
top_info = &adev->psp.xgmi_context.top_info;
|
||||
|
||||
list_add_tail(&adev->gmc.xgmi.head, &hive->device_list);
|
||||
|
@ -604,6 +608,8 @@ int amdgpu_xgmi_ras_late_init(struct amdgpu_device *adev)
|
|||
adev->gmc.xgmi.num_physical_nodes == 0)
|
||||
return 0;
|
||||
|
||||
amdgpu_xgmi_reset_ras_error_count(adev);
|
||||
|
||||
if (!adev->gmc.xgmi.ras_if) {
|
||||
adev->gmc.xgmi.ras_if = kmalloc(sizeof(struct ras_common_if), GFP_KERNEL);
|
||||
if (!adev->gmc.xgmi.ras_if)
|
||||
|
@ -668,6 +674,32 @@ uint64_t amdgpu_xgmi_get_relative_phy_addr(struct amdgpu_device *adev,
|
|||
return addr + dram_base_addr;
|
||||
}
|
||||
|
||||
static void pcs_clear_status(struct amdgpu_device *adev, uint32_t pcs_status_reg)
|
||||
{
|
||||
WREG32_PCIE(pcs_status_reg, 0xFFFFFFFF);
|
||||
WREG32_PCIE(pcs_status_reg, 0);
|
||||
}
|
||||
|
||||
void amdgpu_xgmi_reset_ras_error_count(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_ARCTURUS:
|
||||
for (i = 0; i < ARRAY_SIZE(xgmi_pcs_err_status_reg_arct); i++)
|
||||
pcs_clear_status(adev,
|
||||
xgmi_pcs_err_status_reg_arct[i]);
|
||||
break;
|
||||
case CHIP_VEGA20:
|
||||
for (i = 0; i < ARRAY_SIZE(xgmi_pcs_err_status_reg_vg20); i++)
|
||||
pcs_clear_status(adev,
|
||||
xgmi_pcs_err_status_reg_vg20[i]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int amdgpu_xgmi_query_pcs_error_status(struct amdgpu_device *adev,
|
||||
uint32_t value,
|
||||
uint32_t *ue_count,
|
||||
|
@ -758,6 +790,8 @@ int amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
|
|||
break;
|
||||
}
|
||||
|
||||
amdgpu_xgmi_reset_ras_error_count(adev);
|
||||
|
||||
err_data->ue_count += ue_cnt;
|
||||
err_data->ce_count += ce_cnt;
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <drm/task_barrier.h>
|
||||
#include "amdgpu_psp.h"
|
||||
|
||||
|
||||
struct amdgpu_hive_info {
|
||||
uint64_t hive_id;
|
||||
struct list_head device_list;
|
||||
|
@ -33,8 +34,14 @@ struct amdgpu_hive_info {
|
|||
struct kobject *kobj;
|
||||
struct device_attribute dev_attr;
|
||||
struct amdgpu_device *adev;
|
||||
int pstate; /*0 -- low , 1 -- high , -1 unknown*/
|
||||
int hi_req_count;
|
||||
struct amdgpu_device *hi_req_gpu;
|
||||
struct task_barrier tb;
|
||||
enum {
|
||||
AMDGPU_XGMI_PSTATE_MIN,
|
||||
AMDGPU_XGMI_PSTATE_MAX_VEGA20,
|
||||
AMDGPU_XGMI_PSTATE_UNKNOWN
|
||||
} pstate;
|
||||
};
|
||||
|
||||
struct amdgpu_pcs_ras_field {
|
||||
|
@ -56,6 +63,7 @@ uint64_t amdgpu_xgmi_get_relative_phy_addr(struct amdgpu_device *adev,
|
|||
uint64_t addr);
|
||||
int amdgpu_xgmi_query_ras_error_count(struct amdgpu_device *adev,
|
||||
void *ras_error_status);
|
||||
void amdgpu_xgmi_reset_ras_error_count(struct amdgpu_device *adev);
|
||||
|
||||
static inline bool amdgpu_xgmi_same_hive(struct amdgpu_device *adev,
|
||||
struct amdgpu_device *bo_adev)
|
||||
|
|
|
@ -54,6 +54,8 @@
|
|||
#define PLL_INDEX 2
|
||||
#define PLL_DATA 3
|
||||
|
||||
#define ATOM_CMD_TIMEOUT_SEC 20
|
||||
|
||||
typedef struct {
|
||||
struct atom_context *ctx;
|
||||
uint32_t *ps, *ws;
|
||||
|
@ -744,8 +746,9 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
|
|||
cjiffies = jiffies;
|
||||
if (time_after(cjiffies, ctx->last_jump_jiffies)) {
|
||||
cjiffies -= ctx->last_jump_jiffies;
|
||||
if ((jiffies_to_msecs(cjiffies) > 10000)) {
|
||||
DRM_ERROR("atombios stuck in loop for more than 10secs aborting\n");
|
||||
if ((jiffies_to_msecs(cjiffies) > ATOM_CMD_TIMEOUT_SEC*1000)) {
|
||||
DRM_ERROR("atombios stuck in loop for more than %dsecs aborting\n",
|
||||
ATOM_CMD_TIMEOUT_SEC);
|
||||
ctx->abort = true;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1809,12 +1809,6 @@ static uint32_t cik_get_rev_id(struct amdgpu_device *adev)
|
|||
>> CC_DRM_ID_STRAPS__ATI_REV_ID__SHIFT;
|
||||
}
|
||||
|
||||
static void cik_detect_hw_virtualization(struct amdgpu_device *adev)
|
||||
{
|
||||
if (is_virtual_machine()) /* passthrough mode */
|
||||
adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
|
||||
}
|
||||
|
||||
static void cik_flush_hdp(struct amdgpu_device *adev, struct amdgpu_ring *ring)
|
||||
{
|
||||
if (!ring || !ring->funcs->emit_wreg) {
|
||||
|
@ -2177,8 +2171,6 @@ static const struct amdgpu_ip_block_version cik_common_ip_block =
|
|||
|
||||
int cik_set_ip_blocks(struct amdgpu_device *adev)
|
||||
{
|
||||
cik_detect_hw_virtualization(adev);
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_BONAIRE:
|
||||
amdgpu_device_ip_block_add(adev, &cik_common_ip_block);
|
||||
|
|
|
@ -320,8 +320,6 @@ static void cik_sdma_gfx_stop(struct amdgpu_device *adev)
|
|||
WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl);
|
||||
WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], 0);
|
||||
}
|
||||
sdma0->sched.ready = false;
|
||||
sdma1->sched.ready = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -679,7 +677,8 @@ static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
tmp = 0xCAFEDEAD;
|
||||
adev->wb.wb[index] = cpu_to_le32(tmp);
|
||||
memset(&ib, 0, sizeof(ib));
|
||||
r = amdgpu_ib_get(adev, NULL, 256, &ib);
|
||||
r = amdgpu_ib_get(adev, NULL, 256,
|
||||
AMDGPU_IB_POOL_DIRECT, &ib);
|
||||
if (r)
|
||||
goto err0;
|
||||
|
||||
|
@ -980,7 +979,8 @@ static int cik_sdma_sw_init(void *handle)
|
|||
&adev->sdma.trap_irq,
|
||||
(i == 0) ?
|
||||
AMDGPU_SDMA_IRQ_INSTANCE0 :
|
||||
AMDGPU_SDMA_IRQ_INSTANCE1);
|
||||
AMDGPU_SDMA_IRQ_INSTANCE1,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -2303,9 +2303,9 @@ static void dce_v10_0_hide_cursor(struct drm_crtc *crtc)
|
|||
struct amdgpu_device *adev = crtc->dev->dev_private;
|
||||
u32 tmp;
|
||||
|
||||
tmp = RREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
|
||||
tmp = RREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
|
||||
tmp = REG_SET_FIELD(tmp, CUR_CONTROL, CURSOR_EN, 0);
|
||||
WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
|
||||
WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
|
||||
}
|
||||
|
||||
static void dce_v10_0_show_cursor(struct drm_crtc *crtc)
|
||||
|
@ -2319,10 +2319,10 @@ static void dce_v10_0_show_cursor(struct drm_crtc *crtc)
|
|||
WREG32(mmCUR_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset,
|
||||
lower_32_bits(amdgpu_crtc->cursor_addr));
|
||||
|
||||
tmp = RREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
|
||||
tmp = RREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
|
||||
tmp = REG_SET_FIELD(tmp, CUR_CONTROL, CURSOR_EN, 1);
|
||||
tmp = REG_SET_FIELD(tmp, CUR_CONTROL, CURSOR_MODE, 2);
|
||||
WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
|
||||
WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
|
||||
}
|
||||
|
||||
static int dce_v10_0_cursor_move_locked(struct drm_crtc *crtc,
|
||||
|
|
|
@ -2382,9 +2382,9 @@ static void dce_v11_0_hide_cursor(struct drm_crtc *crtc)
|
|||
struct amdgpu_device *adev = crtc->dev->dev_private;
|
||||
u32 tmp;
|
||||
|
||||
tmp = RREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
|
||||
tmp = RREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
|
||||
tmp = REG_SET_FIELD(tmp, CUR_CONTROL, CURSOR_EN, 0);
|
||||
WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
|
||||
WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
|
||||
}
|
||||
|
||||
static void dce_v11_0_show_cursor(struct drm_crtc *crtc)
|
||||
|
@ -2398,10 +2398,10 @@ static void dce_v11_0_show_cursor(struct drm_crtc *crtc)
|
|||
WREG32(mmCUR_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset,
|
||||
lower_32_bits(amdgpu_crtc->cursor_addr));
|
||||
|
||||
tmp = RREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
|
||||
tmp = RREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset);
|
||||
tmp = REG_SET_FIELD(tmp, CUR_CONTROL, CURSOR_EN, 1);
|
||||
tmp = REG_SET_FIELD(tmp, CUR_CONTROL, CURSOR_MODE, 2);
|
||||
WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
|
||||
WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset, tmp);
|
||||
}
|
||||
|
||||
static int dce_v11_0_cursor_move_locked(struct drm_crtc *crtc,
|
||||
|
|
|
@ -2194,9 +2194,9 @@ static void dce_v6_0_hide_cursor(struct drm_crtc *crtc)
|
|||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
struct amdgpu_device *adev = crtc->dev->dev_private;
|
||||
|
||||
WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
|
||||
(CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
|
||||
(CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
|
||||
WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
|
||||
(CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
|
||||
(CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
|
||||
|
||||
|
||||
}
|
||||
|
@ -2211,10 +2211,10 @@ static void dce_v6_0_show_cursor(struct drm_crtc *crtc)
|
|||
WREG32(mmCUR_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset,
|
||||
lower_32_bits(amdgpu_crtc->cursor_addr));
|
||||
|
||||
WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
|
||||
CUR_CONTROL__CURSOR_EN_MASK |
|
||||
(CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
|
||||
(CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
|
||||
WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
|
||||
CUR_CONTROL__CURSOR_EN_MASK |
|
||||
(CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
|
||||
(CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2205,9 +2205,9 @@ static void dce_v8_0_hide_cursor(struct drm_crtc *crtc)
|
|||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
struct amdgpu_device *adev = crtc->dev->dev_private;
|
||||
|
||||
WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
|
||||
(CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
|
||||
(CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
|
||||
WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
|
||||
(CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
|
||||
(CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
|
||||
}
|
||||
|
||||
static void dce_v8_0_show_cursor(struct drm_crtc *crtc)
|
||||
|
@ -2220,10 +2220,10 @@ static void dce_v8_0_show_cursor(struct drm_crtc *crtc)
|
|||
WREG32(mmCUR_SURFACE_ADDRESS + amdgpu_crtc->crtc_offset,
|
||||
lower_32_bits(amdgpu_crtc->cursor_addr));
|
||||
|
||||
WREG32_IDX(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
|
||||
CUR_CONTROL__CURSOR_EN_MASK |
|
||||
(CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
|
||||
(CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
|
||||
WREG32(mmCUR_CONTROL + amdgpu_crtc->crtc_offset,
|
||||
CUR_CONTROL__CURSOR_EN_MASK |
|
||||
(CURSOR_24_8_PRE_MULT << CUR_CONTROL__CURSOR_MODE__SHIFT) |
|
||||
(CURSOR_URGENT_1_2 << CUR_CONTROL__CURSOR_URGENT_CONTROL__SHIFT));
|
||||
}
|
||||
|
||||
static int dce_v8_0_cursor_move_locked(struct drm_crtc *crtc,
|
||||
|
|
|
@ -172,8 +172,9 @@ static void dce_virtual_crtc_disable(struct drm_crtc *crtc)
|
|||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
|
||||
drm_crtc_vblank_off(crtc);
|
||||
|
||||
amdgpu_crtc->enabled = false;
|
||||
amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
|
||||
amdgpu_crtc->encoder = NULL;
|
||||
amdgpu_crtc->connector = NULL;
|
||||
|
@ -286,7 +287,7 @@ static int dce_virtual_get_modes(struct drm_connector *connector)
|
|||
static const struct mode_size {
|
||||
int w;
|
||||
int h;
|
||||
} common_modes[17] = {
|
||||
} common_modes[21] = {
|
||||
{ 640, 480},
|
||||
{ 720, 480},
|
||||
{ 800, 600},
|
||||
|
@ -303,10 +304,14 @@ static int dce_virtual_get_modes(struct drm_connector *connector)
|
|||
{1680, 1050},
|
||||
{1600, 1200},
|
||||
{1920, 1080},
|
||||
{1920, 1200}
|
||||
{1920, 1200},
|
||||
{4096, 3112},
|
||||
{3656, 2664},
|
||||
{3840, 2160},
|
||||
{4096, 2160},
|
||||
};
|
||||
|
||||
for (i = 0; i < 17; i++) {
|
||||
for (i = 0; i < 21; i++) {
|
||||
mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
|
||||
drm_mode_probed_add(connector, mode);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1914,7 +1914,8 @@ static int gfx_v6_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
|
||||
WREG32(scratch, 0xCAFEDEAD);
|
||||
memset(&ib, 0, sizeof(ib));
|
||||
r = amdgpu_ib_get(adev, NULL, 256, &ib);
|
||||
r = amdgpu_ib_get(adev, NULL, 256,
|
||||
AMDGPU_IB_POOL_DIRECT, &ib);
|
||||
if (r)
|
||||
goto err1;
|
||||
|
||||
|
@ -1950,7 +1951,6 @@ err1:
|
|||
|
||||
static void gfx_v6_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
int i;
|
||||
if (enable) {
|
||||
WREG32(mmCP_ME_CNTL, 0);
|
||||
} else {
|
||||
|
@ -1958,10 +1958,6 @@ static void gfx_v6_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
|
|||
CP_ME_CNTL__PFP_HALT_MASK |
|
||||
CP_ME_CNTL__CE_HALT_MASK));
|
||||
WREG32(mmSCRATCH_UMSK, 0);
|
||||
for (i = 0; i < adev->gfx.num_gfx_rings; i++)
|
||||
adev->gfx.gfx_ring[i].sched.ready = false;
|
||||
for (i = 0; i < adev->gfx.num_compute_rings; i++)
|
||||
adev->gfx.compute_ring[i].sched.ready = false;
|
||||
}
|
||||
udelay(50);
|
||||
}
|
||||
|
@ -3114,7 +3110,9 @@ static int gfx_v6_0_sw_init(void *handle)
|
|||
ring->ring_obj = NULL;
|
||||
sprintf(ring->name, "gfx");
|
||||
r = amdgpu_ring_init(adev, ring, 1024,
|
||||
&adev->gfx.eop_irq, AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP);
|
||||
&adev->gfx.eop_irq,
|
||||
AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
@ -3136,7 +3134,8 @@ static int gfx_v6_0_sw_init(void *handle)
|
|||
sprintf(ring->name, "comp_%d.%d.%d", ring->me, ring->pipe, ring->queue);
|
||||
irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP + ring->pipe;
|
||||
r = amdgpu_ring_init(adev, ring, 1024,
|
||||
&adev->gfx.eop_irq, irq_type);
|
||||
&adev->gfx.eop_irq, irq_type,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -2364,7 +2364,8 @@ static int gfx_v7_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
|
||||
WREG32(scratch, 0xCAFEDEAD);
|
||||
memset(&ib, 0, sizeof(ib));
|
||||
r = amdgpu_ib_get(adev, NULL, 256, &ib);
|
||||
r = amdgpu_ib_get(adev, NULL, 256,
|
||||
AMDGPU_IB_POOL_DIRECT, &ib);
|
||||
if (r)
|
||||
goto err1;
|
||||
|
||||
|
@ -2431,15 +2432,12 @@ err1:
|
|||
*/
|
||||
static void gfx_v7_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (enable) {
|
||||
if (enable)
|
||||
WREG32(mmCP_ME_CNTL, 0);
|
||||
} else {
|
||||
WREG32(mmCP_ME_CNTL, (CP_ME_CNTL__ME_HALT_MASK | CP_ME_CNTL__PFP_HALT_MASK | CP_ME_CNTL__CE_HALT_MASK));
|
||||
for (i = 0; i < adev->gfx.num_gfx_rings; i++)
|
||||
adev->gfx.gfx_ring[i].sched.ready = false;
|
||||
}
|
||||
else
|
||||
WREG32(mmCP_ME_CNTL, (CP_ME_CNTL__ME_HALT_MASK |
|
||||
CP_ME_CNTL__PFP_HALT_MASK |
|
||||
CP_ME_CNTL__CE_HALT_MASK));
|
||||
udelay(50);
|
||||
}
|
||||
|
||||
|
@ -2700,15 +2698,11 @@ static void gfx_v7_0_ring_set_wptr_compute(struct amdgpu_ring *ring)
|
|||
*/
|
||||
static void gfx_v7_0_cp_compute_enable(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (enable) {
|
||||
if (enable)
|
||||
WREG32(mmCP_MEC_CNTL, 0);
|
||||
} else {
|
||||
WREG32(mmCP_MEC_CNTL, (CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK));
|
||||
for (i = 0; i < adev->gfx.num_compute_rings; i++)
|
||||
adev->gfx.compute_ring[i].sched.ready = false;
|
||||
}
|
||||
else
|
||||
WREG32(mmCP_MEC_CNTL, (CP_MEC_CNTL__MEC_ME1_HALT_MASK |
|
||||
CP_MEC_CNTL__MEC_ME2_HALT_MASK));
|
||||
udelay(50);
|
||||
}
|
||||
|
||||
|
@ -4439,7 +4433,8 @@ static int gfx_v7_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
|
|||
|
||||
/* type-2 packets are deprecated on MEC, use type-3 instead */
|
||||
r = amdgpu_ring_init(adev, ring, 1024,
|
||||
&adev->gfx.eop_irq, irq_type);
|
||||
&adev->gfx.eop_irq, irq_type,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -4511,7 +4506,9 @@ static int gfx_v7_0_sw_init(void *handle)
|
|||
ring->ring_obj = NULL;
|
||||
sprintf(ring->name, "gfx");
|
||||
r = amdgpu_ring_init(adev, ring, 1024,
|
||||
&adev->gfx.eop_irq, AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP);
|
||||
&adev->gfx.eop_irq,
|
||||
AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -888,7 +888,8 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
gpu_addr = adev->wb.gpu_addr + (index * 4);
|
||||
adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD);
|
||||
memset(&ib, 0, sizeof(ib));
|
||||
r = amdgpu_ib_get(adev, NULL, 16, &ib);
|
||||
r = amdgpu_ib_get(adev, NULL, 16,
|
||||
AMDGPU_IB_POOL_DIRECT, &ib);
|
||||
if (r)
|
||||
goto err1;
|
||||
|
||||
|
@ -1550,7 +1551,8 @@ static int gfx_v8_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)
|
|||
|
||||
/* allocate an indirect buffer to put the commands in */
|
||||
memset(&ib, 0, sizeof(ib));
|
||||
r = amdgpu_ib_get(adev, NULL, total_size, &ib);
|
||||
r = amdgpu_ib_get(adev, NULL, total_size,
|
||||
AMDGPU_IB_POOL_DIRECT, &ib);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu: failed to get ib (%d).\n", r);
|
||||
return r;
|
||||
|
@ -1892,6 +1894,7 @@ static int gfx_v8_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
|
|||
int r;
|
||||
unsigned irq_type;
|
||||
struct amdgpu_ring *ring = &adev->gfx.compute_ring[ring_id];
|
||||
unsigned int hw_prio;
|
||||
|
||||
ring = &adev->gfx.compute_ring[ring_id];
|
||||
|
||||
|
@ -1911,9 +1914,11 @@ static int gfx_v8_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
|
|||
+ ((ring->me - 1) * adev->gfx.mec.num_pipe_per_mec)
|
||||
+ ring->pipe;
|
||||
|
||||
hw_prio = amdgpu_gfx_is_high_priority_compute_queue(adev, ring->queue) ?
|
||||
AMDGPU_GFX_PIPE_PRIO_HIGH : AMDGPU_RING_PRIO_DEFAULT;
|
||||
/* type-2 packets are deprecated on MEC, use type-3 instead */
|
||||
r = amdgpu_ring_init(adev, ring, 1024,
|
||||
&adev->gfx.eop_irq, irq_type);
|
||||
&adev->gfx.eop_irq, irq_type, hw_prio);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -2017,7 +2022,8 @@ static int gfx_v8_0_sw_init(void *handle)
|
|||
}
|
||||
|
||||
r = amdgpu_ring_init(adev, ring, 1024, &adev->gfx.eop_irq,
|
||||
AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP);
|
||||
AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
@ -4120,7 +4126,6 @@ static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev)
|
|||
|
||||
static void gfx_v8_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
int i;
|
||||
u32 tmp = RREG32(mmCP_ME_CNTL);
|
||||
|
||||
if (enable) {
|
||||
|
@ -4131,8 +4136,6 @@ static void gfx_v8_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
|
|||
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, ME_HALT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, PFP_HALT, 1);
|
||||
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_HALT, 1);
|
||||
for (i = 0; i < adev->gfx.num_gfx_rings; i++)
|
||||
adev->gfx.gfx_ring[i].sched.ready = false;
|
||||
}
|
||||
WREG32(mmCP_ME_CNTL, tmp);
|
||||
udelay(50);
|
||||
|
@ -4320,14 +4323,10 @@ static int gfx_v8_0_cp_gfx_resume(struct amdgpu_device *adev)
|
|||
|
||||
static void gfx_v8_0_cp_compute_enable(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (enable) {
|
||||
WREG32(mmCP_MEC_CNTL, 0);
|
||||
} else {
|
||||
WREG32(mmCP_MEC_CNTL, (CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK));
|
||||
for (i = 0; i < adev->gfx.num_compute_rings; i++)
|
||||
adev->gfx.compute_ring[i].sched.ready = false;
|
||||
adev->gfx.kiq.ring.sched.ready = false;
|
||||
}
|
||||
udelay(50);
|
||||
|
@ -4437,11 +4436,8 @@ static void gfx_v8_0_mqd_set_priority(struct amdgpu_ring *ring, struct vi_mqd *m
|
|||
if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) {
|
||||
if (amdgpu_gfx_is_high_priority_compute_queue(adev, ring->queue)) {
|
||||
mqd->cp_hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_HIGH;
|
||||
ring->has_high_prio = true;
|
||||
mqd->cp_hqd_queue_priority =
|
||||
AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM;
|
||||
} else {
|
||||
ring->has_high_prio = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5619,12 +5615,18 @@ static void gfx_v8_0_update_spm_vmid(struct amdgpu_device *adev, unsigned vmid)
|
|||
{
|
||||
u32 data;
|
||||
|
||||
data = RREG32(mmRLC_SPM_VMID);
|
||||
if (amdgpu_sriov_is_pp_one_vf(adev))
|
||||
data = RREG32_NO_KIQ(mmRLC_SPM_VMID);
|
||||
else
|
||||
data = RREG32(mmRLC_SPM_VMID);
|
||||
|
||||
data &= ~RLC_SPM_VMID__RLC_SPM_VMID_MASK;
|
||||
data |= (vmid & RLC_SPM_VMID__RLC_SPM_VMID_MASK) << RLC_SPM_VMID__RLC_SPM_VMID__SHIFT;
|
||||
|
||||
WREG32(mmRLC_SPM_VMID, data);
|
||||
if (amdgpu_sriov_is_pp_one_vf(adev))
|
||||
WREG32_NO_KIQ(mmRLC_SPM_VMID, data);
|
||||
else
|
||||
WREG32(mmRLC_SPM_VMID, data);
|
||||
}
|
||||
|
||||
static const struct amdgpu_rlc_funcs iceland_rlc_funcs = {
|
||||
|
@ -6387,10 +6389,10 @@ static void gfx_v8_0_ring_emit_patch_cond_exec(struct amdgpu_ring *ring, unsigne
|
|||
ring->ring[offset] = (ring->ring_size >> 2) - offset + cur;
|
||||
}
|
||||
|
||||
static void gfx_v8_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg)
|
||||
static void gfx_v8_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg,
|
||||
uint32_t reg_val_offs)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq;
|
||||
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_COPY_DATA, 4));
|
||||
amdgpu_ring_write(ring, 0 | /* src: register*/
|
||||
|
@ -6399,9 +6401,9 @@ static void gfx_v8_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg)
|
|||
amdgpu_ring_write(ring, reg);
|
||||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, lower_32_bits(adev->wb.gpu_addr +
|
||||
kiq->reg_val_offs * 4));
|
||||
reg_val_offs * 4));
|
||||
amdgpu_ring_write(ring, upper_32_bits(adev->wb.gpu_addr +
|
||||
kiq->reg_val_offs * 4));
|
||||
reg_val_offs * 4));
|
||||
}
|
||||
|
||||
static void gfx_v8_0_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg,
|
||||
|
|
|
@ -50,18 +50,14 @@
|
|||
|
||||
#include "gfx_v9_4.h"
|
||||
|
||||
#include "asic_reg/pwr/pwr_10_0_offset.h"
|
||||
#include "asic_reg/pwr/pwr_10_0_sh_mask.h"
|
||||
|
||||
#define GFX9_NUM_GFX_RINGS 1
|
||||
#define GFX9_MEC_HPD_SIZE 4096
|
||||
#define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L
|
||||
#define RLC_SAVE_RESTORE_ADDR_STARTING_OFFSET 0x00000000L
|
||||
|
||||
#define mmPWR_MISC_CNTL_STATUS 0x0183
|
||||
#define mmPWR_MISC_CNTL_STATUS_BASE_IDX 0
|
||||
#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN__SHIFT 0x0
|
||||
#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT 0x1
|
||||
#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN_MASK 0x00000001L
|
||||
#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK 0x00000006L
|
||||
|
||||
#define mmGCEA_PROBE_MAP 0x070c
|
||||
#define mmGCEA_PROBE_MAP_BASE_IDX 0
|
||||
|
||||
|
@ -1082,7 +1078,8 @@ static int gfx_v9_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
gpu_addr = adev->wb.gpu_addr + (index * 4);
|
||||
adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD);
|
||||
memset(&ib, 0, sizeof(ib));
|
||||
r = amdgpu_ib_get(adev, NULL, 16, &ib);
|
||||
r = amdgpu_ib_get(adev, NULL, 16,
|
||||
AMDGPU_IB_POOL_DIRECT, &ib);
|
||||
if (r)
|
||||
goto err1;
|
||||
|
||||
|
@ -2197,6 +2194,7 @@ static int gfx_v9_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
|
|||
int r;
|
||||
unsigned irq_type;
|
||||
struct amdgpu_ring *ring = &adev->gfx.compute_ring[ring_id];
|
||||
unsigned int hw_prio;
|
||||
|
||||
ring = &adev->gfx.compute_ring[ring_id];
|
||||
|
||||
|
@ -2215,10 +2213,11 @@ static int gfx_v9_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
|
|||
irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
|
||||
+ ((ring->me - 1) * adev->gfx.mec.num_pipe_per_mec)
|
||||
+ ring->pipe;
|
||||
|
||||
hw_prio = amdgpu_gfx_is_high_priority_compute_queue(adev, ring->queue) ?
|
||||
AMDGPU_GFX_PIPE_PRIO_HIGH : AMDGPU_GFX_PIPE_PRIO_NORMAL;
|
||||
/* type-2 packets are deprecated on MEC, use type-3 instead */
|
||||
r = amdgpu_ring_init(adev, ring, 1024,
|
||||
&adev->gfx.eop_irq, irq_type);
|
||||
&adev->gfx.eop_irq, irq_type, hw_prio);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -2312,7 +2311,9 @@ static int gfx_v9_0_sw_init(void *handle)
|
|||
ring->use_doorbell = true;
|
||||
ring->doorbell_index = adev->doorbell_index.gfx_ring0 << 1;
|
||||
r = amdgpu_ring_init(adev, ring, 1024,
|
||||
&adev->gfx.eop_irq, AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP);
|
||||
&adev->gfx.eop_irq,
|
||||
AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
@ -3102,16 +3103,11 @@ static int gfx_v9_0_rlc_resume(struct amdgpu_device *adev)
|
|||
|
||||
static void gfx_v9_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
int i;
|
||||
u32 tmp = RREG32_SOC15(GC, 0, mmCP_ME_CNTL);
|
||||
|
||||
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, ME_HALT, enable ? 0 : 1);
|
||||
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, PFP_HALT, enable ? 0 : 1);
|
||||
tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_HALT, enable ? 0 : 1);
|
||||
if (!enable) {
|
||||
for (i = 0; i < adev->gfx.num_gfx_rings; i++)
|
||||
adev->gfx.gfx_ring[i].sched.ready = false;
|
||||
}
|
||||
WREG32_SOC15_RLC(GC, 0, mmCP_ME_CNTL, tmp);
|
||||
udelay(50);
|
||||
}
|
||||
|
@ -3307,15 +3303,11 @@ static int gfx_v9_0_cp_gfx_resume(struct amdgpu_device *adev)
|
|||
|
||||
static void gfx_v9_0_cp_compute_enable(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (enable) {
|
||||
WREG32_SOC15_RLC(GC, 0, mmCP_MEC_CNTL, 0);
|
||||
} else {
|
||||
WREG32_SOC15_RLC(GC, 0, mmCP_MEC_CNTL,
|
||||
(CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK));
|
||||
for (i = 0; i < adev->gfx.num_compute_rings; i++)
|
||||
adev->gfx.compute_ring[i].sched.ready = false;
|
||||
adev->gfx.kiq.ring.sched.ready = false;
|
||||
}
|
||||
udelay(50);
|
||||
|
@ -3385,11 +3377,8 @@ static void gfx_v9_0_mqd_set_priority(struct amdgpu_ring *ring, struct v9_mqd *m
|
|||
if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) {
|
||||
if (amdgpu_gfx_is_high_priority_compute_queue(adev, ring->queue)) {
|
||||
mqd->cp_hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_HIGH;
|
||||
ring->has_high_prio = true;
|
||||
mqd->cp_hqd_queue_priority =
|
||||
AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM;
|
||||
} else {
|
||||
ring->has_high_prio = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4056,13 +4045,19 @@ static uint64_t gfx_v9_0_kiq_read_clock(struct amdgpu_device *adev)
|
|||
{
|
||||
signed long r, cnt = 0;
|
||||
unsigned long flags;
|
||||
uint32_t seq;
|
||||
uint32_t seq, reg_val_offs = 0;
|
||||
uint64_t value = 0;
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq;
|
||||
struct amdgpu_ring *ring = &kiq->ring;
|
||||
|
||||
BUG_ON(!ring->funcs->emit_rreg);
|
||||
|
||||
spin_lock_irqsave(&kiq->ring_lock, flags);
|
||||
if (amdgpu_device_wb_get(adev, ®_val_offs)) {
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
pr_err("critical bug! too many kiq readers\n");
|
||||
goto failed_kiq_read;
|
||||
}
|
||||
amdgpu_ring_alloc(ring, 32);
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_COPY_DATA, 4));
|
||||
amdgpu_ring_write(ring, 9 | /* src: register*/
|
||||
|
@ -4072,9 +4067,9 @@ static uint64_t gfx_v9_0_kiq_read_clock(struct amdgpu_device *adev)
|
|||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, lower_32_bits(adev->wb.gpu_addr +
|
||||
kiq->reg_val_offs * 4));
|
||||
reg_val_offs * 4));
|
||||
amdgpu_ring_write(ring, upper_32_bits(adev->wb.gpu_addr +
|
||||
kiq->reg_val_offs * 4));
|
||||
reg_val_offs * 4));
|
||||
amdgpu_fence_emit_polling(ring, &seq);
|
||||
amdgpu_ring_commit(ring);
|
||||
spin_unlock_irqrestore(&kiq->ring_lock, flags);
|
||||
|
@ -4101,8 +4096,11 @@ static uint64_t gfx_v9_0_kiq_read_clock(struct amdgpu_device *adev)
|
|||
if (cnt > MAX_KIQ_REG_TRY)
|
||||
goto failed_kiq_read;
|
||||
|
||||
return (uint64_t)adev->wb.wb[kiq->reg_val_offs] |
|
||||
(uint64_t)adev->wb.wb[kiq->reg_val_offs + 1 ] << 32ULL;
|
||||
mb();
|
||||
value = (uint64_t)adev->wb.wb[reg_val_offs] |
|
||||
(uint64_t)adev->wb.wb[reg_val_offs + 1 ] << 32ULL;
|
||||
amdgpu_device_wb_free(adev, reg_val_offs);
|
||||
return value;
|
||||
|
||||
failed_kiq_read:
|
||||
pr_err("failed to read gpu clock\n");
|
||||
|
@ -4489,7 +4487,8 @@ static int gfx_v9_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)
|
|||
|
||||
/* allocate an indirect buffer to put the commands in */
|
||||
memset(&ib, 0, sizeof(ib));
|
||||
r = amdgpu_ib_get(adev, NULL, total_size, &ib);
|
||||
r = amdgpu_ib_get(adev, NULL, total_size,
|
||||
AMDGPU_IB_POOL_DIRECT, &ib);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu: failed to get ib (%d).\n", r);
|
||||
return r;
|
||||
|
@ -4960,14 +4959,21 @@ static int gfx_v9_0_update_gfx_clock_gating(struct amdgpu_device *adev,
|
|||
|
||||
static void gfx_v9_0_update_spm_vmid(struct amdgpu_device *adev, unsigned vmid)
|
||||
{
|
||||
u32 data;
|
||||
u32 reg, data;
|
||||
|
||||
data = RREG32_SOC15(GC, 0, mmRLC_SPM_MC_CNTL);
|
||||
reg = SOC15_REG_OFFSET(GC, 0, mmRLC_SPM_MC_CNTL);
|
||||
if (amdgpu_sriov_is_pp_one_vf(adev))
|
||||
data = RREG32_NO_KIQ(reg);
|
||||
else
|
||||
data = RREG32(reg);
|
||||
|
||||
data &= ~RLC_SPM_MC_CNTL__RLC_SPM_VMID_MASK;
|
||||
data |= (vmid & RLC_SPM_MC_CNTL__RLC_SPM_VMID_MASK) << RLC_SPM_MC_CNTL__RLC_SPM_VMID__SHIFT;
|
||||
|
||||
WREG32_SOC15(GC, 0, mmRLC_SPM_MC_CNTL, data);
|
||||
if (amdgpu_sriov_is_pp_one_vf(adev))
|
||||
WREG32_SOC15_NO_KIQ(GC, 0, mmRLC_SPM_MC_CNTL, data);
|
||||
else
|
||||
WREG32_SOC15(GC, 0, mmRLC_SPM_MC_CNTL, data);
|
||||
}
|
||||
|
||||
static bool gfx_v9_0_check_rlcg_range(struct amdgpu_device *adev,
|
||||
|
@ -5493,10 +5499,10 @@ static void gfx_v9_0_ring_emit_patch_cond_exec(struct amdgpu_ring *ring, unsigne
|
|||
ring->ring[offset] = (ring->ring_size>>2) - offset + cur;
|
||||
}
|
||||
|
||||
static void gfx_v9_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg)
|
||||
static void gfx_v9_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg,
|
||||
uint32_t reg_val_offs)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct amdgpu_kiq *kiq = &adev->gfx.kiq;
|
||||
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_COPY_DATA, 4));
|
||||
amdgpu_ring_write(ring, 0 | /* src: register*/
|
||||
|
@ -5505,9 +5511,9 @@ static void gfx_v9_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg)
|
|||
amdgpu_ring_write(ring, reg);
|
||||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, lower_32_bits(adev->wb.gpu_addr +
|
||||
kiq->reg_val_offs * 4));
|
||||
reg_val_offs * 4));
|
||||
amdgpu_ring_write(ring, upper_32_bits(adev->wb.gpu_addr +
|
||||
kiq->reg_val_offs * 4));
|
||||
reg_val_offs * 4));
|
||||
}
|
||||
|
||||
static void gfx_v9_0_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg,
|
||||
|
@ -6408,15 +6414,15 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
|
|||
|
||||
sec_count = REG_GET_FIELD(data, VM_L2_MEM_ECC_CNT, SEC_COUNT);
|
||||
if (sec_count) {
|
||||
DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
|
||||
vml2_mems[i], sec_count);
|
||||
dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
|
||||
"SEC %d\n", i, vml2_mems[i], sec_count);
|
||||
err_data->ce_count += sec_count;
|
||||
}
|
||||
|
||||
ded_count = REG_GET_FIELD(data, VM_L2_MEM_ECC_CNT, DED_COUNT);
|
||||
if (ded_count) {
|
||||
DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
|
||||
vml2_mems[i], ded_count);
|
||||
dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
|
||||
"DED %d\n", i, vml2_mems[i], ded_count);
|
||||
err_data->ue_count += ded_count;
|
||||
}
|
||||
}
|
||||
|
@ -6428,16 +6434,16 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
|
|||
sec_count = REG_GET_FIELD(data, VM_L2_WALKER_MEM_ECC_CNT,
|
||||
SEC_COUNT);
|
||||
if (sec_count) {
|
||||
DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
|
||||
vml2_walker_mems[i], sec_count);
|
||||
dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
|
||||
"SEC %d\n", i, vml2_walker_mems[i], sec_count);
|
||||
err_data->ce_count += sec_count;
|
||||
}
|
||||
|
||||
ded_count = REG_GET_FIELD(data, VM_L2_WALKER_MEM_ECC_CNT,
|
||||
DED_COUNT);
|
||||
if (ded_count) {
|
||||
DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
|
||||
vml2_walker_mems[i], ded_count);
|
||||
dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
|
||||
"DED %d\n", i, vml2_walker_mems[i], ded_count);
|
||||
err_data->ue_count += ded_count;
|
||||
}
|
||||
}
|
||||
|
@ -6448,8 +6454,9 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
|
|||
|
||||
sec_count = (data & 0x00006000L) >> 0xd;
|
||||
if (sec_count) {
|
||||
DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
|
||||
atc_l2_cache_2m_mems[i], sec_count);
|
||||
dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
|
||||
"SEC %d\n", i, atc_l2_cache_2m_mems[i],
|
||||
sec_count);
|
||||
err_data->ce_count += sec_count;
|
||||
}
|
||||
}
|
||||
|
@ -6460,15 +6467,17 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
|
|||
|
||||
sec_count = (data & 0x00006000L) >> 0xd;
|
||||
if (sec_count) {
|
||||
DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
|
||||
atc_l2_cache_4k_mems[i], sec_count);
|
||||
dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
|
||||
"SEC %d\n", i, atc_l2_cache_4k_mems[i],
|
||||
sec_count);
|
||||
err_data->ce_count += sec_count;
|
||||
}
|
||||
|
||||
ded_count = (data & 0x00018000L) >> 0xf;
|
||||
if (ded_count) {
|
||||
DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
|
||||
atc_l2_cache_4k_mems[i], ded_count);
|
||||
dev_info(adev->dev, "Instance[%d]: SubBlock %s, "
|
||||
"DED %d\n", i, atc_l2_cache_4k_mems[i],
|
||||
ded_count);
|
||||
err_data->ue_count += ded_count;
|
||||
}
|
||||
}
|
||||
|
@ -6481,7 +6490,8 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v9_0_ras_error_count(const struct soc15_reg_entry *reg,
|
||||
static int gfx_v9_0_ras_error_count(struct amdgpu_device *adev,
|
||||
const struct soc15_reg_entry *reg,
|
||||
uint32_t se_id, uint32_t inst_id, uint32_t value,
|
||||
uint32_t *sec_count, uint32_t *ded_count)
|
||||
{
|
||||
|
@ -6498,7 +6508,8 @@ static int gfx_v9_0_ras_error_count(const struct soc15_reg_entry *reg,
|
|||
gfx_v9_0_ras_fields[i].sec_count_mask) >>
|
||||
gfx_v9_0_ras_fields[i].sec_count_shift;
|
||||
if (sec_cnt) {
|
||||
DRM_INFO("GFX SubBlock %s, Instance[%d][%d], SEC %d\n",
|
||||
dev_info(adev->dev, "GFX SubBlock %s, "
|
||||
"Instance[%d][%d], SEC %d\n",
|
||||
gfx_v9_0_ras_fields[i].name,
|
||||
se_id, inst_id,
|
||||
sec_cnt);
|
||||
|
@ -6509,7 +6520,8 @@ static int gfx_v9_0_ras_error_count(const struct soc15_reg_entry *reg,
|
|||
gfx_v9_0_ras_fields[i].ded_count_mask) >>
|
||||
gfx_v9_0_ras_fields[i].ded_count_shift;
|
||||
if (ded_cnt) {
|
||||
DRM_INFO("GFX SubBlock %s, Instance[%d][%d], DED %d\n",
|
||||
dev_info(adev->dev, "GFX SubBlock %s, "
|
||||
"Instance[%d][%d], DED %d\n",
|
||||
gfx_v9_0_ras_fields[i].name,
|
||||
se_id, inst_id,
|
||||
ded_cnt);
|
||||
|
@ -6598,9 +6610,10 @@ static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
|
|||
reg_value =
|
||||
RREG32(SOC15_REG_ENTRY_OFFSET(gfx_v9_0_edc_counter_regs[i]));
|
||||
if (reg_value)
|
||||
gfx_v9_0_ras_error_count(&gfx_v9_0_edc_counter_regs[i],
|
||||
j, k, reg_value,
|
||||
&sec_count, &ded_count);
|
||||
gfx_v9_0_ras_error_count(adev,
|
||||
&gfx_v9_0_edc_counter_regs[i],
|
||||
j, k, reg_value,
|
||||
&sec_count, &ded_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -732,7 +732,8 @@ static int gfx_v9_4_query_utc_edc_status(struct amdgpu_device *adev,
|
|||
sec_count = REG_GET_FIELD(data, VML2_WALKER_MEM_ECC_CNTL,
|
||||
SEC_COUNT);
|
||||
if (sec_count) {
|
||||
DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
|
||||
dev_info(adev->dev,
|
||||
"Instance[%d]: SubBlock %s, SEC %d\n", i,
|
||||
vml2_walker_mems[i], sec_count);
|
||||
err_data->ce_count += sec_count;
|
||||
}
|
||||
|
@ -740,7 +741,8 @@ static int gfx_v9_4_query_utc_edc_status(struct amdgpu_device *adev,
|
|||
ded_count = REG_GET_FIELD(data, VML2_WALKER_MEM_ECC_CNTL,
|
||||
DED_COUNT);
|
||||
if (ded_count) {
|
||||
DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
|
||||
dev_info(adev->dev,
|
||||
"Instance[%d]: SubBlock %s, DED %d\n", i,
|
||||
vml2_walker_mems[i], ded_count);
|
||||
err_data->ue_count += ded_count;
|
||||
}
|
||||
|
@ -752,14 +754,16 @@ static int gfx_v9_4_query_utc_edc_status(struct amdgpu_device *adev,
|
|||
|
||||
sec_count = REG_GET_FIELD(data, UTCL2_MEM_ECC_CNTL, SEC_COUNT);
|
||||
if (sec_count) {
|
||||
DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
|
||||
dev_info(adev->dev,
|
||||
"Instance[%d]: SubBlock %s, SEC %d\n", i,
|
||||
utcl2_router_mems[i], sec_count);
|
||||
err_data->ce_count += sec_count;
|
||||
}
|
||||
|
||||
ded_count = REG_GET_FIELD(data, UTCL2_MEM_ECC_CNTL, DED_COUNT);
|
||||
if (ded_count) {
|
||||
DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
|
||||
dev_info(adev->dev,
|
||||
"Instance[%d]: SubBlock %s, DED %d\n", i,
|
||||
utcl2_router_mems[i], ded_count);
|
||||
err_data->ue_count += ded_count;
|
||||
}
|
||||
|
@ -772,7 +776,8 @@ static int gfx_v9_4_query_utc_edc_status(struct amdgpu_device *adev,
|
|||
sec_count = REG_GET_FIELD(data, ATC_L2_CACHE_2M_DSM_CNTL,
|
||||
SEC_COUNT);
|
||||
if (sec_count) {
|
||||
DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
|
||||
dev_info(adev->dev,
|
||||
"Instance[%d]: SubBlock %s, SEC %d\n", i,
|
||||
atc_l2_cache_2m_mems[i], sec_count);
|
||||
err_data->ce_count += sec_count;
|
||||
}
|
||||
|
@ -780,7 +785,8 @@ static int gfx_v9_4_query_utc_edc_status(struct amdgpu_device *adev,
|
|||
ded_count = REG_GET_FIELD(data, ATC_L2_CACHE_2M_DSM_CNTL,
|
||||
DED_COUNT);
|
||||
if (ded_count) {
|
||||
DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
|
||||
dev_info(adev->dev,
|
||||
"Instance[%d]: SubBlock %s, DED %d\n", i,
|
||||
atc_l2_cache_2m_mems[i], ded_count);
|
||||
err_data->ue_count += ded_count;
|
||||
}
|
||||
|
@ -793,7 +799,8 @@ static int gfx_v9_4_query_utc_edc_status(struct amdgpu_device *adev,
|
|||
sec_count = REG_GET_FIELD(data, ATC_L2_CACHE_4K_DSM_CNTL,
|
||||
SEC_COUNT);
|
||||
if (sec_count) {
|
||||
DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
|
||||
dev_info(adev->dev,
|
||||
"Instance[%d]: SubBlock %s, SEC %d\n", i,
|
||||
atc_l2_cache_4k_mems[i], sec_count);
|
||||
err_data->ce_count += sec_count;
|
||||
}
|
||||
|
@ -801,7 +808,8 @@ static int gfx_v9_4_query_utc_edc_status(struct amdgpu_device *adev,
|
|||
ded_count = REG_GET_FIELD(data, ATC_L2_CACHE_4K_DSM_CNTL,
|
||||
DED_COUNT);
|
||||
if (ded_count) {
|
||||
DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
|
||||
dev_info(adev->dev,
|
||||
"Instance[%d]: SubBlock %s, DED %d\n", i,
|
||||
atc_l2_cache_4k_mems[i], ded_count);
|
||||
err_data->ue_count += ded_count;
|
||||
}
|
||||
|
@ -816,7 +824,8 @@ static int gfx_v9_4_query_utc_edc_status(struct amdgpu_device *adev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int gfx_v9_4_ras_error_count(const struct soc15_reg_entry *reg,
|
||||
static int gfx_v9_4_ras_error_count(struct amdgpu_device *adev,
|
||||
const struct soc15_reg_entry *reg,
|
||||
uint32_t se_id, uint32_t inst_id,
|
||||
uint32_t value, uint32_t *sec_count,
|
||||
uint32_t *ded_count)
|
||||
|
@ -833,7 +842,8 @@ static int gfx_v9_4_ras_error_count(const struct soc15_reg_entry *reg,
|
|||
sec_cnt = (value & gfx_v9_4_ras_fields[i].sec_count_mask) >>
|
||||
gfx_v9_4_ras_fields[i].sec_count_shift;
|
||||
if (sec_cnt) {
|
||||
DRM_INFO("GFX SubBlock %s, Instance[%d][%d], SEC %d\n",
|
||||
dev_info(adev->dev,
|
||||
"GFX SubBlock %s, Instance[%d][%d], SEC %d\n",
|
||||
gfx_v9_4_ras_fields[i].name, se_id, inst_id,
|
||||
sec_cnt);
|
||||
*sec_count += sec_cnt;
|
||||
|
@ -842,7 +852,8 @@ static int gfx_v9_4_ras_error_count(const struct soc15_reg_entry *reg,
|
|||
ded_cnt = (value & gfx_v9_4_ras_fields[i].ded_count_mask) >>
|
||||
gfx_v9_4_ras_fields[i].ded_count_shift;
|
||||
if (ded_cnt) {
|
||||
DRM_INFO("GFX SubBlock %s, Instance[%d][%d], DED %d\n",
|
||||
dev_info(adev->dev,
|
||||
"GFX SubBlock %s, Instance[%d][%d], DED %d\n",
|
||||
gfx_v9_4_ras_fields[i].name, se_id, inst_id,
|
||||
ded_cnt);
|
||||
*ded_count += ded_cnt;
|
||||
|
@ -876,7 +887,7 @@ int gfx_v9_4_query_ras_error_count(struct amdgpu_device *adev,
|
|||
reg_value = RREG32(SOC15_REG_ENTRY_OFFSET(
|
||||
gfx_v9_4_edc_counter_regs[i]));
|
||||
if (reg_value)
|
||||
gfx_v9_4_ras_error_count(
|
||||
gfx_v9_4_ras_error_count(adev,
|
||||
&gfx_v9_4_edc_counter_regs[i],
|
||||
j, k, reg_value, &sec_count,
|
||||
&ded_count);
|
||||
|
|
|
@ -170,6 +170,9 @@ static int gmc_v10_0_process_interrupt(struct amdgpu_device *adev,
|
|||
dev_err(adev->dev,
|
||||
"GCVM_L2_PROTECTION_FAULT_STATUS:0x%08X\n",
|
||||
status);
|
||||
dev_err(adev->dev, "\t Faulty UTCL2 client ID: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
GCVM_L2_PROTECTION_FAULT_STATUS, CID));
|
||||
dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
GCVM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS));
|
||||
|
@ -369,7 +372,7 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
|
|||
* translation. Avoid this by doing the invalidation from the SDMA
|
||||
* itself.
|
||||
*/
|
||||
r = amdgpu_job_alloc_with_ib(adev, 16 * 4, &job);
|
||||
r = amdgpu_job_alloc_with_ib(adev, 16 * 4, AMDGPU_IB_POOL_VM, &job);
|
||||
if (r)
|
||||
goto error_alloc;
|
||||
|
||||
|
|
|
@ -858,7 +858,7 @@ static int gmc_v6_0_sw_init(void *handle)
|
|||
|
||||
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44));
|
||||
if (r) {
|
||||
dev_warn(adev->dev, "amdgpu: No suitable DMA available.\n");
|
||||
dev_warn(adev->dev, "No suitable DMA available.\n");
|
||||
return r;
|
||||
}
|
||||
adev->need_swiotlb = drm_need_swiotlb(44);
|
||||
|
|
|
@ -1019,7 +1019,7 @@ static int gmc_v7_0_sw_init(void *handle)
|
|||
|
||||
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40));
|
||||
if (r) {
|
||||
pr_warn("amdgpu: No suitable DMA available\n");
|
||||
pr_warn("No suitable DMA available\n");
|
||||
return r;
|
||||
}
|
||||
adev->need_swiotlb = drm_need_swiotlb(40);
|
||||
|
|
|
@ -1144,7 +1144,7 @@ static int gmc_v8_0_sw_init(void *handle)
|
|||
|
||||
r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40));
|
||||
if (r) {
|
||||
pr_warn("amdgpu: No suitable DMA available\n");
|
||||
pr_warn("No suitable DMA available\n");
|
||||
return r;
|
||||
}
|
||||
adev->need_swiotlb = drm_need_swiotlb(40);
|
||||
|
|
|
@ -362,6 +362,9 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
|
|||
dev_err(adev->dev,
|
||||
"VM_L2_PROTECTION_FAULT_STATUS:0x%08X\n",
|
||||
status);
|
||||
dev_err(adev->dev, "\t Faulty UTCL2 client ID: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
VM_L2_PROTECTION_FAULT_STATUS, CID));
|
||||
dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n",
|
||||
REG_GET_FIELD(status,
|
||||
VM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS));
|
||||
|
|
|
@ -480,7 +480,8 @@ int jpeg_v1_0_sw_init(void *handle)
|
|||
|
||||
ring = &adev->jpeg.inst->ring_dec;
|
||||
sprintf(ring->name, "jpeg_dec");
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0);
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq,
|
||||
0, AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -106,7 +106,8 @@ static int jpeg_v2_0_sw_init(void *handle)
|
|||
ring->use_doorbell = true;
|
||||
ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1;
|
||||
sprintf(ring->name, "jpeg_dec");
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0);
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq,
|
||||
0, AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -169,14 +170,11 @@ static int jpeg_v2_0_hw_init(void *handle)
|
|||
static int jpeg_v2_0_hw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
|
||||
|
||||
if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
|
||||
RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS))
|
||||
jpeg_v2_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
|
||||
|
||||
ring->sched.ready = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -118,7 +118,8 @@ static int jpeg_v2_5_sw_init(void *handle)
|
|||
ring->use_doorbell = true;
|
||||
ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + 8 * i;
|
||||
sprintf(ring->name, "jpeg_dec_%d", i);
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst[i].irq, 0);
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst[i].irq,
|
||||
0, AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -690,7 +690,8 @@ static const struct soc15_reg_entry mmhub_v1_0_edc_cnt_regs[] = {
|
|||
{ SOC15_REG_ENTRY(MMHUB, 0, mmMMEA1_EDC_CNT2_VG20), 0, 0, 0},
|
||||
};
|
||||
|
||||
static int mmhub_v1_0_get_ras_error_count(const struct soc15_reg_entry *reg,
|
||||
static int mmhub_v1_0_get_ras_error_count(struct amdgpu_device *adev,
|
||||
const struct soc15_reg_entry *reg,
|
||||
uint32_t value, uint32_t *sec_count, uint32_t *ded_count)
|
||||
{
|
||||
uint32_t i;
|
||||
|
@ -704,7 +705,8 @@ static int mmhub_v1_0_get_ras_error_count(const struct soc15_reg_entry *reg,
|
|||
mmhub_v1_0_ras_fields[i].sec_count_mask) >>
|
||||
mmhub_v1_0_ras_fields[i].sec_count_shift;
|
||||
if (sec_cnt) {
|
||||
DRM_INFO("MMHUB SubBlock %s, SEC %d\n",
|
||||
dev_info(adev->dev,
|
||||
"MMHUB SubBlock %s, SEC %d\n",
|
||||
mmhub_v1_0_ras_fields[i].name,
|
||||
sec_cnt);
|
||||
*sec_count += sec_cnt;
|
||||
|
@ -714,7 +716,8 @@ static int mmhub_v1_0_get_ras_error_count(const struct soc15_reg_entry *reg,
|
|||
mmhub_v1_0_ras_fields[i].ded_count_mask) >>
|
||||
mmhub_v1_0_ras_fields[i].ded_count_shift;
|
||||
if (ded_cnt) {
|
||||
DRM_INFO("MMHUB SubBlock %s, DED %d\n",
|
||||
dev_info(adev->dev,
|
||||
"MMHUB SubBlock %s, DED %d\n",
|
||||
mmhub_v1_0_ras_fields[i].name,
|
||||
ded_cnt);
|
||||
*ded_count += ded_cnt;
|
||||
|
@ -739,7 +742,8 @@ static void mmhub_v1_0_query_ras_error_count(struct amdgpu_device *adev,
|
|||
reg_value =
|
||||
RREG32(SOC15_REG_ENTRY_OFFSET(mmhub_v1_0_edc_cnt_regs[i]));
|
||||
if (reg_value)
|
||||
mmhub_v1_0_get_ras_error_count(&mmhub_v1_0_edc_cnt_regs[i],
|
||||
mmhub_v1_0_get_ras_error_count(adev,
|
||||
&mmhub_v1_0_edc_cnt_regs[i],
|
||||
reg_value, &sec_count, &ded_count);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,8 @@ enum idh_event {
|
|||
IDH_SUCCESS,
|
||||
IDH_FAIL,
|
||||
IDH_QUERY_ALIVE,
|
||||
IDH_EVENT_MAX
|
||||
|
||||
IDH_TEXT_MESSAGE = 255,
|
||||
};
|
||||
|
||||
extern const struct amdgpu_virt_ops xgpu_ai_virt_ops;
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include "navi10_ih.h"
|
||||
#include "soc15_common.h"
|
||||
#include "mxgpu_nv.h"
|
||||
#include "mxgpu_ai.h"
|
||||
|
||||
static void xgpu_nv_mailbox_send_ack(struct amdgpu_device *adev)
|
||||
{
|
||||
|
@ -53,8 +52,7 @@ static void xgpu_nv_mailbox_set_valid(struct amdgpu_device *adev, bool val)
|
|||
*/
|
||||
static enum idh_event xgpu_nv_mailbox_peek_msg(struct amdgpu_device *adev)
|
||||
{
|
||||
return RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
|
||||
mmBIF_BX_PF_MAILBOX_MSGBUF_RCV_DW0));
|
||||
return RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,8 +61,7 @@ static int xgpu_nv_mailbox_rcv_msg(struct amdgpu_device *adev,
|
|||
{
|
||||
u32 reg;
|
||||
|
||||
reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
|
||||
mmBIF_BX_PF_MAILBOX_MSGBUF_RCV_DW0));
|
||||
reg = RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW0);
|
||||
if (reg != event)
|
||||
return -ENOENT;
|
||||
|
||||
|
@ -110,7 +107,6 @@ static int xgpu_nv_poll_msg(struct amdgpu_device *adev, enum idh_event event)
|
|||
timeout -= 10;
|
||||
} while (timeout > 1);
|
||||
|
||||
pr_err("Doesn't get msg:%d from pf, error=%d\n", event, r);
|
||||
|
||||
return -ETIME;
|
||||
}
|
||||
|
@ -118,7 +114,6 @@ static int xgpu_nv_poll_msg(struct amdgpu_device *adev, enum idh_event event)
|
|||
static void xgpu_nv_mailbox_trans_msg (struct amdgpu_device *adev,
|
||||
enum idh_request req, u32 data1, u32 data2, u32 data3)
|
||||
{
|
||||
u32 reg;
|
||||
int r;
|
||||
uint8_t trn;
|
||||
|
||||
|
@ -137,19 +132,10 @@ static void xgpu_nv_mailbox_trans_msg (struct amdgpu_device *adev,
|
|||
}
|
||||
} while (trn);
|
||||
|
||||
reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
|
||||
mmBIF_BX_PF_MAILBOX_MSGBUF_TRN_DW0));
|
||||
reg = REG_SET_FIELD(reg, BIF_BX_PF_MAILBOX_MSGBUF_TRN_DW0,
|
||||
MSGBUF_DATA, req);
|
||||
WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_MSGBUF_TRN_DW0),
|
||||
reg);
|
||||
WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_MSGBUF_TRN_DW1),
|
||||
data1);
|
||||
WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_MSGBUF_TRN_DW2),
|
||||
data2);
|
||||
WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_MSGBUF_TRN_DW3),
|
||||
data3);
|
||||
|
||||
WREG32_NO_KIQ(mmMAILBOX_MSGBUF_TRN_DW0, req);
|
||||
WREG32_NO_KIQ(mmMAILBOX_MSGBUF_TRN_DW1, data1);
|
||||
WREG32_NO_KIQ(mmMAILBOX_MSGBUF_TRN_DW2, data2);
|
||||
WREG32_NO_KIQ(mmMAILBOX_MSGBUF_TRN_DW3, data3);
|
||||
xgpu_nv_mailbox_set_valid(adev, true);
|
||||
|
||||
/* start to poll ack */
|
||||
|
@ -164,23 +150,48 @@ static int xgpu_nv_send_access_requests(struct amdgpu_device *adev,
|
|||
enum idh_request req)
|
||||
{
|
||||
int r;
|
||||
enum idh_event event = -1;
|
||||
|
||||
xgpu_nv_mailbox_trans_msg(adev, req, 0, 0, 0);
|
||||
|
||||
/* start to check msg if request is idh_req_gpu_init_access */
|
||||
if (req == IDH_REQ_GPU_INIT_ACCESS ||
|
||||
req == IDH_REQ_GPU_FINI_ACCESS ||
|
||||
req == IDH_REQ_GPU_RESET_ACCESS) {
|
||||
r = xgpu_nv_poll_msg(adev, IDH_READY_TO_ACCESS_GPU);
|
||||
switch (req) {
|
||||
case IDH_REQ_GPU_INIT_ACCESS:
|
||||
case IDH_REQ_GPU_FINI_ACCESS:
|
||||
case IDH_REQ_GPU_RESET_ACCESS:
|
||||
event = IDH_READY_TO_ACCESS_GPU;
|
||||
break;
|
||||
case IDH_REQ_GPU_INIT_DATA:
|
||||
event = IDH_REQ_GPU_INIT_DATA_READY;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (event != -1) {
|
||||
r = xgpu_nv_poll_msg(adev, event);
|
||||
if (r) {
|
||||
pr_err("Doesn't get READY_TO_ACCESS_GPU from pf, give up\n");
|
||||
return r;
|
||||
if (req != IDH_REQ_GPU_INIT_DATA) {
|
||||
pr_err("Doesn't get msg:%d from pf, error=%d\n", event, r);
|
||||
return r;
|
||||
}
|
||||
else /* host doesn't support REQ_GPU_INIT_DATA handshake */
|
||||
adev->virt.req_init_data_ver = 0;
|
||||
} else {
|
||||
if (req == IDH_REQ_GPU_INIT_DATA)
|
||||
{
|
||||
adev->virt.req_init_data_ver =
|
||||
RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW1);
|
||||
|
||||
/* assume V1 in case host doesn't set version number */
|
||||
if (adev->virt.req_init_data_ver < 1)
|
||||
adev->virt.req_init_data_ver = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Retrieve checksum from mailbox2 */
|
||||
if (req == IDH_REQ_GPU_INIT_ACCESS || req == IDH_REQ_GPU_RESET_ACCESS) {
|
||||
adev->virt.fw_reserve.checksum_key =
|
||||
RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
|
||||
mmBIF_BX_PF_MAILBOX_MSGBUF_RCV_DW2));
|
||||
RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,6 +224,11 @@ static int xgpu_nv_release_full_gpu_access(struct amdgpu_device *adev,
|
|||
return r;
|
||||
}
|
||||
|
||||
static int xgpu_nv_request_init_data(struct amdgpu_device *adev)
|
||||
{
|
||||
return xgpu_nv_send_access_requests(adev, IDH_REQ_GPU_INIT_DATA);
|
||||
}
|
||||
|
||||
static int xgpu_nv_mailbox_ack_irq(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
|
@ -226,11 +242,14 @@ static int xgpu_nv_set_mailbox_ack_irq(struct amdgpu_device *adev,
|
|||
unsigned type,
|
||||
enum amdgpu_interrupt_state state)
|
||||
{
|
||||
u32 tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_INT_CNTL));
|
||||
u32 tmp = RREG32_NO_KIQ(mmMAILBOX_INT_CNTL);
|
||||
|
||||
tmp = REG_SET_FIELD(tmp, BIF_BX_PF_MAILBOX_INT_CNTL, ACK_INT_EN,
|
||||
(state == AMDGPU_IRQ_STATE_ENABLE) ? 1 : 0);
|
||||
WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_INT_CNTL), tmp);
|
||||
if (state == AMDGPU_IRQ_STATE_ENABLE)
|
||||
tmp |= 2;
|
||||
else
|
||||
tmp &= ~2;
|
||||
|
||||
WREG32_NO_KIQ(mmMAILBOX_INT_CNTL, tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -282,11 +301,14 @@ static int xgpu_nv_set_mailbox_rcv_irq(struct amdgpu_device *adev,
|
|||
unsigned type,
|
||||
enum amdgpu_interrupt_state state)
|
||||
{
|
||||
u32 tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_INT_CNTL));
|
||||
u32 tmp = RREG32_NO_KIQ(mmMAILBOX_INT_CNTL);
|
||||
|
||||
tmp = REG_SET_FIELD(tmp, BIF_BX_PF_MAILBOX_INT_CNTL, VALID_INT_EN,
|
||||
(state == AMDGPU_IRQ_STATE_ENABLE) ? 1 : 0);
|
||||
WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_INT_CNTL), tmp);
|
||||
if (state == AMDGPU_IRQ_STATE_ENABLE)
|
||||
tmp |= 1;
|
||||
else
|
||||
tmp &= ~1;
|
||||
|
||||
WREG32_NO_KIQ(mmMAILBOX_INT_CNTL, tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -378,6 +400,7 @@ void xgpu_nv_mailbox_put_irq(struct amdgpu_device *adev)
|
|||
const struct amdgpu_virt_ops xgpu_nv_virt_ops = {
|
||||
.req_full_gpu = xgpu_nv_request_full_gpu_access,
|
||||
.rel_full_gpu = xgpu_nv_release_full_gpu_access,
|
||||
.req_init_data = xgpu_nv_request_init_data,
|
||||
.reset_gpu = xgpu_nv_request_reset,
|
||||
.wait_reset = NULL,
|
||||
.trans_msg = xgpu_nv_mailbox_trans_msg,
|
||||
|
|
|
@ -25,9 +25,33 @@
|
|||
#define __MXGPU_NV_H__
|
||||
|
||||
#define NV_MAILBOX_POLL_ACK_TIMEDOUT 500
|
||||
#define NV_MAILBOX_POLL_MSG_TIMEDOUT 12000
|
||||
#define NV_MAILBOX_POLL_MSG_TIMEDOUT 6000
|
||||
#define NV_MAILBOX_POLL_FLR_TIMEDOUT 500
|
||||
|
||||
enum idh_request {
|
||||
IDH_REQ_GPU_INIT_ACCESS = 1,
|
||||
IDH_REL_GPU_INIT_ACCESS,
|
||||
IDH_REQ_GPU_FINI_ACCESS,
|
||||
IDH_REL_GPU_FINI_ACCESS,
|
||||
IDH_REQ_GPU_RESET_ACCESS,
|
||||
IDH_REQ_GPU_INIT_DATA,
|
||||
|
||||
IDH_LOG_VF_ERROR = 200,
|
||||
};
|
||||
|
||||
enum idh_event {
|
||||
IDH_CLR_MSG_BUF = 0,
|
||||
IDH_READY_TO_ACCESS_GPU,
|
||||
IDH_FLR_NOTIFICATION,
|
||||
IDH_FLR_NOTIFICATION_CMPL,
|
||||
IDH_SUCCESS,
|
||||
IDH_FAIL,
|
||||
IDH_QUERY_ALIVE,
|
||||
IDH_REQ_GPU_INIT_DATA_READY,
|
||||
|
||||
IDH_TEXT_MESSAGE = 255,
|
||||
};
|
||||
|
||||
extern const struct amdgpu_virt_ops xgpu_nv_virt_ops;
|
||||
|
||||
void xgpu_nv_mailbox_set_irq_funcs(struct amdgpu_device *adev);
|
||||
|
@ -35,7 +59,21 @@ int xgpu_nv_mailbox_add_irq_id(struct amdgpu_device *adev);
|
|||
int xgpu_nv_mailbox_get_irq(struct amdgpu_device *adev);
|
||||
void xgpu_nv_mailbox_put_irq(struct amdgpu_device *adev);
|
||||
|
||||
#define NV_MAIBOX_CONTROL_TRN_OFFSET_BYTE (SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_CONTROL) * 4)
|
||||
#define NV_MAIBOX_CONTROL_RCV_OFFSET_BYTE (SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_CONTROL) * 4 + 1)
|
||||
#define mmMAILBOX_CONTROL 0xE5E
|
||||
|
||||
#define NV_MAIBOX_CONTROL_TRN_OFFSET_BYTE (mmMAILBOX_CONTROL * 4)
|
||||
#define NV_MAIBOX_CONTROL_RCV_OFFSET_BYTE (NV_MAIBOX_CONTROL_TRN_OFFSET_BYTE + 1)
|
||||
|
||||
#define mmMAILBOX_MSGBUF_TRN_DW0 0xE56
|
||||
#define mmMAILBOX_MSGBUF_TRN_DW1 0xE57
|
||||
#define mmMAILBOX_MSGBUF_TRN_DW2 0xE58
|
||||
#define mmMAILBOX_MSGBUF_TRN_DW3 0xE59
|
||||
|
||||
#define mmMAILBOX_MSGBUF_RCV_DW0 0xE5A
|
||||
#define mmMAILBOX_MSGBUF_RCV_DW1 0xE5B
|
||||
#define mmMAILBOX_MSGBUF_RCV_DW2 0xE5C
|
||||
#define mmMAILBOX_MSGBUF_RCV_DW3 0xE5D
|
||||
|
||||
#define mmMAILBOX_INT_CNTL 0xE5F
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,7 +43,8 @@ enum idh_event {
|
|||
IDH_READY_TO_ACCESS_GPU,
|
||||
IDH_FLR_NOTIFICATION,
|
||||
IDH_FLR_NOTIFICATION_CMPL,
|
||||
IDH_EVENT_MAX
|
||||
|
||||
IDH_TEXT_MESSAGE = 255
|
||||
};
|
||||
|
||||
extern const struct amdgpu_virt_ops xgpu_vi_virt_ops;
|
||||
|
|
|
@ -49,8 +49,48 @@ static void navi10_ih_enable_interrupts(struct amdgpu_device *adev)
|
|||
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 1);
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 1);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
|
||||
if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
|
||||
if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL, ih_rb_cntl)) {
|
||||
DRM_ERROR("PSP program IH_RB_CNTL failed!\n");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
|
||||
}
|
||||
|
||||
adev->irq.ih.enabled = true;
|
||||
|
||||
if (adev->irq.ih1.ring_size) {
|
||||
ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
|
||||
RB_ENABLE, 1);
|
||||
if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
|
||||
if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1,
|
||||
ih_rb_cntl)) {
|
||||
DRM_ERROR("program IH_RB_CNTL_RING1 failed!\n");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
|
||||
}
|
||||
adev->irq.ih1.enabled = true;
|
||||
}
|
||||
|
||||
if (adev->irq.ih2.ring_size) {
|
||||
ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
|
||||
RB_ENABLE, 1);
|
||||
if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
|
||||
if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING2,
|
||||
ih_rb_cntl)) {
|
||||
DRM_ERROR("program IH_RB_CNTL_RING2 failed!\n");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
|
||||
}
|
||||
adev->irq.ih2.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,12 +106,61 @@ static void navi10_ih_disable_interrupts(struct amdgpu_device *adev)
|
|||
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 0);
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 0);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
|
||||
if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
|
||||
if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL, ih_rb_cntl)) {
|
||||
DRM_ERROR("PSP program IH_RB_CNTL failed!\n");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
|
||||
}
|
||||
|
||||
/* set rptr, wptr to 0 */
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
|
||||
adev->irq.ih.enabled = false;
|
||||
adev->irq.ih.rptr = 0;
|
||||
|
||||
if (adev->irq.ih1.ring_size) {
|
||||
ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
|
||||
RB_ENABLE, 0);
|
||||
if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
|
||||
if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1,
|
||||
ih_rb_cntl)) {
|
||||
DRM_ERROR("program IH_RB_CNTL_RING1 failed!\n");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
|
||||
}
|
||||
/* set rptr, wptr to 0 */
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
|
||||
adev->irq.ih1.enabled = false;
|
||||
adev->irq.ih1.rptr = 0;
|
||||
}
|
||||
|
||||
if (adev->irq.ih2.ring_size) {
|
||||
ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
|
||||
RB_ENABLE, 0);
|
||||
if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
|
||||
if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING2,
|
||||
ih_rb_cntl)) {
|
||||
DRM_ERROR("program IH_RB_CNTL_RING2 failed!\n");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
|
||||
}
|
||||
/* set rptr, wptr to 0 */
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
|
||||
adev->irq.ih2.enabled = false;
|
||||
adev->irq.ih2.rptr = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static uint32_t navi10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl)
|
||||
|
@ -97,6 +186,43 @@ static uint32_t navi10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl
|
|||
return ih_rb_cntl;
|
||||
}
|
||||
|
||||
static uint32_t navi10_ih_doorbell_rptr(struct amdgpu_ih_ring *ih)
|
||||
{
|
||||
u32 ih_doorbell_rtpr = 0;
|
||||
|
||||
if (ih->use_doorbell) {
|
||||
ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
|
||||
IH_DOORBELL_RPTR, OFFSET,
|
||||
ih->doorbell_index);
|
||||
ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
|
||||
IH_DOORBELL_RPTR,
|
||||
ENABLE, 1);
|
||||
} else {
|
||||
ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
|
||||
IH_DOORBELL_RPTR,
|
||||
ENABLE, 0);
|
||||
}
|
||||
return ih_doorbell_rtpr;
|
||||
}
|
||||
|
||||
static void navi10_ih_reroute_ih(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
/* Reroute to IH ring 1 for VMC */
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_INDEX, 0x12);
|
||||
tmp = RREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA);
|
||||
tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, CLIENT_TYPE, 1);
|
||||
tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, RING_ID, 1);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA, tmp);
|
||||
|
||||
/* Reroute IH ring 1 for UMC */
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_INDEX, 0x1B);
|
||||
tmp = RREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA);
|
||||
tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, RING_ID, 1);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA, tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* navi10_ih_irq_init - init and enable the interrupt ring
|
||||
*
|
||||
|
@ -111,7 +237,7 @@ static uint32_t navi10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl
|
|||
static int navi10_ih_irq_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ih_ring *ih = &adev->irq.ih;
|
||||
u32 ih_rb_cntl, ih_doorbell_rtpr, ih_chicken;
|
||||
u32 ih_rb_cntl, ih_chicken;
|
||||
u32 tmp;
|
||||
|
||||
/* disable irqs */
|
||||
|
@ -127,6 +253,15 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)
|
|||
ih_rb_cntl = navi10_ih_rb_cntl(ih, ih_rb_cntl);
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM,
|
||||
!!adev->irq.msi_enabled);
|
||||
if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
|
||||
if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL, ih_rb_cntl)) {
|
||||
DRM_ERROR("PSP program IH_RB_CNTL failed!\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
} else {
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
|
||||
}
|
||||
navi10_ih_reroute_ih(adev);
|
||||
|
||||
if (unlikely(adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT)) {
|
||||
if (ih->use_bus_addr) {
|
||||
|
@ -137,8 +272,6 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)
|
|||
}
|
||||
}
|
||||
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
|
||||
|
||||
/* set the writeback address whether it's enabled or not */
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO,
|
||||
lower_32_bits(ih->wptr_addr));
|
||||
|
@ -149,22 +282,68 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)
|
|||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
|
||||
|
||||
ih_doorbell_rtpr = RREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR);
|
||||
if (ih->use_doorbell) {
|
||||
ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
|
||||
IH_DOORBELL_RPTR, OFFSET,
|
||||
ih->doorbell_index);
|
||||
ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
|
||||
IH_DOORBELL_RPTR, ENABLE, 1);
|
||||
} else {
|
||||
ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
|
||||
IH_DOORBELL_RPTR, ENABLE, 0);
|
||||
}
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR, ih_doorbell_rtpr);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR,
|
||||
navi10_ih_doorbell_rptr(ih));
|
||||
|
||||
adev->nbio.funcs->ih_doorbell_range(adev, ih->use_doorbell,
|
||||
ih->doorbell_index);
|
||||
|
||||
ih = &adev->irq.ih1;
|
||||
if (ih->ring_size) {
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING1, ih->gpu_addr >> 8);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING1,
|
||||
(ih->gpu_addr >> 40) & 0xff);
|
||||
|
||||
ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
|
||||
ih_rb_cntl = navi10_ih_rb_cntl(ih, ih_rb_cntl);
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
|
||||
WPTR_OVERFLOW_ENABLE, 0);
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
|
||||
RB_FULL_DRAIN_ENABLE, 1);
|
||||
if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
|
||||
if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1,
|
||||
ih_rb_cntl)) {
|
||||
DRM_ERROR("program IH_RB_CNTL_RING1 failed!\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
} else {
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
|
||||
}
|
||||
/* set rptr, wptr to 0 */
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0);
|
||||
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR_RING1,
|
||||
navi10_ih_doorbell_rptr(ih));
|
||||
}
|
||||
|
||||
ih = &adev->irq.ih2;
|
||||
if (ih->ring_size) {
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING2, ih->gpu_addr >> 8);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING2,
|
||||
(ih->gpu_addr >> 40) & 0xff);
|
||||
|
||||
ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
|
||||
ih_rb_cntl = navi10_ih_rb_cntl(ih, ih_rb_cntl);
|
||||
|
||||
if (amdgpu_sriov_vf(adev) && adev->asic_type < CHIP_NAVI10) {
|
||||
if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING2,
|
||||
ih_rb_cntl)) {
|
||||
DRM_ERROR("program IH_RB_CNTL_RING2 failed!\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
} else {
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
|
||||
}
|
||||
/* set rptr, wptr to 0 */
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0);
|
||||
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR_RING2,
|
||||
navi10_ih_doorbell_rptr(ih));
|
||||
}
|
||||
|
||||
|
||||
tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
|
||||
CLIENT18_IS_STORM_CLIENT, 1);
|
||||
|
@ -217,7 +396,15 @@ static u32 navi10_ih_get_wptr(struct amdgpu_device *adev,
|
|||
if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
|
||||
goto out;
|
||||
|
||||
reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR);
|
||||
if (ih == &adev->irq.ih)
|
||||
reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR);
|
||||
else if (ih == &adev->irq.ih1)
|
||||
reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING1);
|
||||
else if (ih == &adev->irq.ih2)
|
||||
reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING2);
|
||||
else
|
||||
BUG();
|
||||
|
||||
wptr = RREG32_NO_KIQ(reg);
|
||||
if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
|
||||
goto out;
|
||||
|
@ -233,7 +420,15 @@ static u32 navi10_ih_get_wptr(struct amdgpu_device *adev,
|
|||
wptr, ih->rptr, tmp);
|
||||
ih->rptr = tmp;
|
||||
|
||||
reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL);
|
||||
if (ih == &adev->irq.ih)
|
||||
reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL);
|
||||
else if (ih == &adev->irq.ih1)
|
||||
reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING1);
|
||||
else if (ih == &adev->irq.ih2)
|
||||
reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING2);
|
||||
else
|
||||
BUG();
|
||||
|
||||
tmp = RREG32_NO_KIQ(reg);
|
||||
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
|
||||
WREG32_NO_KIQ(reg, tmp);
|
||||
|
@ -333,8 +528,52 @@ static void navi10_ih_set_rptr(struct amdgpu_device *adev,
|
|||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
navi10_ih_irq_rearm(adev, ih);
|
||||
} else
|
||||
} else if (ih == &adev->irq.ih) {
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr);
|
||||
} else if (ih == &adev->irq.ih1) {
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, ih->rptr);
|
||||
} else if (ih == &adev->irq.ih2) {
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, ih->rptr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* navi10_ih_self_irq - dispatch work for ring 1 and 2
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @source: irq source
|
||||
* @entry: IV with WPTR update
|
||||
*
|
||||
* Update the WPTR from the IV and schedule work to handle the entries.
|
||||
*/
|
||||
static int navi10_ih_self_irq(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
{
|
||||
uint32_t wptr = cpu_to_le32(entry->src_data[0]);
|
||||
|
||||
switch (entry->ring_id) {
|
||||
case 1:
|
||||
*adev->irq.ih1.wptr_cpu = wptr;
|
||||
schedule_work(&adev->irq.ih1_work);
|
||||
break;
|
||||
case 2:
|
||||
*adev->irq.ih2.wptr_cpu = wptr;
|
||||
schedule_work(&adev->irq.ih2_work);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct amdgpu_irq_src_funcs navi10_ih_self_irq_funcs = {
|
||||
.process = navi10_ih_self_irq,
|
||||
};
|
||||
|
||||
static void navi10_ih_set_self_irq_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->irq.self_irq.num_types = 0;
|
||||
adev->irq.self_irq.funcs = &navi10_ih_self_irq_funcs;
|
||||
}
|
||||
|
||||
static int navi10_ih_early_init(void *handle)
|
||||
|
@ -342,6 +581,7 @@ static int navi10_ih_early_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
navi10_ih_set_interrupt_funcs(adev);
|
||||
navi10_ih_set_self_irq_funcs(adev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -351,6 +591,12 @@ static int navi10_ih_sw_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
bool use_bus_addr;
|
||||
|
||||
r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_IH, 0,
|
||||
&adev->irq.self_irq);
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* use gpu virtual address for ih ring
|
||||
* until ih_checken is programmed to allow
|
||||
* use bus address for ih ring by psp bl */
|
||||
|
@ -363,6 +609,20 @@ static int navi10_ih_sw_init(void *handle)
|
|||
adev->irq.ih.use_doorbell = true;
|
||||
adev->irq.ih.doorbell_index = adev->doorbell_index.ih << 1;
|
||||
|
||||
r = amdgpu_ih_ring_init(adev, &adev->irq.ih1, PAGE_SIZE, true);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->irq.ih1.use_doorbell = true;
|
||||
adev->irq.ih1.doorbell_index = (adev->doorbell_index.ih + 1) << 1;
|
||||
|
||||
r = amdgpu_ih_ring_init(adev, &adev->irq.ih2, PAGE_SIZE, true);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->irq.ih2.use_doorbell = true;
|
||||
adev->irq.ih2.doorbell_index = (adev->doorbell_index.ih + 2) << 1;
|
||||
|
||||
r = amdgpu_irq_init(adev);
|
||||
|
||||
return r;
|
||||
|
@ -373,6 +633,8 @@ static int navi10_ih_sw_fini(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
amdgpu_irq_fini(adev);
|
||||
amdgpu_ih_ring_fini(adev, &adev->irq.ih2);
|
||||
amdgpu_ih_ring_fini(adev, &adev->irq.ih1);
|
||||
amdgpu_ih_ring_fini(adev, &adev->irq.ih);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -290,23 +290,6 @@ const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg = {
|
|||
.ref_and_mask_sdma1 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__SDMA1_MASK,
|
||||
};
|
||||
|
||||
static void nbio_v2_3_detect_hw_virt(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_RCC_IOV_FUNC_IDENTIFIER);
|
||||
if (reg & 1)
|
||||
adev->virt.caps |= AMDGPU_SRIOV_CAPS_IS_VF;
|
||||
|
||||
if (reg & 0x80000000)
|
||||
adev->virt.caps |= AMDGPU_SRIOV_CAPS_ENABLE_IOV;
|
||||
|
||||
if (!reg) {
|
||||
if (is_virtual_machine()) /* passthrough mode exclus sriov mod */
|
||||
adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
static void nbio_v2_3_init_registers(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t def, data;
|
||||
|
@ -338,6 +321,5 @@ const struct amdgpu_nbio_funcs nbio_v2_3_funcs = {
|
|||
.get_clockgating_state = nbio_v2_3_get_clockgating_state,
|
||||
.ih_control = nbio_v2_3_ih_control,
|
||||
.init_registers = nbio_v2_3_init_registers,
|
||||
.detect_hw_virt = nbio_v2_3_detect_hw_virt,
|
||||
.remap_hdp_registers = nbio_v2_3_remap_hdp_registers,
|
||||
};
|
||||
|
|
|
@ -241,23 +241,6 @@ const struct nbio_hdp_flush_reg nbio_v6_1_hdp_flush_reg = {
|
|||
.ref_and_mask_sdma1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA1_MASK
|
||||
};
|
||||
|
||||
static void nbio_v6_1_detect_hw_virt(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = RREG32_SOC15(NBIO, 0, mmRCC_PF_0_0_RCC_IOV_FUNC_IDENTIFIER);
|
||||
if (reg & 1)
|
||||
adev->virt.caps |= AMDGPU_SRIOV_CAPS_IS_VF;
|
||||
|
||||
if (reg & 0x80000000)
|
||||
adev->virt.caps |= AMDGPU_SRIOV_CAPS_ENABLE_IOV;
|
||||
|
||||
if (!reg) {
|
||||
if (is_virtual_machine()) /* passthrough mode exclus sriov mod */
|
||||
adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
static void nbio_v6_1_init_registers(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t def, data;
|
||||
|
@ -294,5 +277,4 @@ const struct amdgpu_nbio_funcs nbio_v6_1_funcs = {
|
|||
.get_clockgating_state = nbio_v6_1_get_clockgating_state,
|
||||
.ih_control = nbio_v6_1_ih_control,
|
||||
.init_registers = nbio_v6_1_init_registers,
|
||||
.detect_hw_virt = nbio_v6_1_detect_hw_virt,
|
||||
};
|
||||
|
|
|
@ -280,12 +280,6 @@ const struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg = {
|
|||
.ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__SDMA1_MASK,
|
||||
};
|
||||
|
||||
static void nbio_v7_0_detect_hw_virt(struct amdgpu_device *adev)
|
||||
{
|
||||
if (is_virtual_machine()) /* passthrough mode exclus sriov mod */
|
||||
adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
|
||||
}
|
||||
|
||||
static void nbio_v7_0_init_registers(struct amdgpu_device *adev)
|
||||
{
|
||||
|
||||
|
@ -310,6 +304,5 @@ const struct amdgpu_nbio_funcs nbio_v7_0_funcs = {
|
|||
.get_clockgating_state = nbio_v7_0_get_clockgating_state,
|
||||
.ih_control = nbio_v7_0_ih_control,
|
||||
.init_registers = nbio_v7_0_init_registers,
|
||||
.detect_hw_virt = nbio_v7_0_detect_hw_virt,
|
||||
.remap_hdp_registers = nbio_v7_0_remap_hdp_registers,
|
||||
};
|
||||
|
|
|
@ -185,7 +185,7 @@ static void nbio_v7_4_ih_doorbell_range(struct amdgpu_device *adev,
|
|||
|
||||
if (use_doorbell) {
|
||||
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, OFFSET, doorbell_index);
|
||||
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, SIZE, 2);
|
||||
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, SIZE, 4);
|
||||
} else
|
||||
ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, SIZE, 0);
|
||||
|
||||
|
@ -292,23 +292,6 @@ const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg = {
|
|||
.ref_and_mask_sdma7 = GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK,
|
||||
};
|
||||
|
||||
static void nbio_v7_4_detect_hw_virt(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = RREG32_SOC15(NBIO, 0, mmRCC_IOV_FUNC_IDENTIFIER);
|
||||
if (reg & 1)
|
||||
adev->virt.caps |= AMDGPU_SRIOV_CAPS_IS_VF;
|
||||
|
||||
if (reg & 0x80000000)
|
||||
adev->virt.caps |= AMDGPU_SRIOV_CAPS_ENABLE_IOV;
|
||||
|
||||
if (!reg) {
|
||||
if (is_virtual_machine()) /* passthrough mode exclus sriov mod */
|
||||
adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
static void nbio_v7_4_init_registers(struct amdgpu_device *adev)
|
||||
{
|
||||
|
||||
|
@ -340,14 +323,20 @@ static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device
|
|||
obj->err_data.ce_count += err_data.ce_count;
|
||||
|
||||
if (err_data.ce_count)
|
||||
DRM_INFO("%ld correctable errors detected in %s block\n",
|
||||
obj->err_data.ce_count, adev->nbio.ras_if->name);
|
||||
dev_info(adev->dev, "%ld correctable hardware "
|
||||
"errors detected in %s block, "
|
||||
"no user action is needed.\n",
|
||||
obj->err_data.ce_count,
|
||||
adev->nbio.ras_if->name);
|
||||
|
||||
if (err_data.ue_count)
|
||||
DRM_INFO("%ld uncorrectable errors detected in %s block\n",
|
||||
obj->err_data.ue_count, adev->nbio.ras_if->name);
|
||||
dev_info(adev->dev, "%ld uncorrectable hardware "
|
||||
"errors detected in %s block\n",
|
||||
obj->err_data.ue_count,
|
||||
adev->nbio.ras_if->name);
|
||||
|
||||
DRM_WARN("RAS controller interrupt triggered by NBIF error\n");
|
||||
dev_info(adev->dev, "RAS controller interrupt triggered "
|
||||
"by NBIF error\n");
|
||||
|
||||
/* ras_controller_int is dedicated for nbif ras error,
|
||||
* not the global interrupt for sync flood
|
||||
|
@ -561,7 +550,6 @@ const struct amdgpu_nbio_funcs nbio_v7_4_funcs = {
|
|||
.get_clockgating_state = nbio_v7_4_get_clockgating_state,
|
||||
.ih_control = nbio_v7_4_ih_control,
|
||||
.init_registers = nbio_v7_4_init_registers,
|
||||
.detect_hw_virt = nbio_v7_4_detect_hw_virt,
|
||||
.remap_hdp_registers = nbio_v7_4_remap_hdp_registers,
|
||||
.handle_ras_controller_intr_no_bifring = nbio_v7_4_handle_ras_controller_intr_no_bifring,
|
||||
.handle_ras_err_event_athub_intr_no_bifring = nbio_v7_4_handle_ras_err_event_athub_intr_no_bifring,
|
||||
|
|
|
@ -453,19 +453,20 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
|||
{
|
||||
int r;
|
||||
|
||||
adev->nbio.funcs = &nbio_v2_3_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg;
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
adev->virt.ops = &xgpu_nv_virt_ops;
|
||||
/* try send GPU_INIT_DATA request to host */
|
||||
amdgpu_virt_request_init_data(adev);
|
||||
}
|
||||
|
||||
/* Set IP register base before any HW register access */
|
||||
r = nv_reg_base_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->nbio.funcs = &nbio_v2_3_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg;
|
||||
|
||||
adev->nbio.funcs->detect_hw_virt(adev);
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
adev->virt.ops = &xgpu_nv_virt_ops;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
|
|
|
@ -50,7 +50,6 @@ static int psp_v10_0_init_microcode(struct psp_context *psp)
|
|||
const char *chip_name;
|
||||
char fw_name[30];
|
||||
int err = 0;
|
||||
const struct psp_firmware_header_v1_0 *hdr;
|
||||
const struct ta_firmware_header_v1_0 *ta_hdr;
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
|
@ -66,22 +65,10 @@ static int psp_v10_0_init_microcode(struct psp_context *psp)
|
|||
default: BUG();
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_asd.bin", chip_name);
|
||||
err = request_firmware(&adev->psp.asd_fw, fw_name, adev->dev);
|
||||
err = psp_init_asd_microcode(psp, chip_name);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = amdgpu_ucode_validate(adev->psp.asd_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.asd_fw->data;
|
||||
adev->psp.asd_fw_version = le32_to_cpu(hdr->header.ucode_version);
|
||||
adev->psp.asd_feature_version = le32_to_cpu(hdr->ucode_feature_version);
|
||||
adev->psp.asd_ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
|
||||
adev->psp.asd_start_addr = (uint8_t *)hdr +
|
||||
le32_to_cpu(hdr->header.ucode_array_offset_bytes);
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name);
|
||||
err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev);
|
||||
if (err) {
|
||||
|
@ -126,8 +113,6 @@ out:
|
|||
dev_err(adev->dev,
|
||||
"psp v10.0: Failed to load firmware \"%s\"\n",
|
||||
fw_name);
|
||||
release_firmware(adev->psp.asd_fw);
|
||||
adev->psp.asd_fw = NULL;
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -230,129 +215,6 @@ static int psp_v10_0_ring_destroy(struct psp_context *psp,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
psp_v10_0_sram_map(struct amdgpu_device *adev,
|
||||
unsigned int *sram_offset, unsigned int *sram_addr_reg_offset,
|
||||
unsigned int *sram_data_reg_offset,
|
||||
enum AMDGPU_UCODE_ID ucode_id)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch(ucode_id) {
|
||||
/* TODO: needs to confirm */
|
||||
#if 0
|
||||
case AMDGPU_UCODE_ID_SMC:
|
||||
*sram_offset = 0;
|
||||
*sram_addr_reg_offset = 0;
|
||||
*sram_data_reg_offset = 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_CE:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_CE_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_CE_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_PFP:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_PFP_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_PFP_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_ME:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_ME_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_ME_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_MEC1:
|
||||
*sram_offset = 0x10000;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_MEC_ME1_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_MEC_ME1_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_MEC2:
|
||||
*sram_offset = 0x10000;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_MEC2_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_MEC2_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_RLC_G:
|
||||
*sram_offset = 0x2000;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_SDMA0:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_UCODE_DATA);
|
||||
break;
|
||||
|
||||
/* TODO: needs to confirm */
|
||||
#if 0
|
||||
case AMDGPU_UCODE_ID_SDMA1:
|
||||
*sram_offset = ;
|
||||
*sram_addr_reg_offset = ;
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_UVD:
|
||||
*sram_offset = ;
|
||||
*sram_addr_reg_offset = ;
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_VCE:
|
||||
*sram_offset = ;
|
||||
*sram_addr_reg_offset = ;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case AMDGPU_UCODE_ID_MAXIMUM:
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool psp_v10_0_compare_sram_data(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *ucode,
|
||||
enum AMDGPU_UCODE_ID ucode_type)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned int fw_sram_reg_val = 0;
|
||||
unsigned int fw_sram_addr_reg_offset = 0;
|
||||
unsigned int fw_sram_data_reg_offset = 0;
|
||||
unsigned int ucode_size;
|
||||
uint32_t *ucode_mem = NULL;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
err = psp_v10_0_sram_map(adev, &fw_sram_reg_val, &fw_sram_addr_reg_offset,
|
||||
&fw_sram_data_reg_offset, ucode_type);
|
||||
if (err)
|
||||
return false;
|
||||
|
||||
WREG32(fw_sram_addr_reg_offset, fw_sram_reg_val);
|
||||
|
||||
ucode_size = ucode->ucode_size;
|
||||
ucode_mem = (uint32_t *)ucode->kaddr;
|
||||
while (!ucode_size) {
|
||||
fw_sram_reg_val = RREG32(fw_sram_data_reg_offset);
|
||||
|
||||
if (*ucode_mem != fw_sram_reg_val)
|
||||
return false;
|
||||
|
||||
ucode_mem++;
|
||||
/* 4 bytes */
|
||||
ucode_size -= 4;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static int psp_v10_0_mode1_reset(struct psp_context *psp)
|
||||
{
|
||||
DRM_INFO("psp mode 1 reset not supported now! \n");
|
||||
|
@ -379,7 +241,6 @@ static const struct psp_funcs psp_v10_0_funcs = {
|
|||
.ring_create = psp_v10_0_ring_create,
|
||||
.ring_stop = psp_v10_0_ring_stop,
|
||||
.ring_destroy = psp_v10_0_ring_destroy,
|
||||
.compare_sram_data = psp_v10_0_compare_sram_data,
|
||||
.mode1_reset = psp_v10_0_mode1_reset,
|
||||
.ring_get_wptr = psp_v10_0_ring_get_wptr,
|
||||
.ring_set_wptr = psp_v10_0_ring_set_wptr,
|
||||
|
|
|
@ -75,10 +75,6 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
|
|||
const char *chip_name;
|
||||
char fw_name[30];
|
||||
int err = 0;
|
||||
const struct psp_firmware_header_v1_0 *sos_hdr;
|
||||
const struct psp_firmware_header_v1_1 *sos_hdr_v1_1;
|
||||
const struct psp_firmware_header_v1_2 *sos_hdr_v1_2;
|
||||
const struct psp_firmware_header_v1_0 *asd_hdr;
|
||||
const struct ta_firmware_header_v1_0 *ta_hdr;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
@ -103,66 +99,13 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
|
|||
BUG();
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sos.bin", chip_name);
|
||||
err = request_firmware(&adev->psp.sos_fw, fw_name, adev->dev);
|
||||
err = psp_init_sos_microcode(psp, chip_name);
|
||||
if (err)
|
||||
goto out;
|
||||
return err;
|
||||
|
||||
err = amdgpu_ucode_validate(adev->psp.sos_fw);
|
||||
err = psp_init_asd_microcode(psp, chip_name);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
sos_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.sos_fw->data;
|
||||
amdgpu_ucode_print_psp_hdr(&sos_hdr->header);
|
||||
|
||||
switch (sos_hdr->header.header_version_major) {
|
||||
case 1:
|
||||
adev->psp.sos_fw_version = le32_to_cpu(sos_hdr->header.ucode_version);
|
||||
adev->psp.sos_feature_version = le32_to_cpu(sos_hdr->ucode_feature_version);
|
||||
adev->psp.sos_bin_size = le32_to_cpu(sos_hdr->sos_size_bytes);
|
||||
adev->psp.sys_bin_size = le32_to_cpu(sos_hdr->sos_offset_bytes);
|
||||
adev->psp.sys_start_addr = (uint8_t *)sos_hdr +
|
||||
le32_to_cpu(sos_hdr->header.ucode_array_offset_bytes);
|
||||
adev->psp.sos_start_addr = (uint8_t *)adev->psp.sys_start_addr +
|
||||
le32_to_cpu(sos_hdr->sos_offset_bytes);
|
||||
if (sos_hdr->header.header_version_minor == 1) {
|
||||
sos_hdr_v1_1 = (const struct psp_firmware_header_v1_1 *)adev->psp.sos_fw->data;
|
||||
adev->psp.toc_bin_size = le32_to_cpu(sos_hdr_v1_1->toc_size_bytes);
|
||||
adev->psp.toc_start_addr = (uint8_t *)adev->psp.sys_start_addr +
|
||||
le32_to_cpu(sos_hdr_v1_1->toc_offset_bytes);
|
||||
adev->psp.kdb_bin_size = le32_to_cpu(sos_hdr_v1_1->kdb_size_bytes);
|
||||
adev->psp.kdb_start_addr = (uint8_t *)adev->psp.sys_start_addr +
|
||||
le32_to_cpu(sos_hdr_v1_1->kdb_offset_bytes);
|
||||
}
|
||||
if (sos_hdr->header.header_version_minor == 2) {
|
||||
sos_hdr_v1_2 = (const struct psp_firmware_header_v1_2 *)adev->psp.sos_fw->data;
|
||||
adev->psp.kdb_bin_size = le32_to_cpu(sos_hdr_v1_2->kdb_size_bytes);
|
||||
adev->psp.kdb_start_addr = (uint8_t *)adev->psp.sys_start_addr +
|
||||
le32_to_cpu(sos_hdr_v1_2->kdb_offset_bytes);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"Unsupported psp sos firmware\n");
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_asd.bin", chip_name);
|
||||
err = request_firmware(&adev->psp.asd_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out1;
|
||||
|
||||
err = amdgpu_ucode_validate(adev->psp.asd_fw);
|
||||
if (err)
|
||||
goto out1;
|
||||
|
||||
asd_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.asd_fw->data;
|
||||
adev->psp.asd_fw_version = le32_to_cpu(asd_hdr->header.ucode_version);
|
||||
adev->psp.asd_feature_version = le32_to_cpu(asd_hdr->ucode_feature_version);
|
||||
adev->psp.asd_ucode_size = le32_to_cpu(asd_hdr->header.ucode_size_bytes);
|
||||
adev->psp.asd_start_addr = (uint8_t *)asd_hdr +
|
||||
le32_to_cpu(asd_hdr->header.ucode_array_offset_bytes);
|
||||
return err;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
|
@ -229,15 +172,6 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
|
|||
out2:
|
||||
release_firmware(adev->psp.ta_fw);
|
||||
adev->psp.ta_fw = NULL;
|
||||
out1:
|
||||
release_firmware(adev->psp.asd_fw);
|
||||
adev->psp.asd_fw = NULL;
|
||||
out:
|
||||
dev_err(adev->dev,
|
||||
"psp v11.0: Failed to load firmware \"%s\"\n", fw_name);
|
||||
release_firmware(adev->psp.sos_fw);
|
||||
adev->psp.sos_fw = NULL;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -283,11 +217,8 @@ static int psp_v11_0_bootloader_load_kdb(struct psp_context *psp)
|
|||
/* Check tOS sign of life register to confirm sys driver and sOS
|
||||
* are already been loaded.
|
||||
*/
|
||||
if (psp_v11_0_is_sos_alive(psp)) {
|
||||
psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58);
|
||||
dev_info(adev->dev, "sos fw version = 0x%x.\n", psp->sos_fw_version);
|
||||
if (psp_v11_0_is_sos_alive(psp))
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = psp_v11_0_wait_for_bootloader(psp);
|
||||
if (ret)
|
||||
|
@ -319,11 +250,8 @@ static int psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp)
|
|||
/* Check sOS sign of life register to confirm sys driver and sOS
|
||||
* are already been loaded.
|
||||
*/
|
||||
if (psp_v11_0_is_sos_alive(psp)) {
|
||||
psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58);
|
||||
dev_info(adev->dev, "sos fw version = 0x%x.\n", psp->sos_fw_version);
|
||||
if (psp_v11_0_is_sos_alive(psp))
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = psp_v11_0_wait_for_bootloader(psp);
|
||||
if (ret)
|
||||
|
@ -446,13 +374,6 @@ static int psp_v11_0_ring_init(struct psp_context *psp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool psp_v11_0_support_vmr_ring(struct psp_context *psp)
|
||||
{
|
||||
if (amdgpu_sriov_vf(psp->adev) && psp->sos_fw_version > 0x80045)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int psp_v11_0_ring_stop(struct psp_context *psp,
|
||||
enum psp_ring_type ring_type)
|
||||
{
|
||||
|
@ -460,7 +381,7 @@ static int psp_v11_0_ring_stop(struct psp_context *psp,
|
|||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
/* Write the ring destroy command*/
|
||||
if (psp_v11_0_support_vmr_ring(psp))
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101,
|
||||
GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING);
|
||||
else
|
||||
|
@ -471,7 +392,7 @@ static int psp_v11_0_ring_stop(struct psp_context *psp,
|
|||
mdelay(20);
|
||||
|
||||
/* Wait for response flag (bit 31) */
|
||||
if (psp_v11_0_support_vmr_ring(psp))
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_101),
|
||||
0x80000000, 0x80000000, false);
|
||||
else
|
||||
|
@ -489,7 +410,7 @@ static int psp_v11_0_ring_create(struct psp_context *psp,
|
|||
struct psp_ring *ring = &psp->km_ring;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
if (psp_v11_0_support_vmr_ring(psp)) {
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
ret = psp_v11_0_ring_stop(psp, ring_type);
|
||||
if (ret) {
|
||||
DRM_ERROR("psp_v11_0_ring_stop_sriov failed!\n");
|
||||
|
@ -567,138 +488,6 @@ static int psp_v11_0_ring_destroy(struct psp_context *psp,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
psp_v11_0_sram_map(struct amdgpu_device *adev,
|
||||
unsigned int *sram_offset, unsigned int *sram_addr_reg_offset,
|
||||
unsigned int *sram_data_reg_offset,
|
||||
enum AMDGPU_UCODE_ID ucode_id)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (ucode_id) {
|
||||
/* TODO: needs to confirm */
|
||||
#if 0
|
||||
case AMDGPU_UCODE_ID_SMC:
|
||||
*sram_offset = 0;
|
||||
*sram_addr_reg_offset = 0;
|
||||
*sram_data_reg_offset = 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_CE:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_CE_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_CE_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_PFP:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_PFP_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_PFP_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_ME:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_ME_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_ME_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_MEC1:
|
||||
*sram_offset = 0x10000;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_MEC_ME1_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_MEC_ME1_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_MEC2:
|
||||
*sram_offset = 0x10000;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_MEC2_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_MEC2_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_RLC_G:
|
||||
*sram_offset = 0x2000;
|
||||
if (adev->asic_type < CHIP_NAVI10) {
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UCODE_DATA);
|
||||
} else {
|
||||
*sram_addr_reg_offset = adev->reg_offset[GC_HWIP][0][1] + mmRLC_GPM_UCODE_ADDR_NV10;
|
||||
*sram_data_reg_offset = adev->reg_offset[GC_HWIP][0][1] + mmRLC_GPM_UCODE_DATA_NV10;
|
||||
}
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_SDMA0:
|
||||
*sram_offset = 0x0;
|
||||
if (adev->asic_type < CHIP_NAVI10) {
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_UCODE_DATA);
|
||||
} else {
|
||||
*sram_addr_reg_offset = adev->reg_offset[GC_HWIP][0][1] + mmSDMA0_UCODE_ADDR_NV10;
|
||||
*sram_data_reg_offset = adev->reg_offset[GC_HWIP][0][1] + mmSDMA0_UCODE_DATA_NV10;
|
||||
}
|
||||
break;
|
||||
|
||||
/* TODO: needs to confirm */
|
||||
#if 0
|
||||
case AMDGPU_UCODE_ID_SDMA1:
|
||||
*sram_offset = ;
|
||||
*sram_addr_reg_offset = ;
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_UVD:
|
||||
*sram_offset = ;
|
||||
*sram_addr_reg_offset = ;
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_VCE:
|
||||
*sram_offset = ;
|
||||
*sram_addr_reg_offset = ;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case AMDGPU_UCODE_ID_MAXIMUM:
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool psp_v11_0_compare_sram_data(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *ucode,
|
||||
enum AMDGPU_UCODE_ID ucode_type)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned int fw_sram_reg_val = 0;
|
||||
unsigned int fw_sram_addr_reg_offset = 0;
|
||||
unsigned int fw_sram_data_reg_offset = 0;
|
||||
unsigned int ucode_size;
|
||||
uint32_t *ucode_mem = NULL;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
err = psp_v11_0_sram_map(adev, &fw_sram_reg_val, &fw_sram_addr_reg_offset,
|
||||
&fw_sram_data_reg_offset, ucode_type);
|
||||
if (err)
|
||||
return false;
|
||||
|
||||
WREG32(fw_sram_addr_reg_offset, fw_sram_reg_val);
|
||||
|
||||
ucode_size = ucode->ucode_size;
|
||||
ucode_mem = (uint32_t *)ucode->kaddr;
|
||||
while (ucode_size) {
|
||||
fw_sram_reg_val = RREG32(fw_sram_data_reg_offset);
|
||||
|
||||
if (*ucode_mem != fw_sram_reg_val)
|
||||
return false;
|
||||
|
||||
ucode_mem++;
|
||||
/* 4 bytes */
|
||||
ucode_size -= 4;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int psp_v11_0_mode1_reset(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
|
@ -1099,7 +888,7 @@ static uint32_t psp_v11_0_ring_get_wptr(struct psp_context *psp)
|
|||
uint32_t data;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
if (psp_v11_0_support_vmr_ring(psp))
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102);
|
||||
else
|
||||
data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67);
|
||||
|
@ -1111,7 +900,7 @@ static void psp_v11_0_ring_set_wptr(struct psp_context *psp, uint32_t value)
|
|||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
if (psp_v11_0_support_vmr_ring(psp)) {
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, value);
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, GFX_CTRL_CMD_ID_CONSUME_CMD);
|
||||
} else
|
||||
|
@ -1203,13 +992,11 @@ static const struct psp_funcs psp_v11_0_funcs = {
|
|||
.ring_create = psp_v11_0_ring_create,
|
||||
.ring_stop = psp_v11_0_ring_stop,
|
||||
.ring_destroy = psp_v11_0_ring_destroy,
|
||||
.compare_sram_data = psp_v11_0_compare_sram_data,
|
||||
.mode1_reset = psp_v11_0_mode1_reset,
|
||||
.xgmi_get_topology_info = psp_v11_0_xgmi_get_topology_info,
|
||||
.xgmi_set_topology_info = psp_v11_0_xgmi_set_topology_info,
|
||||
.xgmi_get_hive_id = psp_v11_0_xgmi_get_hive_id,
|
||||
.xgmi_get_node_id = psp_v11_0_xgmi_get_node_id,
|
||||
.support_vmr_ring = psp_v11_0_support_vmr_ring,
|
||||
.ras_trigger_error = psp_v11_0_ras_trigger_error,
|
||||
.ras_cure_posion = psp_v11_0_ras_cure_posion,
|
||||
.rlc_autoload_start = psp_v11_0_rlc_autoload_start,
|
||||
|
|
|
@ -45,11 +45,7 @@ static int psp_v12_0_init_microcode(struct psp_context *psp)
|
|||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
const char *chip_name;
|
||||
char fw_name[30];
|
||||
int err = 0;
|
||||
const struct psp_firmware_header_v1_0 *asd_hdr;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_RENOIR:
|
||||
|
@ -59,28 +55,7 @@ static int psp_v12_0_init_microcode(struct psp_context *psp)
|
|||
BUG();
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_asd.bin", chip_name);
|
||||
err = request_firmware(&adev->psp.asd_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out1;
|
||||
|
||||
err = amdgpu_ucode_validate(adev->psp.asd_fw);
|
||||
if (err)
|
||||
goto out1;
|
||||
|
||||
asd_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.asd_fw->data;
|
||||
adev->psp.asd_fw_version = le32_to_cpu(asd_hdr->header.ucode_version);
|
||||
adev->psp.asd_feature_version = le32_to_cpu(asd_hdr->ucode_feature_version);
|
||||
adev->psp.asd_ucode_size = le32_to_cpu(asd_hdr->header.ucode_size_bytes);
|
||||
adev->psp.asd_start_addr = (uint8_t *)asd_hdr +
|
||||
le32_to_cpu(asd_hdr->header.ucode_array_offset_bytes);
|
||||
|
||||
return 0;
|
||||
|
||||
out1:
|
||||
release_firmware(adev->psp.asd_fw);
|
||||
adev->psp.asd_fw = NULL;
|
||||
|
||||
err = psp_init_asd_microcode(psp, chip_name);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -95,11 +70,8 @@ static int psp_v12_0_bootloader_load_sysdrv(struct psp_context *psp)
|
|||
* are already been loaded.
|
||||
*/
|
||||
sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
|
||||
if (sol_reg) {
|
||||
psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58);
|
||||
printk("sos fw version = 0x%x.\n", psp->sos_fw_version);
|
||||
if (sol_reg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait for bootloader to signify that is ready having bit 31 of C2PMSG_35 set to 1 */
|
||||
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35),
|
||||
|
@ -228,13 +200,6 @@ static int psp_v12_0_ring_init(struct psp_context *psp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool psp_v12_0_support_vmr_ring(struct psp_context *psp)
|
||||
{
|
||||
if (amdgpu_sriov_vf(psp->adev) && psp->sos_fw_version > 0x80045)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int psp_v12_0_ring_create(struct psp_context *psp,
|
||||
enum psp_ring_type ring_type)
|
||||
{
|
||||
|
@ -243,7 +208,7 @@ static int psp_v12_0_ring_create(struct psp_context *psp,
|
|||
struct psp_ring *ring = &psp->km_ring;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
if (psp_v12_0_support_vmr_ring(psp)) {
|
||||
if (amdgpu_sriov_vf(psp->adev)) {
|
||||
/* Write low address of the ring to C2PMSG_102 */
|
||||
psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, psp_ring_reg);
|
||||
|
@ -295,7 +260,7 @@ static int psp_v12_0_ring_stop(struct psp_context *psp,
|
|||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
/* Write the ring destroy command*/
|
||||
if (psp_v12_0_support_vmr_ring(psp))
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101,
|
||||
GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING);
|
||||
else
|
||||
|
@ -306,7 +271,7 @@ static int psp_v12_0_ring_stop(struct psp_context *psp,
|
|||
mdelay(20);
|
||||
|
||||
/* Wait for response flag (bit 31) */
|
||||
if (psp_v12_0_support_vmr_ring(psp))
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_101),
|
||||
0x80000000, 0x80000000, false);
|
||||
else
|
||||
|
@ -334,128 +299,6 @@ static int psp_v12_0_ring_destroy(struct psp_context *psp,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
psp_v12_0_sram_map(struct amdgpu_device *adev,
|
||||
unsigned int *sram_offset, unsigned int *sram_addr_reg_offset,
|
||||
unsigned int *sram_data_reg_offset,
|
||||
enum AMDGPU_UCODE_ID ucode_id)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (ucode_id) {
|
||||
/* TODO: needs to confirm */
|
||||
#if 0
|
||||
case AMDGPU_UCODE_ID_SMC:
|
||||
*sram_offset = 0;
|
||||
*sram_addr_reg_offset = 0;
|
||||
*sram_data_reg_offset = 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_CE:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_CE_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_CE_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_PFP:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_PFP_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_PFP_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_ME:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_ME_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_ME_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_MEC1:
|
||||
*sram_offset = 0x10000;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_MEC_ME1_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_MEC_ME1_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_MEC2:
|
||||
*sram_offset = 0x10000;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_MEC2_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_MEC2_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_RLC_G:
|
||||
*sram_offset = 0x2000;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_SDMA0:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_UCODE_DATA);
|
||||
break;
|
||||
|
||||
/* TODO: needs to confirm */
|
||||
#if 0
|
||||
case AMDGPU_UCODE_ID_SDMA1:
|
||||
*sram_offset = ;
|
||||
*sram_addr_reg_offset = ;
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_UVD:
|
||||
*sram_offset = ;
|
||||
*sram_addr_reg_offset = ;
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_VCE:
|
||||
*sram_offset = ;
|
||||
*sram_addr_reg_offset = ;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case AMDGPU_UCODE_ID_MAXIMUM:
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool psp_v12_0_compare_sram_data(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *ucode,
|
||||
enum AMDGPU_UCODE_ID ucode_type)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned int fw_sram_reg_val = 0;
|
||||
unsigned int fw_sram_addr_reg_offset = 0;
|
||||
unsigned int fw_sram_data_reg_offset = 0;
|
||||
unsigned int ucode_size;
|
||||
uint32_t *ucode_mem = NULL;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
err = psp_v12_0_sram_map(adev, &fw_sram_reg_val, &fw_sram_addr_reg_offset,
|
||||
&fw_sram_data_reg_offset, ucode_type);
|
||||
if (err)
|
||||
return false;
|
||||
|
||||
WREG32(fw_sram_addr_reg_offset, fw_sram_reg_val);
|
||||
|
||||
ucode_size = ucode->ucode_size;
|
||||
ucode_mem = (uint32_t *)ucode->kaddr;
|
||||
while (ucode_size) {
|
||||
fw_sram_reg_val = RREG32(fw_sram_data_reg_offset);
|
||||
|
||||
if (*ucode_mem != fw_sram_reg_val)
|
||||
return false;
|
||||
|
||||
ucode_mem++;
|
||||
/* 4 bytes */
|
||||
ucode_size -= 4;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int psp_v12_0_mode1_reset(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
|
@ -495,7 +338,7 @@ static uint32_t psp_v12_0_ring_get_wptr(struct psp_context *psp)
|
|||
uint32_t data;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
if (psp_v12_0_support_vmr_ring(psp))
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102);
|
||||
else
|
||||
data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67);
|
||||
|
@ -507,7 +350,7 @@ static void psp_v12_0_ring_set_wptr(struct psp_context *psp, uint32_t value)
|
|||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
if (psp_v12_0_support_vmr_ring(psp)) {
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, value);
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, GFX_CTRL_CMD_ID_CONSUME_CMD);
|
||||
} else
|
||||
|
@ -522,7 +365,6 @@ static const struct psp_funcs psp_v12_0_funcs = {
|
|||
.ring_create = psp_v12_0_ring_create,
|
||||
.ring_stop = psp_v12_0_ring_stop,
|
||||
.ring_destroy = psp_v12_0_ring_destroy,
|
||||
.compare_sram_data = psp_v12_0_compare_sram_data,
|
||||
.mode1_reset = psp_v12_0_mode1_reset,
|
||||
.ring_get_wptr = psp_v12_0_ring_get_wptr,
|
||||
.ring_set_wptr = psp_v12_0_ring_set_wptr,
|
||||
|
|
|
@ -50,9 +50,6 @@ MODULE_FIRMWARE("amdgpu/vega12_asd.bin");
|
|||
|
||||
#define smnMP1_FIRMWARE_FLAGS 0x3010028
|
||||
|
||||
static uint32_t sos_old_versions[] = {1517616, 1510592, 1448594, 1446554};
|
||||
|
||||
static bool psp_v3_1_support_vmr_ring(struct psp_context *psp);
|
||||
static int psp_v3_1_ring_stop(struct psp_context *psp,
|
||||
enum psp_ring_type ring_type);
|
||||
|
||||
|
@ -60,9 +57,7 @@ static int psp_v3_1_init_microcode(struct psp_context *psp)
|
|||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
const char *chip_name;
|
||||
char fw_name[30];
|
||||
int err = 0;
|
||||
const struct psp_firmware_header_v1_0 *hdr;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
|
@ -76,55 +71,15 @@ static int psp_v3_1_init_microcode(struct psp_context *psp)
|
|||
default: BUG();
|
||||
}
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sos.bin", chip_name);
|
||||
err = request_firmware(&adev->psp.sos_fw, fw_name, adev->dev);
|
||||
err = psp_init_sos_microcode(psp, chip_name);
|
||||
if (err)
|
||||
goto out;
|
||||
return err;
|
||||
|
||||
err = amdgpu_ucode_validate(adev->psp.sos_fw);
|
||||
err = psp_init_asd_microcode(psp, chip_name);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.sos_fw->data;
|
||||
adev->psp.sos_fw_version = le32_to_cpu(hdr->header.ucode_version);
|
||||
adev->psp.sos_feature_version = le32_to_cpu(hdr->ucode_feature_version);
|
||||
adev->psp.sos_bin_size = le32_to_cpu(hdr->sos_size_bytes);
|
||||
adev->psp.sys_bin_size = le32_to_cpu(hdr->header.ucode_size_bytes) -
|
||||
le32_to_cpu(hdr->sos_size_bytes);
|
||||
adev->psp.sys_start_addr = (uint8_t *)hdr +
|
||||
le32_to_cpu(hdr->header.ucode_array_offset_bytes);
|
||||
adev->psp.sos_start_addr = (uint8_t *)adev->psp.sys_start_addr +
|
||||
le32_to_cpu(hdr->sos_offset_bytes);
|
||||
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_asd.bin", chip_name);
|
||||
err = request_firmware(&adev->psp.asd_fw, fw_name, adev->dev);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = amdgpu_ucode_validate(adev->psp.asd_fw);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.asd_fw->data;
|
||||
adev->psp.asd_fw_version = le32_to_cpu(hdr->header.ucode_version);
|
||||
adev->psp.asd_feature_version = le32_to_cpu(hdr->ucode_feature_version);
|
||||
adev->psp.asd_ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
|
||||
adev->psp.asd_start_addr = (uint8_t *)hdr +
|
||||
le32_to_cpu(hdr->header.ucode_array_offset_bytes);
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
out:
|
||||
if (err) {
|
||||
dev_err(adev->dev,
|
||||
"psp v3.1: Failed to load firmware \"%s\"\n",
|
||||
fw_name);
|
||||
release_firmware(adev->psp.sos_fw);
|
||||
adev->psp.sos_fw = NULL;
|
||||
release_firmware(adev->psp.asd_fw);
|
||||
adev->psp.asd_fw = NULL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int psp_v3_1_bootloader_load_sysdrv(struct psp_context *psp)
|
||||
|
@ -168,41 +123,19 @@ static int psp_v3_1_bootloader_load_sysdrv(struct psp_context *psp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool psp_v3_1_match_version(struct amdgpu_device *adev, uint32_t ver)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (ver == adev->psp.sos_fw_version)
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Double check if the latest four legacy versions.
|
||||
* If yes, it is still the right version.
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(sos_old_versions); i++) {
|
||||
if (sos_old_versions[i] == adev->psp.sos_fw_version)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int psp_v3_1_bootloader_load_sos(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
unsigned int psp_gfxdrv_command_reg = 0;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
uint32_t sol_reg, ver;
|
||||
uint32_t sol_reg;
|
||||
|
||||
/* Check sOS sign of life register to confirm sys driver and sOS
|
||||
* are already been loaded.
|
||||
*/
|
||||
sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
|
||||
if (sol_reg) {
|
||||
psp->sos_fw_version = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58);
|
||||
printk("sos fw version = 0x%x.\n", psp->sos_fw_version);
|
||||
if (sol_reg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait for bootloader to signify that is ready having bit 31 of C2PMSG_35 set to 1 */
|
||||
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_35),
|
||||
|
@ -227,11 +160,6 @@ static int psp_v3_1_bootloader_load_sos(struct psp_context *psp)
|
|||
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_81),
|
||||
RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81),
|
||||
0, true);
|
||||
|
||||
ver = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_58);
|
||||
if (!psp_v3_1_match_version(adev, ver))
|
||||
DRM_WARN("SOS version doesn't match\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -302,7 +230,7 @@ static int psp_v3_1_ring_create(struct psp_context *psp,
|
|||
|
||||
psp_v3_1_reroute_ih(psp);
|
||||
|
||||
if (psp_v3_1_support_vmr_ring(psp)) {
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
ret = psp_v3_1_ring_stop(psp, ring_type);
|
||||
if (ret) {
|
||||
DRM_ERROR("psp_v3_1_ring_stop_sriov failed!\n");
|
||||
|
@ -360,34 +288,26 @@ static int psp_v3_1_ring_stop(struct psp_context *psp,
|
|||
enum psp_ring_type ring_type)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int psp_ring_reg = 0;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
if (psp_v3_1_support_vmr_ring(psp)) {
|
||||
/* Write the Destroy GPCOM ring command to C2PMSG_101 */
|
||||
psp_ring_reg = GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING;
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, psp_ring_reg);
|
||||
/* Write the ring destroy command*/
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101,
|
||||
GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING);
|
||||
else
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64,
|
||||
GFX_CTRL_CMD_ID_DESTROY_RINGS);
|
||||
|
||||
/* there might be handshake issue which needs delay */
|
||||
mdelay(20);
|
||||
/* there might be handshake issue with hardware which needs delay */
|
||||
mdelay(20);
|
||||
|
||||
/* Wait for response flag (bit 31) in C2PMSG_101 */
|
||||
ret = psp_wait_for(psp,
|
||||
SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_101),
|
||||
0x80000000, 0x80000000, false);
|
||||
} else {
|
||||
/* Write the ring destroy command to C2PMSG_64 */
|
||||
psp_ring_reg = 3 << 16;
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, psp_ring_reg);
|
||||
|
||||
/* there might be handshake issue which needs delay */
|
||||
mdelay(20);
|
||||
|
||||
/* Wait for response flag (bit 31) in C2PMSG_64 */
|
||||
ret = psp_wait_for(psp,
|
||||
SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
|
||||
0x80000000, 0x80000000, false);
|
||||
}
|
||||
/* Wait for response flag (bit 31) */
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_101),
|
||||
0x80000000, 0x80000000, false);
|
||||
else
|
||||
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
|
||||
0x80000000, 0x80000000, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -410,128 +330,6 @@ static int psp_v3_1_ring_destroy(struct psp_context *psp,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
psp_v3_1_sram_map(struct amdgpu_device *adev,
|
||||
unsigned int *sram_offset, unsigned int *sram_addr_reg_offset,
|
||||
unsigned int *sram_data_reg_offset,
|
||||
enum AMDGPU_UCODE_ID ucode_id)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch(ucode_id) {
|
||||
/* TODO: needs to confirm */
|
||||
#if 0
|
||||
case AMDGPU_UCODE_ID_SMC:
|
||||
*sram_offset = 0;
|
||||
*sram_addr_reg_offset = 0;
|
||||
*sram_data_reg_offset = 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_CE:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_CE_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_CE_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_PFP:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_PFP_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_PFP_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_ME:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_ME_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_ME_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_MEC1:
|
||||
*sram_offset = 0x10000;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_MEC_ME1_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_MEC_ME1_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_CP_MEC2:
|
||||
*sram_offset = 0x10000;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_MEC2_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_HYP_MEC2_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_RLC_G:
|
||||
*sram_offset = 0x2000;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UCODE_DATA);
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_SDMA0:
|
||||
*sram_offset = 0x0;
|
||||
*sram_addr_reg_offset = SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_UCODE_ADDR);
|
||||
*sram_data_reg_offset = SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_UCODE_DATA);
|
||||
break;
|
||||
|
||||
/* TODO: needs to confirm */
|
||||
#if 0
|
||||
case AMDGPU_UCODE_ID_SDMA1:
|
||||
*sram_offset = ;
|
||||
*sram_addr_reg_offset = ;
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_UVD:
|
||||
*sram_offset = ;
|
||||
*sram_addr_reg_offset = ;
|
||||
break;
|
||||
|
||||
case AMDGPU_UCODE_ID_VCE:
|
||||
*sram_offset = ;
|
||||
*sram_addr_reg_offset = ;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case AMDGPU_UCODE_ID_MAXIMUM:
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool psp_v3_1_compare_sram_data(struct psp_context *psp,
|
||||
struct amdgpu_firmware_info *ucode,
|
||||
enum AMDGPU_UCODE_ID ucode_type)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned int fw_sram_reg_val = 0;
|
||||
unsigned int fw_sram_addr_reg_offset = 0;
|
||||
unsigned int fw_sram_data_reg_offset = 0;
|
||||
unsigned int ucode_size;
|
||||
uint32_t *ucode_mem = NULL;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
err = psp_v3_1_sram_map(adev, &fw_sram_reg_val, &fw_sram_addr_reg_offset,
|
||||
&fw_sram_data_reg_offset, ucode_type);
|
||||
if (err)
|
||||
return false;
|
||||
|
||||
WREG32(fw_sram_addr_reg_offset, fw_sram_reg_val);
|
||||
|
||||
ucode_size = ucode->ucode_size;
|
||||
ucode_mem = (uint32_t *)ucode->kaddr;
|
||||
while (ucode_size) {
|
||||
fw_sram_reg_val = RREG32(fw_sram_data_reg_offset);
|
||||
|
||||
if (*ucode_mem != fw_sram_reg_val)
|
||||
return false;
|
||||
|
||||
ucode_mem++;
|
||||
/* 4 bytes */
|
||||
ucode_size -= 4;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool psp_v3_1_smu_reload_quirk(struct psp_context *psp)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
@ -575,20 +373,12 @@ static int psp_v3_1_mode1_reset(struct psp_context *psp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool psp_v3_1_support_vmr_ring(struct psp_context *psp)
|
||||
{
|
||||
if (amdgpu_sriov_vf(psp->adev))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint32_t psp_v3_1_ring_get_wptr(struct psp_context *psp)
|
||||
{
|
||||
uint32_t data;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
if (psp_v3_1_support_vmr_ring(psp))
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102);
|
||||
else
|
||||
data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67);
|
||||
|
@ -599,7 +389,7 @@ static void psp_v3_1_ring_set_wptr(struct psp_context *psp, uint32_t value)
|
|||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
if (psp_v3_1_support_vmr_ring(psp)) {
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, value);
|
||||
/* send interrupt to PSP for SRIOV ring write pointer update */
|
||||
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101,
|
||||
|
@ -616,10 +406,8 @@ static const struct psp_funcs psp_v3_1_funcs = {
|
|||
.ring_create = psp_v3_1_ring_create,
|
||||
.ring_stop = psp_v3_1_ring_stop,
|
||||
.ring_destroy = psp_v3_1_ring_destroy,
|
||||
.compare_sram_data = psp_v3_1_compare_sram_data,
|
||||
.smu_reload_quirk = psp_v3_1_smu_reload_quirk,
|
||||
.mode1_reset = psp_v3_1_mode1_reset,
|
||||
.support_vmr_ring = psp_v3_1_support_vmr_ring,
|
||||
.ring_get_wptr = psp_v3_1_ring_get_wptr,
|
||||
.ring_set_wptr = psp_v3_1_ring_set_wptr,
|
||||
};
|
||||
|
|
|
@ -355,8 +355,6 @@ static void sdma_v2_4_gfx_stop(struct amdgpu_device *adev)
|
|||
ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0);
|
||||
WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl);
|
||||
}
|
||||
sdma0->sched.ready = false;
|
||||
sdma1->sched.ready = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -614,7 +612,8 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
tmp = 0xCAFEDEAD;
|
||||
adev->wb.wb[index] = cpu_to_le32(tmp);
|
||||
memset(&ib, 0, sizeof(ib));
|
||||
r = amdgpu_ib_get(adev, NULL, 256, &ib);
|
||||
r = amdgpu_ib_get(adev, NULL, 256,
|
||||
AMDGPU_IB_POOL_DIRECT, &ib);
|
||||
if (r)
|
||||
goto err0;
|
||||
|
||||
|
@ -874,7 +873,8 @@ static int sdma_v2_4_sw_init(void *handle)
|
|||
&adev->sdma.trap_irq,
|
||||
(i == 0) ?
|
||||
AMDGPU_SDMA_IRQ_INSTANCE0 :
|
||||
AMDGPU_SDMA_IRQ_INSTANCE1);
|
||||
AMDGPU_SDMA_IRQ_INSTANCE1,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -529,8 +529,6 @@ static void sdma_v3_0_gfx_stop(struct amdgpu_device *adev)
|
|||
ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0);
|
||||
WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl);
|
||||
}
|
||||
sdma0->sched.ready = false;
|
||||
sdma1->sched.ready = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -886,7 +884,8 @@ static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
tmp = 0xCAFEDEAD;
|
||||
adev->wb.wb[index] = cpu_to_le32(tmp);
|
||||
memset(&ib, 0, sizeof(ib));
|
||||
r = amdgpu_ib_get(adev, NULL, 256, &ib);
|
||||
r = amdgpu_ib_get(adev, NULL, 256,
|
||||
AMDGPU_IB_POOL_DIRECT, &ib);
|
||||
if (r)
|
||||
goto err0;
|
||||
|
||||
|
@ -1158,7 +1157,8 @@ static int sdma_v3_0_sw_init(void *handle)
|
|||
&adev->sdma.trap_irq,
|
||||
(i == 0) ?
|
||||
AMDGPU_SDMA_IRQ_INSTANCE0 :
|
||||
AMDGPU_SDMA_IRQ_INSTANCE1);
|
||||
AMDGPU_SDMA_IRQ_INSTANCE1,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -115,17 +115,21 @@ static const struct soc15_reg_golden golden_settings_sdma_4[] = {
|
|||
static const struct soc15_reg_golden golden_settings_sdma_vg10[] = {
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG, 0x0018773f, 0x00104002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00104002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CHICKEN_BITS, 0xfe931f07, 0x02831d07),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG, 0x0018773f, 0x00104002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00104002)
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00104002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_sdma_vg12[] = {
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG, 0x0018773f, 0x00104001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00104001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CHICKEN_BITS, 0xfe931f07, 0x02831d07),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG, 0x0018773f, 0x00104001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00104001)
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x0018773f, 0x00104001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_sdma_4_1[] = {
|
||||
|
@ -174,6 +178,7 @@ static const struct soc15_reg_golden golden_settings_sdma0_4_2[] =
|
|||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC7_RB_RPTR_ADDR_LO, 0xfffffffd, 0x00000001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC7_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_sdma1_4_2[] = {
|
||||
|
@ -203,6 +208,7 @@ static const struct soc15_reg_golden golden_settings_sdma1_4_2[] = {
|
|||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC7_RB_RPTR_ADDR_LO, 0xfffffffd, 0x00000001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC7_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_PAGE, 0x000003ff, 0x000003c0),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_sdma_rv1[] =
|
||||
|
@ -222,27 +228,35 @@ static const struct soc15_reg_golden golden_settings_sdma_arct[] =
|
|||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA2, 0, mmSDMA2_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA2, 0, mmSDMA2_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA2, 0, mmSDMA2_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA2, 0, mmSDMA2_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA3, 0, mmSDMA3_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA3, 0, mmSDMA3_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA3, 0, mmSDMA3_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA3, 0, mmSDMA3_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA4, 0, mmSDMA4_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA4, 0, mmSDMA4_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA4, 0, mmSDMA4_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA4, 0, mmSDMA4_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA5, 0, mmSDMA5_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA5, 0, mmSDMA5_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA5, 0, mmSDMA5_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA5, 0, mmSDMA5_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA6, 0, mmSDMA6_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA6, 0, mmSDMA6_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA6, 0, mmSDMA6_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA6, 0, mmSDMA6_UTCL1_TIMEOUT, 0xffffffff, 0x00010001),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA7, 0, mmSDMA7_CHICKEN_BITS, 0xfe931f07, 0x02831f07),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA7, 0, mmSDMA7_GB_ADDR_CONFIG, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA7, 0, mmSDMA7_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002)
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA7, 0, mmSDMA7_GB_ADDR_CONFIG_READ, 0x0000773f, 0x00004002),
|
||||
SOC15_REG_GOLDEN_VALUE(SDMA7, 0, mmSDMA7_UTCL1_TIMEOUT, 0xffffffff, 0x00010001)
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_sdma_4_3[] = {
|
||||
|
@ -923,8 +937,6 @@ static void sdma_v4_0_gfx_stop(struct amdgpu_device *adev)
|
|||
ib_cntl = RREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL);
|
||||
ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0);
|
||||
WREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL, ib_cntl);
|
||||
|
||||
sdma[i]->sched.ready = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -971,8 +983,6 @@ static void sdma_v4_0_page_stop(struct amdgpu_device *adev)
|
|||
ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_PAGE_IB_CNTL,
|
||||
IB_ENABLE, 0);
|
||||
WREG32_SDMA(i, mmSDMA0_PAGE_IB_CNTL, ib_cntl);
|
||||
|
||||
sdma[i]->sched.ready = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1539,7 +1549,8 @@ static int sdma_v4_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
tmp = 0xCAFEDEAD;
|
||||
adev->wb.wb[index] = cpu_to_le32(tmp);
|
||||
memset(&ib, 0, sizeof(ib));
|
||||
r = amdgpu_ib_get(adev, NULL, 256, &ib);
|
||||
r = amdgpu_ib_get(adev, NULL, 256,
|
||||
AMDGPU_IB_POOL_DIRECT, &ib);
|
||||
if (r)
|
||||
goto err0;
|
||||
|
||||
|
@ -1840,7 +1851,7 @@ static int sdma_v4_0_sw_init(void *handle)
|
|||
ring->ring_obj = NULL;
|
||||
ring->use_doorbell = true;
|
||||
|
||||
DRM_INFO("use_doorbell being set to: [%s]\n",
|
||||
DRM_DEBUG("SDMA %d use_doorbell being set to: [%s]\n", i,
|
||||
ring->use_doorbell?"true":"false");
|
||||
|
||||
/* doorbell size is 2 dwords, get DWORD offset */
|
||||
|
@ -1848,7 +1859,8 @@ static int sdma_v4_0_sw_init(void *handle)
|
|||
|
||||
sprintf(ring->name, "sdma%d", i);
|
||||
r = amdgpu_ring_init(adev, ring, 1024, &adev->sdma.trap_irq,
|
||||
AMDGPU_SDMA_IRQ_INSTANCE0 + i);
|
||||
AMDGPU_SDMA_IRQ_INSTANCE0 + i,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -1866,7 +1878,8 @@ static int sdma_v4_0_sw_init(void *handle)
|
|||
sprintf(ring->name, "page%d", i);
|
||||
r = amdgpu_ring_init(adev, ring, 1024,
|
||||
&adev->sdma.trap_irq,
|
||||
AMDGPU_SDMA_IRQ_INSTANCE0 + i);
|
||||
AMDGPU_SDMA_IRQ_INSTANCE0 + i,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,29 @@ static const struct soc15_reg_golden golden_settings_sdma_5[] = {
|
|||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_UTCL1_PAGE, 0x00ffffff, 0x000c5c00)
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_sdma_5_sriov[] = {
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_GFX_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_PAGE_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC2_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC3_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC4_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC5_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC6_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC7_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_GFX_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_PAGE_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC2_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC3_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC4_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC5_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC6_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC7_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
|
||||
};
|
||||
|
||||
static const struct soc15_reg_golden golden_settings_sdma_nv10[] = {
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC3_RB_WPTR_POLL_CNTL, 0x0000fff0, 0x00403000),
|
||||
SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC3_RB_WPTR_POLL_CNTL, 0x0000fff0, 0x00403000),
|
||||
|
@ -141,9 +164,14 @@ static void sdma_v5_0_init_golden_registers(struct amdgpu_device *adev)
|
|||
(const u32)ARRAY_SIZE(golden_settings_sdma_nv14));
|
||||
break;
|
||||
case CHIP_NAVI12:
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_sdma_5,
|
||||
(const u32)ARRAY_SIZE(golden_settings_sdma_5));
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_sdma_5_sriov,
|
||||
(const u32)ARRAY_SIZE(golden_settings_sdma_5_sriov));
|
||||
else
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_sdma_5,
|
||||
(const u32)ARRAY_SIZE(golden_settings_sdma_5));
|
||||
soc15_program_register_sequence(adev,
|
||||
golden_settings_sdma_nv12,
|
||||
(const u32)ARRAY_SIZE(golden_settings_sdma_nv12));
|
||||
|
@ -502,9 +530,6 @@ static void sdma_v5_0_gfx_stop(struct amdgpu_device *adev)
|
|||
ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0);
|
||||
WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_GFX_IB_CNTL), ib_cntl);
|
||||
}
|
||||
|
||||
sdma0->sched.ready = false;
|
||||
sdma1->sched.ready = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -529,7 +554,7 @@ static void sdma_v5_0_rlc_stop(struct amdgpu_device *adev)
|
|||
*/
|
||||
static void sdma_v5_0_ctx_switch_enable(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
u32 f32_cntl, phase_quantum = 0;
|
||||
u32 f32_cntl = 0, phase_quantum = 0;
|
||||
int i;
|
||||
|
||||
if (amdgpu_sdma_phase_quantum) {
|
||||
|
@ -557,9 +582,12 @@ static void sdma_v5_0_ctx_switch_enable(struct amdgpu_device *adev, bool enable)
|
|||
}
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
f32_cntl = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL));
|
||||
f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
|
||||
AUTO_CTXSW_ENABLE, enable ? 1 : 0);
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
f32_cntl = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL));
|
||||
f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
|
||||
AUTO_CTXSW_ENABLE, enable ? 1 : 0);
|
||||
}
|
||||
|
||||
if (enable && amdgpu_sdma_phase_quantum) {
|
||||
WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_PHASE0_QUANTUM),
|
||||
phase_quantum);
|
||||
|
@ -568,7 +596,8 @@ static void sdma_v5_0_ctx_switch_enable(struct amdgpu_device *adev, bool enable)
|
|||
WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_PHASE2_QUANTUM),
|
||||
phase_quantum);
|
||||
}
|
||||
WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL), f32_cntl);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL), f32_cntl);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -591,6 +620,9 @@ static void sdma_v5_0_enable(struct amdgpu_device *adev, bool enable)
|
|||
sdma_v5_0_rlc_stop(adev);
|
||||
}
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return;
|
||||
|
||||
for (i = 0; i < adev->sdma.num_instances; i++) {
|
||||
f32_cntl = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_F32_CNTL));
|
||||
f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, enable ? 0 : 1);
|
||||
|
@ -623,7 +655,8 @@ static int sdma_v5_0_gfx_resume(struct amdgpu_device *adev)
|
|||
ring = &adev->sdma.instance[i].ring;
|
||||
wb_offset = (ring->rptr_offs * 4);
|
||||
|
||||
WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL), 0);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL), 0);
|
||||
|
||||
/* Set ring buffer size in dwords */
|
||||
rb_bufsz = order_base_2(ring->ring_size / 4);
|
||||
|
@ -699,26 +732,28 @@ static int sdma_v5_0_gfx_resume(struct amdgpu_device *adev)
|
|||
/* set minor_ptr_update to 0 after wptr programed */
|
||||
WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_GFX_MINOR_PTR_UPDATE), 0);
|
||||
|
||||
/* set utc l1 enable flag always to 1 */
|
||||
temp = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL));
|
||||
temp = REG_SET_FIELD(temp, SDMA0_CNTL, UTC_L1_ENABLE, 1);
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
/* set utc l1 enable flag always to 1 */
|
||||
temp = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL));
|
||||
temp = REG_SET_FIELD(temp, SDMA0_CNTL, UTC_L1_ENABLE, 1);
|
||||
|
||||
/* enable MCBP */
|
||||
temp = REG_SET_FIELD(temp, SDMA0_CNTL, MIDCMD_PREEMPT_ENABLE, 1);
|
||||
WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL), temp);
|
||||
/* enable MCBP */
|
||||
temp = REG_SET_FIELD(temp, SDMA0_CNTL, MIDCMD_PREEMPT_ENABLE, 1);
|
||||
WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL), temp);
|
||||
|
||||
/* Set up RESP_MODE to non-copy addresses */
|
||||
temp = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_CNTL));
|
||||
temp = REG_SET_FIELD(temp, SDMA0_UTCL1_CNTL, RESP_MODE, 3);
|
||||
temp = REG_SET_FIELD(temp, SDMA0_UTCL1_CNTL, REDO_DELAY, 9);
|
||||
WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_CNTL), temp);
|
||||
/* Set up RESP_MODE to non-copy addresses */
|
||||
temp = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_CNTL));
|
||||
temp = REG_SET_FIELD(temp, SDMA0_UTCL1_CNTL, RESP_MODE, 3);
|
||||
temp = REG_SET_FIELD(temp, SDMA0_UTCL1_CNTL, REDO_DELAY, 9);
|
||||
WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_CNTL), temp);
|
||||
|
||||
/* program default cache read and write policy */
|
||||
temp = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE));
|
||||
/* clean read policy and write policy bits */
|
||||
temp &= 0xFF0FFF;
|
||||
temp |= ((CACHE_READ_POLICY_L2__DEFAULT << 12) | (CACHE_WRITE_POLICY_L2__DEFAULT << 14));
|
||||
WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE), temp);
|
||||
/* program default cache read and write policy */
|
||||
temp = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE));
|
||||
/* clean read policy and write policy bits */
|
||||
temp &= 0xFF0FFF;
|
||||
temp |= ((CACHE_READ_POLICY_L2__DEFAULT << 12) | (CACHE_WRITE_POLICY_L2__DEFAULT << 14));
|
||||
WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE), temp);
|
||||
}
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
/* unhalt engine */
|
||||
|
@ -948,7 +983,8 @@ static int sdma_v5_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
tmp = 0xCAFEDEAD;
|
||||
adev->wb.wb[index] = cpu_to_le32(tmp);
|
||||
memset(&ib, 0, sizeof(ib));
|
||||
r = amdgpu_ib_get(adev, NULL, 256, &ib);
|
||||
r = amdgpu_ib_get(adev, NULL, 256,
|
||||
AMDGPU_IB_POOL_DIRECT, &ib);
|
||||
if (r) {
|
||||
DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r);
|
||||
goto err0;
|
||||
|
@ -1224,7 +1260,7 @@ static int sdma_v5_0_sw_init(void *handle)
|
|||
ring->ring_obj = NULL;
|
||||
ring->use_doorbell = true;
|
||||
|
||||
DRM_INFO("use_doorbell being set to: [%s]\n",
|
||||
DRM_DEBUG("SDMA %d use_doorbell being set to: [%s]\n", i,
|
||||
ring->use_doorbell?"true":"false");
|
||||
|
||||
ring->doorbell_index = (i == 0) ?
|
||||
|
@ -1236,7 +1272,8 @@ static int sdma_v5_0_sw_init(void *handle)
|
|||
&adev->sdma.trap_irq,
|
||||
(i == 0) ?
|
||||
AMDGPU_SDMA_IRQ_INSTANCE0 :
|
||||
AMDGPU_SDMA_IRQ_INSTANCE1);
|
||||
AMDGPU_SDMA_IRQ_INSTANCE1,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
@ -1387,14 +1424,16 @@ static int sdma_v5_0_set_trap_irq_state(struct amdgpu_device *adev,
|
|||
{
|
||||
u32 sdma_cntl;
|
||||
|
||||
u32 reg_offset = (type == AMDGPU_SDMA_IRQ_INSTANCE0) ?
|
||||
sdma_v5_0_get_reg_offset(adev, 0, mmSDMA0_CNTL) :
|
||||
sdma_v5_0_get_reg_offset(adev, 1, mmSDMA0_CNTL);
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
u32 reg_offset = (type == AMDGPU_SDMA_IRQ_INSTANCE0) ?
|
||||
sdma_v5_0_get_reg_offset(adev, 0, mmSDMA0_CNTL) :
|
||||
sdma_v5_0_get_reg_offset(adev, 1, mmSDMA0_CNTL);
|
||||
|
||||
sdma_cntl = RREG32(reg_offset);
|
||||
sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA0_CNTL, TRAP_ENABLE,
|
||||
state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
|
||||
WREG32(reg_offset, sdma_cntl);
|
||||
sdma_cntl = RREG32(reg_offset);
|
||||
sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA0_CNTL, TRAP_ENABLE,
|
||||
state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
|
||||
WREG32(reg_offset, sdma_cntl);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1249,12 +1249,6 @@ static int si_set_uvd_clocks(struct amdgpu_device *adev, u32 vclk, u32 dclk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void si_detect_hw_virtualization(struct amdgpu_device *adev)
|
||||
{
|
||||
if (is_virtual_machine()) /* passthrough mode */
|
||||
adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
|
||||
}
|
||||
|
||||
static void si_flush_hdp(struct amdgpu_device *adev, struct amdgpu_ring *ring)
|
||||
{
|
||||
if (!ring || !ring->funcs->emit_wreg) {
|
||||
|
@ -2165,8 +2159,6 @@ static const struct amdgpu_ip_block_version si_common_ip_block =
|
|||
|
||||
int si_set_ip_blocks(struct amdgpu_device *adev)
|
||||
{
|
||||
si_detect_hw_virtualization(adev);
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VERDE:
|
||||
case CHIP_TAHITI:
|
||||
|
|
|
@ -124,7 +124,6 @@ static void si_dma_stop(struct amdgpu_device *adev)
|
|||
|
||||
if (adev->mman.buffer_funcs_ring == ring)
|
||||
amdgpu_ttm_set_buffer_funcs_status(adev, false);
|
||||
ring->sched.ready = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,7 +266,8 @@ static int si_dma_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
tmp = 0xCAFEDEAD;
|
||||
adev->wb.wb[index] = cpu_to_le32(tmp);
|
||||
memset(&ib, 0, sizeof(ib));
|
||||
r = amdgpu_ib_get(adev, NULL, 256, &ib);
|
||||
r = amdgpu_ib_get(adev, NULL, 256,
|
||||
AMDGPU_IB_POOL_DIRECT, &ib);
|
||||
if (r)
|
||||
goto err0;
|
||||
|
||||
|
@ -504,7 +504,8 @@ static int si_dma_sw_init(void *handle)
|
|||
&adev->sdma.trap_irq,
|
||||
(i == 0) ?
|
||||
AMDGPU_SDMA_IRQ_INSTANCE0 :
|
||||
AMDGPU_SDMA_IRQ_INSTANCE1);
|
||||
AMDGPU_SDMA_IRQ_INSTANCE1,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -345,26 +345,6 @@ static const struct si_dte_data dte_data_tahiti =
|
|||
false
|
||||
};
|
||||
|
||||
#if 0
|
||||
static const struct si_dte_data dte_data_tahiti_le =
|
||||
{
|
||||
{ 0x1E8480, 0x7A1200, 0x2160EC0, 0x3938700, 0 },
|
||||
{ 0x7D, 0x7D, 0x4E4, 0xB00, 0 },
|
||||
0x5,
|
||||
0xAFC8,
|
||||
0x64,
|
||||
0x32,
|
||||
1,
|
||||
0,
|
||||
0x10,
|
||||
{ 0x78, 0x7C, 0x82, 0x88, 0x8E, 0x94, 0x9A, 0xA0, 0xA6, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC, 0xC0, 0xC4 },
|
||||
{ 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700 },
|
||||
{ 0x2AF8, 0x2AF8, 0x29BB, 0x27F9, 0x2637, 0x2475, 0x22B3, 0x20F1, 0x1F2F, 0x1D6D, 0x1734, 0x1414, 0x10F4, 0xDD4, 0xAB4, 0x794 },
|
||||
85,
|
||||
true
|
||||
};
|
||||
#endif
|
||||
|
||||
static const struct si_dte_data dte_data_tahiti_pro =
|
||||
{
|
||||
{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
|
||||
|
|
|
@ -708,7 +708,6 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
|||
adev->df.funcs = &df_v1_7_funcs;
|
||||
|
||||
adev->rev_id = soc15_get_rev_id(adev);
|
||||
adev->nbio.funcs->detect_hw_virt(adev);
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
adev->virt.ops = &xgpu_ai_virt_ops;
|
||||
|
@ -1218,7 +1217,7 @@ static int soc15_common_early_init(void *handle)
|
|||
AMD_CG_SUPPORT_IH_CG |
|
||||
AMD_CG_SUPPORT_VCN_MGCG |
|
||||
AMD_CG_SUPPORT_JPEG_MGCG;
|
||||
adev->pg_flags = 0;
|
||||
adev->pg_flags = AMD_PG_SUPPORT_VCN | AMD_PG_SUPPORT_VCN_DPG;
|
||||
adev->external_rev_id = adev->rev_id + 0x32;
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
|
|
|
@ -118,7 +118,8 @@ static int uvd_v4_2_sw_init(void *handle)
|
|||
|
||||
ring = &adev->uvd.inst->ring;
|
||||
sprintf(ring->name, "uvd");
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0);
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -210,13 +211,10 @@ done:
|
|||
static int uvd_v4_2_hw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_ring *ring = &adev->uvd.inst->ring;
|
||||
|
||||
if (RREG32(mmUVD_STATUS) != 0)
|
||||
uvd_v4_2_stop(adev);
|
||||
|
||||
ring->sched.ready = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,7 +116,8 @@ static int uvd_v5_0_sw_init(void *handle)
|
|||
|
||||
ring = &adev->uvd.inst->ring;
|
||||
sprintf(ring->name, "uvd");
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0);
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -208,13 +209,10 @@ done:
|
|||
static int uvd_v5_0_hw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_ring *ring = &adev->uvd.inst->ring;
|
||||
|
||||
if (RREG32(mmUVD_STATUS) != 0)
|
||||
uvd_v5_0_stop(adev);
|
||||
|
||||
ring->sched.ready = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -216,7 +216,8 @@ static int uvd_v6_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle
|
|||
uint64_t addr;
|
||||
int i, r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
|
||||
AMDGPU_IB_POOL_DIRECT, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -279,7 +280,8 @@ static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring,
|
|||
uint64_t addr;
|
||||
int i, r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
|
||||
AMDGPU_IB_POOL_DIRECT, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -416,7 +418,8 @@ static int uvd_v6_0_sw_init(void *handle)
|
|||
|
||||
ring = &adev->uvd.inst->ring;
|
||||
sprintf(ring->name, "uvd");
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0);
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -428,7 +431,9 @@ static int uvd_v6_0_sw_init(void *handle)
|
|||
for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
|
||||
ring = &adev->uvd.inst->ring_enc[i];
|
||||
sprintf(ring->name, "uvd_enc%d", i);
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0);
|
||||
r = amdgpu_ring_init(adev, ring, 512,
|
||||
&adev->uvd.inst->irq, 0,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
@ -535,13 +540,10 @@ done:
|
|||
static int uvd_v6_0_hw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_ring *ring = &adev->uvd.inst->ring;
|
||||
|
||||
if (RREG32(mmUVD_STATUS) != 0)
|
||||
uvd_v6_0_stop(adev);
|
||||
|
||||
ring->sched.ready = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -224,7 +224,8 @@ static int uvd_v7_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle
|
|||
uint64_t addr;
|
||||
int i, r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
|
||||
AMDGPU_IB_POOL_DIRECT, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -286,7 +287,8 @@ static int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handl
|
|||
uint64_t addr;
|
||||
int i, r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
|
||||
AMDGPU_IB_POOL_DIRECT, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -450,7 +452,9 @@ static int uvd_v7_0_sw_init(void *handle)
|
|||
if (!amdgpu_sriov_vf(adev)) {
|
||||
ring = &adev->uvd.inst[j].ring;
|
||||
sprintf(ring->name, "uvd_%d", ring->me);
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst[j].irq, 0);
|
||||
r = amdgpu_ring_init(adev, ring, 512,
|
||||
&adev->uvd.inst[j].irq, 0,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
@ -469,7 +473,9 @@ static int uvd_v7_0_sw_init(void *handle)
|
|||
else
|
||||
ring->doorbell_index = adev->doorbell_index.uvd_vce.uvd_ring2_3 * 2 + 1;
|
||||
}
|
||||
r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst[j].irq, 0);
|
||||
r = amdgpu_ring_init(adev, ring, 512,
|
||||
&adev->uvd.inst[j].irq, 0,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
@ -598,7 +604,6 @@ done:
|
|||
static int uvd_v7_0_hw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int i;
|
||||
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
uvd_v7_0_stop(adev);
|
||||
|
@ -607,12 +612,6 @@ static int uvd_v7_0_hw_fini(void *handle)
|
|||
DRM_DEBUG("For SRIOV client, shouldn't do anything.\n");
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
|
||||
if (adev->uvd.harvest_config & (1 << i))
|
||||
continue;
|
||||
adev->uvd.inst[i].ring.sched.ready = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1694,7 +1693,7 @@ static int uvd_v7_0_set_clockgating_state(void *handle,
|
|||
enum amd_clockgating_state state)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
|
||||
bool enable = (state == AMD_CG_STATE_GATE);
|
||||
|
||||
uvd_v7_0_set_bypass_mode(adev, enable);
|
||||
|
||||
|
|
|
@ -434,7 +434,8 @@ static int vce_v2_0_sw_init(void *handle)
|
|||
ring = &adev->vce.ring[i];
|
||||
sprintf(ring->name, "vce%d", i);
|
||||
r = amdgpu_ring_init(adev, ring, 512,
|
||||
&adev->vce.irq, 0);
|
||||
&adev->vce.irq, 0,
|
||||
AMDGPU_RING_PRIO_DEFAULT);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue