Lines Matching +full:bus +full:- +full:dmc
1 // SPDX-License-Identifier: GPL-2.0
4 * EDAC driver for DMC-520 memory controller.
25 /* DMC-520 registers */
43 /* DMC-520 types, masks and bitfields */
78 * The max-length message would be: "rank:7 bank:15 row:262143 col:1023".
79 * Max length is 34. Using a 40-size buffer is enough.
82 #define EDAC_MOD_NAME "dmc520-edac"
85 /* the data bus width for the attached memory chips. */
165 * error_lock is to protect concurrent writes to the mci->error_desc through
180 return readl(pvt->reg_base + offset); in dmc520_read_reg()
185 writel(val, pvt->reg_base + offset); in dmc520_write_reg()
244 info->col = FIELD_GET(REG_FIELD_ERR_INFO_LOW_COL, reg_val_low); in dmc520_get_dram_ecc_error_info()
245 info->row = FIELD_GET(REG_FIELD_ERR_INFO_LOW_ROW, reg_val_low); in dmc520_get_dram_ecc_error_info()
246 info->rank = FIELD_GET(REG_FIELD_ERR_INFO_LOW_RANK, reg_val_low); in dmc520_get_dram_ecc_error_info()
247 info->bank = FIELD_GET(REG_FIELD_ERR_INFO_HIGH_BANK, reg_val_high); in dmc520_get_dram_ecc_error_info()
275 /* Get the memory data bus width, in number of bytes. */
362 return (u64)pvt->mem_width_in_bytes << (col_bits + row_bits + bank_bits); in dmc520_get_rank_size()
368 struct dmc520_edac *pvt = mci->pvt_info; in dmc520_handle_dram_ecc_errors()
384 spin_lock(&pvt->error_lock); in dmc520_handle_dram_ecc_errors()
387 mci, cnt, 0, 0, 0, info.rank, -1, -1, in dmc520_handle_dram_ecc_errors()
389 spin_unlock(&pvt->error_lock); in dmc520_handle_dram_ecc_errors()
395 struct dmc520_edac *pvt = mci->pvt_info; in dmc520_edac_dram_ecc_isr()
410 struct dmc520_edac *pvt = mci->pvt_info; in dmc520_edac_dram_all_isr()
430 struct dmc520_edac *pvt = mci->pvt_info; in dmc520_isr()
435 if (pvt->irqs[idx] == irq) { in dmc520_isr()
436 mask = pvt->masks[idx]; in dmc520_isr()
445 struct dmc520_edac *pvt = mci->pvt_info; in dmc520_init_csrow()
459 for (row = 0; row < mci->nr_csrows; row++) { in dmc520_init_csrow()
460 csi = mci->csrows[row]; in dmc520_init_csrow()
462 for (ch = 0; ch < csi->nr_channels; ch++) { in dmc520_init_csrow()
463 dimm = csi->channels[ch]->dimm; in dmc520_init_csrow()
464 dimm->grain = pvt->mem_width_in_bytes; in dmc520_init_csrow()
465 dimm->dtype = dt; in dmc520_init_csrow()
466 dimm->mtype = mt; in dmc520_init_csrow()
467 dimm->edac_mode = EDAC_SECDED; in dmc520_init_csrow()
468 dimm->nr_pages = pages_per_rank / csi->nr_channels; in dmc520_init_csrow()
476 int irqs[NUMBER_OF_IRQS] = { -ENXIO }; in dmc520_edac_probe()
488 dev = &pdev->dev; in dmc520_edac_probe()
503 return -EINVAL; in dmc520_edac_probe()
512 return -ENXIO; in dmc520_edac_probe()
522 ret = -ENOMEM; in dmc520_edac_probe()
526 pvt = mci->pvt_info; in dmc520_edac_probe()
528 pvt->reg_base = reg_base; in dmc520_edac_probe()
529 spin_lock_init(&pvt->error_lock); in dmc520_edac_probe()
530 memcpy(pvt->irqs, irqs, sizeof(irqs)); in dmc520_edac_probe()
531 memcpy(pvt->masks, masks, sizeof(masks)); in dmc520_edac_probe()
535 mci->pdev = dev; in dmc520_edac_probe()
536 mci->mtype_cap = MEM_FLAG_DDR3 | MEM_FLAG_DDR4; in dmc520_edac_probe()
537 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; in dmc520_edac_probe()
538 mci->edac_cap = EDAC_FLAG_SECDED; in dmc520_edac_probe()
539 mci->scrub_cap = SCRUB_FLAG_HW_SRC; in dmc520_edac_probe()
540 mci->scrub_mode = dmc520_get_scrub_type(pvt); in dmc520_edac_probe()
541 mci->ctl_name = EDAC_CTL_NAME; in dmc520_edac_probe()
542 mci->dev_name = dev_name(mci->pdev); in dmc520_edac_probe()
543 mci->mod_name = EDAC_MOD_NAME; in dmc520_edac_probe()
547 pvt->mem_width_in_bytes = dmc520_get_memory_width(pvt); in dmc520_edac_probe()
560 ret = devm_request_irq(&pdev->dev, irq, in dmc520_edac_probe()
562 dev_name(&pdev->dev), mci); in dmc520_edac_probe()
595 devm_free_irq(&pdev->dev, pvt->irqs[idx], mci); in dmc520_edac_probe()
610 pvt = mci->pvt_info; in dmc520_edac_remove()
619 if (pvt->irqs[idx] >= 0) { in dmc520_edac_remove()
620 irq_mask_all |= pvt->masks[idx]; in dmc520_edac_remove()
621 devm_free_irq(&pdev->dev, pvt->irqs[idx], mci); in dmc520_edac_remove()
625 edac_mc_del_mc(&pdev->dev); in dmc520_edac_remove()
630 { .compatible = "arm,dmc-520", },
651 MODULE_DESCRIPTION("DMC-520 ECC driver");