Lines Matching +full:npcm750 +full:- +full:memory +full:- +full:controller
1 // SPDX-License-Identifier: GPL-2.0-only
11 #define EDAC_MOD_NAME "npcm-edac"
46 /* memory controller registers */
106 struct priv_data *priv = mci->pvt_info; in handle_ce()
111 pdata = priv->pdata; in handle_ce()
112 regmap_read(npcm_regmap, pdata->ctl_ce_addr_l, &val_l); in handle_ce()
113 if (pdata->chip == NPCM8XX_CHIP) { in handle_ce()
114 regmap_read(npcm_regmap, pdata->ctl_ce_addr_h, &val_h); in handle_ce()
115 val_h &= pdata->ce_addr_h_mask; in handle_ce()
119 regmap_read(npcm_regmap, pdata->ctl_ce_data_l, &val_l); in handle_ce()
120 if (pdata->chip == NPCM8XX_CHIP) in handle_ce()
121 regmap_read(npcm_regmap, pdata->ctl_ce_data_h, &val_h); in handle_ce()
124 regmap_read(npcm_regmap, pdata->ctl_source_id, &id); in handle_ce()
125 id = (id & pdata->source_id_ce_mask) >> pdata->source_id_ce_shift; in handle_ce()
127 regmap_read(npcm_regmap, pdata->ctl_ce_synd, &synd); in handle_ce()
128 synd = (synd & pdata->ce_synd_mask) >> pdata->ce_synd_shift; in handle_ce()
130 snprintf(priv->message, EDAC_MSG_SIZE, in handle_ce()
134 addr & ~PAGE_MASK, synd, 0, 0, -1, priv->message, ""); in handle_ce()
139 struct priv_data *priv = mci->pvt_info; in handle_ue()
144 pdata = priv->pdata; in handle_ue()
145 regmap_read(npcm_regmap, pdata->ctl_ue_addr_l, &val_l); in handle_ue()
146 if (pdata->chip == NPCM8XX_CHIP) { in handle_ue()
147 regmap_read(npcm_regmap, pdata->ctl_ue_addr_h, &val_h); in handle_ue()
148 val_h &= pdata->ue_addr_h_mask; in handle_ue()
152 regmap_read(npcm_regmap, pdata->ctl_ue_data_l, &val_l); in handle_ue()
153 if (pdata->chip == NPCM8XX_CHIP) in handle_ue()
154 regmap_read(npcm_regmap, pdata->ctl_ue_data_h, &val_h); in handle_ue()
157 regmap_read(npcm_regmap, pdata->ctl_source_id, &id); in handle_ue()
158 id = (id & pdata->source_id_ue_mask) >> pdata->source_id_ue_shift; in handle_ue()
160 regmap_read(npcm_regmap, pdata->ctl_ue_synd, &synd); in handle_ue()
161 synd = (synd & pdata->ue_synd_mask) >> pdata->ue_synd_shift; in handle_ue()
163 snprintf(priv->message, EDAC_MSG_SIZE, in handle_ue()
167 addr & ~PAGE_MASK, synd, 0, 0, -1, priv->message, ""); in handle_ue()
176 pdata = ((struct priv_data *)mci->pvt_info)->pdata; in edac_ecc_isr()
177 regmap_read(npcm_regmap, pdata->ctl_int_status, &status); in edac_ecc_isr()
178 if (status & pdata->int_status_ce_mask) { in edac_ecc_isr()
182 regmap_write(npcm_regmap, pdata->ctl_int_ack, in edac_ecc_isr()
183 pdata->int_ack_ce_mask); in edac_ecc_isr()
185 } else if (status & pdata->int_status_ue_mask) { in edac_ecc_isr()
189 regmap_write(npcm_regmap, pdata->ctl_int_ack, in edac_ecc_isr()
190 pdata->int_ack_ue_mask); in edac_ecc_isr()
201 struct device *dev = file->private_data; in force_ecc_error()
203 struct priv_data *priv = mci->pvt_info; in force_ecc_error()
208 pdata = priv->pdata; in force_ecc_error()
211 priv->error_type, priv->location, priv->bit); in force_ecc_error()
214 ret = regmap_read_poll_timeout(npcm_regmap, pdata->ctl_controller_busy, in force_ecc_error()
215 val, !(val & pdata->controller_busy_mask), in force_ecc_error()
223 regmap_read(npcm_regmap, pdata->ctl_xor_check_bits, &val); in force_ecc_error()
224 val &= ~pdata->xor_check_bits_mask; in force_ecc_error()
227 if (priv->error_type == ERROR_TYPE_CORRECTABLE) { in force_ecc_error()
228 if (priv->location == ERROR_LOCATION_DATA && in force_ecc_error()
229 priv->bit > ERROR_BIT_DATA_MAX) { in force_ecc_error()
232 ERROR_BIT_DATA_MAX, priv->bit); in force_ecc_error()
236 if (priv->location == ERROR_LOCATION_CHECKCODE && in force_ecc_error()
237 priv->bit > ERROR_BIT_CHECKCODE_MAX) { in force_ecc_error()
240 ERROR_BIT_CHECKCODE_MAX, priv->bit); in force_ecc_error()
244 syndrome = priv->location ? 1 << priv->bit in force_ecc_error()
245 : data_synd[priv->bit]; in force_ecc_error()
247 regmap_write(npcm_regmap, pdata->ctl_xor_check_bits, in force_ecc_error()
248 val | (syndrome << pdata->xor_check_bits_shift) | in force_ecc_error()
249 pdata->writeback_en_mask); in force_ecc_error()
250 } else if (priv->error_type == ERROR_TYPE_UNCORRECTABLE) { in force_ecc_error()
251 regmap_write(npcm_regmap, pdata->ctl_xor_check_bits, in force_ecc_error()
252 val | (UE_SYNDROME << pdata->xor_check_bits_shift)); in force_ecc_error()
256 regmap_update_bits(npcm_regmap, pdata->ctl_xor_check_bits, in force_ecc_error()
257 pdata->fwc_mask, pdata->fwc_mask); in force_ecc_error()
272 * error_type - 0: CE, 1: UE
273 * location - 0: data, 1: checkcode
274 * bit - 0 ~ 63 for data and 0 ~ 7 for checkcode
275 * force_ecc_error - trigger
279 * ~# echo 0 > /sys/kernel/debug/edac/npcm-edac/error_type
280 * ~# echo 1 > /sys/kernel/debug/edac/npcm-edac/location
281 * ~# echo 7 > /sys/kernel/debug/edac/npcm-edac/bit
282 * ~# echo 1 > /sys/kernel/debug/edac/npcm-edac/force_ecc_error
285 * ~# echo 1 > /sys/kernel/debug/edac/npcm-edac/error_type
286 * ~# echo 1 > /sys/kernel/debug/edac/npcm-edac/force_ecc_error
290 struct priv_data *priv = mci->pvt_info; in setup_debugfs()
292 priv->debugfs = edac_debugfs_create_dir(mci->mod_name); in setup_debugfs()
293 if (!priv->debugfs) in setup_debugfs()
296 edac_debugfs_create_x8("error_type", 0644, priv->debugfs, &priv->error_type); in setup_debugfs()
297 edac_debugfs_create_x8("location", 0644, priv->debugfs, &priv->location); in setup_debugfs()
298 edac_debugfs_create_x8("bit", 0644, priv->debugfs, &priv->bit); in setup_debugfs()
299 edac_debugfs_create_file("force_ecc_error", 0200, priv->debugfs, in setup_debugfs()
300 &mci->dev, &force_ecc_error_fops); in setup_debugfs()
308 pdata = ((struct priv_data *)mci->pvt_info)->pdata; in setup_irq()
315 ret = devm_request_irq(&pdev->dev, irq, edac_ecc_isr, 0, in setup_irq()
316 dev_name(&pdev->dev), mci); in setup_irq()
323 regmap_write(npcm_regmap, pdata->ctl_int_mask_master, in setup_irq()
324 pdata->int_mask_master_non_ecc_mask); in setup_irq()
326 if (pdata->chip == NPCM8XX_CHIP) in setup_irq()
327 regmap_write(npcm_regmap, pdata->ctl_int_mask_ecc, in setup_irq()
328 pdata->int_mask_ecc_non_event_mask); in setup_irq()
342 struct device *dev = &pdev->dev; in edac_probe()
360 return -EINVAL; in edac_probe()
363 regmap_read(npcm_regmap, pdata->ctl_ecc_en, &val); in edac_probe()
364 if (!(val & pdata->ecc_en_mask)) { in edac_probe()
366 return -EPERM; in edac_probe()
377 return -ENOMEM; in edac_probe()
379 mci->pdev = &pdev->dev; in edac_probe()
380 priv = mci->pvt_info; in edac_probe()
381 priv->reg = reg; in edac_probe()
382 priv->pdata = pdata; in edac_probe()
385 mci->mtype_cap = MEM_FLAG_DDR4; in edac_probe()
386 mci->edac_ctl_cap = EDAC_FLAG_SECDED; in edac_probe()
387 mci->scrub_cap = SCRUB_FLAG_HW_SRC; in edac_probe()
388 mci->scrub_mode = SCRUB_HW_SRC; in edac_probe()
389 mci->edac_cap = EDAC_FLAG_SECDED; in edac_probe()
390 mci->ctl_name = "npcm_ddr_controller"; in edac_probe()
391 mci->dev_name = dev_name(&pdev->dev); in edac_probe()
392 mci->mod_name = EDAC_MOD_NAME; in edac_probe()
393 mci->ctl_page_to_phys = NULL; in edac_probe()
403 if (IS_ENABLED(CONFIG_EDAC_DEBUG) && pdata->chip == NPCM8XX_CHIP) in edac_probe()
416 struct priv_data *priv = mci->pvt_info; in edac_remove()
419 pdata = priv->pdata; in edac_remove()
420 if (IS_ENABLED(CONFIG_EDAC_DEBUG) && pdata->chip == NPCM8XX_CHIP) in edac_remove()
421 edac_debugfs_remove_recursive(priv->debugfs); in edac_remove()
423 edac_mc_del_mc(&pdev->dev); in edac_remove()
426 regmap_write(npcm_regmap, pdata->ctl_int_mask_master, in edac_remove()
427 pdata->int_mask_master_global_mask); in edac_remove()
428 regmap_update_bits(npcm_regmap, pdata->ctl_ecc_en, pdata->ecc_en_mask, 0); in edac_remove()
434 /* memory controller registers */
468 /* memory controller registers */
516 .compatible = "nuvoton,npcm750-memory-controller",
520 .compatible = "nuvoton,npcm845-memory-controller",
530 .name = "npcm-edac",