Lines Matching +full:ecc +full:- +full:size

1 // SPDX-License-Identifier: GPL-2.0-only
25 * associated with the IMB DDR2 ECC controller found in the AMCC/IBM
30 * - Support for registered- and non-registered DDR1 and DDR2 memory.
31 * - 32-bit or 16-bit memory interface with optional ECC.
33 * o ECC support includes:
35 * - 4-bit SEC/DED
36 * - Aligned-nibble error detect
37 * - Bypass mode
39 * - Two (2) memory banks/ranks.
40 * - Up to 1 GiB per bank/rank in 32-bit mode and up to 512 MiB per
41 * bank/rank in 16-bit mode.
45 * - 64-bit or 32-bit memory interface with optional ECC.
47 * o ECC support includes:
49 * - 8-bit SEC/DED
50 * - Aligned-nibble error detect
51 * - Bypass mode
53 * - Up to 4 GiB per bank/rank in 64-bit mode and up to 2 GiB
54 * per bank/rank in 32-bit mode.
58 * - 64-bit or 32-bit memory interface with optional ECC.
60 * o ECC support includes:
62 * - 8-bit SEC/DED
63 * - Aligned-nibble error detect
64 * - Bypass mode
66 * - Four (4) memory banks/ranks.
67 * - Up to 16 GiB per bank/rank in 64-bit mode and up to 8 GiB
68 * per bank/rank in 32-bit mode.
72 * boards (256 MiB w/o ECC memory soldered onto the board) and a
73 * proprietary board based on those designs (128 MiB ECC memory, also
81 * the other known ECC-capable controllers prevalent in other 4xx
84 * - IBM SDRAM (405GP, 405CR and 405EP) "ibm,sdram-4xx"
85 * - IBM DDR1 (440GP, 440GX, 440EP and 440GR) "ibm,sdram-4xx-ddr"
86 * - Denali DDR1/DDR2 (440EPX and 440GRX) "denali,sdram-4xx-ddr2"
96 * following pieces of information in the driver-unique message to the
99 * - Device tree path
100 * - Bank(s)
101 * - Check bit error group
102 * - Beat(s)/lane(s)
129 * Macros to convert bank configuration size enumerations into MiB and
136 << (20 - PAGE_SHIFT + \
140 * The ibm,sdram-4xx-ddr2 Device Control Registers (DCRs) are
153 #define INTMAP_ECCDED_INDEX 0 /* Double-bit Error Detect */
154 #define INTMAP_ECCSEC_INDEX 1 /* Single-bit Error Correct */
164 int sec; /* Single-bit correctable error IRQ assigned */
165 int ded; /* Double-bit detectable error IRQ assigned */
171 * reporting ECC status.
189 .compatible = "ibm,sdram-4xx-ddr2"
204 * SDRAM_BESR or SDRAM_WMIRQ on uncorrectable ECC errors.
208 [SDRAM_PLB_M0ID_PCIE0] = "PCI-E 0",
209 [SDRAM_PLB_M0ID_PCIE1] = "PCI-E 1",
219 * mfsdram - read and return controller register data
231 return __mfdcri(dcr_host->base + SDRAM_DCR_ADDR_OFFSET, in mfsdram()
232 dcr_host->base + SDRAM_DCR_DATA_OFFSET, in mfsdram()
237 * mtsdram - write controller register data
248 return __mtdcri(dcr_host->base + SDRAM_DCR_ADDR_OFFSET, in mtsdram()
249 dcr_host->base + SDRAM_DCR_DATA_OFFSET, in mtsdram()
255 * ppc4xx_edac_check_bank_error - check a bank for an ECC bank error
256 * @status: A pointer to the ECC status structure to check for an
257 * ECC bank error.
258 * @bank: The bank to check for an ECC error.
260 * This routine determines whether the specified bank has an ECC
263 * Returns true if the specified bank has an ECC error; otherwise,
272 return status->ecces & SDRAM_ECCES_BK0ER; in ppc4xx_edac_check_bank_error()
274 return status->ecces & SDRAM_ECCES_BK1ER; in ppc4xx_edac_check_bank_error()
281 * ppc4xx_edac_generate_bank_message - generate interpretted bank status message
284 * @status: A pointer to the ECC status structure to generate the
288 * @size: The size, in bytes, of space available in buffer.
291 * driver-unique report message associated with the ECCESS[BKNER]
292 * field of the specified ECC status.
301 size_t size) in ppc4xx_edac_generate_bank_message() argument
306 n = snprintf(buffer, size, "%s: Banks: ", mci->dev_name); in ppc4xx_edac_generate_bank_message()
308 if (n < 0 || n >= size) in ppc4xx_edac_generate_bank_message()
312 size -= n; in ppc4xx_edac_generate_bank_message()
315 for (rows = 0, row = 0; row < mci->nr_csrows; row++) { in ppc4xx_edac_generate_bank_message()
317 n = snprintf(buffer, size, "%s%u", in ppc4xx_edac_generate_bank_message()
320 if (n < 0 || n >= size) in ppc4xx_edac_generate_bank_message()
324 size -= n; in ppc4xx_edac_generate_bank_message()
329 n = snprintf(buffer, size, "%s; ", rows ? "" : "None"); in ppc4xx_edac_generate_bank_message()
331 if (n < 0 || n >= size) in ppc4xx_edac_generate_bank_message()
335 size -= n; in ppc4xx_edac_generate_bank_message()
343 * ppc4xx_edac_generate_checkbit_message - generate interpretted checkbit message
346 * @status: A pointer to the ECC status structure to generate the
350 * @size: The size, in bytes, of space available in buffer.
353 * driver-unique report message associated with the ECCESS[CKBER]
354 * field of the specified ECC status.
363 size_t size) in ppc4xx_edac_generate_checkbit_message() argument
365 const struct ppc4xx_edac_pdata *pdata = mci->pvt_info; in ppc4xx_edac_generate_checkbit_message()
368 switch (status->ecces & SDRAM_ECCES_CKBER_MASK) { in ppc4xx_edac_generate_checkbit_message()
376 switch (mfsdram(&pdata->dcr_host, SDRAM_MCOPT1) & in ppc4xx_edac_generate_checkbit_message()
397 return snprintf(buffer, size, "Checkbit Error: %s", ckber); in ppc4xx_edac_generate_checkbit_message()
401 * ppc4xx_edac_generate_lane_message - generate interpretted byte lane message
404 * @status: A pointer to the ECC status structure to generate the
408 * @size: The size, in bytes, of space available in buffer.
411 * driver-unique report message associated with the ECCESS[BNCE]
412 * field of the specified ECC status.
421 size_t size) in ppc4xx_edac_generate_lane_message() argument
428 n = snprintf(buffer, size, "; Byte Lane Errors: "); in ppc4xx_edac_generate_lane_message()
430 if (n < 0 || n >= size) in ppc4xx_edac_generate_lane_message()
434 size -= n; in ppc4xx_edac_generate_lane_message()
438 if ((status->ecces & SDRAM_ECCES_BNCE_ENCODE(lane)) != 0) { in ppc4xx_edac_generate_lane_message()
439 n = snprintf(buffer, size, in ppc4xx_edac_generate_lane_message()
443 if (n < 0 || n >= size) in ppc4xx_edac_generate_lane_message()
447 size -= n; in ppc4xx_edac_generate_lane_message()
452 n = snprintf(buffer, size, "%s; ", lanes ? "" : "None"); in ppc4xx_edac_generate_lane_message()
454 if (n < 0 || n >= size) in ppc4xx_edac_generate_lane_message()
458 size -= n; in ppc4xx_edac_generate_lane_message()
466 * ppc4xx_edac_generate_ecc_message - generate interpretted ECC status message
469 * @status: A pointer to the ECC status structure to generate the
473 * @size: The size, in bytes, of space available in buffer.
476 * driver-unique report message associated with the ECCESS register of
477 * the specified ECC status.
486 size_t size) in ppc4xx_edac_generate_ecc_message() argument
490 n = ppc4xx_edac_generate_bank_message(mci, status, buffer, size); in ppc4xx_edac_generate_ecc_message()
492 if (n < 0 || n >= size) in ppc4xx_edac_generate_ecc_message()
496 size -= n; in ppc4xx_edac_generate_ecc_message()
499 n = ppc4xx_edac_generate_checkbit_message(mci, status, buffer, size); in ppc4xx_edac_generate_ecc_message()
501 if (n < 0 || n >= size) in ppc4xx_edac_generate_ecc_message()
505 size -= n; in ppc4xx_edac_generate_ecc_message()
508 n = ppc4xx_edac_generate_lane_message(mci, status, buffer, size); in ppc4xx_edac_generate_ecc_message()
510 if (n < 0 || n >= size) in ppc4xx_edac_generate_ecc_message()
514 size -= n; in ppc4xx_edac_generate_ecc_message()
522 * ppc4xx_edac_generate_plb_message - generate interpretted PLB status message
525 * @status: A pointer to the ECC status structure to generate the
529 * @size: The size, in bytes, of space available in buffer.
532 * driver-unique report message associated with the PLB-related BESR
533 * and/or WMIRQ registers of the specified ECC status.
542 size_t size) in ppc4xx_edac_generate_plb_message() argument
547 if ((status->besr & SDRAM_BESR_MASK) == 0) in ppc4xx_edac_generate_plb_message()
550 if ((status->besr & SDRAM_BESR_M0ET_MASK) == SDRAM_BESR_M0ET_NONE) in ppc4xx_edac_generate_plb_message()
553 read = ((status->besr & SDRAM_BESR_M0RW_MASK) == SDRAM_BESR_M0RW_READ); in ppc4xx_edac_generate_plb_message()
555 master = SDRAM_BESR_M0ID_DECODE(status->besr); in ppc4xx_edac_generate_plb_message()
557 return snprintf(buffer, size, in ppc4xx_edac_generate_plb_message()
567 * ppc4xx_edac_generate_message - generate interpretted status message
569 * with the driver-unique message being generated.
570 * @status: A pointer to the ECC status structure to generate the
574 * @size: The size, in bytes, of space available in buffer.
576 * This routine generates to the provided buffer the driver-unique
577 * EDAC report message from the specified ECC status.
583 size_t size) in ppc4xx_edac_generate_message() argument
587 if (buffer == NULL || size == 0) in ppc4xx_edac_generate_message()
590 n = ppc4xx_edac_generate_ecc_message(mci, status, buffer, size); in ppc4xx_edac_generate_message()
592 if (n < 0 || n >= size) in ppc4xx_edac_generate_message()
596 size -= n; in ppc4xx_edac_generate_message()
598 ppc4xx_edac_generate_plb_message(mci, status, buffer, size); in ppc4xx_edac_generate_message()
603 * ppc4xx_ecc_dump_status - dump controller ECC status registers
606 * @status: A pointer to the ECC status structure to generate the
610 * interpretted specified ECC status.
627 status->ecces, in ppc4xx_ecc_dump_status()
628 status->wmirq, in ppc4xx_ecc_dump_status()
629 status->besr, in ppc4xx_ecc_dump_status()
630 status->bearh, in ppc4xx_ecc_dump_status()
631 status->bearl, in ppc4xx_ecc_dump_status()
637 * ppc4xx_ecc_get_status - get controller ECC status
640 * @status: A pointer to the ECC status structure to populate the
641 * ECC status with.
644 * status registers that deal with ibm,sdram-4xx-ddr2 ECC errors.
653 const struct ppc4xx_edac_pdata *pdata = mci->pvt_info; in ppc4xx_ecc_get_status()
654 const dcr_host_t *dcr_host = &pdata->dcr_host; in ppc4xx_ecc_get_status()
656 status->ecces = mfsdram(dcr_host, SDRAM_ECCES) & SDRAM_ECCES_MASK; in ppc4xx_ecc_get_status()
657 status->wmirq = mfsdram(dcr_host, SDRAM_WMIRQ) & SDRAM_WMIRQ_MASK; in ppc4xx_ecc_get_status()
658 status->besr = mfsdram(dcr_host, SDRAM_BESR) & SDRAM_BESR_MASK; in ppc4xx_ecc_get_status()
659 status->bearl = mfsdram(dcr_host, SDRAM_BEARL); in ppc4xx_ecc_get_status()
660 status->bearh = mfsdram(dcr_host, SDRAM_BEARH); in ppc4xx_ecc_get_status()
664 * ppc4xx_ecc_clear_status - clear controller ECC status
667 * @status: A pointer to the ECC status structure containing the
668 * values to write to clear the ECC status.
670 * This routine clears--by writing the masked (as appropriate) status
671 * values back to--the status registers that deal with
672 * ibm,sdram-4xx-ddr2 ECC errors.
678 const struct ppc4xx_edac_pdata *pdata = mci->pvt_info; in ppc4xx_ecc_clear_status()
679 const dcr_host_t *dcr_host = &pdata->dcr_host; in ppc4xx_ecc_clear_status()
681 mtsdram(dcr_host, SDRAM_ECCES, status->ecces & SDRAM_ECCES_MASK); in ppc4xx_ecc_clear_status()
682 mtsdram(dcr_host, SDRAM_WMIRQ, status->wmirq & SDRAM_WMIRQ_MASK); in ppc4xx_ecc_clear_status()
683 mtsdram(dcr_host, SDRAM_BESR, status->besr & SDRAM_BESR_MASK); in ppc4xx_ecc_clear_status()
689 * ppc4xx_edac_handle_ce - handle controller correctable ECC error (CE)
692 * @status: A pointer to the ECC status structure associated with
695 * This routine handles an ibm,sdram-4xx-ddr2 controller ECC
698 * interface, so we just pass driver-unique message to the "no info"
710 for (row = 0; row < mci->nr_csrows; row++) in ppc4xx_edac_handle_ce()
714 row, 0, -1, in ppc4xx_edac_handle_ce()
719 * ppc4xx_edac_handle_ue - handle controller uncorrectable ECC error (UE)
723 * @status: A pointer to the ECC status structure associated with
726 * This routine handles an ibm,sdram-4xx-ddr2 controller ECC
733 const u64 bear = ((u64)status->bearh << 32 | status->bearl); in ppc4xx_edac_handle_ue()
741 for (row = 0; row < mci->nr_csrows; row++) in ppc4xx_edac_handle_ue()
745 row, 0, -1, in ppc4xx_edac_handle_ue()
750 * ppc4xx_edac_check - check controller for ECC errors
752 * associated with the ibm,sdram-4xx-ddr2 controller being
755 * This routine is used to check and post ECC errors and is called by
784 * ppc4xx_edac_isr - SEC (CE) and DED (UE) interrupt service routine
790 * (CE) and uncorrectable (UE) ECC errors for the ibm,sdram-4xx-ddr2
792 * polling to check, report and clear the ECC status.
807 * ppc4xx_edac_get_dtype - return the controller memory width
808 * @mcopt1: The 32-bit Memory Controller Option 1 register value
817 * the 405EX[r] is 16-/32-bit and the others are 32-/64-bit with the
818 * 16- and 64-bit field definition/value/enumeration (b1) overloaded
836 * ppc4xx_edac_get_mtype - return controller memory type
837 * @mcopt1: The 32-bit Memory Controller Option 1 register value
861 * ppc4xx_edac_init_csrows - initialize driver instance rows
863 * associated with the ibm,sdram-4xx-ddr2 controller for which
865 * @mcopt1: The 32-bit Memory Controller Option 1 register value
870 * with the EDAC memory controller instance. An ibm,sdram-4xx-ddr2
873 * Returns 0 if OK; otherwise, -EINVAL if the memory bank size
878 const struct ppc4xx_edac_pdata *pdata = mci->pvt_info; in ppc4xx_edac_init_csrows()
884 u32 mbxcf, size, nr_pages; in ppc4xx_edac_init_csrows() local
893 if (mci->edac_cap & EDAC_FLAG_SECDED) in ppc4xx_edac_init_csrows()
895 else if (mci->edac_cap & EDAC_FLAG_EC) in ppc4xx_edac_init_csrows()
905 for (row = 0; row < mci->nr_csrows; row++) { in ppc4xx_edac_init_csrows()
906 struct csrow_info *csi = mci->csrows[row]; in ppc4xx_edac_init_csrows()
913 mbxcf = mfsdram(&pdata->dcr_host, SDRAM_MBXCF(row)); in ppc4xx_edac_init_csrows()
918 /* Map the bank configuration size setting to pages. */ in ppc4xx_edac_init_csrows()
920 size = mbxcf & SDRAM_MBCF_SZ_MASK; in ppc4xx_edac_init_csrows()
922 switch (size) { in ppc4xx_edac_init_csrows()
935 nr_pages = SDRAM_MBCF_SZ_TO_PAGES(size); in ppc4xx_edac_init_csrows()
940 "size 0x%08x\n", in ppc4xx_edac_init_csrows()
941 row, SDRAM_MBCF_SZ_DECODE(size)); in ppc4xx_edac_init_csrows()
942 status = -EINVAL; in ppc4xx_edac_init_csrows()
956 * page size (PAGE_SIZE) or the memory width (2 or 4). in ppc4xx_edac_init_csrows()
958 for (j = 0; j < csi->nr_channels; j++) { in ppc4xx_edac_init_csrows()
959 struct dimm_info *dimm = csi->channels[j]->dimm; in ppc4xx_edac_init_csrows()
961 dimm->nr_pages = nr_pages / csi->nr_channels; in ppc4xx_edac_init_csrows()
962 dimm->grain = 1; in ppc4xx_edac_init_csrows()
964 dimm->mtype = mtype; in ppc4xx_edac_init_csrows()
965 dimm->dtype = dtype; in ppc4xx_edac_init_csrows()
967 dimm->edac_mode = edac_mode; in ppc4xx_edac_init_csrows()
976 * ppc4xx_edac_mc_init - initialize driver instance
983 * @mcopt1: The 32-bit Memory Controller Option 1 register value
984 * currently set for the controller, from which ECC capabilities
988 * instance and related driver-private data associated with the
989 * ibm,sdram-4xx-ddr2 memory controller the instance is bound to.
1000 const struct device_node *np = op->dev.of_node; in ppc4xx_edac_mc_init()
1002 if (of_match_device(ppc4xx_edac_match, &op->dev) == NULL) in ppc4xx_edac_mc_init()
1003 return -EINVAL; in ppc4xx_edac_mc_init()
1007 mci->pdev = &op->dev; in ppc4xx_edac_mc_init()
1009 dev_set_drvdata(mci->pdev, mci); in ppc4xx_edac_mc_init()
1011 pdata = mci->pvt_info; in ppc4xx_edac_mc_init()
1013 pdata->dcr_host = *dcr_host; in ppc4xx_edac_mc_init()
1017 mci->mtype_cap = (MEM_FLAG_DDR | MEM_FLAG_RDDR | in ppc4xx_edac_mc_init()
1020 mci->edac_ctl_cap = (EDAC_FLAG_NONE | in ppc4xx_edac_mc_init()
1024 mci->scrub_cap = SCRUB_NONE; in ppc4xx_edac_mc_init()
1025 mci->scrub_mode = SCRUB_NONE; in ppc4xx_edac_mc_init()
1034 mci->edac_cap = EDAC_FLAG_EC; in ppc4xx_edac_mc_init()
1037 mci->edac_cap = (EDAC_FLAG_EC | EDAC_FLAG_SECDED); in ppc4xx_edac_mc_init()
1038 mci->scrub_mode = SCRUB_SW_SRC; in ppc4xx_edac_mc_init()
1041 mci->edac_cap = EDAC_FLAG_NONE; in ppc4xx_edac_mc_init()
1047 mci->mod_name = PPC4XX_EDAC_MODULE_NAME; in ppc4xx_edac_mc_init()
1048 mci->ctl_name = ppc4xx_edac_match->compatible; in ppc4xx_edac_mc_init()
1049 mci->dev_name = np->full_name; in ppc4xx_edac_mc_init()
1053 mci->edac_check = ppc4xx_edac_check; in ppc4xx_edac_mc_init()
1054 mci->ctl_page_to_phys = NULL; in ppc4xx_edac_mc_init()
1068 * ppc4xx_edac_register_irq - setup and register controller interrupts
1072 * associated with the ibm,sdram-4xx-ddr2 controller for which
1079 * Returns 0 if OK; otherwise, -ENODEV if the interrupts could not be
1087 struct ppc4xx_edac_pdata *pdata = mci->pvt_info; in ppc4xx_edac_register_irq()
1088 struct device_node *np = op->dev.of_node; in ppc4xx_edac_register_irq()
1096 status = -ENODEV; in ppc4xx_edac_register_irq()
1108 "Unable to request irq %d for ECC DED", in ppc4xx_edac_register_irq()
1110 status = -ENODEV; in ppc4xx_edac_register_irq()
1122 "Unable to request irq %d for ECC SEC", in ppc4xx_edac_register_irq()
1124 status = -ENODEV; in ppc4xx_edac_register_irq()
1131 pdata->irqs.ded = ded_irq; in ppc4xx_edac_register_irq()
1132 pdata->irqs.sec = sec_irq; in ppc4xx_edac_register_irq()
1147 * ppc4xx_edac_map_dcrs - locate and map controller registers
1166 return -EINVAL; in ppc4xx_edac_map_dcrs()
1176 return -ENODEV; in ppc4xx_edac_map_dcrs()
1183 return -ENODEV; in ppc4xx_edac_map_dcrs()
1192 return -ENODEV; in ppc4xx_edac_map_dcrs()
1199 * ppc4xx_edac_probe - check controller and bind driver
1203 * This routine probes a specific ibm,sdram-4xx-ddr2 controller
1214 const struct device_node *np = op->dev.of_node; in ppc4xx_edac_probe()
1224 if (!of_device_is_compatible(np, "ibm,sdram-405ex") && in ppc4xx_edac_probe()
1225 !of_device_is_compatible(np, "ibm,sdram-405exr")) { in ppc4xx_edac_probe()
1228 return -ENODEV; in ppc4xx_edac_probe()
1242 * First determine whether ECC is enabled at all. If not, in ppc4xx_edac_probe()
1251 ppc4xx_edac_printk(KERN_INFO, "%pOF: No ECC memory detected or " in ppc4xx_edac_probe()
1252 "ECC is disabled.\n", np); in ppc4xx_edac_probe()
1253 status = -ENODEV; in ppc4xx_edac_probe()
1258 * At this point, we know ECC is enabled, allocate an EDAC in ppc4xx_edac_probe()
1263 layers[0].size = ppc4xx_edac_nr_csrows; in ppc4xx_edac_probe()
1266 layers[1].size = ppc4xx_edac_nr_chans; in ppc4xx_edac_probe()
1274 status = -ENOMEM; in ppc4xx_edac_probe()
1295 status = -ENODEV; in ppc4xx_edac_probe()
1311 edac_mc_del_mc(mci->pdev); in ppc4xx_edac_probe()
1321 * ppc4xx_edac_remove - unbind driver from controller
1327 * with the specified ibm,sdram-4xx-ddr2 controller described by the
1335 struct mem_ctl_info *mci = dev_get_drvdata(&op->dev); in ppc4xx_edac_remove()
1336 struct ppc4xx_edac_pdata *pdata = mci->pvt_info; in ppc4xx_edac_remove()
1339 free_irq(pdata->irqs.sec, mci); in ppc4xx_edac_remove()
1340 free_irq(pdata->irqs.ded, mci); in ppc4xx_edac_remove()
1343 dcr_unmap(pdata->dcr_host, SDRAM_DCR_RESOURCE_LEN); in ppc4xx_edac_remove()
1345 edac_mc_del_mc(mci->pdev); in ppc4xx_edac_remove()
1352 * ppc4xx_edac_opstate_init - initialize EDAC reporting method
1390 * ppc4xx_edac_init - driver/module insertion entry point
1408 * ppc4xx_edac_exit - driver/module removal entry point