Merge branch 'socfpga/hw' into next/soc
authorOlof Johansson <olof@lixom.net>
Tue, 12 Feb 2013 03:37:51 +0000 (19:37 -0800)
committerOlof Johansson <olof@lixom.net>
Tue, 12 Feb 2013 03:37:51 +0000 (19:37 -0800)
From Dinh Nguyen, this is a series of patches introducing support for
socfpga hardware (Altera Cyclone5). It also includes a cleanup that
moves some of the ARMv7 cache maintenance functions to a common location,
since three other platforms aready implemented it separately.

* socfpga/hw:
  arm: socfpga: Add SMP support for actual socfpga harware
  arm: Add v7_invalidate_l1 to cache-v7.S
  arm: socfpga: Add entries to enable make dtbs socfpga
  arm: socfpga: Add new device tree source for actual socfpga HW

Trivial conflict in arch/arm/mach-tegra/headsmp.S.

Signed-off-by: Olof Johansson <olof@lixom.net>
13 files changed:
Documentation/devicetree/bindings/arm/altera/socfpga-system.txt
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/socfpga.dtsi
arch/arm/boot/dts/socfpga_cyclone5.dts
arch/arm/boot/dts/socfpga_vt.dts [new file with mode: 0644]
arch/arm/mach-imx/headsmp.S
arch/arm/mach-shmobile/headsmp.S
arch/arm/mach-socfpga/core.h
arch/arm/mach-socfpga/headsmp.S
arch/arm/mach-socfpga/platsmp.c
arch/arm/mach-socfpga/socfpga.c
arch/arm/mach-tegra/headsmp.S
arch/arm/mm/cache-v7.S

index 07c65e3cdcbe1245575d89ef9b3005b9242ad707..f4d04a0672824087de6987b6be4dfd5c4fd2bf84 100644 (file)
@@ -3,9 +3,11 @@ Altera SOCFPGA System Manager
 Required properties:
 - compatible : "altr,sys-mgr"
 - reg : Should contain 1 register ranges(address and length)
+- cpu1-start-addr : CPU1 start address in hex.
 
 Example:
         sysmgr@ffd08000 {
                compatible = "altr,sys-mgr";
                reg = <0xffd08000 0x1000>;
+               cpu1-start-addr = <0xffd080c4>;
        };
index 2e7a7e2de11a5ab0272c6f7ec27b7f30b18878b1..042f2111485bb61ec82a54f55f88d7f61692a881 100644 (file)
@@ -125,6 +125,8 @@ dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
        r8a7740-armadillo800eva.dtb \
        sh73a0-kzm9g.dtb \
        sh7372-mackerel.dtb
+dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_cyclone5.dtb \
+       socfpga_vt.dtb
 dtb-$(CONFIG_ARCH_SPEAR13XX) += spear1310-evb.dtb \
        spear1340-evb.dtb
 dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \
index 19aec421bb26bab363a059e2395ebfe8fc0489a9..936d2306e7e12e9e46fd09294b6af54e41f0ccb3 100644 (file)
                ethernet0 = &gmac0;
                serial0 = &uart0;
                serial1 = &uart1;
+               timer0 = &timer0;
+               timer1 = &timer1;
+               timer2 = &timer2;
+               timer3 = &timer3;
        };
 
        cpus {
                        interrupts = <1 13 0xf04>;
                };
 
