|
10 | 10 | #include <linux/module.h>
|
11 | 11 | #include <linux/platform_device.h>
|
12 | 12 | #include <linux/spinlock.h>
|
| 13 | +#include <linux/sizes.h> |
13 | 14 | #include <linux/interrupt.h>
|
14 | 15 | #include <linux/of.h>
|
15 | 16 |
|
@@ -337,13 +338,17 @@ struct synps_edac_priv {
|
337 | 338 | * @get_mtype: Get mtype.
|
338 | 339 | * @get_dtype: Get dtype.
|
339 | 340 | * @get_ecc_state: Get ECC state.
|
| 341 | + * @get_mem_info: Get EDAC memory info |
340 | 342 | * @quirks: To differentiate IPs.
|
341 | 343 | */
|
342 | 344 | struct synps_platform_data {
|
343 | 345 | int (*get_error_info)(struct synps_edac_priv *priv);
|
344 | 346 | enum mem_type (*get_mtype)(const void __iomem *base);
|
345 | 347 | enum dev_type (*get_dtype)(const void __iomem *base);
|
346 | 348 | bool (*get_ecc_state)(void __iomem *base);
|
| 349 | +#ifdef CONFIG_EDAC_DEBUG |
| 350 | + u64 (*get_mem_info)(struct synps_edac_priv *priv); |
| 351 | +#endif |
347 | 352 | int quirks;
|
348 | 353 | };
|
349 | 354 |
|
@@ -402,6 +407,25 @@ static int zynq_get_error_info(struct synps_edac_priv *priv)
|
402 | 407 | return 0;
|
403 | 408 | }
|
404 | 409 |
|
| 410 | +#ifdef CONFIG_EDAC_DEBUG |
| 411 | +/** |
| 412 | + * zynqmp_get_mem_info - Get the current memory info. |
| 413 | + * @priv: DDR memory controller private instance data. |
| 414 | + * |
| 415 | + * Return: host interface address. |
| 416 | + */ |
| 417 | +static u64 zynqmp_get_mem_info(struct synps_edac_priv *priv) |
| 418 | +{ |
| 419 | + u64 hif_addr = 0, linear_addr; |
| 420 | + |
| 421 | + linear_addr = priv->poison_addr; |
| 422 | + if (linear_addr >= SZ_32G) |
| 423 | + linear_addr = linear_addr - SZ_32G + SZ_2G; |
| 424 | + hif_addr = linear_addr >> 3; |
| 425 | + return hif_addr; |
| 426 | +} |
| 427 | +#endif |
| 428 | + |
405 | 429 | /**
|
406 | 430 | * zynqmp_get_error_info - Get the current ECC error info.
|
407 | 431 | * @priv: DDR memory controller private instance data.
|
@@ -922,6 +946,9 @@ static const struct synps_platform_data zynqmp_edac_def = {
|
922 | 946 | .get_mtype = zynqmp_get_mtype,
|
923 | 947 | .get_dtype = zynqmp_get_dtype,
|
924 | 948 | .get_ecc_state = zynqmp_get_ecc_state,
|
| 949 | +#ifdef CONFIG_EDAC_DEBUG |
| 950 | + .get_mem_info = zynqmp_get_mem_info, |
| 951 | +#endif |
925 | 952 | .quirks = (DDR_ECC_INTR_SUPPORT
|
926 | 953 | #ifdef CONFIG_EDAC_DEBUG
|
927 | 954 | | DDR_ECC_DATA_POISON_SUPPORT
|
@@ -975,10 +1002,16 @@ MODULE_DEVICE_TABLE(of, synps_edac_match);
|
975 | 1002 | static void ddr_poison_setup(struct synps_edac_priv *priv)
|
976 | 1003 | {
|
977 | 1004 | int col = 0, row = 0, bank = 0, bankgrp = 0, rank = 0, regval;
|
| 1005 | + const struct synps_platform_data *p_data; |
978 | 1006 | int index;
|
979 | 1007 | ulong hif_addr = 0;
|
980 | 1008 |
|
981 |
| - hif_addr = priv->poison_addr >> 3; |
| 1009 | + p_data = priv->p_data; |
| 1010 | + |
| 1011 | + if (p_data->get_mem_info) |
| 1012 | + hif_addr = p_data->get_mem_info(priv); |
| 1013 | + else |
| 1014 | + hif_addr = priv->poison_addr >> 3; |
982 | 1015 |
|
983 | 1016 | for (index = 0; index < DDR_MAX_ROW_SHIFT; index++) {
|
984 | 1017 | if (priv->row_shift[index])
|
|
0 commit comments