/* * Architected Timer setup for SMDK5250 board based on EXYNOS5 * * Copyright (C) 2012 Christoffer Dall * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include #include #include #include #include "setup.h" #define ARM_GICV2_DIST_CTRL 0x00 #define ARM_GICV2_DIST_TYPE 0x04 #define ARM_GICV2_DIST_SEC_REG 0x80 #define ARM_GICV2_CPU_CTRL 0x00 #define ARM_GICV2_ICCPMR 0x04 static unsigned long read_mpidr(void) { unsigned long val; asm volatile("mrc p15, 0, %0, c0, c0, 5": "=r" (val)); return val; } static unsigned long read_nsacr(void) { unsigned long val; asm volatile("mrc p15, 0, %0, c1, c1, 2": "=r" (val)); return val; } static void write_nsacr(unsigned long val) { asm volatile("mcr p15, 0, %0, c1, c1, 2": : "r" (val)); } void non_secure_init(void) { unsigned long addr, type, num_regs; unsigned long nsacr, ctrl; int i; addr = EXYNOS5_GIC_DIST_BASE; type = readl(addr + ARM_GICV2_DIST_TYPE); num_regs = (type & 0x1f) + 1; /* Set all interrupts to be non-secure */ addr = EXYNOS5_GIC_DIST_BASE + ARM_GICV2_DIST_SEC_REG; for (i = 0; i < num_regs; i++) { writel(0xffffffff, addr); addr += 4; } /* Set GIC priority mask bit [7] = 1 */ addr = EXYNOS5_GIC_CPU_BASE; writel(0x80, addr + ARM_GICV2_ICCPMR); /* Set NSACR to allow coprocessor access from non-secure */ nsacr = read_nsacr(); nsacr |= 0x43fff; write_nsacr(nsacr); /* Enable group 1 interrupts on CPU interface */ addr = EXYNOS5_GIC_CPU_BASE + ARM_GICV2_CPU_CTRL; ctrl = readl(addr); writel(ctrl | 0x1, addr); /* Disable group 0 interrupts and enable group 1 interrupts on Dist */ addr = EXYNOS5_GIC_DIST_BASE + ARM_GICV2_DIST_CTRL; ctrl = readl(addr); ctrl = (ctrl & ~0x1) | 0x2; writel(ctrl | 0x1, addr); }