-               timer0: timer@ffc08000 {
+               timer0: timer0@ffc08000 {
                        compatible = "snps,dw-apb-timer-sp";
                        interrupts = <0 167 4>;
-                       clock-frequency = <200000000>;
                        reg = <0xffc08000 0x1000>;
                };
 
-               timer1: timer@ffc09000 {
+               timer1: timer1@ffc09000 {
                        compatible = "snps,dw-apb-timer-sp";
                        interrupts = <0 168 4>;
-                       clock-frequency = <200000000>;
                        reg = <0xffc09000 0x1000>;
                };
 
-               timer2: timer@ffd00000 {
+               timer2: timer2@ffd00000 {
                        compatible = "snps,dw-apb-timer-osc";
                        interrupts = <0 169 4>;
-                       clock-frequency = <200000000>;
                        reg = <0xffd00000 0x1000>;
                };
 
-               timer3: timer@ffd01000 {
+               timer3: timer3@ffd01000 {
                        compatible = "snps,dw-apb-timer-osc";
                        interrupts = <0 170 4>;
-                       clock-frequency = <200000000>;
                        reg = <0xffd01000 0x1000>;
                };
 
-               uart0: uart@ffc02000 {
+               uart0: serial0@ffc02000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0xffc02000 0x1000>;
-                       clock-frequency = <7372800>;
                        interrupts = <0 162 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                };
 
-               uart1: uart@ffc03000 {
+               uart1: serial1@ffc03000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0xffc03000 0x1000>;
-                       clock-frequency = <7372800>;
                        interrupts = <0 163 4>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
index ab7e4a94299fbcf704b3560c816f403248ef24ed..3ae8a83a08759021f2946f7872ceb3e53ce79c0a 100644 (file)
@@ -20,7 +20,7 @@
 
 / {
        model = "Altera SOCFPGA Cyclone V";
-       compatible = "altr,socfpga-cyclone5";
+       compatible = "altr,socfpga-cyclone5", "altr,socfpga";
 
        chosen {
                bootargs = "console=ttyS0,57600";
        memory {
                name = "memory";
                device_type = "memory";
-               reg = <0x0 0x10000000>; /* 256MB */
+               reg = <0x0 0x40000000>; /* 1GB */
+       };
+
+       soc {
+               timer0@ffc08000 {
+                       clock-frequency = <100000000>;
+               };
+
+               timer1@ffc09000 {
+                       clock-frequency = <100000000>;
+               };
+
+               timer2@ffd00000 {
+                       clock-frequency = <25000000>;
+               };
+
+               timer3@ffd01000 {
+                       clock-frequency = <25000000>;
+               };
+
+               serial0@ffc02000 {
+                       clock-frequency = <100000000>;
+               };
+
+               serial1@ffc03000 {
+                       clock-frequency = <100000000>;
+               };
+
+               sysmgr@ffd08000 {
+                       cpu1-start-addr = <0xffd080c4>;
+               };
        };
 };
diff --git a/arch/arm/boot/dts/socfpga_vt.dts b/arch/arm/boot/dts/socfpga_vt.dts
new file mode 100644 (file)
index 0000000..1036eba
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ *  Copyright (C) 2013 Altera Corporation <www.altera.com>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/dts-v1/;
+/include/ "socfpga.dtsi"
+
+/ {
+       model = "Altera SOCFPGA VT";
+       compatible = "altr,socfpga-vt", "altr,socfpga";
+
+       chosen {
+               bootargs = "console=ttyS0,57600";
+       };
+
+       memory {
+               name = "memory";
+               device_type = "memory";
+               reg = <0x0 0x40000000>; /* 1 GB */
+       };
+
+       soc {
+               timer0@ffc08000 {
+                       clock-frequency = <7000000>;
+               };
+
+               timer1@ffc09000 {
+                       clock-frequency = <7000000>;
+               };
+
+               timer2@ffd00000 {
+                       clock-frequency = <7000000>;
+               };
+
+               timer3@ffd01000 {
+                       clock-frequency = <7000000>;
+               };
+
+               serial0@ffc02000 {
+                       clock-frequency = <7372800>;
+               };
+
+               serial1@ffc03000 {
+                       clock-frequency = <7372800>;
+               };
+
+               sysmgr@ffd08000 {
+                       cpu1-start-addr = <0xffd08010>;
+               };
+       };
+};
index 7e49deb128a4ce3b91f37a86c6a168d7e8d4447c..921fc15558549093f0ff0bbcc9b9de946d520152 100644 (file)
 
        .section ".text.head", "ax"
 
-/*
- * The secondary kernel init calls v7_flush_dcache_all before it enables
- * the L1; however, the L1 comes out of reset in an undefined state, so
- * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
- * of cache lines with uninitialized data and uninitialized tags to get
- * written out to memory, which does really unpleasant things to the main
- * processor.  We fix this by performing an invalidate, rather than a
- * clean + invalidate, before jumping into the kernel.
- *
- * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs
- * to be called for both secondary cores startup and primary core resume
- * procedures.  Ideally, it should be moved into arch/arm/mm/cache-v7.S.
- */
-ENTRY(v7_invalidate_l1)
-       mov     r0, #0
-       mcr     p15, 0, r0, c7, c5, 0   @ invalidate I cache
-       mcr     p15, 2, r0, c0, c0, 0
-       mrc     p15, 1, r0, c0, c0, 0
-
-       ldr     r1, =0x7fff
-       and     r2, r1, r0, lsr #13
-
-       ldr     r1, =0x3ff
-
-       and     r3, r1, r0, lsr #3      @ NumWays - 1
-       add     r2, r2, #1              @ NumSets
-
-       and     r0, r0, #0x7
-       add     r0, r0, #4      @ SetShift
-
-       clz     r1, r3          @ WayShift
-       add     r4, r3, #1      @ NumWays
-1:     sub     r2, r2, #1      @ NumSets--
-       mov     r3, r4          @ Temp = NumWays
-2:     subs    r3, r3, #1      @ Temp--
-       mov     r5, r3, lsl r1
-       mov     r6, r2, lsl r0
-       orr     r5, r5, r6      @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
-       mcr     p15, 0, r5, c7, c6, 2
-       bgt     2b
-       cmp     r2, #0
-       bgt     1b
-       dsb
-       isb
-       mov     pc, lr
-ENDPROC(v7_invalidate_l1)
-
 #ifdef CONFIG_SMP
 ENTRY(v7_secondary_startup)
        bl      v7_invalidate_l1
index b202c1272526e3f0752b360871016f6f06567aab..96001fd49b6c90e63603186f8a1be99efb3595a6 100644 (file)
 
        __CPUINIT
 
-/* Cache invalidation nicked from arch/arm/mach-imx/head-v7.S, thanks!
- *
- * The secondary kernel init calls v7_flush_dcache_all before it enables
- * the L1; however, the L1 comes out of reset in an undefined state, so
- * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
- * of cache lines with uninitialized data and uninitialized tags to get
- * written out to memory, which does really unpleasant things to the main
- * processor.  We fix this by performing an invalidate, rather than a
- * clean + invalidate, before jumping into the kernel.
- *
- * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs
- * to be called for both secondary cores startup and primary core resume
- * procedures.  Ideally, it should be moved into arch/arm/mm/cache-v7.S.
- */
-ENTRY(v7_invalidate_l1)
-       mov     r0, #0
-       mcr     p15, 0, r0, c7, c5, 0   @ invalidate I cache
-       mcr     p15, 2, r0, c0, c0, 0
-       mrc     p15, 1, r0, c0, c0, 0
-
-       ldr     r1, =0x7fff
-       and     r2, r1, r0, lsr #13
-
-       ldr     r1, =0x3ff
-
-       and     r3, r1, r0, lsr #3      @ NumWays - 1
-       add     r2, r2, #1              @ NumSets
-
-       and     r0, r0, #0x7
-       add     r0, r0, #4      @ SetShift
-
-       clz     r1, r3          @ WayShift
-       add     r4, r3, #1      @ NumWays
-1:     sub     r2, r2, #1      @ NumSets--
-       mov     r3, r4          @ Temp = NumWays
-2:     subs    r3, r3, #1      @ Temp--
-       mov     r5, r3, lsl r1
-       mov     r6, r2, lsl r0
-       orr     r5, r5, r6      @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
-       mcr     p15, 0, r5, c7, c6, 2
-       bgt     2b
-       cmp     r2, #0
-       bgt     1b
-       dsb
-       isb
-       mov     pc, lr
-ENDPROC(v7_invalidate_l1)
-
 ENTRY(shmobile_invalidate_start)
        bl      v7_invalidate_l1
        b       secondary_startup
index 9941caa949310849968859b8b20e3da971dff7ff..315edff610f241747439e92c3c5ff858ed4570cc 100644 (file)
@@ -20,7 +20,7 @@
 #ifndef __MACH_CORE_H
 #define __MACH_CORE_H
 
-extern void secondary_startup(void);
+extern void socfpga_secondary_startup(void);
 extern void __iomem *socfpga_scu_base_addr;
 
 extern void socfpga_init_clocks(void);
@@ -29,6 +29,8 @@ extern void socfpga_sysmgr_init(void);
 extern struct smp_operations socfpga_smp_ops;
 extern char secondary_trampoline, secondary_trampoline_end;
 
+extern unsigned long cpu1start_addr;
+
 #define SOCFPGA_SCU_VIRT_BASE   0xfffec000
 
 #endif
index f09b1283ffca79fa275418bae0abb4519eba2477..9004bfb1756ee345192d78c3f2a125c2b985a8e5 100644 (file)
        __CPUINIT
        .arch   armv7-a
 
-#define CPU1_START_ADDR                0xffd08010
-
 ENTRY(secondary_trampoline)
-       movw    r0, #:lower16:CPU1_START_ADDR
-       movt  r0, #:upper16:CPU1_START_ADDR
+       movw    r2, #:lower16:cpu1start_addr
+       movt  r2, #:upper16:cpu1start_addr
+
+       /* The socfpga VT cannot handle a 0xC0000000 page offset when loading
+               the cpu1start_addr, we bit clear it. Tested on HW and VT. */
+       bic     r2, r2, #0x40000000
 
+       ldr     r0, [r2]
        ldr     r1, [r0]
        bx      r1
 
 ENTRY(secondary_trampoline_end)
+
+ENTRY(socfpga_secondary_startup)
+       bl      v7_invalidate_l1
+       b       secondary_startup
+ENDPROC(socfpga_secondary_startup)
index 4e9e69d9e7de7a69934b17c1e120642f350c3eaa..84c60fa8daa0298d290a06554683fdb22dd921c6 100644 (file)
@@ -47,16 +47,19 @@ static int __cpuinit socfpga_boot_secondary(unsigned int cpu, struct task_struct
 {
        int trampoline_size = &secondary_trampoline_end - &secondary_trampoline;
 
-       memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size);
+       if (cpu1start_addr) {
+               memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size);
 
-       __raw_writel(virt_to_phys(secondary_startup), (sys_manager_base_addr+0x10));
+               __raw_writel(virt_to_phys(socfpga_secondary_startup),
+                       (sys_manager_base_addr + (cpu1start_addr & 0x000000ff)));
 
-       flush_cache_all();
-       smp_wmb();
-       outer_clean_range(0, trampoline_size);
+               flush_cache_all();
+               smp_wmb();
+               outer_clean_range(0, trampoline_size);
 
-       /* This will release CPU #1 out of reset.*/
-       __raw_writel(0, rst_manager_base_addr + 0x10);
+               /* This will release CPU #1 out of reset.*/
+               __raw_writel(0, rst_manager_base_addr + 0x10);
+       }
 
        return 0;
 }
index 27d68468a027b85aaebccc6fc6b9833baa8b4960..1042c023cf248c09850dc1acbbb8fa24d48732be 100644 (file)
@@ -29,6 +29,7 @@
 void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE));
 void __iomem *sys_manager_base_addr;
 void __iomem *rst_manager_base_addr;
+unsigned long cpu1start_addr;
 
 static struct map_desc scu_io_desc __initdata = {
        .virtual        = SOCFPGA_SCU_VIRT_BASE,
@@ -67,6 +68,11 @@ void __init socfpga_sysmgr_init(void)
        struct device_node *np;
 
        np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr");
+
+       if (of_property_read_u32(np, "cpu1-start-addr",
+                       (u32 *) &cpu1start_addr))
+               pr_err("SMP: Need cpu1-start-addr in device tree.\n");
+
        sys_manager_base_addr = of_iomap(np, 0);
 
        np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr");
@@ -93,7 +99,6 @@ static void __init socfpga_cyclone5_init(void)
 
 static const char *altera_dt_match[] = {
        "altr,socfpga",
-       "altr,socfpga-cyclone5",
        NULL
 };
 
index b2834810b02b4bd3a6eea454c433b7fabab24523..fd473f2b4c3d981e391a3fd8560c51f0b3ddedce 100644 (file)
@@ -5,49 +5,6 @@
 
         .section ".text.head", "ax"
 
-/*
- * Tegra specific entry point for secondary CPUs.
- *   The secondary kernel init calls v7_flush_dcache_all before it enables
- *   the L1; however, the L1 comes out of reset in an undefined state, so
- *   the clean + invalidate performed by v7_flush_dcache_all causes a bunch
- *   of cache lines with uninitialized data and uninitialized tags to get
- *   written out to memory, which does really unpleasant things to the main
- *   processor.  We fix this by performing an invalidate, rather than a
- *   clean + invalidate, before jumping into the kernel.
- */
-ENTRY(v7_invalidate_l1)
-        mov     r0, #0
-        mcr     p15, 2, r0, c0, c0, 0
-        mrc     p15, 1, r0, c0, c0, 0
-
-        ldr     r1, =0x7fff
-        and     r2, r1, r0, lsr #13
-
-        ldr     r1, =0x3ff
-
-        and     r3, r1, r0, lsr #3  @ NumWays - 1
-        add     r2, r2, #1          @ NumSets
-
-        and     r0, r0, #0x7
-        add     r0, r0, #4          @ SetShift
-
-        clz     r1, r3              @ WayShift
-        add     r4, r3, #1          @ NumWays
-1:      sub     r2, r2, #1          @ NumSets--
-        mov     r3, r4              @ Temp = NumWays
-2:      subs    r3, r3, #1          @ Temp--
-        mov     r5, r3, lsl r1
-        mov     r6, r2, lsl r0
-        orr     r5, r5, r6          @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
-        mcr     p15, 0, r5, c7, c6, 2
-        bgt     2b
-        cmp     r2, #0
-        bgt     1b
-        dsb
-        isb
-        mov     pc, lr
-ENDPROC(v7_invalidate_l1)
-
 ENTRY(tegra_secondary_startup)
         bl      v7_invalidate_l1
        /* Enable coresight */
index 7539ec27506585f3dd42b04f785c5edba39d1614..15451ee4acc8f61f1ebd2f20164290c28c2b6a12 100644 (file)
 
 #include "proc-macros.S"
 
+/*
+ * The secondary kernel init calls v7_flush_dcache_all before it enables
+ * the L1; however, the L1 comes out of reset in an undefined state, so
+ * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
+ * of cache lines with uninitialized data and uninitialized tags to get
+ * written out to memory, which does really unpleasant things to the main
+ * processor.  We fix this by performing an invalidate, rather than a
+ * clean + invalidate, before jumping into the kernel.
+ *
+ * This function is cloned from arch/arm/mach-tegra/headsmp.S, and needs
+ * to be called for both secondary cores startup and primary core resume
+ * procedures.
+ */
+ENTRY(v7_invalidate_l1)
+       mov     r0, #0
+       mcr     p15, 2, r0, c0, c0, 0
+       mrc     p15, 1, r0, c0, c0, 0
+
+       ldr     r1, =0x7fff
+       and     r2, r1, r0, lsr #13
+
+       ldr     r1, =0x3ff
+
+       and     r3, r1, r0, lsr #3      @ NumWays - 1
+       add     r2, r2, #1              @ NumSets
+
+       and     r0, r0, #0x7
+       add     r0, r0, #4      @ SetShift
+
+       clz     r1, r3          @ WayShift
+       add     r4, r3, #1      @ NumWays
+1:     sub     r2, r2, #1      @ NumSets--
+       mov     r3, r4          @ Temp = NumWays
+2:     subs    r3, r3, #1      @ Temp--
+       mov     r5, r3, lsl r1
+       mov     r6, r2, lsl r0
+       orr     r5, r5, r6      @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
+       mcr     p15, 0, r5, c7, c6, 2
+       bgt     2b
+       cmp     r2, #0
+       bgt     1b
+       dsb
+       isb
+       mov     pc, lr
+ENDPROC(v7_invalidate_l1)
+
 /*
  *     v7_flush_icache_all()
  *