drivers/gpu/drm/amd/ras/rascore/ras_aca.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/ras/rascore/ras_aca.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/ras/rascore/ras_aca.c
Extension
.c
Size
20015 bytes
Lines
684
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ras_fw_eeprom_supported(ras_core)) {
			ret = ras_fw_eeprom_update_record(ras_core, &ras_ecc);
			if (!ret) {
				ras_ecc.nps = ras_core_get_curr_nps_mode(ras_core);
				ras_ecc.status = bank_ecc->bank_info.status;
				ras_ecc.seq_no = bank->seq_no;
			}
		} else {
			ras_ecc.nps = ras_core_get_curr_nps_mode(ras_core);
			ras_ecc.addr = bank_ecc->bank_info.addr;
			ras_ecc.ipid = bank_ecc->bank_info.ipid;
			ras_ecc.status = bank_ecc->bank_info.status;
			ras_ecc.seq_no = bank->seq_no;
		}

		if (!ret) {
			if (ras_core_gpu_in_reset(ras_core))
				ras_umc_log_bad_bank_pending(ras_core, &ras_ecc);
			else
				ras_umc_log_bad_bank(ras_core, &ras_ecc);
		}
	}

	aca_report_ecc_info(ras_core,
		bank->seq_no, aca_blk->blk_info->ras_block_id, info->socket_id, info->die_id,
		&aca_blk->ecc.socket[info->socket_id].aid[info->die_id], bank_ecc);

	return 0;
}

static struct aca_block *aca_get_bank_aca_block(struct ras_core_context *ras_core,
				struct aca_bank_reg *bank)
{
	int i = 0;

	for (i = 0; i < RAS_BLOCK_ID__LAST; i++)
		if (aca_match_bank(&ras_core->ras_aca.aca_blk[i], bank))
			return &ras_core->ras_aca.aca_blk[i];

	return NULL;
}

static int aca_dump_bank(struct ras_core_context *ras_core, u32 ecc_type,
			 int idx, void *data)
{
	struct aca_bank_reg *bank = (struct aca_bank_reg *)data;
	int i, ret, reg_cnt;

	reg_cnt = min_t(int, 16, ARRAY_SIZE(bank->regs));
	for (i = 0; i < reg_cnt; i++) {
		ret = ras_mp1_dump_bank(ras_core, ecc_type, idx, i, &bank->regs[i]);
		if (ret)
			return ret;
	}

	return 0;
}

static uint64_t aca_get_bank_seqno(struct ras_core_context *ras_core,
				enum ras_err_type err_type, struct aca_block *aca_blk,
				struct aca_bank_ecc *bank_ecc)
{
	uint64_t seq_no = 0;

	if (bank_ecc->de_count) {
		if (aca_blk->blk_info->ras_block_id == RAS_BLOCK_ID__UMC)
			seq_no = ras_core_get_seqno(ras_core, RAS_SEQNO_TYPE_DE, true);
		else
			seq_no = ras_core_get_seqno(ras_core,
					RAS_SEQNO_TYPE_POISON_CONSUMPTION, true);
	} else if (bank_ecc->ue_count) {
		seq_no = ras_core_get_seqno(ras_core, RAS_SEQNO_TYPE_UE, true);
	} else {
		seq_no = ras_core_get_seqno(ras_core, RAS_SEQNO_TYPE_CE, true);
	}

	return seq_no;
}

static bool aca_dup_update_ue_in_fatal(struct ras_core_context *ras_core,
				u32 ecc_type)
{
	struct ras_aca *aca = &ras_core->ras_aca;

	if (ecc_type != RAS_ERR_TYPE__UE)
		return false;

	if (aca->ue_updated_mark & ACA_MARK_FATAL_FLAG) {
		if (aca->ue_updated_mark & ACA_MARK_UE_READ_FLAG)
			return true;

Annotation

Implementation Notes