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:
  e663bed7d6

From: 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:
Dave Airlie 2025-02-26 16:41:44 +10:00
commit 425b848175
361 changed files with 87605 additions and 16753 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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(&params->tlb_flush_waitlist))
return;
if (unlocked) {
spin_lock(&vm->status_lock);
list_splice_init(&params->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, &params->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);

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,7 +21,6 @@
*
*/
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "hdp_v4_0.h"
#include "amdgpu_ras.h"

View File

@ -21,7 +21,6 @@
*
*/
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "hdp_v5_0.h"
#include "hdp/hdp_5_0_0_offset.h"

View File

@ -21,7 +21,6 @@
*
*/
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "hdp_v5_2.h"
#include "hdp/hdp_5_2_1_offset.h"

View File

@ -21,7 +21,6 @@
*
*/
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "hdp_v6_0.h"
#include "hdp/hdp_6_0_0_offset.h"

View File

@ -21,7 +21,6 @@
*
*/
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "hdp_v7_0.h"
#include "hdp/hdp_7_0_0_offset.h"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,7 +21,6 @@
*
*/
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "nbio_v2_3.h"
#include "nbio/nbio_2_3_default.h"

View File

@ -21,7 +21,6 @@
*
*/
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "nbio_v4_3.h"
#include "nbio/nbio_4_3_0_offset.h"

View File

@ -21,7 +21,6 @@
*
*/
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "nbio_v6_1.h"
#include "nbio/nbio_6_1_default.h"

View File

@ -21,7 +21,6 @@
*
*/
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "nbio_v7_0.h"
#include "nbio/nbio_7_0_default.h"

View File

@ -21,7 +21,6 @@
*
*/
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "nbio_v7_11.h"
#include "nbio/nbio_7_11_0_offset.h"

View File

@ -21,7 +21,6 @@
*
*/
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "nbio_v7_2.h"
#include "nbio/nbio_7_2_0_offset.h"

View File

@ -21,7 +21,6 @@
*
*/
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "nbio_v7_4.h"
#include "amdgpu_ras.h"

View File

@ -21,7 +21,6 @@
*
*/
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "nbio_v7_7.h"
#include "nbio/nbio_7_7_0_offset.h"

View File

@ -21,7 +21,6 @@
*
*/
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "nbio_v7_9.h"
#include "amdgpu_ras.h"

View File

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

View File

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

View File

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

View File

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

View File

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