Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'arc-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc

Pull ARC updates from Vineet Gupta:
"We have a relatively big changeset for ARC for 4.7.

The highlight is support for EZChip (now Mellanox) NPS-400 network
processor, a 400-Gb throughput C-programmable packet processor based
on ARC700 cores from Synopsys. See

http://www.mellanox.com/related-docs/prod_npu/PB_NPS-400.pdf

Also present are irqchip and clocksource drivers for NPS as agreed
with respective maintainers to go via ARC tree due to an soc header
dependency. I have the needed ACKs from Jason, Marc, Daniel. You
might run into a trivial merge conflict in drivers/irqchip/*

This EZChip platform support required some deep changes in ARC
architecture code and also opportunity to cleanup past sins (legacy
irq domains, missing irq domain lookup, hard coded timer irqs...)

Summary:

- Support for EZChip (now Mellanox) NPS-400 Network processor based
on ARC700

- NPS interrupt controller and clocksource drivers

- ARC timers probed off DT

- ARC iqrchips switching to linear domain (upgrade from legacy
domains)"

* tag 'arc-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: (37 commits)
arc: axs103_smp: Fix CPU frequency to 100MHz for dual-core
arc: axs10x: Add DT bindings for I2S PLL Clock
ARC: pae: STRICT_MM_TYPECHECKS was broken
ARC: Add eznps platform to Kconfig and Makefile
ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
ARC: [plat-eznps] Use dedicated cpu_relax()
ARC: [plat-eznps] Use dedicated identity auxiliary register.
ARC: [plat-eznps] Use dedicated SMP barriers
ARC: [plat-eznps] Use dedicated atomic/bitops/cmpxchg
ARC: [plat-eznps] Use dedicated user stack top
ARC: [plat-eznps] Add eznps platform
ARC: [plat-eznps] Add eznps board defconfig and dts
ARC: Mark secondary cpu online only after all HW setup is done
ARC: rwlock: disable interrupts in !LLSC variant
ARC: Make vmalloc size configurable
ARC: clean out UAPI byteorder.h clean off Kconfig symbol
irqchip: add nps Internal and external irqchips
clocksource: Add NPS400 timers driver
soc: Support for EZchip SoC
Documentation: Add EZchip vendor to binding list
...

+2336 -286
+7
Documentation/devicetree/bindings/arc/eznps.txt
··· 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";
+17
Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
··· 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 + };
+15
Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
··· 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 + };
+31
Documentation/devicetree/bindings/timer/snps,arc-timer.txt
··· 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 + };
+14
Documentation/devicetree/bindings/timer/snps,archs-gfrc.txt
··· 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 + };
+14
Documentation/devicetree/bindings/timer/snps,archs-rtc.txt
··· 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 + };
+1
Documentation/devicetree/bindings/vendor-prefixes.txt
··· 88 88 everest Everest Semiconductor Co. Ltd. 89 89 everspin Everspin Technologies, Inc. 90 90 excito Excito 91 + ezchip EZchip Semiconductor 91 92 fcs Fairchild Semiconductor 92 93 firefly Firefly 93 94 focaltech FocalTech Systems Co.,Ltd
+6
MAINTAINERS
··· 4444 4444 F: drivers/video/fbdev/exynos/exynos_mipi* 4445 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 4453 F71805F HARDWARE MONITORING DRIVER 4448 4454 M: Jean Delvare <jdelvare@suse.com> 4449 4455 L: linux-hwmon@vger.kernel.org
+15 -1
arch/arc/Kconfig
··· 10 10 def_bool y 11 11 select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC 12 12 select BUILDTIME_EXTABLE_SORT 13 - select COMMON_CLK 13 + select CLKSRC_OF 14 14 select CLONE_BACKWARDS 15 + select COMMON_CLK 15 16 select GENERIC_ATOMIC64 16 17 select GENERIC_CLOCKEVENTS 17 18 select GENERIC_FIND_FIRST_BIT ··· 31 30 select HAVE_MOD_ARCH_SPECIFIC if ARC_DW2_UNWIND 32 31 select HAVE_OPROFILE 33 32 select HAVE_PERF_EVENTS 33 + select HANDLE_DOMAIN_IRQ 34 34 select IRQ_DOMAIN 35 35 select MODULES_USE_ELF_RELA 36 36 select NO_BOOTMEM ··· 97 95 source "arch/arc/plat-tb10x/Kconfig" 98 96 source "arch/arc/plat-axs10x/Kconfig" 99 97 #New platform adds here 98 + source "arch/arc/plat-eznps/Kconfig" 100 99 101 100 endmenu 102 101 ··· 492 489 493 490 config ARC_PLAT_NEEDS_PHYS_TO_DMA 494 491 bool 492 + 493 + config ARC_KVADDR_SIZE 494 + int "Kernel Virtaul Address Space size (MB)" 495 + range 0 512 496 + default "256" 497 + help 498 + The kernel address space is carved out of 256MB of translated address 499 + space for catering to vmalloc, modules, pkmap, fixmap. This however may 500 + not suffice vmalloc requirements of a 4K CPU EZChip system. So allow 501 + this to be stretched to 512 MB (by extending into the reserved 502 + kernel-user gutter) 495 503 496 504 config ARC_CURR_IN_REG 497 505 bool "Dedicate Register r25 for current_task pointer"
+5
arch/arc/Makefile
··· 115 115 core-$(CONFIG_ARC_PLAT_SIM) += arch/arc/plat-sim/ 116 116 core-$(CONFIG_ARC_PLAT_TB10X) += arch/arc/plat-tb10x/ 117 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 124 drivers-$(CONFIG_OPROFILE) += arch/arc/oprofile/ 120 125
+14
arch/arc/boot/dts/abilis_tb10x.dtsi
··· 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 52 soc100 { 39 53 #address-cells = <1>; 40 54 #size-cells = <1>;
+11 -3
arch/arc/boot/dts/axc001.dtsi
··· 11 11 * Note that this file only supports the 770D CPU 12 12 */ 13 13 14 + /include/ "skeleton.dtsi" 15 + 14 16 / { 15 17 compatible = "snps,arc"; 16 18 clock-frequency = <750000000>; /* 750 MHZ */ ··· 26 24 27 25 ranges = <0x00000000 0xf0000000 0x10000000>; 28 26 29 - cpu_intc: arc700-intc@cpu { 27 + core_clk: core_clk { 28 + #clock-cells = <0>; 29 + compatible = "fixed-clock"; 30 + clock-frequency = <750000000>; 31 + }; 32 + 33 + core_intc: arc700-intc@cpu { 30 34 compatible = "snps,arc700-intc"; 31 35 interrupt-controller; 32 36 #interrupt-cells = <1>; ··· 56 48 reg = <0>; 57 49 interrupt-controller; 58 50 #interrupt-cells = <2>; 59 - interrupt-parent = <&cpu_intc>; 51 + interrupt-parent = <&core_intc>; 60 52 interrupts = <15>; 61 53 }; 62 54 }; ··· 94 86 compatible = "snps,dw-apb-ictl"; 95 87 reg = < 0xe0012000 0x200 >; 96 88 interrupt-controller; 97 - interrupt-parent = <&cpu_intc>; 89 + interrupt-parent = <&core_intc>; 98 90 interrupts = < 7 >; 99 91 }; 100 92
+12 -4
arch/arc/boot/dts/axc003.dtsi
··· 10 10 * Device tree for AXC003 CPU card: HS38x UP configuration 11 11 */ 12 12 13 + /include/ "skeleton_hs.dtsi" 14 + 13 15 / { 14 16 compatible = "snps,arc"; 15 17 clock-frequency = <90000000>; ··· 25 23 26 24 ranges = <0x00000000 0xf0000000 0x10000000>; 27 25 28 - cpu_intc: archs-intc@cpu { 26 + core_clk: core_clk { 27 + #clock-cells = <0>; 28 + compatible = "fixed-clock"; 29 + clock-frequency = <90000000>; 30 + }; 31 + 32 + core_intc: archs-intc@cpu { 29 33 compatible = "snps,archs-intc"; 30 34 interrupt-controller; 31 35 #interrupt-cells = <1>; ··· 55 47 reg = <0>; 56 48 interrupt-controller; 57 49 #interrupt-cells = <2>; 58 - interrupt-parent = <&cpu_intc>; 50 + interrupt-parent = <&core_intc>; 59 51 interrupts = <25>; 60 52 }; 61 53 }; ··· 74 66 arcpct0: pct { 75 67 compatible = "snps,archs-pct"; 76 68 #interrupt-cells = <1>; 77 - interrupt-parent = <&cpu_intc>; 69 + interrupt-parent = <&core_intc>; 78 70 interrupts = <20>; 79 71 }; 80 72 }; ··· 97 89 compatible = "snps,dw-apb-ictl"; 98 90 reg = < 0xe0012000 0x200 >; 99 91 interrupt-controller; 100 - interrupt-parent = <&cpu_intc>; 92 + interrupt-parent = <&core_intc>; 101 93 interrupts = < 24 >; 102 94 }; 103 95
+11 -3
arch/arc/boot/dts/axc003_idu.dtsi
··· 10 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 16 compatible = "snps,arc"; 15 17 clock-frequency = <90000000>; ··· 25 23 26 24 ranges = <0x00000000 0xf0000000 0x10000000>; 27 25 28 - cpu_intc: archs-intc@cpu { 26 + core_clk: core_clk { 27 + #clock-cells = <0>; 28 + compatible = "fixed-clock"; 29 + clock-frequency = <100000000>; 30 + }; 31 + 32 + core_intc: archs-intc@cpu { 29 33 compatible = "snps,archs-intc"; 30 34 interrupt-controller; 31 35 #interrupt-cells = <1>; ··· 40 32 idu_intc: idu-interrupt-controller { 41 33 compatible = "snps,archs-idu-intc"; 42 34 interrupt-controller; 43 - interrupt-parent = <&cpu_intc>; 35 + interrupt-parent = <&core_intc>; 44 36 45 37 /* 46 38 * <hwirq distribution> ··· 97 89 arcpct0: pct { 98 90 compatible = "snps,archs-pct"; 99 91 #interrupt-cells = <1>; 100 - interrupt-parent = <&cpu_intc>; 92 + interrupt-parent = <&core_intc>; 101 93 interrupts = <20>; 102 94 }; 103 95 };
+13
arch/arc/boot/dts/axs10x_mb.dtsi
··· 16 16 ranges = <0x00000000 0xe0000000 0x10000000>; 17 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 26 clocks { 27 + i2spll_clk: i2spll_clk { 28 + compatible = "fixed-clock"; 29 + clock-frequency = <27000000>; 30 + #clock-cells = <0>; 31 + }; 32 + 20 33 i2cclk: i2cclk { 21 34 compatible = "fixed-clock"; 22 35 clock-frequency = <50000000>;
+96
arch/arc/boot/dts/eznps.dts
··· 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 + };
+8 -2
arch/arc/boot/dts/nsim_700.dts
··· 14 14 clock-frequency = <80000000>; /* 80 MHZ */ 15 15 #address-cells = <1>; 16 16 #size-cells = <1>; 17 - interrupt-parent = <&intc>; 17 + interrupt-parent = <&core_intc>; 18 18 19 19 chosen { 20 20 bootargs = "earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8"; ··· 32 32 /* child and parent address space 1:1 mapped */ 33 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 42 compatible = "snps,arc700-intc"; 37 43 interrupt-controller; 38 44 #interrupt-cells = <1>;
+7 -1
arch/arc/boot/dts/nsim_hs.dts
··· 7 7 */ 8 8 /dts-v1/; 9 9 10 - /include/ "skeleton.dtsi" 10 + /include/ "skeleton_hs.dtsi" 11 11 12 12 / { 13 13 compatible = "snps,nsim_hs"; ··· 38 38 /* only perip space at end of low mem accessible 39 39 bus addr, parent bus addr, size */ 40 40 ranges = <0x80000000 0x0 0x80000000 0x80000000>; 41 + 42 + core_clk: core_clk { 43 + #clock-cells = <0>; 44 + compatible = "fixed-clock"; 45 + clock-frequency = <80000000>; 46 + }; 41 47 42 48 core_intc: core-interrupt-controller { 43 49 compatible = "snps,archs-intc";
+7 -1
arch/arc/boot/dts/nsim_hs_idu.dts
··· 7 7 */ 8 8 /dts-v1/; 9 9 10 - /include/ "skeleton.dtsi" 10 + /include/ "skeleton_hs_idu.dtsi" 11 11 12 12 / { 13 13 compatible = "snps,nsim_hs"; ··· 28 28 29 29 /* child and parent address space 1:1 mapped */ 30 30 ranges; 31 + 32 + core_clk: core_clk { 33 + #clock-cells = <0>; 34 + compatible = "fixed-clock"; 35 + clock-frequency = <80000000>; 36 + }; 31 37 32 38 core_intc: core-interrupt-controller { 33 39 compatible = "snps,archs-intc";
+8 -2
arch/arc/boot/dts/nsimosci.dts
··· 14 14 clock-frequency = <20000000>; /* 20 MHZ */ 15 15 #address-cells = <1>; 16 16 #size-cells = <1>; 17 - interrupt-parent = <&intc>; 17 + interrupt-parent = <&core_intc>; 18 18 19 19 chosen { 20 20 /* this is for console on PGU */ ··· 35 35 /* child and parent address space 1:1 mapped */ 36 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 45 compatible = "snps,arc700-intc"; 40 46 interrupt-controller; 41 47 #interrupt-cells = <1>;
+7 -1
arch/arc/boot/dts/nsimosci_hs.dts
··· 7 7 */ 8 8 /dts-v1/; 9 9 10 - /include/ "skeleton.dtsi" 10 + /include/ "skeleton_hs.dtsi" 11 11 12 12 / { 13 13 compatible = "snps,nsimosci_hs"; ··· 34 34 35 35 /* child and parent address space 1:1 mapped */ 36 36 ranges; 37 + 38 + core_clk: core_clk { 39 + #clock-cells = <0>; 40 + compatible = "fixed-clock"; 41 + clock-frequency = <20000000>; 42 + }; 37 43 38 44 core_intc: core-interrupt-controller { 39 45 compatible = "snps,archs-intc";
+7 -1
arch/arc/boot/dts/nsimosci_hs_idu.dts
··· 7 7 */ 8 8 /dts-v1/; 9 9 10 - /include/ "skeleton.dtsi" 10 + /include/ "skeleton_hs_idu.dtsi" 11 11 12 12 / { 13 13 compatible = "snps,nsimosci_hs"; ··· 32 32 33 33 /* child and parent address space 1:1 mapped */ 34 34 ranges; 35 + 36 + core_clk: core_clk { 37 + #clock-cells = <0>; 38 + compatible = "fixed-clock"; 39 + clock-frequency = <5000000>; 40 + }; 35 41 36 42 core_intc: core-interrupt-controller { 37 43 compatible = "snps,archs-intc";
+14
arch/arc/boot/dts/skeleton.dtsi
··· 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 47 memory { 34 48 device_type = "memory"; 35 49 reg = <0x80000000 0x10000000>; /* 256M */
+52
arch/arc/boot/dts/skeleton_hs.dtsi
··· 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 + };
+46
arch/arc/boot/dts/skeleton_hs_idu.dtsi
··· 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 + };
+11 -3
arch/arc/boot/dts/vdk_axc003.dtsi
··· 10 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 16 compatible = "snps,arc"; 15 17 clock-frequency = <50000000>; ··· 25 23 26 24 ranges = <0x00000000 0xf0000000 0x10000000>; 27 25 28 - cpu_intc: archs-intc@cpu { 26 + core_clk: core_clk { 27 + #clock-cells = <0>; 28 + compatible = "fixed-clock"; 29 + clock-frequency = <50000000>; 30 + }; 31 + 32 + core_intc: archs-intc@cpu { 29 33 compatible = "snps,archs-intc"; 30 34 interrupt-controller; 31 35 #interrupt-cells = <1>; ··· 41 33 compatible = "snps,dw-apb-uart"; 42 34 reg = <0x5000 0x100>; 43 35 clock-frequency = <2403200>; 44 - interrupt-parent = <&cpu_intc>; 36 + interrupt-parent = <&core_intc>; 45 37 interrupts = <19>; 46 38 baud = <115200>; 47 39 reg-shift = <2>; ··· 55 47 compatible = "snps,dw-apb-ictl"; 56 48 reg = < 0xe0012000 0x200 >; 57 49 interrupt-controller; 58 - interrupt-parent = <&cpu_intc>; 50 + interrupt-parent = <&core_intc>; 59 51 interrupts = < 18 >; 60 52 }; 61 53
+10 -2
arch/arc/boot/dts/vdk_axc003_idu.dtsi
··· 11 11 * HS38x2 (Dual Core) with IDU intc (VDK version) 12 12 */ 13 13 14 + /include/ "skeleton_hs_idu.dtsi" 15 + 14 16 / { 15 17 compatible = "snps,arc"; 16 18 clock-frequency = <50000000>; ··· 26 24 27 25 ranges = <0x00000000 0xf0000000 0x10000000>; 28 26 29 - cpu_intc: archs-intc@cpu { 27 + core_clk: core_clk { 28 + #clock-cells = <0>; 29 + compatible = "fixed-clock"; 30 + clock-frequency = <50000000>; 31 + }; 32 + 33 + core_intc: archs-intc@cpu { 30 34 compatible = "snps,archs-intc"; 31 35 interrupt-controller; 32 36 #interrupt-cells = <1>; ··· 41 33 idu_intc: idu-interrupt-controller { 42 34 compatible = "snps,archs-idu-intc"; 43 35 interrupt-controller; 44 - interrupt-parent = <&cpu_intc>; 36 + interrupt-parent = <&core_intc>; 45 37 46 38 /* 47 39 * <hwirq distribution>
+84
arch/arc/configs/nps_defconfig
··· 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
+80 -3
arch/arc/include/asm/atomic.h
··· 17 17 #include <asm/barrier.h> 18 18 #include <asm/smp.h> 19 19 20 + #ifndef CONFIG_ARC_PLAT_EZNPS 21 + 20 22 #define atomic_read(v) READ_ONCE((v)->counter) 21 23 22 24 #ifdef CONFIG_ARC_HAS_LLSC ··· 182 180 ATOMIC_OP(or, |=, or) 183 181 ATOMIC_OP(xor, ^=, xor) 184 182 185 - #undef ATOMIC_OPS 186 - #undef ATOMIC_OP_RETURN 187 - #undef ATOMIC_OP 188 183 #undef SCOND_FAIL_RETRY_VAR_DEF 189 184 #undef SCOND_FAIL_RETRY_ASM 190 185 #undef SCOND_FAIL_RETRY_VARS 186 + 187 + #else /* CONFIG_ARC_PLAT_EZNPS */ 188 + 189 + static inline int atomic_read(const atomic_t *v) 190 + { 191 + int temp; 192 + 193 + __asm__ __volatile__( 194 + " ld.di %0, [%1]" 195 + : "=r"(temp) 196 + : "r"(&v->counter) 197 + : "memory"); 198 + return temp; 199 + } 200 + 201 + static inline void atomic_set(atomic_t *v, int i) 202 + { 203 + __asm__ __volatile__( 204 + " st.di %0,[%1]" 205 + : 206 + : "r"(i), "r"(&v->counter) 207 + : "memory"); 208 + } 209 + 210 + #define ATOMIC_OP(op, c_op, asm_op) \ 211 + static inline void atomic_##op(int i, atomic_t *v) \ 212 + { \ 213 + __asm__ __volatile__( \ 214 + " mov r2, %0\n" \ 215 + " mov r3, %1\n" \ 216 + " .word %2\n" \ 217 + : \ 218 + : "r"(i), "r"(&v->counter), "i"(asm_op) \ 219 + : "r2", "r3", "memory"); \ 220 + } \ 221 + 222 + #define ATOMIC_OP_RETURN(op, c_op, asm_op) \ 223 + static inline int atomic_##op##_return(int i, atomic_t *v) \ 224 + { \ 225 + unsigned int temp = i; \ 226 + \ 227 + /* Explicit full memory barrier needed before/after */ \ 228 + smp_mb(); \ 229 + \ 230 + __asm__ __volatile__( \ 231 + " mov r2, %0\n" \ 232 + " mov r3, %1\n" \ 233 + " .word %2\n" \ 234 + " mov %0, r2" \ 235 + : "+r"(temp) \ 236 + : "r"(&v->counter), "i"(asm_op) \ 237 + : "r2", "r3", "memory"); \ 238 + \ 239 + smp_mb(); \ 240 + \ 241 + temp c_op i; \ 242 + \ 243 + return temp; \ 244 + } 245 + 246 + #define ATOMIC_OPS(op, c_op, asm_op) \ 247 + ATOMIC_OP(op, c_op, asm_op) \ 248 + ATOMIC_OP_RETURN(op, c_op, asm_op) 249 + 250 + ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3) 251 + #define atomic_sub(i, v) atomic_add(-(i), (v)) 252 + #define atomic_sub_return(i, v) atomic_add_return(-(i), (v)) 253 + 254 + ATOMIC_OP(and, &=, CTOP_INST_AAND_DI_R2_R2_R3) 255 + #define atomic_andnot(mask, v) atomic_and(~(mask), (v)) 256 + ATOMIC_OP(or, |=, CTOP_INST_AOR_DI_R2_R2_R3) 257 + ATOMIC_OP(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3) 258 + 259 + #endif /* CONFIG_ARC_PLAT_EZNPS */ 260 + 261 + #undef ATOMIC_OPS 262 + #undef ATOMIC_OP_RETURN 263 + #undef ATOMIC_OP 191 264 192 265 /** 193 266 * __atomic_add_unless - add unless the number is a given value
+9 -3
arch/arc/include/asm/barrier.h
··· 30 30 #define rmb() asm volatile("dmb 1\n" : : : "memory") 31 31 #define wmb() asm volatile("dmb 2\n" : : : "memory") 32 32 33 - #endif 34 - 35 - #ifdef CONFIG_ISA_ARCOMPACT 33 + #elif !defined(CONFIG_ARC_PLAT_EZNPS) /* CONFIG_ISA_ARCOMPACT */ 36 34 37 35 /* 38 36 * ARCompact based cores (ARC700) only have SYNC instruction which is super ··· 39 41 */ 40 42 41 43 #define mb() asm volatile("sync\n" : : : "memory") 44 + 45 + #else /* CONFIG_ARC_PLAT_EZNPS */ 46 + 47 + #include <plat/ctop.h> 48 + 49 + #define mb() asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory") 50 + #define rmb() asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RD) : "memory") 51 + 42 52 #endif 43 53 44 54 #include <asm-generic/barrier.h>
+57 -3
arch/arc/include/asm/bitops.h
··· 22 22 #include <asm/smp.h> 23 23 #endif 24 24 25 - #if defined(CONFIG_ARC_HAS_LLSC) 25 + #ifdef CONFIG_ARC_HAS_LLSC 26 26 27 27 /* 28 28 * Hardware assisted Atomic-R-M-W ··· 88 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 94 * Non hardware assisted Atomic-R-M-W ··· 139 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 193 * Non atomic variants ··· 229 181 /* __test_and_set_bit(), __test_and_clear_bit(), __test_and_change_bit() */\ 230 182 __TEST_N_BIT_OP(op, c_op, asm_op) 231 183 184 + #ifndef CONFIG_ARC_PLAT_EZNPS 232 185 BIT_OPS(set, |, bset) 233 186 BIT_OPS(clear, & ~, bclr) 234 187 BIT_OPS(change, ^, bxor) 188 + #else 189 + BIT_OPS(set, |, CTOP_INST_AOR_DI_R2_R2_R3) 190 + BIT_OPS(clear, & ~, CTOP_INST_AAND_DI_R2_R2_R3) 191 + BIT_OPS(change, ^, CTOP_INST_AXOR_DI_R2_R2_R3) 192 + #endif 235 193 236 194 /* 237 195 * This routine doesn't need to be atomic.
-22
arch/arc/include/asm/clk.h
··· 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
+68 -8
arch/arc/include/asm/cmpxchg.h
··· 44 44 return prev; 45 45 } 46 46 47 - #else 47 + #elif !defined(CONFIG_ARC_PLAT_EZNPS) 48 48 49 49 static inline unsigned long 50 50 __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new) ··· 64 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 93 #endif /* CONFIG_ARC_HAS_LLSC */ 68 94 69 95 #define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \ 70 96 (unsigned long)(o), (unsigned long)(n))) 71 97 72 98 /* 73 - * Since not supported natively, ARC cmpxchg() uses atomic_ops_lock (UP/SMP) 74 - * just to gaurantee semantics. 75 - * atomic_cmpxchg() needs to use the same locks as it's other atomic siblings 76 - * which also happens to be atomic_ops_lock. 77 - * 78 - * Thus despite semantically being different, implementation of atomic_cmpxchg() 79 - * is same as cmpxchg(). 99 + * atomic_cmpxchg is same as cmpxchg 100 + * LLSC: only different in data-type, semantics are exactly same 101 + * !LLSC: cmpxchg() has to use an external lock atomic_ops_lock to guarantee 102 + * semantics, and this lock also happens to be used by atomic_*() 80 103 */ 81 104 #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) 82 105 106 + 107 + #ifndef CONFIG_ARC_PLAT_EZNPS 83 108 84 109 /* 85 110 * xchg (reg with memory) based on "Native atomic" EX insn ··· 167 142 #define xchg(ptr, with) _xchg(ptr, with) 168 143 169 144 #endif 145 + 146 + #else /* CONFIG_ARC_PLAT_EZNPS */ 147 + 148 + static inline unsigned long __xchg(unsigned long val, volatile void *ptr, 149 + int size) 150 + { 151 + extern unsigned long __xchg_bad_pointer(void); 152 + 153 + switch (size) { 154 + case 4: 155 + /* 156 + * Explicit full memory barrier needed before/after 157 + */ 158 + smp_mb(); 159 + 160 + __asm__ __volatile__( 161 + " mov r2, %0\n" 162 + " mov r3, %1\n" 163 + " .word %2\n" 164 + " mov %0, r2\n" 165 + : "+r"(val) 166 + : "r"(ptr), "i"(CTOP_INST_XEX_DI_R2_R2_R3) 167 + : "r2", "r3", "memory"); 168 + 169 + smp_mb(); 170 + 171 + return val; 172 + } 173 + return __xchg_bad_pointer(); 174 + } 175 + 176 + #define xchg(ptr, with) ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), \ 177 + sizeof(*(ptr)))) 178 + 179 + #endif /* CONFIG_ARC_PLAT_EZNPS */ 170 180 171 181 /* 172 182 * "atomic" variant of xchg()
+6
arch/arc/include/asm/entry-compact.h
··· 36 36 #include <asm/irqflags-compact.h> 37 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 44 * Switch to Kernel Mode stack if SP points to User Mode stack 41 45 * ··· 300 296 bic \reg, sp, (THREAD_SIZE - 1) 301 297 .endm 302 298 299 + #ifndef CONFIG_ARC_PLAT_EZNPS 303 300 /* Get CPU-ID of this core */ 304 301 .macro GET_CPU_ID reg 305 302 lr \reg, [identity] 306 303 lsr \reg, \reg, 8 307 304 bmsk \reg, \reg, 7 308 305 .endm 306 + #endif 309 307 310 308 #endif /* __ASM_ARC_ENTRY_COMPACT_H */
+3 -10
arch/arc/include/asm/irq.h
··· 13 13 #define NR_IRQS 128 /* allow some CPU external IRQ handling */ 14 14 15 15 /* Platform Independent IRQs */ 16 - #ifdef CONFIG_ISA_ARCOMPACT 17 - #define TIMER0_IRQ 3 18 - #define TIMER1_IRQ 4 19 - #else 20 - #define TIMER0_IRQ 16 21 - #define TIMER1_IRQ 17 16 + #ifdef CONFIG_ISA_ARCV2 17 + #define IPI_IRQ 19 18 + #define SOFTIRQ_IRQ 21 22 19 #endif 23 20 24 21 #include <linux/interrupt.h> 25 22 #include <asm-generic/irq.h> 26 23 27 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 26 #endif
+4
arch/arc/include/asm/page.h
··· 31 31 * These are used to make use of C type-checking.. 32 32 */ 33 33 typedef struct { 34 + #ifdef CONFIG_ARC_HAS_PAE40 35 + unsigned long long pte; 36 + #else 34 37 unsigned long pte; 38 + #endif 35 39 } pte_t; 36 40 typedef struct { 37 41 unsigned long pgd;
+1 -1
arch/arc/include/asm/pgtable.h
··· 217 217 #define BITS_FOR_PTE (PGDIR_SHIFT - PAGE_SHIFT) 218 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 221 #define PGDIR_MASK (~(PGDIR_SIZE-1)) 222 222 223 223 #define PTRS_PER_PTE _BITUL(BITS_FOR_PTE)
+39 -12
arch/arc/include/asm/processor.h
··· 57 57 * A lot of busy-wait loops in SMP are based off of non-volatile data otherwise 58 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 74 #define copy_segments(tsk, mm) do { } while (0) 65 75 #define release_segments(mm) do { } while (0) ··· 107 97 #endif /* !__ASSEMBLY__ */ 108 98 109 99 /* 110 - * System Memory Map on ARC 100 + * Default System Memory Map on ARC 111 101 * 112 102 * ---------------------------- (lower 2G, Translated) ------------------------- 113 103 * 0x0000_0000 0x5FFF_FFFF (user vaddr: TASK_SIZE) ··· 119 109 * 0xC000_0000 0xFFFF_FFFF (peripheral uncached space) 120 110 * ----------------------------------------------------------------------------- 121 111 */ 122 - #define VMALLOC_START 0x70000000 123 112 124 - /* 125 - * 1 PGDIR_SIZE each for fixmap/pkmap, 2 PGDIR_SIZE gutter 126 - * See asm/highmem.h for details 127 - */ 128 - #define VMALLOC_SIZE (PAGE_OFFSET - VMALLOC_START - PGDIR_SIZE * 4) 113 + #define TASK_SIZE 0x60000000 114 + 115 + #define VMALLOC_START (PAGE_OFFSET - (CONFIG_ARC_KVADDR_SIZE << 20)) 116 + 117 + /* 1 PGDIR_SIZE each for fixmap/pkmap, 2 PGDIR_SIZE gutter (see asm/highmem.h) */ 118 + #define VMALLOC_SIZE ((CONFIG_ARC_KVADDR_SIZE << 20) - PGDIR_SIZE * 4) 119 + 129 120 #define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE) 130 121 131 - #define USER_KERNEL_GUTTER 0x10000000 122 + #define USER_KERNEL_GUTTER (VMALLOC_START - TASK_SIZE) 132 123 133 - #define TASK_SIZE (VMALLOC_START - USER_KERNEL_GUTTER) 134 - 124 + #ifdef CONFIG_ARC_PLAT_EZNPS 125 + /* NPS architecture defines special window of 129M in user address space for 126 + * special memory areas, when accessing this window the MMU do not use TLB. 127 + * Instead MMU direct the access to: 128 + * 0x57f00000:0x57ffffff -- 1M of closely coupled memory (aka CMEM) 129 + * 0x58000000:0x5fffffff -- 16 huge pages, 8M each, with fixed map (aka FMTs) 130 + * 131 + * CMEM - is the fastest memory we got and its size is 16K. 132 + * FMT - is used to map either to internal/external memory. 133 + * Internal memory is the second fast memory and its size is 16M 134 + * External memory is the biggest memory (16G) and also the slowest. 135 + * 136 + * STACK_TOP need to be PMD align (21bit) that is why we supply 0x57e00000. 137 + */ 138 + #define STACK_TOP 0x57e00000 139 + #else 135 140 #define STACK_TOP TASK_SIZE 141 + #endif 142 + 136 143 #define STACK_TOP_MAX STACK_TOP 137 144 138 145 /* This decides where the kernel will search for a free chunk of vm
+4
arch/arc/include/asm/setup.h
··· 12 12 #include <linux/types.h> 13 13 #include <uapi/asm/setup.h> 14 14 15 + #ifdef CONFIG_ARC_PLAT_EZNPS 16 + #define COMMAND_LINE_SIZE 2048 17 + #else 15 18 #define COMMAND_LINE_SIZE 256 19 + #endif 16 20 17 21 /* 18 22 * Data structure to map a ID to string
+14
arch/arc/include/asm/spinlock.h
··· 610 610 static inline int arch_read_trylock(arch_rwlock_t *rw) 611 611 { 612 612 int ret = 0; 613 + unsigned long flags; 613 614 615 + local_irq_save(flags); 614 616 arch_spin_lock(&(rw->lock_mutex)); 615 617 616 618 /* ··· 625 623 } 626 624 627 625 arch_spin_unlock(&(rw->lock_mutex)); 626 + local_irq_restore(flags); 628 627 629 628 smp_mb(); 630 629 return ret; ··· 635 632 static inline int arch_write_trylock(arch_rwlock_t *rw) 636 633 { 637 634 int ret = 0; 635 + unsigned long flags; 638 636 637 + local_irq_save(flags); 639 638 arch_spin_lock(&(rw->lock_mutex)); 640 639 641 640 /* ··· 651 646 ret = 1; 652 647 } 653 648 arch_spin_unlock(&(rw->lock_mutex)); 649 + local_irq_restore(flags); 654 650 655 651 return ret; 656 652 } ··· 670 664 671 665 static inline void arch_read_unlock(arch_rwlock_t *rw) 672 666 { 667 + unsigned long flags; 668 + 669 + local_irq_save(flags); 673 670 arch_spin_lock(&(rw->lock_mutex)); 674 671 rw->counter++; 675 672 arch_spin_unlock(&(rw->lock_mutex)); 673 + local_irq_restore(flags); 676 674 } 677 675 678 676 static inline void arch_write_unlock(arch_rwlock_t *rw) 679 677 { 678 + unsigned long flags; 679 + 680 + local_irq_save(flags); 680 681 arch_spin_lock(&(rw->lock_mutex)); 681 682 rw->counter = __ARCH_RW_LOCK_UNLOCKED__; 682 683 arch_spin_unlock(&(rw->lock_mutex)); 684 + local_irq_restore(flags); 683 685 } 684 686 685 687 #endif
+1 -1
arch/arc/include/uapi/asm/byteorder.h
··· 9 9 #ifndef __ASM_ARC_BYTEORDER_H 10 10 #define __ASM_ARC_BYTEORDER_H 11 11 12 - #ifdef CONFIG_CPU_BIG_ENDIAN 12 + #ifdef __BIG_ENDIAN__ 13 13 #include <linux/byteorder/big_endian.h> 14 14 #else 15 15 #include <linux/byteorder/little_endian.h>
+1 -1
arch/arc/kernel/Makefile
··· 9 9 CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' 10 10 11 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 13 obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o 14 14 obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o 15 15 obj-$(CONFIG_PCI) += pcibios.o
-21
arch/arc/kernel/clk.c
··· 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 - }
+13
arch/arc/kernel/ctx_sw.c
··· 16 16 17 17 #include <asm/asm-offsets.h> 18 18 #include <linux/sched.h> 19 + #ifdef CONFIG_ARC_PLAT_EZNPS 20 + #include <plat/ctop.h> 21 + #endif 19 22 20 23 #define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4) 21 24 ··· 70 67 #ifndef CONFIG_SMP 71 68 "st %2, [@_current_task] \n\t" 72 69 #else 70 + #ifdef CONFIG_ARC_PLAT_EZNPS 71 + "lr r24, [%4] \n\t" 72 + #ifndef CONFIG_EZNPS_MTM_EXT 73 + "lsr r24, r24, 4 \n\t" 74 + #endif 75 + #else 73 76 "lr r24, [identity] \n\t" 74 77 "lsr r24, r24, 8 \n\t" 75 78 "bmsk r24, r24, 7 \n\t" 79 + #endif 76 80 "add2 r24, @_current_task, r24 \n\t" 77 81 "st %2, [r24] \n\t" 78 82 #endif ··· 117 107 118 108 : "=r"(tmp) 119 109 : "n"(KSP_WORD_OFF), "r"(next), "r"(prev) 110 + #ifdef CONFIG_ARC_PLAT_EZNPS 111 + , "i"(CTOP_AUX_LOGIC_GLOBAL_ID) 112 + #endif 120 113 : "blink" 121 114 ); 122 115
+2 -11
arch/arc/kernel/devtree.c
··· 14 14 #include <linux/memblock.h> 15 15 #include <linux/of.h> 16 16 #include <linux/of_fdt.h> 17 - #include <asm/clk.h> 18 17 #include <asm/mach_desc.h> 19 18 20 19 #ifdef CONFIG_SERIAL_EARLYCON ··· 27 28 28 29 static void __init arc_set_early_base_baud(unsigned long dt_root) 29 30 { 30 - unsigned int core_clk = arc_get_core_freq(); 31 - 32 31 if (of_flat_dt_is_compatible(dt_root, "abilis,arc-tb10x")) 33 - arc_base_baud = core_clk/3; 32 + arc_base_baud = 166666666; /* Fixed 166.6MHz clk (TB10x) */ 34 33 else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp")) 35 34 arc_base_baud = 33333333; /* Fixed 33MHz clk (AXS10x) */ 36 35 else 37 - arc_base_baud = core_clk; 36 + arc_base_baud = 50000000; /* Fixed default 50MHz */ 38 37 } 39 38 #else 40 39 #define arc_set_early_base_baud(dt_root) ··· 62 65 { 63 66 const struct machine_desc *mdesc; 64 67 unsigned long dt_root; 65 - const void *clk; 66 - int len; 67 68 68 69 if (!early_init_dt_scan(dt)) 69 70 return NULL; ··· 71 76 machine_halt(); 72 77 73 78 dt_root = of_get_flat_dt_root(); 74 - clk = of_get_flat_dt_prop(dt_root, "clock-frequency", &len); 75 - if (clk) 76 - arc_set_core_freq(of_read_ulong(clk, len/4)); 77 - 78 79 arc_set_early_base_baud(dt_root); 79 80 80 81 return mdesc;
+12 -5
arch/arc/kernel/intc-arcv2.c
··· 137 137 .map = arcv2_irq_map, 138 138 }; 139 139 140 - static struct irq_domain *root_domain; 141 140 142 141 static int __init 143 142 init_onchip_IRQ(struct device_node *intc, struct device_node *parent) 144 143 { 144 + struct irq_domain *root_domain; 145 + 145 146 if (parent) 146 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 - &arcv2_irq_ops, NULL); 150 - 149 + root_domain = irq_domain_add_linear(intc, NR_CPU_IRQS, &arcv2_irq_ops, NULL); 151 150 if (!root_domain) 152 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 157 irq_set_default_host(root_domain); 158 + 159 + #ifdef CONFIG_SMP 160 + irq_create_mapping(root_domain, IPI_IRQ); 161 + #endif 162 + irq_create_mapping(root_domain, SOFTIRQ_IRQ); 156 163 157 164 return 0; 158 165 }
+11 -6
arch/arc/kernel/intc-compact.c
··· 14 14 #include <linux/irqchip.h> 15 15 #include <asm/irq.h> 16 16 17 + #define TIMER0_IRQ 3 /* Fixed by ISA */ 18 + 17 19 /* 18 20 * Early Hardware specific Interrupt setup 19 21 * -Platform independent, needed for each CPU (not foldable into init_IRQ) ··· 81 79 static int arc_intc_domain_map(struct irq_domain *d, unsigned int irq, 82 80 irq_hw_number_t hw) 83 81 { 84 - switch (irq) { 82 + switch (hw) { 85 83 case TIMER0_IRQ: 84 + irq_set_percpu_devid(irq); 86 85 irq_set_chip_and_handler(irq, &onchip_intc, handle_percpu_irq); 87 86 break; 88 87 default: ··· 97 94 .map = arc_intc_domain_map, 98 95 }; 99 96 100 - static struct irq_domain *root_domain; 101 - 102 97 static int __init 103 98 init_onchip_IRQ(struct device_node *intc, struct device_node *parent) 104 99 { 100 + struct irq_domain *root_domain; 101 + 105 102 if (parent) 106 103 panic("DeviceTree incore intc not a root irq controller\n"); 107 104 108 - root_domain = irq_domain_add_legacy(intc, NR_CPU_IRQS, 0, 0, 105 + root_domain = irq_domain_add_linear(intc, NR_CPU_IRQS, 109 106 &arc_intc_domain_ops, NULL); 110 - 111 107 if (!root_domain) 112 108 panic("root irq domain not avail\n"); 113 109 114 - /* with this we don't need to export root_domain */ 110 + /* 111 + * Needed for primary domain lookup to succeed 112 + * This is a primary irqchip, and can never have a parent 113 + */ 115 114 irq_set_default_host(root_domain); 116 115 117 116 return 0;
+2 -48
arch/arc/kernel/irq.c
··· 41 41 * "C" Entry point for any ARC ISR, called from low level vector handler 42 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); 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); 46 + handle_domain_irq(NULL, hwirq, regs); 93 47 }
+1 -6
arch/arc/kernel/mcip.c
··· 15 15 #include <asm/mcip.h> 16 16 #include <asm/setup.h> 17 17 18 - #define IPI_IRQ 19 19 - #define SOFTIRQ_IRQ 21 20 - 21 18 static char smp_cpuinfo_buf[128]; 22 19 static int idu_detected; 23 20 ··· 113 116 IS_AVAIL1(mp.dbg, "DEBUG "), 114 117 IS_AVAIL1(mp.gfrc, "GFRC")); 115 118 119 + cpuinfo_arc700[0].extn.gfrc = mp.gfrc; 116 120 idu_detected = mp.idu; 117 121 118 122 if (mp.dbg) { 119 123 __mcip_cmd_data(CMD_DEBUG_SET_SELECT, 0, 0xf); 120 124 __mcip_cmd_data(CMD_DEBUG_SET_MASK, 0xf, 0xf); 121 125 } 122 - 123 - if (IS_ENABLED(CONFIG_ARC_HAS_GFRC) && !mp.gfrc) 124 - panic("kernel trying to use non-existent GFRC\n"); 125 126 } 126 127 127 128 struct plat_smp_ops plat_smp_ops = {
+7 -10
arch/arc/kernel/setup.c
··· 13 13 #include <linux/console.h> 14 14 #include <linux/module.h> 15 15 #include <linux/cpu.h> 16 - #include <linux/clk-provider.h> 17 16 #include <linux/of_fdt.h> 18 17 #include <linux/of_platform.h> 19 18 #include <linux/cache.h> ··· 23 24 #include <asm/page.h> 24 25 #include <asm/irq.h> 25 26 #include <asm/unwind.h> 26 - #include <asm/clk.h> 27 27 #include <asm/mach_desc.h> 28 28 #include <asm/smp.h> 29 29 ··· 218 220 if (tbl->info.id == 0) 219 221 n += scnprintf(buf + n, len - n, "UNKNOWN ARC Processor\n"); 220 222 221 - n += scnprintf(buf + n, len - n, "CPU speed\t: %u.%02u Mhz\n", 222 - (unsigned int)(arc_get_core_freq() / 1000000), 223 - (unsigned int)(arc_get_core_freq() / 10000) % 100); 224 - 225 223 n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ", 226 224 IS_AVAIL1(cpu->extn.timer0, "Timer0 "), 227 225 IS_AVAIL1(cpu->extn.timer1, "Timer1 "), ··· 307 313 308 314 if (!cpu->extn.timer1) 309 315 panic("Timer1 is not present!\n"); 310 - 311 - if (IS_ENABLED(CONFIG_ARC_HAS_RTC) && !cpu->extn.rtc) 312 - panic("RTC is not present\n"); 313 316 314 317 #ifdef CONFIG_ARC_HAS_DCCM 315 318 /* ··· 435 444 436 445 static int __init customize_machine(void) 437 446 { 438 - of_clk_init(NULL); 439 447 /* 440 448 * Traverses flattened DeviceTree - registering platform devices 441 449 * (if any) complete with their resources ··· 467 477 { 468 478 char *str; 469 479 int cpu_id = ptr_to_cpu(v); 480 + struct device_node *core_clk = of_find_node_by_name(NULL, "core_clk"); 481 + u32 freq = 0; 470 482 471 483 if (!cpu_online(cpu_id)) { 472 484 seq_printf(m, "processor [%d]\t: Offline\n", cpu_id); ··· 480 488 goto done; 481 489 482 490 seq_printf(m, arc_cpu_mumbojumbo(cpu_id, str, PAGE_SIZE)); 491 + 492 + of_property_read_u32(core_clk, "clock-frequency", &freq); 493 + if (freq) 494 + seq_printf(m, "CPU speed\t: %u.%02u Mhz\n", 495 + freq / 1000000, (freq / 10000) % 100); 483 496 484 497 seq_printf(m, "Bogo MIPS\t: %lu.%02lu\n", 485 498 loops_per_jiffy / (500000 / HZ),
+18 -7
arch/arc/kernel/smp.c
··· 126 126 current->active_mm = mm; 127 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 129 /* Some SMP H/w setup - for each cpu */ 135 130 if (plat_smp_ops.init_per_cpu) 136 131 plat_smp_ops.init_per_cpu(cpu); ··· 133 138 if (machine_desc->init_per_cpu) 134 139 machine_desc->init_per_cpu(cpu); 135 140 136 - arc_local_timer_setup(); 141 + notify_cpu_starting(cpu); 142 + set_cpu_online(cpu, true); 143 + 144 + pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu); 137 145 138 146 local_irq_enable(); 139 147 preempt_disable(); ··· 344 346 345 347 /* 346 348 * API called by platform code to hookup arch-common ISR to their IPI IRQ 349 + * 350 + * Note: If IPI is provided by platform (vs. say ARC MCIP), their intc setup/map 351 + * function needs to call call irq_set_percpu_devid() for IPI IRQ, otherwise 352 + * request_percpu_irq() below will fail 347 353 */ 348 354 static DEFINE_PER_CPU(int, ipi_dev); 349 355 ··· 355 353 { 356 354 int *dev = per_cpu_ptr(&ipi_dev, cpu); 357 355 358 - arc_request_percpu_irq(irq, cpu, do_IPI, "IPI Interrupt", dev); 356 + /* Boot cpu calls request, all call enable */ 357 + if (!cpu) { 358 + int rc; 359 + 360 + rc = request_percpu_irq(irq, do_IPI, "IPI Interrupt", dev); 361 + if (rc) 362 + panic("Percpu IRQ request failed for %d\n", irq); 363 + } 364 + 365 + enable_percpu_irq(irq, 0); 359 366 360 367 return 0; 361 368 }
+165 -77
arch/arc/kernel/time.c
··· 29 29 * which however is currently broken 30 30 */ 31 31 32 - #include <linux/spinlock.h> 33 32 #include <linux/interrupt.h> 34 - #include <linux/module.h> 35 - #include <linux/sched.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> 33 + #include <linux/clk.h> 34 + #include <linux/clk-provider.h> 41 35 #include <linux/clocksource.h> 42 36 #include <linux/clockchips.h> 37 + #include <linux/cpu.h> 38 + #include <linux/of.h> 39 + #include <linux/of_irq.h> 43 40 #include <asm/irq.h> 44 41 #include <asm/arcregs.h> 45 - #include <asm/clk.h> 46 - #include <asm/mach_desc.h> 47 42 48 43 #include <asm/mcip.h> 49 44 ··· 55 60 56 61 #define ARC_TIMER_MAX 0xFFFFFFFF 57 62 63 + static unsigned long arc_timer_freq; 64 + 65 + static int noinline arc_get_timer_clk(struct device_node *node) 66 + { 67 + struct clk *clk; 68 + int ret; 69 + 70 + clk = of_clk_get(node, 0); 71 + if (IS_ERR(clk)) { 72 + pr_err("timer missing clk"); 73 + return PTR_ERR(clk); 74 + } 75 + 76 + ret = clk_prepare_enable(clk); 77 + if (ret) { 78 + pr_err("Couldn't enable parent clk\n"); 79 + return ret; 80 + } 81 + 82 + arc_timer_freq = clk_get_rate(clk); 83 + 84 + return 0; 85 + } 86 + 58 87 /********** Clock Source Device *********/ 59 88 60 89 #ifdef CONFIG_ARC_HAS_GFRC 61 90 62 - static int arc_counter_setup(void) 63 - { 64 - return 1; 65 - } 66 - 67 - static cycle_t arc_counter_read(struct clocksource *cs) 91 + static cycle_t arc_read_gfrc(struct clocksource *cs) 68 92 { 69 93 unsigned long flags; 70 94 union { ··· 108 94 return stamp.full; 109 95 } 110 96 111 - static struct clocksource arc_counter = { 97 + static struct clocksource arc_counter_gfrc = { 112 98 .name = "ARConnect GFRC", 113 99 .rating = 400, 114 - .read = arc_counter_read, 100 + .read = arc_read_gfrc, 115 101 .mask = CLOCKSOURCE_MASK(64), 116 102 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 117 103 }; 118 104 119 - #else 105 + static void __init arc_cs_setup_gfrc(struct device_node *node) 106 + { 107 + int exists = cpuinfo_arc700[0].extn.gfrc; 108 + int ret; 109 + 110 + if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected")) 111 + return; 112 + 113 + ret = arc_get_timer_clk(node); 114 + if (ret) 115 + return; 116 + 117 + clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq); 118 + } 119 + CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc); 120 + 121 + #endif 120 122 121 123 #ifdef CONFIG_ARC_HAS_RTC 122 124 ··· 140 110 #define AUX_RTC_LOW 0x104 141 111 #define AUX_RTC_HIGH 0x105 142 112 143 - int arc_counter_setup(void) 144 - { 145 - write_aux_reg(AUX_RTC_CTRL, 1); 146 - 147 - /* Not usable in SMP */ 148 - return !IS_ENABLED(CONFIG_SMP); 149 - } 150 - 151 - static cycle_t arc_counter_read(struct clocksource *cs) 113 + static cycle_t arc_read_rtc(struct clocksource *cs) 152 114 { 153 115 unsigned long status; 154 116 union { ··· 164 142 return stamp.full; 165 143 } 166 144 167 - static struct clocksource arc_counter = { 145 + static struct clocksource arc_counter_rtc = { 168 146 .name = "ARCv2 RTC", 169 147 .rating = 350, 170 - .read = arc_counter_read, 148 + .read = arc_read_rtc, 171 149 .mask = CLOCKSOURCE_MASK(64), 172 150 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 173 151 }; 174 152 175 - #else /* !CONFIG_ARC_HAS_RTC */ 153 + static void __init arc_cs_setup_rtc(struct device_node *node) 154 + { 155 + int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc; 156 + int ret; 157 + 158 + if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected")) 159 + return; 160 + 161 + /* Local to CPU hence not usable in SMP */ 162 + if (WARN(IS_ENABLED(CONFIG_SMP), "Local-64-bit-Ctr not usable in SMP")) 163 + return; 164 + 165 + ret = arc_get_timer_clk(node); 166 + if (ret) 167 + return; 168 + 169 + write_aux_reg(AUX_RTC_CTRL, 1); 170 + 171 + clocksource_register_hz(&arc_counter_rtc, arc_timer_freq); 172 + } 173 + CLOCKSOURCE_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc); 174 + 175 + #endif 176 176 177 177 /* 178 - * set 32bit TIMER1 to keep counting monotonically and wraparound 178 + * 32bit TIMER1 to keep counting monotonically and wraparound 179 179 */ 180 - int arc_counter_setup(void) 181 - { 182 - write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX); 183 - write_aux_reg(ARC_REG_TIMER1_CNT, 0); 184 - write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH); 185 180 186 - /* Not usable in SMP */ 187 - return !IS_ENABLED(CONFIG_SMP); 188 - } 189 - 190 - static cycle_t arc_counter_read(struct clocksource *cs) 181 + static cycle_t arc_read_timer1(struct clocksource *cs) 191 182 { 192 183 return (cycle_t) read_aux_reg(ARC_REG_TIMER1_CNT); 193 184 } 194 185 195 - static struct clocksource arc_counter = { 186 + static struct clocksource arc_counter_timer1 = { 196 187 .name = "ARC Timer1", 197 188 .rating = 300, 198 - .read = arc_counter_read, 189 + .read = arc_read_timer1, 199 190 .mask = CLOCKSOURCE_MASK(32), 200 191 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 201 192 }; 202 193 203 - #endif 204 - #endif 194 + static void __init arc_cs_setup_timer1(struct device_node *node) 195 + { 196 + int ret; 197 + 198 + /* Local to CPU hence not usable in SMP */ 199 + if (IS_ENABLED(CONFIG_SMP)) 200 + return; 201 + 202 + ret = arc_get_timer_clk(node); 203 + if (ret) 204 + return; 205 + 206 + write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX); 207 + write_aux_reg(ARC_REG_TIMER1_CNT, 0); 208 + write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH); 209 + 210 + clocksource_register_hz(&arc_counter_timer1, arc_timer_freq); 211 + } 205 212 206 213 /********** Clock Event Device *********/ 214 + 215 + static int arc_timer_irq; 207 216 208 217 /* 209 218 * Arm the timer to interrupt after @cycles ··· 262 209 * At X Hz, 1 sec = 1000ms -> X cycles; 263 210 * 10ms -> X / 100 cycles 264 211 */ 265 - arc_timer_event_setup(arc_get_core_freq() / HZ); 212 + arc_timer_event_setup(arc_timer_freq / HZ); 266 213 return 0; 267 214 } 268 215 ··· 271 218 .features = CLOCK_EVT_FEAT_ONESHOT | 272 219 CLOCK_EVT_FEAT_PERIODIC, 273 220 .rating = 300, 274 - .irq = TIMER0_IRQ, /* hardwired, no need for resources */ 275 221 .set_next_event = arc_clkevent_set_next_event, 276 222 .set_state_periodic = arc_clkevent_set_periodic, 277 223 }; ··· 296 244 return IRQ_HANDLED; 297 245 } 298 246 299 - /* 300 - * Setup the local event timer for @cpu 301 - */ 302 - void arc_local_timer_setup() 247 + static int arc_timer_cpu_notify(struct notifier_block *self, 248 + unsigned long action, void *hcpu) 303 249 { 304 250 struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device); 305 - int cpu = smp_processor_id(); 306 251 307 - evt->cpumask = cpumask_of(cpu); 308 - clockevents_config_and_register(evt, arc_get_core_freq(), 252 + evt->cpumask = cpumask_of(smp_processor_id()); 253 + 254 + switch (action & ~CPU_TASKS_FROZEN) { 255 + case CPU_STARTING: 256 + clockevents_config_and_register(evt, arc_timer_freq, 257 + 0, ULONG_MAX); 258 + enable_percpu_irq(arc_timer_irq, 0); 259 + break; 260 + case CPU_DYING: 261 + disable_percpu_irq(arc_timer_irq); 262 + break; 263 + } 264 + 265 + return NOTIFY_OK; 266 + } 267 + 268 + static struct notifier_block arc_timer_cpu_nb = { 269 + .notifier_call = arc_timer_cpu_notify, 270 + }; 271 + 272 + /* 273 + * clockevent setup for boot CPU 274 + */ 275 + static void __init arc_clockevent_setup(struct device_node *node) 276 + { 277 + struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device); 278 + int ret; 279 + 280 + register_cpu_notifier(&arc_timer_cpu_nb); 281 + 282 + arc_timer_irq = irq_of_parse_and_map(node, 0); 283 + if (arc_timer_irq <= 0) 284 + panic("clockevent: missing irq"); 285 + 286 + ret = arc_get_timer_clk(node); 287 + if (ret) 288 + panic("clockevent: missing clk"); 289 + 290 + evt->irq = arc_timer_irq; 291 + evt->cpumask = cpumask_of(smp_processor_id()); 292 + clockevents_config_and_register(evt, arc_timer_freq, 309 293 0, ARC_TIMER_MAX); 310 294 311 - /* setup the per-cpu timer IRQ handler - for all cpus */ 312 - arc_request_percpu_irq(TIMER0_IRQ, cpu, timer_irq_handler, 313 - "Timer0 (per-cpu-tick)", evt); 295 + /* Needs apriori irq_set_percpu_devid() done in intc map function */ 296 + ret = request_percpu_irq(arc_timer_irq, timer_irq_handler, 297 + "Timer0 (per-cpu-tick)", evt); 298 + if (ret) 299 + panic("clockevent: unable to request irq\n"); 300 + 301 + enable_percpu_irq(arc_timer_irq, 0); 314 302 } 303 + 304 + static void __init arc_of_timer_init(struct device_node *np) 305 + { 306 + static int init_count = 0; 307 + 308 + if (!init_count) { 309 + init_count = 1; 310 + arc_clockevent_setup(np); 311 + } else { 312 + arc_cs_setup_timer1(np); 313 + } 314 + } 315 + CLOCKSOURCE_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_of_timer_init); 315 316 316 317 /* 317 318 * Called from start_kernel() - boot CPU only 318 - * 319 - * -Sets up h/w timers as applicable on boot cpu 320 - * -Also sets up any global state needed for timer subsystem: 321 - * - for "counting" timer, registers a clocksource, usable across CPUs 322 - * (provided that underlying counter h/w is synchronized across cores) 323 - * - for "event" timer, sets up TIMER0 IRQ (as that is platform agnostic) 324 319 */ 325 320 void __init time_init(void) 326 321 { 327 - /* 328 - * sets up the timekeeping free-flowing counter which also returns 329 - * whether the counter is usable as clocksource 330 - */ 331 - if (arc_counter_setup()) 332 - /* 333 - * CLK upto 4.29 GHz can be safely represented in 32 bits 334 - * because Max 32 bit number is 4,294,967,295 335 - */ 336 - clocksource_register_hz(&arc_counter, arc_get_core_freq()); 337 - 338 - /* sets up the periodic event timer */ 339 - arc_local_timer_setup(); 322 + of_clk_init(NULL); 323 + clocksource_probe(); 340 324 }
+11
arch/arc/mm/tlb.c
··· 814 814 815 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 828 /* For efficiency sake, kernel is compile time built for a MMU ver 818 829 * This must match the hardware it is running on. 819 830 * Linux built for MMU V2, if run on MMU V1 will break down because V1
+20 -7
arch/arc/plat-axs10x/axs10x.c
··· 14 14 * 15 15 */ 16 16 17 + #include <linux/of_fdt.h> 17 18 #include <linux/of_platform.h> 19 + #include <linux/libfdt.h> 18 20 19 21 #include <asm/asm-offsets.h> 20 - #include <asm/clk.h> 21 22 #include <asm/io.h> 22 23 #include <asm/mach_desc.h> 23 24 #include <asm/mcip.h> ··· 390 389 391 390 static void __init axs103_early_init(void) 392 391 { 392 + int offset = fdt_path_offset(initial_boot_params, "/cpu_card/core_clk"); 393 + const struct fdt_property *prop = fdt_get_property(initial_boot_params, 394 + offset, 395 + "clock-frequency", 396 + NULL); 397 + u32 freq = be32_to_cpu(*(u32*)(prop->data)) / 1000000, orig = freq; 398 + 393 399 /* 394 400 * AXS103 configurations for SMP/QUAD configurations share device tree 395 401 * which defaults to 90 MHz. However recent failures of Quad config ··· 409 401 #ifdef CONFIG_ARC_MCIP 410 402 unsigned int num_cores = (read_aux_reg(ARC_REG_MCIP_BCR) >> 16) & 0x3F; 411 403 if (num_cores > 2) 412 - arc_set_core_freq(50 * 1000000); 413 - else if (num_cores == 2) 414 - arc_set_core_freq(75 * 1000000); 404 + freq = 50; 415 405 #endif 416 406 417 - switch (arc_get_core_freq()/1000000) { 407 + switch (freq) { 418 408 case 33: 419 409 axs103_set_freq(1, 1, 1); 420 410 break; ··· 437 431 * DT "clock-frequency" might not match with board value. 438 432 * Hence update it to match the board value. 439 433 */ 440 - arc_set_core_freq(axs103_get_freq() * 1000000); 434 + freq = axs103_get_freq(); 441 435 break; 442 436 } 443 437 444 - pr_info("Freq is %dMHz\n", axs103_get_freq()); 438 + pr_info("Freq is %dMHz\n", freq); 439 + 440 + /* Patching .dtb in-place with new core clock value */ 441 + if (freq != orig ) { 442 + freq = cpu_to_be32(freq * 1000000); 443 + fdt_setprop_inplace(initial_boot_params, offset, 444 + "clock-frequency", &freq, sizeof(freq)); 445 + } 445 446 446 447 /* Memory maps already config in pre-bootloader */ 447 448
+35
arch/arc/plat-eznps/Kconfig
··· 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.
+7
arch/arc/plat-eznps/Makefile
··· 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
+70
arch/arc/plat-eznps/entry.S
··· 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)
+209
arch/arc/plat-eznps/include/plat/ctop.h
··· 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 */
+60
arch/arc/plat-eznps/include/plat/mtm.h
··· 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 */
+26
arch/arc/plat-eznps/include/plat/smp.h
··· 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
+133
arch/arc/plat-eznps/mtm.c
··· 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 + }
+102
arch/arc/plat-eznps/platform.c
··· 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
+155
arch/arc/plat-eznps/smp.c
··· 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 + };
+10
drivers/clocksource/Kconfig
··· 181 181 This option enables support for Texas Instruments 32.768 Hz clocksource 182 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 194 config CLKSRC_STM32 185 195 bool "Clocksource for STM32 SoCs" if !ARCH_STM32 186 196 depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)
+1
drivers/clocksource/Makefile
··· 47 47 obj-$(CONFIG_MTK_TIMER) += mtk_timer.o 48 48 obj-$(CONFIG_CLKSRC_PISTACHIO) += time-pistachio.o 49 49 obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o 50 + obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o 50 51 51 52 obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o 52 53 obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
+98
drivers/clocksource/timer-nps.c
··· 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);
+6
drivers/irqchip/Kconfig
··· 253 253 254 254 config PARTITION_PERCPU 255 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
+1
drivers/irqchip/Makefile
··· 68 68 obj-$(CONFIG_PIC32_EVIC) += irq-pic32-evic.o 69 69 obj-$(CONFIG_MVEBU_ODMI) += irq-mvebu-odmi.o 70 70 obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o 71 + obj-$(CONFIG_EZNPS_GIC) += irq-eznps.o
+165
drivers/irqchip/irq-eznps.c
··· 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);
+166
include/soc/nps/common.h
··· 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 */