/* * Configure interrupt enable registers such that Tag, Data RAM related * interrupts are propagated to interrupt controller for servicing
*/
ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_0_enable,
TRP0_INTERRUPT_ENABLE,
TRP0_INTERRUPT_ENABLE); if (ret) return ret;
ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->trp_interrupt_0_enable,
SB_DB_TRP_INTERRUPT_ENABLE,
SB_DB_TRP_INTERRUPT_ENABLE); if (ret) return ret;
sb_err_threshold = (SB_ERROR_THRESHOLD << SB_ERROR_THRESHOLD_SHIFT);
ret = regmap_write(llcc_bcast_regmap, drv->edac_reg_offset->drp_ecc_error_cfg,
sb_err_threshold); if (ret) return ret;
ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_0_enable,
DRP0_INTERRUPT_ENABLE,
DRP0_INTERRUPT_ENABLE); if (ret) return ret;
ret = regmap_write(llcc_bcast_regmap, drv->edac_reg_offset->drp_interrupt_enable,
SB_DB_DRP_INTERRUPT_ENABLE); return ret;
}
/* Clear the error interrupt and counter registers */ staticint
qcom_llcc_clear_error_status(int err_type, struct llcc_drv_data *drv)
{ int ret;
switch (err_type) { case LLCC_DRAM_CE: case LLCC_DRAM_UE:
ret = regmap_write(drv->bcast_regmap,
drv->edac_reg_offset->drp_interrupt_clear,
DRP_TRP_INT_CLEAR); if (ret) return ret;
ret = regmap_write(drv->bcast_regmap,
drv->edac_reg_offset->drp_ecc_error_cntr_clear,
DRP_TRP_CNT_CLEAR); if (ret) return ret; break; case LLCC_TRAM_CE: case LLCC_TRAM_UE:
ret = regmap_write(drv->bcast_regmap,
drv->edac_reg_offset->trp_interrupt_0_clear,
DRP_TRP_INT_CLEAR); if (ret) return ret;
ret = regmap_write(drv->bcast_regmap,
drv->edac_reg_offset->trp_ecc_error_cntr_clear,
DRP_TRP_CNT_CLEAR); if (ret) return ret; break; default:
ret = -EINVAL;
edac_printk(KERN_CRIT, EDAC_LLCC, "Unexpected error type: %d\n",
err_type);
} return ret;
}
/* Dump Syndrome registers data for Tag RAM, Data RAM bit errors*/ staticint
dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type)
{ struct llcc_edac_reg_data reg_data = edac_reg_data[err_type]; struct qcom_llcc_syn_regs regs = { }; int err_cnt, err_ways, ret, i;
u32 synd_reg, synd_val;
get_reg_offsets(drv, err_type, ®s);
for (i = 0; i < reg_data.reg_cnt; i++) {
synd_reg = regs.synd_reg + (i * 4);
ret = regmap_read(drv->regmaps[bank], synd_reg,
&synd_val); if (ret) goto clear;
edac_printk(KERN_CRIT, EDAC_LLCC, "%s: ECC_SYN%d: 0x%8x\n",
reg_data.name, i, synd_val);
}
ret = regmap_read(drv->regmaps[bank], regs.count_status_reg,
&err_cnt); if (ret) goto clear;
staticint
dump_syn_reg(struct edac_device_ctl_info *edev_ctl, int err_type, u32 bank)
{ struct llcc_drv_data *drv = edev_ctl->dev->platform_data; int ret;
ret = dump_syn_reg_values(drv, bank, err_type); if (ret) return ret;
switch (err_type) { case LLCC_DRAM_CE:
edac_device_handle_ce(edev_ctl, 0, bank, "LLCC Data RAM correctable Error"); break; case LLCC_DRAM_UE:
edac_device_handle_ue(edev_ctl, 0, bank, "LLCC Data RAM uncorrectable Error"); break; case LLCC_TRAM_CE:
edac_device_handle_ce(edev_ctl, 0, bank, "LLCC Tag RAM correctable Error"); break; case LLCC_TRAM_UE:
edac_device_handle_ue(edev_ctl, 0, bank, "LLCC Tag RAM uncorrectable Error"); break; default:
ret = -EINVAL;
edac_printk(KERN_CRIT, EDAC_LLCC, "Unexpected error type: %d\n",
err_type);
}
/* Iterate over the banks and look for Tag RAM or Data RAM errors */ for (i = 0; i < drv->num_banks; i++) {
ret = regmap_read(drv->regmaps[i], drv->edac_reg_offset->drp_interrupt_status,
&drp_error);
if (!ret && (drp_error & SB_ECC_ERROR)) {
edac_printk(KERN_CRIT, EDAC_LLCC, "Single Bit Error detected in Data RAM\n");
ret = dump_syn_reg(edev_ctl, LLCC_DRAM_CE, i);
} elseif (!ret && (drp_error & DB_ECC_ERROR)) {
edac_printk(KERN_CRIT, EDAC_LLCC, "Double Bit Error detected in Data RAM\n");
ret = dump_syn_reg(edev_ctl, LLCC_DRAM_UE, i);
} if (!ret)
irq_rc = IRQ_HANDLED;
ret = regmap_read(drv->regmaps[i], drv->edac_reg_offset->trp_interrupt_0_status,
&trp_error);
if (!ret && (trp_error & SB_ECC_ERROR)) {
edac_printk(KERN_CRIT, EDAC_LLCC, "Single Bit Error detected in Tag RAM\n");
ret = dump_syn_reg(edev_ctl, LLCC_TRAM_CE, i);
} elseif (!ret && (trp_error & DB_ECC_ERROR)) {
edac_printk(KERN_CRIT, EDAC_LLCC, "Double Bit Error detected in Tag RAM\n");
ret = dump_syn_reg(edev_ctl, LLCC_TRAM_UE, i);
} if (!ret)
irq_rc = IRQ_HANDLED;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.