1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright Altera Corporation (C) 2016. All rights reserved. 4 */ 5 #include <linux/io.h> 6 #include <linux/of_platform.h> 7 #include <linux/of_address.h> 8 9 #include "core.h" 10 11 /* A10 System Manager L2 ECC Control register */ 12 #define A10_MPU_CTRL_L2_ECC_OFST 0x0 13 #define A10_MPU_CTRL_L2_ECC_EN BIT(0) 14 15 /* A10 System Manager Global IRQ Mask register */ 16 #define A10_SYSMGR_ECC_INTMASK_CLR_OFST 0x98 17 #define A10_SYSMGR_ECC_INTMASK_CLR_L2 BIT(0) 18 19 /* A10 System Manager L2 ECC IRQ Clear register */ 20 #define A10_SYSMGR_MPU_CLEAR_L2_ECC_OFST 0xA8 21 #define A10_SYSMGR_MPU_CLEAR_L2_ECC (BIT(31) | BIT(15)) 22 23 void socfpga_init_l2_ecc(void) 24 { 25 struct device_node *np; 26 void __iomem *mapped_l2_edac_addr; 27 28 np = of_find_compatible_node(NULL, NULL, "altr,socfpga-l2-ecc"); 29 if (!np) { 30 pr_err("Unable to find socfpga-l2-ecc in dtb\n"); 31 return; 32 } 33 34 mapped_l2_edac_addr = of_iomap(np, 0); 35 of_node_put(np); 36 if (!mapped_l2_edac_addr) { 37 pr_err("Unable to find L2 ECC mapping in dtb\n"); 38 return; 39 } 40 41 /* Enable ECC */ 42 writel(0x01, mapped_l2_edac_addr); 43 iounmap(mapped_l2_edac_addr); 44 } 45 46 void socfpga_init_arria10_l2_ecc(void) 47 { 48 struct device_node *np; 49 void __iomem *mapped_l2_edac_addr; 50 51 /* Find the L2 EDAC device tree node */ 52 np = of_find_compatible_node(NULL, NULL, "altr,socfpga-a10-l2-ecc"); 53 if (!np) { 54 pr_err("Unable to find socfpga-a10-l2-ecc in dtb\n"); 55 return; 56 } 57 58 mapped_l2_edac_addr = of_iomap(np, 0); 59 of_node_put(np); 60 if (!mapped_l2_edac_addr) { 61 pr_err("Unable to find L2 ECC mapping in dtb\n"); 62 return; 63 } 64 65 if (!sys_manager_base_addr) { 66 pr_err("System Manager not mapped for L2 ECC\n"); 67 goto exit; 68 } 69 /* Clear any pending IRQs */ 70 writel(A10_SYSMGR_MPU_CLEAR_L2_ECC, (sys_manager_base_addr + 71 A10_SYSMGR_MPU_CLEAR_L2_ECC_OFST)); 72 /* Enable ECC */ 73 writel(A10_SYSMGR_ECC_INTMASK_CLR_L2, sys_manager_base_addr + 74 A10_SYSMGR_ECC_INTMASK_CLR_OFST); 75 writel(A10_MPU_CTRL_L2_ECC_EN, mapped_l2_edac_addr + 76 A10_MPU_CTRL_L2_ECC_OFST); 77 exit: 78 iounmap(mapped_l2_edac_addr); 79 } 80