aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-19 12:46:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-19 12:46:18 -0400
commit0efacbbaee1e94e9942da0912f5b46ffd45a74bd (patch)
treea17933437de955f4ce5e74760610bab75f2ae385
parentf4f27d0028aabce57e44c16c2fdefccd6310d2f3 (diff)
parent776d7f1694a7d678291354a05f0243965708306a (diff)
Merge tag 'arc-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc
Pull ARC updates from Vineet Gupta: "We have a relatively big changeset for ARC for 4.7. The highlight is support for EZChip (now Mellanox) NPS-400 network processor, a 400-Gb throughput C-programmable packet processor based on ARC700 cores from Synopsys. See http://www.mellanox.com/related-docs/prod_npu/PB_NPS-400.pdf Also present are irqchip and clocksource drivers for NPS as agreed with respective maintainers to go via ARC tree due to an soc header dependency. I have the needed ACKs from Jason, Marc, Daniel. You might run into a trivial merge conflict in drivers/irqchip/* This EZChip platform support required some deep changes in ARC architecture code and also opportunity to cleanup past sins (legacy irq domains, missing irq domain lookup, hard coded timer irqs...) Summary: - Support for EZChip (now Mellanox) NPS-400 Network processor based on ARC700 - NPS interrupt controller and clocksource drivers - ARC timers probed off DT - ARC iqrchips switching to linear domain (upgrade from legacy domains)" * tag 'arc-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: (37 commits) arc: axs103_smp: Fix CPU frequency to 100MHz for dual-core arc: axs10x: Add DT bindings for I2S PLL Clock ARC: pae: STRICT_MM_TYPECHECKS was broken ARC: Add eznps platform to Kconfig and Makefile ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE ARC: [plat-eznps] Use dedicated cpu_relax() ARC: [plat-eznps] Use dedicated identity auxiliary register. ARC: [plat-eznps] Use dedicated SMP barriers ARC: [plat-eznps] Use dedicated atomic/bitops/cmpxchg ARC: [plat-eznps] Use dedicated user stack top ARC: [plat-eznps] Add eznps platform ARC: [plat-eznps] Add eznps board defconfig and dts ARC: Mark secondary cpu online only after all HW setup is done ARC: rwlock: disable interrupts in !LLSC variant ARC: Make vmalloc size configurable ARC: clean out UAPI byteorder.h clean off Kconfig symbol irqchip: add nps Internal and external irqchips clocksource: Add NPS400 timers driver soc: Support for EZchip SoC Documentation: Add EZchip vendor to binding list ...
-rw-r--r--Documentation/devicetree/bindings/arc/eznps.txt7
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt17
-rw-r--r--Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt15
-rw-r--r--Documentation/devicetree/bindings/timer/snps,arc-timer.txt31
-rw-r--r--Documentation/devicetree/bindings/timer/snps,archs-gfrc.txt14
-rw-r--r--Documentation/devicetree/bindings/timer/snps,archs-rtc.txt14
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt1
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/arc/Kconfig16
-rw-r--r--arch/arc/Makefile5
-rw-r--r--arch/arc/boot/dts/abilis_tb10x.dtsi14
-rw-r--r--arch/arc/boot/dts/axc001.dtsi14
-rw-r--r--arch/arc/boot/dts/axc003.dtsi16
-rw-r--r--arch/arc/boot/dts/axc003_idu.dtsi14
-rw-r--r--arch/arc/boot/dts/axs10x_mb.dtsi13
-rw-r--r--arch/arc/boot/dts/eznps.dts96
-rw-r--r--arch/arc/boot/dts/nsim_700.dts10
-rw-r--r--arch/arc/boot/dts/nsim_hs.dts8
-rw-r--r--arch/arc/boot/dts/nsim_hs_idu.dts8
-rw-r--r--arch/arc/boot/dts/nsimosci.dts10
-rw-r--r--arch/arc/boot/dts/nsimosci_hs.dts8
-rw-r--r--arch/arc/boot/dts/nsimosci_hs_idu.dts8
-rw-r--r--arch/arc/boot/dts/skeleton.dtsi14
-rw-r--r--arch/arc/boot/dts/skeleton_hs.dtsi52
-rw-r--r--arch/arc/boot/dts/skeleton_hs_idu.dtsi46
-rw-r--r--arch/arc/boot/dts/vdk_axc003.dtsi14
-rw-r--r--arch/arc/boot/dts/vdk_axc003_idu.dtsi12
-rw-r--r--arch/arc/configs/nps_defconfig84
-rw-r--r--arch/arc/include/asm/atomic.h83
-rw-r--r--arch/arc/include/asm/barrier.h12
-rw-r--r--arch/arc/include/asm/bitops.h60
-rw-r--r--arch/arc/include/asm/clk.h22
-rw-r--r--arch/arc/include/asm/cmpxchg.h76
-rw-r--r--arch/arc/include/asm/entry-compact.h6
-rw-r--r--arch/arc/include/asm/irq.h13
-rw-r--r--arch/arc/include/asm/page.h4
-rw-r--r--arch/arc/include/asm/pgtable.h2
-rw-r--r--arch/arc/include/asm/processor.h51
-rw-r--r--arch/arc/include/asm/setup.h4
-rw-r--r--arch/arc/include/asm/spinlock.h14
-rw-r--r--arch/arc/include/uapi/asm/byteorder.h2
-rw-r--r--arch/arc/kernel/Makefile2
-rw-r--r--arch/arc/kernel/clk.c21
-rw-r--r--arch/arc/kernel/ctx_sw.c13
-rw-r--r--arch/arc/kernel/devtree.c13
-rw-r--r--arch/arc/kernel/intc-arcv2.c17
-rw-r--r--arch/arc/kernel/intc-compact.c17
-rw-r--r--arch/arc/kernel/irq.c50
-rw-r--r--arch/arc/kernel/mcip.c7
-rw-r--r--arch/arc/kernel/setup.c17
-rw-r--r--arch/arc/kernel/smp.c25
-rw-r--r--arch/arc/kernel/time.c238
-rw-r--r--arch/arc/mm/tlb.c11
-rw-r--r--arch/arc/plat-axs10x/axs10x.c27
-rw-r--r--arch/arc/plat-eznps/Kconfig35
-rw-r--r--arch/arc/plat-eznps/Makefile7
-rw-r--r--arch/arc/plat-eznps/entry.S70
-rw-r--r--arch/arc/plat-eznps/include/plat/ctop.h209
-rw-r--r--arch/arc/plat-eznps/include/plat/mtm.h60
-rw-r--r--arch/arc/plat-eznps/include/plat/smp.h26
-rw-r--r--arch/arc/plat-eznps/mtm.c133
-rw-r--r--arch/arc/plat-eznps/platform.c102
-rw-r--r--arch/arc/plat-eznps/smp.c155
-rw-r--r--drivers/clocksource/Kconfig10
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/timer-nps.c98
-rw-r--r--drivers/irqchip/Kconfig6
-rw-r--r--drivers/irqchip/Makefile1
-rw-r--r--drivers/irqchip/irq-eznps.c165
-rw-r--r--include/soc/nps/common.h166
70 files changed, 2334 insertions, 284 deletions
diff --git a/Documentation/devicetree/bindings/arc/eznps.txt b/Documentation/devicetree/bindings/arc/eznps.txt
new file mode 100644
index 000000000000..1aa50c640678
--- /dev/null
+++ b/Documentation/devicetree/bindings/arc/eznps.txt
@@ -0,0 +1,7 @@
1EZchip NPS Network Processor Platforms Device Tree Bindings
2---------------------------------------------------------------------------
3
4Appliance main board with NPS400 ASIC.
5
6Required root node properties:
7 - compatible = "ezchip,arc-nps";
diff --git a/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
new file mode 100644
index 000000000000..888b2b9f7064
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
@@ -0,0 +1,17 @@
1EZchip NPS Interrupt Controller
2
3Required properties:
4
5- compatible : should be "ezchip,nps400-ic"
6- interrupt-controller : Identifies the node as an interrupt controller
7- #interrupt-cells : Specifies the number of cells needed to encode an
8 interrupt source. The value shall be 1.
9
10
11Example:
12
13intc: interrupt-controller {
14 compatible = "ezchip,nps400-ic";
15 interrupt-controller;
16 #interrupt-cells = <1>;
17};
diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
new file mode 100644
index 000000000000..c8c03d700382
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
@@ -0,0 +1,15 @@
1NPS Network Processor
2
3Required properties:
4
5- compatible : should be "ezchip,nps400-timer"
6
7Clocks required for compatible = "ezchip,nps400-timer":
8- clocks : Must contain a single entry describing the clock input
9
10Example:
11
12timer {
13 compatible = "ezchip,nps400-timer";
14 clocks = <&sysclk>;
15};
diff --git a/Documentation/devicetree/bindings/timer/snps,arc-timer.txt b/Documentation/devicetree/bindings/timer/snps,arc-timer.txt
new file mode 100644
index 000000000000..4ef024630d61
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/snps,arc-timer.txt
@@ -0,0 +1,31 @@
1Synopsys ARC Local Timer with Interrupt Capabilities
2- Found on all ARC CPUs (ARC700/ARCHS)
3- Can be optionally programmed to interrupt on Limit
4- Two idential copies TIMER0 and TIMER1 exist in ARC cores and historically
5 TIMER0 used as clockevent provider (true for all ARC cores)
6 TIMER1 used for clocksource (mandatory for ARC700, optional for ARC HS)
7
8Required properties:
9
10- compatible : should be "snps,arc-timer"
11- interrupts : single Interrupt going into parent intc
12 (16 for ARCHS cores, 3 for ARC700 cores)
13- clocks : phandle to the source clock
14
15Optional properties:
16
17- interrupt-parent : phandle to parent intc
18
19Example:
20
21 timer0 {
22 compatible = "snps,arc-timer";
23 interrupts = <3>;
24 interrupt-parent = <&core_intc>;
25 clocks = <&core_clk>;
26 };
27
28 timer1 {
29 compatible = "snps,arc-timer";
30 clocks = <&core_clk>;
31 };
diff --git a/Documentation/devicetree/bindings/timer/snps,archs-gfrc.txt b/Documentation/devicetree/bindings/timer/snps,archs-gfrc.txt
new file mode 100644
index 000000000000..b6cd1b3922de
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/snps,archs-gfrc.txt
@@ -0,0 +1,14 @@
1Synopsys ARC Free Running 64-bit Global Timer for ARC HS CPUs
2- clocksource provider for SMP SoC
3
4Required properties:
5
6- compatible : should be "snps,archs-gfrc"
7- clocks : phandle to the source clock
8
9Example:
10
11 gfrc {
12 compatible = "snps,archs-gfrc";
13 clocks = <&core_clk>;
14 };
diff --git a/Documentation/devicetree/bindings/timer/snps,archs-rtc.txt b/Documentation/devicetree/bindings/timer/snps,archs-rtc.txt
new file mode 100644
index 000000000000..47bd7a702f3f
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/snps,archs-rtc.txt
@@ -0,0 +1,14 @@
1Synopsys ARC Free Running 64-bit Local Timer for ARC HS CPUs
2- clocksource provider for UP SoC
3
4Required properties:
5
6- compatible : should be "snps,archs-rtc"
7- clocks : phandle to the source clock
8
9Example:
10
11 rtc {
12 compatible = "snps,arc-rtc";
13 clocks = <&core_clk>;
14 };
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 3af48e8cc7d0..021bbe7866e0 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -88,6 +88,7 @@ eukrea Eukréa Electromatique
88everest Everest Semiconductor Co. Ltd. 88everest Everest Semiconductor Co. Ltd.
89everspin Everspin Technologies, Inc. 89everspin Everspin Technologies, Inc.
90excito Excito 90excito Excito
91ezchip EZchip Semiconductor
91fcs Fairchild Semiconductor 92fcs Fairchild Semiconductor
92firefly Firefly 93firefly Firefly
93focaltech FocalTech Systems Co.,Ltd 94focaltech FocalTech Systems Co.,Ltd
diff --git a/MAINTAINERS b/MAINTAINERS
index 71bcef4a161c..3f14e1dffa6a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4444,6 +4444,12 @@ S: Maintained
4444F: drivers/video/fbdev/exynos/exynos_mipi* 4444F: drivers/video/fbdev/exynos/exynos_mipi*
4445F: include/video/exynos_mipi* 4445F: include/video/exynos_mipi*
4446 4446
4447EZchip NPS platform support
4448M: Noam Camus <noamc@ezchip.com>
4449S: Supported
4450F: arch/arc/plat-eznps
4451F: arch/arc/boot/dts/eznps.dts
4452
4447F71805F HARDWARE MONITORING DRIVER 4453F71805F HARDWARE MONITORING DRIVER
4448M: Jean Delvare <jdelvare@suse.com> 4454M: Jean Delvare <jdelvare@suse.com>
4449L: linux-hwmon@vger.kernel.org 4455L: linux-hwmon@vger.kernel.org
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index a8767430df7d..8894f7e7e3de 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -10,8 +10,9 @@ config ARC
10 def_bool y 10 def_bool y
11 select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC 11 select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC
12 select BUILDTIME_EXTABLE_SORT 12 select BUILDTIME_EXTABLE_SORT
13 select COMMON_CLK 13 select CLKSRC_OF
14 select CLONE_BACKWARDS 14 select CLONE_BACKWARDS
15 select COMMON_CLK
15 select GENERIC_ATOMIC64 16 select GENERIC_ATOMIC64
16 select GENERIC_CLOCKEVENTS 17 select GENERIC_CLOCKEVENTS
17 select GENERIC_FIND_FIRST_BIT 18 select GENERIC_FIND_FIRST_BIT
@@ -30,6 +31,7 @@ config ARC
30 select HAVE_MOD_ARCH_SPECIFIC if ARC_DW2_UNWIND 31 select HAVE_MOD_ARCH_SPECIFIC if ARC_DW2_UNWIND
31 select HAVE_OPROFILE 32 select HAVE_OPROFILE
32 select HAVE_PERF_EVENTS 33 select HAVE_PERF_EVENTS
34 select HANDLE_DOMAIN_IRQ
33 select IRQ_DOMAIN 35 select IRQ_DOMAIN
34 select MODULES_USE_ELF_RELA 36 select MODULES_USE_ELF_RELA
35 select NO_BOOTMEM 37 select NO_BOOTMEM
@@ -95,6 +97,7 @@ source "arch/arc/plat-sim/Kconfig"
95source "arch/arc/plat-tb10x/Kconfig" 97source "arch/arc/plat-tb10x/Kconfig"
96source "arch/arc/plat-axs10x/Kconfig" 98source "arch/arc/plat-axs10x/Kconfig"
97#New platform adds here 99#New platform adds here
100source "arch/arc/plat-eznps/Kconfig"
98 101
99endmenu 102endmenu
100 103
@@ -490,6 +493,17 @@ config ARCH_DMA_ADDR_T_64BIT
490config ARC_PLAT_NEEDS_PHYS_TO_DMA 493config ARC_PLAT_NEEDS_PHYS_TO_DMA
491 bool 494 bool
492 495
496config ARC_KVADDR_SIZE
497 int "Kernel Virtaul Address Space size (MB)"
498 range 0 512
499 default "256"
500 help
501 The kernel address space is carved out of 256MB of translated address
502 space for catering to vmalloc, modules, pkmap, fixmap. This however may
503 not suffice vmalloc requirements of a 4K CPU EZChip system. So allow
504 this to be stretched to 512 MB (by extending into the reserved
505 kernel-user gutter)
506
493config ARC_CURR_IN_REG 507config ARC_CURR_IN_REG
494 bool "Dedicate Register r25 for current_task pointer" 508 bool "Dedicate Register r25 for current_task pointer"
495 default y 509 default y
diff --git a/arch/arc/Makefile b/arch/arc/Makefile
index def69e347b2d..02fabef2891c 100644
--- a/arch/arc/Makefile
+++ b/arch/arc/Makefile
@@ -115,6 +115,11 @@ core-y += arch/arc/boot/dts/
115core-$(CONFIG_ARC_PLAT_SIM) += arch/arc/plat-sim/ 115core-$(CONFIG_ARC_PLAT_SIM) += arch/arc/plat-sim/
116core-$(CONFIG_ARC_PLAT_TB10X) += arch/arc/plat-tb10x/ 116core-$(CONFIG_ARC_PLAT_TB10X) += arch/arc/plat-tb10x/
117core-$(CONFIG_ARC_PLAT_AXS10X) += arch/arc/plat-axs10x/ 117core-$(CONFIG_ARC_PLAT_AXS10X) += arch/arc/plat-axs10x/
118core-$(CONFIG_ARC_PLAT_EZNPS) += arch/arc/plat-eznps/
119
120ifdef CONFIG_ARC_PLAT_EZNPS
121KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-eznps/include
122endif
118 123
119drivers-$(CONFIG_OPROFILE) += arch/arc/oprofile/ 124drivers-$(CONFIG_OPROFILE) += arch/arc/oprofile/
120 125
diff --git a/arch/arc/boot/dts/abilis_tb10x.dtsi b/arch/arc/boot/dts/abilis_tb10x.dtsi
index cfb5052239a1..663671f22680 100644
--- a/arch/arc/boot/dts/abilis_tb10x.dtsi
+++ b/arch/arc/boot/dts/abilis_tb10x.dtsi
@@ -35,6 +35,20 @@
35 }; 35 };
36 }; 36 };
37 37
38 /* TIMER0 with interrupt for clockevent */
39 timer0 {
40 compatible = "snps,arc-timer";
41 interrupts = <3>;
42 interrupt-parent = <&intc>;
43 clocks = <&cpu_clk>;
44 };
45
46 /* TIMER1 for free running clocksource */
47 timer1 {
48 compatible = "snps,arc-timer";
49 clocks = <&cpu_clk>;
50 };
51
38 soc100 { 52 soc100 {
39 #address-cells = <1>; 53 #address-cells = <1>;
40 #size-cells = <1>; 54 #size-cells = <1>;
diff --git a/arch/arc/boot/dts/axc001.dtsi b/arch/arc/boot/dts/axc001.dtsi
index 420dcfde289f..40bcecfc3687 100644
--- a/arch/arc/boot/dts/axc001.dtsi
+++ b/arch/arc/boot/dts/axc001.dtsi
@@ -11,6 +11,8 @@
11 * Note that this file only supports the 770D CPU 11 * Note that this file only supports the 770D CPU
12 */ 12 */
13 13
14/include/ "skeleton.dtsi"
15
14/ { 16/ {
15 compatible = "snps,arc"; 17 compatible = "snps,arc";
16 clock-frequency = <750000000>; /* 750 MHZ */ 18 clock-frequency = <750000000>; /* 750 MHZ */
@@ -24,7 +26,13 @@
24 26
25 ranges = <0x00000000 0xf0000000 0x10000000>; 27 ranges = <0x00000000 0xf0000000 0x10000000>;
26 28
27 cpu_intc: arc700-intc@cpu { 29 core_clk: core_clk {
30 #clock-cells = <0>;
31 compatible = "fixed-clock";
32 clock-frequency = <750000000>;
33 };
34
35 core_intc: arc700-intc@cpu {
28 compatible = "snps,arc700-intc"; 36 compatible = "snps,arc700-intc";
29 interrupt-controller; 37 interrupt-controller;
30 #interrupt-cells = <1>; 38 #interrupt-cells = <1>;
@@ -48,7 +56,7 @@
48 reg = <0>; 56 reg = <0>;
49 interrupt-controller; 57 interrupt-controller;
50 #interrupt-cells = <2>; 58 #interrupt-cells = <2>;
51 interrupt-parent = <&cpu_intc>; 59 interrupt-parent = <&core_intc>;
52 interrupts = <15>; 60 interrupts = <15>;
53 }; 61 };
54 }; 62 };
@@ -86,7 +94,7 @@
86 compatible = "snps,dw-apb-ictl"; 94 compatible = "snps,dw-apb-ictl";
87 reg = < 0xe0012000 0x200 >; 95 reg = < 0xe0012000 0x200 >;
88 interrupt-controller; 96 interrupt-controller;
89 interrupt-parent = <&cpu_intc>; 97 interrupt-parent = <&core_intc>;
90 interrupts = < 7 >; 98 interrupts = < 7 >;
91 }; 99 };
92 100
diff --git a/arch/arc/boot/dts/axc003.dtsi b/arch/arc/boot/dts/axc003.dtsi
index f90fadf7f94e..cabe0deeb2d8 100644
--- a/arch/arc/boot/dts/axc003.dtsi
+++ b/arch/arc/boot/dts/axc003.dtsi
@@ -10,6 +10,8 @@
10 * Device tree for AXC003 CPU card: HS38x UP configuration 10 * Device tree for AXC003 CPU card: HS38x UP configuration
11 */ 11 */
12 12
13/include/ "skeleton_hs.dtsi"
14
13/ { 15/ {
14 compatible = "snps,arc"; 16 compatible = "snps,arc";
15 clock-frequency = <90000000>; 17 clock-frequency = <90000000>;
@@ -23,7 +25,13 @@
23 25
24 ranges = <0x00000000 0xf0000000 0x10000000>; 26 ranges = <0x00000000 0xf0000000 0x10000000>;
25 27
26 cpu_intc: archs-intc@cpu { 28 core_clk: core_clk {
29 #clock-cells = <0>;
30 compatible = "fixed-clock";
31 clock-frequency = <90000000>;
32 };
33
34 core_intc: archs-intc@cpu {
27 compatible = "snps,archs-intc"; 35 compatible = "snps,archs-intc";
28 interrupt-controller; 36 interrupt-controller;
29 #interrupt-cells = <1>; 37 #interrupt-cells = <1>;
@@ -47,7 +55,7 @@
47 reg = <0>; 55 reg = <0>;
48 interrupt-controller; 56 interrupt-controller;
49 #interrupt-cells = <2>; 57 #interrupt-cells = <2>;
50 interrupt-parent = <&cpu_intc>; 58 interrupt-parent = <&core_intc>;
51 interrupts = <25>; 59 interrupts = <25>;
52 }; 60 };
53 }; 61 };
@@ -66,7 +74,7 @@
66 arcpct0: pct { 74 arcpct0: pct {
67 compatible = "snps,archs-pct"; 75 compatible = "snps,archs-pct";
68 #interrupt-cells = <1>; 76 #interrupt-cells = <1>;
69 interrupt-parent = <&cpu_intc>; 77 interrupt-parent = <&core_intc>;
70 interrupts = <20>; 78 interrupts = <20>;
71 }; 79 };
72 }; 80 };
@@ -89,7 +97,7 @@
89 compatible = "snps,dw-apb-ictl"; 97 compatible = "snps,dw-apb-ictl";
90 reg = < 0xe0012000 0x200 >; 98 reg = < 0xe0012000 0x200 >;
91 interrupt-controller; 99 interrupt-controller;
92 interrupt-parent = <&cpu_intc>; 100 interrupt-parent = <&core_intc>;
93 interrupts = < 24 >; 101 interrupts = < 24 >;
94 }; 102 };
95 103
diff --git a/arch/arc/boot/dts/axc003_idu.dtsi b/arch/arc/boot/dts/axc003_idu.dtsi
index 06a9f294a2e6..ed1674b16e82 100644
--- a/arch/arc/boot/dts/axc003_idu.dtsi
+++ b/arch/arc/boot/dts/axc003_idu.dtsi
@@ -10,6 +10,8 @@
10 * Device tree for AXC003 CPU card: HS38x2 (Dual Core) with IDU intc 10 * Device tree for AXC003 CPU card: HS38x2 (Dual Core) with IDU intc
11 */ 11 */
12 12
13/include/ "skeleton_hs_idu.dtsi"
14
13/ { 15/ {
14 compatible = "snps,arc"; 16 compatible = "snps,arc";
15 clock-frequency = <90000000>; 17 clock-frequency = <90000000>;
@@ -23,7 +25,13 @@
23 25
24 ranges = <0x00000000 0xf0000000 0x10000000>; 26 ranges = <0x00000000 0xf0000000 0x10000000>;
25 27
26 cpu_intc: archs-intc@cpu { 28 core_clk: core_clk {
29 #clock-cells = <0>;
30 compatible = "fixed-clock";
31 clock-frequency = <100000000>;
32 };
33
34 core_intc: archs-intc@cpu {
27 compatible = "snps,archs-intc"; 35 compatible = "snps,archs-intc";
28 interrupt-controller; 36 interrupt-controller;
29 #interrupt-cells = <1>; 37 #interrupt-cells = <1>;
@@ -32,7 +40,7 @@
32 idu_intc: idu-interrupt-controller { 40 idu_intc: idu-interrupt-controller {
33 compatible = "snps,archs-idu-intc"; 41 compatible = "snps,archs-idu-intc";
34 interrupt-controller; 42 interrupt-controller;
35 interrupt-parent = <&cpu_intc>; 43 interrupt-parent = <&core_intc>;
36 44
37 /* 45 /*
38 * <hwirq distribution> 46 * <hwirq distribution>
@@ -89,7 +97,7 @@
89 arcpct0: pct { 97 arcpct0: pct {
90 compatible = "snps,archs-pct"; 98 compatible = "snps,archs-pct";
91 #interrupt-cells = <1>; 99 #interrupt-cells = <1>;
92 interrupt-parent = <&cpu_intc>; 100 interrupt-parent = <&core_intc>;
93 interrupts = <20>; 101 interrupts = <20>;
94 }; 102 };
95 }; 103 };
diff --git a/arch/arc/boot/dts/axs10x_mb.dtsi b/arch/arc/boot/dts/axs10x_mb.dtsi
index 44a578c10732..68c84a2fc1e4 100644
--- a/arch/arc/boot/dts/axs10x_mb.dtsi
+++ b/arch/arc/boot/dts/axs10x_mb.dtsi
@@ -16,7 +16,20 @@
16 ranges = <0x00000000 0xe0000000 0x10000000>; 16 ranges = <0x00000000 0xe0000000 0x10000000>;
17 interrupt-parent = <&mb_intc>; 17 interrupt-parent = <&mb_intc>;
18 18
19 i2sclk: i2sclk@100a0 {
20 compatible = "snps,axs10x-i2s-pll-clock";
21 reg = <0x100a0 0x10>;
22 clocks = <&i2spll_clk>;
23 #clock-cells = <0>;
24 };
25
19 clocks { 26 clocks {
27 i2spll_clk: i2spll_clk {
28 compatible = "fixed-clock";
29 clock-frequency = <27000000>;
30 #clock-cells = <0>;
31 };
32
20 i2cclk: i2cclk { 33 i2cclk: i2cclk {
21 compatible = "fixed-clock"; 34 compatible = "fixed-clock";
22 clock-frequency = <50000000>; 35 clock-frequency = <50000000>;
diff --git a/arch/arc/boot/dts/eznps.dts b/arch/arc/boot/dts/eznps.dts
new file mode 100644
index 000000000000..b89f6c3eb352
--- /dev/null
+++ b/arch/arc/boot/dts/eznps.dts
@@ -0,0 +1,96 @@
1/*
2 * Copyright(c) 2015 EZchip Technologies.
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 * The full GNU General Public License is included in this distribution in
14 * the file called "COPYING".
15 */
16
17/dts-v1/;
18
19/ {
20 compatible = "ezchip,arc-nps";
21 clock-frequency = <83333333>; /* 83.333333 MHZ */
22 #address-cells = <1>;
23 #size-cells = <1>;
24 interrupt-parent = <&intc>;
25 present-cpus = "0-1,16-17";
26 possible-cpus = "0-4095";
27
28 aliases {
29 ethernet0 = &gmac0;
30 };
31
32 chosen {
33 bootargs = "earlycon=uart8250,mmio32be,0xf7209000,115200n8 console=ttyS0,115200n8";
34 };
35
36 memory {
37 device_type = "memory";
38 reg = <0x80000000 0x20000000>; /* 512M */
39 };
40
41 clocks {
42 sysclk: sysclk {
43 compatible = "fixed-clock";
44 #clock-cells = <0>;
45 clock-frequency = <83333333>;
46 };
47 };
48
49 soc {
50 compatible = "simple-bus";
51 #address-cells = <1>;
52 #size-cells = <1>;
53
54 /* child and parent address space 1:1 mapped */
55 ranges;
56
57 intc: interrupt-controller {
58 compatible = "ezchip,nps400-ic";
59 interrupt-controller;
60 #interrupt-cells = <1>;
61 };
62
63 timer0: timer_clkevt {
64 compatible = "snps,arc-timer";
65 interrupts = <3>;
66 clocks = <&sysclk>;
67 };
68
69 timer1: timer_clksrc {
70 compatible = "ezchip,nps400-timer";
71 clocks = <&sysclk>;
72 clock-names="sysclk";
73 };
74
75 uart@f7209000 {
76 compatible = "snps,dw-apb-uart";
77 device_type = "serial";
78 reg = <0xf7209000 0x100>;
79 interrupts = <6>;
80 clocks = <&sysclk>;
81 clock-names="baudclk";
82 baud = <115200>;
83 reg-shift = <2>;
84 reg-io-width = <4>;
85 native-endian;
86 };
87
88 gmac0: ethernet@f7470000 {
89 compatible = "ezchip,nps-mgt-enet";
90 reg = <0xf7470000 0x1940>;
91 interrupts = <7>;
92 /* Filled in by U-Boot */
93 mac-address = [ 00 C0 00 F0 04 03 ];
94 };
95 };
96};
diff --git a/arch/arc/boot/dts/nsim_700.dts b/arch/arc/boot/dts/nsim_700.dts
index 105a0017023f..5d5e373e0ebc 100644
--- a/arch/arc/boot/dts/nsim_700.dts
+++ b/arch/arc/boot/dts/nsim_700.dts
@@ -14,7 +14,7 @@
14 clock-frequency = <80000000>; /* 80 MHZ */ 14 clock-frequency = <80000000>; /* 80 MHZ */
15 #address-cells = <1>; 15 #address-cells = <1>;
16 #size-cells = <1>; 16 #size-cells = <1>;
17 interrupt-parent = <&intc>; 17 interrupt-parent = <&core_intc>;
18 18
19 chosen { 19 chosen {
20 bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8"; 20 bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8";
@@ -32,7 +32,13 @@
32 /* child and parent address space 1:1 mapped */ 32 /* child and parent address space 1:1 mapped */
33 ranges; 33 ranges;
34 34
35 intc: interrupt-controller { 35 core_clk: core_clk {
36 #clock-cells = <0>;
37 compatible = "fixed-clock";
38 clock-frequency = <80000000>;
39 };
40
41 core_intc: interrupt-controller {
36 compatible = "snps,arc700-intc"; 42 compatible = "snps,arc700-intc";
37 interrupt-controller; 43 interrupt-controller;
38 #interrupt-cells = <1>; 44 #interrupt-cells = <1>;
diff --git a/arch/arc/boot/dts/nsim_hs.dts b/arch/arc/boot/dts/nsim_hs.dts
index f46633eeb06b..bf05fe5f67b0 100644
--- a/arch/arc/boot/dts/nsim_hs.dts
+++ b/arch/arc/boot/dts/nsim_hs.dts
@@ -7,7 +7,7 @@
7 */ 7 */
8/dts-v1/; 8/dts-v1/;
9 9
10/include/ "skeleton.dtsi" 10/include/ "skeleton_hs.dtsi"
11 11
12/ { 12/ {
13 compatible = "snps,nsim_hs"; 13 compatible = "snps,nsim_hs";
@@ -39,6 +39,12 @@
39 bus addr, parent bus addr, size */ 39 bus addr, parent bus addr, size */
40 ranges = <0x80000000 0x0 0x80000000 0x80000000>; 40 ranges = <0x80000000 0x0 0x80000000 0x80000000>;
41 41
42 core_clk: core_clk {
43 #clock-cells = <0>;
44 compatible = "fixed-clock";
45 clock-frequency = <80000000>;
46 };
47
42 core_intc: core-interrupt-controller { 48 core_intc: core-interrupt-controller {
43 compatible = "snps,archs-intc"; 49 compatible = "snps,archs-intc";
44 interrupt-controller; 50 interrupt-controller;
diff --git a/arch/arc/boot/dts/nsim_hs_idu.dts b/arch/arc/boot/dts/nsim_hs_idu.dts
index 46ab31975612..99eabe1a2bf6 100644
--- a/arch/arc/boot/dts/nsim_hs_idu.dts
+++ b/arch/arc/boot/dts/nsim_hs_idu.dts
@@ -7,7 +7,7 @@
7 */ 7 */
8/dts-v1/; 8/dts-v1/;
9 9
10/include/ "skeleton.dtsi" 10/include/ "skeleton_hs_idu.dtsi"
11 11
12/ { 12/ {
13 compatible = "snps,nsim_hs"; 13 compatible = "snps,nsim_hs";
@@ -29,6 +29,12 @@
29 /* child and parent address space 1:1 mapped */ 29 /* child and parent address space 1:1 mapped */
30 ranges; 30 ranges;
31 31
32 core_clk: core_clk {
33 #clock-cells = <0>;
34 compatible = "fixed-clock";
35 clock-frequency = <80000000>;
36 };
37
32 core_intc: core-interrupt-controller { 38 core_intc: core-interrupt-controller {
33 compatible = "snps,archs-intc"; 39 compatible = "snps,archs-intc";
34 interrupt-controller; 40 interrupt-controller;
diff --git a/arch/arc/boot/dts/nsimosci.dts b/arch/arc/boot/dts/nsimosci.dts
index d94b4ce516ad..b5b060adce8a 100644
--- a/arch/arc/boot/dts/nsimosci.dts
+++ b/arch/arc/boot/dts/nsimosci.dts
@@ -14,7 +14,7 @@
14 clock-frequency = <20000000>; /* 20 MHZ */ 14 clock-frequency = <20000000>; /* 20 MHZ */
15 #address-cells = <1>; 15 #address-cells = <1>;
16 #size-cells = <1>; 16 #size-cells = <1>;
17 interrupt-parent = <&intc>; 17 interrupt-parent = <&core_intc>;
18 18
19 chosen { 19 chosen {
20 /* this is for console on PGU */ 20 /* this is for console on PGU */
@@ -35,7 +35,13 @@
35 /* child and parent address space 1:1 mapped */ 35 /* child and parent address space 1:1 mapped */
36 ranges; 36 ranges;
37 37
38 intc: interrupt-controller { 38 core_clk: core_clk {
39 #clock-cells = <0>;
40 compatible = "fixed-clock";
41 clock-frequency = <20000000>;
42 };
43
44 core_intc: interrupt-controller {
39 compatible = "snps,arc700-intc"; 45 compatible = "snps,arc700-intc";
40 interrupt-controller; 46 interrupt-controller;
41 #interrupt-cells = <1>; 47 #interrupt-cells = <1>;
diff --git a/arch/arc/boot/dts/nsimosci_hs.dts b/arch/arc/boot/dts/nsimosci_hs.dts
index 034a3139c1e2..325e73090a18 100644
--- a/arch/arc/boot/dts/nsimosci_hs.dts
+++ b/arch/arc/boot/dts/nsimosci_hs.dts
@@ -7,7 +7,7 @@
7 */ 7 */
8/dts-v1/; 8/dts-v1/;
9 9
10/include/ "skeleton.dtsi" 10/include/ "skeleton_hs.dtsi"
11 11
12/ { 12/ {
13 compatible = "snps,nsimosci_hs"; 13 compatible = "snps,nsimosci_hs";
@@ -35,6 +35,12 @@
35 /* child and parent address space 1:1 mapped */ 35 /* child and parent address space 1:1 mapped */
36 ranges; 36 ranges;
37 37
38 core_clk: core_clk {
39 #clock-cells = <0>;
40 compatible = "fixed-clock";
41 clock-frequency = <20000000>;
42 };
43
38 core_intc: core-interrupt-controller { 44 core_intc: core-interrupt-controller {
39 compatible = "snps,archs-intc"; 45 compatible = "snps,archs-intc";
40 interrupt-controller; 46 interrupt-controller;
diff --git a/arch/arc/boot/dts/nsimosci_hs_idu.dts b/arch/arc/boot/dts/nsimosci_hs_idu.dts
index 8a1297e02540..ee03d7126581 100644
--- a/arch/arc/boot/dts/nsimosci_hs_idu.dts
+++ b/arch/arc/boot/dts/nsimosci_hs_idu.dts
@@ -7,7 +7,7 @@
7 */ 7 */
8/dts-v1/; 8/dts-v1/;
9 9
10/include/ "skeleton.dtsi" 10/include/ "skeleton_hs_idu.dtsi"
11 11
12/ { 12/ {
13 compatible = "snps,nsimosci_hs"; 13 compatible = "snps,nsimosci_hs";
@@ -33,6 +33,12 @@
33 /* child and parent address space 1:1 mapped */ 33 /* child and parent address space 1:1 mapped */
34 ranges; 34 ranges;
35 35
36 core_clk: core_clk {
37 #clock-cells = <0>;
38 compatible = "fixed-clock";
39 clock-frequency = <5000000>;
40 };
41
36 core_intc: core-interrupt-controller { 42 core_intc: core-interrupt-controller {
37 compatible = "snps,archs-intc"; 43 compatible = "snps,archs-intc";
38 interrupt-controller; 44 interrupt-controller;
diff --git a/arch/arc/boot/dts/skeleton.dtsi b/arch/arc/boot/dts/skeleton.dtsi
index 296d371a335c..3a10cc633e2b 100644
--- a/arch/arc/boot/dts/skeleton.dtsi
+++ b/arch/arc/boot/dts/skeleton.dtsi
@@ -30,6 +30,20 @@
30 }; 30 };
31 }; 31 };
32 32
33 /* TIMER0 with interrupt for clockevent */
34 timer0 {
35 compatible = "snps,arc-timer";
36 interrupts = <3>;
37 interrupt-parent = <&core_intc>;
38 clocks = <&core_clk>;
39 };
40
41 /* TIMER1 for free running clocksource */
42 timer1 {
43 compatible = "snps,arc-timer";
44 clocks = <&core_clk>;
45 };
46
33 memory { 47 memory {
34 device_type = "memory"; 48 device_type = "memory";
35 reg = <0x80000000 0x10000000>; /* 256M */ 49 reg = <0x80000000 0x10000000>; /* 256M */
diff --git a/arch/arc/boot/dts/skeleton_hs.dtsi b/arch/arc/boot/dts/skeleton_hs.dtsi
new file mode 100644
index 000000000000..71fd308a9298
--- /dev/null
+++ b/arch/arc/boot/dts/skeleton_hs.dtsi
@@ -0,0 +1,52 @@
1/*
2 * Copyright (C) 2016 Synopsys, Inc. (www.synopsys.com)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9/ {
10 compatible = "snps,arc";
11 clock-frequency = <80000000>; /* 80 MHZ */
12 #address-cells = <1>;
13 #size-cells = <1>;
14 chosen { };
15 aliases { };
16
17 cpus {
18 #address-cells = <1>;
19 #size-cells = <0>;
20
21 cpu@0 {
22 device_type = "cpu";
23 compatible = "snps,archs38";
24 reg = <0>;
25 };
26 };
27
28 /* TIMER0 with interrupt for clockevent */
29 timer0 {
30 compatible = "snps,arc-timer";
31 interrupts = <16>;
32 interrupt-parent = <&core_intc>;
33 clocks = <&core_clk>;
34 };
35
36 /* 64-bit Local RTC: preferred clocksource for UP */
37 rtc {
38 compatible = "snps,archs-timer-rtc";
39 clocks = <&core_clk>;
40 };
41
42 /* TIMER1 for free running clocksource: Fallback if rtc not found */
43 timer1 {
44 compatible = "snps,arc-timer";
45 clocks = <&core_clk>;
46 };
47
48 memory {
49 device_type = "memory";
50 reg = <0x80000000 0x10000000>; /* 256M */
51 };
52};
diff --git a/arch/arc/boot/dts/skeleton_hs_idu.dtsi b/arch/arc/boot/dts/skeleton_hs_idu.dtsi
new file mode 100644
index 000000000000..d1cb25a66989
--- /dev/null
+++ b/arch/arc/boot/dts/skeleton_hs_idu.dtsi
@@ -0,0 +1,46 @@
1/*
2 * Copyright (C) 2016 Synopsys, Inc. (www.synopsys.com)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9/ {
10 compatible = "snps,arc";
11 clock-frequency = <80000000>; /* 80 MHZ */
12 #address-cells = <1>;
13 #size-cells = <1>;
14 chosen { };
15 aliases { };
16
17 cpus {
18 #address-cells = <1>;
19 #size-cells = <0>;
20
21 cpu@0 {
22 device_type = "cpu";
23 compatible = "snps,archs38xN";
24 reg = <0>;
25 };
26 };
27
28 /* TIMER0 with interrupt for clockevent */
29 timer0 {
30 compatible = "snps,arc-timer";
31 interrupts = <16>;
32 interrupt-parent = <&core_intc>;
33 clocks = <&core_clk>;
34 };
35
36 /* 64-bit Global Free Running Counter */
37 gfrc {
38 compatible = "snps,archs-timer-gfrc";
39 clocks = <&core_clk>;
40 };
41
42 memory {
43 device_type = "memory";
44 reg = <0x80000000 0x10000000>; /* 256M */
45 };
46};
diff --git a/arch/arc/boot/dts/vdk_axc003.dtsi b/arch/arc/boot/dts/vdk_axc003.dtsi
index 84226bd48baf..ad4ee43bd2ac 100644
--- a/arch/arc/boot/dts/vdk_axc003.dtsi
+++ b/arch/arc/boot/dts/vdk_axc003.dtsi
@@ -10,6 +10,8 @@
10 * Device tree for AXC003 CPU card: HS38x UP configuration (VDK version) 10 * Device tree for AXC003 CPU card: HS38x UP configuration (VDK version)
11 */ 11 */
12 12
13/include/ "skeleton_hs.dtsi"
14
13/ { 15/ {
14 compatible = "snps,arc"; 16 compatible = "snps,arc";
15 clock-frequency = <50000000>; 17 clock-frequency = <50000000>;
@@ -23,7 +25,13 @@
23 25
24 ranges = <0x00000000 0xf0000000 0x10000000>; 26 ranges = <0x00000000 0xf0000000 0x10000000>;
25 27
26 cpu_intc: archs-intc@cpu { 28 core_clk: core_clk {
29 #clock-cells = <0>;
30 compatible = "fixed-clock";
31 clock-frequency = <50000000>;
32 };
33
34 core_intc: archs-intc@cpu {
27 compatible = "snps,archs-intc"; 35 compatible = "snps,archs-intc";
28 interrupt-controller; 36 interrupt-controller;
29 #interrupt-cells = <1>; 37 #interrupt-cells = <1>;
@@ -33,7 +41,7 @@
33 compatible = "snps,dw-apb-uart"; 41 compatible = "snps,dw-apb-uart";
34 reg = <0x5000 0x100>; 42 reg = <0x5000 0x100>;
35 clock-frequency = <2403200>; 43 clock-frequency = <2403200>;
36 interrupt-parent = <&cpu_intc>; 44 interrupt-parent = <&core_intc>;
37 interrupts = <19>; 45 interrupts = <19>;
38 baud = <115200>; 46 baud = <115200>;
39 reg-shift = <2>; 47 reg-shift = <2>;
@@ -47,7 +55,7 @@
47 compatible = "snps,dw-apb-ictl"; 55 compatible = "snps,dw-apb-ictl";
48 reg = < 0xe0012000 0x200 >; 56 reg = < 0xe0012000 0x200 >;
49 interrupt-controller; 57 interrupt-controller;
50 interrupt-parent = <&cpu_intc>; 58 interrupt-parent = <&core_intc>;
51 interrupts = < 18 >; 59 interrupts = < 18 >;
52 }; 60 };
53 61
diff --git a/arch/arc/boot/dts/vdk_axc003_idu.dtsi b/arch/arc/boot/dts/vdk_axc003_idu.dtsi
index 31f0fb5fc91d..a3cb6263c581 100644
--- a/arch/arc/boot/dts/vdk_axc003_idu.dtsi
+++ b/arch/arc/boot/dts/vdk_axc003_idu.dtsi
@@ -11,6 +11,8 @@
11 * HS38x2 (Dual Core) with IDU intc (VDK version) 11 * HS38x2 (Dual Core) with IDU intc (VDK version)
12 */ 12 */
13 13
14/include/ "skeleton_hs_idu.dtsi"
15
14/ { 16/ {
15 compatible = "snps,arc"; 17 compatible = "snps,arc";
16 clock-frequency = <50000000>; 18 clock-frequency = <50000000>;
@@ -24,7 +26,13 @@
24 26
25 ranges = <0x00000000 0xf0000000 0x10000000>; 27 ranges = <0x00000000 0xf0000000 0x10000000>;
26 28
27 cpu_intc: archs-intc@cpu { 29 core_clk: core_clk {
30 #clock-cells = <0>;
31 compatible = "fixed-clock";
32 clock-frequency = <50000000>;
33 };
34
35 core_intc: archs-intc@cpu {
28 compatible = "snps,archs-intc"; 36 compatible = "snps,archs-intc";
29 interrupt-controller; 37 interrupt-controller;
30 #interrupt-cells = <1>; 38 #interrupt-cells = <1>;
@@ -33,7 +41,7 @@
33 idu_intc: idu-interrupt-controller { 41 idu_intc: idu-interrupt-controller {
34 compatible = "snps,archs-idu-intc"; 42 compatible = "snps,archs-idu-intc";
35 interrupt-controller; 43 interrupt-controller;
36 interrupt-parent = <&cpu_intc>; 44 interrupt-parent = <&core_intc>;
37 45
38 /* 46 /*
39 * <hwirq distribution> 47 * <hwirq distribution>
diff --git a/arch/arc/configs/nps_defconfig b/arch/arc/configs/nps_defconfig
new file mode 100644
index 000000000000..ede625c76216
--- /dev/null
+++ b/arch/arc/configs/nps_defconfig
@@ -0,0 +1,84 @@
1# CONFIG_LOCALVERSION_AUTO is not set
2# CONFIG_SWAP is not set
3CONFIG_SYSVIPC=y
4CONFIG_NO_HZ_IDLE=y
5CONFIG_HIGH_RES_TIMERS=y
6CONFIG_IKCONFIG=y
7CONFIG_IKCONFIG_PROC=y
8CONFIG_BLK_DEV_INITRD=y
9CONFIG_SYSCTL_SYSCALL=y
10# CONFIG_EPOLL is not set
11# CONFIG_SIGNALFD is not set
12# CONFIG_TIMERFD is not set
13# CONFIG_EVENTFD is not set
14# CONFIG_AIO is not set
15CONFIG_EMBEDDED=y
16CONFIG_PERF_EVENTS=y
17# CONFIG_COMPAT_BRK is not set
18CONFIG_KPROBES=y
19CONFIG_MODULES=y
20CONFIG_MODULE_FORCE_LOAD=y
21CONFIG_MODULE_UNLOAD=y
22# CONFIG_BLK_DEV_BSG is not set
23# CONFIG_IOSCHED_DEADLINE is not set
24# CONFIG_IOSCHED_CFQ is not set
25CONFIG_ARC_PLAT_EZNPS=y
26CONFIG_SMP=y
27CONFIG_NR_CPUS=4096
28CONFIG_ARC_CACHE_LINE_SHIFT=5
29# CONFIG_ARC_CACHE_PAGES is not set
30# CONFIG_ARC_HAS_LLSC is not set
31CONFIG_ARC_KVADDR_SIZE=402
32CONFIG_ARC_EMUL_UNALIGNED=y
33CONFIG_ARC_UBOOT_SUPPORT=y
34CONFIG_PREEMPT=y
35CONFIG_NET=y
36CONFIG_UNIX=y
37CONFIG_INET=y
38CONFIG_IP_PNP=y
39# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
40# CONFIG_INET_XFRM_MODE_TUNNEL is not set
41# CONFIG_INET_XFRM_MODE_BEET is not set
42# CONFIG_INET_LRO is not set
43# CONFIG_INET_DIAG is not set
44# CONFIG_IPV6 is not set
45# CONFIG_WIRELESS is not set
46CONFIG_DEVTMPFS=y
47CONFIG_DEVTMPFS_MOUNT=y
48# CONFIG_PREVENT_FIRMWARE_BUILD is not set
49CONFIG_BLK_DEV_RAM=y
50CONFIG_BLK_DEV_RAM_COUNT=1
51CONFIG_BLK_DEV_RAM_SIZE=2048
52CONFIG_NETDEVICES=y
53CONFIG_NETCONSOLE=y
54# CONFIG_NET_VENDOR_BROADCOM is not set
55# CONFIG_NET_VENDOR_MICREL is not set
56# CONFIG_NET_VENDOR_STMICRO is not set
57# CONFIG_WLAN is not set
58# CONFIG_INPUT_MOUSEDEV is not set
59# CONFIG_INPUT_KEYBOARD is not set
60# CONFIG_INPUT_MOUSE is not set
61# CONFIG_SERIO is not set
62# CONFIG_LEGACY_PTYS is not set
63# CONFIG_DEVKMEM is not set
64CONFIG_SERIAL_8250=y
65CONFIG_SERIAL_8250_CONSOLE=y
66CONFIG_SERIAL_8250_NR_UARTS=1
67CONFIG_SERIAL_8250_RUNTIME_UARTS=1
68CONFIG_SERIAL_8250_DW=y
69CONFIG_SERIAL_OF_PLATFORM=y
70# CONFIG_HW_RANDOM is not set
71# CONFIG_HWMON is not set
72# CONFIG_USB_SUPPORT is not set
73# CONFIG_DNOTIFY is not set
74CONFIG_PROC_KCORE=y
75CONFIG_TMPFS=y
76# CONFIG_MISC_FILESYSTEMS is not set
77CONFIG_NFS_FS=y
78CONFIG_ROOT_NFS=y
79CONFIG_DEBUG_INFO=y
80# CONFIG_ENABLE_WARN_DEPRECATED is not set
81# CONFIG_ENABLE_MUST_CHECK is not set
82CONFIG_MAGIC_SYSRQ=y
83CONFIG_DEBUG_MEMORY_INIT=y
84CONFIG_ENABLE_DEFAULT_TRACERS=y
diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h
index 7730d302cadb..5f3dcbbc0cc9 100644
--- a/arch/arc/include/asm/atomic.h
+++ b/arch/arc/include/asm/atomic.h
@@ -17,6 +17,8 @@
17#include <asm/barrier.h> 17#include <asm/barrier.h>
18#include <asm/smp.h> 18#include <asm/smp.h>
19 19
20#ifndef CONFIG_ARC_PLAT_EZNPS
21
20#define atomic_read(v) READ_ONCE((v)->counter) 22#define atomic_read(v) READ_ONCE((v)->counter)
21 23
22#ifdef CONFIG_ARC_HAS_LLSC 24#ifdef CONFIG_ARC_HAS_LLSC
@@ -180,13 +182,88 @@ ATOMIC_OP(andnot, &= ~, bic)
180ATOMIC_OP(or, |=, or) 182ATOMIC_OP(or, |=, or)
181ATOMIC_OP(xor, ^=, xor) 183ATOMIC_OP(xor, ^=, xor)
182 184
183#undef ATOMIC_OPS
184#undef ATOMIC_OP_RETURN
185#undef ATOMIC_OP
186#undef SCOND_FAIL_RETRY_VAR_DEF 185#undef SCOND_FAIL_RETRY_VAR_DEF
187#undef SCOND_FAIL_RETRY_ASM 186#undef SCOND_FAIL_RETRY_ASM
188#undef SCOND_FAIL_RETRY_VARS 187#undef SCOND_FAIL_RETRY_VARS
189 188
189#else /* CONFIG_ARC_PLAT_EZNPS */
190
191static inline int atomic_read(const atomic_t *v)
192{
193 int temp;
194
195 __asm__ __volatile__(
196 " ld.di %0, [%1]"
197 : "=r"(temp)
198 : "r"(&v->counter)
199 : "memory");
200 return temp;
201}
202
203static inline void atomic_set(atomic_t *v, int i)
204{
205 __asm__ __volatile__(
206 " st.di %0,[%1]"
207 :
208 : "r"(i), "r"(&v->counter)
209 : "memory");
210}
211
212#define ATOMIC_OP(op, c_op, asm_op) \
213static inline void atomic_##op(int i, atomic_t *v) \
214{ \
215 __asm__ __volatile__( \
216 " mov r2, %0\n" \
217 " mov r3, %1\n" \
218 " .word %2\n" \
219 : \
220 : "r"(i), "r"(&v->counter), "i"(asm_op) \
221 : "r2", "r3", "memory"); \
222} \
223
224#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
225static inline int atomic_##op##_return(int i, atomic_t *v) \
226{ \
227 unsigned int temp = i; \
228 \
229 /* Explicit full memory barrier needed before/after */ \
230 smp_mb(); \
231 \
232 __asm__ __volatile__( \
233 " mov r2, %0\n" \
234 " mov r3, %1\n" \
235 " .word %2\n" \
236 " mov %0, r2" \
237 : "+r"(temp) \
238 : "r"(&v->counter), "i"(asm_op) \
239 : "r2", "r3", "memory"); \
240 \
241 smp_mb(); \
242 \
243 temp c_op i; \
244 \
245 return temp; \
246}
247
248#define ATOMIC_OPS(op, c_op, asm_op) \
249 ATOMIC_OP(op, c_op, asm_op) \
250 ATOMIC_OP_RETURN(op, c_op, asm_op)
251
252ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3)
253#define atomic_sub(i, v) atomic_add(-(i), (v))
254#define atomic_sub_return(i, v) atomic_add_return(-(i), (v))
255
256ATOMIC_OP(and, &=, CTOP_INST_AAND_DI_R2_R2_R3)
257#define atomic_andnot(mask, v) atomic_and(~(mask), (v))
258ATOMIC_OP(or, |=, CTOP_INST_AOR_DI_R2_R2_R3)
259ATOMIC_OP(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3)
260
261#endif /* CONFIG_ARC_PLAT_EZNPS */
262
263#undef ATOMIC_OPS
264#undef ATOMIC_OP_RETURN
265#undef ATOMIC_OP
266
190/** 267/**
191 * __atomic_add_unless - add unless the number is a given value 268 * __atomic_add_unless - add unless the number is a given value
192 * @v: pointer of type atomic_t 269 * @v: pointer of type atomic_t
diff --git a/arch/arc/include/asm/barrier.h b/arch/arc/include/asm/barrier.h
index a7209983ee64..b1e327495c7d 100644
--- a/arch/arc/include/asm/barrier.h
+++ b/arch/arc/include/asm/barrier.h
@@ -30,9 +30,7 @@
30#define rmb() asm volatile("dmb 1\n" : : : "memory") 30#define rmb() asm volatile("dmb 1\n" : : : "memory")
31#define wmb() asm volatile("dmb 2\n" : : : "memory") 31#define wmb() asm volatile("dmb 2\n" : : : "memory")
32 32
33#endif 33#elif !defined(CONFIG_ARC_PLAT_EZNPS) /* CONFIG_ISA_ARCOMPACT */
34
35#ifdef CONFIG_ISA_ARCOMPACT
36 34
37/* 35/*
38 * ARCompact based cores (ARC700) only have SYNC instruction which is super 36 * ARCompact based cores (ARC700) only have SYNC instruction which is super
@@ -41,6 +39,14 @@
41 */ 39 */
42 40
43#define mb() asm volatile("sync\n" : : : "memory") 41#define mb() asm volatile("sync\n" : : : "memory")
42
43#else /* CONFIG_ARC_PLAT_EZNPS */
44
45#include <plat/ctop.h>
46
47#define mb() asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
48#define rmb() asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RD) : "memory")
49
44#endif 50#endif
45 51
46#include <asm-generic/barrier.h> 52#include <asm-generic/barrier.h>
diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h
index 0352fb8d21b9..8da87feec59a 100644
--- a/arch/arc/include/asm/bitops.h
+++ b/arch/arc/include/asm/bitops.h
@@ -22,7 +22,7 @@
22#include <asm/smp.h> 22#include <asm/smp.h>
23#endif 23#endif
24 24
25#if defined(CONFIG_ARC_HAS_LLSC) 25#ifdef CONFIG_ARC_HAS_LLSC
26 26
27/* 27/*
28 * Hardware assisted Atomic-R-M-W 28 * Hardware assisted Atomic-R-M-W
@@ -88,7 +88,7 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *
88 return (old & (1 << nr)) != 0; \ 88 return (old & (1 << nr)) != 0; \
89} 89}
90 90
91#else /* !CONFIG_ARC_HAS_LLSC */ 91#elif !defined(CONFIG_ARC_PLAT_EZNPS)
92 92
93/* 93/*
94 * Non hardware assisted Atomic-R-M-W 94 * Non hardware assisted Atomic-R-M-W
@@ -139,7 +139,55 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *
139 return (old & (1UL << (nr & 0x1f))) != 0; \ 139 return (old & (1UL << (nr & 0x1f))) != 0; \
140} 140}
141 141
142#endif /* CONFIG_ARC_HAS_LLSC */ 142#else /* CONFIG_ARC_PLAT_EZNPS */
143
144#define BIT_OP(op, c_op, asm_op) \
145static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\
146{ \
147 m += nr >> 5; \
148 \
149 nr = (1UL << (nr & 0x1f)); \
150 if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3) \
151 nr = ~nr; \
152 \
153 __asm__ __volatile__( \
154 " mov r2, %0\n" \
155 " mov r3, %1\n" \
156 " .word %2\n" \
157 : \
158 : "r"(nr), "r"(m), "i"(asm_op) \
159 : "r2", "r3", "memory"); \
160}
161
162#define TEST_N_BIT_OP(op, c_op, asm_op) \
163static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *m)\
164{ \
165 unsigned long old; \
166 \
167 m += nr >> 5; \
168 \
169 nr = old = (1UL << (nr & 0x1f)); \
170 if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3) \
171 old = ~old; \
172 \
173 /* Explicit full memory barrier needed before/after */ \
174 smp_mb(); \
175 \
176 __asm__ __volatile__( \
177 " mov r2, %0\n" \
178 " mov r3, %1\n" \
179 " .word %2\n" \
180 " mov %0, r2" \
181 : "+r"(old) \
182 : "r"(m), "i"(asm_op) \
183 : "r2", "r3", "memory"); \
184 \
185 smp_mb(); \
186 \
187 return (old & nr) != 0; \
188}
189
190#endif /* CONFIG_ARC_PLAT_EZNPS */
143 191
144/*************************************** 192/***************************************
145 * Non atomic variants 193 * Non atomic variants
@@ -181,9 +229,15 @@ static inline int __test_and_##op##_bit(unsigned long nr, volatile unsigned long
181 /* __test_and_set_bit(), __test_and_clear_bit(), __test_and_change_bit() */\ 229 /* __test_and_set_bit(), __test_and_clear_bit(), __test_and_change_bit() */\
182 __TEST_N_BIT_OP(op, c_op, asm_op) 230 __TEST_N_BIT_OP(op, c_op, asm_op)
183 231
232#ifndef CONFIG_ARC_PLAT_EZNPS
184BIT_OPS(set, |, bset) 233BIT_OPS(set, |, bset)
185BIT_OPS(clear, & ~, bclr) 234BIT_OPS(clear, & ~, bclr)
186BIT_OPS(change, ^, bxor) 235BIT_OPS(change, ^, bxor)
236#else
237BIT_OPS(set, |, CTOP_INST_AOR_DI_R2_R2_R3)
238BIT_OPS(clear, & ~, CTOP_INST_AAND_DI_R2_R2_R3)
239BIT_OPS(change, ^, CTOP_INST_AXOR_DI_R2_R2_R3)
240#endif
187 241
188/* 242/*
189 * This routine doesn't need to be atomic. 243 * This routine doesn't need to be atomic.
diff --git a/arch/arc/include/asm/clk.h b/arch/arc/include/asm/clk.h
deleted file mode 100644
index bf9d29f5bd53..000000000000
--- a/arch/arc/include/asm/clk.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _ASM_ARC_CLK_H
10#define _ASM_ARC_CLK_H
11
12/* Although we can't really hide core_freq, the accessor is still better way */
13extern unsigned long core_freq;
14
15static inline unsigned long arc_get_core_freq(void)
16{
17 return core_freq;
18}
19
20extern int arc_set_core_freq(unsigned long);
21
22#endif
diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h
index a444be67cd53..d819de1c5d10 100644
--- a/arch/arc/include/asm/cmpxchg.h
+++ b/arch/arc/include/asm/cmpxchg.h
@@ -44,7 +44,7 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
44 return prev; 44 return prev;
45} 45}
46 46
47#else 47#elif !defined(CONFIG_ARC_PLAT_EZNPS)
48 48
49static inline unsigned long 49static inline unsigned long
50__cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new) 50__cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
@@ -64,23 +64,48 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
64 return prev; 64 return prev;
65} 65}
66 66
67#else /* CONFIG_ARC_PLAT_EZNPS */
68
69static inline unsigned long
70__cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
71{
72 /*
73 * Explicit full memory barrier needed before/after
74 */
75 smp_mb();
76
77 write_aux_reg(CTOP_AUX_GPA1, expected);
78
79 __asm__ __volatile__(
80 " mov r2, %0\n"
81 " mov r3, %1\n"
82 " .word %2\n"
83 " mov %0, r2"
84 : "+r"(new)
85 : "r"(ptr), "i"(CTOP_INST_EXC_DI_R2_R2_R3)
86 : "r2", "r3", "memory");
87
88 smp_mb();
89
90 return new;
91}
92
67#endif /* CONFIG_ARC_HAS_LLSC */ 93#endif /* CONFIG_ARC_HAS_LLSC */
68 94
69#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \ 95#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \
70 (unsigned long)(o), (unsigned long)(n))) 96 (unsigned long)(o), (unsigned long)(n)))
71 97
72/* 98/*
73 * Since not supported natively, ARC cmpxchg() uses atomic_ops_lock (UP/SMP) 99 * atomic_cmpxchg is same as cmpxchg
74 * just to gaurantee semantics. 100 * LLSC: only different in data-type, semantics are exactly same
75 * atomic_cmpxchg() needs to use the same locks as it's other atomic siblings 101 * !LLSC: cmpxchg() has to use an external lock atomic_ops_lock to guarantee
76 * which also happens to be atomic_ops_lock. 102 * semantics, and this lock also happens to be used by atomic_*()
77 *
78 * Thus despite semantically being different, implementation of atomic_cmpxchg()
79 * is same as cmpxchg().
80 */ 103 */
81#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) 104#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
82 105
83 106
107#ifndef CONFIG_ARC_PLAT_EZNPS
108
84/* 109/*
85 * xchg (reg with memory) based on "Native atomic" EX insn 110 * xchg (reg with memory) based on "Native atomic" EX insn
86 */ 111 */
@@ -143,6 +168,41 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
143 168
144#endif 169#endif
145 170
171#else /* CONFIG_ARC_PLAT_EZNPS */
172
173static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
174 int size)
175{
176 extern unsigned long __xchg_bad_pointer(void);
177
178 switch (size) {
179 case 4:
180 /*
181 * Explicit full memory barrier needed before/after
182 */
183 smp_mb();
184
185 __asm__ __volatile__(
186 " mov r2, %0\n"
187 " mov r3, %1\n"
188 " .word %2\n"
189 " mov %0, r2\n"
190 : "+r"(val)
191 : "r"(ptr), "i"(CTOP_INST_XEX_DI_R2_R2_R3)
192 : "r2", "r3", "memory");
193
194 smp_mb();
195
196 return val;
197 }
198 return __xchg_bad_pointer();
199}
200
201#define xchg(ptr, with) ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), \
202 sizeof(*(ptr))))
203
204#endif /* CONFIG_ARC_PLAT_EZNPS */
205
146/* 206/*
147 * "atomic" variant of xchg() 207 * "atomic" variant of xchg()
148 * REQ: It needs to follow the same serialization rules as other atomic_xxx() 208 * REQ: It needs to follow the same serialization rules as other atomic_xxx()
diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h
index 1d8f57cd6057..e0e1faf03c50 100644
--- a/arch/arc/include/asm/entry-compact.h
+++ b/arch/arc/include/asm/entry-compact.h
@@ -36,6 +36,10 @@
36#include <asm/irqflags-compact.h> 36#include <asm/irqflags-compact.h>
37#include <asm/thread_info.h> /* For THREAD_SIZE */ 37#include <asm/thread_info.h> /* For THREAD_SIZE */
38 38
39#ifdef CONFIG_ARC_PLAT_EZNPS
40#include <plat/ctop.h>
41#endif
42
39/*-------------------------------------------------------------- 43/*--------------------------------------------------------------
40 * Switch to Kernel Mode stack if SP points to User Mode stack 44 * Switch to Kernel Mode stack if SP points to User Mode stack
41 * 45 *
@@ -296,11 +300,13 @@
296 bic \reg, sp, (THREAD_SIZE - 1) 300 bic \reg, sp, (THREAD_SIZE - 1)
297.endm 301.endm
298 302
303#ifndef CONFIG_ARC_PLAT_EZNPS
299/* Get CPU-ID of this core */ 304/* Get CPU-ID of this core */
300.macro GET_CPU_ID reg 305.macro GET_CPU_ID reg
301 lr \reg, [identity] 306 lr \reg, [identity]
302 lsr \reg, \reg, 8 307 lsr \reg, \reg, 8
303 bmsk \reg, \reg, 7 308 bmsk \reg, \reg, 7
304.endm 309.endm
310#endif
305 311
306#endif /* __ASM_ARC_ENTRY_COMPACT_H */ 312#endif /* __ASM_ARC_ENTRY_COMPACT_H */
diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
index 49014f0ef36d..c0fa0d2de400 100644
--- a/arch/arc/include/asm/irq.h
+++ b/arch/arc/include/asm/irq.h
@@ -13,21 +13,14 @@
13#define NR_IRQS 128 /* allow some CPU external IRQ handling */ 13#define NR_IRQS 128 /* allow some CPU external IRQ handling */
14 14
15/* Platform Independent IRQs */ 15/* Platform Independent IRQs */
16#ifdef CONFIG_ISA_ARCOMPACT 16#ifdef CONFIG_ISA_ARCV2
17#define TIMER0_IRQ 3 17#define IPI_IRQ 19
18#define TIMER1_IRQ 4 18#define SOFTIRQ_IRQ 21
19#else
20#define TIMER0_IRQ 16
21#define TIMER1_IRQ 17
22#endif 19#endif
23 20
24#include <linux/interrupt.h> 21#include <linux/interrupt.h>
25#include <asm-generic/irq.h> 22#include <asm-generic/irq.h>
26 23
27extern void arc_init_IRQ(void); 24extern void arc_init_IRQ(void);
28void arc_local_timer_setup(void);
29void arc_request_percpu_irq(int irq, int cpu,
30 irqreturn_t (*isr)(int irq, void *dev),
31 const char *irq_nm, void *percpu_dev);
32 25
33#endif 26#endif
diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h
index 0d53854884d0..296c3426a6ad 100644
--- a/arch/arc/include/asm/page.h
+++ b/arch/arc/include/asm/page.h
@@ -31,7 +31,11 @@ void clear_user_page(void *to, unsigned long u_vaddr, struct page *page);
31 * These are used to make use of C type-checking.. 31 * These are used to make use of C type-checking..
32 */ 32 */
33typedef struct { 33typedef struct {
34#ifdef CONFIG_ARC_HAS_PAE40
35 unsigned long long pte;
36#else
34 unsigned long pte; 37 unsigned long pte;
38#endif
35} pte_t; 39} pte_t;
36typedef struct { 40typedef struct {
37 unsigned long pgd; 41 unsigned long pgd;
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 10d4b8b8e545..034bbdc0ff61 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -217,7 +217,7 @@
217#define BITS_FOR_PTE (PGDIR_SHIFT - PAGE_SHIFT) 217#define BITS_FOR_PTE (PGDIR_SHIFT - PAGE_SHIFT)
218#define BITS_FOR_PGD (32 - PGDIR_SHIFT) 218#define BITS_FOR_PGD (32 - PGDIR_SHIFT)
219 219
220#define PGDIR_SIZE (1UL << PGDIR_SHIFT) /* vaddr span, not PDG sz */ 220#define PGDIR_SIZE _BITUL(PGDIR_SHIFT) /* vaddr span, not PDG sz */
221#define PGDIR_MASK (~(PGDIR_SIZE-1)) 221#define PGDIR_MASK (~(PGDIR_SIZE-1))
222 222
223#define PTRS_PER_PTE _BITUL(BITS_FOR_PTE) 223#define PTRS_PER_PTE _BITUL(BITS_FOR_PTE)
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 1d694c1ef6d6..f9048994b22f 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -57,9 +57,19 @@ struct task_struct;
57 * A lot of busy-wait loops in SMP are based off of non-volatile data otherwise 57 * A lot of busy-wait loops in SMP are based off of non-volatile data otherwise
58 * get optimised away by gcc 58 * get optimised away by gcc
59 */ 59 */
60#define cpu_relax() __asm__ __volatile__ ("" : : : "memory") 60#ifndef CONFIG_EZNPS_MTM_EXT
61 61
62#define cpu_relax_lowlatency() cpu_relax() 62#define cpu_relax() barrier()
63#define cpu_relax_lowlatency() cpu_relax()
64
65#else
66
67#define cpu_relax() \
68 __asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
69
70#define cpu_relax_lowlatency() barrier()
71
72#endif
63 73
64#define copy_segments(tsk, mm) do { } while (0) 74#define copy_segments(tsk, mm) do { } while (0)
65#define release_segments(mm) do { } while (0) 75#define release_segments(mm) do { } while (0)
@@ -97,7 +107,7 @@ extern unsigned int get_wchan(struct task_struct *p);
97#endif /* !__ASSEMBLY__ */ 107#endif /* !__ASSEMBLY__ */
98 108
99/* 109/*
100 * System Memory Map on ARC 110 * Default System Memory Map on ARC
101 * 111 *
102 * ---------------------------- (lower 2G, Translated) ------------------------- 112 * ---------------------------- (lower 2G, Translated) -------------------------
103 * 0x0000_0000 0x5FFF_FFFF (user vaddr: TASK_SIZE) 113 * 0x0000_0000 0x5FFF_FFFF (user vaddr: TASK_SIZE)
@@ -109,20 +119,37 @@ extern unsigned int get_wchan(struct task_struct *p);
109 * 0xC000_0000 0xFFFF_FFFF (peripheral uncached space) 119 * 0xC000_0000 0xFFFF_FFFF (peripheral uncached space)
110 * ----------------------------------------------------------------------------- 120 * -----------------------------------------------------------------------------
111 */ 121 */
112#define VMALLOC_START 0x70000000
113 122
114/* 123#define TASK_SIZE 0x60000000
115 * 1 PGDIR_SIZE each for fixmap/pkmap, 2 PGDIR_SIZE gutter
116 * See asm/highmem.h for details
117 */
118#define VMALLOC_SIZE (PAGE_OFFSET - VMALLOC_START - PGDIR_SIZE * 4)
119#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE)
120 124
121#define USER_KERNEL_GUTTER 0x10000000 125#define VMALLOC_START (PAGE_OFFSET - (CONFIG_ARC_KVADDR_SIZE << 20))
122 126
123#define TASK_SIZE (VMALLOC_START - USER_KERNEL_GUTTER) 127/* 1 PGDIR_SIZE each for fixmap/pkmap, 2 PGDIR_SIZE gutter (see asm/highmem.h) */
128#define VMALLOC_SIZE ((CONFIG_ARC_KVADDR_SIZE << 20) - PGDIR_SIZE * 4)
124 129
130#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE)
131
132#define USER_KERNEL_GUTTER (VMALLOC_START - TASK_SIZE)
133
134#ifdef CONFIG_ARC_PLAT_EZNPS
135/* NPS architecture defines special window of 129M in user address space for
136 * special memory areas, when accessing this window the MMU do not use TLB.
137 * Instead MMU direct the access to:
138 * 0x57f00000:0x57ffffff -- 1M of closely coupled memory (aka CMEM)
139 * 0x58000000:0x5fffffff -- 16 huge pages, 8M each, with fixed map (aka FMTs)
140 *
141 * CMEM - is the fastest memory we got and its size is 16K.
142 * FMT - is used to map either to internal/external memory.
143 * Internal memory is the second fast memory and its size is 16M
144 * External memory is the biggest memory (16G) and also the slowest.
145 *
146 * STACK_TOP need to be PMD align (21bit) that is why we supply 0x57e00000.
147 */
148#define STACK_TOP 0x57e00000
149#else
125#define STACK_TOP TASK_SIZE 150#define STACK_TOP TASK_SIZE
151#endif
152
126#define STACK_TOP_MAX STACK_TOP 153#define STACK_TOP_MAX STACK_TOP
127 154
128/* This decides where the kernel will search for a free chunk of vm 155/* This decides where the kernel will search for a free chunk of vm
diff --git a/arch/arc/include/asm/setup.h b/arch/arc/include/asm/setup.h
index 307846691be6..48b37c693db3 100644
--- a/arch/arc/include/asm/setup.h
+++ b/arch/arc/include/asm/setup.h
@@ -12,7 +12,11 @@
12#include <linux/types.h> 12#include <linux/types.h>
13#include <uapi/asm/setup.h> 13#include <uapi/asm/setup.h>
14 14
15#ifdef CONFIG_ARC_PLAT_EZNPS
16#define COMMAND_LINE_SIZE 2048
17#else
15#define COMMAND_LINE_SIZE 256 18#define COMMAND_LINE_SIZE 256
19#endif
16 20
17/* 21/*
18 * Data structure to map a ID to string 22 * Data structure to map a ID to string
diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h
index db8c59d1eaeb..800e7c430ca5 100644
--- a/arch/arc/include/asm/spinlock.h
+++ b/arch/arc/include/asm/spinlock.h
@@ -610,7 +610,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
610static inline int arch_read_trylock(arch_rwlock_t *rw) 610static inline int arch_read_trylock(arch_rwlock_t *rw)
611{ 611{
612 int ret = 0; 612 int ret = 0;
613 unsigned long flags;
613 614
615 local_irq_save(flags);
614 arch_spin_lock(&(rw->lock_mutex)); 616 arch_spin_lock(&(rw->lock_mutex));
615 617
616 /* 618 /*
@@ -623,6 +625,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
623 } 625 }
624 626
625 arch_spin_unlock(&(rw->lock_mutex)); 627 arch_spin_unlock(&(rw->lock_mutex));
628 local_irq_restore(flags);
626 629
627 smp_mb(); 630 smp_mb();
628 return ret; 631 return ret;
@@ -632,7 +635,9 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
632static inline int arch_write_trylock(arch_rwlock_t *rw) 635static inline int arch_write_trylock(arch_rwlock_t *rw)
633{ 636{
634 int ret = 0; 637 int ret = 0;
638 unsigned long flags;
635 639
640 local_irq_save(flags);
636 arch_spin_lock(&(rw->lock_mutex)); 641 arch_spin_lock(&(rw->lock_mutex));
637 642
638 /* 643 /*
@@ -646,6 +651,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
646 ret = 1; 651 ret = 1;
647 } 652 }
648 arch_spin_unlock(&(rw->lock_mutex)); 653 arch_spin_unlock(&(rw->lock_mutex));
654 local_irq_restore(flags);
649 655
650 return ret; 656 return ret;
651} 657}
@@ -664,16 +670,24 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
664 670
665static inline void arch_read_unlock(arch_rwlock_t *rw) 671static inline void arch_read_unlock(arch_rwlock_t *rw)
666{ 672{
673 unsigned long flags;
674
675 local_irq_save(flags);
667 arch_spin_lock(&(rw->lock_mutex)); 676 arch_spin_lock(&(rw->lock_mutex));
668 rw->counter++; 677 rw->counter++;
669 arch_spin_unlock(&(rw->lock_mutex)); 678 arch_spin_unlock(&(rw->lock_mutex));
679 local_irq_restore(flags);
670} 680}
671 681
672static inline void arch_write_unlock(arch_rwlock_t *rw) 682static inline void arch_write_unlock(arch_rwlock_t *rw)
673{ 683{
684 unsigned long flags;
685
686 local_irq_save(flags);
674 arch_spin_lock(&(rw->lock_mutex)); 687 arch_spin_lock(&(rw->lock_mutex));
675 rw->counter = __ARCH_RW_LOCK_UNLOCKED__; 688 rw->counter = __ARCH_RW_LOCK_UNLOCKED__;
676 arch_spin_unlock(&(rw->lock_mutex)); 689 arch_spin_unlock(&(rw->lock_mutex));
690 local_irq_restore(flags);
677} 691}
678 692
679#endif 693#endif
diff --git a/arch/arc/include/uapi/asm/byteorder.h b/arch/arc/include/uapi/asm/byteorder.h
index 9da71d415c38..ea5ca444c7e3 100644
--- a/arch/arc/include/uapi/asm/byteorder.h
+++ b/arch/arc/include/uapi/asm/byteorder.h
@@ -9,7 +9,7 @@
9#ifndef __ASM_ARC_BYTEORDER_H 9#ifndef __ASM_ARC_BYTEORDER_H
10#define __ASM_ARC_BYTEORDER_H 10#define __ASM_ARC_BYTEORDER_H
11 11
12#ifdef CONFIG_CPU_BIG_ENDIAN 12#ifdef __BIG_ENDIAN__
13#include <linux/byteorder/big_endian.h> 13#include <linux/byteorder/big_endian.h>
14#else 14#else
15#include <linux/byteorder/little_endian.h> 15#include <linux/byteorder/little_endian.h>
diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile
index 1bc2036b19d7..cfcdedf52ff8 100644
--- a/arch/arc/kernel/Makefile
+++ b/arch/arc/kernel/Makefile
@@ -9,7 +9,7 @@
9CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' 9CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
10 10
11obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o 11obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o
12obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o clk.o 12obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o
13obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o 13obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o
14obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o 14obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o
15obj-$(CONFIG_PCI) += pcibios.o 15obj-$(CONFIG_PCI) += pcibios.o
diff --git a/arch/arc/kernel/clk.c b/arch/arc/kernel/clk.c
deleted file mode 100644
index 10c7b0b5a079..000000000000
--- a/arch/arc/kernel/clk.c
+++ /dev/null
@@ -1,21 +0,0 @@
1/*
2 * Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <asm/clk.h>
10
11unsigned long core_freq = 80000000;
12
13/*
14 * As of now we default to device-tree provided clock
15 * In future we can determine this in early boot
16 */
17int arc_set_core_freq(unsigned long freq)
18{
19 core_freq = freq;
20 return 0;
21}
diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index 5d446df2c413..6f4cb0dab1b9 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -16,6 +16,9 @@
16 16
17#include <asm/asm-offsets.h> 17#include <asm/asm-offsets.h>
18#include <linux/sched.h> 18#include <linux/sched.h>
19#ifdef CONFIG_ARC_PLAT_EZNPS
20#include <plat/ctop.h>
21#endif
19 22
20#define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4) 23#define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4)
21 24
@@ -67,9 +70,16 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
67#ifndef CONFIG_SMP 70#ifndef CONFIG_SMP
68 "st %2, [@_current_task] \n\t" 71 "st %2, [@_current_task] \n\t"
69#else 72#else
73#ifdef CONFIG_ARC_PLAT_EZNPS
74 "lr r24, [%4] \n\t"
75#ifndef CONFIG_EZNPS_MTM_EXT
76 "lsr r24, r24, 4 \n\t"
77#endif
78#else
70 "lr r24, [identity] \n\t" 79 "lr r24, [identity] \n\t"
71 "lsr r24, r24, 8 \n\t" 80 "lsr r24, r24, 8 \n\t"
72 "bmsk r24, r24, 7 \n\t" 81 "bmsk r24, r24, 7 \n\t"
82#endif
73 "add2 r24, @_current_task, r24 \n\t" 83 "add2 r24, @_current_task, r24 \n\t"
74 "st %2, [r24] \n\t" 84 "st %2, [r24] \n\t"
75#endif 85#endif
@@ -107,6 +117,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
107 117
108 : "=r"(tmp) 118 : "=r"(tmp)
109 : "n"(KSP_WORD_OFF), "r"(next), "r"(prev) 119 : "n"(KSP_WORD_OFF), "r"(next), "r"(prev)
120#ifdef CONFIG_ARC_PLAT_EZNPS
121 , "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
122#endif
110 : "blink" 123 : "blink"
111 ); 124 );
112 125
diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c
index 7e844fd8213f..f1e07c2344f8 100644
--- a/arch/arc/kernel/devtree.c
+++ b/arch/arc/kernel/devtree.c
@@ -14,7 +14,6 @@
14#include <linux/memblock.h> 14#include <linux/memblock.h>
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/of_fdt.h> 16#include <linux/of_fdt.h>
17#include <asm/clk.h>
18#include <asm/mach_desc.h> 17#include <asm/mach_desc.h>
19 18
20#ifdef CONFIG_SERIAL_EARLYCON 19#ifdef CONFIG_SERIAL_EARLYCON
@@ -28,14 +27,12 @@ unsigned int __init arc_early_base_baud(void)
28 27
29static void __init arc_set_early_base_baud(unsigned long dt_root) 28static void __init arc_set_early_base_baud(unsigned long dt_root)
30{ 29{
31 unsigned int core_clk = arc_get_core_freq();
32
33 if (of_flat_dt_is_compatible(dt_root, "abilis,arc-tb10x")) 30 if (of_flat_dt_is_compatible(dt_root, "abilis,arc-tb10x"))
34 arc_base_baud = core_clk/3; 31 arc_base_baud = 166666666; /* Fixed 166.6MHz clk (TB10x) */
35 else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp")) 32 else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp"))
36 arc_base_baud = 33333333; /* Fixed 33MHz clk (AXS10x) */ 33 arc_base_baud = 33333333; /* Fixed 33MHz clk (AXS10x) */
37 else 34 else
38 arc_base_baud = core_clk; 35 arc_base_baud = 50000000; /* Fixed default 50MHz */
39} 36}
40#else 37#else
41#define arc_set_early_base_baud(dt_root) 38#define arc_set_early_base_baud(dt_root)
@@ -65,8 +62,6 @@ const struct machine_desc * __init setup_machine_fdt(void *dt)
65{ 62{
66 const struct machine_desc *mdesc; 63 const struct machine_desc *mdesc;
67 unsigned long dt_root; 64 unsigned long dt_root;
68 const void *clk;
69 int len;
70 65
71 if (!early_init_dt_scan(dt)) 66 if (!early_init_dt_scan(dt))
72 return NULL; 67 return NULL;
@@ -76,10 +71,6 @@ const struct machine_desc * __init setup_machine_fdt(void *dt)
76 machine_halt(); 71 machine_halt();
77 72
78 dt_root = of_get_flat_dt_root(); 73 dt_root = of_get_flat_dt_root();
79 clk = of_get_flat_dt_prop(dt_root, "clock-frequency", &len);
80 if (clk)
81 arc_set_core_freq(of_read_ulong(clk, len/4));
82
83 arc_set_early_base_baud(dt_root); 74 arc_set_early_base_baud(dt_root);
84 75
85 return mdesc; 76 return mdesc;
diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c
index 942526322ae7..6c24faf48b16 100644
--- a/arch/arc/kernel/intc-arcv2.c
+++ b/arch/arc/kernel/intc-arcv2.c
@@ -137,23 +137,30 @@ static const struct irq_domain_ops arcv2_irq_ops = {
137 .map = arcv2_irq_map, 137 .map = arcv2_irq_map,
138}; 138};
139 139
140static struct irq_domain *root_domain;
141 140
142static int __init 141static int __init
143init_onchip_IRQ(struct device_node *intc, struct device_node *parent) 142init_onchip_IRQ(struct device_node *intc, struct device_node *parent)
144{ 143{
144 struct irq_domain *root_domain;
145
145 if (parent) 146 if (parent)
146 panic("DeviceTree incore intc not a root irq controller\n"); 147 panic("DeviceTree incore intc not a root irq controller\n");
147 148
148 root_domain = irq_domain_add_legacy(intc, NR_CPU_IRQS, 0, 0, 149 root_domain = irq_domain_add_linear(intc, NR_CPU_IRQS, &arcv2_irq_ops, NULL);
149 &arcv2_irq_ops, NULL);
150
151 if (!root_domain) 150 if (!root_domain)
152 panic("root irq domain not avail\n"); 151 panic("root irq domain not avail\n");
153 152
154 /* with this we don't need to export root_domain */ 153 /*
154 * Needed for primary domain lookup to succeed
155 * This is a primary irqchip, and can never have a parent
156 */
155 irq_set_default_host(root_domain); 157 irq_set_default_host(root_domain);
156 158
159#ifdef CONFIG_SMP
160 irq_create_mapping(root_domain, IPI_IRQ);
161#endif
162 irq_create_mapping(root_domain, SOFTIRQ_IRQ);
163
157 return 0; 164 return 0;
158} 165}
159 166
diff --git a/arch/arc/kernel/intc-compact.c b/arch/arc/kernel/intc-compact.c
index 224d1c3aa9c4..c5cceca36118 100644
--- a/arch/arc/kernel/intc-compact.c
+++ b/arch/arc/kernel/intc-compact.c
@@ -14,6 +14,8 @@
14#include <linux/irqchip.h> 14#include <linux/irqchip.h>
15#include <asm/irq.h> 15#include <asm/irq.h>
16 16
17#define TIMER0_IRQ 3 /* Fixed by ISA */
18
17/* 19/*
18 * Early Hardware specific Interrupt setup 20 * Early Hardware specific Interrupt setup
19 * -Platform independent, needed for each CPU (not foldable into init_IRQ) 21 * -Platform independent, needed for each CPU (not foldable into init_IRQ)
@@ -79,8 +81,9 @@ static struct irq_chip onchip_intc = {
79static int arc_intc_domain_map(struct irq_domain *d, unsigned int irq, 81static int arc_intc_domain_map(struct irq_domain *d, unsigned int irq,
80 irq_hw_number_t hw) 82 irq_hw_number_t hw)
81{ 83{
82 switch (irq) { 84 switch (hw) {
83 case TIMER0_IRQ: 85 case TIMER0_IRQ:
86 irq_set_percpu_devid(irq);
84 irq_set_chip_and_handler(irq, &onchip_intc, handle_percpu_irq); 87 irq_set_chip_and_handler(irq, &onchip_intc, handle_percpu_irq);
85 break; 88 break;
86 default: 89 default:
@@ -94,21 +97,23 @@ static const struct irq_domain_ops arc_intc_domain_ops = {
94 .map = arc_intc_domain_map, 97 .map = arc_intc_domain_map,
95}; 98};
96 99
97static struct irq_domain *root_domain;
98
99static int __init 100static int __init
100init_onchip_IRQ(struct device_node *intc, struct device_node *parent) 101init_onchip_IRQ(struct device_node *intc, struct device_node *parent)
101{ 102{
103 struct irq_domain *root_domain;
104
102 if (parent) 105 if (parent)
103 panic("DeviceTree incore intc not a root irq controller\n"); 106 panic("DeviceTree incore intc not a root irq controller\n");
104 107
105 root_domain = irq_domain_add_legacy(intc, NR_CPU_IRQS, 0, 0, 108 root_domain = irq_domain_add_linear(intc, NR_CPU_IRQS,
106 &arc_intc_domain_ops, NULL); 109 &arc_intc_domain_ops, NULL);
107
108 if (!root_domain) 110 if (!root_domain)
109 panic("root irq domain not avail\n"); 111 panic("root irq domain not avail\n");
110 112
111 /* with this we don't need to export root_domain */ 113 /*
114 * Needed for primary domain lookup to succeed
115 * This is a primary irqchip, and can never have a parent
116 */
112 irq_set_default_host(root_domain); 117 irq_set_default_host(root_domain);
113 118
114 return 0; 119 return 0;
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
index ba17f85285cf..538b36afe89e 100644
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -41,53 +41,7 @@ void __init init_IRQ(void)
41 * "C" Entry point for any ARC ISR, called from low level vector handler 41 * "C" Entry point for any ARC ISR, called from low level vector handler
42 * @irq is the vector number read from ICAUSE reg of on-chip intc 42 * @irq is the vector number read from ICAUSE reg of on-chip intc
43 */ 43 */
44void arch_do_IRQ(unsigned int irq, struct pt_regs *regs) 44void arch_do_IRQ(unsigned int hwirq, struct pt_regs *regs)
45{ 45{
46 struct pt_regs *old_regs = set_irq_regs(regs); 46 handle_domain_irq(NULL, hwirq, regs);
47
48 irq_enter();
49 generic_handle_irq(irq);
50 irq_exit();
51 set_irq_regs(old_regs);
52}
53
54/*
55 * API called for requesting percpu interrupts - called by each CPU
56 * - For boot CPU, actually request the IRQ with genirq core + enables
57 * - For subsequent callers only enable called locally
58 *
59 * Relies on being called by boot cpu first (i.e. request called ahead) of
60 * any enable as expected by genirq. Hence Suitable only for TIMER, IPI
61 * which are guaranteed to be setup on boot core first.
62 * Late probed peripherals such as perf can't use this as there no guarantee
63 * of being called on boot CPU first.
64 */
65
66void arc_request_percpu_irq(int irq, int cpu,
67 irqreturn_t (*isr)(int irq, void *dev),
68 const char *irq_nm,
69 void *percpu_dev)
70{
71 /* Boot cpu calls request, all call enable */
72 if (!cpu) {
73 int rc;
74
75#ifdef CONFIG_ISA_ARCOMPACT
76 /*
77 * A subsequent request_percpu_irq() fails if percpu_devid is
78 * not set. That in turns sets NOAUTOEN, meaning each core needs
79 * to call enable_percpu_irq()
80 *
81 * For ARCv2, this is done in irq map function since we know
82 * which irqs are strictly per cpu
83 */
84 irq_set_percpu_devid(irq);
85#endif
86
87 rc = request_percpu_irq(irq, isr, irq_nm, percpu_dev);
88 if (rc)
89 panic("Percpu IRQ request failed for %d\n", irq);
90 }
91
92 enable_percpu_irq(irq, 0);
93} 47}
diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
index c41c364b926c..72f9179b1a24 100644
--- a/arch/arc/kernel/mcip.c
+++ b/arch/arc/kernel/mcip.c
@@ -15,9 +15,6 @@
15#include <asm/mcip.h> 15#include <asm/mcip.h>
16#include <asm/setup.h> 16#include <asm/setup.h>
17 17
18#define IPI_IRQ 19
19#define SOFTIRQ_IRQ 21
20
21static char smp_cpuinfo_buf[128]; 18static char smp_cpuinfo_buf[128];
22static int idu_detected; 19static int idu_detected;
23 20
@@ -116,15 +113,13 @@ static void mcip_probe_n_setup(void)
116 IS_AVAIL1(mp.dbg, "DEBUG "), 113 IS_AVAIL1(mp.dbg, "DEBUG "),
117 IS_AVAIL1(mp.gfrc, "GFRC")); 114 IS_AVAIL1(mp.gfrc, "GFRC"));
118 115
116 cpuinfo_arc700[0].extn.gfrc = mp.gfrc;
119 idu_detected = mp.idu; 117 idu_detected = mp.idu;
120 118
121 if (mp.dbg) { 119 if (mp.dbg) {
122 __mcip_cmd_data(CMD_DEBUG_SET_SELECT, 0, 0xf); 120 __mcip_cmd_data(CMD_DEBUG_SET_SELECT, 0, 0xf);
123 __mcip_cmd_data(CMD_DEBUG_SET_MASK, 0xf, 0xf); 121 __mcip_cmd_data(CMD_DEBUG_SET_MASK, 0xf, 0xf);
124 } 122 }
125
126 if (IS_ENABLED(CONFIG_ARC_HAS_GFRC) && !mp.gfrc)
127 panic("kernel trying to use non-existent GFRC\n");
128} 123}
129 124
130struct plat_smp_ops plat_smp_ops = { 125struct plat_smp_ops plat_smp_ops = {
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index 151acf0c9383..f63b8bfefb0c 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -13,7 +13,6 @@
13#include <linux/console.h> 13#include <linux/console.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/cpu.h> 15#include <linux/cpu.h>
16#include <linux/clk-provider.h>
17#include <linux/of_fdt.h> 16#include <linux/of_fdt.h>
18#include <linux/of_platform.h> 17#include <linux/of_platform.h>
19#include <linux/cache.h> 18#include <linux/cache.h>
@@ -24,7 +23,6 @@
24#include <asm/page.h> 23#include <asm/page.h>
25#include <asm/irq.h> 24#include <asm/irq.h>
26#include <asm/unwind.h> 25#include <asm/unwind.h>
27#include <asm/clk.h>
28#include <asm/mach_desc.h> 26#include <asm/mach_desc.h>
29#include <asm/smp.h> 27#include <asm/smp.h>
30 28
@@ -220,10 +218,6 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
220 if (tbl->info.id == 0) 218 if (tbl->info.id == 0)
221 n += scnprintf(buf + n, len - n, "UNKNOWN ARC Processor\n"); 219 n += scnprintf(buf + n, len - n, "UNKNOWN ARC Processor\n");
222 220
223 n += scnprintf(buf + n, len - n, "CPU speed\t: %u.%02u Mhz\n",
224 (unsigned int)(arc_get_core_freq() / 1000000),
225 (unsigned int)(arc_get_core_freq() / 10000) % 100);
226
227 n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ", 221 n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ",
228 IS_AVAIL1(cpu->extn.timer0, "Timer0 "), 222 IS_AVAIL1(cpu->extn.timer0, "Timer0 "),
229 IS_AVAIL1(cpu->extn.timer1, "Timer1 "), 223 IS_AVAIL1(cpu->extn.timer1, "Timer1 "),
@@ -314,9 +308,6 @@ static void arc_chk_core_config(void)
314 if (!cpu->extn.timer1) 308 if (!cpu->extn.timer1)
315 panic("Timer1 is not present!\n"); 309 panic("Timer1 is not present!\n");
316 310
317 if (IS_ENABLED(CONFIG_ARC_HAS_RTC) && !cpu->extn.rtc)
318 panic("RTC is not present\n");
319
320#ifdef CONFIG_ARC_HAS_DCCM 311#ifdef CONFIG_ARC_HAS_DCCM
321 /* 312 /*
322 * DCCM can be arbit placed in hardware. 313 * DCCM can be arbit placed in hardware.
@@ -444,7 +435,6 @@ void __init setup_arch(char **cmdline_p)
444 435
445static int __init customize_machine(void) 436static int __init customize_machine(void)
446{ 437{
447 of_clk_init(NULL);
448 /* 438 /*
449 * Traverses flattened DeviceTree - registering platform devices 439 * Traverses flattened DeviceTree - registering platform devices
450 * (if any) complete with their resources 440 * (if any) complete with their resources
@@ -477,6 +467,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
477{ 467{
478 char *str; 468 char *str;
479 int cpu_id = ptr_to_cpu(v); 469 int cpu_id = ptr_to_cpu(v);
470 struct device_node *core_clk = of_find_node_by_name(NULL, "core_clk");
471 u32 freq = 0;
480 472
481 if (!cpu_online(cpu_id)) { 473 if (!cpu_online(cpu_id)) {
482 seq_printf(m, "processor [%d]\t: Offline\n", cpu_id); 474 seq_printf(m, "processor [%d]\t: Offline\n", cpu_id);
@@ -489,6 +481,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
489 481
490 seq_printf(m, arc_cpu_mumbojumbo(cpu_id, str, PAGE_SIZE)); 482 seq_printf(m, arc_cpu_mumbojumbo(cpu_id, str, PAGE_SIZE));
491 483
484 of_property_read_u32(core_clk, "clock-frequency", &freq);
485 if (freq)
486 seq_printf(m, "CPU speed\t: %u.%02u Mhz\n",
487 freq / 1000000, (freq / 10000) % 100);
488
492 seq_printf(m, "Bogo MIPS\t: %lu.%02lu\n", 489 seq_printf(m, "Bogo MIPS\t: %lu.%02lu\n",
493 loops_per_jiffy / (500000 / HZ), 490 loops_per_jiffy / (500000 / HZ),
494 (loops_per_jiffy / (5000 / HZ)) % 100); 491 (loops_per_jiffy / (5000 / HZ)) % 100);
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 4cb3add77c75..f183cc648851 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -126,11 +126,6 @@ void start_kernel_secondary(void)
126 current->active_mm = mm; 126 current->active_mm = mm;
127 cpumask_set_cpu(cpu, mm_cpumask(mm)); 127 cpumask_set_cpu(cpu, mm_cpumask(mm));
128 128
129 notify_cpu_starting(cpu);
130 set_cpu_online(cpu, true);
131
132 pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
133
134 /* Some SMP H/w setup - for each cpu */ 129 /* Some SMP H/w setup - for each cpu */
135 if (plat_smp_ops.init_per_cpu) 130 if (plat_smp_ops.init_per_cpu)
136 plat_smp_ops.init_per_cpu(cpu); 131 plat_smp_ops.init_per_cpu(cpu);
@@ -138,7 +133,10 @@ void start_kernel_secondary(void)
138 if (machine_desc->init_per_cpu) 133 if (machine_desc->init_per_cpu)
139 machine_desc->init_per_cpu(cpu); 134 machine_desc->init_per_cpu(cpu);
140 135
141 arc_local_timer_setup(); 136 notify_cpu_starting(cpu);
137 set_cpu_online(cpu, true);
138
139 pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
142 140
143 local_irq_enable(); 141 local_irq_enable();
144 preempt_disable(); 142 preempt_disable();
@@ -346,6 +344,10 @@ irqreturn_t do_IPI(int irq, void *dev_id)
346 344
347/* 345/*
348 * API called by platform code to hookup arch-common ISR to their IPI IRQ 346 * API called by platform code to hookup arch-common ISR to their IPI IRQ
347 *
348 * Note: If IPI is provided by platform (vs. say ARC MCIP), their intc setup/map
349 * function needs to call call irq_set_percpu_devid() for IPI IRQ, otherwise
350 * request_percpu_irq() below will fail
349 */ 351 */
350static DEFINE_PER_CPU(int, ipi_dev); 352static DEFINE_PER_CPU(int, ipi_dev);
351 353
@@ -353,7 +355,16 @@ int smp_ipi_irq_setup(int cpu, int irq)
353{ 355{
354 int *dev = per_cpu_ptr(&ipi_dev, cpu); 356 int *dev = per_cpu_ptr(&ipi_dev, cpu);
355 357
356 arc_request_percpu_irq(irq, cpu, do_IPI, "IPI Interrupt", dev); 358 /* Boot cpu calls request, all call enable */
359 if (!cpu) {
360 int rc;
361
362 rc = request_percpu_irq(irq, do_IPI, "IPI Interrupt", dev);
363 if (rc)
364 panic("Percpu IRQ request failed for %d\n", irq);
365 }
366
367 enable_percpu_irq(irq, 0);
357 368
358 return 0; 369 return 0;
359} 370}
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index 7d9a736fc7e5..4549ab255dd1 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -29,21 +29,16 @@
29 * which however is currently broken 29 * which however is currently broken
30 */ 30 */
31 31
32#include <linux/spinlock.h>
33#include <linux/interrupt.h> 32#include <linux/interrupt.h>
34#include <linux/module.h> 33#include <linux/clk.h>
35#include <linux/sched.h> 34#include <linux/clk-provider.h>
36#include <linux/kernel.h>
37#include <linux/time.h>
38#include <linux/init.h>
39#include <linux/timex.h>
40#include <linux/profile.h>
41#include <linux/clocksource.h> 35#include <linux/clocksource.h>
42#include <linux/clockchips.h> 36#include <linux/clockchips.h>
37#include <linux/cpu.h>
38#include <linux/of.h>
39#include <linux/of_irq.h>
43#include <asm/irq.h> 40#include <asm/irq.h>
44#include <asm/arcregs.h> 41#include <asm/arcregs.h>
45#include <asm/clk.h>
46#include <asm/mach_desc.h>
47 42
48#include <asm/mcip.h> 43#include <asm/mcip.h>
49 44
@@ -60,16 +55,35 @@
60 55
61#define ARC_TIMER_MAX 0xFFFFFFFF 56#define ARC_TIMER_MAX 0xFFFFFFFF
62 57
63/********** Clock Source Device *********/ 58static unsigned long arc_timer_freq;
64
65#ifdef CONFIG_ARC_HAS_GFRC
66 59
67static int arc_counter_setup(void) 60static int noinline arc_get_timer_clk(struct device_node *node)
68{ 61{
69 return 1; 62 struct clk *clk;
63 int ret;
64
65 clk = of_clk_get(node, 0);
66 if (IS_ERR(clk)) {
67 pr_err("timer missing clk");
68 return PTR_ERR(clk);
69 }
70
71 ret = clk_prepare_enable(clk);
72 if (ret) {
73 pr_err("Couldn't enable parent clk\n");
74 return ret;
75 }
76
77 arc_timer_freq = clk_get_rate(clk);
78
79 return 0;
70} 80}
71 81
72static cycle_t arc_counter_read(struct clocksource *cs) 82/********** Clock Source Device *********/
83
84#ifdef CONFIG_ARC_HAS_GFRC
85
86static cycle_t arc_read_gfrc(struct clocksource *cs)
73{ 87{
74 unsigned long flags; 88 unsigned long flags;
75 union { 89 union {
@@ -94,15 +108,31 @@ static cycle_t arc_counter_read(struct clocksource *cs)
94 return stamp.full; 108 return stamp.full;
95} 109}
96 110
97static struct clocksource arc_counter = { 111static struct clocksource arc_counter_gfrc = {
98 .name = "ARConnect GFRC", 112 .name = "ARConnect GFRC",
99 .rating = 400, 113 .rating = 400,
100 .read = arc_counter_read, 114 .read = arc_read_gfrc,
101 .mask = CLOCKSOURCE_MASK(64), 115 .mask = CLOCKSOURCE_MASK(64),
102 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 116 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
103}; 117};
104 118
105#else 119static void __init arc_cs_setup_gfrc(struct device_node *node)
120{
121 int exists = cpuinfo_arc700[0].extn.gfrc;
122 int ret;
123
124 if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected"))
125 return;
126
127 ret = arc_get_timer_clk(node);
128 if (ret)
129 return;
130
131 clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq);
132}
133CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc);
134
135#endif
106 136
107#ifdef CONFIG_ARC_HAS_RTC 137#ifdef CONFIG_ARC_HAS_RTC
108 138
@@ -110,15 +140,7 @@ static struct clocksource arc_counter = {
110#define AUX_RTC_LOW 0x104 140#define AUX_RTC_LOW 0x104
111#define AUX_RTC_HIGH 0x105 141#define AUX_RTC_HIGH 0x105
112 142
113int arc_counter_setup(void) 143static cycle_t arc_read_rtc(struct clocksource *cs)
114{
115 write_aux_reg(AUX_RTC_CTRL, 1);
116
117 /* Not usable in SMP */
118 return !IS_ENABLED(CONFIG_SMP);
119}
120
121static cycle_t arc_counter_read(struct clocksource *cs)
122{ 144{
123 unsigned long status; 145 unsigned long status;
124 union { 146 union {
@@ -142,47 +164,78 @@ static cycle_t arc_counter_read(struct clocksource *cs)
142 return stamp.full; 164 return stamp.full;
143} 165}
144 166
145static struct clocksource arc_counter = { 167static struct clocksource arc_counter_rtc = {
146 .name = "ARCv2 RTC", 168 .name = "ARCv2 RTC",
147 .rating = 350, 169 .rating = 350,
148 .read = arc_counter_read, 170 .read = arc_read_rtc,
149 .mask = CLOCKSOURCE_MASK(64), 171 .mask = CLOCKSOURCE_MASK(64),
150 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 172 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
151}; 173};
152 174
153#else /* !CONFIG_ARC_HAS_RTC */ 175static void __init arc_cs_setup_rtc(struct device_node *node)
154
155/*
156 * set 32bit TIMER1 to keep counting monotonically and wraparound
157 */
158int arc_counter_setup(void)
159{ 176{
160 write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX); 177 int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc;
161 write_aux_reg(ARC_REG_TIMER1_CNT, 0); 178 int ret;
162 write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH); 179
180 if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected"))
181 return;
182
183 /* Local to CPU hence not usable in SMP */
184 if (WARN(IS_ENABLED(CONFIG_SMP), "Local-64-bit-Ctr not usable in SMP"))
185 return;
186
187 ret = arc_get_timer_clk(node);
188 if (ret)
189 return;
190
191 write_aux_reg(AUX_RTC_CTRL, 1);
163 192
164 /* Not usable in SMP */ 193 clocksource_register_hz(&arc_counter_rtc, arc_timer_freq);
165 return !IS_ENABLED(CONFIG_SMP);
166} 194}
195CLOCKSOURCE_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc);
167 196
168static cycle_t arc_counter_read(struct clocksource *cs) 197#endif
198
199/*
200 * 32bit TIMER1 to keep counting monotonically and wraparound
201 */
202
203static cycle_t arc_read_timer1(struct clocksource *cs)
169{ 204{
170 return (cycle_t) read_aux_reg(ARC_REG_TIMER1_CNT); 205 return (cycle_t) read_aux_reg(ARC_REG_TIMER1_CNT);
171} 206}
172 207
173static struct clocksource arc_counter = { 208static struct clocksource arc_counter_timer1 = {
174 .name = "ARC Timer1", 209 .name = "ARC Timer1",
175 .rating = 300, 210 .rating = 300,
176 .read = arc_counter_read, 211 .read = arc_read_timer1,
177 .mask = CLOCKSOURCE_MASK(32), 212 .mask = CLOCKSOURCE_MASK(32),
178 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 213 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
179}; 214};
180 215
181#endif 216static void __init arc_cs_setup_timer1(struct device_node *node)
182#endif 217{
218 int ret;
219
220 /* Local to CPU hence not usable in SMP */
221 if (IS_ENABLED(CONFIG_SMP))
222 return;
223
224 ret = arc_get_timer_clk(node);
225 if (ret)
226 return;
227
228 write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX);
229 write_aux_reg(ARC_REG_TIMER1_CNT, 0);
230 write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH);
231
232 clocksource_register_hz(&arc_counter_timer1, arc_timer_freq);
233}
183 234
184/********** Clock Event Device *********/ 235/********** Clock Event Device *********/
185 236
237static int arc_timer_irq;
238
186/* 239/*
187 * Arm the timer to interrupt after @cycles 240 * Arm the timer to interrupt after @cycles
188 * The distinction for oneshot/periodic is done in arc_event_timer_ack() below 241 * The distinction for oneshot/periodic is done in arc_event_timer_ack() below
@@ -209,7 +262,7 @@ static int arc_clkevent_set_periodic(struct clock_event_device *dev)
209 * At X Hz, 1 sec = 1000ms -> X cycles; 262 * At X Hz, 1 sec = 1000ms -> X cycles;
210 * 10ms -> X / 100 cycles 263 * 10ms -> X / 100 cycles
211 */ 264 */
212 arc_timer_event_setup(arc_get_core_freq() / HZ); 265 arc_timer_event_setup(arc_timer_freq / HZ);
213 return 0; 266 return 0;
214} 267}
215 268
@@ -218,7 +271,6 @@ static DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = {
218 .features = CLOCK_EVT_FEAT_ONESHOT | 271 .features = CLOCK_EVT_FEAT_ONESHOT |
219 CLOCK_EVT_FEAT_PERIODIC, 272 CLOCK_EVT_FEAT_PERIODIC,
220 .rating = 300, 273 .rating = 300,
221 .irq = TIMER0_IRQ, /* hardwired, no need for resources */
222 .set_next_event = arc_clkevent_set_next_event, 274 .set_next_event = arc_clkevent_set_next_event,
223 .set_state_periodic = arc_clkevent_set_periodic, 275 .set_state_periodic = arc_clkevent_set_periodic,
224}; 276};
@@ -244,45 +296,81 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id)
244 return IRQ_HANDLED; 296 return IRQ_HANDLED;
245} 297}
246 298
299static int arc_timer_cpu_notify(struct notifier_block *self,
300 unsigned long action, void *hcpu)
301{
302 struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
303
304 evt->cpumask = cpumask_of(smp_processor_id());
305
306 switch (action & ~CPU_TASKS_FROZEN) {
307 case CPU_STARTING:
308 clockevents_config_and_register(evt, arc_timer_freq,
309 0, ULONG_MAX);
310 enable_percpu_irq(arc_timer_irq, 0);
311 break;
312 case CPU_DYING:
313 disable_percpu_irq(arc_timer_irq);
314 break;
315 }
316
317 return NOTIFY_OK;
318}
319
320static struct notifier_block arc_timer_cpu_nb = {
321 .notifier_call = arc_timer_cpu_notify,
322};
323
247/* 324/*
248 * Setup the local event timer for @cpu 325 * clockevent setup for boot CPU
249 */ 326 */
250void arc_local_timer_setup() 327static void __init arc_clockevent_setup(struct device_node *node)
251{ 328{
252 struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device); 329 struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
253 int cpu = smp_processor_id(); 330 int ret;
331
332 register_cpu_notifier(&arc_timer_cpu_nb);
254 333
255 evt->cpumask = cpumask_of(cpu); 334 arc_timer_irq = irq_of_parse_and_map(node, 0);
256 clockevents_config_and_register(evt, arc_get_core_freq(), 335 if (arc_timer_irq <= 0)
336 panic("clockevent: missing irq");
337
338 ret = arc_get_timer_clk(node);
339 if (ret)
340 panic("clockevent: missing clk");
341
342 evt->irq = arc_timer_irq;
343 evt->cpumask = cpumask_of(smp_processor_id());
344 clockevents_config_and_register(evt, arc_timer_freq,
257 0, ARC_TIMER_MAX); 345 0, ARC_TIMER_MAX);
258 346
259 /* setup the per-cpu timer IRQ handler - for all cpus */ 347 /* Needs apriori irq_set_percpu_devid() done in intc map function */
260 arc_request_percpu_irq(TIMER0_IRQ, cpu, timer_irq_handler, 348 ret = request_percpu_irq(arc_timer_irq, timer_irq_handler,
261 "Timer0 (per-cpu-tick)", evt); 349 "Timer0 (per-cpu-tick)", evt);
350 if (ret)
351 panic("clockevent: unable to request irq\n");
352
353 enable_percpu_irq(arc_timer_irq, 0);
262} 354}
263 355
356static void __init arc_of_timer_init(struct device_node *np)
357{
358 static int init_count = 0;
359
360 if (!init_count) {
361 init_count = 1;
362 arc_clockevent_setup(np);
363 } else {
364 arc_cs_setup_timer1(np);
365 }
366}
367CLOCKSOURCE_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_of_timer_init);
368
264/* 369/*
265 * Called from start_kernel() - boot CPU only 370 * Called from start_kernel() - boot CPU only
266 *
267 * -Sets up h/w timers as applicable on boot cpu
268 * -Also sets up any global state needed for timer subsystem:
269 * - for "counting" timer, registers a clocksource, usable across CPUs
270 * (provided that underlying counter h/w is synchronized across cores)
271 * - for "event" timer, sets up TIMER0 IRQ (as that is platform agnostic)
272 */ 371 */
273void __init time_init(void) 372void __init time_init(void)
274{ 373{
275 /* 374 of_clk_init(NULL);
276 * sets up the timekeeping free-flowing counter which also returns 375 clocksource_probe();
277 * whether the counter is usable as clocksource
278 */
279 if (arc_counter_setup())
280 /*
281 * CLK upto 4.29 GHz can be safely represented in 32 bits
282 * because Max 32 bit number is 4,294,967,295
283 */
284 clocksource_register_hz(&arc_counter, arc_get_core_freq());
285
286 /* sets up the periodic event timer */
287 arc_local_timer_setup();
288} 376}
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 7046c12c58ed..ec868a9081a1 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -814,6 +814,17 @@ void arc_mmu_init(void)
814 814
815 printk(arc_mmu_mumbojumbo(0, str, sizeof(str))); 815 printk(arc_mmu_mumbojumbo(0, str, sizeof(str)));
816 816
817 /*
818 * Can't be done in processor.h due to header include depenedencies
819 */
820 BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_KVADDR_SIZE << 20), PMD_SIZE));
821
822 /*
823 * stack top size sanity check,
824 * Can't be done in processor.h due to header include depenedencies
825 */
826 BUILD_BUG_ON(!IS_ALIGNED(STACK_TOP, PMD_SIZE));
827
817 /* For efficiency sake, kernel is compile time built for a MMU ver 828 /* For efficiency sake, kernel is compile time built for a MMU ver
818 * This must match the hardware it is running on. 829 * This must match the hardware it is running on.
819 * Linux built for MMU V2, if run on MMU V1 will break down because V1 830 * Linux built for MMU V2, if run on MMU V1 will break down because V1
diff --git a/arch/arc/plat-axs10x/axs10x.c b/arch/arc/plat-axs10x/axs10x.c
index 1b0f0f458a2b..86548701023c 100644
--- a/arch/arc/plat-axs10x/axs10x.c
+++ b/arch/arc/plat-axs10x/axs10x.c
@@ -14,10 +14,11 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/of_fdt.h>
17#include <linux/of_platform.h> 18#include <linux/of_platform.h>
19#include <linux/libfdt.h>
18 20
19#include <asm/asm-offsets.h> 21#include <asm/asm-offsets.h>
20#include <asm/clk.h>
21#include <asm/io.h> 22#include <asm/io.h>
22#include <asm/mach_desc.h> 23#include <asm/mach_desc.h>
23#include <asm/mcip.h> 24#include <asm/mcip.h>
@@ -389,6 +390,13 @@ axs103_set_freq(unsigned int id, unsigned int fd, unsigned int od)
389 390
390static void __init axs103_early_init(void) 391static void __init axs103_early_init(void)
391{ 392{
393 int offset = fdt_path_offset(initial_boot_params, "/cpu_card/core_clk");
394 const struct fdt_property *prop = fdt_get_property(initial_boot_params,
395 offset,
396 "clock-frequency",
397 NULL);
398 u32 freq = be32_to_cpu(*(u32*)(prop->data)) / 1000000, orig = freq;
399
392 /* 400 /*
393 * AXS103 configurations for SMP/QUAD configurations share device tree 401 * AXS103 configurations for SMP/QUAD configurations share device tree
394 * which defaults to 90 MHz. However recent failures of Quad config 402 * which defaults to 90 MHz. However recent failures of Quad config
@@ -401,12 +409,10 @@ static void __init axs103_early_init(void)
401#ifdef CONFIG_ARC_MCIP 409#ifdef CONFIG_ARC_MCIP
402 unsigned int num_cores = (read_aux_reg(ARC_REG_MCIP_BCR) >> 16) & 0x3F; 410 unsigned int num_cores = (read_aux_reg(ARC_REG_MCIP_BCR) >> 16) & 0x3F;
403 if (num_cores > 2) 411 if (num_cores > 2)
404 arc_set_core_freq(50 * 1000000); 412 freq = 50;
405 else if (num_cores == 2)
406 arc_set_core_freq(75 * 1000000);
407#endif 413#endif
408 414
409 switch (arc_get_core_freq()/1000000) { 415 switch (freq) {
410 case 33: 416 case 33:
411 axs103_set_freq(1, 1, 1); 417 axs103_set_freq(1, 1, 1);
412 break; 418 break;
@@ -431,11 +437,18 @@ static void __init axs103_early_init(void)
431 * DT "clock-frequency" might not match with board value. 437 * DT "clock-frequency" might not match with board value.
432 * Hence update it to match the board value. 438 * Hence update it to match the board value.
433 */ 439 */
434 arc_set_core_freq(axs103_get_freq() * 1000000); 440 freq = axs103_get_freq();
435 break; 441 break;
436 } 442 }
437 443
438 pr_info("Freq is %dMHz\n", axs103_get_freq()); 444 pr_info("Freq is %dMHz\n", freq);
445
446 /* Patching .dtb in-place with new core clock value */
447 if (freq != orig ) {
448 freq = cpu_to_be32(freq * 1000000);
449 fdt_setprop_inplace(initial_boot_params, offset,
450 "clock-frequency", &freq, sizeof(freq));
451 }
439 452
440 /* Memory maps already config in pre-bootloader */ 453 /* Memory maps already config in pre-bootloader */
441 454
diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig
new file mode 100644
index 000000000000..1d175cc6ad6d
--- /dev/null
+++ b/arch/arc/plat-eznps/Kconfig
@@ -0,0 +1,35 @@
1#
2# For a description of the syntax of this configuration file,
3# see Documentation/kbuild/kconfig-language.txt.
4#
5
6menuconfig ARC_PLAT_EZNPS
7 bool "\"EZchip\" ARC dev platform"
8 select ARC_HAS_COH_CACHES if SMP
9 select CPU_BIG_ENDIAN
10 select CLKSRC_NPS
11 select EZNPS_GIC
12 select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET
13 help
14 Support for EZchip development platforms,
15 based on ARC700 cores.
16 We handle few flavours:
17 - Hardware Emulator AKA HE which is FPGA based chasis
18 - Simulator based on MetaWare nSIM
19 - NPS400 chip based on ASIC
20
21config EZNPS_MTM_EXT
22 bool "ARC-EZchip MTM Extensions"
23 select CPUMASK_OFFSTACK
24 depends on ARC_PLAT_EZNPS && SMP
25 default y
26 help
27 Here we add new hierarchy for CPUs topology.
28 We got:
29 Core
30 Thread
31 At the new thread level each CPU represent one HW thread.
32 At highest hierarchy each core contain 16 threads,
33 any of them seem like CPU from Linux point of view.
34 All threads within same core share the execution unit of the
35 core and HW scheduler round robin between them.
diff --git a/arch/arc/plat-eznps/Makefile b/arch/arc/plat-eznps/Makefile
new file mode 100644
index 000000000000..21091b199df0
--- /dev/null
+++ b/arch/arc/plat-eznps/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the linux kernel.
3#
4
5obj-y := entry.o platform.o
6obj-$(CONFIG_SMP) += smp.o
7obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o
diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S
new file mode 100644
index 000000000000..328261c27cda
--- /dev/null
+++ b/arch/arc/plat-eznps/entry.S
@@ -0,0 +1,70 @@
1/*******************************************************************************
2
3 EZNPS CPU startup Code
4 Copyright(c) 2012 EZchip Technologies.
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 The full GNU General Public License is included in this distribution in
16 the file called "COPYING".
17
18*******************************************************************************/
19#include <linux/linkage.h>
20#include <asm/entry.h>
21#include <asm/cache.h>
22#include <plat/ctop.h>
23
24 .cpu A7
25
26 .section .init.text, "ax",@progbits
27 .align 1024 ; HW requierment for restart first PC
28
29ENTRY(res_service)
30#ifdef CONFIG_EZNPS_MTM_EXT
31 ; There is no work for HW thread id != 0
32 lr r3, [CTOP_AUX_THREAD_ID]
33 cmp r3, 0
34 jne stext
35#endif
36
37#ifdef CONFIG_ARC_HAS_DCACHE
38 ; With no cache coherency mechanism D$ need to be used very carefully.
39 ; Address space:
40 ; 0G-2G: We disable CONFIG_ARC_CACHE_PAGES.
41 ; 2G-3G: We disable D$ by setting this bit.
42 ; 3G-4G: D$ is disabled by architecture.
43 ; FMT are huge pages for user application reside at 0-2G.
44 ; Only FMT left as one who can use D$ where each such page got
45 ; disable/enable bit for cachability.
46 ; Programmer will use FMT pages for private data so cache coherency
47 ; would not be a problem.
48 ; First thing we invalidate D$
49 sr 1, [ARC_REG_DC_IVDC]
50 sr HW_COMPLY_KRN_NOT_D_CACHED, [CTOP_AUX_HW_COMPLY]
51#endif
52
53#ifdef CONFIG_SMP
54 ; We set logical cpuid to be used by GET_CPUID
55 ; We do not use physical cpuid since we want ids to be continious when
56 ; it comes to cpus on the same quad cluster.
57 ; This is useful for applications that used shared resources of a quad
58 ; cluster such SRAMS.
59 lr r3, [CTOP_AUX_CORE_ID]
60 sr r3, [CTOP_AUX_LOGIC_CORE_ID]
61 lr r3, [CTOP_AUX_CLUSTER_ID]
62 ; Set logical is acheived by swap of 2 middle bits of cluster id (4 bit)
63 ; r3 is used since we use short instruction and we need q-class reg
64 .short CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST
65 .word CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM
66 sr r3, [CTOP_AUX_LOGIC_CLUSTER_ID]
67#endif
68
69 j stext
70END(res_service)
diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
new file mode 100644
index 000000000000..9d6718c1a199
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/ctop.h
@@ -0,0 +1,209 @@
1/*
2 * Copyright(c) 2015 EZchip Technologies.
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 * The full GNU General Public License is included in this distribution in
14 * the file called "COPYING".
15 */
16
17#ifndef _PLAT_EZNPS_CTOP_H
18#define _PLAT_EZNPS_CTOP_H
19
20#ifndef CONFIG_ARC_PLAT_EZNPS
21#error "Incorrect ctop.h include"
22#endif
23
24#include <soc/nps/common.h>
25
26/* core auxiliary registers */
27#ifdef __ASSEMBLY__
28#define CTOP_AUX_BASE (-0x800)
29#else
30#define CTOP_AUX_BASE 0xFFFFF800
31#endif
32
33#define CTOP_AUX_GLOBAL_ID (CTOP_AUX_BASE + 0x000)
34#define CTOP_AUX_CLUSTER_ID (CTOP_AUX_BASE + 0x004)
35#define CTOP_AUX_CORE_ID (CTOP_AUX_BASE + 0x008)
36#define CTOP_AUX_THREAD_ID (CTOP_AUX_BASE + 0x00C)
37#define CTOP_AUX_LOGIC_GLOBAL_ID (CTOP_AUX_BASE + 0x010)
38#define CTOP_AUX_LOGIC_CLUSTER_ID (CTOP_AUX_BASE + 0x014)
39#define CTOP_AUX_LOGIC_CORE_ID (CTOP_AUX_BASE + 0x018)
40#define CTOP_AUX_MT_CTRL (CTOP_AUX_BASE + 0x020)
41#define CTOP_AUX_HW_COMPLY (CTOP_AUX_BASE + 0x024)
42#define CTOP_AUX_LPC (CTOP_AUX_BASE + 0x030)
43#define CTOP_AUX_EFLAGS (CTOP_AUX_BASE + 0x080)
44#define CTOP_AUX_IACK (CTOP_AUX_BASE + 0x088)
45#define CTOP_AUX_GPA1 (CTOP_AUX_BASE + 0x08C)
46#define CTOP_AUX_UDMC (CTOP_AUX_BASE + 0x300)
47
48/* EZchip core instructions */
49#define CTOP_INST_HWSCHD_OFF_R3 0x3B6F00BF
50#define CTOP_INST_HWSCHD_OFF_R4 0x3C6F00BF
51#define CTOP_INST_HWSCHD_RESTORE_R3 0x3E6F70C3
52#define CTOP_INST_HWSCHD_RESTORE_R4 0x3E6F7103
53#define CTOP_INST_SCHD_RW 0x3E6F7004
54#define CTOP_INST_SCHD_RD 0x3E6F7084
55#define CTOP_INST_ASRI_0_R3 0x3B56003E
56#define CTOP_INST_XEX_DI_R2_R2_R3 0x4A664C00
57#define CTOP_INST_EXC_DI_R2_R2_R3 0x4A664C01
58#define CTOP_INST_AADD_DI_R2_R2_R3 0x4A664C02
59#define CTOP_INST_AAND_DI_R2_R2_R3 0x4A664C04
60#define CTOP_INST_AOR_DI_R2_R2_R3 0x4A664C05
61#define CTOP_INST_AXOR_DI_R2_R2_R3 0x4A664C06
62
63/* Do not use D$ for address in 2G-3G */
64#define HW_COMPLY_KRN_NOT_D_CACHED _BITUL(28)
65
66#define NPS_MSU_EN_CFG 0x80
67#define NPS_CRG_BLKID 0x480
68#define NPS_CRG_SYNC_BIT _BITUL(0)
69#define NPS_GIM_BLKID 0x5C0
70
71/* GIM registers and fields*/
72#define NPS_GIM_UART_LINE _BITUL(7)
73#define NPS_GIM_DBG_LAN_EAST_TX_DONE_LINE _BITUL(10)
74#define NPS_GIM_DBG_LAN_EAST_RX_RDY_LINE _BITUL(11)
75#define NPS_GIM_DBG_LAN_WEST_TX_DONE_LINE _BITUL(25)
76#define NPS_GIM_DBG_LAN_WEST_RX_RDY_LINE _BITUL(26)
77
78#ifndef __ASSEMBLY__
79/* Functional registers definition */
80struct nps_host_reg_mtm_cfg {
81 union {
82 struct {
83 u32 gen:1, gdis:1, clk_gate_dis:1, asb:1,
84 __reserved:9, nat:3, ten:16;
85 };
86 u32 value;
87 };
88};
89
90struct nps_host_reg_mtm_cpu_cfg {
91 union {
92 struct {
93 u32 csa:22, dmsid:6, __reserved:3, cs:1;
94 };
95 u32 value;
96 };
97};
98
99struct nps_host_reg_thr_init {
100 union {
101 struct {
102 u32 str:1, __reserved:27, thr_id:4;
103 };
104 u32 value;
105 };
106};
107
108struct nps_host_reg_thr_init_sts {
109 union {
110 struct {
111 u32 bsy:1, err:1, __reserved:26, thr_id:4;
112 };
113 u32 value;
114 };
115};
116
117struct nps_host_reg_msu_en_cfg {
118 union {
119 struct {
120 u32 __reserved1:11,
121 rtc_en:1, ipc_en:1, gim_1_en:1,
122 gim_0_en:1, ipi_en:1, buff_e_rls_bmuw:1,
123 buff_e_alc_bmuw:1, buff_i_rls_bmuw:1, buff_i_alc_bmuw:1,
124 buff_e_rls_bmue:1, buff_e_alc_bmue:1, buff_i_rls_bmue:1,
125 buff_i_alc_bmue:1, __reserved2:1, buff_e_pre_en:1,
126 buff_i_pre_en:1, pmuw_ja_en:1, pmue_ja_en:1,
127 pmuw_nj_en:1, pmue_nj_en:1, msu_en:1;
128 };
129 u32 value;
130 };
131};
132
133struct nps_host_reg_gim_p_int_dst {
134 union {
135 struct {
136 u32 int_out_en:1, __reserved1:4,
137 is:1, intm:2, __reserved2:4,
138 nid:4, __reserved3:4, cid:4,
139 __reserved4:4, tid:4;
140 };
141 u32 value;
142 };
143};
144
145/* AUX registers definition */
146struct nps_host_reg_aux_udmc {
147 union {
148 struct {
149 u32 dcp:1, cme:1, __reserved:19, nat:3,
150 __reserved2:5, dcas:3;
151 };
152 u32 value;
153 };
154};
155
156struct nps_host_reg_aux_mt_ctrl {
157 union {
158 struct {
159 u32 mten:1, hsen:1, scd:1, sten:1,
160 st_cnt:8, __reserved:8,
161 hs_cnt:8, __reserved1:4;
162 };
163 u32 value;
164 };
165};
166
167struct nps_host_reg_aux_hw_comply {
168 union {
169 struct {
170 u32 me:1, le:1, te:1, knc:1, __reserved:28;
171 };
172 u32 value;
173 };
174};
175
176struct nps_host_reg_aux_lpc {
177 union {
178 struct {
179 u32 mep:1, __reserved:31;
180 };
181 u32 value;
182 };
183};
184
185/* CRG registers */
186#define REG_GEN_PURP_0 nps_host_reg_non_cl(NPS_CRG_BLKID, 0x1BF)
187
188/* GIM registers */
189#define REG_GIM_P_INT_EN_0 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x100)
190#define REG_GIM_P_INT_POL_0 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x110)
191#define REG_GIM_P_INT_SENS_0 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x114)
192#define REG_GIM_P_INT_BLK_0 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x118)
193#define REG_GIM_P_INT_DST_10 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13A)
194#define REG_GIM_P_INT_DST_11 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13B)
195#define REG_GIM_P_INT_DST_25 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x149)
196#define REG_GIM_P_INT_DST_26 nps_host_reg_non_cl(NPS_GIM_BLKID, 0x14A)
197
198#else
199
200.macro GET_CPU_ID reg
201 lr \reg, [CTOP_AUX_LOGIC_GLOBAL_ID]
202#ifndef CONFIG_EZNPS_MTM_EXT
203 lsr \reg, \reg, 4
204#endif
205.endm
206
207#endif /* __ASSEMBLY__ */
208
209#endif /* _PLAT_EZNPS_CTOP_H */
diff --git a/arch/arc/plat-eznps/include/plat/mtm.h b/arch/arc/plat-eznps/include/plat/mtm.h
new file mode 100644
index 000000000000..29b91b553bf9
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/mtm.h
@@ -0,0 +1,60 @@
1/*
2 * Copyright(c) 2015 EZchip Technologies.
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 * The full GNU General Public License is included in this distribution in
14 * the file called "COPYING".
15 */
16
17#ifndef _PLAT_EZNPS_MTM_H
18#define _PLAT_EZNPS_MTM_H
19
20#include <plat/ctop.h>
21
22static inline void *nps_mtm_reg_addr(u32 cpu, u32 reg)
23{
24 struct global_id gid;
25 u32 core, blkid;
26
27 gid.value = cpu;
28 core = gid.core;
29 blkid = (((core & 0x0C) << 2) | (core & 0x03));
30
31 return nps_host_reg(cpu, blkid, reg);
32}
33
34#ifdef CONFIG_EZNPS_MTM_EXT
35#define NPS_CPU_TO_THREAD_NUM(cpu) \
36 ({ struct global_id gid; gid.value = cpu; gid.thread; })
37
38/* MTM registers */
39#define MTM_CFG(cpu) nps_mtm_reg_addr(cpu, 0x81)
40#define MTM_THR_INIT(cpu) nps_mtm_reg_addr(cpu, 0x92)
41#define MTM_THR_INIT_STS(cpu) nps_mtm_reg_addr(cpu, 0x93)
42
43#define get_thread(map) map.thread
44#define eznps_max_cpus 4096
45#define eznps_cpus_per_cluster 256
46
47void mtm_enable_core(unsigned int cpu);
48int mtm_enable_thread(int cpu);
49#else /* !CONFIG_EZNPS_MTM_EXT */
50
51#define get_thread(map) 0
52#define eznps_max_cpus 256
53#define eznps_cpus_per_cluster 16
54#define mtm_enable_core(cpu)
55#define mtm_enable_thread(cpu) 1
56#define NPS_CPU_TO_THREAD_NUM(cpu) 0
57
58#endif /* CONFIG_EZNPS_MTM_EXT */
59
60#endif /* _PLAT_EZNPS_MTM_H */
diff --git a/arch/arc/plat-eznps/include/plat/smp.h b/arch/arc/plat-eznps/include/plat/smp.h
new file mode 100644
index 000000000000..06b59bd13a95
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/smp.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright(c) 2015 EZchip Technologies.
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 * The full GNU General Public License is included in this distribution in
14 * the file called "COPYING".
15 */
16
17#ifndef __PLAT_EZNPS_SMP_H
18#define __PLAT_EZNPS_SMP_H
19
20#ifdef CONFIG_SMP
21
22extern void res_service(void);
23
24#endif /* CONFIG_SMP */
25
26#endif
diff --git a/arch/arc/plat-eznps/mtm.c b/arch/arc/plat-eznps/mtm.c
new file mode 100644
index 000000000000..aaaaffd3d940
--- /dev/null
+++ b/arch/arc/plat-eznps/mtm.c
@@ -0,0 +1,133 @@
1/*
2 * Copyright(c) 2015 EZchip Technologies.
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 * The full GNU General Public License is included in this distribution in
14 * the file called "COPYING".
15 */
16
17#include <linux/smp.h>
18#include <linux/io.h>
19#include <linux/log2.h>
20#include <asm/arcregs.h>
21#include <plat/mtm.h>
22#include <plat/smp.h>
23
24#define MT_CTRL_HS_CNT 0xFF
25#define MT_CTRL_ST_CNT 0xF
26#define NPS_NUM_HW_THREADS 0x10
27
28static void mtm_init_nat(int cpu)
29{
30 struct nps_host_reg_mtm_cfg mtm_cfg;
31 struct nps_host_reg_aux_udmc udmc;
32 int log_nat, nat = 0, i, t;
33
34 /* Iterate core threads and update nat */
35 for (i = 0, t = cpu; i < NPS_NUM_HW_THREADS; i++, t++)
36 nat += test_bit(t, cpumask_bits(cpu_possible_mask));
37
38 log_nat = ilog2(nat);
39
40 udmc.value = read_aux_reg(CTOP_AUX_UDMC);
41 udmc.nat = log_nat;
42 write_aux_reg(CTOP_AUX_UDMC, udmc.value);
43
44 mtm_cfg.value = ioread32be(MTM_CFG(cpu));
45 mtm_cfg.nat = log_nat;
46 iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
47}
48
49static void mtm_init_thread(int cpu)
50{
51 int i, tries = 5;
52 struct nps_host_reg_thr_init thr_init;
53 struct nps_host_reg_thr_init_sts thr_init_sts;
54
55 /* Set thread init register */
56 thr_init.value = 0;
57 iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
58 thr_init.thr_id = NPS_CPU_TO_THREAD_NUM(cpu);
59 thr_init.str = 1;
60 iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
61
62 /* Poll till thread init is done */
63 for (i = 0; i < tries; i++) {
64 thr_init_sts.value = ioread32be(MTM_THR_INIT_STS(cpu));
65 if (thr_init_sts.thr_id == thr_init.thr_id) {
66 if (thr_init_sts.bsy)
67 continue;
68 else if (thr_init_sts.err)
69 pr_warn("Failed to thread init cpu %u\n", cpu);
70 break;
71 }
72
73 pr_warn("Wrong thread id in thread init for cpu %u\n", cpu);
74 break;
75 }
76
77 if (i == tries)
78 pr_warn("Got thread init timeout for cpu %u\n", cpu);
79}
80
81int mtm_enable_thread(int cpu)
82{
83 struct nps_host_reg_mtm_cfg mtm_cfg;
84
85 if (NPS_CPU_TO_THREAD_NUM(cpu) == 0)
86 return 1;
87
88 /* Enable thread in mtm */
89 mtm_cfg.value = ioread32be(MTM_CFG(cpu));
90 mtm_cfg.ten |= (1 << (NPS_CPU_TO_THREAD_NUM(cpu)));
91 iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
92
93 return 0;
94}
95
96void mtm_enable_core(unsigned int cpu)
97{
98 int i;
99 struct nps_host_reg_aux_mt_ctrl mt_ctrl;
100 struct nps_host_reg_mtm_cfg mtm_cfg;
101
102 if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
103 return;
104
105 /* Initialize Number of Active Threads */
106 mtm_init_nat(cpu);
107
108 /* Initialize mtm_cfg */
109 mtm_cfg.value = ioread32be(MTM_CFG(cpu));
110 mtm_cfg.ten = 1;
111 iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
112
113 /* Initialize all other threads in core */
114 for (i = 1; i < NPS_NUM_HW_THREADS; i++)
115 mtm_init_thread(cpu + i);
116
117
118 /* Enable HW schedule, stall counter, mtm */
119 mt_ctrl.value = 0;
120 mt_ctrl.hsen = 1;
121 mt_ctrl.hs_cnt = MT_CTRL_HS_CNT;
122 mt_ctrl.sten = 1;
123 mt_ctrl.st_cnt = MT_CTRL_ST_CNT;
124 mt_ctrl.mten = 1;
125 write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value);
126
127 /*
128 * HW scheduling mechanism will start working
129 * Only after call to instruction "schd.rw".
130 * cpu_relax() calls "schd.rw" instruction.
131 */
132 cpu_relax();
133}
diff --git a/arch/arc/plat-eznps/platform.c b/arch/arc/plat-eznps/platform.c
new file mode 100644
index 000000000000..7ad6d2b8f12a
--- /dev/null
+++ b/arch/arc/plat-eznps/platform.c
@@ -0,0 +1,102 @@
1/*
2 * Copyright(c) 2015 EZchip Technologies.
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 * The full GNU General Public License is included in this distribution in
14 * the file called "COPYING".
15 */
16
17#include <linux/init.h>
18#include <linux/io.h>
19#include <asm/mach_desc.h>
20#include <plat/mtm.h>
21
22static void __init eznps_configure_msu(void)
23{
24 int cpu;
25 struct nps_host_reg_msu_en_cfg msu_en_cfg = {.value = 0};
26
27 msu_en_cfg.msu_en = 1;
28 msu_en_cfg.ipi_en = 1;
29 msu_en_cfg.gim_0_en = 1;
30 msu_en_cfg.gim_1_en = 1;
31
32 /* enable IPI and GIM messages on all clusters */
33 for (cpu = 0 ; cpu < eznps_max_cpus; cpu += eznps_cpus_per_cluster)
34 iowrite32be(msu_en_cfg.value,
35 nps_host_reg(cpu, NPS_MSU_BLKID, NPS_MSU_EN_CFG));
36}
37
38static void __init eznps_configure_gim(void)
39{
40 u32 reg_value;
41 u32 gim_int_lines;
42 struct nps_host_reg_gim_p_int_dst gim_p_int_dst = {.value = 0};
43
44 gim_int_lines = NPS_GIM_UART_LINE;
45 gim_int_lines |= NPS_GIM_DBG_LAN_EAST_TX_DONE_LINE;
46 gim_int_lines |= NPS_GIM_DBG_LAN_EAST_RX_RDY_LINE;
47 gim_int_lines |= NPS_GIM_DBG_LAN_WEST_TX_DONE_LINE;
48 gim_int_lines |= NPS_GIM_DBG_LAN_WEST_RX_RDY_LINE;
49
50 /*
51 * IRQ polarity
52 * low or high level
53 * negative or positive edge
54 */
55 reg_value = ioread32be(REG_GIM_P_INT_POL_0);
56 reg_value &= ~gim_int_lines;
57 iowrite32be(reg_value, REG_GIM_P_INT_POL_0);
58
59 /* IRQ type level or edge */
60 reg_value = ioread32be(REG_GIM_P_INT_SENS_0);
61 reg_value |= NPS_GIM_DBG_LAN_EAST_TX_DONE_LINE;
62 reg_value |= NPS_GIM_DBG_LAN_WEST_TX_DONE_LINE;
63 iowrite32be(reg_value, REG_GIM_P_INT_SENS_0);
64
65 /*
66 * GIM interrupt select type for
67 * dbg_lan TX and RX interrupts
68 * should be type 1
69 * type 0 = IRQ line 6
70 * type 1 = IRQ line 7
71 */
72 gim_p_int_dst.is = 1;
73 iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_10);
74 iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_11);
75 iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_25);
76 iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_26);
77
78 /*
79 * CTOP IRQ lines should be defined
80 * as blocking in GIM
81 */
82 iowrite32be(gim_int_lines, REG_GIM_P_INT_BLK_0);
83
84 /* enable CTOP IRQ lines in GIM */
85 iowrite32be(gim_int_lines, REG_GIM_P_INT_EN_0);
86}
87
88static void __init eznps_early_init(void)
89{
90 eznps_configure_msu();
91 eznps_configure_gim();
92}
93
94static const char *eznps_compat[] __initconst = {
95 "ezchip,arc-nps",
96 NULL,
97};
98
99MACHINE_START(NPS, "nps")
100 .dt_compat = eznps_compat,
101 .init_early = eznps_early_init,
102MACHINE_END
diff --git a/arch/arc/plat-eznps/smp.c b/arch/arc/plat-eznps/smp.c
new file mode 100644
index 000000000000..5e901f86e4bd
--- /dev/null
+++ b/arch/arc/plat-eznps/smp.c
@@ -0,0 +1,155 @@
1/*
2 * Copyright(c) 2015 EZchip Technologies.
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 * The full GNU General Public License is included in this distribution in
14 * the file called "COPYING".
15 */
16
17#include <linux/smp.h>
18#include <linux/of_fdt.h>
19#include <linux/io.h>
20#include <linux/irqdomain.h>
21#include <asm/irq.h>
22#include <plat/ctop.h>
23#include <plat/smp.h>
24#include <plat/mtm.h>
25
26#define NPS_DEFAULT_MSID 0x34
27#define NPS_MTM_CPU_CFG 0x90
28
29static char smp_cpuinfo_buf[128] = {"Extn [EZNPS-SMP]\t: On\n"};
30
31/* Get cpu map from device tree */
32static int __init eznps_get_map(const char *name, struct cpumask *cpumask)
33{
34 unsigned long dt_root = of_get_flat_dt_root();
35 const char *buf;
36
37 buf = of_get_flat_dt_prop(dt_root, name, NULL);
38 if (!buf)
39 return 1;
40
41 cpulist_parse(buf, cpumask);
42
43 return 0;
44}
45
46/* Update board cpu maps */
47static void __init eznps_init_cpumasks(void)
48{
49 struct cpumask cpumask;
50
51 if (eznps_get_map("present-cpus", &cpumask)) {
52 pr_err("Failed to get present-cpus from dtb");
53 return;
54 }
55 init_cpu_present(&cpumask);
56
57 if (eznps_get_map("possible-cpus", &cpumask)) {
58 pr_err("Failed to get possible-cpus from dtb");
59 return;
60 }
61 init_cpu_possible(&cpumask);
62}
63
64static void eznps_init_core(unsigned int cpu)
65{
66 u32 sync_value;
67 struct nps_host_reg_aux_hw_comply hw_comply;
68 struct nps_host_reg_aux_lpc lpc;
69
70 if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
71 return;
72
73 hw_comply.value = read_aux_reg(CTOP_AUX_HW_COMPLY);
74 hw_comply.me = 1;
75 hw_comply.le = 1;
76 hw_comply.te = 1;
77 write_aux_reg(CTOP_AUX_HW_COMPLY, hw_comply.value);
78
79 /* Enable MMU clock */
80 lpc.mep = 1;
81 write_aux_reg(CTOP_AUX_LPC, lpc.value);
82
83 /* Boot CPU only */
84 if (!cpu) {
85 /* Write to general purpose register in CRG */
86 sync_value = ioread32be(REG_GEN_PURP_0);
87 sync_value |= NPS_CRG_SYNC_BIT;
88 iowrite32be(sync_value, REG_GEN_PURP_0);
89 }
90}
91
92/*
93 * Master kick starting another CPU
94 */
95static void __init eznps_smp_wakeup_cpu(int cpu, unsigned long pc)
96{
97 struct nps_host_reg_mtm_cpu_cfg cpu_cfg;
98
99 if (mtm_enable_thread(cpu) == 0)
100 return;
101
102 /* set PC, dmsid, and start CPU */
103 cpu_cfg.value = (u32)res_service;
104 cpu_cfg.dmsid = NPS_DEFAULT_MSID;
105 cpu_cfg.cs = 1;
106 iowrite32be(cpu_cfg.value, nps_mtm_reg_addr(cpu, NPS_MTM_CPU_CFG));
107}
108
109static void eznps_ipi_send(int cpu)
110{
111 struct global_id gid;
112 struct {
113 union {
114 struct {
115 u32 num:8, cluster:8, core:8, thread:8;
116 };
117 u32 value;
118 };
119 } ipi;
120
121 gid.value = cpu;
122 ipi.thread = get_thread(gid);
123 ipi.core = gid.core;
124 ipi.cluster = nps_cluster_logic_to_phys(gid.cluster);
125 ipi.num = NPS_IPI_IRQ;
126
127 __asm__ __volatile__(
128 " mov r3, %0\n"
129 " .word %1\n"
130 :
131 : "r"(ipi.value), "i"(CTOP_INST_ASRI_0_R3)
132 : "r3");
133}
134
135static void eznps_init_per_cpu(int cpu)
136{
137 smp_ipi_irq_setup(cpu, NPS_IPI_IRQ);
138
139 eznps_init_core(cpu);
140 mtm_enable_core(cpu);
141}
142
143static void eznps_ipi_clear(int irq)
144{
145 write_aux_reg(CTOP_AUX_IACK, 1 << irq);
146}
147
148struct plat_smp_ops plat_smp_ops = {
149 .info = smp_cpuinfo_buf,
150 .init_early_smp = eznps_init_cpumasks,
151 .cpu_kick = eznps_smp_wakeup_cpu,
152 .ipi_send = eznps_ipi_send,
153 .init_per_cpu = eznps_init_per_cpu,
154 .ipi_clear = eznps_ipi_clear,
155};
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 6ff327abc555..47352d25c15e 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -181,6 +181,16 @@ config CLKSRC_TI_32K
181 This option enables support for Texas Instruments 32.768 Hz clocksource 181 This option enables support for Texas Instruments 32.768 Hz clocksource
182 available on many OMAP-like platforms. 182 available on many OMAP-like platforms.
183 183
184config CLKSRC_NPS
185 bool "NPS400 clocksource driver" if COMPILE_TEST
186 depends on !PHYS_ADDR_T_64BIT
187 select CLKSRC_MMIO
188 select CLKSRC_OF if OF
189 help
190 NPS400 clocksource support.
191 Got 64 bit counter with update rate up to 1000MHz.
192 This counter is accessed via couple of 32 bit memory mapped registers.
193
184config CLKSRC_STM32 194config CLKSRC_STM32
185 bool "Clocksource for STM32 SoCs" if !ARCH_STM32 195 bool "Clocksource for STM32 SoCs" if !ARCH_STM32
186 depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST) 196 depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index b0a3c96fcd4f..473974f9590a 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o
47obj-$(CONFIG_MTK_TIMER) += mtk_timer.o 47obj-$(CONFIG_MTK_TIMER) += mtk_timer.o
48obj-$(CONFIG_CLKSRC_PISTACHIO) += time-pistachio.o 48obj-$(CONFIG_CLKSRC_PISTACHIO) += time-pistachio.o
49obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o 49obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o
50obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o
50 51
51obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o 52obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
52obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o 53obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
new file mode 100644
index 000000000000..d46108920b2c
--- /dev/null
+++ b/drivers/clocksource/timer-nps.c
@@ -0,0 +1,98 @@
1/*
2 * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33#include <linux/interrupt.h>
34#include <linux/clocksource.h>
35#include <linux/clockchips.h>
36#include <linux/clk.h>
37#include <linux/of.h>
38#include <linux/of_irq.h>
39#include <linux/cpu.h>
40#include <soc/nps/common.h>
41
42#define NPS_MSU_TICK_LOW 0xC8
43#define NPS_CLUSTER_OFFSET 8
44#define NPS_CLUSTER_NUM 16
45
46/* This array is per cluster of CPUs (Each NPS400 cluster got 256 CPUs) */
47static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
48
49static unsigned long nps_timer_rate;
50
51static cycle_t nps_clksrc_read(struct clocksource *clksrc)
52{
53 int cluster = raw_smp_processor_id() >> NPS_CLUSTER_OFFSET;
54
55 return (cycle_t)ioread32be(nps_msu_reg_low_addr[cluster]);
56}
57
58static void __init nps_setup_clocksource(struct device_node *node,
59 struct clk *clk)
60{
61 int ret, cluster;
62
63 for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++)
64 nps_msu_reg_low_addr[cluster] =
65 nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
66 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
67
68 ret = clk_prepare_enable(clk);
69 if (ret) {
70 pr_err("Couldn't enable parent clock\n");
71 return;
72 }
73
74 nps_timer_rate = clk_get_rate(clk);
75
76 ret = clocksource_mmio_init(nps_msu_reg_low_addr, "EZnps-tick",
77 nps_timer_rate, 301, 32, nps_clksrc_read);
78 if (ret) {
79 pr_err("Couldn't register clock source.\n");
80 clk_disable_unprepare(clk);
81 }
82}
83
84static void __init nps_timer_init(struct device_node *node)
85{
86 struct clk *clk;
87
88 clk = of_clk_get(node, 0);
89 if (IS_ERR(clk)) {
90 pr_err("Can't get timer clock.\n");
91 return;
92 }
93
94 nps_setup_clocksource(node, clk);
95}
96
97CLOCKSOURCE_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
98 nps_timer_init);
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 81f88ada3a61..46f10ec17d5c 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -253,3 +253,9 @@ config LS_SCFG_MSI
253 253
254config PARTITION_PERCPU 254config PARTITION_PERCPU
255 bool 255 bool
256
257config EZNPS_GIC
258 bool "NPS400 Global Interrupt Manager (GIM)"
259 select IRQ_DOMAIN
260 help
261 Support the EZchip NPS400 global interrupt controller
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index f828244b44c2..38853a187607 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -68,3 +68,4 @@ obj-$(CONFIG_IMX_GPCV2) += irq-imx-gpcv2.o
68obj-$(CONFIG_PIC32_EVIC) += irq-pic32-evic.o 68obj-$(CONFIG_PIC32_EVIC) += irq-pic32-evic.o
69obj-$(CONFIG_MVEBU_ODMI) += irq-mvebu-odmi.o 69obj-$(CONFIG_MVEBU_ODMI) += irq-mvebu-odmi.o
70obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o 70obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o
71obj-$(CONFIG_EZNPS_GIC) += irq-eznps.o
diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c
new file mode 100644
index 000000000000..efbf0e4304b7
--- /dev/null
+++ b/drivers/irqchip/irq-eznps.c
@@ -0,0 +1,165 @@
1/*
2 * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33#include <linux/interrupt.h>
34#include <linux/module.h>
35#include <linux/of.h>
36#include <linux/irq.h>
37#include <linux/irqdomain.h>
38#include <linux/irqchip.h>
39#include <soc/nps/common.h>
40
41#define NPS_NR_CPU_IRQS 8 /* number of interrupt lines of NPS400 CPU */
42#define NPS_TIMER0_IRQ 3
43
44/*
45 * NPS400 core includes an Interrupt Controller (IC) support.
46 * All cores can deactivate level irqs at first level control
47 * at cores mesh layer called MTM.
48 * For devices out side chip e.g. uart, network there is another
49 * level called Global Interrupt Manager (GIM).
50 * This second level can control level and edge interrupt.
51 *
52 * NOTE: AUX_IENABLE and CTOP_AUX_IACK are auxiliary registers
53 * with private HW copy per CPU.
54 */
55
56static void nps400_irq_mask(struct irq_data *irqd)
57{
58 unsigned int ienb;
59 unsigned int irq = irqd_to_hwirq(irqd);
60
61 ienb = read_aux_reg(AUX_IENABLE);
62 ienb &= ~(1 << irq);
63 write_aux_reg(AUX_IENABLE, ienb);
64}
65
66static void nps400_irq_unmask(struct irq_data *irqd)
67{
68 unsigned int ienb;
69 unsigned int irq = irqd_to_hwirq(irqd);
70
71 ienb = read_aux_reg(AUX_IENABLE);
72 ienb |= (1 << irq);
73 write_aux_reg(AUX_IENABLE, ienb);
74}
75
76static void nps400_irq_eoi_global(struct irq_data *irqd)
77{
78 unsigned int __maybe_unused irq = irqd_to_hwirq(irqd);
79
80 write_aux_reg(CTOP_AUX_IACK, 1 << irq);
81
82 /* Don't ack GIC before all device access attempts are done */
83 mb();
84
85 nps_ack_gic();
86}
87
88static void nps400_irq_eoi(struct irq_data *irqd)
89{
90 unsigned int __maybe_unused irq = irqd_to_hwirq(irqd);
91
92 write_aux_reg(CTOP_AUX_IACK, 1 << irq);
93}
94
95static struct irq_chip nps400_irq_chip_fasteoi = {
96 .name = "NPS400 IC Global",
97 .irq_mask = nps400_irq_mask,
98 .irq_unmask = nps400_irq_unmask,
99 .irq_eoi = nps400_irq_eoi_global,
100};
101
102static struct irq_chip nps400_irq_chip_percpu = {
103 .name = "NPS400 IC",
104 .irq_mask = nps400_irq_mask,
105 .irq_unmask = nps400_irq_unmask,
106 .irq_eoi = nps400_irq_eoi,
107};
108
109static int nps400_irq_map(struct irq_domain *d, unsigned int virq,
110 irq_hw_number_t hw)
111{
112 switch (hw) {
113 case NPS_TIMER0_IRQ:
114#ifdef CONFIG_SMP
115 case NPS_IPI_IRQ:
116#endif
117 irq_set_percpu_devid(virq);
118 irq_set_chip_and_handler(virq, &nps400_irq_chip_percpu,
119 handle_percpu_devid_irq);
120 break;
121 default:
122 irq_set_chip_and_handler(virq, &nps400_irq_chip_fasteoi,
123 handle_fasteoi_irq);
124 break;
125 }
126
127 return 0;
128}
129
130static const struct irq_domain_ops nps400_irq_ops = {
131 .xlate = irq_domain_xlate_onecell,
132 .map = nps400_irq_map,
133};
134
135static int __init nps400_of_init(struct device_node *node,
136 struct device_node *parent)
137{
138 static struct irq_domain *nps400_root_domain;
139
140 if (parent) {
141 pr_err("DeviceTree incore ic not a root irq controller\n");
142 return -EINVAL;
143 }
144
145 nps400_root_domain = irq_domain_add_linear(node, NPS_NR_CPU_IRQS,
146 &nps400_irq_ops, NULL);
147
148 if (!nps400_root_domain) {
149 pr_err("nps400 root irq domain not avail\n");
150 return -ENOMEM;
151 }
152
153 /*
154 * Needed for primary domain lookup to succeed
155 * This is a primary irqchip, and can never have a parent
156 */
157 irq_set_default_host(nps400_root_domain);
158
159#ifdef CONFIG_SMP
160 irq_create_mapping(nps400_root_domain, NPS_IPI_IRQ);
161#endif
162
163 return 0;
164}
165IRQCHIP_DECLARE(ezchip_nps400_ic, "ezchip,nps400-ic", nps400_of_init);
diff --git a/include/soc/nps/common.h b/include/soc/nps/common.h
new file mode 100644
index 000000000000..9b1d43d671a3
--- /dev/null
+++ b/include/soc/nps/common.h
@@ -0,0 +1,166 @@
1/*
2 * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33#ifndef SOC_NPS_COMMON_H
34#define SOC_NPS_COMMON_H
35
36#ifdef CONFIG_SMP
37#define NPS_IPI_IRQ 5
38#endif
39
40#define NPS_HOST_REG_BASE 0xF6000000
41
42#define NPS_MSU_BLKID 0x018
43
44#define CTOP_INST_RSPI_GIC_0_R12 0x3C56117E
45#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST 0x5B60
46#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM 0x00010422
47
48#ifndef __ASSEMBLY__
49
50/* In order to increase compilation test coverage */
51#ifdef CONFIG_ARC
52static inline void nps_ack_gic(void)
53{
54 __asm__ __volatile__ (
55 " .word %0\n"
56 :
57 : "i"(CTOP_INST_RSPI_GIC_0_R12)
58 : "memory");
59}
60#else
61static inline void nps_ack_gic(void) { }
62#define write_aux_reg(r, v)
63#define read_aux_reg(r) 0
64#endif
65
66/* CPU global ID */
67struct global_id {
68 union {
69 struct {
70#ifdef CONFIG_EZNPS_MTM_EXT
71 u32 __reserved:20, cluster:4, core:4, thread:4;
72#else
73 u32 __reserved:24, cluster:4, core:4;
74#endif
75 };
76 u32 value;
77 };
78};
79
80/*
81 * Convert logical to physical CPU IDs
82 *
83 * The conversion swap bits 1 and 2 of cluster id (out of 4 bits)
84 * Now quad of logical clusters id's are adjacent physically,
85 * and not like the id's physically came with each cluster.
86 * Below table is 4x4 mesh of core clusters as it layout on chip.
87 * Cluster ids are in format: logical (physical)
88 *
89 * ----------------- ------------------
90 * 3 | 5 (3) 7 (7) | | 13 (11) 15 (15)|
91 *
92 * 2 | 4 (2) 6 (6) | | 12 (10) 14 (14)|
93 * ----------------- ------------------
94 * 1 | 1 (1) 3 (5) | | 9 (9) 11 (13)|
95 *
96 * 0 | 0 (0) 2 (4) | | 8 (8) 10 (12)|
97 * ----------------- ------------------
98 * 0 1 2 3
99 */
100static inline int nps_cluster_logic_to_phys(int cluster)
101{
102#ifdef __arc__
103 __asm__ __volatile__(
104 " mov r3,%0\n"
105 " .short %1\n"
106 " .word %2\n"
107 " mov %0,r3\n"
108 : "+r"(cluster)
109 : "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST),
110 "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM)
111 : "r3");
112#endif
113
114 return cluster;
115}
116
117#define NPS_CPU_TO_CLUSTER_NUM(cpu) \
118 ({ struct global_id gid; gid.value = cpu; \
119 nps_cluster_logic_to_phys(gid.cluster); })
120
121struct nps_host_reg_address {
122 union {
123 struct {
124 u32 base:8, cl_x:4, cl_y:4,
125 blkid:6, reg:8, __reserved:2;
126 };
127 u32 value;
128 };
129};
130
131struct nps_host_reg_address_non_cl {
132 union {
133 struct {
134 u32 base:7, blkid:11, reg:12, __reserved:2;
135 };
136 u32 value;
137 };
138};
139
140static inline void *nps_host_reg_non_cl(u32 blkid, u32 reg)
141{
142 struct nps_host_reg_address_non_cl reg_address;
143
144 reg_address.value = NPS_HOST_REG_BASE;
145 reg_address.blkid = blkid;
146 reg_address.reg = reg;
147
148 return (void *)reg_address.value;
149}
150
151static inline void *nps_host_reg(u32 cpu, u32 blkid, u32 reg)
152{
153 struct nps_host_reg_address reg_address;
154 u32 cl = NPS_CPU_TO_CLUSTER_NUM(cpu);
155
156 reg_address.value = NPS_HOST_REG_BASE;
157 reg_address.cl_x = (cl >> 2) & 0x3;
158 reg_address.cl_y = cl & 0x3;
159 reg_address.blkid = blkid;
160 reg_address.reg = reg;
161
162 return (void *)reg_address.value;
163}
164#endif /* __ASSEMBLY__ */
165
166#endif /* SOC_NPS_COMMON_H */