Lines Matching +full:external +full:- +full:memory +full:- +full:controller

1 // SPDX-License-Identifier: GPL-2.0
3 * Bluefield-specific EDAC driver.
9 #include <linux/arm-smccc.h>
18 #define DRIVER_NAME "bluefield-edac"
21 * Mellanox BlueField EMI (External Memory Interface) register definitions.
57 * a1: (Memory controller index) << 16 | (Dimm index in memory controller)
58 * a2-7: not used.
62 * a1-3: not used.
66 /* Format for the SMC response about the memory information */
90 * Gather the ECC information from the External Memory Interface registers
97 struct bluefield_edac_priv *priv = mci->pvt_info; in bluefield_gather_report_ecc()
108 * Tell the External Memory Interface to populate the relevant in bluefield_gather_report_ecc()
112 writel(ecc_latch_select, priv->emi_base + MLXBF_ECC_LATCH_SEL); in bluefield_gather_report_ecc()
119 dram_syndrom = readl(priv->emi_base + MLXBF_SYNDROM); in bluefield_gather_report_ecc()
126 0, 0, -1, mci->ctl_name, ""); in bluefield_gather_report_ecc()
130 dram_additional_info = readl(priv->emi_base + MLXBF_ADD_INFO); in bluefield_gather_report_ecc()
133 ecc_dimm = (err_prank >= 2 && priv->dimm_ranks[0] <= 2) ? 1 : 0; in bluefield_gather_report_ecc()
135 edea0 = readl(priv->emi_base + MLXBF_ERR_ADDR_0); in bluefield_gather_report_ecc()
136 edea1 = readl(priv->emi_base + MLXBF_ERR_ADDR_1); in bluefield_gather_report_ecc()
143 syndrom, ecc_dimm, 0, 0, mci->ctl_name, ""); in bluefield_gather_report_ecc()
148 struct bluefield_edac_priv *priv = mci->pvt_info; in bluefield_edac_check()
152 * The memory controller might not be initialized by the firmware in bluefield_edac_check()
153 * when there isn't memory, which may lead to bad register readings. in bluefield_edac_check()
155 if (mci->edac_cap == EDAC_FLAG_NONE) in bluefield_edac_check()
158 ecc_count = readl(priv->emi_base + MLXBF_ECC_CNT); in bluefield_edac_check()
176 writel(ecc_error, priv->emi_base + MLXBF_ECC_ERR); in bluefield_edac_check()
179 /* Initialize the DIMMs information for the given memory controller. */
182 struct bluefield_edac_priv *priv = mci->pvt_info; in bluefield_edac_init_dimms()
183 int mem_ctrl_idx = mci->mc_idx; in bluefield_edac_init_dimms()
188 for (i = 0; i < priv->dimm_per_mc; i++) { in bluefield_edac_init_dimms()
189 dimm = mci->dimms[i]; in bluefield_edac_init_dimms()
195 dimm->mtype = MEM_EMPTY; in bluefield_edac_init_dimms()
201 dimm->edac_mode = EDAC_SECDED; in bluefield_edac_init_dimms()
204 dimm->mtype = MEM_NVDIMM; in bluefield_edac_init_dimms()
206 dimm->mtype = MEM_LRDDR4; in bluefield_edac_init_dimms()
208 dimm->mtype = MEM_RDDR4; in bluefield_edac_init_dimms()
210 dimm->mtype = MEM_DDR4; in bluefield_edac_init_dimms()
212 dimm->nr_pages = in bluefield_edac_init_dimms()
215 dimm->grain = MLXBF_EDAC_ERROR_GRAIN; in bluefield_edac_init_dimms()
217 /* Mem controller for BlueField only supports x4, x8 and x16 */ in bluefield_edac_init_dimms()
220 dimm->dtype = DEV_X4; in bluefield_edac_init_dimms()
223 dimm->dtype = DEV_X8; in bluefield_edac_init_dimms()
226 dimm->dtype = DEV_X16; in bluefield_edac_init_dimms()
229 dimm->dtype = DEV_UNKNOWN; in bluefield_edac_init_dimms()
232 priv->dimm_ranks[i] = in bluefield_edac_init_dimms()
237 mci->edac_cap = EDAC_FLAG_NONE; in bluefield_edac_init_dimms()
239 mci->edac_cap = EDAC_FLAG_SECDED; in bluefield_edac_init_dimms()
245 struct device *dev = &pdev->dev; in bluefield_edac_mc_probe()
252 /* Read the MSS (Memory SubSystem) index from ACPI table. */ in bluefield_edac_mc_probe()
255 return -EINVAL; in bluefield_edac_mc_probe()
261 return -EINVAL; in bluefield_edac_mc_probe()
266 return -EINVAL; in bluefield_edac_mc_probe()
271 return -EINVAL; in bluefield_edac_mc_probe()
279 return -ENOMEM; in bluefield_edac_mc_probe()
281 priv = mci->pvt_info; in bluefield_edac_mc_probe()
283 priv->dimm_per_mc = dimm_count; in bluefield_edac_mc_probe()
284 priv->emi_base = devm_ioremap_resource(dev, emi_res); in bluefield_edac_mc_probe()
285 if (IS_ERR(priv->emi_base)) { in bluefield_edac_mc_probe()
287 ret = PTR_ERR(priv->emi_base); in bluefield_edac_mc_probe()
291 mci->pdev = dev; in bluefield_edac_mc_probe()
292 mci->mtype_cap = MEM_FLAG_DDR4 | MEM_FLAG_RDDR4 | in bluefield_edac_mc_probe()
294 mci->edac_ctl_cap = EDAC_FLAG_SECDED; in bluefield_edac_mc_probe()
296 mci->mod_name = DRIVER_NAME; in bluefield_edac_mc_probe()
297 mci->ctl_name = "BlueField_Memory_Controller"; in bluefield_edac_mc_probe()
298 mci->dev_name = dev_name(dev); in bluefield_edac_mc_probe()
299 mci->edac_check = bluefield_edac_check; in bluefield_edac_mc_probe()
330 edac_mc_del_mc(&pdev->dev); in bluefield_edac_mc_remove()
352 MODULE_DESCRIPTION("Mellanox BlueField memory edac driver");