diff options
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 @@ | |||
1 | EZchip NPS Network Processor Platforms Device Tree Bindings | ||
2 | --------------------------------------------------------------------------- | ||
3 | |||
4 | Appliance main board with NPS400 ASIC. | ||
5 | |||
6 | Required 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 @@ | |||
1 | EZchip NPS Interrupt Controller | ||
2 | |||
3 | Required 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 | |||
11 | Example: | ||
12 | |||
13 | intc: 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 @@ | |||
1 | NPS Network Processor | ||
2 | |||
3 | Required properties: | ||
4 | |||
5 | - compatible : should be "ezchip,nps400-timer" | ||
6 | |||
7 | Clocks required for compatible = "ezchip,nps400-timer": | ||
8 | - clocks : Must contain a single entry describing the clock input | ||
9 | |||
10 | Example: | ||
11 | |||
12 | timer { | ||
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 @@ | |||
1 | Synopsys 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 | |||
8 | Required 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 | |||
15 | Optional properties: | ||
16 | |||
17 | - interrupt-parent : phandle to parent intc | ||
18 | |||
19 | Example: | ||
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 @@ | |||
1 | Synopsys ARC Free Running 64-bit Global Timer for ARC HS CPUs | ||
2 | - clocksource provider for SMP SoC | ||
3 | |||
4 | Required properties: | ||
5 | |||
6 | - compatible : should be "snps,archs-gfrc" | ||
7 | - clocks : phandle to the source clock | ||
8 | |||
9 | Example: | ||
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 @@ | |||
1 | Synopsys ARC Free Running 64-bit Local Timer for ARC HS CPUs | ||
2 | - clocksource provider for UP SoC | ||
3 | |||
4 | Required properties: | ||
5 | |||
6 | - compatible : should be "snps,archs-rtc" | ||
7 | - clocks : phandle to the source clock | ||
8 | |||
9 | Example: | ||
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 | |||
88 | everest Everest Semiconductor Co. Ltd. | 88 | everest Everest Semiconductor Co. Ltd. |
89 | everspin Everspin Technologies, Inc. | 89 | everspin Everspin Technologies, Inc. |
90 | excito Excito | 90 | excito Excito |
91 | ezchip EZchip Semiconductor | ||
91 | fcs Fairchild Semiconductor | 92 | fcs Fairchild Semiconductor |
92 | firefly Firefly | 93 | firefly Firefly |
93 | focaltech FocalTech Systems Co.,Ltd | 94 | focaltech FocalTech Systems Co.,Ltd |
diff --git a/MAINTAINERS b/MAINTAINERS index 71bcef4a161c..3f14e1dffa6a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -4444,6 +4444,12 @@ S: Maintained | |||
4444 | F: drivers/video/fbdev/exynos/exynos_mipi* | 4444 | F: drivers/video/fbdev/exynos/exynos_mipi* |
4445 | F: include/video/exynos_mipi* | 4445 | F: include/video/exynos_mipi* |
4446 | 4446 | ||
4447 | EZchip NPS platform support | ||
4448 | M: Noam Camus <noamc@ezchip.com> | ||
4449 | S: Supported | ||
4450 | F: arch/arc/plat-eznps | ||
4451 | F: arch/arc/boot/dts/eznps.dts | ||
4452 | |||
4447 | F71805F HARDWARE MONITORING DRIVER | 4453 | F71805F HARDWARE MONITORING DRIVER |
4448 | M: Jean Delvare <jdelvare@suse.com> | 4454 | M: Jean Delvare <jdelvare@suse.com> |
4449 | L: linux-hwmon@vger.kernel.org | 4455 | L: 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" | |||
95 | source "arch/arc/plat-tb10x/Kconfig" | 97 | source "arch/arc/plat-tb10x/Kconfig" |
96 | source "arch/arc/plat-axs10x/Kconfig" | 98 | source "arch/arc/plat-axs10x/Kconfig" |
97 | #New platform adds here | 99 | #New platform adds here |
100 | source "arch/arc/plat-eznps/Kconfig" | ||
98 | 101 | ||
99 | endmenu | 102 | endmenu |
100 | 103 | ||
@@ -490,6 +493,17 @@ config ARCH_DMA_ADDR_T_64BIT | |||
490 | config ARC_PLAT_NEEDS_PHYS_TO_DMA | 493 | config ARC_PLAT_NEEDS_PHYS_TO_DMA |
491 | bool | 494 | bool |
492 | 495 | ||
496 | config 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 | |||
493 | config ARC_CURR_IN_REG | 507 | config 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/ | |||
115 | core-$(CONFIG_ARC_PLAT_SIM) += arch/arc/plat-sim/ | 115 | core-$(CONFIG_ARC_PLAT_SIM) += arch/arc/plat-sim/ |
116 | core-$(CONFIG_ARC_PLAT_TB10X) += arch/arc/plat-tb10x/ | 116 | core-$(CONFIG_ARC_PLAT_TB10X) += arch/arc/plat-tb10x/ |
117 | core-$(CONFIG_ARC_PLAT_AXS10X) += arch/arc/plat-axs10x/ | 117 | core-$(CONFIG_ARC_PLAT_AXS10X) += arch/arc/plat-axs10x/ |
118 | core-$(CONFIG_ARC_PLAT_EZNPS) += arch/arc/plat-eznps/ | ||
119 | |||
120 | ifdef CONFIG_ARC_PLAT_EZNPS | ||
121 | KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-eznps/include | ||
122 | endif | ||
118 | 123 | ||
119 | drivers-$(CONFIG_OPROFILE) += arch/arc/oprofile/ | 124 | drivers-$(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 | ||
3 | CONFIG_SYSVIPC=y | ||
4 | CONFIG_NO_HZ_IDLE=y | ||
5 | CONFIG_HIGH_RES_TIMERS=y | ||
6 | CONFIG_IKCONFIG=y | ||
7 | CONFIG_IKCONFIG_PROC=y | ||
8 | CONFIG_BLK_DEV_INITRD=y | ||
9 | CONFIG_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 | ||
15 | CONFIG_EMBEDDED=y | ||
16 | CONFIG_PERF_EVENTS=y | ||
17 | # CONFIG_COMPAT_BRK is not set | ||
18 | CONFIG_KPROBES=y | ||
19 | CONFIG_MODULES=y | ||
20 | CONFIG_MODULE_FORCE_LOAD=y | ||
21 | CONFIG_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 | ||
25 | CONFIG_ARC_PLAT_EZNPS=y | ||
26 | CONFIG_SMP=y | ||
27 | CONFIG_NR_CPUS=4096 | ||
28 | CONFIG_ARC_CACHE_LINE_SHIFT=5 | ||
29 | # CONFIG_ARC_CACHE_PAGES is not set | ||
30 | # CONFIG_ARC_HAS_LLSC is not set | ||
31 | CONFIG_ARC_KVADDR_SIZE=402 | ||
32 | CONFIG_ARC_EMUL_UNALIGNED=y | ||
33 | CONFIG_ARC_UBOOT_SUPPORT=y | ||
34 | CONFIG_PREEMPT=y | ||
35 | CONFIG_NET=y | ||
36 | CONFIG_UNIX=y | ||
37 | CONFIG_INET=y | ||
38 | CONFIG_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 | ||
46 | CONFIG_DEVTMPFS=y | ||
47 | CONFIG_DEVTMPFS_MOUNT=y | ||
48 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set | ||
49 | CONFIG_BLK_DEV_RAM=y | ||
50 | CONFIG_BLK_DEV_RAM_COUNT=1 | ||
51 | CONFIG_BLK_DEV_RAM_SIZE=2048 | ||
52 | CONFIG_NETDEVICES=y | ||
53 | CONFIG_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 | ||
64 | CONFIG_SERIAL_8250=y | ||
65 | CONFIG_SERIAL_8250_CONSOLE=y | ||
66 | CONFIG_SERIAL_8250_NR_UARTS=1 | ||
67 | CONFIG_SERIAL_8250_RUNTIME_UARTS=1 | ||
68 | CONFIG_SERIAL_8250_DW=y | ||
69 | CONFIG_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 | ||
74 | CONFIG_PROC_KCORE=y | ||
75 | CONFIG_TMPFS=y | ||
76 | # CONFIG_MISC_FILESYSTEMS is not set | ||
77 | CONFIG_NFS_FS=y | ||
78 | CONFIG_ROOT_NFS=y | ||
79 | CONFIG_DEBUG_INFO=y | ||
80 | # CONFIG_ENABLE_WARN_DEPRECATED is not set | ||
81 | # CONFIG_ENABLE_MUST_CHECK is not set | ||
82 | CONFIG_MAGIC_SYSRQ=y | ||
83 | CONFIG_DEBUG_MEMORY_INIT=y | ||
84 | CONFIG_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) | |||
180 | ATOMIC_OP(or, |=, or) | 182 | ATOMIC_OP(or, |=, or) |
181 | ATOMIC_OP(xor, ^=, xor) | 183 | ATOMIC_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 | |||
191 | static 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 | |||
203 | static 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) \ | ||
213 | static 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) \ | ||
225 | static 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 | |||
252 | ATOMIC_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 | |||
256 | ATOMIC_OP(and, &=, CTOP_INST_AAND_DI_R2_R2_R3) | ||
257 | #define atomic_andnot(mask, v) atomic_and(~(mask), (v)) | ||
258 | ATOMIC_OP(or, |=, CTOP_INST_AOR_DI_R2_R2_R3) | ||
259 | ATOMIC_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) \ | ||
145 | static 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) \ | ||
163 | static 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 | ||
184 | BIT_OPS(set, |, bset) | 233 | BIT_OPS(set, |, bset) |
185 | BIT_OPS(clear, & ~, bclr) | 234 | BIT_OPS(clear, & ~, bclr) |
186 | BIT_OPS(change, ^, bxor) | 235 | BIT_OPS(change, ^, bxor) |
236 | #else | ||
237 | BIT_OPS(set, |, CTOP_INST_AOR_DI_R2_R2_R3) | ||
238 | BIT_OPS(clear, & ~, CTOP_INST_AAND_DI_R2_R2_R3) | ||
239 | BIT_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 */ | ||
13 | extern unsigned long core_freq; | ||
14 | |||
15 | static inline unsigned long arc_get_core_freq(void) | ||
16 | { | ||
17 | return core_freq; | ||
18 | } | ||
19 | |||
20 | extern 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 | ||
49 | static inline unsigned long | 49 | static 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 | |||
69 | static 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 | |||
173 | static 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 | ||
27 | extern void arc_init_IRQ(void); | 24 | extern void arc_init_IRQ(void); |
28 | void arc_local_timer_setup(void); | ||
29 | void 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 | */ |
33 | typedef struct { | 33 | typedef 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; |
36 | typedef struct { | 40 | typedef 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) | |||
610 | static inline int arch_read_trylock(arch_rwlock_t *rw) | 610 | static 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) | |||
632 | static inline int arch_write_trylock(arch_rwlock_t *rw) | 635 | static 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 | ||
665 | static inline void arch_read_unlock(arch_rwlock_t *rw) | 671 | static 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 | ||
672 | static inline void arch_write_unlock(arch_rwlock_t *rw) | 682 | static 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 @@ | |||
9 | CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' | 9 | CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' |
10 | 10 | ||
11 | obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o | 11 | obj-y := arcksyms.o setup.o irq.o time.o reset.o ptrace.o process.o devtree.o |
12 | obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o clk.o | 12 | obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o |
13 | obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o | 13 | obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o |
14 | obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o | 14 | obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o |
15 | obj-$(CONFIG_PCI) += pcibios.o | 15 | obj-$(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 | |||
11 | unsigned 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 | */ | ||
17 | int 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 | ||
29 | static void __init arc_set_early_base_baud(unsigned long dt_root) | 28 | static 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 | ||
140 | static struct irq_domain *root_domain; | ||
141 | 140 | ||
142 | static int __init | 141 | static int __init |
143 | init_onchip_IRQ(struct device_node *intc, struct device_node *parent) | 142 | init_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 = { | |||
79 | static int arc_intc_domain_map(struct irq_domain *d, unsigned int irq, | 81 | static 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 | ||
97 | static struct irq_domain *root_domain; | ||
98 | |||
99 | static int __init | 100 | static int __init |
100 | init_onchip_IRQ(struct device_node *intc, struct device_node *parent) | 101 | init_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 | */ |
44 | void arch_do_IRQ(unsigned int irq, struct pt_regs *regs) | 44 | void 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 | |||
66 | void 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 | |||
21 | static char smp_cpuinfo_buf[128]; | 18 | static char smp_cpuinfo_buf[128]; |
22 | static int idu_detected; | 19 | static 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 | ||
130 | struct plat_smp_ops plat_smp_ops = { | 125 | struct 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 | ||
445 | static int __init customize_machine(void) | 436 | static 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 | */ |
350 | static DEFINE_PER_CPU(int, ipi_dev); | 352 | static 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 *********/ | 58 | static unsigned long arc_timer_freq; |
64 | |||
65 | #ifdef CONFIG_ARC_HAS_GFRC | ||
66 | 59 | ||
67 | static int arc_counter_setup(void) | 60 | static 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 | ||
72 | static cycle_t arc_counter_read(struct clocksource *cs) | 82 | /********** Clock Source Device *********/ |
83 | |||
84 | #ifdef CONFIG_ARC_HAS_GFRC | ||
85 | |||
86 | static 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 | ||
97 | static struct clocksource arc_counter = { | 111 | static 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 | 119 | static 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 | } | ||
133 | CLOCKSOURCE_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 | ||
113 | int arc_counter_setup(void) | 143 | static 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 | |||
121 | static 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 | ||
145 | static struct clocksource arc_counter = { | 167 | static 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 */ | 175 | static void __init arc_cs_setup_rtc(struct device_node *node) |
154 | |||
155 | /* | ||
156 | * set 32bit TIMER1 to keep counting monotonically and wraparound | ||
157 | */ | ||
158 | int 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 | } |
195 | CLOCKSOURCE_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc); | ||
167 | 196 | ||
168 | static cycle_t arc_counter_read(struct clocksource *cs) | 197 | #endif |
198 | |||
199 | /* | ||
200 | * 32bit TIMER1 to keep counting monotonically and wraparound | ||
201 | */ | ||
202 | |||
203 | static 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 | ||
173 | static struct clocksource arc_counter = { | 208 | static 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 | 216 | static 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 | ||
237 | static 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 | ||
299 | static 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 | |||
320 | static 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 | */ |
250 | void arc_local_timer_setup() | 327 | static 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 | ||
356 | static 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 | } | ||
367 | CLOCKSOURCE_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 | */ |
273 | void __init time_init(void) | 372 | void __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 | ||
390 | static void __init axs103_early_init(void) | 391 | static 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 | |||
6 | menuconfig 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 | |||
21 | config 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 | |||
5 | obj-y := entry.o platform.o | ||
6 | obj-$(CONFIG_SMP) += smp.o | ||
7 | obj-$(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 | |||
29 | ENTRY(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 | ||
70 | END(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 */ | ||
80 | struct 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 | |||
90 | struct 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 | |||
99 | struct 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 | |||
108 | struct 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 | |||
117 | struct 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 | |||
133 | struct 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 */ | ||
146 | struct 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 | |||
156 | struct 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 | |||
167 | struct 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 | |||
176 | struct 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 | |||
22 | static 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 | |||
47 | void mtm_enable_core(unsigned int cpu); | ||
48 | int 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 | |||
22 | extern 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 | |||
28 | static 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 | |||
49 | static 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 | |||
81 | int 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 | |||
96 | void 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 | |||
22 | static 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 | |||
38 | static 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 | |||
88 | static void __init eznps_early_init(void) | ||
89 | { | ||
90 | eznps_configure_msu(); | ||
91 | eznps_configure_gim(); | ||
92 | } | ||
93 | |||
94 | static const char *eznps_compat[] __initconst = { | ||
95 | "ezchip,arc-nps", | ||
96 | NULL, | ||
97 | }; | ||
98 | |||
99 | MACHINE_START(NPS, "nps") | ||
100 | .dt_compat = eznps_compat, | ||
101 | .init_early = eznps_early_init, | ||
102 | MACHINE_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 | |||
29 | static char smp_cpuinfo_buf[128] = {"Extn [EZNPS-SMP]\t: On\n"}; | ||
30 | |||
31 | /* Get cpu map from device tree */ | ||
32 | static 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 */ | ||
47 | static 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 | |||
64 | static 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 | */ | ||
95 | static 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 | |||
109 | static 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 | |||
135 | static 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 | |||
143 | static void eznps_ipi_clear(int irq) | ||
144 | { | ||
145 | write_aux_reg(CTOP_AUX_IACK, 1 << irq); | ||
146 | } | ||
147 | |||
148 | struct 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 | ||
184 | config 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 | |||
184 | config CLKSRC_STM32 | 194 | config 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 | |||
47 | obj-$(CONFIG_MTK_TIMER) += mtk_timer.o | 47 | obj-$(CONFIG_MTK_TIMER) += mtk_timer.o |
48 | obj-$(CONFIG_CLKSRC_PISTACHIO) += time-pistachio.o | 48 | obj-$(CONFIG_CLKSRC_PISTACHIO) += time-pistachio.o |
49 | obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o | 49 | obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o |
50 | obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o | ||
50 | 51 | ||
51 | obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o | 52 | obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o |
52 | obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o | 53 | obj-$(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) */ | ||
47 | static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly; | ||
48 | |||
49 | static unsigned long nps_timer_rate; | ||
50 | |||
51 | static 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 | |||
58 | static 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 | |||
84 | static 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 | |||
97 | CLOCKSOURCE_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 | ||
254 | config PARTITION_PERCPU | 254 | config PARTITION_PERCPU |
255 | bool | 255 | bool |
256 | |||
257 | config 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 | |||
68 | obj-$(CONFIG_PIC32_EVIC) += irq-pic32-evic.o | 68 | obj-$(CONFIG_PIC32_EVIC) += irq-pic32-evic.o |
69 | obj-$(CONFIG_MVEBU_ODMI) += irq-mvebu-odmi.o | 69 | obj-$(CONFIG_MVEBU_ODMI) += irq-mvebu-odmi.o |
70 | obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o | 70 | obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o |
71 | obj-$(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 | |||
56 | static 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 | |||
66 | static 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 | |||
76 | static 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 | |||
88 | static 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 | |||
95 | static 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 | |||
102 | static 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 | |||
109 | static 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 | |||
130 | static const struct irq_domain_ops nps400_irq_ops = { | ||
131 | .xlate = irq_domain_xlate_onecell, | ||
132 | .map = nps400_irq_map, | ||
133 | }; | ||
134 | |||
135 | static 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 | } | ||
165 | IRQCHIP_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 | ||
52 | static 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 | ||
61 | static 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 */ | ||
67 | struct 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 | */ | ||
100 | static 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 | |||
121 | struct 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 | |||
131 | struct 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 | |||
140 | static 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 | |||
151 | static 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 */ | ||