Skip to content

Commit 3123c5c

Browse files
tthayer-intelmchehab
authored andcommitted
edac: altera: Move Stratix10 SDRAM ECC to peripheral
ARM32 SoCFPGAs had separate IRQs for SDRAM. ARM64 SoCFPGAs send all DBEs to SError so filtering by source is necessary. The Stratix10 SDRAM ECC is a better match with the generic Altera peripheral ECC framework because the linked list can be searched to find the ECC block offset and printout the DBE Address. Signed-off-by: Thor Thayer <[email protected]> Acked-by: James Morse <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent 1c38bdc commit 3123c5c

File tree

2 files changed

+74
-5
lines changed

2 files changed

+74
-5
lines changed

drivers/edac/altera_edac.c

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,6 @@ static unsigned long get_total_mem(void)
222222
static const struct of_device_id altr_sdram_ctrl_of_match[] = {
223223
{ .compatible = "altr,sdram-edac", .data = &c5_data},
224224
{ .compatible = "altr,sdram-edac-a10", .data = &a10_data},
225-
{ .compatible = "altr,sdram-edac-s10", .data = &a10_data},
226225
{},
227226
};
228227
MODULE_DEVICE_TABLE(of, altr_sdram_ctrl_of_match);
@@ -1170,6 +1169,24 @@ static int __init __maybe_unused altr_init_a10_ecc_device_type(char *compat)
11701169
return 0;
11711170
}
11721171

1172+
/*********************** SDRAM EDAC Device Functions *********************/
1173+
1174+
#ifdef CONFIG_EDAC_ALTERA_SDRAM
1175+
1176+
static const struct edac_device_prv_data s10_sdramecc_data = {
1177+
.setup = altr_check_ecc_deps,
1178+
.ce_clear_mask = ALTR_S10_ECC_SERRPENA,
1179+
.ue_clear_mask = ALTR_S10_ECC_DERRPENA,
1180+
.ecc_enable_mask = ALTR_S10_ECC_EN,
1181+
.ecc_en_ofst = ALTR_S10_ECC_CTRL_SDRAM_OFST,
1182+
.ce_set_mask = ALTR_S10_ECC_TSERRA,
1183+
.ue_set_mask = ALTR_S10_ECC_TDERRA,
1184+
.set_err_ofst = ALTR_S10_ECC_INTTEST_OFST,
1185+
.ecc_irq_handler = altr_edac_a10_ecc_irq,
1186+
.inject_fops = &altr_edac_a10_device_inject_fops,
1187+
};
1188+
#endif /* CONFIG_EDAC_ALTERA_SDRAM */
1189+
11731190
/*********************** OCRAM EDAC Device Functions *********************/
11741191

11751192
#ifdef CONFIG_EDAC_ALTERA_OCRAM
@@ -1758,6 +1775,9 @@ static const struct of_device_id altr_edac_a10_device_of_match[] = {
17581775
#endif
17591776
#ifdef CONFIG_EDAC_ALTERA_SDMMC
17601777
{ .compatible = "altr,socfpga-sdmmc-ecc", .data = &a10_sdmmcecca_data },
1778+
#endif
1779+
#ifdef CONFIG_EDAC_ALTERA_SDRAM
1780+
{ .compatible = "altr,sdram-edac-s10", .data = &s10_sdramecc_data },
17611781
#endif
17621782
{},
17631783
};
@@ -1889,6 +1909,10 @@ static int validate_parent_available(struct device_node *np)
18891909
struct device_node *parent;
18901910
int ret = 0;
18911911

1912+
/* SDRAM must be present for Linux (implied parent) */
1913+
if (of_device_is_compatible(np, "altr,sdram-edac-s10"))
1914+
return 0;
1915+
18921916
/* Ensure parent device is enabled if parent node exists */
18931917
parent = of_parse_phandle(np, "altr,ecc-parent", 0);
18941918
if (parent && !of_device_is_available(parent))
@@ -1898,6 +1922,22 @@ static int validate_parent_available(struct device_node *np)
18981922
return ret;
18991923
}
19001924

