@@ -332,20 +332,26 @@ struct synps_edac_priv {
332332#endif
333333};
334334
335+ enum synps_platform_type {
336+ ZYNQ ,
337+ ZYNQMP ,
338+ SYNPS ,
339+ };
340+
335341/**
336342 * struct synps_platform_data - synps platform data structure.
343+ * @platform: Identifies the target hardware platform
337344 * @get_error_info: Get EDAC error info.
338345 * @get_mtype: Get mtype.
339346 * @get_dtype: Get dtype.
340- * @get_ecc_state: Get ECC state.
341347 * @get_mem_info: Get EDAC memory info
342348 * @quirks: To differentiate IPs.
343349 */
344350struct synps_platform_data {
351+ enum synps_platform_type platform ;
345352 int (* get_error_info )(struct synps_edac_priv * priv );
346353 enum mem_type (* get_mtype )(const void __iomem * base );
347354 enum dev_type (* get_dtype )(const void __iomem * base );
348- bool (* get_ecc_state )(void __iomem * base );
349355#ifdef CONFIG_EDAC_DEBUG
350356 u64 (* get_mem_info )(struct synps_edac_priv * priv );
351357#endif
@@ -720,51 +726,38 @@ static enum dev_type zynqmp_get_dtype(const void __iomem *base)
720726 return dt ;
721727}
722728
723- /**
724- * zynq_get_ecc_state - Return the controller ECC enable/disable status.
725- * @base: DDR memory controller base address.
726- *
727- * Get the ECC enable/disable status of the controller.
728- *
729- * Return: true if enabled, otherwise false.
730- */
731- static bool zynq_get_ecc_state (void __iomem * base )
729+ static bool get_ecc_state (struct synps_edac_priv * priv )
732730{
731+ u32 ecctype , clearval ;
733732 enum dev_type dt ;
734- u32 ecctype ;
735-
736- dt = zynq_get_dtype (base );
737- if (dt == DEV_UNKNOWN )
738- return false;
739733
740- ecctype = readl (base + SCRUB_OFST ) & SCRUB_MODE_MASK ;
741- if ((ecctype == SCRUB_MODE_SECDED ) && (dt == DEV_X2 ))
742- return true;
743-
744- return false;
745- }
746-
747- /**
748- * zynqmp_get_ecc_state - Return the controller ECC enable/disable status.
749- * @base: DDR memory controller base address.
750- *
751- * Get the ECC enable/disable status for the controller.
752- *
753- * Return: a ECC status boolean i.e true/false - enabled/disabled.
754- */
755- static bool zynqmp_get_ecc_state (void __iomem * base )
756- {
757- enum dev_type dt ;
758- u32 ecctype ;
759-
760- dt = zynqmp_get_dtype (base );
761- if (dt == DEV_UNKNOWN )
762- return false;
763-
764- ecctype = readl (base + ECC_CFG0_OFST ) & SCRUB_MODE_MASK ;
765- if ((ecctype == SCRUB_MODE_SECDED ) &&
766- ((dt == DEV_X2 ) || (dt == DEV_X4 ) || (dt == DEV_X8 )))
767- return true;
734+ if (priv -> p_data -> platform == ZYNQ ) {
735+ dt = zynq_get_dtype (priv -> baseaddr );
736+ if (dt == DEV_UNKNOWN )
737+ return false;
738+
739+ ecctype = readl (priv -> baseaddr + SCRUB_OFST ) & SCRUB_MODE_MASK ;
740+ if (ecctype == SCRUB_MODE_SECDED && dt == DEV_X2 ) {
741+ clearval = ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_UE_ERR ;
742+ writel (clearval , priv -> baseaddr + ECC_CTRL_OFST );
743+ writel (0x0 , priv -> baseaddr + ECC_CTRL_OFST );
744+ return true;
745+ }
746+ } else {
747+ dt = zynqmp_get_dtype (priv -> baseaddr );
748+ if (dt == DEV_UNKNOWN )
749+ return false;
750+
751+ ecctype = readl (priv -> baseaddr + ECC_CFG0_OFST ) & SCRUB_MODE_MASK ;
752+ if (ecctype == SCRUB_MODE_SECDED &&
753+ (dt == DEV_X2 || dt == DEV_X4 || dt == DEV_X8 )) {
754+ clearval = readl (priv -> baseaddr + ECC_CLR_OFST ) |
755+ ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT |
756+ ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT ;
757+ writel (clearval , priv -> baseaddr + ECC_CLR_OFST );
758+ return true;
759+ }
760+ }
768761
769762 return false;
770763}
@@ -934,18 +927,18 @@ static int setup_irq(struct mem_ctl_info *mci,
934927}
935928
936929static const struct synps_platform_data zynq_edac_def = {
930+ .platform = ZYNQ ,
937931 .get_error_info = zynq_get_error_info ,
938932 .get_mtype = zynq_get_mtype ,
939933 .get_dtype = zynq_get_dtype ,
940- .get_ecc_state = zynq_get_ecc_state ,
941934 .quirks = 0 ,
942935};
943936
944937static const struct synps_platform_data zynqmp_edac_def = {
938+ .platform = ZYNQMP ,
945939 .get_error_info = zynqmp_get_error_info ,
946940 .get_mtype = zynqmp_get_mtype ,
947941 .get_dtype = zynqmp_get_dtype ,
948- .get_ecc_state = zynqmp_get_ecc_state ,
949942#ifdef CONFIG_EDAC_DEBUG
950943 .get_mem_info = zynqmp_get_mem_info ,
951944#endif
@@ -957,10 +950,10 @@ static const struct synps_platform_data zynqmp_edac_def = {
957950};
958951
959952static const struct synps_platform_data synopsys_edac_def = {
953+ .platform = SYNPS ,
960954 .get_error_info = zynqmp_get_error_info ,
961955 .get_mtype = zynqmp_get_mtype ,
962956 .get_dtype = zynqmp_get_dtype ,
963- .get_ecc_state = zynqmp_get_ecc_state ,
964957 .quirks = (DDR_ECC_INTR_SUPPORT | DDR_ECC_INTR_SELF_CLEAR
965958#ifdef CONFIG_EDAC_DEBUG
966959 | DDR_ECC_DATA_POISON_SUPPORT
@@ -1390,10 +1383,6 @@ static int mc_probe(struct platform_device *pdev)
13901383 if (!p_data )
13911384 return - ENODEV ;
13921385
1393- if (!p_data -> get_ecc_state (baseaddr )) {
1394- edac_printk (KERN_INFO , EDAC_MC , "ECC not enabled\n" );
1395- return - ENXIO ;
1396- }
13971386
13981387 layers [0 ].type = EDAC_MC_LAYER_CHIP_SELECT ;
13991388 layers [0 ].size = SYNPS_EDAC_NR_CSROWS ;
@@ -1413,6 +1402,12 @@ static int mc_probe(struct platform_device *pdev)
14131402 priv = mci -> pvt_info ;
14141403 priv -> baseaddr = baseaddr ;
14151404 priv -> p_data = p_data ;
1405+ if (!get_ecc_state (priv )) {
1406+ edac_printk (KERN_INFO , EDAC_MC , "ECC not enabled\n" );
1407+ rc = - ENODEV ;
1408+ goto free_edac_mc ;
1409+ }
1410+
14161411 spin_lock_init (& priv -> reglock );
14171412
14181413 mc_init (mci , pdev );
0 commit comments