From c6882fb2e83525e97663df1d2d96f29d034189ab Mon Sep 17 00:00:00 2001 From: Thor Thayer Date: Thu, 14 Jul 2016 11:06:43 -0500 Subject: EDAC, altera: Add Arria10 NAND support Add Altera Arria10 NAND FIFO memory support. Signed-off-by: Thor Thayer Cc: dinguyen@opensource.altera.com Cc: linux-arm-kernel@lists.infradead.org Cc: linux-edac Link: http://lkml.kernel.org/r/1468512408-5156-6-git-send-email-tthayer@opensource.altera.com [ Reformat loop in altr_edac_a10_probe() for better readability. ] Signed-off-by: Borislav Petkov --- drivers/edac/Kconfig | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/edac/Kconfig') diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index d0c1dab9b435..47378b30c8c3 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -398,6 +398,13 @@ config EDAC_ALTERA_ETHERNET Support for error detection and correction on the Altera Ethernet FIFO Memory for Altera SoCs. +config EDAC_ALTERA_NAND + bool "Altera NAND FIFO ECC" + depends on EDAC_ALTERA=y && MTD_NAND_DENALI + help + Support for error detection and correction on the + Altera NAND FIFO Memory for Altera SoCs. + config EDAC_SYNOPSYS tristate "Synopsys DDR Memory Controller" depends on EDAC_MM_EDAC && ARCH_ZYNQ -- cgit v1.2.3-58-ga151 From e8263793b7248ec78316d5915152c105e1034a28 Mon Sep 17 00:00:00 2001 From: Thor Thayer Date: Thu, 28 Jul 2016 10:03:57 +0200 Subject: EDAC, altera: Add Arria10 DMA support Add Altera Arria10 DMA FIFO memory support. Signed-off-by: Thor Thayer Cc: dinguyen@opensource.altera.com Cc: linux-arm-kernel@lists.infradead.org Cc: linux-edac Link: http://lkml.kernel.org/r/1468512408-5156-7-git-send-email-tthayer@opensource.altera.com Signed-off-by: Borislav Petkov --- drivers/edac/Kconfig | 7 +++++++ drivers/edac/altera_edac.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) (limited to 'drivers/edac/Kconfig') diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 47378b30c8c3..d1fd57ab742b 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -405,6 +405,13 @@ config EDAC_ALTERA_NAND Support for error detection and correction on the Altera NAND FIFO Memory for Altera SoCs. +config EDAC_ALTERA_DMA + bool "Altera DMA FIFO ECC" + depends on EDAC_ALTERA=y && PL330_DMA=y + help + Support for error detection and correction on the + Altera DMA FIFO Memory for Altera SoCs. + config EDAC_SYNOPSYS tristate "Synopsys DDR Memory Controller" depends on EDAC_MM_EDAC && ARCH_ZYNQ diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index fe6374236bd9..83edc6861eb1 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -1312,6 +1312,33 @@ early_initcall(socfpga_init_nand_ecc); #endif /* CONFIG_EDAC_ALTERA_NAND */ +/********************** DMA Device Functions **********************/ + +#ifdef CONFIG_EDAC_ALTERA_DMA + +static const struct edac_device_prv_data a10_dmaecc_data = { + .setup = altr_check_ecc_deps, + .ce_clear_mask = ALTR_A10_ECC_SERRPENA, + .ue_clear_mask = ALTR_A10_ECC_DERRPENA, + .dbgfs_name = "altr_trigger", + .ecc_enable_mask = ALTR_A10_COMMON_ECC_EN_CTL, + .ecc_en_ofst = ALTR_A10_ECC_CTRL_OFST, + .ce_set_mask = ALTR_A10_ECC_TSERRA, + .ue_set_mask = ALTR_A10_ECC_TDERRA, + .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST, + .ecc_irq_handler = altr_edac_a10_ecc_irq, + .inject_fops = &altr_edac_a10_device_inject_fops, +}; + +static int __init socfpga_init_dma_ecc(void) +{ + return altr_init_a10_ecc_device_type("altr,socfpga-dma-ecc"); +} + +early_initcall(socfpga_init_dma_ecc); + +#endif /* CONFIG_EDAC_ALTERA_DMA */ + /********************* Arria10 EDAC Device Functions *************************/ static const struct of_device_id altr_edac_a10_device_of_match[] = { #ifdef CONFIG_EDAC_ALTERA_L2C @@ -1327,6 +1354,9 @@ static const struct of_device_id altr_edac_a10_device_of_match[] = { #endif #ifdef CONFIG_EDAC_ALTERA_NAND { .compatible = "altr,socfpga-nand-ecc", .data = &a10_nandecc_data }, +#endif +#ifdef CONFIG_EDAC_ALTERA_DMA + { .compatible = "altr,socfpga-dma-ecc", .data = &a10_dmaecc_data }, #endif {}, }; @@ -1618,7 +1648,8 @@ static int altr_edac_a10_probe(struct platform_device *pdev) if (of_device_is_compatible(child, "altr,socfpga-a10-l2-ecc") || of_device_is_compatible(child, "altr,socfpga-a10-ocram-ecc") || of_device_is_compatible(child, "altr,socfpga-eth-mac-ecc") || - of_device_is_compatible(child, "altr,socfpga-nand-ecc")) + of_device_is_compatible(child, "altr,socfpga-nand-ecc") || + of_device_is_compatible(child, "altr,socfpga-dma-ecc")) altr_edac_a10_device_add(edac, child); -- cgit v1.2.3-58-ga151 From c609581d1f75e6965db8258015f5ae357df477c8 Mon Sep 17 00:00:00 2001 From: Thor Thayer Date: Thu, 14 Jul 2016 11:06:45 -0500 Subject: EDAC, altera: Add Arria10 USB support Add Altera Arria10 USB FIFO memory support. Signed-off-by: Thor Thayer Cc: dinguyen@opensource.altera.com Cc: linux-arm-kernel@lists.infradead.org Cc: linux-edac Link: http://lkml.kernel.org/r/1468512408-5156-8-git-send-email-tthayer@opensource.altera.com Signed-off-by: Borislav Petkov --- drivers/edac/Kconfig | 7 +++++++ drivers/edac/altera_edac.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) (limited to 'drivers/edac/Kconfig') diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index d1fd57ab742b..1966068f583b 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -412,6 +412,13 @@ config EDAC_ALTERA_DMA Support for error detection and correction on the Altera DMA FIFO Memory for Altera SoCs. +config EDAC_ALTERA_USB + bool "Altera USB FIFO ECC" + depends on EDAC_ALTERA=y && USB_DWC2 + help + Support for error detection and correction on the + Altera USB FIFO Memory for Altera SoCs. + config EDAC_SYNOPSYS tristate "Synopsys DDR Memory Controller" depends on EDAC_MM_EDAC && ARCH_ZYNQ diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index 83edc6861eb1..84798536b6a8 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -1339,6 +1339,33 @@ early_initcall(socfpga_init_dma_ecc); #endif /* CONFIG_EDAC_ALTERA_DMA */ +/********************** USB Device Functions **********************/ + +#ifdef CONFIG_EDAC_ALTERA_USB + +static const struct edac_device_prv_data a10_usbecc_data = { + .setup = altr_check_ecc_deps, + .ce_clear_mask = ALTR_A10_ECC_SERRPENA, + .ue_clear_mask = ALTR_A10_ECC_DERRPENA, + .dbgfs_name = "altr_trigger", + .ecc_enable_mask = ALTR_A10_COMMON_ECC_EN_CTL, + .ecc_en_ofst = ALTR_A10_ECC_CTRL_OFST, + .ce_set_mask = ALTR_A10_ECC_TSERRA, + .ue_set_mask = ALTR_A10_ECC_TDERRA, + .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST, + .ecc_irq_handler = altr_edac_a10_ecc_irq, + .inject_fops = &altr_edac_a10_device_inject_fops, +}; + +static int __init socfpga_init_usb_ecc(void) +{ + return altr_init_a10_ecc_device_type("altr,socfpga-usb-ecc"); +} + +early_initcall(socfpga_init_usb_ecc); + +#endif /* CONFIG_EDAC_ALTERA_USB */ + /********************* Arria10 EDAC Device Functions *************************/ static const struct of_device_id altr_edac_a10_device_of_match[] = { #ifdef CONFIG_EDAC_ALTERA_L2C @@ -1357,6 +1384,9 @@ static const struct of_device_id altr_edac_a10_device_of_match[] = { #endif #ifdef CONFIG_EDAC_ALTERA_DMA { .compatible = "altr,socfpga-dma-ecc", .data = &a10_dmaecc_data }, +#endif +#ifdef CONFIG_EDAC_ALTERA_USB + { .compatible = "altr,socfpga-usb-ecc", .data = &a10_usbecc_data }, #endif {}, }; @@ -1649,7 +1679,8 @@ static int altr_edac_a10_probe(struct platform_device *pdev) of_device_is_compatible(child, "altr,socfpga-a10-ocram-ecc") || of_device_is_compatible(child, "altr,socfpga-eth-mac-ecc") || of_device_is_compatible(child, "altr,socfpga-nand-ecc") || - of_device_is_compatible(child, "altr,socfpga-dma-ecc")) + of_device_is_compatible(child, "altr,socfpga-dma-ecc") || + of_device_is_compatible(child, "altr,socfpga-usb-ecc")) altr_edac_a10_device_add(edac, child); -- cgit v1.2.3-58-ga151 From 485fe9e24e53fbeef7594e90eed1e09e23b9c184 Mon Sep 17 00:00:00 2001 From: Thor Thayer Date: Thu, 14 Jul 2016 11:06:46 -0500 Subject: EDAC, altera: Add Arria10 QSPI support Add Altera Arria10 QSPI FIFO memory support. Signed-off-by: Thor Thayer Cc: dinguyen@opensource.altera.com Cc: linux-arm-kernel@lists.infradead.org Cc: linux-edac Link: http://lkml.kernel.org/r/1468512408-5156-9-git-send-email-tthayer@opensource.altera.com Signed-off-by: Borislav Petkov --- drivers/edac/Kconfig | 7 +++++++ drivers/edac/altera_edac.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) (limited to 'drivers/edac/Kconfig') diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 1966068f583b..72752f460cbb 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -419,6 +419,13 @@ config EDAC_ALTERA_USB Support for error detection and correction on the Altera USB FIFO Memory for Altera SoCs. +config EDAC_ALTERA_QSPI + bool "Altera QSPI FIFO ECC" + depends on EDAC_ALTERA=y && SPI_CADENCE_QUADSPI + help + Support for error detection and correction on the + Altera QSPI FIFO Memory for Altera SoCs. + config EDAC_SYNOPSYS tristate "Synopsys DDR Memory Controller" depends on EDAC_MM_EDAC && ARCH_ZYNQ diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index 84798536b6a8..28247f82e1d5 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -1366,6 +1366,33 @@ early_initcall(socfpga_init_usb_ecc); #endif /* CONFIG_EDAC_ALTERA_USB */ +/********************** QSPI Device Functions **********************/ + +#ifdef CONFIG_EDAC_ALTERA_QSPI + +static const struct edac_device_prv_data a10_qspiecc_data = { + .setup = altr_check_ecc_deps, + .ce_clear_mask = ALTR_A10_ECC_SERRPENA, + .ue_clear_mask = ALTR_A10_ECC_DERRPENA, + .dbgfs_name = "altr_trigger", + .ecc_enable_mask = ALTR_A10_COMMON_ECC_EN_CTL, + .ecc_en_ofst = ALTR_A10_ECC_CTRL_OFST, + .ce_set_mask = ALTR_A10_ECC_TSERRA, + .ue_set_mask = ALTR_A10_ECC_TDERRA, + .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST, + .ecc_irq_handler = altr_edac_a10_ecc_irq, + .inject_fops = &altr_edac_a10_device_inject_fops, +}; + +static int __init socfpga_init_qspi_ecc(void) +{ + return altr_init_a10_ecc_device_type("altr,socfpga-qspi-ecc"); +} + +early_initcall(socfpga_init_qspi_ecc); + +#endif /* CONFIG_EDAC_ALTERA_QSPI */ + /********************* Arria10 EDAC Device Functions *************************/ static const struct of_device_id altr_edac_a10_device_of_match[] = { #ifdef CONFIG_EDAC_ALTERA_L2C @@ -1387,6 +1414,9 @@ static const struct of_device_id altr_edac_a10_device_of_match[] = { #endif #ifdef CONFIG_EDAC_ALTERA_USB { .compatible = "altr,socfpga-usb-ecc", .data = &a10_usbecc_data }, +#endif +#ifdef CONFIG_EDAC_ALTERA_QSPI + { .compatible = "altr,socfpga-qspi-ecc", .data = &a10_qspiecc_data }, #endif {}, }; @@ -1680,7 +1710,8 @@ static int altr_edac_a10_probe(struct platform_device *pdev) of_device_is_compatible(child, "altr,socfpga-eth-mac-ecc") || of_device_is_compatible(child, "altr,socfpga-nand-ecc") || of_device_is_compatible(child, "altr,socfpga-dma-ecc") || - of_device_is_compatible(child, "altr,socfpga-usb-ecc")) + of_device_is_compatible(child, "altr,socfpga-usb-ecc") || + of_device_is_compatible(child, "altr,socfpga-qspi-ecc")) altr_edac_a10_device_add(edac, child); -- cgit v1.2.3-58-ga151 From 911049845d7096c27304930ff478cbf3f2623ba3 Mon Sep 17 00:00:00 2001 From: Thor Thayer Date: Tue, 9 Aug 2016 09:40:52 -0500 Subject: EDAC, altera: Add Arria10 SD-MMC EDAC support Add Altera Arria10 SD-MMC FIFO memory EDAC support. The SD-MMC is a dual port RAM implementation which is different than any of the other peripherals and therefore requires additional code. Signed-off-by: Thor Thayer Cc: dinguyen@opensource.altera.com Cc: linux-arm-kernel@lists.infradead.org Cc: linux-edac Link: http://lkml.kernel.org/r/1470753653-23465-3-git-send-email-tthayer@opensource.altera.com Signed-off-by: Borislav Petkov --- drivers/edac/Kconfig | 7 ++ drivers/edac/altera_edac.c | 188 ++++++++++++++++++++++++++++++++++++++++++++- drivers/edac/altera_edac.h | 5 ++ 3 files changed, 199 insertions(+), 1 deletion(-) (limited to 'drivers/edac/Kconfig') diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 72752f460cbb..394cd16dd58f 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -426,6 +426,13 @@ config EDAC_ALTERA_QSPI Support for error detection and correction on the Altera QSPI FIFO Memory for Altera SoCs. +config EDAC_ALTERA_SDMMC + bool "Altera SDMMC FIFO ECC" + depends on EDAC_ALTERA=y && MMC_DW + help + Support for error detection and correction on the + Altera SDMMC FIFO Memory for Altera SoCs. + config EDAC_SYNOPSYS tristate "Synopsys DDR Memory Controller" depends on EDAC_MM_EDAC && ARCH_ZYNQ diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index 28247f82e1d5..efaf727be25a 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -1393,6 +1393,188 @@ early_initcall(socfpga_init_qspi_ecc); #endif /* CONFIG_EDAC_ALTERA_QSPI */ +/********************* SDMMC Device Functions **********************/ + +#ifdef CONFIG_EDAC_ALTERA_SDMMC + +static const struct edac_device_prv_data a10_sdmmceccb_data; +static int altr_portb_setup(struct altr_edac_device_dev *device) +{ + struct edac_device_ctl_info *dci; + struct altr_edac_device_dev *altdev; + char *ecc_name = "sdmmcb-ecc"; + int edac_idx, rc; + struct device_node *np; + const struct edac_device_prv_data *prv = &a10_sdmmceccb_data; + + rc = altr_check_ecc_deps(device); + if (rc) + return rc; + + np = of_find_compatible_node(NULL, NULL, "altr,socfpga-sdmmc-ecc"); + if (!np) { + edac_printk(KERN_WARNING, EDAC_DEVICE, "SDMMC node not found\n"); + return -ENODEV; + } + + /* Create the PortB EDAC device */ + edac_idx = edac_device_alloc_index(); + dci = edac_device_alloc_ctl_info(sizeof(*altdev), ecc_name, 1, + ecc_name, 1, 0, NULL, 0, edac_idx); + if (!dci) { + edac_printk(KERN_ERR, EDAC_DEVICE, + "%s: Unable to allocate PortB EDAC device\n", + ecc_name); + return -ENOMEM; + } + + /* Initialize the PortB EDAC device structure from PortA structure */ + altdev = dci->pvt_info; + *altdev = *device; + + if (!devres_open_group(&altdev->ddev, altr_portb_setup, GFP_KERNEL)) + return -ENOMEM; + + /* Update PortB specific values */ + altdev->edac_dev_name = ecc_name; + altdev->edac_idx = edac_idx; + altdev->edac_dev = dci; + altdev->data = prv; + dci->dev = &altdev->ddev; + dci->ctl_name = "Altera ECC Manager"; + dci->mod_name = ecc_name; + dci->dev_name = ecc_name; + + /* Update the IRQs for PortB */ + altdev->sb_irq = irq_of_parse_and_map(np, 2); + if (!altdev->sb_irq) { + edac_printk(KERN_ERR, EDAC_DEVICE, "Error PortB SBIRQ alloc\n"); + rc = -ENODEV; + goto err_release_group_1; + } + rc = devm_request_irq(&altdev->ddev, altdev->sb_irq, + prv->ecc_irq_handler, + IRQF_SHARED, ecc_name, altdev); + if (rc) { + edac_printk(KERN_ERR, EDAC_DEVICE, "PortB SBERR IRQ error\n"); + goto err_release_group_1; + } + + altdev->db_irq = irq_of_parse_and_map(np, 3); + if (!altdev->db_irq) { + edac_printk(KERN_ERR, EDAC_DEVICE, "Error PortB DBIRQ alloc\n"); + rc = -ENODEV; + goto err_release_group_1; + } + rc = devm_request_irq(&altdev->ddev, altdev->db_irq, + prv->ecc_irq_handler, + IRQF_SHARED, ecc_name, altdev); + if (rc) { + edac_printk(KERN_ERR, EDAC_DEVICE, "PortB DBERR IRQ error\n"); + goto err_release_group_1; + } + + rc = edac_device_add_device(dci); + if (rc) { + edac_printk(KERN_ERR, EDAC_DEVICE, + "edac_device_add_device portB failed\n"); + rc = -ENOMEM; + goto err_release_group_1; + } + altr_create_edacdev_dbgfs(dci, prv); + + list_add(&altdev->next, &altdev->edac->a10_ecc_devices); + + devres_remove_group(&altdev->ddev, altr_portb_setup); + + return 0; + +err_release_group_1: + edac_device_free_ctl_info(dci); + devres_release_group(&altdev->ddev, altr_portb_setup); + edac_printk(KERN_ERR, EDAC_DEVICE, + "%s:Error setting up EDAC device: %d\n", ecc_name, rc); + return rc; +} + +static irqreturn_t altr_edac_a10_ecc_irq_portb(int irq, void *dev_id) +{ + struct altr_edac_device_dev *ad = dev_id; + void __iomem *base = ad->base; + const struct edac_device_prv_data *priv = ad->data; + + if (irq == ad->sb_irq) { + writel(priv->ce_clear_mask, + base + ALTR_A10_ECC_INTSTAT_OFST); + edac_device_handle_ce(ad->edac_dev, 0, 0, ad->edac_dev_name); + return IRQ_HANDLED; + } else if (irq == ad->db_irq) { + writel(priv->ue_clear_mask, + base + ALTR_A10_ECC_INTSTAT_OFST); + edac_device_handle_ue(ad->edac_dev, 0, 0, ad->edac_dev_name); + return IRQ_HANDLED; + } + + WARN_ONCE(1, "Unhandled IRQ%d on Port B.", irq); + + return IRQ_NONE; +} + +static const struct edac_device_prv_data a10_sdmmcecca_data = { + .setup = altr_portb_setup, + .ce_clear_mask = ALTR_A10_ECC_SERRPENA, + .ue_clear_mask = ALTR_A10_ECC_DERRPENA, + .dbgfs_name = "altr_trigger", + .ecc_enable_mask = ALTR_A10_COMMON_ECC_EN_CTL, + .ecc_en_ofst = ALTR_A10_ECC_CTRL_OFST, + .ce_set_mask = ALTR_A10_ECC_SERRPENA, + .ue_set_mask = ALTR_A10_ECC_DERRPENA, + .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST, + .ecc_irq_handler = altr_edac_a10_ecc_irq, + .inject_fops = &altr_edac_a10_device_inject_fops, +}; + +static const struct edac_device_prv_data a10_sdmmceccb_data = { + .setup = altr_portb_setup, + .ce_clear_mask = ALTR_A10_ECC_SERRPENB, + .ue_clear_mask = ALTR_A10_ECC_DERRPENB, + .dbgfs_name = "altr_trigger", + .ecc_enable_mask = ALTR_A10_COMMON_ECC_EN_CTL, + .ecc_en_ofst = ALTR_A10_ECC_CTRL_OFST, + .ce_set_mask = ALTR_A10_ECC_TSERRB, + .ue_set_mask = ALTR_A10_ECC_TDERRB, + .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST, + .ecc_irq_handler = altr_edac_a10_ecc_irq_portb, + .inject_fops = &altr_edac_a10_device_inject_fops, +}; + +static int __init socfpga_init_sdmmc_ecc(void) +{ + int rc = -ENODEV; + struct device_node *child = of_find_compatible_node(NULL, NULL, + "altr,socfpga-sdmmc-ecc"); + if (!child) { + edac_printk(KERN_WARNING, EDAC_DEVICE, "SDMMC node not found\n"); + return -ENODEV; + } + + if (!of_device_is_available(child)) + goto exit; + + if (validate_parent_available(child)) + goto exit; + + rc = altr_init_a10_ecc_block(child, ALTR_A10_SDMMC_IRQ_MASK, + a10_sdmmcecca_data.ecc_enable_mask, 1); +exit: + of_node_put(child); + return rc; +} + +early_initcall(socfpga_init_sdmmc_ecc); + +#endif /* CONFIG_EDAC_ALTERA_SDMMC */ + /********************* Arria10 EDAC Device Functions *************************/ static const struct of_device_id altr_edac_a10_device_of_match[] = { #ifdef CONFIG_EDAC_ALTERA_L2C @@ -1417,6 +1599,9 @@ static const struct of_device_id altr_edac_a10_device_of_match[] = { #endif #ifdef CONFIG_EDAC_ALTERA_QSPI { .compatible = "altr,socfpga-qspi-ecc", .data = &a10_qspiecc_data }, +#endif +#ifdef CONFIG_EDAC_ALTERA_SDMMC + { .compatible = "altr,socfpga-sdmmc-ecc", .data = &a10_sdmmcecca_data }, #endif {}, }; @@ -1711,7 +1896,8 @@ static int altr_edac_a10_probe(struct platform_device *pdev) of_device_is_compatible(child, "altr,socfpga-nand-ecc") || of_device_is_compatible(child, "altr,socfpga-dma-ecc") || of_device_is_compatible(child, "altr,socfpga-usb-ecc") || - of_device_is_compatible(child, "altr,socfpga-qspi-ecc")) + of_device_is_compatible(child, "altr,socfpga-qspi-ecc") || + of_device_is_compatible(child, "altr,socfpga-sdmmc-ecc")) altr_edac_a10_device_add(edac, child); diff --git a/drivers/edac/altera_edac.h b/drivers/edac/altera_edac.h index 687d8e754d36..cf3a68bec100 100644 --- a/drivers/edac/altera_edac.h +++ b/drivers/edac/altera_edac.h @@ -250,6 +250,8 @@ struct altr_sdram_mc_data { #define ALTR_A10_ECC_INTTEST_OFST 0x24 #define ALTR_A10_ECC_TSERRA BIT(0) #define ALTR_A10_ECC_TDERRA BIT(8) +#define ALTR_A10_ECC_TSERRB BIT(16) +#define ALTR_A10_ECC_TDERRB BIT(24) /* ECC Manager Defines */ #define A10_SYSMGR_ECC_INTMASK_SET_OFST 0x94 @@ -288,6 +290,9 @@ struct altr_sdram_mc_data { /* Arria 10 Ethernet ECC Management Group Defines */ #define ALTR_A10_COMMON_ECC_EN_CTL BIT(0) +/* Arria 10 SDMMC ECC Management Group Defines */ +#define ALTR_A10_SDMMC_IRQ_MASK (BIT(16) | BIT(15)) + /* A10 ECC Controller memory initialization timeout */ #define ALTR_A10_ECC_INIT_WATCHDOG_10US 10000 -- cgit v1.2.3-58-ga151 From eeb3d68b6c83abdb80bc0823cbb77cd49484793c Mon Sep 17 00:00:00 2001 From: York Sun Date: Tue, 23 Aug 2016 15:14:03 -0700 Subject: EDAC, layerscape: Add Layerscape EDAC support Add DDR EDAC driver for ARM-based compatible controllers. Both big-endian and little-endian are supported, as specified in device tree. Signed-off-by: York Sun Cc: linux-arm-kernel@lists.infradead.org Cc: linux-edac Link: http://lkml.kernel.org/r/1471990465-27443-1-git-send-email-york.sun@nxp.com Signed-off-by: Borislav Petkov --- arch/arm64/Kconfig.platforms | 1 + drivers/edac/Kconfig | 7 ++++ drivers/edac/Makefile | 3 ++ drivers/edac/fsl_ddr_edac.c | 2 +- drivers/edac/layerscape_edac.c | 73 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 drivers/edac/layerscape_edac.c (limited to 'drivers/edac/Kconfig') diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index bb2616b16157..52f30a62e6e5 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -55,6 +55,7 @@ config ARCH_EXYNOS config ARCH_LAYERSCAPE bool "ARMv8 based Freescale Layerscape SoC family" + select EDAC_SUPPORT help This enables support for the Freescale Layerscape SoC family. diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 394cd16dd58f..49d79002f69c 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -258,6 +258,13 @@ config EDAC_MPC85XX Support for error detection and correction on the Freescale MPC8349, MPC8560, MPC8540, MPC8548, T4240 +config EDAC_LAYERSCAPE + tristate "Freescale Layerscape DDR" + depends on EDAC_MM_EDAC && ARCH_LAYERSCAPE + help + Support for error detection and correction on Freescale memory + controllers on Layerscape SoCs. + config EDAC_MV64X60 tristate "Marvell MV64x60" depends on EDAC_MM_EDAC && MV64X60 diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index ee047a415722..910dc83d3629 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -54,6 +54,9 @@ obj-$(CONFIG_EDAC_PASEMI) += pasemi_edac.o mpc85xx_edac_mod-y := fsl_ddr_edac.o mpc85xx_edac.o obj-$(CONFIG_EDAC_MPC85XX) += mpc85xx_edac_mod.o +layerscape_edac_mod-y := fsl_ddr_edac.o layerscape_edac.o +obj-$(CONFIG_EDAC_LAYERSCAPE) += layerscape_edac_mod.o + obj-$(CONFIG_EDAC_MV64X60) += mv64x60_edac.o obj-$(CONFIG_EDAC_CELL) += cell_edac.o obj-$(CONFIG_EDAC_PPC4XX) += ppc4xx_edac.o diff --git a/drivers/edac/fsl_ddr_edac.c b/drivers/edac/fsl_ddr_edac.c index d8ce1f635c38..afade14c3e93 100644 --- a/drivers/edac/fsl_ddr_edac.c +++ b/drivers/edac/fsl_ddr_edac.c @@ -26,6 +26,7 @@ #include #include +#include #include "edac_module.h" #include "edac_core.h" #include "fsl_ddr_edac.h" @@ -478,7 +479,6 @@ int fsl_mc_err_probe(struct platform_device *op) pdata = mci->pvt_info; pdata->name = "fsl_mc_err"; - pdata->irq = NO_IRQ; mci->pdev = &op->dev; pdata->edac_idx = edac_mc_idx++; dev_set_drvdata(mci->pdev, mci); diff --git a/drivers/edac/layerscape_edac.c b/drivers/edac/layerscape_edac.c new file mode 100644 index 000000000000..6c59d897ad12 --- /dev/null +++ b/drivers/edac/layerscape_edac.c @@ -0,0 +1,73 @@ +/* + * Freescale Memory Controller kernel module + * + * Author: York Sun + * + * Copyright 2016 NXP Semiconductor + * + * Derived from mpc85xx_edac.c + * Author: Dave Jiang + * + * 2006-2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include "edac_core.h" +#include "fsl_ddr_edac.h" + +static const struct of_device_id fsl_ddr_mc_err_of_match[] = { + { .compatible = "fsl,qoriq-memory-controller", }, + {}, +}; +MODULE_DEVICE_TABLE(of, fsl_ddr_mc_err_of_match); + +static struct platform_driver fsl_ddr_mc_err_driver = { + .probe = fsl_mc_err_probe, + .remove = fsl_mc_err_remove, + .driver = { + .name = "fsl_ddr_mc_err", + .of_match_table = fsl_ddr_mc_err_of_match, + }, +}; + +static int __init fsl_ddr_mc_init(void) +{ + int res; + + /* make sure error reporting method is sane */ + switch (edac_op_state) { + case EDAC_OPSTATE_POLL: + case EDAC_OPSTATE_INT: + break; + default: + edac_op_state = EDAC_OPSTATE_INT; + break; + } + + res = platform_driver_register(&fsl_ddr_mc_err_driver); + if (res) { + pr_err("MC fails to register\n"); + return res; + } + + return 0; +} + +module_init(fsl_ddr_mc_init); + +static void __exit fsl_ddr_mc_exit(void) +{ + platform_driver_unregister(&fsl_ddr_mc_err_driver); +} + +module_exit(fsl_ddr_mc_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("NXP Semiconductor"); +module_param(edac_op_state, int, 0444); +MODULE_PARM_DESC(edac_op_state, + "EDAC Error Reporting state: 0=Poll, 2=Interrupt"); -- cgit v1.2.3-58-ga151