mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 16:44:58 +02:00
amd-drm-next-6.15-2025-02-21:
amdgpu: - Add OEM i2c support for RGB lights, etc. - Add support for GC 11.5.3 - Add support for GC 11.5.2 - Add support for SDMA 6.1.3 - Add support for NBIO 7.11.2 - Add support for NBIO 7.9.1 - Add support for MMHUB 3.3.2 - Add support for MMHUB 1.8.1 - Add support for SMU 14.0.5 - Add support for SMUIO 13.0.11 - Add support for PSP 14.0.5 - Add support for UMC 12.5.0 - Add support for DCN 3.6.0 - JPEG 4.0.3 updates - Add dynamic workload profile switching for GC 10-12 - support larger vbios sizes - GC 9.5.0 updates - SMU 13.0.12 updates - SMU 13.0.6 updates - IP discovery updates - GC 10 queue reset updates - DCN 4.0.1 updates - UHBR link rate fixes - Aborted suspend fix - Mark gttsize parameter as deprecated - GC 10 cleaner shader updates - PSR-SU fixes - Clean up PM4 headers - Cursor fixes - Enable devcoredump for JPEG - Misc cleanups - Runpm cleanups - MES updates - GC 9 gfxoff fixes - Vbios fetching cleanups - Documentation updates - Update secondary plane handling - DML2 updates - SDMA fixes for MI - Cleaner shader fixes for GC 11/12 - ACA updates - Initial JPEG queue reset support - RAS updates - Initial RAS CPER support - DCN/DCE panic screen handling cleanup - BT2020 fixes - SR-IOV fixes amdkfd: - synchronize pasid values between KGD and KFD - Misc cleanups - Improve GTT/VRAM handling for APUs - Topology updates - Fix user queue validation on GC 7/8 UAPI: - Enable "Broadcast RGB" drm property - Add INFO IOCTL query for virtualization mode Proposed userspace:e663bed7d6-----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQgO5Idg2tXNTSZAr293/aFa7yZ2AUCZ7jwVwAKCRC93/aFa7yZ 2EBmAP42gCX0ESuLJlwLTrobhs9mALp5g6AClLTSBuxNcgfOJwEAvqq12R2db8F9 hFF3rq07C8YaL3bMIi3IhqIXVsnUBgo= =uvFs -----END PGP SIGNATURE----- Merge tag 'amd-drm-next-6.15-2025-02-21' of https://gitlab.freedesktop.org/agd5f/linux into drm-next amd-drm-next-6.15-2025-02-21: amdgpu: - Add OEM i2c support for RGB lights, etc. - Add support for GC 11.5.3 - Add support for GC 11.5.2 - Add support for SDMA 6.1.3 - Add support for NBIO 7.11.2 - Add support for NBIO 7.9.1 - Add support for MMHUB 3.3.2 - Add support for MMHUB 1.8.1 - Add support for SMU 14.0.5 - Add support for SMUIO 13.0.11 - Add support for PSP 14.0.5 - Add support for UMC 12.5.0 - Add support for DCN 3.6.0 - JPEG 4.0.3 updates - Add dynamic workload profile switching for GC 10-12 - support larger vbios sizes - GC 9.5.0 updates - SMU 13.0.12 updates - SMU 13.0.6 updates - IP discovery updates - GC 10 queue reset updates - DCN 4.0.1 updates - UHBR link rate fixes - Aborted suspend fix - Mark gttsize parameter as deprecated - GC 10 cleaner shader updates - PSR-SU fixes - Clean up PM4 headers - Cursor fixes - Enable devcoredump for JPEG - Misc cleanups - Runpm cleanups - MES updates - GC 9 gfxoff fixes - Vbios fetching cleanups - Documentation updates - Update secondary plane handling - DML2 updates - SDMA fixes for MI - Cleaner shader fixes for GC 11/12 - ACA updates - Initial JPEG queue reset support - RAS updates - Initial RAS CPER support - DCN/DCE panic screen handling cleanup - BT2020 fixes - SR-IOV fixes amdkfd: - synchronize pasid values between KGD and KFD - Misc cleanups - Improve GTT/VRAM handling for APUs - Topology updates - Fix user queue validation on GC 7/8 UAPI: - Enable "Broadcast RGB" drm property - Add INFO IOCTL query for virtualization mode Proposed userspace:e663bed7d6From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20250221213651.4176031-1-alexander.deucher@amd.com Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
commit
425b848175
|
|
@ -65,7 +65,8 @@ amdgpu-y += amdgpu_device.o amdgpu_doorbell_mgr.o amdgpu_kms.o \
|
|||
amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o amdgpu_rap.o \
|
||||
amdgpu_fw_attestation.o amdgpu_securedisplay.o \
|
||||
amdgpu_eeprom.o amdgpu_mca.o amdgpu_psp_ta.o amdgpu_lsdma.o \
|
||||
amdgpu_ring_mux.o amdgpu_xcp.o amdgpu_seq64.o amdgpu_aca.o amdgpu_dev_coredump.o
|
||||
amdgpu_ring_mux.o amdgpu_xcp.o amdgpu_seq64.o amdgpu_aca.o amdgpu_dev_coredump.o \
|
||||
amdgpu_cper.o
|
||||
|
||||
amdgpu-$(CONFIG_PROC_FS) += amdgpu_fdinfo.o
|
||||
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@
|
|||
#include "amdgpu_mca.h"
|
||||
#include "amdgpu_aca.h"
|
||||
#include "amdgpu_ras.h"
|
||||
#include "amdgpu_cper.h"
|
||||
#include "amdgpu_xcp.h"
|
||||
#include "amdgpu_seq64.h"
|
||||
#include "amdgpu_reg_state.h"
|
||||
|
|
@ -415,6 +416,7 @@ bool amdgpu_get_bios(struct amdgpu_device *adev);
|
|||
bool amdgpu_read_bios(struct amdgpu_device *adev);
|
||||
bool amdgpu_soc15_read_bios_from_rom(struct amdgpu_device *adev,
|
||||
u8 *bios, u32 length_bytes);
|
||||
void amdgpu_bios_release(struct amdgpu_device *adev);
|
||||
/*
|
||||
* Clocks
|
||||
*/
|
||||
|
|
@ -1090,6 +1092,9 @@ struct amdgpu_device {
|
|||
/* ACA */
|
||||
struct amdgpu_aca aca;
|
||||
|
||||
/* CPER */
|
||||
struct amdgpu_cper cper;
|
||||
|
||||
struct amdgpu_ip_block ip_blocks[AMDGPU_MAX_IP_NUM];
|
||||
uint32_t harvest_ip_mask;
|
||||
int num_ip_blocks;
|
||||
|
|
@ -1149,6 +1154,7 @@ struct amdgpu_device {
|
|||
struct ratelimit_state throttling_logging_rs;
|
||||
uint32_t ras_hw_enabled;
|
||||
uint32_t ras_enabled;
|
||||
bool ras_default_ecc_enabled;
|
||||
|
||||
bool no_hw_access;
|
||||
struct pci_saved_state *pci_state;
|
||||
|
|
@ -1192,6 +1198,11 @@ struct amdgpu_device {
|
|||
struct mutex enforce_isolation_mutex;
|
||||
|
||||
struct amdgpu_init_level *init_lvl;
|
||||
|
||||
/* This flag is used to determine how VRAM allocations are handled for APUs
|
||||
* in KFD: VRAM or GTT.
|
||||
*/
|
||||
bool apu_prefer_gtt;
|
||||
};
|
||||
|
||||
static inline uint32_t amdgpu_ip_version(const struct amdgpu_device *adev,
|
||||
|
|
|
|||
|
|
@ -30,16 +30,6 @@
|
|||
|
||||
typedef int bank_handler_t(struct aca_handle *handle, struct aca_bank *bank, enum aca_smu_type type, void *data);
|
||||
|
||||
struct aca_banks {
|
||||
int nr_banks;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct aca_hwip {
|
||||
int hwid;
|
||||
int mcatype;
|
||||
};
|
||||
|
||||
static struct aca_hwip aca_hwid_mcatypes[ACA_HWIP_TYPE_COUNT] = {
|
||||
ACA_BANK_HWID(SMU, 0x01, 0x01),
|
||||
ACA_BANK_HWID(PCS_XGMI, 0x50, 0x00),
|
||||
|
|
@ -111,7 +101,7 @@ static struct aca_regs_dump {
|
|||
{"STATUS", ACA_REG_IDX_STATUS},
|
||||
{"ADDR", ACA_REG_IDX_ADDR},
|
||||
{"MISC", ACA_REG_IDX_MISC0},
|
||||
{"CONFIG", ACA_REG_IDX_CONFG},
|
||||
{"CONFIG", ACA_REG_IDX_CONFIG},
|
||||
{"IPID", ACA_REG_IDX_IPID},
|
||||
{"SYND", ACA_REG_IDX_SYND},
|
||||
{"DESTAT", ACA_REG_IDX_DESTAT},
|
||||
|
|
@ -168,7 +158,7 @@ static int aca_smu_get_valid_aca_banks(struct amdgpu_device *adev, enum aca_smu_
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
bank.type = type;
|
||||
bank.smu_err_type = type;
|
||||
|
||||
aca_smu_bank_dump(adev, i, count, &bank, qctx);
|
||||
|
||||
|
|
@ -394,6 +384,36 @@ static bool aca_bank_should_update(struct amdgpu_device *adev, enum aca_smu_type
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void aca_banks_generate_cper(struct amdgpu_device *adev,
|
||||
enum aca_smu_type type,
|
||||
struct aca_banks *banks,
|
||||
int count)
|
||||
{
|
||||
struct aca_bank_node *node;
|
||||
struct aca_bank *bank;
|
||||
|
||||
if (!banks || !count) {
|
||||
dev_warn(adev->dev, "fail to generate cper records\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* UEs must be encoded into separate CPER entries */
|
||||
if (type == ACA_SMU_TYPE_UE) {
|
||||
list_for_each_entry(node, &banks->list, node) {
|
||||
bank = &node->bank;
|
||||
if (amdgpu_cper_generate_ue_record(adev, bank))
|
||||
dev_warn(adev->dev, "fail to generate ue cper records\n");
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* SMU_TYPE_CE banks are combined into 1 CPER entries,
|
||||
* they could be CEs or DEs or both
|
||||
*/
|
||||
if (amdgpu_cper_generate_ce_records(adev, banks, count))
|
||||
dev_warn(adev->dev, "fail to generate ce cper records\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int aca_banks_update(struct amdgpu_device *adev, enum aca_smu_type type,
|
||||
bank_handler_t handler, struct ras_query_context *qctx, void *data)
|
||||
{
|
||||
|
|
@ -431,6 +451,8 @@ static int aca_banks_update(struct amdgpu_device *adev, enum aca_smu_type type,
|
|||
if (ret)
|
||||
goto err_release_banks;
|
||||
|
||||
aca_banks_generate_cper(adev, type, &banks, count);
|
||||
|
||||
err_release_banks:
|
||||
aca_banks_release(&banks);
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ enum aca_reg_idx {
|
|||
ACA_REG_IDX_STATUS = 1,
|
||||
ACA_REG_IDX_ADDR = 2,
|
||||
ACA_REG_IDX_MISC0 = 3,
|
||||
ACA_REG_IDX_CONFG = 4,
|
||||
ACA_REG_IDX_CONFIG = 4,
|
||||
ACA_REG_IDX_IPID = 5,
|
||||
ACA_REG_IDX_SYND = 6,
|
||||
ACA_REG_IDX_DESTAT = 8,
|
||||
|
|
@ -108,13 +108,20 @@ enum aca_error_type {
|
|||
};
|
||||
|
||||
enum aca_smu_type {
|
||||
ACA_SMU_TYPE_INVALID = -1,
|
||||
ACA_SMU_TYPE_UE = 0,
|
||||
ACA_SMU_TYPE_CE,
|
||||
ACA_SMU_TYPE_COUNT,
|
||||
};
|
||||
|
||||
struct aca_hwip {
|
||||
int hwid;
|
||||
int mcatype;
|
||||
};
|
||||
|
||||
struct aca_bank {
|
||||
enum aca_smu_type type;
|
||||
enum aca_error_type aca_err_type;
|
||||
enum aca_smu_type smu_err_type;
|
||||
u64 regs[ACA_MAX_REGS_COUNT];
|
||||
};
|
||||
|
||||
|
|
@ -123,6 +130,11 @@ struct aca_bank_node {
|
|||
struct list_head node;
|
||||
};
|
||||
|
||||
struct aca_banks {
|
||||
int nr_banks;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct aca_bank_info {
|
||||
int die_id;
|
||||
int socket_id;
|
||||
|
|
|
|||
|
|
@ -459,7 +459,7 @@ void amdgpu_amdkfd_get_local_mem_info(struct amdgpu_device *adev,
|
|||
else
|
||||
mem_info->local_mem_size_private =
|
||||
KFD_XCP_MEMORY_SIZE(adev, xcp->id);
|
||||
} else if (adev->flags & AMD_IS_APU) {
|
||||
} else if (adev->apu_prefer_gtt) {
|
||||
mem_info->local_mem_size_public = (ttm_tt_pages_limit() << PAGE_SHIFT);
|
||||
mem_info->local_mem_size_private = 0;
|
||||
} else {
|
||||
|
|
@ -818,7 +818,7 @@ u64 amdgpu_amdkfd_xcp_memory_size(struct amdgpu_device *adev, int xcp_id)
|
|||
}
|
||||
do_div(tmp, adev->xcp_mgr->num_xcp_per_mem_partition);
|
||||
return ALIGN_DOWN(tmp, PAGE_SIZE);
|
||||
} else if (adev->flags & AMD_IS_APU) {
|
||||
} else if (adev->apu_prefer_gtt) {
|
||||
return (ttm_tt_pages_limit() << PAGE_SHIFT);
|
||||
} else {
|
||||
return adev->gmc.real_vram_size;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ enum TLB_FLUSH_TYPE {
|
|||
};
|
||||
|
||||
struct amdgpu_device;
|
||||
struct kfd_process_device;
|
||||
struct amdgpu_reset_context;
|
||||
|
||||
enum kfd_mem_attachment_type {
|
||||
|
|
@ -299,14 +300,10 @@ bool amdgpu_amdkfd_compute_active(struct amdgpu_device *adev, uint32_t node_id);
|
|||
(&((struct amdgpu_fpriv *) \
|
||||
((struct drm_file *)(drm_priv))->driver_priv)->vm)
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_set_vm_pasid(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *avm, u32 pasid);
|
||||
int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *avm,
|
||||
void **process_info,
|
||||
struct dma_fence **ef);
|
||||
void amdgpu_amdkfd_gpuvm_release_process_vm(struct amdgpu_device *adev,
|
||||
void *drm_priv);
|
||||
uint64_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *drm_priv);
|
||||
size_t amdgpu_amdkfd_get_available_memory(struct amdgpu_device *adev,
|
||||
uint8_t xcp_id);
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
|
|||
return -EINVAL;
|
||||
|
||||
vram_size = KFD_XCP_MEMORY_SIZE(adev, xcp_id);
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
if (adev->apu_prefer_gtt) {
|
||||
system_mem_needed = size;
|
||||
ttm_mem_needed = size;
|
||||
}
|
||||
|
|
@ -234,7 +234,7 @@ int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
|
|||
if (adev && xcp_id >= 0) {
|
||||
adev->kfd.vram_used[xcp_id] += vram_needed;
|
||||
adev->kfd.vram_used_aligned[xcp_id] +=
|
||||
(adev->flags & AMD_IS_APU) ?
|
||||
adev->apu_prefer_gtt ?
|
||||
vram_needed :
|
||||
ALIGN(vram_needed, VRAM_AVAILABLITY_ALIGN);
|
||||
}
|
||||
|
|
@ -262,7 +262,7 @@ void amdgpu_amdkfd_unreserve_mem_limit(struct amdgpu_device *adev,
|
|||
|
||||
if (adev) {
|
||||
adev->kfd.vram_used[xcp_id] -= size;
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
if (adev->apu_prefer_gtt) {
|
||||
adev->kfd.vram_used_aligned[xcp_id] -= size;
|
||||
kfd_mem_limit.system_mem_used -= size;
|
||||
kfd_mem_limit.ttm_mem_used -= size;
|
||||
|
|
@ -890,7 +890,7 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem,
|
|||
* if peer device has large BAR. In contrast, access over xGMI is
|
||||
* allowed for both small and large BAR configurations of peer device
|
||||
*/
|
||||
if ((adev != bo_adev && !(adev->flags & AMD_IS_APU)) &&
|
||||
if ((adev != bo_adev && !adev->apu_prefer_gtt) &&
|
||||
((mem->domain == AMDGPU_GEM_DOMAIN_VRAM) ||
|
||||
(mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL) ||
|
||||
(mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP))) {
|
||||
|
|
@ -1529,27 +1529,6 @@ static void amdgpu_amdkfd_gpuvm_unpin_bo(struct amdgpu_bo *bo)
|
|||
amdgpu_bo_unreserve(bo);
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_set_vm_pasid(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *avm, u32 pasid)
|
||||
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Free the original amdgpu allocated pasid,
|
||||
* will be replaced with kfd allocated pasid.
|
||||
*/
|
||||
if (avm->pasid) {
|
||||
amdgpu_pasid_free(avm->pasid);
|
||||
amdgpu_vm_set_pasid(adev, avm, 0);
|
||||
}
|
||||
|
||||
ret = amdgpu_vm_set_pasid(adev, avm, pasid);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *avm,
|
||||
void **process_info,
|
||||
|
|
@ -1607,27 +1586,6 @@ void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
|
|||
}
|
||||
}
|
||||
|
||||
void amdgpu_amdkfd_gpuvm_release_process_vm(struct amdgpu_device *adev,
|
||||
void *drm_priv)
|
||||
{
|
||||
struct amdgpu_vm *avm;
|
||||
|
||||
if (WARN_ON(!adev || !drm_priv))
|
||||
return;
|
||||
|
||||
avm = drm_priv_to_vm(drm_priv);
|
||||
|
||||
pr_debug("Releasing process vm %p\n", avm);
|
||||
|
||||
/* The original pasid of amdgpu vm has already been
|
||||
* released during making a amdgpu vm to a compute vm
|
||||
* The current pasid is managed by kfd and will be
|
||||
* released on kfd process destroy. Set amdgpu pasid
|
||||
* to 0 to avoid duplicate release.
|
||||
*/
|
||||
amdgpu_vm_release_compute(adev, avm);
|
||||
}
|
||||
|
||||
uint64_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *drm_priv)
|
||||
{
|
||||
struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv);
|
||||
|
|
@ -1688,7 +1646,7 @@ size_t amdgpu_amdkfd_get_available_memory(struct amdgpu_device *adev,
|
|||
- reserved_for_pt
|
||||
- reserved_for_ras;
|
||||
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
if (adev->apu_prefer_gtt) {
|
||||
system_mem_available = no_system_mem_limit ?
|
||||
kfd_mem_limit.max_system_mem_limit :
|
||||
kfd_mem_limit.max_system_mem_limit -
|
||||
|
|
@ -1736,7 +1694,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
|
|||
if (flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
|
||||
domain = alloc_domain = AMDGPU_GEM_DOMAIN_VRAM;
|
||||
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
if (adev->apu_prefer_gtt) {
|
||||
domain = AMDGPU_GEM_DOMAIN_GTT;
|
||||
alloc_domain = AMDGPU_GEM_DOMAIN_GTT;
|
||||
alloc_flags = 0;
|
||||
|
|
@ -1987,7 +1945,7 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
|
|||
if (size) {
|
||||
if (!is_imported &&
|
||||
(mem->bo->preferred_domains == AMDGPU_GEM_DOMAIN_VRAM ||
|
||||
((adev->flags & AMD_IS_APU) &&
|
||||
(adev->apu_prefer_gtt &&
|
||||
mem->bo->preferred_domains == AMDGPU_GEM_DOMAIN_GTT)))
|
||||
*size = bo_size;
|
||||
else
|
||||
|
|
@ -2414,7 +2372,7 @@ static int import_obj_create(struct amdgpu_device *adev,
|
|||
(*mem)->bo = bo;
|
||||
(*mem)->va = va;
|
||||
(*mem)->domain = (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) &&
|
||||
!(adev->flags & AMD_IS_APU) ?
|
||||
!adev->apu_prefer_gtt ?
|
||||
AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT;
|
||||
|
||||
(*mem)->mapped_to_gpu_memory = 0;
|
||||
|
|
|
|||
|
|
@ -36,13 +36,6 @@
|
|||
#include "atombios_encoders.h"
|
||||
#include "bif/bif_4_1_d.h"
|
||||
|
||||
static void amdgpu_atombios_lookup_i2c_gpio_quirks(struct amdgpu_device *adev,
|
||||
ATOM_GPIO_I2C_ASSIGMENT *gpio,
|
||||
u8 index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static struct amdgpu_i2c_bus_rec amdgpu_atombios_get_bus_rec_for_i2c_gpio(ATOM_GPIO_I2C_ASSIGMENT *gpio)
|
||||
{
|
||||
struct amdgpu_i2c_bus_rec i2c;
|
||||
|
|
@ -108,9 +101,6 @@ struct amdgpu_i2c_bus_rec amdgpu_atombios_lookup_i2c_gpio(struct amdgpu_device *
|
|||
|
||||
gpio = &i2c_info->asGPIO_Info[0];
|
||||
for (i = 0; i < num_indices; i++) {
|
||||
|
||||
amdgpu_atombios_lookup_i2c_gpio_quirks(adev, gpio, i);
|
||||
|
||||
if (gpio->sucI2cId.ucAccess == id) {
|
||||
i2c = amdgpu_atombios_get_bus_rec_for_i2c_gpio(gpio);
|
||||
break;
|
||||
|
|
@ -142,8 +132,6 @@ void amdgpu_atombios_i2c_init(struct amdgpu_device *adev)
|
|||
|
||||
gpio = &i2c_info->asGPIO_Info[0];
|
||||
for (i = 0; i < num_indices; i++) {
|
||||
amdgpu_atombios_lookup_i2c_gpio_quirks(adev, gpio, i);
|
||||
|
||||
i2c = amdgpu_atombios_get_bus_rec_for_i2c_gpio(gpio);
|
||||
|
||||
if (i2c.valid) {
|
||||
|
|
@ -156,6 +144,38 @@ void amdgpu_atombios_i2c_init(struct amdgpu_device *adev)
|
|||
}
|
||||
}
|
||||
|
||||
void amdgpu_atombios_oem_i2c_init(struct amdgpu_device *adev, u8 i2c_id)
|
||||
{
|
||||
struct atom_context *ctx = adev->mode_info.atom_context;
|
||||
ATOM_GPIO_I2C_ASSIGMENT *gpio;
|
||||
struct amdgpu_i2c_bus_rec i2c;
|
||||
int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
|
||||
struct _ATOM_GPIO_I2C_INFO *i2c_info;
|
||||
uint16_t data_offset, size;
|
||||
int i, num_indices;
|
||||
char stmp[32];
|
||||
|
||||
if (amdgpu_atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
|
||||
i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
|
||||
|
||||
num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
|
||||
sizeof(ATOM_GPIO_I2C_ASSIGMENT);
|
||||
|
||||
gpio = &i2c_info->asGPIO_Info[0];
|
||||
for (i = 0; i < num_indices; i++) {
|
||||
i2c = amdgpu_atombios_get_bus_rec_for_i2c_gpio(gpio);
|
||||
|
||||
if (i2c.valid && i2c.i2c_id == i2c_id) {
|
||||
sprintf(stmp, "OEM 0x%x", i2c.i2c_id);
|
||||
adev->i2c_bus[i] = amdgpu_i2c_create(adev_to_drm(adev), &i2c, stmp);
|
||||
break;
|
||||
}
|
||||
gpio = (ATOM_GPIO_I2C_ASSIGMENT *)
|
||||
((u8 *)gpio + sizeof(ATOM_GPIO_I2C_ASSIGMENT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct amdgpu_gpio_rec
|
||||
amdgpu_atombios_lookup_gpio(struct amdgpu_device *adev,
|
||||
u8 id)
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ amdgpu_atombios_lookup_gpio(struct amdgpu_device *adev,
|
|||
struct amdgpu_i2c_bus_rec amdgpu_atombios_lookup_i2c_gpio(struct amdgpu_device *adev,
|
||||
uint8_t id);
|
||||
void amdgpu_atombios_i2c_init(struct amdgpu_device *adev);
|
||||
void amdgpu_atombios_oem_i2c_init(struct amdgpu_device *adev, u8 i2c_id);
|
||||
|
||||
bool amdgpu_atombios_has_dce_engine_info(struct amdgpu_device *adev);
|
||||
|
||||
|
|
|
|||
|
|
@ -549,9 +549,10 @@ bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev)
|
|||
u16 data_offset, size;
|
||||
union umc_info *umc_info;
|
||||
u8 frev, crev;
|
||||
bool ecc_default_enabled = false;
|
||||
bool mem_ecc_enabled = false;
|
||||
u8 umc_config;
|
||||
u32 umc_config1;
|
||||
adev->ras_default_ecc_enabled = false;
|
||||
|
||||
index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
|
||||
umc_info);
|
||||
|
|
@ -563,20 +564,22 @@ bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev)
|
|||
switch (crev) {
|
||||
case 1:
|
||||
umc_config = le32_to_cpu(umc_info->v31.umc_config);
|
||||
ecc_default_enabled =
|
||||
mem_ecc_enabled =
|
||||
(umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false;
|
||||
break;
|
||||
case 2:
|
||||
umc_config = le32_to_cpu(umc_info->v32.umc_config);
|
||||
ecc_default_enabled =
|
||||
mem_ecc_enabled =
|
||||
(umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false;
|
||||
break;
|
||||
case 3:
|
||||
umc_config = le32_to_cpu(umc_info->v33.umc_config);
|
||||
umc_config1 = le32_to_cpu(umc_info->v33.umc_config1);
|
||||
ecc_default_enabled =
|
||||
mem_ecc_enabled =
|
||||
((umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ||
|
||||
(umc_config1 & UMC_CONFIG1__ENABLE_ECC_CAPABLE)) ? true : false;
|
||||
adev->ras_default_ecc_enabled =
|
||||
(umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false;
|
||||
break;
|
||||
default:
|
||||
/* unsupported crev */
|
||||
|
|
@ -585,9 +588,12 @@ bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev)
|
|||
} else if (frev == 4) {
|
||||
switch (crev) {
|
||||
case 0:
|
||||
umc_config = le32_to_cpu(umc_info->v40.umc_config);
|
||||
umc_config1 = le32_to_cpu(umc_info->v40.umc_config1);
|
||||
ecc_default_enabled =
|
||||
mem_ecc_enabled =
|
||||
(umc_config1 & UMC_CONFIG1__ENABLE_ECC_CAPABLE) ? true : false;
|
||||
adev->ras_default_ecc_enabled =
|
||||
(umc_config & UMC_CONFIG__DEFAULT_MEM_ECC_ENABLE) ? true : false;
|
||||
break;
|
||||
default:
|
||||
/* unsupported crev */
|
||||
|
|
@ -599,7 +605,7 @@ bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev)
|
|||
}
|
||||
}
|
||||
|
||||
return ecc_default_enabled;
|
||||
return mem_ecc_enabled;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -84,6 +84,13 @@ static bool check_atom_bios(struct amdgpu_device *adev, size_t size)
|
|||
return false;
|
||||
}
|
||||
|
||||
void amdgpu_bios_release(struct amdgpu_device *adev)
|
||||
{
|
||||
kfree(adev->bios);
|
||||
adev->bios = NULL;
|
||||
adev->bios_size = 0;
|
||||
}
|
||||
|
||||
/* If you boot an IGP board with a discrete card as the primary,
|
||||
* the IGP rom is not accessible via the rom bar as the IGP rom is
|
||||
* part of the system bios. On boot, the system bios puts a
|
||||
|
|
@ -121,7 +128,7 @@ static bool amdgpu_read_bios_from_vram(struct amdgpu_device *adev)
|
|||
iounmap(bios);
|
||||
|
||||
if (!check_atom_bios(adev, size)) {
|
||||
kfree(adev->bios);
|
||||
amdgpu_bios_release(adev);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -149,7 +156,7 @@ bool amdgpu_read_bios(struct amdgpu_device *adev)
|
|||
pci_unmap_rom(adev->pdev, bios);
|
||||
|
||||
if (!check_atom_bios(adev, size)) {
|
||||
kfree(adev->bios);
|
||||
amdgpu_bios_release(adev);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -189,7 +196,7 @@ static bool amdgpu_read_bios_from_rom(struct amdgpu_device *adev)
|
|||
amdgpu_asic_read_bios_from_rom(adev, adev->bios, len);
|
||||
|
||||
if (!check_atom_bios(adev, len)) {
|
||||
kfree(adev->bios);
|
||||
amdgpu_bios_release(adev);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -225,7 +232,8 @@ static bool amdgpu_read_platform_bios(struct amdgpu_device *adev)
|
|||
|
||||
return true;
|
||||
free_bios:
|
||||
kfree(adev->bios);
|
||||
amdgpu_bios_release(adev);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -327,7 +335,7 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
if (!check_atom_bios(adev, size)) {
|
||||
kfree(adev->bios);
|
||||
amdgpu_bios_release(adev);
|
||||
return false;
|
||||
}
|
||||
adev->bios_size = size;
|
||||
|
|
@ -392,7 +400,7 @@ static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
|
|||
GFP_KERNEL);
|
||||
|
||||
if (!check_atom_bios(adev, vhdr->ImageLength)) {
|
||||
kfree(adev->bios);
|
||||
amdgpu_bios_release(adev);
|
||||
return false;
|
||||
}
|
||||
adev->bios_size = vhdr->ImageLength;
|
||||
|
|
|
|||
564
drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c
Normal file
564
drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c
Normal file
|
|
@ -0,0 +1,564 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2025 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/list.h>
|
||||
#include "amdgpu.h"
|
||||
|
||||
static const guid_t MCE = CPER_NOTIFY_MCE;
|
||||
static const guid_t CMC = CPER_NOTIFY_CMC;
|
||||
static const guid_t BOOT = BOOT_TYPE;
|
||||
|
||||
static const guid_t CRASHDUMP = AMD_CRASHDUMP;
|
||||
static const guid_t RUNTIME = AMD_GPU_NONSTANDARD_ERROR;
|
||||
|
||||
static void __inc_entry_length(struct cper_hdr *hdr, uint32_t size)
|
||||
{
|
||||
hdr->record_length += size;
|
||||
}
|
||||
|
||||
static void amdgpu_cper_get_timestamp(struct cper_timestamp *timestamp)
|
||||
{
|
||||
struct tm tm;
|
||||
time64_t now = ktime_get_real_seconds();
|
||||
|
||||
time64_to_tm(now, 0, &tm);
|
||||
timestamp->seconds = tm.tm_sec;
|
||||
timestamp->minutes = tm.tm_min;
|
||||
timestamp->hours = tm.tm_hour;
|
||||
timestamp->flag = 0;
|
||||
timestamp->day = tm.tm_mday;
|
||||
timestamp->month = 1 + tm.tm_mon;
|
||||
timestamp->year = (1900 + tm.tm_year) % 100;
|
||||
timestamp->century = (1900 + tm.tm_year) / 100;
|
||||
}
|
||||
|
||||
void amdgpu_cper_entry_fill_hdr(struct amdgpu_device *adev,
|
||||
struct cper_hdr *hdr,
|
||||
enum amdgpu_cper_type type,
|
||||
enum cper_error_severity sev)
|
||||
{
|
||||
hdr->signature[0] = 'C';
|
||||
hdr->signature[1] = 'P';
|
||||
hdr->signature[2] = 'E';
|
||||
hdr->signature[3] = 'R';
|
||||
hdr->revision = CPER_HDR_REV_1;
|
||||
hdr->signature_end = 0xFFFFFFFF;
|
||||
hdr->error_severity = sev;
|
||||
|
||||
hdr->valid_bits.platform_id = 1;
|
||||
hdr->valid_bits.partition_id = 1;
|
||||
hdr->valid_bits.timestamp = 1;
|
||||
|
||||
amdgpu_cper_get_timestamp(&hdr->timestamp);
|
||||
|
||||
snprintf(hdr->record_id, 8, "%d", atomic_inc_return(&adev->cper.unique_id));
|
||||
snprintf(hdr->platform_id, 16, "0x%04X:0x%04X",
|
||||
adev->pdev->vendor, adev->pdev->device);
|
||||
/* pmfw version should be part of creator_id according to CPER spec */
|
||||
snprintf(hdr->creator_id, 16, "%s", CPER_CREATOR_ID_AMDGPU);
|
||||
|
||||
switch (type) {
|
||||
case AMDGPU_CPER_TYPE_BOOT:
|
||||
hdr->notify_type = BOOT;
|
||||
break;
|
||||
case AMDGPU_CPER_TYPE_FATAL:
|
||||
case AMDGPU_CPER_TYPE_BP_THRESHOLD:
|
||||
hdr->notify_type = MCE;
|
||||
break;
|
||||
case AMDGPU_CPER_TYPE_RUNTIME:
|
||||
if (sev == CPER_SEV_NON_FATAL_CORRECTED)
|
||||
hdr->notify_type = CMC;
|
||||
else
|
||||
hdr->notify_type = MCE;
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev, "Unknown CPER Type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
__inc_entry_length(hdr, HDR_LEN);
|
||||
}
|
||||
|
||||
static int amdgpu_cper_entry_fill_section_desc(struct amdgpu_device *adev,
|
||||
struct cper_sec_desc *section_desc,
|
||||
bool bp_threshold,
|
||||
bool poison,
|
||||
enum cper_error_severity sev,
|
||||
guid_t sec_type,
|
||||
uint32_t section_length,
|
||||
uint32_t section_offset)
|
||||
{
|
||||
section_desc->revision_minor = CPER_SEC_MINOR_REV_1;
|
||||
section_desc->revision_major = CPER_SEC_MAJOR_REV_22;
|
||||
section_desc->sec_offset = section_offset;
|
||||
section_desc->sec_length = section_length;
|
||||
section_desc->valid_bits.fru_id = 1;
|
||||
section_desc->valid_bits.fru_text = 1;
|
||||
section_desc->flag_bits.primary = 1;
|
||||
section_desc->severity = sev;
|
||||
section_desc->sec_type = sec_type;
|
||||
|
||||
if (adev->smuio.funcs &&
|
||||
adev->smuio.funcs->get_socket_id)
|
||||
snprintf(section_desc->fru_text, 20, "OAM%d",
|
||||
adev->smuio.funcs->get_socket_id(adev));
|
||||
/* TODO: fru_id is 16 bytes in CPER spec, but driver defines it as 20 bytes */
|
||||
snprintf(section_desc->fru_id, 16, "%llx", adev->unique_id);
|
||||
|
||||
if (bp_threshold)
|
||||
section_desc->flag_bits.exceed_err_threshold = 1;
|
||||
if (poison)
|
||||
section_desc->flag_bits.latent_err = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_cper_entry_fill_fatal_section(struct amdgpu_device *adev,
|
||||
struct cper_hdr *hdr,
|
||||
uint32_t idx,
|
||||
struct cper_sec_crashdump_reg_data reg_data)
|
||||
{
|
||||
struct cper_sec_desc *section_desc;
|
||||
struct cper_sec_crashdump_fatal *section;
|
||||
|
||||
section_desc = (struct cper_sec_desc *)((uint8_t *)hdr + SEC_DESC_OFFSET(idx));
|
||||
section = (struct cper_sec_crashdump_fatal *)((uint8_t *)hdr +
|
||||
FATAL_SEC_OFFSET(hdr->sec_cnt, idx));
|
||||
|
||||
amdgpu_cper_entry_fill_section_desc(adev, section_desc, false, false,
|
||||
CPER_SEV_FATAL, CRASHDUMP, FATAL_SEC_LEN,
|
||||
FATAL_SEC_OFFSET(hdr->sec_cnt, idx));
|
||||
|
||||
section->body.reg_ctx_type = CPER_CTX_TYPE_CRASH;
|
||||
section->body.reg_arr_size = sizeof(reg_data);
|
||||
section->body.data = reg_data;
|
||||
|
||||
__inc_entry_length(hdr, SEC_DESC_LEN + FATAL_SEC_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_cper_entry_fill_runtime_section(struct amdgpu_device *adev,
|
||||
struct cper_hdr *hdr,
|
||||
uint32_t idx,
|
||||
enum cper_error_severity sev,
|
||||
uint32_t *reg_dump,
|
||||
uint32_t reg_count)
|
||||
{
|
||||
struct cper_sec_desc *section_desc;
|
||||
struct cper_sec_nonstd_err *section;
|
||||
bool poison;
|
||||
|
||||
poison = (sev == CPER_SEV_NON_FATAL_CORRECTED) ? false : true;
|
||||
section_desc = (struct cper_sec_desc *)((uint8_t *)hdr + SEC_DESC_OFFSET(idx));
|
||||
section = (struct cper_sec_nonstd_err *)((uint8_t *)hdr +
|
||||
NONSTD_SEC_OFFSET(hdr->sec_cnt, idx));
|
||||
|
||||
amdgpu_cper_entry_fill_section_desc(adev, section_desc, false, poison,
|
||||
sev, RUNTIME, NONSTD_SEC_LEN,
|
||||
NONSTD_SEC_OFFSET(hdr->sec_cnt, idx));
|
||||
|
||||
reg_count = umin(reg_count, CPER_ACA_REG_COUNT);
|
||||
|
||||
section->hdr.valid_bits.err_info_cnt = 1;
|
||||
section->hdr.valid_bits.err_context_cnt = 1;
|
||||
|
||||
section->info.error_type = RUNTIME;
|
||||
section->info.ms_chk_bits.err_type_valid = 1;
|
||||
section->ctx.reg_ctx_type = CPER_CTX_TYPE_CRASH;
|
||||
section->ctx.reg_arr_size = sizeof(section->ctx.reg_dump);
|
||||
|
||||
memcpy(section->ctx.reg_dump, reg_dump, reg_count * sizeof(uint32_t));
|
||||
|
||||
__inc_entry_length(hdr, SEC_DESC_LEN + NONSTD_SEC_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_cper_entry_fill_bad_page_threshold_section(struct amdgpu_device *adev,
|
||||
struct cper_hdr *hdr,
|
||||
uint32_t idx)
|
||||
{
|
||||
struct cper_sec_desc *section_desc;
|
||||
struct cper_sec_nonstd_err *section;
|
||||
|
||||
section_desc = (struct cper_sec_desc *)((uint8_t *)hdr + SEC_DESC_OFFSET(idx));
|
||||
section = (struct cper_sec_nonstd_err *)((uint8_t *)hdr +
|
||||
NONSTD_SEC_OFFSET(hdr->sec_cnt, idx));
|
||||
|
||||
amdgpu_cper_entry_fill_section_desc(adev, section_desc, true, false,
|
||||
CPER_SEV_NUM, RUNTIME, NONSTD_SEC_LEN,
|
||||
NONSTD_SEC_OFFSET(hdr->sec_cnt, idx));
|
||||
|
||||
section->hdr.valid_bits.err_info_cnt = 1;
|
||||
section->hdr.valid_bits.err_context_cnt = 1;
|
||||
|
||||
section->info.error_type = RUNTIME;
|
||||
section->info.ms_chk_bits.err_type_valid = 1;
|
||||
section->ctx.reg_ctx_type = CPER_CTX_TYPE_CRASH;
|
||||
section->ctx.reg_arr_size = sizeof(section->ctx.reg_dump);
|
||||
|
||||
/* Hardcoded Reg dump for bad page threshold CPER */
|
||||
section->ctx.reg_dump[CPER_ACA_REG_CTL_LO] = 0x1;
|
||||
section->ctx.reg_dump[CPER_ACA_REG_CTL_HI] = 0x0;
|
||||
section->ctx.reg_dump[CPER_ACA_REG_STATUS_LO] = 0x137;
|
||||
section->ctx.reg_dump[CPER_ACA_REG_STATUS_HI] = 0xB0000000;
|
||||
section->ctx.reg_dump[CPER_ACA_REG_ADDR_LO] = 0x0;
|
||||
section->ctx.reg_dump[CPER_ACA_REG_ADDR_HI] = 0x0;
|
||||
section->ctx.reg_dump[CPER_ACA_REG_MISC0_LO] = 0x0;
|
||||
section->ctx.reg_dump[CPER_ACA_REG_MISC0_HI] = 0x0;
|
||||
section->ctx.reg_dump[CPER_ACA_REG_CONFIG_LO] = 0x2;
|
||||
section->ctx.reg_dump[CPER_ACA_REG_CONFIG_HI] = 0x1ff;
|
||||
section->ctx.reg_dump[CPER_ACA_REG_IPID_LO] = 0x0;
|
||||
section->ctx.reg_dump[CPER_ACA_REG_IPID_HI] = 0x96;
|
||||
section->ctx.reg_dump[CPER_ACA_REG_SYND_LO] = 0x0;
|
||||
section->ctx.reg_dump[CPER_ACA_REG_SYND_HI] = 0x0;
|
||||
|
||||
__inc_entry_length(hdr, SEC_DESC_LEN + NONSTD_SEC_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct cper_hdr *amdgpu_cper_alloc_entry(struct amdgpu_device *adev,
|
||||
enum amdgpu_cper_type type,
|
||||
uint16_t section_count)
|
||||
{
|
||||
struct cper_hdr *hdr;
|
||||
uint32_t size = 0;
|
||||
|
||||
size += HDR_LEN;
|
||||
size += (SEC_DESC_LEN * section_count);
|
||||
|
||||
switch (type) {
|
||||
case AMDGPU_CPER_TYPE_RUNTIME:
|
||||
case AMDGPU_CPER_TYPE_BP_THRESHOLD:
|
||||
size += (NONSTD_SEC_LEN * section_count);
|
||||
break;
|
||||
case AMDGPU_CPER_TYPE_FATAL:
|
||||
size += (FATAL_SEC_LEN * section_count);
|
||||
break;
|
||||
case AMDGPU_CPER_TYPE_BOOT:
|
||||
size += (BOOT_SEC_LEN * section_count);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev, "Unknown CPER Type!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hdr = kzalloc(size, GFP_KERNEL);
|
||||
if (!hdr)
|
||||
return NULL;
|
||||
|
||||
/* Save this early */
|
||||
hdr->sec_cnt = section_count;
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
int amdgpu_cper_generate_ue_record(struct amdgpu_device *adev,
|
||||
struct aca_bank *bank)
|
||||
{
|
||||
struct cper_hdr *fatal = NULL;
|
||||
struct cper_sec_crashdump_reg_data reg_data = { 0 };
|
||||
struct amdgpu_ring *ring = &adev->cper.ring_buf;
|
||||
int ret;
|
||||
|
||||
fatal = amdgpu_cper_alloc_entry(adev, AMDGPU_CPER_TYPE_FATAL, 1);
|
||||
if (!fatal) {
|
||||
dev_err(adev->dev, "fail to alloc cper entry for ue record\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
reg_data.status_lo = lower_32_bits(bank->regs[ACA_REG_IDX_STATUS]);
|
||||
reg_data.status_hi = upper_32_bits(bank->regs[ACA_REG_IDX_STATUS]);
|
||||
reg_data.addr_lo = lower_32_bits(bank->regs[ACA_REG_IDX_ADDR]);
|
||||
reg_data.addr_hi = upper_32_bits(bank->regs[ACA_REG_IDX_ADDR]);
|
||||
reg_data.ipid_lo = lower_32_bits(bank->regs[ACA_REG_IDX_IPID]);
|
||||
reg_data.ipid_hi = upper_32_bits(bank->regs[ACA_REG_IDX_IPID]);
|
||||
reg_data.synd_lo = lower_32_bits(bank->regs[ACA_REG_IDX_SYND]);
|
||||
reg_data.synd_hi = upper_32_bits(bank->regs[ACA_REG_IDX_SYND]);
|
||||
|
||||
amdgpu_cper_entry_fill_hdr(adev, fatal, AMDGPU_CPER_TYPE_FATAL, CPER_SEV_FATAL);
|
||||
ret = amdgpu_cper_entry_fill_fatal_section(adev, fatal, 0, reg_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
amdgpu_cper_ring_write(ring, fatal, fatal->record_length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_cper_generate_bp_threshold_record(struct amdgpu_device *adev)
|
||||
{
|
||||
struct cper_hdr *bp_threshold = NULL;
|
||||
struct amdgpu_ring *ring = &adev->cper.ring_buf;
|
||||
int ret;
|
||||
|
||||
bp_threshold = amdgpu_cper_alloc_entry(adev, AMDGPU_CPER_TYPE_BP_THRESHOLD, 1);
|
||||
if (!bp_threshold) {
|
||||
dev_err(adev->dev, "fail to alloc cper entry for bad page threshold record\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
amdgpu_cper_entry_fill_hdr(adev, bp_threshold, AMDGPU_CPER_TYPE_BP_THRESHOLD, CPER_SEV_NUM);
|
||||
ret = amdgpu_cper_entry_fill_bad_page_threshold_section(adev, bp_threshold, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
amdgpu_cper_ring_write(ring, bp_threshold, bp_threshold->record_length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum cper_error_severity amdgpu_aca_err_type_to_cper_sev(struct amdgpu_device *adev,
|
||||
enum aca_error_type aca_err_type)
|
||||
{
|
||||
switch (aca_err_type) {
|
||||
case ACA_ERROR_TYPE_UE:
|
||||
return CPER_SEV_FATAL;
|
||||
case ACA_ERROR_TYPE_CE:
|
||||
return CPER_SEV_NON_FATAL_CORRECTED;
|
||||
case ACA_ERROR_TYPE_DEFERRED:
|
||||
return CPER_SEV_NON_FATAL_UNCORRECTED;
|
||||
default:
|
||||
dev_err(adev->dev, "Unknown ACA error type!\n");
|
||||
return CPER_SEV_FATAL;
|
||||
}
|
||||
}
|
||||
|
||||
int amdgpu_cper_generate_ce_records(struct amdgpu_device *adev,
|
||||
struct aca_banks *banks,
|
||||
uint16_t bank_count)
|
||||
{
|
||||
struct cper_hdr *corrected = NULL;
|
||||
enum cper_error_severity sev = CPER_SEV_NON_FATAL_CORRECTED;
|
||||
struct amdgpu_ring *ring = &adev->cper.ring_buf;
|
||||
uint32_t reg_data[CPER_ACA_REG_COUNT] = { 0 };
|
||||
struct aca_bank_node *node;
|
||||
struct aca_bank *bank;
|
||||
uint32_t i = 0;
|
||||
int ret;
|
||||
|
||||
corrected = amdgpu_cper_alloc_entry(adev, AMDGPU_CPER_TYPE_RUNTIME, bank_count);
|
||||
if (!corrected) {
|
||||
dev_err(adev->dev, "fail to allocate cper entry for ce records\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Raise severity if any DE is detected in the ACA bank list */
|
||||
list_for_each_entry(node, &banks->list, node) {
|
||||
bank = &node->bank;
|
||||
if (bank->aca_err_type == ACA_ERROR_TYPE_DEFERRED) {
|
||||
sev = CPER_SEV_NON_FATAL_UNCORRECTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
amdgpu_cper_entry_fill_hdr(adev, corrected, AMDGPU_CPER_TYPE_RUNTIME, sev);
|
||||
|
||||
/* Combine CE and UE in cper record */
|
||||
list_for_each_entry(node, &banks->list, node) {
|
||||
bank = &node->bank;
|
||||
reg_data[CPER_ACA_REG_CTL_LO] = lower_32_bits(bank->regs[ACA_REG_IDX_CTL]);
|
||||
reg_data[CPER_ACA_REG_CTL_HI] = upper_32_bits(bank->regs[ACA_REG_IDX_CTL]);
|
||||
reg_data[CPER_ACA_REG_STATUS_LO] = lower_32_bits(bank->regs[ACA_REG_IDX_STATUS]);
|
||||
reg_data[CPER_ACA_REG_STATUS_HI] = upper_32_bits(bank->regs[ACA_REG_IDX_STATUS]);
|
||||
reg_data[CPER_ACA_REG_ADDR_LO] = lower_32_bits(bank->regs[ACA_REG_IDX_ADDR]);
|
||||
reg_data[CPER_ACA_REG_ADDR_HI] = upper_32_bits(bank->regs[ACA_REG_IDX_ADDR]);
|
||||
reg_data[CPER_ACA_REG_MISC0_LO] = lower_32_bits(bank->regs[ACA_REG_IDX_MISC0]);
|
||||
reg_data[CPER_ACA_REG_MISC0_HI] = upper_32_bits(bank->regs[ACA_REG_IDX_MISC0]);
|
||||
reg_data[CPER_ACA_REG_CONFIG_LO] = lower_32_bits(bank->regs[ACA_REG_IDX_CONFIG]);
|
||||
reg_data[CPER_ACA_REG_CONFIG_HI] = upper_32_bits(bank->regs[ACA_REG_IDX_CONFIG]);
|
||||
reg_data[CPER_ACA_REG_IPID_LO] = lower_32_bits(bank->regs[ACA_REG_IDX_IPID]);
|
||||
reg_data[CPER_ACA_REG_IPID_HI] = upper_32_bits(bank->regs[ACA_REG_IDX_IPID]);
|
||||
reg_data[CPER_ACA_REG_SYND_LO] = lower_32_bits(bank->regs[ACA_REG_IDX_SYND]);
|
||||
reg_data[CPER_ACA_REG_SYND_HI] = upper_32_bits(bank->regs[ACA_REG_IDX_SYND]);
|
||||
|
||||
ret = amdgpu_cper_entry_fill_runtime_section(adev, corrected, i++,
|
||||
amdgpu_aca_err_type_to_cper_sev(adev, bank->aca_err_type),
|
||||
reg_data, CPER_ACA_REG_COUNT);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
amdgpu_cper_ring_write(ring, corrected, corrected->record_length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool amdgpu_cper_is_hdr(struct amdgpu_ring *ring, u64 pos)
|
||||
{
|
||||
struct cper_hdr *chdr;
|
||||
|
||||
chdr = (struct cper_hdr *)&(ring->ring[pos]);
|
||||
return strcmp(chdr->signature, "CPER") ? false : true;
|
||||
}
|
||||
|
||||
static u32 amdgpu_cper_ring_get_ent_sz(struct amdgpu_ring *ring, u64 pos)
|
||||
{
|
||||
struct cper_hdr *chdr;
|
||||
u64 p;
|
||||
u32 chunk, rec_len = 0;
|
||||
|
||||
chdr = (struct cper_hdr *)&(ring->ring[pos]);
|
||||
chunk = ring->ring_size - (pos << 2);
|
||||
|
||||
if (!strcmp(chdr->signature, "CPER")) {
|
||||
rec_len = chdr->record_length;
|
||||
goto calc;
|
||||
}
|
||||
|
||||
/* ring buffer is not full, no cper data after ring->wptr */
|
||||
if (ring->count_dw)
|
||||
goto calc;
|
||||
|
||||
for (p = pos + 1; p <= ring->buf_mask; p++) {
|
||||
chdr = (struct cper_hdr *)&(ring->ring[p]);
|
||||
if (!strcmp(chdr->signature, "CPER")) {
|
||||
rec_len = (p - pos) << 2;
|
||||
goto calc;
|
||||
}
|
||||
}
|
||||
|
||||
calc:
|
||||
if (!rec_len)
|
||||
return chunk;
|
||||
else
|
||||
return umin(rec_len, chunk);
|
||||
}
|
||||
|
||||
void amdgpu_cper_ring_write(struct amdgpu_ring *ring,
|
||||
void *src, int count)
|
||||
{
|
||||
u64 pos, wptr_old, rptr = *ring->rptr_cpu_addr & ring->ptr_mask;
|
||||
u32 chunk, ent_sz;
|
||||
u8 *s = (u8 *)src;
|
||||
|
||||
if (count >= ring->ring_size - 4) {
|
||||
dev_err(ring->adev->dev,
|
||||
"CPER data size(%d) is larger than ring size(%d)\n",
|
||||
count, ring->ring_size - 4);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
wptr_old = ring->wptr;
|
||||
|
||||
mutex_lock(&ring->adev->cper.ring_lock);
|
||||
while (count) {
|
||||
ent_sz = amdgpu_cper_ring_get_ent_sz(ring, ring->wptr);
|
||||
chunk = umin(ent_sz, count);
|
||||
|
||||
memcpy(&ring->ring[ring->wptr], s, chunk);
|
||||
|
||||
ring->wptr += (chunk >> 2);
|
||||
ring->wptr &= ring->ptr_mask;
|
||||
count -= chunk;
|
||||
s += chunk;
|
||||
}
|
||||
|
||||
/* the buffer is overflow, adjust rptr */
|
||||
if (((wptr_old < rptr) && (rptr <= ring->wptr)) ||
|
||||
((ring->wptr < wptr_old) && (wptr_old < rptr)) ||
|
||||
((rptr <= ring->wptr) && (ring->wptr < wptr_old))) {
|
||||
pos = (ring->wptr + 1) & ring->ptr_mask;
|
||||
|
||||
do {
|
||||
ent_sz = amdgpu_cper_ring_get_ent_sz(ring, pos);
|
||||
|
||||
rptr += (ent_sz >> 2);
|
||||
rptr &= ring->ptr_mask;
|
||||
*ring->rptr_cpu_addr = rptr;
|
||||
|
||||
pos = rptr;
|
||||
} while (!amdgpu_cper_is_hdr(ring, rptr));
|
||||
}
|
||||
mutex_unlock(&ring->adev->cper.ring_lock);
|
||||
|
||||
if (ring->count_dw >= (count >> 2))
|
||||
ring->count_dw -= (count >> 2);
|
||||
else
|
||||
ring->count_dw = 0;
|
||||
}
|
||||
|
||||
static u64 amdgpu_cper_ring_get_rptr(struct amdgpu_ring *ring)
|
||||
{
|
||||
return *(ring->rptr_cpu_addr);
|
||||
}
|
||||
|
||||
static u64 amdgpu_cper_ring_get_wptr(struct amdgpu_ring *ring)
|
||||
{
|
||||
return ring->wptr;
|
||||
}
|
||||
|
||||
static const struct amdgpu_ring_funcs cper_ring_funcs = {
|
||||
.type = AMDGPU_RING_TYPE_CPER,
|
||||
.align_mask = 0xff,
|
||||
.support_64bit_ptrs = false,
|
||||
.get_rptr = amdgpu_cper_ring_get_rptr,
|
||||
.get_wptr = amdgpu_cper_ring_get_wptr,
|
||||
};
|
||||
|
||||
static int amdgpu_cper_ring_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *ring = &(adev->cper.ring_buf);
|
||||
|
||||
mutex_init(&adev->cper.ring_lock);
|
||||
|
||||
ring->adev = NULL;
|
||||
ring->ring_obj = NULL;
|
||||
ring->use_doorbell = false;
|
||||
ring->no_scheduler = true;
|
||||
ring->funcs = &cper_ring_funcs;
|
||||
|
||||
sprintf(ring->name, "cper");
|
||||
return amdgpu_ring_init(adev, ring, CPER_MAX_RING_SIZE, NULL, 0,
|
||||
AMDGPU_RING_PRIO_DEFAULT, NULL);
|
||||
}
|
||||
|
||||
int amdgpu_cper_init(struct amdgpu_device *adev)
|
||||
{
|
||||
if (!amdgpu_aca_is_enabled(adev))
|
||||
return 0;
|
||||
|
||||
mutex_init(&adev->cper.cper_lock);
|
||||
|
||||
adev->cper.enabled = true;
|
||||
adev->cper.max_count = CPER_MAX_ALLOWED_COUNT;
|
||||
|
||||
return amdgpu_cper_ring_init(adev);
|
||||
}
|
||||
|
||||
int amdgpu_cper_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
if (!amdgpu_aca_is_enabled(adev))
|
||||
return 0;
|
||||
|
||||
adev->cper.enabled = false;
|
||||
|
||||
amdgpu_ring_fini(&(adev->cper.ring_buf));
|
||||
adev->cper.count = 0;
|
||||
adev->cper.wptr = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
105
drivers/gpu/drm/amd/amdgpu/amdgpu_cper.h
Normal file
105
drivers/gpu/drm/amd/amdgpu/amdgpu_cper.h
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright 2025 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_CPER_H__
|
||||
#define __AMDGPU_CPER_H__
|
||||
|
||||
#include "amd_cper.h"
|
||||
#include "amdgpu_aca.h"
|
||||
|
||||
#define CPER_MAX_ALLOWED_COUNT 0x1000
|
||||
#define CPER_MAX_RING_SIZE 0X100000
|
||||
#define HDR_LEN (sizeof(struct cper_hdr))
|
||||
#define SEC_DESC_LEN (sizeof(struct cper_sec_desc))
|
||||
|
||||
#define BOOT_SEC_LEN (sizeof(struct cper_sec_crashdump_boot))
|
||||
#define FATAL_SEC_LEN (sizeof(struct cper_sec_crashdump_fatal))
|
||||
#define NONSTD_SEC_LEN (sizeof(struct cper_sec_nonstd_err))
|
||||
|
||||
#define SEC_DESC_OFFSET(idx) (HDR_LEN + (SEC_DESC_LEN * idx))
|
||||
|
||||
#define BOOT_SEC_OFFSET(count, idx) (HDR_LEN + (SEC_DESC_LEN * count) + (BOOT_SEC_LEN * idx))
|
||||
#define FATAL_SEC_OFFSET(count, idx) (HDR_LEN + (SEC_DESC_LEN * count) + (FATAL_SEC_LEN * idx))
|
||||
#define NONSTD_SEC_OFFSET(count, idx) (HDR_LEN + (SEC_DESC_LEN * count) + (NONSTD_SEC_LEN * idx))
|
||||
|
||||
enum amdgpu_cper_type {
|
||||
AMDGPU_CPER_TYPE_RUNTIME,
|
||||
AMDGPU_CPER_TYPE_FATAL,
|
||||
AMDGPU_CPER_TYPE_BOOT,
|
||||
AMDGPU_CPER_TYPE_BP_THRESHOLD,
|
||||
};
|
||||
|
||||
struct amdgpu_cper {
|
||||
bool enabled;
|
||||
|
||||
atomic_t unique_id;
|
||||
struct mutex cper_lock;
|
||||
|
||||
/* Lifetime CPERs generated */
|
||||
uint32_t count;
|
||||
uint32_t max_count;
|
||||
|
||||
uint32_t wptr;
|
||||
|
||||
void *ring[CPER_MAX_ALLOWED_COUNT];
|
||||
struct amdgpu_ring ring_buf;
|
||||
struct mutex ring_lock;
|
||||
};
|
||||
|
||||
void amdgpu_cper_entry_fill_hdr(struct amdgpu_device *adev,
|
||||
struct cper_hdr *hdr,
|
||||
enum amdgpu_cper_type type,
|
||||
enum cper_error_severity sev);
|
||||
int amdgpu_cper_entry_fill_fatal_section(struct amdgpu_device *adev,
|
||||
struct cper_hdr *hdr,
|
||||
uint32_t idx,
|
||||
struct cper_sec_crashdump_reg_data reg_data);
|
||||
int amdgpu_cper_entry_fill_runtime_section(struct amdgpu_device *adev,
|
||||
struct cper_hdr *hdr,
|
||||
uint32_t idx,
|
||||
enum cper_error_severity sev,
|
||||
uint32_t *reg_dump,
|
||||
uint32_t reg_count);
|
||||
int amdgpu_cper_entry_fill_bad_page_threshold_section(struct amdgpu_device *adev,
|
||||
struct cper_hdr *hdr,
|
||||
uint32_t section_idx);
|
||||
|
||||
struct cper_hdr *amdgpu_cper_alloc_entry(struct amdgpu_device *adev,
|
||||
enum amdgpu_cper_type type,
|
||||
uint16_t section_count);
|
||||
/* UE must be encoded into separated cper entries, 1 UE 1 cper */
|
||||
int amdgpu_cper_generate_ue_record(struct amdgpu_device *adev,
|
||||
struct aca_bank *bank);
|
||||
/* CEs and DEs are combined into 1 cper entry */
|
||||
int amdgpu_cper_generate_ce_records(struct amdgpu_device *adev,
|
||||
struct aca_banks *banks,
|
||||
uint16_t bank_count);
|
||||
/* Bad page threshold is encoded into separated cper entry */
|
||||
int amdgpu_cper_generate_bp_threshold_record(struct amdgpu_device *adev);
|
||||
void amdgpu_cper_ring_write(struct amdgpu_ring *ring,
|
||||
void *src, int count);
|
||||
int amdgpu_cper_init(struct amdgpu_device *adev);
|
||||
int amdgpu_cper_fini(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
|
@ -102,6 +102,9 @@ MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin");
|
|||
#define AMDGPU_PCIE_INDEX_HI_FALLBACK (0x44 >> 2)
|
||||
#define AMDGPU_PCIE_DATA_FALLBACK (0x3C >> 2)
|
||||
|
||||
#define AMDGPU_VBIOS_SKIP (1U << 0)
|
||||
#define AMDGPU_VBIOS_OPTIONAL (1U << 1)
|
||||
|
||||
static const struct drm_driver amdgpu_kms_driver;
|
||||
|
||||
const char *amdgpu_asic_name[] = {
|
||||
|
|
@ -1389,6 +1392,17 @@ static void amdgpu_block_invalid_wreg(struct amdgpu_device *adev,
|
|||
BUG();
|
||||
}
|
||||
|
||||
static uint32_t amdgpu_device_get_vbios_flags(struct amdgpu_device *adev)
|
||||
{
|
||||
if (hweight32(adev->aid_mask) && (adev->flags & AMD_IS_APU))
|
||||
return AMDGPU_VBIOS_SKIP;
|
||||
|
||||
if (hweight32(adev->aid_mask) && amdgpu_passthrough(adev))
|
||||
return AMDGPU_VBIOS_OPTIONAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_asic_init - Wrapper for atom asic_init
|
||||
*
|
||||
|
|
@ -1398,18 +1412,28 @@ static void amdgpu_block_invalid_wreg(struct amdgpu_device *adev,
|
|||
*/
|
||||
static int amdgpu_device_asic_init(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t flags;
|
||||
bool optional;
|
||||
int ret;
|
||||
|
||||
amdgpu_asic_pre_asic_init(adev);
|
||||
flags = amdgpu_device_get_vbios_flags(adev);
|
||||
optional = !!(flags & (AMDGPU_VBIOS_OPTIONAL | AMDGPU_VBIOS_SKIP));
|
||||
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 5, 0) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(11, 0, 0)) {
|
||||
amdgpu_psp_wait_for_bootloader(adev);
|
||||
if (optional && !adev->bios)
|
||||
return 0;
|
||||
|
||||
ret = amdgpu_atomfirmware_asic_init(adev, true);
|
||||
return ret;
|
||||
} else {
|
||||
if (optional && !adev->bios)
|
||||
return 0;
|
||||
|
||||
return amdgpu_atom_asic_init(adev->mode_info.atom_context);
|
||||
}
|
||||
|
||||
|
|
@ -1698,14 +1722,6 @@ int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool amdgpu_device_read_bios(struct amdgpu_device *adev)
|
||||
{
|
||||
if (hweight32(adev->aid_mask) && (adev->flags & AMD_IS_APU))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* GPU helpers function.
|
||||
*/
|
||||
|
|
@ -1720,12 +1736,15 @@ static bool amdgpu_device_read_bios(struct amdgpu_device *adev)
|
|||
*/
|
||||
bool amdgpu_device_need_post(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t reg, flags;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return false;
|
||||
|
||||
if (!amdgpu_device_read_bios(adev))
|
||||
flags = amdgpu_device_get_vbios_flags(adev);
|
||||
if (flags & AMDGPU_VBIOS_SKIP)
|
||||
return false;
|
||||
if ((flags & AMDGPU_VBIOS_OPTIONAL) && !adev->bios)
|
||||
return false;
|
||||
|
||||
if (amdgpu_passthrough(adev)) {
|
||||
|
|
@ -2233,7 +2252,8 @@ void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev,
|
|||
if (!adev->ip_blocks[i].status.valid)
|
||||
continue;
|
||||
if (adev->ip_blocks[i].version->funcs->get_clockgating_state)
|
||||
adev->ip_blocks[i].version->funcs->get_clockgating_state((void *)adev, flags);
|
||||
adev->ip_blocks[i].version->funcs->get_clockgating_state(
|
||||
&adev->ip_blocks[i], flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2578,8 +2598,9 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
|
|||
{
|
||||
struct amdgpu_ip_block *ip_block;
|
||||
struct pci_dev *parent;
|
||||
bool total, skip_bios;
|
||||
uint32_t bios_flags;
|
||||
int i, r;
|
||||
bool total;
|
||||
|
||||
amdgpu_device_enable_virtual_display(adev);
|
||||
|
||||
|
|
@ -2692,16 +2713,31 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
bios_flags = amdgpu_device_get_vbios_flags(adev);
|
||||
skip_bios = !!(bios_flags & AMDGPU_VBIOS_SKIP);
|
||||
/* Read BIOS */
|
||||
if (amdgpu_device_read_bios(adev)) {
|
||||
if (!amdgpu_get_bios(adev))
|
||||
if (!skip_bios) {
|
||||
bool optional =
|
||||
!!(bios_flags & AMDGPU_VBIOS_OPTIONAL);
|
||||
if (!amdgpu_get_bios(adev) && !optional)
|
||||
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;
|
||||
if (optional && !adev->bios)
|
||||
dev_info(
|
||||
adev->dev,
|
||||
"VBIOS image optional, proceeding without VBIOS image");
|
||||
|
||||
if (adev->bios) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3062,6 +3098,8 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
|||
|
||||
amdgpu_fru_get_product_info(adev);
|
||||
|
||||
r = amdgpu_cper_init(adev);
|
||||
|
||||
init_failed:
|
||||
|
||||
return r;
|
||||
|
|
@ -3422,6 +3460,8 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
|
|||
{
|
||||
int i, r;
|
||||
|
||||
amdgpu_cper_fini(adev);
|
||||
|
||||
if (amdgpu_sriov_vf(adev) && adev->virt.ras_init_done)
|
||||
amdgpu_virt_release_ras_err_handler_data(adev);
|
||||
|
||||
|
|
@ -4222,7 +4262,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
mutex_init(&adev->grbm_idx_mutex);
|
||||
mutex_init(&adev->mn_lock);
|
||||
mutex_init(&adev->virt.vf_errors.lock);
|
||||
mutex_init(&adev->virt.rlcg_reg_lock);
|
||||
hash_init(adev->mn_hash);
|
||||
mutex_init(&adev->psp.mutex);
|
||||
mutex_init(&adev->notifier_lock);
|
||||
|
|
@ -4248,6 +4287,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
spin_lock_init(&adev->se_cac_idx_lock);
|
||||
spin_lock_init(&adev->audio_endpt_idx_lock);
|
||||
spin_lock_init(&adev->mm_stats.lock);
|
||||
spin_lock_init(&adev->virt.rlcg_reg_lock);
|
||||
spin_lock_init(&adev->wb.lock);
|
||||
|
||||
INIT_LIST_HEAD(&adev->reset_list);
|
||||
|
|
@ -4471,8 +4511,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
goto failed;
|
||||
}
|
||||
/* init i2c buses */
|
||||
if (!amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_atombios_i2c_init(adev);
|
||||
amdgpu_i2c_init(adev);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4741,14 +4780,13 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
|
|||
amdgpu_reset_fini(adev);
|
||||
|
||||
/* free i2c buses */
|
||||
if (!amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_i2c_fini(adev);
|
||||
amdgpu_i2c_fini(adev);
|
||||
|
||||
if (amdgpu_emu_mode != 1)
|
||||
amdgpu_atombios_fini(adev);
|
||||
|
||||
kfree(adev->bios);
|
||||
adev->bios = NULL;
|
||||
if (adev->bios) {
|
||||
if (amdgpu_emu_mode != 1)
|
||||
amdgpu_atombios_fini(adev);
|
||||
amdgpu_bios_release(adev);
|
||||
}
|
||||
|
||||
kfree(adev->fru_info);
|
||||
adev->fru_info = NULL;
|
||||
|
|
@ -5374,7 +5412,8 @@ int amdgpu_device_mode1_reset(struct amdgpu_device *adev)
|
|||
u32 i;
|
||||
int ret = 0;
|
||||
|
||||
amdgpu_atombios_scratch_regs_engine_hung(adev, true);
|
||||
if (adev->bios)
|
||||
amdgpu_atombios_scratch_regs_engine_hung(adev, true);
|
||||
|
||||
dev_info(adev->dev, "GPU mode1 reset\n");
|
||||
|
||||
|
|
@ -5416,7 +5455,8 @@ int amdgpu_device_mode1_reset(struct amdgpu_device *adev)
|
|||
goto mode1_reset_failed;
|
||||
}
|
||||
|
||||
amdgpu_atombios_scratch_regs_engine_hung(adev, false);
|
||||
if (adev->bios)
|
||||
amdgpu_atombios_scratch_regs_engine_hung(adev, false);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -587,16 +587,19 @@ void amdgpu_discovery_fini(struct amdgpu_device *adev)
|
|||
adev->mman.discovery_bin = NULL;
|
||||
}
|
||||
|
||||
static int amdgpu_discovery_validate_ip(const struct ip_v4 *ip)
|
||||
static int amdgpu_discovery_validate_ip(struct amdgpu_device *adev,
|
||||
uint8_t instance, uint16_t hw_id)
|
||||
{
|
||||
if (ip->instance_number >= HWIP_MAX_INSTANCE) {
|
||||
DRM_ERROR("Unexpected instance_number (%d) from ip discovery blob\n",
|
||||
ip->instance_number);
|
||||
if (instance >= HWIP_MAX_INSTANCE) {
|
||||
dev_err(adev->dev,
|
||||
"Unexpected instance_number (%d) from ip discovery blob\n",
|
||||
instance);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (le16_to_cpu(ip->hw_id) >= HW_ID_MAX) {
|
||||
DRM_ERROR("Unexpected hw_id (%d) from ip discovery blob\n",
|
||||
le16_to_cpu(ip->hw_id));
|
||||
if (hw_id >= HW_ID_MAX) {
|
||||
dev_err(adev->dev,
|
||||
"Unexpected hw_id (%d) from ip discovery blob\n",
|
||||
hw_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -609,8 +612,10 @@ static void amdgpu_discovery_read_harvest_bit_per_ip(struct amdgpu_device *adev,
|
|||
struct binary_header *bhdr;
|
||||
struct ip_discovery_header *ihdr;
|
||||
struct die_header *dhdr;
|
||||
struct ip_v4 *ip;
|
||||
struct ip *ip;
|
||||
uint16_t die_offset, ip_offset, num_dies, num_ips;
|
||||
uint16_t hw_id;
|
||||
uint8_t inst;
|
||||
int i, j;
|
||||
|
||||
bhdr = (struct binary_header *)adev->mman.discovery_bin;
|
||||
|
|
@ -626,16 +631,18 @@ static void amdgpu_discovery_read_harvest_bit_per_ip(struct amdgpu_device *adev,
|
|||
ip_offset = die_offset + sizeof(*dhdr);
|
||||
|
||||
for (j = 0; j < num_ips; j++) {
|
||||
ip = (struct ip_v4 *)(adev->mman.discovery_bin + ip_offset);
|
||||
|
||||
if (amdgpu_discovery_validate_ip(ip))
|
||||
ip = (struct ip *)(adev->mman.discovery_bin +
|
||||
ip_offset);
|
||||
inst = ip->number_instance;
|
||||
hw_id = le16_to_cpu(ip->hw_id);
|
||||
if (amdgpu_discovery_validate_ip(adev, inst, hw_id))
|
||||
goto next_ip;
|
||||
|
||||
if (le16_to_cpu(ip->variant) == 1) {
|
||||
switch (le16_to_cpu(ip->hw_id)) {
|
||||
if (ip->harvest == 1) {
|
||||
switch (hw_id) {
|
||||
case VCN_HWID:
|
||||
(*vcn_harvest_count)++;
|
||||
if (ip->instance_number == 0) {
|
||||
if (inst == 0) {
|
||||
adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN0;
|
||||
adev->vcn.inst_mask &=
|
||||
~AMDGPU_VCN_HARVEST_VCN0;
|
||||
|
|
@ -657,10 +664,8 @@ static void amdgpu_discovery_read_harvest_bit_per_ip(struct amdgpu_device *adev,
|
|||
}
|
||||
}
|
||||
next_ip:
|
||||
if (ihdr->base_addr_64_bit)
|
||||
ip_offset += struct_size(ip, base_address_64, ip->num_base_address);
|
||||
else
|
||||
ip_offset += struct_size(ip, base_address, ip->num_base_address);
|
||||
ip_offset += struct_size(ip, base_address,
|
||||
ip->num_base_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1019,6 +1024,8 @@ static int amdgpu_discovery_sysfs_ips(struct amdgpu_device *adev,
|
|||
bool reg_base_64)
|
||||
{
|
||||
int ii, jj, kk, res;
|
||||
uint16_t hw_id;
|
||||
uint8_t inst;
|
||||
|
||||
DRM_DEBUG("num_ips:%d", num_ips);
|
||||
|
||||
|
|
@ -1034,8 +1041,10 @@ static int amdgpu_discovery_sysfs_ips(struct amdgpu_device *adev,
|
|||
struct ip_hw_instance *ip_hw_instance;
|
||||
|
||||
ip = (struct ip_v4 *)(adev->mman.discovery_bin + ip_offset);
|
||||
if (amdgpu_discovery_validate_ip(ip) ||
|
||||
le16_to_cpu(ip->hw_id) != ii)
|
||||
inst = ip->instance_number;
|
||||
hw_id = le16_to_cpu(ip->hw_id);
|
||||
if (amdgpu_discovery_validate_ip(adev, inst, hw_id) ||
|
||||
hw_id != ii)
|
||||
goto next_ip;
|
||||
|
||||
DRM_DEBUG("match:%d @ ip_offset:%zu", ii, ip_offset);
|
||||
|
|
@ -1282,6 +1291,8 @@ static int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
|
|||
uint16_t ip_offset;
|
||||
uint16_t num_dies;
|
||||
uint16_t num_ips;
|
||||
uint16_t hw_id;
|
||||
uint8_t inst;
|
||||
int hw_ip;
|
||||
int i, j, k;
|
||||
int r;
|
||||
|
|
@ -1321,7 +1332,9 @@ static int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
|
|||
for (j = 0; j < num_ips; j++) {
|
||||
ip = (struct ip_v4 *)(adev->mman.discovery_bin + ip_offset);
|
||||
|
||||
if (amdgpu_discovery_validate_ip(ip))
|
||||
inst = ip->instance_number;
|
||||
hw_id = le16_to_cpu(ip->hw_id);
|
||||
if (amdgpu_discovery_validate_ip(adev, inst, hw_id))
|
||||
goto next_ip;
|
||||
|
||||
num_base_address = ip->num_base_address;
|
||||
|
|
@ -1460,17 +1473,24 @@ static int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
|
|||
|
||||
static void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev)
|
||||
{
|
||||
struct ip_discovery_header *ihdr;
|
||||
struct binary_header *bhdr;
|
||||
int vcn_harvest_count = 0;
|
||||
int umc_harvest_count = 0;
|
||||
uint16_t offset, ihdr_ver;
|
||||
|
||||
bhdr = (struct binary_header *)adev->mman.discovery_bin;
|
||||
offset = le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset);
|
||||
ihdr = (struct ip_discovery_header *)(adev->mman.discovery_bin +
|
||||
offset);
|
||||
ihdr_ver = le16_to_cpu(ihdr->version);
|
||||
/*
|
||||
* Harvest table does not fit Navi1x and legacy GPUs,
|
||||
* so read harvest bit per IP data structure to set
|
||||
* harvest configuration.
|
||||
*/
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(10, 2, 0) &&
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) != IP_VERSION(9, 4, 3) &&
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) != IP_VERSION(9, 4, 4)) {
|
||||
ihdr_ver <= 2) {
|
||||
if ((adev->pdev->device == 0x731E &&
|
||||
(adev->pdev->revision == 0xC6 ||
|
||||
adev->pdev->revision == 0xC7)) ||
|
||||
|
|
@ -1864,6 +1884,7 @@ static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(11, 5, 3):
|
||||
amdgpu_device_ip_block_add(adev, &soc21_common_ip_block);
|
||||
break;
|
||||
case IP_VERSION(12, 0, 0):
|
||||
|
|
@ -1919,6 +1940,7 @@ static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(11, 5, 3):
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v11_0_ip_block);
|
||||
break;
|
||||
case IP_VERSION(12, 0, 0):
|
||||
|
|
@ -1998,6 +2020,7 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(11, 0, 12):
|
||||
case IP_VERSION(11, 0, 13):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
break;
|
||||
case IP_VERSION(11, 0, 8):
|
||||
|
|
@ -2029,6 +2052,7 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
|
|||
break;
|
||||
case IP_VERSION(14, 0, 2):
|
||||
case IP_VERSION(14, 0, 3):
|
||||
case IP_VERSION(14, 0, 5):
|
||||
amdgpu_device_ip_block_add(adev, &psp_v14_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -2061,6 +2085,7 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(11, 0, 12):
|
||||
case IP_VERSION(11, 0, 13):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
break;
|
||||
case IP_VERSION(12, 0, 0):
|
||||
|
|
@ -2079,6 +2104,7 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(13, 0, 10):
|
||||
case IP_VERSION(13, 0, 11):
|
||||
case IP_VERSION(13, 0, 14):
|
||||
case IP_VERSION(13, 0, 12):
|
||||
amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
|
||||
break;
|
||||
case IP_VERSION(14, 0, 0):
|
||||
|
|
@ -2086,6 +2112,7 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(14, 0, 2):
|
||||
case IP_VERSION(14, 0, 3):
|
||||
case IP_VERSION(14, 0, 4):
|
||||
case IP_VERSION(14, 0, 5):
|
||||
amdgpu_device_ip_block_add(adev, &smu_v14_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -2137,6 +2164,7 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(3, 2, 1):
|
||||
case IP_VERSION(3, 5, 0):
|
||||
case IP_VERSION(3, 5, 1):
|
||||
case IP_VERSION(3, 6, 0):
|
||||
case IP_VERSION(4, 1, 0):
|
||||
/* TODO: Fix IP version. DC code expects version 4.0.1 */
|
||||
if (adev->ip_versions[DCE_HWIP][0] == IP_VERSION(4, 1, 0))
|
||||
|
|
@ -2215,6 +2243,7 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(11, 5, 3):
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v11_0_ip_block);
|
||||
break;
|
||||
case IP_VERSION(12, 0, 0):
|
||||
|
|
@ -2270,6 +2299,7 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(6, 1, 0):
|
||||
case IP_VERSION(6, 1, 1):
|
||||
case IP_VERSION(6, 1, 2):
|
||||
case IP_VERSION(6, 1, 3):
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v6_0_ip_block);
|
||||
break;
|
||||
case IP_VERSION(7, 0, 0):
|
||||
|
|
@ -2393,6 +2423,7 @@ static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(11, 5, 3):
|
||||
amdgpu_device_ip_block_add(adev, &mes_v11_0_ip_block);
|
||||
adev->enable_mes = true;
|
||||
adev->enable_mes_kiq = true;
|
||||
|
|
@ -2708,6 +2739,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(11, 5, 3):
|
||||
adev->family = AMDGPU_FAMILY_GC_11_5_0;
|
||||
break;
|
||||
case IP_VERSION(12, 0, 0):
|
||||
|
|
@ -2733,6 +2765,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(11, 5, 3):
|
||||
adev->flags |= AMD_IS_APU;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -2766,11 +2799,13 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
|||
adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg;
|
||||
break;
|
||||
case IP_VERSION(7, 9, 0):
|
||||
case IP_VERSION(7, 9, 1):
|
||||
adev->nbio.funcs = &nbio_v7_9_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v7_9_hdp_flush_reg;
|
||||
break;
|
||||
case IP_VERSION(7, 11, 0):
|
||||
case IP_VERSION(7, 11, 1):
|
||||
case IP_VERSION(7, 11, 2):
|
||||
case IP_VERSION(7, 11, 3):
|
||||
adev->nbio.funcs = &nbio_v7_11_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v7_11_hdp_flush_reg;
|
||||
|
|
@ -2898,6 +2933,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
|||
case IP_VERSION(11, 0, 10):
|
||||
case IP_VERSION(11, 0, 11):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(13, 0, 1):
|
||||
case IP_VERSION(13, 0, 9):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
|
|
@ -2907,6 +2943,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
|||
adev->smuio.funcs = &smuio_v13_0_funcs;
|
||||
break;
|
||||
case IP_VERSION(13, 0, 3):
|
||||
case IP_VERSION(13, 0, 11):
|
||||
adev->smuio.funcs = &smuio_v13_0_3_funcs;
|
||||
if (adev->smuio.funcs->get_pkg_type(adev) == AMDGPU_PKG_TYPE_APU) {
|
||||
adev->flags |= AMD_IS_APU;
|
||||
|
|
|
|||
|
|
@ -121,9 +121,10 @@
|
|||
* - 3.59.0 - Cleared VRAM
|
||||
* - 3.60.0 - Add AMDGPU_TILING_GFX12_DCC_WRITE_COMPRESS_DISABLE (Vulkan requirement)
|
||||
* - 3.61.0 - Contains fix for RV/PCO compute queues
|
||||
* - 3.62.0 - Add AMDGPU_IDS_FLAGS_MODE_PF, AMDGPU_IDS_FLAGS_MODE_VF & AMDGPU_IDS_FLAGS_MODE_PT
|
||||
*/
|
||||
#define KMS_DRIVER_MAJOR 3
|
||||
#define KMS_DRIVER_MINOR 61
|
||||
#define KMS_DRIVER_MINOR 62
|
||||
#define KMS_DRIVER_PATCHLEVEL 0
|
||||
|
||||
/*
|
||||
|
|
@ -283,6 +284,7 @@ module_param_named(gartsize, amdgpu_gart_size, uint, 0600);
|
|||
* DOC: gttsize (int)
|
||||
* Restrict the size of GTT domain (for userspace use) in MiB for testing.
|
||||
* The default is -1 (Use value specified by TTM).
|
||||
* This parameter is deprecated and will be removed in the future.
|
||||
*/
|
||||
MODULE_PARM_DESC(gttsize, "Size of the GTT userspace domain in megabytes (-1 = auto)");
|
||||
module_param_named(gttsize, amdgpu_gtt_size, int, 0600);
|
||||
|
|
@ -963,7 +965,7 @@ module_param_named_unsafe(reset_method, amdgpu_reset_method, int, 0644);
|
|||
* result in the GPU entering bad status when the number of total
|
||||
* faulty pages by ECC exceeds the threshold value.
|
||||
*/
|
||||
MODULE_PARM_DESC(bad_page_threshold, "Bad page threshold(-1 = ignore threshold (default value), 0 = disable bad page retirement, -2 = driver sets threshold)");
|
||||
MODULE_PARM_DESC(bad_page_threshold, "Bad page threshold(-1 = ignore threshold (default value), 0 = disable bad page retirement, -2 = threshold determined by a formula, 0 < threshold < max records, user-defined threshold)");
|
||||
module_param_named(bad_page_threshold, amdgpu_bad_page_threshold, int, 0444);
|
||||
|
||||
MODULE_PARM_DESC(num_kcq, "number of kernel compute queue user want to setup (8 if set to greater than 8 or less than 0, only affect gfx 8+)");
|
||||
|
|
|
|||
|
|
@ -63,10 +63,10 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev, u32 *fru_addr)
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
/* D161 and D163 are the VG20 server SKUs */
|
||||
if (strnstr(atom_ctx->vbios_pn, "D161",
|
||||
sizeof(atom_ctx->vbios_pn)) ||
|
||||
strnstr(atom_ctx->vbios_pn, "D163",
|
||||
sizeof(atom_ctx->vbios_pn))) {
|
||||
if (atom_ctx && (strnstr(atom_ctx->vbios_pn, "D161",
|
||||
sizeof(atom_ctx->vbios_pn)) ||
|
||||
strnstr(atom_ctx->vbios_pn, "D163",
|
||||
sizeof(atom_ctx->vbios_pn)))) {
|
||||
if (fru_addr)
|
||||
*fru_addr = FRU_EEPROM_MADDR_6;
|
||||
return true;
|
||||
|
|
@ -78,8 +78,8 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev, u32 *fru_addr)
|
|||
return false;
|
||||
}
|
||||
case IP_VERSION(11, 0, 7):
|
||||
if (strnstr(atom_ctx->vbios_pn, "D603",
|
||||
sizeof(atom_ctx->vbios_pn))) {
|
||||
if (atom_ctx && strnstr(atom_ctx->vbios_pn, "D603",
|
||||
sizeof(atom_ctx->vbios_pn))) {
|
||||
if (strnstr(atom_ctx->vbios_pn, "D603GLXE",
|
||||
sizeof(atom_ctx->vbios_pn))) {
|
||||
return false;
|
||||
|
|
@ -94,8 +94,8 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev, u32 *fru_addr)
|
|||
}
|
||||
case IP_VERSION(13, 0, 2):
|
||||
/* All Aldebaran SKUs have an FRU */
|
||||
if (!strnstr(atom_ctx->vbios_pn, "D673",
|
||||
sizeof(atom_ctx->vbios_pn)))
|
||||
if (atom_ctx && !strnstr(atom_ctx->vbios_pn, "D673",
|
||||
sizeof(atom_ctx->vbios_pn)))
|
||||
if (fru_addr)
|
||||
*fru_addr = FRU_EEPROM_MADDR_6;
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -771,18 +771,8 @@ int amdgpu_gfx_enable_kgq(struct amdgpu_device *adev, int xcc_id)
|
|||
return r;
|
||||
}
|
||||
|
||||
/* amdgpu_gfx_off_ctrl - Handle gfx off feature enable/disable
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @bool enable true: enable gfx off feature, false: disable gfx off feature
|
||||
*
|
||||
* 1. gfx off feature will be enabled by gfx ip after gfx cg gp enabled.
|
||||
* 2. other client can send request to disable gfx off feature, the request should be honored.
|
||||
* 3. other client can cancel their request of disable gfx off feature
|
||||
* 4. other client should not send request to enable gfx off feature before disable gfx off feature.
|
||||
*/
|
||||
|
||||
void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
|
||||
static void amdgpu_gfx_do_off_ctrl(struct amdgpu_device *adev, bool enable,
|
||||
bool no_delay)
|
||||
{
|
||||
unsigned long delay = GFX_OFF_DELAY_ENABLE;
|
||||
|
||||
|
|
@ -804,7 +794,7 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
|
|||
if (adev->gfx.gfx_off_req_count == 0 &&
|
||||
!adev->gfx.gfx_off_state) {
|
||||
/* If going to s2idle, no need to wait */
|
||||
if (adev->in_s0ix) {
|
||||
if (no_delay) {
|
||||
if (!amdgpu_dpm_set_powergating_by_smu(adev,
|
||||
AMD_IP_BLOCK_TYPE_GFX, true, 0))
|
||||
adev->gfx.gfx_off_state = true;
|
||||
|
|
@ -836,6 +826,43 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
|
|||
mutex_unlock(&adev->gfx.gfx_off_mutex);
|
||||
}
|
||||
|
||||
/* amdgpu_gfx_off_ctrl - Handle gfx off feature enable/disable
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @bool enable true: enable gfx off feature, false: disable gfx off feature
|
||||
*
|
||||
* 1. gfx off feature will be enabled by gfx ip after gfx cg pg enabled.
|
||||
* 2. other client can send request to disable gfx off feature, the request should be honored.
|
||||
* 3. other client can cancel their request of disable gfx off feature
|
||||
* 4. other client should not send request to enable gfx off feature before disable gfx off feature.
|
||||
*
|
||||
* gfx off allow will be delayed by GFX_OFF_DELAY_ENABLE ms.
|
||||
*/
|
||||
void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
/* If going to s2idle, no need to wait */
|
||||
bool no_delay = adev->in_s0ix ? true : false;
|
||||
|
||||
amdgpu_gfx_do_off_ctrl(adev, enable, no_delay);
|
||||
}
|
||||
|
||||
/* amdgpu_gfx_off_ctrl_immediate - Handle gfx off feature enable/disable
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @bool enable true: enable gfx off feature, false: disable gfx off feature
|
||||
*
|
||||
* 1. gfx off feature will be enabled by gfx ip after gfx cg pg enabled.
|
||||
* 2. other client can send request to disable gfx off feature, the request should be honored.
|
||||
* 3. other client can cancel their request of disable gfx off feature
|
||||
* 4. other client should not send request to enable gfx off feature before disable gfx off feature.
|
||||
*
|
||||
* gfx off allow will be issued immediately.
|
||||
*/
|
||||
void amdgpu_gfx_off_ctrl_immediate(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
amdgpu_gfx_do_off_ctrl(adev, enable, true);
|
||||
}
|
||||
|
||||
int amdgpu_set_gfx_off_residency(struct amdgpu_device *adev, bool value)
|
||||
{
|
||||
int r = 0;
|
||||
|
|
@ -1643,11 +1670,13 @@ static ssize_t amdgpu_gfx_set_enforce_isolation(struct device *dev,
|
|||
if (adev->enforce_isolation[i] && !partition_values[i]) {
|
||||
/* Going from enabled to disabled */
|
||||
amdgpu_vmid_free_reserved(adev, AMDGPU_GFXHUB(i));
|
||||
amdgpu_mes_set_enforce_isolation(adev, i, false);
|
||||
if (adev->enable_mes && adev->gfx.enable_cleaner_shader)
|
||||
amdgpu_mes_set_enforce_isolation(adev, i, false);
|
||||
} else if (!adev->enforce_isolation[i] && partition_values[i]) {
|
||||
/* Going from disabled to enabled */
|
||||
amdgpu_vmid_alloc_reserved(adev, AMDGPU_GFXHUB(i));
|
||||
amdgpu_mes_set_enforce_isolation(adev, i, true);
|
||||
if (adev->enable_mes && adev->gfx.enable_cleaner_shader)
|
||||
amdgpu_mes_set_enforce_isolation(adev, i, true);
|
||||
}
|
||||
adev->enforce_isolation[i] = partition_values[i];
|
||||
}
|
||||
|
|
@ -2118,6 +2147,63 @@ void amdgpu_gfx_enforce_isolation_ring_end_use(struct amdgpu_ring *ring)
|
|||
amdgpu_gfx_kfd_sch_ctrl(adev, idx, true);
|
||||
}
|
||||
|
||||
void amdgpu_gfx_profile_idle_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct amdgpu_device *adev =
|
||||
container_of(work, struct amdgpu_device, gfx.idle_work.work);
|
||||
enum PP_SMC_POWER_PROFILE profile;
|
||||
u32 i, fences = 0;
|
||||
int r;
|
||||
|
||||
if (adev->gfx.num_gfx_rings)
|
||||
profile = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
|
||||
else
|
||||
profile = PP_SMC_POWER_PROFILE_COMPUTE;
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_GFX_RINGS; ++i)
|
||||
fences += amdgpu_fence_count_emitted(&adev->gfx.gfx_ring[i]);
|
||||
for (i = 0; i < (AMDGPU_MAX_COMPUTE_RINGS * AMDGPU_MAX_GC_INSTANCES); ++i)
|
||||
fences += amdgpu_fence_count_emitted(&adev->gfx.compute_ring[i]);
|
||||
if (!fences && !atomic_read(&adev->gfx.total_submission_cnt)) {
|
||||
r = amdgpu_dpm_switch_power_profile(adev, profile, false);
|
||||
if (r)
|
||||
dev_warn(adev->dev, "(%d) failed to disable %s power profile mode\n", r,
|
||||
profile == PP_SMC_POWER_PROFILE_FULLSCREEN3D ?
|
||||
"fullscreen 3D" : "compute");
|
||||
} else {
|
||||
schedule_delayed_work(&adev->gfx.idle_work, GFX_PROFILE_IDLE_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_gfx_profile_ring_begin_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
enum PP_SMC_POWER_PROFILE profile;
|
||||
int r;
|
||||
|
||||
if (adev->gfx.num_gfx_rings)
|
||||
profile = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
|
||||
else
|
||||
profile = PP_SMC_POWER_PROFILE_COMPUTE;
|
||||
|
||||
atomic_inc(&adev->gfx.total_submission_cnt);
|
||||
|
||||
if (!cancel_delayed_work_sync(&adev->gfx.idle_work)) {
|
||||
r = amdgpu_dpm_switch_power_profile(adev, profile, true);
|
||||
if (r)
|
||||
dev_warn(adev->dev, "(%d) failed to disable %s power profile mode\n", r,
|
||||
profile == PP_SMC_POWER_PROFILE_FULLSCREEN3D ?
|
||||
"fullscreen 3D" : "compute");
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_gfx_profile_ring_end_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
atomic_dec(&ring->adev->gfx.total_submission_cnt);
|
||||
|
||||
schedule_delayed_work(&ring->adev->gfx.idle_work, GFX_PROFILE_IDLE_TIMEOUT);
|
||||
}
|
||||
|
||||
/*
|
||||
* debugfs for to enable/disable gfx job submission to specific core.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ enum amdgpu_gfx_pipe_priority {
|
|||
#define AMDGPU_GFX_QUEUE_PRIORITY_MINIMUM 0
|
||||
#define AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM 15
|
||||
|
||||
/* 1 second timeout */
|
||||
#define GFX_PROFILE_IDLE_TIMEOUT msecs_to_jiffies(1000)
|
||||
|
||||
enum amdgpu_gfx_partition {
|
||||
AMDGPU_SPX_PARTITION_MODE = 0,
|
||||
AMDGPU_DPX_PARTITION_MODE = 1,
|
||||
|
|
@ -476,6 +479,9 @@ struct amdgpu_gfx {
|
|||
bool kfd_sch_inactive[MAX_XCP];
|
||||
unsigned long enforce_isolation_jiffies[MAX_XCP];
|
||||
unsigned long enforce_isolation_time[MAX_XCP];
|
||||
|
||||
atomic_t total_submission_cnt;
|
||||
struct delayed_work idle_work;
|
||||
};
|
||||
|
||||
struct amdgpu_gfx_ras_reg_entry {
|
||||
|
|
@ -547,6 +553,7 @@ int amdgpu_gfx_me_queue_to_bit(struct amdgpu_device *adev, int me,
|
|||
bool amdgpu_gfx_is_me_queue_enabled(struct amdgpu_device *adev, int me,
|
||||
int pipe, int queue);
|
||||
void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable);
|
||||
void amdgpu_gfx_off_ctrl_immediate(struct amdgpu_device *adev, bool enable);
|
||||
int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value);
|
||||
int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
|
||||
void amdgpu_gfx_ras_fini(struct amdgpu_device *adev);
|
||||
|
|
@ -584,6 +591,11 @@ void amdgpu_gfx_cleaner_shader_init(struct amdgpu_device *adev,
|
|||
void amdgpu_gfx_enforce_isolation_handler(struct work_struct *work);
|
||||
void amdgpu_gfx_enforce_isolation_ring_begin_use(struct amdgpu_ring *ring);
|
||||
void amdgpu_gfx_enforce_isolation_ring_end_use(struct amdgpu_ring *ring);
|
||||
|
||||
void amdgpu_gfx_profile_idle_work_handler(struct work_struct *work);
|
||||
void amdgpu_gfx_profile_ring_begin_use(struct amdgpu_ring *ring);
|
||||
void amdgpu_gfx_profile_ring_end_use(struct amdgpu_ring *ring);
|
||||
|
||||
void amdgpu_debugfs_gfx_sched_mask_init(struct amdgpu_device *adev);
|
||||
void amdgpu_debugfs_compute_sched_mask_init(struct amdgpu_device *adev);
|
||||
|
||||
|
|
|
|||
|
|
@ -591,7 +591,8 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)
|
|||
|
||||
if (ring == &adev->mes.ring[0] ||
|
||||
ring == &adev->mes.ring[1] ||
|
||||
ring == &adev->umsch_mm.ring)
|
||||
ring == &adev->umsch_mm.ring ||
|
||||
ring == &adev->cper.ring_buf)
|
||||
continue;
|
||||
|
||||
inv_eng = ffs(vm_inv_engs[vmhub]);
|
||||
|
|
@ -851,6 +852,7 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
|
|||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(11, 5, 3):
|
||||
/* Don't enable it by default yet.
|
||||
*/
|
||||
if (amdgpu_tmz < 1) {
|
||||
|
|
@ -888,6 +890,7 @@ void amdgpu_gmc_noretry_set(struct amdgpu_device *adev)
|
|||
gc_ver == IP_VERSION(9, 4, 2) ||
|
||||
gc_ver == IP_VERSION(9, 4, 3) ||
|
||||
gc_ver == IP_VERSION(9, 4, 4) ||
|
||||
gc_ver == IP_VERSION(9, 5, 0) ||
|
||||
gc_ver >= IP_VERSION(10, 3, 0));
|
||||
|
||||
if (!amdgpu_sriov_xnack_support(adev))
|
||||
|
|
|
|||
|
|
@ -225,6 +225,25 @@ void amdgpu_i2c_destroy(struct amdgpu_i2c_chan *i2c)
|
|||
kfree(i2c);
|
||||
}
|
||||
|
||||
void amdgpu_i2c_init(struct amdgpu_device *adev)
|
||||
{
|
||||
if (!adev->is_atom_fw) {
|
||||
if (!amdgpu_device_has_dc_support(adev)) {
|
||||
amdgpu_atombios_i2c_init(adev);
|
||||
} else {
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_POLARIS10:
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS12:
|
||||
amdgpu_atombios_oem_i2c_init(adev, 0x97);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* remove all the buses */
|
||||
void amdgpu_i2c_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ struct amdgpu_i2c_chan *amdgpu_i2c_create(struct drm_device *dev,
|
|||
const struct amdgpu_i2c_bus_rec *rec,
|
||||
const char *name);
|
||||
void amdgpu_i2c_destroy(struct amdgpu_i2c_chan *i2c);
|
||||
void amdgpu_i2c_init(struct amdgpu_device *adev);
|
||||
void amdgpu_i2c_fini(struct amdgpu_device *adev);
|
||||
struct amdgpu_i2c_chan *
|
||||
amdgpu_i2c_lookup(struct amdgpu_device *adev,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#define JPEG_IDLE_TIMEOUT msecs_to_jiffies(1000)
|
||||
|
||||
static void amdgpu_jpeg_idle_work_handler(struct work_struct *work);
|
||||
static void amdgpu_jpeg_reg_dump_fini(struct amdgpu_device *adev);
|
||||
|
||||
int amdgpu_jpeg_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
|
|
@ -85,6 +86,9 @@ int amdgpu_jpeg_sw_fini(struct amdgpu_device *adev)
|
|||
amdgpu_ring_fini(&adev->jpeg.inst[i].ring_dec[j]);
|
||||
}
|
||||
|
||||
if (adev->jpeg.reg_list)
|
||||
amdgpu_jpeg_reg_dump_fini(adev);
|
||||
|
||||
mutex_destroy(&adev->jpeg.jpeg_pg_lock);
|
||||
|
||||
return 0;
|
||||
|
|
@ -452,3 +456,83 @@ void amdgpu_jpeg_sysfs_reset_mask_fini(struct amdgpu_device *adev)
|
|||
device_remove_file(adev->dev, &dev_attr_jpeg_reset_mask);
|
||||
}
|
||||
}
|
||||
|
||||
int amdgpu_jpeg_reg_dump_init(struct amdgpu_device *adev,
|
||||
const struct amdgpu_hwip_reg_entry *reg, u32 count)
|
||||
{
|
||||
adev->jpeg.ip_dump = kcalloc(adev->jpeg.num_jpeg_inst * count,
|
||||
sizeof(uint32_t), GFP_KERNEL);
|
||||
if (!adev->jpeg.ip_dump) {
|
||||
DRM_ERROR("Failed to allocate memory for JPEG IP Dump\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
adev->jpeg.reg_list = reg;
|
||||
adev->jpeg.reg_count = count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void amdgpu_jpeg_reg_dump_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
kfree(adev->jpeg.ip_dump);
|
||||
adev->jpeg.reg_list = NULL;
|
||||
adev->jpeg.reg_count = 0;
|
||||
}
|
||||
|
||||
void amdgpu_jpeg_dump_ip_state(struct amdgpu_ip_block *ip_block)
|
||||
{
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
u32 inst_off, inst_id, is_powered;
|
||||
int i, j;
|
||||
|
||||
if (!adev->jpeg.ip_dump)
|
||||
return;
|
||||
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) {
|
||||
if (adev->jpeg.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
inst_id = GET_INST(JPEG, i);
|
||||
inst_off = i * adev->jpeg.reg_count;
|
||||
/* check power status from UVD_JPEG_POWER_STATUS */
|
||||
adev->jpeg.ip_dump[inst_off] =
|
||||
RREG32(SOC15_REG_ENTRY_OFFSET_INST(adev->jpeg.reg_list[0],
|
||||
inst_id));
|
||||
is_powered = ((adev->jpeg.ip_dump[inst_off] & 0x1) != 1);
|
||||
|
||||
if (is_powered)
|
||||
for (j = 1; j < adev->jpeg.reg_count; j++)
|
||||
adev->jpeg.ip_dump[inst_off + j] =
|
||||
RREG32(SOC15_REG_ENTRY_OFFSET_INST(adev->jpeg.reg_list[j],
|
||||
inst_id));
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_jpeg_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p)
|
||||
{
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
u32 inst_off, is_powered;
|
||||
int i, j;
|
||||
|
||||
if (!adev->jpeg.ip_dump)
|
||||
return;
|
||||
|
||||
drm_printf(p, "num_instances:%d\n", adev->jpeg.num_jpeg_inst);
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) {
|
||||
if (adev->jpeg.harvest_config & (1 << i)) {
|
||||
drm_printf(p, "\nHarvested Instance:JPEG%d Skipping dump\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
inst_off = i * adev->jpeg.reg_count;
|
||||
is_powered = ((adev->jpeg.ip_dump[inst_off] & 0x1) != 1);
|
||||
|
||||
if (is_powered) {
|
||||
drm_printf(p, "Active Instance:JPEG%d\n", i);
|
||||
for (j = 0; j < adev->jpeg.reg_count; j++)
|
||||
drm_printf(p, "%-50s \t 0x%08x\n", adev->jpeg.reg_list[j].reg_name,
|
||||
adev->jpeg.ip_dump[inst_off + j]);
|
||||
} else
|
||||
drm_printf(p, "\nInactive Instance:JPEG%d\n", i);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,6 +92,14 @@
|
|||
*adev->jpeg.inst[inst_idx].dpg_sram_curr_addr++ = value; \
|
||||
} while (0)
|
||||
|
||||
struct amdgpu_hwip_reg_entry;
|
||||
|
||||
enum amdgpu_jpeg_caps {
|
||||
AMDGPU_JPEG_RRMT_ENABLED,
|
||||
};
|
||||
|
||||
#define AMDGPU_JPEG_CAPS(caps) BIT(AMDGPU_JPEG_##caps)
|
||||
|
||||
struct amdgpu_jpeg_reg{
|
||||
unsigned jpeg_pitch[AMDGPU_MAX_JPEG_RINGS];
|
||||
};
|
||||
|
|
@ -130,6 +138,10 @@ struct amdgpu_jpeg {
|
|||
uint8_t num_inst_per_aid;
|
||||
bool indirect_sram;
|
||||
uint32_t supported_reset;
|
||||
uint32_t caps;
|
||||
u32 *ip_dump;
|
||||
u32 reg_count;
|
||||
const struct amdgpu_hwip_reg_entry *reg_list;
|
||||
};
|
||||
|
||||
int amdgpu_jpeg_sw_init(struct amdgpu_device *adev);
|
||||
|
|
@ -154,5 +166,9 @@ int amdgpu_jpeg_psp_update_sram(struct amdgpu_device *adev, int inst_idx,
|
|||
void amdgpu_debugfs_jpeg_sched_mask_init(struct amdgpu_device *adev);
|
||||
int amdgpu_jpeg_sysfs_reset_mask_init(struct amdgpu_device *adev);
|
||||
void amdgpu_jpeg_sysfs_reset_mask_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_jpeg_reg_dump_init(struct amdgpu_device *adev,
|
||||
const struct amdgpu_hwip_reg_entry *reg, u32 count);
|
||||
void amdgpu_jpeg_dump_ip_state(struct amdgpu_ip_block *ip_block);
|
||||
void amdgpu_jpeg_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p);
|
||||
|
||||
#endif /*__AMDGPU_JPEG_H__*/
|
||||
|
|
|
|||
|
|
@ -888,6 +888,15 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|||
if (adev->gfx.config.ta_cntl2_truncate_coord_mode)
|
||||
dev_info->ids_flags |= AMDGPU_IDS_FLAGS_CONFORMANT_TRUNC_COORD;
|
||||
|
||||
if (amdgpu_passthrough(adev))
|
||||
dev_info->ids_flags |= (AMDGPU_IDS_FLAGS_MODE_PT <<
|
||||
AMDGPU_IDS_FLAGS_MODE_SHIFT) &
|
||||
AMDGPU_IDS_FLAGS_MODE_MASK;
|
||||
else if (amdgpu_sriov_vf(adev))
|
||||
dev_info->ids_flags |= (AMDGPU_IDS_FLAGS_MODE_VF <<
|
||||
AMDGPU_IDS_FLAGS_MODE_SHIFT) &
|
||||
AMDGPU_IDS_FLAGS_MODE_MASK;
|
||||
|
||||
vm_size = adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE;
|
||||
vm_size -= AMDGPU_VA_RESERVED_TOP;
|
||||
|
||||
|
|
|
|||
|
|
@ -609,6 +609,7 @@ struct amdgpu_i2c_adapter {
|
|||
struct i2c_adapter base;
|
||||
|
||||
struct ddc_service *ddc_service;
|
||||
bool oem;
|
||||
};
|
||||
|
||||
#define TO_DM_AUX(x) container_of((x), struct amdgpu_dm_dp_aux, aux)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
#include "amdgpu_securedisplay.h"
|
||||
#include "amdgpu_atomfirmware.h"
|
||||
|
||||
#define AMD_VBIOS_FILE_MAX_SIZE_B (1024*1024*3)
|
||||
#define AMD_VBIOS_FILE_MAX_SIZE_B (1024*1024*16)
|
||||
|
||||
static int psp_load_smu_fw(struct psp_context *psp);
|
||||
static int psp_rap_terminate(struct psp_context *psp);
|
||||
|
|
@ -193,6 +193,7 @@ static int psp_early_init(struct amdgpu_ip_block *ip_block)
|
|||
case IP_VERSION(11, 0, 9):
|
||||
case IP_VERSION(11, 0, 11):
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(11, 0, 12):
|
||||
case IP_VERSION(11, 0, 13):
|
||||
psp_v11_0_set_psp_funcs(psp);
|
||||
|
|
@ -208,11 +209,15 @@ static int psp_early_init(struct amdgpu_ip_block *ip_block)
|
|||
psp->boot_time_tmr = false;
|
||||
fallthrough;
|
||||
case IP_VERSION(13, 0, 6):
|
||||
case IP_VERSION(13, 0, 12):
|
||||
case IP_VERSION(13, 0, 14):
|
||||
psp_v13_0_set_psp_funcs(psp);
|
||||
psp->autoload_supported = false;
|
||||
break;
|
||||
case IP_VERSION(13, 0, 12):
|
||||
psp_v13_0_set_psp_funcs(psp);
|
||||
psp->autoload_supported = false;
|
||||
adev->psp.sup_ifwi_up = !amdgpu_sriov_vf(adev);
|
||||
break;
|
||||
case IP_VERSION(13, 0, 1):
|
||||
case IP_VERSION(13, 0, 3):
|
||||
case IP_VERSION(13, 0, 5):
|
||||
|
|
@ -246,6 +251,10 @@ static int psp_early_init(struct amdgpu_ip_block *ip_block)
|
|||
case IP_VERSION(14, 0, 3):
|
||||
psp_v14_0_set_psp_funcs(psp);
|
||||
break;
|
||||
case IP_VERSION(14, 0, 5):
|
||||
psp_v14_0_set_psp_funcs(psp);
|
||||
psp->boot_time_tmr = false;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -533,7 +542,6 @@ static int psp_sw_fini(struct amdgpu_ip_block *ip_block)
|
|||
{
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
struct psp_gfx_cmd_resp *cmd = psp->cmd;
|
||||
|
||||
psp_memory_training_fini(psp);
|
||||
|
||||
|
|
@ -543,8 +551,8 @@ static int psp_sw_fini(struct amdgpu_ip_block *ip_block)
|
|||
amdgpu_ucode_release(&psp->cap_fw);
|
||||
amdgpu_ucode_release(&psp->toc_fw);
|
||||
|
||||
kfree(cmd);
|
||||
cmd = NULL;
|
||||
kfree(psp->cmd);
|
||||
psp->cmd = NULL;
|
||||
|
||||
psp_free_shared_bufs(psp);
|
||||
|
||||
|
|
@ -1786,34 +1794,47 @@ int psp_ras_initialize(struct psp_context *psp)
|
|||
if (ret)
|
||||
dev_warn(adev->dev, "PSP get boot config failed\n");
|
||||
|
||||
if (!amdgpu_ras_is_supported(psp->adev, AMDGPU_RAS_BLOCK__UMC)) {
|
||||
if (!boot_cfg) {
|
||||
dev_info(adev->dev, "GECC is disabled\n");
|
||||
} else {
|
||||
/* disable GECC in next boot cycle if ras is
|
||||
* disabled by module parameter amdgpu_ras_enable
|
||||
* and/or amdgpu_ras_mask, or boot_config_get call
|
||||
* is failed
|
||||
*/
|
||||
ret = psp_boot_config_set(adev, 0);
|
||||
if (ret)
|
||||
dev_warn(adev->dev, "PSP set boot config failed\n");
|
||||
else
|
||||
dev_warn(adev->dev, "GECC will be disabled in next boot cycle if set amdgpu_ras_enable and/or amdgpu_ras_mask to 0x0\n");
|
||||
}
|
||||
if (boot_cfg == 1 && !adev->ras_default_ecc_enabled &&
|
||||
amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) {
|
||||
dev_warn(adev->dev, "GECC is currently enabled, which may affect performance\n");
|
||||
dev_warn(adev->dev,
|
||||
"To disable GECC, please reboot the system and load the amdgpu driver with the parameter amdgpu_ras_enable=0\n");
|
||||
} else {
|
||||
if (boot_cfg == 1) {
|
||||
dev_info(adev->dev, "GECC is enabled\n");
|
||||
if ((adev->ras_default_ecc_enabled || amdgpu_ras_enable == 1) &&
|
||||
amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) {
|
||||
if (boot_cfg == 1) {
|
||||
dev_info(adev->dev, "GECC is enabled\n");
|
||||
} else {
|
||||
/* enable GECC in next boot cycle if it is disabled
|
||||
* in boot config, or force enable GECC if failed to
|
||||
* get boot configuration
|
||||
*/
|
||||
ret = psp_boot_config_set(adev, BOOT_CONFIG_GECC);
|
||||
if (ret)
|
||||
dev_warn(adev->dev, "PSP set boot config failed\n");
|
||||
else
|
||||
dev_warn(adev->dev, "GECC will be enabled in next boot cycle\n");
|
||||
}
|
||||
} else {
|
||||
/* enable GECC in next boot cycle if it is disabled
|
||||
* in boot config, or force enable GECC if failed to
|
||||
* get boot configuration
|
||||
*/
|
||||
ret = psp_boot_config_set(adev, BOOT_CONFIG_GECC);
|
||||
if (ret)
|
||||
dev_warn(adev->dev, "PSP set boot config failed\n");
|
||||
else
|
||||
dev_warn(adev->dev, "GECC will be enabled in next boot cycle\n");
|
||||
if (!boot_cfg) {
|
||||
if (!adev->ras_default_ecc_enabled &&
|
||||
amdgpu_ras_enable != 1 &&
|
||||
amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC))
|
||||
dev_warn(adev->dev, "GECC is disabled, set amdgpu_ras_enable=1 to enable GECC in next boot cycle if needed\n");
|
||||
else
|
||||
dev_info(adev->dev, "GECC is disabled\n");
|
||||
} else {
|
||||
/* disable GECC in next boot cycle if ras is
|
||||
* disabled by module parameter amdgpu_ras_enable
|
||||
* and/or amdgpu_ras_mask, or boot_config_get call
|
||||
* is failed
|
||||
*/
|
||||
ret = psp_boot_config_set(adev, 0);
|
||||
if (ret)
|
||||
dev_warn(adev->dev, "PSP set boot config failed\n");
|
||||
else
|
||||
dev_warn(adev->dev, "GECC will be disabled in next boot cycle if set amdgpu_ras_enable and/or amdgpu_ras_mask to 0x0\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1864,6 +1864,9 @@ int amdgpu_ras_sysfs_create(struct amdgpu_device *adev,
|
|||
if (!obj || obj->attr_inuse)
|
||||
return -EINVAL;
|
||||
|
||||
if (amdgpu_sriov_vf(adev) && !amdgpu_virt_ras_telemetry_block_en(adev, head->block))
|
||||
return 0;
|
||||
|
||||
get_obj(obj);
|
||||
|
||||
snprintf(obj->fs_data.sysfs_name, sizeof(obj->fs_data.sysfs_name),
|
||||
|
|
@ -3080,31 +3083,29 @@ static void amdgpu_ras_validate_threshold(struct amdgpu_device *adev,
|
|||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
|
||||
/*
|
||||
* Justification of value bad_page_cnt_threshold in ras structure
|
||||
*
|
||||
* Generally, 0 <= amdgpu_bad_page_threshold <= max record length
|
||||
* in eeprom or amdgpu_bad_page_threshold == -2, introduce two
|
||||
* scenarios accordingly.
|
||||
*
|
||||
* Bad page retirement enablement:
|
||||
* - If amdgpu_bad_page_threshold = -2,
|
||||
* bad_page_cnt_threshold = typical value by formula.
|
||||
*
|
||||
* - When the value from user is 0 < amdgpu_bad_page_threshold <
|
||||
* max record length in eeprom, use it directly.
|
||||
*
|
||||
* Bad page retirement disablement:
|
||||
* - If amdgpu_bad_page_threshold = 0, bad page retirement
|
||||
* functionality is disabled, and bad_page_cnt_threshold will
|
||||
* take no effect.
|
||||
* amdgpu_bad_page_threshold is used to config
|
||||
* the threshold for the number of bad pages.
|
||||
* -1: Threshold is set to default value
|
||||
* Driver will issue a warning message when threshold is reached
|
||||
* and continue runtime services.
|
||||
* 0: Disable bad page retirement
|
||||
* Driver will not retire bad pages
|
||||
* which is intended for debugging purpose.
|
||||
* -2: Threshold is determined by a formula
|
||||
* that assumes 1 bad page per 100M of local memory.
|
||||
* Driver will continue runtime services when threhold is reached.
|
||||
* 0 < threshold < max number of bad page records in EEPROM,
|
||||
* A user-defined threshold is set
|
||||
* Driver will halt runtime services when this custom threshold is reached.
|
||||
*/
|
||||
|
||||
if (amdgpu_bad_page_threshold < 0) {
|
||||
if (amdgpu_bad_page_threshold == -2) {
|
||||
u64 val = adev->gmc.mc_vram_size;
|
||||
|
||||
do_div(val, RAS_BAD_PAGE_COVER);
|
||||
con->bad_page_cnt_threshold = min(lower_32_bits(val),
|
||||
max_count);
|
||||
} else if (amdgpu_bad_page_threshold == -1) {
|
||||
con->bad_page_cnt_threshold = ((con->reserved_pages_in_bytes) >> 21) << 4;
|
||||
} else {
|
||||
con->bad_page_cnt_threshold = min_t(int, max_count,
|
||||
amdgpu_bad_page_threshold);
|
||||
|
|
@ -3759,8 +3760,9 @@ static void amdgpu_ras_check_supported(struct amdgpu_device *adev)
|
|||
adev->ras_enabled = amdgpu_ras_enable == 0 ? 0 :
|
||||
adev->ras_hw_enabled & amdgpu_ras_mask;
|
||||
|
||||
/* aca is disabled by default */
|
||||
adev->aca.is_enabled = false;
|
||||
/* aca is disabled by default except for psp v13_0_12 */
|
||||
adev->aca.is_enabled =
|
||||
(amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 12));
|
||||
|
||||
/* bad page feature is not applicable to specific app platform */
|
||||
if (adev->gmc.is_app_apu &&
|
||||
|
|
@ -3848,8 +3850,10 @@ static void amdgpu_ras_init_reserved_vram_size(struct amdgpu_device *adev)
|
|||
case IP_VERSION(13, 0, 2):
|
||||
case IP_VERSION(13, 0, 6):
|
||||
case IP_VERSION(13, 0, 12):
|
||||
con->reserved_pages_in_bytes = AMDGPU_RAS_RESERVED_VRAM_SIZE_DEFAULT;
|
||||
break;
|
||||
case IP_VERSION(13, 0, 14):
|
||||
con->reserved_pages_in_bytes = AMDGPU_RAS_RESERVED_VRAM_SIZE;
|
||||
con->reserved_pages_in_bytes = (AMDGPU_RAS_RESERVED_VRAM_SIZE_DEFAULT << 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ struct amdgpu_iv_entry;
|
|||
|
||||
/* Reserve 8 physical dram row for possible retirement.
|
||||
* In worst cases, it will lose 8 * 2MB memory in vram domain */
|
||||
#define AMDGPU_RAS_RESERVED_VRAM_SIZE (16ULL << 20)
|
||||
#define AMDGPU_RAS_RESERVED_VRAM_SIZE_DEFAULT (16ULL << 20)
|
||||
/* The high three bits indicates socketid */
|
||||
#define AMDGPU_RAS_GET_FEATURES(val) ((val) & ~AMDGPU_RAS_FEATURES_SOCKETID_MASK)
|
||||
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev,
|
|||
if (!control)
|
||||
return false;
|
||||
|
||||
if (amdgpu_atomfirmware_ras_rom_addr(adev, &i2c_addr)) {
|
||||
if (adev->bios && amdgpu_atomfirmware_ras_rom_addr(adev, &i2c_addr)) {
|
||||
/* The address given by VBIOS is an 8-bit, wire-format
|
||||
* address, i.e. the most significant byte.
|
||||
*
|
||||
|
|
@ -558,16 +558,17 @@ bool amdgpu_ras_eeprom_check_err_threshold(struct amdgpu_device *adev)
|
|||
return false;
|
||||
|
||||
if (con->eeprom_control.tbl_hdr.header == RAS_TABLE_HDR_BAD) {
|
||||
if (amdgpu_bad_page_threshold == -1) {
|
||||
if (con->eeprom_control.ras_num_bad_pages > con->bad_page_cnt_threshold)
|
||||
dev_warn(adev->dev, "RAS records:%d exceed threshold:%d",
|
||||
con->eeprom_control.ras_num_bad_pages, con->bad_page_cnt_threshold);
|
||||
con->eeprom_control.ras_num_bad_pages, con->bad_page_cnt_threshold);
|
||||
if ((amdgpu_bad_page_threshold == -1) ||
|
||||
(amdgpu_bad_page_threshold == -2)) {
|
||||
dev_warn(adev->dev,
|
||||
"But GPU can be operated due to bad_page_threshold = -1.\n");
|
||||
"Please consult AMD Service Action Guide (SAG) for appropriate service procedures.\n");
|
||||
return false;
|
||||
} else {
|
||||
dev_warn(adev->dev, "This GPU is in BAD status.");
|
||||
dev_warn(adev->dev, "Please retire it or set a larger "
|
||||
"threshold value when reloading driver.\n");
|
||||
dev_warn(adev->dev,
|
||||
"Please consider adjusting the customized threshold.\n");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -758,7 +759,8 @@ amdgpu_ras_eeprom_update_header(struct amdgpu_ras_eeprom_control *control)
|
|||
control->tbl_rai.health_percent = 0;
|
||||
}
|
||||
|
||||
if (amdgpu_bad_page_threshold != -1)
|
||||
if ((amdgpu_bad_page_threshold != -1) &&
|
||||
(amdgpu_bad_page_threshold != -2))
|
||||
ras->is_rma = true;
|
||||
|
||||
/* ignore the -ENOTSUPP return value */
|
||||
|
|
@ -1428,8 +1430,9 @@ int amdgpu_ras_eeprom_check(struct amdgpu_ras_eeprom_control *control)
|
|||
|
||||
res = __verify_ras_table_checksum(control);
|
||||
if (res)
|
||||
DRM_ERROR("RAS table incorrect checksum or error:%d\n",
|
||||
res);
|
||||
dev_err(adev->dev,
|
||||
"RAS table incorrect checksum or error:%d\n",
|
||||
res);
|
||||
|
||||
/* Warn if we are at 90% of the threshold or above
|
||||
*/
|
||||
|
|
@ -1447,8 +1450,9 @@ int amdgpu_ras_eeprom_check(struct amdgpu_ras_eeprom_control *control)
|
|||
|
||||
res = __verify_ras_table_checksum(control);
|
||||
if (res) {
|
||||
dev_err(adev->dev, "RAS Table incorrect checksum or error:%d\n",
|
||||
res);
|
||||
dev_err(adev->dev,
|
||||
"RAS Table incorrect checksum or error:%d\n",
|
||||
res);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ras->bad_page_cnt_threshold > control->ras_num_bad_pages) {
|
||||
|
|
@ -1466,17 +1470,18 @@ int amdgpu_ras_eeprom_check(struct amdgpu_ras_eeprom_control *control)
|
|||
res = amdgpu_ras_eeprom_correct_header_tag(control,
|
||||
RAS_TABLE_HDR_VAL);
|
||||
} else {
|
||||
dev_err(adev->dev, "RAS records:%d exceed threshold:%d",
|
||||
dev_warn(adev->dev,
|
||||
"RAS records:%d exceed threshold:%d\n",
|
||||
control->ras_num_bad_pages, ras->bad_page_cnt_threshold);
|
||||
if (amdgpu_bad_page_threshold == -1) {
|
||||
dev_warn(adev->dev, "GPU will be initialized due to bad_page_threshold = -1.");
|
||||
if ((amdgpu_bad_page_threshold == -1) ||
|
||||
(amdgpu_bad_page_threshold == -2)) {
|
||||
res = 0;
|
||||
dev_warn(adev->dev,
|
||||
"Please consult AMD Service Action Guide (SAG) for appropriate service procedures\n");
|
||||
} else {
|
||||
ras->is_rma = true;
|
||||
dev_err(adev->dev,
|
||||
"RAS records:%d exceed threshold:%d, "
|
||||
"GPU will not be initialized. Replace this GPU or increase the threshold",
|
||||
control->ras_num_bad_pages, ras->bad_page_cnt_threshold);
|
||||
dev_warn(adev->dev,
|
||||
"User defined threshold is set, runtime service will be halt when threshold is reached\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -324,21 +324,28 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
|
|||
/* always set cond_exec_polling to CONTINUE */
|
||||
*ring->cond_exe_cpu_addr = 1;
|
||||
|
||||
r = amdgpu_fence_driver_start_ring(ring, irq_src, irq_type);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "failed initializing fences (%d).\n", r);
|
||||
return r;
|
||||
if (ring->funcs->type != AMDGPU_RING_TYPE_CPER) {
|
||||
r = amdgpu_fence_driver_start_ring(ring, irq_src, irq_type);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "failed initializing fences (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
max_ibs_dw = ring->funcs->emit_frame_size +
|
||||
amdgpu_ring_max_ibs(ring->funcs->type) * ring->funcs->emit_ib_size;
|
||||
max_ibs_dw = (max_ibs_dw + ring->funcs->align_mask) & ~ring->funcs->align_mask;
|
||||
|
||||
if (WARN_ON(max_ibs_dw > max_dw))
|
||||
max_dw = max_ibs_dw;
|
||||
|
||||
ring->ring_size = roundup_pow_of_two(max_dw * 4 * sched_hw_submission);
|
||||
} else {
|
||||
ring->ring_size = roundup_pow_of_two(max_dw * 4);
|
||||
ring->count_dw = (ring->ring_size - 4) >> 2;
|
||||
/* ring buffer is empty now */
|
||||
ring->wptr = *ring->rptr_cpu_addr = 0;
|
||||
}
|
||||
|
||||
max_ibs_dw = ring->funcs->emit_frame_size +
|
||||
amdgpu_ring_max_ibs(ring->funcs->type) * ring->funcs->emit_ib_size;
|
||||
max_ibs_dw = (max_ibs_dw + ring->funcs->align_mask) & ~ring->funcs->align_mask;
|
||||
|
||||
if (WARN_ON(max_ibs_dw > max_dw))
|
||||
max_dw = max_ibs_dw;
|
||||
|
||||
ring->ring_size = roundup_pow_of_two(max_dw * 4 * sched_hw_submission);
|
||||
|
||||
ring->buf_mask = (ring->ring_size / 4) - 1;
|
||||
ring->ptr_mask = ring->funcs->support_64bit_ptrs ?
|
||||
0xffffffffffffffff : ring->buf_mask;
|
||||
|
|
@ -493,6 +500,7 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
|
|||
{
|
||||
struct amdgpu_ring *ring = file_inode(f)->i_private;
|
||||
uint32_t value, result, early[3];
|
||||
uint64_t p;
|
||||
loff_t i;
|
||||
int r;
|
||||
|
||||
|
|
@ -502,13 +510,18 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
|
|||
result = 0;
|
||||
|
||||
if (*pos < 12) {
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_CPER)
|
||||
mutex_lock(&ring->adev->cper.ring_lock);
|
||||
|
||||
early[0] = amdgpu_ring_get_rptr(ring) & ring->buf_mask;
|
||||
early[1] = amdgpu_ring_get_wptr(ring) & ring->buf_mask;
|
||||
early[2] = ring->wptr & ring->buf_mask;
|
||||
for (i = *pos / 4; i < 3 && size; i++) {
|
||||
r = put_user(early[i], (uint32_t *)buf);
|
||||
if (r)
|
||||
return r;
|
||||
if (r) {
|
||||
result = r;
|
||||
goto out;
|
||||
}
|
||||
buf += 4;
|
||||
result += 4;
|
||||
size -= 4;
|
||||
|
|
@ -516,20 +529,50 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
|
|||
}
|
||||
}
|
||||
|
||||
while (size) {
|
||||
if (*pos >= (ring->ring_size + 12))
|
||||
return result;
|
||||
if (ring->funcs->type != AMDGPU_RING_TYPE_CPER) {
|
||||
while (size) {
|
||||
if (*pos >= (ring->ring_size + 12))
|
||||
return result;
|
||||
|
||||
value = ring->ring[(*pos - 12)/4];
|
||||
r = put_user(value, (uint32_t *)buf);
|
||||
if (r)
|
||||
return r;
|
||||
buf += 4;
|
||||
result += 4;
|
||||
size -= 4;
|
||||
*pos += 4;
|
||||
value = ring->ring[(*pos - 12)/4];
|
||||
r = put_user(value, (uint32_t *)buf);
|
||||
if (r)
|
||||
return r;
|
||||
buf += 4;
|
||||
result += 4;
|
||||
size -= 4;
|
||||
*pos += 4;
|
||||
}
|
||||
} else {
|
||||
p = early[0];
|
||||
if (early[0] <= early[1])
|
||||
size = (early[1] - early[0]);
|
||||
else
|
||||
size = ring->ring_size - (early[0] - early[1]);
|
||||
|
||||
while (size) {
|
||||
if (p == early[1])
|
||||
goto out;
|
||||
|
||||
value = ring->ring[p];
|
||||
r = put_user(value, (uint32_t *)buf);
|
||||
if (r) {
|
||||
result = r;
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf += 4;
|
||||
result += 4;
|
||||
size--;
|
||||
p++;
|
||||
p &= ring->ptr_mask;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_CPER)
|
||||
mutex_unlock(&ring->adev->cper.ring_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ struct amdgpu_job;
|
|||
struct amdgpu_vm;
|
||||
|
||||
/* max number of rings */
|
||||
#define AMDGPU_MAX_RINGS 124
|
||||
#define AMDGPU_MAX_RINGS 132
|
||||
#define AMDGPU_MAX_HWIP_RINGS 64
|
||||
#define AMDGPU_MAX_GFX_RINGS 2
|
||||
#define AMDGPU_MAX_SW_GFX_RINGS 2
|
||||
|
|
@ -82,6 +82,7 @@ enum amdgpu_ring_type {
|
|||
AMDGPU_RING_TYPE_KIQ,
|
||||
AMDGPU_RING_TYPE_MES,
|
||||
AMDGPU_RING_TYPE_UMSCH_MM,
|
||||
AMDGPU_RING_TYPE_CPER,
|
||||
};
|
||||
|
||||
enum amdgpu_ib_pool_type {
|
||||
|
|
|
|||
|
|
@ -1964,10 +1964,19 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
|
|||
/* Compute GTT size, either based on TTM limit
|
||||
* or whatever the user passed on module init.
|
||||
*/
|
||||
if (amdgpu_gtt_size == -1)
|
||||
gtt_size = ttm_tt_pages_limit() << PAGE_SHIFT;
|
||||
else
|
||||
gtt_size = (uint64_t)amdgpu_gtt_size << 20;
|
||||
gtt_size = ttm_tt_pages_limit() << PAGE_SHIFT;
|
||||
if (amdgpu_gtt_size != -1) {
|
||||
uint64_t configured_size = (uint64_t)amdgpu_gtt_size << 20;
|
||||
|
||||
drm_warn(&adev->ddev,
|
||||
"Configuring gttsize via module parameter is deprecated, please use ttm.pages_limit\n");
|
||||
if (gtt_size != configured_size)
|
||||
drm_warn(&adev->ddev,
|
||||
"GTT size has been set as %llu but TTM size has been set as %llu, this is unusual\n",
|
||||
configured_size, gtt_size);
|
||||
|
||||
gtt_size = configured_size;
|
||||
}
|
||||
|
||||
/* Initialize GTT memory pool */
|
||||
r = amdgpu_gtt_mgr_init(adev, gtt_size);
|
||||
|
|
@ -1978,6 +1987,11 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
|
|||
DRM_INFO("amdgpu: %uM of GTT memory ready.\n",
|
||||
(unsigned int)(gtt_size / (1024 * 1024)));
|
||||
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
if (adev->gmc.real_vram_size < gtt_size)
|
||||
adev->apu_prefer_gtt = true;
|
||||
}
|
||||
|
||||
/* Initialize doorbell pool on PCI BAR */
|
||||
r = amdgpu_ttm_init_on_chip(adev, AMDGPU_PL_DOORBELL, adev->doorbell.size / PAGE_SIZE);
|
||||
if (r) {
|
||||
|
|
|
|||
|
|
@ -1216,6 +1216,7 @@ static const char *amdgpu_ucode_legacy_naming(struct amdgpu_device *adev, int bl
|
|||
case IP_VERSION(11, 0, 13):
|
||||
return "beige_goby";
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
return "vangogh";
|
||||
case IP_VERSION(12, 0, 1):
|
||||
return "green_sardine";
|
||||
|
|
|
|||
|
|
@ -387,6 +387,45 @@ int amdgpu_umc_fill_error_record(struct ras_err_data *err_data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_umc_loop_all_aid(struct amdgpu_device *adev, umc_func func,
|
||||
void *data)
|
||||
{
|
||||
uint32_t umc_node_inst;
|
||||
uint32_t node_inst;
|
||||
uint32_t umc_inst;
|
||||
uint32_t ch_inst;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* This loop is done based on the following -
|
||||
* umc.active mask = mask of active umc instances across all nodes
|
||||
* umc.umc_inst_num = maximum number of umc instancess per node
|
||||
* umc.node_inst_num = maximum number of node instances
|
||||
* Channel instances are not assumed to be harvested.
|
||||
*/
|
||||
dev_dbg(adev->dev, "active umcs :%lx umc_inst per node: %d",
|
||||
adev->umc.active_mask, adev->umc.umc_inst_num);
|
||||
for_each_set_bit(umc_node_inst, &(adev->umc.active_mask),
|
||||
adev->umc.node_inst_num * adev->umc.umc_inst_num) {
|
||||
node_inst = umc_node_inst / adev->umc.umc_inst_num;
|
||||
umc_inst = umc_node_inst % adev->umc.umc_inst_num;
|
||||
LOOP_UMC_CH_INST(ch_inst) {
|
||||
dev_dbg(adev->dev,
|
||||
"node_inst :%d umc_inst: %d ch_inst: %d",
|
||||
node_inst, umc_inst, ch_inst);
|
||||
ret = func(adev, node_inst, umc_inst, ch_inst, data);
|
||||
if (ret) {
|
||||
dev_err(adev->dev,
|
||||
"Node %d umc %d ch %d func returns %d\n",
|
||||
node_inst, umc_inst, ch_inst, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_umc_loop_channels(struct amdgpu_device *adev,
|
||||
umc_func func, void *data)
|
||||
{
|
||||
|
|
@ -395,6 +434,9 @@ int amdgpu_umc_loop_channels(struct amdgpu_device *adev,
|
|||
uint32_t ch_inst = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (adev->aid_mask)
|
||||
return amdgpu_umc_loop_all_aid(adev, func, data);
|
||||
|
||||
if (adev->umc.node_inst_num) {
|
||||
LOOP_UMC_EACH_NODE_INST_AND_CH(node_inst, umc_inst, ch_inst) {
|
||||
ret = func(adev, node_inst, umc_inst, ch_inst, data);
|
||||
|
|
|
|||
|
|
@ -32,462 +32,7 @@
|
|||
#include "amdgpu_umsch_mm.h"
|
||||
#include "umsch_mm_v4_0.h"
|
||||
|
||||
struct umsch_mm_test_ctx_data {
|
||||
uint8_t process_csa[PAGE_SIZE];
|
||||
uint8_t vpe_ctx_csa[PAGE_SIZE];
|
||||
uint8_t vcn_ctx_csa[PAGE_SIZE];
|
||||
};
|
||||
|
||||
struct umsch_mm_test_mqd_data {
|
||||
uint8_t vpe_mqd[PAGE_SIZE];
|
||||
uint8_t vcn_mqd[PAGE_SIZE];
|
||||
};
|
||||
|
||||
struct umsch_mm_test_ring_data {
|
||||
uint8_t vpe_ring[PAGE_SIZE];
|
||||
uint8_t vpe_ib[PAGE_SIZE];
|
||||
uint8_t vcn_ring[PAGE_SIZE];
|
||||
uint8_t vcn_ib[PAGE_SIZE];
|
||||
};
|
||||
|
||||
struct umsch_mm_test_queue_info {
|
||||
uint64_t mqd_addr;
|
||||
uint64_t csa_addr;
|
||||
uint32_t doorbell_offset_0;
|
||||
uint32_t doorbell_offset_1;
|
||||
enum UMSCH_SWIP_ENGINE_TYPE engine;
|
||||
};
|
||||
|
||||
struct umsch_mm_test {
|
||||
struct amdgpu_bo *ctx_data_obj;
|
||||
uint64_t ctx_data_gpu_addr;
|
||||
uint32_t *ctx_data_cpu_addr;
|
||||
|
||||
struct amdgpu_bo *mqd_data_obj;
|
||||
uint64_t mqd_data_gpu_addr;
|
||||
uint32_t *mqd_data_cpu_addr;
|
||||
|
||||
struct amdgpu_bo *ring_data_obj;
|
||||
uint64_t ring_data_gpu_addr;
|
||||
uint32_t *ring_data_cpu_addr;
|
||||
|
||||
|
||||
struct amdgpu_vm *vm;
|
||||
struct amdgpu_bo_va *bo_va;
|
||||
uint32_t pasid;
|
||||
uint32_t vm_cntx_cntl;
|
||||
uint32_t num_queues;
|
||||
};
|
||||
|
||||
static int map_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
struct amdgpu_bo *bo, struct amdgpu_bo_va **bo_va,
|
||||
uint64_t addr, uint32_t size)
|
||||
{
|
||||
struct amdgpu_sync sync;
|
||||
struct drm_exec exec;
|
||||
int r;
|
||||
|
||||
amdgpu_sync_create(&sync);
|
||||
|
||||
drm_exec_init(&exec, 0, 0);
|
||||
drm_exec_until_all_locked(&exec) {
|
||||
r = drm_exec_lock_obj(&exec, &bo->tbo.base);
|
||||
drm_exec_retry_on_contention(&exec);
|
||||
if (unlikely(r))
|
||||
goto error_fini_exec;
|
||||
|
||||
r = amdgpu_vm_lock_pd(vm, &exec, 0);
|
||||
drm_exec_retry_on_contention(&exec);
|
||||
if (unlikely(r))
|
||||
goto error_fini_exec;
|
||||
}
|
||||
|
||||
*bo_va = amdgpu_vm_bo_add(adev, vm, bo);
|
||||
if (!*bo_va) {
|
||||
r = -ENOMEM;
|
||||
goto error_fini_exec;
|
||||
}
|
||||
|
||||
r = amdgpu_vm_bo_map(adev, *bo_va, addr, 0, size,
|
||||
AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE |
|
||||
AMDGPU_PTE_EXECUTABLE);
|
||||
|
||||
if (r)
|
||||
goto error_del_bo_va;
|
||||
|
||||
|
||||
r = amdgpu_vm_bo_update(adev, *bo_va, false);
|
||||
if (r)
|
||||
goto error_del_bo_va;
|
||||
|
||||
amdgpu_sync_fence(&sync, (*bo_va)->last_pt_update);
|
||||
|
||||
r = amdgpu_vm_update_pdes(adev, vm, false);
|
||||
if (r)
|
||||
goto error_del_bo_va;
|
||||
|
||||
amdgpu_sync_fence(&sync, vm->last_update);
|
||||
|
||||
amdgpu_sync_wait(&sync, false);
|
||||
drm_exec_fini(&exec);
|
||||
|
||||
amdgpu_sync_free(&sync);
|
||||
|
||||
return 0;
|
||||
|
||||
error_del_bo_va:
|
||||
amdgpu_vm_bo_del(adev, *bo_va);
|
||||
amdgpu_sync_free(&sync);
|
||||
|
||||
error_fini_exec:
|
||||
drm_exec_fini(&exec);
|
||||
amdgpu_sync_free(&sync);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int unmap_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
struct amdgpu_bo *bo, struct amdgpu_bo_va *bo_va,
|
||||
uint64_t addr)
|
||||
{
|
||||
struct drm_exec exec;
|
||||
long r;
|
||||
|
||||
drm_exec_init(&exec, 0, 0);
|
||||
drm_exec_until_all_locked(&exec) {
|
||||
r = drm_exec_lock_obj(&exec, &bo->tbo.base);
|
||||
drm_exec_retry_on_contention(&exec);
|
||||
if (unlikely(r))
|
||||
goto out_unlock;
|
||||
|
||||
r = amdgpu_vm_lock_pd(vm, &exec, 0);
|
||||
drm_exec_retry_on_contention(&exec);
|
||||
if (unlikely(r))
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
|
||||
r = amdgpu_vm_bo_unmap(adev, bo_va, addr);
|
||||
if (r)
|
||||
goto out_unlock;
|
||||
|
||||
amdgpu_vm_bo_del(adev, bo_va);
|
||||
|
||||
out_unlock:
|
||||
drm_exec_fini(&exec);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void setup_vpe_queue(struct amdgpu_device *adev,
|
||||
struct umsch_mm_test *test,
|
||||
struct umsch_mm_test_queue_info *qinfo)
|
||||
{
|
||||
struct MQD_INFO *mqd = (struct MQD_INFO *)test->mqd_data_cpu_addr;
|
||||
uint64_t ring_gpu_addr = test->ring_data_gpu_addr;
|
||||
|
||||
mqd->rb_base_lo = (ring_gpu_addr >> 8);
|
||||
mqd->rb_base_hi = (ring_gpu_addr >> 40);
|
||||
mqd->rb_size = PAGE_SIZE / 4;
|
||||
mqd->wptr_val = 0;
|
||||
mqd->rptr_val = 0;
|
||||
mqd->unmapped = 1;
|
||||
|
||||
if (adev->vpe.collaborate_mode)
|
||||
memcpy(++mqd, test->mqd_data_cpu_addr, sizeof(struct MQD_INFO));
|
||||
|
||||
qinfo->mqd_addr = test->mqd_data_gpu_addr;
|
||||
qinfo->csa_addr = test->ctx_data_gpu_addr +
|
||||
offsetof(struct umsch_mm_test_ctx_data, vpe_ctx_csa);
|
||||
qinfo->doorbell_offset_0 = 0;
|
||||
qinfo->doorbell_offset_1 = 0;
|
||||
}
|
||||
|
||||
static void setup_vcn_queue(struct amdgpu_device *adev,
|
||||
struct umsch_mm_test *test,
|
||||
struct umsch_mm_test_queue_info *qinfo)
|
||||
{
|
||||
}
|
||||
|
||||
static int add_test_queue(struct amdgpu_device *adev,
|
||||
struct umsch_mm_test *test,
|
||||
struct umsch_mm_test_queue_info *qinfo)
|
||||
{
|
||||
struct umsch_mm_add_queue_input queue_input = {};
|
||||
int r;
|
||||
|
||||
queue_input.process_id = test->pasid;
|
||||
queue_input.page_table_base_addr = amdgpu_gmc_pd_addr(test->vm->root.bo);
|
||||
|
||||
queue_input.process_va_start = 0;
|
||||
queue_input.process_va_end = (adev->vm_manager.max_pfn - 1) << AMDGPU_GPU_PAGE_SHIFT;
|
||||
|
||||
queue_input.process_quantum = 100000; /* 10ms */
|
||||
queue_input.process_csa_addr = test->ctx_data_gpu_addr +
|
||||
offsetof(struct umsch_mm_test_ctx_data, process_csa);
|
||||
|
||||
queue_input.context_quantum = 10000; /* 1ms */
|
||||
queue_input.context_csa_addr = qinfo->csa_addr;
|
||||
|
||||
queue_input.inprocess_context_priority = CONTEXT_PRIORITY_LEVEL_NORMAL;
|
||||
queue_input.context_global_priority_level = CONTEXT_PRIORITY_LEVEL_NORMAL;
|
||||
queue_input.doorbell_offset_0 = qinfo->doorbell_offset_0;
|
||||
queue_input.doorbell_offset_1 = qinfo->doorbell_offset_1;
|
||||
|
||||
queue_input.engine_type = qinfo->engine;
|
||||
queue_input.mqd_addr = qinfo->mqd_addr;
|
||||
queue_input.vm_context_cntl = test->vm_cntx_cntl;
|
||||
|
||||
amdgpu_umsch_mm_lock(&adev->umsch_mm);
|
||||
r = adev->umsch_mm.funcs->add_queue(&adev->umsch_mm, &queue_input);
|
||||
amdgpu_umsch_mm_unlock(&adev->umsch_mm);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int remove_test_queue(struct amdgpu_device *adev,
|
||||
struct umsch_mm_test *test,
|
||||
struct umsch_mm_test_queue_info *qinfo)
|
||||
{
|
||||
struct umsch_mm_remove_queue_input queue_input = {};
|
||||
int r;
|
||||
|
||||
queue_input.doorbell_offset_0 = qinfo->doorbell_offset_0;
|
||||
queue_input.doorbell_offset_1 = qinfo->doorbell_offset_1;
|
||||
queue_input.context_csa_addr = qinfo->csa_addr;
|
||||
|
||||
amdgpu_umsch_mm_lock(&adev->umsch_mm);
|
||||
r = adev->umsch_mm.funcs->remove_queue(&adev->umsch_mm, &queue_input);
|
||||
amdgpu_umsch_mm_unlock(&adev->umsch_mm);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int submit_vpe_queue(struct amdgpu_device *adev, struct umsch_mm_test *test)
|
||||
{
|
||||
struct MQD_INFO *mqd = (struct MQD_INFO *)test->mqd_data_cpu_addr;
|
||||
uint32_t *ring = test->ring_data_cpu_addr +
|
||||
offsetof(struct umsch_mm_test_ring_data, vpe_ring) / 4;
|
||||
uint32_t *ib = test->ring_data_cpu_addr +
|
||||
offsetof(struct umsch_mm_test_ring_data, vpe_ib) / 4;
|
||||
uint64_t ib_gpu_addr = test->ring_data_gpu_addr +
|
||||
offsetof(struct umsch_mm_test_ring_data, vpe_ib);
|
||||
uint32_t *fence = ib + 2048 / 4;
|
||||
uint64_t fence_gpu_addr = ib_gpu_addr + 2048;
|
||||
const uint32_t test_pattern = 0xdeadbeef;
|
||||
int i;
|
||||
|
||||
ib[0] = VPE_CMD_HEADER(VPE_CMD_OPCODE_FENCE, 0);
|
||||
ib[1] = lower_32_bits(fence_gpu_addr);
|
||||
ib[2] = upper_32_bits(fence_gpu_addr);
|
||||
ib[3] = test_pattern;
|
||||
|
||||
ring[0] = VPE_CMD_HEADER(VPE_CMD_OPCODE_INDIRECT, 0);
|
||||
ring[1] = (ib_gpu_addr & 0xffffffe0);
|
||||
ring[2] = upper_32_bits(ib_gpu_addr);
|
||||
ring[3] = 4;
|
||||
ring[4] = 0;
|
||||
ring[5] = 0;
|
||||
|
||||
mqd->wptr_val = (6 << 2);
|
||||
if (adev->vpe.collaborate_mode)
|
||||
(++mqd)->wptr_val = (6 << 2);
|
||||
|
||||
WDOORBELL32(adev->umsch_mm.agdb_index[CONTEXT_PRIORITY_LEVEL_NORMAL], mqd->wptr_val);
|
||||
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (*fence == test_pattern)
|
||||
return 0;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
dev_err(adev->dev, "vpe queue submission timeout\n");
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int submit_vcn_queue(struct amdgpu_device *adev, struct umsch_mm_test *test)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setup_umsch_mm_test(struct amdgpu_device *adev,
|
||||
struct umsch_mm_test *test)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB0(0)];
|
||||
int r;
|
||||
|
||||
test->vm_cntx_cntl = hub->vm_cntx_cntl;
|
||||
|
||||
test->vm = kzalloc(sizeof(*test->vm), GFP_KERNEL);
|
||||
if (!test->vm) {
|
||||
r = -ENOMEM;
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_vm_init(adev, test->vm, -1);
|
||||
if (r)
|
||||
goto error_free_vm;
|
||||
|
||||
r = amdgpu_pasid_alloc(16);
|
||||
if (r < 0)
|
||||
goto error_fini_vm;
|
||||
test->pasid = r;
|
||||
|
||||
r = amdgpu_bo_create_kernel(adev, sizeof(struct umsch_mm_test_ctx_data),
|
||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
|
||||
&test->ctx_data_obj,
|
||||
&test->ctx_data_gpu_addr,
|
||||
(void **)&test->ctx_data_cpu_addr);
|
||||
if (r)
|
||||
goto error_free_pasid;
|
||||
|
||||
memset(test->ctx_data_cpu_addr, 0, sizeof(struct umsch_mm_test_ctx_data));
|
||||
|
||||
r = amdgpu_bo_create_kernel(adev, PAGE_SIZE,
|
||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
|
||||
&test->mqd_data_obj,
|
||||
&test->mqd_data_gpu_addr,
|
||||
(void **)&test->mqd_data_cpu_addr);
|
||||
if (r)
|
||||
goto error_free_ctx_data_obj;
|
||||
|
||||
memset(test->mqd_data_cpu_addr, 0, PAGE_SIZE);
|
||||
|
||||
r = amdgpu_bo_create_kernel(adev, sizeof(struct umsch_mm_test_ring_data),
|
||||
PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
|
||||
&test->ring_data_obj,
|
||||
NULL,
|
||||
(void **)&test->ring_data_cpu_addr);
|
||||
if (r)
|
||||
goto error_free_mqd_data_obj;
|
||||
|
||||
memset(test->ring_data_cpu_addr, 0, sizeof(struct umsch_mm_test_ring_data));
|
||||
|
||||
test->ring_data_gpu_addr = AMDGPU_VA_RESERVED_BOTTOM;
|
||||
r = map_ring_data(adev, test->vm, test->ring_data_obj, &test->bo_va,
|
||||
test->ring_data_gpu_addr, sizeof(struct umsch_mm_test_ring_data));
|
||||
if (r)
|
||||
goto error_free_ring_data_obj;
|
||||
|
||||
return 0;
|
||||
|
||||
error_free_ring_data_obj:
|
||||
amdgpu_bo_free_kernel(&test->ring_data_obj, NULL,
|
||||
(void **)&test->ring_data_cpu_addr);
|
||||
error_free_mqd_data_obj:
|
||||
amdgpu_bo_free_kernel(&test->mqd_data_obj, &test->mqd_data_gpu_addr,
|
||||
(void **)&test->mqd_data_cpu_addr);
|
||||
error_free_ctx_data_obj:
|
||||
amdgpu_bo_free_kernel(&test->ctx_data_obj, &test->ctx_data_gpu_addr,
|
||||
(void **)&test->ctx_data_cpu_addr);
|
||||
error_free_pasid:
|
||||
amdgpu_pasid_free(test->pasid);
|
||||
error_fini_vm:
|
||||
amdgpu_vm_fini(adev, test->vm);
|
||||
error_free_vm:
|
||||
kfree(test->vm);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void cleanup_umsch_mm_test(struct amdgpu_device *adev,
|
||||
struct umsch_mm_test *test)
|
||||
{
|
||||
unmap_ring_data(adev, test->vm, test->ring_data_obj,
|
||||
test->bo_va, test->ring_data_gpu_addr);
|
||||
amdgpu_bo_free_kernel(&test->mqd_data_obj, &test->mqd_data_gpu_addr,
|
||||
(void **)&test->mqd_data_cpu_addr);
|
||||
amdgpu_bo_free_kernel(&test->ring_data_obj, NULL,
|
||||
(void **)&test->ring_data_cpu_addr);
|
||||
amdgpu_bo_free_kernel(&test->ctx_data_obj, &test->ctx_data_gpu_addr,
|
||||
(void **)&test->ctx_data_cpu_addr);
|
||||
amdgpu_pasid_free(test->pasid);
|
||||
amdgpu_vm_fini(adev, test->vm);
|
||||
kfree(test->vm);
|
||||
}
|
||||
|
||||
static int setup_test_queues(struct amdgpu_device *adev,
|
||||
struct umsch_mm_test *test,
|
||||
struct umsch_mm_test_queue_info *qinfo)
|
||||
{
|
||||
int i, r;
|
||||
|
||||
for (i = 0; i < test->num_queues; i++) {
|
||||
if (qinfo[i].engine == UMSCH_SWIP_ENGINE_TYPE_VPE)
|
||||
setup_vpe_queue(adev, test, &qinfo[i]);
|
||||
else
|
||||
setup_vcn_queue(adev, test, &qinfo[i]);
|
||||
|
||||
r = add_test_queue(adev, test, &qinfo[i]);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int submit_test_queues(struct amdgpu_device *adev,
|
||||
struct umsch_mm_test *test,
|
||||
struct umsch_mm_test_queue_info *qinfo)
|
||||
{
|
||||
int i, r;
|
||||
|
||||
for (i = 0; i < test->num_queues; i++) {
|
||||
if (qinfo[i].engine == UMSCH_SWIP_ENGINE_TYPE_VPE)
|
||||
r = submit_vpe_queue(adev, test);
|
||||
else
|
||||
r = submit_vcn_queue(adev, test);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cleanup_test_queues(struct amdgpu_device *adev,
|
||||
struct umsch_mm_test *test,
|
||||
struct umsch_mm_test_queue_info *qinfo)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < test->num_queues; i++)
|
||||
remove_test_queue(adev, test, &qinfo[i]);
|
||||
}
|
||||
|
||||
static int umsch_mm_test(struct amdgpu_device *adev)
|
||||
{
|
||||
struct umsch_mm_test_queue_info qinfo[] = {
|
||||
{ .engine = UMSCH_SWIP_ENGINE_TYPE_VPE },
|
||||
};
|
||||
struct umsch_mm_test test = { .num_queues = ARRAY_SIZE(qinfo) };
|
||||
int r;
|
||||
|
||||
r = setup_umsch_mm_test(adev, &test);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = setup_test_queues(adev, &test, qinfo);
|
||||
if (r)
|
||||
goto cleanup;
|
||||
|
||||
r = submit_test_queues(adev, &test, qinfo);
|
||||
if (r)
|
||||
goto cleanup;
|
||||
|
||||
cleanup_test_queues(adev, &test, qinfo);
|
||||
cleanup_umsch_mm_test(adev, &test);
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
cleanup_test_queues(adev, &test, qinfo);
|
||||
cleanup_umsch_mm_test(adev, &test);
|
||||
return r;
|
||||
}
|
||||
MODULE_FIRMWARE("amdgpu/umsch_mm_4_0_0.bin");
|
||||
|
||||
int amdgpu_umsch_mm_submit_pkt(struct amdgpu_umsch_mm *umsch, void *pkt, int ndws)
|
||||
{
|
||||
|
|
@ -581,14 +126,14 @@ int amdgpu_umsch_mm_init_microcode(struct amdgpu_umsch_mm *umsch)
|
|||
switch (amdgpu_ip_version(adev, VCN_HWIP, 0)) {
|
||||
case IP_VERSION(4, 0, 5):
|
||||
case IP_VERSION(4, 0, 6):
|
||||
fw_name = "amdgpu/umsch_mm_4_0_0.bin";
|
||||
fw_name = "4_0_0";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = amdgpu_ucode_request(adev, &adev->umsch_mm.fw, AMDGPU_UCODE_REQUIRED,
|
||||
"%s", fw_name);
|
||||
"amdgpu/umsch_mm_%s.bin", fw_name);
|
||||
if (r) {
|
||||
release_firmware(adev->umsch_mm.fw);
|
||||
adev->umsch_mm.fw = NULL;
|
||||
|
|
@ -792,7 +337,7 @@ static int umsch_mm_late_init(struct amdgpu_ip_block *ip_block)
|
|||
if (amdgpu_in_reset(adev) || adev->in_s0ix || adev->in_suspend)
|
||||
return 0;
|
||||
|
||||
return umsch_mm_test(adev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int umsch_mm_sw_init(struct amdgpu_ip_block *ip_block)
|
||||
|
|
|
|||
|
|
@ -238,6 +238,12 @@
|
|||
|
||||
#define AMDGPU_DRM_KEY_INJECT_WORKAROUND_VCNFW_ASD_HANDSHAKING 2
|
||||
|
||||
enum amdgpu_vcn_caps {
|
||||
AMDGPU_VCN_RRMT_ENABLED,
|
||||
};
|
||||
|
||||
#define AMDGPU_VCN_CAPS(caps) BIT(AMDGPU_VCN_##caps)
|
||||
|
||||
enum fw_queue_mode {
|
||||
FW_QUEUE_RING_RESET = 1,
|
||||
FW_QUEUE_DPG_HOLD_OFF = 2,
|
||||
|
|
@ -345,6 +351,7 @@ struct amdgpu_vcn {
|
|||
uint32_t *ip_dump;
|
||||
|
||||
uint32_t supported_reset;
|
||||
uint32_t caps;
|
||||
};
|
||||
|
||||
struct amdgpu_fw_shared_rb_ptrs_struct {
|
||||
|
|
|
|||
|
|
@ -1017,6 +1017,7 @@ u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 f
|
|||
void *scratch_reg2;
|
||||
void *scratch_reg3;
|
||||
void *spare_int;
|
||||
unsigned long flags;
|
||||
|
||||
if (!adev->gfx.rlc.rlcg_reg_access_supported) {
|
||||
dev_err(adev->dev,
|
||||
|
|
@ -1038,7 +1039,7 @@ u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 f
|
|||
scratch_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2;
|
||||
scratch_reg3 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg3;
|
||||
|
||||
mutex_lock(&adev->virt.rlcg_reg_lock);
|
||||
spin_lock_irqsave(&adev->virt.rlcg_reg_lock, flags);
|
||||
|
||||
if (reg_access_ctrl->spare_int)
|
||||
spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int;
|
||||
|
|
@ -1097,7 +1098,7 @@ u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 f
|
|||
|
||||
ret = readl(scratch_reg0);
|
||||
|
||||
mutex_unlock(&adev->virt.rlcg_reg_lock);
|
||||
spin_unlock_irqrestore(&adev->virt.rlcg_reg_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1246,7 +1247,8 @@ amdgpu_ras_block_to_sriov(struct amdgpu_device *adev, enum amdgpu_ras_block bloc
|
|||
case AMDGPU_RAS_BLOCK__MPIO:
|
||||
return RAS_TELEMETRY_GPU_BLOCK_MPIO;
|
||||
default:
|
||||
dev_err(adev->dev, "Unsupported SRIOV RAS telemetry block 0x%x\n", block);
|
||||
DRM_WARN_ONCE("Unsupported SRIOV RAS telemetry block 0x%x\n",
|
||||
block);
|
||||
return RAS_TELEMETRY_GPU_BLOCK_COUNT;
|
||||
}
|
||||
}
|
||||
|
|
@ -1331,3 +1333,17 @@ int amdgpu_virt_ras_telemetry_post_reset(struct amdgpu_device *adev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool amdgpu_virt_ras_telemetry_block_en(struct amdgpu_device *adev,
|
||||
enum amdgpu_ras_block block)
|
||||
{
|
||||
enum amd_sriov_ras_telemetry_gpu_block sriov_block;
|
||||
|
||||
sriov_block = amdgpu_ras_block_to_sriov(adev, block);
|
||||
|
||||
if (sriov_block >= RAS_TELEMETRY_GPU_BLOCK_COUNT ||
|
||||
!amdgpu_sriov_ras_telemetry_block_en(adev, sriov_block))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -279,7 +279,8 @@ struct amdgpu_virt {
|
|||
/* the ucode id to signal the autoload */
|
||||
uint32_t autoload_ucode_id;
|
||||
|
||||
struct mutex rlcg_reg_lock;
|
||||
/* Spinlock to protect access to the RLCG register interface */
|
||||
spinlock_t rlcg_reg_lock;
|
||||
|
||||
union amd_sriov_ras_caps ras_en_caps;
|
||||
union amd_sriov_ras_caps ras_telemetry_en_caps;
|
||||
|
|
@ -406,4 +407,6 @@ bool amdgpu_virt_get_ras_capability(struct amdgpu_device *adev);
|
|||
int amdgpu_virt_req_ras_err_count(struct amdgpu_device *adev, enum amdgpu_ras_block block,
|
||||
struct ras_err_data *err_data);
|
||||
int amdgpu_virt_ras_telemetry_post_reset(struct amdgpu_device *adev);
|
||||
bool amdgpu_virt_ras_telemetry_block_en(struct amdgpu_device *adev,
|
||||
enum amdgpu_ras_block block);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2534,8 +2534,6 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
spin_lock_init(&vm->status_lock);
|
||||
INIT_LIST_HEAD(&vm->freed);
|
||||
INIT_LIST_HEAD(&vm->done);
|
||||
INIT_LIST_HEAD(&vm->pt_freed);
|
||||
INIT_WORK(&vm->pt_free_work, amdgpu_vm_pt_free_work);
|
||||
INIT_KFIFO(vm->faults);
|
||||
|
||||
r = amdgpu_vm_init_entities(adev, vm);
|
||||
|
|
@ -2674,20 +2672,6 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
|||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_release_compute - release a compute vm
|
||||
* @adev: amdgpu_device pointer
|
||||
* @vm: a vm turned into compute vm by calling amdgpu_vm_make_compute
|
||||
*
|
||||
* This is a correspondant of amdgpu_vm_make_compute. It decouples compute
|
||||
* pasid from vm. Compute should stop use of vm after this call.
|
||||
*/
|
||||
void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
||||
{
|
||||
amdgpu_vm_set_pasid(adev, vm, 0);
|
||||
vm->is_compute_context = false;
|
||||
}
|
||||
|
||||
static int amdgpu_vm_stats_is_zero(struct amdgpu_vm *vm)
|
||||
{
|
||||
for (int i = 0; i < __AMDGPU_PL_NUM; ++i) {
|
||||
|
|
@ -2717,8 +2701,6 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
|||
|
||||
amdgpu_amdkfd_gpuvm_destroy_cb(adev, vm);
|
||||
|
||||
flush_work(&vm->pt_free_work);
|
||||
|
||||
root = amdgpu_bo_ref(vm->root.bo);
|
||||
amdgpu_bo_reserve(root, true);
|
||||
amdgpu_vm_set_pasid(adev, vm, 0);
|
||||
|
|
|
|||
|
|
@ -374,10 +374,6 @@ struct amdgpu_vm {
|
|||
/* BOs which are invalidated, has been updated in the PTs */
|
||||
struct list_head done;
|
||||
|
||||
/* PT BOs scheduled to free and fill with zero if vm_resv is not hold */
|
||||
struct list_head pt_freed;
|
||||
struct work_struct pt_free_work;
|
||||
|
||||
/* contains the page directory */
|
||||
struct amdgpu_vm_bo_base root;
|
||||
struct dma_fence *last_update;
|
||||
|
|
@ -493,7 +489,6 @@ int amdgpu_vm_set_pasid(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout);
|
||||
int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp_id);
|
||||
int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm);
|
||||
void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm);
|
||||
void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
|
||||
int amdgpu_vm_lock_pd(struct amdgpu_vm *vm, struct drm_exec *exec,
|
||||
unsigned int num_fences);
|
||||
|
|
|
|||
|
|
@ -547,27 +547,6 @@ static void amdgpu_vm_pt_free(struct amdgpu_vm_bo_base *entry)
|
|||
amdgpu_bo_unref(&entry->bo);
|
||||
}
|
||||
|
||||
void amdgpu_vm_pt_free_work(struct work_struct *work)
|
||||
{
|
||||
struct amdgpu_vm_bo_base *entry, *next;
|
||||
struct amdgpu_vm *vm;
|
||||
LIST_HEAD(pt_freed);
|
||||
|
||||
vm = container_of(work, struct amdgpu_vm, pt_free_work);
|
||||
|
||||
spin_lock(&vm->status_lock);
|
||||
list_splice_init(&vm->pt_freed, &pt_freed);
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
/* flush_work in amdgpu_vm_fini ensure vm->root.bo is valid. */
|
||||
amdgpu_bo_reserve(vm->root.bo, true);
|
||||
|
||||
list_for_each_entry_safe(entry, next, &pt_freed, vm_status)
|
||||
amdgpu_vm_pt_free(entry);
|
||||
|
||||
amdgpu_bo_unreserve(vm->root.bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_pt_free_list - free PD/PT levels
|
||||
*
|
||||
|
|
@ -580,19 +559,15 @@ void amdgpu_vm_pt_free_list(struct amdgpu_device *adev,
|
|||
struct amdgpu_vm_update_params *params)
|
||||
{
|
||||
struct amdgpu_vm_bo_base *entry, *next;
|
||||
struct amdgpu_vm *vm = params->vm;
|
||||
bool unlocked = params->unlocked;
|
||||
|
||||
if (list_empty(¶ms->tlb_flush_waitlist))
|
||||
return;
|
||||
|
||||
if (unlocked) {
|
||||
spin_lock(&vm->status_lock);
|
||||
list_splice_init(¶ms->tlb_flush_waitlist, &vm->pt_freed);
|
||||
spin_unlock(&vm->status_lock);
|
||||
schedule_work(&vm->pt_free_work);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* unlocked unmap clear page table leaves, warning to free the page entry.
|
||||
*/
|
||||
WARN_ON(unlocked);
|
||||
|
||||
list_for_each_entry_safe(entry, next, ¶ms->tlb_flush_waitlist, vm_status)
|
||||
amdgpu_vm_pt_free(entry);
|
||||
|
|
@ -900,7 +875,15 @@ int amdgpu_vm_ptes_update(struct amdgpu_vm_update_params *params,
|
|||
incr = (uint64_t)AMDGPU_GPU_PAGE_SIZE << shift;
|
||||
mask = amdgpu_vm_pt_entries_mask(adev, cursor.level);
|
||||
pe_start = ((cursor.pfn >> shift) & mask) * 8;
|
||||
entry_end = ((uint64_t)mask + 1) << shift;
|
||||
|
||||
if (cursor.level < AMDGPU_VM_PTB && params->unlocked)
|
||||
/*
|
||||
* MMU notifier callback unlocked unmap huge page, leave is PDE entry,
|
||||
* only clear one entry. Next entry search again for PDE or PTE leave.
|
||||
*/
|
||||
entry_end = 1ULL << shift;
|
||||
else
|
||||
entry_end = ((uint64_t)mask + 1) << shift;
|
||||
entry_end += cursor.pfn & ~(entry_end - 1);
|
||||
entry_end = min(entry_end, end);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
#include "amdgpu.h"
|
||||
#include "amdgpu_vm.h"
|
||||
#include "amdgpu_res_cursor.h"
|
||||
#include "amdgpu_atomfirmware.h"
|
||||
#include "atom.h"
|
||||
|
||||
#define AMDGPU_MAX_SG_SEGMENT_SIZE (2UL << 30)
|
||||
|
|
|
|||
|
|
@ -1123,10 +1123,12 @@ static int xgmi_v6_4_0_aca_bank_parser(struct aca_handle *handle, struct aca_ban
|
|||
if (ext_error_code != 0 && ext_error_code != 9)
|
||||
count = 0ULL;
|
||||
|
||||
bank->aca_err_type = ACA_ERROR_TYPE_UE;
|
||||
ret = aca_error_cache_log_bank_error(handle, &info, ACA_ERROR_TYPE_UE, count);
|
||||
break;
|
||||
case ACA_SMU_TYPE_CE:
|
||||
count = ext_error_code == 6 ? count : 0ULL;
|
||||
bank->aca_err_type = ACA_ERROR_TYPE_CE;
|
||||
ret = aca_error_cache_log_bank_error(handle, &info, ACA_ERROR_TYPE_CE, count);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -77,7 +77,8 @@ static void aqua_vanjaram_set_xcp_id(struct amdgpu_device *adev,
|
|||
ring->xcp_id = AMDGPU_XCP_NO_PARTITION;
|
||||
if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE)
|
||||
adev->gfx.enforce_isolation[0].xcp_id = ring->xcp_id;
|
||||
if (adev->xcp_mgr->mode == AMDGPU_XCP_MODE_NONE)
|
||||
if ((adev->xcp_mgr->mode == AMDGPU_XCP_MODE_NONE) ||
|
||||
(ring->funcs->type == AMDGPU_RING_TYPE_CPER))
|
||||
return;
|
||||
|
||||
inst_mask = 1 << inst_idx;
|
||||
|
|
@ -559,8 +560,11 @@ static bool __aqua_vanjaram_is_valid_mode(struct amdgpu_xcp_mgr *xcp_mgr,
|
|||
adev->gmc.num_mem_partitions == 4) &&
|
||||
(num_xccs_per_xcp >= 2);
|
||||
case AMDGPU_CPX_PARTITION_MODE:
|
||||
/* (num_xcc > 1) because 1 XCC is considered SPX, not CPX.
|
||||
* (num_xcc % adev->gmc.num_mem_partitions) == 0 because
|
||||
* num_compute_partitions can't be less than num_mem_partitions
|
||||
*/
|
||||
return ((num_xcc > 1) &&
|
||||
(adev->gmc.num_mem_partitions == 1 || adev->gmc.num_mem_partitions == 4) &&
|
||||
(num_xcc % adev->gmc.num_mem_partitions) == 0);
|
||||
default:
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@
|
|||
#include "ivsrcid/gfx/irqsrcs_gfx_10_1.h"
|
||||
|
||||
#include "soc15.h"
|
||||
#include "soc15d.h"
|
||||
#include "soc15_common.h"
|
||||
#include "clearstate_gfx10.h"
|
||||
#include "v10_structs.h"
|
||||
|
|
@ -3790,12 +3789,65 @@ static void gfx10_kiq_invalidate_tlbs(struct amdgpu_ring *kiq_ring,
|
|||
gfx_v10_0_ring_invalidate_tlbs(kiq_ring, pasid, flush_type, all_hub, 1);
|
||||
}
|
||||
|
||||
static void gfx_v10_0_kiq_reset_hw_queue(struct amdgpu_ring *kiq_ring, uint32_t queue_type,
|
||||
uint32_t me_id, uint32_t pipe_id, uint32_t queue_id,
|
||||
uint32_t xcc_id, uint32_t vmid)
|
||||
{
|
||||
struct amdgpu_device *adev = kiq_ring->adev;
|
||||
unsigned i;
|
||||
uint32_t tmp;
|
||||
|
||||
/* enter save mode */
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev, xcc_id);
|
||||
mutex_lock(&adev->srbm_mutex);
|
||||
nv_grbm_select(adev, me_id, pipe_id, queue_id, 0);
|
||||
|
||||
if (queue_type == AMDGPU_RING_TYPE_COMPUTE) {
|
||||
WREG32_SOC15(GC, 0, mmCP_HQD_DEQUEUE_REQUEST, 0x2);
|
||||
WREG32_SOC15(GC, 0, mmSPI_COMPUTE_QUEUE_RESET, 0x1);
|
||||
/* wait till dequeue take effects */
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (!(RREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE) & 1))
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
if (i >= adev->usec_timeout)
|
||||
dev_err(adev->dev, "fail to wait on hqd deactive\n");
|
||||
} else if (queue_type == AMDGPU_RING_TYPE_GFX) {
|
||||
WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX,
|
||||
(uint32_t)(0x1 << GRBM_GFX_INDEX__SE_BROADCAST_WRITES__SHIFT));
|
||||
tmp = REG_SET_FIELD(0, CP_VMID_RESET, RESET_REQUEST, 1 << vmid);
|
||||
if (pipe_id == 0)
|
||||
tmp = REG_SET_FIELD(tmp, CP_VMID_RESET, PIPE0_QUEUES, 1 << queue_id);
|
||||
else
|
||||
tmp = REG_SET_FIELD(tmp, CP_VMID_RESET, PIPE1_QUEUES, 1 << queue_id);
|
||||
WREG32_SOC15(GC, 0, mmCP_VMID_RESET, tmp);
|
||||
|
||||
/* wait till dequeue take effects */
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (!(RREG32_SOC15(GC, 0, mmCP_GFX_HQD_ACTIVE) & 1))
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
if (i >= adev->usec_timeout)
|
||||
dev_err(adev->dev, "failed to wait on gfx hqd deactivate\n");
|
||||
} else {
|
||||
dev_err(adev->dev, "reset queue_type(%d) not supported\n", queue_type);
|
||||
}
|
||||
|
||||
nv_grbm_select(adev, 0, 0, 0, 0);
|
||||
mutex_unlock(&adev->srbm_mutex);
|
||||
/* exit safe mode */
|
||||
amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
|
||||
}
|
||||
|
||||
static const struct kiq_pm4_funcs gfx_v10_0_kiq_pm4_funcs = {
|
||||
.kiq_set_resources = gfx10_kiq_set_resources,
|
||||
.kiq_map_queues = gfx10_kiq_map_queues,
|
||||
.kiq_unmap_queues = gfx10_kiq_unmap_queues,
|
||||
.kiq_query_status = gfx10_kiq_query_status,
|
||||
.kiq_invalidate_tlbs = gfx10_kiq_invalidate_tlbs,
|
||||
.kiq_reset_hw_queue = gfx_v10_0_kiq_reset_hw_queue,
|
||||
.set_resources_size = 8,
|
||||
.map_queues_size = 7,
|
||||
.unmap_queues_size = 6,
|
||||
|
|
@ -4701,6 +4753,8 @@ static int gfx_v10_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
int xcc_id = 0;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
|
||||
INIT_DELAYED_WORK(&adev->gfx.idle_work, amdgpu_gfx_profile_idle_work_handler);
|
||||
|
||||
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
|
||||
case IP_VERSION(10, 1, 10):
|
||||
case IP_VERSION(10, 1, 1):
|
||||
|
|
@ -4739,6 +4793,22 @@ static int gfx_v10_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
break;
|
||||
}
|
||||
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
|
||||
case IP_VERSION(10, 1, 10):
|
||||
case IP_VERSION(10, 1, 1):
|
||||
case IP_VERSION(10, 1, 2):
|
||||
adev->gfx.cleaner_shader_ptr = gfx_10_1_10_cleaner_shader_hex;
|
||||
adev->gfx.cleaner_shader_size = sizeof(gfx_10_1_10_cleaner_shader_hex);
|
||||
if (adev->gfx.me_fw_version >= 101 &&
|
||||
adev->gfx.pfp_fw_version >= 158 &&
|
||||
adev->gfx.mec_fw_version >= 152) {
|
||||
adev->gfx.enable_cleaner_shader = true;
|
||||
r = amdgpu_gfx_cleaner_shader_sw_init(adev, adev->gfx.cleaner_shader_size);
|
||||
if (r) {
|
||||
adev->gfx.enable_cleaner_shader = false;
|
||||
dev_err(adev->dev, "Failed to initialize cleaner shader\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IP_VERSION(10, 3, 0):
|
||||
case IP_VERSION(10, 3, 2):
|
||||
case IP_VERSION(10, 3, 4):
|
||||
|
|
@ -7467,6 +7537,8 @@ static int gfx_v10_0_hw_fini(struct amdgpu_ip_block *ip_block)
|
|||
{
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
|
||||
cancel_delayed_work_sync(&adev->gfx.idle_work);
|
||||
|
||||
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
|
||||
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
|
||||
amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
|
||||
|
|
@ -8431,9 +8503,9 @@ static int gfx_v10_0_set_clockgating_state(struct amdgpu_ip_block *ip_block,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_v10_0_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void gfx_v10_0_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
int data;
|
||||
|
||||
/* AMD_CG_SUPPORT_GFX_FGCG */
|
||||
|
|
@ -9748,6 +9820,20 @@ static void gfx_v10_0_ring_emit_cleaner_shader(struct amdgpu_ring *ring)
|
|||
amdgpu_ring_write(ring, 0); /* RESERVED field, programmed to zero */
|
||||
}
|
||||
|
||||
static void gfx_v10_0_ring_begin_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
amdgpu_gfx_profile_ring_begin_use(ring);
|
||||
|
||||
amdgpu_gfx_enforce_isolation_ring_begin_use(ring);
|
||||
}
|
||||
|
||||
static void gfx_v10_0_ring_end_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
amdgpu_gfx_profile_ring_end_use(ring);
|
||||
|
||||
amdgpu_gfx_enforce_isolation_ring_end_use(ring);
|
||||
}
|
||||
|
||||
static const struct amd_ip_funcs gfx_v10_0_ip_funcs = {
|
||||
.name = "gfx_v10_0",
|
||||
.early_init = gfx_v10_0_early_init,
|
||||
|
|
@ -9823,8 +9909,8 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {
|
|||
.emit_mem_sync = gfx_v10_0_emit_mem_sync,
|
||||
.reset = gfx_v10_0_reset_kgq,
|
||||
.emit_cleaner_shader = gfx_v10_0_ring_emit_cleaner_shader,
|
||||
.begin_use = amdgpu_gfx_enforce_isolation_ring_begin_use,
|
||||
.end_use = amdgpu_gfx_enforce_isolation_ring_end_use,
|
||||
.begin_use = gfx_v10_0_ring_begin_use,
|
||||
.end_use = gfx_v10_0_ring_end_use,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = {
|
||||
|
|
@ -9864,8 +9950,8 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = {
|
|||
.emit_mem_sync = gfx_v10_0_emit_mem_sync,
|
||||
.reset = gfx_v10_0_reset_kcq,
|
||||
.emit_cleaner_shader = gfx_v10_0_ring_emit_cleaner_shader,
|
||||
.begin_use = amdgpu_gfx_enforce_isolation_ring_begin_use,
|
||||
.end_use = amdgpu_gfx_enforce_isolation_ring_end_use,
|
||||
.begin_use = gfx_v10_0_ring_begin_use,
|
||||
.end_use = gfx_v10_0_ring_end_use,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_kiq = {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,41 @@
|
|||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Define the cleaner shader gfx_10_1_10 */
|
||||
static const u32 gfx_10_1_10_cleaner_shader_hex[] = {
|
||||
0xb0804004, 0xbf8a0000,
|
||||
0xbf068100, 0xbf840023,
|
||||
0xbe8203b8, 0xbefc0380,
|
||||
0x7e008480, 0x7e028480,
|
||||
0x7e048480, 0x7e068480,
|
||||
0x7e088480, 0x7e0a8480,
|
||||
0x7e0c8480, 0x7e0e8480,
|
||||
0xbefc0302, 0x80828802,
|
||||
0xbf84fff5, 0xbe8203ff,
|
||||
0x80000000, 0x87020102,
|
||||
0xbf840012, 0xbefe03c1,
|
||||
0xbeff03c1, 0xd7650001,
|
||||
0x0001007f, 0xd7660001,
|
||||
0x0002027e, 0x16020288,
|
||||
0xbe8203bf, 0xbefc03c1,
|
||||
0xd9382000, 0x00020201,
|
||||
0xd9386040, 0x00040401,
|
||||
0xd70f6a01, 0x000202ff,
|
||||
0x00000400, 0x80828102,
|
||||
0xbf84fff7, 0xbefc03ff,
|
||||
0x00000068, 0xbe803080,
|
||||
0xbe813080, 0xbe823080,
|
||||
0xbe833080, 0x80fc847c,
|
||||
0xbf84fffa, 0xbeea0480,
|
||||
0xbeec0480, 0xbeee0480,
|
||||
0xbef00480, 0xbef20480,
|
||||
0xbef40480, 0xbef60480,
|
||||
0xbef80480, 0xbefa0480,
|
||||
0xbf810000, 0xbf9f0000,
|
||||
0xbf9f0000, 0xbf9f0000,
|
||||
0xbf9f0000, 0xbf9f0000,
|
||||
};
|
||||
|
||||
/* Define the cleaner shader gfx_10_3_0 */
|
||||
static const u32 gfx_10_3_0_cleaner_shader_hex[] = {
|
||||
0xb0804004, 0xbf8a0000,
|
||||
|
|
|
|||
126
drivers/gpu/drm/amd/amdgpu/gfx_v10_1_10_cleaner_shader.asm
Normal file
126
drivers/gpu/drm/amd/amdgpu/gfx_v10_1_10_cleaner_shader.asm
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright 2025 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.
|
||||
*/
|
||||
|
||||
// This shader is to clean LDS, SGPRs and VGPRs. It is first 64 Dwords or 256 bytes of 256 Dwords cleaner shader.
|
||||
|
||||
// GFX10.1 : Clear SGPRs, VGPRs and LDS
|
||||
// Launch 32 waves per CU (16 per SIMD) as a workgroup (threadgroup) to fill every wave slot
|
||||
// Waves are "wave32" and have 64 VGPRs each, which uses all 1024 VGPRs per SIMD
|
||||
// Waves are launched in "CU" mode, and the workgroup shares 64KB of LDS (half of the WGP's LDS)
|
||||
// It takes 2 workgroups to use all of LDS: one on each CU of the WGP
|
||||
// Each wave clears SGPRs 0 - 107
|
||||
// Each wave clears VGPRs 0 - 63
|
||||
// The first wave of the workgroup clears its 64KB of LDS
|
||||
// The shader starts with "S_BARRIER" to ensure SPI has launched all waves of the workgroup
|
||||
// before any wave in the workgroup could end. Without this, it is possible not all SGPRs get cleared.
|
||||
|
||||
|
||||
shader main
|
||||
asic(GFX10.1)
|
||||
type(CS)
|
||||
wave_size(32)
|
||||
// Note: original source code from SQ team
|
||||
|
||||
//
|
||||
// Create 32 waves in a threadgroup (CS waves)
|
||||
// Each allocates 64 VGPRs
|
||||
// The workgroup allocates all of LDS (64kbytes)
|
||||
//
|
||||
// Takes about 2500 clocks to run.
|
||||
// (theorhetical fastest = 1024clks vgpr + 640lds = 1660 clks)
|
||||
//
|
||||
S_BARRIER
|
||||
s_cmp_eq_u32 s0, 1 // Bit0 is set, sgpr0 is set then clear VGPRS and LDS as FW set COMPUTE_USER_DATA_0
|
||||
s_cbranch_scc0 label_0023 // Clean VGPRs and LDS if sgpr0 of wave is set, scc = (s0 == 1)
|
||||
|
||||
s_mov_b32 s2, 0x00000038 // Loop 64/8=8 times (loop unrolled for performance)
|
||||
s_mov_b32 m0, 0
|
||||
//
|
||||
// CLEAR VGPRs
|
||||
//
|
||||
label_0005:
|
||||
v_movreld_b32 v0, 0
|
||||
v_movreld_b32 v1, 0
|
||||
v_movreld_b32 v2, 0
|
||||
v_movreld_b32 v3, 0
|
||||
v_movreld_b32 v4, 0
|
||||
v_movreld_b32 v5, 0
|
||||
v_movreld_b32 v6, 0
|
||||
v_movreld_b32 v7, 0
|
||||
s_mov_b32 m0, s2
|
||||
s_sub_u32 s2, s2, 8
|
||||
s_cbranch_scc0 label_0005
|
||||
//
|
||||
s_mov_b32 s2, 0x80000000 // Bit31 is first_wave
|
||||
s_and_b32 s2, s2, s0 // sgpr0 has tg_size (first_wave) term as in ucode only COMPUTE_PGM_RSRC2.tg_size_en is set
|
||||
s_cbranch_scc0 label_0023 // Clean LDS if its first wave of ThreadGroup/WorkGroup
|
||||
// CLEAR LDS
|
||||
//
|
||||
s_mov_b32 exec_lo, 0xffffffff
|
||||
s_mov_b32 exec_hi, 0xffffffff
|
||||
v_mbcnt_lo_u32_b32 v1, exec_hi, 0 // Set V1 to thread-ID (0..63)
|
||||
v_mbcnt_hi_u32_b32 v1, exec_lo, v1 // Set V1 to thread-ID (0..63)
|
||||
v_mul_u32_u24 v1, 0x00000008, v1 // * 8, so each thread is a double-dword address (8byte)
|
||||
s_mov_b32 s2, 0x00000003f // 64 loop iterations
|
||||
s_mov_b32 m0, 0xffffffff
|
||||
// Clear all of LDS space
|
||||
// Each FirstWave of WorkGroup clears 64kbyte block
|
||||
|
||||
label_001F:
|
||||
ds_write2_b64 v1, v[2:3], v[2:3] offset1:32
|
||||
ds_write2_b64 v1, v[4:5], v[4:5] offset0:64 offset1:96
|
||||
v_add_co_u32 v1, vcc, 0x00000400, v1
|
||||
s_sub_u32 s2, s2, 1
|
||||
s_cbranch_scc0 label_001F
|
||||
|
||||
//
|
||||
// CLEAR SGPRs
|
||||
//
|
||||
label_0023:
|
||||
s_mov_b32 m0, 0x00000068 // Loop 108/4=27 times (loop unrolled for performance)
|
||||
label_sgpr_loop:
|
||||
s_movreld_b32 s0, 0
|
||||
s_movreld_b32 s1, 0
|
||||
s_movreld_b32 s2, 0
|
||||
s_movreld_b32 s3, 0
|
||||
s_sub_u32 m0, m0, 4
|
||||
s_cbranch_scc0 label_sgpr_loop
|
||||
|
||||
//clear vcc
|
||||
s_mov_b64 vcc, 0 //clear vcc
|
||||
//s_setreg_imm32_b32 hw_reg_shader_flat_scratch_lo, 0 //clear flat scratch lo SGPR
|
||||
//s_setreg_imm32_b32 hw_reg_shader_flat_scratch_hi, 0 //clear flat scratch hi SGPR
|
||||
s_mov_b64 ttmp0, 0 //Clear ttmp0 and ttmp1
|
||||
s_mov_b64 ttmp2, 0 //Clear ttmp2 and ttmp3
|
||||
s_mov_b64 ttmp4, 0 //Clear ttmp4 and ttmp5
|
||||
s_mov_b64 ttmp6, 0 //Clear ttmp6 and ttmp7
|
||||
s_mov_b64 ttmp8, 0 //Clear ttmp8 and ttmp9
|
||||
s_mov_b64 ttmp10, 0 //Clear ttmp10 and ttmp11
|
||||
s_mov_b64 ttmp12, 0 //Clear ttmp12 and ttmp13
|
||||
s_mov_b64 ttmp14, 0 //Clear ttmp14 and ttmp15
|
||||
|
||||
s_endpgm
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
|
@ -29,7 +29,6 @@
|
|||
#include "amdgpu_gfx.h"
|
||||
#include "amdgpu_psp.h"
|
||||
#include "amdgpu_smu.h"
|
||||
#include "amdgpu_atomfirmware.h"
|
||||
#include "imu_v11_0.h"
|
||||
#include "soc21.h"
|
||||
#include "nvd.h"
|
||||
|
|
@ -42,7 +41,6 @@
|
|||
#include "ivsrcid/gfx/irqsrcs_gfx_11_0_0.h"
|
||||
|
||||
#include "soc15.h"
|
||||
#include "soc15d.h"
|
||||
#include "clearstate_gfx11.h"
|
||||
#include "v11_structs.h"
|
||||
#include "gfx_v11_0.h"
|
||||
|
|
@ -98,6 +96,10 @@ MODULE_FIRMWARE("amdgpu/gc_11_5_2_pfp.bin");
|
|||
MODULE_FIRMWARE("amdgpu/gc_11_5_2_me.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_2_mec.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_2_rlc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_3_pfp.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_3_me.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_3_mec.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_3_rlc.bin");
|
||||
|
||||
static const struct amdgpu_hwip_reg_entry gc_reg_list_11_0[] = {
|
||||
SOC15_REG_ENTRY_STR(GC, 0, regGRBM_STATUS),
|
||||
|
|
@ -1087,6 +1089,7 @@ static int gfx_v11_0_gpu_early_init(struct amdgpu_device *adev)
|
|||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(11, 5, 3):
|
||||
adev->gfx.config.max_hw_contexts = 8;
|
||||
adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
|
||||
adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
|
||||
|
|
@ -1552,6 +1555,8 @@ static int gfx_v11_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
int xcc_id = 0;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
|
||||
INIT_DELAYED_WORK(&adev->gfx.idle_work, amdgpu_gfx_profile_idle_work_handler);
|
||||
|
||||
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
|
||||
case IP_VERSION(11, 0, 0):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
|
|
@ -1568,6 +1573,7 @@ static int gfx_v11_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(11, 5, 3):
|
||||
adev->gfx.me.num_me = 1;
|
||||
adev->gfx.me.num_pipe_per_me = 1;
|
||||
adev->gfx.me.num_queue_per_pipe = 1;
|
||||
|
|
@ -2926,7 +2932,8 @@ static int gfx_v11_0_wait_for_rlc_autoload_complete(struct amdgpu_device *adev)
|
|||
IP_VERSION(11, 0, 4) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 5, 0) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 5, 1) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 5, 2))
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 5, 2) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 5, 3))
|
||||
bootload_status = RREG32_SOC15(GC, 0,
|
||||
regRLC_RLCS_BOOTLOAD_STATUS_gc_11_0_1);
|
||||
else
|
||||
|
|
@ -4734,6 +4741,8 @@ static int gfx_v11_0_hw_fini(struct amdgpu_ip_block *ip_block)
|
|||
{
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
|
||||
cancel_delayed_work_sync(&adev->gfx.idle_work);
|
||||
|
||||
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
|
||||
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
|
||||
amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
|
||||
|
|
@ -5448,6 +5457,7 @@ static void gfx_v11_cntl_power_gating(struct amdgpu_device *adev, bool enable)
|
|||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(11, 5, 3):
|
||||
WREG32_SOC15(GC, 0, regRLC_PG_DELAY_3, RLC_PG_DELAY_3_DEFAULT_GC_11_0_1);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -5485,6 +5495,7 @@ static int gfx_v11_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
|||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(11, 5, 3):
|
||||
if (!enable)
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
|
||||
|
|
@ -5518,6 +5529,7 @@ static int gfx_v11_0_set_clockgating_state(struct amdgpu_ip_block *ip_block,
|
|||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(11, 5, 3):
|
||||
gfx_v11_0_update_gfx_clock_gating(adev,
|
||||
state == AMD_CG_STATE_GATE);
|
||||
break;
|
||||
|
|
@ -5528,9 +5540,9 @@ static int gfx_v11_0_set_clockgating_state(struct amdgpu_ip_block *ip_block,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_v11_0_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void gfx_v11_0_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
int data;
|
||||
|
||||
/* AMD_CG_SUPPORT_GFX_MGCG */
|
||||
|
|
@ -6826,6 +6838,20 @@ static void gfx_v11_0_ring_emit_cleaner_shader(struct amdgpu_ring *ring)
|
|||
amdgpu_ring_write(ring, 0); /* RESERVED field, programmed to zero */
|
||||
}
|
||||
|
||||
static void gfx_v11_0_ring_begin_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
amdgpu_gfx_profile_ring_begin_use(ring);
|
||||
|
||||
amdgpu_gfx_enforce_isolation_ring_begin_use(ring);
|
||||
}
|
||||
|
||||
static void gfx_v11_0_ring_end_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
amdgpu_gfx_profile_ring_end_use(ring);
|
||||
|
||||
amdgpu_gfx_enforce_isolation_ring_end_use(ring);
|
||||
}
|
||||
|
||||
static const struct amd_ip_funcs gfx_v11_0_ip_funcs = {
|
||||
.name = "gfx_v11_0",
|
||||
.early_init = gfx_v11_0_early_init,
|
||||
|
|
@ -6900,8 +6926,8 @@ static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_gfx = {
|
|||
.emit_mem_sync = gfx_v11_0_emit_mem_sync,
|
||||
.reset = gfx_v11_0_reset_kgq,
|
||||
.emit_cleaner_shader = gfx_v11_0_ring_emit_cleaner_shader,
|
||||
.begin_use = amdgpu_gfx_enforce_isolation_ring_begin_use,
|
||||
.end_use = amdgpu_gfx_enforce_isolation_ring_end_use,
|
||||
.begin_use = gfx_v11_0_ring_begin_use,
|
||||
.end_use = gfx_v11_0_ring_end_use,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_compute = {
|
||||
|
|
@ -6942,8 +6968,8 @@ static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_compute = {
|
|||
.emit_mem_sync = gfx_v11_0_emit_mem_sync,
|
||||
.reset = gfx_v11_0_reset_kcq,
|
||||
.emit_cleaner_shader = gfx_v11_0_ring_emit_cleaner_shader,
|
||||
.begin_use = amdgpu_gfx_enforce_isolation_ring_begin_use,
|
||||
.end_use = amdgpu_gfx_enforce_isolation_ring_end_use,
|
||||
.begin_use = gfx_v11_0_ring_begin_use,
|
||||
.end_use = gfx_v11_0_ring_end_use,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_kiq = {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
#include "amdgpu_gfx.h"
|
||||
#include "amdgpu_psp.h"
|
||||
#include "amdgpu_smu.h"
|
||||
#include "amdgpu_atomfirmware.h"
|
||||
#include "imu_v12_0.h"
|
||||
#include "soc24.h"
|
||||
#include "nvd.h"
|
||||
|
|
@ -40,7 +39,6 @@
|
|||
#include "ivsrcid/gfx/irqsrcs_gfx_11_0_0.h"
|
||||
|
||||
#include "soc15.h"
|
||||
#include "soc15d.h"
|
||||
#include "clearstate_gfx12.h"
|
||||
#include "v12_structs.h"
|
||||
#include "gfx_v12_0.h"
|
||||
|
|
@ -1331,6 +1329,8 @@ static int gfx_v12_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
int xcc_id = 0;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
|
||||
INIT_DELAYED_WORK(&adev->gfx.idle_work, amdgpu_gfx_profile_idle_work_handler);
|
||||
|
||||
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
|
||||
case IP_VERSION(12, 0, 0):
|
||||
case IP_VERSION(12, 0, 1):
|
||||
|
|
@ -3648,6 +3648,8 @@ static int gfx_v12_0_hw_fini(struct amdgpu_ip_block *ip_block)
|
|||
struct amdgpu_device *adev = ip_block->adev;
|
||||
uint32_t tmp;
|
||||
|
||||
cancel_delayed_work_sync(&adev->gfx.idle_work);
|
||||
|
||||
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
|
||||
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
|
||||
amdgpu_irq_put(adev, &adev->gfx.bad_op_irq, 0);
|
||||
|
|
@ -4147,9 +4149,9 @@ static int gfx_v12_0_set_clockgating_state(struct amdgpu_ip_block *ip_block,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_v12_0_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void gfx_v12_0_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
int data;
|
||||
|
||||
/* AMD_CG_SUPPORT_GFX_MGCG */
|
||||
|
|
@ -5280,6 +5282,20 @@ static int gfx_v12_0_reset_kcq(struct amdgpu_ring *ring, unsigned int vmid)
|
|||
return amdgpu_ring_test_ring(ring);
|
||||
}
|
||||
|
||||
static void gfx_v12_0_ring_begin_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
amdgpu_gfx_profile_ring_begin_use(ring);
|
||||
|
||||
amdgpu_gfx_enforce_isolation_ring_begin_use(ring);
|
||||
}
|
||||
|
||||
static void gfx_v12_0_ring_end_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
amdgpu_gfx_profile_ring_end_use(ring);
|
||||
|
||||
amdgpu_gfx_enforce_isolation_ring_end_use(ring);
|
||||
}
|
||||
|
||||
static const struct amd_ip_funcs gfx_v12_0_ip_funcs = {
|
||||
.name = "gfx_v12_0",
|
||||
.early_init = gfx_v12_0_early_init,
|
||||
|
|
@ -5345,8 +5361,8 @@ static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_gfx = {
|
|||
.emit_mem_sync = gfx_v12_0_emit_mem_sync,
|
||||
.reset = gfx_v12_0_reset_kgq,
|
||||
.emit_cleaner_shader = gfx_v12_0_ring_emit_cleaner_shader,
|
||||
.begin_use = amdgpu_gfx_enforce_isolation_ring_begin_use,
|
||||
.end_use = amdgpu_gfx_enforce_isolation_ring_end_use,
|
||||
.begin_use = gfx_v12_0_ring_begin_use,
|
||||
.end_use = gfx_v12_0_ring_end_use,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_compute = {
|
||||
|
|
@ -5384,8 +5400,8 @@ static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_compute = {
|
|||
.emit_mem_sync = gfx_v12_0_emit_mem_sync,
|
||||
.reset = gfx_v12_0_reset_kcq,
|
||||
.emit_cleaner_shader = gfx_v12_0_ring_emit_cleaner_shader,
|
||||
.begin_use = amdgpu_gfx_enforce_isolation_ring_begin_use,
|
||||
.end_use = amdgpu_gfx_enforce_isolation_ring_end_use,
|
||||
.begin_use = gfx_v12_0_ring_begin_use,
|
||||
.end_use = gfx_v12_0_ring_end_use,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v12_0_ring_funcs_kiq = {
|
||||
|
|
|
|||
|
|
@ -5452,9 +5452,9 @@ static int gfx_v8_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_v8_0_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void gfx_v8_0_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
int data;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
|
|
|
|||
|
|
@ -5241,7 +5241,7 @@ static int gfx_v9_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
|||
case IP_VERSION(9, 1, 0):
|
||||
case IP_VERSION(9, 3, 0):
|
||||
if (!enable)
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
amdgpu_gfx_off_ctrl_immediate(adev, false);
|
||||
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_RLC_SMU_HS) {
|
||||
gfx_v9_0_enable_sck_slow_down_on_power_up(adev, true);
|
||||
|
|
@ -5263,10 +5263,10 @@ static int gfx_v9_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
|||
gfx_v9_0_update_gfx_mg_power_gating(adev, enable);
|
||||
|
||||
if (enable)
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
amdgpu_gfx_off_ctrl_immediate(adev, true);
|
||||
break;
|
||||
case IP_VERSION(9, 2, 1):
|
||||
amdgpu_gfx_off_ctrl(adev, enable);
|
||||
amdgpu_gfx_off_ctrl_immediate(adev, enable);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -5301,9 +5301,9 @@ static int gfx_v9_0_set_clockgating_state(struct amdgpu_ip_block *ip_block,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_v9_0_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void gfx_v9_0_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
int data;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#include "amdgpu_gfx.h"
|
||||
#include "soc15.h"
|
||||
#include "soc15d.h"
|
||||
#include "amdgpu_atomfirmware.h"
|
||||
#include "amdgpu_pm.h"
|
||||
|
||||
#include "gc/gc_9_4_1_offset.h"
|
||||
|
|
|
|||
|
|
@ -891,10 +891,12 @@ static int gfx_v9_4_3_aca_bank_parser(struct aca_handle *handle,
|
|||
|
||||
switch (type) {
|
||||
case ACA_SMU_TYPE_UE:
|
||||
bank->aca_err_type = ACA_ERROR_TYPE_UE;
|
||||
ret = aca_error_cache_log_bank_error(handle, &info,
|
||||
ACA_ERROR_TYPE_UE, 1ULL);
|
||||
break;
|
||||
case ACA_SMU_TYPE_CE:
|
||||
bank->aca_err_type = ACA_ERROR_TYPE_CE;
|
||||
ret = aca_error_cache_log_bank_error(handle, &info,
|
||||
ACA_ERROR_TYPE_CE, ACA_REG__MISC0__ERRCNT(misc0));
|
||||
break;
|
||||
|
|
@ -942,21 +944,12 @@ static int gfx_v9_4_3_gpu_early_init(struct amdgpu_device *adev)
|
|||
adev->gfx.funcs = &gfx_v9_4_3_gfx_funcs;
|
||||
adev->gfx.ras = &gfx_v9_4_3_ras;
|
||||
|
||||
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
|
||||
case IP_VERSION(9, 4, 3):
|
||||
case IP_VERSION(9, 4, 4):
|
||||
case IP_VERSION(9, 5, 0):
|
||||
adev->gfx.config.max_hw_contexts = 8;
|
||||
adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
|
||||
adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
|
||||
adev->gfx.config.sc_hiz_tile_fifo_size = 0x30;
|
||||
adev->gfx.config.sc_earlyz_tile_fifo_size = 0x4C0;
|
||||
gb_addr_config = RREG32_SOC15(GC, GET_INST(GC, 0), regGB_ADDR_CONFIG);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
adev->gfx.config.max_hw_contexts = 8;
|
||||
adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
|
||||
adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
|
||||
adev->gfx.config.sc_hiz_tile_fifo_size = 0x30;
|
||||
adev->gfx.config.sc_earlyz_tile_fifo_size = 0x4C0;
|
||||
gb_addr_config = RREG32_SOC15(GC, GET_INST(GC, 0), regGB_ADDR_CONFIG);
|
||||
|
||||
adev->gfx.config.gb_addr_config = gb_addr_config;
|
||||
|
||||
|
|
@ -2795,22 +2788,16 @@ static int gfx_v9_4_3_set_clockgating_state(struct amdgpu_ip_block *ip_block,
|
|||
return 0;
|
||||
|
||||
num_xcc = NUM_XCC(adev->gfx.xcc_mask);
|
||||
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
|
||||
case IP_VERSION(9, 4, 3):
|
||||
case IP_VERSION(9, 4, 4):
|
||||
for (i = 0; i < num_xcc; i++)
|
||||
gfx_v9_4_3_xcc_update_gfx_clock_gating(
|
||||
adev, state == AMD_CG_STATE_GATE, i);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < num_xcc; i++)
|
||||
gfx_v9_4_3_xcc_update_gfx_clock_gating(
|
||||
adev, state == AMD_CG_STATE_GATE, i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_v9_4_3_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void gfx_v9_4_3_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
int data;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
|
|
@ -4867,34 +4854,13 @@ static void gfx_v9_4_3_set_rlc_funcs(struct amdgpu_device *adev)
|
|||
|
||||
static void gfx_v9_4_3_set_gds_init(struct amdgpu_device *adev)
|
||||
{
|
||||
/* init asci gds info */
|
||||
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
|
||||
case IP_VERSION(9, 4, 3):
|
||||
case IP_VERSION(9, 4, 4):
|
||||
case IP_VERSION(9, 5, 0):
|
||||
/* 9.4.3 removed all the GDS internal memory,
|
||||
* only support GWS opcode in kernel, like barrier
|
||||
* semaphore.etc */
|
||||
adev->gds.gds_size = 0;
|
||||
break;
|
||||
default:
|
||||
adev->gds.gds_size = 0x10000;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
|
||||
case IP_VERSION(9, 4, 3):
|
||||
case IP_VERSION(9, 4, 4):
|
||||
case IP_VERSION(9, 5, 0):
|
||||
/* deprecated for 9.4.3, no usage at all */
|
||||
adev->gds.gds_compute_max_wave_id = 0;
|
||||
break;
|
||||
default:
|
||||
/* this really depends on the chip */
|
||||
adev->gds.gds_compute_max_wave_id = 0x7ff;
|
||||
break;
|
||||
}
|
||||
/* 9.4.3 variants removed all the GDS internal memory,
|
||||
* only support GWS opcode in kernel, like barrier
|
||||
* semaphore.etc */
|
||||
|
||||
/* init asic gds info */
|
||||
adev->gds.gds_size = 0;
|
||||
adev->gds.gds_compute_max_wave_id = 0;
|
||||
adev->gds.gws_size = 64;
|
||||
adev->gds.oa_size = 16;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -313,6 +313,16 @@ gfxhub_v1_2_xcc_disable_identity_aperture(struct amdgpu_device *adev,
|
|||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
gfxhub_v1_2_per_process_xnack_support(struct amdgpu_device *adev)
|
||||
{
|
||||
/*
|
||||
* TODO: Check if this function is really needed, so far only 9.4.3
|
||||
* variants use GFXHUB 1.2
|
||||
*/
|
||||
return !!adev->aid_mask;
|
||||
}
|
||||
|
||||
static void gfxhub_v1_2_xcc_setup_vmid_config(struct amdgpu_device *adev,
|
||||
uint32_t xcc_mask)
|
||||
{
|
||||
|
|
@ -355,7 +365,7 @@ static void gfxhub_v1_2_xcc_setup_vmid_config(struct amdgpu_device *adev,
|
|||
PAGE_TABLE_BLOCK_SIZE,
|
||||
block_size);
|
||||
/* Send no-retry XNACK on fault to suppress VM fault storm.
|
||||
* On 9.4.2 and 9.4.3, XNACK can be enabled in
|
||||
* On 9.4.3 variants, XNACK can be enabled in
|
||||
* the SQ per-process.
|
||||
* Retry faults need to be enabled for that to work.
|
||||
*/
|
||||
|
|
@ -363,14 +373,8 @@ static void gfxhub_v1_2_xcc_setup_vmid_config(struct amdgpu_device *adev,
|
|||
tmp, VM_CONTEXT1_CNTL,
|
||||
RETRY_PERMISSION_OR_INVALID_PAGE_FAULT,
|
||||
!adev->gmc.noretry ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) ==
|
||||
IP_VERSION(9, 4, 2) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) ==
|
||||
IP_VERSION(9, 4, 3) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) ==
|
||||
IP_VERSION(9, 4, 4) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) ==
|
||||
IP_VERSION(9, 5, 0));
|
||||
gfxhub_v1_2_per_process_xnack_support(
|
||||
adev));
|
||||
WREG32_SOC15_OFFSET(GC, GET_INST(GC, j), regVM_CONTEXT1_CNTL,
|
||||
i * hub->ctx_distance, tmp);
|
||||
WREG32_SOC15_OFFSET(GC, GET_INST(GC, j),
|
||||
|
|
|
|||
|
|
@ -1115,9 +1115,9 @@ static int gmc_v10_0_set_clockgating_state(struct amdgpu_ip_block *ip_block,
|
|||
return athub_v2_0_set_clockgating(adev, state);
|
||||
}
|
||||
|
||||
static void gmc_v10_0_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void gmc_v10_0_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(10, 1, 3) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(10, 1, 4))
|
||||
|
|
|
|||
|
|
@ -579,6 +579,7 @@ static void gmc_v11_0_set_mmhub_funcs(struct amdgpu_device *adev)
|
|||
break;
|
||||
case IP_VERSION(3, 3, 0):
|
||||
case IP_VERSION(3, 3, 1):
|
||||
case IP_VERSION(3, 3, 2):
|
||||
adev->mmhub.funcs = &mmhub_v3_3_funcs;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -596,6 +597,7 @@ static void gmc_v11_0_set_gfxhub_funcs(struct amdgpu_device *adev)
|
|||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(11, 5, 3):
|
||||
adev->gfxhub.funcs = &gfxhub_v11_5_0_funcs;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -759,6 +761,7 @@ static int gmc_v11_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 1):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(11, 5, 3):
|
||||
set_bit(AMDGPU_GFXHUB(0), adev->vmhubs_mask);
|
||||
set_bit(AMDGPU_MMHUB0(0), adev->vmhubs_mask);
|
||||
/*
|
||||
|
|
@ -1009,9 +1012,9 @@ static int gmc_v11_0_set_clockgating_state(struct amdgpu_ip_block *ip_block,
|
|||
return athub_v3_0_set_clockgating(adev, state);
|
||||
}
|
||||
|
||||
static void gmc_v11_0_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void gmc_v11_0_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
|
||||
adev->mmhub.funcs->get_clockgating(adev, flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -1009,9 +1009,9 @@ static int gmc_v12_0_set_clockgating_state(struct amdgpu_ip_block *ip_block,
|
|||
return athub_v4_1_0_set_clockgating(adev, state);
|
||||
}
|
||||
|
||||
static void gmc_v12_0_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void gmc_v12_0_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
|
||||
adev->mmhub.funcs->get_clockgating(adev, flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -1686,9 +1686,9 @@ static int gmc_v8_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void gmc_v8_0_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void gmc_v8_0_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
int data;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
|
|
|
|||
|
|
@ -411,6 +411,11 @@ static const uint32_t ecc_umc_mcumc_ctrl_mask_addrs[] = {
|
|||
(0x001d43e0 + 0x00001800),
|
||||
};
|
||||
|
||||
static inline bool gmc_v9_0_is_multi_chiplet(struct amdgpu_device *adev)
|
||||
{
|
||||
return !!adev->aid_mask;
|
||||
}
|
||||
|
||||
static int gmc_v9_0_ecc_interrupt_state(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *src,
|
||||
unsigned int type,
|
||||
|
|
@ -647,9 +652,7 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
|
|||
addr, entry->client_id,
|
||||
soc15_ih_clientid_name[entry->client_id]);
|
||||
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 5, 0))
|
||||
if (gmc_v9_0_is_multi_chiplet(adev))
|
||||
dev_err(adev->dev, " cookie node_id %d fault from die %s%d%s\n",
|
||||
node_id, node_id % 4 == 3 ? "RSV" : "AID", node_id / 4,
|
||||
node_id % 4 == 1 ? ".XCD0" : node_id % 4 == 2 ? ".XCD1" : "");
|
||||
|
|
@ -798,9 +801,7 @@ static bool gmc_v9_0_use_invalidate_semaphore(struct amdgpu_device *adev,
|
|||
uint32_t vmhub)
|
||||
{
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 2) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 5, 0))
|
||||
gmc_v9_0_is_multi_chiplet(adev))
|
||||
return false;
|
||||
|
||||
return ((vmhub == AMDGPU_MMHUB0(0) ||
|
||||
|
|
@ -1278,9 +1279,8 @@ static void gmc_v9_0_override_vm_pte_flags(struct amdgpu_device *adev,
|
|||
/* Only GFX 9.4.3 APUs associate GPUs with NUMA nodes. Local system
|
||||
* memory can use more efficient MTYPEs.
|
||||
*/
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) != IP_VERSION(9, 4, 3) &&
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) != IP_VERSION(9, 4, 4) &&
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) != IP_VERSION(9, 5, 0))
|
||||
if (!(adev->flags & AMD_IS_APU) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) != IP_VERSION(9, 4, 3))
|
||||
return;
|
||||
|
||||
/* Only direct-mapped memory allows us to determine the NUMA node from
|
||||
|
|
@ -1498,13 +1498,13 @@ static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev)
|
|||
adev->umc.channel_idx_tbl = &umc_v6_7_channel_idx_tbl_second[0][0];
|
||||
break;
|
||||
case IP_VERSION(12, 0, 0):
|
||||
case IP_VERSION(12, 5, 0):
|
||||
adev->umc.max_ras_err_cnt_per_query =
|
||||
UMC_V12_0_TOTAL_CHANNEL_NUM(adev) * UMC_V12_0_BAD_PAGE_NUM_PER_CHANNEL;
|
||||
adev->umc.channel_inst_num = UMC_V12_0_CHANNEL_INSTANCE_NUM;
|
||||
adev->umc.umc_inst_num = UMC_V12_0_UMC_INSTANCE_NUM;
|
||||
adev->umc.node_inst_num /= UMC_V12_0_UMC_INSTANCE_NUM;
|
||||
adev->umc.channel_offs = UMC_V12_0_PER_CHANNEL_OFFSET;
|
||||
adev->umc.active_mask = adev->aid_mask;
|
||||
adev->umc.retire_unit = UMC_V12_0_BAD_PAGE_NUM_PER_CHANNEL;
|
||||
if (!adev->gmc.xgmi.connected_to_cpu && !adev->gmc.is_app_apu)
|
||||
adev->umc.ras = &umc_v12_0_ras;
|
||||
|
|
@ -1524,6 +1524,7 @@ static void gmc_v9_0_set_mmhub_funcs(struct amdgpu_device *adev)
|
|||
adev->mmhub.funcs = &mmhub_v1_7_funcs;
|
||||
break;
|
||||
case IP_VERSION(1, 8, 0):
|
||||
case IP_VERSION(1, 8, 1):
|
||||
adev->mmhub.funcs = &mmhub_v1_8_funcs;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1556,9 +1557,7 @@ static void gmc_v9_0_set_mmhub_ras_funcs(struct amdgpu_device *adev)
|
|||
|
||||
static void gmc_v9_0_set_gfxhub_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 5, 0))
|
||||
if (gmc_v9_0_is_multi_chiplet(adev))
|
||||
adev->gfxhub.funcs = &gfxhub_v1_2_funcs;
|
||||
else
|
||||
adev->gfxhub.funcs = &gfxhub_v1_0_funcs;
|
||||
|
|
@ -1595,23 +1594,39 @@ static void gmc_v9_0_set_xgmi_ras_funcs(struct amdgpu_device *adev)
|
|||
|
||||
static void gmc_v9_0_init_nps_details(struct amdgpu_device *adev)
|
||||
{
|
||||
enum amdgpu_memory_partition mode;
|
||||
uint32_t supp_modes;
|
||||
int i;
|
||||
|
||||
adev->gmc.supported_nps_modes = 0;
|
||||
|
||||
if (amdgpu_sriov_vf(adev) || (adev->flags & AMD_IS_APU))
|
||||
return;
|
||||
|
||||
/*TODO: Check PSP version also which supports NPS switch. Otherwise keep
|
||||
mode = gmc_v9_0_get_memory_partition(adev, &supp_modes);
|
||||
|
||||
/* Mode detected by hardware and supported modes available */
|
||||
if ((mode != UNKNOWN_MEMORY_PARTITION_MODE) && supp_modes) {
|
||||
for (i = AMDGPU_NPS1_PARTITION_MODE;
|
||||
supp_modes && i <= AMDGPU_NPS8_PARTITION_MODE; i++) {
|
||||
if (supp_modes & BIT(i - 1))
|
||||
adev->gmc.supported_nps_modes |= BIT(i);
|
||||
supp_modes &= supp_modes - 1;
|
||||
}
|
||||
} else {
|
||||
/*TODO: Check PSP version also which supports NPS switch. Otherwise keep
|
||||
* supported modes as 0.
|
||||
*/
|
||||
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
|
||||
case IP_VERSION(9, 4, 3):
|
||||
case IP_VERSION(9, 4, 4):
|
||||
adev->gmc.supported_nps_modes =
|
||||
BIT(AMDGPU_NPS1_PARTITION_MODE) |
|
||||
BIT(AMDGPU_NPS4_PARTITION_MODE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
|
||||
case IP_VERSION(9, 4, 3):
|
||||
case IP_VERSION(9, 4, 4):
|
||||
adev->gmc.supported_nps_modes =
|
||||
BIT(AMDGPU_NPS1_PARTITION_MODE) |
|
||||
BIT(AMDGPU_NPS4_PARTITION_MODE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1625,9 +1640,7 @@ static int gmc_v9_0_early_init(struct amdgpu_ip_block *ip_block)
|
|||
*/
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 0) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 1) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 5, 0))
|
||||
gmc_v9_0_is_multi_chiplet(adev))
|
||||
adev->gmc.xgmi.supported = true;
|
||||
|
||||
if (amdgpu_ip_version(adev, XGMI_HWIP, 0) == IP_VERSION(6, 1, 0)) {
|
||||
|
|
@ -1636,8 +1649,7 @@ static int gmc_v9_0_early_init(struct amdgpu_ip_block *ip_block)
|
|||
adev->smuio.funcs->is_host_gpu_xgmi_supported(adev);
|
||||
}
|
||||
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4)) {
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3)) {
|
||||
enum amdgpu_pkg_type pkg_type =
|
||||
adev->smuio.funcs->get_pkg_type(adev);
|
||||
/* On GFXIP 9.4.3. APU, there is no physical VRAM domain present
|
||||
|
|
@ -2078,9 +2090,7 @@ static int gmc_v9_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
|
||||
spin_lock_init(&adev->gmc.invalidate_lock);
|
||||
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 5, 0)) {
|
||||
if (gmc_v9_0_is_multi_chiplet(adev)) {
|
||||
gmc_v9_4_3_init_vram_info(adev);
|
||||
} else if (!adev->bios) {
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
|
|
@ -2230,9 +2240,7 @@ static int gmc_v9_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
|
||||
amdgpu_gmc_get_vbios_allocations(adev);
|
||||
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 5, 0)) {
|
||||
if (gmc_v9_0_is_multi_chiplet(adev)) {
|
||||
r = gmc_v9_0_init_mem_ranges(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
|
@ -2261,9 +2269,7 @@ static int gmc_v9_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
adev->vm_manager.first_kfd_vmid =
|
||||
(amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 1) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 2) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 5, 0)) ?
|
||||
gmc_v9_0_is_multi_chiplet(adev)) ?
|
||||
3 :
|
||||
8;
|
||||
|
||||
|
|
@ -2275,9 +2281,7 @@ static int gmc_v9_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 5, 0))
|
||||
if (gmc_v9_0_is_multi_chiplet(adev))
|
||||
amdgpu_gmc_sysfs_init(adev);
|
||||
|
||||
return 0;
|
||||
|
|
@ -2287,9 +2291,7 @@ static int gmc_v9_0_sw_fini(struct amdgpu_ip_block *ip_block)
|
|||
{
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 5, 0))
|
||||
if (gmc_v9_0_is_multi_chiplet(adev))
|
||||
amdgpu_gmc_sysfs_fini(adev);
|
||||
|
||||
amdgpu_gmc_ras_fini(adev);
|
||||
|
|
@ -2571,9 +2573,9 @@ static int gmc_v9_0_set_clockgating_state(struct amdgpu_ip_block *ip_block,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void gmc_v9_0_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void gmc_v9_0_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
|
||||
adev->mmhub.funcs->get_clockgating(adev, flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "hdp_v4_0.h"
|
||||
#include "amdgpu_ras.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "hdp_v5_0.h"
|
||||
|
||||
#include "hdp/hdp_5_0_0_offset.h"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "hdp_v5_2.h"
|
||||
|
||||
#include "hdp/hdp_5_2_1_offset.h"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "hdp_v6_0.h"
|
||||
|
||||
#include "hdp/hdp_6_0_0_offset.h"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "hdp_v7_0.h"
|
||||
|
||||
#include "hdp/hdp_7_0_0_offset.h"
|
||||
|
|
|
|||
|
|
@ -768,9 +768,9 @@ static int ih_v6_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ih_v6_0_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void ih_v6_0_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
|
||||
if (!RREG32_SOC15(OSSSYS, 0, regIH_CLK_CTRL))
|
||||
*flags |= AMD_CG_SUPPORT_IH_CG;
|
||||
|
|
|
|||
|
|
@ -749,9 +749,9 @@ static int ih_v6_1_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ih_v6_1_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void ih_v6_1_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
|
||||
if (!RREG32_SOC15(OSSSYS, 0, regIH_CLK_CTRL))
|
||||
*flags |= AMD_CG_SUPPORT_IH_CG;
|
||||
|
|
|
|||
|
|
@ -739,9 +739,9 @@ static int ih_v7_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ih_v7_0_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void ih_v7_0_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
|
||||
if (!RREG32_SOC15(OSSSYS, 0, regIH_CLK_CTRL))
|
||||
*flags |= AMD_CG_SUPPORT_IH_CG;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_4_imu.bin");
|
|||
MODULE_FIRMWARE("amdgpu/gc_11_5_0_imu.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_1_imu.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_2_imu.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_3_imu.bin");
|
||||
|
||||
static int imu_v11_0_init_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,6 +33,22 @@
|
|||
#include "vcn/vcn_2_0_0_sh_mask.h"
|
||||
#include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
|
||||
|
||||
static const struct amdgpu_hwip_reg_entry jpeg_reg_list_2_0[] = {
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JPEG_POWER_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JPEG_INT_STAT),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JRBC_RB_CNTL),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JRBC_RB_SIZE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmJPEG_DEC_ADDR_MODE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmJPEG_DEC_GFX10_ADDR_CONFIG),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmJPEG_DEC_Y_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmJPEG_DEC_UV_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JPEG_PITCH),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JPEG_UV_PITCH),
|
||||
};
|
||||
|
||||
static void jpeg_v2_0_set_dec_ring_funcs(struct amdgpu_device *adev);
|
||||
static void jpeg_v2_0_set_irq_funcs(struct amdgpu_device *adev);
|
||||
static int jpeg_v2_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
||||
|
|
@ -98,7 +114,14 @@ static int jpeg_v2_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
adev->jpeg.internal.jpeg_pitch[0] = mmUVD_JPEG_PITCH_INTERNAL_OFFSET;
|
||||
adev->jpeg.inst->external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH);
|
||||
|
||||
return 0;
|
||||
r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_2_0, ARRAY_SIZE(jpeg_reg_list_2_0));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
|
||||
r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -117,6 +140,8 @@ static int jpeg_v2_0_sw_fini(struct amdgpu_ip_block *ip_block)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
amdgpu_jpeg_sysfs_reset_mask_fini(adev);
|
||||
|
||||
r = amdgpu_jpeg_sw_fini(adev);
|
||||
|
||||
return r;
|
||||
|
|
@ -739,6 +764,13 @@ static int jpeg_v2_0_process_interrupt(struct amdgpu_device *adev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int jpeg_v2_0_ring_reset(struct amdgpu_ring *ring, unsigned int vmid)
|
||||
{
|
||||
jpeg_v2_0_stop(ring->adev);
|
||||
jpeg_v2_0_start(ring->adev);
|
||||
return amdgpu_ring_test_helper(ring);
|
||||
}
|
||||
|
||||
static const struct amd_ip_funcs jpeg_v2_0_ip_funcs = {
|
||||
.name = "jpeg_v2_0",
|
||||
.early_init = jpeg_v2_0_early_init,
|
||||
|
|
@ -752,6 +784,8 @@ static const struct amd_ip_funcs jpeg_v2_0_ip_funcs = {
|
|||
.wait_for_idle = jpeg_v2_0_wait_for_idle,
|
||||
.set_clockgating_state = jpeg_v2_0_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v2_0_set_powergating_state,
|
||||
.dump_ip_state = amdgpu_jpeg_dump_ip_state,
|
||||
.print_ip_state = amdgpu_jpeg_print_ip_state,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v2_0_dec_ring_vm_funcs = {
|
||||
|
|
@ -782,6 +816,7 @@ static const struct amdgpu_ring_funcs jpeg_v2_0_dec_ring_vm_funcs = {
|
|||
.emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
|
||||
.emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
|
||||
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
|
||||
.reset = jpeg_v2_0_ring_reset,
|
||||
};
|
||||
|
||||
static void jpeg_v2_0_set_dec_ring_funcs(struct amdgpu_device *adev)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,22 @@
|
|||
|
||||
#define JPEG25_MAX_HW_INSTANCES_ARCTURUS 2
|
||||
|
||||
static const struct amdgpu_hwip_reg_entry jpeg_reg_list_2_5[] = {
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JPEG_POWER_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JPEG_INT_STAT),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JRBC_RB_CNTL),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JRBC_RB_SIZE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmJPEG_DEC_ADDR_MODE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmJPEG_DEC_GFX10_ADDR_CONFIG),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmJPEG_DEC_Y_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmJPEG_DEC_UV_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JPEG_PITCH),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JPEG_UV_PITCH),
|
||||
};
|
||||
|
||||
static void jpeg_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev);
|
||||
static void jpeg_v2_5_set_irq_funcs(struct amdgpu_device *adev);
|
||||
static int jpeg_v2_5_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
||||
|
|
@ -147,7 +163,14 @@ static int jpeg_v2_5_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_2_5, ARRAY_SIZE(jpeg_reg_list_2_5));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
|
||||
r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -166,6 +189,8 @@ static int jpeg_v2_5_sw_fini(struct amdgpu_ip_block *ip_block)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
amdgpu_jpeg_sysfs_reset_mask_fini(adev);
|
||||
|
||||
r = amdgpu_jpeg_sw_fini(adev);
|
||||
|
||||
return r;
|
||||
|
|
@ -310,6 +335,44 @@ static void jpeg_v2_5_enable_clock_gating(struct amdgpu_device *adev, int inst)
|
|||
WREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE, data);
|
||||
}
|
||||
|
||||
static void jpeg_v2_5_start_inst(struct amdgpu_device *adev, int i)
|
||||
{
|
||||
struct amdgpu_ring *ring = adev->jpeg.inst[i].ring_dec;
|
||||
/* disable anti hang mechanism */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_POWER_STATUS), 0,
|
||||
~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
|
||||
|
||||
/* JPEG disable CGC */
|
||||
jpeg_v2_5_disable_clock_gating(adev, i);
|
||||
|
||||
/* MJPEG global tiling registers */
|
||||
WREG32_SOC15(JPEG, i, mmJPEG_DEC_GFX8_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
WREG32_SOC15(JPEG, i, mmJPEG_DEC_GFX10_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
|
||||
/* enable JMI channel */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JMI_CNTL), 0,
|
||||
~UVD_JMI_CNTL__SOFT_RESET_MASK);
|
||||
|
||||
/* enable System Interrupt for JRBC */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmJPEG_SYS_INT_EN),
|
||||
JPEG_SYS_INT_EN__DJRBC_MASK,
|
||||
~JPEG_SYS_INT_EN__DJRBC_MASK);
|
||||
|
||||
WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_VMID, 0);
|
||||
WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
|
||||
WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
|
||||
lower_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
|
||||
upper_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_RPTR, 0);
|
||||
WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_WPTR, 0);
|
||||
WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_CNTL, 0x00000002L);
|
||||
WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_SIZE, ring->ring_size / 4);
|
||||
ring->wptr = RREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_WPTR);
|
||||
}
|
||||
|
||||
/**
|
||||
* jpeg_v2_5_start - start JPEG block
|
||||
*
|
||||
|
|
@ -319,52 +382,33 @@ static void jpeg_v2_5_enable_clock_gating(struct amdgpu_device *adev, int inst)
|
|||
*/
|
||||
static int jpeg_v2_5_start(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *ring;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
if (adev->jpeg.harvest_config & (1 << i))
|
||||
continue;
|
||||
jpeg_v2_5_start_inst(adev, i);
|
||||
|
||||
ring = adev->jpeg.inst[i].ring_dec;
|
||||
/* disable anti hang mechanism */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_POWER_STATUS), 0,
|
||||
~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
|
||||
|
||||
/* JPEG disable CGC */
|
||||
jpeg_v2_5_disable_clock_gating(adev, i);
|
||||
|
||||
/* MJPEG global tiling registers */
|
||||
WREG32_SOC15(JPEG, i, mmJPEG_DEC_GFX8_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
WREG32_SOC15(JPEG, i, mmJPEG_DEC_GFX10_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
|
||||
/* enable JMI channel */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JMI_CNTL), 0,
|
||||
~UVD_JMI_CNTL__SOFT_RESET_MASK);
|
||||
|
||||
/* enable System Interrupt for JRBC */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmJPEG_SYS_INT_EN),
|
||||
JPEG_SYS_INT_EN__DJRBC_MASK,
|
||||
~JPEG_SYS_INT_EN__DJRBC_MASK);
|
||||
|
||||
WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_VMID, 0);
|
||||
WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
|
||||
WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
|
||||
lower_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
|
||||
upper_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_RPTR, 0);
|
||||
WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_WPTR, 0);
|
||||
WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_CNTL, 0x00000002L);
|
||||
WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_SIZE, ring->ring_size / 4);
|
||||
ring->wptr = RREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_WPTR);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void jpeg_v2_5_stop_inst(struct amdgpu_device *adev, int i)
|
||||
{
|
||||
/* reset JMI */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JMI_CNTL),
|
||||
UVD_JMI_CNTL__SOFT_RESET_MASK,
|
||||
~UVD_JMI_CNTL__SOFT_RESET_MASK);
|
||||
|
||||
jpeg_v2_5_enable_clock_gating(adev, i);
|
||||
|
||||
/* enable anti hang mechanism */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_POWER_STATUS),
|
||||
UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
|
||||
~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* jpeg_v2_5_stop - stop JPEG block
|
||||
*
|
||||
|
|
@ -379,18 +423,7 @@ static int jpeg_v2_5_stop(struct amdgpu_device *adev)
|
|||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
if (adev->jpeg.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
/* reset JMI */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JMI_CNTL),
|
||||
UVD_JMI_CNTL__SOFT_RESET_MASK,
|
||||
~UVD_JMI_CNTL__SOFT_RESET_MASK);
|
||||
|
||||
jpeg_v2_5_enable_clock_gating(adev, i);
|
||||
|
||||
/* enable anti hang mechanism */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_POWER_STATUS),
|
||||
UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
|
||||
~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
|
||||
jpeg_v2_5_stop_inst(adev, i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -610,6 +643,13 @@ static int jpeg_v2_5_process_interrupt(struct amdgpu_device *adev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int jpeg_v2_5_ring_reset(struct amdgpu_ring *ring, unsigned int vmid)
|
||||
{
|
||||
jpeg_v2_5_stop_inst(ring->adev, ring->me);
|
||||
jpeg_v2_5_start_inst(ring->adev, ring->me);
|
||||
return amdgpu_ring_test_helper(ring);
|
||||
}
|
||||
|
||||
static const struct amd_ip_funcs jpeg_v2_5_ip_funcs = {
|
||||
.name = "jpeg_v2_5",
|
||||
.early_init = jpeg_v2_5_early_init,
|
||||
|
|
@ -623,6 +663,8 @@ static const struct amd_ip_funcs jpeg_v2_5_ip_funcs = {
|
|||
.wait_for_idle = jpeg_v2_5_wait_for_idle,
|
||||
.set_clockgating_state = jpeg_v2_5_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v2_5_set_powergating_state,
|
||||
.dump_ip_state = amdgpu_jpeg_dump_ip_state,
|
||||
.print_ip_state = amdgpu_jpeg_print_ip_state,
|
||||
};
|
||||
|
||||
static const struct amd_ip_funcs jpeg_v2_6_ip_funcs = {
|
||||
|
|
@ -638,6 +680,8 @@ static const struct amd_ip_funcs jpeg_v2_6_ip_funcs = {
|
|||
.wait_for_idle = jpeg_v2_5_wait_for_idle,
|
||||
.set_clockgating_state = jpeg_v2_5_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v2_5_set_powergating_state,
|
||||
.dump_ip_state = amdgpu_jpeg_dump_ip_state,
|
||||
.print_ip_state = amdgpu_jpeg_print_ip_state,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v2_5_dec_ring_vm_funcs = {
|
||||
|
|
@ -668,6 +712,7 @@ static const struct amdgpu_ring_funcs jpeg_v2_5_dec_ring_vm_funcs = {
|
|||
.emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
|
||||
.emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
|
||||
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
|
||||
.reset = jpeg_v2_5_ring_reset,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v2_6_dec_ring_vm_funcs = {
|
||||
|
|
@ -698,6 +743,7 @@ static const struct amdgpu_ring_funcs jpeg_v2_6_dec_ring_vm_funcs = {
|
|||
.emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
|
||||
.emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
|
||||
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
|
||||
.reset = jpeg_v2_5_ring_reset,
|
||||
};
|
||||
|
||||
static void jpeg_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,22 @@
|
|||
|
||||
#define mmUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f
|
||||
|
||||
static const struct amdgpu_hwip_reg_entry jpeg_reg_list_3_0[] = {
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JPEG_POWER_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JPEG_INT_STAT),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JRBC_RB_CNTL),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JRBC_RB_SIZE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmJPEG_DEC_ADDR_MODE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmJPEG_DEC_GFX10_ADDR_CONFIG),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmJPEG_DEC_Y_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmJPEG_DEC_UV_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JPEG_PITCH),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, mmUVD_JPEG_UV_PITCH),
|
||||
};
|
||||
|
||||
static void jpeg_v3_0_set_dec_ring_funcs(struct amdgpu_device *adev);
|
||||
static void jpeg_v3_0_set_irq_funcs(struct amdgpu_device *adev);
|
||||
static int jpeg_v3_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
||||
|
|
@ -112,7 +128,14 @@ static int jpeg_v3_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
adev->jpeg.internal.jpeg_pitch[0] = mmUVD_JPEG_PITCH_INTERNAL_OFFSET;
|
||||
adev->jpeg.inst->external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH);
|
||||
|
||||
return 0;
|
||||
r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_3_0, ARRAY_SIZE(jpeg_reg_list_3_0));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
|
||||
r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -131,6 +154,8 @@ static int jpeg_v3_0_sw_fini(struct amdgpu_ip_block *ip_block)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
amdgpu_jpeg_sysfs_reset_mask_fini(adev);
|
||||
|
||||
r = amdgpu_jpeg_sw_fini(adev);
|
||||
|
||||
return r;
|
||||
|
|
@ -530,6 +555,13 @@ static int jpeg_v3_0_process_interrupt(struct amdgpu_device *adev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int jpeg_v3_0_ring_reset(struct amdgpu_ring *ring, unsigned int vmid)
|
||||
{
|
||||
jpeg_v3_0_stop(ring->adev);
|
||||
jpeg_v3_0_start(ring->adev);
|
||||
return amdgpu_ring_test_helper(ring);
|
||||
}
|
||||
|
||||
static const struct amd_ip_funcs jpeg_v3_0_ip_funcs = {
|
||||
.name = "jpeg_v3_0",
|
||||
.early_init = jpeg_v3_0_early_init,
|
||||
|
|
@ -543,6 +575,8 @@ static const struct amd_ip_funcs jpeg_v3_0_ip_funcs = {
|
|||
.wait_for_idle = jpeg_v3_0_wait_for_idle,
|
||||
.set_clockgating_state = jpeg_v3_0_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v3_0_set_powergating_state,
|
||||
.dump_ip_state = amdgpu_jpeg_dump_ip_state,
|
||||
.print_ip_state = amdgpu_jpeg_print_ip_state,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v3_0_dec_ring_vm_funcs = {
|
||||
|
|
@ -573,6 +607,7 @@ static const struct amdgpu_ring_funcs jpeg_v3_0_dec_ring_vm_funcs = {
|
|||
.emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
|
||||
.emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
|
||||
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
|
||||
.reset = jpeg_v3_0_ring_reset,
|
||||
};
|
||||
|
||||
static void jpeg_v3_0_set_dec_ring_funcs(struct amdgpu_device *adev)
|
||||
|
|
|
|||
|
|
@ -36,13 +36,28 @@
|
|||
|
||||
#define regUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f
|
||||
|
||||
static const struct amdgpu_hwip_reg_entry jpeg_reg_list_4_0[] = {
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_POWER_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_INT_STAT),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_CNTL),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_SIZE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_ADDR_MODE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_Y_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_UV_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_PITCH),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_UV_PITCH),
|
||||
};
|
||||
|
||||
static int jpeg_v4_0_start_sriov(struct amdgpu_device *adev);
|
||||
static void jpeg_v4_0_set_dec_ring_funcs(struct amdgpu_device *adev);
|
||||
static void jpeg_v4_0_set_irq_funcs(struct amdgpu_device *adev);
|
||||
static int jpeg_v4_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
||||
enum amd_powergating_state state);
|
||||
static void jpeg_v4_0_set_ras_funcs(struct amdgpu_device *adev);
|
||||
|
||||
static void jpeg_v4_0_dec_ring_set_wptr(struct amdgpu_ring *ring);
|
||||
|
||||
/**
|
||||
|
|
@ -123,14 +138,15 @@ static int jpeg_v4_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
r = amdgpu_jpeg_ras_sw_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
/* TODO: Add queue reset mask when FW fully supports it */
|
||||
adev->jpeg.supported_reset =
|
||||
amdgpu_get_soft_full_reset_mask(&adev->jpeg.inst[0].ring_dec[0]);
|
||||
r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
|
||||
|
||||
r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_4_0, ARRAY_SIZE(jpeg_reg_list_4_0));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
|
||||
r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -704,6 +720,16 @@ static int jpeg_v4_0_process_interrupt(struct amdgpu_device *adev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int jpeg_v4_0_ring_reset(struct amdgpu_ring *ring, unsigned int vmid)
|
||||
{
|
||||
if (amdgpu_sriov_vf(ring->adev))
|
||||
return -EINVAL;
|
||||
|
||||
jpeg_v4_0_stop(ring->adev);
|
||||
jpeg_v4_0_start(ring->adev);
|
||||
return amdgpu_ring_test_helper(ring);
|
||||
}
|
||||
|
||||
static const struct amd_ip_funcs jpeg_v4_0_ip_funcs = {
|
||||
.name = "jpeg_v4_0",
|
||||
.early_init = jpeg_v4_0_early_init,
|
||||
|
|
@ -717,6 +743,8 @@ static const struct amd_ip_funcs jpeg_v4_0_ip_funcs = {
|
|||
.wait_for_idle = jpeg_v4_0_wait_for_idle,
|
||||
.set_clockgating_state = jpeg_v4_0_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v4_0_set_powergating_state,
|
||||
.dump_ip_state = amdgpu_jpeg_dump_ip_state,
|
||||
.print_ip_state = amdgpu_jpeg_print_ip_state,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v4_0_dec_ring_vm_funcs = {
|
||||
|
|
@ -747,6 +775,7 @@ static const struct amdgpu_ring_funcs jpeg_v4_0_dec_ring_vm_funcs = {
|
|||
.emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
|
||||
.emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
|
||||
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
|
||||
.reset = jpeg_v4_0_ring_reset,
|
||||
};
|
||||
|
||||
static void jpeg_v4_0_set_dec_ring_funcs(struct amdgpu_device *adev)
|
||||
|
|
|
|||
|
|
@ -59,10 +59,53 @@ static int amdgpu_ih_srcid_jpeg[] = {
|
|||
VCN_4_0__SRCID__JPEG7_DECODE
|
||||
};
|
||||
|
||||
static const struct amdgpu_hwip_reg_entry jpeg_reg_list_4_0_3[] = {
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_POWER_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_INT_STAT),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_SYS_INT_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_ADDR_MODE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_Y_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_UV_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_PITCH),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_UV_PITCH),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_STATUS),
|
||||
};
|
||||
|
||||
static inline bool jpeg_v4_0_3_normalizn_reqd(struct amdgpu_device *adev)
|
||||
{
|
||||
return amdgpu_sriov_vf(adev) ||
|
||||
(amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4));
|
||||
return (adev->jpeg.caps & AMDGPU_JPEG_CAPS(RRMT_ENABLED)) == 0;
|
||||
}
|
||||
|
||||
static inline int jpeg_v4_0_3_core_reg_offset(u32 pipe)
|
||||
{
|
||||
if (pipe)
|
||||
return ((0x40 * pipe) - 0xc80);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -144,10 +187,8 @@ static int jpeg_v4_0_3_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
adev->jpeg.internal.jpeg_pitch[j] =
|
||||
regUVD_JRBC0_UVD_JRBC_SCRATCH0_INTERNAL_OFFSET;
|
||||
adev->jpeg.inst[i].external.jpeg_pitch[j] =
|
||||
SOC15_REG_OFFSET1(
|
||||
JPEG, jpeg_inst,
|
||||
regUVD_JRBC0_UVD_JRBC_SCRATCH0,
|
||||
(j ? (0x40 * j - 0xc80) : 0));
|
||||
SOC15_REG_OFFSET1(JPEG, jpeg_inst, regUVD_JRBC0_UVD_JRBC_SCRATCH0,
|
||||
jpeg_v4_0_3_core_reg_offset(j));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,13 +200,17 @@ static int jpeg_v4_0_3_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
}
|
||||
}
|
||||
|
||||
/* TODO: Add queue reset mask when FW fully supports it */
|
||||
adev->jpeg.supported_reset =
|
||||
amdgpu_get_soft_full_reset_mask(&adev->jpeg.inst[0].ring_dec[0]);
|
||||
r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
|
||||
r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_4_0_3, ARRAY_SIZE(jpeg_reg_list_4_0_3));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
|
||||
r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -185,7 +230,9 @@ static int jpeg_v4_0_3_sw_fini(struct amdgpu_ip_block *ip_block)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
amdgpu_jpeg_sysfs_reset_mask_fini(adev);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
amdgpu_jpeg_sysfs_reset_mask_fini(adev);
|
||||
|
||||
r = amdgpu_jpeg_sw_fini(adev);
|
||||
|
||||
return r;
|
||||
|
|
@ -331,6 +378,11 @@ static int jpeg_v4_0_3_hw_init(struct amdgpu_ip_block *ip_block)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
/* This flag is not set for VF, assumed to be disabled always */
|
||||
if (RREG32_SOC15(VCN, GET_INST(VCN, 0), regVCN_RRMT_CNTL) &
|
||||
0x100)
|
||||
adev->jpeg.caps |= AMDGPU_JPEG_CAPS(RRMT_ENABLED);
|
||||
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
jpeg_inst = GET_INST(JPEG, i);
|
||||
|
||||
|
|
@ -475,6 +527,75 @@ static void jpeg_v4_0_3_enable_clock_gating(struct amdgpu_device *adev, int inst
|
|||
WREG32_SOC15(JPEG, jpeg_inst, regJPEG_CGC_GATE, data);
|
||||
}
|
||||
|
||||
static void jpeg_v4_0_3_start_inst(struct amdgpu_device *adev, int inst)
|
||||
{
|
||||
int jpeg_inst = GET_INST(JPEG, inst);
|
||||
|
||||
WREG32_SOC15(JPEG, jpeg_inst, regUVD_PGFSM_CONFIG,
|
||||
1 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT);
|
||||
SOC15_WAIT_ON_RREG(JPEG, jpeg_inst, regUVD_PGFSM_STATUS,
|
||||
UVD_PGFSM_STATUS__UVDJ_PWR_ON <<
|
||||
UVD_PGFSM_STATUS__UVDJ_PWR_STATUS__SHIFT,
|
||||
UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK);
|
||||
|
||||
/* disable anti hang mechanism */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS),
|
||||
0, ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
|
||||
|
||||
/* JPEG disable CGC */
|
||||
jpeg_v4_0_3_disable_clock_gating(adev, inst);
|
||||
|
||||
/* MJPEG global tiling registers */
|
||||
WREG32_SOC15(JPEG, jpeg_inst, regJPEG_DEC_GFX8_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
WREG32_SOC15(JPEG, jpeg_inst, regJPEG_DEC_GFX10_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
|
||||
/* enable JMI channel */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL), 0,
|
||||
~UVD_JMI_CNTL__SOFT_RESET_MASK);
|
||||
}
|
||||
|
||||
static void jpeg_v4_0_3_start_jrbc(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
int jpeg_inst = GET_INST(JPEG, ring->me);
|
||||
int reg_offset = jpeg_v4_0_3_core_reg_offset(ring->pipe);
|
||||
|
||||
/* enable System Interrupt for JRBC */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regJPEG_SYS_INT_EN),
|
||||
JPEG_SYS_INT_EN__DJRBC0_MASK << ring->pipe,
|
||||
~(JPEG_SYS_INT_EN__DJRBC0_MASK << ring->pipe));
|
||||
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JMI0_UVD_LMI_JRBC_RB_VMID,
|
||||
reg_offset, 0);
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JRBC0_UVD_JRBC_RB_CNTL,
|
||||
reg_offset,
|
||||
(0x00000001L | 0x00000002L));
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JMI0_UVD_LMI_JRBC_RB_64BIT_BAR_LOW,
|
||||
reg_offset, lower_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JMI0_UVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
|
||||
reg_offset, upper_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JRBC0_UVD_JRBC_RB_RPTR,
|
||||
reg_offset, 0);
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JRBC0_UVD_JRBC_RB_WPTR,
|
||||
reg_offset, 0);
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JRBC0_UVD_JRBC_RB_CNTL,
|
||||
reg_offset, 0x00000002L);
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JRBC0_UVD_JRBC_RB_SIZE,
|
||||
reg_offset, ring->ring_size / 4);
|
||||
ring->wptr = RREG32_SOC15_OFFSET(JPEG, jpeg_inst, regUVD_JRBC0_UVD_JRBC_RB_WPTR,
|
||||
reg_offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* jpeg_v4_0_3_start - start JPEG block
|
||||
*
|
||||
|
|
@ -485,84 +606,42 @@ static void jpeg_v4_0_3_enable_clock_gating(struct amdgpu_device *adev, int inst
|
|||
static int jpeg_v4_0_3_start(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *ring;
|
||||
int i, j, jpeg_inst;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
jpeg_inst = GET_INST(JPEG, i);
|
||||
|
||||
WREG32_SOC15(JPEG, jpeg_inst, regUVD_PGFSM_CONFIG,
|
||||
1 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT);
|
||||
SOC15_WAIT_ON_RREG(
|
||||
JPEG, jpeg_inst, regUVD_PGFSM_STATUS,
|
||||
UVD_PGFSM_STATUS__UVDJ_PWR_ON
|
||||
<< UVD_PGFSM_STATUS__UVDJ_PWR_STATUS__SHIFT,
|
||||
UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK);
|
||||
|
||||
/* disable anti hang mechanism */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JPEG_POWER_STATUS),
|
||||
0, ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
|
||||
|
||||
/* JPEG disable CGC */
|
||||
jpeg_v4_0_3_disable_clock_gating(adev, i);
|
||||
|
||||
/* MJPEG global tiling registers */
|
||||
WREG32_SOC15(JPEG, jpeg_inst, regJPEG_DEC_GFX8_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
WREG32_SOC15(JPEG, jpeg_inst, regJPEG_DEC_GFX10_ADDR_CONFIG,
|
||||
adev->gfx.config.gb_addr_config);
|
||||
|
||||
/* enable JMI channel */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL), 0,
|
||||
~UVD_JMI_CNTL__SOFT_RESET_MASK);
|
||||
|
||||
jpeg_v4_0_3_start_inst(adev, i);
|
||||
for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
|
||||
unsigned int reg_offset = (j?(0x40 * j - 0xc80):0);
|
||||
|
||||
ring = &adev->jpeg.inst[i].ring_dec[j];
|
||||
|
||||
/* enable System Interrupt for JRBC */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst,
|
||||
regJPEG_SYS_INT_EN),
|
||||
JPEG_SYS_INT_EN__DJRBC0_MASK << j,
|
||||
~(JPEG_SYS_INT_EN__DJRBC0_MASK << j));
|
||||
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JMI0_UVD_LMI_JRBC_RB_VMID,
|
||||
reg_offset, 0);
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JRBC0_UVD_JRBC_RB_CNTL,
|
||||
reg_offset,
|
||||
(0x00000001L | 0x00000002L));
|
||||
WREG32_SOC15_OFFSET(
|
||||
JPEG, jpeg_inst,
|
||||
regUVD_JMI0_UVD_LMI_JRBC_RB_64BIT_BAR_LOW,
|
||||
reg_offset, lower_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15_OFFSET(
|
||||
JPEG, jpeg_inst,
|
||||
regUVD_JMI0_UVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
|
||||
reg_offset, upper_32_bits(ring->gpu_addr));
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JRBC0_UVD_JRBC_RB_RPTR,
|
||||
reg_offset, 0);
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JRBC0_UVD_JRBC_RB_WPTR,
|
||||
reg_offset, 0);
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JRBC0_UVD_JRBC_RB_CNTL,
|
||||
reg_offset, 0x00000002L);
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JRBC0_UVD_JRBC_RB_SIZE,
|
||||
reg_offset, ring->ring_size / 4);
|
||||
ring->wptr = RREG32_SOC15_OFFSET(
|
||||
JPEG, jpeg_inst, regUVD_JRBC0_UVD_JRBC_RB_WPTR,
|
||||
reg_offset);
|
||||
jpeg_v4_0_3_start_jrbc(ring);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void jpeg_v4_0_3_stop_inst(struct amdgpu_device *adev, int inst)
|
||||
{
|
||||
int jpeg_inst = GET_INST(JPEG, inst);
|
||||
/* reset JMI */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL),
|
||||
UVD_JMI_CNTL__SOFT_RESET_MASK,
|
||||
~UVD_JMI_CNTL__SOFT_RESET_MASK);
|
||||
|
||||
jpeg_v4_0_3_enable_clock_gating(adev, inst);
|
||||
|
||||
/* enable anti hang mechanism */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS),
|
||||
UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
|
||||
~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
|
||||
|
||||
WREG32_SOC15(JPEG, jpeg_inst, regUVD_PGFSM_CONFIG,
|
||||
2 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT);
|
||||
SOC15_WAIT_ON_RREG(JPEG, jpeg_inst, regUVD_PGFSM_STATUS,
|
||||
UVD_PGFSM_STATUS__UVDJ_PWR_OFF <<
|
||||
UVD_PGFSM_STATUS__UVDJ_PWR_STATUS__SHIFT,
|
||||
UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* jpeg_v4_0_3_stop - stop JPEG block
|
||||
*
|
||||
|
|
@ -572,31 +651,10 @@ static int jpeg_v4_0_3_start(struct amdgpu_device *adev)
|
|||
*/
|
||||
static int jpeg_v4_0_3_stop(struct amdgpu_device *adev)
|
||||
{
|
||||
int i, jpeg_inst;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
jpeg_inst = GET_INST(JPEG, i);
|
||||
/* reset JMI */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL),
|
||||
UVD_JMI_CNTL__SOFT_RESET_MASK,
|
||||
~UVD_JMI_CNTL__SOFT_RESET_MASK);
|
||||
|
||||
jpeg_v4_0_3_enable_clock_gating(adev, i);
|
||||
|
||||
/* enable anti hang mechanism */
|
||||
WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JPEG_POWER_STATUS),
|
||||
UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
|
||||
~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
|
||||
|
||||
WREG32_SOC15(JPEG, jpeg_inst, regUVD_PGFSM_CONFIG,
|
||||
2 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT);
|
||||
SOC15_WAIT_ON_RREG(
|
||||
JPEG, jpeg_inst, regUVD_PGFSM_STATUS,
|
||||
UVD_PGFSM_STATUS__UVDJ_PWR_OFF
|
||||
<< UVD_PGFSM_STATUS__UVDJ_PWR_STATUS__SHIFT,
|
||||
UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK);
|
||||
}
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i)
|
||||
jpeg_v4_0_3_stop_inst(adev, i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -612,9 +670,8 @@ static uint64_t jpeg_v4_0_3_dec_ring_get_rptr(struct amdgpu_ring *ring)
|
|||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
|
||||
return RREG32_SOC15_OFFSET(
|
||||
JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC0_UVD_JRBC_RB_RPTR,
|
||||
ring->pipe ? (0x40 * ring->pipe - 0xc80) : 0);
|
||||
return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC0_UVD_JRBC_RB_RPTR,
|
||||
jpeg_v4_0_3_core_reg_offset(ring->pipe));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -630,11 +687,9 @@ static uint64_t jpeg_v4_0_3_dec_ring_get_wptr(struct amdgpu_ring *ring)
|
|||
|
||||
if (ring->use_doorbell)
|
||||
return adev->wb.wb[ring->wptr_offs];
|
||||
else
|
||||
return RREG32_SOC15_OFFSET(
|
||||
JPEG, GET_INST(JPEG, ring->me),
|
||||
regUVD_JRBC0_UVD_JRBC_RB_WPTR,
|
||||
ring->pipe ? (0x40 * ring->pipe - 0xc80) : 0);
|
||||
|
||||
return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC0_UVD_JRBC_RB_WPTR,
|
||||
jpeg_v4_0_3_core_reg_offset(ring->pipe));
|
||||
}
|
||||
|
||||
static void jpeg_v4_0_3_ring_emit_hdp_flush(struct amdgpu_ring *ring)
|
||||
|
|
@ -659,10 +714,8 @@ static void jpeg_v4_0_3_dec_ring_set_wptr(struct amdgpu_ring *ring)
|
|||
adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
|
||||
WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
|
||||
} else {
|
||||
WREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me),
|
||||
regUVD_JRBC0_UVD_JRBC_RB_WPTR,
|
||||
(ring->pipe ? (0x40 * ring->pipe - 0xc80) :
|
||||
0),
|
||||
WREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC0_UVD_JRBC_RB_WPTR,
|
||||
jpeg_v4_0_3_core_reg_offset(ring->pipe),
|
||||
lower_32_bits(ring->wptr));
|
||||
}
|
||||
}
|
||||
|
|
@ -915,13 +968,9 @@ static bool jpeg_v4_0_3_is_idle(void *handle)
|
|||
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
|
||||
unsigned int reg_offset = (j?(0x40 * j - 0xc80):0);
|
||||
|
||||
ret &= ((RREG32_SOC15_OFFSET(
|
||||
JPEG, GET_INST(JPEG, i),
|
||||
regUVD_JRBC0_UVD_JRBC_STATUS,
|
||||
reg_offset) &
|
||||
UVD_JRBC0_UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
|
||||
ret &= ((RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, i),
|
||||
regUVD_JRBC0_UVD_JRBC_STATUS, jpeg_v4_0_3_core_reg_offset(j)) &
|
||||
UVD_JRBC0_UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
|
||||
UVD_JRBC0_UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
|
||||
}
|
||||
}
|
||||
|
|
@ -937,13 +986,10 @@ static int jpeg_v4_0_3_wait_for_idle(struct amdgpu_ip_block *ip_block)
|
|||
|
||||
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
|
||||
for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
|
||||
unsigned int reg_offset = (j?(0x40 * j - 0xc80):0);
|
||||
|
||||
ret &= SOC15_WAIT_ON_RREG_OFFSET(
|
||||
JPEG, GET_INST(JPEG, i),
|
||||
regUVD_JRBC0_UVD_JRBC_STATUS, reg_offset,
|
||||
ret &= (SOC15_WAIT_ON_RREG_OFFSET(JPEG, GET_INST(JPEG, i),
|
||||
regUVD_JRBC0_UVD_JRBC_STATUS, jpeg_v4_0_3_core_reg_offset(j),
|
||||
UVD_JRBC0_UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
|
||||
UVD_JRBC0_UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
|
||||
UVD_JRBC0_UVD_JRBC_STATUS__RB_JOB_DONE_MASK));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -1055,6 +1101,45 @@ static int jpeg_v4_0_3_process_interrupt(struct amdgpu_device *adev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void jpeg_v4_0_3_core_stall_reset(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
int jpeg_inst = GET_INST(JPEG, ring->me);
|
||||
int reg_offset = jpeg_v4_0_3_core_reg_offset(ring->pipe);
|
||||
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JMI0_UVD_JMI_CLIENT_STALL,
|
||||
reg_offset, 0x1F);
|
||||
SOC15_WAIT_ON_RREG(JPEG, jpeg_inst,
|
||||
regUVD_JMI0_UVD_JMI_CLIENT_CLEAN_STATUS,
|
||||
0x1F, 0x1F);
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JMI0_JPEG_LMI_DROP,
|
||||
reg_offset, 0x1F);
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regJPEG_CORE_RST_CTRL,
|
||||
reg_offset, 1 << ring->pipe);
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JMI0_UVD_JMI_CLIENT_STALL,
|
||||
reg_offset, 0x00);
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regUVD_JMI0_JPEG_LMI_DROP,
|
||||
reg_offset, 0x00);
|
||||
WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
|
||||
regJPEG_CORE_RST_CTRL,
|
||||
reg_offset, 0x00);
|
||||
}
|
||||
|
||||
static int jpeg_v4_0_3_ring_reset(struct amdgpu_ring *ring, unsigned int vmid)
|
||||
{
|
||||
if (amdgpu_sriov_vf(ring->adev))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
jpeg_v4_0_3_core_stall_reset(ring);
|
||||
jpeg_v4_0_3_start_jrbc(ring);
|
||||
return amdgpu_ring_test_helper(ring);
|
||||
}
|
||||
|
||||
static const struct amd_ip_funcs jpeg_v4_0_3_ip_funcs = {
|
||||
.name = "jpeg_v4_0_3",
|
||||
.early_init = jpeg_v4_0_3_early_init,
|
||||
|
|
@ -1068,6 +1153,8 @@ static const struct amd_ip_funcs jpeg_v4_0_3_ip_funcs = {
|
|||
.wait_for_idle = jpeg_v4_0_3_wait_for_idle,
|
||||
.set_clockgating_state = jpeg_v4_0_3_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v4_0_3_set_powergating_state,
|
||||
.dump_ip_state = amdgpu_jpeg_dump_ip_state,
|
||||
.print_ip_state = amdgpu_jpeg_print_ip_state,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v4_0_3_dec_ring_vm_funcs = {
|
||||
|
|
@ -1099,6 +1186,7 @@ static const struct amdgpu_ring_funcs jpeg_v4_0_3_dec_ring_vm_funcs = {
|
|||
.emit_wreg = jpeg_v4_0_3_dec_ring_emit_wreg,
|
||||
.emit_reg_wait = jpeg_v4_0_3_dec_ring_emit_reg_wait,
|
||||
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
|
||||
.reset = jpeg_v4_0_3_ring_reset,
|
||||
};
|
||||
|
||||
static void jpeg_v4_0_3_set_dec_ring_funcs(struct amdgpu_device *adev)
|
||||
|
|
@ -1245,10 +1333,12 @@ static int jpeg_v4_0_3_aca_bank_parser(struct aca_handle *handle, struct aca_ban
|
|||
misc0 = bank->regs[ACA_REG_IDX_MISC0];
|
||||
switch (type) {
|
||||
case ACA_SMU_TYPE_UE:
|
||||
bank->aca_err_type = ACA_ERROR_TYPE_UE;
|
||||
ret = aca_error_cache_log_bank_error(handle, &info, ACA_ERROR_TYPE_UE,
|
||||
1ULL);
|
||||
break;
|
||||
case ACA_SMU_TYPE_CE:
|
||||
bank->aca_err_type = ACA_ERROR_TYPE_CE;
|
||||
ret = aca_error_cache_log_bank_error(handle, &info, ACA_ERROR_TYPE_CE,
|
||||
ACA_REG__MISC0__ERRCNT(misc0));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -46,11 +46,26 @@
|
|||
#define regJPEG_CGC_GATE_INTERNAL_OFFSET 0x4160
|
||||
#define regUVD_NO_OP_INTERNAL_OFFSET 0x0029
|
||||
|
||||
static const struct amdgpu_hwip_reg_entry jpeg_reg_list_4_0_5[] = {
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_POWER_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_INT_STAT),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_CNTL),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_SIZE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_ADDR_MODE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_Y_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_UV_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_PITCH),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_UV_PITCH),
|
||||
};
|
||||
|
||||
static void jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device *adev);
|
||||
static void jpeg_v4_0_5_set_irq_funcs(struct amdgpu_device *adev);
|
||||
static int jpeg_v4_0_5_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
||||
enum amd_powergating_state state);
|
||||
|
||||
static void jpeg_v4_0_5_dec_ring_set_wptr(struct amdgpu_ring *ring);
|
||||
|
||||
static int amdgpu_ih_clientid_jpeg[] = {
|
||||
|
|
@ -58,6 +73,8 @@ static int amdgpu_ih_clientid_jpeg[] = {
|
|||
SOC15_IH_CLIENTID_VCN1
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* jpeg_v4_0_5_early_init - set function pointers
|
||||
*
|
||||
|
|
@ -153,6 +170,10 @@ static int jpeg_v4_0_5_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
adev->jpeg.inst[i].external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, i, regUVD_JPEG_PITCH);
|
||||
}
|
||||
|
||||
r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_4_0_5, ARRAY_SIZE(jpeg_reg_list_4_0_5));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* TODO: Add queue reset mask when FW fully supports it */
|
||||
adev->jpeg.supported_reset =
|
||||
amdgpu_get_soft_full_reset_mask(&adev->jpeg.inst[0].ring_dec[0]);
|
||||
|
|
@ -759,6 +780,8 @@ static const struct amd_ip_funcs jpeg_v4_0_5_ip_funcs = {
|
|||
.wait_for_idle = jpeg_v4_0_5_wait_for_idle,
|
||||
.set_clockgating_state = jpeg_v4_0_5_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v4_0_5_set_powergating_state,
|
||||
.dump_ip_state = amdgpu_jpeg_dump_ip_state,
|
||||
.print_ip_state = amdgpu_jpeg_print_ip_state,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v4_0_5_dec_ring_vm_funcs = {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,22 @@
|
|||
#include "ivsrcid/vcn/irqsrcs_vcn_5_0.h"
|
||||
#include "jpeg_v5_0_0.h"
|
||||
|
||||
static const struct amdgpu_hwip_reg_entry jpeg_reg_list_5_0[] = {
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_POWER_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_INT_STAT),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_CNTL),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_SIZE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_ADDR_MODE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_Y_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_UV_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_PITCH),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_UV_PITCH),
|
||||
};
|
||||
|
||||
static void jpeg_v5_0_0_set_dec_ring_funcs(struct amdgpu_device *adev);
|
||||
static void jpeg_v5_0_0_set_irq_funcs(struct amdgpu_device *adev);
|
||||
static int jpeg_v5_0_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
||||
|
|
@ -100,6 +116,10 @@ static int jpeg_v5_0_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
adev->jpeg.internal.jpeg_pitch[0] = regUVD_JPEG_PITCH_INTERNAL_OFFSET;
|
||||
adev->jpeg.inst->external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_PITCH);
|
||||
|
||||
r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_5_0, ARRAY_SIZE(jpeg_reg_list_5_0));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* TODO: Add queue reset mask when FW fully supports it */
|
||||
adev->jpeg.supported_reset =
|
||||
amdgpu_get_soft_full_reset_mask(&adev->jpeg.inst[0].ring_dec[0]);
|
||||
|
|
@ -637,6 +657,8 @@ static const struct amd_ip_funcs jpeg_v5_0_0_ip_funcs = {
|
|||
.wait_for_idle = jpeg_v5_0_0_wait_for_idle,
|
||||
.set_clockgating_state = jpeg_v5_0_0_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v5_0_0_set_powergating_state,
|
||||
.dump_ip_state = amdgpu_jpeg_dump_ip_state,
|
||||
.print_ip_state = amdgpu_jpeg_print_ip_state,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v5_0_0_dec_ring_vm_funcs = {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,47 @@ static int amdgpu_ih_srcid_jpeg[] = {
|
|||
VCN_5_0__SRCID__JPEG9_DECODE,
|
||||
};
|
||||
|
||||
static const struct amdgpu_hwip_reg_entry jpeg_reg_list_5_0_1[] = {
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_POWER_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_INT_STAT),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_ADDR_MODE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_Y_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_UV_GFX10_TILING_SURFACE),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_PITCH),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_UV_PITCH),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC8_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC8_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC8_UVD_JRBC_STATUS),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC9_UVD_JRBC_RB_RPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC9_UVD_JRBC_RB_WPTR),
|
||||
SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC9_UVD_JRBC_STATUS),
|
||||
};
|
||||
|
||||
static int jpeg_v5_0_1_core_reg_offset(u32 pipe)
|
||||
{
|
||||
if (pipe <= AMDGPU_MAX_JPEG_RINGS_4_0_3)
|
||||
|
|
@ -145,6 +186,10 @@ static int jpeg_v5_0_1_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
}
|
||||
}
|
||||
|
||||
r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_5_0_1, ARRAY_SIZE(jpeg_reg_list_5_0_1));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -635,8 +680,8 @@ static const struct amd_ip_funcs jpeg_v5_0_1_ip_funcs = {
|
|||
.post_soft_reset = NULL,
|
||||
.set_clockgating_state = jpeg_v5_0_1_set_clockgating_state,
|
||||
.set_powergating_state = jpeg_v5_0_1_set_powergating_state,
|
||||
.dump_ip_state = NULL,
|
||||
.print_ip_state = NULL,
|
||||
.dump_ip_state = amdgpu_jpeg_dump_ip_state,
|
||||
.print_ip_state = amdgpu_jpeg_print_ip_state,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs jpeg_v5_0_1_dec_ring_vm_funcs = {
|
||||
|
|
|
|||
|
|
@ -26,4 +26,65 @@
|
|||
|
||||
extern const struct amdgpu_ip_block_version jpeg_v5_0_1_ip_block;
|
||||
|
||||
#define regUVD_JRBC0_UVD_JRBC_RB_WPTR 0x0640
|
||||
#define regUVD_JRBC0_UVD_JRBC_RB_WPTR_BASE_IDX 1
|
||||
#define regUVD_JRBC0_UVD_JRBC_STATUS 0x0649
|
||||
#define regUVD_JRBC0_UVD_JRBC_STATUS_BASE_IDX 1
|
||||
#define regUVD_JRBC0_UVD_JRBC_RB_RPTR 0x064a
|
||||
#define regUVD_JRBC0_UVD_JRBC_RB_RPTR_BASE_IDX 1
|
||||
#define regUVD_JRBC1_UVD_JRBC_RB_WPTR 0x0000
|
||||
#define regUVD_JRBC1_UVD_JRBC_RB_WPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC1_UVD_JRBC_STATUS 0x0009
|
||||
#define regUVD_JRBC1_UVD_JRBC_STATUS_BASE_IDX 0
|
||||
#define regUVD_JRBC1_UVD_JRBC_RB_RPTR 0x000a
|
||||
#define regUVD_JRBC1_UVD_JRBC_RB_RPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC2_UVD_JRBC_RB_WPTR 0x0040
|
||||
#define regUVD_JRBC2_UVD_JRBC_RB_WPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC2_UVD_JRBC_STATUS 0x0049
|
||||
#define regUVD_JRBC2_UVD_JRBC_STATUS_BASE_IDX 0
|
||||
#define regUVD_JRBC2_UVD_JRBC_RB_RPTR 0x004a
|
||||
#define regUVD_JRBC2_UVD_JRBC_RB_RPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC3_UVD_JRBC_RB_WPTR 0x0080
|
||||
#define regUVD_JRBC3_UVD_JRBC_RB_WPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC3_UVD_JRBC_STATUS 0x0089
|
||||
#define regUVD_JRBC3_UVD_JRBC_STATUS_BASE_IDX 0
|
||||
#define regUVD_JRBC3_UVD_JRBC_RB_RPTR 0x008a
|
||||
#define regUVD_JRBC3_UVD_JRBC_RB_RPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC4_UVD_JRBC_RB_WPTR 0x00c0
|
||||
#define regUVD_JRBC4_UVD_JRBC_RB_WPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC4_UVD_JRBC_STATUS 0x00c9
|
||||
#define regUVD_JRBC4_UVD_JRBC_STATUS_BASE_IDX 0
|
||||
#define regUVD_JRBC4_UVD_JRBC_RB_RPTR 0x00ca
|
||||
#define regUVD_JRBC4_UVD_JRBC_RB_RPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC5_UVD_JRBC_RB_WPTR 0x0100
|
||||
#define regUVD_JRBC5_UVD_JRBC_RB_WPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC5_UVD_JRBC_STATUS 0x0109
|
||||
#define regUVD_JRBC5_UVD_JRBC_STATUS_BASE_IDX 0
|
||||
#define regUVD_JRBC5_UVD_JRBC_RB_RPTR 0x010a
|
||||
#define regUVD_JRBC5_UVD_JRBC_RB_RPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC6_UVD_JRBC_RB_WPTR 0x0140
|
||||
#define regUVD_JRBC6_UVD_JRBC_RB_WPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC6_UVD_JRBC_STATUS 0x0149
|
||||
#define regUVD_JRBC6_UVD_JRBC_STATUS_BASE_IDX 0
|
||||
#define regUVD_JRBC6_UVD_JRBC_RB_RPTR 0x014a
|
||||
#define regUVD_JRBC6_UVD_JRBC_RB_RPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC7_UVD_JRBC_RB_WPTR 0x0180
|
||||
#define regUVD_JRBC7_UVD_JRBC_RB_WPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC7_UVD_JRBC_STATUS 0x0189
|
||||
#define regUVD_JRBC7_UVD_JRBC_STATUS_BASE_IDX 0
|
||||
#define regUVD_JRBC7_UVD_JRBC_RB_RPTR 0x018a
|
||||
#define regUVD_JRBC7_UVD_JRBC_RB_RPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC8_UVD_JRBC_RB_WPTR 0x01c0
|
||||
#define regUVD_JRBC8_UVD_JRBC_RB_WPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC8_UVD_JRBC_STATUS 0x01c9
|
||||
#define regUVD_JRBC8_UVD_JRBC_STATUS_BASE_IDX 0
|
||||
#define regUVD_JRBC8_UVD_JRBC_RB_RPTR 0x01ca
|
||||
#define regUVD_JRBC8_UVD_JRBC_RB_RPTR_BASE_IDX 0
|
||||
#define regUVD_JRBC9_UVD_JRBC_RB_WPTR 0x0440
|
||||
#define regUVD_JRBC9_UVD_JRBC_RB_WPTR_BASE_IDX 1
|
||||
#define regUVD_JRBC9_UVD_JRBC_STATUS 0x0449
|
||||
#define regUVD_JRBC9_UVD_JRBC_STATUS_BASE_IDX 1
|
||||
#define regUVD_JRBC9_UVD_JRBC_RB_RPTR 0x044a
|
||||
#define regUVD_JRBC9_UVD_JRBC_RB_RPTR_BASE_IDX 1
|
||||
|
||||
#endif /* __JPEG_V5_0_0_H__ */
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ MODULE_FIRMWARE("amdgpu/gc_11_5_1_mes_2.bin");
|
|||
MODULE_FIRMWARE("amdgpu/gc_11_5_1_mes1.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_2_mes_2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_2_mes1.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_3_mes_2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_5_3_mes1.bin");
|
||||
|
||||
static int mes_v11_0_hw_init(struct amdgpu_ip_block *ip_block);
|
||||
static int mes_v11_0_hw_fini(struct amdgpu_ip_block *ip_block);
|
||||
|
|
@ -62,6 +64,7 @@ static int mes_v11_0_kiq_hw_fini(struct amdgpu_device *adev);
|
|||
|
||||
#define MES_EOP_SIZE 2048
|
||||
#define GFX_MES_DRAM_SIZE 0x80000
|
||||
#define MES11_HW_RESOURCE_1_SIZE (128 * AMDGPU_GPU_PAGE_SIZE)
|
||||
|
||||
static void mes_v11_0_ring_set_wptr(struct amdgpu_ring *ring)
|
||||
{
|
||||
|
|
@ -730,9 +733,6 @@ static int mes_v11_0_set_hw_resources(struct amdgpu_mes *mes)
|
|||
|
||||
static int mes_v11_0_set_hw_resources_1(struct amdgpu_mes *mes)
|
||||
{
|
||||
int size = 128 * PAGE_SIZE;
|
||||
int ret = 0;
|
||||
struct amdgpu_device *adev = mes->adev;
|
||||
union MESAPI_SET_HW_RESOURCES_1 mes_set_hw_res_pkt;
|
||||
memset(&mes_set_hw_res_pkt, 0, sizeof(mes_set_hw_res_pkt));
|
||||
|
||||
|
|
@ -740,19 +740,11 @@ static int mes_v11_0_set_hw_resources_1(struct amdgpu_mes *mes)
|
|||
mes_set_hw_res_pkt.header.opcode = MES_SCH_API_SET_HW_RSRC_1;
|
||||
mes_set_hw_res_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS;
|
||||
mes_set_hw_res_pkt.enable_mes_info_ctx = 1;
|
||||
|
||||
ret = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&mes->resource_1,
|
||||
&mes->resource_1_gpu_addr,
|
||||
&mes->resource_1_addr);
|
||||
if (ret) {
|
||||
dev_err(adev->dev, "(%d) failed to create mes resource_1 bo\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
mes_set_hw_res_pkt.mes_info_ctx_mc_addr = mes->resource_1_gpu_addr;
|
||||
mes_set_hw_res_pkt.mes_info_ctx_size = mes->resource_1->tbo.base.size;
|
||||
mes_set_hw_res_pkt.mes_info_ctx_size = MES11_HW_RESOURCE_1_SIZE;
|
||||
mes_set_hw_res_pkt.cleaner_shader_fence_mc_addr =
|
||||
mes->resource_1_gpu_addr + MES11_HW_RESOURCE_1_SIZE;
|
||||
|
||||
return mes_v11_0_submit_pkt_and_poll_completion(mes,
|
||||
&mes_set_hw_res_pkt, sizeof(mes_set_hw_res_pkt),
|
||||
offsetof(union MESAPI_SET_HW_RESOURCES_1, api_status));
|
||||
|
|
@ -1424,6 +1416,21 @@ static int mes_v11_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
if (amdgpu_sriov_is_mes_info_enable(adev) ||
|
||||
adev->gfx.enable_cleaner_shader) {
|
||||
r = amdgpu_bo_create_kernel(adev,
|
||||
MES11_HW_RESOURCE_1_SIZE + AMDGPU_GPU_PAGE_SIZE,
|
||||
PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&adev->mes.resource_1,
|
||||
&adev->mes.resource_1_gpu_addr,
|
||||
&adev->mes.resource_1_addr);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "(%d) failed to create mes resource_1 bo\n", r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1432,6 +1439,12 @@ static int mes_v11_0_sw_fini(struct amdgpu_ip_block *ip_block)
|
|||
struct amdgpu_device *adev = ip_block->adev;
|
||||
int pipe;
|
||||
|
||||
if (amdgpu_sriov_is_mes_info_enable(adev) ||
|
||||
adev->gfx.enable_cleaner_shader) {
|
||||
amdgpu_bo_free_kernel(&adev->mes.resource_1, &adev->mes.resource_1_gpu_addr,
|
||||
&adev->mes.resource_1_addr);
|
||||
}
|
||||
|
||||
for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++) {
|
||||
kfree(adev->mes.mqd_backup[pipe]);
|
||||
|
||||
|
|
@ -1619,7 +1632,8 @@ static int mes_v11_0_hw_init(struct amdgpu_ip_block *ip_block)
|
|||
if (r)
|
||||
goto failure;
|
||||
|
||||
if (amdgpu_sriov_is_mes_info_enable(adev)) {
|
||||
if (amdgpu_sriov_is_mes_info_enable(adev) ||
|
||||
adev->gfx.enable_cleaner_shader) {
|
||||
r = mes_v11_0_set_hw_resources_1(&adev->mes);
|
||||
if (r) {
|
||||
DRM_ERROR("failed mes_v11_0_set_hw_resources_1, r=%d\n", r);
|
||||
|
|
@ -1651,11 +1665,6 @@ static int mes_v11_0_hw_init(struct amdgpu_ip_block *ip_block)
|
|||
|
||||
static int mes_v11_0_hw_fini(struct amdgpu_ip_block *ip_block)
|
||||
{
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
if (amdgpu_sriov_is_mes_info_enable(adev)) {
|
||||
amdgpu_bo_free_kernel(&adev->mes.resource_1, &adev->mes.resource_1_gpu_addr,
|
||||
&adev->mes.resource_1_addr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -686,6 +686,8 @@ static int mes_v12_0_set_hw_resources_1(struct amdgpu_mes *mes, int pipe)
|
|||
mes_set_hw_res_1_pkt.header.opcode = MES_SCH_API_SET_HW_RSRC_1;
|
||||
mes_set_hw_res_1_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS;
|
||||
mes_set_hw_res_1_pkt.mes_kiq_unmap_timeout = 0xa;
|
||||
mes_set_hw_res_1_pkt.cleaner_shader_fence_mc_addr =
|
||||
mes->resource_1_gpu_addr;
|
||||
|
||||
return mes_v12_0_submit_pkt_and_poll_completion(mes, pipe,
|
||||
&mes_set_hw_res_1_pkt, sizeof(mes_set_hw_res_1_pkt),
|
||||
|
|
@ -1525,6 +1527,18 @@ static int mes_v12_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
return r;
|
||||
}
|
||||
|
||||
if (adev->enable_uni_mes) {
|
||||
r = amdgpu_bo_create_kernel(adev, AMDGPU_GPU_PAGE_SIZE, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&adev->mes.resource_1,
|
||||
&adev->mes.resource_1_gpu_addr,
|
||||
&adev->mes.resource_1_addr);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "(%d) failed to create mes resource_1 bo\n", r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1533,6 +1547,11 @@ static int mes_v12_0_sw_fini(struct amdgpu_ip_block *ip_block)
|
|||
struct amdgpu_device *adev = ip_block->adev;
|
||||
int pipe;
|
||||
|
||||
if (adev->enable_uni_mes)
|
||||
amdgpu_bo_free_kernel(&adev->mes.resource_1,
|
||||
&adev->mes.resource_1_gpu_addr,
|
||||
&adev->mes.resource_1_addr);
|
||||
|
||||
for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++) {
|
||||
kfree(adev->mes.mqd_backup[pipe]);
|
||||
|
||||
|
|
|
|||
|
|
@ -172,6 +172,30 @@ static void mmhub_v1_7_init_tlb_regs(struct amdgpu_device *adev)
|
|||
WREG32_SOC15(MMHUB, 0, regMC_VM_MX_L1_TLB_CNTL, tmp);
|
||||
}
|
||||
|
||||
/* Set snoop bit for SDMA so that SDMA writes probe-invalidates RW lines */
|
||||
static void mmhub_v1_7_init_snoop_override_regs(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
int i;
|
||||
uint32_t distance = regDAGB1_WRCLI_GPU_SNOOP_OVERRIDE -
|
||||
regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE;
|
||||
|
||||
for (i = 0; i < 5; i++) { /* DAGB instances */
|
||||
tmp = RREG32_SOC15_OFFSET(MMHUB, 0,
|
||||
regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE, i * distance);
|
||||
tmp |= (1 << 15); /* SDMA client is BIT15 */
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0,
|
||||
regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE, i * distance, tmp);
|
||||
|
||||
tmp = RREG32_SOC15_OFFSET(MMHUB, 0,
|
||||
regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE, i * distance);
|
||||
tmp |= (1 << 15);
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0,
|
||||
regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE, i * distance, tmp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void mmhub_v1_7_init_cache_regs(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
|
@ -337,6 +361,7 @@ static int mmhub_v1_7_gart_enable(struct amdgpu_device *adev)
|
|||
mmhub_v1_7_init_system_aperture_regs(adev);
|
||||
mmhub_v1_7_init_tlb_regs(adev);
|
||||
mmhub_v1_7_init_cache_regs(adev);
|
||||
mmhub_v1_7_init_snoop_override_regs(adev);
|
||||
|
||||
mmhub_v1_7_enable_system_domain(adev);
|
||||
mmhub_v1_7_disable_identity_aperture(adev);
|
||||
|
|
|
|||
|
|
@ -213,6 +213,32 @@ static void mmhub_v1_8_init_tlb_regs(struct amdgpu_device *adev)
|
|||
}
|
||||
}
|
||||
|
||||
/* Set snoop bit for SDMA so that SDMA writes probe-invalidates RW lines */
|
||||
static void mmhub_v1_8_init_snoop_override_regs(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t tmp, inst_mask;
|
||||
int i, j;
|
||||
uint32_t distance = regDAGB1_WRCLI_GPU_SNOOP_OVERRIDE -
|
||||
regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE;
|
||||
|
||||
inst_mask = adev->aid_mask;
|
||||
for_each_inst(i, inst_mask) {
|
||||
for (j = 0; j < 5; j++) { /* DAGB instances */
|
||||
tmp = RREG32_SOC15_OFFSET(MMHUB, i,
|
||||
regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE, j * distance);
|
||||
tmp |= (1 << 15); /* SDMA client is BIT15 */
|
||||
WREG32_SOC15_OFFSET(MMHUB, i,
|
||||
regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE, j * distance, tmp);
|
||||
|
||||
tmp = RREG32_SOC15_OFFSET(MMHUB, i,
|
||||
regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE, j * distance);
|
||||
tmp |= (1 << 15);
|
||||
WREG32_SOC15_OFFSET(MMHUB, i,
|
||||
regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE, j * distance, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mmhub_v1_8_init_cache_regs(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t tmp, inst_mask;
|
||||
|
|
@ -418,6 +444,7 @@ static int mmhub_v1_8_gart_enable(struct amdgpu_device *adev)
|
|||
mmhub_v1_8_init_system_aperture_regs(adev);
|
||||
mmhub_v1_8_init_tlb_regs(adev);
|
||||
mmhub_v1_8_init_cache_regs(adev);
|
||||
mmhub_v1_8_init_snoop_override_regs(adev);
|
||||
|
||||
mmhub_v1_8_enable_system_domain(adev);
|
||||
mmhub_v1_8_disable_identity_aperture(adev);
|
||||
|
|
@ -719,10 +746,12 @@ static int mmhub_v1_8_aca_bank_parser(struct aca_handle *handle, struct aca_bank
|
|||
misc0 = bank->regs[ACA_REG_IDX_MISC0];
|
||||
switch (type) {
|
||||
case ACA_SMU_TYPE_UE:
|
||||
bank->aca_err_type = ACA_ERROR_TYPE_UE;
|
||||
ret = aca_error_cache_log_bank_error(handle, &info, ACA_ERROR_TYPE_UE,
|
||||
1ULL);
|
||||
break;
|
||||
case ACA_SMU_TYPE_CE:
|
||||
bank->aca_err_type = ACA_ERROR_TYPE_CE;
|
||||
ret = aca_error_cache_log_bank_error(handle, &info, ACA_ERROR_TYPE_CE,
|
||||
ACA_REG__MISC0__ERRCNT(misc0));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ mmhub_v3_3_print_l2_protection_fault_status(struct amdgpu_device *adev,
|
|||
switch (amdgpu_ip_version(adev, MMHUB_HWIP, 0)) {
|
||||
case IP_VERSION(3, 3, 0):
|
||||
case IP_VERSION(3, 3, 1):
|
||||
case IP_VERSION(3, 3, 2):
|
||||
mmhub_cid = cid < ARRAY_SIZE(mmhub_client_ids_v3_3) ?
|
||||
mmhub_client_ids_v3_3[cid][rw] :
|
||||
cid == 0x140 ? "UMSCH" : NULL;
|
||||
|
|
|
|||
|
|
@ -198,6 +198,36 @@ static void mmhub_v9_4_init_tlb_regs(struct amdgpu_device *adev, int hubid)
|
|||
hubid * MMHUB_INSTANCE_REGISTER_OFFSET, tmp);
|
||||
}
|
||||
|
||||
/* Set snoop bit for SDMA so that SDMA writes probe-invalidates RW lines */
|
||||
static void mmhub_v9_4_init_snoop_override_regs(struct amdgpu_device *adev, int hubid)
|
||||
{
|
||||
uint32_t tmp;
|
||||
int i;
|
||||
uint32_t distance = mmDAGB1_WRCLI_GPU_SNOOP_OVERRIDE -
|
||||
mmDAGB0_WRCLI_GPU_SNOOP_OVERRIDE;
|
||||
uint32_t huboffset = hubid * MMHUB_INSTANCE_REGISTER_OFFSET;
|
||||
|
||||
for (i = 0; i < 5 - (2 * hubid); i++) {
|
||||
/* DAGB instances 0 to 4 are in hub0 and 5 to 7 are in hub1 */
|
||||
tmp = RREG32_SOC15_OFFSET(MMHUB, 0,
|
||||
mmDAGB0_WRCLI_GPU_SNOOP_OVERRIDE,
|
||||
huboffset + i * distance);
|
||||
tmp |= (1 << 15); /* SDMA client is BIT15 */
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0,
|
||||
mmDAGB0_WRCLI_GPU_SNOOP_OVERRIDE,
|
||||
huboffset + i * distance, tmp);
|
||||
|
||||
tmp = RREG32_SOC15_OFFSET(MMHUB, 0,
|
||||
mmDAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE,
|
||||
huboffset + i * distance);
|
||||
tmp |= (1 << 15);
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0,
|
||||
mmDAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE,
|
||||
huboffset + i * distance, tmp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void mmhub_v9_4_init_cache_regs(struct amdgpu_device *adev, int hubid)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
|
@ -392,6 +422,7 @@ static int mmhub_v9_4_gart_enable(struct amdgpu_device *adev)
|
|||
if (!amdgpu_sriov_vf(adev))
|
||||
mmhub_v9_4_init_cache_regs(adev, i);
|
||||
|
||||
mmhub_v9_4_init_snoop_override_regs(adev, i);
|
||||
mmhub_v9_4_enable_system_domain(adev, i);
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
mmhub_v9_4_disable_identity_aperture(adev, i);
|
||||
|
|
|
|||
|
|
@ -682,9 +682,9 @@ static int navi10_ih_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void navi10_ih_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void navi10_ih_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
|
||||
if (!RREG32_SOC15(OSSSYS, 0, mmIH_CLK_CTRL))
|
||||
*flags |= AMD_CG_SUPPORT_IH_CG;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "nbif_v6_3_1.h"
|
||||
|
||||
#include "nbif/nbif_6_3_1_offset.h"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "nbio_v2_3.h"
|
||||
|
||||
#include "nbio/nbio_2_3_default.h"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "nbio_v4_3.h"
|
||||
|
||||
#include "nbio/nbio_4_3_0_offset.h"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "nbio_v6_1.h"
|
||||
|
||||
#include "nbio/nbio_6_1_default.h"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "nbio_v7_0.h"
|
||||
|
||||
#include "nbio/nbio_7_0_default.h"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "nbio_v7_11.h"
|
||||
|
||||
#include "nbio/nbio_7_11_0_offset.h"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "nbio_v7_2.h"
|
||||
|
||||
#include "nbio/nbio_7_2_0_offset.h"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "nbio_v7_4.h"
|
||||
#include "amdgpu_ras.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "nbio_v7_7.h"
|
||||
|
||||
#include "nbio/nbio_7_7_0_offset.h"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
*
|
||||
*/
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_atombios.h"
|
||||
#include "nbio_v7_9.h"
|
||||
#include "amdgpu_ras.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -454,6 +454,7 @@ nv_asic_reset_method(struct amdgpu_device *adev)
|
|||
|
||||
switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
case IP_VERSION(13, 0, 1):
|
||||
case IP_VERSION(13, 0, 3):
|
||||
case IP_VERSION(13, 0, 5):
|
||||
|
|
@ -1077,9 +1078,9 @@ static int nv_common_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void nv_common_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void nv_common_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
*flags = 0;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,24 @@
|
|||
#define PACKET3_INDIRECT_BUFFER_CNST_END 0x19
|
||||
#define PACKET3_ATOMIC_GDS 0x1D
|
||||
#define PACKET3_ATOMIC_MEM 0x1E
|
||||
#define PACKET3_ATOMIC_MEM__ATOMIC(x) ((((unsigned)(x)) & 0x7F) << 0)
|
||||
#define PACKET3_ATOMIC_MEM__COMMAND(x) ((((unsigned)(x)) & 0xF) << 8)
|
||||
#define PACKET3_ATOMIC_MEM__CACHE_POLICY(x) ((((unsigned)(x)) & 0x3) << 25)
|
||||
#define PACKET3_ATOMIC_MEM__ADDR_LO(x) (((unsigned)(x)))
|
||||
#define PACKET3_ATOMIC_MEM__ADDR_HI(x) (((unsigned)(x)))
|
||||
#define PACKET3_ATOMIC_MEM__SRC_DATA_LO(x) (((unsigned)(x)))
|
||||
#define PACKET3_ATOMIC_MEM__SRC_DATA_HI(x) (((unsigned)(x)))
|
||||
#define PACKET3_ATOMIC_MEM__CMP_DATA_LO(x) (((unsigned)(x)))
|
||||
#define PACKET3_ATOMIC_MEM__CMP_DATA_HI(x) (((unsigned)(x)))
|
||||
#define PACKET3_ATOMIC_MEM__LOOP_INTERVAL(x) ((((unsigned)(x)) & 0x1FFF) << 0)
|
||||
#define PACKET3_ATOMIC_MEM__COMMAND__SINGLE_PASS_ATOMIC 0
|
||||
#define PACKET3_ATOMIC_MEM__COMMAND__LOOP_UNTIL_COMPARE_SATISFIED 1
|
||||
#define PACKET3_ATOMIC_MEM__COMMAND__WAIT_FOR_WRITE_CONFIRMATION 2
|
||||
#define PACKET3_ATOMIC_MEM__COMMAND__SEND_AND_CONTINUE 3
|
||||
#define PACKET3_ATOMIC_MEM__CACHE_POLICY__LRU 0
|
||||
#define PACKET3_ATOMIC_MEM__CACHE_POLICY__STREAM 1
|
||||
#define PACKET3_ATOMIC_MEM__CACHE_POLICY__NOA 2
|
||||
#define PACKET3_ATOMIC_MEM__CACHE_POLICY__BYPASS 3
|
||||
#define PACKET3_OCCLUSION_QUERY 0x1F
|
||||
#define PACKET3_SET_PREDICATION 0x20
|
||||
#define PACKET3_REG_RMW 0x21
|
||||
|
|
@ -105,6 +123,38 @@
|
|||
* 1 - pfp
|
||||
* 2 - ce
|
||||
*/
|
||||
#define PACKET3_WRITE_DATA__DST_SEL(x) ((((unsigned)(x)) & 0xF) << 8)
|
||||
#define PACKET3_WRITE_DATA__ADDR_INCR(x) ((((unsigned)(x)) & 0x1) << 16)
|
||||
#define PACKET3_WRITE_DATA__WR_CONFIRM(x) ((((unsigned)(x)) & 0x1) << 20)
|
||||
#define PACKET3_WRITE_DATA__CACHE_POLICY(x) ((((unsigned)(x)) & 0x3) << 25)
|
||||
#define PACKET3_WRITE_DATA__DST_MMREG_ADDR(x) ((((unsigned)(x)) & 0x3FFFF) << 0)
|
||||
#define PACKET3_WRITE_DATA__DST_GDS_ADDR(x) ((((unsigned)(x)) & 0xFFFF) << 0)
|
||||
#define PACKET3_WRITE_DATA__DST_MEM_ADDR_LO(x) ((((unsigned)(x)) & 0x3FFFFFFF) << 2)
|
||||
#define PACKET3_WRITE_DATA__DST_MEM_ADDR_HI(x) ((unsigned)(x))
|
||||
#define PACKET3_WRITE_DATA__MODE(x) ((((unsigned)(x)) & 0x1) << 21)
|
||||
#define PACKET3_WRITE_DATA__AID_ID(x) ((((unsigned)(x)) & 0x3) << 22)
|
||||
#define PACKET3_WRITE_DATA__TEMPORAL(x) ((((unsigned)(x)) & 0x3) << 24)
|
||||
#define PACKET3_WRITE_DATA__DST_MMREG_ADDR_LO(x) ((unsigned)(x))
|
||||
#define PACKET3_WRITE_DATA__DST_MMREG_ADDR_HI(x) ((((unsigned)(x)) & 0xFF) << 0)
|
||||
#define PACKET3_WRITE_DATA__DST_SEL__MEM_MAPPED_REGISTER 0
|
||||
#define PACKET3_WRITE_DATA__DST_SEL__TC_L2 2
|
||||
#define PACKET3_WRITE_DATA__DST_SEL__GDS 3
|
||||
#define PACKET3_WRITE_DATA__DST_SEL__MEMORY 5
|
||||
#define PACKET3_WRITE_DATA__DST_SEL__MEMORY_MAPPED_ADC_PERSISTENT_STATE 6
|
||||
#define PACKET3_WRITE_DATA__ADDR_INCR__INCREMENT_ADDRESS 0
|
||||
#define PACKET3_WRITE_DATA__ADDR_INCR__DO_NOT_INCREMENT_ADDRESS 1
|
||||
#define PACKET3_WRITE_DATA__WR_CONFIRM__DO_NOT_WAIT_FOR_WRITE_CONFIRMATION 0
|
||||
#define PACKET3_WRITE_DATA__WR_CONFIRM__WAIT_FOR_WRITE_CONFIRMATION 1
|
||||
#define PACKET3_WRITE_DATA__MODE__PF_VF_DISABLED 0
|
||||
#define PACKET3_WRITE_DATA__MODE__PF_VF_ENABLED 1
|
||||
#define PACKET3_WRITE_DATA__TEMPORAL__RT 0
|
||||
#define PACKET3_WRITE_DATA__TEMPORAL__NT 1
|
||||
#define PACKET3_WRITE_DATA__TEMPORAL__HT 2
|
||||
#define PACKET3_WRITE_DATA__TEMPORAL__LU 3
|
||||
#define PACKET3_WRITE_DATA__CACHE_POLICY__LRU 0
|
||||
#define PACKET3_WRITE_DATA__CACHE_POLICY__STREAM 1
|
||||
#define PACKET3_WRITE_DATA__CACHE_POLICY__NOA 2
|
||||
#define PACKET3_WRITE_DATA__CACHE_POLICY__BYPASS 3
|
||||
#define PACKET3_DRAW_INDEX_INDIRECT_MULTI 0x38
|
||||
#define PACKET3_MEM_SEMAPHORE 0x39
|
||||
# define PACKET3_SEM_USE_MAILBOX (0x1 << 16)
|
||||
|
|
@ -135,6 +185,42 @@
|
|||
/* 0 - me
|
||||
* 1 - pfp
|
||||
*/
|
||||
#define PACKET3_WAIT_REG_MEM__FUNCTION(x) ((((unsigned)(x)) & 0x7) << 0)
|
||||
#define PACKET3_WAIT_REG_MEM__MEM_SPACE(x) ((((unsigned)(x)) & 0x3) << 4)
|
||||
#define PACKET3_WAIT_REG_MEM__OPERATION(x) ((((unsigned)(x)) & 0x3) << 6)
|
||||
#define PACKET3_WAIT_REG_MEM__MES_INTR_PIPE(x) ((((unsigned)(x)) & 0x3) << 22)
|
||||
#define PACKET3_WAIT_REG_MEM__MES_ACTION(x) ((((unsigned)(x)) & 0x1) << 24)
|
||||
#define PACKET3_WAIT_REG_MEM__CACHE_POLICY(x) ((((unsigned)(x)) & 0x3) << 25)
|
||||
#define PACKET3_WAIT_REG_MEM__TEMPORAL(x) ((((unsigned)(x)) & 0x3) << 25)
|
||||
#define PACKET3_WAIT_REG_MEM__MEM_POLL_ADDR_LO(x) ((((unsigned)(x)) & 0x3FFFFFFF) << 2)
|
||||
#define PACKET3_WAIT_REG_MEM__REG_POLL_ADDR(x) ((((unsigned)(x)) & 0X3FFFF) << 0)
|
||||
#define PACKET3_WAIT_REG_MEM__REG_WRITE_ADDR1(x) ((((unsigned)(x)) & 0X3FFFF) << 0)
|
||||
#define PACKET3_WAIT_REG_MEM__MEM_POLL_ADDR_HI(x) ((unsigned)(x))
|
||||
#define PACKET3_WAIT_REG_MEM__REG_WRITE_ADDR2(x) ((((unsigned)(x)) & 0x3FFFF) << 0)
|
||||
#define PACKET3_WAIT_REG_MEM__REFERENCE(x) ((unsigned)(x))
|
||||
#define PACKET3_WAIT_REG_MEM__MASK(x) ((unsigned)(x))
|
||||
#define PACKET3_WAIT_REG_MEM__POLL_INTERVAL(x) ((((unsigned)(x)) & 0xFFFF) << 0)
|
||||
#define PACKET3_WAIT_REG_MEM__OPTIMIZE_ACE_OFFLOAD_MODE(x) ((((unsigned)(x)) & 0x1) << 31)
|
||||
#define PACKET3_WAIT_REG_MEM__FUNCTION__ALWAYS_PASS 0
|
||||
#define PACKET3_WAIT_REG_MEM__FUNCTION__LESS_THAN_REF_VALUE 1
|
||||
#define PACKET3_WAIT_REG_MEM__FUNCTION__LESS_THAN_EQUAL_TO_THE_REF_VALUE 2
|
||||
#define PACKET3_WAIT_REG_MEM__FUNCTION__EQUAL_TO_THE_REFERENCE_VALUE 3
|
||||
#define PACKET3_WAIT_REG_MEM__FUNCTION__NOT_EQUAL_REFERENCE_VALUE 4
|
||||
#define PACKET3_WAIT_REG_MEM__FUNCTION__GREATER_THAN_OR_EQUAL_REFERENCE_VALUE 5
|
||||
#define PACKET3_WAIT_REG_MEM__FUNCTION__GREATER_THAN_REFERENCE_VALUE 6
|
||||
#define PACKET3_WAIT_REG_MEM__MEM_SPACE__REGISTER_SPACE 0
|
||||
#define PACKET3_WAIT_REG_MEM__MEM_SPACE__MEMORY_SPACE 1
|
||||
#define PACKET3_WAIT_REG_MEM__OPERATION__WAIT_REG_MEM 0
|
||||
#define PACKET3_WAIT_REG_MEM__OPERATION__WR_WAIT_WR_REG 1
|
||||
#define PACKET3_WAIT_REG_MEM__OPERATION__WAIT_MEM_PREEMPTABLE 3
|
||||
#define PACKET3_WAIT_REG_MEM__CACHE_POLICY__LRU 0
|
||||
#define PACKET3_WAIT_REG_MEM__CACHE_POLICY__STREAM 1
|
||||
#define PACKET3_WAIT_REG_MEM__CACHE_POLICY__NOA 2
|
||||
#define PACKET3_WAIT_REG_MEM__CACHE_POLICY__BYPASS 3
|
||||
#define PACKET3_WAIT_REG_MEM__TEMPORAL__RT 0
|
||||
#define PACKET3_WAIT_REG_MEM__TEMPORAL__NT 1
|
||||
#define PACKET3_WAIT_REG_MEM__TEMPORAL__HT 2
|
||||
#define PACKET3_WAIT_REG_MEM__TEMPORAL__LU 3
|
||||
#define PACKET3_INDIRECT_BUFFER 0x3F
|
||||
#define INDIRECT_BUFFER_VALID (1 << 23)
|
||||
#define INDIRECT_BUFFER_CACHE_POLICY(x) ((x) << 28)
|
||||
|
|
@ -144,8 +230,94 @@
|
|||
*/
|
||||
#define INDIRECT_BUFFER_PRE_ENB(x) ((x) << 21)
|
||||
#define INDIRECT_BUFFER_PRE_RESUME(x) ((x) << 30)
|
||||
#define PACKET3_INDIRECT_BUFFER__IB_BASE_LO(x) ((((unsigned)(x)) & 0x3FFFFFFF) << 2)
|
||||
#define PACKET3_INDIRECT_BUFFER__IB_BASE_HI(x) ((unsigned)(x))
|
||||
#define PACKET3_INDIRECT_BUFFER__IB_SIZE(x) ((((unsigned)(x)) & 0xFFFFF) << 0)
|
||||
#define PACKET3_INDIRECT_BUFFER__CHAIN(x) ((((unsigned)(x)) & 0x1) << 20)
|
||||
#define PACKET3_INDIRECT_BUFFER__OFFLOAD_POLLING(x) ((((unsigned)(x)) & 0x1) << 21)
|
||||
#define PACKET3_INDIRECT_BUFFER__VALID(x) ((((unsigned)(x)) & 0x1) << 23)
|
||||
#define PACKET3_INDIRECT_BUFFER__VMID(x) ((((unsigned)(x)) & 0xF) << 24)
|
||||
#define PACKET3_INDIRECT_BUFFER__CACHE_POLICY(x) ((((unsigned)(x)) & 0x3) << 28)
|
||||
#define PACKET3_INDIRECT_BUFFER__TEMPORAL(x) ((((unsigned)(x)) & 0x3) << 28)
|
||||
#define PACKET3_INDIRECT_BUFFER__PRIV(x) ((((unsigned)(x)) & 0x1) << 31)
|
||||
#define PACKET3_INDIRECT_BUFFER__TEMPORAL__RT 0
|
||||
#define PACKET3_INDIRECT_BUFFER__TEMPORAL__NT 1
|
||||
#define PACKET3_INDIRECT_BUFFER__TEMPORAL__HT 2
|
||||
#define PACKET3_INDIRECT_BUFFER__TEMPORAL__LU 3
|
||||
#define PACKET3_INDIRECT_BUFFER__CACHE_POLICY__LRU 0
|
||||
#define PACKET3_INDIRECT_BUFFER__CACHE_POLICY__STREAM 1
|
||||
#define PACKET3_INDIRECT_BUFFER__CACHE_POLICY__NOA 2
|
||||
#define PACKET3_INDIRECT_BUFFER__CACHE_POLICY__BYPASS 3
|
||||
#define PACKET3_COND_INDIRECT_BUFFER 0x3F
|
||||
#define PACKET3_COPY_DATA 0x40
|
||||
#define PACKET3_COPY_DATA__SRC_SEL(x) ((((unsigned)(x)) & 0xF) << 0)
|
||||
#define PACKET3_COPY_DATA__DST_SEL(x) ((((unsigned)(x)) & 0xF) << 8)
|
||||
#define PACKET3_COPY_DATA__SRC_CACHE_POLICY(x) ((((unsigned)(x)) & 0x3) << 13)
|
||||
#define PACKET3_COPY_DATA__SRC_TEMPORAL(x) ((((unsigned)(x)) & 0x3) << 13)
|
||||
#define PACKET3_COPY_DATA__COUNT_SEL(x) ((((unsigned)(x)) & 0x1) << 16)
|
||||
#define PACKET3_COPY_DATA__WR_CONFIRM(x) ((((unsigned)(x)) & 0x1) << 20)
|
||||
#define PACKET3_COPY_DATA__DST_CACHE_POLICY(x) ((((unsigned)(x)) & 0x3) << 25)
|
||||
#define PACKET3_COPY_DATA__PQ_EXE_STATUS(x) ((((unsigned)(x)) & 0x1) << 29)
|
||||
#define PACKET3_COPY_DATA__SRC_REG_OFFSET(x) ((((unsigned)(x)) & 0x3FFFF) << 0)
|
||||
#define PACKET3_COPY_DATA__SRC_32B_ADDR_LO(x) ((((unsigned)(x)) & 0x3FFFFFFF) << 2)
|
||||
#define PACKET3_COPY_DATA__SRC_64B_ADDR_LO(x) ((((unsigned)(x)) & 0x1FFFFFFF) << 3)
|
||||
#define PACKET3_COPY_DATA__SRC_GDS_ADDR_LO(x) ((((unsigned)(x)) & 0xFFFF) << 0)
|
||||
#define PACKET3_COPY_DATA__IMM_DATA(x) ((unsigned)(x))
|
||||
#define PACKET3_COPY_DATA__SRC_MEMTC_ADDR_HI(x) ((unsigned)(x))
|
||||
#define PACKET3_COPY_DATA__SRC_IMM_DATA(x) ((unsigned)(x))
|
||||
#define PACKET3_COPY_DATA__DST_REG_OFFSET(x) ((((unsigned)(x)) & 0x3FFFF) << 0)
|
||||
#define PACKET3_COPY_DATA__DST_32B_ADDR_LO(x) ((((unsigned)(x)) & 0x3FFFFFFF) << 2)
|
||||
#define PACKET3_COPY_DATA__DST_64B_ADDR_LO(x) ((((unsigned)(x)) & 0x1FFFFFFF) << 3)
|
||||
#define PACKET3_COPY_DATA__DST_GDS_ADDR_LO(x) ((((unsigned)(x)) & 0xFFFF) << 0)
|
||||
#define PACKET3_COPY_DATA__DST_ADDR_HI(x) ((unsigned)(x))
|
||||
#define PACKET3_COPY_DATA__MODE(x) ((((unsigned)(x)) & 0x1) << 21)
|
||||
#define PACKET3_COPY_DATA__AID_ID(x) ((((unsigned)(x)) & 0x3) << 23)
|
||||
#define PACKET3_COPY_DATA__DST_TEMPORAL(x) ((((unsigned)(x)) & 0x3) << 25)
|
||||
#define PACKET3_COPY_DATA__SRC_REG_OFFSET_LO(x) ((unsigned)(x))
|
||||
#define PACKET3_COPY_DATA__SRC_REG_OFFSET_HI(x) ((((unsigned)(x)) & 0xFF) << 0)
|
||||
#define PACKET3_COPY_DATA__DST_REG_OFFSET_LO(x) ((unsigned)(x))
|
||||
#define PACKET3_COPY_DATA__DST_REG_OFFSET_HI(x) ((((unsigned)(x)) & 0xFF) << 0)
|
||||
#define PACKET3_COPY_DATA__SRC_SEL__MEM_MAPPED_REGISTER 0
|
||||
#define PACKET3_COPY_DATA__SRC_SEL__TC_L2_OBSOLETE 1
|
||||
#define PACKET3_COPY_DATA__SRC_SEL__TC_L2 2
|
||||
#define PACKET3_COPY_DATA__SRC_SEL__GDS 3
|
||||
#define PACKET3_COPY_DATA__SRC_SEL__PERFCOUNTERS 4
|
||||
#define PACKET3_COPY_DATA__SRC_SEL__IMMEDIATE_DATA 5
|
||||
#define PACKET3_COPY_DATA__SRC_SEL__ATOMIC_RETURN_DATA 6
|
||||
#define PACKET3_COPY_DATA__SRC_SEL__GDS_ATOMIC_RETURN_DATA0 7
|
||||
#define PACKET3_COPY_DATA__SRC_SEL__GDS_ATOMIC_RETURN_DATA1 8
|
||||
#define PACKET3_COPY_DATA__SRC_SEL__GPU_CLOCK_COUNT 9
|
||||
#define PACKET3_COPY_DATA__SRC_SEL__SYSTEM_CLOCK_COUNT 10
|
||||
#define PACKET3_COPY_DATA__DST_SEL__MEM_MAPPED_REGISTER 0
|
||||
#define PACKET3_COPY_DATA__DST_SEL__TC_L2 2
|
||||
#define PACKET3_COPY_DATA__DST_SEL__GDS 3
|
||||
#define PACKET3_COPY_DATA__DST_SEL__PERFCOUNTERS 4
|
||||
#define PACKET3_COPY_DATA__DST_SEL__TC_L2_OBSOLETE 5
|
||||
#define PACKET3_COPY_DATA__DST_SEL__MEM_MAPPED_REG_DC 6
|
||||
#define PACKET3_COPY_DATA__SRC_TEMPORAL__RT 0
|
||||
#define PACKET3_COPY_DATA__SRC_TEMPORAL__NT 1
|
||||
#define PACKET3_COPY_DATA__SRC_TEMPORAL__HT 2
|
||||
#define PACKET3_COPY_DATA__SRC_TEMPORAL__LU 3
|
||||
#define PACKET3_COPY_DATA__SRC_CACHE_POLICY__LRU 0
|
||||
#define PACKET3_COPY_DATA__SRC_CACHE_POLICY__STREAM 1
|
||||
#define PACKET3_COPY_DATA__SRC_CACHE_POLICY__NOA 2
|
||||
#define PACKET3_COPY_DATA__SRC_CACHE_POLICY__BYPASS 3
|
||||
#define PACKET3_COPY_DATA__COUNT_SEL__32_BITS_OF_DATA 0
|
||||
#define PACKET3_COPY_DATA__COUNT_SEL__64_BITS_OF_DATA 1
|
||||
#define PACKET3_COPY_DATA__WR_CONFIRM__DO_NOT_WAIT_FOR_CONFIRMATION 0
|
||||
#define PACKET3_COPY_DATA__WR_CONFIRM__WAIT_FOR_CONFIRMATION 1
|
||||
#define PACKET3_COPY_DATA__MODE__PF_VF_DISABLED 0
|
||||
#define PACKET3_COPY_DATA__MODE__PF_VF_ENABLED 1
|
||||
#define PACKET3_COPY_DATA__DST_TEMPORAL__RT 0
|
||||
#define PACKET3_COPY_DATA__DST_TEMPORAL__NT 1
|
||||
#define PACKET3_COPY_DATA__DST_TEMPORAL__HT 2
|
||||
#define PACKET3_COPY_DATA__DST_TEMPORAL__LU 3
|
||||
#define PACKET3_COPY_DATA__DST_CACHE_POLICY__LRU 0
|
||||
#define PACKET3_COPY_DATA__DST_CACHE_POLICY__STREAM 1
|
||||
#define PACKET3_COPY_DATA__DST_CACHE_POLICY__NOA 2
|
||||
#define PACKET3_COPY_DATA__DST_CACHE_POLICY__BYPASS 3
|
||||
#define PACKET3_COPY_DATA__PQ_EXE_STATUS__DEFAULT 0
|
||||
#define PACKET3_COPY_DATA__PQ_EXE_STATUS__PHASE_UPDATE 1
|
||||
#define PACKET3_CP_DMA 0x41
|
||||
#define PACKET3_PFP_SYNC_ME 0x42
|
||||
#define PACKET3_SURFACE_SYNC 0x43
|
||||
|
|
@ -160,6 +332,23 @@
|
|||
* 3 - SAMPLE_STREAMOUTSTAT*
|
||||
* 4 - *S_PARTIAL_FLUSH
|
||||
*/
|
||||
#define PACKET3_EVENT_WRITE__EVENT_TYPE(x) ((((unsigned)(x)) & 0x3F) << 0)
|
||||
#define PACKET3_EVENT_WRITE__EVENT_INDEX(x) ((((unsigned)(x)) & 0xF) << 8)
|
||||
#define PACKET3_EVENT_WRITE__SAMP_PLST_CNTR_MODE(x) ((((unsigned)(x)) & 0x3) << 29)
|
||||
#define PACKET3_EVENT_WRITE__OFFLOAD_ENABLE(x) ((((unsigned)(x)) & 0x1) << 0)
|
||||
#define PACKET3_EVENT_WRITE__ADDRESS_LO(x) ((((unsigned)(x)) & 0x1FFFFFFF) << 3)
|
||||
#define PACKET3_EVENT_WRITE__ADDRESS_HI(x) ((unsigned)(x))
|
||||
#define PACKET3_EVENT_WRITE__EVENT_INDEX__OTHER 0
|
||||
#define PACKET3_EVENT_WRITE__EVENT_INDEX__SAMPLE_PIPELINESTAT 2
|
||||
#define PACKET3_EVENT_WRITE__EVENT_INDEX__CS_PARTIAL_FLUSH 4
|
||||
#define PACKET3_EVENT_WRITE__EVENT_INDEX__SAMPLE_STREAMOUTSTATS 8
|
||||
#define PACKET3_EVENT_WRITE__EVENT_INDEX__SAMPLE_STREAMOUTSTATS1 9
|
||||
#define PACKET3_EVENT_WRITE__EVENT_INDEX__SAMPLE_STREAMOUTSTATS2 10
|
||||
#define PACKET3_EVENT_WRITE__EVENT_INDEX__SAMPLE_STREAMOUTSTATS3 11
|
||||
#define PACKET3_EVENT_WRITE__SAMP_PLST_CNTR_MODE__LEGACY_MODE 0
|
||||
#define PACKET3_EVENT_WRITE__SAMP_PLST_CNTR_MODE__MIXED_MODE1 1
|
||||
#define PACKET3_EVENT_WRITE__SAMP_PLST_CNTR_MODE__NEW_MODE 2
|
||||
#define PACKET3_EVENT_WRITE__SAMP_PLST_CNTR_MODE__MIXED_MODE3 3
|
||||
#define PACKET3_EVENT_WRITE_EOP 0x47
|
||||
#define PACKET3_EVENT_WRITE_EOS 0x48
|
||||
#define PACKET3_RELEASE_MEM 0x49
|
||||
|
|
@ -304,6 +493,12 @@
|
|||
* 2: REVERSE
|
||||
*/
|
||||
#define PACKET3_ACQUIRE_MEM_GCR_RANGE_IS_PA (1 << 18)
|
||||
#define PACKET3_ACQUIRE_MEM__COHER_SIZE(x) ((unsigned)(x))
|
||||
#define PACKET3_ACQUIRE_MEM__COHER_SIZE_HI(x) ((((unsigned)(x)) & 0xFF) << 0)
|
||||
#define PACKET3_ACQUIRE_MEM__COHER_BASE_LO(x) ((unsigned)(x))
|
||||
#define PACKET3_ACQUIRE_MEM__COHER_BASE_HI(x) ((((unsigned)(x)) & 0xFFFFFF) << 0)
|
||||
#define PACKET3_ACQUIRE_MEM__POLL_INTERVAL(x) ((((unsigned)(x)) & 0xFFFF) << 0)
|
||||
#define PACKET3_ACQUIRE_MEM__GCR_CNTL(x) ((((unsigned)(x)) & 0x7FFFF) << 0)
|
||||
#define PACKET3_REWIND 0x59
|
||||
#define PACKET3_INTERRUPT 0x5A
|
||||
#define PACKET3_GEN_PDEPTE 0x5B
|
||||
|
|
@ -330,11 +525,17 @@
|
|||
#define PACKET3_SET_SH_REG 0x76
|
||||
#define PACKET3_SET_SH_REG_START 0x00002c00
|
||||
#define PACKET3_SET_SH_REG_END 0x00003000
|
||||
#define PACKET3_SET_SH_REG__REG_OFFSET(x) ((((unsigned)(x)) & 0xFFFF) << 0)
|
||||
#define PACKET3_SET_SH_REG__VMID_SHIFT(x) ((((unsigned)(x)) & 0x1F) << 23)
|
||||
#define PACKET3_SET_SH_REG__INDEX(x) ((((unsigned)(x)) & 0xF) << 28)
|
||||
#define PACKET3_SET_SH_REG__INDEX__DEFAULT 0
|
||||
#define PACKET3_SET_SH_REG__INDEX__INSERT_VMID 1
|
||||
#define PACKET3_SET_SH_REG_OFFSET 0x77
|
||||
#define PACKET3_SET_QUEUE_REG 0x78
|
||||
#define PACKET3_SET_UCONFIG_REG 0x79
|
||||
#define PACKET3_SET_UCONFIG_REG_START 0x0000c000
|
||||
#define PACKET3_SET_UCONFIG_REG_END 0x0000c400
|
||||
#define PACKET3_SET_UCONFIG_REG__REG_OFFSET(x) ((((unsigned)(x)) & 0xFFFF) << 0)
|
||||
#define PACKET3_SET_UCONFIG_REG_INDEX 0x7A
|
||||
#define PACKET3_FORWARD_HEADER 0x7C
|
||||
#define PACKET3_SCRATCH_RAM_WRITE 0x7D
|
||||
|
|
@ -369,6 +570,7 @@
|
|||
# define PACKET3_INVALIDATE_TLBS_DST_SEL(x) ((x) << 0)
|
||||
# define PACKET3_INVALIDATE_TLBS_ALL_HUB(x) ((x) << 4)
|
||||
# define PACKET3_INVALIDATE_TLBS_PASID(x) ((x) << 5)
|
||||
# define PACKET3_INVALIDATE_TLBS_FLUSH_TYPE(x) ((x) << 29)
|
||||
#define PACKET3_AQL_PACKET 0x99
|
||||
#define PACKET3_DMA_DATA_FILL_MULTI 0x9A
|
||||
#define PACKET3_SET_SH_REG_INDEX 0x9B
|
||||
|
|
@ -462,6 +664,12 @@
|
|||
# define PACKET3_QUERY_STATUS_ENG_SEL(x) ((x) << 25)
|
||||
#define PACKET3_RUN_LIST 0xA5
|
||||
#define PACKET3_MAP_PROCESS_VM 0xA6
|
||||
|
||||
#define PACKET3_RUN_CLEANER_SHADER 0xD2
|
||||
/* 1. header
|
||||
* 2. RESERVED [31:0]
|
||||
*/
|
||||
|
||||
/* GFX11 */
|
||||
#define PACKET3_SET_Q_PREEMPTION_MODE 0xF0
|
||||
# define PACKET3_SET_Q_PREEMPTION_MODE_IB_VMID(x) ((x) << 0)
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
|
|||
err = psp_init_ta_microcode(psp, ucode_prefix);
|
||||
break;
|
||||
case IP_VERSION(11, 5, 0):
|
||||
case IP_VERSION(11, 5, 2):
|
||||
err = psp_init_asd_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ MODULE_FIRMWARE("amdgpu/psp_14_0_2_sos.bin");
|
|||
MODULE_FIRMWARE("amdgpu/psp_14_0_2_ta.bin");
|
||||
MODULE_FIRMWARE("amdgpu/psp_14_0_3_sos.bin");
|
||||
MODULE_FIRMWARE("amdgpu/psp_14_0_3_ta.bin");
|
||||
MODULE_FIRMWARE("amdgpu/psp_14_0_5_toc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/psp_14_0_5_ta.bin");
|
||||
|
||||
/* For large FW files the time to complete can be very long */
|
||||
#define USBC_PD_POLLING_LIMIT_S 240
|
||||
|
|
@ -72,6 +74,14 @@ static int psp_v14_0_init_microcode(struct psp_context *psp)
|
|||
if (err)
|
||||
return err;
|
||||
break;
|
||||
case IP_VERSION(14, 0, 5):
|
||||
err = psp_init_toc_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
err = psp_init_ta_microcode(psp, ucode_prefix);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1514,9 +1514,9 @@ static int sdma_v3_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void sdma_v3_0_get_clockgating_state(void *handle, u64 *flags)
|
||||
static void sdma_v3_0_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64 *flags)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_device *adev = ip_block->adev;
|
||||
int data;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user