diff options
Diffstat (limited to 'arch')
274 files changed, 10903 insertions, 5433 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2277f9530b00..8c83d98424c7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -533,6 +533,7 @@ config ARCH_IXP4XX config ARCH_DOVE bool "Marvell Dove" select ARCH_REQUIRE_GPIOLIB + select COMMON_CLK_DOVE select CPU_V7 select GENERIC_CLOCKEVENTS select MIGHT_HAVE_PCI diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 2af359cfe985..0f441740c22a 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -77,7 +77,9 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-dns320.dtb \ dtb-$(CONFIG_ARCH_MSM) += msm8660-surf.dtb \ msm8960-cdp.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \ - armada-xp-db.dtb + armada-370-mirabox.dtb \ + armada-xp-db.dtb \ + armada-xp-openblocks-ax3-4.dtb dtb-$(CONFIG_ARCH_MXC) += imx51-babbage.dtb \ imx53-ard.dtb \ imx53-evk.dtb \ @@ -126,7 +128,8 @@ dtb-$(CONFIG_ARCH_SPEAR13XX) += spear1310-evb.dtb \ spear1340-evb.dtb dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \ spear310-evb.dtb \ - spear320-evb.dtb + spear320-evb.dtb \ + spear320-hmi.dtb dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun4i-cubieboard.dtb \ sun5i-olinuxino.dtb diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts index fffd5c2a3041..00044026ef1f 100644 --- a/arch/arm/boot/dts/armada-370-db.dts +++ b/arch/arm/boot/dts/armada-370-db.dts @@ -34,9 +34,30 @@ clock-frequency = <200000000>; status = "okay"; }; - timer@d0020300 { - clock-frequency = <600000000>; + sata@d00a0000 { + nr-ports = <2>; status = "okay"; }; + + mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; + + phy1: ethernet-phy@1 { + reg = <1>; + }; + }; + + ethernet@d0070000 { + status = "okay"; + phy = <&phy0>; + phy-mode = "rgmii-id"; + }; + ethernet@d0074000 { + status = "okay"; + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; }; }; diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts new file mode 100644 index 000000000000..3b4071336599 --- /dev/null +++ b/arch/arm/boot/dts/armada-370-mirabox.dts @@ -0,0 +1,56 @@ +/* + * Device Tree file for Globalscale Mirabox + * + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +/dts-v1/; +/include/ "armada-370.dtsi" + +/ { + model = "Globalscale Mirabox"; + compatible = "globalscale,mirabox", "marvell,armada370", "marvell,armada-370-xp"; + + chosen { + bootargs = "console=ttyS0,115200 earlyprintk"; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x20000000>; /* 512 MB */ + }; + + soc { + serial@d0012000 { + clock-frequency = <200000000>; + status = "okay"; + }; + timer@d0020300 { + clock-frequency = <600000000>; + status = "okay"; + }; + mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; + + phy1: ethernet-phy@1 { + reg = <1>; + }; + }; + ethernet@d0070000 { + status = "okay"; + phy = <&phy0>; + phy-mode = "rgmii-id"; + }; + ethernet@d0074000 { + status = "okay"; + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; + }; +}; diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi index 16cc82cdaa81..cf6c48a09eac 100644 --- a/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/arch/arm/boot/dts/armada-370-xp.dtsi @@ -20,7 +20,7 @@ / { model = "Marvell Armada 370 and XP SoC"; - compatible = "marvell,armada_370_xp"; + compatible = "marvell,armada-370-xp"; cpus { cpu@0 { @@ -36,6 +36,12 @@ interrupt-controller; }; + coherency-fabric@d0020200 { + compatible = "marvell,coherency-fabric"; + reg = <0xd0020200 0xb0>, + <0xd0021810 0x1c>; + }; + soc { #address-cells = <1>; #size-cells = <1>; @@ -62,12 +68,67 @@ compatible = "marvell,armada-370-xp-timer"; reg = <0xd0020300 0x30>; interrupts = <37>, <38>, <39>, <40>; + clocks = <&coreclk 2>; }; addr-decoding@d0020000 { compatible = "marvell,armada-addr-decoding-controller"; reg = <0xd0020000 0x258>; }; + + sata@d00a0000 { + compatible = "marvell,orion-sata"; + reg = <0xd00a0000 0x2400>; + interrupts = <55>; + clocks = <&gateclk 15>, <&gateclk 30>; + clock-names = "0", "1"; + status = "disabled"; + }; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + compatible = "marvell,orion-mdio"; + reg = <0xd0072004 0x4>; + }; + + ethernet@d0070000 { + compatible = "marvell,armada-370-neta"; + reg = <0xd0070000 0x2500>; + interrupts = <8>; + clocks = <&gateclk 4>; + status = "disabled"; + }; + + ethernet@d0074000 { + compatible = "marvell,armada-370-neta"; + reg = <0xd0074000 0x2500>; + interrupts = <10>; + clocks = <&gateclk 3>; + status = "disabled"; + }; + + i2c0: i2c@d0011000 { + compatible = "marvell,mv64xxx-i2c"; + reg = <0xd0011000 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <31>; + timeout-ms = <1000>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + i2c1: i2c@d0011100 { + compatible = "marvell,mv64xxx-i2c"; + reg = <0xd0011100 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <32>; + timeout-ms = <1000>; + clocks = <&coreclk 0>; + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi index 2069151afe01..636cf7d4009e 100644 --- a/arch/arm/boot/dts/armada-370.dtsi +++ b/arch/arm/boot/dts/armada-370.dtsi @@ -20,6 +20,12 @@ / { model = "Marvell Armada 370 family SoC"; compatible = "marvell,armada370", "marvell,armada-370-xp"; + L2: l2-cache { + compatible = "marvell,aurora-outer-cache"; + reg = <0xd0008000 0x1000>; + cache-id-part = <0x100>; + wt-override; + }; aliases { gpio0 = &gpio0; @@ -75,5 +81,56 @@ #interrupts-cells = <2>; interrupts = <91>; }; + + coreclk: mvebu-sar@d0018230 { + compatible = "marvell,armada-370-core-clock"; + reg = <0xd0018230 0x08>; + #clock-cells = <1>; + }; + + gateclk: clock-gating-control@d0018220 { + compatible = "marvell,armada-370-gating-clock"; + reg = <0xd0018220 0x4>; + clocks = <&coreclk 0>; + #clock-cells = <1>; + }; + + xor@d0060800 { + compatible = "marvell,orion-xor"; + reg = <0xd0060800 0x100 + 0xd0060A00 0x100>; + status = "okay"; + + xor00 { + interrupts = <51>; + dmacap,memcpy; + dmacap,xor; + }; + xor01 { + interrupts = <52>; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; + }; + + xor@d0060900 { + compatible = "marvell,orion-xor"; + reg = <0xd0060900 0x100 + 0xd0060b00 0x100>; + status = "okay"; + + xor10 { + interrupts = <94>; + dmacap,memcpy; + dmacap,xor; + }; + xor11 { + interrupts = <95>; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; + }; }; }; diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts index b1fc728515e9..8e53b25b5508 100644 --- a/arch/arm/boot/dts/armada-xp-db.dts +++ b/arch/arm/boot/dts/armada-xp-db.dts @@ -46,5 +46,49 @@ clock-frequency = <250000000>; status = "okay"; }; + + sata@d00a0000 { + nr-ports = <2>; + status = "okay"; + }; + + mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; + + phy1: ethernet-phy@1 { + reg = <1>; + }; + + phy2: ethernet-phy@2 { + reg = <25>; + }; + + phy3: ethernet-phy@3 { + reg = <27>; + }; + }; + + ethernet@d0070000 { + status = "okay"; + phy = <&phy0>; + phy-mode = "rgmii-id"; + }; + ethernet@d0074000 { + status = "okay"; + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; + ethernet@d0030000 { + status = "okay"; + phy = <&phy2>; + phy-mode = "sgmii"; + }; + ethernet@d0034000 { + status = "okay"; + phy = <&phy3>; + phy-mode = "sgmii"; + }; }; }; diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi index ea355192be6f..c45c7b4dc352 100644 --- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi @@ -24,6 +24,18 @@ gpio1 = &gpio1; }; + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <0>; + clocks = <&cpuclk 0>; + }; + } + soc { pinctrl { compatible = "marvell,mv78230-pinctrl"; diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi index 2057863f3dfa..a2aee5707377 100644 --- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi @@ -25,6 +25,25 @@ gpio2 = &gpio2; }; + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <0>; + clocks = <&cpuclk 0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <1>; + clocks = <&cpuclk 1>; + }; + }; + soc { pinctrl { compatible = "marvell,mv78260-pinctrl"; diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi index ffac98373792..da03a129243a 100644 --- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi @@ -25,6 +25,40 @@ gpio2 = &gpio2; }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <0>; + clocks = <&cpuclk 0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <1>; + clocks = <&cpuclk 1>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <2>; + clocks = <&cpuclk 2>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <3>; + clocks = <&cpuclk 3>; + }; + }; + soc { pinctrl { compatible = "marvell,mv78460-pinctrl"; diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts new file mode 100644 index 000000000000..b42652fd3d8c --- /dev/null +++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts @@ -0,0 +1,125 @@ +/* + * Device Tree file for OpenBlocks AX3-4 board + * + * Copyright (C) 2012 Marvell + * + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +/dts-v1/; +/include/ "armada-xp-mv78260.dtsi" + +/ { + model = "PlatHome OpenBlocks AX3-4 board"; + compatible = "plathome,openblocks-ax3-4", "marvell,armadaxp-mv78260", "marvell,armadaxp", "marvell,armada-370-xp"; + + chosen { + bootargs = "console=ttyS0,115200 earlyprintk"; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0xC0000000>; /* 3 GB */ + }; + + soc { + serial@d0012000 { + clock-frequency = <250000000>; + status = "okay"; + }; + serial@d0012100 { + clock-frequency = <250000000>; + status = "okay"; + }; + pinctrl { + led_pins: led-pins-0 { + marvell,pins = "mpp49", "mpp51", "mpp53"; + marvell,function = "gpio"; + }; + }; + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins>; + + red_led { + label = "red_led"; + gpios = <&gpio1 17 1>; + default-state = "off"; + }; + + yellow_led { + label = "yellow_led"; + gpios = <&gpio1 19 1>; + default-state = "off"; + }; + + green_led { + label = "green_led"; + gpios = <&gpio1 21 1>; + default-state = "off"; + linux,default-trigger = "heartbeat"; + }; + }; + + mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; + + phy1: ethernet-phy@1 { + reg = <1>; + }; + + phy2: ethernet-phy@2 { + reg = <2>; + }; + + phy3: ethernet-phy@3 { + reg = <3>; + }; + }; + + ethernet@d0070000 { + status = "okay"; + phy = <&phy0>; + phy-mode = "sgmii"; + }; + ethernet@d0074000 { + status = "okay"; + phy = <&phy1>; + phy-mode = "sgmii"; + }; + ethernet@d0030000 { + status = "okay"; + phy = <&phy2>; + phy-mode = "sgmii"; + }; + ethernet@d0034000 { + status = "okay"; + phy = <&phy3>; + phy-mode = "sgmii"; + }; + i2c@d0011000 { + status = "okay"; + clock-frequency = <400000>; + }; + i2c@d0011100 { + status = "okay"; + clock-frequency = <400000>; + + s35390a: s35390a@30 { + compatible = "s35390a"; + reg = <0x30>; + }; + }; + sata@d00a0000 { + nr-ports = <2>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi index 71d6b5d0daf1..367aa3f94912 100644 --- a/arch/arm/boot/dts/armada-xp.dtsi +++ b/arch/arm/boot/dts/armada-xp.dtsi @@ -22,9 +22,22 @@ model = "Marvell Armada XP family SoC"; compatible = "marvell,armadaxp", "marvell,armada-370-xp"; + L2: l2-cache { + compatible = "marvell,aurora-system-cache"; + reg = <0xd0008000 0x1000>; + cache-id-part = <0x100>; + wt-override; + }; + mpic: interrupt-controller@d0020000 { reg = <0xd0020a00 0x1d0>, - <0xd0021870 0x58>; + <0xd0021070 0x58>; + }; + + armada-370-xp-pmsu@d0022000 { + compatible = "marvell,armada-370-xp-pmsu"; + reg = <0xd0022100 0x430>, + <0xd0020800 0x20>; }; soc { @@ -47,9 +60,85 @@ marvell,timer-25Mhz; }; + coreclk: mvebu-sar@d0018230 { + compatible = "marvell,armada-xp-core-clock"; + reg = <0xd0018230 0x08>; + #clock-cells = <1>; + }; + + cpuclk: clock-complex@d0018700 { + #clock-cells = <1>; + compatible = "marvell,armada-xp-cpu-clock"; + reg = <0xd0018700 0xA0>; + clocks = <&coreclk 1>; + }; + + gateclk: clock-gating-control@d0018220 { + compatible = "marvell,armada-xp-gating-clock"; + reg = <0xd0018220 0x4>; + clocks = <&coreclk 0>; + #clock-cells = <1>; + }; + system-controller@d0018200 { compatible = "marvell,armada-370-xp-system-controller"; reg = <0xd0018200 0x500>; }; + + ethernet@d0030000 { + compatible = "marvell,armada-370-neta"; + reg = <0xd0030000 0x2500>; + interrupts = <12>; + clocks = <&gateclk 2>; + status = "disabled"; + }; + + ethernet@d0034000 { + compatible = "marvell,armada-370-neta"; + reg = <0xd0034000 0x2500>; + interrupts = <14>; + clocks = <&gateclk 1>; + status = "disabled"; + }; + + xor@d0060900 { + compatible = "marvell,orion-xor"; + reg = <0xd0060900 0x100 + 0xd0060b00 0x100>; + clocks = <&gateclk 22>; + status = "okay"; + + xor10 { + interrupts = <51>; + dmacap,memcpy; + dmacap,xor; + }; + xor11 { + interrupts = <52>; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; + }; + + xor@d00f0900 { + compatible = "marvell,orion-xor"; + reg = <0xd00F0900 0x100 + 0xd00F0B00 0x100>; + clocks = <&gateclk 28>; + status = "okay"; + + xor00 { + interrupts = <94>; + dmacap,memcpy; + dmacap,xor; + }; + xor01 { + interrupts = <95>; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; + }; }; }; diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi index 61f391412a5a..f3f7e9d8adca 100644 --- a/arch/arm/boot/dts/dove.dtsi +++ b/arch/arm/boot/dts/dove.dtsi @@ -37,6 +37,19 @@ reg = <0x20204 0x04>, <0x20214 0x04>; }; + core_clk: core-clocks@d0214 { + compatible = "marvell,dove-core-clock"; + reg = <0xd0214 0x4>; + #clock-cells = <1>; + }; + + gate_clk: clock-gating-control@d0038 { + compatible = "marvell,dove-gating-clock"; + reg = <0xd0038 0x4>; + clocks = <&core_clk 0>; + #clock-cells = <1>; + }; + uart0: serial@12000 { compatible = "ns16550a"; reg = <0x12000 0x100>; @@ -113,6 +126,7 @@ cell-index = <0>; interrupts = <6>; reg = <0x10600 0x28>; + clocks = <&core_clk 0>; status = "disabled"; }; @@ -123,6 +137,7 @@ cell-index = <1>; interrupts = <5>; reg = <0x14600 0x28>; + clocks = <&core_clk 0>; status = "disabled"; }; @@ -134,6 +149,7 @@ interrupts = <11>; clock-frequency = <400000>; timeout-ms = <1000>; + clocks = <&core_clk 0>; status = "disabled"; }; @@ -141,6 +157,7 @@ compatible = "marvell,dove-sdhci"; reg = <0x92000 0x100>; interrupts = <35>, <37>; + clocks = <&gate_clk 8>; status = "disabled"; }; @@ -148,6 +165,7 @@ compatible = "marvell,dove-sdhci"; reg = <0x90000 0x100>; interrupts = <36>, <38>; + clocks = <&gate_clk 9>; status = "disabled"; }; @@ -155,6 +173,7 @@ compatible = "marvell,orion-sata"; reg = <0xa0000 0x2400>; interrupts = <62>; + clocks = <&gate_clk 3>; nr-ports = <1>; status = "disabled"; }; @@ -165,7 +184,50 @@ <0xc8000000 0x800>; reg-names = "regs", "sram"; interrupts = <31>; + clocks = <&gate_clk 15>; + status = "okay"; + }; + + xor0: dma-engine@60800 { + compatible = "marvell,orion-xor"; + reg = <0x60800 0x100 + 0x60a00 0x100>; + clocks = <&gate_clk 23>; status = "okay"; + + channel0 { + interrupts = <39>; + dmacap,memcpy; + dmacap,xor; + }; + + channel1 { + interrupts = <40>; + dmacap,memset; + dmacap,memcpy; + dmacap,xor; + }; + }; + + xor1: dma-engine@60900 { + compatible = "marvell,orion-xor"; + reg = <0x60900 0x100 + 0x60b00 0x100>; + clocks = <&gate_clk 24>; + status = "okay"; + + channel0 { + interrupts = <42>; + dmacap,memcpy; + dmacap,xor; + }; + + channel1 { + interrupts = <43>; + dmacap,memset; + dmacap,memcpy; + dmacap,xor; + }; }; }; }; diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 36d8246ea50e..2e3b6efaf1a2 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -35,6 +35,15 @@ mshc1 = &dwmmc_1; mshc2 = &dwmmc_2; mshc3 = &dwmmc_3; + i2c0 = &i2c_0; + i2c1 = &i2c_1; + i2c2 = &i2c_2; + i2c3 = &i2c_3; + i2c4 = &i2c_4; + i2c5 = &i2c_5; + i2c6 = &i2c_6; + i2c7 = &i2c_7; + i2c8 = &i2c_8; }; gic:interrupt-controller@10481000 { @@ -119,7 +128,7 @@ reg = <0x12170000 0x1ff>; }; - i2c@12C60000 { + i2c_0: i2c@12C60000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12C60000 0x100>; interrupts = <0 56 0>; @@ -127,7 +136,7 @@ #size-cells = <0>; }; - i2c@12C70000 { + i2c_1: i2c@12C70000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12C70000 0x100>; interrupts = <0 57 0>; @@ -135,7 +144,7 @@ #size-cells = <0>; }; - i2c@12C80000 { + i2c_2: i2c@12C80000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12C80000 0x100>; interrupts = <0 58 0>; @@ -143,7 +152,7 @@ #size-cells = <0>; }; - i2c@12C90000 { + i2c_3: i2c@12C90000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12C90000 0x100>; interrupts = <0 59 0>; @@ -151,7 +160,7 @@ #size-cells = <0>; }; - i2c@12CA0000 { + i2c_4: i2c@12CA0000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12CA0000 0x100>; interrupts = <0 60 0>; @@ -159,7 +168,7 @@ #size-cells = <0>; }; - i2c@12CB0000 { + i2c_5: i2c@12CB0000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12CB0000 0x100>; interrupts = <0 61 0>; @@ -167,7 +176,7 @@ #size-cells = <0>; }; - i2c@12CC0000 { + i2c_6: i2c@12CC0000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12CC0000 0x100>; interrupts = <0 62 0>; @@ -175,7 +184,7 @@ #size-cells = <0>; }; - i2c@12CD0000 { + i2c_7: i2c@12CD0000 { compatible = "samsung,s3c2440-i2c"; reg = <0x12CD0000 0x100>; interrupts = <0 63 0>; @@ -183,7 +192,7 @@ #size-cells = <0>; }; - i2c@12CE0000 { + i2c_8: i2c@12CE0000 { compatible = "samsung,s3c2440-hdmiphy-i2c"; reg = <0x12CE0000 0x1000>; interrupts = <0 64 0>; diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index a990c30f0a26..7735cee4a9c6 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi @@ -23,6 +23,12 @@ #address-cells = <1>; #size-cells = <1>; + core_clk: core-clocks@10030 { + compatible = "marvell,kirkwood-core-clock"; + reg = <0x10030 0x4>; + #clock-cells = <1>; + }; + gpio0: gpio@10100 { compatible = "marvell,orion-gpio"; #gpio-cells = <2>; @@ -48,6 +54,7 @@ reg = <0x12000 0x100>; reg-shift = <2>; interrupts = <33>; + clocks = <&gate_clk 7>; /* set clock-frequency in board dts */ status = "disabled"; }; @@ -57,6 +64,7 @@ reg = <0x12100 0x100>; reg-shift = <2>; interrupts = <34>; + clocks = <&gate_clk 7>; /* set clock-frequency in board dts */ status = "disabled"; }; @@ -74,13 +82,62 @@ cell-index = <0>; interrupts = <23>; reg = <0x10600 0x28>; + clocks = <&gate_clk 7>; status = "disabled"; }; + gate_clk: clock-gating-control@2011c { + compatible = "marvell,kirkwood-gating-clock"; + reg = <0x2011c 0x4>; + clocks = <&core_clk 0>; + #clock-cells = <1>; + }; + wdt@20300 { compatible = "marvell,orion-wdt"; reg = <0x20300 0x28>; + clocks = <&gate_clk 7>; + status = "okay"; + }; + + xor@60800 { + compatible = "marvell,orion-xor"; + reg = <0x60800 0x100 + 0x60A00 0x100>; + status = "okay"; + clocks = <&gate_clk 8>; + + xor00 { + interrupts = <5>; + dmacap,memcpy; + dmacap,xor; + }; + xor01 { + interrupts = <6>; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; + }; + + xor@60900 { + compatible = "marvell,orion-xor"; + reg = <0x60900 0x100 + 0xd0B00 0x100>; status = "okay"; + clocks = <&gate_clk 16>; + + xor00 { + interrupts = <7>; + dmacap,memcpy; + dmacap,xor; + }; + xor01 { + interrupts = <8>; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; }; ehci@50000 { @@ -94,6 +151,8 @@ compatible = "marvell,orion-sata"; reg = <0x80000 0x5000>; interrupts = <21>; + clocks = <&gate_clk 14>, <&gate_clk 15>; + clock-names = "0", "1"; status = "disabled"; }; @@ -107,6 +166,7 @@ reg = <0x3000000 0x400>; chip-delay = <25>; /* set partition map and/or chip-delay in board dts */ + clocks = <&gate_clk 7>; status = "disabled"; }; @@ -117,6 +177,7 @@ #size-cells = <0>; interrupts = <29>; clock-frequency = <100000>; + clocks = <&gate_clk 7>; status = "disabled"; }; @@ -126,6 +187,7 @@ <0xf5000000 0x800>; reg-names = "regs", "sram"; interrupts = <22>; + clocks = <&gate_clk 17>; status = "okay"; }; }; diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi index 0772f5739f59..19aec421bb26 100644 --- a/arch/arm/boot/dts/socfpga.dtsi +++ b/arch/arm/boot/dts/socfpga.dtsi @@ -143,5 +143,15 @@ reg-shift = <2>; reg-io-width = <4>; }; + + rstmgr@ffd05000 { + compatible = "altr,rst-mgr"; + reg = <0xffd05000 0x1000>; + }; + + sysmgr@ffd08000 { + compatible = "altr,sys-mgr"; + reg = <0xffd08000 0x4000>; + }; }; }; diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts index 2e4c5727468e..b56a801e42a2 100644 --- a/arch/arm/boot/dts/spear1310-evb.dts +++ b/arch/arm/boot/dts/spear1310-evb.dts @@ -30,10 +30,14 @@ pinctrl-0 = <&state_default>; state_default: pinmux { - i2c0-pmx { + i2c0 { st,pins = "i2c0_grp"; st,function = "i2c0"; }; + i2s0 { + st,pins = "i2s0_grp"; + st,function = "i2s0"; + }; i2s1 { st,pins = "i2s1_grp"; st,function = "i2s1"; @@ -42,6 +46,10 @@ st,pins = "arm_gpio_grp"; st,function = "arm_gpio"; }; + clcd { + st,pins = "clcd_grp" , "clcd_high_res"; + st,function = "clcd"; + }; eth { st,pins = "gmii_grp"; st,function = "gmii"; @@ -74,11 +82,6 @@ st,pins = "i2c_1_2_grp"; st,function = "i2c_1_2"; }; - pci { - st,pins = "pcie0_grp","pcie1_grp", - "pcie2_grp"; - st,function = "pci"; - }; smii { st,pins = "smii_0_1_2_grp"; st,function = "smii_0_1_2"; @@ -88,6 +91,14 @@ "nand_16bit_grp"; st,function = "nand"; }; + sata { + st,pins = "sata0_grp"; + st,function = "sata"; + }; + pcie { + st,pins = "pcie1_grp", "pcie2_grp"; + st,function = "pci_express"; + }; }; }; @@ -109,9 +120,49 @@ fsmc: flash@b0000000 { status = "okay"; + + partition@0 { + label = "xloader"; + reg = <0x0 0x80000>; + }; + partition@80000 { + label = "u-boot"; + reg = <0x80000 0x140000>; + }; + partition@1C0000 { + label = "environment"; + reg = <0x1C0000 0x40000>; + }; + partition@200000 { + label = "dtb"; + reg = <0x200000 0x40000>; + }; + partition@240000 { + label = "linux"; + reg = <0x240000 0xC00000>; + }; + partition@E40000 { + label = "rootfs"; + reg = <0xE40000 0x0>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + button@1 { + label = "wakeup"; + linux,code = <0x100>; + gpios = <&gpio0 7 0x4>; + debounce-interval = <20>; + gpio-key,wakeup = <1>; + }; }; gmac0: eth@e2000000 { + phy-mode = "gmii"; status = "okay"; }; @@ -135,23 +186,27 @@ }; partition@10000 { label = "u-boot"; - reg = <0x10000 0x40000>; + reg = <0x10000 0x50000>; + }; + partition@60000 { + label = "environment"; + reg = <0x60000 0x10000>; }; - partition@50000 { + partition@70000 { + label = "dtb"; + reg = <0x70000 0x10000>; + }; + partition@80000 { label = "linux"; - reg = <0x50000 0x2c0000>; + reg = <0x80000 0x310000>; }; - partition@310000 { + partition@390000 { label = "rootfs"; - reg = <0x310000 0x4f0000>; + reg = <0x390000 0x0>; }; }; }; - spi0: spi@e0100000 { - status = "okay"; - }; - ehci@e4800000 { status = "okay"; }; @@ -189,10 +244,6 @@ status = "okay"; }; - i2c1: i2c@5cd00000 { - status = "okay"; - }; - kbd@e0300000 { linux,keymap = < 0x00000001 0x00010002 @@ -277,6 +328,7 @@ 0x08080052 >; autorepeat; st,mode = <0>; + suspended_rate = <2000000>; status = "okay"; }; @@ -286,6 +338,81 @@ serial@e0000000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + + spi0: spi@e0100000 { + status = "okay"; + num-cs = <3>; + cs-gpios = <&gpio1 7 0>, <&spics 0>, <&spics 1>; + + stmpe610@0 { + compatible = "st,stmpe610"; + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <1000000>; + spi-cpha; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,slave-tx-disable; + pl022,com-mode = <0>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + pl022,ctrl-len = <0x7>; + pl022,wait-state = <0>; + pl022,duplex = <0>; + interrupts = <6 0x4>; + interrupt-parent = <&gpio1>; + irq-trigger = <0x2>; + + stmpe_touchscreen { + compatible = "st,stmpe-ts"; + ts,sample-time = <4>; + ts,mod-12b = <1>; + ts,ref-sel = <0>; + ts,adc-freq = <1>; + ts,ave-ctrl = <1>; + ts,touch-det-delay = <2>; + ts,settling = <2>; + ts,fraction-z = <7>; + ts,i-drive = <1>; + }; + }; + + m25p80@1 { + compatible = "st,m25p80"; + reg = <1>; + spi-max-frequency = <12000000>; + spi-cpol; + spi-cpha; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,slave-tx-disable; + pl022,com-mode = <0x2>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + pl022,ctrl-len = <0x11>; + pl022,wait-state = <0>; + pl022,duplex = <0>; + }; + + spidev@2 { + compatible = "spidev"; + reg = <2>; + spi-max-frequency = <25000000>; + spi-cpha; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,slave-tx-disable; + pl022,com-mode = <0x2>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + pl022,ctrl-len = <0x11>; + pl022,wait-state = <0>; + pl022,duplex = <0>; + }; }; wdt@ec800620 { diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi index 7cd25eb4f8e0..1513c1927cc8 100644 --- a/arch/arm/boot/dts/spear1310.dtsi +++ b/arch/arm/boot/dts/spear1310.dtsi @@ -17,6 +17,18 @@ compatible = "st,spear1310"; ahb { + spics: spics@e0700000{ + compatible = "st,spear-spics-gpio"; + reg = <0xe0700000 0x1000>; + st-spics,peripcfg-reg = <0x3b0>; + st-spics,sw-enable-bit = <12>; + st-spics,cs-value-bit = <11>; + st-spics,cs-enable-mask = <3>; + st-spics,cs-enable-shift = <8>; + gpio-controller; + #gpio-cells = <2>; + }; + ahci@b1000000 { compatible = "snps,spear-ahci"; reg = <0xb1000000 0x10000>; @@ -43,6 +55,7 @@ reg = <0x5c400000 0x8000>; interrupts = <0 95 0x4>; interrupt-names = "macirq"; + phy-mode = "mii"; status = "disabled"; }; @@ -51,6 +64,7 @@ reg = <0x5c500000 0x8000>; interrupts = <0 96 0x4>; interrupt-names = "macirq"; + phy-mode = "mii"; status = "disabled"; }; @@ -59,6 +73,7 @@ reg = <0x5c600000 0x8000>; interrupts = <0 97 0x4>; interrupt-names = "macirq"; + phy-mode = "rmii"; status = "disabled"; }; @@ -67,6 +82,7 @@ reg = <0x5c700000 0x8000>; interrupts = <0 98 0x4>; interrupt-names = "macirq"; + phy-mode = "rgmii"; status = "disabled"; }; @@ -76,13 +92,6 @@ #gpio-range-cells = <2>; }; - spi1: spi@5d400000 { - compatible = "arm,pl022", "arm,primecell"; - reg = <0x5d400000 0x1000>; - interrupts = <0 99 0x4>; - status = "disabled"; - }; - apb { i2c1: i2c@5cd00000 { #address-cells = <1>; @@ -147,6 +156,15 @@ status = "disabled"; }; + spi1: spi@5d400000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x5d400000 0x1000>; + interrupts = <0 99 0x4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + serial@5c800000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x5c800000 0x1000>; diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts index 045f7123ffac..d6c30ae0a8d7 100644 --- a/arch/arm/boot/dts/spear1340-evb.dts +++ b/arch/arm/boot/dts/spear1340-evb.dts @@ -38,20 +38,15 @@ st,pins = "fsmc_8bit_grp"; st,function = "fsmc"; }; - kbd { - st,pins = "keyboard_row_col_grp", - "keyboard_col5_grp"; - st,function = "keyboard"; - }; uart0 { - st,pins = "uart0_grp", "uart0_enh_grp"; + st,pins = "uart0_grp"; st,function = "uart0"; }; - i2c0-pmx { + i2c0 { st,pins = "i2c0_grp"; st,function = "i2c0"; }; - i2c1-pmx { + i2c1 { st,pins = "i2c1_grp"; st,function = "i2c1"; }; @@ -64,14 +59,9 @@ st,function = "spdif_out"; }; ssp0 { - st,pins = "ssp0_grp", "ssp0_cs1_grp", - "ssp0_cs3_grp"; + st,pins = "ssp0_grp", "ssp0_cs1_grp", "ssp0_cs2_grp", "ssp0_cs3_grp"; st,function = "ssp0"; }; - pwm { - st,pins = "pwm2_grp", "pwm3_grp"; - st,function = "pwm"; - }; smi-pmx { st,pins = "smi_grp"; st,function = "smi"; @@ -84,6 +74,18 @@ st,pins = "gmii_grp", "rgmii_grp"; st,function = "gmac"; }; + cam0 { + st,pins = "cam0_grp"; + st,function = "cam0"; + }; + cam1 { + st,pins = "cam1_grp"; + st,function = "cam1"; + }; + cam2 { + st,pins = "cam2_grp"; + st,function = "cam2"; + }; cam3 { st,pins = "cam3_grp"; st,function = "cam3"; @@ -108,9 +110,18 @@ st,pins = "sata_grp"; st,function = "sata"; }; + pcie { + st,pins = "pcie_grp"; + st,function = "pcie"; + }; + }; }; + ahci@b1000000 { + status = "okay"; + }; + dma@ea800000 { status = "okay"; }; @@ -121,9 +132,35 @@ fsmc: flash@b0000000 { status = "okay"; + + partition@0 { + label = "xloader"; + reg = <0x0 0x200000>; + }; + partition@200000 { + label = "u-boot"; + reg = <0x200000 0x200000>; + }; + partition@400000 { + label = "environment"; + reg = <0x400000 0x100000>; + }; + partition@500000 { + label = "dtb"; + reg = <0x500000 0x100000>; + }; + partition@600000 { + label = "linux"; + reg = <0x600000 0xC00000>; + }; + partition@1200000 { + label = "rootfs"; + reg = <0x1200000 0x0>; + }; }; gmac0: eth@e2000000 { + phy-mode = "rgmii"; status = "okay"; }; @@ -147,31 +184,62 @@ }; partition@10000 { label = "u-boot"; - reg = <0x10000 0x40000>; + reg = <0x10000 0x50000>; + }; + partition@60000 { + label = "environment"; + reg = <0x60000 0x10000>; }; - partition@50000 { + partition@70000 { + label = "dtb"; + reg = <0x70000 0x10000>; + }; + partition@80000 { label = "linux"; - reg = <0x50000 0x2c0000>; + reg = <0x80000 0x310000>; }; - partition@310000 { + partition@390000 { label = "rootfs"; - reg = <0x310000 0x4f0000>; + reg = <0x390000 0x0>; }; }; }; - spi0: spi@e0100000 { + ehci@e4800000 { status = "okay"; }; - ehci@e4800000 { - status = "okay"; + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + button@1 { + label = "wakeup"; + linux,code = <0x100>; + gpios = <&gpio1 1 0x4>; + debounce-interval = <20>; + gpio-key,wakeup = <1>; + }; }; ehci@e5800000 { status = "okay"; }; + i2s0: i2s-play@b2400000 { + status = "okay"; + }; + + i2s1: i2s-rec@b2000000 { + status = "okay"; + }; + + incodec: dir-hifi { + compatible = "dummy,dir-hifi"; + status = "okay"; + }; + ohci@e4000000 { status = "okay"; }; @@ -180,11 +248,43 @@ status = "okay"; }; + outcodec: dit-hifi { + compatible = "dummy,dit-hifi"; + status = "okay"; + }; + + sound { + compatible = "spear,spear-evb"; + audio-controllers = <&spdif0 &spdif1 &i2s0 &i2s1>; + audio-codecs = <&incodec &outcodec &sta529 &sta529>; + codec_dai_name = "dir-hifi", "dit-hifi", "sta529-audio", "sta529-audio"; + stream_name = "spdif-cap", "spdif-play", "i2s-play", "i2s-cap"; + dai_name = "spdifin-pcm", "spdifout-pcm", "i2s0-pcm", "i2s1-pcm"; + nr_controllers = <4>; + status = "okay"; + }; + + spdif0: spdif-in@d0100000 { + status = "okay"; + }; + + spdif1: spdif-out@d0000000 { + status = "okay"; + }; + apb { adc@e0080000 { status = "okay"; }; + i2s-play@b2400000 { + status = "okay"; + }; + + i2s-rec@b2000000 { + status = "okay"; + }; + gpio0: gpio@e0600000 { status = "okay"; }; @@ -199,10 +299,36 @@ i2c0: i2c@e0280000 { status = "okay"; + + sta529: sta529@1a { + compatible = "st,sta529"; + reg = <0x1a>; + }; }; i2c1: i2c@b4000000 { status = "okay"; + + eeprom0@56 { + compatible = "st,eeprom"; + reg = <0x56>; + }; + + stmpe801@41 { + compatible = "st,stmpe801"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x41>; + interrupts = <4 0x4>; + interrupt-parent = <&gpio0>; + irq-trigger = <0x2>; + + stmpegpio: stmpe_gpio { + compatible = "st,stmpe-gpio"; + gpio-controller; + #gpio-cells = <2>; + }; + }; }; kbd@e0300000 { @@ -289,6 +415,7 @@ 0x08080052 >; autorepeat; st,mode = <0>; + suspended_rate = <2000000>; status = "okay"; }; @@ -298,10 +425,92 @@ serial@e0000000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; }; serial@b4100000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + + spi0: spi@e0100000 { + status = "okay"; + num-cs = <3>; + cs-gpios = <&gpiopinctrl 80 0>, <&gpiopinctrl 24 0>, + <&gpiopinctrl 85 0>; + + m25p80@0 { + compatible = "m25p80"; + reg = <0>; + spi-max-frequency = <12000000>; + spi-cpol; + spi-cpha; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,slave-tx-disable; + pl022,com-mode = <0x2>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + pl022,ctrl-len = <0x11>; + pl022,wait-state = <0>; + pl022,duplex = <0>; + }; + + stmpe610@1 { + compatible = "st,stmpe610"; + spi-max-frequency = <1000000>; + spi-cpha; + reg = <1>; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,slave-tx-disable; + pl022,com-mode = <0>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + pl022,ctrl-len = <0x7>; + pl022,wait-state = <0>; + pl022,duplex = <0>; + interrupts = <100 0>; + interrupt-parent = <&gpiopinctrl>; + irq-trigger = <0x2>; + #address-cells = <1>; + #size-cells = <0>; + + stmpe_touchscreen { + compatible = "st,stmpe-ts"; + ts,sample-time = <4>; + ts,mod-12b = <1>; + ts,ref-sel = <0>; + ts,adc-freq = <1>; + ts,ave-ctrl = <1>; + ts,touch-det-delay = <2>; + ts,settling = <2>; + ts,fraction-z = <7>; + ts,i-drive = <1>; + }; + }; + + spidev@2 { + compatible = "spidev"; + reg = <2>; + spi-max-frequency = <25000000>; + spi-cpha; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,slave-tx-disable; + pl022,com-mode = <0x2>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + pl022,ctrl-len = <0x11>; + pl022,wait-state = <0>; + pl022,duplex = <0>; + }; + }; + + timer@ec800600 { + status = "okay"; }; wdt@ec800620 { diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi index 6c09eb0a1b2b..34da11aa6795 100644 --- a/arch/arm/boot/dts/spear1340.dtsi +++ b/arch/arm/boot/dts/spear1340.dtsi @@ -17,6 +17,20 @@ compatible = "st,spear1340"; ahb { + + spics: spics@e0700000{ + compatible = "st,spear-spics-gpio"; + reg = <0xe0700000 0x1000>; + st-spics,peripcfg-reg = <0x42c>; + st-spics,sw-enable-bit = <21>; + st-spics,cs-value-bit = <20>; + st-spics,cs-enable-mask = <3>; + st-spics,cs-enable-shift = <18>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + ahci@b1000000 { compatible = "snps,spear-ahci"; reg = <0xb1000000 0x10000>; @@ -24,15 +38,61 @@ status = "disabled"; }; + i2s-play@b2400000 { + compatible = "snps,designware-i2s"; + reg = <0xb2400000 0x10000>; + interrupt-names = "play_irq"; + interrupts = <0 98 0x4 + 0 99 0x4>; + play; + channel = <8>; + status = "disabled"; + }; + + i2s-rec@b2000000 { + compatible = "snps,designware-i2s"; + reg = <0xb2000000 0x10000>; + interrupt-names = "record_irq"; + interrupts = <0 100 0x4 + 0 101 0x4>; + record; + channel = <8>; + status = "disabled"; + }; + pinmux: pinmux@e0700000 { compatible = "st,spear1340-pinmux"; reg = <0xe0700000 0x1000>; #gpio-range-cells = <2>; }; + pwm: pwm@e0180000 { + compatible ="st,spear13xx-pwm"; + reg = <0xe0180000 0x1000>; + #pwm-cells = <2>; + status = "disabled"; + }; + + spdif-in@d0100000 { + compatible = "st,spdif-in"; + reg = < 0xd0100000 0x20000 + 0xd0110000 0x10000 >; + interrupts = <0 84 0x4>; + status = "disabled"; + }; + + spdif-out@d0000000 { + compatible = "st,spdif-out"; + reg = <0xd0000000 0x20000>; + interrupts = <0 85 0x4>; + status = "disabled"; + }; + spi1: spi@5d400000 { compatible = "arm,pl022", "arm,primecell"; reg = <0x5d400000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; interrupts = <0 99 0x4>; status = "disabled"; }; @@ -44,6 +104,7 @@ compatible = "snps,designware-i2c"; reg = <0xb4000000 0x1000>; interrupts = <0 104 0x4>; + write-16bit; status = "disabled"; }; diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi index f7b84aced654..009096d1d2c3 100644 --- a/arch/arm/boot/dts/spear13xx.dtsi +++ b/arch/arm/boot/dts/spear13xx.dtsi @@ -64,12 +64,26 @@ bootargs = "console=ttyAMA0,115200"; }; + cpufreq { + compatible = "st,cpufreq-spear"; + cpufreq_tbl = < 166000 + 200000 + 250000 + 300000 + 400000 + 500000 + 600000 >; + status = "disable"; + }; + ahb { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; ranges = <0x50000000 0x50000000 0x10000000 0xb0000000 0xb0000000 0x10000000 + 0xd0000000 0xd0000000 0x02000000 + 0xd8000000 0xd8000000 0x01000000 0xe0000000 0xe0000000 0x10000000>; sdhci@b3000000 { @@ -81,7 +95,7 @@ cf@b2800000 { compatible = "arasan,cf-spear1340"; - reg = <0xb2800000 0x100>; + reg = <0xb2800000 0x1000>; interrupts = <0 29 0x4>; status = "disabled"; }; @@ -113,6 +127,7 @@ 0 23 0x4>; st,ale-off = <0x20000>; st,cle-off = <0x10000>; + st,mode = <2>; status = "disabled"; }; @@ -125,6 +140,13 @@ status = "disabled"; }; + pcm { + compatible = "st,pcm-audio"; + #address-cells = <0>; + #size-cells = <0>; + status = "disable"; + }; + smi: flash@ea000000 { compatible = "st,spear600-smi"; #address-cells = <1>; @@ -134,17 +156,11 @@ status = "disabled"; }; - spi0: spi@e0100000 { - compatible = "arm,pl022", "arm,primecell"; - reg = <0xe0100000 0x1000>; - interrupts = <0 31 0x4>; - status = "disabled"; - }; - ehci@e4800000 { compatible = "st,spear600-ehci", "usb-ehci"; reg = <0xe4800000 0x1000>; interrupts = <0 64 0x4>; + usbh0_id = <0>; status = "disabled"; }; @@ -152,6 +168,7 @@ compatible = "st,spear600-ehci", "usb-ehci"; reg = <0xe5800000 0x1000>; interrupts = <0 66 0x4>; + usbh1_id = <1>; status = "disabled"; }; @@ -159,6 +176,7 @@ compatible = "st,spear600-ohci", "usb-ohci"; reg = <0xe4000000 0x1000>; interrupts = <0 65 0x4>; + usbh0_id = <0>; status = "disabled"; }; @@ -166,6 +184,7 @@ compatible = "st,spear600-ohci", "usb-ohci"; reg = <0xe5000000 0x1000>; interrupts = <0 67 0x4>; + usbh1_id = <1>; status = "disabled"; }; @@ -175,6 +194,8 @@ compatible = "simple-bus"; ranges = <0x50000000 0x50000000 0x10000000 0xb0000000 0xb0000000 0x10000000 + 0xd0000000 0xd0000000 0x02000000 + 0xd8000000 0xd8000000 0x01000000 0xe0000000 0xe0000000 0x10000000>; gpio0: gpio@e0600000 { @@ -215,8 +236,35 @@ status = "disabled"; }; + i2s@e0180000 { + compatible = "st,designware-i2s"; + reg = <0xe0180000 0x1000>; + interrupt-names = "play_irq", "record_irq"; + interrupts = <0 10 0x4 + 0 11 0x4 >; + status = "disabled"; + }; + + i2s@e0200000 { + compatible = "st,designware-i2s"; + reg = <0xe0200000 0x1000>; + interrupt-names = "play_irq", "record_irq"; + interrupts = <0 26 0x4 + 0 53 0x4>; + status = "disabled"; + }; + + spi0: spi@e0100000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0xe0100000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0 31 0x4>; + status = "disabled"; + }; + rtc@e0580000 { - compatible = "st,spear-rtc"; + compatible = "st,spear600-rtc"; reg = <0xe0580000 0x1000>; interrupts = <0 36 0x4>; status = "disabled"; @@ -232,7 +280,7 @@ adc@e0080000 { compatible = "st,spear600-adc"; reg = <0xe0080000 0x1000>; - interrupts = <0 44 0x4>; + interrupts = <0 12 0x4>; status = "disabled"; }; @@ -245,7 +293,8 @@ timer@ec800600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0xec800600 0x20>; - interrupts = <1 13 0x301>; + interrupts = <1 13 0x4>; + status = "disabled"; }; wdt@ec800620 { @@ -257,6 +306,7 @@ thermal@e07008c4 { compatible = "st,thermal-spear1340"; reg = <0xe07008c4 0x4>; + thermal_flags = <0x7000>; }; }; }; diff --git a/arch/arm/boot/dts/spear300-evb.dts b/arch/arm/boot/dts/spear300-evb.dts index 1e7c7a8e2123..5de1431653e4 100644 --- a/arch/arm/boot/dts/spear300-evb.dts +++ b/arch/arm/boot/dts/spear300-evb.dts @@ -100,15 +100,23 @@ }; partition@10000 { label = "u-boot"; - reg = <0x10000 0x40000>; + reg = <0x10000 0x50000>; }; - partition@50000 { + partition@60000 { + label = "environment"; + reg = <0x60000 0x10000>; + }; + partition@70000 { + label = "dtb"; + reg = <0x70000 0x10000>; + }; + partition@80000 { label = "linux"; - reg = <0x50000 0x2c0000>; + reg = <0x80000 0x310000>; }; - partition@310000 { + partition@390000 { label = "rootfs"; - reg = <0x310000 0x4f0000>; + reg = <0x390000 0x0>; }; }; }; @@ -235,6 +243,8 @@ serial@d0000000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; }; wdt@fc880000 { diff --git a/arch/arm/boot/dts/spear300.dtsi b/arch/arm/boot/dts/spear300.dtsi index ed3627c116cc..090adc656015 100644 --- a/arch/arm/boot/dts/spear300.dtsi +++ b/arch/arm/boot/dts/spear300.dtsi @@ -27,7 +27,7 @@ }; clcd@60000000 { - compatible = "arm,clcd-pl110", "arm,primecell"; + compatible = "arm,pl110", "arm,primecell"; reg = <0x60000000 0x1000>; interrupts = <30>; status = "disabled"; @@ -52,6 +52,14 @@ status = "disabled"; }; + shirq: interrupt-controller@0x50000000 { + compatible = "st,spear300-shirq"; + reg = <0x50000000 0x1000>; + interrupts = <28>; + #interrupt-cells = <1>; + interrupt-controller; + }; + apb { #address-cells = <1>; #size-cells = <1>; @@ -64,12 +72,16 @@ compatible = "arm,pl061", "arm,primecell"; gpio-controller; reg = <0xa9000000 0x1000>; + interrupts = <8>; + interrupt-parent = <&shirq>; status = "disabled"; }; kbd@a0000000 { compatible = "st,spear300-kbd"; reg = <0xa0000000 0x1000>; + interrupts = <7>; + interrupt-parent = <&shirq>; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/spear310-evb.dts b/arch/arm/boot/dts/spear310-evb.dts index b00544e0cd5d..b09632963d15 100644 --- a/arch/arm/boot/dts/spear310-evb.dts +++ b/arch/arm/boot/dts/spear310-evb.dts @@ -114,15 +114,23 @@ }; partition@10000 { label = "u-boot"; - reg = <0x10000 0x40000>; + reg = <0x10000 0x50000>; }; - partition@50000 { + partition@60000 { + label = "environment"; + reg = <0x60000 0x10000>; + }; + partition@70000 { + label = "dtb"; + reg = <0x70000 0x10000>; + }; + partition@80000 { label = "linux"; - reg = <0x50000 0x2c0000>; + reg = <0x80000 0x310000>; }; - partition@310000 { + partition@390000 { label = "rootfs"; - reg = <0x310000 0x4f0000>; + reg = <0x390000 0x0>; }; }; }; @@ -158,26 +166,38 @@ serial@d0000000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; }; serial@b2000000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; }; serial@b2080000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; }; serial@b2100000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; }; serial@b2180000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; }; serial@b2200000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; }; wdt@fc880000 { diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi index 930303e48df9..e814e5e97083 100644 --- a/arch/arm/boot/dts/spear310.dtsi +++ b/arch/arm/boot/dts/spear310.dtsi @@ -40,6 +40,14 @@ status = "disabled"; }; + shirq: interrupt-controller@0xb4000000 { + compatible = "st,spear310-shirq"; + reg = <0xb4000000 0x1000>; + interrupts = <28 29 30 1>; + #interrupt-cells = <1>; + interrupt-controller; + }; + apb { #address-cells = <1>; #size-cells = <1>; @@ -50,30 +58,40 @@ serial@b2000000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb2000000 0x1000>; + interrupts = <8>; + interrupt-parent = <&shirq>; status = "disabled"; }; serial@b2080000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb2080000 0x1000>; + interrupts = <9>; + interrupt-parent = <&shirq>; status = "disabled"; }; serial@b2100000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb2100000 0x1000>; + interrupts = <10>; + interrupt-parent = <&shirq>; status = "disabled"; }; serial@b2180000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb2180000 0x1000>; + interrupts = <11>; + interrupt-parent = <&shirq>; status = "disabled"; }; serial@b2200000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb2200000 0x1000>; + interrupts = <12>; + interrupt-parent = <&shirq>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts index ad4bfc68ee05..fdedbb514102 100644 --- a/arch/arm/boot/dts/spear320-evb.dts +++ b/arch/arm/boot/dts/spear320-evb.dts @@ -76,20 +76,12 @@ st,function = "mii2"; }; pwm0_1 { - st,pins = "pwm0_1_pin_14_15_grp"; + st,pins = "pwm0_1_pin_37_38_grp"; st,function = "pwm0_1"; }; - pwm2 { - st,pins = "pwm2_pin_13_grp"; - st,function = "pwm2"; - }; }; }; - clcd@90000000 { - status = "okay"; - }; - dma@fc400000 { status = "okay"; }; @@ -103,6 +95,7 @@ }; sdhci@70000000 { + power-gpio = <&gpiopinctrl 61 1>; status = "okay"; }; @@ -122,15 +115,23 @@ }; partition@10000 { label = "u-boot"; - reg = <0x10000 0x40000>; + reg = <0x10000 0x50000>; + }; + partition@60000 { + label = "environment"; + reg = <0x60000 0x10000>; + }; + partition@70000 { + label = "dtb"; + reg = <0x70000 0x10000>; }; - partition@50000 { + partition@80000 { label = "linux"; - reg = <0x50000 0x2c0000>; + reg = <0x80000 0x310000>; }; - partition@310000 { + partition@390000 { label = "rootfs"; - reg = <0x310000 0x4f0000>; + reg = <0x390000 0x0>; }; }; }; @@ -182,14 +183,20 @@ serial@d0000000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; }; serial@a3000000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; }; serial@a4000000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; }; wdt@fc880000 { diff --git a/arch/arm/boot/dts/spear320-hmi.dts b/arch/arm/boot/dts/spear320-hmi.dts new file mode 100644 index 000000000000..3075d2d3a8be --- /dev/null +++ b/arch/arm/boot/dts/spear320-hmi.dts @@ -0,0 +1,305 @@ +/* + * DTS file for SPEAr320 Evaluation Baord + * + * Copyright 2012 Shiraz Hashim <shiraz.hashim@st.com> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +/include/ "spear320.dtsi" + +/ { + model = "ST SPEAr320 HMI Board"; + compatible = "st,spear320-hmi", "st,spear320"; + #address-cells = <1>; + #size-cells = <1>; + + memory { + reg = <0 0x40000000>; + }; + + ahb { + pinmux@b3000000 { + st,pinmux-mode = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + + state_default: pinmux { + i2c0 { + st,pins = "i2c0_grp"; + st,function = "i2c0"; + }; + ssp0 { + st,pins = "ssp0_grp"; + st,function = "ssp0"; + }; + uart0 { + st,pins = "uart0_grp"; + st,function = "uart0"; + }; + clcd { + st,pins = "clcd_grp"; + st,function = "clcd"; + }; + fsmc { + st,pins = "fsmc_8bit_grp"; + st,function = "fsmc"; + }; + sdhci { + st,pins = "sdhci_cd_12_grp"; + st,function = "sdhci"; + }; + i2s { + st,pins = "i2s_grp"; + st,function = "i2s"; + }; + uart1 { + st,pins = "uart1_grp"; + st,function = "uart1"; + }; + uart2 { + st,pins = "uart2_grp"; + st,function = "uart2"; + }; + can0 { + st,pins = "can0_grp"; + st,function = "can0"; + }; + can1 { + st,pins = "can1_grp"; + st,function = "can1"; + }; + mii0_1 { + st,pins = "rmii0_1_grp"; + st,function = "mii0_1"; + }; + pwm0_1 { + st,pins = "pwm0_1_pin_37_38_grp"; + st,function = "pwm0_1"; + }; + pwm2 { + st,pins = "pwm2_pin_34_grp"; + st,function = "pwm2"; + }; + }; + }; + + clcd@90000000 { + status = "okay"; + }; + + dma@fc400000 { + status = "okay"; + }; + + ehci@e1800000 { + status = "okay"; + }; + + fsmc: flash@4c000000 { + status = "okay"; + + partition@0 { + label = "xloader"; + reg = <0x0 0x80000>; + }; + partition@80000 { + label = "u-boot"; + reg = <0x80000 0x140000>; + }; + partition@1C0000 { + label = "environment"; + reg = <0x1C0000 0x40000>; + }; + partition@200000 { + label = "dtb"; + reg = <0x200000 0x40000>; + }; + partition@240000 { + label = "linux"; + reg = <0x240000 0xC00000>; + }; + partition@E40000 { + label = "rootfs"; + reg = <0xE40000 0x0>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + button@1 { + label = "user button 1"; + linux,code = <0x100>; + gpios = <&stmpegpio 3 0x4>; + debounce-interval = <20>; + gpio-key,wakeup = <1>; + }; + + button@2 { + label = "user button 2"; + linux,code = <0x200>; + gpios = <&stmpegpio 2 0x4>; + debounce-interval = <20>; + gpio-key,wakeup = <1>; + }; + }; + + ohci@e1900000 { + status = "okay"; + }; + + ohci@e2100000 { + status = "okay"; + }; + + pwm: pwm@a8000000 { + status = "okay"; + }; + + sdhci@70000000 { + power-gpio = <&gpiopinctrl 50 1>; + power_always_enb; + status = "okay"; + }; + + smi: flash@fc000000 { + status = "okay"; + clock-rate=<50000000>; + + flash@f8000000 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0xf8000000 0x800000>; + st,smi-fast-mode; + + partition@0 { + label = "xloader"; + reg = <0x0 0x10000>; + }; + partition@10000 { + label = "u-boot"; + reg = <0x10000 0x50000>; + }; + partition@60000 { + label = "environment"; + reg = <0x60000 0x10000>; + }; + partition@70000 { + label = "dtb"; + reg = <0x70000 0x10000>; + }; + partition@80000 { + label = "linux"; + reg = <0x80000 0x310000>; + }; + partition@390000 { + label = "rootfs"; + reg = <0x390000 0x0>; + }; + }; + }; + + spi0: spi@d0100000 { + status = "okay"; + }; + + spi1: spi@a5000000 { + status = "okay"; + }; + + spi2: spi@a6000000 { + status = "okay"; + }; + + usbd@e1100000 { + status = "okay"; + }; + + apb { + gpio0: gpio@fc980000 { + status = "okay"; + }; + + gpio@b3000000 { + status = "okay"; + }; + + i2c0: i2c@d0180000 { + status = "okay"; + + stmpe811@41 { + compatible = "st,stmpe811"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x41>; + irq-over-gpio; + irq-gpios = <&gpiopinctrl 29 0x4>; + id = <0>; + blocks = <0x5>; + irq-trigger = <0x1>; + + stmpegpio: stmpe-gpio { + compatible = "stmpe,gpio"; + reg = <0>; + gpio-controller; + #gpio-cells = <2>; + gpio,norequest-mask = <0xF3>; + }; + + stmpe610-ts { + compatible = "stmpe,ts"; + reg = <0>; + ts,sample-time = <4>; + ts,mod-12b = <1>; + ts,ref-sel = <0>; + ts,adc-freq = <1>; + ts,ave-ctrl = <1>; + ts,touch-det-delay = <3>; + ts,settling = <4>; + ts,fraction-z = <7>; + ts,i-drive = <1>; + }; + }; + }; + + i2c1: i2c@a7000000 { + status = "okay"; + }; + + rtc@fc900000 { + status = "okay"; + }; + + serial@d0000000 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + + serial@a3000000 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + + serial@a4000000 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + + wdt@fc880000 { + status = "okay"; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi index 67d7ada71275..c056a84deabf 100644 --- a/arch/arm/boot/dts/spear320.dtsi +++ b/arch/arm/boot/dts/spear320.dtsi @@ -28,9 +28,10 @@ }; clcd@90000000 { - compatible = "arm,clcd-pl110", "arm,primecell"; + compatible = "arm,pl110", "arm,primecell"; reg = <0x90000000 0x1000>; - interrupts = <33>; + interrupts = <8>; + interrupt-parent = <&shirq>; status = "disabled"; }; @@ -49,27 +50,51 @@ sdhci@70000000 { compatible = "st,sdhci-spear"; reg = <0x70000000 0x100>; - interrupts = <29>; + interrupts = <10>; + interrupt-parent = <&shirq>; status = "disabled"; }; + shirq: interrupt-controller@0xb3000000 { + compatible = "st,spear320-shirq"; + reg = <0xb3000000 0x1000>; + interrupts = <30 28 29 1>; + #interrupt-cells = <1>; + interrupt-controller; + }; + spi1: spi@a5000000 { compatible = "arm,pl022", "arm,primecell"; reg = <0xa5000000 0x1000>; + interrupts = <15>; + interrupt-parent = <&shirq>; + #address-cells = <1>; + #size-cells = <0>; status = "disabled"; }; spi2: spi@a6000000 { compatible = "arm,pl022", "arm,primecell"; reg = <0xa6000000 0x1000>; + interrupts = <16>; + interrupt-parent = <&shirq>; + #address-cells = <1>; + #size-cells = <0>; status = "disabled"; }; + pwm: pwm@a8000000 { + compatible ="st,spear-pwm"; + reg = <0xa8000000 0x1000>; + #pwm-cells = <2>; + status = "disabled"; + }; + apb { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; - ranges = <0xa0000000 0xa0000000 0x10000000 + ranges = <0xa0000000 0xa0000000 0x20000000 0xd0000000 0xd0000000 0x30000000>; i2c1: i2c@a7000000 { @@ -77,18 +102,24 @@ #size-cells = <0>; compatible = "snps,designware-i2c"; reg = <0xa7000000 0x1000>; + interrupts = <21>; + interrupt-parent = <&shirq>; status = "disabled"; }; serial@a3000000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xa3000000 0x1000>; + interrupts = <13>; + interrupt-parent = <&shirq>; status = "disabled"; }; serial@a4000000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xa4000000 0x1000>; + interrupts = <14>; + interrupt-parent = <&shirq>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/spear3xx.dtsi b/arch/arm/boot/dts/spear3xx.dtsi index 3a8bb5736928..c2a852d43c48 100644 --- a/arch/arm/boot/dts/spear3xx.dtsi +++ b/arch/arm/boot/dts/spear3xx.dtsi @@ -53,6 +53,7 @@ reg = <0xe0800000 0x8000>; interrupts = <23 22>; interrupt-names = "macirq", "eth_wake_irq"; + phy-mode = "mii"; status = "disabled"; }; @@ -69,6 +70,8 @@ compatible = "arm,pl022", "arm,primecell"; reg = <0xd0100000 0x1000>; interrupts = <20>; + #address-cells = <1>; + #size-cells = <0>; status = "disabled"; }; @@ -120,7 +123,7 @@ }; rtc@fc900000 { - compatible = "st,spear-rtc"; + compatible = "st,spear600-rtc"; reg = <0xfc900000 0x1000>; interrupts = <10>; status = "disabled"; diff --git a/arch/arm/boot/dts/spear600-evb.dts b/arch/arm/boot/dts/spear600-evb.dts index 1119c22c9a82..d865a891776d 100644 --- a/arch/arm/boot/dts/spear600-evb.dts +++ b/arch/arm/boot/dts/spear600-evb.dts @@ -24,15 +24,35 @@ }; ahb { + clcd@fc200000 { + status = "okay"; + }; + dma@fc400000 { status = "okay"; }; + ehci@e1800000 { + status = "okay"; + }; + + ehci@e2000000 { + status = "okay"; + }; + gmac: ethernet@e0800000 { phy-mode = "gmii"; status = "okay"; }; + ohci@e1900000 { + status = "okay"; + }; + + ohci@e2100000 { + status = "okay"; + }; + smi: flash@fc000000 { status = "okay"; clock-rate=<50000000>; @@ -49,15 +69,23 @@ }; partition@10000 { label = "u-boot"; - reg = <0x10000 0x40000>; + reg = <0x10000 0x50000>; }; - partition@50000 { + partition@60000 { + label = "environment"; + reg = <0x60000 0x10000>; + }; + partition@70000 { + label = "dtb"; + reg = <0x70000 0x10000>; + }; + partition@80000 { label = "linux"; - reg = <0x50000 0x2c0000>; + reg = <0x80000 0x310000>; }; - partition@310000 { + partition@390000 { label = "rootfs"; - reg = <0x310000 0x4f0000>; + reg = <0x390000 0x0>; }; }; }; @@ -65,10 +93,18 @@ apb { serial@d0000000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; }; serial@d0080000 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <>; + }; + + rtc@fc900000 { + status = "okay"; }; i2c@d0200000 { diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi index a3c36e47d7ef..e051dde5181f 100644 --- a/arch/arm/boot/dts/spear600.dtsi +++ b/arch/arm/boot/dts/spear600.dtsi @@ -45,6 +45,14 @@ #interrupt-cells = <1>; }; + clcd@fc200000 { + compatible = "arm,pl110", "arm,primecell"; + reg = <0xfc200000 0x1000>; + interrupt-parent = <&vic1>; + interrupts = <12>; + status = "disabled"; + }; + dma@fc400000 { compatible = "arm,pl080", "arm,primecell"; reg = <0xfc400000 0x1000>; @@ -59,6 +67,7 @@ interrupt-parent = <&vic1>; interrupts = <24 23>; interrupt-names = "macirq", "eth_wake_irq"; + phy-mode = "gmii"; status = "disabled"; }; @@ -178,6 +187,13 @@ status = "disabled"; }; + rtc@fc900000 { + compatible = "st,spear600-rtc"; + reg = <0xfc900000 0x1000>; + interrupts = <10>; + status = "disabled"; + }; + timer@f0000000 { compatible = "st,spear-timer"; reg = <0xf0000000 0x400>; diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 159f75fc4377..dbea6f4efe9f 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -17,8 +17,10 @@ CONFIG_ARM_APPENDED_DTB=y CONFIG_VFP=y CONFIG_NEON=y CONFIG_NET=y +CONFIG_BLK_DEV_SD=y CONFIG_ATA=y CONFIG_SATA_HIGHBANK=y +CONFIG_SATA_MV=y CONFIG_NETDEVICES=y CONFIG_NET_CALXEDA_XGMAC=y CONFIG_SMSC911X=y diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig index 3458752c4bb2..a702fb345c01 100644 --- a/arch/arm/configs/mvebu_defconfig +++ b/arch/arm/configs/mvebu_defconfig @@ -12,6 +12,9 @@ CONFIG_ARCH_MVEBU=y CONFIG_MACH_ARMADA_370=y CONFIG_MACH_ARMADA_XP=y # CONFIG_CACHE_L2X0 is not set +# CONFIG_SWP_EMULATE is not set +CONFIG_SMP=y +# CONFIG_LOCAL_TIMERS is not set CONFIG_AEABI=y CONFIG_HIGHMEM=y # CONFIG_COMPACTION is not set @@ -19,13 +22,27 @@ CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_ARM_APPENDED_DTB=y CONFIG_VFP=y +CONFIG_NET=y +CONFIG_INET=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_BLK_DEV_SD=y +CONFIG_ATA=y +CONFIG_SATA_MV=y +CONFIG_NETDEVICES=y +CONFIG_MVNETA=y +CONFIG_MARVELL_PHY=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_I2C=y +CONFIG_I2C_MV64XXX=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y # CONFIG_USB_SUPPORT is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_S35390A=y +CONFIG_DMADEVICES=y +CONFIG_MV_XOR=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig index 0ac1293dba10..4e1ce211d43f 100644 --- a/arch/arm/configs/socfpga_defconfig +++ b/arch/arm/configs/socfpga_defconfig @@ -18,9 +18,10 @@ CONFIG_MODULE_UNLOAD=y CONFIG_ARCH_SOCFPGA=y CONFIG_MACH_SOCFPGA_CYCLONE5=y CONFIG_ARM_THUMBEE=y +# CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set # CONFIG_CACHE_L2X0 is not set CONFIG_HIGH_RES_TIMERS=y -CONFIG_VMSPLIT_2G=y +CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_AEABI=y CONFIG_ZBOOT_ROM_TEXT=0x0 diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 8ea02ac3ec1a..67d06324e74a 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -111,6 +111,8 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size, extern int dma_supported(struct device *dev, u64 mask); +extern int arm_dma_set_mask(struct device *dev, u64 dma_mask); + /** * arm_dma_alloc - allocate consistent memory for DMA * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig index 00154e74ce6b..603c5fd99e8a 100644 --- a/arch/arm/mach-dove/Kconfig +++ b/arch/arm/mach-dove/Kconfig @@ -17,6 +17,8 @@ config MACH_CM_A510 config MACH_DOVE_DT bool "Marvell Dove Flattened Device Tree" + select MVEBU_CLK_CORE + select MVEBU_CLK_GATING select USE_OF help Say 'Y' here if you want your kernel to support the diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index f723fe13d0f0..89f4f993cd03 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c @@ -14,6 +14,7 @@ #include <linux/platform_device.h> #include <linux/pci.h> #include <linux/clk-provider.h> +#include <linux/clk/mvebu.h> #include <linux/ata_platform.h> #include <linux/gpio.h> #include <linux/of.h> @@ -32,6 +33,7 @@ #include <linux/irq.h> #include <plat/time.h> #include <linux/platform_data/usb-ehci-orion.h> +#include <linux/platform_data/dma-mv_xor.h> #include <plat/irq.h> #include <plat/common.h> #include <plat/addr-map.h> @@ -123,8 +125,8 @@ static void __init dove_clk_init(void) orion_clkdev_add(NULL, "mv_crypto", crypto); orion_clkdev_add(NULL, "dove-ac97", ac97); orion_clkdev_add(NULL, "dove-pdma", pdma); - orion_clkdev_add(NULL, "mv_xor_shared.0", xor0); - orion_clkdev_add(NULL, "mv_xor_shared.1", xor1); + orion_clkdev_add(NULL, MV_XOR_NAME ".0", xor0); + orion_clkdev_add(NULL, MV_XOR_NAME ".1", xor1); } /***************************************************************************** @@ -376,19 +378,44 @@ void dove_restart(char mode, const char *cmd) #if defined(CONFIG_MACH_DOVE_DT) /* - * Auxdata required until real OF clock provider + * There are still devices that doesn't even know about DT, + * get clock gates here and add a clock lookup. */ -struct of_dev_auxdata dove_auxdata_lookup[] __initdata = { - OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL), - OF_DEV_AUXDATA("marvell,orion-spi", 0xf1014600, "orion_spi.1", NULL), - OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL), - OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0", - NULL), - OF_DEV_AUXDATA("marvell,orion-sata", 0xf10a0000, "sata_mv.0", NULL), - OF_DEV_AUXDATA("marvell,dove-sdhci", 0xf1092000, "sdhci-dove.0", NULL), - OF_DEV_AUXDATA("marvell,dove-sdhci", 0xf1090000, "sdhci-dove.1", NULL), - {}, -}; +static void __init dove_legacy_clk_init(void) +{ + struct device_node *np = of_find_compatible_node(NULL, NULL, + "marvell,dove-gating-clock"); + struct of_phandle_args clkspec; + + clkspec.np = np; + clkspec.args_count = 1; + + clkspec.args[0] = CLOCK_GATING_BIT_USB0; + orion_clkdev_add(NULL, "orion-ehci.0", + of_clk_get_from_provider(&clkspec)); + + clkspec.args[0] = CLOCK_GATING_BIT_USB1; + orion_clkdev_add(NULL, "orion-ehci.1", + of_clk_get_from_provider(&clkspec)); + + clkspec.args[0] = CLOCK_GATING_BIT_GBE; + orion_clkdev_add(NULL, "mv643xx_eth_port.0", + of_clk_get_from_provider(&clkspec)); + + clkspec.args[0] = CLOCK_GATING_BIT_PCIE0; + orion_clkdev_add("0", "pcie", + of_clk_get_from_provider(&clkspec)); + + clkspec.args[0] = CLOCK_GATING_BIT_PCIE1; + orion_clkdev_add("1", "pcie", + of_clk_get_from_provider(&clkspec)); +} + +static void __init dove_of_clk_init(void) +{ + mvebu_clocks_init(); + dove_legacy_clk_init(); +} static struct mv643xx_eth_platform_data dove_dt_ge00_data = { .phy_addr = MV643XX_ETH_PHY_ADDR_DEFAULT, @@ -405,20 +432,17 @@ static void __init dove_dt_init(void) dove_setup_cpu_mbus(); /* Setup root of clk tree */ - dove_clk_init(); + dove_of_clk_init(); /* Internal devices not ported to DT yet */ dove_rtc_init(); - dove_xor0_init(); - dove_xor1_init(); dove_ge00_init(&dove_dt_ge00_data); dove_ehci0_init(); dove_ehci1_init(); dove_pcie_init(1, 1); - of_platform_populate(NULL, of_default_bus_match_table, - dove_auxdata_lookup, NULL); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } static const char * const dove_dt_board_compat[] = { diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c index 7652f5d78a56..e9d7b80bae49 100644 --- a/arch/arm/mach-exynos/clock-exynos5.c +++ b/arch/arm/mach-exynos/clock-exynos5.c @@ -80,6 +80,8 @@ static struct sleep_save exynos5_clock_save[] = { SAVE_ITEM(EXYNOS5_VPLL_CON0), SAVE_ITEM(EXYNOS5_VPLL_CON1), SAVE_ITEM(EXYNOS5_VPLL_CON2), + SAVE_ITEM(EXYNOS5_PWR_CTRL1), + SAVE_ITEM(EXYNOS5_PWR_CTRL2), }; #endif @@ -661,15 +663,20 @@ static struct clk exynos5_init_clocks_off[] = { .ctrlbit = (1 << 15), }, { .name = "sata", - .devname = "ahci", + .devname = "exynos5-sata", + .parent = &exynos5_clk_aclk_200.clk, .enable = exynos5_clk_ip_fsys_ctrl, .ctrlbit = (1 << 6), }, { - .name = "sata_phy", + .name = "sata-phy", + .devname = "exynos5-sata-phy", + .parent = &exynos5_clk_aclk_200.clk, .enable = exynos5_clk_ip_fsys_ctrl, .ctrlbit = (1 << 24), }, { - .name = "sata_phy_i2c", + .name = "i2c", + .devname = "exynos5-sata-phy-i2c", + .parent = &exynos5_clk_aclk_200.clk, .enable = exynos5_clk_ip_fsys_ctrl, .ctrlbit = (1 << 25), }, { @@ -693,6 +700,11 @@ static struct clk exynos5_init_clocks_off[] = { .enable = exynos5_clk_ip_disp1_ctrl, .ctrlbit = (1 << 5), }, { + .name = "dp", + .devname = "exynos-dp", + .enable = exynos5_clk_ip_disp1_ctrl, + .ctrlbit = (1 << 4), + }, { .name = "jpeg", .enable = exynos5_clk_ip_gen_ctrl, .ctrlbit = (1 << 2), @@ -1241,6 +1253,16 @@ static struct clksrc_clk exynos5_clksrcs[] = { .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 }, }, { .clk = { + .name = "sclk_sata", + .devname = "exynos5-sata", + .enable = exynos5_clksrc_mask_fsys_ctrl, + .ctrlbit = (1 << 24), + }, + .sources = &exynos5_clkset_aclk, + .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 24, .size = 1 }, + .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS0, .shift = 20, .size = 4 }, + }, { + .clk = { .name = "sclk_gscl_wrap", .devname = "s5p-mipi-csis.0", .enable = exynos5_clksrc_mask_gscl_ctrl, diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c index 8e4ec21ef2cf..050924152776 100644 --- a/arch/arm/mach-exynos/cpuidle.c +++ b/arch/arm/mach-exynos/cpuidle.c @@ -21,6 +21,7 @@ #include <asm/suspend.h> #include <asm/unified.h> #include <asm/cpuidle.h> +#include <mach/regs-clock.h> #include <mach/regs-pmu.h> #include <mach/pmu.h> @@ -157,12 +158,47 @@ static int exynos4_enter_lowpower(struct cpuidle_device *dev, return exynos4_enter_core0_aftr(dev, drv, new_index); } +static void __init exynos5_core_down_clk(void) +{ + unsigned int tmp; + + /* + * Enable arm clock down (in idle) and set arm divider + * ratios in WFI/WFE state. + */ + tmp = PWR_CTRL1_CORE2_DOWN_RATIO | \ + PWR_CTRL1_CORE1_DOWN_RATIO | \ + PWR_CTRL1_DIV2_DOWN_EN | \ + PWR_CTRL1_DIV1_DOWN_EN | \ + PWR_CTRL1_USE_CORE1_WFE | \ + PWR_CTRL1_USE_CORE0_WFE | \ + PWR_CTRL1_USE_CORE1_WFI | \ + PWR_CTRL1_USE_CORE0_WFI; + __raw_writel(tmp, EXYNOS5_PWR_CTRL1); + + /* + * Enable arm clock up (on exiting idle). Set arm divider + * ratios when not in idle along with the standby duration + * ratios. + */ + tmp = PWR_CTRL2_DIV2_UP_EN | \ + PWR_CTRL2_DIV1_UP_EN | \ + PWR_CTRL2_DUR_STANDBY2_VAL | \ + PWR_CTRL2_DUR_STANDBY1_VAL | \ + PWR_CTRL2_CORE2_UP_RATIO | \ + PWR_CTRL2_CORE1_UP_RATIO; + __raw_writel(tmp, EXYNOS5_PWR_CTRL2); +} + static int __init exynos4_init_cpuidle(void) { int i, max_cpuidle_state, cpu_id; struct cpuidle_device *device; struct cpuidle_driver *drv = &exynos4_idle_driver; + if (soc_is_exynos5250()) + exynos5_core_down_clk(); + /* Setup cpuidle driver */ drv->state_count = (sizeof(exynos4_cpuidle_set) / sizeof(struct cpuidle_state)); diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h index 8c9b38c9c504..d36ad76ad6a4 100644 --- a/arch/arm/mach-exynos/include/mach/regs-clock.h +++ b/arch/arm/mach-exynos/include/mach/regs-clock.h @@ -267,6 +267,9 @@ #define EXYNOS5_CLKDIV_STATCPU0 EXYNOS_CLKREG(0x00600) #define EXYNOS5_CLKDIV_STATCPU1 EXYNOS_CLKREG(0x00604) +#define EXYNOS5_PWR_CTRL1 EXYNOS_CLKREG(0x01020) +#define EXYNOS5_PWR_CTRL2 EXYNOS_CLKREG(0x01024) + #define EXYNOS5_MPLL_CON0 EXYNOS_CLKREG(0x04100) #define EXYNOS5_CLKSRC_CORE1 EXYNOS_CLKREG(0x04204) @@ -344,6 +347,22 @@ #define EXYNOS5_EPLLCON0_LOCKED_SHIFT (29) +#define PWR_CTRL1_CORE2_DOWN_RATIO (7 << 28) +#define PWR_CTRL1_CORE1_DOWN_RATIO (7 << 16) +#define PWR_CTRL1_DIV2_DOWN_EN (1 << 9) +#define PWR_CTRL1_DIV1_DOWN_EN (1 << 8) +#define PWR_CTRL1_USE_CORE1_WFE (1 << 5) +#define PWR_CTRL1_USE_CORE0_WFE (1 << 4) +#define PWR_CTRL1_USE_CORE1_WFI (1 << 1) +#define PWR_CTRL1_USE_CORE0_WFI (1 << 0) + +#define PWR_CTRL2_DIV2_UP_EN (1 << 25) +#define PWR_CTRL2_DIV1_UP_EN (1 << 24) +#define PWR_CTRL2_DUR_STANDBY2_VAL (1 << 16) +#define PWR_CTRL2_DUR_STANDBY1_VAL (1 << 8) +#define PWR_CTRL2_CORE2_UP_RATIO (1 << 4) +#define PWR_CTRL2_CORE1_UP_RATIO (1 << 0) + /* Compatibility defines and inclusion */ #include <mach/regs-pmu.h> diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h index 84428e72cf5e..3f30aa1ae354 100644 --- a/arch/arm/mach-exynos/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h @@ -15,6 +15,7 @@ #include <mach/map.h> #define S5P_PMUREG(x) (S5P_VA_PMU + (x)) +#define S5P_SYSREG(x) (S3C_VA_SYS + (x)) #define S5P_CENTRAL_SEQ_CONFIGURATION S5P_PMUREG(0x0200) @@ -231,6 +232,8 @@ /* For EXYNOS5 */ +#define EXYNOS5_SYS_I2C_CFG S5P_SYSREG(0x0234) + #define EXYNOS5_AUTO_WDTRESET_DISABLE S5P_PMUREG(0x0408) #define EXYNOS5_MASK_WDTRESET_REQUEST S5P_PMUREG(0x040C) diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c index 929de766d490..f038c8cadca4 100644 --- a/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c @@ -13,11 +13,12 @@ #include <linux/of_fdt.h> #include <linux/serial_core.h> #include <linux/memblock.h> -#include <linux/of_fdt.h> +#include <linux/io.h> #include <asm/mach/arch.h> #include <asm/hardware/gic.h> #include <mach/map.h> +#include <mach/regs-pmu.h> #include <plat/cpu.h> #include <plat/regs-serial.h> @@ -124,6 +125,28 @@ static void __init exynos5_dt_map_io(void) static void __init exynos5_dt_machine_init(void) { + struct device_node *i2c_np; + const char *i2c_compat = "samsung,s3c2440-i2c"; + unsigned int tmp; + + /* + * Exynos5's legacy i2c controller and new high speed i2c + * controller have muxed interrupt sources. By default the + * interrupts for 4-channel HS-I2C controller are enabled. + * If node for first four channels of legacy i2c controller + * are available then re-configure the interrupts via the + * system register. + */ + for_each_compatible_node(i2c_np, NULL, i2c_compat) { + if (of_device_is_available(i2c_np)) { + if (of_alias_get_id(i2c_np, "i2c") < 4) { + tmp = readl(EXYNOS5_SYS_I2C_CFG); + writel(tmp & ~(0x1 << of_alias_get_id(i2c_np, "i2c")), + EXYNOS5_SYS_I2C_CFG); + } + } + } + if (of_machine_is_compatible("samsung,exynos5250")) of_platform_populate(NULL, of_default_bus_match_table, exynos5250_auxdata_lookup, NULL); diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index 8df6ec547f78..b9b539cac81e 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -62,6 +62,10 @@ static struct sleep_save exynos4_vpll_save[] = { SAVE_ITEM(EXYNOS4_VPLL_CON1), }; +static struct sleep_save exynos5_sys_save[] = { + SAVE_ITEM(EXYNOS5_SYS_I2C_CFG), +}; + static struct sleep_save exynos_core_save[] = { /* SROM side */ SAVE_ITEM(S5P_SROM_BW), @@ -101,6 +105,7 @@ static void exynos_pm_prepare(void) s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); } else { + s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save)); /* Disable USE_RETENTION of JPEG_MEM_OPTION */ tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION); tmp &= ~EXYNOS5_OPTION_USE_RETENTION; @@ -304,6 +309,10 @@ static void exynos_pm_resume(void) __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); + if (soc_is_exynos5250()) + s3c_pm_do_restore(exynos5_sys_save, + ARRAY_SIZE(exynos5_sys_save)); + s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); if (!soc_is_exynos5250()) { diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index 503d7dd944ff..f91cdff5a3e4 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig @@ -51,6 +51,8 @@ config ARCH_KIRKWOOD_DT select POWER_RESET_GPIO select REGULATOR select REGULATOR_FIXED_VOLTAGE + select MVEBU_CLK_CORE + select MVEBU_CLK_GATING select USE_OF help Say 'Y' here if you want your kernel to support the diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c index 375f7d88551c..ff4150a2ad05 100644 --- a/arch/arm/mach-kirkwood/board-dt.c +++ b/arch/arm/mach-kirkwood/board-dt.c @@ -14,11 +14,15 @@ #include <linux/init.h> #include <linux/of.h> #include <linux/of_platform.h> +#include <linux/clk-provider.h> +#include <linux/clk/mvebu.h> #include <linux/kexec.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <mach/bridge-regs.h> +#include <linux/platform_data/usb-ehci-orion.h> #include <plat/irq.h> +#include <plat/common.h> #include "common.h" static struct of_device_id kirkwood_dt_match_table[] __initdata = { @@ -26,18 +30,50 @@ static struct of_device_id kirkwood_dt_match_table[] __initdata = { { } }; -static struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = { - OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL), - OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0", - NULL), - OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011100, "mv64xxx_i2c.1", - NULL), - OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL), - OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL), - OF_DEV_AUXDATA("marvell,orion-nand", 0xf4000000, "orion_nand", NULL), - OF_DEV_AUXDATA("marvell,orion-crypto", 0xf1030000, "mv_crypto", NULL), - {}, -}; +/* + * There are still devices that doesn't know about DT yet. Get clock + * gates here and add a clock lookup alias, so that old platform + * devices still work. +*/ + +static void __init kirkwood_legacy_clk_init(void) +{ + + struct device_node *np = of_find_compatible_node( + NULL, NULL, "marvell,kirkwood-gating-clock"); + + struct of_phandle_args clkspec; + + clkspec.np = np; + clkspec.args_count = 1; + + clkspec.args[0] = CGC_BIT_GE0; + orion_clkdev_add(NULL, "mv643xx_eth_port.0", + of_clk_get_from_provider(&clkspec)); + + clkspec.args[0] = CGC_BIT_PEX0; + orion_clkdev_add("0", "pcie", + of_clk_get_from_provider(&clkspec)); + + clkspec.args[0] = CGC_BIT_USB0; + orion_clkdev_add(NULL, "orion-ehci.0", + of_clk_get_from_provider(&clkspec)); + + clkspec.args[0] = CGC_BIT_PEX1; + orion_clkdev_add("1", "pcie", + of_clk_get_from_provider(&clkspec)); + + clkspec.args[0] = CGC_BIT_GE1; + orion_clkdev_add(NULL, "mv643xx_eth_port.1", + of_clk_get_from_provider(&clkspec)); + +} + +static void __init kirkwood_of_clk_init(void) +{ + mvebu_clocks_init(); + kirkwood_legacy_clk_init(); +} static void __init kirkwood_dt_init(void) { @@ -56,11 +92,7 @@ static void __init kirkwood_dt_init(void) kirkwood_l2_init(); /* Setup root of clk tree */ - kirkwood_clk_init(); - - /* internal devices that every board has */ - kirkwood_xor0_init(); - kirkwood_xor1_init(); + kirkwood_of_clk_init(); #ifdef CONFIG_KEXEC kexec_reinit = kirkwood_enable_pcie; @@ -115,8 +147,7 @@ static void __init kirkwood_dt_init(void) if (of_machine_is_compatible("zyxel,nsa310")) nsa310_init(); - of_platform_populate(NULL, kirkwood_dt_match_table, - kirkwood_auxdata_lookup, NULL); + of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL); } static const char * const kirkwood_dt_board_compat[] = { diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 5303be62b311..bac21a554c91 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -260,8 +260,8 @@ void __init kirkwood_clk_init(void) orion_clkdev_add(NULL, "orion_nand", runit); orion_clkdev_add(NULL, "mvsdio", sdio); orion_clkdev_add(NULL, "mv_crypto", crypto); - orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".0", xor0); - orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".1", xor1); + orion_clkdev_add(NULL, MV_XOR_NAME ".0", xor0); + orion_clkdev_add(NULL, MV_XOR_NAME ".1", xor1); orion_clkdev_add("0", "pcie", pex0); orion_clkdev_add("1", "pcie", pex1); orion_clkdev_add(NULL, "kirkwood-i2s", audio); diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 416d46ef7ebd..440b13ef1fed 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -9,6 +9,10 @@ config ARCH_MVEBU select PINCTRL select PLAT_ORION select SPARSE_IRQ + select CLKDEV_LOOKUP + select MVEBU_CLK_CORE + select MVEBU_CLK_CPU + select MVEBU_CLK_GATING if ARCH_MVEBU @@ -17,7 +21,9 @@ menu "Marvell SOC with device tree" config MACH_ARMADA_370_XP bool select ARMADA_370_XP_TIMER - select CPU_V7 + select HAVE_SMP + select CACHE_L2X0 + select CPU_PJ4B config MACH_ARMADA_370 bool "Marvell Armada 370 boards" diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index 57f996b6aa0e..5dcb369b58aa 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile @@ -2,4 +2,6 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \ -I$(srctree)/arch/arm/plat-orion/include obj-y += system-controller.o -obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o +obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o coherency.o coherency_ll.o pmsu.o +obj-$(CONFIG_SMP) += platsmp.o headsmp.o +obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/arch/arm/mach-mvebu/addr-map.c b/arch/arm/mach-mvebu/addr-map.c index fe454a4430be..ab9b3bd4fef5 100644 --- a/arch/arm/mach-mvebu/addr-map.c +++ b/arch/arm/mach-mvebu/addr-map.c @@ -78,7 +78,7 @@ armada_cfg_base(const struct orion_addr_map_cfg *cfg, int win) if (win < 8) offset = (win << 4); else - offset = ARMADA_WINDOW_8_PLUS_OFFSET + (win << 3); + offset = ARMADA_WINDOW_8_PLUS_OFFSET + ((win - 8) << 3); return cfg->bridge_virt_base + offset; } @@ -108,6 +108,9 @@ static int __init armada_setup_cpu_mbus(void) addr_map_cfg.bridge_virt_base = mbus_unit_addr_decoding_base; + if (of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric")) + addr_map_cfg.hw_io_coherency = 1; + /* * Disable, clear and configure windows. */ diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c index 49d791548ad6..7434b5e36197 100644 --- a/arch/arm/mach-mvebu/armada-370-xp.c +++ b/arch/arm/mach-mvebu/armada-370-xp.c @@ -17,11 +17,14 @@ #include <linux/of_platform.h> #include <linux/io.h> #include <linux/time-armada-370-xp.h> +#include <linux/clk/mvebu.h> +#include <linux/dma-mapping.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/time.h> #include "armada-370-xp.h" #include "common.h" +#include "coherency.h" static struct map_desc armada_370_xp_io_desc[] __initdata = { { @@ -37,27 +40,45 @@ void __init armada_370_xp_map_io(void) iotable_init(armada_370_xp_io_desc, ARRAY_SIZE(armada_370_xp_io_desc)); } +void __init armada_370_xp_timer_and_clk_init(void) +{ + mvebu_clocks_init(); + armada_370_xp_timer_init(); +} + +void __init armada_370_xp_init_early(void) +{ + /* + * Some Armada 370/XP devices allocate their coherent buffers + * from atomic context. Increase size of atomic coherent pool + * to make sure such the allocations won't fail. + */ + init_dma_coherent_pool_size(SZ_1M); +} + struct sys_timer armada_370_xp_timer = { - .init = armada_370_xp_timer_init, + .init = armada_370_xp_timer_and_clk_init, }; static void __init armada_370_xp_dt_init(void) { of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + coherency_init(); } -static const char * const armada_370_xp_dt_board_dt_compat[] = { - "marvell,a370-db", - "marvell,axp-db", +static const char * const armada_370_xp_dt_compat[] = { + "marvell,armada-370-xp", NULL, }; -DT_MACHINE_START(ARMADA_XP_DT, "Marvell Aramada 370/XP (Device Tree)") +DT_MACHINE_START(ARMADA_XP_DT, "Marvell Armada 370/XP (Device Tree)") + .smp = smp_ops(armada_xp_smp_ops), .init_machine = armada_370_xp_dt_init, .map_io = armada_370_xp_map_io, + .init_early = armada_370_xp_init_early, .init_irq = armada_370_xp_init_irq, .handle_irq = armada_370_xp_handle_irq, .timer = &armada_370_xp_timer, .restart = mvebu_restart, - .dt_compat = armada_370_xp_dt_board_dt_compat, + .dt_compat = armada_370_xp_dt_compat, MACHINE_END diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h index aac9bebc6b03..c6a7d74fddfe 100644 --- a/arch/arm/mach-mvebu/armada-370-xp.h +++ b/arch/arm/mach-mvebu/armada-370-xp.h @@ -19,4 +19,11 @@ #define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfeb00000) #define ARMADA_370_XP_REGS_SIZE SZ_1M +#ifdef CONFIG_SMP +#include <linux/cpumask.h> + +void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq); +void armada_xp_mpic_smp_cpu_init(void); +#endif + #endif /* __MACH_ARMADA_370_XP_H */ diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c new file mode 100644 index 000000000000..8278960066c3 --- /dev/null +++ b/arch/arm/mach-mvebu/coherency.c @@ -0,0 +1,155 @@ +/* + * Coherency fabric (Aurora) support for Armada 370 and XP platforms. + * + * Copyright (C) 2012 Marvell + * + * Yehuda Yitschak <yehuday@marvell.com> + * Gregory Clement <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + * + * The Armada 370 and Armada XP SOCs have a coherency fabric which is + * responsible for ensuring hardware coherency between all CPUs and between + * CPUs and I/O masters. This file initializes the coherency fabric and + * supplies basic routines for configuring and controlling hardware coherency + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/of_address.h> +#include <linux/io.h> +#include <linux/smp.h> +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <asm/smp_plat.h> +#include "armada-370-xp.h" + +/* + * Some functions in this file are called very early during SMP + * initialization. At that time the device tree framework is not yet + * ready, and it is not possible to get the register address to + * ioremap it. That's why the pointer below is given with an initial + * value matching its virtual mapping + */ +static void __iomem *coherency_base = ARMADA_370_XP_REGS_VIRT_BASE + 0x20200; +static void __iomem *coherency_cpu_base; + +/* Coherency fabric registers */ +#define COHERENCY_FABRIC_CFG_OFFSET 0x4 + +#define IO_SYNC_BARRIER_CTL_OFFSET 0x0 + +static struct of_device_id of_coherency_table[] = { + {.compatible = "marvell,coherency-fabric"}, + { /* end of list */ }, +}; + +#ifdef CONFIG_SMP +int coherency_get_cpu_count(void) +{ + int reg, cnt; + + reg = readl(coherency_base + COHERENCY_FABRIC_CFG_OFFSET); + cnt = (reg & 0xF) + 1; + + return cnt; +} +#endif + +/* Function defined in coherency_ll.S */ +int ll_set_cpu_coherent(void __iomem *base_addr, unsigned int hw_cpu_id); + +int set_cpu_coherent(unsigned int hw_cpu_id, int smp_group_id) +{ + if (!coherency_base) { + pr_warn("Can't make CPU %d cache coherent.\n", hw_cpu_id); + pr_warn("Coherency fabric is not initialized\n"); + return 1; + } + + return ll_set_cpu_coherent(coherency_base, hw_cpu_id); +} + +static inline void mvebu_hwcc_sync_io_barrier(void) +{ + writel(0x1, coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET); + while (readl(coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET) & 0x1); +} + +static dma_addr_t mvebu_hwcc_dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + if (dir != DMA_TO_DEVICE) + mvebu_hwcc_sync_io_barrier(); + return pfn_to_dma(dev, page_to_pfn(page)) + offset; +} + + +static void mvebu_hwcc_dma_unmap_page(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + if (dir != DMA_TO_DEVICE) + mvebu_hwcc_sync_io_barrier(); +} + +static void mvebu_hwcc_dma_sync(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction dir) +{ + if (dir != DMA_TO_DEVICE) + mvebu_hwcc_sync_io_barrier(); +} + +static struct dma_map_ops mvebu_hwcc_dma_ops = { + .alloc = arm_dma_alloc, + .free = arm_dma_free, + .mmap = arm_dma_mmap, + .map_page = mvebu_hwcc_dma_map_page, + .unmap_page = mvebu_hwcc_dma_unmap_page, + .get_sgtable = arm_dma_get_sgtable, + .map_sg = arm_dma_map_sg, + .unmap_sg = arm_dma_unmap_sg, + .sync_single_for_cpu = mvebu_hwcc_dma_sync, + .sync_single_for_device = mvebu_hwcc_dma_sync, + .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu, + .sync_sg_for_device = arm_dma_sync_sg_for_device, + .set_dma_mask = arm_dma_set_mask, +}; + +static int mvebu_hwcc_platform_notifier(struct notifier_block *nb, + unsigned long event, void *__dev) +{ + struct device *dev = __dev; + + if (event != BUS_NOTIFY_ADD_DEVICE) + return NOTIFY_DONE; + set_dma_ops(dev, &mvebu_hwcc_dma_ops); + + return NOTIFY_OK; +} + +static struct notifier_block mvebu_hwcc_platform_nb = { + .notifier_call = mvebu_hwcc_platform_notifier, +}; + +int __init coherency_init(void) +{ + struct device_node *np; + + np = of_find_matching_node(NULL, of_coherency_table); + if (np) { + pr_info("Initializing Coherency fabric\n"); + coherency_base = of_iomap(np, 0); + coherency_cpu_base = of_iomap(np, 1); + set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0); + bus_register_notifier(&platform_bus_type, + &mvebu_hwcc_platform_nb); + } + + return 0; +} diff --git a/arch/arm/mach-mvebu/coherency.h b/arch/arm/mach-mvebu/coherency.h new file mode 100644 index 000000000000..2f428137f6fe --- /dev/null +++ b/arch/arm/mach-mvebu/coherency.h @@ -0,0 +1,24 @@ +/* + * arch/arm/mach-mvebu/include/mach/coherency.h + * + * + * Coherency fabric (Aurora) support for Armada 370 and XP platforms. + * + * Copyright (C) 2012 Marvell + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __MACH_370_XP_COHERENCY_H +#define __MACH_370_XP_COHERENCY_H + +#ifdef CONFIG_SMP +int coherency_get_cpu_count(void); +#endif + +int set_cpu_coherent(int cpu_id, int smp_group_id); +int coherency_init(void); + +#endif /* __MACH_370_XP_COHERENCY_H */ diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S new file mode 100644 index 000000000000..53e8391192cd --- /dev/null +++ b/arch/arm/mach-mvebu/coherency_ll.S @@ -0,0 +1,49 @@ +/* + * Coherency fabric: low level functions + * + * Copyright (C) 2012 Marvell + * + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + * + * This file implements the assembly function to add a CPU to the + * coherency fabric. This function is called by each of the secondary + * CPUs during their early boot in an SMP kernel, this why this + * function have to callable from assembly. It can also be called by a + * primary CPU from C code during its boot. + */ + +#include <linux/linkage.h> +#define ARMADA_XP_CFB_CTL_REG_OFFSET 0x0 +#define ARMADA_XP_CFB_CFG_REG_OFFSET 0x4 + + .text +/* + * r0: Coherency fabric base register address + * r1: HW CPU id + */ +ENTRY(ll_set_cpu_coherent) + /* Create bit by cpu index */ + mov r3, #(1 << 24) + lsl r1, r3, r1 + + /* Add CPU to SMP group - Atomic */ + add r3, r0, #ARMADA_XP_CFB_CTL_REG_OFFSET + ldr r2, [r3] + orr r2, r2, r1 + str r2, [r3] + + /* Enable coherency on CPU - Atomic */ + add r3, r0, #ARMADA_XP_CFB_CFG_REG_OFFSET + ldr r2, [r3] + orr r2, r2, r1 + str r2, [r3] + + dsb + + mov r0, #0 + mov pc, lr +ENDPROC(ll_set_cpu_coherent) diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h index 02f89eaa25fe..aa27bc2ffb60 100644 --- a/arch/arm/mach-mvebu/common.h +++ b/arch/arm/mach-mvebu/common.h @@ -20,4 +20,9 @@ void mvebu_restart(char mode, const char *cmd); void armada_370_xp_init_irq(void); void armada_370_xp_handle_irq(struct pt_regs *regs); +void armada_xp_cpu_die(unsigned int cpu); +int armada_370_xp_coherency_init(void); +int armada_370_xp_pmsu_init(void); +void armada_xp_secondary_startup(void); +extern struct smp_operations armada_xp_smp_ops; #endif diff --git a/arch/arm/mach-mvebu/headsmp.S b/arch/arm/mach-mvebu/headsmp.S new file mode 100644 index 000000000000..a06e0ede8c08 --- /dev/null +++ b/arch/arm/mach-mvebu/headsmp.S @@ -0,0 +1,49 @@ +/* + * SMP support: Entry point for secondary CPUs + * + * Copyright (C) 2012 Marvell + * + * Yehuda Yitschak <yehuday@marvell.com> + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + * + * This file implements the assembly entry point for secondary CPUs in + * an SMP kernel. The only thing we need to do is to add the CPU to + * the coherency fabric by writing to 2 registers. Currently the base + * register addresses are hard coded due to the early initialisation + * problems. + */ + +#include <linux/linkage.h> +#include <linux/init.h> + +/* + * At this stage the secondary CPUs don't have acces yet to the MMU, so + * we have to provide physical addresses + */ +#define ARMADA_XP_CFB_BASE 0xD0020200 + + __CPUINIT + +/* + * Armada XP specific entry point for secondary CPUs. + * We add the CPU to the coherency fabric and then jump to secondary + * startup + */ +ENTRY(armada_xp_secondary_startup) + + /* Read CPU id */ + mrc p15, 0, r1, c0, c0, 5 + and r1, r1, #0xF + + /* Add CPU to coherency fabric */ + ldr r0, =ARMADA_XP_CFB_BASE + + bl ll_set_cpu_coherent + b secondary_startup + +ENDPROC(armada_xp_secondary_startup) diff --git a/arch/arm/mach-mvebu/hotplug.c b/arch/arm/mach-mvebu/hotplug.c new file mode 100644 index 000000000000..b228b6a80c85 --- /dev/null +++ b/arch/arm/mach-mvebu/hotplug.c @@ -0,0 +1,30 @@ +/* + * Symmetric Multi Processing (SMP) support for Armada XP + * + * Copyright (C) 2012 Marvell + * + * Lior Amsalem <alior@marvell.com> + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/smp.h> +#include <asm/proc-fns.h> + +/* + * platform-specific code to shutdown a CPU + * + * Called with IRQs disabled + */ +void __ref armada_xp_cpu_die(unsigned int cpu) +{ + cpu_do_idle(); + + /* We should never return from idle */ + panic("mvebu: cpu %d unexpectedly exit from shutdown\n", cpu); +} diff --git a/arch/arm/mach-mvebu/irq-armada-370-xp.c b/arch/arm/mach-mvebu/irq-armada-370-xp.c index 5f5f9394b6b2..8e3fb082c3c6 100644 --- a/arch/arm/mach-mvebu/irq-armada-370-xp.c +++ b/arch/arm/mach-mvebu/irq-armada-370-xp.c @@ -24,6 +24,8 @@ #include <linux/irqdomain.h> #include <asm/mach/arch.h> #include <asm/exception.h> +#include <asm/smp_plat.h> +#include <asm/hardware/cache-l2x0.h> /* Interrupt Controller Registers Map */ #define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48) @@ -35,6 +37,12 @@ #define ARMADA_370_XP_CPU_INTACK_OFFS (0x44) +#define ARMADA_370_XP_SW_TRIG_INT_OFFS (0x4) +#define ARMADA_370_XP_IN_DRBEL_MSK_OFFS (0xc) +#define ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS (0x8) + +#define ACTIVE_DOORBELLS (8) + static void __iomem *per_cpu_int_base; static void __iomem *main_int_base; static struct irq_domain *armada_370_xp_mpic_domain; @@ -51,11 +59,22 @@ static void armada_370_xp_irq_unmask(struct irq_data *d) per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); } +#ifdef CONFIG_SMP +static int armada_xp_set_affinity(struct irq_data *d, + const struct cpumask *mask_val, bool force) +{ + return 0; +} +#endif + static struct irq_chip armada_370_xp_irq_chip = { .name = "armada_370_xp_irq", .irq_mask = armada_370_xp_irq_mask, .irq_mask_ack = armada_370_xp_irq_mask, .irq_unmask = armada_370_xp_irq_unmask, +#ifdef CONFIG_SMP + .irq_set_affinity = armada_xp_set_affinity, +#endif }; static int armada_370_xp_mpic_irq_map(struct irq_domain *h, @@ -72,6 +91,41 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h, return 0; } +#ifdef CONFIG_SMP +void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq) +{ + int cpu; + unsigned long map = 0; + + /* Convert our logical CPU mask into a physical one. */ + for_each_cpu(cpu, mask) + map |= 1 << cpu_logical_map(cpu); + + /* + * Ensure that stores to Normal memory are visible to the + * other CPUs before issuing the IPI. + */ + dsb(); + + /* submit softirq */ + writel((map << 8) | irq, main_int_base + + ARMADA_370_XP_SW_TRIG_INT_OFFS); +} + +void armada_xp_mpic_smp_cpu_init(void) +{ + /* Clear pending IPIs */ + writel(0, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); + + /* Enable first 8 IPIs */ + writel((1 << ACTIVE_DOORBELLS) - 1, per_cpu_int_base + + ARMADA_370_XP_IN_DRBEL_MSK_OFFS); + + /* Unmask IPI interrupt */ + writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); +} +#endif /* CONFIG_SMP */ + static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { .map = armada_370_xp_mpic_irq_map, .xlate = irq_domain_xlate_onecell, @@ -91,13 +145,18 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL); armada_370_xp_mpic_domain = - irq_domain_add_linear(node, (control >> 2) & 0x3ff, - &armada_370_xp_mpic_irq_ops, NULL); + irq_domain_add_linear(node, (control >> 2) & 0x3ff, + &armada_370_xp_mpic_irq_ops, NULL); if (!armada_370_xp_mpic_domain) panic("Unable to add Armada_370_Xp MPIC irq domain (DT)\n"); irq_set_default_host(armada_370_xp_mpic_domain); + +#ifdef CONFIG_SMP + armada_xp_mpic_smp_cpu_init(); +#endif + return 0; } @@ -111,14 +170,36 @@ asmlinkage void __exception_irq_entry armada_370_xp_handle_irq(struct pt_regs ARMADA_370_XP_CPU_INTACK_OFFS); irqnr = irqstat & 0x3FF; - if (irqnr < 1023) { - irqnr = - irq_find_mapping(armada_370_xp_mpic_domain, irqnr); + if (irqnr > 1022) + break; + + if (irqnr >= 8) { + irqnr = irq_find_mapping(armada_370_xp_mpic_domain, + irqnr); handle_IRQ(irqnr, regs); continue; } +#ifdef CONFIG_SMP + /* IPI Handling */ + if (irqnr == 0) { + u32 ipimask, ipinr; + + ipimask = readl_relaxed(per_cpu_int_base + + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS) + & 0xFF; + + writel(0x0, per_cpu_int_base + + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); + + /* Handle all pending doorbells */ + for (ipinr = 0; ipinr < ACTIVE_DOORBELLS; ipinr++) { + if (ipimask & (0x1 << ipinr)) + handle_IPI(ipinr, regs); + } + continue; + } +#endif - break; } while (1); } @@ -130,4 +211,7 @@ static const struct of_device_id mpic_of_match[] __initconst = { void __init armada_370_xp_init_irq(void) { of_irq_init(mpic_of_match); +#ifdef CONFIG_CACHE_L2X0 + l2x0_of_init(0, ~0UL); +#endif } diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c new file mode 100644 index 000000000000..fe16aaf7c19c --- /dev/null +++ b/arch/arm/mach-mvebu/platsmp.c @@ -0,0 +1,122 @@ +/* + * Symmetric Multi Processing (SMP) support for Armada XP + * + * Copyright (C) 2012 Marvell + * + * Lior Amsalem <alior@marvell.com> + * Yehuda Yitschak <yehuday@marvell.com> + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + * + * The Armada XP SoC has 4 ARMv7 PJ4B CPUs running in full HW coherency + * This file implements the routines for preparing the SMP infrastructure + * and waking up the secondary CPUs + */ + +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/clk.h> +#include <linux/of.h> +#include <asm/cacheflush.h> +#include <asm/smp_plat.h> +#include "common.h" +#include "armada-370-xp.h" +#include "pmsu.h" +#include "coherency.h" + +void __init set_secondary_cpus_clock(void) +{ + int thiscpu; + unsigned long rate; + struct clk *cpu_clk = NULL; + struct device_node *np = NULL; + + thiscpu = smp_processor_id(); + for_each_node_by_type(np, "cpu") { + int err; + int cpu; + + err = of_property_read_u32(np, "reg", &cpu); + if (WARN_ON(err)) + return; + + if (cpu == thiscpu) { + cpu_clk = of_clk_get(np, 0); + break; + } + } + if (WARN_ON(IS_ERR(cpu_clk))) + return; + clk_prepare_enable(cpu_clk); + rate = clk_get_rate(cpu_clk); + + /* set all the other CPU clk to the same rate than the boot CPU */ + for_each_node_by_type(np, "cpu") { + int err; + int cpu; + + err = of_property_read_u32(np, "reg", &cpu); + if (WARN_ON(err)) + return; + + if (cpu != thiscpu) { + cpu_clk = of_clk_get(np, 0); + clk_set_rate(cpu_clk, rate); + } + } +} + +static void __cpuinit armada_xp_secondary_init(unsigned int cpu) +{ + armada_xp_mpic_smp_cpu_init(); +} + +static int __cpuinit armada_xp_boot_secondary(unsigned int cpu, + struct task_struct *idle) +{ + pr_info("Booting CPU %d\n", cpu); + + armada_xp_boot_cpu(cpu, armada_xp_secondary_startup); + + return 0; +} + +static void __init armada_xp_smp_init_cpus(void) +{ + unsigned int i, ncores; + ncores = coherency_get_cpu_count(); + + /* Limit possible CPUs to defconfig */ + if (ncores > nr_cpu_ids) { + pr_warn("SMP: %d CPUs physically present. Only %d configured.", + ncores, nr_cpu_ids); + pr_warn("Clipping CPU count to %d\n", nr_cpu_ids); + ncores = nr_cpu_ids; + } + + for (i = 0; i < ncores; i++) + set_cpu_possible(i, true); + + set_smp_cross_call(armada_mpic_send_doorbell); +} + +void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus) +{ + set_secondary_cpus_clock(); + flush_cache_all(); + set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0); +} + +struct smp_operations armada_xp_smp_ops __initdata = { + .smp_init_cpus = armada_xp_smp_init_cpus, + .smp_prepare_cpus = armada_xp_smp_prepare_cpus, + .smp_secondary_init = armada_xp_secondary_init, + .smp_boot_secondary = armada_xp_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_die = armada_xp_cpu_die, +#endif +}; diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c new file mode 100644 index 000000000000..3cc4bef6401c --- /dev/null +++ b/arch/arm/mach-mvebu/pmsu.c @@ -0,0 +1,75 @@ +/* + * Power Management Service Unit(PMSU) support for Armada 370/XP platforms. + * + * Copyright (C) 2012 Marvell + * + * Yehuda Yitschak <yehuday@marvell.com> + * Gregory Clement <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + * + * The Armada 370 and Armada XP SOCs have a power management service + * unit which is responsible for powering down and waking up CPUs and + * other SOC units + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/of_address.h> +#include <linux/io.h> +#include <linux/smp.h> +#include <asm/smp_plat.h> + +static void __iomem *pmsu_mp_base; +static void __iomem *pmsu_reset_base; + +#define PMSU_BOOT_ADDR_REDIRECT_OFFSET(cpu) ((cpu * 0x100) + 0x24) +#define PMSU_RESET_CTL_OFFSET(cpu) (cpu * 0x8) + +static struct of_device_id of_pmsu_table[] = { + {.compatible = "marvell,armada-370-xp-pmsu"}, + { /* end of list */ }, +}; + +#ifdef CONFIG_SMP +int armada_xp_boot_cpu(unsigned int cpu_id, void *boot_addr) +{ + int reg, hw_cpu; + + if (!pmsu_mp_base || !pmsu_reset_base) { + pr_warn("Can't boot CPU. PMSU is uninitialized\n"); + return 1; + } + + hw_cpu = cpu_logical_map(cpu_id); + + writel(virt_to_phys(boot_addr), pmsu_mp_base + + PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu)); + + /* Release CPU from reset by clearing reset bit*/ + reg = readl(pmsu_reset_base + PMSU_RESET_CTL_OFFSET(hw_cpu)); + reg &= (~0x1); + writel(reg, pmsu_reset_base + PMSU_RESET_CTL_OFFSET(hw_cpu)); + + return 0; +} +#endif + +int __init armada_370_xp_pmsu_init(void) +{ + struct device_node *np; + + np = of_find_matching_node(NULL, of_pmsu_table); + if (np) { + pr_info("Initializing Power Management Service Unit\n"); + pmsu_mp_base = of_iomap(np, 0); + pmsu_reset_base = of_iomap(np, 1); + } + + return 0; +} + +early_initcall(armada_370_xp_pmsu_init); diff --git a/arch/arm/mach-mvebu/pmsu.h b/arch/arm/mach-mvebu/pmsu.h new file mode 100644 index 000000000000..07a737c6b95d --- /dev/null +++ b/arch/arm/mach-mvebu/pmsu.h @@ -0,0 +1,16 @@ +/* + * Power Management Service Unit (PMSU) support for Armada 370/XP platforms. + * + * Copyright (C) 2012 Marvell + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __MACH_MVEBU_PMSU_H +#define __MACH_MVEBU_PMSU_H + +int armada_xp_boot_cpu(unsigned int cpu_id, void *phys_addr); + +#endif /* __MACH_370_XP_PMSU_H */ diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index 4d57e342537b..3ca6757b129a 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c @@ -295,10 +295,10 @@ struct clk sh7372_pllc2_clk = { }; /* External input clock (pin name: FSIACK/FSIBCK ) */ -struct clk sh7372_fsiack_clk = { +static struct clk fsiack_clk = { }; -struct clk sh7372_fsibck_clk = { +static struct clk fsibck_clk = { }; static struct clk *main_clks[] = { @@ -314,8 +314,8 @@ static struct clk *main_clks[] = { &pllc1_clk, &pllc1_div2_clk, &sh7372_pllc2_clk, - &sh7372_fsiack_clk, - &sh7372_fsibck_clk, + &fsiack_clk, + &fsibck_clk, }; static void div4_kick(struct clk *clk) @@ -399,14 +399,14 @@ static struct clk *hdmi_parent[] = { static struct clk *fsiackcr_parent[] = { [0] = &pllc1_div2_clk, [1] = &sh7372_pllc2_clk, - [2] = &sh7372_fsiack_clk, /* external input for FSI A */ + [2] = &fsiack_clk, /* external input for FSI A */ [3] = NULL, /* setting prohibited */ }; static struct clk *fsibckcr_parent[] = { [0] = &pllc1_div2_clk, [1] = &sh7372_pllc2_clk, - [2] = &sh7372_fsibck_clk, /* external input for FSI B */ + [2] = &fsibck_clk, /* external input for FSI B */ [3] = NULL, /* setting prohibited */ }; @@ -507,8 +507,8 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk), - CLKDEV_CON_ID("fsidiva", &fsidivs[FSIDIV_A]), - CLKDEV_CON_ID("fsidivb", &fsidivs[FSIDIV_B]), + CLKDEV_CON_ID("fsiack", &fsiack_clk), + CLKDEV_CON_ID("fsibck", &fsibck_clk), /* DIV4 clocks */ CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), @@ -606,8 +606,8 @@ static struct clk_lookup lookups[] = { CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]), CLKDEV_ICK_ID("diva", "sh_fsi2", &fsidivs[FSIDIV_A]), CLKDEV_ICK_ID("divb", "sh_fsi2", &fsidivs[FSIDIV_B]), - CLKDEV_ICK_ID("xcka", "sh_fsi2", &sh7372_fsiack_clk), - CLKDEV_ICK_ID("xckb", "sh_fsi2", &sh7372_fsibck_clk), + CLKDEV_ICK_ID("xcka", "sh_fsi2", &fsiack_clk), + CLKDEV_ICK_ID("xckb", "sh_fsi2", &fsibck_clk), }; void __init sh7372_clock_init(void) diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index 26cd1016fad8..b582facc1cf6 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h @@ -477,8 +477,6 @@ extern struct clk sh7372_extal2_clk; extern struct clk sh7372_dv_clki_clk; extern struct clk sh7372_dv_clki_div2_clk; extern struct clk sh7372_pllc2_clk; -extern struct clk sh7372_fsiack_clk; -extern struct clk sh7372_fsibck_clk; extern void sh7372_intcs_suspend(void); extern void sh7372_intcs_resume(void); diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c index 535426c306bd..f67456286280 100644 --- a/arch/arm/mach-shmobile/smp-emev2.c +++ b/arch/arm/mach-shmobile/smp-emev2.c @@ -32,8 +32,24 @@ #define EMEV2_SCU_BASE 0x1e000000 +static DEFINE_SPINLOCK(scu_lock); static void __iomem *scu_base; +static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) +{ + unsigned long tmp; + + /* we assume this code is running on a different cpu + * than the one that is changing coherency setting */ + spin_lock(&scu_lock); + tmp = readl(scu_base + 8); + tmp &= ~clr; + tmp |= set; + writel(tmp, scu_base + 8); + spin_unlock(&scu_lock); + +} + static unsigned int __init emev2_get_core_count(void) { if (!scu_base) { @@ -79,7 +95,7 @@ static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct * cpu = cpu_logical_map(cpu); /* enable cache coherency */ - scu_power_mode(scu_base, 0); + modify_scu_cpu_psr(0, 3 << (cpu * 8)); /* Tell ROM loader about our vector (in headsmp.S) */ emev2_set_boot_vector(__pa(shmobile_secondary_vector)); @@ -90,10 +106,12 @@ static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct * static void __init emev2_smp_prepare_cpus(unsigned int max_cpus) { + int cpu = cpu_logical_map(0); + scu_enable(scu_base); /* enable cache coherency on CPU0 */ - scu_power_mode(scu_base, 0); + modify_scu_cpu_psr(0, 3 << (cpu * 8)); } static void __init emev2_smp_init_cpus(void) diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index 9def0f22bf22..2ce6af9a6a37 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c @@ -61,6 +61,9 @@ static void __iomem *scu_base_addr(void) return (void __iomem *)0xf0000000; } +static DEFINE_SPINLOCK(scu_lock); +static unsigned long tmp; + #ifdef CONFIG_HAVE_ARM_TWD static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); @@ -70,6 +73,20 @@ void __init r8a7779_register_twd(void) } #endif +static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) +{ + void __iomem *scu_base = scu_base_addr(); + + spin_lock(&scu_lock); + tmp = __raw_readl(scu_base + 8); + tmp &= ~clr; + tmp |= set; + spin_unlock(&scu_lock); + + /* disable cache coherency after releasing the lock */ + __raw_writel(tmp, scu_base + 8); +} + static unsigned int __init r8a7779_get_core_count(void) { void __iomem *scu_base = scu_base_addr(); @@ -85,7 +102,7 @@ static int r8a7779_platform_cpu_kill(unsigned int cpu) cpu = cpu_logical_map(cpu); /* disable cache coherency */ - scu_power_mode(scu_base_addr(), 3); + modify_scu_cpu_psr(3 << (cpu * 8), 0); if (cpu < ARRAY_SIZE(r8a7779_ch_cpu)) ch = r8a7779_ch_cpu[cpu]; @@ -128,7 +145,7 @@ static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct cpu = cpu_logical_map(cpu); /* enable cache coherency */ - scu_power_mode(scu_base_addr(), 0); + modify_scu_cpu_psr(0, 3 << (cpu * 8)); if (cpu < ARRAY_SIZE(r8a7779_ch_cpu)) ch = r8a7779_ch_cpu[cpu]; @@ -141,13 +158,15 @@ static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus) { + int cpu = cpu_logical_map(0); + scu_enable(scu_base_addr()); /* Map the reset vector (in headsmp.S) */ __raw_writel(__pa(shmobile_secondary_vector), AVECR); /* enable cache coherency on CPU0 */ - scu_power_mode(scu_base_addr(), 0); + modify_scu_cpu_psr(0, 3 << (cpu * 8)); r8a7779_pm_init(); diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index 96ddb97babbe..624f00f70abf 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c @@ -41,6 +41,9 @@ static void __iomem *scu_base_addr(void) return (void __iomem *)0xf0000000; } +static DEFINE_SPINLOCK(scu_lock); +static unsigned long tmp; + #ifdef CONFIG_HAVE_ARM_TWD static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); void __init sh73a0_register_twd(void) @@ -49,6 +52,20 @@ void __init sh73a0_register_twd(void) } #endif +static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) +{ + void __iomem *scu_base = scu_base_addr(); + + spin_lock(&scu_lock); + tmp = __raw_readl(scu_base + 8); + tmp &= ~clr; + tmp |= set; + spin_unlock(&scu_lock); + + /* disable cache coherency after releasing the lock */ + __raw_writel(tmp, scu_base + 8); +} + static unsigned int __init sh73a0_get_core_count(void) { void __iomem *scu_base = scu_base_addr(); @@ -66,7 +83,7 @@ static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct cpu = cpu_logical_map(cpu); /* enable cache coherency */ - scu_power_mode(scu_base_addr(), 0); + modify_scu_cpu_psr(0, 3 << (cpu * 8)); if (((__raw_readl(PSTR) >> (4 * cpu)) & 3) == 3) __raw_writel(1 << cpu, WUPCR); /* wake up */ @@ -78,6 +95,8 @@ static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) { + int cpu = cpu_logical_map(0); + scu_enable(scu_base_addr()); /* Map the reset vector (in headsmp.S) */ @@ -85,7 +104,7 @@ static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) __raw_writel(__pa(shmobile_secondary_vector), SBAR); /* enable cache coherency on CPU0 */ - scu_power_mode(scu_base_addr(), 0); + modify_scu_cpu_psr(0, 3 << (cpu * 8)); } static void __init sh73a0_smp_init_cpus(void) diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig index 803a3281feb5..566e804d4036 100644 --- a/arch/arm/mach-socfpga/Kconfig +++ b/arch/arm/mach-socfpga/Kconfig @@ -12,5 +12,6 @@ config ARCH_SOCFPGA select GENERIC_CLOCKEVENTS select GPIO_PL061 if GPIOLIB select HAVE_ARM_SCU + select HAVE_SMP select SPARSE_IRQ select USE_OF diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile index 4fb93240971d..6dd7a93a90fe 100644 --- a/arch/arm/mach-socfpga/Makefile +++ b/arch/arm/mach-socfpga/Makefile @@ -3,3 +3,4 @@ # obj-y := socfpga.o +obj-$(CONFIG_SMP) += headsmp.o platsmp.o diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h new file mode 100644 index 000000000000..9941caa94931 --- /dev/null +++ b/arch/arm/mach-socfpga/core.h @@ -0,0 +1,34 @@ +/* + * Copyright 2012 Pavel Machek <pavel@denx.de> + * Copyright (C) 2012 Altera Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MACH_CORE_H +#define __MACH_CORE_H + +extern void secondary_startup(void); +extern void __iomem *socfpga_scu_base_addr; + +extern void socfpga_init_clocks(void); +extern void socfpga_sysmgr_init(void); + +extern struct smp_operations socfpga_smp_ops; +extern char secondary_trampoline, secondary_trampoline_end; + +#define SOCFPGA_SCU_VIRT_BASE 0xfffec000 + +#endif diff --git a/arch/arm/mach-socfpga/headsmp.S b/arch/arm/mach-socfpga/headsmp.S new file mode 100644 index 000000000000..f09b1283ffca --- /dev/null +++ b/arch/arm/mach-socfpga/headsmp.S @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2003 ARM Limited + * Copyright (c) u-boot contributors + * Copyright (c) 2012 Pavel Machek <pavel@denx.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/linkage.h> +#include <linux/init.h> + + __CPUINIT + .arch armv7-a + +#define CPU1_START_ADDR 0xffd08010 + +ENTRY(secondary_trampoline) + movw r0, #:lower16:CPU1_START_ADDR + movt r0, #:upper16:CPU1_START_ADDR + + ldr r1, [r0] + bx r1 + +ENTRY(secondary_trampoline_end) diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c new file mode 100644 index 000000000000..68dd1b69512a --- /dev/null +++ b/arch/arm/mach-socfpga/platsmp.c @@ -0,0 +1,116 @@ +/* + * Copyright 2010-2011 Calxeda, Inc. + * Copyright 2012 Pavel Machek <pavel@denx.de> + * Based on platsmp.c, Copyright (C) 2002 ARM Ltd. + * Copyright (C) 2012 Altera Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> + +#include <asm/cacheflush.h> +#include <asm/hardware/gic.h> +#include <asm/smp_scu.h> +#include <asm/smp_plat.h> + +#include "core.h" + +extern void __iomem *sys_manager_base_addr; +extern void __iomem *rst_manager_base_addr; + +static void __cpuinit socfpga_secondary_init(unsigned int cpu) +{ + /* + * if any interrupts are already enabled for the primary + * core (e.g. timer irq), then they will not have been enabled + * for us: do so + */ + gic_secondary_init(0); +} + +static int __cpuinit socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; + + memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); + + __raw_writel(virt_to_phys(secondary_startup), (sys_manager_base_addr+0x10)); + + flush_cache_all(); + smp_wmb(); + outer_clean_range(0, trampoline_size); + + /* This will release CPU #1 out of reset.*/ + __raw_writel(0, rst_manager_base_addr + 0x10); + + return 0; +} + +/* + * Initialise the CPU possible map early - this describes the CPUs + * which may be present or become present in the system. + */ +static void __init socfpga_smp_init_cpus(void) +{ + unsigned int i, ncores; + + ncores = scu_get_core_count(socfpga_scu_base_addr); + + for (i = 0; i < ncores; i++) + set_cpu_possible(i, true); + + /* sanity check */ + if (ncores > num_possible_cpus()) { + pr_warn("socfpga: no. of cores (%d) greater than configured" + "maximum of %d - clipping\n", ncores, num_possible_cpus()); + ncores = num_possible_cpus(); + } + + for (i = 0; i < ncores; i++) + set_cpu_possible(i, true); + + set_smp_cross_call(gic_raise_softirq); +} + +static void __init socfpga_smp_prepare_cpus(unsigned int max_cpus) +{ + scu_enable(socfpga_scu_base_addr); +} + +/* + * platform-specific code to shutdown a CPU + * + * Called with IRQs disabled + */ +static void socfpga_cpu_die(unsigned int cpu) +{ + cpu_do_idle(); + + /* We should have never returned from idle */ + panic("cpu %d unexpectedly exit from shutdown\n", cpu); +} + +struct smp_operations socfpga_smp_ops __initdata = { + .smp_init_cpus = socfpga_smp_init_cpus, + .smp_prepare_cpus = socfpga_smp_prepare_cpus, + .smp_secondary_init = socfpga_secondary_init, + .smp_boot_secondary = socfpga_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_die = socfpga_cpu_die, +#endif +}; diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c index f01e1ebf5396..6732924a5fee 100644 --- a/arch/arm/mach-socfpga/socfpga.c +++ b/arch/arm/mach-socfpga/socfpga.c @@ -15,23 +15,73 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/dw_apb_timer.h> +#include <linux/of_address.h> #include <linux/of_irq.h> #include <linux/of_platform.h> #include <asm/hardware/cache-l2x0.h> #include <asm/hardware/gic.h> #include <asm/mach/arch.h> +#include <asm/mach/map.h> -extern void socfpga_init_clocks(void); +#include "core.h" + +void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE)); +void __iomem *sys_manager_base_addr; +void __iomem *rst_manager_base_addr; + +static struct map_desc scu_io_desc __initdata = { + .virtual = SOCFPGA_SCU_VIRT_BASE, + .pfn = 0, /* run-time */ + .length = SZ_8K, + .type = MT_DEVICE, +}; + +static struct map_desc uart_io_desc __initdata = { + .virtual = 0xfec02000, + .pfn = __phys_to_pfn(0xffc02000), + .length = SZ_8K, + .type = MT_DEVICE, +}; + +static void __init socfpga_scu_map_io(void) +{ + unsigned long base; + + /* Get SCU base */ + asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base)); + + scu_io_desc.pfn = __phys_to_pfn(base); + iotable_init(&scu_io_desc, 1); +} + +static void __init socfpga_map_io(void) +{ + socfpga_scu_map_io(); + iotable_init(&uart_io_desc, 1); + early_printk("Early printk initialized\n"); +} const static struct of_device_id irq_match[] = { { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, {} }; +void __init socfpga_sysmgr_init(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr"); + sys_manager_base_addr = of_iomap(np, 0); + + np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr"); + rst_manager_base_addr = of_iomap(np, 0); +} + static void __init gic_init_irq(void) { of_irq_init(irq_match); + socfpga_sysmgr_init(); } static void socfpga_cyclone5_restart(char mode, const char *cmd) @@ -53,6 +103,8 @@ static const char *altera_dt_match[] = { }; DT_MACHINE_START(SOCFPGA, "Altera SOCFPGA") + .smp = smp_ops(socfpga_smp_ops), + .map_io = socfpga_map_io, .init_irq = gic_init_irq, .handle_irq = gic_handle_irq, .timer = &dw_apb_timer, diff --git a/arch/arm/mach-spear13xx/include/mach/spear.h b/arch/arm/mach-spear13xx/include/mach/spear.h index 07d90acc92c8..7cfa6818865a 100644 --- a/arch/arm/mach-spear13xx/include/mach/spear.h +++ b/arch/arm/mach-spear13xx/include/mach/spear.h @@ -47,14 +47,6 @@ #define DMAC1_BASE UL(0xEB000000) #define MCIF_CF_BASE UL(0xB2800000) -/* Devices present in SPEAr1310 */ -#ifdef CONFIG_MACH_SPEAR1310 -#define SPEAR1310_RAS_GRP1_BASE UL(0xD8000000) -#define VA_SPEAR1310_RAS_GRP1_BASE UL(0xFA000000) -#define SPEAR1310_RAS_BASE UL(0xD8400000) -#define VA_SPEAR1310_RAS_BASE IOMEM(UL(0xFA400000)) -#endif /* CONFIG_MACH_SPEAR1310 */ - /* Debug uart for linux, will be used for debug and uncompress messages */ #define SPEAR_DBG_UART_BASE UART_BASE #define VA_SPEAR_DBG_UART_BASE VA_UART_BASE diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c index 9fbbfc5650aa..02f4724bb0d4 100644 --- a/arch/arm/mach-spear13xx/spear1310.c +++ b/arch/arm/mach-spear13xx/spear1310.c @@ -15,6 +15,7 @@ #include <linux/amba/pl022.h> #include <linux/of_platform.h> +#include <linux/pata_arasan_cf_data.h> #include <asm/hardware/gic.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -27,16 +28,25 @@ #define SPEAR1310_SATA1_BASE UL(0xB1800000) #define SPEAR1310_SATA2_BASE UL(0xB4000000) +#define SPEAR1310_RAS_GRP1_BASE UL(0xD8000000) +#define VA_SPEAR1310_RAS_GRP1_BASE UL(0xFA000000) +#define SPEAR1310_RAS_BASE UL(0xD8400000) +#define VA_SPEAR1310_RAS_BASE IOMEM(UL(0xFA400000)) + +static struct arasan_cf_pdata cf_pdata = { + .cf_if_clk = CF_IF_CLK_166M, + .quirk = CF_BROKEN_UDMA, + .dma_priv = &cf_dma_priv, +}; + /* ssp device registration */ static struct pl022_ssp_controller ssp1_plat_data = { - .bus_id = 0, .enable_dma = 0, - .num_chipselect = 3, }; /* Add SPEAr1310 auxdata to pass platform data */ static struct of_dev_auxdata spear1310_auxdata_lookup[] __initdata = { - OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_dma_priv), + OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_pdata), OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data), OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data), OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data), diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c index 5633d698f1e1..c4af775a8451 100644 --- a/arch/arm/mach-spear13xx/spear13xx.c +++ b/arch/arm/mach-spear13xx/spear13xx.c @@ -57,12 +57,10 @@ static struct dw_dma_slave ssp_dma_param[] = { }; struct pl022_ssp_controller pl022_plat_data = { - .bus_id = 0, .enable_dma = 1, .dma_filter = dw_dma_filter, .dma_rx_param = &ssp_dma_param[1], .dma_tx_param = &ssp_dma_param[0], - .num_chipselect = 3, }; /* CF device registration */ diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h index 803de76f5f36..f95e5b2b6686 100644 --- a/arch/arm/mach-spear3xx/include/mach/irqs.h +++ b/arch/arm/mach-spear3xx/include/mach/irqs.h @@ -14,14 +14,6 @@ #ifndef __MACH_IRQS_H #define __MACH_IRQS_H -/* FIXME: probe all these from DT */ -#define SPEAR3XX_IRQ_INTRCOMM_RAS_ARM 1 -#define SPEAR3XX_IRQ_GEN_RAS_1 28 -#define SPEAR3XX_IRQ_GEN_RAS_2 29 -#define SPEAR3XX_IRQ_GEN_RAS_3 30 -#define SPEAR3XX_IRQ_VIC_END 32 -#define SPEAR3XX_VIRQ_START SPEAR3XX_IRQ_VIC_END - -#define NR_IRQS 160 +#define NR_IRQS 256 #endif /* __MACH_IRQS_H */ diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c index 6ec300549960..a69cbfdb07ee 100644 --- a/arch/arm/mach-spear3xx/spear300.c +++ b/arch/arm/mach-spear3xx/spear300.c @@ -17,102 +17,9 @@ #include <linux/of_platform.h> #include <asm/hardware/vic.h> #include <asm/mach/arch.h> -#include <plat/shirq.h> #include <mach/generic.h> #include <mach/spear.h> -/* Base address of various IPs */ -#define SPEAR300_TELECOM_BASE UL(0x50000000) - -/* Interrupt registers offsets and masks */ -#define SPEAR300_INT_ENB_MASK_REG 0x54 -#define SPEAR300_INT_STS_MASK_REG 0x58 -#define SPEAR300_IT_PERS_S_IRQ_MASK (1 << 0) -#define SPEAR300_IT_CHANGE_S_IRQ_MASK (1 << 1) -#define SPEAR300_I2S_IRQ_MASK (1 << 2) -#define SPEAR300_TDM_IRQ_MASK (1 << 3) -#define SPEAR300_CAMERA_L_IRQ_MASK (1 << 4) -#define SPEAR300_CAMERA_F_IRQ_MASK (1 << 5) -#define SPEAR300_CAMERA_V_IRQ_MASK (1 << 6) -#define SPEAR300_KEYBOARD_IRQ_MASK (1 << 7) -#define SPEAR300_GPIO1_IRQ_MASK (1 << 8) - -#define SPEAR300_SHIRQ_RAS1_MASK 0x1FF - -#define SPEAR300_SOC_CONFIG_BASE UL(0x99000000) - - -/* SPEAr300 Virtual irq definitions */ -/* IRQs sharing IRQ_GEN_RAS_1 */ -#define SPEAR300_VIRQ_IT_PERS_S (SPEAR3XX_VIRQ_START + 0) -#define SPEAR300_VIRQ_IT_CHANGE_S (SPEAR3XX_VIRQ_START + 1) -#define SPEAR300_VIRQ_I2S (SPEAR3XX_VIRQ_START + 2) -#define SPEAR300_VIRQ_TDM (SPEAR3XX_VIRQ_START + 3) -#define SPEAR300_VIRQ_CAMERA_L (SPEAR3XX_VIRQ_START + 4) -#define SPEAR300_VIRQ_CAMERA_F (SPEAR3XX_VIRQ_START + 5) -#define SPEAR300_VIRQ_CAMERA_V (SPEAR3XX_VIRQ_START + 6) -#define SPEAR300_VIRQ_KEYBOARD (SPEAR3XX_VIRQ_START + 7) -#define SPEAR300_VIRQ_GPIO1 (SPEAR3XX_VIRQ_START + 8) - -/* IRQs sharing IRQ_GEN_RAS_3 */ -#define SPEAR300_IRQ_CLCD SPEAR3XX_IRQ_GEN_RAS_3 - -/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */ -#define SPEAR300_IRQ_SDHCI SPEAR3XX_IRQ_INTRCOMM_RAS_ARM - -/* spear3xx shared irq */ -static struct shirq_dev_config shirq_ras1_config[] = { - { - .virq = SPEAR300_VIRQ_IT_PERS_S, - .enb_mask = SPEAR300_IT_PERS_S_IRQ_MASK, - .status_mask = SPEAR300_IT_PERS_S_IRQ_MASK, - }, { - .virq = SPEAR300_VIRQ_IT_CHANGE_S, - .enb_mask = SPEAR300_IT_CHANGE_S_IRQ_MASK, - .status_mask = SPEAR300_IT_CHANGE_S_IRQ_MASK, - }, { - .virq = SPEAR300_VIRQ_I2S, - .enb_mask = SPEAR300_I2S_IRQ_MASK, - .status_mask = SPEAR300_I2S_IRQ_MASK, - }, { - .virq = SPEAR300_VIRQ_TDM, - .enb_mask = SPEAR300_TDM_IRQ_MASK, - .status_mask = SPEAR300_TDM_IRQ_MASK, - }, { - .virq = SPEAR300_VIRQ_CAMERA_L, - .enb_mask = SPEAR300_CAMERA_L_IRQ_MASK, - .status_mask = SPEAR300_CAMERA_L_IRQ_MASK, - }, { - .virq = SPEAR300_VIRQ_CAMERA_F, - .enb_mask = SPEAR300_CAMERA_F_IRQ_MASK, - .status_mask = SPEAR300_CAMERA_F_IRQ_MASK, - }, { - .virq = SPEAR300_VIRQ_CAMERA_V, - .enb_mask = SPEAR300_CAMERA_V_IRQ_MASK, - .status_mask = SPEAR300_CAMERA_V_IRQ_MASK, - }, { - .virq = SPEAR300_VIRQ_KEYBOARD, - .enb_mask = SPEAR300_KEYBOARD_IRQ_MASK, - .status_mask = SPEAR300_KEYBOARD_IRQ_MASK, - }, { - .virq = SPEAR300_VIRQ_GPIO1, - .enb_mask = SPEAR300_GPIO1_IRQ_MASK, - .status_mask = SPEAR300_GPIO1_IRQ_MASK, - }, -}; - -static struct spear_shirq shirq_ras1 = { - .irq = SPEAR3XX_IRQ_GEN_RAS_1, - .dev_config = shirq_ras1_config, - .dev_count = ARRAY_SIZE(shirq_ras1_config), - .regs = { - .enb_reg = SPEAR300_INT_ENB_MASK_REG, - .status_reg = SPEAR300_INT_STS_MASK_REG, - .status_reg_mask = SPEAR300_SHIRQ_RAS1_MASK, - .clear_reg = -1, - }, -}; - /* DMAC platform data's slave info */ struct pl08x_channel_data spear300_dma_info[] = { { @@ -285,21 +192,11 @@ static struct of_dev_auxdata spear300_auxdata_lookup[] __initdata = { static void __init spear300_dt_init(void) { - int ret; - pl080_plat_data.slave_channels = spear300_dma_info; pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear300_dma_info); of_platform_populate(NULL, of_default_bus_match_table, spear300_auxdata_lookup, NULL); - - /* shared irq registration */ - shirq_ras1.regs.base = ioremap(SPEAR300_TELECOM_BASE, SZ_4K); - if (shirq_ras1.regs.base) { - ret = spear_shirq_register(&shirq_ras1); - if (ret) - pr_err("Error registering Shared IRQ\n"); - } } static const char * const spear300_dt_board_compat[] = { diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c index 1d0e435b9045..b963ebb10b56 100644 --- a/arch/arm/mach-spear3xx/spear310.c +++ b/arch/arm/mach-spear3xx/spear310.c @@ -18,7 +18,6 @@ #include <linux/of_platform.h> #include <asm/hardware/vic.h> #include <asm/mach/arch.h> -#include <plat/shirq.h> #include <mach/generic.h> #include <mach/spear.h> @@ -27,176 +26,6 @@ #define SPEAR310_UART3_BASE UL(0xB2100000) #define SPEAR310_UART4_BASE UL(0xB2180000) #define SPEAR310_UART5_BASE UL(0xB2200000) -#define SPEAR310_SOC_CONFIG_BASE UL(0xB4000000) - -/* Interrupt registers offsets and masks */ -#define SPEAR310_INT_STS_MASK_REG 0x04 -#define SPEAR310_SMII0_IRQ_MASK (1 << 0) -#define SPEAR310_SMII1_IRQ_MASK (1 << 1) -#define SPEAR310_SMII2_IRQ_MASK (1 << 2) -#define SPEAR310_SMII3_IRQ_MASK (1 << 3) -#define SPEAR310_WAKEUP_SMII0_IRQ_MASK (1 << 4) -#define SPEAR310_WAKEUP_SMII1_IRQ_MASK (1 << 5) -#define SPEAR310_WAKEUP_SMII2_IRQ_MASK (1 << 6) -#define SPEAR310_WAKEUP_SMII3_IRQ_MASK (1 << 7) -#define SPEAR310_UART1_IRQ_MASK (1 << 8) -#define SPEAR310_UART2_IRQ_MASK (1 << 9) -#define SPEAR310_UART3_IRQ_MASK (1 << 10) -#define SPEAR310_UART4_IRQ_MASK (1 << 11) -#define SPEAR310_UART5_IRQ_MASK (1 << 12) -#define SPEAR310_EMI_IRQ_MASK (1 << 13) -#define SPEAR310_TDM_HDLC_IRQ_MASK (1 << 14) -#define SPEAR310_RS485_0_IRQ_MASK (1 << 15) -#define SPEAR310_RS485_1_IRQ_MASK (1 << 16) - -#define SPEAR310_SHIRQ_RAS1_MASK 0x000FF -#define SPEAR310_SHIRQ_RAS2_MASK 0x01F00 -#define SPEAR310_SHIRQ_RAS3_MASK 0x02000 -#define SPEAR310_SHIRQ_INTRCOMM_RAS_MASK 0x1C000 - -/* SPEAr310 Virtual irq definitions */ -/* IRQs sharing IRQ_GEN_RAS_1 */ -#define SPEAR310_VIRQ_SMII0 (SPEAR3XX_VIRQ_START + 0) -#define SPEAR310_VIRQ_SMII1 (SPEAR3XX_VIRQ_START + 1) -#define SPEAR310_VIRQ_SMII2 (SPEAR3XX_VIRQ_START + 2) -#define SPEAR310_VIRQ_SMII3 (SPEAR3XX_VIRQ_START + 3) -#define SPEAR310_VIRQ_WAKEUP_SMII0 (SPEAR3XX_VIRQ_START + 4) -#define SPEAR310_VIRQ_WAKEUP_SMII1 (SPEAR3XX_VIRQ_START + 5) -#define SPEAR310_VIRQ_WAKEUP_SMII2 (SPEAR3XX_VIRQ_START + 6) -#define SPEAR310_VIRQ_WAKEUP_SMII3 (SPEAR3XX_VIRQ_START + 7) - -/* IRQs sharing IRQ_GEN_RAS_2 */ -#define SPEAR310_VIRQ_UART1 (SPEAR3XX_VIRQ_START + 8) -#define SPEAR310_VIRQ_UART2 (SPEAR3XX_VIRQ_START + 9) -#define SPEAR310_VIRQ_UART3 (SPEAR3XX_VIRQ_START + 10) -#define SPEAR310_VIRQ_UART4 (SPEAR3XX_VIRQ_START + 11) -#define SPEAR310_VIRQ_UART5 (SPEAR3XX_VIRQ_START + 12) - -/* IRQs sharing IRQ_GEN_RAS_3 */ -#define SPEAR310_VIRQ_EMI (SPEAR3XX_VIRQ_START + 13) -#define SPEAR310_VIRQ_PLGPIO (SPEAR3XX_VIRQ_START + 14) - -/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */ -#define SPEAR310_VIRQ_TDM_HDLC (SPEAR3XX_VIRQ_START + 15) -#define SPEAR310_VIRQ_RS485_0 (SPEAR3XX_VIRQ_START + 16) -#define SPEAR310_VIRQ_RS485_1 (SPEAR3XX_VIRQ_START + 17) - - -/* spear3xx shared irq */ -static struct shirq_dev_config shirq_ras1_config[] = { - { - .virq = SPEAR310_VIRQ_SMII0, - .status_mask = SPEAR310_SMII0_IRQ_MASK, - }, { - .virq = SPEAR310_VIRQ_SMII1, - .status_mask = SPEAR310_SMII1_IRQ_MASK, - }, { - .virq = SPEAR310_VIRQ_SMII2, - .status_mask = SPEAR310_SMII2_IRQ_MASK, - }, { - .virq = SPEAR310_VIRQ_SMII3, - .status_mask = SPEAR310_SMII3_IRQ_MASK, - }, { - .virq = SPEAR310_VIRQ_WAKEUP_SMII0, - .status_mask = SPEAR310_WAKEUP_SMII0_IRQ_MASK, - }, { - .virq = SPEAR310_VIRQ_WAKEUP_SMII1, - .status_mask = SPEAR310_WAKEUP_SMII1_IRQ_MASK, - }, { - .virq = SPEAR310_VIRQ_WAKEUP_SMII2, - .status_mask = SPEAR310_WAKEUP_SMII2_IRQ_MASK, - }, { - .virq = SPEAR310_VIRQ_WAKEUP_SMII3, - .status_mask = SPEAR310_WAKEUP_SMII3_IRQ_MASK, - }, -}; - -static struct spear_shirq shirq_ras1 = { - .irq = SPEAR3XX_IRQ_GEN_RAS_1, - .dev_config = shirq_ras1_config, - .dev_count = ARRAY_SIZE(shirq_ras1_config), - .regs = { - .enb_reg = -1, - .status_reg = SPEAR310_INT_STS_MASK_REG, - .status_reg_mask = SPEAR310_SHIRQ_RAS1_MASK, - .clear_reg = -1, - }, -}; - -static struct shirq_dev_config shirq_ras2_config[] = { - { - .virq = SPEAR310_VIRQ_UART1, - .status_mask = SPEAR310_UART1_IRQ_MASK, - }, { - .virq = SPEAR310_VIRQ_UART2, - .status_mask = SPEAR310_UART2_IRQ_MASK, - }, { - .virq = SPEAR310_VIRQ_UART3, - .status_mask = SPEAR310_UART3_IRQ_MASK, - }, { - .virq = SPEAR310_VIRQ_UART4, - .status_mask = SPEAR310_UART4_IRQ_MASK, - }, { - .virq = SPEAR310_VIRQ_UART5, - .status_mask = SPEAR310_UART5_IRQ_MASK, - }, -}; - -static struct spear_shirq shirq_ras2 = { - .irq = SPEAR3XX_IRQ_GEN_RAS_2, - .dev_config = shirq_ras2_config, - .dev_count = ARRAY_SIZE(shirq_ras2_config), - .regs = { - .enb_reg = -1, - .status_reg = SPEAR310_INT_STS_MASK_REG, - .status_reg_mask = SPEAR310_SHIRQ_RAS2_MASK, - .clear_reg = -1, - }, -}; - -static struct shirq_dev_config shirq_ras3_config[] = { - { - .virq = SPEAR310_VIRQ_EMI, - .status_mask = SPEAR310_EMI_IRQ_MASK, - }, -}; - -static struct spear_shirq shirq_ras3 = { - .irq = SPEAR3XX_IRQ_GEN_RAS_3, - .dev_config = shirq_ras3_config, - .dev_count = ARRAY_SIZE(shirq_ras3_config), - .regs = { - .enb_reg = -1, - .status_reg = SPEAR310_INT_STS_MASK_REG, - .status_reg_mask = SPEAR310_SHIRQ_RAS3_MASK, - .clear_reg = -1, - }, -}; - -static struct shirq_dev_config shirq_intrcomm_ras_config[] = { - { - .virq = SPEAR310_VIRQ_TDM_HDLC, - .status_mask = SPEAR310_TDM_HDLC_IRQ_MASK, - }, { - .virq = SPEAR310_VIRQ_RS485_0, - .status_mask = SPEAR310_RS485_0_IRQ_MASK, - }, { - .virq = SPEAR310_VIRQ_RS485_1, - .status_mask = SPEAR310_RS485_1_IRQ_MASK, - }, -}; - -static struct spear_shirq shirq_intrcomm_ras = { - .irq = SPEAR3XX_IRQ_INTRCOMM_RAS_ARM, - .dev_config = shirq_intrcomm_ras_config, - .dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config), - .regs = { - .enb_reg = -1, - .status_reg = SPEAR310_INT_STS_MASK_REG, - .status_reg_mask = SPEAR310_SHIRQ_INTRCOMM_RAS_MASK, - .clear_reg = -1, - }, -}; /* DMAC platform data's slave info */ struct pl08x_channel_data spear310_dma_info[] = { @@ -405,42 +234,11 @@ static struct of_dev_auxdata spear310_auxdata_lookup[] __initdata = { static void __init spear310_dt_init(void) { - void __iomem *base; - int ret; - pl080_plat_data.slave_channels = spear310_dma_info; pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear310_dma_info); of_platform_populate(NULL, of_default_bus_match_table, spear310_auxdata_lookup, NULL); - - /* shared irq registration */ - base = ioremap(SPEAR310_SOC_CONFIG_BASE, SZ_4K); - if (base) { - /* shirq 1 */ - shirq_ras1.regs.base = base; - ret = spear_shirq_register(&shirq_ras1); - if (ret) - pr_err("Error registering Shared IRQ 1\n"); - - /* shirq 2 */ - shirq_ras2.regs.base = base; - ret = spear_shirq_register(&shirq_ras2); - if (ret) - pr_err("Error registering Shared IRQ 2\n"); - - /* shirq 3 */ - shirq_ras3.regs.base = base; - ret = spear_shirq_register(&shirq_ras3); - if (ret) - pr_err("Error registering Shared IRQ 3\n"); - - /* shirq 4 */ - shirq_intrcomm_ras.regs.base = base; - ret = spear_shirq_register(&shirq_intrcomm_ras); - if (ret) - pr_err("Error registering Shared IRQ 4\n"); - } } static const char * const spear310_dt_board_compat[] = { diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c index fd823c624575..66e3a0c33e75 100644 --- a/arch/arm/mach-spear3xx/spear320.c +++ b/arch/arm/mach-spear3xx/spear320.c @@ -19,7 +19,6 @@ #include <linux/of_platform.h> #include <asm/hardware/vic.h> #include <asm/mach/arch.h> -#include <plat/shirq.h> #include <mach/generic.h> #include <mach/spear.h> @@ -28,184 +27,6 @@ #define SPEAR320_SSP0_BASE UL(0xA5000000) #define SPEAR320_SSP1_BASE UL(0xA6000000) -/* Interrupt registers offsets and masks */ -#define SPEAR320_INT_STS_MASK_REG 0x04 -#define SPEAR320_INT_CLR_MASK_REG 0x04 -#define SPEAR320_INT_ENB_MASK_REG 0x08 -#define SPEAR320_GPIO_IRQ_MASK (1 << 0) -#define SPEAR320_I2S_PLAY_IRQ_MASK (1 << 1) -#define SPEAR320_I2S_REC_IRQ_MASK (1 << 2) -#define SPEAR320_EMI_IRQ_MASK (1 << 7) -#define SPEAR320_CLCD_IRQ_MASK (1 << 8) -#define SPEAR320_SPP_IRQ_MASK (1 << 9) -#define SPEAR320_SDHCI_IRQ_MASK (1 << 10) -#define SPEAR320_CAN_U_IRQ_MASK (1 << 11) -#define SPEAR320_CAN_L_IRQ_MASK (1 << 12) -#define SPEAR320_UART1_IRQ_MASK (1 << 13) -#define SPEAR320_UART2_IRQ_MASK (1 << 14) -#define SPEAR320_SSP1_IRQ_MASK (1 << 15) -#define SPEAR320_SSP2_IRQ_MASK (1 << 16) -#define SPEAR320_SMII0_IRQ_MASK (1 << 17) -#define SPEAR320_MII1_SMII1_IRQ_MASK (1 << 18) -#define SPEAR320_WAKEUP_SMII0_IRQ_MASK (1 << 19) -#define SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK (1 << 20) -#define SPEAR320_I2C1_IRQ_MASK (1 << 21) - -#define SPEAR320_SHIRQ_RAS1_MASK 0x000380 -#define SPEAR320_SHIRQ_RAS3_MASK 0x000007 -#define SPEAR320_SHIRQ_INTRCOMM_RAS_MASK 0x3FF800 - -/* SPEAr320 Virtual irq definitions */ -/* IRQs sharing IRQ_GEN_RAS_1 */ -#define SPEAR320_VIRQ_EMI (SPEAR3XX_VIRQ_START + 0) -#define SPEAR320_VIRQ_CLCD (SPEAR3XX_VIRQ_START + 1) -#define SPEAR320_VIRQ_SPP (SPEAR3XX_VIRQ_START + 2) - -/* IRQs sharing IRQ_GEN_RAS_2 */ -#define SPEAR320_IRQ_SDHCI SPEAR3XX_IRQ_GEN_RAS_2 - -/* IRQs sharing IRQ_GEN_RAS_3 */ -#define SPEAR320_VIRQ_PLGPIO (SPEAR3XX_VIRQ_START + 3) -#define SPEAR320_VIRQ_I2S_PLAY (SPEAR3XX_VIRQ_START + 4) -#define SPEAR320_VIRQ_I2S_REC (SPEAR3XX_VIRQ_START + 5) - -/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */ -#define SPEAR320_VIRQ_CANU (SPEAR3XX_VIRQ_START + 6) -#define SPEAR320_VIRQ_CANL (SPEAR3XX_VIRQ_START + 7) -#define SPEAR320_VIRQ_UART1 (SPEAR3XX_VIRQ_START + 8) -#define SPEAR320_VIRQ_UART2 (SPEAR3XX_VIRQ_START + 9) -#define SPEAR320_VIRQ_SSP1 (SPEAR3XX_VIRQ_START + 10) -#define SPEAR320_VIRQ_SSP2 (SPEAR3XX_VIRQ_START + 11) -#define SPEAR320_VIRQ_SMII0 (SPEAR3XX_VIRQ_START + 12) -#define SPEAR320_VIRQ_MII1_SMII1 (SPEAR3XX_VIRQ_START + 13) -#define SPEAR320_VIRQ_WAKEUP_SMII0 (SPEAR3XX_VIRQ_START + 14) -#define SPEAR320_VIRQ_WAKEUP_MII1_SMII1 (SPEAR3XX_VIRQ_START + 15) -#define SPEAR320_VIRQ_I2C1 (SPEAR3XX_VIRQ_START + 16) - -/* spear3xx shared irq */ -static struct shirq_dev_config shirq_ras1_config[] = { - { - .virq = SPEAR320_VIRQ_EMI, - .status_mask = SPEAR320_EMI_IRQ_MASK, - .clear_mask = SPEAR320_EMI_IRQ_MASK, - }, { - .virq = SPEAR320_VIRQ_CLCD, - .status_mask = SPEAR320_CLCD_IRQ_MASK, - .clear_mask = SPEAR320_CLCD_IRQ_MASK, - }, { - .virq = SPEAR320_VIRQ_SPP, - .status_mask = SPEAR320_SPP_IRQ_MASK, - .clear_mask = SPEAR320_SPP_IRQ_MASK, - }, -}; - -static struct spear_shirq shirq_ras1 = { - .irq = SPEAR3XX_IRQ_GEN_RAS_1, - .dev_config = shirq_ras1_config, - .dev_count = ARRAY_SIZE(shirq_ras1_config), - .regs = { - .enb_reg = -1, - .status_reg = SPEAR320_INT_STS_MASK_REG, - .status_reg_mask = SPEAR320_SHIRQ_RAS1_MASK, - .clear_reg = SPEAR320_INT_CLR_MASK_REG, - .reset_to_clear = 1, - }, -}; - -static struct shirq_dev_config shirq_ras3_config[] = { - { - .virq = SPEAR320_VIRQ_PLGPIO, - .enb_mask = SPEAR320_GPIO_IRQ_MASK, - .status_mask = SPEAR320_GPIO_IRQ_MASK, - .clear_mask = SPEAR320_GPIO_IRQ_MASK, - }, { - .virq = SPEAR320_VIRQ_I2S_PLAY, - .enb_mask = SPEAR320_I2S_PLAY_IRQ_MASK, - .status_mask = SPEAR320_I2S_PLAY_IRQ_MASK, - .clear_mask = SPEAR320_I2S_PLAY_IRQ_MASK, - }, { - .virq = SPEAR320_VIRQ_I2S_REC, - .enb_mask = SPEAR320_I2S_REC_IRQ_MASK, - .status_mask = SPEAR320_I2S_REC_IRQ_MASK, - .clear_mask = SPEAR320_I2S_REC_IRQ_MASK, - }, -}; - -static struct spear_shirq shirq_ras3 = { - .irq = SPEAR3XX_IRQ_GEN_RAS_3, - .dev_config = shirq_ras3_config, - .dev_count = ARRAY_SIZE(shirq_ras3_config), - .regs = { - .enb_reg = SPEAR320_INT_ENB_MASK_REG, - .reset_to_enb = 1, - .status_reg = SPEAR320_INT_STS_MASK_REG, - .status_reg_mask = SPEAR320_SHIRQ_RAS3_MASK, - .clear_reg = SPEAR320_INT_CLR_MASK_REG, - .reset_to_clear = 1, - }, -}; - -static struct shirq_dev_config shirq_intrcomm_ras_config[] = { - { - .virq = SPEAR320_VIRQ_CANU, - .status_mask = SPEAR320_CAN_U_IRQ_MASK, - .clear_mask = SPEAR320_CAN_U_IRQ_MASK, - }, { - .virq = SPEAR320_VIRQ_CANL, - .status_mask = SPEAR320_CAN_L_IRQ_MASK, - .clear_mask = SPEAR320_CAN_L_IRQ_MASK, - }, { - .virq = SPEAR320_VIRQ_UART1, - .status_mask = SPEAR320_UART1_IRQ_MASK, - .clear_mask = SPEAR320_UART1_IRQ_MASK, - }, { - .virq = SPEAR320_VIRQ_UART2, - .status_mask = SPEAR320_UART2_IRQ_MASK, - .clear_mask = SPEAR320_UART2_IRQ_MASK, - }, { - .virq = SPEAR320_VIRQ_SSP1, - .status_mask = SPEAR320_SSP1_IRQ_MASK, - .clear_mask = SPEAR320_SSP1_IRQ_MASK, - }, { - .virq = SPEAR320_VIRQ_SSP2, - .status_mask = SPEAR320_SSP2_IRQ_MASK, - .clear_mask = SPEAR320_SSP2_IRQ_MASK, - }, { - .virq = SPEAR320_VIRQ_SMII0, - .status_mask = SPEAR320_SMII0_IRQ_MASK, - .clear_mask = SPEAR320_SMII0_IRQ_MASK, - }, { - .virq = SPEAR320_VIRQ_MII1_SMII1, - .status_mask = SPEAR320_MII1_SMII1_IRQ_MASK, - .clear_mask = SPEAR320_MII1_SMII1_IRQ_MASK, - }, { - .virq = SPEAR320_VIRQ_WAKEUP_SMII0, - .status_mask = SPEAR320_WAKEUP_SMII0_IRQ_MASK, - .clear_mask = SPEAR320_WAKEUP_SMII0_IRQ_MASK, - }, { - .virq = SPEAR320_VIRQ_WAKEUP_MII1_SMII1, - .status_mask = SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK, - .clear_mask = SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK, - }, { - .virq = SPEAR320_VIRQ_I2C1, - .status_mask = SPEAR320_I2C1_IRQ_MASK, - .clear_mask = SPEAR320_I2C1_IRQ_MASK, - }, -}; - -static struct spear_shirq shirq_intrcomm_ras = { - .irq = SPEAR3XX_IRQ_INTRCOMM_RAS_ARM, - .dev_config = shirq_intrcomm_ras_config, - .dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config), - .regs = { - .enb_reg = -1, - .status_reg = SPEAR320_INT_STS_MASK_REG, - .status_reg_mask = SPEAR320_SHIRQ_INTRCOMM_RAS_MASK, - .clear_reg = SPEAR320_INT_CLR_MASK_REG, - .reset_to_clear = 1, - }, -}; - /* DMAC platform data's slave info */ struct pl08x_channel_data spear320_dma_info[] = { { @@ -416,41 +237,17 @@ static struct of_dev_auxdata spear320_auxdata_lookup[] __initdata = { static void __init spear320_dt_init(void) { - void __iomem *base; - int ret; - pl080_plat_data.slave_channels = spear320_dma_info; pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear320_dma_info); of_platform_populate(NULL, of_default_bus_match_table, spear320_auxdata_lookup, NULL); - - /* shared irq registration */ - base = ioremap(SPEAR320_SOC_CONFIG_BASE, SZ_4K); - if (base) { - /* shirq 1 */ - shirq_ras1.regs.base = base; - ret = spear_shirq_register(&shirq_ras1); - if (ret) - pr_err("Error registering Shared IRQ 1\n"); - - /* shirq 3 */ - shirq_ras3.regs.base = base; - ret = spear_shirq_register(&shirq_ras3); - if (ret) - pr_err("Error registering Shared IRQ 3\n"); - - /* shirq 4 */ - shirq_intrcomm_ras.regs.base = base; - ret = spear_shirq_register(&shirq_intrcomm_ras); - if (ret) - pr_err("Error registering Shared IRQ 4\n"); - } } static const char * const spear320_dt_board_compat[] = { "st,spear320", "st,spear320-evb", + "st,spear320-hmi", NULL, }; diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c index 98144baf8883..38fe95db31a7 100644 --- a/arch/arm/mach-spear3xx/spear3xx.c +++ b/arch/arm/mach-spear3xx/spear3xx.c @@ -15,6 +15,7 @@ #include <linux/amba/pl022.h> #include <linux/amba/pl08x.h> +#include <linux/irqchip/spear-shirq.h> #include <linux/of_irq.h> #include <linux/io.h> #include <asm/hardware/pl080.h> @@ -121,6 +122,9 @@ struct sys_timer spear3xx_timer = { static const struct of_device_id vic_of_match[] __initconst = { { .compatible = "arm,pl190-vic", .data = vic_of_init, }, + { .compatible = "st,spear300-shirq", .data = spear300_shirq_of_init, }, + { .compatible = "st,spear310-shirq", .data = spear310_shirq_of_init, }, + { .compatible = "st,spear320-shirq", .data = spear320_shirq_of_init, }, { /* Sentinel */ } }; diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 94186b6c685f..3fd629d5a513 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -352,6 +352,10 @@ config CPU_PJ4 select ARM_THUMBEE select CPU_V7 +config CPU_PJ4B + bool + select CPU_V7 + # ARMv6 config CPU_V6 bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 58bc3e4d3bd0..5383bc018571 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -124,8 +124,6 @@ static void arm_dma_sync_single_for_device(struct device *dev, __dma_page_cpu_to_dev(page, offset, size, dir); } -static int arm_dma_set_mask(struct device *dev, u64 dma_mask); - struct dma_map_ops arm_dma_ops = { .alloc = arm_dma_alloc, .free = arm_dma_free, @@ -971,7 +969,7 @@ int dma_supported(struct device *dev, u64 mask) } EXPORT_SYMBOL(dma_supported); -static int arm_dma_set_mask(struct device *dev, u64 dma_mask) +int arm_dma_set_mask(struct device *dev, u64 dma_mask) { if (!dev->dma_mask || !dma_supported(dev, dma_mask)) return -EIO; diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 42cc833aa02f..350f6a74992b 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -169,6 +169,63 @@ __v7_ca15mp_setup: orreq r0, r0, r10 @ Enable CPU-specific SMP bits mcreq p15, 0, r0, c1, c0, 1 #endif + +__v7_pj4b_setup: +#ifdef CONFIG_CPU_PJ4B + +/* Auxiliary Debug Modes Control 1 Register */ +#define PJ4B_STATIC_BP (1 << 2) /* Enable Static BP */ +#define PJ4B_INTER_PARITY (1 << 8) /* Disable Internal Parity Handling */ +#define PJ4B_BCK_OFF_STREX (1 << 5) /* Enable the back off of STREX instr */ +#define PJ4B_CLEAN_LINE (1 << 16) /* Disable data transfer for clean line */ + +/* Auxiliary Debug Modes Control 2 Register */ +#define PJ4B_FAST_LDR (1 << 23) /* Disable fast LDR */ +#define PJ4B_SNOOP_DATA (1 << 25) /* Do not interleave write and snoop data */ +#define PJ4B_CWF (1 << 27) /* Disable Critical Word First feature */ +#define PJ4B_OUTSDNG_NC (1 << 29) /* Disable outstanding non cacheable rqst */ +#define PJ4B_L1_REP_RR (1 << 30) /* L1 replacement - Strict round robin */ +#define PJ4B_AUX_DBG_CTRL2 (PJ4B_SNOOP_DATA | PJ4B_CWF |\ + PJ4B_OUTSDNG_NC | PJ4B_L1_REP_RR) + +/* Auxiliary Functional Modes Control Register 0 */ +#define PJ4B_SMP_CFB (1 << 1) /* Set SMP mode. Join the coherency fabric */ +#define PJ4B_L1_PAR_CHK (1 << 2) /* Support L1 parity checking */ +#define PJ4B_BROADCAST_CACHE (1 << 8) /* Broadcast Cache and TLB maintenance */ + +/* Auxiliary Debug Modes Control 0 Register */ +#define PJ4B_WFI_WFE (1 << 22) /* WFI/WFE - serve the DVM and back to idle */ + + /* Auxiliary Debug Modes Control 1 Register */ + mrc p15, 1, r0, c15, c1, 1 + orr r0, r0, #PJ4B_CLEAN_LINE + orr r0, r0, #PJ4B_BCK_OFF_STREX + orr r0, r0, #PJ4B_INTER_PARITY + bic r0, r0, #PJ4B_STATIC_BP + mcr p15, 1, r0, c15, c1, 1 + + /* Auxiliary Debug Modes Control 2 Register */ + mrc p15, 1, r0, c15, c1, 2 + bic r0, r0, #PJ4B_FAST_LDR + orr r0, r0, #PJ4B_AUX_DBG_CTRL2 + mcr p15, 1, r0, c15, c1, 2 + + /* Auxiliary Functional Modes Control Register 0 */ + mrc p15, 1, r0, c15, c2, 0 +#ifdef CONFIG_SMP + orr r0, r0, #PJ4B_SMP_CFB +#endif + orr r0, r0, #PJ4B_L1_PAR_CHK + orr r0, r0, #PJ4B_BROADCAST_CACHE + mcr p15, 1, r0, c15, c2, 0 + + /* Auxiliary Debug Modes Control 0 Register */ + mrc p15, 1, r0, c15, c1, 0 + orr r0, r0, #PJ4B_WFI_WFE + mcr p15, 1, r0, c15, c1, 0 + +#endif /* CONFIG_CPU_PJ4B */ + __v7_setup: adr r12, __v7_setup_stack @ the local stack stmia r12, {r0-r5, r7, r9, r11, lr} @@ -342,6 +399,16 @@ __v7_ca9mp_proc_info: .long 0xff0ffff0 __v7_proc __v7_ca9mp_setup .size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info + + /* + * Marvell PJ4B processor. + */ + .type __v7_pj4b_proc_info, #object +__v7_pj4b_proc_info: + .long 0x562f5840 + .long 0xfffffff0 + __v7_proc __v7_pj4b_setup + .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info #endif /* CONFIG_ARM_LPAE */ /* diff --git a/arch/arm/plat-orion/addr-map.c b/arch/arm/plat-orion/addr-map.c index a7b8060c293a..febe3862873c 100644 --- a/arch/arm/plat-orion/addr-map.c +++ b/arch/arm/plat-orion/addr-map.c @@ -42,6 +42,8 @@ EXPORT_SYMBOL_GPL(mv_mbus_dram_info); #define WIN_REMAP_LO_OFF 0x0008 #define WIN_REMAP_HI_OFF 0x000c +#define ATTR_HW_COHERENCY (0x1 << 4) + /* * Default implementation */ @@ -163,6 +165,8 @@ void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg, w = &orion_mbus_dram_info.cs[cs++]; w->cs_index = i; w->mbus_attr = 0xf & ~(1 << i); + if (cfg->hw_io_coherency) + w->mbus_attr |= ATTR_HW_COHERENCY; w->base = base & 0xffff0000; w->size = (size | 0x0000ffff) + 1; } diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index b8a688cad4c2..2d4b6414609f 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -606,26 +606,6 @@ void __init orion_wdt_init(void) ****************************************************************************/ static u64 orion_xor_dmamask = DMA_BIT_MASK(32); -void __init orion_xor_init_channels( - struct mv_xor_platform_data *orion_xor0_data, - struct platform_device *orion_xor0_channel, - struct mv_xor_platform_data *orion_xor1_data, - struct platform_device *orion_xor1_channel) -{ - /* - * two engines can't do memset simultaneously, this limitation - * satisfied by removing memset support from one of the engines. - */ - dma_cap_set(DMA_MEMCPY, orion_xor0_data->cap_mask); - dma_cap_set(DMA_XOR, orion_xor0_data->cap_mask); - platform_device_register(orion_xor0_channel); - - dma_cap_set(DMA_MEMCPY, orion_xor1_data->cap_mask); - dma_cap_set(DMA_MEMSET, orion_xor1_data->cap_mask); - dma_cap_set(DMA_XOR, orion_xor1_data->cap_mask); - platform_device_register(orion_xor1_channel); -} - /***************************************************************************** * XOR0 ****************************************************************************/ @@ -636,61 +616,30 @@ static struct resource orion_xor0_shared_resources[] = { }, { .name = "xor 0 high", .flags = IORESOURCE_MEM, + }, { + .name = "irq channel 0", + .flags = IORESOURCE_IRQ, + }, { + .name = "irq channel 1", + .flags = IORESOURCE_IRQ, }, }; -static struct platform_device orion_xor0_shared = { - .name = MV_XOR_SHARED_NAME, - .id = 0, - .num_resources = ARRAY_SIZE(orion_xor0_shared_resources), - .resource = orion_xor0_shared_resources, -}; +static struct mv_xor_channel_data orion_xor0_channels_data[2]; -static struct resource orion_xor00_resources[] = { - [0] = { - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mv_xor_platform_data orion_xor00_data = { - .shared = &orion_xor0_shared, - .hw_id = 0, - .pool_size = PAGE_SIZE, +static struct mv_xor_platform_data orion_xor0_pdata = { + .channels = orion_xor0_channels_data, }; -static struct platform_device orion_xor00_channel = { +static struct platform_device orion_xor0_shared = { .name = MV_XOR_NAME, .id = 0, - .num_resources = ARRAY_SIZE(orion_xor00_resources), - .resource = orion_xor00_resources, - .dev = { - .dma_mask = &orion_xor_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(64), - .platform_data = &orion_xor00_data, - }, -}; - -static struct resource orion_xor01_resources[] = { - [0] = { - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mv_xor_platform_data orion_xor01_data = { - .shared = &orion_xor0_shared, - .hw_id = 1, - .pool_size = PAGE_SIZE, -}; - -static struct platform_device orion_xor01_channel = { - .name = MV_XOR_NAME, - .id = 1, - .num_resources = ARRAY_SIZE(orion_xor01_resources), - .resource = orion_xor01_resources, - .dev = { - .dma_mask = &orion_xor_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(64), - .platform_data = &orion_xor01_data, + .num_resources = ARRAY_SIZE(orion_xor0_shared_resources), + .resource = orion_xor0_shared_resources, + .dev = { + .dma_mask = &orion_xor_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(64), + .platform_data = &orion_xor0_pdata, }, }; @@ -704,15 +653,23 @@ void __init orion_xor0_init(unsigned long mapbase_low, orion_xor0_shared_resources[1].start = mapbase_high; orion_xor0_shared_resources[1].end = mapbase_high + 0xff; - orion_xor00_resources[0].start = irq_0; - orion_xor00_resources[0].end = irq_0; - orion_xor01_resources[0].start = irq_1; - orion_xor01_resources[0].end = irq_1; + orion_xor0_shared_resources[2].start = irq_0; + orion_xor0_shared_resources[2].end = irq_0; + orion_xor0_shared_resources[3].start = irq_1; + orion_xor0_shared_resources[3].end = irq_1; - platform_device_register(&orion_xor0_shared); + /* + * two engines can't do memset simultaneously, this limitation + * satisfied by removing memset support from one of the engines. + */ + dma_cap_set(DMA_MEMCPY, orion_xor0_channels_data[0].cap_mask); + dma_cap_set(DMA_XOR, orion_xor0_channels_data[0].cap_mask); + + dma_cap_set(DMA_MEMSET, orion_xor0_channels_data[1].cap_mask); + dma_cap_set(DMA_MEMCPY, orion_xor0_channels_data[1].cap_mask); + dma_cap_set(DMA_XOR, orion_xor0_channels_data[1].cap_mask); - orion_xor_init_channels(&orion_xor00_data, &orion_xor00_channel, - &orion_xor01_data, &orion_xor01_channel); + platform_device_register(&orion_xor0_shared); } /***************************************************************************** @@ -725,61 +682,30 @@ static struct resource orion_xor1_shared_resources[] = { }, { .name = "xor 1 high", .flags = IORESOURCE_MEM, + }, { + .name = "irq channel 0", + .flags = IORESOURCE_IRQ, + }, { + .name = "irq channel 1", + .flags = IORESOURCE_IRQ, }, }; -static struct platform_device orion_xor1_shared = { - .name = MV_XOR_SHARED_NAME, - .id = 1, - .num_resources = ARRAY_SIZE(orion_xor1_shared_resources), - .resource = orion_xor1_shared_resources, -}; - -static struct resource orion_xor10_resources[] = { - [0] = { - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mv_xor_platform_data orion_xor10_data = { - .shared = &orion_xor1_shared, - .hw_id = 0, - .pool_size = PAGE_SIZE, -}; - -static struct platform_device orion_xor10_channel = { - .name = MV_XOR_NAME, - .id = 2, - .num_resources = ARRAY_SIZE(orion_xor10_resources), - .resource = orion_xor10_resources, - .dev = { - .dma_mask = &orion_xor_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(64), - .platform_data = &orion_xor10_data, - }, -}; - -static struct resource orion_xor11_resources[] = { - [0] = { - .flags = IORESOURCE_IRQ, - }, -}; +static struct mv_xor_channel_data orion_xor1_channels_data[2]; -static struct mv_xor_platform_data orion_xor11_data = { - .shared = &orion_xor1_shared, - .hw_id = 1, - .pool_size = PAGE_SIZE, +static struct mv_xor_platform_data orion_xor1_pdata = { + .channels = orion_xor1_channels_data, }; -static struct platform_device orion_xor11_channel = { +static struct platform_device orion_xor1_shared = { .name = MV_XOR_NAME, - .id = 3, - .num_resources = ARRAY_SIZE(orion_xor11_resources), - .resource = orion_xor11_resources, - .dev = { - .dma_mask = &orion_xor_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(64), - .platform_data = &orion_xor11_data, + .id = 1, + .num_resources = ARRAY_SIZE(orion_xor1_shared_resources), + .resource = orion_xor1_shared_resources, + .dev = { + .dma_mask = &orion_xor_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(64), + .platform_data = &orion_xor1_pdata, }, }; @@ -793,15 +719,23 @@ void __init orion_xor1_init(unsigned long mapbase_low, orion_xor1_shared_resources[1].start = mapbase_high; orion_xor1_shared_resources[1].end = mapbase_high + 0xff; - orion_xor10_resources[0].start = irq_0; - orion_xor10_resources[0].end = irq_0; - orion_xor11_resources[0].start = irq_1; - orion_xor11_resources[0].end = irq_1; + orion_xor1_shared_resources[2].start = irq_0; + orion_xor1_shared_resources[2].end = irq_0; + orion_xor1_shared_resources[3].start = irq_1; + orion_xor1_shared_resources[3].end = irq_1; - platform_device_register(&orion_xor1_shared); + /* + * two engines can't do memset simultaneously, this limitation + * satisfied by removing memset support from one of the engines. + */ + dma_cap_set(DMA_MEMCPY, orion_xor1_channels_data[0].cap_mask); + dma_cap_set(DMA_XOR, orion_xor1_channels_data[0].cap_mask); - orion_xor_init_channels(&orion_xor10_data, &orion_xor10_channel, - &orion_xor11_data, &orion_xor11_channel); + dma_cap_set(DMA_MEMSET, orion_xor1_channels_data[1].cap_mask); + dma_cap_set(DMA_MEMCPY, orion_xor1_channels_data[1].cap_mask); + dma_cap_set(DMA_XOR, orion_xor1_channels_data[1].cap_mask); + + platform_device_register(&orion_xor1_shared); } /***************************************************************************** diff --git a/arch/arm/plat-orion/include/plat/addr-map.h b/arch/arm/plat-orion/include/plat/addr-map.h index ec63e4a627d0..b76c06569fe5 100644 --- a/arch/arm/plat-orion/include/plat/addr-map.h +++ b/arch/arm/plat-orion/include/plat/addr-map.h @@ -17,6 +17,7 @@ struct orion_addr_map_cfg { const int num_wins; /* Total number of windows */ const int remappable_wins; void __iomem *bridge_virt_base; + int hw_io_coherency; /* If NULL, the default cpu_win_can_remap will be used, using the value in remappable_wins */ diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h index 6bbc3fe5f58e..e06fc5fefa14 100644 --- a/arch/arm/plat-orion/include/plat/common.h +++ b/arch/arm/plat-orion/include/plat/common.h @@ -12,6 +12,7 @@ #include <linux/mv643xx_eth.h> struct dsa_platform_data; +struct mv_sata_platform_data; void __init orion_uart0_init(void __iomem *membase, resource_size_t mapbase, diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c index 012bbd0b8d81..47c9fad43f00 100644 --- a/arch/arm/plat-samsung/clock.c +++ b/arch/arm/plat-samsung/clock.c @@ -389,6 +389,72 @@ int __init s3c24xx_register_baseclocks(unsigned long xtal) static struct dentry *clk_debugfs_root; +static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level) +{ + struct clk *child; + const char *state; + char buf[255] = { 0 }; + int n = 0; + + if (c->name) + n = snprintf(buf, sizeof(buf) - 1, "%s", c->name); + + if (c->devname) + n += snprintf(buf + n, sizeof(buf) - 1 - n, ":%s", c->devname); + + state = (c->usage > 0) ? "on" : "off"; + + seq_printf(s, "%*s%-*s %-6s %-3d %-10lu\n", + level * 3 + 1, "", + 50 - level * 3, buf, + state, c->usage, clk_get_rate(c)); + + list_for_each_entry(child, &clocks, list) { + if (child->parent != c) + continue; + + clock_tree_show_one(s, child, level + 1); + } +} + +static int clock_tree_show(struct seq_file *s, void *data) +{ + struct clk *c; + unsigned long flags; + + seq_printf(s, " clock state ref rate\n"); + seq_printf(s, "----------------------------------------------------\n"); + + spin_lock_irqsave(&clocks_lock, flags); + + list_for_each_entry(c, &clocks, list) + if (c->parent == NULL) + clock_tree_show_one(s, c, 0); + + spin_unlock_irqrestore(&clocks_lock, flags); + return 0; +} + +static int clock_tree_open(struct inode *inode, struct file *file) +{ + return single_open(file, clock_tree_show, inode->i_private); +} + +static const struct file_operations clock_tree_fops = { + .open = clock_tree_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int clock_rate_show(void *data, u64 *val) +{ + struct clk *c = data; + *val = clk_get_rate(c); + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_rate_show, NULL, "%llu\n"); + static int clk_debugfs_register_one(struct clk *c) { int err; @@ -411,7 +477,7 @@ static int clk_debugfs_register_one(struct clk *c) goto err_out; } - d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate); + d = debugfs_create_file("rate", S_IRUGO, c->dent, c, &clock_rate_fops); if (!d) { err = -ENOMEM; goto err_out; @@ -446,13 +512,18 @@ static int __init clk_debugfs_init(void) { struct clk *c; struct dentry *d; - int err; + int err = -ENOMEM; d = debugfs_create_dir("clock", NULL); if (!d) return -ENOMEM; clk_debugfs_root = d; + d = debugfs_create_file("clock_tree", S_IRUGO, clk_debugfs_root, NULL, + &clock_tree_fops); + if (!d) + goto err_out; + list_for_each_entry(c, &clocks, list) { err = clk_debugfs_register(c); if (err) diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile index 2607bd05c525..01e88532a5db 100644 --- a/arch/arm/plat-spear/Makefile +++ b/arch/arm/plat-spear/Makefile @@ -5,5 +5,5 @@ # Common support obj-y := restart.o time.o -obj-$(CONFIG_ARCH_SPEAR3XX) += pl080.o shirq.o +obj-$(CONFIG_ARCH_SPEAR3XX) += pl080.o obj-$(CONFIG_ARCH_SPEAR6XX) += pl080.o diff --git a/arch/arm/plat-spear/include/plat/shirq.h b/arch/arm/plat-spear/include/plat/shirq.h deleted file mode 100644 index 88a7fbd24793..000000000000 --- a/arch/arm/plat-spear/include/plat/shirq.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * arch/arm/plat-spear/include/plat/shirq.h - * - * SPEAr platform shared irq layer header file - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar <viresh.linux@gmail.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __PLAT_SHIRQ_H -#define __PLAT_SHIRQ_H - -#include <linux/irq.h> -#include <linux/types.h> - -/* - * struct shirq_dev_config: shared irq device configuration - * - * virq: virtual irq number of device - * enb_mask: enable mask of device - * status_mask: status mask of device - * clear_mask: clear mask of device - */ -struct shirq_dev_config { - u32 virq; - u32 enb_mask; - u32 status_mask; - u32 clear_mask; -}; - -/* - * struct shirq_regs: shared irq register configuration - * - * base: base address of shared irq register - * enb_reg: enable register offset - * reset_to_enb: val 1 indicates, we need to clear bit for enabling interrupt - * status_reg: status register offset - * status_reg_mask: status register valid mask - * clear_reg: clear register offset - * reset_to_clear: val 1 indicates, we need to clear bit for clearing interrupt - */ -struct shirq_regs { - void __iomem *base; - u32 enb_reg; - u32 reset_to_enb; - u32 status_reg; - u32 status_reg_mask; - u32 clear_reg; - u32 reset_to_clear; -}; - -/* - * struct spear_shirq: shared irq structure - * - * irq: hardware irq number - * dev_config: array of device config structures which are using "irq" line - * dev_count: size of dev_config array - * regs: register configuration for shared irq block - */ -struct spear_shirq { - u32 irq; - struct shirq_dev_config *dev_config; - u32 dev_count; - struct shirq_regs regs; -}; - -int spear_shirq_register(struct spear_shirq *shirq); - -#endif /* __PLAT_SHIRQ_H */ diff --git a/arch/arm/plat-spear/shirq.c b/arch/arm/plat-spear/shirq.c deleted file mode 100644 index 853e891e1184..000000000000 --- a/arch/arm/plat-spear/shirq.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * arch/arm/plat-spear/shirq.c - * - * SPEAr platform shared irq layer source file - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar <viresh.linux@gmail.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include <linux/err.h> -#include <linux/io.h> -#include <linux/irq.h> -#include <linux/spinlock.h> -#include <plat/shirq.h> - -struct spear_shirq *shirq; -static DEFINE_SPINLOCK(lock); - -static void shirq_irq_mask(struct irq_data *d) -{ - struct spear_shirq *shirq = irq_data_get_irq_chip_data(d); - u32 val, id = d->irq - shirq->dev_config[0].virq; - unsigned long flags; - - if ((shirq->regs.enb_reg == -1) || shirq->dev_config[id].enb_mask == -1) - return; - - spin_lock_irqsave(&lock, flags); - val = readl(shirq->regs.base + shirq->regs.enb_reg); - if (shirq->regs.reset_to_enb) - val |= shirq->dev_config[id].enb_mask; - else - val &= ~(shirq->dev_config[id].enb_mask); - writel(val, shirq->regs.base + shirq->regs.enb_reg); - spin_unlock_irqrestore(&lock, flags); -} - -static void shirq_irq_unmask(struct irq_data *d) -{ - struct spear_shirq *shirq = irq_data_get_irq_chip_data(d); - u32 val, id = d->irq - shirq->dev_config[0].virq; - unsigned long flags; - - if ((shirq->regs.enb_reg == -1) || shirq->dev_config[id].enb_mask == -1) - return; - - spin_lock_irqsave(&lock, flags); - val = readl(shirq->regs.base + shirq->regs.enb_reg); - if (shirq->regs.reset_to_enb) - val &= ~(shirq->dev_config[id].enb_mask); - else - val |= shirq->dev_config[id].enb_mask; - writel(val, shirq->regs.base + shirq->regs.enb_reg); - spin_unlock_irqrestore(&lock, flags); -} - -static struct irq_chip shirq_chip = { - .name = "spear_shirq", - .irq_ack = shirq_irq_mask, - .irq_mask = shirq_irq_mask, - .irq_unmask = shirq_irq_unmask, -}; - -static void shirq_handler(unsigned irq, struct irq_desc *desc) -{ - u32 i, val, mask; - struct spear_shirq *shirq = irq_get_handler_data(irq); - - desc->irq_data.chip->irq_ack(&desc->irq_data); - while ((val = readl(shirq->regs.base + shirq->regs.status_reg) & - shirq->regs.status_reg_mask)) { - for (i = 0; (i < shirq->dev_count) && val; i++) { - if (!(shirq->dev_config[i].status_mask & val)) - continue; - - generic_handle_irq(shirq->dev_config[i].virq); - - /* clear interrupt */ - val &= ~shirq->dev_config[i].status_mask; - if ((shirq->regs.clear_reg == -1) || - shirq->dev_config[i].clear_mask == -1) - continue; - mask = readl(shirq->regs.base + shirq->regs.clear_reg); - if (shirq->regs.reset_to_clear) - mask &= ~shirq->dev_config[i].clear_mask; - else - mask |= shirq->dev_config[i].clear_mask; - writel(mask, shirq->regs.base + shirq->regs.clear_reg); - } - } - desc->irq_data.chip->irq_unmask(&desc->irq_data); -} - -int spear_shirq_register(struct spear_shirq *shirq) -{ - int i; - - if (!shirq || !shirq->dev_config || !shirq->regs.base) - return -EFAULT; - - if (!shirq->dev_count) - return -EINVAL; - - irq_set_chained_handler(shirq->irq, shirq_handler); - for (i = 0; i < shirq->dev_count; i++) { - irq_set_chip_and_handler(shirq->dev_config[i].virq, - &shirq_chip, handle_simple_irq); - set_irq_flags(shirq->dev_config[i].virq, IRQF_VALID); - irq_set_chip_data(shirq->dev_config[i].virq, shirq); - } - - irq_set_handler_data(shirq->irq, shirq); - return 0; -} diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 4183e62f178c..d971d1586f1c 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -19,6 +19,7 @@ config MIPS select HAVE_KRETPROBES select HAVE_DEBUG_KMEMLEAK select ARCH_BINFMT_ELF_RANDOMIZE_PIE + select HAVE_ARCH_TRANSPARENT_HUGEPAGE select RTC_LIB if !MACH_LOONGSON select GENERIC_ATOMIC64 if !64BIT select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE @@ -55,8 +56,8 @@ choice config MIPS_ALCHEMY bool "Alchemy processor based machines" select 64BIT_PHYS_ADDR - select CEVT_R4K_LIB - select CSRC_R4K_LIB + select CEVT_R4K + select CSRC_R4K select IRQ_CPU select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_32BIT_KERNEL @@ -107,16 +108,16 @@ config ATH79 config BCM47XX bool "Broadcom BCM47XX based boards" + select ARCH_WANT_OPTIONAL_GPIOLIB select CEVT_R4K select CSRC_R4K select DMA_NONCOHERENT + select FW_CFE select HW_HAS_PCI select IRQ_CPU select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN - select GENERIC_GPIO select SYS_HAS_EARLY_PRINTK - select CFE help Support for BCM47XX based boards @@ -193,8 +194,8 @@ config MACH_DECSTATION config MACH_JAZZ bool "Jazz family of machines" - select ARC - select ARC32 + select FW_ARC + select FW_ARC32 select ARCH_MAY_HAVE_PC_FDC select CEVT_R4K select CSRC_R4K @@ -417,27 +418,6 @@ config PMC_MSP of integrated peripherals, interfaces and DSPs in addition to a variety of MIPS cores. -config PMC_YOSEMITE - bool "PMC-Sierra Yosemite eval board" - select CEVT_R4K - select CSRC_R4K - select DMA_COHERENT - select HW_HAS_PCI - select IRQ_CPU - select IRQ_CPU_RM7K - select IRQ_CPU_RM9K - select SWAP_IO_SPACE - select SYS_HAS_CPU_RM9000 - select SYS_HAS_EARLY_PRINTK - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_BIG_ENDIAN - select SYS_SUPPORTS_HIGHMEM - select SYS_SUPPORTS_SMP - help - Yosemite is an evaluation board for the RM9000x2 processor - manufactured by PMC-Sierra. - config POWERTV bool "Cisco PowerTV" select BOOT_ELF32 @@ -458,8 +438,8 @@ config POWERTV config SGI_IP22 bool "SGI IP22 (Indy/Indigo2)" - select ARC - select ARC32 + select FW_ARC + select FW_ARC32 select BOOT_ELF32 select CEVT_R4K select CSRC_R4K @@ -498,8 +478,8 @@ config SGI_IP22 config SGI_IP27 bool "SGI IP27 (Origin200/2000)" - select ARC - select ARC64 + select FW_ARC + select FW_ARC64 select BOOT_ELF64 select DEFAULT_SGI_PARTITION select DMA_COHERENT @@ -519,8 +499,8 @@ config SGI_IP27 config SGI_IP28 bool "SGI IP28 (Indigo2 R10k) (EXPERIMENTAL)" depends on EXPERIMENTAL - select ARC - select ARC64 + select FW_ARC + select FW_ARC64 select BOOT_ELF64 select CEVT_R4K select CSRC_R4K @@ -555,8 +535,8 @@ config SGI_IP28 config SGI_IP32 bool "SGI IP32 (O2)" - select ARC - select ARC32 + select FW_ARC + select FW_ARC32 select BOOT_ELF32 select CEVT_R4K select CSRC_R4K @@ -674,8 +654,8 @@ config SIBYTE_BIGSUR config SNI_RM bool "SNI RM200/300/400" - select ARC if CPU_LITTLE_ENDIAN - select ARC32 if CPU_LITTLE_ENDIAN + select FW_ARC if CPU_LITTLE_ENDIAN + select FW_ARC32 if CPU_LITTLE_ENDIAN select SNIPROM if CPU_BIG_ENDIAN select ARCH_MAY_HAVE_PC_FDC select BOOT_ELF32 @@ -776,6 +756,7 @@ config CAVIUM_OCTEON_REFERENCE_BOARD select DMA_COHERENT select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN + select EDAC_SUPPORT select SYS_SUPPORTS_HOTPLUG_CPU select SYS_HAS_EARLY_PRINTK select SYS_HAS_CPU_CAVIUM_OCTEON @@ -819,7 +800,7 @@ config NLM_XLR_BOARD select CSRC_R4K select IRQ_CPU select ARCH_SUPPORTS_MSI - select ZONE_DMA if 64BIT + select ZONE_DMA32 if 64BIT select SYNC_R4K select SYS_HAS_EARLY_PRINTK select USB_ARCH_HAS_OHCI if USB_SUPPORT @@ -847,7 +828,7 @@ config NLM_XLP_BOARD select CEVT_R4K select CSRC_R4K select IRQ_CPU - select ZONE_DMA if 64BIT + select ZONE_DMA32 if 64BIT select SYNC_R4K select SYS_HAS_EARLY_PRINTK select USE_OF @@ -908,7 +889,7 @@ config SCHED_OMIT_FRAME_POINTER # # Select some configuration options automatically based on user selections. # -config ARC +config FW_ARC bool config ARCH_MAY_HAVE_PC_FDC @@ -926,11 +907,7 @@ config CEVT_DS1287 config CEVT_GT641XX bool -config CEVT_R4K_LIB - bool - config CEVT_R4K - select CEVT_R4K_LIB bool config CEVT_SB1250 @@ -948,11 +925,7 @@ config CSRC_IOASIC config CSRC_POWERTV bool -config CSRC_R4K_LIB - bool - config CSRC_R4K - select CSRC_R4K_LIB bool config CSRC_SB1250 @@ -963,7 +936,7 @@ config GPIO_TXX9 select ARCH_REQUIRE_GPIOLIB bool -config CFE +config FW_CFE bool config ARCH_DMA_ADDR_T_64BIT @@ -1079,15 +1052,15 @@ config SYS_SUPPORTS_HUGETLBFS depends on CPU_SUPPORTS_HUGEPAGES && 64BIT default y +config MIPS_HUGE_TLB_SUPPORT + def_bool HUGETLB_PAGE || TRANSPARENT_HUGEPAGE + config IRQ_CPU bool config IRQ_CPU_RM7K bool -config IRQ_CPU_RM9K - bool - config IRQ_MSP_SLP bool @@ -1112,10 +1085,6 @@ config PCI_GT64XXX_PCI0 config NO_EXCEPT_FILL bool -config MIPS_RM9122 - bool - select SERIAL_RM9000 - config SOC_EMMA2RH bool select CEVT_R4K @@ -1161,9 +1130,6 @@ config SOC_PNX8550 config SWAP_IO_SPACE bool -config SERIAL_RM9000 - bool - config SGI_HAS_INDYDOG bool @@ -1185,7 +1151,7 @@ config SGI_HAS_I8042 config DEFAULT_SGI_PARTITION bool -config ARC32 +config FW_ARC32 bool config SNIPROM @@ -1218,7 +1184,7 @@ config ARC_PROMLIB depends on MACH_JAZZ || SNI_RM || SGI_IP22 || SGI_IP28 || SGI_IP32 default y -config ARC64 +config FW_ARC64 bool config BOOT_ELF64 @@ -1370,6 +1336,7 @@ config CPU_R4X00 depends on SYS_HAS_CPU_R4X00 select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL + select CPU_SUPPORTS_HUGEPAGES help MIPS Technologies R4000-series processors other than 4300, including the R4000, R4400, R4600, and 4700. @@ -1380,12 +1347,14 @@ config CPU_TX49XX select CPU_HAS_PREFETCH select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL + select CPU_SUPPORTS_HUGEPAGES config CPU_R5000 bool "R5000" depends on SYS_HAS_CPU_R5000 select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL + select CPU_SUPPORTS_HUGEPAGES help MIPS Technologies R5000-series processors other than the Nevada. @@ -1394,6 +1363,7 @@ config CPU_R5432 depends on SYS_HAS_CPU_R5432 select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL + select CPU_SUPPORTS_HUGEPAGES config CPU_R5500 bool "R5500" @@ -1419,6 +1389,7 @@ config CPU_NEVADA depends on SYS_HAS_CPU_NEVADA select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL + select CPU_SUPPORTS_HUGEPAGES help QED / PMC-Sierra RM52xx-series ("Nevada") processors. @@ -1439,6 +1410,7 @@ config CPU_R10000 select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HIGHMEM + select CPU_SUPPORTS_HUGEPAGES help MIPS Technologies R10000-series processors. @@ -1449,15 +1421,7 @@ config CPU_RM7000 select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HIGHMEM - -config CPU_RM9000 - bool "RM9000" - depends on SYS_HAS_CPU_RM9000 - select CPU_HAS_PREFETCH - select CPU_SUPPORTS_32BIT_KERNEL - select CPU_SUPPORTS_64BIT_KERNEL - select CPU_SUPPORTS_HIGHMEM - select WEAK_ORDERING + select CPU_SUPPORTS_HUGEPAGES config CPU_SB1 bool "SB1" @@ -1465,6 +1429,7 @@ config CPU_SB1 select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HIGHMEM + select CPU_SUPPORTS_HUGEPAGES select WEAK_ORDERING config CPU_CAVIUM_OCTEON @@ -1528,9 +1493,9 @@ config CPU_XLR select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HIGHMEM + select CPU_SUPPORTS_HUGEPAGES select WEAK_ORDERING select WEAK_REORDERING_BEYOND_LLSC - select CPU_SUPPORTS_HUGEPAGES help Netlogic Microsystems XLR/XLS processors. @@ -1544,6 +1509,7 @@ config CPU_XLP select WEAK_ORDERING select WEAK_REORDERING_BEYOND_LLSC select CPU_HAS_PREFETCH + select CPU_MIPSR2 help Netlogic Microsystems XLP processors. endchoice @@ -1591,6 +1557,7 @@ config CPU_LOONGSON2 select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HIGHMEM + select CPU_SUPPORTS_HUGEPAGES config CPU_LOONGSON1 bool @@ -1675,9 +1642,6 @@ config SYS_HAS_CPU_R10000 config SYS_HAS_CPU_RM7000 bool -config SYS_HAS_CPU_RM9000 - bool - config SYS_HAS_CPU_SB1 bool @@ -1757,7 +1721,7 @@ config CPU_SUPPORTS_UNCACHED_ACCELERATED bool config MIPS_PGD_C0_CONTEXT bool - default y if 64BIT && CPU_MIPSR2 + default y if 64BIT && CPU_MIPSR2 && !CPU_XLP # # Set to y for ptrace access to watch registers. @@ -2188,7 +2152,7 @@ config NODES_SHIFT config HW_PERF_EVENTS bool "Enable hardware performance counter support for perf events" - depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON) + depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP) default y help Enable hardware performance counter support for perf events. If @@ -2366,6 +2330,29 @@ config KEXEC support. As of this writing the exact hardware interface is strongly in flux, so no good recommendation can be made. +config CRASH_DUMP + bool "Kernel crash dumps" + help + Generate crash dump after being started by kexec. + This should be normally only set in special crash dump kernels + which are loaded in the main kernel with kexec-tools into + a specially reserved region and then later executed after + a crash by kdump/kexec. The crash dump kernel must be compiled + to a memory address not used by the main kernel or firmware using + PHYSICAL_START. + +config PHYSICAL_START + hex "Physical address where the kernel is loaded" + default "0xffffffff84000000" if 64BIT + default "0x84000000" if 32BIT + depends on CRASH_DUMP + help + This gives the CKSEG0 or KSEG0 address where the kernel is loaded. + If you plan to use kernel for capturing the crash dump change + this value to start of the reserved region (the "X" value as + specified in the "crashkernel=YM@XM" command line boot parameter + passed to the panic-ed kernel). + config SECCOMP bool "Enable seccomp to safely compute untrusted bytecode" depends on PROC_FS @@ -2572,6 +2559,8 @@ source "net/Kconfig" source "drivers/Kconfig" +source "drivers/firmware/Kconfig" + source "fs/Kconfig" source "arch/mips/Kconfig.debug" diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 654b1ad39f05..f2dfd404550c 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -145,8 +145,6 @@ cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=r5000) \ -Wa,--trap cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=r5000) \ -Wa,--trap -cflags-$(CONFIG_CPU_RM9000) += $(call cc-option,-march=rm9000,-march=r5000) \ - -Wa,--trap cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1,-march=r5000) \ -Wa,--trap cflags-$(CONFIG_CPU_R8000) += -march=r8000 -Wa,--trap @@ -173,9 +171,9 @@ endif # # Firmware support # -libs-$(CONFIG_ARC) += arch/mips/fw/arc/ -libs-$(CONFIG_CFE) += arch/mips/fw/cfe/ -libs-$(CONFIG_SNIPROM) += arch/mips/fw/sni/ +libs-$(CONFIG_FW_ARC) += arch/mips/fw/arc/ +libs-$(CONFIG_FW_CFE) += arch/mips/fw/cfe/ +libs-$(CONFIG_FW_SNIPROM) += arch/mips/fw/sni/ libs-y += arch/mips/fw/lib/ # @@ -192,6 +190,10 @@ endif # include $(srctree)/arch/mips/Kbuild.platforms +ifdef CONFIG_PHYSICAL_START +load-y = $(CONFIG_PHYSICAL_START) +endif + cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic drivers-$(CONFIG_PCI) += arch/mips/pci/ diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index 1bbc24b08685..7477fd2127ad 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c @@ -202,8 +202,11 @@ static struct resource physmap_flash_resource = { .end = 0x107fffff, }; +static const char *ar7_probe_types[] = { "ar7part", NULL }; + static struct physmap_flash_data physmap_flash_data = { .width = 2, + .part_probe_types = ar7_probe_types, }; static struct platform_device physmap_flash = { diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig index b311be45a720..d7af29f1fcf0 100644 --- a/arch/mips/bcm47xx/Kconfig +++ b/arch/mips/bcm47xx/Kconfig @@ -9,6 +9,7 @@ config BCM47XX_SSB select SSB_EMBEDDED select SSB_B43_PCI_BRIDGE if PCI select SSB_PCICORE_HOSTMODE if PCI + select SSB_DRIVER_GPIO default y help Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support. @@ -23,6 +24,7 @@ config BCM47XX_BCMA select BCMA_DRIVER_MIPS select BCMA_HOST_PCI if PCI select BCMA_DRIVER_PCI_HOSTMODE if PCI + select BCMA_DRIVER_GPIO default y help Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus. diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile index 4389de182eb4..1a3567f07e73 100644 --- a/arch/mips/bcm47xx/Makefile +++ b/arch/mips/bcm47xx/Makefile @@ -3,5 +3,5 @@ # under Linux. # -obj-y += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o sprom.o +obj-y += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o obj-$(CONFIG_BCM47XX_SSB) += wgt634u.o diff --git a/arch/mips/bcm47xx/gpio.c b/arch/mips/bcm47xx/gpio.c deleted file mode 100644 index 5ebdf62e96bb..000000000000 --- a/arch/mips/bcm47xx/gpio.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net> - */ - -#include <linux/export.h> -#include <linux/ssb/ssb.h> -#include <linux/ssb/ssb_driver_chipcommon.h> -#include <linux/ssb/ssb_driver_extif.h> -#include <asm/mach-bcm47xx/bcm47xx.h> -#include <asm/mach-bcm47xx/gpio.h> - -#if (BCM47XX_CHIPCO_GPIO_LINES > BCM47XX_EXTIF_GPIO_LINES) -static DECLARE_BITMAP(gpio_in_use, BCM47XX_CHIPCO_GPIO_LINES); -#else -static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES); -#endif - -int gpio_request(unsigned gpio, const char *tag) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) && - ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)) - return -EINVAL; - - if (ssb_extif_available(&bcm47xx_bus.ssb.extif) && - ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) - return -EINVAL; - - if (test_and_set_bit(gpio, gpio_in_use)) - return -EBUSY; - - return 0; -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - if (gpio >= BCM47XX_CHIPCO_GPIO_LINES) - return -EINVAL; - - if (test_and_set_bit(gpio, gpio_in_use)) - return -EBUSY; - - return 0; -#endif - } - return -EINVAL; -} -EXPORT_SYMBOL(gpio_request); - -void gpio_free(unsigned gpio) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) && - ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)) - return; - - if (ssb_extif_available(&bcm47xx_bus.ssb.extif) && - ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) - return; - - clear_bit(gpio, gpio_in_use); - return; -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - if (gpio >= BCM47XX_CHIPCO_GPIO_LINES) - return; - - clear_bit(gpio, gpio_in_use); - return; -#endif - } -} -EXPORT_SYMBOL(gpio_free); - -int gpio_to_irq(unsigned gpio) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco)) - return ssb_mips_irq(bcm47xx_bus.ssb.chipco.dev) + 2; - else if (ssb_extif_available(&bcm47xx_bus.ssb.extif)) - return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2; - else - return -EINVAL; -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - return bcma_core_mips_irq(bcm47xx_bus.bcma.bus.drv_cc.core) + 2; -#endif - } - return -EINVAL; -} -EXPORT_SYMBOL_GPL(gpio_to_irq); diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c index f6e9063cc4c2..8c155afb1299 100644 --- a/arch/mips/bcm47xx/prom.c +++ b/arch/mips/bcm47xx/prom.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net> + * Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -27,6 +28,7 @@ #include <linux/types.h> #include <linux/kernel.h> #include <linux/spinlock.h> +#include <linux/smp.h> #include <asm/bootinfo.h> #include <asm/fw/cfe/cfe_api.h> #include <asm/fw/cfe/cfe_error.h> @@ -127,6 +129,8 @@ static __init void prom_init_mem(void) { unsigned long mem; unsigned long max; + unsigned long off; + struct cpuinfo_mips *c = ¤t_cpu_data; /* Figure out memory size by finding aliases. * @@ -143,18 +147,26 @@ static __init void prom_init_mem(void) * max contains the biggest possible address supported by the platform. * If the method wants to try something above we assume 128MB ram. */ - max = ((unsigned long)(prom_init) | ((128 << 20) - 1)); + off = (unsigned long)prom_init; + max = off | ((128 << 20) - 1); for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) { - if (((unsigned long)(prom_init) + mem) > max) { + if ((off + mem) > max) { mem = (128 << 20); printk(KERN_DEBUG "assume 128MB RAM\n"); break; } - if (*(unsigned long *)((unsigned long)(prom_init) + mem) == - *(unsigned long *)(prom_init)) + if (!memcmp(prom_init, prom_init + mem, 32)) break; } + /* Ignoring the last page when ddr size is 128M. Cached + * accesses to last page is causing the processor to prefetch + * using address above 128M stepping out of the ddr address + * space. + */ + if (c->cputype == CPU_74K && (mem == (128 << 20))) + mem -= 0x1000; + add_memory_region(0, mem, BOOT_MEM_RAM); } diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index 95bf4d7bac21..4d54b58dbd32 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -94,7 +94,7 @@ static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) snprintf(prefix, sizeof(prefix), "pci/%u/%u/", bus->host_pci->bus->number + 1, PCI_SLOT(bus->host_pci->devfn)); - bcm47xx_fill_sprom(out, prefix); + bcm47xx_fill_sprom(out, prefix, false); return 0; } else { printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n"); @@ -113,7 +113,7 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus, bcm47xx_fill_ssb_boardinfo(&iv->boardinfo, NULL); memset(&iv->sprom, 0, sizeof(struct ssb_sprom)); - bcm47xx_fill_sprom(&iv->sprom, NULL); + bcm47xx_fill_sprom(&iv->sprom, NULL, false); if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0) iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10); @@ -165,16 +165,17 @@ static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) snprintf(prefix, sizeof(prefix), "pci/%u/%u/", bus->host_pci->bus->number + 1, PCI_SLOT(bus->host_pci->devfn)); - bcm47xx_fill_sprom(out, prefix); + bcm47xx_fill_sprom(out, prefix, false); return 0; case BCMA_HOSTTYPE_SOC: memset(out, 0, sizeof(struct ssb_sprom)); - bcm47xx_fill_sprom_ethernet(out, NULL); core = bcma_find_core(bus, BCMA_CORE_80211); if (core) { snprintf(prefix, sizeof(prefix), "sb/%u/", core->core_index); - bcm47xx_fill_sprom(out, prefix); + bcm47xx_fill_sprom(out, prefix, true); + } else { + bcm47xx_fill_sprom(out, NULL, false); } return 0; default: diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c index d3a889745e20..289cc0a38638 100644 --- a/arch/mips/bcm47xx/sprom.c +++ b/arch/mips/bcm47xx/sprom.c @@ -42,25 +42,39 @@ static void create_key(const char *prefix, const char *postfix, snprintf(buf, len, "%s", name); } +static int get_nvram_var(const char *prefix, const char *postfix, + const char *name, char *buf, int len, bool fallback) +{ + char key[40]; + int err; + + create_key(prefix, postfix, name, key, sizeof(key)); + + err = nvram_getenv(key, buf, len); + if (fallback && err == NVRAM_ERR_ENVNOTFOUND && prefix) { + create_key(NULL, postfix, name, key, sizeof(key)); + err = nvram_getenv(key, buf, len); + } + return err; +} + #define NVRAM_READ_VAL(type) \ static void nvram_read_ ## type (const char *prefix, \ const char *postfix, const char *name, \ - type *val, type allset) \ + type *val, type allset, bool fallback) \ { \ char buf[100]; \ - char key[40]; \ int err; \ type var; \ \ - create_key(prefix, postfix, name, key, sizeof(key)); \ - \ - err = nvram_getenv(key, buf, sizeof(buf)); \ + err = get_nvram_var(prefix, postfix, name, buf, sizeof(buf), \ + fallback); \ if (err < 0) \ return; \ err = kstrto ## type (buf, 0, &var); \ if (err) { \ - pr_warn("can not parse nvram name %s with value %s" \ - " got %i", key, buf, err); \ + pr_warn("can not parse nvram name %s%s%s with value %s got %i\n", \ + prefix, name, postfix, buf, err); \ return; \ } \ if (allset && var == allset) \ @@ -76,22 +90,19 @@ NVRAM_READ_VAL(u32) #undef NVRAM_READ_VAL static void nvram_read_u32_2(const char *prefix, const char *name, - u16 *val_lo, u16 *val_hi) + u16 *val_lo, u16 *val_hi, bool fallback) { char buf[100]; - char key[40]; int err; u32 val; - create_key(prefix, NULL, name, key, sizeof(key)); - - err = nvram_getenv(key, buf, sizeof(buf)); + err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback); if (err < 0) return; err = kstrtou32(buf, 0, &val); if (err) { - pr_warn("can not parse nvram name %s with value %s got %i", - key, buf, err); + pr_warn("can not parse nvram name %s%s with value %s got %i\n", + prefix, name, buf, err); return; } *val_lo = (val & 0x0000FFFFU); @@ -99,22 +110,20 @@ static void nvram_read_u32_2(const char *prefix, const char *name, } static void nvram_read_leddc(const char *prefix, const char *name, - u8 *leddc_on_time, u8 *leddc_off_time) + u8 *leddc_on_time, u8 *leddc_off_time, + bool fallback) { char buf[100]; - char key[40]; int err; u32 val; - create_key(prefix, NULL, name, key, sizeof(key)); - - err = nvram_getenv(key, buf, sizeof(buf)); + err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback); if (err < 0) return; err = kstrtou32(buf, 0, &val); if (err) { - pr_warn("can not parse nvram name %s with value %s got %i", - key, buf, err); + pr_warn("can not parse nvram name %s%s with value %s got %i\n", + prefix, name, buf, err); return; } @@ -126,355 +135,435 @@ static void nvram_read_leddc(const char *prefix, const char *name, } static void nvram_read_macaddr(const char *prefix, const char *name, - u8 (*val)[6]) + u8 (*val)[6], bool fallback) { char buf[100]; - char key[40]; int err; - create_key(prefix, NULL, name, key, sizeof(key)); - - err = nvram_getenv(key, buf, sizeof(buf)); + err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback); if (err < 0) return; + nvram_parse_macaddr(buf, *val); } static void nvram_read_alpha2(const char *prefix, const char *name, - char (*val)[2]) + char (*val)[2], bool fallback) { char buf[10]; - char key[40]; int err; - create_key(prefix, NULL, name, key, sizeof(key)); - - err = nvram_getenv(key, buf, sizeof(buf)); + err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback); if (err < 0) return; if (buf[0] == '0') return; if (strlen(buf) > 2) { - pr_warn("alpha2 is too long %s", buf); + pr_warn("alpha2 is too long %s\n", buf); return; } memcpy(val, buf, sizeof(val)); } static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom, - const char *prefix) + const char *prefix, bool fallback) { - nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0); - if (!sprom->board_rev) - nvram_read_u16(NULL, NULL, "boardrev", &sprom->board_rev, 0); - nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0); - nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff); - nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff); - nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff); - nvram_read_u8(prefix, NULL, "ledbh3", &sprom->gpio3, 0xff); - nvram_read_u8(prefix, NULL, "aa2g", &sprom->ant_available_bg, 0); - nvram_read_u8(prefix, NULL, "aa5g", &sprom->ant_available_a, 0); - nvram_read_s8(prefix, NULL, "ag0", &sprom->antenna_gain.a0, 0); - nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0); - nvram_read_alpha2(prefix, "ccode", &sprom->alpha2); + nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff, fallback); + nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff, fallback); + nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff, fallback); + nvram_read_u8(prefix, NULL, "ledbh3", &sprom->gpio3, 0xff, fallback); + nvram_read_u8(prefix, NULL, "aa2g", &sprom->ant_available_bg, 0, + fallback); + nvram_read_u8(prefix, NULL, "aa5g", &sprom->ant_available_a, 0, + fallback); + nvram_read_s8(prefix, NULL, "ag0", &sprom->antenna_gain.a0, 0, + fallback); + nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0, + fallback); + nvram_read_alpha2(prefix, "ccode", &sprom->alpha2, fallback); } static void bcm47xx_fill_sprom_r12389(struct ssb_sprom *sprom, - const char *prefix) + const char *prefix, bool fallback) { - nvram_read_u16(prefix, NULL, "pa0b0", &sprom->pa0b0, 0); - nvram_read_u16(prefix, NULL, "pa0b1", &sprom->pa0b1, 0); - nvram_read_u16(prefix, NULL, "pa0b2", &sprom->pa0b2, 0); - nvram_read_u8(prefix, NULL, "pa0itssit", &sprom->itssi_bg, 0); - nvram_read_u8(prefix, NULL, "pa0maxpwr", &sprom->maxpwr_bg, 0); - nvram_read_u16(prefix, NULL, "pa1b0", &sprom->pa1b0, 0); - nvram_read_u16(prefix, NULL, "pa1b1", &sprom->pa1b1, 0); - nvram_read_u16(prefix, NULL, "pa1b2", &sprom->pa1b2, 0); - nvram_read_u8(prefix, NULL, "pa1itssit", &sprom->itssi_a, 0); - nvram_read_u8(prefix, NULL, "pa1maxpwr", &sprom->maxpwr_a, 0); + nvram_read_u16(prefix, NULL, "pa0b0", &sprom->pa0b0, 0, fallback); + nvram_read_u16(prefix, NULL, "pa0b1", &sprom->pa0b1, 0, fallback); + nvram_read_u16(prefix, NULL, "pa0b2", &sprom->pa0b2, 0, fallback); + nvram_read_u8(prefix, NULL, "pa0itssit", &sprom->itssi_bg, 0, fallback); + nvram_read_u8(prefix, NULL, "pa0maxpwr", &sprom->maxpwr_bg, 0, + fallback); + nvram_read_u16(prefix, NULL, "pa1b0", &sprom->pa1b0, 0, fallback); + nvram_read_u16(prefix, NULL, "pa1b1", &sprom->pa1b1, 0, fallback); + nvram_read_u16(prefix, NULL, "pa1b2", &sprom->pa1b2, 0, fallback); + nvram_read_u8(prefix, NULL, "pa1itssit", &sprom->itssi_a, 0, fallback); + nvram_read_u8(prefix, NULL, "pa1maxpwr", &sprom->maxpwr_a, 0, fallback); } -static void bcm47xx_fill_sprom_r1(struct ssb_sprom *sprom, const char *prefix) +static void bcm47xx_fill_sprom_r1(struct ssb_sprom *sprom, const char *prefix, + bool fallback) { - nvram_read_u16(prefix, NULL, "boardflags", &sprom->boardflags_lo, 0); - nvram_read_u8(prefix, NULL, "cc", &sprom->country_code, 0); + nvram_read_u16(prefix, NULL, "boardflags", &sprom->boardflags_lo, 0, + fallback); + nvram_read_u8(prefix, NULL, "cc", &sprom->country_code, 0, fallback); } static void bcm47xx_fill_sprom_r2389(struct ssb_sprom *sprom, - const char *prefix) -{ - nvram_read_u8(prefix, NULL, "opo", &sprom->opo, 0); - nvram_read_u16(prefix, NULL, "pa1lob0", &sprom->pa1lob0, 0); - nvram_read_u16(prefix, NULL, "pa1lob1", &sprom->pa1lob1, 0); - nvram_read_u16(prefix, NULL, "pa1lob2", &sprom->pa1lob2, 0); - nvram_read_u16(prefix, NULL, "pa1hib0", &sprom->pa1hib0, 0); - nvram_read_u16(prefix, NULL, "pa1hib1", &sprom->pa1hib1, 0); - nvram_read_u16(prefix, NULL, "pa1hib2", &sprom->pa1hib2, 0); - nvram_read_u8(prefix, NULL, "pa1lomaxpwr", &sprom->maxpwr_al, 0); - nvram_read_u8(prefix, NULL, "pa1himaxpwr", &sprom->maxpwr_ah, 0); -} - -static void bcm47xx_fill_sprom_r2(struct ssb_sprom *sprom, const char *prefix) + const char *prefix, bool fallback) { - nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, - &sprom->boardflags_hi); - nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); + nvram_read_u8(prefix, NULL, "opo", &sprom->opo, 0, fallback); + nvram_read_u16(prefix, NULL, "pa1lob0", &sprom->pa1lob0, 0, fallback); + nvram_read_u16(prefix, NULL, "pa1lob1", &sprom->pa1lob1, 0, fallback); + nvram_read_u16(prefix, NULL, "pa1lob2", &sprom->pa1lob2, 0, fallback); + nvram_read_u16(prefix, NULL, "pa1hib0", &sprom->pa1hib0, 0, fallback); + nvram_read_u16(prefix, NULL, "pa1hib1", &sprom->pa1hib1, 0, fallback); + nvram_read_u16(prefix, NULL, "pa1hib2", &sprom->pa1hib2, 0, fallback); + nvram_read_u8(prefix, NULL, "pa1lomaxpwr", &sprom->maxpwr_al, 0, + fallback); + nvram_read_u8(prefix, NULL, "pa1himaxpwr", &sprom->maxpwr_ah, 0, + fallback); } -static void bcm47xx_fill_sprom_r389(struct ssb_sprom *sprom, const char *prefix) +static void bcm47xx_fill_sprom_r389(struct ssb_sprom *sprom, const char *prefix, + bool fallback) { - nvram_read_u8(prefix, NULL, "bxa2g", &sprom->bxa2g, 0); - nvram_read_u8(prefix, NULL, "rssisav2g", &sprom->rssisav2g, 0); - nvram_read_u8(prefix, NULL, "rssismc2g", &sprom->rssismc2g, 0); - nvram_read_u8(prefix, NULL, "rssismf2g", &sprom->rssismf2g, 0); - nvram_read_u8(prefix, NULL, "bxa5g", &sprom->bxa5g, 0); - nvram_read_u8(prefix, NULL, "rssisav5g", &sprom->rssisav5g, 0); - nvram_read_u8(prefix, NULL, "rssismc5g", &sprom->rssismc5g, 0); - nvram_read_u8(prefix, NULL, "rssismf5g", &sprom->rssismf5g, 0); - nvram_read_u8(prefix, NULL, "tri2g", &sprom->tri2g, 0); - nvram_read_u8(prefix, NULL, "tri5g", &sprom->tri5g, 0); - nvram_read_u8(prefix, NULL, "tri5gl", &sprom->tri5gl, 0); - nvram_read_u8(prefix, NULL, "tri5gh", &sprom->tri5gh, 0); - nvram_read_s8(prefix, NULL, "rxpo2g", &sprom->rxpo2g, 0); - nvram_read_s8(prefix, NULL, "rxpo5g", &sprom->rxpo5g, 0); + nvram_read_u8(prefix, NULL, "bxa2g", &sprom->bxa2g, 0, fallback); + nvram_read_u8(prefix, NULL, "rssisav2g", &sprom->rssisav2g, 0, + fallback); + nvram_read_u8(prefix, NULL, "rssismc2g", &sprom->rssismc2g, 0, + fallback); + nvram_read_u8(prefix, NULL, "rssismf2g", &sprom->rssismf2g, 0, + fallback); + nvram_read_u8(prefix, NULL, "bxa5g", &sprom->bxa5g, 0, fallback); + nvram_read_u8(prefix, NULL, "rssisav5g", &sprom->rssisav5g, 0, + fallback); + nvram_read_u8(prefix, NULL, "rssismc5g", &sprom->rssismc5g, 0, + fallback); + nvram_read_u8(prefix, NULL, "rssismf5g", &sprom->rssismf5g, 0, + fallback); + nvram_read_u8(prefix, NULL, "tri2g", &sprom->tri2g, 0, fallback); + nvram_read_u8(prefix, NULL, "tri5g", &sprom->tri5g, 0, fallback); + nvram_read_u8(prefix, NULL, "tri5gl", &sprom->tri5gl, 0, fallback); + nvram_read_u8(prefix, NULL, "tri5gh", &sprom->tri5gh, 0, fallback); + nvram_read_s8(prefix, NULL, "rxpo2g", &sprom->rxpo2g, 0, fallback); + nvram_read_s8(prefix, NULL, "rxpo5g", &sprom->rxpo5g, 0, fallback); } -static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix) +static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix, + bool fallback) { - nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, - &sprom->boardflags_hi); - nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); - nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0); + nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0, fallback); nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time, - &sprom->leddc_off_time); + &sprom->leddc_off_time, fallback); } static void bcm47xx_fill_sprom_r4589(struct ssb_sprom *sprom, - const char *prefix) + const char *prefix, bool fallback) { - nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, - &sprom->boardflags_hi); - nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo, - &sprom->boardflags2_hi); - nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); - nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0); - nvram_read_s8(prefix, NULL, "ag2", &sprom->antenna_gain.a2, 0); - nvram_read_s8(prefix, NULL, "ag3", &sprom->antenna_gain.a3, 0); - nvram_read_u8(prefix, NULL, "txchain", &sprom->txchain, 0xf); - nvram_read_u8(prefix, NULL, "rxchain", &sprom->rxchain, 0xf); - nvram_read_u8(prefix, NULL, "antswitch", &sprom->antswitch, 0xff); + nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0, fallback); + nvram_read_s8(prefix, NULL, "ag2", &sprom->antenna_gain.a2, 0, + fallback); + nvram_read_s8(prefix, NULL, "ag3", &sprom->antenna_gain.a3, 0, + fallback); + nvram_read_u8(prefix, NULL, "txchain", &sprom->txchain, 0xf, fallback); + nvram_read_u8(prefix, NULL, "rxchain", &sprom->rxchain, 0xf, fallback); + nvram_read_u8(prefix, NULL, "antswitch", &sprom->antswitch, 0xff, + fallback); nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time, - &sprom->leddc_off_time); + &sprom->leddc_off_time, fallback); } -static void bcm47xx_fill_sprom_r458(struct ssb_sprom *sprom, const char *prefix) +static void bcm47xx_fill_sprom_r458(struct ssb_sprom *sprom, const char *prefix, + bool fallback) { - nvram_read_u16(prefix, NULL, "cck2gpo", &sprom->cck2gpo, 0); - nvram_read_u32(prefix, NULL, "ofdm2gpo", &sprom->ofdm2gpo, 0); - nvram_read_u32(prefix, NULL, "ofdm5gpo", &sprom->ofdm5gpo, 0); - nvram_read_u32(prefix, NULL, "ofdm5glpo", &sprom->ofdm5glpo, 0); - nvram_read_u32(prefix, NULL, "ofdm5ghpo", &sprom->ofdm5ghpo, 0); - nvram_read_u16(prefix, NULL, "cddpo", &sprom->cddpo, 0); - nvram_read_u16(prefix, NULL, "stbcpo", &sprom->stbcpo, 0); - nvram_read_u16(prefix, NULL, "bw40po", &sprom->bw40po, 0); - nvram_read_u16(prefix, NULL, "bwduppo", &sprom->bwduppo, 0); - nvram_read_u16(prefix, NULL, "mcs2gpo0", &sprom->mcs2gpo[0], 0); - nvram_read_u16(prefix, NULL, "mcs2gpo1", &sprom->mcs2gpo[1], 0); - nvram_read_u16(prefix, NULL, "mcs2gpo2", &sprom->mcs2gpo[2], 0); - nvram_read_u16(prefix, NULL, "mcs2gpo3", &sprom->mcs2gpo[3], 0); - nvram_read_u16(prefix, NULL, "mcs2gpo4", &sprom->mcs2gpo[4], 0); - nvram_read_u16(prefix, NULL, "mcs2gpo5", &sprom->mcs2gpo[5], 0); - nvram_read_u16(prefix, NULL, "mcs2gpo6", &sprom->mcs2gpo[6], 0); - nvram_read_u16(prefix, NULL, "mcs2gpo7", &sprom->mcs2gpo[7], 0); - nvram_read_u16(prefix, NULL, "mcs5gpo0", &sprom->mcs5gpo[0], 0); - nvram_read_u16(prefix, NULL, "mcs5gpo1", &sprom->mcs5gpo[1], 0); - nvram_read_u16(prefix, NULL, "mcs5gpo2", &sprom->mcs5gpo[2], 0); - nvram_read_u16(prefix, NULL, "mcs5gpo3", &sprom->mcs5gpo[3], 0); - nvram_read_u16(prefix, NULL, "mcs5gpo4", &sprom->mcs5gpo[4], 0); - nvram_read_u16(prefix, NULL, "mcs5gpo5", &sprom->mcs5gpo[5], 0); - nvram_read_u16(prefix, NULL, "mcs5gpo6", &sprom->mcs5gpo[6], 0); - nvram_read_u16(prefix, NULL, "mcs5gpo7", &sprom->mcs5gpo[7], 0); - nvram_read_u16(prefix, NULL, "mcs5glpo0", &sprom->mcs5glpo[0], 0); - nvram_read_u16(prefix, NULL, "mcs5glpo1", &sprom->mcs5glpo[1], 0); - nvram_read_u16(prefix, NULL, "mcs5glpo2", &sprom->mcs5glpo[2], 0); - nvram_read_u16(prefix, NULL, "mcs5glpo3", &sprom->mcs5glpo[3], 0); - nvram_read_u16(prefix, NULL, "mcs5glpo4", &sprom->mcs5glpo[4], 0); - nvram_read_u16(prefix, NULL, "mcs5glpo5", &sprom->mcs5glpo[5], 0); - nvram_read_u16(prefix, NULL, "mcs5glpo6", &sprom->mcs5glpo[6], 0); - nvram_read_u16(prefix, NULL, "mcs5glpo7", &sprom->mcs5glpo[7], 0); - nvram_read_u16(prefix, NULL, "mcs5ghpo0", &sprom->mcs5ghpo[0], 0); - nvram_read_u16(prefix, NULL, "mcs5ghpo1", &sprom->mcs5ghpo[1], 0); - nvram_read_u16(prefix, NULL, "mcs5ghpo2", &sprom->mcs5ghpo[2], 0); - nvram_read_u16(prefix, NULL, "mcs5ghpo3", &sprom->mcs5ghpo[3], 0); - nvram_read_u16(prefix, NULL, "mcs5ghpo4", &sprom->mcs5ghpo[4], 0); - nvram_read_u16(prefix, NULL, "mcs5ghpo5", &sprom->mcs5ghpo[5], 0); - nvram_read_u16(prefix, NULL, "mcs5ghpo6", &sprom->mcs5ghpo[6], 0); - nvram_read_u16(prefix, NULL, "mcs5ghpo7", &sprom->mcs5ghpo[7], 0); + nvram_read_u16(prefix, NULL, "cck2gpo", &sprom->cck2gpo, 0, fallback); + nvram_read_u32(prefix, NULL, "ofdm2gpo", &sprom->ofdm2gpo, 0, fallback); + nvram_read_u32(prefix, NULL, "ofdm5gpo", &sprom->ofdm5gpo, 0, fallback); + nvram_read_u32(prefix, NULL, "ofdm5glpo", &sprom->ofdm5glpo, 0, + fallback); + nvram_read_u32(prefix, NULL, "ofdm5ghpo", &sprom->ofdm5ghpo, 0, + fallback); + nvram_read_u16(prefix, NULL, "cddpo", &sprom->cddpo, 0, fallback); + nvram_read_u16(prefix, NULL, "stbcpo", &sprom->stbcpo, 0, fallback); + nvram_read_u16(prefix, NULL, "bw40po", &sprom->bw40po, 0, fallback); + nvram_read_u16(prefix, NULL, "bwduppo", &sprom->bwduppo, 0, fallback); + nvram_read_u16(prefix, NULL, "mcs2gpo0", &sprom->mcs2gpo[0], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs2gpo1", &sprom->mcs2gpo[1], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs2gpo2", &sprom->mcs2gpo[2], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs2gpo3", &sprom->mcs2gpo[3], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs2gpo4", &sprom->mcs2gpo[4], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs2gpo5", &sprom->mcs2gpo[5], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs2gpo6", &sprom->mcs2gpo[6], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs2gpo7", &sprom->mcs2gpo[7], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5gpo0", &sprom->mcs5gpo[0], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5gpo1", &sprom->mcs5gpo[1], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5gpo2", &sprom->mcs5gpo[2], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5gpo3", &sprom->mcs5gpo[3], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5gpo4", &sprom->mcs5gpo[4], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5gpo5", &sprom->mcs5gpo[5], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5gpo6", &sprom->mcs5gpo[6], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5gpo7", &sprom->mcs5gpo[7], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5glpo0", &sprom->mcs5glpo[0], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5glpo1", &sprom->mcs5glpo[1], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5glpo2", &sprom->mcs5glpo[2], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5glpo3", &sprom->mcs5glpo[3], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5glpo4", &sprom->mcs5glpo[4], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5glpo5", &sprom->mcs5glpo[5], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5glpo6", &sprom->mcs5glpo[6], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5glpo7", &sprom->mcs5glpo[7], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5ghpo0", &sprom->mcs5ghpo[0], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5ghpo1", &sprom->mcs5ghpo[1], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5ghpo2", &sprom->mcs5ghpo[2], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5ghpo3", &sprom->mcs5ghpo[3], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5ghpo4", &sprom->mcs5ghpo[4], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5ghpo5", &sprom->mcs5ghpo[5], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5ghpo6", &sprom->mcs5ghpo[6], 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs5ghpo7", &sprom->mcs5ghpo[7], 0, + fallback); } -static void bcm47xx_fill_sprom_r45(struct ssb_sprom *sprom, const char *prefix) +static void bcm47xx_fill_sprom_r45(struct ssb_sprom *sprom, const char *prefix, + bool fallback) { - nvram_read_u8(prefix, NULL, "txpid2ga0", &sprom->txpid2g[0], 0); - nvram_read_u8(prefix, NULL, "txpid2ga1", &sprom->txpid2g[1], 0); - nvram_read_u8(prefix, NULL, "txpid2ga2", &sprom->txpid2g[2], 0); - nvram_read_u8(prefix, NULL, "txpid2ga3", &sprom->txpid2g[3], 0); - nvram_read_u8(prefix, NULL, "txpid5ga0", &sprom->txpid5g[0], 0); - nvram_read_u8(prefix, NULL, "txpid5ga1", &sprom->txpid5g[1], 0); - nvram_read_u8(prefix, NULL, "txpid5ga2", &sprom->txpid5g[2], 0); - nvram_read_u8(prefix, NULL, "txpid5ga3", &sprom->txpid5g[3], 0); - nvram_read_u8(prefix, NULL, "txpid5gla0", &sprom->txpid5gl[0], 0); - nvram_read_u8(prefix, NULL, "txpid5gla1", &sprom->txpid5gl[1], 0); - nvram_read_u8(prefix, NULL, "txpid5gla2", &sprom->txpid5gl[2], 0); - nvram_read_u8(prefix, NULL, "txpid5gla3", &sprom->txpid5gl[3], 0); - nvram_read_u8(prefix, NULL, "txpid5gha0", &sprom->txpid5gh[0], 0); - nvram_read_u8(prefix, NULL, "txpid5gha1", &sprom->txpid5gh[1], 0); - nvram_read_u8(prefix, NULL, "txpid5gha2", &sprom->txpid5gh[2], 0); - nvram_read_u8(prefix, NULL, "txpid5gha3", &sprom->txpid5gh[3], 0); + nvram_read_u8(prefix, NULL, "txpid2ga0", &sprom->txpid2g[0], 0, + fallback); + nvram_read_u8(prefix, NULL, "txpid2ga1", &sprom->txpid2g[1], 0, + fallback); + nvram_read_u8(prefix, NULL, "txpid2ga2", &sprom->txpid2g[2], 0, + fallback); + nvram_read_u8(prefix, NULL, "txpid2ga3", &sprom->txpid2g[3], 0, + fallback); + nvram_read_u8(prefix, NULL, "txpid5ga0", &sprom->txpid5g[0], 0, + fallback); + nvram_read_u8(prefix, NULL, "txpid5ga1", &sprom->txpid5g[1], 0, + fallback); + nvram_read_u8(prefix, NULL, "txpid5ga2", &sprom->txpid5g[2], 0, + fallback); + nvram_read_u8(prefix, NULL, "txpid5ga3", &sprom->txpid5g[3], 0, + fallback); + nvram_read_u8(prefix, NULL, "txpid5gla0", &sprom->txpid5gl[0], 0, + fallback); + nvram_read_u8(prefix, NULL, "txpid5gla1", &sprom->txpid5gl[1], 0, + fallback); + nvram_read_u8(prefix, NULL, "txpid5gla2", &sprom->txpid5gl[2], 0, + fallback); + nvram_read_u8(prefix, NULL, "txpid5gla3", &sprom->txpid5gl[3], 0, + fallback); + nvram_read_u8(prefix, NULL, "txpid5gha0", &sprom->txpid5gh[0], 0, + fallback); + nvram_read_u8(prefix, NULL, "txpid5gha1", &sprom->txpid5gh[1], 0, + fallback); + nvram_read_u8(prefix, NULL, "txpid5gha2", &sprom->txpid5gh[2], 0, + fallback); + nvram_read_u8(prefix, NULL, "txpid5gha3", &sprom->txpid5gh[3], 0, + fallback); } -static void bcm47xx_fill_sprom_r89(struct ssb_sprom *sprom, const char *prefix) +static void bcm47xx_fill_sprom_r89(struct ssb_sprom *sprom, const char *prefix, + bool fallback) { - nvram_read_u8(prefix, NULL, "tssipos2g", &sprom->fem.ghz2.tssipos, 0); + nvram_read_u8(prefix, NULL, "tssipos2g", &sprom->fem.ghz2.tssipos, 0, + fallback); nvram_read_u8(prefix, NULL, "extpagain2g", - &sprom->fem.ghz2.extpa_gain, 0); + &sprom->fem.ghz2.extpa_gain, 0, fallback); nvram_read_u8(prefix, NULL, "pdetrange2g", - &sprom->fem.ghz2.pdet_range, 0); - nvram_read_u8(prefix, NULL, "triso2g", &sprom->fem.ghz2.tr_iso, 0); - nvram_read_u8(prefix, NULL, "antswctl2g", &sprom->fem.ghz2.antswlut, 0); - nvram_read_u8(prefix, NULL, "tssipos5g", &sprom->fem.ghz5.tssipos, 0); + &sprom->fem.ghz2.pdet_range, 0, fallback); + nvram_read_u8(prefix, NULL, "triso2g", &sprom->fem.ghz2.tr_iso, 0, + fallback); + nvram_read_u8(prefix, NULL, "antswctl2g", &sprom->fem.ghz2.antswlut, 0, + fallback); + nvram_read_u8(prefix, NULL, "tssipos5g", &sprom->fem.ghz5.tssipos, 0, + fallback); nvram_read_u8(prefix, NULL, "extpagain5g", - &sprom->fem.ghz5.extpa_gain, 0); + &sprom->fem.ghz5.extpa_gain, 0, fallback); nvram_read_u8(prefix, NULL, "pdetrange5g", - &sprom->fem.ghz5.pdet_range, 0); - nvram_read_u8(prefix, NULL, "triso5g", &sprom->fem.ghz5.tr_iso, 0); - nvram_read_u8(prefix, NULL, "antswctl5g", &sprom->fem.ghz5.antswlut, 0); - nvram_read_u8(prefix, NULL, "tempthresh", &sprom->tempthresh, 0); - nvram_read_u8(prefix, NULL, "tempoffset", &sprom->tempoffset, 0); - nvram_read_u16(prefix, NULL, "rawtempsense", &sprom->rawtempsense, 0); - nvram_read_u8(prefix, NULL, "measpower", &sprom->measpower, 0); + &sprom->fem.ghz5.pdet_range, 0, fallback); + nvram_read_u8(prefix, NULL, "triso5g", &sprom->fem.ghz5.tr_iso, 0, + fallback); + nvram_read_u8(prefix, NULL, "antswctl5g", &sprom->fem.ghz5.antswlut, 0, + fallback); + nvram_read_u8(prefix, NULL, "tempthresh", &sprom->tempthresh, 0, + fallback); + nvram_read_u8(prefix, NULL, "tempoffset", &sprom->tempoffset, 0, + fallback); + nvram_read_u16(prefix, NULL, "rawtempsense", &sprom->rawtempsense, 0, + fallback); + nvram_read_u8(prefix, NULL, "measpower", &sprom->measpower, 0, + fallback); nvram_read_u8(prefix, NULL, "tempsense_slope", - &sprom->tempsense_slope, 0); - nvram_read_u8(prefix, NULL, "tempcorrx", &sprom->tempcorrx, 0); + &sprom->tempsense_slope, 0, fallback); + nvram_read_u8(prefix, NULL, "tempcorrx", &sprom->tempcorrx, 0, + fallback); nvram_read_u8(prefix, NULL, "tempsense_option", - &sprom->tempsense_option, 0); + &sprom->tempsense_option, 0, fallback); nvram_read_u8(prefix, NULL, "freqoffset_corr", - &sprom->freqoffset_corr, 0); - nvram_read_u8(prefix, NULL, "iqcal_swp_dis", &sprom->iqcal_swp_dis, 0); - nvram_read_u8(prefix, NULL, "hw_iqcal_en", &sprom->hw_iqcal_en, 0); - nvram_read_u8(prefix, NULL, "elna2g", &sprom->elna2g, 0); - nvram_read_u8(prefix, NULL, "elna5g", &sprom->elna5g, 0); + &sprom->freqoffset_corr, 0, fallback); + nvram_read_u8(prefix, NULL, "iqcal_swp_dis", &sprom->iqcal_swp_dis, 0, + fallback); + nvram_read_u8(prefix, NULL, "hw_iqcal_en", &sprom->hw_iqcal_en, 0, + fallback); + nvram_read_u8(prefix, NULL, "elna2g", &sprom->elna2g, 0, fallback); + nvram_read_u8(prefix, NULL, "elna5g", &sprom->elna5g, 0, fallback); nvram_read_u8(prefix, NULL, "phycal_tempdelta", - &sprom->phycal_tempdelta, 0); - nvram_read_u8(prefix, NULL, "temps_period", &sprom->temps_period, 0); + &sprom->phycal_tempdelta, 0, fallback); + nvram_read_u8(prefix, NULL, "temps_period", &sprom->temps_period, 0, + fallback); nvram_read_u8(prefix, NULL, "temps_hysteresis", - &sprom->temps_hysteresis, 0); - nvram_read_u8(prefix, NULL, "measpower1", &sprom->measpower1, 0); - nvram_read_u8(prefix, NULL, "measpower2", &sprom->measpower2, 0); + &sprom->temps_hysteresis, 0, fallback); + nvram_read_u8(prefix, NULL, "measpower1", &sprom->measpower1, 0, + fallback); + nvram_read_u8(prefix, NULL, "measpower2", &sprom->measpower2, 0, + fallback); nvram_read_u8(prefix, NULL, "rxgainerr2ga0", - &sprom->rxgainerr2ga[0], 0); + &sprom->rxgainerr2ga[0], 0, fallback); nvram_read_u8(prefix, NULL, "rxgainerr2ga1", - &sprom->rxgainerr2ga[1], 0); + &sprom->rxgainerr2ga[1], 0, fallback); nvram_read_u8(prefix, NULL, "rxgainerr2ga2", - &sprom->rxgainerr2ga[2], 0); + &sprom->rxgainerr2ga[2], 0, fallback); nvram_read_u8(prefix, NULL, "rxgainerr5gla0", - &sprom->rxgainerr5gla[0], 0); + &sprom->rxgainerr5gla[0], 0, fallback); nvram_read_u8(prefix, NULL, "rxgainerr5gla1", - &sprom->rxgainerr5gla[1], 0); + &sprom->rxgainerr5gla[1], 0, fallback); nvram_read_u8(prefix, NULL, "rxgainerr5gla2", - &sprom->rxgainerr5gla[2], 0); + &sprom->rxgainerr5gla[2], 0, fallback); nvram_read_u8(prefix, NULL, "rxgainerr5gma0", - &sprom->rxgainerr5gma[0], 0); + &sprom->rxgainerr5gma[0], 0, fallback); nvram_read_u8(prefix, NULL, "rxgainerr5gma1", - &sprom->rxgainerr5gma[1], 0); + &sprom->rxgainerr5gma[1], 0, fallback); nvram_read_u8(prefix, NULL, "rxgainerr5gma2", - &sprom->rxgainerr5gma[2], 0); + &sprom->rxgainerr5gma[2], 0, fallback); nvram_read_u8(prefix, NULL, "rxgainerr5gha0", - &sprom->rxgainerr5gha[0], 0); + &sprom->rxgainerr5gha[0], 0, fallback); nvram_read_u8(prefix, NULL, "rxgainerr5gha1", - &sprom->rxgainerr5gha[1], 0); + &sprom->rxgainerr5gha[1], 0, fallback); nvram_read_u8(prefix, NULL, "rxgainerr5gha2", - &sprom->rxgainerr5gha[2], 0); + &sprom->rxgainerr5gha[2], 0, fallback); nvram_read_u8(prefix, NULL, "rxgainerr5gua0", - &sprom->rxgainerr5gua[0], 0); + &sprom->rxgainerr5gua[0], 0, fallback); nvram_read_u8(prefix, NULL, "rxgainerr5gua1", - &sprom->rxgainerr5gua[1], 0); + &sprom->rxgainerr5gua[1], 0, fallback); nvram_read_u8(prefix, NULL, "rxgainerr5gua2", - &sprom->rxgainerr5gua[2], 0); - nvram_read_u8(prefix, NULL, "noiselvl2ga0", &sprom->noiselvl2ga[0], 0); - nvram_read_u8(prefix, NULL, "noiselvl2ga1", &sprom->noiselvl2ga[1], 0); - nvram_read_u8(prefix, NULL, "noiselvl2ga2", &sprom->noiselvl2ga[2], 0); + &sprom->rxgainerr5gua[2], 0, fallback); + nvram_read_u8(prefix, NULL, "noiselvl2ga0", &sprom->noiselvl2ga[0], 0, + fallback); + nvram_read_u8(prefix, NULL, "noiselvl2ga1", &sprom->noiselvl2ga[1], 0, + fallback); + nvram_read_u8(prefix, NULL, "noiselvl2ga2", &sprom->noiselvl2ga[2], 0, + fallback); nvram_read_u8(prefix, NULL, "noiselvl5gla0", - &sprom->noiselvl5gla[0], 0); + &sprom->noiselvl5gla[0], 0, fallback); nvram_read_u8(prefix, NULL, "noiselvl5gla1", - &sprom->noiselvl5gla[1], 0); + &sprom->noiselvl5gla[1], 0, fallback); nvram_read_u8(prefix, NULL, "noiselvl5gla2", - &sprom->noiselvl5gla[2], 0); + &sprom->noiselvl5gla[2], 0, fallback); nvram_read_u8(prefix, NULL, "noiselvl5gma0", - &sprom->noiselvl5gma[0], 0); + &sprom->noiselvl5gma[0], 0, fallback); nvram_read_u8(prefix, NULL, "noiselvl5gma1", - &sprom->noiselvl5gma[1], 0); + &sprom->noiselvl5gma[1], 0, fallback); nvram_read_u8(prefix, NULL, "noiselvl5gma2", - &sprom->noiselvl5gma[2], 0); + &sprom->noiselvl5gma[2], 0, fallback); nvram_read_u8(prefix, NULL, "noiselvl5gha0", - &sprom->noiselvl5gha[0], 0); + &sprom->noiselvl5gha[0], 0, fallback); nvram_read_u8(prefix, NULL, "noiselvl5gha1", - &sprom->noiselvl5gha[1], 0); + &sprom->noiselvl5gha[1], 0, fallback); nvram_read_u8(prefix, NULL, "noiselvl5gha2", - &sprom->noiselvl5gha[2], 0); + &sprom->noiselvl5gha[2], 0, fallback); nvram_read_u8(prefix, NULL, "noiselvl5gua0", - &sprom->noiselvl5gua[0], 0); + &sprom->noiselvl5gua[0], 0, fallback); nvram_read_u8(prefix, NULL, "noiselvl5gua1", - &sprom->noiselvl5gua[1], 0); + &sprom->noiselvl5gua[1], 0, fallback); nvram_read_u8(prefix, NULL, "noiselvl5gua2", - &sprom->noiselvl5gua[2], 0); + &sprom->noiselvl5gua[2], 0, fallback); nvram_read_u8(prefix, NULL, "pcieingress_war", - &sprom->pcieingress_war, 0); + &sprom->pcieingress_war, 0, fallback); } -static void bcm47xx_fill_sprom_r9(struct ssb_sprom *sprom, const char *prefix) +static void bcm47xx_fill_sprom_r9(struct ssb_sprom *sprom, const char *prefix, + bool fallback) { - nvram_read_u16(prefix, NULL, "cckbw202gpo", &sprom->cckbw202gpo, 0); - nvram_read_u16(prefix, NULL, "cckbw20ul2gpo", &sprom->cckbw20ul2gpo, 0); + nvram_read_u16(prefix, NULL, "cckbw202gpo", &sprom->cckbw202gpo, 0, + fallback); + nvram_read_u16(prefix, NULL, "cckbw20ul2gpo", &sprom->cckbw20ul2gpo, 0, + fallback); nvram_read_u32(prefix, NULL, "legofdmbw202gpo", - &sprom->legofdmbw202gpo, 0); + &sprom->legofdmbw202gpo, 0, fallback); nvram_read_u32(prefix, NULL, "legofdmbw20ul2gpo", - &sprom->legofdmbw20ul2gpo, 0); + &sprom->legofdmbw20ul2gpo, 0, fallback); nvram_read_u32(prefix, NULL, "legofdmbw205glpo", - &sprom->legofdmbw205glpo, 0); + &sprom->legofdmbw205glpo, 0, fallback); nvram_read_u32(prefix, NULL, "legofdmbw20ul5glpo", - &sprom->legofdmbw20ul5glpo, 0); + &sprom->legofdmbw20ul5glpo, 0, fallback); nvram_read_u32(prefix, NULL, "legofdmbw205gmpo", - &sprom->legofdmbw205gmpo, 0); + &sprom->legofdmbw205gmpo, 0, fallback); nvram_read_u32(prefix, NULL, "legofdmbw20ul5gmpo", - &sprom->legofdmbw20ul5gmpo, 0); + &sprom->legofdmbw20ul5gmpo, 0, fallback); nvram_read_u32(prefix, NULL, "legofdmbw205ghpo", - &sprom->legofdmbw205ghpo, 0); + &sprom->legofdmbw205ghpo, 0, fallback); nvram_read_u32(prefix, NULL, "legofdmbw20ul5ghpo", - &sprom->legofdmbw20ul5ghpo, 0); - nvram_read_u32(prefix, NULL, "mcsbw202gpo", &sprom->mcsbw202gpo, 0); - nvram_read_u32(prefix, NULL, "mcsbw20ul2gpo", &sprom->mcsbw20ul2gpo, 0); - nvram_read_u32(prefix, NULL, "mcsbw402gpo", &sprom->mcsbw402gpo, 0); - nvram_read_u32(prefix, NULL, "mcsbw205glpo", &sprom->mcsbw205glpo, 0); + &sprom->legofdmbw20ul5ghpo, 0, fallback); + nvram_read_u32(prefix, NULL, "mcsbw202gpo", &sprom->mcsbw202gpo, 0, + fallback); + nvram_read_u32(prefix, NULL, "mcsbw20ul2gpo", &sprom->mcsbw20ul2gpo, 0, + fallback); + nvram_read_u32(prefix, NULL, "mcsbw402gpo", &sprom->mcsbw402gpo, 0, + fallback); + nvram_read_u32(prefix, NULL, "mcsbw205glpo", &sprom->mcsbw205glpo, 0, + fallback); nvram_read_u32(prefix, NULL, "mcsbw20ul5glpo", - &sprom->mcsbw20ul5glpo, 0); - nvram_read_u32(prefix, NULL, "mcsbw405glpo", &sprom->mcsbw405glpo, 0); - nvram_read_u32(prefix, NULL, "mcsbw205gmpo", &sprom->mcsbw205gmpo, 0); + &sprom->mcsbw20ul5glpo, 0, fallback); + nvram_read_u32(prefix, NULL, "mcsbw405glpo", &sprom->mcsbw405glpo, 0, + fallback); + nvram_read_u32(prefix, NULL, "mcsbw205gmpo", &sprom->mcsbw205gmpo, 0, + fallback); nvram_read_u32(prefix, NULL, "mcsbw20ul5gmpo", - &sprom->mcsbw20ul5gmpo, 0); - nvram_read_u32(prefix, NULL, "mcsbw405gmpo", &sprom->mcsbw405gmpo, 0); - nvram_read_u32(prefix, NULL, "mcsbw205ghpo", &sprom->mcsbw205ghpo, 0); + &sprom->mcsbw20ul5gmpo, 0, fallback); + nvram_read_u32(prefix, NULL, "mcsbw405gmpo", &sprom->mcsbw405gmpo, 0, + fallback); + nvram_read_u32(prefix, NULL, "mcsbw205ghpo", &sprom->mcsbw205ghpo, 0, + fallback); nvram_read_u32(prefix, NULL, "mcsbw20ul5ghpo", - &sprom->mcsbw20ul5ghpo, 0); - nvram_read_u32(prefix, NULL, "mcsbw405ghpo", &sprom->mcsbw405ghpo, 0); - nvram_read_u16(prefix, NULL, "mcs32po", &sprom->mcs32po, 0); + &sprom->mcsbw20ul5ghpo, 0, fallback); + nvram_read_u32(prefix, NULL, "mcsbw405ghpo", &sprom->mcsbw405ghpo, 0, + fallback); + nvram_read_u16(prefix, NULL, "mcs32po", &sprom->mcs32po, 0, fallback); nvram_read_u16(prefix, NULL, "legofdm40duppo", - &sprom->legofdm40duppo, 0); - nvram_read_u8(prefix, NULL, "sar2g", &sprom->sar2g, 0); - nvram_read_u8(prefix, NULL, "sar5g", &sprom->sar5g, 0); + &sprom->legofdm40duppo, 0, fallback); + nvram_read_u8(prefix, NULL, "sar2g", &sprom->sar2g, 0, fallback); + nvram_read_u8(prefix, NULL, "sar5g", &sprom->sar5g, 0, fallback); } static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom, - const char *prefix) + const char *prefix, bool fallback) { char postfix[2]; int i; @@ -483,46 +572,46 @@ static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom, struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i]; snprintf(postfix, sizeof(postfix), "%i", i); nvram_read_u8(prefix, postfix, "maxp2ga", - &pwr_info->maxpwr_2g, 0); + &pwr_info->maxpwr_2g, 0, fallback); nvram_read_u8(prefix, postfix, "itt2ga", - &pwr_info->itssi_2g, 0); + &pwr_info->itssi_2g, 0, fallback); nvram_read_u8(prefix, postfix, "itt5ga", - &pwr_info->itssi_5g, 0); + &pwr_info->itssi_5g, 0, fallback); nvram_read_u16(prefix, postfix, "pa2gw0a", - &pwr_info->pa_2g[0], 0); + &pwr_info->pa_2g[0], 0, fallback); nvram_read_u16(prefix, postfix, "pa2gw1a", - &pwr_info->pa_2g[1], 0); + &pwr_info->pa_2g[1], 0, fallback); nvram_read_u16(prefix, postfix, "pa2gw2a", - &pwr_info->pa_2g[2], 0); + &pwr_info->pa_2g[2], 0, fallback); nvram_read_u8(prefix, postfix, "maxp5ga", - &pwr_info->maxpwr_5g, 0); + &pwr_info->maxpwr_5g, 0, fallback); nvram_read_u8(prefix, postfix, "maxp5gha", - &pwr_info->maxpwr_5gh, 0); + &pwr_info->maxpwr_5gh, 0, fallback); nvram_read_u8(prefix, postfix, "maxp5gla", - &pwr_info->maxpwr_5gl, 0); + &pwr_info->maxpwr_5gl, 0, fallback); nvram_read_u16(prefix, postfix, "pa5gw0a", - &pwr_info->pa_5g[0], 0); + &pwr_info->pa_5g[0], 0, fallback); nvram_read_u16(prefix, postfix, "pa5gw1a", - &pwr_info->pa_5g[1], 0); + &pwr_info->pa_5g[1], 0, fallback); nvram_read_u16(prefix, postfix, "pa5gw2a", - &pwr_info->pa_5g[2], 0); + &pwr_info->pa_5g[2], 0, fallback); nvram_read_u16(prefix, postfix, "pa5glw0a", - &pwr_info->pa_5gl[0], 0); + &pwr_info->pa_5gl[0], 0, fallback); nvram_read_u16(prefix, postfix, "pa5glw1a", - &pwr_info->pa_5gl[1], 0); + &pwr_info->pa_5gl[1], 0, fallback); nvram_read_u16(prefix, postfix, "pa5glw2a", - &pwr_info->pa_5gl[2], 0); + &pwr_info->pa_5gl[2], 0, fallback); nvram_read_u16(prefix, postfix, "pa5ghw0a", - &pwr_info->pa_5gh[0], 0); + &pwr_info->pa_5gh[0], 0, fallback); nvram_read_u16(prefix, postfix, "pa5ghw1a", - &pwr_info->pa_5gh[1], 0); + &pwr_info->pa_5gh[1], 0, fallback); nvram_read_u16(prefix, postfix, "pa5ghw2a", - &pwr_info->pa_5gh[2], 0); + &pwr_info->pa_5gh[2], 0, fallback); } } static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom, - const char *prefix) + const char *prefix, bool fallback) { char postfix[2]; int i; @@ -531,91 +620,112 @@ static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom, struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i]; snprintf(postfix, sizeof(postfix), "%i", i); nvram_read_u16(prefix, postfix, "pa2gw3a", - &pwr_info->pa_2g[3], 0); + &pwr_info->pa_2g[3], 0, fallback); nvram_read_u16(prefix, postfix, "pa5gw3a", - &pwr_info->pa_5g[3], 0); + &pwr_info->pa_5g[3], 0, fallback); nvram_read_u16(prefix, postfix, "pa5glw3a", - &pwr_info->pa_5gl[3], 0); + &pwr_info->pa_5gl[3], 0, fallback); nvram_read_u16(prefix, postfix, "pa5ghw3a", - &pwr_info->pa_5gh[3], 0); + &pwr_info->pa_5gh[3], 0, fallback); } } -void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix) +static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, + const char *prefix, bool fallback) { - nvram_read_macaddr(prefix, "et0macaddr", &sprom->et0mac); - nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0); - nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0); - - nvram_read_macaddr(prefix, "et1macaddr", &sprom->et1mac); - nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0); - nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0); + nvram_read_macaddr(prefix, "et0macaddr", &sprom->et0mac, fallback); + nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0, + fallback); + nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0, + fallback); + + nvram_read_macaddr(prefix, "et1macaddr", &sprom->et1mac, fallback); + nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0, + fallback); + nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0, + fallback); + + nvram_read_macaddr(prefix, "macaddr", &sprom->il0mac, fallback); + nvram_read_macaddr(prefix, "il0macaddr", &sprom->il0mac, fallback); +} - nvram_read_macaddr(prefix, "macaddr", &sprom->il0mac); - nvram_read_macaddr(prefix, "il0macaddr", &sprom->il0mac); +static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix, + bool fallback) +{ + nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0, + fallback); + nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0, + fallback); + nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0, + fallback); + nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, + &sprom->boardflags_hi, fallback); + nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo, + &sprom->boardflags2_hi, fallback); } -void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix) +void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix, + bool fallback) { - bcm47xx_fill_sprom_ethernet(sprom, prefix); + bcm47xx_fill_sprom_ethernet(sprom, prefix, fallback); + bcm47xx_fill_board_data(sprom, prefix, fallback); - nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0); + nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0, fallback); switch (sprom->revision) { case 1: - bcm47xx_fill_sprom_r1234589(sprom, prefix); - bcm47xx_fill_sprom_r12389(sprom, prefix); - bcm47xx_fill_sprom_r1(sprom, prefix); + bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); + bcm47xx_fill_sprom_r12389(sprom, prefix, fallback); + bcm47xx_fill_sprom_r1(sprom, prefix, fallback); break; case 2: - bcm47xx_fill_sprom_r1234589(sprom, prefix); - bcm47xx_fill_sprom_r12389(sprom, prefix); - bcm47xx_fill_sprom_r2389(sprom, prefix); - bcm47xx_fill_sprom_r2(sprom, prefix); + bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); + bcm47xx_fill_sprom_r12389(sprom, prefix, fallback); + bcm47xx_fill_sprom_r2389(sprom, prefix, fallback); break; case 3: - bcm47xx_fill_sprom_r1234589(sprom, prefix); - bcm47xx_fill_sprom_r12389(sprom, prefix); - bcm47xx_fill_sprom_r2389(sprom, prefix); - bcm47xx_fill_sprom_r389(sprom, prefix); - bcm47xx_fill_sprom_r3(sprom, prefix); + bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); + bcm47xx_fill_sprom_r12389(sprom, prefix, fallback); + bcm47xx_fill_sprom_r2389(sprom, prefix, fallback); + bcm47xx_fill_sprom_r389(sprom, prefix, fallback); + bcm47xx_fill_sprom_r3(sprom, prefix, fallback); break; case 4: case 5: - bcm47xx_fill_sprom_r1234589(sprom, prefix); - bcm47xx_fill_sprom_r4589(sprom, prefix); - bcm47xx_fill_sprom_r458(sprom, prefix); - bcm47xx_fill_sprom_r45(sprom, prefix); - bcm47xx_fill_sprom_path_r4589(sprom, prefix); - bcm47xx_fill_sprom_path_r45(sprom, prefix); + bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); + bcm47xx_fill_sprom_r4589(sprom, prefix, fallback); + bcm47xx_fill_sprom_r458(sprom, prefix, fallback); + bcm47xx_fill_sprom_r45(sprom, prefix, fallback); + bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback); + bcm47xx_fill_sprom_path_r45(sprom, prefix, fallback); break; case 8: - bcm47xx_fill_sprom_r1234589(sprom, prefix); - bcm47xx_fill_sprom_r12389(sprom, prefix); - bcm47xx_fill_sprom_r2389(sprom, prefix); - bcm47xx_fill_sprom_r389(sprom, prefix); - bcm47xx_fill_sprom_r4589(sprom, prefix); - bcm47xx_fill_sprom_r458(sprom, prefix); - bcm47xx_fill_sprom_r89(sprom, prefix); - bcm47xx_fill_sprom_path_r4589(sprom, prefix); + bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); + bcm47xx_fill_sprom_r12389(sprom, prefix, fallback); + bcm47xx_fill_sprom_r2389(sprom, prefix, fallback); + bcm47xx_fill_sprom_r389(sprom, prefix, fallback); + bcm47xx_fill_sprom_r4589(sprom, prefix, fallback); + bcm47xx_fill_sprom_r458(sprom, prefix, fallback); + bcm47xx_fill_sprom_r89(sprom, prefix, fallback); + bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback); break; case 9: - bcm47xx_fill_sprom_r1234589(sprom, prefix); - bcm47xx_fill_sprom_r12389(sprom, prefix); - bcm47xx_fill_sprom_r2389(sprom, prefix); - bcm47xx_fill_sprom_r389(sprom, prefix); - bcm47xx_fill_sprom_r4589(sprom, prefix); - bcm47xx_fill_sprom_r89(sprom, prefix); - bcm47xx_fill_sprom_r9(sprom, prefix); - bcm47xx_fill_sprom_path_r4589(sprom, prefix); + bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); + bcm47xx_fill_sprom_r12389(sprom, prefix, fallback); + bcm47xx_fill_sprom_r2389(sprom, prefix, fallback); + bcm47xx_fill_sprom_r389(sprom, prefix, fallback); + bcm47xx_fill_sprom_r4589(sprom, prefix, fallback); + bcm47xx_fill_sprom_r89(sprom, prefix, fallback); + bcm47xx_fill_sprom_r9(sprom, prefix, fallback); + bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback); break; default: pr_warn("Unsupported SPROM revision %d detected. Will extract" " v1\n", sprom->revision); sprom->revision = 1; - bcm47xx_fill_sprom_r1234589(sprom, prefix); - bcm47xx_fill_sprom_r12389(sprom, prefix); - bcm47xx_fill_sprom_r1(sprom, prefix); + bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); + bcm47xx_fill_sprom_r12389(sprom, prefix, fallback); + bcm47xx_fill_sprom_r1(sprom, prefix, fallback); } } @@ -623,11 +733,12 @@ void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix) void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo, const char *prefix) { - nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0); + nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0, + true); if (!boardinfo->vendor) boardinfo->vendor = SSB_BOARDVENDOR_BCM; - nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0); + nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true); } #endif @@ -635,10 +746,11 @@ void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo, void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo, const char *prefix) { - nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0); + nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0, + true); if (!boardinfo->vendor) boardinfo->vendor = SSB_BOARDVENDOR_BCM; - nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0); + nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true); } #endif diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c index e80d585731aa..9d111e8087ec 100644 --- a/arch/mips/bcm47xx/wgt634u.c +++ b/arch/mips/bcm47xx/wgt634u.c @@ -11,6 +11,7 @@ #include <linux/leds.h> #include <linux/mtd/physmap.h> #include <linux/ssb/ssb.h> +#include <linux/ssb/ssb_embedded.h> #include <linux/interrupt.h> #include <linux/reboot.h> #include <linux/gpio.h> @@ -116,7 +117,8 @@ static irqreturn_t gpio_interrupt(int irq, void *ignored) /* Interrupt are level triggered, revert the interrupt polarity to clear the interrupt. */ - gpio_polarity(WGT634U_GPIO_RESET, state); + ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << WGT634U_GPIO_RESET, + state ? 1 << WGT634U_GPIO_RESET : 0); if (!state) { printk(KERN_INFO "Reset button pressed"); @@ -150,7 +152,9 @@ static int __init wgt634u_init(void) gpio_interrupt, IRQF_SHARED, "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) { gpio_direction_input(WGT634U_GPIO_RESET); - gpio_intmask(WGT634U_GPIO_RESET, 1); + ssb_gpio_intmask(&bcm47xx_bus.ssb, + 1 << WGT634U_GPIO_RESET, + 1 << WGT634U_GPIO_RESET); ssb_chipco_irq_mask(&bcm47xx_bus.ssb.chipco, SSB_CHIPCO_IRQ_GPIO, SSB_CHIPCO_IRQ_GPIO); diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile index 9bbb30a9dc20..ac2807397c1c 100644 --- a/arch/mips/bcm63xx/Makefile +++ b/arch/mips/bcm63xx/Makefile @@ -1,6 +1,7 @@ -obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ - dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \ - dev-spi.o dev-uart.o dev-wdt.o dev-usb-usbd.o +obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o reset.o \ + setup.o timer.o dev-dsp.o dev-enet.o dev-flash.o \ + dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-wdt.o \ + dev-usb-usbd.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-y += boards/ diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index 1cd4d73f23c7..73be9b349690 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -18,6 +18,7 @@ #include <bcm63xx_dev_uart.h> #include <bcm63xx_regs.h> #include <bcm63xx_io.h> +#include <bcm63xx_nvram.h> #include <bcm63xx_dev_pci.h> #include <bcm63xx_dev_enet.h> #include <bcm63xx_dev_dsp.h> @@ -29,8 +30,6 @@ #define PFX "board_bcm963xx: " -static struct bcm963xx_nvram nvram; -static unsigned int mac_addr_used; static struct board_info board; /* @@ -716,50 +715,14 @@ const char *board_get_name(void) } /* - * register & return a new board mac address - */ -static int board_get_mac_address(u8 *mac) -{ - u8 *oui; - int count; - - if (mac_addr_used >= nvram.mac_addr_count) { - printk(KERN_ERR PFX "not enough mac address\n"); - return -ENODEV; - } - - memcpy(mac, nvram.mac_addr_base, ETH_ALEN); - oui = mac + ETH_ALEN/2 - 1; - count = mac_addr_used; - - while (count--) { - u8 *p = mac + ETH_ALEN - 1; - - do { - (*p)++; - if (*p != 0) - break; - p--; - } while (p != oui); - - if (p == oui) { - printk(KERN_ERR PFX "unable to fetch mac address\n"); - return -ENODEV; - } - } - - mac_addr_used++; - return 0; -} - -/* * early init callback, read nvram data from flash and checksum it */ void __init board_prom_init(void) { - unsigned int check_len, i; - u8 *boot_addr, *cfe, *p; + unsigned int i; + u8 *boot_addr, *cfe; char cfe_version[32]; + char *board_name; u32 val; /* read base address of boot chip select (0) @@ -782,27 +745,15 @@ void __init board_prom_init(void) strcpy(cfe_version, "unknown"); printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); - /* extract nvram data */ - memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram)); - - /* check checksum before using data */ - if (nvram.version <= 4) - check_len = offsetof(struct bcm963xx_nvram, checksum_old); - else - check_len = sizeof(nvram); - val = 0; - p = (u8 *)&nvram; - while (check_len--) - val += *p; - if (val) { + if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) { printk(KERN_ERR PFX "invalid nvram checksum\n"); return; } + board_name = bcm63xx_nvram_get_name(); /* find board by name */ for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { - if (strncmp(nvram.name, bcm963xx_boards[i]->name, - sizeof(nvram.name))) + if (strncmp(board_name, bcm963xx_boards[i]->name, 16)) continue; /* copy, board desc array is marked initdata */ memcpy(&board, bcm963xx_boards[i], sizeof(board)); @@ -812,7 +763,7 @@ void __init board_prom_init(void) /* bail out if board is not found, will complain later */ if (!board.name[0]) { char name[17]; - memcpy(name, nvram.name, 16); + memcpy(name, board_name, 16); name[16] = 0; printk(KERN_ERR PFX "unknown bcm963xx board: %s\n", name); @@ -890,11 +841,11 @@ int __init board_register_devices(void) bcm63xx_pcmcia_register(); if (board.has_enet0 && - !board_get_mac_address(board.enet0.mac_addr)) + !bcm63xx_nvram_get_mac_address(board.enet0.mac_addr)) bcm63xx_enet_register(0, &board.enet0); if (board.has_enet1 && - !board_get_mac_address(board.enet1.mac_addr)) + !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr)) bcm63xx_enet_register(1, &board.enet1); if (board.has_usbd) @@ -907,7 +858,7 @@ int __init board_register_devices(void) * do this after registering enet devices */ #ifdef CONFIG_SSB_PCIHOST - if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { + if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) { memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); if (ssb_arch_register_fallback_sprom( diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c index dff79ab6005e..b9e948d59430 100644 --- a/arch/mips/bcm63xx/clk.c +++ b/arch/mips/bcm63xx/clk.c @@ -14,6 +14,7 @@ #include <bcm63xx_cpu.h> #include <bcm63xx_io.h> #include <bcm63xx_regs.h> +#include <bcm63xx_reset.h> #include <bcm63xx_clk.h> static DEFINE_MUTEX(clocks_mutex); @@ -124,15 +125,10 @@ static void enetsw_set(struct clk *clk, int enable) CKCTL_6368_SWPKT_USB_EN | CKCTL_6368_SWPKT_SAR_EN, enable); if (enable) { - u32 val; - /* reset switch core afer clock change */ - val = bcm_perf_readl(PERF_SOFTRESET_6368_REG); - val &= ~SOFTRESET_6368_ENETSW_MASK; - bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); + bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 1); msleep(10); - val |= SOFTRESET_6368_ENETSW_MASK; - bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); + bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 0); msleep(10); } } @@ -222,15 +218,10 @@ static void xtm_set(struct clk *clk, int enable) CKCTL_6368_SWPKT_SAR_EN, enable); if (enable) { - u32 val; - /* reset sar core afer clock change */ - val = bcm_perf_readl(PERF_SOFTRESET_6368_REG); - val &= ~SOFTRESET_6368_SAR_MASK; - bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); + bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 1); mdelay(1); - val |= SOFTRESET_6368_SAR_MASK; - bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); + bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 0); mdelay(1); } } @@ -253,6 +244,19 @@ static struct clk clk_ipsec = { }; /* + * PCIe clock + */ + +static void pcie_set(struct clk *clk, int enable) +{ + bcm_hwclock_set(CKCTL_6328_PCIE_EN, enable); +} + +static struct clk clk_pcie = { + .set = pcie_set, +}; + +/* * Internal peripheral clock */ static struct clk clk_periph = { @@ -313,6 +317,8 @@ struct clk *clk_get(struct device *dev, const char *id) return &clk_pcm; if (BCMCPU_IS_6368() && !strcmp(id, "ipsec")) return &clk_ipsec; + if (BCMCPU_IS_6328() && !strcmp(id, "pcie")) + return &clk_pcie; return ERR_PTR(-ENOENT); } diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c new file mode 100644 index 000000000000..620611680839 --- /dev/null +++ b/arch/mips/bcm63xx/nvram.c @@ -0,0 +1,107 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org> + * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com> + */ + +#define pr_fmt(fmt) "bcm63xx_nvram: " fmt + +#include <linux/init.h> +#include <linux/crc32.h> +#include <linux/export.h> +#include <linux/kernel.h> +#include <linux/if_ether.h> + +#include <bcm63xx_nvram.h> + +/* + * nvram structure + */ +struct bcm963xx_nvram { + u32 version; + u8 reserved1[256]; + u8 name[16]; + u32 main_tp_number; + u32 psi_size; + u32 mac_addr_count; + u8 mac_addr_base[ETH_ALEN]; + u8 reserved2[2]; + u32 checksum_old; + u8 reserved3[720]; + u32 checksum_high; +}; + +static struct bcm963xx_nvram nvram; +static int mac_addr_used; + +int __init bcm63xx_nvram_init(void *addr) +{ + unsigned int check_len; + u32 crc, expected_crc; + + /* extract nvram data */ + memcpy(&nvram, addr, sizeof(nvram)); + + /* check checksum before using data */ + if (nvram.version <= 4) { + check_len = offsetof(struct bcm963xx_nvram, reserved3); + expected_crc = nvram.checksum_old; + nvram.checksum_old = 0; + } else { + check_len = sizeof(nvram); + expected_crc = nvram.checksum_high; + nvram.checksum_high = 0; + } + + crc = crc32_le(~0, (u8 *)&nvram, check_len); + + if (crc != expected_crc) + return -EINVAL; + + return 0; +} + +u8 *bcm63xx_nvram_get_name(void) +{ + return nvram.name; +} +EXPORT_SYMBOL(bcm63xx_nvram_get_name); + +int bcm63xx_nvram_get_mac_address(u8 *mac) +{ + u8 *oui; + int count; + + if (mac_addr_used >= nvram.mac_addr_count) { + pr_err("not enough mac addresses\n"); + return -ENODEV; + } + + memcpy(mac, nvram.mac_addr_base, ETH_ALEN); + oui = mac + ETH_ALEN/2 - 1; + count = mac_addr_used; + + while (count--) { + u8 *p = mac + ETH_ALEN - 1; + + do { + (*p)++; + if (*p != 0) + break; + p--; + } while (p != oui); + + if (p == oui) { + pr_err("unable to fetch mac address\n"); + return -ENODEV; + } + } + + mac_addr_used++; + return 0; +} +EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); diff --git a/arch/mips/bcm63xx/reset.c b/arch/mips/bcm63xx/reset.c new file mode 100644 index 000000000000..68a31bb90cbf --- /dev/null +++ b/arch/mips/bcm63xx/reset.c @@ -0,0 +1,223 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com> + */ + +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <bcm63xx_cpu.h> +#include <bcm63xx_io.h> +#include <bcm63xx_regs.h> +#include <bcm63xx_reset.h> + +#define __GEN_RESET_BITS_TABLE(__cpu) \ + [BCM63XX_RESET_SPI] = BCM## __cpu ##_RESET_SPI, \ + [BCM63XX_RESET_ENET] = BCM## __cpu ##_RESET_ENET, \ + [BCM63XX_RESET_USBH] = BCM## __cpu ##_RESET_USBH, \ + [BCM63XX_RESET_USBD] = BCM## __cpu ##_RESET_USBD, \ + [BCM63XX_RESET_DSL] = BCM## __cpu ##_RESET_DSL, \ + [BCM63XX_RESET_SAR] = BCM## __cpu ##_RESET_SAR, \ + [BCM63XX_RESET_EPHY] = BCM## __cpu ##_RESET_EPHY, \ + [BCM63XX_RESET_ENETSW] = BCM## __cpu ##_RESET_ENETSW, \ + [BCM63XX_RESET_PCM] = BCM## __cpu ##_RESET_PCM, \ + [BCM63XX_RESET_MPI] = BCM## __cpu ##_RESET_MPI, \ + [BCM63XX_RESET_PCIE] = BCM## __cpu ##_RESET_PCIE, \ + [BCM63XX_RESET_PCIE_EXT] = BCM## __cpu ##_RESET_PCIE_EXT, + +#define BCM6328_RESET_SPI SOFTRESET_6328_SPI_MASK +#define BCM6328_RESET_ENET 0 +#define BCM6328_RESET_USBH SOFTRESET_6328_USBH_MASK +#define BCM6328_RESET_USBD SOFTRESET_6328_USBS_MASK +#define BCM6328_RESET_DSL 0 +#define BCM6328_RESET_SAR SOFTRESET_6328_SAR_MASK +#define BCM6328_RESET_EPHY SOFTRESET_6328_EPHY_MASK +#define BCM6328_RESET_ENETSW SOFTRESET_6328_ENETSW_MASK +#define BCM6328_RESET_PCM SOFTRESET_6328_PCM_MASK +#define BCM6328_RESET_MPI 0 +#define BCM6328_RESET_PCIE \ + (SOFTRESET_6328_PCIE_MASK | \ + SOFTRESET_6328_PCIE_CORE_MASK | \ + SOFTRESET_6328_PCIE_HARD_MASK) +#define BCM6328_RESET_PCIE_EXT SOFTRESET_6328_PCIE_EXT_MASK + +#define BCM6338_RESET_SPI SOFTRESET_6338_SPI_MASK +#define BCM6338_RESET_ENET SOFTRESET_6338_ENET_MASK +#define BCM6338_RESET_USBH SOFTRESET_6338_USBH_MASK +#define BCM6338_RESET_USBD SOFTRESET_6338_USBS_MASK +#define BCM6338_RESET_DSL SOFTRESET_6338_ADSL_MASK +#define BCM6338_RESET_SAR SOFTRESET_6338_SAR_MASK +#define BCM6338_RESET_EPHY 0 +#define BCM6338_RESET_ENETSW 0 +#define BCM6338_RESET_PCM 0 +#define BCM6338_RESET_MPI 0 +#define BCM6338_RESET_PCIE 0 +#define BCM6338_RESET_PCIE_EXT 0 + +#define BCM6348_RESET_SPI SOFTRESET_6348_SPI_MASK +#define BCM6348_RESET_ENET SOFTRESET_6348_ENET_MASK +#define BCM6348_RESET_USBH SOFTRESET_6348_USBH_MASK +#define BCM6348_RESET_USBD SOFTRESET_6348_USBS_MASK +#define BCM6348_RESET_DSL SOFTRESET_6348_ADSL_MASK +#define BCM6348_RESET_SAR SOFTRESET_6348_SAR_MASK +#define BCM6348_RESET_EPHY 0 +#define BCM6348_RESET_ENETSW 0 +#define BCM6348_RESET_PCM 0 +#define BCM6348_RESET_MPI 0 +#define BCM6348_RESET_PCIE 0 +#define BCM6348_RESET_PCIE_EXT 0 + +#define BCM6358_RESET_SPI SOFTRESET_6358_SPI_MASK +#define BCM6358_RESET_ENET SOFTRESET_6358_ENET_MASK +#define BCM6358_RESET_USBH SOFTRESET_6358_USBH_MASK +#define BCM6358_RESET_USBD 0 +#define BCM6358_RESET_DSL SOFTRESET_6358_ADSL_MASK +#define BCM6358_RESET_SAR SOFTRESET_6358_SAR_MASK +#define BCM6358_RESET_EPHY SOFTRESET_6358_EPHY_MASK +#define BCM6358_RESET_ENETSW 0 +#define BCM6358_RESET_PCM SOFTRESET_6358_PCM_MASK +#define BCM6358_RESET_MPI SOFTRESET_6358_MPI_MASK +#define BCM6358_RESET_PCIE 0 +#define BCM6358_RESET_PCIE_EXT 0 + +#define BCM6368_RESET_SPI SOFTRESET_6368_SPI_MASK +#define BCM6368_RESET_ENET 0 +#define BCM6368_RESET_USBH SOFTRESET_6368_USBH_MASK +#define BCM6368_RESET_USBD SOFTRESET_6368_USBS_MASK +#define BCM6368_RESET_DSL 0 +#define BCM6368_RESET_SAR SOFTRESET_6368_SAR_MASK +#define BCM6368_RESET_EPHY SOFTRESET_6368_EPHY_MASK +#define BCM6368_RESET_ENETSW 0 +#define BCM6368_RESET_PCM SOFTRESET_6368_PCM_MASK +#define BCM6368_RESET_MPI SOFTRESET_6368_MPI_MASK +#define BCM6368_RESET_PCIE 0 +#define BCM6368_RESET_PCIE_EXT 0 + +#ifdef BCMCPU_RUNTIME_DETECT + +/* + * core reset bits + */ +static const u32 bcm6328_reset_bits[] = { + __GEN_RESET_BITS_TABLE(6328) +}; + +static const u32 bcm6338_reset_bits[] = { + __GEN_RESET_BITS_TABLE(6338) +}; + +static const u32 bcm6348_reset_bits[] = { + __GEN_RESET_BITS_TABLE(6348) +}; + +static const u32 bcm6358_reset_bits[] = { + __GEN_RESET_BITS_TABLE(6358) +}; + +static const u32 bcm6368_reset_bits[] = { + __GEN_RESET_BITS_TABLE(6368) +}; + +const u32 *bcm63xx_reset_bits; +static int reset_reg; + +static int __init bcm63xx_reset_bits_init(void) +{ + if (BCMCPU_IS_6328()) { + reset_reg = PERF_SOFTRESET_6328_REG; + bcm63xx_reset_bits = bcm6328_reset_bits; + } else if (BCMCPU_IS_6338()) { + reset_reg = PERF_SOFTRESET_REG; + bcm63xx_reset_bits = bcm6338_reset_bits; + } else if (BCMCPU_IS_6348()) { + reset_reg = PERF_SOFTRESET_REG; + bcm63xx_reset_bits = bcm6348_reset_bits; + } else if (BCMCPU_IS_6358()) { + reset_reg = PERF_SOFTRESET_6358_REG; + bcm63xx_reset_bits = bcm6358_reset_bits; + } else if (BCMCPU_IS_6368()) { + reset_reg = PERF_SOFTRESET_6368_REG; + bcm63xx_reset_bits = bcm6368_reset_bits; + } + + return 0; +} +#else + +#ifdef CONFIG_BCM63XX_CPU_6328 +static const u32 bcm63xx_reset_bits[] = { + __GEN_RESET_BITS_TABLE(6328) +}; +#define reset_reg PERF_SOFTRESET_6328_REG +#endif + +#ifdef CONFIG_BCM63XX_CPU_6338 +static const u32 bcm63xx_reset_bits[] = { + __GEN_RESET_BITS_TABLE(6338) +}; +#define reset_reg PERF_SOFTRESET_REG +#endif + +#ifdef CONFIG_BCM63XX_CPU_6345 +static const u32 bcm63xx_reset_bits[] = { }; +#define reset_reg 0 +#endif + +#ifdef CONFIG_BCM63XX_CPU_6348 +static const u32 bcm63xx_reset_bits[] = { + __GEN_RESET_BITS_TABLE(6348) +}; +#define reset_reg PERF_SOFTRESET_REG +#endif + +#ifdef CONFIG_BCM63XX_CPU_6358 +static const u32 bcm63xx_reset_bits[] = { + __GEN_RESET_BITS_TABLE(6358) +}; +#define reset_reg PERF_SOFTRESET_6358_REG +#endif + +#ifdef CONFIG_BCM63XX_CPU_6368 +static const u32 bcm63xx_reset_bits[] = { + __GEN_RESET_BITS_TABLE(6368) +}; +#define reset_reg PERF_SOFTRESET_6368_REG +#endif + +static int __init bcm63xx_reset_bits_init(void) { return 0; } +#endif + +static DEFINE_SPINLOCK(reset_mutex); + +static void __bcm63xx_core_set_reset(u32 mask, int enable) +{ + unsigned long flags; + u32 val; + + if (!mask) + return; + + spin_lock_irqsave(&reset_mutex, flags); + val = bcm_perf_readl(reset_reg); + + if (enable) + val &= ~mask; + else + val |= mask; + + bcm_perf_writel(val, reset_reg); + spin_unlock_irqrestore(&reset_mutex, flags); +} + +void bcm63xx_core_set_reset(enum bcm63xx_core_reset core, int reset) +{ + __bcm63xx_core_set_reset(bcm63xx_reset_bits[core], reset); +} +EXPORT_SYMBOL(bcm63xx_core_set_reset); + +postcore_initcall(bcm63xx_reset_bits_init); diff --git a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c index fdf5f19bfdb0..6d5ddbc112cc 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c +++ b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c @@ -688,3 +688,8 @@ int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr, cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock)); return addr_allocated; } + +struct cvmx_bootmem_desc *cvmx_bootmem_get_desc(void) +{ + return cvmx_bootmem_desc; +} diff --git a/arch/mips/cavium-octeon/flash_setup.c b/arch/mips/cavium-octeon/flash_setup.c index e44a55bc7f0d..237e5b1a72d8 100644 --- a/arch/mips/cavium-octeon/flash_setup.c +++ b/arch/mips/cavium-octeon/flash_setup.c @@ -51,7 +51,8 @@ static int __init flash_init(void) flash_map.name = "phys_mapped_flash"; flash_map.phys = region_cfg.s.base << 16; flash_map.size = 0x1fc00000 - flash_map.phys; - flash_map.bankwidth = 1; + /* 8-bit bus (0 + 1) or 16-bit bus (1 + 1) */ + flash_map.bankwidth = region_cfg.s.width + 1; flash_map.virt = ioremap(flash_map.phys, flash_map.size); pr_notice("Bootbus flash: Setting flash for %luMB flash at " "0x%08llx\n", flash_map.size >> 20, flash_map.phys); diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index 02b15eed4bcd..46f5dbceeecc 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c @@ -1266,7 +1266,6 @@ static void __init octeon_irq_init_ciu(void) octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_TIMER0, 0, i + 52); octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB0, 0, 56); - octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_BOOTDMA, 0, 63); /* CIU_1 */ for (i = 0; i < 16; i++) diff --git a/arch/mips/cavium-octeon/octeon-memcpy.S b/arch/mips/cavium-octeon/octeon-memcpy.S index db478dbb9c7b..0ba0eb96d9ac 100644 --- a/arch/mips/cavium-octeon/octeon-memcpy.S +++ b/arch/mips/cavium-octeon/octeon-memcpy.S @@ -79,11 +79,6 @@ /* * Only on the 64-bit kernel we can made use of 64-bit registers. */ -#ifdef CONFIG_64BIT -#define USE_DOUBLE -#endif - -#ifdef USE_DOUBLE #define LOAD ld #define LOADL ldl @@ -119,26 +114,6 @@ #define t6 $14 #define t7 $15 -#else - -#define LOAD lw -#define LOADL lwl -#define LOADR lwr -#define STOREL swl -#define STORER swr -#define STORE sw -#define ADD addu -#define SUB subu -#define SRL srl -#define SLL sll -#define SRA sra -#define SLLV sllv -#define SRLV srlv -#define NBYTES 4 -#define LOG_NBYTES 2 - -#endif /* USE_DOUBLE */ - #ifdef CONFIG_CPU_LITTLE_ENDIAN #define LDFIRST LOADR #define LDREST LOADL @@ -395,12 +370,10 @@ EXC( sb t0, N(dst), s_exc_p1) COPY_BYTE(0) COPY_BYTE(1) -#ifdef USE_DOUBLE COPY_BYTE(2) COPY_BYTE(3) COPY_BYTE(4) COPY_BYTE(5) -#endif EXC( lb t0, NBYTES-2(src), l_exc) SUB len, len, 1 jr ra diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c index 0938df10a71c..3c1b625a5859 100644 --- a/arch/mips/cavium-octeon/octeon-platform.c +++ b/arch/mips/cavium-octeon/octeon-platform.c @@ -24,108 +24,6 @@ #include <asm/octeon/cvmx-helper.h> #include <asm/octeon/cvmx-helper-board.h> -static struct octeon_cf_data octeon_cf_data; - -static int __init octeon_cf_device_init(void) -{ - union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg; - unsigned long base_ptr, region_base, region_size; - struct platform_device *pd; - struct resource cf_resources[3]; - unsigned int num_resources; - int i; - int ret = 0; - - /* Setup octeon-cf platform device if present. */ - base_ptr = 0; - if (octeon_bootinfo->major_version == 1 - && octeon_bootinfo->minor_version >= 1) { - if (octeon_bootinfo->compact_flash_common_base_addr) - base_ptr = - octeon_bootinfo->compact_flash_common_base_addr; - } else { - base_ptr = 0x1d000800; - } - - if (!base_ptr) - return ret; - - /* Find CS0 region. */ - for (i = 0; i < 8; i++) { - mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i)); - region_base = mio_boot_reg_cfg.s.base << 16; - region_size = (mio_boot_reg_cfg.s.size + 1) << 16; - if (mio_boot_reg_cfg.s.en && base_ptr >= region_base - && base_ptr < region_base + region_size) - break; - } - if (i >= 7) { - /* i and i + 1 are CS0 and CS1, both must be less than 8. */ - goto out; - } - octeon_cf_data.base_region = i; - octeon_cf_data.is16bit = mio_boot_reg_cfg.s.width; - octeon_cf_data.base_region_bias = base_ptr - region_base; - memset(cf_resources, 0, sizeof(cf_resources)); - num_resources = 0; - cf_resources[num_resources].flags = IORESOURCE_MEM; - cf_resources[num_resources].start = region_base; - cf_resources[num_resources].end = region_base + region_size - 1; - num_resources++; - - - if (!(base_ptr & 0xfffful)) { - /* - * Boot loader signals availability of DMA (true_ide - * mode) by setting low order bits of base_ptr to - * zero. - */ - - /* Assume that CS1 immediately follows. */ - mio_boot_reg_cfg.u64 = - cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i + 1)); - region_base = mio_boot_reg_cfg.s.base << 16; - region_size = (mio_boot_reg_cfg.s.size + 1) << 16; - if (!mio_boot_reg_cfg.s.en) - goto out; - - cf_resources[num_resources].flags = IORESOURCE_MEM; - cf_resources[num_resources].start = region_base; - cf_resources[num_resources].end = region_base + region_size - 1; - num_resources++; - - octeon_cf_data.dma_engine = 0; - cf_resources[num_resources].flags = IORESOURCE_IRQ; - cf_resources[num_resources].start = OCTEON_IRQ_BOOTDMA; - cf_resources[num_resources].end = OCTEON_IRQ_BOOTDMA; - num_resources++; - } else { - octeon_cf_data.dma_engine = -1; - } - - pd = platform_device_alloc("pata_octeon_cf", -1); - if (!pd) { - ret = -ENOMEM; - goto out; - } - pd->dev.platform_data = &octeon_cf_data; - - ret = platform_device_add_resources(pd, cf_resources, num_resources); - if (ret) - goto fail; - - ret = platform_device_add(pd); - if (ret) - goto fail; - - return ret; -fail: - platform_device_put(pd); -out: - return ret; -} -device_initcall(octeon_cf_device_init); - /* Octeon Random Number Generator. */ static int __init octeon_rng_device_init(void) { diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 04dd8ff0e0d8..d7e0a09f77c2 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -4,9 +4,11 @@ * for more details. * * Copyright (C) 2004-2007 Cavium Networks - * Copyright (C) 2008 Wind River Systems + * Copyright (C) 2008, 2009 Wind River Systems + * written by Ralf Baechle <ralf@linux-mips.org> */ #include <linux/init.h> +#include <linux/kernel.h> #include <linux/console.h> #include <linux/delay.h> #include <linux/export.h> @@ -23,6 +25,7 @@ #include <linux/serial_8250.h> #include <linux/of_fdt.h> #include <linux/libfdt.h> +#include <linux/kexec.h> #include <asm/processor.h> #include <asm/reboot.h> @@ -56,11 +59,208 @@ struct octeon_boot_descriptor *octeon_boot_desc_ptr; struct cvmx_bootinfo *octeon_bootinfo; EXPORT_SYMBOL(octeon_bootinfo); +static unsigned long long RESERVE_LOW_MEM = 0ull; +#ifdef CONFIG_KEXEC +#ifdef CONFIG_SMP +/* + * Wait for relocation code is prepared and send + * secondary CPUs to spin until kernel is relocated. + */ +static void octeon_kexec_smp_down(void *ignored) +{ + int cpu = smp_processor_id(); + + local_irq_disable(); + set_cpu_online(cpu, false); + while (!atomic_read(&kexec_ready_to_reboot)) + cpu_relax(); + + asm volatile ( + " sync \n" + " synci ($0) \n"); + + relocated_kexec_smp_wait(NULL); +} +#endif + +#define OCTEON_DDR0_BASE (0x0ULL) +#define OCTEON_DDR0_SIZE (0x010000000ULL) +#define OCTEON_DDR1_BASE (0x410000000ULL) +#define OCTEON_DDR1_SIZE (0x010000000ULL) +#define OCTEON_DDR2_BASE (0x020000000ULL) +#define OCTEON_DDR2_SIZE (0x3e0000000ULL) +#define OCTEON_MAX_PHY_MEM_SIZE (16*1024*1024*1024ULL) + +static struct kimage *kimage_ptr; + +static void kexec_bootmem_init(uint64_t mem_size, uint32_t low_reserved_bytes) +{ + int64_t addr; + struct cvmx_bootmem_desc *bootmem_desc; + + bootmem_desc = cvmx_bootmem_get_desc(); + + if (mem_size > OCTEON_MAX_PHY_MEM_SIZE) { + mem_size = OCTEON_MAX_PHY_MEM_SIZE; + pr_err("Error: requested memory too large," + "truncating to maximum size\n"); + } + + bootmem_desc->major_version = CVMX_BOOTMEM_DESC_MAJ_VER; + bootmem_desc->minor_version = CVMX_BOOTMEM_DESC_MIN_VER; + + addr = (OCTEON_DDR0_BASE + RESERVE_LOW_MEM + low_reserved_bytes); + bootmem_desc->head_addr = 0; + + if (mem_size <= OCTEON_DDR0_SIZE) { + __cvmx_bootmem_phy_free(addr, + mem_size - RESERVE_LOW_MEM - + low_reserved_bytes, 0); + return; + } + + __cvmx_bootmem_phy_free(addr, + OCTEON_DDR0_SIZE - RESERVE_LOW_MEM - + low_reserved_bytes, 0); + + mem_size -= OCTEON_DDR0_SIZE; + + if (mem_size > OCTEON_DDR1_SIZE) { + __cvmx_bootmem_phy_free(OCTEON_DDR1_BASE, OCTEON_DDR1_SIZE, 0); + __cvmx_bootmem_phy_free(OCTEON_DDR2_BASE, + mem_size - OCTEON_DDR1_SIZE, 0); + } else + __cvmx_bootmem_phy_free(OCTEON_DDR1_BASE, mem_size, 0); +} + +static int octeon_kexec_prepare(struct kimage *image) +{ + int i; + char *bootloader = "kexec"; + + octeon_boot_desc_ptr->argc = 0; + for (i = 0; i < image->nr_segments; i++) { + if (!strncmp(bootloader, (char *)image->segment[i].buf, + strlen(bootloader))) { + /* + * convert command line string to array + * of parameters (as bootloader does). + */ + int argc = 0, offt; + char *str = (char *)image->segment[i].buf; + char *ptr = strchr(str, ' '); + while (ptr && (OCTEON_ARGV_MAX_ARGS > argc)) { + *ptr = '\0'; + if (ptr[1] != ' ') { + offt = (int)(ptr - str + 1); + octeon_boot_desc_ptr->argv[argc] = + image->segment[i].mem + offt; + argc++; + } + ptr = strchr(ptr + 1, ' '); + } + octeon_boot_desc_ptr->argc = argc; + break; + } + } + + /* + * Information about segments will be needed during pre-boot memory + * initialization. + */ + kimage_ptr = image; + return 0; +} + +static void octeon_generic_shutdown(void) +{ + int cpu, i; + struct cvmx_bootmem_desc *bootmem_desc; + void *named_block_array_ptr; + + bootmem_desc = cvmx_bootmem_get_desc(); + named_block_array_ptr = + cvmx_phys_to_ptr(bootmem_desc->named_block_array_addr); + +#ifdef CONFIG_SMP + /* disable watchdogs */ + for_each_online_cpu(cpu) + cvmx_write_csr(CVMX_CIU_WDOGX(cpu_logical_map(cpu)), 0); +#else + cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0); +#endif + if (kimage_ptr != kexec_crash_image) { + memset(named_block_array_ptr, + 0x0, + CVMX_BOOTMEM_NUM_NAMED_BLOCKS * + sizeof(struct cvmx_bootmem_named_block_desc)); + /* + * Mark all memory (except low 0x100000 bytes) as free. + * It is the same thing that bootloader does. + */ + kexec_bootmem_init(octeon_bootinfo->dram_size*1024ULL*1024ULL, + 0x100000); + /* + * Allocate all segments to avoid their corruption during boot. + */ + for (i = 0; i < kimage_ptr->nr_segments; i++) + cvmx_bootmem_alloc_address( + kimage_ptr->segment[i].memsz + 2*PAGE_SIZE, + kimage_ptr->segment[i].mem - PAGE_SIZE, + PAGE_SIZE); + } else { + /* + * Do not mark all memory as free. Free only named sections + * leaving the rest of memory unchanged. + */ + struct cvmx_bootmem_named_block_desc *ptr = + (struct cvmx_bootmem_named_block_desc *) + named_block_array_ptr; + + for (i = 0; i < bootmem_desc->named_block_num_blocks; i++) + if (ptr[i].size) + cvmx_bootmem_free_named(ptr[i].name); + } + kexec_args[2] = 1UL; /* running on octeon_main_processor */ + kexec_args[3] = (unsigned long)octeon_boot_desc_ptr; +#ifdef CONFIG_SMP + secondary_kexec_args[2] = 0UL; /* running on secondary cpu */ + secondary_kexec_args[3] = (unsigned long)octeon_boot_desc_ptr; +#endif +} + +static void octeon_shutdown(void) +{ + octeon_generic_shutdown(); +#ifdef CONFIG_SMP + smp_call_function(octeon_kexec_smp_down, NULL, 0); + smp_wmb(); + while (num_online_cpus() > 1) { + cpu_relax(); + mdelay(1); + } +#endif +} + +static void octeon_crash_shutdown(struct pt_regs *regs) +{ + octeon_generic_shutdown(); + default_machine_crash_shutdown(regs); +} + +#endif /* CONFIG_KEXEC */ + #ifdef CONFIG_CAVIUM_RESERVE32 uint64_t octeon_reserve32_memory; EXPORT_SYMBOL(octeon_reserve32_memory); #endif +#ifdef CONFIG_KEXEC +/* crashkernel cmdline parameter is parsed _after_ memory setup + * we also parse it here (workaround for EHB5200) */ +static uint64_t crashk_size, crashk_base; +#endif + static int octeon_uart; extern asmlinkage void handle_int(void); @@ -415,6 +615,8 @@ void octeon_user_io_init(void) void __init prom_init(void) { struct cvmx_sysinfo *sysinfo; + const char *arg; + char *p; int i; int argc; #ifdef CONFIG_CAVIUM_RESERVE32 @@ -566,6 +768,15 @@ void __init prom_init(void) if (octeon_is_simulation()) MAX_MEMORY = 64ull << 20; + arg = strstr(arcs_cmdline, "mem="); + if (arg) { + MAX_MEMORY = memparse(arg + 4, &p); + if (MAX_MEMORY == 0) + MAX_MEMORY = 32ull << 30; + if (*p == '@') + RESERVE_LOW_MEM = memparse(p + 1, &p); + } + arcs_cmdline[0] = 0; argc = octeon_boot_desc_ptr->argc; for (i = 0; i < argc; i++) { @@ -573,16 +784,30 @@ void __init prom_init(void) cvmx_phys_to_ptr(octeon_boot_desc_ptr->argv[i]); if ((strncmp(arg, "MEM=", 4) == 0) || (strncmp(arg, "mem=", 4) == 0)) { - sscanf(arg + 4, "%llu", &MAX_MEMORY); - MAX_MEMORY <<= 20; + MAX_MEMORY = memparse(arg + 4, &p); if (MAX_MEMORY == 0) MAX_MEMORY = 32ull << 30; + if (*p == '@') + RESERVE_LOW_MEM = memparse(p + 1, &p); } else if (strcmp(arg, "ecc_verbose") == 0) { #ifdef CONFIG_CAVIUM_REPORT_SINGLE_BIT_ECC __cvmx_interrupt_ecc_report_single_bit_errors = 1; pr_notice("Reporting of single bit ECC errors is " "turned on\n"); #endif +#ifdef CONFIG_KEXEC + } else if (strncmp(arg, "crashkernel=", 12) == 0) { + crashk_size = memparse(arg+12, &p); + if (*p == '@') + crashk_base = memparse(p+1, &p); + strcat(arcs_cmdline, " "); + strcat(arcs_cmdline, arg); + /* + * To do: switch parsing to new style, something like: + * parse_crashkernel(arg, sysinfo->system_dram_size, + * &crashk_size, &crashk_base); + */ +#endif } else if (strlen(arcs_cmdline) + strlen(arg) + 1 < sizeof(arcs_cmdline) - 1) { strcat(arcs_cmdline, " "); @@ -617,11 +842,18 @@ void __init prom_init(void) _machine_restart = octeon_restart; _machine_halt = octeon_halt; +#ifdef CONFIG_KEXEC + _machine_kexec_shutdown = octeon_shutdown; + _machine_crash_shutdown = octeon_crash_shutdown; + _machine_kexec_prepare = octeon_kexec_prepare; +#endif + octeon_user_io_init(); register_smp_ops(&octeon_smp_ops); } /* Exclude a single page from the regions obtained in plat_mem_setup. */ +#ifndef CONFIG_CRASH_DUMP static __init void memory_exclude_page(u64 addr, u64 *mem, u64 *size) { if (addr > *mem && addr < *mem + *size) { @@ -636,14 +868,21 @@ static __init void memory_exclude_page(u64 addr, u64 *mem, u64 *size) *size -= PAGE_SIZE; } } +#endif /* CONFIG_CRASH_DUMP */ void __init plat_mem_setup(void) { uint64_t mem_alloc_size; uint64_t total; + uint64_t crashk_end; +#ifndef CONFIG_CRASH_DUMP int64_t memory; + uint64_t kernel_start; + uint64_t kernel_size; +#endif total = 0; + crashk_end = 0; /* * The Mips memory init uses the first memory location for @@ -656,6 +895,17 @@ void __init plat_mem_setup(void) if (mem_alloc_size > MAX_MEMORY) mem_alloc_size = MAX_MEMORY; +/* Crashkernel ignores bootmem list. It relies on mem=X@Y option */ +#ifdef CONFIG_CRASH_DUMP + add_memory_region(RESERVE_LOW_MEM, MAX_MEMORY, BOOT_MEM_RAM); + total += MAX_MEMORY; +#else +#ifdef CONFIG_KEXEC + if (crashk_size > 0) { + add_memory_region(crashk_base, crashk_size, BOOT_MEM_RAM); + crashk_end = crashk_base + crashk_size; + } +#endif /* * When allocating memory, we want incrementing addresses from * bootmem_alloc so the code in add_memory_region can merge @@ -664,22 +914,15 @@ void __init plat_mem_setup(void) cvmx_bootmem_lock(); while ((boot_mem_map.nr_map < BOOT_MEM_MAP_MAX) && (total < MAX_MEMORY)) { -#if defined(CONFIG_64BIT) || defined(CONFIG_64BIT_PHYS_ADDR) memory = cvmx_bootmem_phy_alloc(mem_alloc_size, __pa_symbol(&__init_end), -1, 0x100000, CVMX_BOOTMEM_FLAG_NO_LOCKING); -#elif defined(CONFIG_HIGHMEM) - memory = cvmx_bootmem_phy_alloc(mem_alloc_size, 0, 1ull << 31, - 0x100000, - CVMX_BOOTMEM_FLAG_NO_LOCKING); -#else - memory = cvmx_bootmem_phy_alloc(mem_alloc_size, 0, 512 << 20, - 0x100000, - CVMX_BOOTMEM_FLAG_NO_LOCKING); -#endif if (memory >= 0) { u64 size = mem_alloc_size; +#ifdef CONFIG_KEXEC + uint64_t end; +#endif /* * exclude a page at the beginning and end of @@ -692,20 +935,67 @@ void __init plat_mem_setup(void) memory_exclude_page(CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_PHYS_SIZE, &memory, &size); +#ifdef CONFIG_KEXEC + end = memory + mem_alloc_size; /* - * This function automatically merges address - * regions next to each other if they are - * received in incrementing order. + * This function automatically merges address regions + * next to each other if they are received in + * incrementing order */ - if (size) - add_memory_region(memory, size, BOOT_MEM_RAM); + if (memory < crashk_base && end > crashk_end) { + /* region is fully in */ + add_memory_region(memory, + crashk_base - memory, + BOOT_MEM_RAM); + total += crashk_base - memory; + add_memory_region(crashk_end, + end - crashk_end, + BOOT_MEM_RAM); + total += end - crashk_end; + continue; + } + + if (memory >= crashk_base && end <= crashk_end) + /* + * Entire memory region is within the new + * kernel's memory, ignore it. + */ + continue; + + if (memory > crashk_base && memory < crashk_end && + end > crashk_end) { + /* + * Overlap with the beginning of the region, + * reserve the beginning. + */ + mem_alloc_size -= crashk_end - memory; + memory = crashk_end; + } else if (memory < crashk_base && end > crashk_base && + end < crashk_end) + /* + * Overlap with the beginning of the region, + * chop of end. + */ + mem_alloc_size -= end - crashk_base; +#endif + add_memory_region(memory, mem_alloc_size, BOOT_MEM_RAM); total += mem_alloc_size; + /* Recovering mem_alloc_size */ + mem_alloc_size = 4 << 20; } else { break; } } cvmx_bootmem_unlock(); + /* Add the memory region for the kernel. */ + kernel_start = (unsigned long) _text; + kernel_size = ALIGN(_end - _text, 0x100000); + + /* Adjust for physical offset. */ + kernel_start &= ~0xffffffff80000000ULL; + add_memory_region(kernel_start, kernel_size, BOOT_MEM_RAM); +#endif /* CONFIG_CRASH_DUMP */ #ifdef CONFIG_CAVIUM_RESERVE32 /* @@ -821,3 +1111,51 @@ void __init device_tree_init(void) } unflatten_device_tree(); } + +static int __initdata disable_octeon_edac_p; + +static int __init disable_octeon_edac(char *str) +{ + disable_octeon_edac_p = 1; + return 0; +} +early_param("disable_octeon_edac", disable_octeon_edac); + +static char *edac_device_names[] = { + "octeon_l2c_edac", + "octeon_pc_edac", +}; + +static int __init edac_devinit(void) +{ + struct platform_device *dev; + int i, err = 0; + int num_lmc; + char *name; + + if (disable_octeon_edac_p) + return 0; + + for (i = 0; i < ARRAY_SIZE(edac_device_names); i++) { + name = edac_device_names[i]; + dev = platform_device_register_simple(name, -1, NULL, 0); + if (IS_ERR(dev)) { + pr_err("Registation of %s failed!\n", name); + err = PTR_ERR(dev); + } + } + + num_lmc = OCTEON_IS_MODEL(OCTEON_CN68XX) ? 4 : + (OCTEON_IS_MODEL(OCTEON_CN56XX) ? 2 : 1); + for (i = 0; i < num_lmc; i++) { + dev = platform_device_register_simple("octeon_lmc_edac", + i, NULL, 0); + if (IS_ERR(dev)) { + pr_err("Registation of octeon_lmc_edac %d failed!\n", i); + err = PTR_ERR(dev); + } + } + + return err; +} +device_initcall(edac_devinit); diff --git a/arch/mips/configs/ath79_defconfig b/arch/mips/configs/ath79_defconfig new file mode 100644 index 000000000000..ea87d43ba607 --- /dev/null +++ b/arch/mips/configs/ath79_defconfig @@ -0,0 +1,111 @@ +CONFIG_ATH79=y +CONFIG_ATH79_MACH_AP121=y +CONFIG_ATH79_MACH_AP81=y +CONFIG_ATH79_MACH_DB120=y +CONFIG_ATH79_MACH_PB44=y +CONFIG_ATH79_MACH_UBNT_XM=y +CONFIG_HZ_100=y +# CONFIG_SECCOMP is not set +CONFIG_EXPERIMENTAL=y +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BLK_DEV_INITRD=y +# CONFIG_RD_GZIP is not set +CONFIG_RD_LZMA=y +# CONFIG_KALLSYMS is not set +# CONFIG_AIO is not set +CONFIG_EMBEDDED=y +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_PCI=y +# CONFIG_SUSPEND is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_IPV6 is not set +CONFIG_CFG80211=m +CONFIG_MAC80211=m +CONFIG_MAC80211_DEBUGFS=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_MTD=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-2 +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_M25P80=y +# CONFIG_M25PXX_USE_FAST_READ is not set +CONFIG_NETDEVICES=y +# CONFIG_NET_PACKET_ENGINE is not set +CONFIG_ATH_COMMON=m +CONFIG_ATH9K=m +CONFIG_ATH9K_AHB=y +CONFIG_INPUT=m +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_GPIO_POLLED=m +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_MISC=y +# CONFIG_SERIO is not set +# CONFIG_VT is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_PCI is not set +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=1 +CONFIG_SERIAL_AR933X=y +CONFIG_SERIAL_AR933X_CONSOLE=y +# CONFIG_HW_RANDOM is not set +CONFIG_I2C=y +# CONFIG_I2C_COMPAT is not set +# CONFIG_I2C_HELPER_AUTO is not set +CONFIG_I2C_GPIO=y +CONFIG_SPI=y +CONFIG_SPI_ATH79=y +CONFIG_SPI_GPIO=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_PCF857X=y +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_ATH79_WDT=y +# CONFIG_VGA_ARB is not set +# CONFIG_HID is not set +# CONFIG_USB_HID is not set +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +# CONFIG_IOMMU_SUPPORT is not set +# CONFIG_DNOTIFY is not set +# CONFIG_PROC_PAGE_MONITOR is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_STRIP_ASM_SYMS=y +CONFIG_DEBUG_FS=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_FTRACE is not set +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRC_ITU_T=m diff --git a/arch/mips/configs/cavium_octeon_defconfig b/arch/mips/configs/cavium_octeon_defconfig index 75165dfa60c1..014ba4bbba7d 100644 --- a/arch/mips/configs/cavium_octeon_defconfig +++ b/arch/mips/configs/cavium_octeon_defconfig @@ -1,7 +1,11 @@ CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD=y +CONFIG_CAVIUM_CN63XXP1=y CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=2 CONFIG_SPARSEMEM_MANUAL=y +CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_SMP=y +CONFIG_NR_CPUS=32 +CONFIG_HZ_100=y CONFIG_PREEMPT=y CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y @@ -11,16 +15,15 @@ CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_SYSFS_DEPRECATED_V2=y CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EXPERT=y -# CONFIG_PCSPKR_PLATFORM is not set CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set +CONFIG_PCI=y +CONFIG_PCI_MSI=y CONFIG_MIPS32_COMPAT=y CONFIG_MIPS32_O32=y CONFIG_MIPS32_N32=y @@ -42,22 +45,68 @@ CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y # CONFIG_INET_LRO is not set -# CONFIG_IPV6 is not set +CONFIG_IPV6=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_OF_PARTS is not set CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_SLRAM=y +CONFIG_PROC_DEVICETREE=y CONFIG_BLK_DEV_LOOP=y -# CONFIG_MISC_DEVICES is not set +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_AT25=y +CONFIG_BLK_DEV_SD=y +CONFIG_ATA=y +CONFIG_SATA_AHCI=y +CONFIG_PATA_OCTEON_CF=y +CONFIG_SATA_SIL=y CONFIG_NETDEVICES=y -CONFIG_NET_ETHERNET=y CONFIG_MII=y -# CONFIG_NETDEV_10000 is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_ADAPTEC is not set +# CONFIG_NET_VENDOR_ALTEON is not set +# CONFIG_NET_VENDOR_AMD is not set +# CONFIG_NET_VENDOR_ATHEROS is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_BROCADE is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_CISCO is not set +# CONFIG_NET_VENDOR_DEC is not set +# CONFIG_NET_VENDOR_DLINK is not set +# CONFIG_NET_VENDOR_EMULEX is not set +# CONFIG_NET_VENDOR_EXAR is not set +# CONFIG_NET_VENDOR_HP is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MELLANOX is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MYRI is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NVIDIA is not set +# CONFIG_NET_VENDOR_OKI is not set +# CONFIG_NET_PACKET_ENGINE is not set +# CONFIG_NET_VENDOR_QLOGIC is not set +# CONFIG_NET_VENDOR_REALTEK is not set +# CONFIG_NET_VENDOR_RDC is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SILAN is not set +# CONFIG_NET_VENDOR_SIS is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_SUN is not set +# CONFIG_NET_VENDOR_TEHUTI is not set +# CONFIG_NET_VENDOR_TI is not set +# CONFIG_NET_VENDOR_TOSHIBA is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_MARVELL_PHY=y +CONFIG_BROADCOM_PHY=y +CONFIG_BCM87XX_PHY=y +# CONFIG_WLAN is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -66,24 +115,39 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=2 CONFIG_SERIAL_8250_RUNTIME_UARTS=2 # CONFIG_HW_RANDOM is not set +CONFIG_I2C=y +CONFIG_I2C_OCTEON=y +CONFIG_SPI=y +CONFIG_SPI_OCTEON=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_USB_SUPPORT is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_DS1307=y +CONFIG_STAGING=y +CONFIG_OCTEON_ETHERNET=y +# CONFIG_NET_VENDOR_SILICOM is not set +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y CONFIG_PROC_KCORE=y CONFIG_TMPFS=y -# CONFIG_NETWORK_FILESYSTEMS is not set -CONFIG_NLS=y +CONFIG_HUGETLBFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_ROOT_NFS=y CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_SPINLOCK=y -CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_SCHED_DEBUG is not set CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y -# CONFIG_EARLY_PRINTK is not set CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_CRYPTO_CBC=y diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig deleted file mode 100644 index f72d305a3f08..000000000000 --- a/arch/mips/configs/yosemite_defconfig +++ /dev/null @@ -1,94 +0,0 @@ -CONFIG_PMC_YOSEMITE=y -CONFIG_HIGHMEM=y -CONFIG_SMP=y -CONFIG_NR_CPUS=2 -CONFIG_HZ_1000=y -CONFIG_SYSVIPC=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_EXPERT=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_PCI=y -CONFIG_PM=y -CONFIG_NET=y -CONFIG_PACKET=m -CONFIG_UNIX=y -CONFIG_XFRM_USER=m -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m -CONFIG_IPV6_PRIVACY=y -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_TUNNEL=m -CONFIG_NETWORK_SECMARK=y -CONFIG_FW_LOADER=m -CONFIG_CONNECTOR=m -CONFIG_CDROM_PKTCDVD=m -CONFIG_ATA_OVER_ETH=m -CONFIG_SGI_IOC4=m -CONFIG_RAID_ATTRS=m -CONFIG_NETDEVICES=y -CONFIG_PHYLIB=m -CONFIG_MARVELL_PHY=m -CONFIG_DAVICOM_PHY=m -CONFIG_QSEMI_PHY=m -CONFIG_LXT_PHY=m -CONFIG_CICADA_PHY=m -CONFIG_VITESSE_PHY=m -CONFIG_SMSC_PHY=m -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -CONFIG_QLA3XXX=m -CONFIG_CHELSIO_T3=m -CONFIG_NETXEN_NIC=m -# CONFIG_INPUT is not set -# CONFIG_SERIO is not set -# CONFIG_VT is not set -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_HW_RANDOM is not set -# CONFIG_HWMON is not set -CONFIG_FUSE_FS=m -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_MUTEXES=y -CONFIG_KEYS=y -CONFIG_KEYS_DEBUG_PROC_KEYS=y -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRC16=m -CONFIG_CRC32=m -CONFIG_LIBCRC32C=m diff --git a/arch/mips/fw/sni/Makefile b/arch/mips/fw/sni/Makefile index d9740a3788e2..3f01dd36e6b7 100644 --- a/arch/mips/fw/sni/Makefile +++ b/arch/mips/fw/sni/Makefile @@ -2,4 +2,4 @@ # Makefile for the SNI prom monitor routines under Linux. # -lib-$(CONFIG_SNIPROM) += sniprom.o +lib-$(CONFIG_FW_SNIPROM) += sniprom.o diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 52c4e914f95a..90112adb1940 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -243,9 +243,9 @@ enum cpu_type_enum { */ CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, CPU_R4300, CPU_R4310, CPU_R4400PC, CPU_R4400SC, CPU_R4400MC, CPU_R4600, CPU_R4640, CPU_R4650, - CPU_R4700, CPU_R5000, CPU_R5000A, CPU_R5500, CPU_NEVADA, CPU_R5432, - CPU_R10000, CPU_R12000, CPU_R14000, CPU_VR41XX, CPU_VR4111, CPU_VR4121, - CPU_VR4122, CPU_VR4131, CPU_VR4133, CPU_VR4181, CPU_VR4181A, CPU_RM7000, + CPU_R4700, CPU_R5000, CPU_R5500, CPU_NEVADA, CPU_R5432, CPU_R10000, + CPU_R12000, CPU_R14000, CPU_VR41XX, CPU_VR4111, CPU_VR4121, CPU_VR4122, + CPU_VR4131, CPU_VR4133, CPU_VR4181, CPU_VR4181A, CPU_RM7000, CPU_SR71000, CPU_RM9000, CPU_TX49XX, /* diff --git a/arch/mips/include/asm/fw/arc/types.h b/arch/mips/include/asm/fw/arc/types.h index b9adcd6f0860..2b11f87d6fb3 100644 --- a/arch/mips/include/asm/fw/arc/types.h +++ b/arch/mips/include/asm/fw/arc/types.h @@ -10,7 +10,7 @@ #define _ASM_ARC_TYPES_H -#ifdef CONFIG_ARC32 +#ifdef CONFIG_FW_ARC32 typedef char CHAR; typedef short SHORT; @@ -33,9 +33,9 @@ typedef LONG _PUSHORT; typedef LONG _PULONG; typedef LONG _PVOID; -#endif /* CONFIG_ARC32 */ +#endif /* CONFIG_FW_ARC32 */ -#ifdef CONFIG_ARC64 +#ifdef CONFIG_FW_ARC64 typedef char CHAR; typedef short SHORT; @@ -57,7 +57,7 @@ typedef USHORT *_PUSHORT; typedef ULONG *_PULONG; typedef VOID *_PVOID; -#endif /* CONFIG_ARC64 */ +#endif /* CONFIG_FW_ARC64 */ typedef CHAR *PCHAR; typedef SHORT *PSHORT; diff --git a/arch/mips/include/asm/hazards.h b/arch/mips/include/asm/hazards.h index b4c20e4f87cd..f0324e92d089 100644 --- a/arch/mips/include/asm/hazards.h +++ b/arch/mips/include/asm/hazards.h @@ -161,31 +161,6 @@ ASMMACRO(back_to_back_c0_hazard, ) #define instruction_hazard() do { } while (0) -#elif defined(CONFIG_CPU_RM9000) - -/* - * RM9000 hazards. When the JTLB is updated by tlbwi or tlbwr, a subsequent - * use of the JTLB for instructions should not occur for 4 cpu cycles and use - * for data translations should not occur for 3 cpu cycles. - */ - -ASMMACRO(mtc0_tlbw_hazard, - _ssnop; _ssnop; _ssnop; _ssnop - ) -ASMMACRO(tlbw_use_hazard, - _ssnop; _ssnop; _ssnop; _ssnop - ) -ASMMACRO(tlb_probe_hazard, - _ssnop; _ssnop; _ssnop; _ssnop - ) -ASMMACRO(irq_enable_hazard, - ) -ASMMACRO(irq_disable_hazard, - ) -ASMMACRO(back_to_back_c0_hazard, - ) -#define instruction_hazard() do { } while (0) - #elif defined(CONFIG_CPU_SB1) /* diff --git a/arch/mips/include/asm/kexec.h b/arch/mips/include/asm/kexec.h index 4314892aaebb..ee25ebbf2a28 100644 --- a/arch/mips/include/asm/kexec.h +++ b/arch/mips/include/asm/kexec.h @@ -9,22 +9,43 @@ #ifndef _MIPS_KEXEC # define _MIPS_KEXEC +#include <asm/stacktrace.h> + /* Maximum physical address we can use pages from */ #define KEXEC_SOURCE_MEMORY_LIMIT (0x20000000) /* Maximum address we can reach in physical address mode */ #define KEXEC_DESTINATION_MEMORY_LIMIT (0x20000000) /* Maximum address we can use for the control code buffer */ #define KEXEC_CONTROL_MEMORY_LIMIT (0x20000000) - -#define KEXEC_CONTROL_PAGE_SIZE 4096 +/* Reserve 3*4096 bytes for board-specific info */ +#define KEXEC_CONTROL_PAGE_SIZE (4096 + 3*4096) /* The native architecture */ #define KEXEC_ARCH KEXEC_ARCH_MIPS +#define MAX_NOTE_BYTES 1024 static inline void crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs) { - /* Dummy implementation for now */ + if (oldregs) + memcpy(newregs, oldregs, sizeof(*newregs)); + else + prepare_frametrace(newregs); } +#ifdef CONFIG_KEXEC +struct kimage; +extern unsigned long kexec_args[4]; +extern int (*_machine_kexec_prepare)(struct kimage *); +extern void (*_machine_kexec_shutdown)(void); +extern void (*_machine_crash_shutdown)(struct pt_regs *regs); +extern void default_machine_crash_shutdown(struct pt_regs *regs); +#ifdef CONFIG_SMP +extern const unsigned char kexec_smp_wait[]; +extern unsigned long secondary_kexec_args[4]; +extern void (*relocated_kexec_smp_wait) (void *); +extern atomic_t kexec_ready_to_reboot; +#endif +#endif + #endif /* !_MIPS_KEXEC */ diff --git a/arch/mips/include/asm/mach-ar7/war.h b/arch/mips/include/asm/mach-ar7/war.h index f4862b563080..99071e50faab 100644 --- a/arch/mips/include/asm/mach-ar7/war.h +++ b/arch/mips/include/asm/mach-ar7/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-ath79/war.h b/arch/mips/include/asm/mach-ath79/war.h index 323d9f1d8c45..0bb30905fd5b 100644 --- a/arch/mips/include/asm/mach-ath79/war.h +++ b/arch/mips/include/asm/mach-ath79/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-au1x00/war.h b/arch/mips/include/asm/mach-au1x00/war.h index dd57d03d68ba..72e260d24e59 100644 --- a/arch/mips/include/asm/mach-au1x00/war.h +++ b/arch/mips/include/asm/mach-au1x00/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h index 26fdaf40b930..cc7563ba1cbf 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h @@ -44,8 +44,8 @@ union bcm47xx_bus { extern union bcm47xx_bus bcm47xx_bus; extern enum bcm47xx_bus_type bcm47xx_bus_type; -void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix); -void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix); +void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix, + bool fallback); #ifdef CONFIG_BCM47XX_SSB void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo, diff --git a/arch/mips/include/asm/mach-bcm47xx/gpio.h b/arch/mips/include/asm/mach-bcm47xx/gpio.h index 2ef17e8df403..90daefa24a4d 100644 --- a/arch/mips/include/asm/mach-bcm47xx/gpio.h +++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h @@ -1,155 +1,17 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net> - */ +#ifndef __ASM_MIPS_MACH_BCM47XX_GPIO_H +#define __ASM_MIPS_MACH_BCM47XX_GPIO_H -#ifndef __BCM47XX_GPIO_H -#define __BCM47XX_GPIO_H +#include <asm-generic/gpio.h> -#include <linux/ssb/ssb_embedded.h> -#include <linux/bcma/bcma.h> -#include <asm/mach-bcm47xx/bcm47xx.h> +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value -#define BCM47XX_EXTIF_GPIO_LINES 5 -#define BCM47XX_CHIPCO_GPIO_LINES 16 +#define gpio_cansleep __gpio_cansleep +#define gpio_to_irq __gpio_to_irq -extern int gpio_request(unsigned gpio, const char *label); -extern void gpio_free(unsigned gpio); -extern int gpio_to_irq(unsigned gpio); - -static inline int gpio_get_value(unsigned gpio) +static inline int irq_to_gpio(unsigned int irq) { - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio); -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc, - 1 << gpio); -#endif - } return -EINVAL; } -#define gpio_get_value_cansleep gpio_get_value - -static inline void gpio_set_value(unsigned gpio, int value) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio, - value ? 1 << gpio : 0); - return; -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio, - value ? 1 << gpio : 0); - return; #endif - } -} - -#define gpio_set_value_cansleep gpio_set_value - -static inline int gpio_cansleep(unsigned gpio) -{ - return 0; -} - -static inline int gpio_is_valid(unsigned gpio) -{ - return gpio < (BCM47XX_EXTIF_GPIO_LINES + BCM47XX_CHIPCO_GPIO_LINES); -} - - -static inline int gpio_direction_input(unsigned gpio) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0); - return 0; -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio, - 0); - return 0; -#endif - } - return -EINVAL; -} - -static inline int gpio_direction_output(unsigned gpio, int value) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - /* first set the gpio out value */ - ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio, - value ? 1 << gpio : 0); - /* then set the gpio mode */ - ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio); - return 0; -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - /* first set the gpio out value */ - bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio, - value ? 1 << gpio : 0); - /* then set the gpio mode */ - bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio, - 1 << gpio); - return 0; -#endif - } - return -EINVAL; -} - -static inline int gpio_intmask(unsigned gpio, int value) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio, - value ? 1 << gpio : 0); - return 0; -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc, - 1 << gpio, value ? 1 << gpio : 0); - return 0; -#endif - } - return -EINVAL; -} - -static inline int gpio_polarity(unsigned gpio, int value) -{ - switch (bcm47xx_bus_type) { -#ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio, - value ? 1 << gpio : 0); - return 0; -#endif -#ifdef CONFIG_BCM47XX_BCMA - case BCM47XX_BUS_TYPE_BCMA: - bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc, - 1 << gpio, value ? 1 << gpio : 0); - return 0; -#endif - } - return -EINVAL; -} - - -#endif /* __BCM47XX_GPIO_H */ diff --git a/arch/mips/include/asm/mach-bcm47xx/war.h b/arch/mips/include/asm/mach-bcm47xx/war.h index 87cd4651dda3..a3d2f448b10e 100644 --- a/arch/mips/include/asm/mach-bcm47xx/war.h +++ b/arch/mips/include/asm/mach-bcm47xx/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h new file mode 100644 index 000000000000..62d6a3b4d3b7 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h @@ -0,0 +1,35 @@ +#ifndef BCM63XX_NVRAM_H +#define BCM63XX_NVRAM_H + +#include <linux/types.h> + +/** + * bcm63xx_nvram_init() - initializes nvram + * @nvram: address of the nvram data + * + * Initialized the local nvram copy from the target address and checks + * its checksum. + * + * Returns 0 on success. + */ +int __init bcm63xx_nvram_init(void *nvram); + +/** + * bcm63xx_nvram_get_name() - returns the board name according to nvram + * + * Returns the board name field from nvram. Note that it might not be + * null terminated if it is exactly 16 bytes long. + */ +u8 *bcm63xx_nvram_get_name(void); + +/** + * bcm63xx_nvram_get_mac_address() - register & return a new mac address + * @mac: pointer to array for allocated mac + * + * Registers and returns a mac address from the allocated macs from nvram. + * + * Returns 0 on success. + */ +int bcm63xx_nvram_get_mac_address(u8 *mac); + +#endif /* BCM63XX_NVRAM_H */ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h index 12963d05da86..c3eeb90b480a 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h @@ -53,13 +53,18 @@ CKCTL_6338_SAR_EN | \ CKCTL_6338_SPI_EN) -#define CKCTL_6345_CPU_EN (1 << 0) -#define CKCTL_6345_BUS_EN (1 << 1) -#define CKCTL_6345_EBI_EN (1 << 2) -#define CKCTL_6345_UART_EN (1 << 3) -#define CKCTL_6345_ADSLPHY_EN (1 << 4) -#define CKCTL_6345_ENET_EN (1 << 7) -#define CKCTL_6345_USBH_EN (1 << 8) +/* BCM6345 clock bits are shifted by 16 on the left, because of the test + * control register which is 16-bits wide. That way we do not have any + * specific BCM6345 code for handling clocks, and writing 0 to the test + * control register is fine. + */ +#define CKCTL_6345_CPU_EN (1 << 16) +#define CKCTL_6345_BUS_EN (1 << 17) +#define CKCTL_6345_EBI_EN (1 << 18) +#define CKCTL_6345_UART_EN (1 << 19) +#define CKCTL_6345_ADSLPHY_EN (1 << 20) +#define CKCTL_6345_ENET_EN (1 << 23) +#define CKCTL_6345_USBH_EN (1 << 24) #define CKCTL_6345_ALL_SAFE_EN (CKCTL_6345_ENET_EN | \ CKCTL_6345_USBH_EN | \ @@ -191,6 +196,7 @@ /* Soft Reset register */ #define PERF_SOFTRESET_REG 0x28 #define PERF_SOFTRESET_6328_REG 0x10 +#define PERF_SOFTRESET_6358_REG 0x34 #define PERF_SOFTRESET_6368_REG 0x10 #define SOFTRESET_6328_SPI_MASK (1 << 0) @@ -244,6 +250,15 @@ SOFTRESET_6348_ACLC_MASK | \ SOFTRESET_6348_ADSLMIPSPLL_MASK) +#define SOFTRESET_6358_SPI_MASK (1 << 0) +#define SOFTRESET_6358_ENET_MASK (1 << 2) +#define SOFTRESET_6358_MPI_MASK (1 << 3) +#define SOFTRESET_6358_EPHY_MASK (1 << 6) +#define SOFTRESET_6358_SAR_MASK (1 << 7) +#define SOFTRESET_6358_USBH_MASK (1 << 12) +#define SOFTRESET_6358_PCM_MASK (1 << 13) +#define SOFTRESET_6358_ADSL_MASK (1 << 14) + #define SOFTRESET_6368_SPI_MASK (1 << 0) #define SOFTRESET_6368_MPI_MASK (1 << 3) #define SOFTRESET_6368_EPHY_MASK (1 << 6) diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_reset.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_reset.h new file mode 100644 index 000000000000..3a6eb9c1adc6 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_reset.h @@ -0,0 +1,21 @@ +#ifndef __BCM63XX_RESET_H +#define __BCM63XX_RESET_H + +enum bcm63xx_core_reset { + BCM63XX_RESET_SPI, + BCM63XX_RESET_ENET, + BCM63XX_RESET_USBH, + BCM63XX_RESET_USBD, + BCM63XX_RESET_SAR, + BCM63XX_RESET_DSL, + BCM63XX_RESET_EPHY, + BCM63XX_RESET_ENETSW, + BCM63XX_RESET_PCM, + BCM63XX_RESET_MPI, + BCM63XX_RESET_PCIE, + BCM63XX_RESET_PCIE_EXT, +}; + +void bcm63xx_core_set_reset(enum bcm63xx_core_reset, int reset); + +#endif diff --git a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h index b0dd4bb53f7e..682bcf3b492a 100644 --- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h +++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h @@ -15,23 +15,6 @@ #define BCM963XX_NVRAM_OFFSET 0x580 /* - * nvram structure - */ -struct bcm963xx_nvram { - u32 version; - u8 reserved1[256]; - u8 name[16]; - u32 main_tp_number; - u32 psi_size; - u32 mac_addr_count; - u8 mac_addr_base[6]; - u8 reserved2[2]; - u32 checksum_old; - u8 reserved3[720]; - u32 checksum_high; -}; - -/* * board definition */ struct board_info { diff --git a/arch/mips/include/asm/mach-bcm63xx/war.h b/arch/mips/include/asm/mach-bcm63xx/war.h index 8e3f3fdf3209..05ee8671bef1 100644 --- a/arch/mips/include/asm/mach-bcm63xx/war.h +++ b/arch/mips/include/asm/mach-bcm63xx/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-cavium-octeon/irq.h b/arch/mips/include/asm/mach-cavium-octeon/irq.h index ff0d4909d848..502bb1815ae8 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/irq.h +++ b/arch/mips/include/asm/mach-cavium-octeon/irq.h @@ -42,7 +42,6 @@ enum octeon_irq { OCTEON_IRQ_TIMER3, OCTEON_IRQ_USB0, OCTEON_IRQ_USB1, - OCTEON_IRQ_BOOTDMA, #ifndef CONFIG_PCI_MSI OCTEON_IRQ_LAST = 127 #endif diff --git a/arch/mips/include/asm/mach-cavium-octeon/war.h b/arch/mips/include/asm/mach-cavium-octeon/war.h index c4712d7cc81d..eb72b35cf04b 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/war.h +++ b/arch/mips/include/asm/mach-cavium-octeon/war.h @@ -18,7 +18,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-cobalt/war.h b/arch/mips/include/asm/mach-cobalt/war.h index 97884fd18ac0..34ae4046541e 100644 --- a/arch/mips/include/asm/mach-cobalt/war.h +++ b/arch/mips/include/asm/mach-cobalt/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-dec/war.h b/arch/mips/include/asm/mach-dec/war.h index ca5e2ef909ad..d29996feb3e7 100644 --- a/arch/mips/include/asm/mach-dec/war.h +++ b/arch/mips/include/asm/mach-dec/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-emma2rh/war.h b/arch/mips/include/asm/mach-emma2rh/war.h index b660a4c30e6a..79ae82da3ec7 100644 --- a/arch/mips/include/asm/mach-emma2rh/war.h +++ b/arch/mips/include/asm/mach-emma2rh/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-generic/irq.h b/arch/mips/include/asm/mach-generic/irq.h index 70d9a25132c5..e014264b2be2 100644 --- a/arch/mips/include/asm/mach-generic/irq.h +++ b/arch/mips/include/asm/mach-generic/irq.h @@ -34,12 +34,6 @@ #endif #endif -#ifdef CONFIG_IRQ_CPU_RM9K -#ifndef RM9K_CPU_IRQ_BASE -#define RM9K_CPU_IRQ_BASE (MIPS_CPU_IRQ_BASE+12) -#endif -#endif - #endif /* CONFIG_IRQ_CPU */ #endif /* __ASM_MACH_GENERIC_IRQ_H */ diff --git a/arch/mips/include/asm/mach-ip22/war.h b/arch/mips/include/asm/mach-ip22/war.h index a44fa9656a82..fba640517f4f 100644 --- a/arch/mips/include/asm/mach-ip22/war.h +++ b/arch/mips/include/asm/mach-ip22/war.h @@ -21,7 +21,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-ip27/war.h b/arch/mips/include/asm/mach-ip27/war.h index e2ddcc9b1fff..4ee0e4bdf4fb 100644 --- a/arch/mips/include/asm/mach-ip27/war.h +++ b/arch/mips/include/asm/mach-ip27/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 1 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-ip28/war.h b/arch/mips/include/asm/mach-ip28/war.h index a1baafab486a..4821c7b7a38c 100644 --- a/arch/mips/include/asm/mach-ip28/war.h +++ b/arch/mips/include/asm/mach-ip28/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 1 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-ip32/war.h b/arch/mips/include/asm/mach-ip32/war.h index d194056dcd7a..7237a935a133 100644 --- a/arch/mips/include/asm/mach-ip32/war.h +++ b/arch/mips/include/asm/mach-ip32/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 1 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-jazz/war.h b/arch/mips/include/asm/mach-jazz/war.h index 6158ee861bfd..5b18b9a3d0ec 100644 --- a/arch/mips/include/asm/mach-jazz/war.h +++ b/arch/mips/include/asm/mach-jazz/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-jz4740/war.h b/arch/mips/include/asm/mach-jz4740/war.h index 3a5bc17e28fe..9b511d323838 100644 --- a/arch/mips/include/asm/mach-jz4740/war.h +++ b/arch/mips/include/asm/mach-jz4740/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-lantiq/war.h b/arch/mips/include/asm/mach-lantiq/war.h index 01b08ef368d1..b6c568c280ef 100644 --- a/arch/mips/include/asm/mach-lantiq/war.h +++ b/arch/mips/include/asm/mach-lantiq/war.h @@ -16,7 +16,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h index 6a2df709c576..133336b493b6 100644 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h @@ -82,6 +82,9 @@ extern __iomem void *ltq_cgu_membase; #define LTQ_MPS_BASE_ADDR (KSEG1 + 0x1F107000) #define LTQ_MPS_CHIPID ((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344)) +/* allow booting xrx200 phys */ +int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr); + /* request a non-gpio and set the PIO config */ #define PMU_PPE BIT(13) extern void ltq_pmu_enable(unsigned int module); diff --git a/arch/mips/include/asm/mach-lasat/war.h b/arch/mips/include/asm/mach-lasat/war.h index bb1e0325c9be..741ae724adc6 100644 --- a/arch/mips/include/asm/mach-lasat/war.h +++ b/arch/mips/include/asm/mach-lasat/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-loongson/war.h b/arch/mips/include/asm/mach-loongson/war.h index 4b971c3ffd8d..f2570df66bb5 100644 --- a/arch/mips/include/asm/mach-loongson/war.h +++ b/arch/mips/include/asm/mach-loongson/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-loongson1/platform.h b/arch/mips/include/asm/mach-loongson1/platform.h index 2f171617bade..718a1228a4f3 100644 --- a/arch/mips/include/asm/mach-loongson1/platform.h +++ b/arch/mips/include/asm/mach-loongson1/platform.h @@ -18,6 +18,7 @@ extern struct platform_device ls1x_eth0_device; extern struct platform_device ls1x_ehci_device; extern struct platform_device ls1x_rtc_device; -void ls1x_serial_setup(void); +extern void __init ls1x_clk_init(void); +extern void __init ls1x_serial_setup(struct platform_device *pdev); #endif /* __ASM_MACH_LOONGSON1_PLATFORM_H */ diff --git a/arch/mips/include/asm/mach-loongson1/regs-clk.h b/arch/mips/include/asm/mach-loongson1/regs-clk.h index 8efa7fb9f73a..a81fa3d0dc91 100644 --- a/arch/mips/include/asm/mach-loongson1/regs-clk.h +++ b/arch/mips/include/asm/mach-loongson1/regs-clk.h @@ -20,14 +20,15 @@ /* Clock PLL Divisor Register Bits */ #define DIV_DC_EN (0x1 << 31) -#define DIV_DC (0x1f << 26) #define DIV_CPU_EN (0x1 << 25) -#define DIV_CPU (0x1f << 20) #define DIV_DDR_EN (0x1 << 19) -#define DIV_DDR (0x1f << 14) #define DIV_DC_SHIFT 26 #define DIV_CPU_SHIFT 20 #define DIV_DDR_SHIFT 14 +#define DIV_DC_WIDTH 5 +#define DIV_CPU_WIDTH 5 +#define DIV_DDR_WIDTH 5 + #endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */ diff --git a/arch/mips/include/asm/mach-loongson1/war.h b/arch/mips/include/asm/mach-loongson1/war.h index e3680a8fb349..8fb50d008131 100644 --- a/arch/mips/include/asm/mach-loongson1/war.h +++ b/arch/mips/include/asm/mach-loongson1/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-malta/war.h b/arch/mips/include/asm/mach-malta/war.h index 7c6931d5f45f..d068fc411f47 100644 --- a/arch/mips/include/asm/mach-malta/war.h +++ b/arch/mips/include/asm/mach-malta/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 1 #define MIPS_CACHE_SYNC_WAR 1 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 1 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-netlogic/irq.h b/arch/mips/include/asm/mach-netlogic/irq.h index b5902458e7c1..868ed8a2ed5c 100644 --- a/arch/mips/include/asm/mach-netlogic/irq.h +++ b/arch/mips/include/asm/mach-netlogic/irq.h @@ -8,7 +8,9 @@ #ifndef __ASM_NETLOGIC_IRQ_H #define __ASM_NETLOGIC_IRQ_H -#define NR_IRQS 64 +#include <asm/mach-netlogic/multi-node.h> +#define NR_IRQS (64 * NLM_NR_NODES) + #define MIPS_CPU_IRQ_BASE 0 #endif /* __ASM_NETLOGIC_IRQ_H */ diff --git a/arch/mips/include/asm/mach-netlogic/multi-node.h b/arch/mips/include/asm/mach-netlogic/multi-node.h new file mode 100644 index 000000000000..d62fc773f4d7 --- /dev/null +++ b/arch/mips/include/asm/mach-netlogic/multi-node.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2003-2012 Broadcom Corporation + * All Rights Reserved + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the Broadcom + * license below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _NETLOGIC_MULTI_NODE_H_ +#define _NETLOGIC_MULTI_NODE_H_ + +#ifndef CONFIG_NLM_MULTINODE +#define NLM_NR_NODES 1 +#else +#if defined(CONFIG_NLM_MULTINODE_2) +#define NLM_NR_NODES 2 +#elif defined(CONFIG_NLM_MULTINODE_4) +#define NLM_NR_NODES 4 +#else +#define NLM_NR_NODES 1 +#endif +#endif + +#define NLM_CORES_PER_NODE 8 +#define NLM_THREADS_PER_CORE 4 +#define NLM_CPUS_PER_NODE (NLM_CORES_PER_NODE * NLM_THREADS_PER_CORE) + +#endif diff --git a/arch/mips/include/asm/mach-netlogic/war.h b/arch/mips/include/asm/mach-netlogic/war.h index 22da89327352..2c7216840e18 100644 --- a/arch/mips/include/asm/mach-netlogic/war.h +++ b/arch/mips/include/asm/mach-netlogic/war.h @@ -18,7 +18,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-pnx833x/war.h b/arch/mips/include/asm/mach-pnx833x/war.h index 82cd1e97bc2e..edaa06d9d492 100644 --- a/arch/mips/include/asm/mach-pnx833x/war.h +++ b/arch/mips/include/asm/mach-pnx833x/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-pnx8550/war.h b/arch/mips/include/asm/mach-pnx8550/war.h index d0458dd082f9..de8894c46686 100644 --- a/arch/mips/include/asm/mach-pnx8550/war.h +++ b/arch/mips/include/asm/mach-pnx8550/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-powertv/war.h b/arch/mips/include/asm/mach-powertv/war.h index 7ac05ecc512b..c5651c8e58d1 100644 --- a/arch/mips/include/asm/mach-powertv/war.h +++ b/arch/mips/include/asm/mach-powertv/war.h @@ -20,7 +20,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 1 #define MIPS_CACHE_SYNC_WAR 1 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 1 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-rc32434/war.h b/arch/mips/include/asm/mach-rc32434/war.h index 3ddf187e98a6..1bfd489a3708 100644 --- a/arch/mips/include/asm/mach-rc32434/war.h +++ b/arch/mips/include/asm/mach-rc32434/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 1 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-rm/war.h b/arch/mips/include/asm/mach-rm/war.h index 948d3129a114..a3dde98549bb 100644 --- a/arch/mips/include/asm/mach-rm/war.h +++ b/arch/mips/include/asm/mach-rm/war.h @@ -21,7 +21,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-sead3/war.h b/arch/mips/include/asm/mach-sead3/war.h index 7c6931d5f45f..d068fc411f47 100644 --- a/arch/mips/include/asm/mach-sead3/war.h +++ b/arch/mips/include/asm/mach-sead3/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 1 #define MIPS_CACHE_SYNC_WAR 1 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 1 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-sibyte/war.h b/arch/mips/include/asm/mach-sibyte/war.h index 743385d7b5f2..176f5b32dc69 100644 --- a/arch/mips/include/asm/mach-sibyte/war.h +++ b/arch/mips/include/asm/mach-sibyte/war.h @@ -33,7 +33,6 @@ extern int sb1250_m3_workaround_needed(void); #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-tx39xx/war.h b/arch/mips/include/asm/mach-tx39xx/war.h index 433814616359..6a52e6534776 100644 --- a/arch/mips/include/asm/mach-tx39xx/war.h +++ b/arch/mips/include/asm/mach-tx39xx/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-tx49xx/war.h b/arch/mips/include/asm/mach-tx49xx/war.h index 39b5d1177c57..a8e2c586a18c 100644 --- a/arch/mips/include/asm/mach-tx49xx/war.h +++ b/arch/mips/include/asm/mach-tx49xx/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 1 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-vr41xx/war.h b/arch/mips/include/asm/mach-vr41xx/war.h index 56a38926412a..ffe31e736009 100644 --- a/arch/mips/include/asm/mach-vr41xx/war.h +++ b/arch/mips/include/asm/mach-vr41xx/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-wrppmc/war.h b/arch/mips/include/asm/mach-wrppmc/war.h index ac48629bb1ce..e86084c0bd6b 100644 --- a/arch/mips/include/asm/mach-wrppmc/war.h +++ b/arch/mips/include/asm/mach-wrppmc/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 1 #define R10000_LLSC_WAR 0 #define MIPS34K_MISSED_ITLB_WAR 0 diff --git a/arch/mips/include/asm/mach-yosemite/cpu-feature-overrides.h b/arch/mips/include/asm/mach-yosemite/cpu-feature-overrides.h deleted file mode 100644 index 56bdd3298600..000000000000 --- a/arch/mips/include/asm/mach-yosemite/cpu-feature-overrides.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2003, 04, 07 Ralf Baechle (ralf@linux-mips.org) - */ -#ifndef __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H -#define __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H - -/* - * Momentum Jaguar ATX always has the RM9000 processor. - */ -#define cpu_has_watch 1 -#define cpu_has_mips16 0 -#define cpu_has_divec 0 -#define cpu_has_vce 0 -#define cpu_has_cache_cdex_p 0 -#define cpu_has_cache_cdex_s 0 -#define cpu_has_prefetch 1 -#define cpu_has_mcheck 0 -#define cpu_has_ejtag 0 - -#define cpu_has_llsc 1 -#define cpu_has_vtag_icache 0 -#define cpu_has_dc_aliases 0 -#define cpu_has_ic_fills_f_dc 0 -#define cpu_has_dsp 0 -#define cpu_has_dsp2 0 -#define cpu_has_mipsmt 0 -#define cpu_has_userlocal 0 -#define cpu_icache_snoops_remote_store 0 - -#define cpu_has_nofpuex 0 -#define cpu_has_64bits 1 - -#define cpu_has_inclusive_pcaches 0 - -#define cpu_dcache_line_size() 32 -#define cpu_icache_line_size() 32 -#define cpu_scache_line_size() 32 - -#define cpu_has_mips32r1 0 -#define cpu_has_mips32r2 0 -#define cpu_has_mips64r1 0 -#define cpu_has_mips64r2 0 - -#endif /* __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-yosemite/war.h b/arch/mips/include/asm/mach-yosemite/war.h deleted file mode 100644 index e5c6d53efc86..000000000000 --- a/arch/mips/include/asm/mach-yosemite/war.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - */ -#ifndef __ASM_MIPS_MACH_YOSEMITE_WAR_H -#define __ASM_MIPS_MACH_YOSEMITE_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 1 -#define ICACHE_REFILLS_WORKAROUND_WAR 1 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_YOSEMITE_WAR_H */ diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index eb742895dcbe..7e4e6f8fab37 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -240,7 +240,7 @@ #define PM_HUGE_MASK PM_64M #elif defined(CONFIG_PAGE_SIZE_64KB) #define PM_HUGE_MASK PM_256M -#elif defined(CONFIG_HUGETLB_PAGE) +#elif defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) #error Bad page size configuration for hugetlbfs! #endif @@ -977,10 +977,6 @@ do { \ #define read_c0_framemask() __read_32bit_c0_register($21, 0) #define write_c0_framemask(val) __write_32bit_c0_register($21, 0, val) -/* RM9000 PerfControl performance counter control register */ -#define read_c0_perfcontrol() __read_32bit_c0_register($22, 0) -#define write_c0_perfcontrol(val) __write_32bit_c0_register($22, 0, val) - #define read_c0_diag() __read_32bit_c0_register($22, 0) #define write_c0_diag(val) __write_32bit_c0_register($22, 0, val) @@ -1033,10 +1029,6 @@ do { \ #define read_c0_perfcntr3_64() __read_64bit_c0_register($25, 7) #define write_c0_perfcntr3_64(val) __write_64bit_c0_register($25, 7, val) -/* RM9000 PerfCount performance counter register */ -#define read_c0_perfcount() __read_64bit_c0_register($25, 0) -#define write_c0_perfcount(val) __write_64bit_c0_register($25, 0, val) - #define read_c0_ecc() __read_32bit_c0_register($26, 0) #define write_c0_ecc(val) __write_32bit_c0_register($26, 0, val) diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h index 9b02cfba7449..45cfa1ad86a6 100644 --- a/arch/mips/include/asm/mmu_context.h +++ b/arch/mips/include/asm/mmu_context.h @@ -72,12 +72,6 @@ extern unsigned long pgd_current[]; #define ASID_INC 0x10 #define ASID_MASK 0xff0 -#elif defined(CONFIG_CPU_RM9000) - -#define ASID_INC 0x1 -#define ASID_MASK 0xfff - -/* SMTC/34K debug hack - but maybe we'll keep it */ #elif defined(CONFIG_MIPS_MT_SMTC) #define ASID_INC 0x1 diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h index 26137da1c713..44b705d08262 100644 --- a/arch/mips/include/asm/module.h +++ b/arch/mips/include/asm/module.h @@ -120,8 +120,6 @@ search_module_dbetables(unsigned long addr) #define MODULE_PROC_FAMILY "R10000 " #elif defined CONFIG_CPU_RM7000 #define MODULE_PROC_FAMILY "RM7000 " -#elif defined CONFIG_CPU_RM9000 -#define MODULE_PROC_FAMILY "RM9000 " #elif defined CONFIG_CPU_SB1 #define MODULE_PROC_FAMILY "SB1 " #elif defined CONFIG_CPU_LOONGSON1 diff --git a/arch/mips/include/asm/netlogic/common.h b/arch/mips/include/asm/netlogic/common.h index fdd2f44c7b59..42bfd5f1eeec 100644 --- a/arch/mips/include/asm/netlogic/common.h +++ b/arch/mips/include/asm/netlogic/common.h @@ -45,15 +45,19 @@ #define BOOT_NMI_HANDLER 8 #ifndef __ASSEMBLY__ +#include <linux/cpumask.h> +#include <linux/spinlock.h> +#include <asm/irq.h> +#include <asm/mach-netlogic/multi-node.h> + struct irq_desc; -extern struct plat_smp_ops nlm_smp_ops; -extern char nlm_reset_entry[], nlm_reset_entry_end[]; void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc); void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc); -void nlm_smp_irq_init(void); +void nlm_smp_irq_init(int hwcpuid); void nlm_boot_secondary_cpus(void); -int nlm_wakeup_secondary_cpus(u32 wakeup_mask); +int nlm_wakeup_secondary_cpus(void); void nlm_rmiboot_preboot(void); +void nlm_percpu_init(int hwcpuid); static inline void nlm_set_nmi_handler(void *handler) @@ -68,9 +72,42 @@ nlm_set_nmi_handler(void *handler) * Misc. */ unsigned int nlm_get_cpu_frequency(void); +void nlm_node_init(int node); +extern struct plat_smp_ops nlm_smp_ops; +extern char nlm_reset_entry[], nlm_reset_entry_end[]; + +extern unsigned int nlm_threads_per_core; +extern cpumask_t nlm_cpumask; + +struct nlm_soc_info { + unsigned long coremask; /* cores enabled on the soc */ + unsigned long ebase; + uint64_t irqmask; + uint64_t sysbase; /* only for XLP */ + uint64_t picbase; + spinlock_t piclock; +}; + +#define nlm_get_node(i) (&nlm_nodes[i]) +#ifdef CONFIG_CPU_XLR +#define nlm_current_node() (&nlm_nodes[0]) +#else +#define nlm_current_node() (&nlm_nodes[nlm_nodeid()]) +#endif + +struct irq_data; +uint64_t nlm_pci_irqmask(int node); +void nlm_set_pic_extra_ack(int node, int irq, void (*xack)(struct irq_data *)); + +/* + * The NR_IRQs is divided between nodes, each of them has a separate irq space + */ +static inline int nlm_irq_to_xirq(int node, int irq) +{ + return node * NR_IRQS / NLM_NR_NODES + irq; +} -extern unsigned long nlm_common_ebase; -extern int nlm_threads_per_core; -extern uint32_t nlm_cpumask, nlm_coremask; +extern struct nlm_soc_info nlm_nodes[NLM_NR_NODES]; +extern int nlm_cpu_ready[]; #endif #endif /* _NETLOGIC_COMMON_H_ */ diff --git a/arch/mips/include/asm/netlogic/interrupt.h b/arch/mips/include/asm/netlogic/interrupt.h index a85aadb6cfd7..ed5993d9b7b8 100644 --- a/arch/mips/include/asm/netlogic/interrupt.h +++ b/arch/mips/include/asm/netlogic/interrupt.h @@ -39,7 +39,7 @@ #define IRQ_IPI_SMP_FUNCTION 3 #define IRQ_IPI_SMP_RESCHEDULE 4 -#define IRQ_MSGRING 6 +#define IRQ_FMN 5 #define IRQ_TIMER 7 #endif diff --git a/arch/mips/include/asm/netlogic/mips-extns.h b/arch/mips/include/asm/netlogic/mips-extns.h index 8c53d0ba4bf2..32ba6d95d47c 100644 --- a/arch/mips/include/asm/netlogic/mips-extns.h +++ b/arch/mips/include/asm/netlogic/mips-extns.h @@ -73,4 +73,146 @@ static inline int hard_smp_processor_id(void) return __read_32bit_c0_register($15, 1) & 0x3ff; } +static inline int nlm_nodeid(void) +{ + return (__read_32bit_c0_register($15, 1) >> 5) & 0x3; +} + +static inline unsigned int nlm_core_id(void) +{ + return (read_c0_ebase() & 0x1c) >> 2; +} + +static inline unsigned int nlm_thread_id(void) +{ + return read_c0_ebase() & 0x3; +} + +#define __read_64bit_c2_split(source, sel) \ +({ \ + unsigned long long __val; \ + unsigned long __flags; \ + \ + local_irq_save(__flags); \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc2\t%M0, " #source "\n\t" \ + "dsll\t%L0, %M0, 32\n\t" \ + "dsra\t%M0, %M0, 32\n\t" \ + "dsra\t%L0, %L0, 32\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__val)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc2\t%M0, " #source ", " #sel "\n\t" \ + "dsll\t%L0, %M0, 32\n\t" \ + "dsra\t%M0, %M0, 32\n\t" \ + "dsra\t%L0, %L0, 32\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__val)); \ + local_irq_restore(__flags); \ + \ + __val; \ +}) + +#define __write_64bit_c2_split(source, sel, val) \ +do { \ + unsigned long __flags; \ + \ + local_irq_save(__flags); \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dsll\t%L0, %L0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + "dsll\t%M0, %M0, 32\n\t" \ + "or\t%L0, %L0, %M0\n\t" \ + "dmtc2\t%L0, " #source "\n\t" \ + ".set\tmips0\n\t" \ + : : "r" (val)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dsll\t%L0, %L0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + "dsll\t%M0, %M0, 32\n\t" \ + "or\t%L0, %L0, %M0\n\t" \ + "dmtc2\t%L0, " #source ", " #sel "\n\t" \ + ".set\tmips0\n\t" \ + : : "r" (val)); \ + local_irq_restore(__flags); \ +} while (0) + +#define __read_32bit_c2_register(source, sel) \ +({ uint32_t __res; \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mfc2\t%0, " #source "\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mfc2\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __read_64bit_c2_register(source, sel) \ +({ unsigned long long __res; \ + if (sizeof(unsigned long) == 4) \ + __res = __read_64bit_c2_split(source, sel); \ + else if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc2\t%0, " #source "\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc2\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __write_64bit_c2_register(register, sel, value) \ +do { \ + if (sizeof(unsigned long) == 4) \ + __write_64bit_c2_split(register, sel, value); \ + else if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmtc2\t%z0, " #register "\n\t" \ + ".set\tmips0\n\t" \ + : : "Jr" (value)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmtc2\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0\n\t" \ + : : "Jr" (value)); \ +} while (0) + +#define __write_32bit_c2_register(reg, sel, value) \ +({ \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mtc2\t%z0, " #reg "\n\t" \ + ".set\tmips0\n\t" \ + : : "Jr" (value)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mtc2\t%z0, " #reg ", " #sel "\n\t" \ + ".set\tmips0\n\t" \ + : : "Jr" (value)); \ +}) + #endif /*_ASM_NLM_MIPS_EXTS_H */ diff --git a/arch/mips/include/asm/netlogic/xlp-hal/pic.h b/arch/mips/include/asm/netlogic/xlp-hal/pic.h index ad8b80233a63..b2e53a5383ab 100644 --- a/arch/mips/include/asm/netlogic/xlp-hal/pic.h +++ b/arch/mips/include/asm/netlogic/xlp-hal/pic.h @@ -273,36 +273,16 @@ nlm_pic_read_irt(uint64_t base, int irt_index) return nlm_read_pic_reg(base, PIC_IRT(irt_index)); } -static inline uint64_t -nlm_pic_read_control(uint64_t base) -{ - return nlm_read_pic_reg(base, PIC_CTRL); -} - -static inline void -nlm_pic_write_control(uint64_t base, uint64_t control) -{ - nlm_write_pic_reg(base, PIC_CTRL, control); -} - -static inline void -nlm_pic_update_control(uint64_t base, uint64_t control) -{ - uint64_t val; - - val = nlm_read_pic_reg(base, PIC_CTRL); - nlm_write_pic_reg(base, PIC_CTRL, control | val); -} - static inline void nlm_set_irt_to_cpu(uint64_t base, int irt, int cpu) { uint64_t val; val = nlm_read_pic_reg(base, PIC_IRT(irt)); - val |= cpu & 0xf; - if (cpu > 15) - val |= 1 << 16; + /* clear cpuset and mask */ + val &= ~((0x7ull << 16) | 0xffff); + /* set DB, cpuset and cpumask */ + val |= (1 << 19) | ((cpu >> 4) << 16) | (1 << (cpu & 0xf)); nlm_write_pic_reg(base, PIC_IRT(irt), val); } @@ -369,7 +349,7 @@ nlm_pic_enable_irt(uint64_t base, int irt) static inline void nlm_pic_disable_irt(uint64_t base, int irt) { - uint32_t reg; + uint64_t reg; reg = nlm_read_pic_reg(base, PIC_IRT(irt)); nlm_write_pic_reg(base, PIC_IRT(irt), reg & ~((uint64_t)1 << 31)); @@ -379,15 +359,9 @@ static inline void nlm_pic_send_ipi(uint64_t base, int hwt, int irq, int nmi) { uint64_t ipi; - int node, ncpu; - - node = hwt / 32; - ncpu = hwt & 0x1f; - ipi = ((uint64_t)nmi << 31) | (irq << 20) | (node << 17) | - (1 << (ncpu & 0xf)); - if (ncpu > 15) - ipi |= 0x10000; /* Setting bit 16 to select cpus 16-31 */ + ipi = (nmi << 31) | (irq << 20); + ipi |= ((hwt >> 4) << 16) | (1 << (hwt & 0xf)); /* cpuset and mask */ nlm_write_pic_reg(base, PIC_IPI_CTL, ipi); } @@ -404,12 +378,10 @@ nlm_pic_ack(uint64_t base, int irt_num) static inline void nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt) { - nlm_pic_write_irt_direct(base, irt, 0, 0, 0, irq, 0); + nlm_pic_write_irt_direct(base, irt, 0, 0, 0, irq, hwt); } -extern uint64_t nlm_pic_base; int nlm_irq_to_irt(int irq); -int nlm_irt_to_irq(int irt); #endif /* __ASSEMBLY__ */ #endif /* _NLM_HAL_PIC_H */ diff --git a/arch/mips/include/asm/netlogic/xlp-hal/sys.h b/arch/mips/include/asm/netlogic/xlp-hal/sys.h index 21432f7d89b9..258e8cc00e99 100644 --- a/arch/mips/include/asm/netlogic/xlp-hal/sys.h +++ b/arch/mips/include/asm/netlogic/xlp-hal/sys.h @@ -124,6 +124,5 @@ #define nlm_get_sys_pcibase(node) nlm_pcicfg_base(XLP_IO_SYS_OFFSET(node)) #define nlm_get_sys_regbase(node) (nlm_get_sys_pcibase(node) + XLP_IO_PCI_HDRSZ) -extern uint64_t nlm_sys_base; #endif #endif diff --git a/arch/mips/include/asm/netlogic/xlr/fmn.h b/arch/mips/include/asm/netlogic/xlr/fmn.h new file mode 100644 index 000000000000..68d5167c86bb --- /dev/null +++ b/arch/mips/include/asm/netlogic/xlr/fmn.h @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2003-2012 Broadcom Corporation + * All Rights Reserved + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the Broadcom + * license below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _NLM_FMN_H_ +#define _NLM_FMN_H_ + +#include <asm/netlogic/mips-extns.h> /* for COP2 access */ + +/* Station IDs */ +#define FMN_STNID_CPU0 0x00 +#define FMN_STNID_CPU1 0x08 +#define FMN_STNID_CPU2 0x10 +#define FMN_STNID_CPU3 0x18 +#define FMN_STNID_CPU4 0x20 +#define FMN_STNID_CPU5 0x28 +#define FMN_STNID_CPU6 0x30 +#define FMN_STNID_CPU7 0x38 + +#define FMN_STNID_XGS0_TX 64 +#define FMN_STNID_XMAC0_00_TX 64 +#define FMN_STNID_XMAC0_01_TX 65 +#define FMN_STNID_XMAC0_02_TX 66 +#define FMN_STNID_XMAC0_03_TX 67 +#define FMN_STNID_XMAC0_04_TX 68 +#define FMN_STNID_XMAC0_05_TX 69 +#define FMN_STNID_XMAC0_06_TX 70 +#define FMN_STNID_XMAC0_07_TX 71 +#define FMN_STNID_XMAC0_08_TX 72 +#define FMN_STNID_XMAC0_09_TX 73 +#define FMN_STNID_XMAC0_10_TX 74 +#define FMN_STNID_XMAC0_11_TX 75 +#define FMN_STNID_XMAC0_12_TX 76 +#define FMN_STNID_XMAC0_13_TX 77 +#define FMN_STNID_XMAC0_14_TX 78 +#define FMN_STNID_XMAC0_15_TX 79 + +#define FMN_STNID_XGS1_TX 80 +#define FMN_STNID_XMAC1_00_TX 80 +#define FMN_STNID_XMAC1_01_TX 81 +#define FMN_STNID_XMAC1_02_TX 82 +#define FMN_STNID_XMAC1_03_TX 83 +#define FMN_STNID_XMAC1_04_TX 84 +#define FMN_STNID_XMAC1_05_TX 85 +#define FMN_STNID_XMAC1_06_TX 86 +#define FMN_STNID_XMAC1_07_TX 87 +#define FMN_STNID_XMAC1_08_TX 88 +#define FMN_STNID_XMAC1_09_TX 89 +#define FMN_STNID_XMAC1_10_TX 90 +#define FMN_STNID_XMAC1_11_TX 91 +#define FMN_STNID_XMAC1_12_TX 92 +#define FMN_STNID_XMAC1_13_TX 93 +#define FMN_STNID_XMAC1_14_TX 94 +#define FMN_STNID_XMAC1_15_TX 95 + +#define FMN_STNID_GMAC 96 +#define FMN_STNID_GMACJFR_0 96 +#define FMN_STNID_GMACRFR_0 97 +#define FMN_STNID_GMACTX0 98 +#define FMN_STNID_GMACTX1 99 +#define FMN_STNID_GMACTX2 100 +#define FMN_STNID_GMACTX3 101 +#define FMN_STNID_GMACJFR_1 102 +#define FMN_STNID_GMACRFR_1 103 + +#define FMN_STNID_DMA 104 +#define FMN_STNID_DMA_0 104 +#define FMN_STNID_DMA_1 105 +#define FMN_STNID_DMA_2 106 +#define FMN_STNID_DMA_3 107 + +#define FMN_STNID_XGS0FR 112 +#define FMN_STNID_XMAC0JFR 112 +#define FMN_STNID_XMAC0RFR 113 + +#define FMN_STNID_XGS1FR 114 +#define FMN_STNID_XMAC1JFR 114 +#define FMN_STNID_XMAC1RFR 115 +#define FMN_STNID_SEC 120 +#define FMN_STNID_SEC0 120 +#define FMN_STNID_SEC1 121 +#define FMN_STNID_SEC2 122 +#define FMN_STNID_SEC3 123 +#define FMN_STNID_PK0 124 +#define FMN_STNID_SEC_RSA 124 +#define FMN_STNID_SEC_RSVD0 125 +#define FMN_STNID_SEC_RSVD1 126 +#define FMN_STNID_SEC_RSVD2 127 + +#define FMN_STNID_GMAC1 80 +#define FMN_STNID_GMAC1_FR_0 81 +#define FMN_STNID_GMAC1_TX0 82 +#define FMN_STNID_GMAC1_TX1 83 +#define FMN_STNID_GMAC1_TX2 84 +#define FMN_STNID_GMAC1_TX3 85 +#define FMN_STNID_GMAC1_FR_1 87 +#define FMN_STNID_GMAC0 96 +#define FMN_STNID_GMAC0_FR_0 97 +#define FMN_STNID_GMAC0_TX0 98 +#define FMN_STNID_GMAC0_TX1 99 +#define FMN_STNID_GMAC0_TX2 100 +#define FMN_STNID_GMAC0_TX3 101 +#define FMN_STNID_GMAC0_FR_1 103 +#define FMN_STNID_CMP_0 108 +#define FMN_STNID_CMP_1 109 +#define FMN_STNID_CMP_2 110 +#define FMN_STNID_CMP_3 111 +#define FMN_STNID_PCIE_0 116 +#define FMN_STNID_PCIE_1 117 +#define FMN_STNID_PCIE_2 118 +#define FMN_STNID_PCIE_3 119 +#define FMN_STNID_XLS_PK0 121 + +#define nlm_read_c2_cc0(s) __read_32bit_c2_register($16, s) +#define nlm_read_c2_cc1(s) __read_32bit_c2_register($17, s) +#define nlm_read_c2_cc2(s) __read_32bit_c2_register($18, s) +#define nlm_read_c2_cc3(s) __read_32bit_c2_register($19, s) +#define nlm_read_c2_cc4(s) __read_32bit_c2_register($20, s) +#define nlm_read_c2_cc5(s) __read_32bit_c2_register($21, s) +#define nlm_read_c2_cc6(s) __read_32bit_c2_register($22, s) +#define nlm_read_c2_cc7(s) __read_32bit_c2_register($23, s) +#define nlm_read_c2_cc8(s) __read_32bit_c2_register($24, s) +#define nlm_read_c2_cc9(s) __read_32bit_c2_register($25, s) +#define nlm_read_c2_cc10(s) __read_32bit_c2_register($26, s) +#define nlm_read_c2_cc11(s) __read_32bit_c2_register($27, s) +#define nlm_read_c2_cc12(s) __read_32bit_c2_register($28, s) +#define nlm_read_c2_cc13(s) __read_32bit_c2_register($29, s) +#define nlm_read_c2_cc14(s) __read_32bit_c2_register($30, s) +#define nlm_read_c2_cc15(s) __read_32bit_c2_register($31, s) + +#define nlm_write_c2_cc0(s, v) __write_32bit_c2_register($16, s, v) +#define nlm_write_c2_cc1(s, v) __write_32bit_c2_register($17, s, v) +#define nlm_write_c2_cc2(s, v) __write_32bit_c2_register($18, s, v) +#define nlm_write_c2_cc3(s, v) __write_32bit_c2_register($19, s, v) +#define nlm_write_c2_cc4(s, v) __write_32bit_c2_register($20, s, v) +#define nlm_write_c2_cc5(s, v) __write_32bit_c2_register($21, s, v) +#define nlm_write_c2_cc6(s, v) __write_32bit_c2_register($22, s, v) +#define nlm_write_c2_cc7(s, v) __write_32bit_c2_register($23, s, v) +#define nlm_write_c2_cc8(s, v) __write_32bit_c2_register($24, s, v) +#define nlm_write_c2_cc9(s, v) __write_32bit_c2_register($25, s, v) +#define nlm_write_c2_cc10(s, v) __write_32bit_c2_register($26, s, v) +#define nlm_write_c2_cc11(s, v) __write_32bit_c2_register($27, s, v) +#define nlm_write_c2_cc12(s, v) __write_32bit_c2_register($28, s, v) +#define nlm_write_c2_cc13(s, v) __write_32bit_c2_register($29, s, v) +#define nlm_write_c2_cc14(s, v) __write_32bit_c2_register($30, s, v) +#define nlm_write_c2_cc15(s, v) __write_32bit_c2_register($31, s, v) + +#define nlm_read_c2_status(sel) __read_32bit_c2_register($2, 0) +#define nlm_read_c2_config() __read_32bit_c2_register($3, 0) +#define nlm_write_c2_config(v) __write_32bit_c2_register($3, 0, v) +#define nlm_read_c2_bucksize(b) __read_32bit_c2_register($4, b) +#define nlm_write_c2_bucksize(b, v) __write_32bit_c2_register($4, b, v) + +#define nlm_read_c2_rx_msg0() __read_64bit_c2_register($1, 0) +#define nlm_read_c2_rx_msg1() __read_64bit_c2_register($1, 1) +#define nlm_read_c2_rx_msg2() __read_64bit_c2_register($1, 2) +#define nlm_read_c2_rx_msg3() __read_64bit_c2_register($1, 3) + +#define nlm_write_c2_tx_msg0(v) __write_64bit_c2_register($0, 0, v) +#define nlm_write_c2_tx_msg1(v) __write_64bit_c2_register($0, 1, v) +#define nlm_write_c2_tx_msg2(v) __write_64bit_c2_register($0, 2, v) +#define nlm_write_c2_tx_msg3(v) __write_64bit_c2_register($0, 3, v) + +#define FMN_STN_RX_QSIZE 256 +#define FMN_NSTATIONS 128 +#define FMN_CORE_NBUCKETS 8 + +static inline void nlm_msgsnd(unsigned int stid) +{ + __asm__ volatile ( + ".set push\n" + ".set noreorder\n" + ".set noat\n" + "move $1, %0\n" + "c2 0x10001\n" /* msgsnd $1 */ + ".set pop\n" + : : "r" (stid) : "$1" + ); +} + +static inline void nlm_msgld(unsigned int pri) +{ + __asm__ volatile ( + ".set push\n" + ".set noreorder\n" + ".set noat\n" + "move $1, %0\n" + "c2 0x10002\n" /* msgld $1 */ + ".set pop\n" + : : "r" (pri) : "$1" + ); +} + +static inline void nlm_msgwait(unsigned int mask) +{ + __asm__ volatile ( + ".set push\n" + ".set noreorder\n" + ".set noat\n" + "move $8, %0\n" + "c2 0x10003\n" /* msgwait $1 */ + ".set pop\n" + : : "r" (mask) : "$1" + ); +} + +/* + * Disable interrupts and enable COP2 access + */ +static inline uint32_t nlm_cop2_enable(void) +{ + uint32_t sr = read_c0_status(); + + write_c0_status((sr & ~ST0_IE) | ST0_CU2); + return sr; +} + +static inline void nlm_cop2_restore(uint32_t sr) +{ + write_c0_status(sr); +} + +static inline void nlm_fmn_setup_intr(int irq, unsigned int tmask) +{ + uint32_t config; + + config = (1 << 24) /* interrupt water mark - 1 msg */ + | (irq << 16) /* irq */ + | (tmask << 8) /* thread mask */ + | 0x2; /* enable watermark intr, disable empty intr */ + nlm_write_c2_config(config); +} + +struct nlm_fmn_msg { + uint64_t msg0; + uint64_t msg1; + uint64_t msg2; + uint64_t msg3; +}; + +static inline int nlm_fmn_send(unsigned int size, unsigned int code, + unsigned int stid, struct nlm_fmn_msg *msg) +{ + unsigned int dest; + uint32_t status; + int i; + + /* + * Make sure that all the writes pending at the cpu are flushed. + * Any writes pending on CPU will not be see by devices. L1/L2 + * caches are coherent with IO, so no cache flush needed. + */ + __asm __volatile("sync"); + + /* Load TX message buffers */ + nlm_write_c2_tx_msg0(msg->msg0); + nlm_write_c2_tx_msg1(msg->msg1); + nlm_write_c2_tx_msg2(msg->msg2); + nlm_write_c2_tx_msg3(msg->msg3); + dest = ((size - 1) << 16) | (code << 8) | stid; + + /* + * Retry a few times on credit fail, this should be a + * transient condition, unless there is a configuration + * failure, or the receiver is stuck. + */ + for (i = 0; i < 8; i++) { + nlm_msgsnd(dest); + status = nlm_read_c2_status(0); + if ((status & 0x2) == 1) + pr_info("Send pending fail!\n"); + if ((status & 0x4) == 0) + return 0; + } + + /* If there is a credit failure, return error */ + return status & 0x06; +} + +static inline int nlm_fmn_receive(int bucket, int *size, int *code, int *stid, + struct nlm_fmn_msg *msg) +{ + uint32_t status, tmp; + + nlm_msgld(bucket); + + /* wait for load pending to clear */ + do { + status = nlm_read_c2_status(1); + } while ((status & 0x08) != 0); + + /* receive error bits */ + tmp = status & 0x30; + if (tmp != 0) + return tmp; + + *size = ((status & 0xc0) >> 6) + 1; + *code = (status & 0xff00) >> 8; + *stid = (status & 0x7f0000) >> 16; + msg->msg0 = nlm_read_c2_rx_msg0(); + msg->msg1 = nlm_read_c2_rx_msg1(); + msg->msg2 = nlm_read_c2_rx_msg2(); + msg->msg3 = nlm_read_c2_rx_msg3(); + + return 0; +} + +struct xlr_fmn_info { + int num_buckets; + int start_stn_id; + int end_stn_id; + int credit_config[128]; +}; + +struct xlr_board_fmn_config { + int bucket_size[128]; /* size of buckets for all stations */ + struct xlr_fmn_info cpu[8]; + struct xlr_fmn_info gmac[2]; + struct xlr_fmn_info dma; + struct xlr_fmn_info cmp; + struct xlr_fmn_info sae; + struct xlr_fmn_info xgmac[2]; +}; + +extern int nlm_register_fmn_handler(int start, int end, + void (*fn)(int, int, int, int, struct nlm_fmn_msg *, void *), + void *arg); +extern void xlr_percpu_fmn_init(void); +extern void nlm_setup_fmn_irq(void); +extern void xlr_board_info_setup(void); + +extern struct xlr_board_fmn_config xlr_board_fmn_config; +#endif diff --git a/arch/mips/include/asm/netlogic/xlr/pic.h b/arch/mips/include/asm/netlogic/xlr/pic.h index 868013e62f32..9a691b1f91ba 100644 --- a/arch/mips/include/asm/netlogic/xlr/pic.h +++ b/arch/mips/include/asm/netlogic/xlr/pic.h @@ -258,7 +258,5 @@ nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt) nlm_write_reg(base, PIC_IRT_1(irt), (1 << 30) | (1 << 6) | irq); } - -extern uint64_t nlm_pic_base; #endif #endif /* _ASM_NLM_XLR_PIC_H */ diff --git a/arch/mips/include/asm/netlogic/xlr/xlr.h b/arch/mips/include/asm/netlogic/xlr/xlr.h index ff4a17b0bf78..c1667e0c272a 100644 --- a/arch/mips/include/asm/netlogic/xlr/xlr.h +++ b/arch/mips/include/asm/netlogic/xlr/xlr.h @@ -51,10 +51,8 @@ static inline unsigned int nlm_chip_is_xls_b(void) return ((prid & 0xf000) == 0x4000); } -/* - * XLR chip types - */ - /* The XLS product line has chip versions 0x[48c]? */ +/* XLR chip types */ +/* The XLS product line has chip versions 0x[48c]? */ static inline unsigned int nlm_chip_is_xls(void) { uint32_t prid = read_c0_prid(); diff --git a/arch/mips/include/asm/octeon/cvmx-bootmem.h b/arch/mips/include/asm/octeon/cvmx-bootmem.h index 877845b84b14..42db2be663f1 100644 --- a/arch/mips/include/asm/octeon/cvmx-bootmem.h +++ b/arch/mips/include/asm/octeon/cvmx-bootmem.h @@ -370,4 +370,6 @@ void cvmx_bootmem_lock(void); */ void cvmx_bootmem_unlock(void); +extern struct cvmx_bootmem_desc *cvmx_bootmem_get_desc(void); + #endif /* __CVMX_BOOTMEM_H__ */ diff --git a/arch/mips/include/asm/octeon/cvmx-lmcx-defs.h b/arch/mips/include/asm/octeon/cvmx-lmcx-defs.h new file mode 100644 index 000000000000..36f510721141 --- /dev/null +++ b/arch/mips/include/asm/octeon/cvmx-lmcx-defs.h @@ -0,0 +1,3457 @@ +/***********************license start*************** + * Author: Cavium Inc. + * + * Contact: support@cavium.com + * This file is part of the OCTEON SDK + * + * Copyright (c) 2003-2012 Cavium Inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * or visit http://www.gnu.org/licenses/. + * + * This file may also be available under a different license from Cavium. + * Contact Cavium Inc. for more information + ***********************license end**************************************/ + +#ifndef __CVMX_LMCX_DEFS_H__ +#define __CVMX_LMCX_DEFS_H__ + +#define CVMX_LMCX_BIST_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800880000F0ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_BIST_RESULT(block_id) (CVMX_ADD_IO_SEG(0x00011800880000F8ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_CHAR_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000220ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_CHAR_MASK0(block_id) (CVMX_ADD_IO_SEG(0x0001180088000228ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_CHAR_MASK1(block_id) (CVMX_ADD_IO_SEG(0x0001180088000230ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_CHAR_MASK2(block_id) (CVMX_ADD_IO_SEG(0x0001180088000238ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_CHAR_MASK3(block_id) (CVMX_ADD_IO_SEG(0x0001180088000240ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_CHAR_MASK4(block_id) (CVMX_ADD_IO_SEG(0x0001180088000318ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_COMP_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000028ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_COMP_CTL2(block_id) (CVMX_ADD_IO_SEG(0x00011800880001B8ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_CONFIG(block_id) (CVMX_ADD_IO_SEG(0x0001180088000188ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_CONTROL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000190ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000010ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_CTL1(block_id) (CVMX_ADD_IO_SEG(0x0001180088000090ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_DCLK_CNT(block_id) (CVMX_ADD_IO_SEG(0x00011800880001E0ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_DCLK_CNT_HI(block_id) (CVMX_ADD_IO_SEG(0x0001180088000070ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_DCLK_CNT_LO(block_id) (CVMX_ADD_IO_SEG(0x0001180088000068ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_DCLK_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800880000B8ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_DDR2_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000018ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_DDR_PLL_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000258ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_DELAY_CFG(block_id) (CVMX_ADD_IO_SEG(0x0001180088000088ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_DIMMX_PARAMS(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180088000270ull) + (((offset) & 1) + ((block_id) & 3) * 0x200000ull) * 8) +#define CVMX_LMCX_DIMM_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000310ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_DLL_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800880000C0ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_DLL_CTL2(block_id) (CVMX_ADD_IO_SEG(0x00011800880001C8ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_DLL_CTL3(block_id) (CVMX_ADD_IO_SEG(0x0001180088000218ull) + ((block_id) & 3) * 0x1000000ull) +static inline uint64_t CVMX_LMCX_DUAL_MEMCFG(unsigned long block_id) +{ + switch (cvmx_get_octeon_family()) { + case OCTEON_CNF71XX & OCTEON_FAMILY_MASK: + case OCTEON_CN50XX & OCTEON_FAMILY_MASK: + case OCTEON_CN58XX & OCTEON_FAMILY_MASK: + case OCTEON_CN66XX & OCTEON_FAMILY_MASK: + case OCTEON_CN52XX & OCTEON_FAMILY_MASK: + case OCTEON_CN61XX & OCTEON_FAMILY_MASK: + case OCTEON_CN63XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x0001180088000098ull) + (block_id) * 0x60000000ull; + case OCTEON_CN56XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x0001180088000098ull) + (block_id) * 0x60000000ull; + case OCTEON_CN68XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x0001180088000098ull) + (block_id) * 0x1000000ull; + } + return CVMX_ADD_IO_SEG(0x0001180088000098ull) + (block_id) * 0x60000000ull; +} + +static inline uint64_t CVMX_LMCX_ECC_SYND(unsigned long block_id) +{ + switch (cvmx_get_octeon_family()) { + case OCTEON_CN30XX & OCTEON_FAMILY_MASK: + case OCTEON_CN50XX & OCTEON_FAMILY_MASK: + case OCTEON_CN38XX & OCTEON_FAMILY_MASK: + case OCTEON_CN31XX & OCTEON_FAMILY_MASK: + case OCTEON_CN58XX & OCTEON_FAMILY_MASK: + case OCTEON_CN66XX & OCTEON_FAMILY_MASK: + case OCTEON_CN52XX & OCTEON_FAMILY_MASK: + case OCTEON_CN61XX & OCTEON_FAMILY_MASK: + case OCTEON_CNF71XX & OCTEON_FAMILY_MASK: + case OCTEON_CN63XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x0001180088000038ull) + (block_id) * 0x60000000ull; + case OCTEON_CN56XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x0001180088000038ull) + (block_id) * 0x60000000ull; + case OCTEON_CN68XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x0001180088000038ull) + (block_id) * 0x1000000ull; + } + return CVMX_ADD_IO_SEG(0x0001180088000038ull) + (block_id) * 0x60000000ull; +} + +static inline uint64_t CVMX_LMCX_FADR(unsigned long block_id) +{ + switch (cvmx_get_octeon_family()) { + case OCTEON_CN30XX & OCTEON_FAMILY_MASK: + case OCTEON_CN50XX & OCTEON_FAMILY_MASK: + case OCTEON_CN38XX & OCTEON_FAMILY_MASK: + case OCTEON_CN31XX & OCTEON_FAMILY_MASK: + case OCTEON_CN58XX & OCTEON_FAMILY_MASK: + case OCTEON_CN66XX & OCTEON_FAMILY_MASK: + case OCTEON_CN52XX & OCTEON_FAMILY_MASK: + case OCTEON_CN61XX & OCTEON_FAMILY_MASK: + case OCTEON_CNF71XX & OCTEON_FAMILY_MASK: + case OCTEON_CN63XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x0001180088000020ull) + (block_id) * 0x60000000ull; + case OCTEON_CN56XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x0001180088000020ull) + (block_id) * 0x60000000ull; + case OCTEON_CN68XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x0001180088000020ull) + (block_id) * 0x1000000ull; + } + return CVMX_ADD_IO_SEG(0x0001180088000020ull) + (block_id) * 0x60000000ull; +} + +#define CVMX_LMCX_IFB_CNT(block_id) (CVMX_ADD_IO_SEG(0x00011800880001D0ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_IFB_CNT_HI(block_id) (CVMX_ADD_IO_SEG(0x0001180088000050ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_IFB_CNT_LO(block_id) (CVMX_ADD_IO_SEG(0x0001180088000048ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_INT(block_id) (CVMX_ADD_IO_SEG(0x00011800880001F0ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_INT_EN(block_id) (CVMX_ADD_IO_SEG(0x00011800880001E8ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_MEM_CFG0(block_id) (CVMX_ADD_IO_SEG(0x0001180088000000ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_MEM_CFG1(block_id) (CVMX_ADD_IO_SEG(0x0001180088000008ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_MODEREG_PARAMS0(block_id) (CVMX_ADD_IO_SEG(0x00011800880001A8ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_MODEREG_PARAMS1(block_id) (CVMX_ADD_IO_SEG(0x0001180088000260ull) + ((block_id) & 3) * 0x1000000ull) +static inline uint64_t CVMX_LMCX_NXM(unsigned long block_id) +{ + switch (cvmx_get_octeon_family()) { + case OCTEON_CNF71XX & OCTEON_FAMILY_MASK: + case OCTEON_CN61XX & OCTEON_FAMILY_MASK: + case OCTEON_CN66XX & OCTEON_FAMILY_MASK: + case OCTEON_CN52XX & OCTEON_FAMILY_MASK: + case OCTEON_CN58XX & OCTEON_FAMILY_MASK: + case OCTEON_CN63XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x00011800880000C8ull) + (block_id) * 0x60000000ull; + case OCTEON_CN56XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x00011800880000C8ull) + (block_id) * 0x60000000ull; + case OCTEON_CN68XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x00011800880000C8ull) + (block_id) * 0x1000000ull; + } + return CVMX_ADD_IO_SEG(0x00011800880000C8ull) + (block_id) * 0x60000000ull; +} + +#define CVMX_LMCX_OPS_CNT(block_id) (CVMX_ADD_IO_SEG(0x00011800880001D8ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_OPS_CNT_HI(block_id) (CVMX_ADD_IO_SEG(0x0001180088000060ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_OPS_CNT_LO(block_id) (CVMX_ADD_IO_SEG(0x0001180088000058ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_PHY_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000210ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_PLL_BWCTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000040ull)) +#define CVMX_LMCX_PLL_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800880000A8ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_PLL_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800880000B0ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_READ_LEVEL_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000140ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_READ_LEVEL_DBG(block_id) (CVMX_ADD_IO_SEG(0x0001180088000148ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_READ_LEVEL_RANKX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180088000100ull) + (((offset) & 3) + ((block_id) & 1) * 0xC000000ull) * 8) +#define CVMX_LMCX_RESET_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000180ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_RLEVEL_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800880002A0ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_RLEVEL_DBG(block_id) (CVMX_ADD_IO_SEG(0x00011800880002A8ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_RLEVEL_RANKX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180088000280ull) + (((offset) & 3) + ((block_id) & 3) * 0x200000ull) * 8) +#define CVMX_LMCX_RODT_COMP_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800880000A0ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_RODT_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000078ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_RODT_MASK(block_id) (CVMX_ADD_IO_SEG(0x0001180088000268ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_SCRAMBLED_FADR(block_id) (CVMX_ADD_IO_SEG(0x0001180088000330ull)) +#define CVMX_LMCX_SCRAMBLE_CFG0(block_id) (CVMX_ADD_IO_SEG(0x0001180088000320ull)) +#define CVMX_LMCX_SCRAMBLE_CFG1(block_id) (CVMX_ADD_IO_SEG(0x0001180088000328ull)) +#define CVMX_LMCX_SLOT_CTL0(block_id) (CVMX_ADD_IO_SEG(0x00011800880001F8ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_SLOT_CTL1(block_id) (CVMX_ADD_IO_SEG(0x0001180088000200ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_SLOT_CTL2(block_id) (CVMX_ADD_IO_SEG(0x0001180088000208ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_TIMING_PARAMS0(block_id) (CVMX_ADD_IO_SEG(0x0001180088000198ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_TIMING_PARAMS1(block_id) (CVMX_ADD_IO_SEG(0x00011800880001A0ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_TRO_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000248ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_TRO_STAT(block_id) (CVMX_ADD_IO_SEG(0x0001180088000250ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_WLEVEL_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180088000300ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_WLEVEL_DBG(block_id) (CVMX_ADD_IO_SEG(0x0001180088000308ull) + ((block_id) & 3) * 0x1000000ull) +#define CVMX_LMCX_WLEVEL_RANKX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800880002B0ull) + (((offset) & 3) + ((block_id) & 3) * 0x200000ull) * 8) +#define CVMX_LMCX_WODT_CTL0(block_id) (CVMX_ADD_IO_SEG(0x0001180088000030ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_WODT_CTL1(block_id) (CVMX_ADD_IO_SEG(0x0001180088000080ull) + ((block_id) & 1) * 0x60000000ull) +#define CVMX_LMCX_WODT_MASK(block_id) (CVMX_ADD_IO_SEG(0x00011800880001B0ull) + ((block_id) & 3) * 0x1000000ull) + +union cvmx_lmcx_bist_ctl { + uint64_t u64; + struct cvmx_lmcx_bist_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_1_63:63; + uint64_t start:1; +#else + uint64_t start:1; + uint64_t reserved_1_63:63; +#endif + } s; + struct cvmx_lmcx_bist_ctl_s cn50xx; + struct cvmx_lmcx_bist_ctl_s cn52xx; + struct cvmx_lmcx_bist_ctl_s cn52xxp1; + struct cvmx_lmcx_bist_ctl_s cn56xx; + struct cvmx_lmcx_bist_ctl_s cn56xxp1; +}; + +union cvmx_lmcx_bist_result { + uint64_t u64; + struct cvmx_lmcx_bist_result_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_11_63:53; + uint64_t csrd2e:1; + uint64_t csre2d:1; + uint64_t mwf:1; + uint64_t mwd:3; + uint64_t mwc:1; + uint64_t mrf:1; + uint64_t mrd:3; +#else + uint64_t mrd:3; + uint64_t mrf:1; + uint64_t mwc:1; + uint64_t mwd:3; + uint64_t mwf:1; + uint64_t csre2d:1; + uint64_t csrd2e:1; + uint64_t reserved_11_63:53; +#endif + } s; + struct cvmx_lmcx_bist_result_cn50xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_9_63:55; + uint64_t mwf:1; + uint64_t mwd:3; + uint64_t mwc:1; + uint64_t mrf:1; + uint64_t mrd:3; +#else + uint64_t mrd:3; + uint64_t mrf:1; + uint64_t mwc:1; + uint64_t mwd:3; + uint64_t mwf:1; + uint64_t reserved_9_63:55; +#endif + } cn50xx; + struct cvmx_lmcx_bist_result_s cn52xx; + struct cvmx_lmcx_bist_result_s cn52xxp1; + struct cvmx_lmcx_bist_result_s cn56xx; + struct cvmx_lmcx_bist_result_s cn56xxp1; +}; + +union cvmx_lmcx_char_ctl { + uint64_t u64; + struct cvmx_lmcx_char_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_44_63:20; + uint64_t dr:1; + uint64_t skew_on:1; + uint64_t en:1; + uint64_t sel:1; + uint64_t prog:8; + uint64_t prbs:32; +#else + uint64_t prbs:32; + uint64_t prog:8; + uint64_t sel:1; + uint64_t en:1; + uint64_t skew_on:1; + uint64_t dr:1; + uint64_t reserved_44_63:20; +#endif + } s; + struct cvmx_lmcx_char_ctl_s cn61xx; + struct cvmx_lmcx_char_ctl_cn63xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_42_63:22; + uint64_t en:1; + uint64_t sel:1; + uint64_t prog:8; + uint64_t prbs:32; +#else + uint64_t prbs:32; + uint64_t prog:8; + uint64_t sel:1; + uint64_t en:1; + uint64_t reserved_42_63:22; +#endif + } cn63xx; + struct cvmx_lmcx_char_ctl_cn63xx cn63xxp1; + struct cvmx_lmcx_char_ctl_s cn66xx; + struct cvmx_lmcx_char_ctl_s cn68xx; + struct cvmx_lmcx_char_ctl_cn63xx cn68xxp1; + struct cvmx_lmcx_char_ctl_s cnf71xx; +}; + +union cvmx_lmcx_char_mask0 { + uint64_t u64; + struct cvmx_lmcx_char_mask0_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t mask:64; +#else + uint64_t mask:64; +#endif + } s; + struct cvmx_lmcx_char_mask0_s cn61xx; + struct cvmx_lmcx_char_mask0_s cn63xx; + struct cvmx_lmcx_char_mask0_s cn63xxp1; + struct cvmx_lmcx_char_mask0_s cn66xx; + struct cvmx_lmcx_char_mask0_s cn68xx; + struct cvmx_lmcx_char_mask0_s cn68xxp1; + struct cvmx_lmcx_char_mask0_s cnf71xx; +}; + +union cvmx_lmcx_char_mask1 { + uint64_t u64; + struct cvmx_lmcx_char_mask1_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_8_63:56; + uint64_t mask:8; +#else + uint64_t mask:8; + uint64_t reserved_8_63:56; +#endif + } s; + struct cvmx_lmcx_char_mask1_s cn61xx; + struct cvmx_lmcx_char_mask1_s cn63xx; + struct cvmx_lmcx_char_mask1_s cn63xxp1; + struct cvmx_lmcx_char_mask1_s cn66xx; + struct cvmx_lmcx_char_mask1_s cn68xx; + struct cvmx_lmcx_char_mask1_s cn68xxp1; + struct cvmx_lmcx_char_mask1_s cnf71xx; +}; + +union cvmx_lmcx_char_mask2 { + uint64_t u64; + struct cvmx_lmcx_char_mask2_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t mask:64; +#else + uint64_t mask:64; +#endif + } s; + struct cvmx_lmcx_char_mask2_s cn61xx; + struct cvmx_lmcx_char_mask2_s cn63xx; + struct cvmx_lmcx_char_mask2_s cn63xxp1; + struct cvmx_lmcx_char_mask2_s cn66xx; + struct cvmx_lmcx_char_mask2_s cn68xx; + struct cvmx_lmcx_char_mask2_s cn68xxp1; + struct cvmx_lmcx_char_mask2_s cnf71xx; +}; + +union cvmx_lmcx_char_mask3 { + uint64_t u64; + struct cvmx_lmcx_char_mask3_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_8_63:56; + uint64_t mask:8; +#else + uint64_t mask:8; + uint64_t reserved_8_63:56; +#endif + } s; + struct cvmx_lmcx_char_mask3_s cn61xx; + struct cvmx_lmcx_char_mask3_s cn63xx; + struct cvmx_lmcx_char_mask3_s cn63xxp1; + struct cvmx_lmcx_char_mask3_s cn66xx; + struct cvmx_lmcx_char_mask3_s cn68xx; + struct cvmx_lmcx_char_mask3_s cn68xxp1; + struct cvmx_lmcx_char_mask3_s cnf71xx; +}; + +union cvmx_lmcx_char_mask4 { + uint64_t u64; + struct cvmx_lmcx_char_mask4_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_33_63:31; + uint64_t reset_n_mask:1; + uint64_t a_mask:16; + uint64_t ba_mask:3; + uint64_t we_n_mask:1; + uint64_t cas_n_mask:1; + uint64_t ras_n_mask:1; + uint64_t odt1_mask:2; + uint64_t odt0_mask:2; + uint64_t cs1_n_mask:2; + uint64_t cs0_n_mask:2; + uint64_t cke_mask:2; +#else + uint64_t cke_mask:2; + uint64_t cs0_n_mask:2; + uint64_t cs1_n_mask:2; + uint64_t odt0_mask:2; + uint64_t odt1_mask:2; + uint64_t ras_n_mask:1; + uint64_t cas_n_mask:1; + uint64_t we_n_mask:1; + uint64_t ba_mask:3; + uint64_t a_mask:16; + uint64_t reset_n_mask:1; + uint64_t reserved_33_63:31; +#endif + } s; + struct cvmx_lmcx_char_mask4_s cn61xx; + struct cvmx_lmcx_char_mask4_s cn63xx; + struct cvmx_lmcx_char_mask4_s cn63xxp1; + struct cvmx_lmcx_char_mask4_s cn66xx; + struct cvmx_lmcx_char_mask4_s cn68xx; + struct cvmx_lmcx_char_mask4_s cn68xxp1; + struct cvmx_lmcx_char_mask4_s cnf71xx; +}; + +union cvmx_lmcx_comp_ctl { + uint64_t u64; + struct cvmx_lmcx_comp_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t nctl_csr:4; + uint64_t nctl_clk:4; + uint64_t nctl_cmd:4; + uint64_t nctl_dat:4; + uint64_t pctl_csr:4; + uint64_t pctl_clk:4; + uint64_t reserved_0_7:8; +#else + uint64_t reserved_0_7:8; + uint64_t pctl_clk:4; + uint64_t pctl_csr:4; + uint64_t nctl_dat:4; + uint64_t nctl_cmd:4; + uint64_t nctl_clk:4; + uint64_t nctl_csr:4; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_comp_ctl_cn30xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t nctl_csr:4; + uint64_t nctl_clk:4; + uint64_t nctl_cmd:4; + uint64_t nctl_dat:4; + uint64_t pctl_csr:4; + uint64_t pctl_clk:4; + uint64_t pctl_cmd:4; + uint64_t pctl_dat:4; +#else + uint64_t pctl_dat:4; + uint64_t pctl_cmd:4; + uint64_t pctl_clk:4; + uint64_t pctl_csr:4; + uint64_t nctl_dat:4; + uint64_t nctl_cmd:4; + uint64_t nctl_clk:4; + uint64_t nctl_csr:4; + uint64_t reserved_32_63:32; +#endif + } cn30xx; + struct cvmx_lmcx_comp_ctl_cn30xx cn31xx; + struct cvmx_lmcx_comp_ctl_cn30xx cn38xx; + struct cvmx_lmcx_comp_ctl_cn30xx cn38xxp2; + struct cvmx_lmcx_comp_ctl_cn50xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t nctl_csr:4; + uint64_t reserved_20_27:8; + uint64_t nctl_dat:4; + uint64_t pctl_csr:4; + uint64_t reserved_5_11:7; + uint64_t pctl_dat:5; +#else + uint64_t pctl_dat:5; + uint64_t reserved_5_11:7; + uint64_t pctl_csr:4; + uint64_t nctl_dat:4; + uint64_t reserved_20_27:8; + uint64_t nctl_csr:4; + uint64_t reserved_32_63:32; +#endif + } cn50xx; + struct cvmx_lmcx_comp_ctl_cn50xx cn52xx; + struct cvmx_lmcx_comp_ctl_cn50xx cn52xxp1; + struct cvmx_lmcx_comp_ctl_cn50xx cn56xx; + struct cvmx_lmcx_comp_ctl_cn50xx cn56xxp1; + struct cvmx_lmcx_comp_ctl_cn50xx cn58xx; + struct cvmx_lmcx_comp_ctl_cn58xxp1 { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t nctl_csr:4; + uint64_t reserved_20_27:8; + uint64_t nctl_dat:4; + uint64_t pctl_csr:4; + uint64_t reserved_4_11:8; + uint64_t pctl_dat:4; +#else + uint64_t pctl_dat:4; + uint64_t reserved_4_11:8; + uint64_t pctl_csr:4; + uint64_t nctl_dat:4; + uint64_t reserved_20_27:8; + uint64_t nctl_csr:4; + uint64_t reserved_32_63:32; +#endif + } cn58xxp1; +}; + +union cvmx_lmcx_comp_ctl2 { + uint64_t u64; + struct cvmx_lmcx_comp_ctl2_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_34_63:30; + uint64_t ddr__ptune:4; + uint64_t ddr__ntune:4; + uint64_t m180:1; + uint64_t byp:1; + uint64_t ptune:4; + uint64_t ntune:4; + uint64_t rodt_ctl:4; + uint64_t cmd_ctl:4; + uint64_t ck_ctl:4; + uint64_t dqx_ctl:4; +#else + uint64_t dqx_ctl:4; + uint64_t ck_ctl:4; + uint64_t cmd_ctl:4; + uint64_t rodt_ctl:4; + uint64_t ntune:4; + uint64_t ptune:4; + uint64_t byp:1; + uint64_t m180:1; + uint64_t ddr__ntune:4; + uint64_t ddr__ptune:4; + uint64_t reserved_34_63:30; +#endif + } s; + struct cvmx_lmcx_comp_ctl2_s cn61xx; + struct cvmx_lmcx_comp_ctl2_s cn63xx; + struct cvmx_lmcx_comp_ctl2_s cn63xxp1; + struct cvmx_lmcx_comp_ctl2_s cn66xx; + struct cvmx_lmcx_comp_ctl2_s cn68xx; + struct cvmx_lmcx_comp_ctl2_s cn68xxp1; + struct cvmx_lmcx_comp_ctl2_s cnf71xx; +}; + +union cvmx_lmcx_config { + uint64_t u64; + struct cvmx_lmcx_config_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_61_63:3; + uint64_t mode32b:1; + uint64_t scrz:1; + uint64_t early_unload_d1_r1:1; + uint64_t early_unload_d1_r0:1; + uint64_t early_unload_d0_r1:1; + uint64_t early_unload_d0_r0:1; + uint64_t init_status:4; + uint64_t mirrmask:4; + uint64_t rankmask:4; + uint64_t rank_ena:1; + uint64_t sref_with_dll:1; + uint64_t early_dqx:1; + uint64_t sequence:3; + uint64_t ref_zqcs_int:19; + uint64_t reset:1; + uint64_t ecc_adr:1; + uint64_t forcewrite:4; + uint64_t idlepower:3; + uint64_t pbank_lsb:4; + uint64_t row_lsb:3; + uint64_t ecc_ena:1; + uint64_t init_start:1; +#else + uint64_t init_start:1; + uint64_t ecc_ena:1; + uint64_t row_lsb:3; + uint64_t pbank_lsb:4; + uint64_t idlepower:3; + uint64_t forcewrite:4; + uint64_t ecc_adr:1; + uint64_t reset:1; + uint64_t ref_zqcs_int:19; + uint64_t sequence:3; + uint64_t early_dqx:1; + uint64_t sref_with_dll:1; + uint64_t rank_ena:1; + uint64_t rankmask:4; + uint64_t mirrmask:4; + uint64_t init_status:4; + uint64_t early_unload_d0_r0:1; + uint64_t early_unload_d0_r1:1; + uint64_t early_unload_d1_r0:1; + uint64_t early_unload_d1_r1:1; + uint64_t scrz:1; + uint64_t mode32b:1; + uint64_t reserved_61_63:3; +#endif + } s; + struct cvmx_lmcx_config_s cn61xx; + struct cvmx_lmcx_config_cn63xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_59_63:5; + uint64_t early_unload_d1_r1:1; + uint64_t early_unload_d1_r0:1; + uint64_t early_unload_d0_r1:1; + uint64_t early_unload_d0_r0:1; + uint64_t init_status:4; + uint64_t mirrmask:4; + uint64_t rankmask:4; + uint64_t rank_ena:1; + uint64_t sref_with_dll:1; + uint64_t early_dqx:1; + uint64_t sequence:3; + uint64_t ref_zqcs_int:19; + uint64_t reset:1; + uint64_t ecc_adr:1; + uint64_t forcewrite:4; + uint64_t idlepower:3; + uint64_t pbank_lsb:4; + uint64_t row_lsb:3; + uint64_t ecc_ena:1; + uint64_t init_start:1; +#else + uint64_t init_start:1; + uint64_t ecc_ena:1; + uint64_t row_lsb:3; + uint64_t pbank_lsb:4; + uint64_t idlepower:3; + uint64_t forcewrite:4; + uint64_t ecc_adr:1; + uint64_t reset:1; + uint64_t ref_zqcs_int:19; + uint64_t sequence:3; + uint64_t early_dqx:1; + uint64_t sref_with_dll:1; + uint64_t rank_ena:1; + uint64_t rankmask:4; + uint64_t mirrmask:4; + uint64_t init_status:4; + uint64_t early_unload_d0_r0:1; + uint64_t early_unload_d0_r1:1; + uint64_t early_unload_d1_r0:1; + uint64_t early_unload_d1_r1:1; + uint64_t reserved_59_63:5; +#endif + } cn63xx; + struct cvmx_lmcx_config_cn63xxp1 { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_55_63:9; + uint64_t init_status:4; + uint64_t mirrmask:4; + uint64_t rankmask:4; + uint64_t rank_ena:1; + uint64_t sref_with_dll:1; + uint64_t early_dqx:1; + uint64_t sequence:3; + uint64_t ref_zqcs_int:19; + uint64_t reset:1; + uint64_t ecc_adr:1; + uint64_t forcewrite:4; + uint64_t idlepower:3; + uint64_t pbank_lsb:4; + uint64_t row_lsb:3; + uint64_t ecc_ena:1; + uint64_t init_start:1; +#else + uint64_t init_start:1; + uint64_t ecc_ena:1; + uint64_t row_lsb:3; + uint64_t pbank_lsb:4; + uint64_t idlepower:3; + uint64_t forcewrite:4; + uint64_t ecc_adr:1; + uint64_t reset:1; + uint64_t ref_zqcs_int:19; + uint64_t sequence:3; + uint64_t early_dqx:1; + uint64_t sref_with_dll:1; + uint64_t rank_ena:1; + uint64_t rankmask:4; + uint64_t mirrmask:4; + uint64_t init_status:4; + uint64_t reserved_55_63:9; +#endif + } cn63xxp1; + struct cvmx_lmcx_config_cn66xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_60_63:4; + uint64_t scrz:1; + uint64_t early_unload_d1_r1:1; + uint64_t early_unload_d1_r0:1; + uint64_t early_unload_d0_r1:1; + uint64_t early_unload_d0_r0:1; + uint64_t init_status:4; + uint64_t mirrmask:4; + uint64_t rankmask:4; + uint64_t rank_ena:1; + uint64_t sref_with_dll:1; + uint64_t early_dqx:1; + uint64_t sequence:3; + uint64_t ref_zqcs_int:19; + uint64_t reset:1; + uint64_t ecc_adr:1; + uint64_t forcewrite:4; + uint64_t idlepower:3; + uint64_t pbank_lsb:4; + uint64_t row_lsb:3; + uint64_t ecc_ena:1; + uint64_t init_start:1; +#else + uint64_t init_start:1; + uint64_t ecc_ena:1; + uint64_t row_lsb:3; + uint64_t pbank_lsb:4; + uint64_t idlepower:3; + uint64_t forcewrite:4; + uint64_t ecc_adr:1; + uint64_t reset:1; + uint64_t ref_zqcs_int:19; + uint64_t sequence:3; + uint64_t early_dqx:1; + uint64_t sref_with_dll:1; + uint64_t rank_ena:1; + uint64_t rankmask:4; + uint64_t mirrmask:4; + uint64_t init_status:4; + uint64_t early_unload_d0_r0:1; + uint64_t early_unload_d0_r1:1; + uint64_t early_unload_d1_r0:1; + uint64_t early_unload_d1_r1:1; + uint64_t scrz:1; + uint64_t reserved_60_63:4; +#endif + } cn66xx; + struct cvmx_lmcx_config_cn63xx cn68xx; + struct cvmx_lmcx_config_cn63xx cn68xxp1; + struct cvmx_lmcx_config_s cnf71xx; +}; + +union cvmx_lmcx_control { + uint64_t u64; + struct cvmx_lmcx_control_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t scramble_ena:1; + uint64_t thrcnt:12; + uint64_t persub:8; + uint64_t thrmax:4; + uint64_t crm_cnt:5; + uint64_t crm_thr:5; + uint64_t crm_max:5; + uint64_t rodt_bprch:1; + uint64_t wodt_bprch:1; + uint64_t bprch:2; + uint64_t ext_zqcs_dis:1; + uint64_t int_zqcs_dis:1; + uint64_t auto_dclkdis:1; + uint64_t xor_bank:1; + uint64_t max_write_batch:4; + uint64_t nxm_write_en:1; + uint64_t elev_prio_dis:1; + uint64_t inorder_wr:1; + uint64_t inorder_rd:1; + uint64_t throttle_wr:1; + uint64_t throttle_rd:1; + uint64_t fprch2:2; + uint64_t pocas:1; + uint64_t ddr2t:1; + uint64_t bwcnt:1; + uint64_t rdimm_ena:1; +#else + uint64_t rdimm_ena:1; + uint64_t bwcnt:1; + uint64_t ddr2t:1; + uint64_t pocas:1; + uint64_t fprch2:2; + uint64_t throttle_rd:1; + uint64_t throttle_wr:1; + uint64_t inorder_rd:1; + uint64_t inorder_wr:1; + uint64_t elev_prio_dis:1; + uint64_t nxm_write_en:1; + uint64_t max_write_batch:4; + uint64_t xor_bank:1; + uint64_t auto_dclkdis:1; + uint64_t int_zqcs_dis:1; + uint64_t ext_zqcs_dis:1; + uint64_t bprch:2; + uint64_t wodt_bprch:1; + uint64_t rodt_bprch:1; + uint64_t crm_max:5; + uint64_t crm_thr:5; + uint64_t crm_cnt:5; + uint64_t thrmax:4; + uint64_t persub:8; + uint64_t thrcnt:12; + uint64_t scramble_ena:1; +#endif + } s; + struct cvmx_lmcx_control_s cn61xx; + struct cvmx_lmcx_control_cn63xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_24_63:40; + uint64_t rodt_bprch:1; + uint64_t wodt_bprch:1; + uint64_t bprch:2; + uint64_t ext_zqcs_dis:1; + uint64_t int_zqcs_dis:1; + uint64_t auto_dclkdis:1; + uint64_t xor_bank:1; + uint64_t max_write_batch:4; + uint64_t nxm_write_en:1; + uint64_t elev_prio_dis:1; + uint64_t inorder_wr:1; + uint64_t inorder_rd:1; + uint64_t throttle_wr:1; + uint64_t throttle_rd:1; + uint64_t fprch2:2; + uint64_t pocas:1; + uint64_t ddr2t:1; + uint64_t bwcnt:1; + uint64_t rdimm_ena:1; +#else + uint64_t rdimm_ena:1; + uint64_t bwcnt:1; + uint64_t ddr2t:1; + uint64_t pocas:1; + uint64_t fprch2:2; + uint64_t throttle_rd:1; + uint64_t throttle_wr:1; + uint64_t inorder_rd:1; + uint64_t inorder_wr:1; + uint64_t elev_prio_dis:1; + uint64_t nxm_write_en:1; + uint64_t max_write_batch:4; + uint64_t xor_bank:1; + uint64_t auto_dclkdis:1; + uint64_t int_zqcs_dis:1; + uint64_t ext_zqcs_dis:1; + uint64_t bprch:2; + uint64_t wodt_bprch:1; + uint64_t rodt_bprch:1; + uint64_t reserved_24_63:40; +#endif + } cn63xx; + struct cvmx_lmcx_control_cn63xx cn63xxp1; + struct cvmx_lmcx_control_cn66xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t scramble_ena:1; + uint64_t reserved_24_62:39; + uint64_t rodt_bprch:1; + uint64_t wodt_bprch:1; + uint64_t bprch:2; + uint64_t ext_zqcs_dis:1; + uint64_t int_zqcs_dis:1; + uint64_t auto_dclkdis:1; + uint64_t xor_bank:1; + uint64_t max_write_batch:4; + uint64_t nxm_write_en:1; + uint64_t elev_prio_dis:1; + uint64_t inorder_wr:1; + uint64_t inorder_rd:1; + uint64_t throttle_wr:1; + uint64_t throttle_rd:1; + uint64_t fprch2:2; + uint64_t pocas:1; + uint64_t ddr2t:1; + uint64_t bwcnt:1; + uint64_t rdimm_ena:1; +#else + uint64_t rdimm_ena:1; + uint64_t bwcnt:1; + uint64_t ddr2t:1; + uint64_t pocas:1; + uint64_t fprch2:2; + uint64_t throttle_rd:1; + uint64_t throttle_wr:1; + uint64_t inorder_rd:1; + uint64_t inorder_wr:1; + uint64_t elev_prio_dis:1; + uint64_t nxm_write_en:1; + uint64_t max_write_batch:4; + uint64_t xor_bank:1; + uint64_t auto_dclkdis:1; + uint64_t int_zqcs_dis:1; + uint64_t ext_zqcs_dis:1; + uint64_t bprch:2; + uint64_t wodt_bprch:1; + uint64_t rodt_bprch:1; + uint64_t reserved_24_62:39; + uint64_t scramble_ena:1; +#endif + } cn66xx; + struct cvmx_lmcx_control_cn68xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_63_63:1; + uint64_t thrcnt:12; + uint64_t persub:8; + uint64_t thrmax:4; + uint64_t crm_cnt:5; + uint64_t crm_thr:5; + uint64_t crm_max:5; + uint64_t rodt_bprch:1; + uint64_t wodt_bprch:1; + uint64_t bprch:2; + uint64_t ext_zqcs_dis:1; + uint64_t int_zqcs_dis:1; + uint64_t auto_dclkdis:1; + uint64_t xor_bank:1; + uint64_t max_write_batch:4; + uint64_t nxm_write_en:1; + uint64_t elev_prio_dis:1; + uint64_t inorder_wr:1; + uint64_t inorder_rd:1; + uint64_t throttle_wr:1; + uint64_t throttle_rd:1; + uint64_t fprch2:2; + uint64_t pocas:1; + uint64_t ddr2t:1; + uint64_t bwcnt:1; + uint64_t rdimm_ena:1; +#else + uint64_t rdimm_ena:1; + uint64_t bwcnt:1; + uint64_t ddr2t:1; + uint64_t pocas:1; + uint64_t fprch2:2; + uint64_t throttle_rd:1; + uint64_t throttle_wr:1; + uint64_t inorder_rd:1; + uint64_t inorder_wr:1; + uint64_t elev_prio_dis:1; + uint64_t nxm_write_en:1; + uint64_t max_write_batch:4; + uint64_t xor_bank:1; + uint64_t auto_dclkdis:1; + uint64_t int_zqcs_dis:1; + uint64_t ext_zqcs_dis:1; + uint64_t bprch:2; + uint64_t wodt_bprch:1; + uint64_t rodt_bprch:1; + uint64_t crm_max:5; + uint64_t crm_thr:5; + uint64_t crm_cnt:5; + uint64_t thrmax:4; + uint64_t persub:8; + uint64_t thrcnt:12; + uint64_t reserved_63_63:1; +#endif + } cn68xx; + struct cvmx_lmcx_control_cn68xx cn68xxp1; + struct cvmx_lmcx_control_cn66xx cnf71xx; +}; + +union cvmx_lmcx_ctl { + uint64_t u64; + struct cvmx_lmcx_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t ddr__nctl:4; + uint64_t ddr__pctl:4; + uint64_t slow_scf:1; + uint64_t xor_bank:1; + uint64_t max_write_batch:4; + uint64_t pll_div2:1; + uint64_t pll_bypass:1; + uint64_t rdimm_ena:1; + uint64_t r2r_slot:1; + uint64_t inorder_mwf:1; + uint64_t inorder_mrf:1; + uint64_t reserved_10_11:2; + uint64_t fprch2:1; + uint64_t bprch:1; + uint64_t sil_lat:2; + uint64_t tskw:2; + uint64_t qs_dic:2; + uint64_t dic:2; +#else + uint64_t dic:2; + uint64_t qs_dic:2; + uint64_t tskw:2; + uint64_t sil_lat:2; + uint64_t bprch:1; + uint64_t fprch2:1; + uint64_t reserved_10_11:2; + uint64_t inorder_mrf:1; + uint64_t inorder_mwf:1; + uint64_t r2r_slot:1; + uint64_t rdimm_ena:1; + uint64_t pll_bypass:1; + uint64_t pll_div2:1; + uint64_t max_write_batch:4; + uint64_t xor_bank:1; + uint64_t slow_scf:1; + uint64_t ddr__pctl:4; + uint64_t ddr__nctl:4; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_ctl_cn30xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t ddr__nctl:4; + uint64_t ddr__pctl:4; + uint64_t slow_scf:1; + uint64_t xor_bank:1; + uint64_t max_write_batch:4; + uint64_t pll_div2:1; + uint64_t pll_bypass:1; + uint64_t rdimm_ena:1; + uint64_t r2r_slot:1; + uint64_t inorder_mwf:1; + uint64_t inorder_mrf:1; + uint64_t dreset:1; + uint64_t mode32b:1; + uint64_t fprch2:1; + uint64_t bprch:1; + uint64_t sil_lat:2; + uint64_t tskw:2; + uint64_t qs_dic:2; + uint64_t dic:2; +#else + uint64_t dic:2; + uint64_t qs_dic:2; + uint64_t tskw:2; + uint64_t sil_lat:2; + uint64_t bprch:1; + uint64_t fprch2:1; + uint64_t mode32b:1; + uint64_t dreset:1; + uint64_t inorder_mrf:1; + uint64_t inorder_mwf:1; + uint64_t r2r_slot:1; + uint64_t rdimm_ena:1; + uint64_t pll_bypass:1; + uint64_t pll_div2:1; + uint64_t max_write_batch:4; + uint64_t xor_bank:1; + uint64_t slow_scf:1; + uint64_t ddr__pctl:4; + uint64_t ddr__nctl:4; + uint64_t reserved_32_63:32; +#endif + } cn30xx; + struct cvmx_lmcx_ctl_cn30xx cn31xx; + struct cvmx_lmcx_ctl_cn38xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t ddr__nctl:4; + uint64_t ddr__pctl:4; + uint64_t slow_scf:1; + uint64_t xor_bank:1; + uint64_t max_write_batch:4; + uint64_t reserved_16_17:2; + uint64_t rdimm_ena:1; + uint64_t r2r_slot:1; + uint64_t inorder_mwf:1; + uint64_t inorder_mrf:1; + uint64_t set_zero:1; + uint64_t mode128b:1; + uint64_t fprch2:1; + uint64_t bprch:1; + uint64_t sil_lat:2; + uint64_t tskw:2; + uint64_t qs_dic:2; + uint64_t dic:2; +#else + uint64_t dic:2; + uint64_t qs_dic:2; + uint64_t tskw:2; + uint64_t sil_lat:2; + uint64_t bprch:1; + uint64_t fprch2:1; + uint64_t mode128b:1; + uint64_t set_zero:1; + uint64_t inorder_mrf:1; + uint64_t inorder_mwf:1; + uint64_t r2r_slot:1; + uint64_t rdimm_ena:1; + uint64_t reserved_16_17:2; + uint64_t max_write_batch:4; + uint64_t xor_bank:1; + uint64_t slow_scf:1; + uint64_t ddr__pctl:4; + uint64_t ddr__nctl:4; + uint64_t reserved_32_63:32; +#endif + } cn38xx; + struct cvmx_lmcx_ctl_cn38xx cn38xxp2; + struct cvmx_lmcx_ctl_cn50xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t ddr__nctl:4; + uint64_t ddr__pctl:4; + uint64_t slow_scf:1; + uint64_t xor_bank:1; + uint64_t max_write_batch:4; + uint64_t reserved_17_17:1; + uint64_t pll_bypass:1; + uint64_t rdimm_ena:1; + uint64_t r2r_slot:1; + uint64_t inorder_mwf:1; + uint64_t inorder_mrf:1; + uint64_t dreset:1; + uint64_t mode32b:1; + uint64_t fprch2:1; + uint64_t bprch:1; + uint64_t sil_lat:2; + uint64_t tskw:2; + uint64_t qs_dic:2; + uint64_t dic:2; +#else + uint64_t dic:2; + uint64_t qs_dic:2; + uint64_t tskw:2; + uint64_t sil_lat:2; + uint64_t bprch:1; + uint64_t fprch2:1; + uint64_t mode32b:1; + uint64_t dreset:1; + uint64_t inorder_mrf:1; + uint64_t inorder_mwf:1; + uint64_t r2r_slot:1; + uint64_t rdimm_ena:1; + uint64_t pll_bypass:1; + uint64_t reserved_17_17:1; + uint64_t max_write_batch:4; + uint64_t xor_bank:1; + uint64_t slow_scf:1; + uint64_t ddr__pctl:4; + uint64_t ddr__nctl:4; + uint64_t reserved_32_63:32; +#endif + } cn50xx; + struct cvmx_lmcx_ctl_cn52xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t ddr__nctl:4; + uint64_t ddr__pctl:4; + uint64_t slow_scf:1; + uint64_t xor_bank:1; + uint64_t max_write_batch:4; + uint64_t reserved_16_17:2; + uint64_t rdimm_ena:1; + uint64_t r2r_slot:1; + uint64_t inorder_mwf:1; + uint64_t inorder_mrf:1; + uint64_t dreset:1; + uint64_t mode32b:1; + uint64_t fprch2:1; + uint64_t bprch:1; + uint64_t sil_lat:2; + uint64_t tskw:2; + uint64_t qs_dic:2; + uint64_t dic:2; +#else + uint64_t dic:2; + uint64_t qs_dic:2; + uint64_t tskw:2; + uint64_t sil_lat:2; + uint64_t bprch:1; + uint64_t fprch2:1; + uint64_t mode32b:1; + uint64_t dreset:1; + uint64_t inorder_mrf:1; + uint64_t inorder_mwf:1; + uint64_t r2r_slot:1; + uint64_t rdimm_ena:1; + uint64_t reserved_16_17:2; + uint64_t max_write_batch:4; + uint64_t xor_bank:1; + uint64_t slow_scf:1; + uint64_t ddr__pctl:4; + uint64_t ddr__nctl:4; + uint64_t reserved_32_63:32; +#endif + } cn52xx; + struct cvmx_lmcx_ctl_cn52xx cn52xxp1; + struct cvmx_lmcx_ctl_cn52xx cn56xx; + struct cvmx_lmcx_ctl_cn52xx cn56xxp1; + struct cvmx_lmcx_ctl_cn58xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t ddr__nctl:4; + uint64_t ddr__pctl:4; + uint64_t slow_scf:1; + uint64_t xor_bank:1; + uint64_t max_write_batch:4; + uint64_t reserved_16_17:2; + uint64_t rdimm_ena:1; + uint64_t r2r_slot:1; + uint64_t inorder_mwf:1; + uint64_t inorder_mrf:1; + uint64_t dreset:1; + uint64_t mode128b:1; + uint64_t fprch2:1; + uint64_t bprch:1; + uint64_t sil_lat:2; + uint64_t tskw:2; + uint64_t qs_dic:2; + uint64_t dic:2; +#else + uint64_t dic:2; + uint64_t qs_dic:2; + uint64_t tskw:2; + uint64_t sil_lat:2; + uint64_t bprch:1; + uint64_t fprch2:1; + uint64_t mode128b:1; + uint64_t dreset:1; + uint64_t inorder_mrf:1; + uint64_t inorder_mwf:1; + uint64_t r2r_slot:1; + uint64_t rdimm_ena:1; + uint64_t reserved_16_17:2; + uint64_t max_write_batch:4; + uint64_t xor_bank:1; + uint64_t slow_scf:1; + uint64_t ddr__pctl:4; + uint64_t ddr__nctl:4; + uint64_t reserved_32_63:32; +#endif + } cn58xx; + struct cvmx_lmcx_ctl_cn58xx cn58xxp1; +}; + +union cvmx_lmcx_ctl1 { + uint64_t u64; + struct cvmx_lmcx_ctl1_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_21_63:43; + uint64_t ecc_adr:1; + uint64_t forcewrite:4; + uint64_t idlepower:3; + uint64_t sequence:3; + uint64_t sil_mode:1; + uint64_t dcc_enable:1; + uint64_t reserved_2_7:6; + uint64_t data_layout:2; +#else + uint64_t data_layout:2; + uint64_t reserved_2_7:6; + uint64_t dcc_enable:1; + uint64_t sil_mode:1; + uint64_t sequence:3; + uint64_t idlepower:3; + uint64_t forcewrite:4; + uint64_t ecc_adr:1; + uint64_t reserved_21_63:43; +#endif + } s; + struct cvmx_lmcx_ctl1_cn30xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_2_63:62; + uint64_t data_layout:2; +#else + uint64_t data_layout:2; + uint64_t reserved_2_63:62; +#endif + } cn30xx; + struct cvmx_lmcx_ctl1_cn50xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_10_63:54; + uint64_t sil_mode:1; + uint64_t dcc_enable:1; + uint64_t reserved_2_7:6; + uint64_t data_layout:2; +#else + uint64_t data_layout:2; + uint64_t reserved_2_7:6; + uint64_t dcc_enable:1; + uint64_t sil_mode:1; + uint64_t reserved_10_63:54; +#endif + } cn50xx; + struct cvmx_lmcx_ctl1_cn52xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_21_63:43; + uint64_t ecc_adr:1; + uint64_t forcewrite:4; + uint64_t idlepower:3; + uint64_t sequence:3; + uint64_t sil_mode:1; + uint64_t dcc_enable:1; + uint64_t reserved_0_7:8; +#else + uint64_t reserved_0_7:8; + uint64_t dcc_enable:1; + uint64_t sil_mode:1; + uint64_t sequence:3; + uint64_t idlepower:3; + uint64_t forcewrite:4; + uint64_t ecc_adr:1; + uint64_t reserved_21_63:43; +#endif + } cn52xx; + struct cvmx_lmcx_ctl1_cn52xx cn52xxp1; + struct cvmx_lmcx_ctl1_cn52xx cn56xx; + struct cvmx_lmcx_ctl1_cn52xx cn56xxp1; + struct cvmx_lmcx_ctl1_cn58xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_10_63:54; + uint64_t sil_mode:1; + uint64_t dcc_enable:1; + uint64_t reserved_0_7:8; +#else + uint64_t reserved_0_7:8; + uint64_t dcc_enable:1; + uint64_t sil_mode:1; + uint64_t reserved_10_63:54; +#endif + } cn58xx; + struct cvmx_lmcx_ctl1_cn58xx cn58xxp1; +}; + +union cvmx_lmcx_dclk_cnt { + uint64_t u64; + struct cvmx_lmcx_dclk_cnt_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t dclkcnt:64; +#else + uint64_t dclkcnt:64; +#endif + } s; + struct cvmx_lmcx_dclk_cnt_s cn61xx; + struct cvmx_lmcx_dclk_cnt_s cn63xx; + struct cvmx_lmcx_dclk_cnt_s cn63xxp1; + struct cvmx_lmcx_dclk_cnt_s cn66xx; + struct cvmx_lmcx_dclk_cnt_s cn68xx; + struct cvmx_lmcx_dclk_cnt_s cn68xxp1; + struct cvmx_lmcx_dclk_cnt_s cnf71xx; +}; + +union cvmx_lmcx_dclk_cnt_hi { + uint64_t u64; + struct cvmx_lmcx_dclk_cnt_hi_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t dclkcnt_hi:32; +#else + uint64_t dclkcnt_hi:32; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_dclk_cnt_hi_s cn30xx; + struct cvmx_lmcx_dclk_cnt_hi_s cn31xx; + struct cvmx_lmcx_dclk_cnt_hi_s cn38xx; + struct cvmx_lmcx_dclk_cnt_hi_s cn38xxp2; + struct cvmx_lmcx_dclk_cnt_hi_s cn50xx; + struct cvmx_lmcx_dclk_cnt_hi_s cn52xx; + struct cvmx_lmcx_dclk_cnt_hi_s cn52xxp1; + struct cvmx_lmcx_dclk_cnt_hi_s cn56xx; + struct cvmx_lmcx_dclk_cnt_hi_s cn56xxp1; + struct cvmx_lmcx_dclk_cnt_hi_s cn58xx; + struct cvmx_lmcx_dclk_cnt_hi_s cn58xxp1; +}; + +union cvmx_lmcx_dclk_cnt_lo { + uint64_t u64; + struct cvmx_lmcx_dclk_cnt_lo_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t dclkcnt_lo:32; +#else + uint64_t dclkcnt_lo:32; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_dclk_cnt_lo_s cn30xx; + struct cvmx_lmcx_dclk_cnt_lo_s cn31xx; + struct cvmx_lmcx_dclk_cnt_lo_s cn38xx; + struct cvmx_lmcx_dclk_cnt_lo_s cn38xxp2; + struct cvmx_lmcx_dclk_cnt_lo_s cn50xx; + struct cvmx_lmcx_dclk_cnt_lo_s cn52xx; + struct cvmx_lmcx_dclk_cnt_lo_s cn52xxp1; + struct cvmx_lmcx_dclk_cnt_lo_s cn56xx; + struct cvmx_lmcx_dclk_cnt_lo_s cn56xxp1; + struct cvmx_lmcx_dclk_cnt_lo_s cn58xx; + struct cvmx_lmcx_dclk_cnt_lo_s cn58xxp1; +}; + +union cvmx_lmcx_dclk_ctl { + uint64_t u64; + struct cvmx_lmcx_dclk_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_8_63:56; + uint64_t off90_ena:1; + uint64_t dclk90_byp:1; + uint64_t dclk90_ld:1; + uint64_t dclk90_vlu:5; +#else + uint64_t dclk90_vlu:5; + uint64_t dclk90_ld:1; + uint64_t dclk90_byp:1; + uint64_t off90_ena:1; + uint64_t reserved_8_63:56; +#endif + } s; + struct cvmx_lmcx_dclk_ctl_s cn56xx; + struct cvmx_lmcx_dclk_ctl_s cn56xxp1; +}; + +union cvmx_lmcx_ddr2_ctl { + uint64_t u64; + struct cvmx_lmcx_ddr2_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t bank8:1; + uint64_t burst8:1; + uint64_t addlat:3; + uint64_t pocas:1; + uint64_t bwcnt:1; + uint64_t twr:3; + uint64_t silo_hc:1; + uint64_t ddr_eof:4; + uint64_t tfaw:5; + uint64_t crip_mode:1; + uint64_t ddr2t:1; + uint64_t odt_ena:1; + uint64_t qdll_ena:1; + uint64_t dll90_vlu:5; + uint64_t dll90_byp:1; + uint64_t rdqs:1; + uint64_t ddr2:1; +#else + uint64_t ddr2:1; + uint64_t rdqs:1; + uint64_t dll90_byp:1; + uint64_t dll90_vlu:5; + uint64_t qdll_ena:1; + uint64_t odt_ena:1; + uint64_t ddr2t:1; + uint64_t crip_mode:1; + uint64_t tfaw:5; + uint64_t ddr_eof:4; + uint64_t silo_hc:1; + uint64_t twr:3; + uint64_t bwcnt:1; + uint64_t pocas:1; + uint64_t addlat:3; + uint64_t burst8:1; + uint64_t bank8:1; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_ddr2_ctl_cn30xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t bank8:1; + uint64_t burst8:1; + uint64_t addlat:3; + uint64_t pocas:1; + uint64_t bwcnt:1; + uint64_t twr:3; + uint64_t silo_hc:1; + uint64_t ddr_eof:4; + uint64_t tfaw:5; + uint64_t crip_mode:1; + uint64_t ddr2t:1; + uint64_t odt_ena:1; + uint64_t qdll_ena:1; + uint64_t dll90_vlu:5; + uint64_t dll90_byp:1; + uint64_t reserved_1_1:1; + uint64_t ddr2:1; +#else + uint64_t ddr2:1; + uint64_t reserved_1_1:1; + uint64_t dll90_byp:1; + uint64_t dll90_vlu:5; + uint64_t qdll_ena:1; + uint64_t odt_ena:1; + uint64_t ddr2t:1; + uint64_t crip_mode:1; + uint64_t tfaw:5; + uint64_t ddr_eof:4; + uint64_t silo_hc:1; + uint64_t twr:3; + uint64_t bwcnt:1; + uint64_t pocas:1; + uint64_t addlat:3; + uint64_t burst8:1; + uint64_t bank8:1; + uint64_t reserved_32_63:32; +#endif + } cn30xx; + struct cvmx_lmcx_ddr2_ctl_cn30xx cn31xx; + struct cvmx_lmcx_ddr2_ctl_s cn38xx; + struct cvmx_lmcx_ddr2_ctl_s cn38xxp2; + struct cvmx_lmcx_ddr2_ctl_s cn50xx; + struct cvmx_lmcx_ddr2_ctl_s cn52xx; + struct cvmx_lmcx_ddr2_ctl_s cn52xxp1; + struct cvmx_lmcx_ddr2_ctl_s cn56xx; + struct cvmx_lmcx_ddr2_ctl_s cn56xxp1; + struct cvmx_lmcx_ddr2_ctl_s cn58xx; + struct cvmx_lmcx_ddr2_ctl_s cn58xxp1; +}; + +union cvmx_lmcx_ddr_pll_ctl { + uint64_t u64; + struct cvmx_lmcx_ddr_pll_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_27_63:37; + uint64_t jtg_test_mode:1; + uint64_t dfm_div_reset:1; + uint64_t dfm_ps_en:3; + uint64_t ddr_div_reset:1; + uint64_t ddr_ps_en:3; + uint64_t diffamp:4; + uint64_t cps:3; + uint64_t cpb:3; + uint64_t reset_n:1; + uint64_t clkf:7; +#else + uint64_t clkf:7; + uint64_t reset_n:1; + uint64_t cpb:3; + uint64_t cps:3; + uint64_t diffamp:4; + uint64_t ddr_ps_en:3; + uint64_t ddr_div_reset:1; + uint64_t dfm_ps_en:3; + uint64_t dfm_div_reset:1; + uint64_t jtg_test_mode:1; + uint64_t reserved_27_63:37; +#endif + } s; + struct cvmx_lmcx_ddr_pll_ctl_s cn61xx; + struct cvmx_lmcx_ddr_pll_ctl_s cn63xx; + struct cvmx_lmcx_ddr_pll_ctl_s cn63xxp1; + struct cvmx_lmcx_ddr_pll_ctl_s cn66xx; + struct cvmx_lmcx_ddr_pll_ctl_s cn68xx; + struct cvmx_lmcx_ddr_pll_ctl_s cn68xxp1; + struct cvmx_lmcx_ddr_pll_ctl_s cnf71xx; +}; + +union cvmx_lmcx_delay_cfg { + uint64_t u64; + struct cvmx_lmcx_delay_cfg_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_15_63:49; + uint64_t dq:5; + uint64_t cmd:5; + uint64_t clk:5; +#else + uint64_t clk:5; + uint64_t cmd:5; + uint64_t dq:5; + uint64_t reserved_15_63:49; +#endif + } s; + struct cvmx_lmcx_delay_cfg_s cn30xx; + struct cvmx_lmcx_delay_cfg_cn38xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_14_63:50; + uint64_t dq:4; + uint64_t reserved_9_9:1; + uint64_t cmd:4; + uint64_t reserved_4_4:1; + uint64_t clk:4; +#else + uint64_t clk:4; + uint64_t reserved_4_4:1; + uint64_t cmd:4; + uint64_t reserved_9_9:1; + uint64_t dq:4; + uint64_t reserved_14_63:50; +#endif + } cn38xx; + struct cvmx_lmcx_delay_cfg_cn38xx cn50xx; + struct cvmx_lmcx_delay_cfg_cn38xx cn52xx; + struct cvmx_lmcx_delay_cfg_cn38xx cn52xxp1; + struct cvmx_lmcx_delay_cfg_cn38xx cn56xx; + struct cvmx_lmcx_delay_cfg_cn38xx cn56xxp1; + struct cvmx_lmcx_delay_cfg_cn38xx cn58xx; + struct cvmx_lmcx_delay_cfg_cn38xx cn58xxp1; +}; + +union cvmx_lmcx_dimmx_params { + uint64_t u64; + struct cvmx_lmcx_dimmx_params_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t rc15:4; + uint64_t rc14:4; + uint64_t rc13:4; + uint64_t rc12:4; + uint64_t rc11:4; + uint64_t rc10:4; + uint64_t rc9:4; + uint64_t rc8:4; + uint64_t rc7:4; + uint64_t rc6:4; + uint64_t rc5:4; + uint64_t rc4:4; + uint64_t rc3:4; + uint64_t rc2:4; + uint64_t rc1:4; + uint64_t rc0:4; +#else + uint64_t rc0:4; + uint64_t rc1:4; + uint64_t rc2:4; + uint64_t rc3:4; + uint64_t rc4:4; + uint64_t rc5:4; + uint64_t rc6:4; + uint64_t rc7:4; + uint64_t rc8:4; + uint64_t rc9:4; + uint64_t rc10:4; + uint64_t rc11:4; + uint64_t rc12:4; + uint64_t rc13:4; + uint64_t rc14:4; + uint64_t rc15:4; +#endif + } s; + struct cvmx_lmcx_dimmx_params_s cn61xx; + struct cvmx_lmcx_dimmx_params_s cn63xx; + struct cvmx_lmcx_dimmx_params_s cn63xxp1; + struct cvmx_lmcx_dimmx_params_s cn66xx; + struct cvmx_lmcx_dimmx_params_s cn68xx; + struct cvmx_lmcx_dimmx_params_s cn68xxp1; + struct cvmx_lmcx_dimmx_params_s cnf71xx; +}; + +union cvmx_lmcx_dimm_ctl { + uint64_t u64; + struct cvmx_lmcx_dimm_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_46_63:18; + uint64_t parity:1; + uint64_t tcws:13; + uint64_t dimm1_wmask:16; + uint64_t dimm0_wmask:16; +#else + uint64_t dimm0_wmask:16; + uint64_t dimm1_wmask:16; + uint64_t tcws:13; + uint64_t parity:1; + uint64_t reserved_46_63:18; +#endif + } s; + struct cvmx_lmcx_dimm_ctl_s cn61xx; + struct cvmx_lmcx_dimm_ctl_s cn63xx; + struct cvmx_lmcx_dimm_ctl_s cn63xxp1; + struct cvmx_lmcx_dimm_ctl_s cn66xx; + struct cvmx_lmcx_dimm_ctl_s cn68xx; + struct cvmx_lmcx_dimm_ctl_s cn68xxp1; + struct cvmx_lmcx_dimm_ctl_s cnf71xx; +}; + +union cvmx_lmcx_dll_ctl { + uint64_t u64; + struct cvmx_lmcx_dll_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_8_63:56; + uint64_t dreset:1; + uint64_t dll90_byp:1; + uint64_t dll90_ena:1; + uint64_t dll90_vlu:5; +#else + uint64_t dll90_vlu:5; + uint64_t dll90_ena:1; + uint64_t dll90_byp:1; + uint64_t dreset:1; + uint64_t reserved_8_63:56; +#endif + } s; + struct cvmx_lmcx_dll_ctl_s cn52xx; + struct cvmx_lmcx_dll_ctl_s cn52xxp1; + struct cvmx_lmcx_dll_ctl_s cn56xx; + struct cvmx_lmcx_dll_ctl_s cn56xxp1; +}; + +union cvmx_lmcx_dll_ctl2 { + uint64_t u64; + struct cvmx_lmcx_dll_ctl2_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_16_63:48; + uint64_t intf_en:1; + uint64_t dll_bringup:1; + uint64_t dreset:1; + uint64_t quad_dll_ena:1; + uint64_t byp_sel:4; + uint64_t byp_setting:8; +#else + uint64_t byp_setting:8; + uint64_t byp_sel:4; + uint64_t quad_dll_ena:1; + uint64_t dreset:1; + uint64_t dll_bringup:1; + uint64_t intf_en:1; + uint64_t reserved_16_63:48; +#endif + } s; + struct cvmx_lmcx_dll_ctl2_s cn61xx; + struct cvmx_lmcx_dll_ctl2_cn63xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_15_63:49; + uint64_t dll_bringup:1; + uint64_t dreset:1; + uint64_t quad_dll_ena:1; + uint64_t byp_sel:4; + uint64_t byp_setting:8; +#else + uint64_t byp_setting:8; + uint64_t byp_sel:4; + uint64_t quad_dll_ena:1; + uint64_t dreset:1; + uint64_t dll_bringup:1; + uint64_t reserved_15_63:49; +#endif + } cn63xx; + struct cvmx_lmcx_dll_ctl2_cn63xx cn63xxp1; + struct cvmx_lmcx_dll_ctl2_cn63xx cn66xx; + struct cvmx_lmcx_dll_ctl2_s cn68xx; + struct cvmx_lmcx_dll_ctl2_s cn68xxp1; + struct cvmx_lmcx_dll_ctl2_s cnf71xx; +}; + +union cvmx_lmcx_dll_ctl3 { + uint64_t u64; + struct cvmx_lmcx_dll_ctl3_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_41_63:23; + uint64_t dclk90_fwd:1; + uint64_t ddr_90_dly_byp:1; + uint64_t dclk90_recal_dis:1; + uint64_t dclk90_byp_sel:1; + uint64_t dclk90_byp_setting:8; + uint64_t dll_fast:1; + uint64_t dll90_setting:8; + uint64_t fine_tune_mode:1; + uint64_t dll_mode:1; + uint64_t dll90_byte_sel:4; + uint64_t offset_ena:1; + uint64_t load_offset:1; + uint64_t mode_sel:2; + uint64_t byte_sel:4; + uint64_t offset:6; +#else + uint64_t offset:6; + uint64_t byte_sel:4; + uint64_t mode_sel:2; + uint64_t load_offset:1; + uint64_t offset_ena:1; + uint64_t dll90_byte_sel:4; + uint64_t dll_mode:1; + uint64_t fine_tune_mode:1; + uint64_t dll90_setting:8; + uint64_t dll_fast:1; + uint64_t dclk90_byp_setting:8; + uint64_t dclk90_byp_sel:1; + uint64_t dclk90_recal_dis:1; + uint64_t ddr_90_dly_byp:1; + uint64_t dclk90_fwd:1; + uint64_t reserved_41_63:23; +#endif + } s; + struct cvmx_lmcx_dll_ctl3_s cn61xx; + struct cvmx_lmcx_dll_ctl3_cn63xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_29_63:35; + uint64_t dll_fast:1; + uint64_t dll90_setting:8; + uint64_t fine_tune_mode:1; + uint64_t dll_mode:1; + uint64_t dll90_byte_sel:4; + uint64_t offset_ena:1; + uint64_t load_offset:1; + uint64_t mode_sel:2; + uint64_t byte_sel:4; + uint64_t offset:6; +#else + uint64_t offset:6; + uint64_t byte_sel:4; + uint64_t mode_sel:2; + uint64_t load_offset:1; + uint64_t offset_ena:1; + uint64_t dll90_byte_sel:4; + uint64_t dll_mode:1; + uint64_t fine_tune_mode:1; + uint64_t dll90_setting:8; + uint64_t dll_fast:1; + uint64_t reserved_29_63:35; +#endif + } cn63xx; + struct cvmx_lmcx_dll_ctl3_cn63xx cn63xxp1; + struct cvmx_lmcx_dll_ctl3_cn63xx cn66xx; + struct cvmx_lmcx_dll_ctl3_s cn68xx; + struct cvmx_lmcx_dll_ctl3_s cn68xxp1; + struct cvmx_lmcx_dll_ctl3_s cnf71xx; +}; + +union cvmx_lmcx_dual_memcfg { + uint64_t u64; + struct cvmx_lmcx_dual_memcfg_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_20_63:44; + uint64_t bank8:1; + uint64_t row_lsb:3; + uint64_t reserved_8_15:8; + uint64_t cs_mask:8; +#else + uint64_t cs_mask:8; + uint64_t reserved_8_15:8; + uint64_t row_lsb:3; + uint64_t bank8:1; + uint64_t reserved_20_63:44; +#endif + } s; + struct cvmx_lmcx_dual_memcfg_s cn50xx; + struct cvmx_lmcx_dual_memcfg_s cn52xx; + struct cvmx_lmcx_dual_memcfg_s cn52xxp1; + struct cvmx_lmcx_dual_memcfg_s cn56xx; + struct cvmx_lmcx_dual_memcfg_s cn56xxp1; + struct cvmx_lmcx_dual_memcfg_s cn58xx; + struct cvmx_lmcx_dual_memcfg_s cn58xxp1; + struct cvmx_lmcx_dual_memcfg_cn61xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_19_63:45; + uint64_t row_lsb:3; + uint64_t reserved_8_15:8; + uint64_t cs_mask:8; +#else + uint64_t cs_mask:8; + uint64_t reserved_8_15:8; + uint64_t row_lsb:3; + uint64_t reserved_19_63:45; +#endif + } cn61xx; + struct cvmx_lmcx_dual_memcfg_cn61xx cn63xx; + struct cvmx_lmcx_dual_memcfg_cn61xx cn63xxp1; + struct cvmx_lmcx_dual_memcfg_cn61xx cn66xx; + struct cvmx_lmcx_dual_memcfg_cn61xx cn68xx; + struct cvmx_lmcx_dual_memcfg_cn61xx cn68xxp1; + struct cvmx_lmcx_dual_memcfg_cn61xx cnf71xx; +}; + +union cvmx_lmcx_ecc_synd { + uint64_t u64; + struct cvmx_lmcx_ecc_synd_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t mrdsyn3:8; + uint64_t mrdsyn2:8; + uint64_t mrdsyn1:8; + uint64_t mrdsyn0:8; +#else + uint64_t mrdsyn0:8; + uint64_t mrdsyn1:8; + uint64_t mrdsyn2:8; + uint64_t mrdsyn3:8; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_ecc_synd_s cn30xx; + struct cvmx_lmcx_ecc_synd_s cn31xx; + struct cvmx_lmcx_ecc_synd_s cn38xx; + struct cvmx_lmcx_ecc_synd_s cn38xxp2; + struct cvmx_lmcx_ecc_synd_s cn50xx; + struct cvmx_lmcx_ecc_synd_s cn52xx; + struct cvmx_lmcx_ecc_synd_s cn52xxp1; + struct cvmx_lmcx_ecc_synd_s cn56xx; + struct cvmx_lmcx_ecc_synd_s cn56xxp1; + struct cvmx_lmcx_ecc_synd_s cn58xx; + struct cvmx_lmcx_ecc_synd_s cn58xxp1; + struct cvmx_lmcx_ecc_synd_s cn61xx; + struct cvmx_lmcx_ecc_synd_s cn63xx; + struct cvmx_lmcx_ecc_synd_s cn63xxp1; + struct cvmx_lmcx_ecc_synd_s cn66xx; + struct cvmx_lmcx_ecc_synd_s cn68xx; + struct cvmx_lmcx_ecc_synd_s cn68xxp1; + struct cvmx_lmcx_ecc_synd_s cnf71xx; +}; + +union cvmx_lmcx_fadr { + uint64_t u64; + struct cvmx_lmcx_fadr_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_0_63:64; +#else + uint64_t reserved_0_63:64; +#endif + } s; + struct cvmx_lmcx_fadr_cn30xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t fdimm:2; + uint64_t fbunk:1; + uint64_t fbank:3; + uint64_t frow:14; + uint64_t fcol:12; +#else + uint64_t fcol:12; + uint64_t frow:14; + uint64_t fbank:3; + uint64_t fbunk:1; + uint64_t fdimm:2; + uint64_t reserved_32_63:32; +#endif + } cn30xx; + struct cvmx_lmcx_fadr_cn30xx cn31xx; + struct cvmx_lmcx_fadr_cn30xx cn38xx; + struct cvmx_lmcx_fadr_cn30xx cn38xxp2; + struct cvmx_lmcx_fadr_cn30xx cn50xx; + struct cvmx_lmcx_fadr_cn30xx cn52xx; + struct cvmx_lmcx_fadr_cn30xx cn52xxp1; + struct cvmx_lmcx_fadr_cn30xx cn56xx; + struct cvmx_lmcx_fadr_cn30xx cn56xxp1; + struct cvmx_lmcx_fadr_cn30xx cn58xx; + struct cvmx_lmcx_fadr_cn30xx cn58xxp1; + struct cvmx_lmcx_fadr_cn61xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_36_63:28; + uint64_t fdimm:2; + uint64_t fbunk:1; + uint64_t fbank:3; + uint64_t frow:16; + uint64_t fcol:14; +#else + uint64_t fcol:14; + uint64_t frow:16; + uint64_t fbank:3; + uint64_t fbunk:1; + uint64_t fdimm:2; + uint64_t reserved_36_63:28; +#endif + } cn61xx; + struct cvmx_lmcx_fadr_cn61xx cn63xx; + struct cvmx_lmcx_fadr_cn61xx cn63xxp1; + struct cvmx_lmcx_fadr_cn61xx cn66xx; + struct cvmx_lmcx_fadr_cn61xx cn68xx; + struct cvmx_lmcx_fadr_cn61xx cn68xxp1; + struct cvmx_lmcx_fadr_cn61xx cnf71xx; +}; + +union cvmx_lmcx_ifb_cnt { + uint64_t u64; + struct cvmx_lmcx_ifb_cnt_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t ifbcnt:64; +#else + uint64_t ifbcnt:64; +#endif + } s; + struct cvmx_lmcx_ifb_cnt_s cn61xx; + struct cvmx_lmcx_ifb_cnt_s cn63xx; + struct cvmx_lmcx_ifb_cnt_s cn63xxp1; + struct cvmx_lmcx_ifb_cnt_s cn66xx; + struct cvmx_lmcx_ifb_cnt_s cn68xx; + struct cvmx_lmcx_ifb_cnt_s cn68xxp1; + struct cvmx_lmcx_ifb_cnt_s cnf71xx; +}; + +union cvmx_lmcx_ifb_cnt_hi { + uint64_t u64; + struct cvmx_lmcx_ifb_cnt_hi_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t ifbcnt_hi:32; +#else + uint64_t ifbcnt_hi:32; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_ifb_cnt_hi_s cn30xx; + struct cvmx_lmcx_ifb_cnt_hi_s cn31xx; + struct cvmx_lmcx_ifb_cnt_hi_s cn38xx; + struct cvmx_lmcx_ifb_cnt_hi_s cn38xxp2; + struct cvmx_lmcx_ifb_cnt_hi_s cn50xx; + struct cvmx_lmcx_ifb_cnt_hi_s cn52xx; + struct cvmx_lmcx_ifb_cnt_hi_s cn52xxp1; + struct cvmx_lmcx_ifb_cnt_hi_s cn56xx; + struct cvmx_lmcx_ifb_cnt_hi_s cn56xxp1; + struct cvmx_lmcx_ifb_cnt_hi_s cn58xx; + struct cvmx_lmcx_ifb_cnt_hi_s cn58xxp1; +}; + +union cvmx_lmcx_ifb_cnt_lo { + uint64_t u64; + struct cvmx_lmcx_ifb_cnt_lo_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t ifbcnt_lo:32; +#else + uint64_t ifbcnt_lo:32; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_ifb_cnt_lo_s cn30xx; + struct cvmx_lmcx_ifb_cnt_lo_s cn31xx; + struct cvmx_lmcx_ifb_cnt_lo_s cn38xx; + struct cvmx_lmcx_ifb_cnt_lo_s cn38xxp2; + struct cvmx_lmcx_ifb_cnt_lo_s cn50xx; + struct cvmx_lmcx_ifb_cnt_lo_s cn52xx; + struct cvmx_lmcx_ifb_cnt_lo_s cn52xxp1; + struct cvmx_lmcx_ifb_cnt_lo_s cn56xx; + struct cvmx_lmcx_ifb_cnt_lo_s cn56xxp1; + struct cvmx_lmcx_ifb_cnt_lo_s cn58xx; + struct cvmx_lmcx_ifb_cnt_lo_s cn58xxp1; +}; + +union cvmx_lmcx_int { + uint64_t u64; + struct cvmx_lmcx_int_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_9_63:55; + uint64_t ded_err:4; + uint64_t sec_err:4; + uint64_t nxm_wr_err:1; +#else + uint64_t nxm_wr_err:1; + uint64_t sec_err:4; + uint64_t ded_err:4; + uint64_t reserved_9_63:55; +#endif + } s; + struct cvmx_lmcx_int_s cn61xx; + struct cvmx_lmcx_int_s cn63xx; + struct cvmx_lmcx_int_s cn63xxp1; + struct cvmx_lmcx_int_s cn66xx; + struct cvmx_lmcx_int_s cn68xx; + struct cvmx_lmcx_int_s cn68xxp1; + struct cvmx_lmcx_int_s cnf71xx; +}; + +union cvmx_lmcx_int_en { + uint64_t u64; + struct cvmx_lmcx_int_en_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_3_63:61; + uint64_t intr_ded_ena:1; + uint64_t intr_sec_ena:1; + uint64_t intr_nxm_wr_ena:1; +#else + uint64_t intr_nxm_wr_ena:1; + uint64_t intr_sec_ena:1; + uint64_t intr_ded_ena:1; + uint64_t reserved_3_63:61; +#endif + } s; + struct cvmx_lmcx_int_en_s cn61xx; + struct cvmx_lmcx_int_en_s cn63xx; + struct cvmx_lmcx_int_en_s cn63xxp1; + struct cvmx_lmcx_int_en_s cn66xx; + struct cvmx_lmcx_int_en_s cn68xx; + struct cvmx_lmcx_int_en_s cn68xxp1; + struct cvmx_lmcx_int_en_s cnf71xx; +}; + +union cvmx_lmcx_mem_cfg0 { + uint64_t u64; + struct cvmx_lmcx_mem_cfg0_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t reset:1; + uint64_t silo_qc:1; + uint64_t bunk_ena:1; + uint64_t ded_err:4; + uint64_t sec_err:4; + uint64_t intr_ded_ena:1; + uint64_t intr_sec_ena:1; + uint64_t tcl:4; + uint64_t ref_int:6; + uint64_t pbank_lsb:4; + uint64_t row_lsb:3; + uint64_t ecc_ena:1; + uint64_t init_start:1; +#else + uint64_t init_start:1; + uint64_t ecc_ena:1; + uint64_t row_lsb:3; + uint64_t pbank_lsb:4; + uint64_t ref_int:6; + uint64_t tcl:4; + uint64_t intr_sec_ena:1; + uint64_t intr_ded_ena:1; + uint64_t sec_err:4; + uint64_t ded_err:4; + uint64_t bunk_ena:1; + uint64_t silo_qc:1; + uint64_t reset:1; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_mem_cfg0_s cn30xx; + struct cvmx_lmcx_mem_cfg0_s cn31xx; + struct cvmx_lmcx_mem_cfg0_s cn38xx; + struct cvmx_lmcx_mem_cfg0_s cn38xxp2; + struct cvmx_lmcx_mem_cfg0_s cn50xx; + struct cvmx_lmcx_mem_cfg0_s cn52xx; + struct cvmx_lmcx_mem_cfg0_s cn52xxp1; + struct cvmx_lmcx_mem_cfg0_s cn56xx; + struct cvmx_lmcx_mem_cfg0_s cn56xxp1; + struct cvmx_lmcx_mem_cfg0_s cn58xx; + struct cvmx_lmcx_mem_cfg0_s cn58xxp1; +}; + +union cvmx_lmcx_mem_cfg1 { + uint64_t u64; + struct cvmx_lmcx_mem_cfg1_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t comp_bypass:1; + uint64_t trrd:3; + uint64_t caslat:3; + uint64_t tmrd:3; + uint64_t trfc:5; + uint64_t trp:4; + uint64_t twtr:4; + uint64_t trcd:4; + uint64_t tras:5; +#else + uint64_t tras:5; + uint64_t trcd:4; + uint64_t twtr:4; + uint64_t trp:4; + uint64_t trfc:5; + uint64_t tmrd:3; + uint64_t caslat:3; + uint64_t trrd:3; + uint64_t comp_bypass:1; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_mem_cfg1_s cn30xx; + struct cvmx_lmcx_mem_cfg1_s cn31xx; + struct cvmx_lmcx_mem_cfg1_cn38xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_31_63:33; + uint64_t trrd:3; + uint64_t caslat:3; + uint64_t tmrd:3; + uint64_t trfc:5; + uint64_t trp:4; + uint64_t twtr:4; + uint64_t trcd:4; + uint64_t tras:5; +#else + uint64_t tras:5; + uint64_t trcd:4; + uint64_t twtr:4; + uint64_t trp:4; + uint64_t trfc:5; + uint64_t tmrd:3; + uint64_t caslat:3; + uint64_t trrd:3; + uint64_t reserved_31_63:33; +#endif + } cn38xx; + struct cvmx_lmcx_mem_cfg1_cn38xx cn38xxp2; + struct cvmx_lmcx_mem_cfg1_s cn50xx; + struct cvmx_lmcx_mem_cfg1_cn38xx cn52xx; + struct cvmx_lmcx_mem_cfg1_cn38xx cn52xxp1; + struct cvmx_lmcx_mem_cfg1_cn38xx cn56xx; + struct cvmx_lmcx_mem_cfg1_cn38xx cn56xxp1; + struct cvmx_lmcx_mem_cfg1_cn38xx cn58xx; + struct cvmx_lmcx_mem_cfg1_cn38xx cn58xxp1; +}; + +union cvmx_lmcx_modereg_params0 { + uint64_t u64; + struct cvmx_lmcx_modereg_params0_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_25_63:39; + uint64_t ppd:1; + uint64_t wrp:3; + uint64_t dllr:1; + uint64_t tm:1; + uint64_t rbt:1; + uint64_t cl:4; + uint64_t bl:2; + uint64_t qoff:1; + uint64_t tdqs:1; + uint64_t wlev:1; + uint64_t al:2; + uint64_t dll:1; + uint64_t mpr:1; + uint64_t mprloc:2; + uint64_t cwl:3; +#else + uint64_t cwl:3; + uint64_t mprloc:2; + uint64_t mpr:1; + uint64_t dll:1; + uint64_t al:2; + uint64_t wlev:1; + uint64_t tdqs:1; + uint64_t qoff:1; + uint64_t bl:2; + uint64_t cl:4; + uint64_t rbt:1; + uint64_t tm:1; + uint64_t dllr:1; + uint64_t wrp:3; + uint64_t ppd:1; + uint64_t reserved_25_63:39; +#endif + } s; + struct cvmx_lmcx_modereg_params0_s cn61xx; + struct cvmx_lmcx_modereg_params0_s cn63xx; + struct cvmx_lmcx_modereg_params0_s cn63xxp1; + struct cvmx_lmcx_modereg_params0_s cn66xx; + struct cvmx_lmcx_modereg_params0_s cn68xx; + struct cvmx_lmcx_modereg_params0_s cn68xxp1; + struct cvmx_lmcx_modereg_params0_s cnf71xx; +}; + +union cvmx_lmcx_modereg_params1 { + uint64_t u64; + struct cvmx_lmcx_modereg_params1_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_48_63:16; + uint64_t rtt_nom_11:3; + uint64_t dic_11:2; + uint64_t rtt_wr_11:2; + uint64_t srt_11:1; + uint64_t asr_11:1; + uint64_t pasr_11:3; + uint64_t rtt_nom_10:3; + uint64_t dic_10:2; + uint64_t rtt_wr_10:2; + uint64_t srt_10:1; + uint64_t asr_10:1; + uint64_t pasr_10:3; + uint64_t rtt_nom_01:3; + uint64_t dic_01:2; + uint64_t rtt_wr_01:2; + uint64_t srt_01:1; + uint64_t asr_01:1; + uint64_t pasr_01:3; + uint64_t rtt_nom_00:3; + uint64_t dic_00:2; + uint64_t rtt_wr_00:2; + uint64_t srt_00:1; + uint64_t asr_00:1; + uint64_t pasr_00:3; +#else + uint64_t pasr_00:3; + uint64_t asr_00:1; + uint64_t srt_00:1; + uint64_t rtt_wr_00:2; + uint64_t dic_00:2; + uint64_t rtt_nom_00:3; + uint64_t pasr_01:3; + uint64_t asr_01:1; + uint64_t srt_01:1; + uint64_t rtt_wr_01:2; + uint64_t dic_01:2; + uint64_t rtt_nom_01:3; + uint64_t pasr_10:3; + uint64_t asr_10:1; + uint64_t srt_10:1; + uint64_t rtt_wr_10:2; + uint64_t dic_10:2; + uint64_t rtt_nom_10:3; + uint64_t pasr_11:3; + uint64_t asr_11:1; + uint64_t srt_11:1; + uint64_t rtt_wr_11:2; + uint64_t dic_11:2; + uint64_t rtt_nom_11:3; + uint64_t reserved_48_63:16; +#endif + } s; + struct cvmx_lmcx_modereg_params1_s cn61xx; + struct cvmx_lmcx_modereg_params1_s cn63xx; + struct cvmx_lmcx_modereg_params1_s cn63xxp1; + struct cvmx_lmcx_modereg_params1_s cn66xx; + struct cvmx_lmcx_modereg_params1_s cn68xx; + struct cvmx_lmcx_modereg_params1_s cn68xxp1; + struct cvmx_lmcx_modereg_params1_s cnf71xx; +}; + +union cvmx_lmcx_nxm { + uint64_t u64; + struct cvmx_lmcx_nxm_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_40_63:24; + uint64_t mem_msb_d3_r1:4; + uint64_t mem_msb_d3_r0:4; + uint64_t mem_msb_d2_r1:4; + uint64_t mem_msb_d2_r0:4; + uint64_t mem_msb_d1_r1:4; + uint64_t mem_msb_d1_r0:4; + uint64_t mem_msb_d0_r1:4; + uint64_t mem_msb_d0_r0:4; + uint64_t cs_mask:8; +#else + uint64_t cs_mask:8; + uint64_t mem_msb_d0_r0:4; + uint64_t mem_msb_d0_r1:4; + uint64_t mem_msb_d1_r0:4; + uint64_t mem_msb_d1_r1:4; + uint64_t mem_msb_d2_r0:4; + uint64_t mem_msb_d2_r1:4; + uint64_t mem_msb_d3_r0:4; + uint64_t mem_msb_d3_r1:4; + uint64_t reserved_40_63:24; +#endif + } s; + struct cvmx_lmcx_nxm_cn52xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_8_63:56; + uint64_t cs_mask:8; +#else + uint64_t cs_mask:8; + uint64_t reserved_8_63:56; +#endif + } cn52xx; + struct cvmx_lmcx_nxm_cn52xx cn56xx; + struct cvmx_lmcx_nxm_cn52xx cn58xx; + struct cvmx_lmcx_nxm_s cn61xx; + struct cvmx_lmcx_nxm_s cn63xx; + struct cvmx_lmcx_nxm_s cn63xxp1; + struct cvmx_lmcx_nxm_s cn66xx; + struct cvmx_lmcx_nxm_s cn68xx; + struct cvmx_lmcx_nxm_s cn68xxp1; + struct cvmx_lmcx_nxm_s cnf71xx; +}; + +union cvmx_lmcx_ops_cnt { + uint64_t u64; + struct cvmx_lmcx_ops_cnt_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t opscnt:64; +#else + uint64_t opscnt:64; +#endif + } s; + struct cvmx_lmcx_ops_cnt_s cn61xx; + struct cvmx_lmcx_ops_cnt_s cn63xx; + struct cvmx_lmcx_ops_cnt_s cn63xxp1; + struct cvmx_lmcx_ops_cnt_s cn66xx; + struct cvmx_lmcx_ops_cnt_s cn68xx; + struct cvmx_lmcx_ops_cnt_s cn68xxp1; + struct cvmx_lmcx_ops_cnt_s cnf71xx; +}; + +union cvmx_lmcx_ops_cnt_hi { + uint64_t u64; + struct cvmx_lmcx_ops_cnt_hi_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t opscnt_hi:32; +#else + uint64_t opscnt_hi:32; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_ops_cnt_hi_s cn30xx; + struct cvmx_lmcx_ops_cnt_hi_s cn31xx; + struct cvmx_lmcx_ops_cnt_hi_s cn38xx; + struct cvmx_lmcx_ops_cnt_hi_s cn38xxp2; + struct cvmx_lmcx_ops_cnt_hi_s cn50xx; + struct cvmx_lmcx_ops_cnt_hi_s cn52xx; + struct cvmx_lmcx_ops_cnt_hi_s cn52xxp1; + struct cvmx_lmcx_ops_cnt_hi_s cn56xx; + struct cvmx_lmcx_ops_cnt_hi_s cn56xxp1; + struct cvmx_lmcx_ops_cnt_hi_s cn58xx; + struct cvmx_lmcx_ops_cnt_hi_s cn58xxp1; +}; + +union cvmx_lmcx_ops_cnt_lo { + uint64_t u64; + struct cvmx_lmcx_ops_cnt_lo_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t opscnt_lo:32; +#else + uint64_t opscnt_lo:32; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_ops_cnt_lo_s cn30xx; + struct cvmx_lmcx_ops_cnt_lo_s cn31xx; + struct cvmx_lmcx_ops_cnt_lo_s cn38xx; + struct cvmx_lmcx_ops_cnt_lo_s cn38xxp2; + struct cvmx_lmcx_ops_cnt_lo_s cn50xx; + struct cvmx_lmcx_ops_cnt_lo_s cn52xx; + struct cvmx_lmcx_ops_cnt_lo_s cn52xxp1; + struct cvmx_lmcx_ops_cnt_lo_s cn56xx; + struct cvmx_lmcx_ops_cnt_lo_s cn56xxp1; + struct cvmx_lmcx_ops_cnt_lo_s cn58xx; + struct cvmx_lmcx_ops_cnt_lo_s cn58xxp1; +}; + +union cvmx_lmcx_phy_ctl { + uint64_t u64; + struct cvmx_lmcx_phy_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_15_63:49; + uint64_t rx_always_on:1; + uint64_t lv_mode:1; + uint64_t ck_tune1:1; + uint64_t ck_dlyout1:4; + uint64_t ck_tune0:1; + uint64_t ck_dlyout0:4; + uint64_t loopback:1; + uint64_t loopback_pos:1; + uint64_t ts_stagger:1; +#else + uint64_t ts_stagger:1; + uint64_t loopback_pos:1; + uint64_t loopback:1; + uint64_t ck_dlyout0:4; + uint64_t ck_tune0:1; + uint64_t ck_dlyout1:4; + uint64_t ck_tune1:1; + uint64_t lv_mode:1; + uint64_t rx_always_on:1; + uint64_t reserved_15_63:49; +#endif + } s; + struct cvmx_lmcx_phy_ctl_s cn61xx; + struct cvmx_lmcx_phy_ctl_s cn63xx; + struct cvmx_lmcx_phy_ctl_cn63xxp1 { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_14_63:50; + uint64_t lv_mode:1; + uint64_t ck_tune1:1; + uint64_t ck_dlyout1:4; + uint64_t ck_tune0:1; + uint64_t ck_dlyout0:4; + uint64_t loopback:1; + uint64_t loopback_pos:1; + uint64_t ts_stagger:1; +#else + uint64_t ts_stagger:1; + uint64_t loopback_pos:1; + uint64_t loopback:1; + uint64_t ck_dlyout0:4; + uint64_t ck_tune0:1; + uint64_t ck_dlyout1:4; + uint64_t ck_tune1:1; + uint64_t lv_mode:1; + uint64_t reserved_14_63:50; +#endif + } cn63xxp1; + struct cvmx_lmcx_phy_ctl_s cn66xx; + struct cvmx_lmcx_phy_ctl_s cn68xx; + struct cvmx_lmcx_phy_ctl_s cn68xxp1; + struct cvmx_lmcx_phy_ctl_s cnf71xx; +}; + +union cvmx_lmcx_pll_bwctl { + uint64_t u64; + struct cvmx_lmcx_pll_bwctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_5_63:59; + uint64_t bwupd:1; + uint64_t bwctl:4; +#else + uint64_t bwctl:4; + uint64_t bwupd:1; + uint64_t reserved_5_63:59; +#endif + } s; + struct cvmx_lmcx_pll_bwctl_s cn30xx; + struct cvmx_lmcx_pll_bwctl_s cn31xx; + struct cvmx_lmcx_pll_bwctl_s cn38xx; + struct cvmx_lmcx_pll_bwctl_s cn38xxp2; +}; + +union cvmx_lmcx_pll_ctl { + uint64_t u64; + struct cvmx_lmcx_pll_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_30_63:34; + uint64_t bypass:1; + uint64_t fasten_n:1; + uint64_t div_reset:1; + uint64_t reset_n:1; + uint64_t clkf:12; + uint64_t clkr:6; + uint64_t reserved_6_7:2; + uint64_t en16:1; + uint64_t en12:1; + uint64_t en8:1; + uint64_t en6:1; + uint64_t en4:1; + uint64_t en2:1; +#else + uint64_t en2:1; + uint64_t en4:1; + uint64_t en6:1; + uint64_t en8:1; + uint64_t en12:1; + uint64_t en16:1; + uint64_t reserved_6_7:2; + uint64_t clkr:6; + uint64_t clkf:12; + uint64_t reset_n:1; + uint64_t div_reset:1; + uint64_t fasten_n:1; + uint64_t bypass:1; + uint64_t reserved_30_63:34; +#endif + } s; + struct cvmx_lmcx_pll_ctl_cn50xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_29_63:35; + uint64_t fasten_n:1; + uint64_t div_reset:1; + uint64_t reset_n:1; + uint64_t clkf:12; + uint64_t clkr:6; + uint64_t reserved_6_7:2; + uint64_t en16:1; + uint64_t en12:1; + uint64_t en8:1; + uint64_t en6:1; + uint64_t en4:1; + uint64_t en2:1; +#else + uint64_t en2:1; + uint64_t en4:1; + uint64_t en6:1; + uint64_t en8:1; + uint64_t en12:1; + uint64_t en16:1; + uint64_t reserved_6_7:2; + uint64_t clkr:6; + uint64_t clkf:12; + uint64_t reset_n:1; + uint64_t div_reset:1; + uint64_t fasten_n:1; + uint64_t reserved_29_63:35; +#endif + } cn50xx; + struct cvmx_lmcx_pll_ctl_s cn52xx; + struct cvmx_lmcx_pll_ctl_s cn52xxp1; + struct cvmx_lmcx_pll_ctl_cn50xx cn56xx; + struct cvmx_lmcx_pll_ctl_cn56xxp1 { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_28_63:36; + uint64_t div_reset:1; + uint64_t reset_n:1; + uint64_t clkf:12; + uint64_t clkr:6; + uint64_t reserved_6_7:2; + uint64_t en16:1; + uint64_t en12:1; + uint64_t en8:1; + uint64_t en6:1; + uint64_t en4:1; + uint64_t en2:1; +#else + uint64_t en2:1; + uint64_t en4:1; + uint64_t en6:1; + uint64_t en8:1; + uint64_t en12:1; + uint64_t en16:1; + uint64_t reserved_6_7:2; + uint64_t clkr:6; + uint64_t clkf:12; + uint64_t reset_n:1; + uint64_t div_reset:1; + uint64_t reserved_28_63:36; +#endif + } cn56xxp1; + struct cvmx_lmcx_pll_ctl_cn56xxp1 cn58xx; + struct cvmx_lmcx_pll_ctl_cn56xxp1 cn58xxp1; +}; + +union cvmx_lmcx_pll_status { + uint64_t u64; + struct cvmx_lmcx_pll_status_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t ddr__nctl:5; + uint64_t ddr__pctl:5; + uint64_t reserved_2_21:20; + uint64_t rfslip:1; + uint64_t fbslip:1; +#else + uint64_t fbslip:1; + uint64_t rfslip:1; + uint64_t reserved_2_21:20; + uint64_t ddr__pctl:5; + uint64_t ddr__nctl:5; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_pll_status_s cn50xx; + struct cvmx_lmcx_pll_status_s cn52xx; + struct cvmx_lmcx_pll_status_s cn52xxp1; + struct cvmx_lmcx_pll_status_s cn56xx; + struct cvmx_lmcx_pll_status_s cn56xxp1; + struct cvmx_lmcx_pll_status_s cn58xx; + struct cvmx_lmcx_pll_status_cn58xxp1 { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_2_63:62; + uint64_t rfslip:1; + uint64_t fbslip:1; +#else + uint64_t fbslip:1; + uint64_t rfslip:1; + uint64_t reserved_2_63:62; +#endif + } cn58xxp1; +}; + +union cvmx_lmcx_read_level_ctl { + uint64_t u64; + struct cvmx_lmcx_read_level_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_44_63:20; + uint64_t rankmask:4; + uint64_t pattern:8; + uint64_t row:16; + uint64_t col:12; + uint64_t reserved_3_3:1; + uint64_t bnk:3; +#else + uint64_t bnk:3; + uint64_t reserved_3_3:1; + uint64_t col:12; + uint64_t row:16; + uint64_t pattern:8; + uint64_t rankmask:4; + uint64_t reserved_44_63:20; +#endif + } s; + struct cvmx_lmcx_read_level_ctl_s cn52xx; + struct cvmx_lmcx_read_level_ctl_s cn52xxp1; + struct cvmx_lmcx_read_level_ctl_s cn56xx; + struct cvmx_lmcx_read_level_ctl_s cn56xxp1; +}; + +union cvmx_lmcx_read_level_dbg { + uint64_t u64; + struct cvmx_lmcx_read_level_dbg_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t bitmask:16; + uint64_t reserved_4_15:12; + uint64_t byte:4; +#else + uint64_t byte:4; + uint64_t reserved_4_15:12; + uint64_t bitmask:16; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_read_level_dbg_s cn52xx; + struct cvmx_lmcx_read_level_dbg_s cn52xxp1; + struct cvmx_lmcx_read_level_dbg_s cn56xx; + struct cvmx_lmcx_read_level_dbg_s cn56xxp1; +}; + +union cvmx_lmcx_read_level_rankx { + uint64_t u64; + struct cvmx_lmcx_read_level_rankx_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_38_63:26; + uint64_t status:2; + uint64_t byte8:4; + uint64_t byte7:4; + uint64_t byte6:4; + uint64_t byte5:4; + uint64_t byte4:4; + uint64_t byte3:4; + uint64_t byte2:4; + uint64_t byte1:4; + uint64_t byte0:4; +#else + uint64_t byte0:4; + uint64_t byte1:4; + uint64_t byte2:4; + uint64_t byte3:4; + uint64_t byte4:4; + uint64_t byte5:4; + uint64_t byte6:4; + uint64_t byte7:4; + uint64_t byte8:4; + uint64_t status:2; + uint64_t reserved_38_63:26; +#endif + } s; + struct cvmx_lmcx_read_level_rankx_s cn52xx; + struct cvmx_lmcx_read_level_rankx_s cn52xxp1; + struct cvmx_lmcx_read_level_rankx_s cn56xx; + struct cvmx_lmcx_read_level_rankx_s cn56xxp1; +}; + +union cvmx_lmcx_reset_ctl { + uint64_t u64; + struct cvmx_lmcx_reset_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_4_63:60; + uint64_t ddr3psv:1; + uint64_t ddr3psoft:1; + uint64_t ddr3pwarm:1; + uint64_t ddr3rst:1; +#else + uint64_t ddr3rst:1; + uint64_t ddr3pwarm:1; + uint64_t ddr3psoft:1; + uint64_t ddr3psv:1; + uint64_t reserved_4_63:60; +#endif + } s; + struct cvmx_lmcx_reset_ctl_s cn61xx; + struct cvmx_lmcx_reset_ctl_s cn63xx; + struct cvmx_lmcx_reset_ctl_s cn63xxp1; + struct cvmx_lmcx_reset_ctl_s cn66xx; + struct cvmx_lmcx_reset_ctl_s cn68xx; + struct cvmx_lmcx_reset_ctl_s cn68xxp1; + struct cvmx_lmcx_reset_ctl_s cnf71xx; +}; + +union cvmx_lmcx_rlevel_ctl { + uint64_t u64; + struct cvmx_lmcx_rlevel_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_22_63:42; + uint64_t delay_unload_3:1; + uint64_t delay_unload_2:1; + uint64_t delay_unload_1:1; + uint64_t delay_unload_0:1; + uint64_t bitmask:8; + uint64_t or_dis:1; + uint64_t offset_en:1; + uint64_t offset:4; + uint64_t byte:4; +#else + uint64_t byte:4; + uint64_t offset:4; + uint64_t offset_en:1; + uint64_t or_dis:1; + uint64_t bitmask:8; + uint64_t delay_unload_0:1; + uint64_t delay_unload_1:1; + uint64_t delay_unload_2:1; + uint64_t delay_unload_3:1; + uint64_t reserved_22_63:42; +#endif + } s; + struct cvmx_lmcx_rlevel_ctl_s cn61xx; + struct cvmx_lmcx_rlevel_ctl_s cn63xx; + struct cvmx_lmcx_rlevel_ctl_cn63xxp1 { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_9_63:55; + uint64_t offset_en:1; + uint64_t offset:4; + uint64_t byte:4; +#else + uint64_t byte:4; + uint64_t offset:4; + uint64_t offset_en:1; + uint64_t reserved_9_63:55; +#endif + } cn63xxp1; + struct cvmx_lmcx_rlevel_ctl_s cn66xx; + struct cvmx_lmcx_rlevel_ctl_s cn68xx; + struct cvmx_lmcx_rlevel_ctl_s cn68xxp1; + struct cvmx_lmcx_rlevel_ctl_s cnf71xx; +}; + +union cvmx_lmcx_rlevel_dbg { + uint64_t u64; + struct cvmx_lmcx_rlevel_dbg_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t bitmask:64; +#else + uint64_t bitmask:64; +#endif + } s; + struct cvmx_lmcx_rlevel_dbg_s cn61xx; + struct cvmx_lmcx_rlevel_dbg_s cn63xx; + struct cvmx_lmcx_rlevel_dbg_s cn63xxp1; + struct cvmx_lmcx_rlevel_dbg_s cn66xx; + struct cvmx_lmcx_rlevel_dbg_s cn68xx; + struct cvmx_lmcx_rlevel_dbg_s cn68xxp1; + struct cvmx_lmcx_rlevel_dbg_s cnf71xx; +}; + +union cvmx_lmcx_rlevel_rankx { + uint64_t u64; + struct cvmx_lmcx_rlevel_rankx_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_56_63:8; + uint64_t status:2; + uint64_t byte8:6; + uint64_t byte7:6; + uint64_t byte6:6; + uint64_t byte5:6; + uint64_t byte4:6; + uint64_t byte3:6; + uint64_t byte2:6; + uint64_t byte1:6; + uint64_t byte0:6; +#else + uint64_t byte0:6; + uint64_t byte1:6; + uint64_t byte2:6; + uint64_t byte3:6; + uint64_t byte4:6; + uint64_t byte5:6; + uint64_t byte6:6; + uint64_t byte7:6; + uint64_t byte8:6; + uint64_t status:2; + uint64_t reserved_56_63:8; +#endif + } s; + struct cvmx_lmcx_rlevel_rankx_s cn61xx; + struct cvmx_lmcx_rlevel_rankx_s cn63xx; + struct cvmx_lmcx_rlevel_rankx_s cn63xxp1; + struct cvmx_lmcx_rlevel_rankx_s cn66xx; + struct cvmx_lmcx_rlevel_rankx_s cn68xx; + struct cvmx_lmcx_rlevel_rankx_s cn68xxp1; + struct cvmx_lmcx_rlevel_rankx_s cnf71xx; +}; + +union cvmx_lmcx_rodt_comp_ctl { + uint64_t u64; + struct cvmx_lmcx_rodt_comp_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_17_63:47; + uint64_t enable:1; + uint64_t reserved_12_15:4; + uint64_t nctl:4; + uint64_t reserved_5_7:3; + uint64_t pctl:5; +#else + uint64_t pctl:5; + uint64_t reserved_5_7:3; + uint64_t nctl:4; + uint64_t reserved_12_15:4; + uint64_t enable:1; + uint64_t reserved_17_63:47; +#endif + } s; + struct cvmx_lmcx_rodt_comp_ctl_s cn50xx; + struct cvmx_lmcx_rodt_comp_ctl_s cn52xx; + struct cvmx_lmcx_rodt_comp_ctl_s cn52xxp1; + struct cvmx_lmcx_rodt_comp_ctl_s cn56xx; + struct cvmx_lmcx_rodt_comp_ctl_s cn56xxp1; + struct cvmx_lmcx_rodt_comp_ctl_s cn58xx; + struct cvmx_lmcx_rodt_comp_ctl_s cn58xxp1; +}; + +union cvmx_lmcx_rodt_ctl { + uint64_t u64; + struct cvmx_lmcx_rodt_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t rodt_hi3:4; + uint64_t rodt_hi2:4; + uint64_t rodt_hi1:4; + uint64_t rodt_hi0:4; + uint64_t rodt_lo3:4; + uint64_t rodt_lo2:4; + uint64_t rodt_lo1:4; + uint64_t rodt_lo0:4; +#else + uint64_t rodt_lo0:4; + uint64_t rodt_lo1:4; + uint64_t rodt_lo2:4; + uint64_t rodt_lo3:4; + uint64_t rodt_hi0:4; + uint64_t rodt_hi1:4; + uint64_t rodt_hi2:4; + uint64_t rodt_hi3:4; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_rodt_ctl_s cn30xx; + struct cvmx_lmcx_rodt_ctl_s cn31xx; + struct cvmx_lmcx_rodt_ctl_s cn38xx; + struct cvmx_lmcx_rodt_ctl_s cn38xxp2; + struct cvmx_lmcx_rodt_ctl_s cn50xx; + struct cvmx_lmcx_rodt_ctl_s cn52xx; + struct cvmx_lmcx_rodt_ctl_s cn52xxp1; + struct cvmx_lmcx_rodt_ctl_s cn56xx; + struct cvmx_lmcx_rodt_ctl_s cn56xxp1; + struct cvmx_lmcx_rodt_ctl_s cn58xx; + struct cvmx_lmcx_rodt_ctl_s cn58xxp1; +}; + +union cvmx_lmcx_rodt_mask { + uint64_t u64; + struct cvmx_lmcx_rodt_mask_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t rodt_d3_r1:8; + uint64_t rodt_d3_r0:8; + uint64_t rodt_d2_r1:8; + uint64_t rodt_d2_r0:8; + uint64_t rodt_d1_r1:8; + uint64_t rodt_d1_r0:8; + uint64_t rodt_d0_r1:8; + uint64_t rodt_d0_r0:8; +#else + uint64_t rodt_d0_r0:8; + uint64_t rodt_d0_r1:8; + uint64_t rodt_d1_r0:8; + uint64_t rodt_d1_r1:8; + uint64_t rodt_d2_r0:8; + uint64_t rodt_d2_r1:8; + uint64_t rodt_d3_r0:8; + uint64_t rodt_d3_r1:8; +#endif + } s; + struct cvmx_lmcx_rodt_mask_s cn61xx; + struct cvmx_lmcx_rodt_mask_s cn63xx; + struct cvmx_lmcx_rodt_mask_s cn63xxp1; + struct cvmx_lmcx_rodt_mask_s cn66xx; + struct cvmx_lmcx_rodt_mask_s cn68xx; + struct cvmx_lmcx_rodt_mask_s cn68xxp1; + struct cvmx_lmcx_rodt_mask_s cnf71xx; +}; + +union cvmx_lmcx_scramble_cfg0 { + uint64_t u64; + struct cvmx_lmcx_scramble_cfg0_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t key:64; +#else + uint64_t key:64; +#endif + } s; + struct cvmx_lmcx_scramble_cfg0_s cn61xx; + struct cvmx_lmcx_scramble_cfg0_s cn66xx; + struct cvmx_lmcx_scramble_cfg0_s cnf71xx; +}; + +union cvmx_lmcx_scramble_cfg1 { + uint64_t u64; + struct cvmx_lmcx_scramble_cfg1_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t key:64; +#else + uint64_t key:64; +#endif + } s; + struct cvmx_lmcx_scramble_cfg1_s cn61xx; + struct cvmx_lmcx_scramble_cfg1_s cn66xx; + struct cvmx_lmcx_scramble_cfg1_s cnf71xx; +}; + +union cvmx_lmcx_scrambled_fadr { + uint64_t u64; + struct cvmx_lmcx_scrambled_fadr_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_36_63:28; + uint64_t fdimm:2; + uint64_t fbunk:1; + uint64_t fbank:3; + uint64_t frow:16; + uint64_t fcol:14; +#else + uint64_t fcol:14; + uint64_t frow:16; + uint64_t fbank:3; + uint64_t fbunk:1; + uint64_t fdimm:2; + uint64_t reserved_36_63:28; +#endif + } s; + struct cvmx_lmcx_scrambled_fadr_s cn61xx; + struct cvmx_lmcx_scrambled_fadr_s cn66xx; + struct cvmx_lmcx_scrambled_fadr_s cnf71xx; +}; + +union cvmx_lmcx_slot_ctl0 { + uint64_t u64; + struct cvmx_lmcx_slot_ctl0_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_24_63:40; + uint64_t w2w_init:6; + uint64_t w2r_init:6; + uint64_t r2w_init:6; + uint64_t r2r_init:6; +#else + uint64_t r2r_init:6; + uint64_t r2w_init:6; + uint64_t w2r_init:6; + uint64_t w2w_init:6; + uint64_t reserved_24_63:40; +#endif + } s; + struct cvmx_lmcx_slot_ctl0_s cn61xx; + struct cvmx_lmcx_slot_ctl0_s cn63xx; + struct cvmx_lmcx_slot_ctl0_s cn63xxp1; + struct cvmx_lmcx_slot_ctl0_s cn66xx; + struct cvmx_lmcx_slot_ctl0_s cn68xx; + struct cvmx_lmcx_slot_ctl0_s cn68xxp1; + struct cvmx_lmcx_slot_ctl0_s cnf71xx; +}; + +union cvmx_lmcx_slot_ctl1 { + uint64_t u64; + struct cvmx_lmcx_slot_ctl1_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_24_63:40; + uint64_t w2w_xrank_init:6; + uint64_t w2r_xrank_init:6; + uint64_t r2w_xrank_init:6; + uint64_t r2r_xrank_init:6; +#else + uint64_t r2r_xrank_init:6; + uint64_t r2w_xrank_init:6; + uint64_t w2r_xrank_init:6; + uint64_t w2w_xrank_init:6; + uint64_t reserved_24_63:40; +#endif + } s; + struct cvmx_lmcx_slot_ctl1_s cn61xx; + struct cvmx_lmcx_slot_ctl1_s cn63xx; + struct cvmx_lmcx_slot_ctl1_s cn63xxp1; + struct cvmx_lmcx_slot_ctl1_s cn66xx; + struct cvmx_lmcx_slot_ctl1_s cn68xx; + struct cvmx_lmcx_slot_ctl1_s cn68xxp1; + struct cvmx_lmcx_slot_ctl1_s cnf71xx; +}; + +union cvmx_lmcx_slot_ctl2 { + uint64_t u64; + struct cvmx_lmcx_slot_ctl2_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_24_63:40; + uint64_t w2w_xdimm_init:6; + uint64_t w2r_xdimm_init:6; + uint64_t r2w_xdimm_init:6; + uint64_t r2r_xdimm_init:6; +#else + uint64_t r2r_xdimm_init:6; + uint64_t r2w_xdimm_init:6; + uint64_t w2r_xdimm_init:6; + uint64_t w2w_xdimm_init:6; + uint64_t reserved_24_63:40; +#endif + } s; + struct cvmx_lmcx_slot_ctl2_s cn61xx; + struct cvmx_lmcx_slot_ctl2_s cn63xx; + struct cvmx_lmcx_slot_ctl2_s cn63xxp1; + struct cvmx_lmcx_slot_ctl2_s cn66xx; + struct cvmx_lmcx_slot_ctl2_s cn68xx; + struct cvmx_lmcx_slot_ctl2_s cn68xxp1; + struct cvmx_lmcx_slot_ctl2_s cnf71xx; +}; + +union cvmx_lmcx_timing_params0 { + uint64_t u64; + struct cvmx_lmcx_timing_params0_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_47_63:17; + uint64_t trp_ext:1; + uint64_t tcksre:4; + uint64_t trp:4; + uint64_t tzqinit:4; + uint64_t tdllk:4; + uint64_t tmod:4; + uint64_t tmrd:4; + uint64_t txpr:4; + uint64_t tcke:4; + uint64_t tzqcs:4; + uint64_t tckeon:10; +#else + uint64_t tckeon:10; + uint64_t tzqcs:4; + uint64_t tcke:4; + uint64_t txpr:4; + uint64_t tmrd:4; + uint64_t tmod:4; + uint64_t tdllk:4; + uint64_t tzqinit:4; + uint64_t trp:4; + uint64_t tcksre:4; + uint64_t trp_ext:1; + uint64_t reserved_47_63:17; +#endif + } s; + struct cvmx_lmcx_timing_params0_cn61xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_47_63:17; + uint64_t trp_ext:1; + uint64_t tcksre:4; + uint64_t trp:4; + uint64_t tzqinit:4; + uint64_t tdllk:4; + uint64_t tmod:4; + uint64_t tmrd:4; + uint64_t txpr:4; + uint64_t tcke:4; + uint64_t tzqcs:4; + uint64_t reserved_0_9:10; +#else + uint64_t reserved_0_9:10; + uint64_t tzqcs:4; + uint64_t tcke:4; + uint64_t txpr:4; + uint64_t tmrd:4; + uint64_t tmod:4; + uint64_t tdllk:4; + uint64_t tzqinit:4; + uint64_t trp:4; + uint64_t tcksre:4; + uint64_t trp_ext:1; + uint64_t reserved_47_63:17; +#endif + } cn61xx; + struct cvmx_lmcx_timing_params0_cn61xx cn63xx; + struct cvmx_lmcx_timing_params0_cn63xxp1 { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_46_63:18; + uint64_t tcksre:4; + uint64_t trp:4; + uint64_t tzqinit:4; + uint64_t tdllk:4; + uint64_t tmod:4; + uint64_t tmrd:4; + uint64_t txpr:4; + uint64_t tcke:4; + uint64_t tzqcs:4; + uint64_t tckeon:10; +#else + uint64_t tckeon:10; + uint64_t tzqcs:4; + uint64_t tcke:4; + uint64_t txpr:4; + uint64_t tmrd:4; + uint64_t tmod:4; + uint64_t tdllk:4; + uint64_t tzqinit:4; + uint64_t trp:4; + uint64_t tcksre:4; + uint64_t reserved_46_63:18; +#endif + } cn63xxp1; + struct cvmx_lmcx_timing_params0_cn61xx cn66xx; + struct cvmx_lmcx_timing_params0_cn61xx cn68xx; + struct cvmx_lmcx_timing_params0_cn61xx cn68xxp1; + struct cvmx_lmcx_timing_params0_cn61xx cnf71xx; +}; + +union cvmx_lmcx_timing_params1 { + uint64_t u64; + struct cvmx_lmcx_timing_params1_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_47_63:17; + uint64_t tras_ext:1; + uint64_t txpdll:5; + uint64_t tfaw:5; + uint64_t twldqsen:4; + uint64_t twlmrd:4; + uint64_t txp:3; + uint64_t trrd:3; + uint64_t trfc:5; + uint64_t twtr:4; + uint64_t trcd:4; + uint64_t tras:5; + uint64_t tmprr:4; +#else + uint64_t tmprr:4; + uint64_t tras:5; + uint64_t trcd:4; + uint64_t twtr:4; + uint64_t trfc:5; + uint64_t trrd:3; + uint64_t txp:3; + uint64_t twlmrd:4; + uint64_t twldqsen:4; + uint64_t tfaw:5; + uint64_t txpdll:5; + uint64_t tras_ext:1; + uint64_t reserved_47_63:17; +#endif + } s; + struct cvmx_lmcx_timing_params1_s cn61xx; + struct cvmx_lmcx_timing_params1_s cn63xx; + struct cvmx_lmcx_timing_params1_cn63xxp1 { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_46_63:18; + uint64_t txpdll:5; + uint64_t tfaw:5; + uint64_t twldqsen:4; + uint64_t twlmrd:4; + uint64_t txp:3; + uint64_t trrd:3; + uint64_t trfc:5; + uint64_t twtr:4; + uint64_t trcd:4; + uint64_t tras:5; + uint64_t tmprr:4; +#else + uint64_t tmprr:4; + uint64_t tras:5; + uint64_t trcd:4; + uint64_t twtr:4; + uint64_t trfc:5; + uint64_t trrd:3; + uint64_t txp:3; + uint64_t twlmrd:4; + uint64_t twldqsen:4; + uint64_t tfaw:5; + uint64_t txpdll:5; + uint64_t reserved_46_63:18; +#endif + } cn63xxp1; + struct cvmx_lmcx_timing_params1_s cn66xx; + struct cvmx_lmcx_timing_params1_s cn68xx; + struct cvmx_lmcx_timing_params1_s cn68xxp1; + struct cvmx_lmcx_timing_params1_s cnf71xx; +}; + +union cvmx_lmcx_tro_ctl { + uint64_t u64; + struct cvmx_lmcx_tro_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_33_63:31; + uint64_t rclk_cnt:32; + uint64_t treset:1; +#else + uint64_t treset:1; + uint64_t rclk_cnt:32; + uint64_t reserved_33_63:31; +#endif + } s; + struct cvmx_lmcx_tro_ctl_s cn61xx; + struct cvmx_lmcx_tro_ctl_s cn63xx; + struct cvmx_lmcx_tro_ctl_s cn63xxp1; + struct cvmx_lmcx_tro_ctl_s cn66xx; + struct cvmx_lmcx_tro_ctl_s cn68xx; + struct cvmx_lmcx_tro_ctl_s cn68xxp1; + struct cvmx_lmcx_tro_ctl_s cnf71xx; +}; + +union cvmx_lmcx_tro_stat { + uint64_t u64; + struct cvmx_lmcx_tro_stat_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t ring_cnt:32; +#else + uint64_t ring_cnt:32; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_tro_stat_s cn61xx; + struct cvmx_lmcx_tro_stat_s cn63xx; + struct cvmx_lmcx_tro_stat_s cn63xxp1; + struct cvmx_lmcx_tro_stat_s cn66xx; + struct cvmx_lmcx_tro_stat_s cn68xx; + struct cvmx_lmcx_tro_stat_s cn68xxp1; + struct cvmx_lmcx_tro_stat_s cnf71xx; +}; + +union cvmx_lmcx_wlevel_ctl { + uint64_t u64; + struct cvmx_lmcx_wlevel_ctl_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_22_63:42; + uint64_t rtt_nom:3; + uint64_t bitmask:8; + uint64_t or_dis:1; + uint64_t sset:1; + uint64_t lanemask:9; +#else + uint64_t lanemask:9; + uint64_t sset:1; + uint64_t or_dis:1; + uint64_t bitmask:8; + uint64_t rtt_nom:3; + uint64_t reserved_22_63:42; +#endif + } s; + struct cvmx_lmcx_wlevel_ctl_s cn61xx; + struct cvmx_lmcx_wlevel_ctl_s cn63xx; + struct cvmx_lmcx_wlevel_ctl_cn63xxp1 { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_10_63:54; + uint64_t sset:1; + uint64_t lanemask:9; +#else + uint64_t lanemask:9; + uint64_t sset:1; + uint64_t reserved_10_63:54; +#endif + } cn63xxp1; + struct cvmx_lmcx_wlevel_ctl_s cn66xx; + struct cvmx_lmcx_wlevel_ctl_s cn68xx; + struct cvmx_lmcx_wlevel_ctl_s cn68xxp1; + struct cvmx_lmcx_wlevel_ctl_s cnf71xx; +}; + +union cvmx_lmcx_wlevel_dbg { + uint64_t u64; + struct cvmx_lmcx_wlevel_dbg_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_12_63:52; + uint64_t bitmask:8; + uint64_t byte:4; +#else + uint64_t byte:4; + uint64_t bitmask:8; + uint64_t reserved_12_63:52; +#endif + } s; + struct cvmx_lmcx_wlevel_dbg_s cn61xx; + struct cvmx_lmcx_wlevel_dbg_s cn63xx; + struct cvmx_lmcx_wlevel_dbg_s cn63xxp1; + struct cvmx_lmcx_wlevel_dbg_s cn66xx; + struct cvmx_lmcx_wlevel_dbg_s cn68xx; + struct cvmx_lmcx_wlevel_dbg_s cn68xxp1; + struct cvmx_lmcx_wlevel_dbg_s cnf71xx; +}; + +union cvmx_lmcx_wlevel_rankx { + uint64_t u64; + struct cvmx_lmcx_wlevel_rankx_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_47_63:17; + uint64_t status:2; + uint64_t byte8:5; + uint64_t byte7:5; + uint64_t byte6:5; + uint64_t byte5:5; + uint64_t byte4:5; + uint64_t byte3:5; + uint64_t byte2:5; + uint64_t byte1:5; + uint64_t byte0:5; +#else + uint64_t byte0:5; + uint64_t byte1:5; + uint64_t byte2:5; + uint64_t byte3:5; + uint64_t byte4:5; + uint64_t byte5:5; + uint64_t byte6:5; + uint64_t byte7:5; + uint64_t byte8:5; + uint64_t status:2; + uint64_t reserved_47_63:17; +#endif + } s; + struct cvmx_lmcx_wlevel_rankx_s cn61xx; + struct cvmx_lmcx_wlevel_rankx_s cn63xx; + struct cvmx_lmcx_wlevel_rankx_s cn63xxp1; + struct cvmx_lmcx_wlevel_rankx_s cn66xx; + struct cvmx_lmcx_wlevel_rankx_s cn68xx; + struct cvmx_lmcx_wlevel_rankx_s cn68xxp1; + struct cvmx_lmcx_wlevel_rankx_s cnf71xx; +}; + +union cvmx_lmcx_wodt_ctl0 { + uint64_t u64; + struct cvmx_lmcx_wodt_ctl0_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_0_63:64; +#else + uint64_t reserved_0_63:64; +#endif + } s; + struct cvmx_lmcx_wodt_ctl0_cn30xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t wodt_d1_r1:8; + uint64_t wodt_d1_r0:8; + uint64_t wodt_d0_r1:8; + uint64_t wodt_d0_r0:8; +#else + uint64_t wodt_d0_r0:8; + uint64_t wodt_d0_r1:8; + uint64_t wodt_d1_r0:8; + uint64_t wodt_d1_r1:8; + uint64_t reserved_32_63:32; +#endif + } cn30xx; + struct cvmx_lmcx_wodt_ctl0_cn30xx cn31xx; + struct cvmx_lmcx_wodt_ctl0_cn38xx { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t wodt_hi3:4; + uint64_t wodt_hi2:4; + uint64_t wodt_hi1:4; + uint64_t wodt_hi0:4; + uint64_t wodt_lo3:4; + uint64_t wodt_lo2:4; + uint64_t wodt_lo1:4; + uint64_t wodt_lo0:4; +#else + uint64_t wodt_lo0:4; + uint64_t wodt_lo1:4; + uint64_t wodt_lo2:4; + uint64_t wodt_lo3:4; + uint64_t wodt_hi0:4; + uint64_t wodt_hi1:4; + uint64_t wodt_hi2:4; + uint64_t wodt_hi3:4; + uint64_t reserved_32_63:32; +#endif + } cn38xx; + struct cvmx_lmcx_wodt_ctl0_cn38xx cn38xxp2; + struct cvmx_lmcx_wodt_ctl0_cn38xx cn50xx; + struct cvmx_lmcx_wodt_ctl0_cn30xx cn52xx; + struct cvmx_lmcx_wodt_ctl0_cn30xx cn52xxp1; + struct cvmx_lmcx_wodt_ctl0_cn30xx cn56xx; + struct cvmx_lmcx_wodt_ctl0_cn30xx cn56xxp1; + struct cvmx_lmcx_wodt_ctl0_cn38xx cn58xx; + struct cvmx_lmcx_wodt_ctl0_cn38xx cn58xxp1; +}; + +union cvmx_lmcx_wodt_ctl1 { + uint64_t u64; + struct cvmx_lmcx_wodt_ctl1_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t reserved_32_63:32; + uint64_t wodt_d3_r1:8; + uint64_t wodt_d3_r0:8; + uint64_t wodt_d2_r1:8; + uint64_t wodt_d2_r0:8; +#else + uint64_t wodt_d2_r0:8; + uint64_t wodt_d2_r1:8; + uint64_t wodt_d3_r0:8; + uint64_t wodt_d3_r1:8; + uint64_t reserved_32_63:32; +#endif + } s; + struct cvmx_lmcx_wodt_ctl1_s cn30xx; + struct cvmx_lmcx_wodt_ctl1_s cn31xx; + struct cvmx_lmcx_wodt_ctl1_s cn52xx; + struct cvmx_lmcx_wodt_ctl1_s cn52xxp1; + struct cvmx_lmcx_wodt_ctl1_s cn56xx; + struct cvmx_lmcx_wodt_ctl1_s cn56xxp1; +}; + +union cvmx_lmcx_wodt_mask { + uint64_t u64; + struct cvmx_lmcx_wodt_mask_s { +#ifdef __BIG_ENDIAN_BITFIELD + uint64_t wodt_d3_r1:8; + uint64_t wodt_d3_r0:8; + uint64_t wodt_d2_r1:8; + uint64_t wodt_d2_r0:8; + uint64_t wodt_d1_r1:8; + uint64_t wodt_d1_r0:8; + uint64_t wodt_d0_r1:8; + uint64_t wodt_d0_r0:8; +#else + uint64_t wodt_d0_r0:8; + uint64_t wodt_d0_r1:8; + uint64_t wodt_d1_r0:8; + uint64_t wodt_d1_r1:8; + uint64_t wodt_d2_r0:8; + uint64_t wodt_d2_r1:8; + uint64_t wodt_d3_r0:8; + uint64_t wodt_d3_r1:8; +#endif + } s; + struct cvmx_lmcx_wodt_mask_s cn61xx; + struct cvmx_lmcx_wodt_mask_s cn63xx; + struct cvmx_lmcx_wodt_mask_s cn63xxp1; + struct cvmx_lmcx_wodt_mask_s cn66xx; + struct cvmx_lmcx_wodt_mask_s cn68xx; + struct cvmx_lmcx_wodt_mask_s cn68xxp1; + struct cvmx_lmcx_wodt_mask_s cnf71xx; +}; + +#endif diff --git a/arch/mips/include/asm/octeon/octeon-model.h b/arch/mips/include/asm/octeon/octeon-model.h index 14dd11f4492a..349bb2ba840c 100644 --- a/arch/mips/include/asm/octeon/octeon-model.h +++ b/arch/mips/include/asm/octeon/octeon-model.h @@ -218,6 +218,12 @@ #define OCTEON_CN5XXX (OCTEON_CN58XX_PASS1_0 | OM_MATCH_5XXX_FAMILY_MODELS) #define OCTEON_CN6XXX (OCTEON_CN63XX_PASS1_0 | OM_MATCH_6XXX_FAMILY_MODELS) +/* These are used to cover entire families of OCTEON processors */ +#define OCTEON_FAM_1 (OCTEON_CN3XXX) +#define OCTEON_FAM_PLUS (OCTEON_CN5XXX) +#define OCTEON_FAM_1_PLUS (OCTEON_FAM_PLUS | OM_MATCH_PREVIOUS_MODELS) +#define OCTEON_FAM_2 (OCTEON_CN6XXX) + /* The revision byte (low byte) has two different encodings. * CN3XXX: * diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h index 790939dd8244..254e9954ed71 100644 --- a/arch/mips/include/asm/octeon/octeon.h +++ b/arch/mips/include/asm/octeon/octeon.h @@ -209,13 +209,6 @@ union octeon_cvmemctl { } s; }; -struct octeon_cf_data { - unsigned long base_region_bias; - unsigned int base_region; /* The chip select region used by CF */ - int is16bit; /* 0 - 8bit, !0 - 16bit */ - int dma_engine; /* -1 for no DMA */ -}; - extern void octeon_write_lcd(const char *s); extern void octeon_check_cpu_bist(void); extern int octeon_get_boot_debug_flag(void); diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index da9bd7d270d1..31ab10f02bad 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h @@ -31,19 +31,19 @@ #define PAGE_SHIFT 16 #endif #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) +#define PAGE_MASK (~(PAGE_SIZE - 1)) -#ifdef CONFIG_HUGETLB_PAGE +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT #define HPAGE_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3) #define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT) #define HPAGE_MASK (~(HPAGE_SIZE - 1)) #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) -#else /* !CONFIG_HUGETLB_PAGE */ +#else /* !CONFIG_MIPS_HUGE_TLB_SUPPORT */ #define HPAGE_SHIFT ({BUILD_BUG(); 0; }) #define HPAGE_SIZE ({BUILD_BUG(); 0; }) #define HPAGE_MASK ({BUILD_BUG(); 0; }) #define HUGETLB_PAGE_ORDER ({BUILD_BUG(); 0; }) -#endif /* CONFIG_HUGETLB_PAGE */ +#endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */ #ifndef __ASSEMBLY__ diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h index f5b521d5a67d..c63191055e69 100644 --- a/arch/mips/include/asm/pgtable-64.h +++ b/arch/mips/include/asm/pgtable-64.h @@ -175,7 +175,7 @@ static inline int pmd_none(pmd_t pmd) static inline int pmd_bad(pmd_t pmd) { -#ifdef CONFIG_HUGETLB_PAGE +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT /* pmd_huge(pmd) but inline */ if (unlikely(pmd_val(pmd) & _PAGE_HUGE)) return 0; diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h index da4ba49adcf6..f6a0439a4085 100644 --- a/arch/mips/include/asm/pgtable-bits.h +++ b/arch/mips/include/asm/pgtable-bits.h @@ -34,38 +34,72 @@ */ #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) -#define _PAGE_PRESENT (1<<6) /* implemented in software */ -#define _PAGE_READ (1<<7) /* implemented in software */ -#define _PAGE_WRITE (1<<8) /* implemented in software */ -#define _PAGE_ACCESSED (1<<9) /* implemented in software */ -#define _PAGE_MODIFIED (1<<10) /* implemented in software */ -#define _PAGE_FILE (1<<10) /* set:pagecache unset:swap */ - -#define _PAGE_R4KBUG (1<<0) /* workaround for r4k bug */ -#define _PAGE_GLOBAL (1<<0) -#define _PAGE_VALID (1<<1) -#define _PAGE_SILENT_READ (1<<1) /* synonym */ -#define _PAGE_DIRTY (1<<2) /* The MIPS dirty bit */ -#define _PAGE_SILENT_WRITE (1<<2) -#define _CACHE_SHIFT 3 -#define _CACHE_MASK (7<<3) +/* + * The following bits are directly used by the TLB hardware + */ +#define _PAGE_R4KBUG (1 << 0) /* workaround for r4k bug */ +#define _PAGE_GLOBAL (1 << 0) +#define _PAGE_VALID_SHIFT 1 +#define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) +#define _PAGE_SILENT_READ (1 << 1) /* synonym */ +#define _PAGE_DIRTY_SHIFT 2 +#define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) /* The MIPS dirty bit */ +#define _PAGE_SILENT_WRITE (1 << 2) +#define _CACHE_SHIFT 3 +#define _CACHE_MASK (7 << 3) + +/* + * The following bits are implemented in software + * + * _PAGE_FILE semantics: set:pagecache unset:swap + */ +#define _PAGE_PRESENT_SHIFT 6 +#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) +#define _PAGE_READ_SHIFT 7 +#define _PAGE_READ (1 << _PAGE_READ_SHIFT) +#define _PAGE_WRITE_SHIFT 8 +#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) +#define _PAGE_ACCESSED_SHIFT 9 +#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) +#define _PAGE_MODIFIED_SHIFT 10 +#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) + +#define _PAGE_FILE (1 << 10) #elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) -#define _PAGE_PRESENT (1<<0) /* implemented in software */ -#define _PAGE_READ (1<<1) /* implemented in software */ -#define _PAGE_WRITE (1<<2) /* implemented in software */ -#define _PAGE_ACCESSED (1<<3) /* implemented in software */ -#define _PAGE_MODIFIED (1<<4) /* implemented in software */ -#define _PAGE_FILE (1<<4) /* set:pagecache unset:swap */ - -#define _PAGE_GLOBAL (1<<8) -#define _PAGE_VALID (1<<9) -#define _PAGE_SILENT_READ (1<<9) /* synonym */ -#define _PAGE_DIRTY (1<<10) /* The MIPS dirty bit */ -#define _PAGE_SILENT_WRITE (1<<10) -#define _CACHE_UNCACHED (1<<11) -#define _CACHE_MASK (1<<11) +/* + * The following are implemented by software + * + * _PAGE_FILE semantics: set:pagecache unset:swap + */ +#define _PAGE_PRESENT_SHIFT 0 +#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) +#define _PAGE_READ_SHIFT 1 +#define _PAGE_READ (1 << _PAGE_READ_SHIFT) +#define _PAGE_WRITE_SHIFT 2 +#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) +#define _PAGE_ACCESSED_SHIFT 3 +#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) +#define _PAGE_MODIFIED_SHIFT 4 +#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) +#define _PAGE_FILE_SHIFT 4 +#define _PAGE_FILE (1 << _PAGE_FILE_SHIFT) + +/* + * And these are the hardware TLB bits + */ +#define _PAGE_GLOBAL_SHIFT 8 +#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) +#define _PAGE_VALID_SHIFT 9 +#define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) +#define _PAGE_SILENT_READ (1 << _PAGE_VALID_SHIFT) /* synonym */ +#define _PAGE_DIRTY_SHIFT 10 +#define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) +#define _PAGE_SILENT_WRITE (1 << _PAGE_DIRTY_SHIFT) +#define _CACHE_UNCACHED_SHIFT 11 +#define _CACHE_UNCACHED (1 << _CACHE_UNCACHED_SHIFT) +#define _CACHE_MASK (1 << _CACHE_UNCACHED_SHIFT) #else /* 'Normal' r4K case */ /* @@ -76,25 +110,25 @@ * which is more than we need right now. */ -/* implemented in software */ +/* + * The following bits are implemented in software + * + * _PAGE_READ / _PAGE_READ_SHIFT should be unused if cpu_has_rixi. + * _PAGE_FILE semantics: set:pagecache unset:swap + */ #define _PAGE_PRESENT_SHIFT (0) #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) -/* implemented in software, should be unused if cpu_has_rixi. */ #define _PAGE_READ_SHIFT (cpu_has_rixi ? _PAGE_PRESENT_SHIFT : _PAGE_PRESENT_SHIFT + 1) #define _PAGE_READ ({BUG_ON(cpu_has_rixi); 1 << _PAGE_READ_SHIFT; }) -/* implemented in software */ #define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1) #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) -/* implemented in software */ #define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1) #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) -/* implemented in software */ #define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1) #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) -/* set:pagecache unset:swap */ #define _PAGE_FILE (_PAGE_MODIFIED) -#ifdef CONFIG_HUGETLB_PAGE +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT /* huge tlb page */ #define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT + 1) #define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT) @@ -103,8 +137,17 @@ #define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */ #endif +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT +/* huge tlb page */ +#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT + 1) +#define _PAGE_SPLITTING (1 << _PAGE_SPLITTING_SHIFT) +#else +#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT) +#define _PAGE_SPLITTING ({BUG(); 1; }) /* Dummy value */ +#endif + /* Page cannot be executed */ -#define _PAGE_NO_EXEC_SHIFT (cpu_has_rixi ? _PAGE_HUGE_SHIFT + 1 : _PAGE_HUGE_SHIFT) +#define _PAGE_NO_EXEC_SHIFT (cpu_has_rixi ? _PAGE_SPLITTING_SHIFT + 1 : _PAGE_SPLITTING_SHIFT) #define _PAGE_NO_EXEC ({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_EXEC_SHIFT; }) /* Page cannot be read */ @@ -192,20 +235,6 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val) #define _CACHE_CACHABLE_NONCOHERENT (5<<_CACHE_SHIFT) #define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT) -#elif defined(CONFIG_CPU_RM9000) - -#define _CACHE_WT (0<<_CACHE_SHIFT) -#define _CACHE_WTWA (1<<_CACHE_SHIFT) -#define _CACHE_UC_B (2<<_CACHE_SHIFT) -#define _CACHE_WB (3<<_CACHE_SHIFT) -#define _CACHE_CWBEA (4<<_CACHE_SHIFT) -#define _CACHE_CWB (5<<_CACHE_SHIFT) -#define _CACHE_UCNB (6<<_CACHE_SHIFT) -#define _CACHE_FPC (7<<_CACHE_SHIFT) - -#define _CACHE_UNCACHED _CACHE_UC_B -#define _CACHE_CACHABLE_NONCOHERENT _CACHE_WB - #else #define _CACHE_CACHABLE_NO_WA (0<<_CACHE_SHIFT) /* R4600 only */ diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index 14490e9443af..ec50d52cfb74 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -8,6 +8,7 @@ #ifndef _ASM_PGTABLE_H #define _ASM_PGTABLE_H +#include <linux/mmzone.h> #ifdef CONFIG_32BIT #include <asm/pgtable-32.h> #endif @@ -85,7 +86,12 @@ extern void paging_init(void); * and a page entry and page directory to the page they refer to. */ #define pmd_phys(pmd) virt_to_phys((void *)pmd_val(pmd)) -#define pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT)) + +#define __pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT)) +#ifndef CONFIG_TRANSPARENT_HUGEPAGE +#define pmd_page(pmd) __pmd_page(pmd) +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + #define pmd_page_vaddr(pmd) pmd_val(pmd) #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) @@ -98,7 +104,6 @@ static inline void set_pte(pte_t *ptep, pte_t pte) ptep->pte_high = pte.pte_high; smp_wmb(); ptep->pte_low = pte.pte_low; - //printk("pte_high %x pte_low %x\n", ptep->pte_high, ptep->pte_low); if (pte.pte_low & _PAGE_GLOBAL) { pte_t *buddy = ptep_buddy(ptep); @@ -366,6 +371,14 @@ static inline void update_mmu_cache(struct vm_area_struct *vma, __update_cache(vma, address, pte); } +static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, + unsigned long address, pmd_t *pmdp) +{ + pte_t pte = *(pte_t *)pmdp; + + __update_tlb(vma, address, pte); +} + #define kern_addr_valid(addr) (1) #ifdef CONFIG_64BIT_PHYS_ADDR @@ -385,6 +398,157 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, remap_pfn_range(vma, vaddr, pfn, size, prot) #endif +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + +extern int has_transparent_hugepage(void); + +static inline int pmd_trans_huge(pmd_t pmd) +{ + return !!(pmd_val(pmd) & _PAGE_HUGE); +} + +static inline pmd_t pmd_mkhuge(pmd_t pmd) +{ + pmd_val(pmd) |= _PAGE_HUGE; + + return pmd; +} + +static inline int pmd_trans_splitting(pmd_t pmd) +{ + return !!(pmd_val(pmd) & _PAGE_SPLITTING); +} + +static inline pmd_t pmd_mksplitting(pmd_t pmd) +{ + pmd_val(pmd) |= _PAGE_SPLITTING; + + return pmd; +} + +extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, + pmd_t *pmdp, pmd_t pmd); + +#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH +/* Extern to avoid header file madness */ +extern void pmdp_splitting_flush(struct vm_area_struct *vma, + unsigned long address, + pmd_t *pmdp); + +#define __HAVE_ARCH_PMD_WRITE +static inline int pmd_write(pmd_t pmd) +{ + return !!(pmd_val(pmd) & _PAGE_WRITE); +} + +static inline pmd_t pmd_wrprotect(pmd_t pmd) +{ + pmd_val(pmd) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE); + return pmd; +} + +static inline pmd_t pmd_mkwrite(pmd_t pmd) +{ + pmd_val(pmd) |= _PAGE_WRITE; + if (pmd_val(pmd) & _PAGE_MODIFIED) + pmd_val(pmd) |= _PAGE_SILENT_WRITE; + + return pmd; +} + +static inline int pmd_dirty(pmd_t pmd) +{ + return !!(pmd_val(pmd) & _PAGE_MODIFIED); +} + +static inline pmd_t pmd_mkclean(pmd_t pmd) +{ + pmd_val(pmd) &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE); + return pmd; +} + +static inline pmd_t pmd_mkdirty(pmd_t pmd) +{ + pmd_val(pmd) |= _PAGE_MODIFIED; + if (pmd_val(pmd) & _PAGE_WRITE) + pmd_val(pmd) |= _PAGE_SILENT_WRITE; + + return pmd; +} + +static inline int pmd_young(pmd_t pmd) +{ + return !!(pmd_val(pmd) & _PAGE_ACCESSED); +} + +static inline pmd_t pmd_mkold(pmd_t pmd) +{ + pmd_val(pmd) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ); + + return pmd; +} + +static inline pmd_t pmd_mkyoung(pmd_t pmd) +{ + pmd_val(pmd) |= _PAGE_ACCESSED; + + if (cpu_has_rixi) { + if (!(pmd_val(pmd) & _PAGE_NO_READ)) + pmd_val(pmd) |= _PAGE_SILENT_READ; + } else { + if (pmd_val(pmd) & _PAGE_READ) + pmd_val(pmd) |= _PAGE_SILENT_READ; + } + + return pmd; +} + +/* Extern to avoid header file madness */ +extern pmd_t mk_pmd(struct page *page, pgprot_t prot); + +static inline unsigned long pmd_pfn(pmd_t pmd) +{ + return pmd_val(pmd) >> _PFN_SHIFT; +} + +static inline struct page *pmd_page(pmd_t pmd) +{ + if (pmd_trans_huge(pmd)) + return pfn_to_page(pmd_pfn(pmd)); + + return pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT); +} + +static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) +{ + pmd_val(pmd) = (pmd_val(pmd) & _PAGE_CHG_MASK) | pgprot_val(newprot); + return pmd; +} + +static inline pmd_t pmd_mknotpresent(pmd_t pmd) +{ + pmd_val(pmd) &= ~(_PAGE_PRESENT | _PAGE_VALID | _PAGE_DIRTY); + + return pmd; +} + +/* + * The generic version pmdp_get_and_clear uses a version of pmd_clear() with a + * different prototype. + */ +#define __HAVE_ARCH_PMDP_GET_AND_CLEAR +static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm, + unsigned long address, pmd_t *pmdp) +{ + pmd_t old = *pmdp; + + pmd_clear(pmdp); + + return old; +} + +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + #include <asm-generic/pgtable.h> /* diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/war.h b/arch/mips/include/asm/pmc-sierra/msp71xx/war.h index 9e2ee429c529..c74eb1657f5f 100644 --- a/arch/mips/include/asm/pmc-sierra/msp71xx/war.h +++ b/arch/mips/include/asm/pmc-sierra/msp71xx/war.h @@ -17,7 +17,6 @@ #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 #define ICACHE_REFILLS_WORKAROUND_WAR 0 #define R10000_LLSC_WAR 0 #if defined(CONFIG_PMC_MSP7120_EVAL) || defined(CONFIG_PMC_MSP7120_GW) || \ diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index d28c41e0887c..bd98b503f04c 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -226,8 +226,6 @@ struct thread_struct { unsigned long cp0_badvaddr; /* Last user fault */ unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */ unsigned long error_code; - unsigned long irix_trampoline; /* Wheee... */ - unsigned long irix_oldctx; #ifdef CONFIG_CPU_CAVIUM_OCTEON struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128))); struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128))); @@ -297,8 +295,6 @@ struct thread_struct { .cp0_badvaddr = 0, \ .cp0_baduaddr = 0, \ .error_code = 0, \ - .irix_trampoline = 0, \ - .irix_oldctx = 0, \ /* \ * Cavium Octeon specifics (null if not Octeon) \ */ \ diff --git a/arch/mips/include/asm/sgiarcs.h b/arch/mips/include/asm/sgiarcs.h index 149342951436..3dce7c788b3e 100644 --- a/arch/mips/include/asm/sgiarcs.h +++ b/arch/mips/include/asm/sgiarcs.h @@ -366,7 +366,7 @@ struct linux_smonblock { * Macros for calling a 32-bit ARC implementation from 64-bit code */ -#if defined(CONFIG_64BIT) && defined(CONFIG_ARC32) +#if defined(CONFIG_64BIT) && defined(CONFIG_FW_ARC32) #define __arc_clobbers \ "$2", "$3" /* ... */, "$8", "$9", "$10", "$11", \ @@ -475,10 +475,10 @@ struct linux_smonblock { __res; \ }) -#endif /* defined(CONFIG_64BIT) && defined(CONFIG_ARC32) */ +#endif /* defined(CONFIG_64BIT) && defined(CONFIG_FW_ARC32) */ -#if (defined(CONFIG_32BIT) && defined(CONFIG_ARC32)) || \ - (defined(CONFIG_64BIT) && defined(CONFIG_ARC64)) +#if (defined(CONFIG_32BIT) && defined(CONFIG_FW_ARC32)) || \ + (defined(CONFIG_64BIT) && defined(CONFIG_FW_ARC64)) #define ARC_CALL0(dest) \ ({ long __res; \ diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h index d4fb4d852a6d..f33b5fd6972b 100644 --- a/arch/mips/include/asm/smp.h +++ b/arch/mips/include/asm/smp.h @@ -40,6 +40,8 @@ extern int __cpu_logical_map[NR_CPUS]; #define SMP_CALL_FUNCTION 0x2 /* Octeon - Tell another core to flush its icache */ #define SMP_ICACHE_FLUSH 0x4 +/* Used by kexec crashdump to save all cpu's state */ +#define SMP_DUMP 0x8 extern volatile cpumask_t cpu_callin_map; @@ -91,4 +93,8 @@ static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask) mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION); } +#if defined(CONFIG_KEXEC) +extern void (*dump_ipi_function_ptr)(void *); +void dump_send_ipi(void (*dump_ipi_callback)(void *)); +#endif #endif /* __ASM_SMP_H */ diff --git a/arch/mips/include/asm/smvp.h b/arch/mips/include/asm/smvp.h deleted file mode 100644 index 0d0e80a39e8a..000000000000 --- a/arch/mips/include/asm/smvp.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _ASM_SMVP_H -#define _ASM_SMVP_H - -/* - * Definitions for SMVP multitasking on MIPS MT cores - */ -struct task_struct; - -extern void smvp_smp_setup(void); -extern void smvp_smp_finish(void); -extern void smvp_boot_secondary(int cpu, struct task_struct *t); -extern void smvp_init_secondary(void); -extern void smvp_smp_finish(void); -extern void smvp_cpus_done(void); -extern void smvp_prepare_cpus(unsigned int max_cpus); - -/* This is platform specific */ -extern void smvp_send_ipi(int cpu, unsigned int action); -#endif /* _ASM_SMVP_H */ diff --git a/arch/mips/include/asm/sparsemem.h b/arch/mips/include/asm/sparsemem.h index 4461198361c9..65900dab3ad3 100644 --- a/arch/mips/include/asm/sparsemem.h +++ b/arch/mips/include/asm/sparsemem.h @@ -6,7 +6,7 @@ * SECTION_SIZE_BITS 2^N: how big each section will be * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space */ -#if defined(CONFIG_HUGETLB_PAGE) && defined(CONFIG_PAGE_SIZE_64KB) +#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) && defined(CONFIG_PAGE_SIZE_64KB) # define SECTION_SIZE_BITS 29 #else # define SECTION_SIZE_BITS 28 diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h index bc14447e69b5..761f2e92119e 100644 --- a/arch/mips/include/asm/time.h +++ b/arch/mips/include/asm/time.h @@ -50,10 +50,8 @@ extern int (*perf_irq)(void); /* * Initialize the calling CPU's compare interrupt as clockevent device */ -#ifdef CONFIG_CEVT_R4K_LIB extern unsigned int __weak get_c0_compare_int(void); extern int r4k_clockevent_init(void); -#endif static inline int mips_clockevent_init(void) { @@ -71,7 +69,7 @@ static inline int mips_clockevent_init(void) /* * Initialize the count register as a clocksource */ -#ifdef CONFIG_CSRC_R4K_LIB +#ifdef CONFIG_CSRC_R4K extern int init_r4k_clocksource(void); #endif diff --git a/arch/mips/include/asm/titan_dep.h b/arch/mips/include/asm/titan_dep.h deleted file mode 100644 index fee1908c65d2..000000000000 --- a/arch/mips/include/asm/titan_dep.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2003 PMC-Sierra - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * - * Board specific definititions for the PMC-Sierra Yosemite - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef __TITAN_DEP_H__ -#define __TITAN_DEP_H__ - -#include <asm/addrspace.h> /* for KSEG1ADDR() */ -#include <asm/byteorder.h> /* for cpu_to_le32() */ - -#define TITAN_READ(ofs) \ - (*(volatile u32 *)(ocd_base+(ofs))) -#define TITAN_READ_16(ofs) \ - (*(volatile u16 *)(ocd_base+(ofs))) -#define TITAN_READ_8(ofs) \ - (*(volatile u8 *)(ocd_base+(ofs))) - -#define TITAN_WRITE(ofs, data) \ - do { *(volatile u32 *)(ocd_base+(ofs)) = (data); } while (0) -#define TITAN_WRITE_16(ofs, data) \ - do { *(volatile u16 *)(ocd_base+(ofs)) = (data); } while (0) -#define TITAN_WRITE_8(ofs, data) \ - do { *(volatile u8 *)(ocd_base+(ofs)) = (data); } while (0) - -/* - * PCI specific defines - */ -#define TITAN_PCI_0_CONFIG_ADDRESS 0x780 -#define TITAN_PCI_0_CONFIG_DATA 0x784 - -/* - * HT specific defines - */ -#define RM9000x2_HTLINK_REG 0xbb000644 -#define RM9000x2_BASE_ADDR 0xbb000000 - -#define OCD_BASE 0xfb000000UL -#define OCD_SIZE 0x3000UL - -extern unsigned long ocd_base; - -/* - * OCD Registers - */ -#define RM9000x2_OCD_LKB5 0x0128 /* Ethernet */ -#define RM9000x2_OCD_LKM5 0x012c - -#define RM9000x2_OCD_LKB7 0x0138 /* HT Region 0 */ -#define RM9000x2_OCD_LKM7 0x013c -#define RM9000x2_OCD_LKB8 0x0140 /* HT Region 1 */ -#define RM9000x2_OCD_LKM8 0x0144 - -#define RM9000x2_OCD_LKB9 0x0148 /* Local Bus */ -#define RM9000x2_OCD_LKM9 0x014c -#define RM9000x2_OCD_LKB10 0x0150 -#define RM9000x2_OCD_LKM10 0x0154 -#define RM9000x2_OCD_LKB11 0x0158 -#define RM9000x2_OCD_LKM11 0x015c -#define RM9000x2_OCD_LKB12 0x0160 -#define RM9000x2_OCD_LKM12 0x0164 - -#define RM9000x2_OCD_LKB13 0x0168 /* Scratch RAM */ -#define RM9000x2_OCD_LKM13 0x016c - -#define RM9000x2_OCD_LPD0 0x0200 /* Local Bus */ -#define RM9000x2_OCD_LPD1 0x0210 -#define RM9000x2_OCD_LPD2 0x0220 -#define RM9000x2_OCD_LPD3 0x0230 - -#define RM9000x2_OCD_HTDVID 0x0600 /* HT Device Header */ -#define RM9000x2_OCD_HTSC 0x0604 -#define RM9000x2_OCD_HTCCR 0x0608 -#define RM9000x2_OCD_HTBHL 0x060c -#define RM9000x2_OCD_HTBAR0 0x0610 -#define RM9000x2_OCD_HTBAR1 0x0614 -#define RM9000x2_OCD_HTBAR2 0x0618 -#define RM9000x2_OCD_HTBAR3 0x061c -#define RM9000x2_OCD_HTBAR4 0x0620 -#define RM9000x2_OCD_HTBAR5 0x0624 -#define RM9000x2_OCD_HTCBCPT 0x0628 -#define RM9000x2_OCD_HTSDVID 0x062c -#define RM9000x2_OCD_HTXRA 0x0630 -#define RM9000x2_OCD_HTCAP1 0x0634 -#define RM9000x2_OCD_HTIL 0x063c - -#define RM9000x2_OCD_HTLCC 0x0640 /* HT Capability Block */ -#define RM9000x2_OCD_HTLINK 0x0644 -#define RM9000x2_OCD_HTFQREV 0x0648 - -#define RM9000x2_OCD_HTERCTL 0x0668 /* HT Controller */ -#define RM9000x2_OCD_HTRXDB 0x066c -#define RM9000x2_OCD_HTIMPED 0x0670 -#define RM9000x2_OCD_HTSWIMP 0x0674 -#define RM9000x2_OCD_HTCAL 0x0678 - -#define RM9000x2_OCD_HTBAA30 0x0680 -#define RM9000x2_OCD_HTBAA54 0x0684 -#define RM9000x2_OCD_HTMASK0 0x0688 -#define RM9000x2_OCD_HTMASK1 0x068c -#define RM9000x2_OCD_HTMASK2 0x0690 -#define RM9000x2_OCD_HTMASK3 0x0694 -#define RM9000x2_OCD_HTMASK4 0x0698 -#define RM9000x2_OCD_HTMASK5 0x069c - -#define RM9000x2_OCD_HTIFCTL 0x06a0 -#define RM9000x2_OCD_HTPLL 0x06a4 - -#define RM9000x2_OCD_HTSRI 0x06b0 -#define RM9000x2_OCD_HTRXNUM 0x06b4 -#define RM9000x2_OCD_HTTXNUM 0x06b8 - -#define RM9000x2_OCD_HTTXCNT 0x06c8 - -#define RM9000x2_OCD_HTERROR 0x06d8 -#define RM9000x2_OCD_HTRCRCE 0x06dc -#define RM9000x2_OCD_HTEOI 0x06e0 - -#define RM9000x2_OCD_CRCR 0x06f0 - -#define RM9000x2_OCD_HTCFGA 0x06f8 -#define RM9000x2_OCD_HTCFGD 0x06fc - -#define RM9000x2_OCD_INTMSG 0x0a00 - -#define RM9000x2_OCD_INTPIN0 0x0a40 -#define RM9000x2_OCD_INTPIN1 0x0a44 -#define RM9000x2_OCD_INTPIN2 0x0a48 -#define RM9000x2_OCD_INTPIN3 0x0a4c -#define RM9000x2_OCD_INTPIN4 0x0a50 -#define RM9000x2_OCD_INTPIN5 0x0a54 -#define RM9000x2_OCD_INTPIN6 0x0a58 -#define RM9000x2_OCD_INTPIN7 0x0a5c -#define RM9000x2_OCD_SEM 0x0a60 -#define RM9000x2_OCD_SEMSET 0x0a64 -#define RM9000x2_OCD_SEMCLR 0x0a68 - -#define RM9000x2_OCD_TKT 0x0a70 -#define RM9000x2_OCD_TKTINC 0x0a74 - -#define RM9000x2_OCD_NMICONFIG 0x0ac0 /* Interrupts */ -#define RM9000x2_OCD_INTP0PRI 0x1a80 -#define RM9000x2_OCD_INTP1PRI 0x1a80 -#define RM9000x2_OCD_INTP0STATUS0 0x1b00 -#define RM9000x2_OCD_INTP0MASK0 0x1b04 -#define RM9000x2_OCD_INTP0SET0 0x1b08 -#define RM9000x2_OCD_INTP0CLEAR0 0x1b0c -#define RM9000x2_OCD_INTP0STATUS1 0x1b10 -#define RM9000x2_OCD_INTP0MASK1 0x1b14 -#define RM9000x2_OCD_INTP0SET1 0x1b18 -#define RM9000x2_OCD_INTP0CLEAR1 0x1b1c -#define RM9000x2_OCD_INTP0STATUS2 0x1b20 -#define RM9000x2_OCD_INTP0MASK2 0x1b24 -#define RM9000x2_OCD_INTP0SET2 0x1b28 -#define RM9000x2_OCD_INTP0CLEAR2 0x1b2c -#define RM9000x2_OCD_INTP0STATUS3 0x1b30 -#define RM9000x2_OCD_INTP0MASK3 0x1b34 -#define RM9000x2_OCD_INTP0SET3 0x1b38 -#define RM9000x2_OCD_INTP0CLEAR3 0x1b3c -#define RM9000x2_OCD_INTP0STATUS4 0x1b40 -#define RM9000x2_OCD_INTP0MASK4 0x1b44 -#define RM9000x2_OCD_INTP0SET4 0x1b48 -#define RM9000x2_OCD_INTP0CLEAR4 0x1b4c -#define RM9000x2_OCD_INTP0STATUS5 0x1b50 -#define RM9000x2_OCD_INTP0MASK5 0x1b54 -#define RM9000x2_OCD_INTP0SET5 0x1b58 -#define RM9000x2_OCD_INTP0CLEAR5 0x1b5c -#define RM9000x2_OCD_INTP0STATUS6 0x1b60 -#define RM9000x2_OCD_INTP0MASK6 0x1b64 -#define RM9000x2_OCD_INTP0SET6 0x1b68 -#define RM9000x2_OCD_INTP0CLEAR6 0x1b6c -#define RM9000x2_OCD_INTP0STATUS7 0x1b70 -#define RM9000x2_OCD_INTP0MASK7 0x1b74 -#define RM9000x2_OCD_INTP0SET7 0x1b78 -#define RM9000x2_OCD_INTP0CLEAR7 0x1b7c -#define RM9000x2_OCD_INTP1STATUS0 0x2b00 -#define RM9000x2_OCD_INTP1MASK0 0x2b04 -#define RM9000x2_OCD_INTP1SET0 0x2b08 -#define RM9000x2_OCD_INTP1CLEAR0 0x2b0c -#define RM9000x2_OCD_INTP1STATUS1 0x2b10 -#define RM9000x2_OCD_INTP1MASK1 0x2b14 -#define RM9000x2_OCD_INTP1SET1 0x2b18 -#define RM9000x2_OCD_INTP1CLEAR1 0x2b1c -#define RM9000x2_OCD_INTP1STATUS2 0x2b20 -#define RM9000x2_OCD_INTP1MASK2 0x2b24 -#define RM9000x2_OCD_INTP1SET2 0x2b28 -#define RM9000x2_OCD_INTP1CLEAR2 0x2b2c -#define RM9000x2_OCD_INTP1STATUS3 0x2b30 -#define RM9000x2_OCD_INTP1MASK3 0x2b34 -#define RM9000x2_OCD_INTP1SET3 0x2b38 -#define RM9000x2_OCD_INTP1CLEAR3 0x2b3c -#define RM9000x2_OCD_INTP1STATUS4 0x2b40 -#define RM9000x2_OCD_INTP1MASK4 0x2b44 -#define RM9000x2_OCD_INTP1SET4 0x2b48 -#define RM9000x2_OCD_INTP1CLEAR4 0x2b4c -#define RM9000x2_OCD_INTP1STATUS5 0x2b50 -#define RM9000x2_OCD_INTP1MASK5 0x2b54 -#define RM9000x2_OCD_INTP1SET5 0x2b58 -#define RM9000x2_OCD_INTP1CLEAR5 0x2b5c -#define RM9000x2_OCD_INTP1STATUS6 0x2b60 -#define RM9000x2_OCD_INTP1MASK6 0x2b64 -#define RM9000x2_OCD_INTP1SET6 0x2b68 -#define RM9000x2_OCD_INTP1CLEAR6 0x2b6c -#define RM9000x2_OCD_INTP1STATUS7 0x2b70 -#define RM9000x2_OCD_INTP1MASK7 0x2b74 -#define RM9000x2_OCD_INTP1SET7 0x2b78 -#define RM9000x2_OCD_INTP1CLEAR7 0x2b7c - -#define OCD_READ(reg) (*(volatile unsigned int *)(ocd_base + (reg))) -#define OCD_WRITE(reg, val) \ - do { *(volatile unsigned int *)(ocd_base + (reg)) = (val); } while (0) - -/* - * Hypertransport specific macros - */ -#define RM9K_WRITE(ofs, data) *(volatile u_int32_t *)(RM9000x2_BASE_ADDR+ofs) = data -#define RM9K_WRITE_8(ofs, data) *(volatile u8 *)(RM9000x2_BASE_ADDR+ofs) = data -#define RM9K_WRITE_16(ofs, data) *(volatile u16 *)(RM9000x2_BASE_ADDR+ofs) = data - -#define RM9K_READ(ofs, val) *(val) = *(volatile u_int32_t *)(RM9000x2_BASE_ADDR+ofs) -#define RM9K_READ_8(ofs, val) *(val) = *(volatile u8 *)(RM9000x2_BASE_ADDR+ofs) -#define RM9K_READ_16(ofs, val) *(val) = *(volatile u16 *)(RM9000x2_BASE_ADDR+ofs) - -#endif diff --git a/arch/mips/include/asm/war.h b/arch/mips/include/asm/war.h index fa133c1bc1f9..65e344532ded 100644 --- a/arch/mips/include/asm/war.h +++ b/arch/mips/include/asm/war.h @@ -209,14 +209,6 @@ #endif /* - * On the RM9000 there is a problem which makes the CreateDirtyExclusive - * eache operation unusable on SMP systems. - */ -#ifndef RM9000_CDEX_SMP_WAR -#error Check setting of RM9000_CDEX_SMP_WAR for your platform -#endif - -/* * The RM7000 processors and the E9000 cores have a bug (though PMC-Sierra * opposes it being called that) where invalid instructions in the same * I-cache line worth of instructions being fetched may case spurious diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 8b28bc4e14ea..007c33d73715 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -16,7 +16,7 @@ CFLAGS_REMOVE_perf_event_mipsxx.o = -pg endif obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o -obj-$(CONFIG_CEVT_R4K_LIB) += cevt-r4k.o +obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o obj-$(CONFIG_MIPS_MT_SMTC) += cevt-smtc.o obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o @@ -25,7 +25,7 @@ obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o obj-$(CONFIG_CSRC_POWERTV) += csrc-powertv.o -obj-$(CONFIG_CSRC_R4K_LIB) += csrc-r4k.o +obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o obj-$(CONFIG_SYNC_R4K) += sync-r4k.o @@ -58,7 +58,6 @@ obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o obj-$(CONFIG_I8259) += i8259.o obj-$(CONFIG_IRQ_CPU) += irq_cpu.o obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o -obj-$(CONFIG_IRQ_CPU_RM9K) += irq-rm9000.o obj-$(CONFIG_MIPS_MSC) += irq-msc01.o obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o @@ -80,7 +79,8 @@ obj-$(CONFIG_I8253) += i8253.o obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o -obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o +obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o +obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_SPINLOCK_TEST) += spinlock_test.o obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 0c4bce4882a6..9690998d4ef3 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c @@ -125,10 +125,6 @@ void output_thread_defines(void) thread.cp0_baduaddr); OFFSET(THREAD_ECODE, task_struct, \ thread.error_code); - OFFSET(THREAD_TRAMP, task_struct, \ - thread.irix_trampoline); - OFFSET(THREAD_OLDCTX, task_struct, \ - thread.irix_oldctx); BLANK(); } diff --git a/arch/mips/kernel/crash.c b/arch/mips/kernel/crash.c new file mode 100644 index 000000000000..0f53c39324bb --- /dev/null +++ b/arch/mips/kernel/crash.c @@ -0,0 +1,71 @@ +#include <linux/kernel.h> +#include <linux/smp.h> +#include <linux/reboot.h> +#include <linux/kexec.h> +#include <linux/bootmem.h> +#include <linux/crash_dump.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/types.h> +#include <linux/sched.h> + +/* This keeps a track of which one is crashing cpu. */ +static int crashing_cpu = -1; +static cpumask_t cpus_in_crash = CPU_MASK_NONE; + +#ifdef CONFIG_SMP +static void crash_shutdown_secondary(void *ignore) +{ + struct pt_regs *regs; + int cpu = smp_processor_id(); + + regs = task_pt_regs(current); + + if (!cpu_online(cpu)) + return; + + local_irq_disable(); + if (!cpu_isset(cpu, cpus_in_crash)) + crash_save_cpu(regs, cpu); + cpu_set(cpu, cpus_in_crash); + + while (!atomic_read(&kexec_ready_to_reboot)) + cpu_relax(); + relocated_kexec_smp_wait(NULL); + /* NOTREACHED */ +} + +static void crash_kexec_prepare_cpus(void) +{ + unsigned int msecs; + + unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ + + dump_send_ipi(crash_shutdown_secondary); + smp_wmb(); + + /* + * The crash CPU sends an IPI and wait for other CPUs to + * respond. Delay of at least 10 seconds. + */ + pr_emerg("Sending IPI to other cpus...\n"); + msecs = 10000; + while ((cpus_weight(cpus_in_crash) < ncpus) && (--msecs > 0)) { + cpu_relax(); + mdelay(1); + } +} + +#else /* !defined(CONFIG_SMP) */ +static void crash_kexec_prepare_cpus(void) {} +#endif /* !defined(CONFIG_SMP) */ + +void default_machine_crash_shutdown(struct pt_regs *regs) +{ + local_irq_disable(); + crashing_cpu = smp_processor_id(); + crash_save_cpu(regs, crashing_cpu); + crash_kexec_prepare_cpus(); + cpu_set(crashing_cpu, cpus_in_crash); +} diff --git a/arch/mips/kernel/crash_dump.c b/arch/mips/kernel/crash_dump.c new file mode 100644 index 000000000000..35bed0d2342c --- /dev/null +++ b/arch/mips/kernel/crash_dump.c @@ -0,0 +1,75 @@ +#include <linux/highmem.h> +#include <linux/bootmem.h> +#include <linux/crash_dump.h> +#include <asm/uaccess.h> + +static int __init parse_savemaxmem(char *p) +{ + if (p) + saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1; + + return 1; +} +__setup("savemaxmem=", parse_savemaxmem); + + +static void *kdump_buf_page; + +/** + * copy_oldmem_page - copy one page from "oldmem" + * @pfn: page frame number to be copied + * @buf: target memory address for the copy; this can be in kernel address + * space or user address space (see @userbuf) + * @csize: number of bytes to copy + * @offset: offset in bytes into the page (based on pfn) to begin the copy + * @userbuf: if set, @buf is in user address space, use copy_to_user(), + * otherwise @buf is in kernel address space, use memcpy(). + * + * Copy a page from "oldmem". For this page, there is no pte mapped + * in the current kernel. + * + * Calling copy_to_user() in atomic context is not desirable. Hence first + * copying the data to a pre-allocated kernel page and then copying to user + * space in non-atomic context. + */ +ssize_t copy_oldmem_page(unsigned long pfn, char *buf, + size_t csize, unsigned long offset, int userbuf) +{ + void *vaddr; + + if (!csize) + return 0; + + vaddr = kmap_atomic_pfn(pfn); + + if (!userbuf) { + memcpy(buf, (vaddr + offset), csize); + kunmap_atomic(vaddr); + } else { + if (!kdump_buf_page) { + pr_warning("Kdump: Kdump buffer page not allocated\n"); + + return -EFAULT; + } + copy_page(kdump_buf_page, vaddr); + kunmap_atomic(vaddr); + if (copy_to_user(buf, (kdump_buf_page + offset), csize)) + return -EFAULT; + } + + return csize; +} + +static int __init kdump_buf_page_init(void) +{ + int ret = 0; + + kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!kdump_buf_page) { + pr_warning("Kdump: Failed to allocate kdump buffer page\n"); + ret = -ENOMEM; + } + + return ret; +} +arch_initcall(kdump_buf_page_init); diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c deleted file mode 100644 index 1282b9ae81c4..000000000000 --- a/arch/mips/kernel/irq-rm9000.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2003 Ralf Baechle - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Handler for RM9000 extended interrupts. These are a non-standard - * feature so we handle them separately from standard interrupts. - */ -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/kernel.h> -#include <linux/module.h> - -#include <asm/irq_cpu.h> -#include <asm/mipsregs.h> - -static inline void unmask_rm9k_irq(struct irq_data *d) -{ - set_c0_intcontrol(0x1000 << (d->irq - RM9K_CPU_IRQ_BASE)); -} - -static inline void mask_rm9k_irq(struct irq_data *d) -{ - clear_c0_intcontrol(0x1000 << (d->irq - RM9K_CPU_IRQ_BASE)); -} - -static inline void rm9k_cpu_irq_enable(struct irq_data *d) -{ - unsigned long flags; - - local_irq_save(flags); - unmask_rm9k_irq(d); - local_irq_restore(flags); -} - -/* - * Performance counter interrupts are global on all processors. - */ -static void local_rm9k_perfcounter_irq_startup(void *args) -{ - rm9k_cpu_irq_enable(args); -} - -static unsigned int rm9k_perfcounter_irq_startup(struct irq_data *d) -{ - on_each_cpu(local_rm9k_perfcounter_irq_startup, d, 1); - - return 0; -} - -static void local_rm9k_perfcounter_irq_shutdown(void *args) -{ - unsigned long flags; - - local_irq_save(flags); - mask_rm9k_irq(args); - local_irq_restore(flags); -} - -static void rm9k_perfcounter_irq_shutdown(struct irq_data *d) -{ - on_each_cpu(local_rm9k_perfcounter_irq_shutdown, d, 1); -} - -static struct irq_chip rm9k_irq_controller = { - .name = "RM9000", - .irq_ack = mask_rm9k_irq, - .irq_mask = mask_rm9k_irq, - .irq_mask_ack = mask_rm9k_irq, - .irq_unmask = unmask_rm9k_irq, - .irq_eoi = unmask_rm9k_irq -}; - -static struct irq_chip rm9k_perfcounter_irq = { - .name = "RM9000", - .irq_startup = rm9k_perfcounter_irq_startup, - .irq_shutdown = rm9k_perfcounter_irq_shutdown, - .irq_ack = mask_rm9k_irq, - .irq_mask = mask_rm9k_irq, - .irq_mask_ack = mask_rm9k_irq, - .irq_unmask = unmask_rm9k_irq, -}; - -unsigned int rm9000_perfcount_irq; - -EXPORT_SYMBOL(rm9000_perfcount_irq); - -void __init rm9k_cpu_irq_init(void) -{ - int base = RM9K_CPU_IRQ_BASE; - int i; - - clear_c0_intcontrol(0x0000f000); /* Mask all */ - - for (i = base; i < base + 4; i++) - irq_set_chip_and_handler(i, &rm9k_irq_controller, - handle_level_irq); - - rm9000_perfcount_irq = base + 1; - irq_set_chip_and_handler(rm9000_perfcount_irq, &rm9k_perfcounter_irq, - handle_percpu_irq); -} diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c index 85beb9b0b2d0..992e18474da5 100644 --- a/arch/mips/kernel/machine_kexec.c +++ b/arch/mips/kernel/machine_kexec.c @@ -5,7 +5,7 @@ * This source code is licensed under the GNU General Public License, * Version 2. See the file COPYING for more details. */ - +#include <linux/compiler.h> #include <linux/kexec.h> #include <linux/mm.h> #include <linux/delay.h> @@ -19,9 +19,19 @@ extern const size_t relocate_new_kernel_size; extern unsigned long kexec_start_address; extern unsigned long kexec_indirection_page; +int (*_machine_kexec_prepare)(struct kimage *) = NULL; +void (*_machine_kexec_shutdown)(void) = NULL; +void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL; +#ifdef CONFIG_SMP +void (*relocated_kexec_smp_wait) (void *); +atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0); +#endif + int machine_kexec_prepare(struct kimage *kimage) { + if (_machine_kexec_prepare) + return _machine_kexec_prepare(kimage); return 0; } @@ -33,14 +43,20 @@ machine_kexec_cleanup(struct kimage *kimage) void machine_shutdown(void) { + if (_machine_kexec_shutdown) + _machine_kexec_shutdown(); } void machine_crash_shutdown(struct pt_regs *regs) { + if (_machine_crash_shutdown) + _machine_crash_shutdown(regs); + else + default_machine_crash_shutdown(regs); } -typedef void (*noretfun_t)(void) __attribute__((noreturn)); +typedef void (*noretfun_t)(void) __noreturn; void machine_kexec(struct kimage *image) @@ -52,7 +68,9 @@ machine_kexec(struct kimage *image) reboot_code_buffer = (unsigned long)page_address(image->control_code_page); - kexec_start_address = image->start; + kexec_start_address = + (unsigned long) phys_to_virt(image->start); + kexec_indirection_page = (unsigned long) phys_to_virt(image->head & PAGE_MASK); @@ -63,7 +81,7 @@ machine_kexec(struct kimage *image) * The generic kexec code builds a page list with physical * addresses. they are directly accessible through KSEG0 (or * CKSEG0 or XPHYS if on 64bit system), hence the - * pys_to_virt() call. + * phys_to_virt() call. */ for (ptr = &image->head; (entry = *ptr) && !(entry &IND_DONE); ptr = (entry & IND_INDIRECTION) ? @@ -81,5 +99,12 @@ machine_kexec(struct kimage *image) printk("Will call new kernel at %08lx\n", image->start); printk("Bye ...\n"); __flush_cache_all(); +#ifdef CONFIG_SMP + /* All secondary cpus now may jump to kexec_wait cycle */ + relocated_kexec_smp_wait = reboot_code_buffer + + (void *)(kexec_smp_wait - relocate_new_kernel); + smp_wmb(); + atomic_set(&kexec_ready_to_reboot, 1); +#endif ((noretfun_t) reboot_code_buffer)(); } diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c index 33f63bab478a..fd814e08c945 100644 --- a/arch/mips/kernel/mips-mt-fpaff.c +++ b/arch/mips/kernel/mips-mt-fpaff.c @@ -50,8 +50,8 @@ static bool check_same_owner(struct task_struct *p) rcu_read_lock(); pcred = __task_cred(p); - match = (cred->euid == pcred->euid || - cred->euid == pcred->uid); + match = (uid_eq(cred->euid, pcred->euid) || + uid_eq(cred->euid, pcred->uid)); rcu_read_unlock(); return match; } diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index 2d9304c2b54c..df1e3e455f9a 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c @@ -11,7 +11,7 @@ #include <linux/interrupt.h> #include <linux/export.h> #include <asm/checksum.h> -#include <asm/pgtable.h> +#include <linux/mm.h> #include <asm/uaccess.h> #include <asm/ftrace.h> diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index a9b995dcf691..b14c14d90fc2 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c @@ -840,6 +840,16 @@ static const struct mips_perf_event bmips5000_event_map [PERF_COUNT_HW_BRANCH_MISSES] = { 0x02, CNTR_ODD, T }, }; +static const struct mips_perf_event xlp_event_map[PERF_COUNT_HW_MAX] = { + [PERF_COUNT_HW_CPU_CYCLES] = { 0x01, CNTR_ALL }, + [PERF_COUNT_HW_INSTRUCTIONS] = { 0x18, CNTR_ALL }, /* PAPI_TOT_INS */ + [PERF_COUNT_HW_CACHE_REFERENCES] = { 0x04, CNTR_ALL }, /* PAPI_L1_ICA */ + [PERF_COUNT_HW_CACHE_MISSES] = { 0x07, CNTR_ALL }, /* PAPI_L1_ICM */ + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x1b, CNTR_ALL }, /* PAPI_BR_CN */ + [PERF_COUNT_HW_BRANCH_MISSES] = { 0x1c, CNTR_ALL }, /* PAPI_BR_MSP */ + [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID }, +}; + /* 24K/34K/1004K cores can share the same cache event map. */ static const struct mips_perf_event mipsxxcore_cache_map [PERF_COUNT_HW_CACHE_MAX] @@ -1092,6 +1102,100 @@ static const struct mips_perf_event octeon_cache_map }, }; +static const struct mips_perf_event xlp_cache_map + [PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] = { +[C(L1D)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = { 0x31, CNTR_ALL }, /* PAPI_L1_DCR */ + [C(RESULT_MISS)] = { 0x30, CNTR_ALL }, /* PAPI_L1_LDM */ + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = { 0x2f, CNTR_ALL }, /* PAPI_L1_DCW */ + [C(RESULT_MISS)] = { 0x2e, CNTR_ALL }, /* PAPI_L1_STM */ + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, + }, +}, +[C(L1I)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = { 0x04, CNTR_ALL }, /* PAPI_L1_ICA */ + [C(RESULT_MISS)] = { 0x07, CNTR_ALL }, /* PAPI_L1_ICM */ + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, + }, +}, +[C(LL)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = { 0x35, CNTR_ALL }, /* PAPI_L2_DCR */ + [C(RESULT_MISS)] = { 0x37, CNTR_ALL }, /* PAPI_L2_LDM */ + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = { 0x34, CNTR_ALL }, /* PAPI_L2_DCA */ + [C(RESULT_MISS)] = { 0x36, CNTR_ALL }, /* PAPI_L2_DCM */ + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, + }, +}, +[C(DTLB)] = { + /* + * Only general DTLB misses are counted use the same event for + * read and write. + */ + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, + [C(RESULT_MISS)] = { 0x2d, CNTR_ALL }, /* PAPI_TLB_DM */ + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, + [C(RESULT_MISS)] = { 0x2d, CNTR_ALL }, /* PAPI_TLB_DM */ + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, + }, +}, +[C(ITLB)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, + [C(RESULT_MISS)] = { 0x08, CNTR_ALL }, /* PAPI_TLB_IM */ + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, + [C(RESULT_MISS)] = { 0x08, CNTR_ALL }, /* PAPI_TLB_IM */ + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, + }, +}, +[C(BPU)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, + [C(RESULT_MISS)] = { 0x25, CNTR_ALL }, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID }, + [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID }, + }, +}, +}; + #ifdef CONFIG_MIPS_MT_SMP static void check_and_calc_range(struct perf_event *event, const struct mips_perf_event *pev) @@ -1444,6 +1548,20 @@ static const struct mips_perf_event *octeon_pmu_map_raw_event(u64 config) return &raw_event; } +static const struct mips_perf_event *xlp_pmu_map_raw_event(u64 config) +{ + unsigned int raw_id = config & 0xff; + + /* Only 1-63 are defined */ + if ((raw_id < 0x01) || (raw_id > 0x3f)) + return ERR_PTR(-EOPNOTSUPP); + + raw_event.cntr_mask = CNTR_ALL; + raw_event.event_id = raw_id; + + return &raw_event; +} + static int __init init_hw_perf_events(void) { @@ -1522,6 +1640,12 @@ init_hw_perf_events(void) mipspmu.general_event_map = &bmips5000_event_map; mipspmu.cache_event_map = &bmips5000_cache_map; break; + case CPU_XLP: + mipspmu.name = "xlp"; + mipspmu.general_event_map = &xlp_event_map; + mipspmu.cache_event_map = &xlp_cache_map; + mipspmu.map_raw_event = xlp_pmu_map_raw_event; + break; default: pr_cont("Either hardware does not support performance " "counters, or not yet implemented.\n"); diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 38097652d62d..a11c6f9fdd5e 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -72,9 +72,7 @@ void __noreturn cpu_idle(void) } } #ifdef CONFIG_HOTPLUG_CPU - if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) && - (system_state == SYSTEM_RUNNING || - system_state == SYSTEM_BOOTING)) + if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map)) play_dead(); #endif rcu_idle_exit(); diff --git a/arch/mips/kernel/relocate_kernel.S b/arch/mips/kernel/relocate_kernel.S index 87481f916a61..e4142c5f7c2b 100644 --- a/arch/mips/kernel/relocate_kernel.S +++ b/arch/mips/kernel/relocate_kernel.S @@ -15,6 +15,11 @@ #include <asm/addrspace.h> LEAF(relocate_new_kernel) + PTR_L a0, arg0 + PTR_L a1, arg1 + PTR_L a2, arg2 + PTR_L a3, arg3 + PTR_L s0, kexec_indirection_page PTR_L s1, kexec_start_address @@ -26,7 +31,6 @@ process_entry: and s3, s2, 0x1 beq s3, zero, 1f and s4, s2, ~0x1 /* store destination addr in s4 */ - move a0, s4 b process_entry 1: @@ -60,10 +64,111 @@ copy_word: b process_entry done: +#ifdef CONFIG_SMP + /* kexec_flag reset is signal to other CPUs what kernel + was moved to it's location. Note - we need relocated address + of kexec_flag. */ + + bal 1f + 1: move t1,ra; + PTR_LA t2,1b + PTR_LA t0,kexec_flag + PTR_SUB t0,t0,t2; + PTR_ADD t0,t1,t0; + LONG_S zero,(t0) +#endif + +#ifdef CONFIG_CPU_CAVIUM_OCTEON + /* We need to flush I-cache before jumping to new kernel. + * Unfortunatelly, this code is cpu-specific. + */ + .set push + .set noreorder + syncw + syncw + synci 0($0) + .set pop +#else + sync +#endif /* jump to kexec_start_address */ j s1 END(relocate_new_kernel) +#ifdef CONFIG_SMP +/* + * Other CPUs should wait until code is relocated and + * then start at entry (?) point. + */ +LEAF(kexec_smp_wait) + PTR_L a0, s_arg0 + PTR_L a1, s_arg1 + PTR_L a2, s_arg2 + PTR_L a3, s_arg3 + PTR_L s1, kexec_start_address + + /* Non-relocated address works for args and kexec_start_address ( old + * kernel is not overwritten). But we need relocated address of + * kexec_flag. + */ + + bal 1f +1: move t1,ra; + PTR_LA t2,1b + PTR_LA t0,kexec_flag + PTR_SUB t0,t0,t2; + PTR_ADD t0,t1,t0; + +1: LONG_L s0, (t0) + bne s0, zero,1b + +#ifdef CONFIG_CPU_CAVIUM_OCTEON + .set push + .set noreorder + synci 0($0) + .set pop +#else + sync +#endif + j s1 + END(kexec_smp_wait) +#endif + +#ifdef __mips64 + /* all PTR's must be aligned to 8 byte in 64-bit mode */ + .align 3 +#endif + +/* All parameters to new kernel are passed in registers a0-a3. + * kexec_args[0..3] are uses to prepare register values. + */ + +kexec_args: + EXPORT(kexec_args) +arg0: PTR 0x0 +arg1: PTR 0x0 +arg2: PTR 0x0 +arg3: PTR 0x0 + .size kexec_args,PTRSIZE*4 + +#ifdef CONFIG_SMP +/* + * Secondary CPUs may have different kernel parameters in + * their registers a0-a3. secondary_kexec_args[0..3] are used + * to prepare register values. + */ +secondary_kexec_args: + EXPORT(secondary_kexec_args) +s_arg0: PTR 0x0 +s_arg1: PTR 0x0 +s_arg2: PTR 0x0 +s_arg3: PTR 0x0 + .size secondary_kexec_args,PTRSIZE*4 +kexec_flag: + LONG 0x1 + +#endif + kexec_start_address: EXPORT(kexec_start_address) PTR 0x0 diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 629719143763..ad3de9668da9 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -17,12 +17,6 @@ #include <asm/thread_info.h> #include <asm/unistd.h> -/* This duplicates the definition from <linux/sched.h> */ -#define PT_TRACESYS 0x00000002 /* tracing system calls */ - -/* This duplicates the definition from <asm/signal.h> */ -#define SIGILL 4 /* Illegal instruction (ANSI). */ - #ifndef CONFIG_MIPS32_O32 /* No O32, so define handle_sys here */ #define handle_sysn32 handle_sys diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 290dc6a1d7a3..8c41187801ce 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -22,6 +22,7 @@ #include <linux/console.h> #include <linux/pfn.h> #include <linux/debugfs.h> +#include <linux/kexec.h> #include <asm/addrspace.h> #include <asm/bootinfo.h> @@ -536,12 +537,64 @@ static void __init arch_mem_init(char **cmdline_p) } bootmem_init(); +#ifdef CONFIG_KEXEC + if (crashk_res.start != crashk_res.end) + reserve_bootmem(crashk_res.start, + crashk_res.end - crashk_res.start + 1, + BOOTMEM_DEFAULT); +#endif device_tree_init(); sparse_init(); plat_swiotlb_setup(); paging_init(); } +#ifdef CONFIG_KEXEC +static inline unsigned long long get_total_mem(void) +{ + unsigned long long total; + + total = max_pfn - min_low_pfn; + return total << PAGE_SHIFT; +} + +static void __init mips_parse_crashkernel(void) +{ + unsigned long long total_mem; + unsigned long long crash_size, crash_base; + int ret; + + total_mem = get_total_mem(); + ret = parse_crashkernel(boot_command_line, total_mem, + &crash_size, &crash_base); + if (ret != 0 || crash_size <= 0) + return; + + crashk_res.start = crash_base; + crashk_res.end = crash_base + crash_size - 1; +} + +static void __init request_crashkernel(struct resource *res) +{ + int ret; + + ret = request_resource(res, &crashk_res); + if (!ret) + pr_info("Reserving %ldMB of memory at %ldMB for crashkernel\n", + (unsigned long)((crashk_res.end - + crashk_res.start + 1) >> 20), + (unsigned long)(crashk_res.start >> 20)); +} +#else /* !defined(CONFIG_KEXEC) */ +static void __init mips_parse_crashkernel(void) +{ +} + +static void __init request_crashkernel(struct resource *res) +{ +} +#endif /* !defined(CONFIG_KEXEC) */ + static void __init resource_init(void) { int i; @@ -557,6 +610,8 @@ static void __init resource_init(void) /* * Request address space for all standard RAM. */ + mips_parse_crashkernel(); + for (i = 0; i < boot_mem_map.nr_map; i++) { struct resource *res; unsigned long start, end; @@ -593,6 +648,7 @@ static void __init resource_init(void) */ request_resource(res, &code_resource); request_resource(res, &data_resource); + request_crashkernel(res); } } diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 0e1a5b8ae817..b6aa77035019 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -568,17 +568,20 @@ static void do_signal(struct pt_regs *regs) } if (regs->regs[0]) { - if (regs->regs[2] == ERESTARTNOHAND || - regs->regs[2] == ERESTARTSYS || - regs->regs[2] == ERESTARTNOINTR) { + switch (regs->regs[2]) { + case ERESTARTNOHAND: + case ERESTARTSYS: + case ERESTARTNOINTR: regs->regs[2] = regs->regs[0]; regs->regs[7] = regs->regs[26]; regs->cp0_epc -= 4; - } - if (regs->regs[2] == ERESTART_RESTARTBLOCK) { + break; + + case ERESTART_RESTARTBLOCK: regs->regs[2] = current->thread.abi->restart; regs->regs[7] = regs->regs[26]; regs->cp0_epc -= 4; + break; } regs->regs[0] = 0; /* Don't deal with this again. */ } diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 9005bf9fb859..2e6374a589ec 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -386,3 +386,20 @@ void flush_tlb_one(unsigned long vaddr) EXPORT_SYMBOL(flush_tlb_page); EXPORT_SYMBOL(flush_tlb_one); + +#if defined(CONFIG_KEXEC) +void (*dump_ipi_function_ptr)(void *) = NULL; +void dump_send_ipi(void (*dump_ipi_callback)(void *)) +{ + int i; + int cpu = smp_processor_id(); + + dump_ipi_function_ptr = dump_ipi_callback; + smp_mb(); + for_each_online_cpu(i) + if (i != cpu) + mp_ops->send_ipi_single(i, SMP_DUMP); + +} +EXPORT_SYMBOL(dump_send_ipi); +#endif diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 9be3df1fa8a4..cf7ac5483f53 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -13,6 +13,7 @@ */ #include <linux/bug.h> #include <linux/compiler.h> +#include <linux/kexec.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> @@ -409,6 +410,9 @@ void __noreturn die(const char *str, struct pt_regs *regs) panic("Fatal exception"); } + if (regs && kexec_should_crash(current)) + crash_kexec(regs); + do_exit(sig); } @@ -1021,6 +1025,24 @@ asmlinkage void do_cpu(struct pt_regs *regs) return; + case 3: + /* + * Old (MIPS I and MIPS II) processors will set this code + * for COP1X opcode instructions that replaced the original + * COP3 space. We don't limit COP1 space instructions in + * the emulator according to the CPU ISA, so we want to + * treat COP1X instructions consistently regardless of which + * code the CPU chose. Therefore we redirect this trap to + * the FP emulator too. + * + * Then some newer FPU-less processors use this code + * erroneously too, so they are covered by this choice + * as well. + */ + if (raw_cpu_has_fpu) + break; + /* Fall through. */ + case 1: if (used_math()) /* Using the FPU again. */ own_fpu(1); @@ -1044,9 +1066,6 @@ asmlinkage void do_cpu(struct pt_regs *regs) case 2: raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs); return; - - case 3: - break; } force_sig(SIGILL, current); diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig index d84f361f1e45..c0021912131e 100644 --- a/arch/mips/lantiq/Kconfig +++ b/arch/mips/lantiq/Kconfig @@ -36,4 +36,8 @@ config PCI_LANTIQ bool "PCI Support" depends on SOC_XWAY && PCI +config XRX200_PHY_FW + bool "XRX200 PHY firmware loader" + depends on SOC_XWAY + endif diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index 6cfd6117fbfd..9f9e875967aa 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c @@ -87,9 +87,6 @@ void __init device_tree_init(void) reserve_bootmem(base, size, BOOTMEM_DEFAULT); unflatten_device_tree(); - - /* free the space reserved for the dt blob */ - free_bootmem(base, size); } void __init prom_init(void) @@ -119,7 +116,7 @@ int __init plat_of_setup(void) sizeof(of_ids[0].compatible)); strncpy(of_ids[1].compatible, "simple-bus", sizeof(of_ids[1].compatible)); - return of_platform_bus_probe(NULL, of_ids, NULL); + return of_platform_populate(NULL, of_ids, NULL, NULL); } arch_initcall(plat_of_setup); diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile index 70a58c747bd0..7a13660d630d 100644 --- a/arch/mips/lantiq/xway/Makefile +++ b/arch/mips/lantiq/xway/Makefile @@ -1 +1,3 @@ obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o + +obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c index 55d2c4fa4714..6453962ac898 100644 --- a/arch/mips/lantiq/xway/dma.c +++ b/arch/mips/lantiq/xway/dma.c @@ -25,6 +25,7 @@ #include <lantiq_soc.h> #include <xway_dma.h> +#define LTQ_DMA_ID 0x08 #define LTQ_DMA_CTRL 0x10 #define LTQ_DMA_CPOLL 0x14 #define LTQ_DMA_CS 0x18 @@ -48,7 +49,7 @@ #define DMA_CLK_DIV4 BIT(6) /* polling clock divider */ #define DMA_2W_BURST BIT(1) /* 2 word burst length */ #define DMA_MAX_CHANNEL 20 /* the soc has 20 channels */ -#define DMA_ETOP_ENDIANESS (0xf << 8) /* endianess swap etop channels */ +#define DMA_ETOP_ENDIANNESS (0xf << 8) /* endianness swap etop channels */ #define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */ #define ltq_dma_r32(x) ltq_r32(ltq_dma_membase + (x)) @@ -191,10 +192,10 @@ ltq_dma_init_port(int p) switch (p) { case DMA_PORT_ETOP: /* - * Tell the DMA engine to swap the endianess of data frames and + * Tell the DMA engine to swap the endianness of data frames and * drop packets if the channel arbitration fails. */ - ltq_dma_w32_mask(0, DMA_ETOP_ENDIANESS | DMA_PDEN, + ltq_dma_w32_mask(0, DMA_ETOP_ENDIANNESS | DMA_PDEN, LTQ_DMA_PCTRL); break; @@ -214,6 +215,7 @@ ltq_dma_init(struct platform_device *pdev) { struct clk *clk; struct resource *res; + unsigned id; int i; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -243,7 +245,12 @@ ltq_dma_init(struct platform_device *pdev) ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL); ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); } - dev_info(&pdev->dev, "init done\n"); + + id = ltq_dma_r32(LTQ_DMA_ID); + dev_info(&pdev->dev, + "Init done - hw rev: %X, ports: %d, channels: %d\n", + id & 0x1f, (id >> 16) & 0xf, id >> 20); + return 0; } diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c index 22c55f73aa9d..544dbb7fb421 100644 --- a/arch/mips/lantiq/xway/reset.c +++ b/arch/mips/lantiq/xway/reset.c @@ -28,17 +28,24 @@ #define RCU_RST_REQ 0x0010 /* reset status register */ #define RCU_RST_STAT 0x0014 +/* vr9 gphy registers */ +#define RCU_GFS_ADD0_XRX200 0x0020 +#define RCU_GFS_ADD1_XRX200 0x0068 /* reboot bit */ +#define RCU_RD_GPHY0_XRX200 BIT(31) #define RCU_RD_SRST BIT(30) +#define RCU_RD_GPHY1_XRX200 BIT(29) + /* reset cause */ #define RCU_STAT_SHIFT 26 /* boot selection */ -#define RCU_BOOT_SEL_SHIFT 26 -#define RCU_BOOT_SEL_MASK 0x7 +#define RCU_BOOT_SEL(x) ((x >> 18) & 0x7) +#define RCU_BOOT_SEL_XRX200(x) (((x >> 17) & 0xf) | ((x >> 8) & 0x10)) /* remapped base addr of the reset control unit */ static void __iomem *ltq_rcu_membase; +static struct device_node *ltq_rcu_np; /* This function is used by the watchdog driver */ int ltq_reset_cause(void) @@ -52,7 +59,41 @@ EXPORT_SYMBOL_GPL(ltq_reset_cause); unsigned char ltq_boot_select(void) { u32 val = ltq_rcu_r32(RCU_RST_STAT); - return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK; + + if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) + return RCU_BOOT_SEL_XRX200(val); + + return RCU_BOOT_SEL(val); +} + +/* reset / boot a gphy */ +static struct ltq_xrx200_gphy_reset { + u32 rd; + u32 addr; +} xrx200_gphy[] = { + {RCU_RD_GPHY0_XRX200, RCU_GFS_ADD0_XRX200}, + {RCU_RD_GPHY1_XRX200, RCU_GFS_ADD1_XRX200}, +}; + +/* reset and boot a gphy. these phys only exist on xrx200 SoC */ +int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr) +{ + if (!of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) { + dev_err(dev, "this SoC has no GPHY\n"); + return -EINVAL; + } + if (id > 1) { + dev_err(dev, "%u is an invalid gphy id\n", id); + return -EINVAL; + } + dev_info(dev, "booting GPHY%u firmware at %X\n", id, dev_addr); + + ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | xrx200_gphy[id].rd, + RCU_RST_REQ); + ltq_rcu_w32(dev_addr, xrx200_gphy[id].addr); + ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~xrx200_gphy[id].rd, + RCU_RST_REQ); + return 0; } /* reset a io domain for u micro seconds */ @@ -85,14 +126,17 @@ static void ltq_machine_power_off(void) static int __init mips_reboot_setup(void) { struct resource res; - struct device_node *np = - of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway"); + + ltq_rcu_np = of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway"); + if (!ltq_rcu_np) + ltq_rcu_np = of_find_compatible_node(NULL, NULL, + "lantiq,rcu-xrx200"); /* check if all the reset register range is available */ - if (!np) + if (!ltq_rcu_np) panic("Failed to load reset resources from devicetree"); - if (of_address_to_resource(np, 0, &res)) + if (of_address_to_resource(ltq_rcu_np, 0, &res)) panic("Failed to get rcu memory range"); if (request_mem_region(res.start, resource_size(&res), res.name) < 0) diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index 2917b56b6b25..3925e6609acc 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c @@ -370,6 +370,10 @@ void __init ltq_soc_init(void) clkdev_add_pmu("1d900000.pcie", "pdi", 1, PMU1_PCIE_PDI); clkdev_add_pmu("1d900000.pcie", "ctl", 1, PMU1_PCIE_CTL); clkdev_add_pmu("1d900000.pcie", "ahb", 0, PMU_AHBM | PMU_AHBS); + clkdev_add_pmu("1e108000.eth", NULL, 0, + PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM | + PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 | + PMU_PPE_QSB | PMU_PPE_TOP); } else if (of_machine_is_compatible("lantiq,ar9")) { clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(), ltq_ar9_fpi_hz()); diff --git a/arch/mips/lantiq/xway/xrx200_phy_fw.c b/arch/mips/lantiq/xway/xrx200_phy_fw.c new file mode 100644 index 000000000000..fe808bf5366d --- /dev/null +++ b/arch/mips/lantiq/xway/xrx200_phy_fw.c @@ -0,0 +1,97 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * Copyright (C) 2012 John Crispin <blogic@openwrt.org> + */ + +#include <linux/delay.h> +#include <linux/dma-mapping.h> +#include <linux/module.h> +#include <linux/firmware.h> +#include <linux/of_platform.h> + +#include <lantiq_soc.h> + +#define XRX200_GPHY_FW_ALIGN (16 * 1024) + +static dma_addr_t xway_gphy_load(struct platform_device *pdev) +{ + const struct firmware *fw; + dma_addr_t dev_addr = 0; + const char *fw_name; + void *fw_addr; + size_t size; + + if (of_property_read_string(pdev->dev.of_node, "firmware", &fw_name)) { + dev_err(&pdev->dev, "failed to load firmware filename\n"); + return 0; + } + + dev_info(&pdev->dev, "requesting %s\n", fw_name); + if (request_firmware(&fw, fw_name, &pdev->dev)) { + dev_err(&pdev->dev, "failed to load firmware: %s\n", fw_name); + return 0; + } + + /* + * GPHY cores need the firmware code in a persistent and contiguous + * memory area with a 16 kB boundary aligned start address + */ + size = fw->size + XRX200_GPHY_FW_ALIGN; + + fw_addr = dma_alloc_coherent(&pdev->dev, size, &dev_addr, GFP_KERNEL); + if (fw_addr) { + fw_addr = PTR_ALIGN(fw_addr, XRX200_GPHY_FW_ALIGN); + dev_addr = ALIGN(dev_addr, XRX200_GPHY_FW_ALIGN); + memcpy(fw_addr, fw->data, fw->size); + } else { + dev_err(&pdev->dev, "failed to alloc firmware memory\n"); + } + + release_firmware(fw); + return dev_addr; +} + +static int __devinit xway_phy_fw_probe(struct platform_device *pdev) +{ + dma_addr_t fw_addr; + struct property *pp; + unsigned char *phyids; + int i, ret = 0; + + fw_addr = xway_gphy_load(pdev); + if (!fw_addr) + return -EINVAL; + pp = of_find_property(pdev->dev.of_node, "phys", NULL); + if (!pp) + return -ENOENT; + phyids = pp->value; + for (i = 0; i < pp->length && !ret; i++) + ret = xrx200_gphy_boot(&pdev->dev, phyids[i], fw_addr); + if (!ret) + mdelay(100); + return ret; +} + +static const struct of_device_id xway_phy_match[] = { + { .compatible = "lantiq,phy-xrx200" }, + {}, +}; +MODULE_DEVICE_TABLE(of, xway_phy_match); + +static struct platform_driver xway_phy_driver = { + .probe = xway_phy_fw_probe, + .driver = { + .name = "phy-xrx200", + .owner = THIS_MODULE, + .of_match_table = xway_phy_match, + }, +}; + +module_platform_driver(xway_phy_driver); + +MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); +MODULE_DESCRIPTION("Lantiq XRX200 PHY Firmware Loader"); +MODULE_LICENSE("GPL"); diff --git a/arch/mips/loongson1/Kconfig b/arch/mips/loongson1/Kconfig index a9a14d6e81af..fbf75f635798 100644 --- a/arch/mips/loongson1/Kconfig +++ b/arch/mips/loongson1/Kconfig @@ -15,7 +15,7 @@ config LOONGSON1_LS1B select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_HIGHMEM select SYS_HAS_EARLY_PRINTK - select HAVE_CLK + select COMMON_CLK endchoice diff --git a/arch/mips/loongson1/common/clock.c b/arch/mips/loongson1/common/clock.c index 1bbbbec12085..07133defa148 100644 --- a/arch/mips/loongson1/common/clock.c +++ b/arch/mips/loongson1/common/clock.c @@ -7,175 +7,22 @@ * option) any later version. */ -#include <linux/module.h> -#include <linux/list.h> -#include <linux/mutex.h> #include <linux/clk.h> #include <linux/err.h> -#include <asm/clock.h> #include <asm/time.h> - -#include <loongson1.h> - -static LIST_HEAD(clocks); -static DEFINE_MUTEX(clocks_mutex); - -struct clk *clk_get(struct device *dev, const char *name) -{ - struct clk *c; - struct clk *ret = NULL; - - mutex_lock(&clocks_mutex); - list_for_each_entry(c, &clocks, node) { - if (!strcmp(c->name, name)) { - ret = c; - break; - } - } - mutex_unlock(&clocks_mutex); - - return ret; -} -EXPORT_SYMBOL(clk_get); - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); - -static void pll_clk_init(struct clk *clk) -{ - u32 pll; - - pll = __raw_readl(LS1X_CLK_PLL_FREQ); - clk->rate = (12 + (pll & 0x3f)) * 33 / 2 - + ((pll >> 8) & 0x3ff) * 33 / 1024 / 2; - clk->rate *= 1000000; -} - -static void cpu_clk_init(struct clk *clk) -{ - u32 pll, ctrl; - - pll = clk_get_rate(clk->parent); - ctrl = __raw_readl(LS1X_CLK_PLL_DIV) & DIV_CPU; - clk->rate = pll / (ctrl >> DIV_CPU_SHIFT); -} - -static void ddr_clk_init(struct clk *clk) -{ - u32 pll, ctrl; - - pll = clk_get_rate(clk->parent); - ctrl = __raw_readl(LS1X_CLK_PLL_DIV) & DIV_DDR; - clk->rate = pll / (ctrl >> DIV_DDR_SHIFT); -} - -static void dc_clk_init(struct clk *clk) -{ - u32 pll, ctrl; - - pll = clk_get_rate(clk->parent); - ctrl = __raw_readl(LS1X_CLK_PLL_DIV) & DIV_DC; - clk->rate = pll / (ctrl >> DIV_DC_SHIFT); -} - -static struct clk_ops pll_clk_ops = { - .init = pll_clk_init, -}; - -static struct clk_ops cpu_clk_ops = { - .init = cpu_clk_init, -}; - -static struct clk_ops ddr_clk_ops = { - .init = ddr_clk_init, -}; - -static struct clk_ops dc_clk_ops = { - .init = dc_clk_init, -}; - -static struct clk pll_clk = { - .name = "pll", - .ops = &pll_clk_ops, -}; - -static struct clk cpu_clk = { - .name = "cpu", - .parent = &pll_clk, - .ops = &cpu_clk_ops, -}; - -static struct clk ddr_clk = { - .name = "ddr", - .parent = &pll_clk, - .ops = &ddr_clk_ops, -}; - -static struct clk dc_clk = { - .name = "dc", - .parent = &pll_clk, - .ops = &dc_clk_ops, -}; - -int clk_register(struct clk *clk) -{ - mutex_lock(&clocks_mutex); - list_add(&clk->node, &clocks); - if (clk->ops->init) - clk->ops->init(clk); - mutex_unlock(&clocks_mutex); - - return 0; -} -EXPORT_SYMBOL(clk_register); - -static struct clk *ls1x_clks[] = { - &pll_clk, - &cpu_clk, - &ddr_clk, - &dc_clk, -}; - -int __init ls1x_clock_init(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(ls1x_clks); i++) - clk_register(ls1x_clks[i]); - - return 0; -} +#include <platform.h> void __init plat_time_init(void) { struct clk *clk; /* Initialize LS1X clocks */ - ls1x_clock_init(); + ls1x_clk_init(); /* setup mips r4k timer */ clk = clk_get(NULL, "cpu"); if (IS_ERR(clk)) - panic("unable to get dc clock, err=%ld", PTR_ERR(clk)); + panic("unable to get cpu clock, err=%ld", PTR_ERR(clk)); mips_hpt_frequency = clk_get_rate(clk) / 2; } diff --git a/arch/mips/loongson1/common/platform.c b/arch/mips/loongson1/common/platform.c index 0412ad61e290..69dad4cfaaf4 100644 --- a/arch/mips/loongson1/common/platform.c +++ b/arch/mips/loongson1/common/platform.c @@ -43,16 +43,17 @@ struct platform_device ls1x_uart_device = { }, }; -void __init ls1x_serial_setup(void) +void __init ls1x_serial_setup(struct platform_device *pdev) { struct clk *clk; struct plat_serial8250_port *p; - clk = clk_get(NULL, "dc"); + clk = clk_get(NULL, pdev->name); if (IS_ERR(clk)) - panic("unable to get dc clock, err=%ld", PTR_ERR(clk)); + panic("unable to get %s clock, err=%ld", + pdev->name, PTR_ERR(clk)); - for (p = ls1x_serial8250_port; p->flags != 0; ++p) + for (p = pdev->dev.platform_data; p->flags != 0; ++p) p->uartclk = clk_get_rate(clk); } @@ -71,7 +72,6 @@ static struct resource ls1x_eth0_resources[] = { }; static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { - .bus_id = 0, .phy_mask = 0, }; diff --git a/arch/mips/loongson1/ls1b/board.c b/arch/mips/loongson1/ls1b/board.c index 295b1be893e3..1fbd5264f667 100644 --- a/arch/mips/loongson1/ls1b/board.c +++ b/arch/mips/loongson1/ls1b/board.c @@ -9,9 +9,6 @@ #include <platform.h> -#include <linux/serial_8250.h> -#include <loongson1.h> - static struct platform_device *ls1b_platform_devices[] __initdata = { &ls1x_uart_device, &ls1x_eth0_device, @@ -23,7 +20,7 @@ static int __init ls1b_platform_init(void) { int err; - ls1x_serial_setup(); + ls1x_serial_setup(&ls1x_uart_device); err = platform_add_devices(ls1b_platform_devices, ARRAY_SIZE(ls1b_platform_devices)); diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index a03bf00a1a9c..47c77e7ffbf8 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -171,16 +171,17 @@ static int isBranchInstr(mips_instruction * i) * In the Linux kernel, we support selection of FPR format on the * basis of the Status.FR bit. If an FPU is not present, the FR bit * is hardwired to zero, which would imply a 32-bit FPU even for - * 64-bit CPUs. For 64-bit kernels with no FPU we use TIF_32BIT_REGS - * as a proxy for the FR bit so that a 64-bit FPU is emulated. In any - * case, for a 32-bit kernel which uses the O32 MIPS ABI, only the - * even FPRs are used (Status.FR = 0). + * 64-bit CPUs so we rather look at TIF_32BIT_REGS. + * FPU emu is slow and bulky and optimizing this function offers fairly + * sizeable benefits so we try to be clever and make this function return + * a constant whenever possible, that is on 64-bit kernels without O32 + * compatibility enabled and on 32-bit kernels. */ static inline int cop1_64bit(struct pt_regs *xcp) { - if (cpu_has_fpu) - return xcp->cp0_status & ST0_FR; -#ifdef CONFIG_64BIT +#if defined(CONFIG_64BIT) && !defined(CONFIG_MIPS32_O32) + return 1; +#elif defined(CONFIG_64BIT) && defined(CONFIG_MIPS32_O32) return !test_thread_flag(TIF_32BIT_REGS); #else return 0; diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c index 44e69e7a4519..6ec04daf4231 100644 --- a/arch/mips/mm/c-octeon.c +++ b/arch/mips/mm/c-octeon.c @@ -5,6 +5,7 @@ * * Copyright (C) 2005-2007 Cavium Networks */ +#include <linux/export.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -28,6 +29,7 @@ #include <asm/octeon/octeon.h> unsigned long long cache_err_dcache[NR_CPUS]; +EXPORT_SYMBOL_GPL(cache_err_dcache); /** * Octeon automatically flushes the dcache on tlb changes, so @@ -284,39 +286,59 @@ void __cpuinit octeon_cache_init(void) board_cache_error_setup = octeon_cache_error_setup; } -/** +/* * Handle a cache error exception */ +static RAW_NOTIFIER_HEAD(co_cache_error_chain); -static void cache_parity_error_octeon(int non_recoverable) +int register_co_cache_error_notifier(struct notifier_block *nb) { - unsigned long coreid = cvmx_get_core_num(); - uint64_t icache_err = read_octeon_c0_icacheerr(); - - pr_err("Cache error exception:\n"); - pr_err("cp0_errorepc == %lx\n", read_c0_errorepc()); - if (icache_err & 1) { - pr_err("CacheErr (Icache) == %llx\n", - (unsigned long long)icache_err); - write_octeon_c0_icacheerr(0); - } - if (cache_err_dcache[coreid] & 1) { - pr_err("CacheErr (Dcache) == %llx\n", - (unsigned long long)cache_err_dcache[coreid]); - cache_err_dcache[coreid] = 0; - } + return raw_notifier_chain_register(&co_cache_error_chain, nb); +} +EXPORT_SYMBOL_GPL(register_co_cache_error_notifier); + +int unregister_co_cache_error_notifier(struct notifier_block *nb) +{ + return raw_notifier_chain_unregister(&co_cache_error_chain, nb); +} +EXPORT_SYMBOL_GPL(unregister_co_cache_error_notifier); - if (non_recoverable) - panic("Can't handle cache error: nested exception"); +static void co_cache_error_call_notifiers(unsigned long val) +{ + int rv = raw_notifier_call_chain(&co_cache_error_chain, val, NULL); + if ((rv & ~NOTIFY_STOP_MASK) != NOTIFY_OK) { + u64 dcache_err; + unsigned long coreid = cvmx_get_core_num(); + u64 icache_err = read_octeon_c0_icacheerr(); + + if (val) { + dcache_err = cache_err_dcache[coreid]; + cache_err_dcache[coreid] = 0; + } else { + dcache_err = read_octeon_c0_dcacheerr(); + } + + pr_err("Core%lu: Cache error exception:\n", coreid); + pr_err("cp0_errorepc == %lx\n", read_c0_errorepc()); + if (icache_err & 1) { + pr_err("CacheErr (Icache) == %llx\n", + (unsigned long long)icache_err); + write_octeon_c0_icacheerr(0); + } + if (dcache_err & 1) { + pr_err("CacheErr (Dcache) == %llx\n", + (unsigned long long)dcache_err); + } + } } -/** +/* * Called when the the exception is recoverable */ asmlinkage void cache_parity_error_octeon_recoverable(void) { - cache_parity_error_octeon(0); + co_cache_error_call_notifiers(0); } /** @@ -325,5 +347,6 @@ asmlinkage void cache_parity_error_octeon_recoverable(void) asmlinkage void cache_parity_error_octeon_non_recoverable(void) { - cache_parity_error_octeon(1); + co_cache_error_call_notifiers(1); + panic("Can't handle cache error: nested exception"); } diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 4c32ede464b5..0f7d788e8810 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -632,9 +632,6 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) if (size >= scache_size) r4k_blast_scache(); else { - unsigned long lsize = cpu_scache_line_size(); - unsigned long almask = ~(lsize - 1); - /* * There is no clearly documented alignment requirement * for the cache instruction on MIPS processors and @@ -643,9 +640,6 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) * hit ops with insufficient alignment. Solved by * aligning the address to cache line size. */ - cache_op(Hit_Writeback_Inv_SD, addr & almask); - cache_op(Hit_Writeback_Inv_SD, - (addr + size - 1) & almask); blast_inv_scache_range(addr, addr + size); } __sync(); @@ -655,12 +649,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) if (cpu_has_safe_index_cacheops && size >= dcache_size) { r4k_blast_dcache(); } else { - unsigned long lsize = cpu_dcache_line_size(); - unsigned long almask = ~(lsize - 1); - R4600_HIT_CACHEOP_WAR_IMPL; - cache_op(Hit_Writeback_Inv_D, addr & almask); - cache_op(Hit_Writeback_Inv_D, (addr + size - 1) & almask); blast_inv_dcache_range(addr, addr + size); } @@ -947,7 +936,6 @@ static void __cpuinit probe_pcache(void) case CPU_RM7000: rm7k_erratum31(); - case CPU_RM9000: icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); c->icache.linesz = 16 << ((config & CONF_IB) >> 5); c->icache.ways = 4; @@ -958,9 +946,7 @@ static void __cpuinit probe_pcache(void) c->dcache.ways = 4; c->dcache.waybit = __ffs(dcache_size / c->dcache.ways); -#if !defined(CONFIG_SMP) || !defined(RM9000_CDEX_SMP_WAR) c->options |= MIPS_CPU_CACHE_CDEX_P; -#endif c->options |= MIPS_CPU_PREFETCH; break; @@ -1245,7 +1231,6 @@ static void __cpuinit setup_scache(void) return; case CPU_RM7000: - case CPU_RM9000: #ifdef CONFIG_RM7000_CPU_SCACHE rm7k_sc_init(); #endif @@ -1348,10 +1333,10 @@ static int __init cca_setup(char *str) { get_option(&str, &cca); - return 1; + return 0; } -__setup("cca=", cca_setup); +early_param("cca", cca_setup); static void __cpuinit coherency_setup(void) { @@ -1401,10 +1386,10 @@ static int __init setcoherentio(char *str) { coherentio = 1; - return 1; + return 0; } -__setup("coherentio", setcoherentio); +early_param("coherentio", setcoherentio); #endif static void __cpuinit r4k_cache_error_setup(void) diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index aff57057a949..da815d295239 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c @@ -1,3 +1,4 @@ +#include <linux/compiler.h> #include <linux/module.h> #include <linux/highmem.h> #include <linux/sched.h> @@ -67,7 +68,7 @@ EXPORT_SYMBOL(kmap_atomic); void __kunmap_atomic(void *kvaddr) { unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; - int type; + int type __maybe_unused; if (vaddr < FIXADDR_START) { // FIXME pagefault_enable(); diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c index 98f530e18216..8e666c55f4d4 100644 --- a/arch/mips/mm/page.c +++ b/arch/mips/mm/page.c @@ -140,15 +140,6 @@ static void __cpuinit set_prefetch_parameters(void) pref_bias_copy_load = 256; break; - case CPU_RM9000: - /* - * As a workaround for erratum G105 which make the - * PrepareForStore hint unusable we fall back to - * StoreRetained on the RM9000. Once it is known which - * versions of the RM9000 we'll be able to condition- - * alize this. - */ - case CPU_R10000: case CPU_R12000: case CPU_R14000: diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c index 25407794edb4..ee331bbd8f8a 100644 --- a/arch/mips/mm/pgtable-64.c +++ b/arch/mips/mm/pgtable-64.c @@ -11,6 +11,7 @@ #include <asm/fixmap.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> +#include <asm/tlbflush.h> void pgd_init(unsigned long page) { @@ -61,6 +62,36 @@ void pmd_init(unsigned long addr, unsigned long pagetable) } #endif +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + +void pmdp_splitting_flush(struct vm_area_struct *vma, + unsigned long address, + pmd_t *pmdp) +{ + if (!pmd_trans_splitting(*pmdp)) { + pmd_t pmd = pmd_mksplitting(*pmdp); + set_pmd_at(vma->vm_mm, address, pmdp, pmd); + } +} + +#endif + +pmd_t mk_pmd(struct page *page, pgprot_t prot) +{ + pmd_t pmd; + + pmd_val(pmd) = (page_to_pfn(page) << _PFN_SHIFT) | pgprot_val(prot); + + return pmd; +} + +void set_pmd_at(struct mm_struct *mm, unsigned long addr, + pmd_t *pmdp, pmd_t pmd) +{ + *pmdp = pmd; + flush_tlb_all(); +} + void __init pagetable_init(void) { unsigned long vaddr; diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 88e79ad6f811..2a7c9725b2a3 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -295,7 +295,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) pudp = pud_offset(pgdp, address); pmdp = pmd_offset(pudp, address); idx = read_c0_index(); -#ifdef CONFIG_HUGETLB_PAGE +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT /* this could be a huge page */ if (pmd_huge(*pmdp)) { unsigned long lo; @@ -367,6 +367,26 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, EXIT_CRITICAL(flags); } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + +int __init has_transparent_hugepage(void) +{ + unsigned int mask; + unsigned long flags; + + ENTER_CRITICAL(flags); + write_c0_pagemask(PM_HUGE_MASK); + back_to_back_c0_hazard(); + mask = read_c0_pagemask(); + write_c0_pagemask(PM_DEFAULT_MASK); + + EXIT_CRITICAL(flags); + + return mask == PM_HUGE_MASK; +} + +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + static int __cpuinitdata ntlb; static int __init set_ntlb(char *str) { diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 2833dcb67b5a..05613355627b 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -158,7 +158,7 @@ enum label_id { label_smp_pgtable_change, label_r3000_write_probe_fail, label_large_segbits_fault, -#ifdef CONFIG_HUGETLB_PAGE +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT label_tlb_huge_update, #endif }; @@ -177,13 +177,15 @@ UASM_L_LA(_nopage_tlbm) UASM_L_LA(_smp_pgtable_change) UASM_L_LA(_r3000_write_probe_fail) UASM_L_LA(_large_segbits_fault) -#ifdef CONFIG_HUGETLB_PAGE +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT UASM_L_LA(_tlb_huge_update) #endif static int __cpuinitdata hazard_instance; -static void uasm_bgezl_hazard(u32 **p, struct uasm_reloc **r, int instance) +static void __cpuinit uasm_bgezl_hazard(u32 **p, + struct uasm_reloc **r, + int instance) { switch (instance) { case 0 ... 7: @@ -194,7 +196,9 @@ static void uasm_bgezl_hazard(u32 **p, struct uasm_reloc **r, int instance) } } -static void uasm_bgezl_label(struct uasm_label **l, u32 **p, int instance) +static void __cpuinit uasm_bgezl_label(struct uasm_label **l, + u32 **p, + int instance) { switch (instance) { case 0 ... 7: @@ -206,19 +210,59 @@ static void uasm_bgezl_label(struct uasm_label **l, u32 **p, int instance) } /* - * For debug purposes. + * pgtable bits are assigned dynamically depending on processor feature + * and statically based on kernel configuration. This spits out the actual + * values the kernel is using. Required to make sense from disassembled + * TLB exception handlers. */ -static inline void dump_handler(const u32 *handler, int count) +static void output_pgtable_bits_defines(void) +{ +#define pr_define(fmt, ...) \ + pr_debug("#define " fmt, ##__VA_ARGS__) + + pr_debug("#include <asm/asm.h>\n"); + pr_debug("#include <asm/regdef.h>\n"); + pr_debug("\n"); + + pr_define("_PAGE_PRESENT_SHIFT %d\n", _PAGE_PRESENT_SHIFT); + pr_define("_PAGE_READ_SHIFT %d\n", _PAGE_READ_SHIFT); + pr_define("_PAGE_WRITE_SHIFT %d\n", _PAGE_WRITE_SHIFT); + pr_define("_PAGE_ACCESSED_SHIFT %d\n", _PAGE_ACCESSED_SHIFT); + pr_define("_PAGE_MODIFIED_SHIFT %d\n", _PAGE_MODIFIED_SHIFT); +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT + pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT); + pr_define("_PAGE_SPLITTING_SHIFT %d\n", _PAGE_SPLITTING_SHIFT); +#endif + if (cpu_has_rixi) { +#ifdef _PAGE_NO_EXEC_SHIFT + pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT); +#endif +#ifdef _PAGE_NO_READ_SHIFT + pr_define("_PAGE_NO_READ_SHIFT %d\n", _PAGE_NO_READ_SHIFT); +#endif + } + pr_define("_PAGE_GLOBAL_SHIFT %d\n", _PAGE_GLOBAL_SHIFT); + pr_define("_PAGE_VALID_SHIFT %d\n", _PAGE_VALID_SHIFT); + pr_define("_PAGE_DIRTY_SHIFT %d\n", _PAGE_DIRTY_SHIFT); + pr_define("_PFN_SHIFT %d\n", _PFN_SHIFT); + pr_debug("\n"); +} + +static inline void dump_handler(const char *symbol, const u32 *handler, int count) { int i; + pr_debug("LEAF(%s)\n", symbol); + pr_debug("\t.set push\n"); pr_debug("\t.set noreorder\n"); for (i = 0; i < count; i++) - pr_debug("\t%p\t.word 0x%08x\n", &handler[i], handler[i]); + pr_debug("\t.word\t0x%08x\t\t# %p\n", handler[i], &handler[i]); + + pr_debug("\t.set\tpop\n"); - pr_debug("\t.set pop\n"); + pr_debug("\tEND(%s)\n", symbol); } /* The only general purpose registers allowed in TLB handlers. */ @@ -401,7 +445,7 @@ static void __cpuinit build_r3000_tlb_refill_handler(void) memcpy((void *)ebase, tlb_handler, 0x80); - dump_handler((u32 *)ebase, 32); + dump_handler("r3000_tlb_refill", (u32 *)ebase, 32); } #endif /* CONFIG_MIPS_PGD_C0_CONTEXT */ @@ -443,7 +487,6 @@ static void __cpuinit __maybe_unused build_tlb_probe_entry(u32 **p) case CPU_R4600: case CPU_R4700: case CPU_R5000: - case CPU_R5000A: case CPU_NEVADA: uasm_i_nop(p); uasm_i_tlbp(p); @@ -517,7 +560,6 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l, break; case CPU_R5000: - case CPU_R5000A: case CPU_NEVADA: uasm_i_nop(p); /* QED specifies 2 nops hazard */ uasm_i_nop(p); /* QED specifies 2 nops hazard */ @@ -565,24 +607,6 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l, tlbw(p); break; - case CPU_RM9000: - /* - * When the JTLB is updated by tlbwi or tlbwr, a subsequent - * use of the JTLB for instructions should not occur for 4 - * cpu cycles and use for data translations should not occur - * for 3 cpu cycles. - */ - uasm_i_ssnop(p); - uasm_i_ssnop(p); - uasm_i_ssnop(p); - uasm_i_ssnop(p); - tlbw(p); - uasm_i_ssnop(p); - uasm_i_ssnop(p); - uasm_i_ssnop(p); - uasm_i_ssnop(p); - break; - case CPU_VR4111: case CPU_VR4121: case CPU_VR4122: @@ -629,7 +653,7 @@ static __cpuinit __maybe_unused void build_convert_pte_to_entrylo(u32 **p, } } -#ifdef CONFIG_HUGETLB_PAGE +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT static __cpuinit void build_restore_pagemask(u32 **p, struct uasm_reloc **r, @@ -755,7 +779,7 @@ static __cpuinit void build_huge_handler_tail(u32 **p, build_huge_update_entries(p, pte, ptr); build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed, 0); } -#endif /* CONFIG_HUGETLB_PAGE */ +#endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */ #ifdef CONFIG_64BIT /* @@ -1200,7 +1224,7 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l, /* Adjust the context during the load latency. */ build_adjust_context(p, tmp); -#ifdef CONFIG_HUGETLB_PAGE +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT uasm_il_bbit1(p, r, scratch, ilog2(_PAGE_HUGE), label_tlb_huge_update); /* * The in the LWX case we don't want to do the load in the @@ -1209,7 +1233,7 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l, */ if (use_lwx_insns()) uasm_i_nop(p); -#endif /* CONFIG_HUGETLB_PAGE */ +#endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */ /* build_update_entries */ @@ -1312,7 +1336,7 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) build_get_pgde32(&p, K0, K1); /* get pgd in K1 */ #endif -#ifdef CONFIG_HUGETLB_PAGE +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT build_is_huge_pte(&p, &r, K0, K1, label_tlb_huge_update); #endif @@ -1322,7 +1346,7 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) uasm_l_leave(&l, p); uasm_i_eret(&p); /* return from trap */ } -#ifdef CONFIG_HUGETLB_PAGE +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT uasm_l_tlb_huge_update(&l, p); build_huge_update_entries(&p, htlb_info.huge_pte, K1); build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random, @@ -1367,7 +1391,7 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) uasm_copy_handler(relocs, labels, tlb_handler, p, f); final_len = p - tlb_handler; } else { -#if defined(CONFIG_HUGETLB_PAGE) +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT const enum label_id ls = label_tlb_huge_update; #else const enum label_id ls = label_vmalloc; @@ -1436,7 +1460,7 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) memcpy((void *)ebase, final_handler, 0x100); - dump_handler((u32 *)ebase, 64); + dump_handler("r4000_tlb_refill", (u32 *)ebase, 64); } /* @@ -1493,7 +1517,8 @@ static void __cpuinit build_r4000_setup_pgd(void) pr_debug("Wrote tlbmiss_handler_setup_pgd (%u instructions).\n", (unsigned int)(p - tlbmiss_handler_setup_pgd)); - dump_handler(tlbmiss_handler_setup_pgd, + dump_handler("tlbmiss_handler", + tlbmiss_handler_setup_pgd, ARRAY_SIZE(tlbmiss_handler_setup_pgd)); } #endif @@ -1763,7 +1788,7 @@ static void __cpuinit build_r3000_tlb_load_handler(void) pr_debug("Wrote TLB load handler fastpath (%u instructions).\n", (unsigned int)(p - handle_tlbl)); - dump_handler(handle_tlbl, ARRAY_SIZE(handle_tlbl)); + dump_handler("r3000_tlb_load", handle_tlbl, ARRAY_SIZE(handle_tlbl)); } static void __cpuinit build_r3000_tlb_store_handler(void) @@ -1793,7 +1818,7 @@ static void __cpuinit build_r3000_tlb_store_handler(void) pr_debug("Wrote TLB store handler fastpath (%u instructions).\n", (unsigned int)(p - handle_tlbs)); - dump_handler(handle_tlbs, ARRAY_SIZE(handle_tlbs)); + dump_handler("r3000_tlb_store", handle_tlbs, ARRAY_SIZE(handle_tlbs)); } static void __cpuinit build_r3000_tlb_modify_handler(void) @@ -1823,7 +1848,7 @@ static void __cpuinit build_r3000_tlb_modify_handler(void) pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n", (unsigned int)(p - handle_tlbm)); - dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm)); + dump_handler("r3000_tlb_modify", handle_tlbm, ARRAY_SIZE(handle_tlbm)); } #endif /* CONFIG_MIPS_PGD_C0_CONTEXT */ @@ -1842,7 +1867,7 @@ build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l, build_get_pgde32(p, wr.r1, wr.r2); /* get pgd in ptr */ #endif -#ifdef CONFIG_HUGETLB_PAGE +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT /* * For huge tlb entries, pmd doesn't contain an address but * instead contains the tlb pte. Check the PAGE_HUGE bit and @@ -1958,7 +1983,7 @@ static void __cpuinit build_r4000_tlb_load_handler(void) build_make_valid(&p, &r, wr.r1, wr.r2); build_r4000_tlbchange_handler_tail(&p, &l, &r, wr.r1, wr.r2); -#ifdef CONFIG_HUGETLB_PAGE +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT /* * This is the entry point when build_r4000_tlbchange_handler_head * spots a huge page. @@ -2030,7 +2055,7 @@ static void __cpuinit build_r4000_tlb_load_handler(void) pr_debug("Wrote TLB load handler fastpath (%u instructions).\n", (unsigned int)(p - handle_tlbl)); - dump_handler(handle_tlbl, ARRAY_SIZE(handle_tlbl)); + dump_handler("r4000_tlb_load", handle_tlbl, ARRAY_SIZE(handle_tlbl)); } static void __cpuinit build_r4000_tlb_store_handler(void) @@ -2051,7 +2076,7 @@ static void __cpuinit build_r4000_tlb_store_handler(void) build_make_write(&p, &r, wr.r1, wr.r2); build_r4000_tlbchange_handler_tail(&p, &l, &r, wr.r1, wr.r2); -#ifdef CONFIG_HUGETLB_PAGE +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT /* * This is the entry point when * build_r4000_tlbchange_handler_head spots a huge page. @@ -2077,7 +2102,7 @@ static void __cpuinit build_r4000_tlb_store_handler(void) pr_debug("Wrote TLB store handler fastpath (%u instructions).\n", (unsigned int)(p - handle_tlbs)); - dump_handler(handle_tlbs, ARRAY_SIZE(handle_tlbs)); + dump_handler("r4000_tlb_store", handle_tlbs, ARRAY_SIZE(handle_tlbs)); } static void __cpuinit build_r4000_tlb_modify_handler(void) @@ -2099,7 +2124,7 @@ static void __cpuinit build_r4000_tlb_modify_handler(void) build_make_write(&p, &r, wr.r1, wr.r2); build_r4000_tlbchange_handler_tail(&p, &l, &r, wr.r1, wr.r2); -#ifdef CONFIG_HUGETLB_PAGE +#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT /* * This is the entry point when * build_r4000_tlbchange_handler_head spots a huge page. @@ -2125,7 +2150,7 @@ static void __cpuinit build_r4000_tlb_modify_handler(void) pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n", (unsigned int)(p - handle_tlbm)); - dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm)); + dump_handler("r4000_tlb_modify", handle_tlbm, ARRAY_SIZE(handle_tlbm)); } void __cpuinit build_tlb_refill_handler(void) @@ -2137,6 +2162,8 @@ void __cpuinit build_tlb_refill_handler(void) */ static int run_once = 0; + output_pgtable_bits_defines(); + #ifdef CONFIG_64BIT check_for_high_segbits = current_cpu_data.vmbits > (PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3); #endif diff --git a/arch/mips/netlogic/Kconfig b/arch/mips/netlogic/Kconfig index 8059eb76f8eb..3c05bf9e280a 100644 --- a/arch/mips/netlogic/Kconfig +++ b/arch/mips/netlogic/Kconfig @@ -9,6 +9,34 @@ config DT_XLP_EVP This DTB will be used if the firmware does not pass in a DTB pointer to the kernel. The corresponding DTS file is at arch/mips/netlogic/dts/xlp_evp.dts + +config NLM_MULTINODE + bool "Support for multi-chip boards" + depends on NLM_XLP_BOARD + default n + help + Add support for boards with 2 or 4 XLPs connected over ICI. + +if NLM_MULTINODE +choice + prompt "Number of XLPs on the board" + default NLM_MULTINODE_2 + help + In the multi-node case, specify the number of SoCs on the board. + +config NLM_MULTINODE_2 + bool "Dual-XLP board" + help + Support boards with upto two XLPs connected over ICI. + +config NLM_MULTINODE_4 + bool "Quad-XLP board" + help + Support boards with upto four XLPs connected over ICI. + +endchoice + +endif endif config NLM_COMMON diff --git a/arch/mips/netlogic/common/irq.c b/arch/mips/netlogic/common/irq.c index e52bfcbce093..00dcc7a2bc5a 100644 --- a/arch/mips/netlogic/common/irq.c +++ b/arch/mips/netlogic/common/irq.c @@ -36,7 +36,6 @@ #include <linux/init.h> #include <linux/linkage.h> #include <linux/interrupt.h> -#include <linux/spinlock.h> #include <linux/mm.h> #include <linux/slab.h> #include <linux/irq.h> @@ -59,68 +58,70 @@ #elif defined(CONFIG_CPU_XLR) #include <asm/netlogic/xlr/iomap.h> #include <asm/netlogic/xlr/pic.h> +#include <asm/netlogic/xlr/fmn.h> #else #error "Unknown CPU" #endif -/* - * These are the routines that handle all the low level interrupt stuff. - * Actions handled here are: initialization of the interrupt map, requesting of - * interrupt lines by handlers, dispatching if interrupts to handlers, probing - * for interrupt lines - */ -/* Globals */ -static uint64_t nlm_irq_mask; -static DEFINE_SPINLOCK(nlm_pic_lock); +#ifdef CONFIG_SMP +#define SMP_IRQ_MASK ((1ULL << IRQ_IPI_SMP_FUNCTION) | \ + (1ULL << IRQ_IPI_SMP_RESCHEDULE)) +#else +#define SMP_IRQ_MASK 0 +#endif +#define PERCPU_IRQ_MASK (SMP_IRQ_MASK | (1ull << IRQ_TIMER) | \ + (1ull << IRQ_FMN)) + +struct nlm_pic_irq { + void (*extra_ack)(struct irq_data *); + struct nlm_soc_info *node; + int picirq; + int irt; + int flags; +}; static void xlp_pic_enable(struct irq_data *d) { unsigned long flags; - int irt; + struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); - irt = nlm_irq_to_irt(d->irq); - if (irt == -1) - return; - spin_lock_irqsave(&nlm_pic_lock, flags); - nlm_pic_enable_irt(nlm_pic_base, irt); - spin_unlock_irqrestore(&nlm_pic_lock, flags); + BUG_ON(!pd); + spin_lock_irqsave(&pd->node->piclock, flags); + nlm_pic_enable_irt(pd->node->picbase, pd->irt); + spin_unlock_irqrestore(&pd->node->piclock, flags); } static void xlp_pic_disable(struct irq_data *d) { + struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); unsigned long flags; - int irt; - irt = nlm_irq_to_irt(d->irq); - if (irt == -1) - return; - spin_lock_irqsave(&nlm_pic_lock, flags); - nlm_pic_disable_irt(nlm_pic_base, irt); - spin_unlock_irqrestore(&nlm_pic_lock, flags); + BUG_ON(!pd); + spin_lock_irqsave(&pd->node->piclock, flags); + nlm_pic_disable_irt(pd->node->picbase, pd->irt); + spin_unlock_irqrestore(&pd->node->piclock, flags); } static void xlp_pic_mask_ack(struct irq_data *d) { - uint64_t mask = 1ull << d->irq; + struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); + uint64_t mask = 1ull << pd->picirq; write_c0_eirr(mask); /* ack by writing EIRR */ } static void xlp_pic_unmask(struct irq_data *d) { - void *hd = irq_data_get_irq_handler_data(d); - int irt; + struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d); - irt = nlm_irq_to_irt(d->irq); - if (irt == -1) + if (!pd) return; - if (hd) { - void (*extra_ack)(void *) = hd; - extra_ack(d); - } + if (pd->extra_ack) + pd->extra_ack(d); + /* Ack is a single write, no need to lock */ - nlm_pic_ack(nlm_pic_base, irt); + nlm_pic_ack(pd->node->picbase, pd->irt); } static struct irq_chip xlp_pic = { @@ -174,64 +175,108 @@ struct irq_chip nlm_cpu_intr = { .irq_eoi = cpuintr_ack, }; -void __init init_nlm_common_irqs(void) +static void __init nlm_init_percpu_irqs(void) { - int i, irq, irt; + int i; for (i = 0; i < PIC_IRT_FIRST_IRQ; i++) irq_set_chip_and_handler(i, &nlm_cpu_intr, handle_percpu_irq); - - for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ ; i++) - irq_set_chip_and_handler(i, &xlp_pic, handle_level_irq); - #ifdef CONFIG_SMP irq_set_chip_and_handler(IRQ_IPI_SMP_FUNCTION, &nlm_cpu_intr, nlm_smp_function_ipi_handler); irq_set_chip_and_handler(IRQ_IPI_SMP_RESCHEDULE, &nlm_cpu_intr, nlm_smp_resched_ipi_handler); - nlm_irq_mask |= - ((1ULL << IRQ_IPI_SMP_FUNCTION) | (1ULL << IRQ_IPI_SMP_RESCHEDULE)); #endif +} + +void nlm_setup_pic_irq(int node, int picirq, int irq, int irt) +{ + struct nlm_pic_irq *pic_data; + int xirq; + + xirq = nlm_irq_to_xirq(node, irq); + pic_data = kzalloc(sizeof(*pic_data), GFP_KERNEL); + BUG_ON(pic_data == NULL); + pic_data->irt = irt; + pic_data->picirq = picirq; + pic_data->node = nlm_get_node(node); + irq_set_chip_and_handler(xirq, &xlp_pic, handle_level_irq); + irq_set_handler_data(xirq, pic_data); +} + +void nlm_set_pic_extra_ack(int node, int irq, void (*xack)(struct irq_data *)) +{ + struct nlm_pic_irq *pic_data; + int xirq; + + xirq = nlm_irq_to_xirq(node, irq); + pic_data = irq_get_handler_data(xirq); + pic_data->extra_ack = xack; +} - for (irq = PIC_IRT_FIRST_IRQ; irq <= PIC_IRT_LAST_IRQ; irq++) { - irt = nlm_irq_to_irt(irq); +static void nlm_init_node_irqs(int node) +{ + int i, irt; + uint64_t irqmask; + struct nlm_soc_info *nodep; + + pr_info("Init IRQ for node %d\n", node); + nodep = nlm_get_node(node); + irqmask = PERCPU_IRQ_MASK; + for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ; i++) { + irt = nlm_irq_to_irt(i); if (irt == -1) continue; - nlm_irq_mask |= (1ULL << irq); - nlm_pic_init_irt(nlm_pic_base, irt, irq, 0); + nlm_setup_pic_irq(node, i, i, irt); + /* set interrupts to first cpu in node */ + nlm_pic_init_irt(nodep->picbase, irt, i, + node * NLM_CPUS_PER_NODE); + irqmask |= (1ull << i); } - - nlm_irq_mask |= (1ULL << IRQ_TIMER); + nodep->irqmask = irqmask; } void __init arch_init_irq(void) { /* Initialize the irq descriptors */ - init_nlm_common_irqs(); - - write_c0_eimr(nlm_irq_mask); + nlm_init_percpu_irqs(); + nlm_init_node_irqs(0); + write_c0_eimr(nlm_current_node()->irqmask); +#if defined(CONFIG_CPU_XLR) + nlm_setup_fmn_irq(); +#endif } -void __cpuinit nlm_smp_irq_init(void) +void nlm_smp_irq_init(int hwcpuid) { - /* set interrupt mask for non-zero cpus */ - write_c0_eimr(nlm_irq_mask); + int node, cpu; + + node = hwcpuid / NLM_CPUS_PER_NODE; + cpu = hwcpuid % NLM_CPUS_PER_NODE; + + if (cpu == 0 && node != 0) + nlm_init_node_irqs(node); + write_c0_eimr(nlm_current_node()->irqmask); } asmlinkage void plat_irq_dispatch(void) { uint64_t eirr; - int i; + int i, node; + node = nlm_nodeid(); eirr = read_c0_eirr() & read_c0_eimr(); - if (eirr & (1 << IRQ_TIMER)) { - do_IRQ(IRQ_TIMER); - return; - } i = __ilog2_u64(eirr); if (i == -1) return; - do_IRQ(i); + /* per-CPU IRQs don't need translation */ + if (eirr & PERCPU_IRQ_MASK) { + do_IRQ(i); + return; + } + + /* top level irq handling */ + do_IRQ(nlm_irq_to_xirq(node, i)); } diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c index fab316de57e9..a080d9ee3cd7 100644 --- a/arch/mips/netlogic/common/smp.c +++ b/arch/mips/netlogic/common/smp.c @@ -59,12 +59,17 @@ void nlm_send_ipi_single(int logical_cpu, unsigned int action) { - int cpu = cpu_logical_map(logical_cpu); + int cpu, node; + uint64_t picbase; + + cpu = cpu_logical_map(logical_cpu); + node = cpu / NLM_CPUS_PER_NODE; + picbase = nlm_get_node(node)->picbase; if (action & SMP_CALL_FUNCTION) - nlm_pic_send_ipi(nlm_pic_base, cpu, IRQ_IPI_SMP_FUNCTION, 0); + nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_FUNCTION, 0); if (action & SMP_RESCHEDULE_YOURSELF) - nlm_pic_send_ipi(nlm_pic_base, cpu, IRQ_IPI_SMP_RESCHEDULE, 0); + nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_RESCHEDULE, 0); } void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action) @@ -96,11 +101,12 @@ void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc) void nlm_early_init_secondary(int cpu) { change_c0_config(CONF_CM_CMASK, 0x3); - write_c0_ebase((uint32_t)nlm_common_ebase); #ifdef CONFIG_CPU_XLP - if (hard_smp_processor_id() % 4 == 0) + /* mmu init, once per core */ + if (cpu % NLM_THREADS_PER_CORE == 0) xlp_mmu_init(); #endif + write_c0_ebase(nlm_current_node()->ebase); } /* @@ -108,8 +114,12 @@ void nlm_early_init_secondary(int cpu) */ static void __cpuinit nlm_init_secondary(void) { - current_cpu_data.core = hard_smp_processor_id() / 4; - nlm_smp_irq_init(); + int hwtid; + + hwtid = hard_smp_processor_id(); + current_cpu_data.core = hwtid / NLM_THREADS_PER_CORE; + nlm_percpu_init(hwtid); + nlm_smp_irq_init(hwtid); } void nlm_prepare_cpus(unsigned int max_cpus) @@ -120,9 +130,6 @@ void nlm_prepare_cpus(unsigned int max_cpus) void nlm_smp_finish(void) { -#ifdef notyet - nlm_common_msgring_cpu_init(); -#endif local_irq_enable(); } @@ -142,27 +149,27 @@ cpumask_t phys_cpu_present_map; void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) { - unsigned long gp = (unsigned long)task_thread_info(idle); - unsigned long sp = (unsigned long)__KSTK_TOS(idle); - int cpu = cpu_logical_map(logical_cpu); + int cpu, node; - nlm_next_sp = sp; - nlm_next_gp = gp; + cpu = cpu_logical_map(logical_cpu); + node = cpu / NLM_CPUS_PER_NODE; + nlm_next_sp = (unsigned long)__KSTK_TOS(idle); + nlm_next_gp = (unsigned long)task_thread_info(idle); - /* barrier */ + /* barrier for sp/gp store above */ __sync(); - nlm_pic_send_ipi(nlm_pic_base, cpu, 1, 1); + nlm_pic_send_ipi(nlm_get_node(node)->picbase, cpu, 1, 1); /* NMI */ } void __init nlm_smp_setup(void) { unsigned int boot_cpu; - int num_cpus, i; + int num_cpus, i, ncore; boot_cpu = hard_smp_processor_id(); - cpus_clear(phys_cpu_present_map); + cpumask_clear(&phys_cpu_present_map); - cpu_set(boot_cpu, phys_cpu_present_map); + cpumask_set_cpu(boot_cpu, &phys_cpu_present_map); __cpu_number_map[boot_cpu] = 0; __cpu_logical_map[0] = boot_cpu; set_cpu_possible(0, true); @@ -174,7 +181,7 @@ void __init nlm_smp_setup(void) * it is only set for ASPs (see smpboot.S) */ if (nlm_cpu_ready[i]) { - cpu_set(i, phys_cpu_present_map); + cpumask_set_cpu(i, &phys_cpu_present_map); __cpu_number_map[i] = num_cpus; __cpu_logical_map[num_cpus] = i; set_cpu_possible(num_cpus, true); @@ -182,20 +189,28 @@ void __init nlm_smp_setup(void) } } + /* check with the cores we have worken up */ + for (ncore = 0, i = 0; i < NLM_NR_NODES; i++) + ncore += hweight32(nlm_get_node(i)->coremask); + pr_info("Phys CPU present map: %lx, possible map %lx\n", - (unsigned long)phys_cpu_present_map.bits[0], + (unsigned long)cpumask_bits(&phys_cpu_present_map)[0], (unsigned long)cpumask_bits(cpu_possible_mask)[0]); - pr_info("Detected %i Slave CPU(s)\n", num_cpus); + pr_info("Detected (%dc%dt) %d Slave CPU(s)\n", ncore, + nlm_threads_per_core, num_cpus); nlm_set_nmi_handler(nlm_boot_secondary_cpus); } -static int nlm_parse_cpumask(u32 cpu_mask) +static int nlm_parse_cpumask(cpumask_t *wakeup_mask) { uint32_t core0_thr_mask, core_thr_mask; - int threadmode, i; + int threadmode, i, j; - core0_thr_mask = cpu_mask & 0xf; + core0_thr_mask = 0; + for (i = 0; i < NLM_THREADS_PER_CORE; i++) + if (cpumask_test_cpu(i, wakeup_mask)) + core0_thr_mask |= (1 << i); switch (core0_thr_mask) { case 1: nlm_threads_per_core = 1; @@ -214,25 +229,23 @@ static int nlm_parse_cpumask(u32 cpu_mask) } /* Verify other cores CPU masks */ - nlm_coremask = 1; - nlm_cpumask = core0_thr_mask; - for (i = 1; i < 8; i++) { - core_thr_mask = (cpu_mask >> (i * 4)) & 0xf; - if (core_thr_mask) { - if (core_thr_mask != core0_thr_mask) + for (i = 0; i < NR_CPUS; i += NLM_THREADS_PER_CORE) { + core_thr_mask = 0; + for (j = 0; j < NLM_THREADS_PER_CORE; j++) + if (cpumask_test_cpu(i + j, wakeup_mask)) + core_thr_mask |= (1 << j); + if (core_thr_mask != 0 && core_thr_mask != core0_thr_mask) goto unsupp; - nlm_coremask |= 1 << i; - nlm_cpumask |= core0_thr_mask << (4 * i); - } } return threadmode; unsupp: - panic("Unsupported CPU mask %x\n", cpu_mask); + panic("Unsupported CPU mask %lx\n", + (unsigned long)cpumask_bits(wakeup_mask)[0]); return 0; } -int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask) +int __cpuinit nlm_wakeup_secondary_cpus(void) { unsigned long reset_vec; char *reset_data; @@ -244,7 +257,7 @@ int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask) (nlm_reset_entry_end - nlm_reset_entry)); /* verify the mask and setup core config variables */ - threadmode = nlm_parse_cpumask(wakeup_mask); + threadmode = nlm_parse_cpumask(&nlm_cpumask); /* Setup CPU init parameters */ reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS); diff --git a/arch/mips/netlogic/common/smpboot.S b/arch/mips/netlogic/common/smpboot.S index a13355cc97eb..a0b74874bebe 100644 --- a/arch/mips/netlogic/common/smpboot.S +++ b/arch/mips/netlogic/common/smpboot.S @@ -61,7 +61,7 @@ li t0, LSU_DEFEATURE mfcr t1, t0 - lui t2, 0x4080 /* Enable Unaligned Access, L2HPE */ + lui t2, 0xc080 /* SUE, Enable Unaligned Access, L2HPE */ or t1, t1, t2 #ifdef XLP_AX_WORKAROUND li t2, ~0xe /* S1RCM */ @@ -186,7 +186,7 @@ EXPORT(nlm_boot_siblings) * jump to the secondary wait function. */ mfc0 v0, CP0_EBASE, 1 - andi v0, 0x7f /* v0 <- node/core */ + andi v0, 0x3ff /* v0 <- node/core */ /* Init MMU in the first thread after changing THREAD_MODE * register (Ax Errata?) @@ -263,6 +263,8 @@ NESTED(nlm_boot_secondary_cpus, 16, sp) PTR_L gp, 0(t1) /* a0 has the processor id */ + mfc0 a0, CP0_EBASE, 1 + andi a0, 0x3ff /* a0 <- node/core */ PTR_LA t0, nlm_early_init_secondary jalr t0 nop diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c index 6c65ac701912..529e74742d9f 100644 --- a/arch/mips/netlogic/xlp/nlm_hal.c +++ b/arch/mips/netlogic/xlp/nlm_hal.c @@ -40,23 +40,23 @@ #include <asm/mipsregs.h> #include <asm/time.h> +#include <asm/netlogic/common.h> #include <asm/netlogic/haldefs.h> #include <asm/netlogic/xlp-hal/iomap.h> #include <asm/netlogic/xlp-hal/xlp.h> #include <asm/netlogic/xlp-hal/pic.h> #include <asm/netlogic/xlp-hal/sys.h> -/* These addresses are computed by the nlm_hal_init() */ -uint64_t nlm_io_base; -uint64_t nlm_sys_base; -uint64_t nlm_pic_base; - /* Main initialization */ -void nlm_hal_init(void) +void nlm_node_init(int node) { - nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE); - nlm_sys_base = nlm_get_sys_regbase(0); /* node 0 */ - nlm_pic_base = nlm_get_pic_regbase(0); /* node 0 */ + struct nlm_soc_info *nodep; + + nodep = nlm_get_node(node); + nodep->sysbase = nlm_get_sys_regbase(node); + nodep->picbase = nlm_get_pic_regbase(node); + nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1)); + spin_lock_init(&nodep->piclock); } int nlm_irq_to_irt(int irq) @@ -100,52 +100,15 @@ int nlm_irq_to_irt(int irq) } } -int nlm_irt_to_irq(int irt) -{ - switch (irt) { - case PIC_IRT_UART_0_INDEX: - return PIC_UART_0_IRQ; - case PIC_IRT_UART_1_INDEX: - return PIC_UART_1_IRQ; - case PIC_IRT_PCIE_LINK_0_INDEX: - return PIC_PCIE_LINK_0_IRQ; - case PIC_IRT_PCIE_LINK_1_INDEX: - return PIC_PCIE_LINK_1_IRQ; - case PIC_IRT_PCIE_LINK_2_INDEX: - return PIC_PCIE_LINK_2_IRQ; - case PIC_IRT_PCIE_LINK_3_INDEX: - return PIC_PCIE_LINK_3_IRQ; - case PIC_IRT_EHCI_0_INDEX: - return PIC_EHCI_0_IRQ; - case PIC_IRT_EHCI_1_INDEX: - return PIC_EHCI_1_IRQ; - case PIC_IRT_OHCI_0_INDEX: - return PIC_OHCI_0_IRQ; - case PIC_IRT_OHCI_1_INDEX: - return PIC_OHCI_1_IRQ; - case PIC_IRT_OHCI_2_INDEX: - return PIC_OHCI_2_IRQ; - case PIC_IRT_OHCI_3_INDEX: - return PIC_OHCI_3_IRQ; - case PIC_IRT_MMC_INDEX: - return PIC_MMC_IRQ; - case PIC_IRT_I2C_0_INDEX: - return PIC_I2C_0_IRQ; - case PIC_IRT_I2C_1_INDEX: - return PIC_I2C_1_IRQ; - default: - return -1; - } -} - -unsigned int nlm_get_core_frequency(int core) +unsigned int nlm_get_core_frequency(int node, int core) { unsigned int pll_divf, pll_divr, dfs_div, ext_div; unsigned int rstval, dfsval, denom; - uint64_t num; + uint64_t num, sysbase; - rstval = nlm_read_sys_reg(nlm_sys_base, SYS_POWER_ON_RESET_CFG); - dfsval = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIV_VALUE); + sysbase = nlm_get_node(node)->sysbase; + rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG); + dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE); pll_divf = ((rstval >> 10) & 0x7f) + 1; pll_divr = ((rstval >> 8) & 0x3) + 1; ext_div = ((rstval >> 30) & 0x3) + 1; @@ -159,5 +122,5 @@ unsigned int nlm_get_core_frequency(int core) unsigned int nlm_get_cpu_frequency(void) { - return nlm_get_core_frequency(0); + return nlm_get_core_frequency(0, 0); } diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c index d8997098defd..4894d62043ac 100644 --- a/arch/mips/netlogic/xlp/setup.c +++ b/arch/mips/netlogic/xlp/setup.c @@ -52,26 +52,40 @@ #include <asm/netlogic/xlp-hal/xlp.h> #include <asm/netlogic/xlp-hal/sys.h> -unsigned long nlm_common_ebase = 0x0; - -/* default to uniprocessor */ -uint32_t nlm_coremask = 1, nlm_cpumask = 1; -int nlm_threads_per_core = 1; +uint64_t nlm_io_base; +struct nlm_soc_info nlm_nodes[NLM_NR_NODES]; +cpumask_t nlm_cpumask = CPU_MASK_CPU0; +unsigned int nlm_threads_per_core; extern u32 __dtb_start[]; static void nlm_linux_exit(void) { - nlm_write_sys_reg(nlm_sys_base, SYS_CHIP_RESET, 1); + uint64_t sysbase = nlm_get_node(0)->sysbase; + + nlm_write_sys_reg(sysbase, SYS_CHIP_RESET, 1); for ( ; ; ) cpu_wait(); } void __init plat_mem_setup(void) { + void *fdtp; + panic_timeout = 5; _machine_restart = (void (*)(char *))nlm_linux_exit; _machine_halt = nlm_linux_exit; pm_power_off = nlm_linux_exit; + + /* + * If no FDT pointer is passed in, use the built-in FDT. + * device_tree_init() does not handle CKSEG0 pointers in + * 64-bit, so convert pointer. + */ + fdtp = (void *)(long)fw_arg0; + if (!fdtp) + fdtp = __dtb_start; + fdtp = phys_to_virt(__pa(fdtp)); + early_init_devtree(fdtp); } const char *get_system_type(void) @@ -94,27 +108,19 @@ void xlp_mmu_init(void) (13 + (ffz(PM_DEFAULT_MASK >> 13) / 2))); } -void __init prom_init(void) +void nlm_percpu_init(int hwcpuid) { - void *fdtp; +} +void __init prom_init(void) +{ + nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE); xlp_mmu_init(); - nlm_hal_init(); - - /* - * If no FDT pointer is passed in, use the built-in FDT. - * device_tree_init() does not handle CKSEG0 pointers in - * 64-bit, so convert pointer. - */ - fdtp = (void *)(long)fw_arg0; - if (!fdtp) - fdtp = __dtb_start; - fdtp = phys_to_virt(__pa(fdtp)); - early_init_devtree(fdtp); + nlm_node_init(0); - nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1)); #ifdef CONFIG_SMP - nlm_wakeup_secondary_cpus(0xffffffff); + cpumask_setall(&nlm_cpumask); + nlm_wakeup_secondary_cpus(); /* update TLB size after waking up threads */ current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1; diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c index 44d923ff3846..cb9010642ac3 100644 --- a/arch/mips/netlogic/xlp/wakeup.c +++ b/arch/mips/netlogic/xlp/wakeup.c @@ -51,45 +51,72 @@ #include <asm/netlogic/xlp-hal/xlp.h> #include <asm/netlogic/xlp-hal/sys.h> -static void xlp_enable_secondary_cores(void) +static int xlp_wakeup_core(uint64_t sysbase, int core) { - uint32_t core, value, coremask, syscoremask; + uint32_t coremask, value; int count; - /* read cores in reset from SYS block */ - syscoremask = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET); + coremask = (1 << core); - /* update user specified */ - nlm_coremask = nlm_coremask & (syscoremask | 1); + /* Enable CPU clock */ + value = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL); + value &= ~coremask; + nlm_write_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL, value); - for (core = 1; core < 8; core++) { - coremask = 1 << core; - if ((nlm_coremask & coremask) == 0) - continue; + /* Remove CPU Reset */ + value = nlm_read_sys_reg(sysbase, SYS_CPU_RESET); + value &= ~coremask; + nlm_write_sys_reg(sysbase, SYS_CPU_RESET, value); - /* Enable CPU clock */ - value = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL); - value &= ~coremask; - nlm_write_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL, value); + /* Poll for CPU to mark itself coherent */ + count = 100000; + do { + value = nlm_read_sys_reg(sysbase, SYS_CPU_NONCOHERENT_MODE); + } while ((value & coremask) != 0 && --count > 0); - /* Remove CPU Reset */ - value = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET); - value &= ~coremask; - nlm_write_sys_reg(nlm_sys_base, SYS_CPU_RESET, value); + return count != 0; +} + +static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) +{ + struct nlm_soc_info *nodep; + uint64_t syspcibase; + uint32_t syscoremask; + int core, n, cpu; + + for (n = 0; n < NLM_NR_NODES; n++) { + syspcibase = nlm_get_sys_pcibase(n); + if (nlm_read_reg(syspcibase, 0) == 0xffffffff) + break; + + /* read cores in reset from SYS and account for boot cpu */ + nlm_node_init(n); + nodep = nlm_get_node(n); + syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET); + if (n == 0) + syscoremask |= 1; + + for (core = 0; core < NLM_CORES_PER_NODE; core++) { + /* see if the core exists */ + if ((syscoremask & (1 << core)) == 0) + continue; - /* Poll for CPU to mark itself coherent */ - count = 100000; - do { - value = nlm_read_sys_reg(nlm_sys_base, - SYS_CPU_NONCOHERENT_MODE); - } while ((value & coremask) != 0 && count-- > 0); + /* see if at least the first thread is enabled */ + cpu = (n * NLM_CORES_PER_NODE + core) + * NLM_THREADS_PER_CORE; + if (!cpumask_test_cpu(cpu, wakeup_mask)) + continue; - if (count == 0) - pr_err("Failed to enable core %d\n", core); + /* wake up the core */ + if (xlp_wakeup_core(nodep->sysbase, core)) + nodep->coremask |= 1u << core; + else + pr_err("Failed to enable core %d\n", core); + } } } -void xlp_wakeup_secondary_cpus(void) +void xlp_wakeup_secondary_cpus() { /* * In case of u-boot, the secondaries are in reset @@ -98,5 +125,5 @@ void xlp_wakeup_secondary_cpus(void) xlp_boot_core0_siblings(); /* now get other cores out of reset */ - xlp_enable_secondary_cores(); + xlp_enable_secondary_cores(&nlm_cpumask); } diff --git a/arch/mips/netlogic/xlr/Makefile b/arch/mips/netlogic/xlr/Makefile index c287dea87570..05902bc6f080 100644 --- a/arch/mips/netlogic/xlr/Makefile +++ b/arch/mips/netlogic/xlr/Makefile @@ -1,2 +1,2 @@ -obj-y += setup.o platform.o platform-flash.o -obj-$(CONFIG_SMP) += wakeup.o +obj-y += fmn.o fmn-config.o setup.o platform.o platform-flash.o +obj-$(CONFIG_SMP) += wakeup.o diff --git a/arch/mips/netlogic/xlr/fmn-config.c b/arch/mips/netlogic/xlr/fmn-config.c new file mode 100644 index 000000000000..bed2cffa1008 --- /dev/null +++ b/arch/mips/netlogic/xlr/fmn-config.c @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2003-2012 Broadcom Corporation + * All Rights Reserved + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the Broadcom + * license below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <asm/cpu-info.h> +#include <linux/irq.h> +#include <linux/interrupt.h> + +#include <asm/mipsregs.h> +#include <asm/netlogic/xlr/fmn.h> +#include <asm/netlogic/xlr/xlr.h> +#include <asm/netlogic/common.h> +#include <asm/netlogic/haldefs.h> + +struct xlr_board_fmn_config xlr_board_fmn_config; + +static void __maybe_unused print_credit_config(struct xlr_fmn_info *fmn_info) +{ + int bkt; + + pr_info("Bucket size :\n"); + pr_info("Station\t: Size\n"); + for (bkt = 0; bkt < 16; bkt++) + pr_info(" %d %d %d %d %d %d %d %d\n", + xlr_board_fmn_config.bucket_size[(bkt * 8) + 0], + xlr_board_fmn_config.bucket_size[(bkt * 8) + 1], + xlr_board_fmn_config.bucket_size[(bkt * 8) + 2], + xlr_board_fmn_config.bucket_size[(bkt * 8) + 3], + xlr_board_fmn_config.bucket_size[(bkt * 8) + 4], + xlr_board_fmn_config.bucket_size[(bkt * 8) + 5], + xlr_board_fmn_config.bucket_size[(bkt * 8) + 6], + xlr_board_fmn_config.bucket_size[(bkt * 8) + 7]); + pr_info("\n"); + + pr_info("Credits distribution :\n"); + pr_info("Station\t: Size\n"); + for (bkt = 0; bkt < 16; bkt++) + pr_info(" %d %d %d %d %d %d %d %d\n", + fmn_info->credit_config[(bkt * 8) + 0], + fmn_info->credit_config[(bkt * 8) + 1], + fmn_info->credit_config[(bkt * 8) + 2], + fmn_info->credit_config[(bkt * 8) + 3], + fmn_info->credit_config[(bkt * 8) + 4], + fmn_info->credit_config[(bkt * 8) + 5], + fmn_info->credit_config[(bkt * 8) + 6], + fmn_info->credit_config[(bkt * 8) + 7]); + pr_info("\n"); +} + +static void check_credit_distribution(void) +{ + struct xlr_board_fmn_config *cfg = &xlr_board_fmn_config; + int bkt, n, total_credits, ncores; + + ncores = hweight32(nlm_current_node()->coremask); + for (bkt = 0; bkt < 128; bkt++) { + total_credits = 0; + for (n = 0; n < ncores; n++) + total_credits += cfg->cpu[n].credit_config[bkt]; + total_credits += cfg->gmac[0].credit_config[bkt]; + total_credits += cfg->gmac[1].credit_config[bkt]; + total_credits += cfg->dma.credit_config[bkt]; + total_credits += cfg->cmp.credit_config[bkt]; + total_credits += cfg->sae.credit_config[bkt]; + total_credits += cfg->xgmac[0].credit_config[bkt]; + total_credits += cfg->xgmac[1].credit_config[bkt]; + if (total_credits > cfg->bucket_size[bkt]) + pr_err("ERROR: Bucket %d: credits (%d) > size (%d)\n", + bkt, total_credits, cfg->bucket_size[bkt]); + } + pr_info("Credit distribution complete.\n"); +} + +/** + * Configure bucket size and credits for a device. 'size' is the size of + * the buckets for the device. This size is distributed among all the CPUs + * so that all of them can send messages to the device. + * + * The device is also given 'cpu_credits' to send messages to the CPUs + * + * @dev_info: FMN information structure for each devices + * @start_stn_id: Starting station id of dev_info + * @end_stn_id: End station id of dev_info + * @num_buckets: Total number of buckets for den_info + * @cpu_credits: Allowed credits to cpu for each devices pointing by dev_info + * @size: Size of the each buckets in the device station + */ +static void setup_fmn_cc(struct xlr_fmn_info *dev_info, int start_stn_id, + int end_stn_id, int num_buckets, int cpu_credits, int size) +{ + int i, j, num_core, n, credits_per_cpu; + struct xlr_fmn_info *cpu = xlr_board_fmn_config.cpu; + + num_core = hweight32(nlm_current_node()->coremask); + dev_info->num_buckets = num_buckets; + dev_info->start_stn_id = start_stn_id; + dev_info->end_stn_id = end_stn_id; + + n = num_core; + if (num_core == 3) + n = 4; + + for (i = start_stn_id; i <= end_stn_id; i++) { + xlr_board_fmn_config.bucket_size[i] = size; + + /* Dividing device credits equally to cpus */ + credits_per_cpu = size / n; + for (j = 0; j < num_core; j++) + cpu[j].credit_config[i] = credits_per_cpu; + + /* credits left to distribute */ + credits_per_cpu = size - (credits_per_cpu * num_core); + + /* distribute the remaining credits (if any), among cores */ + for (j = 0; (j < num_core) && (credits_per_cpu >= 4); j++) { + cpu[j].credit_config[i] += 4; + credits_per_cpu -= 4; + } + } + + /* Distributing cpu per bucket credits to devices */ + for (i = 0; i < num_core; i++) { + for (j = 0; j < FMN_CORE_NBUCKETS; j++) + dev_info->credit_config[(i * 8) + j] = cpu_credits; + } +} + +/* + * Each core has 256 slots and 8 buckets, + * Configure the 8 buckets each with 32 slots + */ +static void setup_cpu_fmninfo(struct xlr_fmn_info *cpu, int num_core) +{ + int i, j; + + for (i = 0; i < num_core; i++) { + cpu[i].start_stn_id = (8 * i); + cpu[i].end_stn_id = (8 * i + 8); + + for (j = cpu[i].start_stn_id; j < cpu[i].end_stn_id; j++) + xlr_board_fmn_config.bucket_size[j] = 32; + } +} + +/** + * Setup the FMN details for each devices according to the device available + * in each variant of XLR/XLS processor + */ +void xlr_board_info_setup(void) +{ + struct xlr_fmn_info *cpu = xlr_board_fmn_config.cpu; + struct xlr_fmn_info *gmac = xlr_board_fmn_config.gmac; + struct xlr_fmn_info *xgmac = xlr_board_fmn_config.xgmac; + struct xlr_fmn_info *dma = &xlr_board_fmn_config.dma; + struct xlr_fmn_info *cmp = &xlr_board_fmn_config.cmp; + struct xlr_fmn_info *sae = &xlr_board_fmn_config.sae; + int processor_id, num_core; + + num_core = hweight32(nlm_current_node()->coremask); + processor_id = read_c0_prid() & 0xff00; + + setup_cpu_fmninfo(cpu, num_core); + switch (processor_id) { + case PRID_IMP_NETLOGIC_XLS104: + case PRID_IMP_NETLOGIC_XLS108: + setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, + FMN_STNID_GMAC0_TX3, 8, 16, 32); + setup_fmn_cc(dma, FMN_STNID_DMA_0, + FMN_STNID_DMA_3, 4, 8, 64); + setup_fmn_cc(sae, FMN_STNID_SEC0, + FMN_STNID_SEC1, 2, 8, 128); + break; + + case PRID_IMP_NETLOGIC_XLS204: + case PRID_IMP_NETLOGIC_XLS208: + setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, + FMN_STNID_GMAC0_TX3, 8, 16, 32); + setup_fmn_cc(dma, FMN_STNID_DMA_0, + FMN_STNID_DMA_3, 4, 8, 64); + setup_fmn_cc(sae, FMN_STNID_SEC0, + FMN_STNID_SEC1, 2, 8, 128); + break; + + case PRID_IMP_NETLOGIC_XLS404: + case PRID_IMP_NETLOGIC_XLS408: + case PRID_IMP_NETLOGIC_XLS404B: + case PRID_IMP_NETLOGIC_XLS408B: + case PRID_IMP_NETLOGIC_XLS416B: + setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, + FMN_STNID_GMAC0_TX3, 8, 8, 32); + setup_fmn_cc(&gmac[1], FMN_STNID_GMAC1_FR_0, + FMN_STNID_GMAC1_TX3, 8, 8, 32); + setup_fmn_cc(dma, FMN_STNID_DMA_0, + FMN_STNID_DMA_3, 4, 4, 64); + setup_fmn_cc(cmp, FMN_STNID_CMP_0, + FMN_STNID_CMP_3, 4, 4, 64); + setup_fmn_cc(sae, FMN_STNID_SEC0, + FMN_STNID_SEC1, 2, 8, 128); + break; + + case PRID_IMP_NETLOGIC_XLS412B: + setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, + FMN_STNID_GMAC0_TX3, 8, 8, 32); + setup_fmn_cc(&gmac[1], FMN_STNID_GMAC1_FR_0, + FMN_STNID_GMAC1_TX3, 8, 8, 32); + setup_fmn_cc(dma, FMN_STNID_DMA_0, + FMN_STNID_DMA_3, 4, 4, 64); + setup_fmn_cc(cmp, FMN_STNID_CMP_0, + FMN_STNID_CMP_3, 4, 4, 64); + setup_fmn_cc(sae, FMN_STNID_SEC0, + FMN_STNID_SEC1, 2, 8, 128); + break; + + case PRID_IMP_NETLOGIC_XLR308: + case PRID_IMP_NETLOGIC_XLR308C: + setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, + FMN_STNID_GMAC0_TX3, 8, 16, 32); + setup_fmn_cc(dma, FMN_STNID_DMA_0, + FMN_STNID_DMA_3, 4, 8, 64); + setup_fmn_cc(sae, FMN_STNID_SEC0, + FMN_STNID_SEC1, 2, 4, 128); + break; + + case PRID_IMP_NETLOGIC_XLR532: + case PRID_IMP_NETLOGIC_XLR532C: + case PRID_IMP_NETLOGIC_XLR516C: + case PRID_IMP_NETLOGIC_XLR508C: + setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, + FMN_STNID_GMAC0_TX3, 8, 16, 32); + setup_fmn_cc(dma, FMN_STNID_DMA_0, + FMN_STNID_DMA_3, 4, 8, 64); + setup_fmn_cc(sae, FMN_STNID_SEC0, + FMN_STNID_SEC1, 2, 4, 128); + break; + + case PRID_IMP_NETLOGIC_XLR732: + case PRID_IMP_NETLOGIC_XLR716: + setup_fmn_cc(&xgmac[0], FMN_STNID_XMAC0_00_TX, + FMN_STNID_XMAC0_15_TX, 8, 0, 32); + setup_fmn_cc(&xgmac[1], FMN_STNID_XMAC1_00_TX, + FMN_STNID_XMAC1_15_TX, 8, 0, 32); + setup_fmn_cc(&gmac[0], FMN_STNID_GMAC0, + FMN_STNID_GMAC0_TX3, 8, 24, 32); + setup_fmn_cc(dma, FMN_STNID_DMA_0, + FMN_STNID_DMA_3, 4, 4, 64); + setup_fmn_cc(sae, FMN_STNID_SEC0, + FMN_STNID_SEC1, 2, 4, 128); + break; + default: + pr_err("Unknown CPU with processor ID [%d]\n", processor_id); + pr_err("Error: Cannot initialize FMN credits.\n"); + } + + check_credit_distribution(); + +#if 0 /* debug */ + print_credit_config(&cpu[0]); + print_credit_config(&gmac[0]); +#endif +} diff --git a/arch/mips/netlogic/xlr/fmn.c b/arch/mips/netlogic/xlr/fmn.c new file mode 100644 index 000000000000..4d74f03de506 --- /dev/null +++ b/arch/mips/netlogic/xlr/fmn.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2003-2012 Broadcom Corporation + * All Rights Reserved + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the Broadcom + * license below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <linux/kernel.h> +#include <linux/irqreturn.h> +#include <linux/irq.h> +#include <linux/interrupt.h> + +#include <asm/mipsregs.h> +#include <asm/netlogic/interrupt.h> +#include <asm/netlogic/xlr/fmn.h> +#include <asm/netlogic/common.h> + +#define COP2_CC_INIT_CPU_DEST(dest, conf) \ +do { \ + nlm_write_c2_cc##dest(0, conf[(dest * 8) + 0]); \ + nlm_write_c2_cc##dest(1, conf[(dest * 8) + 1]); \ + nlm_write_c2_cc##dest(2, conf[(dest * 8) + 2]); \ + nlm_write_c2_cc##dest(3, conf[(dest * 8) + 3]); \ + nlm_write_c2_cc##dest(4, conf[(dest * 8) + 4]); \ + nlm_write_c2_cc##dest(5, conf[(dest * 8) + 5]); \ + nlm_write_c2_cc##dest(6, conf[(dest * 8) + 6]); \ + nlm_write_c2_cc##dest(7, conf[(dest * 8) + 7]); \ +} while (0) + +struct fmn_message_handler { + void (*action)(int, int, int, int, struct nlm_fmn_msg *, void *); + void *arg; +} msg_handlers[128]; + +/* + * FMN interrupt handler. We configure the FMN so that any messages in + * any of the CPU buckets will trigger an interrupt on the CPU. + * The message can be from any device on the FMN (like NAE/SAE/DMA). + * The source station id is used to figure out which of the registered + * handlers have to be called. + */ +static irqreturn_t fmn_message_handler(int irq, void *data) +{ + struct fmn_message_handler *hndlr; + int bucket, rv; + int size = 0, code = 0, src_stnid = 0; + struct nlm_fmn_msg msg; + uint32_t mflags, bkt_status; + + mflags = nlm_cop2_enable(); + /* Disable message ring interrupt */ + nlm_fmn_setup_intr(irq, 0); + while (1) { + /* 8 bkts per core, [24:31] each bit represents one bucket + * Bit is Zero if bucket is not empty */ + bkt_status = (nlm_read_c2_status() >> 24) & 0xff; + if (bkt_status == 0xff) + break; + for (bucket = 0; bucket < 8; bucket++) { + /* Continue on empty bucket */ + if (bkt_status & (1 << bucket)) + continue; + rv = nlm_fmn_receive(bucket, &size, &code, &src_stnid, + &msg); + if (rv != 0) + continue; + + hndlr = &msg_handlers[src_stnid]; + if (hndlr->action == NULL) + pr_warn("No msgring handler for stnid %d\n", + src_stnid); + else { + nlm_cop2_restore(mflags); + hndlr->action(bucket, src_stnid, size, code, + &msg, hndlr->arg); + mflags = nlm_cop2_enable(); + } + } + }; + /* Enable message ring intr, to any thread in core */ + nlm_fmn_setup_intr(irq, (1 << nlm_threads_per_core) - 1); + nlm_cop2_restore(mflags); + return IRQ_HANDLED; +} + +struct irqaction fmn_irqaction = { + .handler = fmn_message_handler, + .flags = IRQF_PERCPU, + .name = "fmn", +}; + +void xlr_percpu_fmn_init(void) +{ + struct xlr_fmn_info *cpu_fmn_info; + int *bucket_sizes; + uint32_t flags; + int id; + + BUG_ON(nlm_thread_id() != 0); + id = nlm_core_id(); + + bucket_sizes = xlr_board_fmn_config.bucket_size; + cpu_fmn_info = &xlr_board_fmn_config.cpu[id]; + flags = nlm_cop2_enable(); + + /* Setup bucket sizes for the core. */ + nlm_write_c2_bucksize(0, bucket_sizes[id * 8 + 0]); + nlm_write_c2_bucksize(1, bucket_sizes[id * 8 + 1]); + nlm_write_c2_bucksize(2, bucket_sizes[id * 8 + 2]); + nlm_write_c2_bucksize(3, bucket_sizes[id * 8 + 3]); + nlm_write_c2_bucksize(4, bucket_sizes[id * 8 + 4]); + nlm_write_c2_bucksize(5, bucket_sizes[id * 8 + 5]); + nlm_write_c2_bucksize(6, bucket_sizes[id * 8 + 6]); + nlm_write_c2_bucksize(7, bucket_sizes[id * 8 + 7]); + + /* + * For sending FMN messages, we need credits on the destination + * bucket. Program the credits this core has on the 128 possible + * destination buckets. + * We cannot use a loop here, because the the first argument has + * to be a constant integer value. + */ + COP2_CC_INIT_CPU_DEST(0, cpu_fmn_info->credit_config); + COP2_CC_INIT_CPU_DEST(1, cpu_fmn_info->credit_config); + COP2_CC_INIT_CPU_DEST(2, cpu_fmn_info->credit_config); + COP2_CC_INIT_CPU_DEST(3, cpu_fmn_info->credit_config); + COP2_CC_INIT_CPU_DEST(4, cpu_fmn_info->credit_config); + COP2_CC_INIT_CPU_DEST(5, cpu_fmn_info->credit_config); + COP2_CC_INIT_CPU_DEST(6, cpu_fmn_info->credit_config); + COP2_CC_INIT_CPU_DEST(7, cpu_fmn_info->credit_config); + COP2_CC_INIT_CPU_DEST(8, cpu_fmn_info->credit_config); + COP2_CC_INIT_CPU_DEST(9, cpu_fmn_info->credit_config); + COP2_CC_INIT_CPU_DEST(10, cpu_fmn_info->credit_config); + COP2_CC_INIT_CPU_DEST(11, cpu_fmn_info->credit_config); + COP2_CC_INIT_CPU_DEST(12, cpu_fmn_info->credit_config); + COP2_CC_INIT_CPU_DEST(13, cpu_fmn_info->credit_config); + COP2_CC_INIT_CPU_DEST(14, cpu_fmn_info->credit_config); + COP2_CC_INIT_CPU_DEST(15, cpu_fmn_info->credit_config); + + /* enable FMN interrupts on this CPU */ + nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1); + nlm_cop2_restore(flags); +} + + +/* + * Register a FMN message handler with respect to the source station id + * @stnid: source station id + * @action: Handler function pointer + */ +int nlm_register_fmn_handler(int start_stnid, int end_stnid, + void (*action)(int, int, int, int, struct nlm_fmn_msg *, void *), + void *arg) +{ + int sstnid; + + for (sstnid = start_stnid; sstnid <= end_stnid; sstnid++) { + msg_handlers[sstnid].arg = arg; + smp_wmb(); + msg_handlers[sstnid].action = action; + } + pr_debug("Registered FMN msg handler for stnid %d-%d\n", + start_stnid, end_stnid); + return 0; +} + +void nlm_setup_fmn_irq(void) +{ + uint32_t flags; + + /* setup irq only once */ + setup_irq(IRQ_FMN, &fmn_irqaction); + + flags = nlm_cop2_enable(); + nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1); + nlm_cop2_restore(flags); +} diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c index 81b1d311834f..4e7f49d3d5a8 100644 --- a/arch/mips/netlogic/xlr/setup.c +++ b/arch/mips/netlogic/xlr/setup.c @@ -49,16 +49,15 @@ #include <asm/netlogic/xlr/iomap.h> #include <asm/netlogic/xlr/pic.h> #include <asm/netlogic/xlr/gpio.h> +#include <asm/netlogic/xlr/fmn.h> uint64_t nlm_io_base = DEFAULT_NETLOGIC_IO_BASE; -uint64_t nlm_pic_base; struct psb_info nlm_prom_info; -unsigned long nlm_common_ebase = 0x0; - /* default to uniprocessor */ -uint32_t nlm_coremask = 1, nlm_cpumask = 1; -int nlm_threads_per_core = 1; +unsigned int nlm_threads_per_core = 1; +struct nlm_soc_info nlm_nodes[NLM_NR_NODES]; +cpumask_t nlm_cpumask = CPU_MASK_CPU0; static void __init nlm_early_serial_setup(void) { @@ -113,6 +112,12 @@ void __init prom_free_prom_memory(void) /* Nothing yet */ } +void nlm_percpu_init(int hwcpuid) +{ + if (hwcpuid % 4 == 0) + xlr_percpu_fmn_init(); +} + static void __init build_arcs_cmdline(int *argv) { int i, remain, len; @@ -176,9 +181,19 @@ static void prom_add_memory(void) } } +static void nlm_init_node(void) +{ + struct nlm_soc_info *nodep; + + nodep = nlm_current_node(); + nodep->picbase = nlm_mmio_base(NETLOGIC_IO_PIC_OFFSET); + nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1)); + spin_lock_init(&nodep->piclock); +} + void __init prom_init(void) { - int *argv, *envp; /* passed as 32 bit ptrs */ + int i, *argv, *envp; /* passed as 32 bit ptrs */ struct psb_info *prom_infop; /* truncate to 32 bit and sign extend all args */ @@ -187,15 +202,19 @@ void __init prom_init(void) prom_infop = (struct psb_info *)(long)(int)fw_arg3; nlm_prom_info = *prom_infop; - nlm_pic_base = nlm_mmio_base(NETLOGIC_IO_PIC_OFFSET); + nlm_init_node(); nlm_early_serial_setup(); build_arcs_cmdline(argv); - nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1)); prom_add_memory(); #ifdef CONFIG_SMP - nlm_wakeup_secondary_cpus(nlm_prom_info.online_cpu_map); + for (i = 0; i < 32; i++) + if (nlm_prom_info.online_cpu_map & (1 << i)) + cpumask_set_cpu(i, &nlm_cpumask); + nlm_wakeup_secondary_cpus(); register_smp_ops(&nlm_smp_ops); #endif + xlr_board_info_setup(); + xlr_percpu_fmn_init(); } diff --git a/arch/mips/netlogic/xlr/wakeup.c b/arch/mips/netlogic/xlr/wakeup.c index db5d987d4881..3ebf7411d67b 100644 --- a/arch/mips/netlogic/xlr/wakeup.c +++ b/arch/mips/netlogic/xlr/wakeup.c @@ -33,6 +33,7 @@ */ #include <linux/init.h> +#include <linux/delay.h> #include <linux/threads.h> #include <asm/asm.h> @@ -50,18 +51,34 @@ int __cpuinit xlr_wakeup_secondary_cpus(void) { - unsigned int i, boot_cpu; + struct nlm_soc_info *nodep; + unsigned int i, j, boot_cpu; /* * In case of RMI boot, hit with NMI to get the cores * from bootloader to linux code. */ + nodep = nlm_get_node(0); boot_cpu = hard_smp_processor_id(); nlm_set_nmi_handler(nlm_rmiboot_preboot); for (i = 0; i < NR_CPUS; i++) { - if (i == boot_cpu || (nlm_cpumask & (1u << i)) == 0) + if (i == boot_cpu || !cpumask_test_cpu(i, &nlm_cpumask)) continue; - nlm_pic_send_ipi(nlm_pic_base, i, 1, 1); /* send NMI */ + nlm_pic_send_ipi(nodep->picbase, i, 1, 1); /* send NMI */ + } + + /* Fill up the coremask early */ + nodep->coremask = 1; + for (i = 1; i < NLM_CORES_PER_NODE; i++) { + for (j = 1000000; j > 0; j--) { + if (nlm_cpu_ready[i * NLM_THREADS_PER_CORE]) + break; + udelay(10); + } + if (j != 0) + nodep->coremask |= (1u << i); + else + pr_err("Failed to wakeup core %d\n", i); } return 0; diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile index 1208c280f77d..9c0a6782c091 100644 --- a/arch/mips/oprofile/Makefile +++ b/arch/mips/oprofile/Makefile @@ -12,5 +12,5 @@ oprofile-$(CONFIG_CPU_MIPS32) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_MIPS64) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o -oprofile-$(CONFIG_CPU_RM9000) += op_model_rm9000.o +oprofile-$(CONFIG_CPU_XLR) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index f80480a5a032..e32db1ff02c7 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c @@ -16,7 +16,6 @@ #include "op_impl.h" extern struct op_mips_model op_model_mipsxx_ops __weak; -extern struct op_mips_model op_model_rm9000_ops __weak; extern struct op_mips_model op_model_loongson2_ops __weak; static struct op_mips_model *model; @@ -91,12 +90,10 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) case CPU_R10000: case CPU_R12000: case CPU_R14000: + case CPU_XLR: lmodel = &op_model_mipsxx_ops; break; - case CPU_RM9000: - lmodel = &op_model_rm9000_ops; - break; case CPU_LOONGSON2: lmodel = &op_model_loongson2_ops; break; diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 28ea1a4cc576..786254630403 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -31,8 +31,22 @@ #define M_COUNTER_OVERFLOW (1UL << 31) +/* Netlogic XLR specific, count events in all threads in a core */ +#define M_PERFCTL_COUNT_ALL_THREADS (1UL << 13) + static int (*save_perf_irq)(void); +/* + * XLR has only one set of counters per core. Designate the + * first hardware thread in the core for setup and init. + * Skip CPUs with non-zero hardware thread id (4 hwt per core) + */ +#ifdef CONFIG_CPU_XLR +#define oprofile_skip_cpu(c) ((cpu_logical_map(c) & 0x3) != 0) +#else +#define oprofile_skip_cpu(c) 0 +#endif + #ifdef CONFIG_MIPS_MT_SMP static int cpu_has_mipsmt_pertccounters; #define WHAT (M_TC_EN_VPE | \ @@ -152,6 +166,8 @@ static void mipsxx_reg_setup(struct op_counter_config *ctr) reg.control[i] |= M_PERFCTL_USER; if (ctr[i].exl) reg.control[i] |= M_PERFCTL_EXL; + if (current_cpu_type() == CPU_XLR) + reg.control[i] |= M_PERFCTL_COUNT_ALL_THREADS; reg.counter[i] = 0x80000000 - ctr[i].count; } } @@ -162,6 +178,9 @@ static void mipsxx_cpu_setup(void *args) { unsigned int counters = op_model_mipsxx_ops.num_counters; + if (oprofile_skip_cpu(smp_processor_id())) + return; + switch (counters) { case 4: w_c0_perfctrl3(0); @@ -183,6 +202,9 @@ static void mipsxx_cpu_start(void *args) { unsigned int counters = op_model_mipsxx_ops.num_counters; + if (oprofile_skip_cpu(smp_processor_id())) + return; + switch (counters) { case 4: w_c0_perfctrl3(WHAT | reg.control[3]); @@ -200,6 +222,9 @@ static void mipsxx_cpu_stop(void *args) { unsigned int counters = op_model_mipsxx_ops.num_counters; + if (oprofile_skip_cpu(smp_processor_id())) + return; + switch (counters) { case 4: w_c0_perfctrl3(0); @@ -372,6 +397,10 @@ static int __init mipsxx_init(void) op_model_mipsxx_ops.cpu_type = "mips/loongson1"; break; + case CPU_XLR: + op_model_mipsxx_ops.cpu_type = "mips/xlr"; + break; + default: printk(KERN_ERR "Profiling unsupported for this CPU\n"); diff --git a/arch/mips/oprofile/op_model_rm9000.c b/arch/mips/oprofile/op_model_rm9000.c deleted file mode 100644 index 3aa81384966d..000000000000 --- a/arch/mips/oprofile/op_model_rm9000.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2004 by Ralf Baechle - */ -#include <linux/init.h> -#include <linux/oprofile.h> -#include <linux/interrupt.h> -#include <linux/smp.h> - -#include "op_impl.h" - -#define RM9K_COUNTER1_EVENT(event) ((event) << 0) -#define RM9K_COUNTER1_SUPERVISOR (1ULL << 7) -#define RM9K_COUNTER1_KERNEL (1ULL << 8) -#define RM9K_COUNTER1_USER (1ULL << 9) -#define RM9K_COUNTER1_ENABLE (1ULL << 10) -#define RM9K_COUNTER1_OVERFLOW (1ULL << 15) - -#define RM9K_COUNTER2_EVENT(event) ((event) << 16) -#define RM9K_COUNTER2_SUPERVISOR (1ULL << 23) -#define RM9K_COUNTER2_KERNEL (1ULL << 24) -#define RM9K_COUNTER2_USER (1ULL << 25) -#define RM9K_COUNTER2_ENABLE (1ULL << 26) -#define RM9K_COUNTER2_OVERFLOW (1ULL << 31) - -extern unsigned int rm9000_perfcount_irq; - -static struct rm9k_register_config { - unsigned int control; - unsigned int reset_counter1; - unsigned int reset_counter2; -} reg; - -/* Compute all of the registers in preparation for enabling profiling. */ - -static void rm9000_reg_setup(struct op_counter_config *ctr) -{ - unsigned int control = 0; - - /* Compute the performance counter control word. */ - /* For now count kernel and user mode */ - if (ctr[0].enabled) - control |= RM9K_COUNTER1_EVENT(ctr[0].event) | - RM9K_COUNTER1_KERNEL | - RM9K_COUNTER1_USER | - RM9K_COUNTER1_ENABLE; - if (ctr[1].enabled) - control |= RM9K_COUNTER2_EVENT(ctr[1].event) | - RM9K_COUNTER2_KERNEL | - RM9K_COUNTER2_USER | - RM9K_COUNTER2_ENABLE; - reg.control = control; - - reg.reset_counter1 = 0x80000000 - ctr[0].count; - reg.reset_counter2 = 0x80000000 - ctr[1].count; -} - -/* Program all of the registers in preparation for enabling profiling. */ - -static void rm9000_cpu_setup(void *args) -{ - uint64_t perfcount; - - perfcount = ((uint64_t) reg.reset_counter2 << 32) | reg.reset_counter1; - write_c0_perfcount(perfcount); -} - -static void rm9000_cpu_start(void *args) -{ - /* Start all counters on current CPU */ - write_c0_perfcontrol(reg.control); -} - -static void rm9000_cpu_stop(void *args) -{ - /* Stop all counters on current CPU */ - write_c0_perfcontrol(0); -} - -static irqreturn_t rm9000_perfcount_handler(int irq, void *dev_id) -{ - unsigned int control = read_c0_perfcontrol(); - struct pt_regs *regs = get_irq_regs(); - uint32_t counter1, counter2; - uint64_t counters; - - /* - * RM9000 combines two 32-bit performance counters into a single - * 64-bit coprocessor zero register. To avoid a race updating the - * registers we need to stop the counters while we're messing with - * them ... - */ - write_c0_perfcontrol(0); - - counters = read_c0_perfcount(); - counter1 = counters; - counter2 = counters >> 32; - - if (control & RM9K_COUNTER1_OVERFLOW) { - oprofile_add_sample(regs, 0); - counter1 = reg.reset_counter1; - } - if (control & RM9K_COUNTER2_OVERFLOW) { - oprofile_add_sample(regs, 1); - counter2 = reg.reset_counter2; - } - - counters = ((uint64_t)counter2 << 32) | counter1; - write_c0_perfcount(counters); - write_c0_perfcontrol(reg.control); - - return IRQ_HANDLED; -} - -static int __init rm9000_init(void) -{ - return request_irq(rm9000_perfcount_irq, rm9000_perfcount_handler, - 0, "Perfcounter", NULL); -} - -static void rm9000_exit(void) -{ - free_irq(rm9000_perfcount_irq, NULL); -} - -struct op_mips_model op_model_rm9000_ops = { - .reg_setup = rm9000_reg_setup, - .cpu_setup = rm9000_cpu_setup, - .init = rm9000_init, - .exit = rm9000_exit, - .cpu_start = rm9000_cpu_start, - .cpu_stop = rm9000_cpu_stop, - .cpu_type = "mips/rm9000", - .num_counters = 2 -}; diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index e13a71cbc3c7..ce995d3d9440 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -34,8 +34,6 @@ obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o obj-$(CONFIG_PMC_MSP7120_FPGA) += fixup-pmcmsp.o ops-pmcmsp.o -obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \ - pci-yosemite.o obj-$(CONFIG_SGI_IP27) += ops-bridge.o pci-ip27.o obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o diff --git a/arch/mips/pci/fixup-yosemite.c b/arch/mips/pci/fixup-yosemite.c deleted file mode 100644 index fdafb13a793b..000000000000 --- a/arch/mips/pci/fixup-yosemite.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2003 PMC-Sierra - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/pci.h> - -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - if (pin == 0) - return -1; - - return 3; /* Everything goes to one irq bit */ -} - -/* Do platform specific device initialization at pci_enable_device() time */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - return 0; -} diff --git a/arch/mips/pci/ops-bridge.c b/arch/mips/pci/ops-bridge.c index b46b3e211775..438319465cb4 100644 --- a/arch/mips/pci/ops-bridge.c +++ b/arch/mips/pci/ops-bridge.c @@ -56,7 +56,7 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_DEVICE_NOT_FOUND; /* - * IOC3 is fucked fucked beyond believe ... Don't even give the + * IOC3 is fucking fucked beyond belief ... Don't even give the * generic PCI code a chance to look at it for real ... */ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) @@ -76,7 +76,7 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, oh_my_gawd: /* - * IOC3 is fucked fucked beyond believe ... Don't even give the + * IOC3 is fucking fucked beyond belief ... Don't even give the * generic PCI code a chance to look at the wrong register. */ if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { @@ -85,7 +85,7 @@ oh_my_gawd: } /* - * IOC3 is fucked fucked beyond believe ... Don't try to access + * IOC3 is fucking fucked beyond belief ... Don't try to access * anything but 32-bit words ... */ addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; @@ -118,7 +118,7 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_DEVICE_NOT_FOUND; /* - * IOC3 is fucked fucked beyond believe ... Don't even give the + * IOC3 is fucking fucked beyond belief ... Don't even give the * generic PCI code a chance to look at it for real ... */ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) @@ -139,7 +139,7 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, oh_my_gawd: /* - * IOC3 is fucked fucked beyond believe ... Don't even give the + * IOC3 is fucking fucked beyond belief ... Don't even give the * generic PCI code a chance to look at the wrong register. */ if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { @@ -148,7 +148,7 @@ oh_my_gawd: } /* - * IOC3 is fucked fucked beyond believe ... Don't try to access + * IOC3 is fucking fucked beyond belief ... Don't try to access * anything but 32-bit words ... */ bridge->b_pci_cfg = (busno << 16) | (slot << 11); @@ -189,7 +189,7 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_DEVICE_NOT_FOUND; /* - * IOC3 is fucked fucked beyond believe ... Don't even give the + * IOC3 is fucking fucked beyond belief ... Don't even give the * generic PCI code a chance to look at it for real ... */ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) @@ -213,14 +213,14 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn, oh_my_gawd: /* - * IOC3 is fucked fucked beyond believe ... Don't even give the + * IOC3 is fucking fucked beyond belief ... Don't even give the * generic PCI code a chance to touch the wrong register. */ if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) return PCIBIOS_SUCCESSFUL; /* - * IOC3 is fucked fucked beyond believe ... Don't try to access + * IOC3 is fucking fucked beyond belief ... Don't try to access * anything but 32-bit words ... */ addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; @@ -257,7 +257,7 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_DEVICE_NOT_FOUND; /* - * IOC3 is fucked fucked beyond believe ... Don't even give the + * IOC3 is fucking fucked beyond belief ... Don't even give the * generic PCI code a chance to look at it for real ... */ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) @@ -281,14 +281,14 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, oh_my_gawd: /* - * IOC3 is fucked fucked beyond believe ... Don't even give the + * IOC3 is fucking fucked beyond belief ... Don't even give the * generic PCI code a chance to touch the wrong register. */ if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) return PCIBIOS_SUCCESSFUL; /* - * IOC3 is fucked fucked beyond believe ... Don't try to access + * IOC3 is fucking fucked beyond belief ... Don't try to access * anything but 32-bit words ... */ addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; diff --git a/arch/mips/pci/ops-titan-ht.c b/arch/mips/pci/ops-titan-ht.c deleted file mode 100644 index 57d54adc9e20..000000000000 --- a/arch/mips/pci/ops-titan-ht.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2003 PMC-Sierra - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <asm/io.h> - -#include <asm/titan_dep.h> - -static int titan_ht_config_read_dword(struct pci_bus *bus, unsigned int devfn, - int offset, u32 *val) -{ - volatile uint32_t address; - int busno; - - busno = bus->number; - - address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000; - if (busno != 0) - address |= 1; - - /* - * RM9000 HT Errata: Issue back to back HT config - * transcations. Issue a BIU sync before and - * after the HT cycle - */ - - *(volatile int32_t *) 0xfb0000f0 |= 0x2; - - udelay(30); - - *(volatile int32_t *) 0xfb0006f8 = address; - *(val) = *(volatile int32_t *) 0xfb0006fc; - - udelay(30); - - * (volatile int32_t *) 0xfb0000f0 |= 0x2; - - return PCIBIOS_SUCCESSFUL; -} - -static int titan_ht_config_read(struct pci_bus *bus, unsigned int devfn, - int offset, int size, u32 *val) -{ - uint32_t dword; - - titan_ht_config_read_dword(bus, devfn, offset, &dword); - - dword >>= ((offset & 3) << 3); - dword &= (0xffffffffU >> ((4 - size) << 8)); - - return PCIBIOS_SUCCESSFUL; -} - -static inline int titan_ht_config_write_dword(struct pci_bus *bus, - unsigned int devfn, int offset, u32 val) -{ - volatile uint32_t address; - int busno; - - busno = bus->number; - - address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000; - if (busno != 0) - address |= 1; - - *(volatile int32_t *) 0xfb0000f0 |= 0x2; - - udelay(30); - - *(volatile int32_t *) 0xfb0006f8 = address; - *(volatile int32_t *) 0xfb0006fc = val; - - udelay(30); - - *(volatile int32_t *) 0xfb0000f0 |= 0x2; - - return PCIBIOS_SUCCESSFUL; -} - -static int titan_ht_config_write(struct pci_bus *bus, unsigned int devfn, - int offset, int size, u32 val) -{ - uint32_t val1, val2, mask; - - titan_ht_config_read_dword(bus, devfn, offset, &val2); - - val1 = val << ((offset & 3) << 3); - mask = ~(0xffffffffU >> ((4 - size) << 8)); - val2 &= ~(mask << ((offset & 3) << 8)); - - titan_ht_config_write_dword(bus, devfn, offset, val1 | val2); - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops titan_ht_pci_ops = { - .read = titan_ht_config_read, - .write = titan_ht_config_write, -}; diff --git a/arch/mips/pci/ops-titan.c b/arch/mips/pci/ops-titan.c deleted file mode 100644 index ebf8fc40e9b2..000000000000 --- a/arch/mips/pci/ops-titan.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2003 PMC-Sierra - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/kernel.h> - -#include <asm/pci.h> -#include <asm/io.h> -#include <asm/rm9k-ocd.h> - -/* - * PCI specific defines - */ -#define TITAN_PCI_0_CONFIG_ADDRESS 0x780 -#define TITAN_PCI_0_CONFIG_DATA 0x784 - -/* - * Titan PCI Config Read Byte - */ -static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg, - int size, u32 * val) -{ - uint32_t address, tmp; - int dev, busno, func; - - busno = bus->number; - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - address = (busno << 16) | (dev << 11) | (func << 8) | - (reg & 0xfc) | 0x80000000; - - - /* start the configuration cycle */ - ocd_writel(address, TITAN_PCI_0_CONFIG_ADDRESS); - tmp = ocd_readl(TITAN_PCI_0_CONFIG_DATA) >> ((reg & 3) << 3); - - switch (size) { - case 1: - tmp &= 0xff; - case 2: - tmp &= 0xffff; - } - *val = tmp; - - return PCIBIOS_SUCCESSFUL; -} - -static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg, - int size, u32 val) -{ - uint32_t address; - int dev, busno, func; - - busno = bus->number; - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - address = (busno << 16) | (dev << 11) | (func << 8) | - (reg & 0xfc) | 0x80000000; - - /* start the configuration cycle */ - ocd_writel(address, TITAN_PCI_0_CONFIG_ADDRESS); - - /* write the data */ - switch (size) { - case 1: - ocd_writeb(val, TITAN_PCI_0_CONFIG_DATA + (~reg & 0x3)); - break; - - case 2: - ocd_writew(val, TITAN_PCI_0_CONFIG_DATA + (~reg & 0x2)); - break; - - case 4: - ocd_writel(val, TITAN_PCI_0_CONFIG_DATA); - break; - } - - return PCIBIOS_SUCCESSFUL; -} - -/* - * Titan PCI structure - */ -struct pci_ops titan_pci_ops = { - titan_read_config, - titan_write_config, -}; diff --git a/arch/mips/pci/pci-bcm63xx.c b/arch/mips/pci/pci-bcm63xx.c index 8a48139d219c..ca179b6ff39b 100644 --- a/arch/mips/pci/pci-bcm63xx.c +++ b/arch/mips/pci/pci-bcm63xx.c @@ -11,8 +11,11 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/delay.h> +#include <linux/clk.h> #include <asm/bootinfo.h> +#include <bcm63xx_reset.h> + #include "pci-bcm63xx.h" /* @@ -119,41 +122,36 @@ static void __init bcm63xx_reset_pcie(void) { u32 val; - /* enable clock */ - val = bcm_perf_readl(PERF_CKCTL_REG); - val |= CKCTL_6328_PCIE_EN; - bcm_perf_writel(val, PERF_CKCTL_REG); - /* enable SERDES */ val = bcm_misc_readl(MISC_SERDES_CTRL_REG); val |= SERDES_PCIE_EN | SERDES_PCIE_EXD_EN; bcm_misc_writel(val, MISC_SERDES_CTRL_REG); /* reset the PCIe core */ - val = bcm_perf_readl(PERF_SOFTRESET_6328_REG); - - val &= ~SOFTRESET_6328_PCIE_MASK; - val &= ~SOFTRESET_6328_PCIE_CORE_MASK; - val &= ~SOFTRESET_6328_PCIE_HARD_MASK; - val &= ~SOFTRESET_6328_PCIE_EXT_MASK; - bcm_perf_writel(val, PERF_SOFTRESET_6328_REG); + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 1); + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 1); mdelay(10); - val |= SOFTRESET_6328_PCIE_MASK; - val |= SOFTRESET_6328_PCIE_CORE_MASK; - val |= SOFTRESET_6328_PCIE_HARD_MASK; - bcm_perf_writel(val, PERF_SOFTRESET_6328_REG); + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 0); mdelay(10); - val |= SOFTRESET_6328_PCIE_EXT_MASK; - bcm_perf_writel(val, PERF_SOFTRESET_6328_REG); + bcm63xx_core_set_reset(BCM63XX_RESET_PCIE_EXT, 0); mdelay(200); } +static struct clk *pcie_clk; + static int __init bcm63xx_register_pcie(void) { u32 val; + /* enable clock */ + pcie_clk = clk_get(NULL, "pcie"); + if (IS_ERR_OR_NULL(pcie_clk)) + return -ENODEV; + + clk_prepare_enable(pcie_clk); + bcm63xx_reset_pcie(); /* configure the PCIe bridge */ diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c index 4b0c347d7a82..5b5ed76c6f47 100644 --- a/arch/mips/pci/pci-octeon.c +++ b/arch/mips/pci/pci-octeon.c @@ -11,6 +11,7 @@ #include <linux/interrupt.h> #include <linux/time.h> #include <linux/delay.h> +#include <linux/platform_device.h> #include <linux/swiotlb.h> #include <asm/time.h> @@ -704,6 +705,10 @@ static int __init octeon_pci_setup(void) */ cvmx_write_csr(CVMX_NPI_PCI_INT_SUM2, -1); + if (IS_ERR(platform_device_register_simple("octeon_pci_edac", + -1, NULL, 0))) + pr_err("Registation of co_pci_edac failed!\n"); + octeon_pci_dma_init(); return 0; diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c index 18af021d289a..0c18ccc79623 100644 --- a/arch/mips/pci/pci-xlr.c +++ b/arch/mips/pci/pci-xlr.c @@ -47,6 +47,7 @@ #include <asm/netlogic/interrupt.h> #include <asm/netlogic/haldefs.h> +#include <asm/netlogic/common.h> #include <asm/netlogic/xlr/msidef.h> #include <asm/netlogic/xlr/iomap.h> @@ -174,22 +175,9 @@ static struct pci_dev *xls_get_pcie_link(const struct pci_dev *dev) return p ? bus->self : NULL; } -static int get_irq_vector(const struct pci_dev *dev) +static int nlm_pci_link_to_irq(int link) { - struct pci_dev *lnk; - - if (!nlm_chip_is_xls()) - return PIC_PCIX_IRQ; /* for XLR just one IRQ */ - - /* - * For XLS PCIe, there is an IRQ per Link, find out which - * link the device is on to assign interrupts - */ - lnk = xls_get_pcie_link(dev); - if (lnk == NULL) - return 0; - - switch (PCI_SLOT(lnk->devfn)) { + switch (link) { case 0: return PIC_PCIE_LINK0_IRQ; case 1: @@ -205,10 +193,26 @@ static int get_irq_vector(const struct pci_dev *dev) else return PIC_PCIE_LINK3_IRQ; } - WARN(1, "Unexpected devfn %d\n", lnk->devfn); + WARN(1, "Unexpected link %d\n", link); return 0; } +static int get_irq_vector(const struct pci_dev *dev) +{ + struct pci_dev *lnk; + int link; + + if (!nlm_chip_is_xls()) + return PIC_PCIX_IRQ; /* for XLR just one IRQ */ + + lnk = xls_get_pcie_link(dev); + if (lnk == NULL) + return 0; + + link = PCI_SLOT(lnk->devfn); + return nlm_pci_link_to_irq(link); +} + #ifdef CONFIG_PCI_MSI void destroy_irq(unsigned int irq) { @@ -332,6 +336,9 @@ int pcibios_plat_dev_init(struct pci_dev *dev) static int __init pcibios_init(void) { + void (*extra_ack)(struct irq_data *); + int link, irq; + /* PSB assigns PCI resources */ pci_set_flags(PCI_PROBE_ONLY); pci_config_base = ioremap(DEFAULT_PCI_CONFIG_BASE, 16 << 20); @@ -350,27 +357,19 @@ static int __init pcibios_init(void) * For PCI interrupts, we need to ack the PCI controller too, overload * irq handler data to do this */ - if (nlm_chip_is_xls()) { - if (nlm_chip_is_xls_b()) { - irq_set_handler_data(PIC_PCIE_LINK0_IRQ, - xls_pcie_ack_b); - irq_set_handler_data(PIC_PCIE_LINK1_IRQ, - xls_pcie_ack_b); - irq_set_handler_data(PIC_PCIE_XLSB0_LINK2_IRQ, - xls_pcie_ack_b); - irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ, - xls_pcie_ack_b); - } else { - irq_set_handler_data(PIC_PCIE_LINK0_IRQ, xls_pcie_ack); - irq_set_handler_data(PIC_PCIE_LINK1_IRQ, xls_pcie_ack); - irq_set_handler_data(PIC_PCIE_LINK2_IRQ, xls_pcie_ack); - irq_set_handler_data(PIC_PCIE_LINK3_IRQ, xls_pcie_ack); - } - } else { + if (!nlm_chip_is_xls()) { /* XLR PCI controller ACK */ - irq_set_handler_data(PIC_PCIX_IRQ, xlr_pci_ack); + nlm_set_pic_extra_ack(0, PIC_PCIX_IRQ, xlr_pci_ack); + } else { + if (nlm_chip_is_xls_b()) + extra_ack = xls_pcie_ack_b; + else + extra_ack = xls_pcie_ack; + for (link = 0; link < 4; link++) { + irq = nlm_pci_link_to_irq(link); + nlm_set_pic_extra_ack(0, irq, extra_ack); + } } - return 0; } diff --git a/arch/mips/pci/pci-yosemite.c b/arch/mips/pci/pci-yosemite.c deleted file mode 100644 index cf5e1a25cb7d..000000000000 --- a/arch/mips/pci/pci-yosemite.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/pci.h> -#include <asm/titan_dep.h> - -extern struct pci_ops titan_pci_ops; - -static struct resource py_mem_resource = { - .start = 0xe0000000UL, - .end = 0xe3ffffffUL, - .name = "Titan PCI MEM", - .flags = IORESOURCE_MEM -}; - -/* - * PMON really reserves 16MB of I/O port space but that's stupid, nothing - * needs that much since allocations are limited to 256 bytes per device - * anyway. So we just claim 64kB here. - */ -#define TITAN_IO_SIZE 0x0000ffffUL -#define TITAN_IO_BASE 0xe8000000UL - -static struct resource py_io_resource = { - .start = 0x00001000UL, - .end = TITAN_IO_SIZE - 1, - .name = "Titan IO MEM", - .flags = IORESOURCE_IO, -}; - -static struct pci_controller py_controller = { - .pci_ops = &titan_pci_ops, - .mem_resource = &py_mem_resource, - .mem_offset = 0x00000000UL, - .io_resource = &py_io_resource, - .io_offset = 0x00000000UL -}; - -static char ioremap_failed[] __initdata = "Could not ioremap I/O port range"; - -static int __init pmc_yosemite_setup(void) -{ - unsigned long io_v_base; - - io_v_base = (unsigned long) ioremap(TITAN_IO_BASE, TITAN_IO_SIZE); - if (!io_v_base) - panic(ioremap_failed); - - set_io_port_base(io_v_base); - py_controller.io_map_base = io_v_base; - TITAN_WRITE(RM9000x2_OCD_LKM7, TITAN_READ(RM9000x2_OCD_LKM7) | 1); - - ioport_resource.end = TITAN_IO_SIZE - 1; - - register_pci_controller(&py_controller); - - return 0; -} - -arch_initcall(pmc_yosemite_setup); diff --git a/arch/mips/pmc-sierra/Kconfig b/arch/mips/pmc-sierra/Kconfig index bbd76082fa8c..3482b8c8640c 100644 --- a/arch/mips/pmc-sierra/Kconfig +++ b/arch/mips/pmc-sierra/Kconfig @@ -34,10 +34,6 @@ config PMC_MSP7120_FPGA endchoice -config HYPERTRANSPORT - bool "Hypertransport Support for PMC-Sierra Yosemite" - depends on PMC_YOSEMITE - config MSP_HAS_USB boolean depends on PMC_MSP diff --git a/arch/mips/pmc-sierra/Platform b/arch/mips/pmc-sierra/Platform index f092f2524c5f..387fda6c28c6 100644 --- a/arch/mips/pmc-sierra/Platform +++ b/arch/mips/pmc-sierra/Platform @@ -5,10 +5,3 @@ platform-$(CONFIG_PMC_MSP) += pmc-sierra/msp71xx/ cflags-$(CONFIG_PMC_MSP) += -I$(srctree)/arch/mips/include/asm/pmc-sierra/msp71xx \ -mno-branch-likely load-$(CONFIG_PMC_MSP) += 0xffffffff80100000 - -# -# PMC-Sierra Yosemite -# -platform-$(CONFIG_PMC_YOSEMITE) += pmc-sierra/yosemite/ -cflags-$(CONFIG_PMC_YOSEMITE) += -I$(srctree)/arch/mips/include/asm/mach-yosemite -load-$(CONFIG_PMC_YOSEMITE) += 0xffffffff80100000 diff --git a/arch/mips/pmc-sierra/yosemite/Makefile b/arch/mips/pmc-sierra/yosemite/Makefile deleted file mode 100644 index 5af95ec3319d..000000000000 --- a/arch/mips/pmc-sierra/yosemite/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for the PMC-Sierra Titan -# - -obj-y += irq.o prom.o py-console.o setup.o - -obj-$(CONFIG_SMP) += smp.o diff --git a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c deleted file mode 100644 index d6f8bdff8cbb..000000000000 --- a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2003 PMC-Sierra Inc. - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * Description: - * - * This code reads the ATMEL 24CXX EEPROM. The PMC-Sierra Yosemite board uses the ATMEL - * 24C32/24C64 which uses two byte addressing as compared to 24C16. Note that this program - * uses the serial port like /dev/ttyS0, to communicate with the EEPROM. Hence, you are - * expected to have a connectivity from the EEPROM to the serial port. This program does - * __not__ communicate using the I2C protocol - */ - -#include "atmel_read_eeprom.h" - -static void delay(int delay) -{ - while (delay--); -} - -static void send_bit(unsigned char bit) -{ - scl_lo; - delay(TXX); - if (bit) - sda_hi; - else - sda_lo; - - delay(TXX); - scl_hi; - delay(TXX); -} - -static void send_ack(void) -{ - send_bit(0); -} - -static void send_byte(unsigned char byte) -{ - int i = 0; - - for (i = 7; i >= 0; i--) - send_bit((byte >> i) & 0x01); -} - -static void send_start(void) -{ - sda_hi; - delay(TXX); - scl_hi; - delay(TXX); - sda_lo; - delay(TXX); -} - -static void send_stop(void) -{ - sda_lo; - delay(TXX); - scl_hi; - delay(TXX); - sda_hi; - delay(TXX); -} - -static void do_idle(void) -{ - sda_hi; - scl_hi; - vcc_off; -} - -static int recv_bit(void) -{ - int status; - - scl_lo; - delay(TXX); - sda_hi; - delay(TXX); - scl_hi; - delay(TXX); - - return 1; -} - -static unsigned char recv_byte(void) { - int i; - unsigned char byte=0; - - for (i=7;i>=0;i--) - byte |= (recv_bit() << i); - - return byte; -} - -static int recv_ack(void) -{ - unsigned int ack; - - ack = (unsigned int)recv_bit(); - scl_lo; - - if (ack) { - do_idle(); - printk(KERN_ERR "Error reading the Atmel 24C32/24C64 EEPROM\n"); - return -1; - } - - return ack; -} - -/* - * This function does the actual read of the EEPROM. It needs the buffer into which the - * read data is copied, the size of the EEPROM being read and the buffer size - */ -int read_eeprom(char *buffer, int eeprom_size, int size) -{ - int i = 0, err; - - send_start(); - send_byte(W_HEADER); - recv_ack(); - - /* EEPROM with size of more than 2K need two byte addressing */ - if (eeprom_size > 2048) { - send_byte(0x00); - recv_ack(); - } - - send_start(); - send_byte(R_HEADER); - err = recv_ack(); - if (err == -1) - return err; - - for (i = 0; i < size; i++) { - *buffer++ = recv_byte(); - send_ack(); - } - - /* Note : We should do some check if the buffer contains correct information */ - - send_stop(); -} diff --git a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h deleted file mode 100644 index d6c7ec469fa8..000000000000 --- a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c - * - * Copyright (C) 2003 PMC-Sierra Inc. - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * Header file for atmel_read_eeprom.c - */ - -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <asm/pci.h> -#include <asm/io.h> -#include <linux/init.h> -#include <asm/termios.h> -#include <asm/ioctls.h> -#include <linux/ioctl.h> -#include <linux/fcntl.h> - -#define DEFAULT_PORT "/dev/ttyS0" /* Port to open */ -#define TXX 0 /* Dummy loop for spinning */ - -#define BLOCK_SEL 0x00 -#define SLAVE_ADDR 0xa0 -#define READ_BIT 0x01 -#define WRITE_BIT 0x00 -#define R_HEADER SLAVE_ADDR + BLOCK_SEL + READ_BIT -#define W_HEADER SLAVE_ADDR + BLOCK_SEL + WRITE_BIT - -/* - * Clock, Voltages and Data - */ -#define vcc_off (ioctl(fd, TIOCSBRK, 0)) -#define vcc_on (ioctl(fd, TIOCCBRK, 0)) -#define sda_hi (ioctl(fd, TIOCMBIS, &dtr)) -#define sda_lo (ioctl(fd, TIOCMBIC, &dtr)) -#define scl_lo (ioctl(fd, TIOCMBIC, &rts)) -#define scl_hi (ioctl(fd, TIOCMBIS, &rts)) - -const char rts = TIOCM_RTS; -const char dtr = TIOCM_DTR; -int fd; diff --git a/arch/mips/pmc-sierra/yosemite/ht-irq.c b/arch/mips/pmc-sierra/yosemite/ht-irq.c deleted file mode 100644 index 62ead6601c69..000000000000 --- a/arch/mips/pmc-sierra/yosemite/ht-irq.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2003 PMC-Sierra - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <asm/pci.h> - -/* - * HT Bus fixup for the Titan - * XXX IRQ values need to change based on the board layout - */ -void __init titan_ht_pcibios_fixup_bus(struct pci_bus *bus) -{ - /* - * PLX and SPKT related changes go here - */ -} diff --git a/arch/mips/pmc-sierra/yosemite/ht.c b/arch/mips/pmc-sierra/yosemite/ht.c deleted file mode 100644 index 14dc9c8fff0e..000000000000 --- a/arch/mips/pmc-sierra/yosemite/ht.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Copyright 2003 PMC-Sierra - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <asm/pci.h> -#include <asm/io.h> - -#include <linux/init.h> -#include <asm/titan_dep.h> - -#ifdef CONFIG_HYPERTRANSPORT - - -/* - * This function check if the Hypertransport Link Initialization completed. If - * it did, then proceed further with scanning bus #2 - */ -static __inline__ int check_titan_htlink(void) -{ - u32 val; - - val = *(volatile uint32_t *)(RM9000x2_HTLINK_REG); - if (val & 0x00000020) - /* HT Link Initialization completed */ - return 1; - else - return 0; -} - -static int titan_ht_config_read_dword(struct pci_dev *device, - int offset, u32* val) -{ - int dev, bus, func; - uint32_t address_reg, data_reg; - uint32_t address; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - func = PCI_FUNC(device->devfn); - - /* XXX Need to change the Bus # */ - if (bus > 2) - address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | - 0x80000000 | 0x1; - else - address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; - - address_reg = RM9000x2_OCD_HTCFGA; - data_reg = RM9000x2_OCD_HTCFGD; - - RM9K_WRITE(address_reg, address); - RM9K_READ(data_reg, val); - - return PCIBIOS_SUCCESSFUL; -} - - -static int titan_ht_config_read_word(struct pci_dev *device, - int offset, u16* val) -{ - int dev, bus, func; - uint32_t address_reg, data_reg; - uint32_t address; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - func = PCI_FUNC(device->devfn); - - /* XXX Need to change the Bus # */ - if (bus > 2) - address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | - 0x80000000 | 0x1; - else - address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; - - address_reg = RM9000x2_OCD_HTCFGA; - data_reg = RM9000x2_OCD_HTCFGD; - - if ((offset & 0x3) == 0) - offset = 0x2; - else - offset = 0x0; - - RM9K_WRITE(address_reg, address); - RM9K_READ_16(data_reg + offset, val); - - return PCIBIOS_SUCCESSFUL; -} - - -u32 longswap(unsigned long l) -{ - unsigned char b1, b2, b3, b4; - - b1 = l&255; - b2 = (l>>8)&255; - b3 = (l>>16)&255; - b4 = (l>>24)&255; - - return ((b1<<24) + (b2<<16) + (b3<<8) + b4); -} - - -static int titan_ht_config_read_byte(struct pci_dev *device, - int offset, u8* val) -{ - int dev, bus, func; - uint32_t address_reg, data_reg; - uint32_t address; - int offset1; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - func = PCI_FUNC(device->devfn); - - /* XXX Need to change the Bus # */ - if (bus > 2) - address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | - 0x80000000 | 0x1; - else - address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; - - address_reg = RM9000x2_OCD_HTCFGA; - data_reg = RM9000x2_OCD_HTCFGD; - - RM9K_WRITE(address_reg, address); - - if ((offset & 0x3) == 0) { - offset1 = 0x3; - } - if ((offset & 0x3) == 1) { - offset1 = 0x2; - } - if ((offset & 0x3) == 2) { - offset1 = 0x1; - } - if ((offset & 0x3) == 3) { - offset1 = 0x0; - } - RM9K_READ_8(data_reg + offset1, val); - - return PCIBIOS_SUCCESSFUL; -} - - -static int titan_ht_config_write_dword(struct pci_dev *device, - int offset, u8 val) -{ - int dev, bus, func; - uint32_t address_reg, data_reg; - uint32_t address; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - func = PCI_FUNC(device->devfn); - - /* XXX Need to change the Bus # */ - if (bus > 2) - address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | - 0x80000000 | 0x1; - else - address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; - - address_reg = RM9000x2_OCD_HTCFGA; - data_reg = RM9000x2_OCD_HTCFGD; - - RM9K_WRITE(address_reg, address); - RM9K_WRITE(data_reg, val); - - return PCIBIOS_SUCCESSFUL; -} - -static int titan_ht_config_write_word(struct pci_dev *device, - int offset, u8 val) -{ - int dev, bus, func; - uint32_t address_reg, data_reg; - uint32_t address; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - func = PCI_FUNC(device->devfn); - - /* XXX Need to change the Bus # */ - if (bus > 2) - address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | - 0x80000000 | 0x1; - else - address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; - - address_reg = RM9000x2_OCD_HTCFGA; - data_reg = RM9000x2_OCD_HTCFGD; - - if ((offset & 0x3) == 0) - offset = 0x2; - else - offset = 0x0; - - RM9K_WRITE(address_reg, address); - RM9K_WRITE_16(data_reg + offset, val); - - return PCIBIOS_SUCCESSFUL; -} - -static int titan_ht_config_write_byte(struct pci_dev *device, - int offset, u8 val) -{ - int dev, bus, func; - uint32_t address_reg, data_reg; - uint32_t address; - int offset1; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - func = PCI_FUNC(device->devfn); - - /* XXX Need to change the Bus # */ - if (bus > 2) - address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | - 0x80000000 | 0x1; - else - address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; - - address_reg = RM9000x2_OCD_HTCFGA; - data_reg = RM9000x2_OCD_HTCFGD; - - RM9K_WRITE(address_reg, address); - - if ((offset & 0x3) == 0) { - offset1 = 0x3; - } - if ((offset & 0x3) == 1) { - offset1 = 0x2; - } - if ((offset & 0x3) == 2) { - offset1 = 0x1; - } - if ((offset & 0x3) == 3) { - offset1 = 0x0; - } - - RM9K_WRITE_8(data_reg + offset1, val); - return PCIBIOS_SUCCESSFUL; -} - - -static void titan_pcibios_set_master(struct pci_dev *dev) -{ - u16 cmd; - int bus = dev->bus->number; - - if (check_titan_htlink()) - titan_ht_config_read_word(dev, PCI_COMMAND, &cmd); - - cmd |= PCI_COMMAND_MASTER; - - if (check_titan_htlink()) - titan_ht_config_write_word(dev, PCI_COMMAND, cmd); -} - - -int pcibios_enable_resources(struct pci_dev *dev) -{ - u16 cmd, old_cmd; - u8 tmp1; - int idx; - struct resource *r; - int bus = dev->bus->number; - - if (check_titan_htlink()) - titan_ht_config_read_word(dev, PCI_COMMAND, &cmd); - - old_cmd = cmd; - for (idx = 0; idx < 6; idx++) { - r = &dev->resource[idx]; - if (!r->start && r->end) { - printk(KERN_ERR - "PCI: Device %s not available because of " - "resource collisions\n", pci_name(dev)); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - if (check_titan_htlink()) - titan_ht_config_write_word(dev, PCI_COMMAND, cmd); - } - - if (check_titan_htlink()) - titan_ht_config_read_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1); - - if (tmp1 != 8) { - printk(KERN_WARNING "PCI setting cache line size to 8 from " - "%d\n", tmp1); - } - - if (check_titan_htlink()) - titan_ht_config_write_byte(dev, PCI_CACHE_LINE_SIZE, 8); - - if (check_titan_htlink()) - titan_ht_config_read_byte(dev, PCI_LATENCY_TIMER, &tmp1); - - if (tmp1 < 32 || tmp1 == 0xff) { - printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n", - tmp1); - } - - if (check_titan_htlink()) - titan_ht_config_write_byte(dev, PCI_LATENCY_TIMER, 32); - - return 0; -} - - -int pcibios_enable_device(struct pci_dev *dev, int mask) -{ - return pcibios_enable_resources(dev); -} - -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - struct pci_dev *dev = data; - resource_size_t start = res->start; - - if (res->flags & IORESOURCE_IO) { - /* We need to avoid collisions with `mirrored' VGA ports - and other strange ISA hardware, so we always want the - addresses kilobyte aligned. */ - if (size > 0x100) { - printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", pci_name(dev), - dev->resource - res, size); - } - - start = (start + 1024 - 1) & ~(1024 - 1); - } - - return start; -} - -struct pci_ops titan_pci_ops = { - titan_ht_config_read_byte, - titan_ht_config_read_word, - titan_ht_config_read_dword, - titan_ht_config_write_byte, - titan_ht_config_write_word, - titan_ht_config_write_dword -}; - -void __init pcibios_fixup_bus(struct pci_bus *c) -{ - titan_ht_pcibios_fixup_bus(c); -} - -void __init pcibios_init(void) -{ - - /* Reset PCI I/O and PCI MEM values */ - /* XXX Need to add the proper values here */ - ioport_resource.start = 0xe0000000; - ioport_resource.end = 0xe0000000 + 0x20000000 - 1; - iomem_resource.start = 0xc0000000; - iomem_resource.end = 0xc0000000 + 0x20000000 - 1; - - /* XXX Need to add bus values */ - pci_scan_bus(2, &titan_pci_ops, NULL); - pci_scan_bus(3, &titan_pci_ops, NULL); -} - -unsigned __init int pcibios_assign_all_busses(void) -{ - /* We want to use the PCI bus detection done by PMON */ - return 0; -} - -#endif /* CONFIG_HYPERTRANSPORT */ diff --git a/arch/mips/pmc-sierra/yosemite/irq.c b/arch/mips/pmc-sierra/yosemite/irq.c deleted file mode 100644 index 6590812daa56..000000000000 --- a/arch/mips/pmc-sierra/yosemite/irq.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2003 PMC-Sierra Inc. - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * - * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Second level Interrupt handlers for the PMC-Sierra Titan/Yosemite board - */ -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel_stat.h> -#include <linux/module.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/irq.h> -#include <linux/timex.h> -#include <linux/random.h> -#include <linux/bitops.h> -#include <asm/bootinfo.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/irq_cpu.h> -#include <asm/mipsregs.h> -#include <asm/titan_dep.h> - -/* Hypertransport specific */ -#define IRQ_ACK_BITS 0x00000000 /* Ack bits */ - -#define HYPERTRANSPORT_INTA 0x78 /* INTA# */ -#define HYPERTRANSPORT_INTB 0x79 /* INTB# */ -#define HYPERTRANSPORT_INTC 0x7a /* INTC# */ -#define HYPERTRANSPORT_INTD 0x7b /* INTD# */ - -extern void titan_mailbox_irq(void); - -#ifdef CONFIG_HYPERTRANSPORT -/* - * Handle hypertransport & SMP interrupts. The interrupt lines are scarce. - * For interprocessor interrupts, the best thing to do is to use the INTMSG - * register. We use the same external interrupt line, i.e. INTB3 and monitor - * another status bit - */ -static void ll_ht_smp_irq_handler(int irq) -{ - u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4); - - /* Ack all the bits that correspond to the interrupt sources */ - if (status != 0) - OCD_WRITE(RM9000x2_OCD_INTP0STATUS4, IRQ_ACK_BITS); - - status = OCD_READ(RM9000x2_OCD_INTP1STATUS4); - if (status != 0) - OCD_WRITE(RM9000x2_OCD_INTP1STATUS4, IRQ_ACK_BITS); - -#ifdef CONFIG_HT_LEVEL_TRIGGER - /* - * Level Trigger Mode only. Send the HT EOI message back to the source. - */ - switch (status) { - case 0x1000000: - OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTA); - break; - case 0x2000000: - OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTB); - break; - case 0x4000000: - OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTC); - break; - case 0x8000000: - OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTD); - break; - case 0x0000001: - /* PLX */ - OCD_WRITE(RM9000x2_OCD_HTEOI, 0x20); - OCD_WRITE(IRQ_CLEAR_REG, IRQ_ACK_BITS); - break; - case 0xf000000: - OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTA); - OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTB); - OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTC); - OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTD); - break; - } -#endif /* CONFIG_HT_LEVEL_TRIGGER */ - - do_IRQ(irq); -} -#endif - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int cause = read_c0_cause(); - unsigned int status = read_c0_status(); - unsigned int pending = cause & status; - - if (pending & STATUSF_IP7) { - do_IRQ(7); - } else if (pending & STATUSF_IP2) { -#ifdef CONFIG_HYPERTRANSPORT - ll_ht_smp_irq_handler(2); -#else - do_IRQ(2); -#endif - } else if (pending & STATUSF_IP3) { - do_IRQ(3); - } else if (pending & STATUSF_IP4) { - do_IRQ(4); - } else if (pending & STATUSF_IP5) { -#ifdef CONFIG_SMP - titan_mailbox_irq(); -#else - do_IRQ(5); -#endif - } else if (pending & STATUSF_IP6) { - do_IRQ(4); - } -} - -/* - * Initialize the next level interrupt handler - */ -void __init arch_init_irq(void) -{ - clear_c0_status(ST0_IM); - - mips_cpu_irq_init(); - rm7k_cpu_irq_init(); - rm9k_cpu_irq_init(); -} diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c deleted file mode 100644 index 6a2754c4f106..000000000000 --- a/arch/mips/pmc-sierra/yosemite/prom.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Copyright (C) 2003, 2004 PMC-Sierra Inc. - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * Copyright (C) 2004 Ralf Baechle - */ -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/delay.h> -#include <linux/pm.h> -#include <linux/smp.h> - -#include <asm/io.h> -#include <asm/pgtable.h> -#include <asm/processor.h> -#include <asm/reboot.h> -#include <asm/smp-ops.h> -#include <asm/bootinfo.h> -#include <asm/pmon.h> - -#ifdef CONFIG_SMP -extern void prom_grab_secondary(void); -#else -#define prom_grab_secondary() do { } while (0) -#endif - -#include "setup.h" - -struct callvectors *debug_vectors; - -extern unsigned long yosemite_base; -extern unsigned long cpu_clock_freq; - -const char *get_system_type(void) -{ - return "PMC-Sierra Yosemite"; -} - -static void prom_cpu0_exit(void *arg) -{ - void *nvram = (void *) YOSEMITE_RTC_BASE; - - /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */ - writeb(0x84, nvram + 0xff7); - - /* wait for the watchdog to go off */ - mdelay(100 + (1000 / 16)); - - /* if the watchdog fails for some reason, let people know */ - printk(KERN_NOTICE "Watchdog reset failed\n"); -} - -/* - * Reset the NVRAM over the local bus - */ -static void prom_exit(void) -{ -#ifdef CONFIG_SMP - if (smp_processor_id()) - /* CPU 1 */ - smp_call_function(prom_cpu0_exit, NULL, 1); -#endif - prom_cpu0_exit(NULL); -} - -/* - * Halt the system - */ -static void prom_halt(void) -{ - printk(KERN_NOTICE "\n** You can safely turn off the power\n"); - while (1) - __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0"); -} - -extern struct plat_smp_ops yos_smp_ops; - -/* - * Init routine which accepts the variables from PMON - */ -void __init prom_init(void) -{ - int argc = fw_arg0; - char **arg = (char **) fw_arg1; - char **env = (char **) fw_arg2; - struct callvectors *cv = (struct callvectors *) fw_arg3; - int i = 0; - - /* Callbacks for halt, restart */ - _machine_restart = (void (*)(char *)) prom_exit; - _machine_halt = prom_halt; - pm_power_off = prom_halt; - - debug_vectors = cv; - arcs_cmdline[0] = '\0'; - - /* Get the boot parameters */ - for (i = 1; i < argc; i++) { - if (strlen(arcs_cmdline) + strlen(arg[i]) + 1 >= - sizeof(arcs_cmdline)) - break; - - strcat(arcs_cmdline, arg[i]); - strcat(arcs_cmdline, " "); - } - -#ifdef CONFIG_SERIAL_8250_CONSOLE - if ((strstr(arcs_cmdline, "console=ttyS")) == NULL) - strcat(arcs_cmdline, "console=ttyS0,115200"); -#endif - - while (*env) { - if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0) - yosemite_base = - simple_strtol(*env + strlen("ocd_base="), NULL, - 16); - - if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) - cpu_clock_freq = - simple_strtol(*env + strlen("cpuclock="), NULL, - 10); - - env++; - } - - prom_grab_secondary(); - - register_smp_ops(&yos_smp_ops); -} - -void __init prom_free_prom_memory(void) -{ -} - -void __init prom_fixup_mem_map(unsigned long start, unsigned long end) -{ -} diff --git a/arch/mips/pmc-sierra/yosemite/py-console.c b/arch/mips/pmc-sierra/yosemite/py-console.c deleted file mode 100644 index b7f1d9c4a8a3..000000000000 --- a/arch/mips/pmc-sierra/yosemite/py-console.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001, 2002, 2004 Ralf Baechle - */ -#include <linux/init.h> -#include <linux/console.h> -#include <linux/kdev_t.h> -#include <linux/major.h> -#include <linux/termios.h> -#include <linux/sched.h> -#include <linux/tty.h> - -#include <linux/serial.h> -#include <linux/serial_core.h> -#include <asm/serial.h> -#include <asm/io.h> - -/* SUPERIO uart register map */ -struct yo_uartregs { - union { - volatile u8 rbr; /* read only, DLAB == 0 */ - volatile u8 thr; /* write only, DLAB == 0 */ - volatile u8 dll; /* DLAB == 1 */ - } u1; - union { - volatile u8 ier; /* DLAB == 0 */ - volatile u8 dlm; /* DLAB == 1 */ - } u2; - union { - volatile u8 iir; /* read only */ - volatile u8 fcr; /* write only */ - } u3; - volatile u8 iu_lcr; - volatile u8 iu_mcr; - volatile u8 iu_lsr; - volatile u8 iu_msr; - volatile u8 iu_scr; -} yo_uregs_t; - -#define iu_rbr u1.rbr -#define iu_thr u1.thr -#define iu_dll u1.dll -#define iu_ier u2.ier -#define iu_dlm u2.dlm -#define iu_iir u3.iir -#define iu_fcr u3.fcr - -#define ssnop() __asm__ __volatile__("sll $0, $0, 1\n"); -#define ssnop_4() do { ssnop(); ssnop(); ssnop(); ssnop(); } while (0) - -#define IO_BASE_64 0x9000000000000000ULL - -static unsigned char readb_outer_space(unsigned long long phys) -{ - unsigned long long vaddr = IO_BASE_64 | phys; - unsigned char res; - unsigned int sr; - - sr = read_c0_status(); - write_c0_status((sr | ST0_KX) & ~ ST0_IE); - ssnop_4(); - - __asm__ __volatile__ ( - " .set mips3 \n" - " ld %0, %1 \n" - " lbu %0, (%0) \n" - " .set mips0 \n" - : "=r" (res) - : "m" (vaddr)); - - write_c0_status(sr); - ssnop_4(); - - return res; -} - -static void writeb_outer_space(unsigned long long phys, unsigned char c) -{ - unsigned long long vaddr = IO_BASE_64 | phys; - unsigned long tmp; - unsigned int sr; - - sr = read_c0_status(); - write_c0_status((sr | ST0_KX) & ~ ST0_IE); - ssnop_4(); - - __asm__ __volatile__ ( - " .set mips3 \n" - " ld %0, %1 \n" - " sb %2, (%0) \n" - " .set mips0 \n" - : "=&r" (tmp) - : "m" (vaddr), "r" (c)); - - write_c0_status(sr); - ssnop_4(); -} - -void prom_putchar(char c) -{ - unsigned long lsr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_lsr); - unsigned long thr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_thr); - - while ((readb_outer_space(lsr) & 0x20) == 0); - writeb_outer_space(thr, c); -} diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c deleted file mode 100644 index b6472fc88a99..000000000000 --- a/arch/mips/pmc-sierra/yosemite/setup.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2003 PMC-Sierra Inc. - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * - * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include <linux/bcd.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/export.h> -#include <linux/types.h> -#include <linux/mm.h> -#include <linux/bootmem.h> -#include <linux/swap.h> -#include <linux/ioport.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/timex.h> -#include <linux/termios.h> -#include <linux/tty.h> -#include <linux/serial.h> -#include <linux/serial_core.h> -#include <linux/serial_8250.h> - -#include <asm/time.h> -#include <asm/bootinfo.h> -#include <asm/page.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/processor.h> -#include <asm/reboot.h> -#include <asm/serial.h> -#include <asm/titan_dep.h> -#include <asm/m48t37.h> - -#include "setup.h" - -unsigned char titan_ge_mac_addr_base[6] = { - // 0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00 - 0x00, 0xe0, 0x04, 0x00, 0x00, 0x21 -}; - -unsigned long cpu_clock_freq; -unsigned long yosemite_base; - -static struct m48t37_rtc *m48t37_base; - -void __init bus_error_init(void) -{ - /* Do nothing */ -} - - -void read_persistent_clock(struct timespec *ts) -{ - unsigned int year, month, day, hour, min, sec; - unsigned long flags; - - spin_lock_irqsave(&rtc_lock, flags); - /* Stop the update to the time */ - m48t37_base->control = 0x40; - - year = bcd2bin(m48t37_base->year); - year += bcd2bin(m48t37_base->century) * 100; - - month = bcd2bin(m48t37_base->month); - day = bcd2bin(m48t37_base->date); - hour = bcd2bin(m48t37_base->hour); - min = bcd2bin(m48t37_base->min); - sec = bcd2bin(m48t37_base->sec); - - /* Start the update to the time again */ - m48t37_base->control = 0x00; - spin_unlock_irqrestore(&rtc_lock, flags); - - ts->tv_sec = mktime(year, month, day, hour, min, sec); - ts->tv_nsec = 0; -} - -int rtc_mips_set_time(unsigned long tim) -{ - struct rtc_time tm; - unsigned long flags; - - /* - * Convert to a more useful format -- note months count from 0 - * and years from 1900 - */ - rtc_time_to_tm(tim, &tm); - tm.tm_year += 1900; - tm.tm_mon += 1; - - spin_lock_irqsave(&rtc_lock, flags); - /* enable writing */ - m48t37_base->control = 0x80; - - /* year */ - m48t37_base->year = bin2bcd(tm.tm_year % 100); - m48t37_base->century = bin2bcd(tm.tm_year / 100); - - /* month */ - m48t37_base->month = bin2bcd(tm.tm_mon); - - /* day */ - m48t37_base->date = bin2bcd(tm.tm_mday); - - /* hour/min/sec */ - m48t37_base->hour = bin2bcd(tm.tm_hour); - m48t37_base->min = bin2bcd(tm.tm_min); - m48t37_base->sec = bin2bcd(tm.tm_sec); - - /* day of week -- not really used, but let's keep it up-to-date */ - m48t37_base->day = bin2bcd(tm.tm_wday + 1); - - /* disable writing */ - m48t37_base->control = 0x00; - spin_unlock_irqrestore(&rtc_lock, flags); - - return 0; -} - -void __init plat_time_init(void) -{ - mips_hpt_frequency = cpu_clock_freq / 2; -mips_hpt_frequency = 33000000 * 3 * 5; -} - -unsigned long ocd_base; - -EXPORT_SYMBOL(ocd_base); - -/* - * Common setup before any secondaries are started - */ - -#define TITAN_UART_CLK 3686400 -#define TITAN_SERIAL_BASE_BAUD (TITAN_UART_CLK / 16) -#define TITAN_SERIAL_IRQ 4 -#define TITAN_SERIAL_BASE 0xfd000008UL - -static void __init py_map_ocd(void) -{ - ocd_base = (unsigned long) ioremap(OCD_BASE, OCD_SIZE); - if (!ocd_base) - panic("Mapping OCD failed - game over. Your score is 0."); - - /* Kludge for PMON bug ... */ - OCD_WRITE(0x0710, 0x0ffff029); -} - -static void __init py_uart_setup(void) -{ -#ifdef CONFIG_SERIAL_8250 - struct uart_port up; - - /* - * Register to interrupt zero because we share the interrupt with - * the serial driver which we don't properly support yet. - */ - memset(&up, 0, sizeof(up)); - up.membase = (unsigned char *) ioremap(TITAN_SERIAL_BASE, 8); - up.irq = TITAN_SERIAL_IRQ; - up.uartclk = TITAN_UART_CLK; - up.regshift = 0; - up.iotype = UPIO_MEM; - up.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; - up.line = 0; - - if (early_serial_setup(&up)) - printk(KERN_ERR "Early serial init of port 0 failed\n"); -#endif /* CONFIG_SERIAL_8250 */ -} - -static void __init py_rtc_setup(void) -{ - m48t37_base = ioremap(YOSEMITE_RTC_BASE, YOSEMITE_RTC_SIZE); - if (!m48t37_base) - printk(KERN_ERR "Mapping the RTC failed\n"); -} - -/* Not only time init but that's what the hook it's called through is named */ -static void __init py_late_time_init(void) -{ - py_map_ocd(); - py_uart_setup(); - py_rtc_setup(); -} - -void __init plat_mem_setup(void) -{ - late_time_init = py_late_time_init; - - /* Add memory regions */ - add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM); - -#if 0 /* XXX Crash ... */ - OCD_WRITE(RM9000x2_OCD_HTSC, - OCD_READ(RM9000x2_OCD_HTSC) | HYPERTRANSPORT_ENABLE); - - /* Set the BAR. Shifted mode */ - OCD_WRITE(RM9000x2_OCD_HTBAR0, HYPERTRANSPORT_BAR0_ADDR); - OCD_WRITE(RM9000x2_OCD_HTMASK0, HYPERTRANSPORT_SIZE0); -#endif -} diff --git a/arch/mips/pmc-sierra/yosemite/setup.h b/arch/mips/pmc-sierra/yosemite/setup.h deleted file mode 100644 index 1a01abfc7d33..000000000000 --- a/arch/mips/pmc-sierra/yosemite/setup.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2003, 04 PMC-Sierra - * Author: Manish Lachwani (lachwani@pmc-sierra.com) - * Copyright 2004 Ralf Baechle <ralf@linux-mips.org> - * - * Board specific definititions for the PMC-Sierra Yosemite - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#ifndef __SETUP_H__ -#define __SETUP_H__ - -/* M48T37 RTC + NVRAM */ -#define YOSEMITE_RTC_BASE 0xfc800000 -#define YOSEMITE_RTC_SIZE 0x00800000 - -#define HYPERTRANSPORT_BAR0_ADDR 0x00000006 -#define HYPERTRANSPORT_SIZE0 0x0fffffff -#define HYPERTRANSPORT_BAR0_ATTR 0x00002000 - -#define HYPERTRANSPORT_ENABLE 0x6 - -/* - * EEPROM Size - */ -#define TITAN_ATMEL_24C32_SIZE 32768 -#define TITAN_ATMEL_24C64_SIZE 65536 - -#endif /* __SETUP_H__ */ diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c deleted file mode 100644 index 5edab2bc6fc0..000000000000 --- a/arch/mips/pmc-sierra/yosemite/smp.c +++ /dev/null @@ -1,185 +0,0 @@ -#include <linux/linkage.h> -#include <linux/sched.h> -#include <linux/smp.h> - -#include <asm/pmon.h> -#include <asm/titan_dep.h> -#include <asm/time.h> - -#define LAUNCHSTACK_SIZE 256 - -static __cpuinitdata arch_spinlock_t launch_lock = __ARCH_SPIN_LOCK_UNLOCKED; - -static unsigned long secondary_sp __cpuinitdata; -static unsigned long secondary_gp __cpuinitdata; - -static unsigned char launchstack[LAUNCHSTACK_SIZE] __initdata - __attribute__((aligned(2 * sizeof(long)))); - -static void __init prom_smp_bootstrap(void) -{ - local_irq_disable(); - - while (arch_spin_is_locked(&launch_lock)); - - __asm__ __volatile__( - " move $sp, %0 \n" - " move $gp, %1 \n" - " j smp_bootstrap \n" - : - : "r" (secondary_sp), "r" (secondary_gp)); -} - -/* - * PMON is a fragile beast. It'll blow up once the mappings it's littering - * right into the middle of KSEG3 are blown away so we have to grab the slave - * core early and keep it in a waiting loop. - */ -void __init prom_grab_secondary(void) -{ - arch_spin_lock(&launch_lock); - - pmon_cpustart(1, &prom_smp_bootstrap, - launchstack + LAUNCHSTACK_SIZE, 0); -} - -void titan_mailbox_irq(void) -{ - int cpu = smp_processor_id(); - unsigned long status; - - switch (cpu) { - case 0: - status = OCD_READ(RM9000x2_OCD_INTP0STATUS3); - OCD_WRITE(RM9000x2_OCD_INTP0CLEAR3, status); - - if (status & 0x2) - smp_call_function_interrupt(); - if (status & 0x4) - scheduler_ipi(); - break; - - case 1: - status = OCD_READ(RM9000x2_OCD_INTP1STATUS3); - OCD_WRITE(RM9000x2_OCD_INTP1CLEAR3, status); - - if (status & 0x2) - smp_call_function_interrupt(); - if (status & 0x4) - scheduler_ipi(); - break; - } -} - -/* - * Send inter-processor interrupt - */ -static void yos_send_ipi_single(int cpu, unsigned int action) -{ - /* - * Generate an INTMSG so that it can be sent over to the - * destination CPU. The INTMSG will put the STATUS bits - * based on the action desired. An alternative strategy - * is to write to the Interrupt Set register, read the - * Interrupt Status register and clear the Interrupt - * Clear register. The latter is preffered. - */ - switch (action) { - case SMP_RESCHEDULE_YOURSELF: - if (cpu == 1) - OCD_WRITE(RM9000x2_OCD_INTP1SET3, 4); - else - OCD_WRITE(RM9000x2_OCD_INTP0SET3, 4); - break; - - case SMP_CALL_FUNCTION: - if (cpu == 1) - OCD_WRITE(RM9000x2_OCD_INTP1SET3, 2); - else - OCD_WRITE(RM9000x2_OCD_INTP0SET3, 2); - break; - } -} - -static void yos_send_ipi_mask(const struct cpumask *mask, unsigned int action) -{ - unsigned int i; - - for_each_cpu(i, mask) - yos_send_ipi_single(i, action); -} - -/* - * After we've done initial boot, this function is called to allow the - * board code to clean up state, if needed - */ -static void __cpuinit yos_init_secondary(void) -{ -} - -static void __cpuinit yos_smp_finish(void) -{ - set_c0_status(ST0_CO | ST0_IM | ST0_IE); -} - -/* Hook for after all CPUs are online */ -static void yos_cpus_done(void) -{ -} - -/* - * Firmware CPU startup hook - * Complicated by PMON's weird interface which tries to minimic the UNIX fork. - * It launches the next * available CPU and copies some information on the - * stack so the first thing we do is throw away that stuff and load useful - * values into the registers ... - */ -static void __cpuinit yos_boot_secondary(int cpu, struct task_struct *idle) -{ - unsigned long gp = (unsigned long) task_thread_info(idle); - unsigned long sp = __KSTK_TOS(idle); - - secondary_sp = sp; - secondary_gp = gp; - - arch_spin_unlock(&launch_lock); -} - -/* - * Detect available CPUs, populate cpu_possible_mask before smp_init - * - * We don't want to start the secondary CPU yet nor do we have a nice probing - * feature in PMON so we just assume presence of the secondary core. - */ -static void __init yos_smp_setup(void) -{ - int i; - - init_cpu_possible(cpu_none_mask); - - for (i = 0; i < 2; i++) { - set_cpu_possible(i, true); - __cpu_number_map[i] = i; - __cpu_logical_map[i] = i; - } -} - -static void __init yos_prepare_cpus(unsigned int max_cpus) -{ - /* - * Be paranoid. Enable the IPI only if we're really about to go SMP. - */ - if (num_possible_cpus()) - set_c0_status(STATUSF_IP5); -} - -struct plat_smp_ops yos_smp_ops = { - .send_ipi_single = yos_send_ipi_single, - .send_ipi_mask = yos_send_ipi_mask, - .init_secondary = yos_init_secondary, - .smp_finish = yos_smp_finish, - .cpus_done = yos_cpus_done, - .boot_secondary = yos_boot_secondary, - .smp_setup = yos_smp_setup, - .prepare_cpus = yos_prepare_cpus, -}; diff --git a/arch/mips/powertv/init.c b/arch/mips/powertv/init.c index 1cf5abbef715..c6979353980b 100644 --- a/arch/mips/powertv/init.c +++ b/arch/mips/powertv/init.c @@ -69,40 +69,6 @@ char *prom_getenv(char *envname) return result; } -/* TODO: Verify on linux-mips mailing list that the following two */ -/* functions are correct */ -/* TODO: Copy NMI and EJTAG exception vectors to memory from the */ -/* BootROM exception vectors. Flush their cache entries. test it. */ - -static void __init mips_nmi_setup(void) -{ - void *base; -#if defined(CONFIG_CPU_MIPS32_R1) - base = cpu_has_veic ? - (void *)(CAC_BASE + 0xa80) : - (void *)(CAC_BASE + 0x380); -#elif defined(CONFIG_CPU_MIPS32_R2) - base = (void *)0xbfc00000; -#else -#error NMI exception handler address not defined -#endif -} - -static void __init mips_ejtag_setup(void) -{ - void *base; - -#if defined(CONFIG_CPU_MIPS32_R1) - base = cpu_has_veic ? - (void *)(CAC_BASE + 0xa00) : - (void *)(CAC_BASE + 0x300); -#elif defined(CONFIG_CPU_MIPS32_R2) - base = (void *)0xbfc00480; -#else -#error EJTAG exception handler address not defined -#endif -} - void __init prom_init(void) { int prom_argc; @@ -113,9 +79,6 @@ void __init prom_init(void) _prom_envp = (int *) fw_arg2; _prom_memsize = (unsigned long) fw_arg3; - board_nmi_handler_setup = mips_nmi_setup; - board_ejtag_handler_setup = mips_ejtag_setup; - if (prom_argc == 1) { strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE); strlcat(arcs_cmdline, prom_argv, COMMAND_LINE_SIZE); diff --git a/arch/mips/rb532/prom.c b/arch/mips/rb532/prom.c index d7c26d00cfef..a757ded437cd 100644 --- a/arch/mips/rb532/prom.c +++ b/arch/mips/rb532/prom.c @@ -72,12 +72,11 @@ void __init prom_setup_cmdline(void) static char cmd_line[COMMAND_LINE_SIZE] __initdata; char *cp, *board; int prom_argc; - char **prom_argv, **prom_envp; + char **prom_argv; int i; prom_argc = fw_arg0; prom_argv = (char **) fw_arg1; - prom_envp = (char **) fw_arg2; cp = cmd_line; /* Note: it is common that parameters start diff --git a/arch/mips/sgi-ip22/ip22-eisa.c b/arch/mips/sgi-ip22/ip22-eisa.c index da44ccb20829..4a6057b35b9d 100644 --- a/arch/mips/sgi-ip22/ip22-eisa.c +++ b/arch/mips/sgi-ip22/ip22-eisa.c @@ -73,12 +73,10 @@ static char __init *decode_eisa_sig(unsigned long addr) static irqreturn_t ip22_eisa_intr(int irq, void *dev_id) { - u8 eisa_irq; - u8 dma1, dma2; + u8 eisa_irq = inb(EIU_INTRPT_ACK); - eisa_irq = inb(EIU_INTRPT_ACK); - dma1 = inb(EISA_DMA1_STATUS); - dma2 = inb(EISA_DMA2_STATUS); + inb(EISA_DMA1_STATUS); + inb(EISA_DMA2_STATUS); if (eisa_irq < EISA_MAX_IRQ) { do_IRQ(eisa_irq); diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig index 3cd937e0e9a3..01cc1a749c73 100644 --- a/arch/mips/sibyte/Kconfig +++ b/arch/mips/sibyte/Kconfig @@ -74,7 +74,7 @@ config SIBYTE_SB1xxx_SOC select SWAP_IO_SPACE select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL - select CFE + select FW_CFE select SYS_HAS_EARLY_PRINTK choice diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c index 413f17f8e892..d6c7bd4b5ab0 100644 --- a/arch/mips/sni/setup.c +++ b/arch/mips/sni/setup.c @@ -15,12 +15,12 @@ #include <linux/fb.h> #include <linux/screen_info.h> -#ifdef CONFIG_ARC +#ifdef CONFIG_FW_ARC #include <asm/fw/arc/types.h> #include <asm/sgialib.h> #endif -#ifdef CONFIG_SNIPROM +#ifdef CONFIG_FW_SNIPROM #include <asm/mipsprom.h> #endif @@ -37,7 +37,7 @@ extern void sni_machine_power_off(void); static void __init sni_display_setup(void) { -#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) && defined(CONFIG_ARC) +#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) && defined(CONFIG_FW_ARC) struct screen_info *si = &screen_info; DISPLAY_STATUS *di; @@ -56,7 +56,7 @@ static void __init sni_display_setup(void) static void __init sni_console_setup(void) { -#ifndef CONFIG_ARC +#ifndef CONFIG_FW_ARC char *ctype; char *cdev; char *baud; diff --git a/arch/mips/wrppmc/pci.c b/arch/mips/wrppmc/pci.c index d06192faeb7c..8b8a0e1a40ca 100644 --- a/arch/mips/wrppmc/pci.c +++ b/arch/mips/wrppmc/pci.c @@ -38,10 +38,8 @@ static struct pci_controller hose_0 = { static int __init gt64120_pci_init(void) { - u32 tmp; - - tmp = GT_READ(GT_PCI0_CMD_OFS); /* Huh??? -- Ralf */ - tmp = GT_READ(GT_PCI0_BARE_OFS); + (void) GT_READ(GT_PCI0_CMD_OFS); /* Huh??? -- Ralf */ + (void) GT_READ(GT_PCI0_BARE_OFS); /* reset the whole PCI I/O space range */ ioport_resource.start = GT_PCI_IO_BASE; |