1 /* 2 * Copyright Altera Corporation (C) 2016. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms and conditions of the GNU General Public License, 6 * version 2, as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * more details. 12 * 13 * You should have received a copy of the GNU General Public License along with 14 * this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 #include <linux/io.h> 17 #include <linux/of_platform.h> 18 #include <linux/of_address.h> 19 20 #include "core.h" 21 22 /* A10 System Manager L2 ECC Control register */ 23 #define A10_MPU_CTRL_L2_ECC_OFST 0x0 24 #define A10_MPU_CTRL_L2_ECC_EN BIT(0) 25 26 /* A10 System Manager Global IRQ Mask register */ 27 #define A10_SYSMGR_ECC_INTMASK_CLR_OFST 0x98 28 #define A10_SYSMGR_ECC_INTMASK_CLR_L2 BIT(0) 29 30 /* A10 System Manager L2 ECC IRQ Clear register */ 31 #define A10_SYSMGR_MPU_CLEAR_L2_ECC_OFST 0xA8 32 #define A10_SYSMGR_MPU_CLEAR_L2_ECC (BIT(31) | BIT(15)) 33 34 void socfpga_init_l2_ecc(void) 35 { 36 struct device_node *np; 37 void __iomem *mapped_l2_edac_addr; 38 39 np = of_find_compatible_node(NULL, NULL, "altr,socfpga-l2-ecc"); 40 if (!np) { 41 pr_err("Unable to find socfpga-l2-ecc in dtb\n"); 42 return; 43 } 44 45 mapped_l2_edac_addr = of_iomap(np, 0); 46 of_node_put(np); 47 if (!mapped_l2_edac_addr) { 48 pr_err("Unable to find L2 ECC mapping in dtb\n"); 49 return; 50 } 51 52 /* Enable ECC */ 53 writel(0x01, mapped_l2_edac_addr); 54 iounmap(mapped_l2_edac_addr); 55 } 56 57 void socfpga_init_arria10_l2_ecc(void) 58 { 59 struct device_node *np; 60 void __iomem *mapped_l2_edac_addr; 61 62 /* Find the L2 EDAC device tree node */ 63 np = of_find_compatible_node(NULL, NULL, "altr,socfpga-a10-l2-ecc"); 64 if (!np) { 65 pr_err("Unable to find socfpga-a10-l2-ecc in dtb\n"); 66 return; 67 } 68 69 mapped_l2_edac_addr = of_iomap(np, 0); 70 of_node_put(np); 71 if (!mapped_l2_edac_addr) { 72 pr_err("Unable to find L2 ECC mapping in dtb\n"); 73 return; 74 } 75 76 if (!sys_manager_base_addr) { 77 pr_err("System Manager not mapped for L2 ECC\n"); 78 goto exit; 79 } 80 /* Clear any pending IRQs */ 81 writel(A10_SYSMGR_MPU_CLEAR_L2_ECC, (sys_manager_base_addr + 82 A10_SYSMGR_MPU_CLEAR_L2_ECC_OFST)); 83 /* Enable ECC */ 84 writel(A10_SYSMGR_ECC_INTMASK_CLR_L2, sys_manager_base_addr + 85 A10_SYSMGR_ECC_INTMASK_CLR_OFST); 86 writel(A10_MPU_CTRL_L2_ECC_EN, mapped_l2_edac_addr + 87 A10_MPU_CTRL_L2_ECC_OFST); 88 exit: 89 iounmap(mapped_l2_edac_addr); 90 } 91