1925+
static int get_s10_sdram_edac_resource(struct device_node *np,
1926+
struct resource *res)
1927+
{
1928+
struct device_node *parent;
1929+
int ret;
1930+
1931+
parent = of_parse_phandle(np, "altr,sdr-syscon", 0);
1932+
if (!parent)
1933+
return -ENODEV;
1934+
1935+
ret = of_address_to_resource(parent, 0, res);
1936+
of_node_put(parent);
1937+
1938+
return ret;
1939+
}
1940+
19011941
static int altr_edac_a10_device_add(struct altr_arria10_edac *edac,
19021942
struct device_node *np)
19031943
{
@@ -1925,7 +1965,11 @@ static int altr_edac_a10_device_add(struct altr_arria10_edac *edac,
19251965
if (!devres_open_group(edac->dev, altr_edac_a10_device_add, GFP_KERNEL))
19261966
return -ENOMEM;
19271967

1928-
rc = of_address_to_resource(np, 0, &res);
1968+
if (of_device_is_compatible(np, "altr,sdram-edac-s10"))
1969+
rc = get_s10_sdram_edac_resource(np, &res);
1970+
else
1971+
rc = of_address_to_resource(np, 0, &res);
1972+
19291973
if (rc < 0) {
19301974
edac_printk(KERN_ERR, EDAC_DEVICE,
19311975
"%s: no resource address\n", ecc_name);
@@ -2231,13 +2275,15 @@ static int altr_edac_a10_probe(struct platform_device *pdev)
22312275
of_device_is_compatible(child, "altr,socfpga-dma-ecc") ||
22322276
of_device_is_compatible(child, "altr,socfpga-usb-ecc") ||
22332277
of_device_is_compatible(child, "altr,socfpga-qspi-ecc") ||
2278+
#ifdef CONFIG_EDAC_ALTERA_SDRAM
2279+
of_device_is_compatible(child, "altr,sdram-edac-s10") ||
2280+
#endif
22342281
of_device_is_compatible(child, "altr,socfpga-sdmmc-ecc"))
22352282

22362283
altr_edac_a10_device_add(edac, child);
22372284

22382285
#ifdef CONFIG_EDAC_ALTERA_SDRAM
2239-
else if ((of_device_is_compatible(child, "altr,sdram-edac-a10")) ||
2240-
(of_device_is_compatible(child, "altr,sdram-edac-s10")))
2286+
else if (of_device_is_compatible(child, "altr,sdram-edac-a10"))
22412287
of_platform_populate(pdev->dev.of_node,
22422288
altr_sdram_ctrl_of_match,
22432289
NULL, &pdev->dev);

drivers/edac/altera_edac.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,29 @@ struct altr_sdram_mc_data {
289289
#define ALTR_A10_ECC_INIT_WATCHDOG_10US 10000
290290

291291
/************* Stratix10 Defines **************/
292+
#define ALTR_S10_ECC_CTRL_SDRAM_OFST 0x00
293+
#define ALTR_S10_ECC_EN BIT(0)
294+
295+
#define ALTR_S10_ECC_ERRINTEN_OFST 0x10
296+
#define ALTR_S10_ECC_ERRINTENS_OFST 0x14
297+
#define ALTR_S10_ECC_ERRINTENR_OFST 0x18
298+
#define ALTR_S10_ECC_SERRINTEN BIT(0)
299+
300+
#define ALTR_S10_ECC_INTMODE_OFST 0x1C
301+
#define ALTR_S10_ECC_INTMODE BIT(0)
302+
303+
#define ALTR_S10_ECC_INTSTAT_OFST 0x20
304+
#define ALTR_S10_ECC_SERRPENA BIT(0)
305+
#define ALTR_S10_ECC_DERRPENA BIT(8)
306+
#define ALTR_S10_ECC_ERRPENA_MASK (ALTR_S10_ECC_SERRPENA | \
307+
ALTR_S10_ECC_DERRPENA)
308+
309+
#define ALTR_S10_ECC_INTTEST_OFST 0x24
310+
#define ALTR_S10_ECC_TSERRA BIT(0)
311+
#define ALTR_S10_ECC_TDERRA BIT(8)
312+
#define ALTR_S10_ECC_TSERRB BIT(16)
313+
#define ALTR_S10_ECC_TDERRB BIT(24)
314+
292315
#define ALTR_S10_DERR_ADDRA_OFST 0x2C
293316

294317
/* Stratix10 ECC Manager Defines */
@@ -300,7 +323,7 @@ struct altr_sdram_mc_data {
300323
#define S10_SYSMGR_UE_ADDR_OFST 0x224
301324

302325
#define S10_DDR0_IRQ_MASK BIT(16)
303-
#define S10_DBE_IRQ_MASK 0x3FE
326+
#define S10_DBE_IRQ_MASK 0x3FFFE
304327

305328
/* Define ECC Block Offsets for peripherals */
306329
#define ECC_BLK_ADDRESS_OFST 0x40

0 commit comments

Comments
 (0)