Commit db39ad7d authored by Olof Johansson's avatar Olof Johansson

Merge tag 'dt-3.10-4' of git://git.infradead.org/users/jcooper/linux into next/dt2

From Jason Cooper:
mvebu dt for v3.10 round 4

 - mvebu LPAE 64bit dts file changes

* tag 'dt-3.10-4' of git://git.infradead.org/users/jcooper/linux: (52 commits)
  ARM: dts: mvebu: Convert mvebu device tree files to 64 bits
  ARM: dts: mvebu: introduce internal-regs node
  ARM: dts: mvebu: Convert all the mvebu files to use the range property
  ARM: dts: mvebu: move all peripherals inside soc
  ARM: dts: mvebu: fix cpus section indentation
  arm: mvebu: PCIe Device Tree informations for Armada XP GP
  arm: mvebu: PCIe Device Tree informations for Armada 370 DB
  arm: mvebu: PCIe Device Tree informations for Armada 370 Mirabox
  arm: mvebu: PCIe Device Tree informations for Armada XP DB
  arm: mvebu: PCIe Device Tree informations for OpenBlocks AX3-4
  arm: mvebu: add PCIe Device Tree informations for Armada XP
  arm: mvebu: add PCIe Device Tree informations for Armada 370
  ARM: mvebu: Align the internal registers virtual base to support LPAE
  ARM: mvebu: Limit the DMA zone when LPAE is selected
  arm: plat-orion: remove addr-map code
  arm: mach-mv78xx0: convert to use the mvebu-mbus driver
  arm: mach-orion5x: convert to use mvebu-mbus driver
  arm: mach-dove: convert to use mvebu-mbus driver
  arm: mach-kirkwood: convert to use mvebu-mbus driver
  arm: mach-mvebu: convert to use mvebu-mbus driver
  ...
Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents bf049ded 74898364
......@@ -564,6 +564,7 @@ config ARCH_DOVE
select PINCTRL_DOVE
select PLAT_ORION_LEGACY
select USB_ARCH_HAS_EHCI
select MVEBU_MBUS
help
Support for the Marvell Dove SoC 88AP510
......@@ -577,6 +578,7 @@ config ARCH_KIRKWOOD
select PINCTRL
select PINCTRL_KIRKWOOD
select PLAT_ORION_LEGACY
select MVEBU_MBUS
help
Support for the following Marvell Kirkwood series SoCs:
88F6180, 88F6192 and 88F6281.
......@@ -588,6 +590,7 @@ config ARCH_MV78XX0
select GENERIC_CLOCKEVENTS
select PCI
select PLAT_ORION_LEGACY
select MVEBU_MBUS
help
Support for the following Marvell MV78xx0 series SoCs:
MV781x0, MV782x0.
......@@ -600,6 +603,7 @@ config ARCH_ORION5X
select GENERIC_CLOCKEVENTS
select PCI
select PLAT_ORION_LEGACY
select MVEBU_MBUS
help
Support for the following Marvell Orion 5x series SoCs:
Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
......
......@@ -30,11 +30,12 @@ memory {
};
soc {
serial@d0012000 {
internal-regs {
serial@12000 {
clock-frequency = <200000000>;
status = "okay";
};
sata@d00a0000 {
sata@a0000 {
nr-ports = <2>;
status = "okay";
};
......@@ -49,18 +50,18 @@ phy1: ethernet-phy@1 {
};
};
ethernet@d0070000 {
ethernet@70000 {
status = "okay";
phy = <&phy0>;
phy-mode = "rgmii-id";
};
ethernet@d0074000 {
ethernet@74000 {
status = "okay";
phy = <&phy1>;
phy-mode = "rgmii-id";
};
mvsdio@d00d4000 {
mvsdio@d4000 {
pinctrl-0 = <&sdio_pins1>;
pinctrl-names = "default";
/*
......@@ -75,15 +76,15 @@ mvsdio@d00d4000 {
/* No CD or WP GPIOs */
};
usb@d0050000 {
usb@50000 {
status = "okay";
};
usb@d0051000 {
usb@51000 {
status = "okay";
};
spi0: spi@d0010600 {
spi0: spi@10600 {
status = "okay";
spi-flash@0 {
......@@ -94,5 +95,23 @@ spi-flash@0 {
spi-max-frequency = <50000000>;
};
};
pcie-controller {
status = "okay";
/*
* The two PCIe units are accessible through
* both standard PCIe slots and mini-PCIe
* slots on the board.
*/
pcie@1,0 {
/* Port 0, Lane 0 */
status = "okay";
};
pcie@2,0 {
/* Port 1, Lane 0 */
status = "okay";
};
};
};
};
};
......@@ -25,14 +25,52 @@ memory {
};
soc {
serial@d0012000 {
internal-regs {
serial@12000 {
clock-frequency = <200000000>;
status = "okay";
};
timer@d0020300 {
timer@20300 {
clock-frequency = <600000000>;
status = "okay";
};
pinctrl {
pwr_led_pin: pwr-led-pin {
marvell,pins = "mpp63";
marvell,function = "gpo";
};
stat_led_pins: stat-led-pins {
marvell,pins = "mpp64", "mpp65";
marvell,function = "gpio";
};
};
gpio_leds {
compatible = "gpio-leds";
pinctrl-names = "default";
pinctrl-0 = <&pwr_led_pin &stat_led_pins>;
green_pwr_led {
label = "mirabox:green:pwr";
gpios = <&gpio1 31 1>;
linux,default-trigger = "heartbeat";
};
blue_stat_led {
label = "mirabox:blue:stat";
gpios = <&gpio2 0 1>;
linux,default-trigger = "cpu0";
};
green_stat_led {
label = "mirabox:green:stat";
gpios = <&gpio2 1 1>;
default-state = "off";
};
};
mdio {
phy0: ethernet-phy@0 {
reg = <0>;
......@@ -42,19 +80,19 @@ phy1: ethernet-phy@1 {
reg = <1>;
};
};
ethernet@d0070000 {
ethernet@70000 {
status = "okay";
phy = <&phy0>;
phy-mode = "rgmii-id";
};
ethernet@d0074000 {
ethernet@74000 {
status = "okay";
phy = <&phy1>;
phy-mode = "rgmii-id";
};
mvsdio@d00d4000 {
pinctrl-0 = <&sdio_pins2>;
mvsdio@d4000 {
pinctrl-0 = <&sdio_pins3>;
pinctrl-names = "default";
status = "okay";
/*
......@@ -63,12 +101,40 @@ mvsdio@d00d4000 {
*/
};
usb@d0050000 {
usb@50000 {
status = "okay";
};
usb@d0051000 {
usb@51000 {
status = "okay";
};
i2c@11000 {
status = "okay";
clock-frequency = <100000>;
pca9505: pca9505@25 {
compatible = "nxp,pca9505";
gpio-controller;
#gpio-cells = <2>;
reg = <0x25>;
};
};
pcie-controller {
status = "okay";
/* Internal mini-PCIe connector */
pcie@1,0 {
/* Port 0, Lane 0 */
status = "okay";
};
/* Connected on the PCB to a USB 3.0 XHCI controller */
pcie@2,0 {
/* Port 1, Lane 0 */
status = "okay";
};
};
};
};
};
......@@ -28,11 +28,12 @@ memory {
};
soc {
serial@d0012000 {
internal-regs {
serial@12000 {
clock-frequency = <200000000>;
status = "okay";
};
sata@d00a0000 {
sata@a0000 {
nr-ports = <2>;
status = "okay";
};
......@@ -47,30 +48,42 @@ phy1: ethernet-phy@1 {
};
};
ethernet@d0070000 {
ethernet@70000 {
status = "okay";
phy = <&phy0>;
phy-mode = "sgmii";
};
ethernet@d0074000 {
ethernet@74000 {
status = "okay";
phy = <&phy1>;
phy-mode = "rgmii-id";
};
mvsdio@d00d4000 {
mvsdio@d4000 {
pinctrl-0 = <&sdio_pins1>;
pinctrl-names = "default";
status = "okay";
/* No CD or WP GPIOs */
};
usb@d0050000 {
usb@50000 {
status = "okay";
};
usb@d0051000 {
usb@51000 {
status = "okay";
};
gpio-keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
button@1 {
label = "Software Button";
linux,code = <116>;
gpios = <&gpio0 6 1>;
};
};
};
};
};
};
......@@ -16,7 +16,7 @@
* 370 and Armada XP SoC.
*/
/include/ "skeleton.dtsi"
/include/ "skeleton64.dtsi"
/ {
model = "Marvell Armada 370 and XP SoC";
......@@ -28,59 +28,58 @@ cpu@0 {
};
};
mpic: interrupt-controller@d0020000 {
soc {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
interrupt-parent = <&mpic>;
ranges = <0 0 0xd0000000 0x100000>;
internal-regs {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges;
mpic: interrupt-controller@20000 {
compatible = "marvell,mpic";
#interrupt-cells = <1>;
#size-cells = <1>;
interrupt-controller;
};
coherency-fabric@d0020200 {
coherency-fabric@20200 {
compatible = "marvell,coherency-fabric";
reg = <0xd0020200 0xb0>,
<0xd0021810 0x1c>;
reg = <0x20200 0xb0>, <0x21810 0x1c>;
};
soc {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
interrupt-parent = <&mpic>;
ranges;
serial@d0012000 {
serial@12000 {
compatible = "snps,dw-apb-uart";
reg = <0xd0012000 0x100>;
reg = <0x12000 0x100>;
reg-shift = <2>;
interrupts = <41>;
reg-io-width = <1>;
status = "disabled";
};
serial@d0012100 {
serial@12100 {
compatible = "snps,dw-apb-uart";
reg = <0xd0012100 0x100>;
reg = <0x12100 0x100>;
reg-shift = <2>;
interrupts = <42>;
reg-io-width = <1>;
status = "disabled";
};
timer@d0020300 {
timer@20300 {
compatible = "marvell,armada-370-xp-timer";
reg = <0xd0020300 0x30>,
<0xd0021040 0x30>;
reg = <0x20300 0x30>, <0x21040 0x30>;
interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
clocks = <&coreclk 2>;
};
addr-decoding@d0020000 {
compatible = "marvell,armada-addr-decoding-controller";
reg = <0xd0020000 0x258>;
};
sata@d00a0000 {
sata@a0000 {
compatible = "marvell,orion-sata";
reg = <0xd00a0000 0x2400>;
reg = <0xa0000 0x2400>;
interrupts = <55>;
clocks = <&gateclk 15>, <&gateclk 30>;
clock-names = "0", "1";
......@@ -91,28 +90,28 @@ mdio {
#address-cells = <1>;
#size-cells = <0>;
compatible = "marvell,orion-mdio";
reg = <0xd0072004 0x4>;
reg = <0x72004 0x4>;
};
ethernet@d0070000 {
ethernet@70000 {
compatible = "marvell,armada-370-neta";
reg = <0xd0070000 0x2500>;
reg = <0x70000 0x2500>;
interrupts = <8>;
clocks = <&gateclk 4>;
status = "disabled";
};
ethernet@d0074000 {
ethernet@74000 {
compatible = "marvell,armada-370-neta";
reg = <0xd0074000 0x2500>;
reg = <0x74000 0x2500>;
interrupts = <10>;
clocks = <&gateclk 3>;
status = "disabled";
};
i2c0: i2c@d0011000 {
i2c0: i2c@11000 {
compatible = "marvell,mv64xxx-i2c";
reg = <0xd0011000 0x20>;
reg = <0x11000 0x20>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <31>;
......@@ -121,9 +120,9 @@ i2c0: i2c@d0011000 {
status = "disabled";
};
i2c1: i2c@d0011100 {
i2c1: i2c@11100 {
compatible = "marvell,mv64xxx-i2c";
reg = <0xd0011100 0x20>;
reg = <0x11100 0x20>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <32>;
......@@ -134,35 +133,35 @@ i2c1: i2c@d0011100 {
rtc@10300 {
compatible = "marvell,orion-rtc";
reg = <0xd0010300 0x20>;
reg = <0x10300 0x20>;
interrupts = <50>;
};
mvsdio@d00d4000 {
mvsdio@d4000 {
compatible = "marvell,orion-sdio";
reg = <0xd00d4000 0x200>;
reg = <0xd4000 0x200>;
interrupts = <54>;
clocks = <&gateclk 17>;
status = "disabled";
};
usb@d0050000 {
usb@50000 {
compatible = "marvell,orion-ehci";
reg = <0xd0050000 0x500>;
reg = <0x50000 0x500>;
interrupts = <45>;
status = "disabled";
};
usb@d0051000 {
usb@51000 {
compatible = "marvell,orion-ehci";
reg = <0xd0051000 0x500>;
reg = <0x51000 0x500>;
interrupts = <46>;
status = "disabled";
};
spi0: spi@d0010600 {
spi0: spi@10600 {
compatible = "marvell,orion-spi";
reg = <0xd0010600 0x28>;
reg = <0x10600 0x28>;
#address-cells = <1>;
#size-cells = <0>;
cell-index = <0>;
......@@ -171,9 +170,9 @@ spi0: spi@d0010600 {
status = "disabled";
};
spi1: spi@d0010680 {
spi1: spi@10680 {
compatible = "marvell,orion-spi";
reg = <0xd0010680 0x28>;
reg = <0x10680 0x28>;
#address-cells = <1>;
#size-cells = <0>;
cell-index = <1>;
......@@ -181,6 +180,51 @@ spi1: spi@d0010680 {
clocks = <&coreclk 0>;
status = "disabled";
};
devbus-bootcs@10400 {
compatible = "marvell,mvebu-devbus";
reg = <0x10400 0x8>;
#address-cells = <1>;
#size-cells = <1>;
clocks = <&coreclk 0>;
status = "disabled";
};
};
devbus-cs0@10408 {
compatible = "marvell,mvebu-devbus";
reg = <0x10408 0x8>;
#address-cells = <1>;
#size-cells = <1>;
clocks = <&coreclk 0>;
status = "disabled";
};
devbus-cs1@10410 {
compatible = "marvell,mvebu-devbus";
reg = <0x10410 0x8>;
#address-cells = <1>;
#size-cells = <1>;
clocks = <&coreclk 0>;
status = "disabled";
};
devbus-cs2@10418 {
compatible = "marvell,mvebu-devbus";
reg = <0x10418 0x8>;
#address-cells = <1>;
#size-cells = <1>;
clocks = <&coreclk 0>;
status = "disabled";
};
devbus-cs3@10420 {
compatible = "marvell,mvebu-devbus";
reg = <0x10420 0x8>;
#address-cells = <1>;
#size-cells = <1>;
clocks = <&coreclk 0>;
status = "disabled";
};
};
};
};
......@@ -16,16 +16,11 @@
*/
/include/ "armada-370-xp.dtsi"
/include/ "skeleton.dtsi"
/ {
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;
......@@ -33,20 +28,28 @@ aliases {
gpio2 = &gpio2;
};
mpic: interrupt-controller@d0020000 {
reg = <0xd0020a00 0x1d0>,
<0xd0021870 0x58>;
};
soc {
system-controller@d0018200 {
ranges = <0 0xd0000000 0x100000>;
internal-regs {
system-controller@18200 {
compatible = "marvell,armada-370-xp-system-controller";
reg = <0xd0018200 0x100>;
reg = <0x18200 0x100>;
};
L2: l2-cache {
compatible = "marvell,aurora-outer-cache";
reg = <0xd0008000 0x1000>;
cache-id-part = <0x100>;
wt-override;
};
mpic: interrupt-controller@20000 {
reg = <0x20a00 0x1d0>, <0x21870 0x58>;
};
pinctrl {
compatible = "marvell,mv88f6710-pinctrl";
reg = <0xd0018000 0x38>;
reg = <0x18000 0x38>;
sdio_pins1: sdio-pins1 {
marvell,pins = "mpp9", "mpp11", "mpp12",
......@@ -59,11 +62,17 @@ sdio_pins2: sdio-pins2 {
"mpp50", "mpp51", "mpp52";
marvell,function = "sd0";
};
sdio_pins3: sdio-pins3 {
marvell,pins = "mpp48", "mpp49", "mpp50",
"mpp51", "mpp52", "mpp53";
marvell,function = "sd0";
};
};
gpio0: gpio@d0018100 {
gpio0: gpio@18100 {
compatible = "marvell,orion-gpio";
reg = <0xd0018100 0x40>;
reg = <0x18100 0x40>;
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
......@@ -72,9 +81,9 @@ gpio0: gpio@d0018100 {
interrupts = <82>, <83>, <84>, <85>;
};
gpio1: gpio@d0018140 {
gpio1: gpio@18140 {
compatible = "marvell,orion-gpio";
reg = <0xd0018140 0x40>;
reg = <0x18140 0x40>;
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
......@@ -83,9 +92,9 @@ gpio1: gpio@d0018140 {
interrupts = <87>, <88>, <89>, <90>;
};
gpio2: gpio@d0018180 {
gpio2: gpio@18180 {
compatible = "marvell,orion-gpio";
reg = <0xd0018180 0x40>;
reg = <0x18180 0x40>;
ngpios = <2>;
gpio-controller;
#gpio-cells = <2>;
......@@ -94,23 +103,23 @@ gpio2: gpio@d0018180 {
interrupts = <91>;
};
coreclk: mvebu-sar@d0018230 {
coreclk: mvebu-sar@18230 {
compatible = "marvell,armada-370-core-clock";
reg = <0xd0018230 0x08>;
reg = <0x18230 0x08>;
#clock-cells = <1>;
};
gateclk: clock-gating-control@d0018220 {
gateclk: clock-gating-control@18220 {
compatible = "marvell,armada-370-gating-clock";
reg = <0xd0018220 0x4>;
reg = <0x18220 0x4>;
clocks = <&coreclk 0>;
#clock-cells = <1>;
};
xor@d0060800 {
xor@60800 {
compatible = "marvell,orion-xor";
reg = <0xd0060800 0x100
0xd0060A00 0x100>;
reg = <0x60800 0x100
0x60A00 0x100>;
status = "okay";
xor00 {
......@@ -126,10 +135,10 @@ xor01 {
};
};
xor@d0060900 {
xor@60900 {
compatible = "marvell,orion-xor";
reg = <0xd0060900 0x100
0xd0060b00 0x100>;
reg = <0x60900 0x100
0x60b00 0x100>;
status = "okay";
xor10 {
......@@ -145,13 +154,72 @@ xor11 {
};
};
usb@d0050000 {
usb@50000 {
clocks = <&coreclk 0>;
};
usb@d0051000 {
usb@51000 {
clocks = <&coreclk 0>;
};
thermal@18300 {
compatible = "marvell,armada370-thermal";
reg = <0x18300 0x4
0x18304 0x4>;
status = "okay";
};
pcie-controller {
compatible = "marvell,armada-370-pcie";
status = "disabled";
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
bus-range = <0x00 0xff>;
reg = <0x40000 0x2000>, <0x80000 0x2000>;
reg-names = "pcie0.0", "pcie1.0";
ranges = <0x82000000 0 0x40000 0x40000 0 0x00002000 /* Port 0.0 registers */
0x82000000 0 0x80000 0x80000 0 0x00002000 /* Port 1.0 registers */
0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */
0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */
pcie@1,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
reg = <0x0800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 58>;
marvell,pcie-port = <0>;
marvell,pcie-lane = <0>;
clocks = <&gateclk 5>;
status = "disabled";
};
pcie@2,0 {
device_type = "pci";
assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
reg = <0x1000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 62>;
marvell,pcie-port = <1>;
marvell,pcie-lane = <0>;
clocks = <&gateclk 9>;
status = "disabled";
};
};
};
};
};
......@@ -26,28 +26,29 @@ chosen {
memory {
device_type = "memory";
reg = <0x00000000 0x80000000>; /* 2 GB */
reg = <0 0x00000000 0 0x80000000>; /* 2 GB */
};
soc {
serial@d0012000 {
internal-regs {
serial@12000 {
clock-frequency = <250000000>;
status = "okay";
};
serial@d0012100 {
serial@12100 {
clock-frequency = <250000000>;
status = "okay";
};
serial@d0012200 {
serial@12200 {
clock-frequency = <250000000>;
status = "okay";
};
serial@d0012300 {
serial@12300 {
clock-frequency = <250000000>;
status = "okay";
};
sata@d00a0000 {
sata@a0000 {
nr-ports = <2>;
status = "okay";
};
......@@ -70,47 +71,47 @@ phy3: ethernet-phy@3 {
};
};
ethernet@d0070000 {
ethernet@70000 {
status = "okay";
phy = <&phy0>;
phy-mode = "rgmii-id";
};
ethernet@d0074000 {
ethernet@74000 {
status = "okay";
phy = <&phy1>;
phy-mode = "rgmii-id";
};
ethernet@d0030000 {
ethernet@30000 {
status = "okay";
phy = <&phy2>;
phy-mode = "sgmii";
};
ethernet@d0034000 {
ethernet@34000 {
status = "okay";
phy = <&phy3>;
phy-mode = "sgmii";
};
mvsdio@d00d4000 {
mvsdio@d4000 {
pinctrl-0 = <&sdio_pins>;
pinctrl-names = "default";
status = "okay";
/* No CD or WP GPIOs */
};
usb@d0050000 {
usb@50000 {
status = "okay";
};
usb@d0051000 {
usb@51000 {
status = "okay";
};
usb@d0052000 {
usb@52000 {
status = "okay";
};
spi0: spi@d0010600 {
spi0: spi@10600 {
status = "okay";
spi-flash@0 {
......@@ -121,5 +122,39 @@ spi-flash@0 {
spi-max-frequency = <20000000>;
};
};
pcie-controller {
status = "okay";
/*
* All 6 slots are physically present as
* standard PCIe slots on the board.
*/
pcie@1,0 {
/* Port 0, Lane 0 */
status = "okay";
};
pcie@2,0 {
/* Port 0, Lane 1 */
status = "okay";
};
pcie@3,0 {
/* Port 0, Lane 2 */
status = "okay";
};
pcie@4,0 {
/* Port 0, Lane 3 */
status = "okay";
};
pcie@9,0 {
/* Port 2, Lane 0 */
status = "okay";
};
pcie@10,0 {
/* Port 3, Lane 0 */
status = "okay";
};
};
};
};
};
......@@ -26,35 +26,38 @@ chosen {
memory {
device_type = "memory";
/*
* 4 GB of plug-in RAM modules by default but only 3GB
* are visible, the amount of memory available can be
* changed by the bootloader according the size of the
* module actually plugged
* 8 GB of plug-in RAM modules by default.The amount
* of memory available can be changed by the
* bootloader according the size of the module
* actually plugged. Only 7GB are usable because
* addresses from 0xC0000000 to 0xffffffff are used by
* the internal registers of the SoC.
*/
reg = <0x00000000 0xC0000000>;
reg = <0x00000000 0x00000000 0x00000000 0xC0000000>,
<0x00000001 0x00000000 0x00000001 0x00000000>;
};
soc {
serial@d0012000 {
internal-regs {
serial@12000 {
clock-frequency = <250000000>;
status = "okay";
};
serial@d0012100 {
serial@12100 {
clock-frequency = <250000000>;
status = "okay";
};
serial@d0012200 {
serial@12200 {
clock-frequency = <250000000>;
status = "okay";
};
serial@d0012300 {
serial@12300 {
clock-frequency = <250000000>;
status = "okay";
};
sata@d00a0000 {
sata@a0000 {
nr-ports = <2>;
status = "okay";
};
......@@ -77,28 +80,28 @@ phy3: ethernet-phy@3 {
};
};
ethernet@d0070000 {
ethernet@70000 {
status = "okay";
phy = <&phy0>;
phy-mode = "rgmii-id";
};
ethernet@d0074000 {
ethernet@74000 {
status = "okay";
phy = <&phy1>;
phy-mode = "rgmii-id";
};
ethernet@d0030000 {
ethernet@30000 {
status = "okay";
phy = <&phy2>;
phy-mode = "rgmii-id";
};
ethernet@d0034000 {
ethernet@34000 {
status = "okay";
phy = <&phy3>;
phy-mode = "rgmii-id";
};
spi0: spi@d0010600 {
spi0: spi@10600 {
status = "okay";
spi-flash@0 {
......@@ -109,5 +112,56 @@ spi-flash@0 {
spi-max-frequency = <108000000>;
};
};
devbus-bootcs@10400 {
status = "okay";
ranges = <0 0xf0000000 0x1000000>; /* @addr 0xf000000, size 0x1000000 */
/* Device Bus parameters are required */
/* Read parameters */
devbus,bus-width = <8>;
devbus,turn-off-ps = <60000>;
devbus,badr-skew-ps = <0>;
devbus,acc-first-ps = <124000>;
devbus,acc-next-ps = <248000>;
devbus,rd-setup-ps = <0>;
devbus,rd-hold-ps = <0>;
/* Write parameters */
devbus,sync-enable = <0>;
devbus,wr-high-ps = <60000>;
devbus,wr-low-ps = <60000>;
devbus,ale-wr-ps = <60000>;
/* NOR 16 MiB */
nor@0 {
compatible = "cfi-flash";
reg = <0 0x1000000>;
bank-width = <2>;
};
};
pcie-controller {
status = "okay";
/*
* The 3 slots are physically present as
* standard PCIe slots on the board.
*/
pcie@1,0 {
/* Port 0, Lane 0 */
status = "okay";
};
pcie@9,0 {
/* Port 2, Lane 0 */
status = "okay";
};
pcie@10,0 {
/* Port 3, Lane 0 */
status = "okay";
};
};
};
};
};
......@@ -44,9 +44,10 @@ cpu@1 {
};
soc {
internal-regs {
pinctrl {
compatible = "marvell,mv78230-pinctrl";
reg = <0xd0018000 0x38>;
reg = <0x18000 0x38>;
sdio_pins: sdio-pins {
marvell,pins = "mpp30", "mpp31", "mpp32",
......@@ -55,9 +56,9 @@ sdio_pins: sdio-pins {
};
};
gpio0: gpio@d0018100 {
gpio0: gpio@18100 {
compatible = "marvell,orion-gpio";
reg = <0xd0018100 0x40>;
reg = <0x18100 0x40>;
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
......@@ -66,9 +67,9 @@ gpio0: gpio@d0018100 {
interrupts = <82>, <83>, <84>, <85>;
};
gpio1: gpio@d0018140 {
gpio1: gpio@18140 {
compatible = "marvell,orion-gpio";
reg = <0xd0018140 0x40>;
reg = <0x18140 0x40>;
ngpios = <17>;
gpio-controller;
#gpio-cells = <2>;
......@@ -76,5 +77,110 @@ gpio1: gpio@d0018140 {
#interrupts-cells = <2>;
interrupts = <87>, <88>, <89>;
};
/*
* MV78230 has 2 PCIe units Gen2.0: One unit can be
* configured as x4 or quad x1 lanes. One unit is
* x4/x1.
*/
pcie-controller {
compatible = "marvell,armada-xp-pcie";
status = "disabled";
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
bus-range = <0x00 0xff>;
ranges = <0x82000000 0 0x40000 0x40000 0 0x00002000 /* Port 0.0 registers */
0x82000000 0 0x42000 0x42000 0 0x00002000 /* Port 2.0 registers */
0x82000000 0 0x44000 0x44000 0 0x00002000 /* Port 0.1 registers */
0x82000000 0 0x48000 0x48000 0 0x00002000 /* Port 0.2 registers */
0x82000000 0 0x4c000 0x4c000 0 0x00002000 /* Port 0.3 registers */
0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */
0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */
pcie@1,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
reg = <0x0800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 58>;
marvell,pcie-port = <0>;
marvell,pcie-lane = <0>;
clocks = <&gateclk 5>;
status = "disabled";
};
pcie@2,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
reg = <0x1000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 59>;
marvell,pcie-port = <0>;
marvell,pcie-lane = <1>;
clocks = <&gateclk 6>;
status = "disabled";
};
pcie@3,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
reg = <0x1800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 60>;
marvell,pcie-port = <0>;
marvell,pcie-lane = <2>;
clocks = <&gateclk 7>;
status = "disabled";
};
pcie@4,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>;
reg = <0x2000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 61>;
marvell,pcie-port = <0>;
marvell,pcie-lane = <3>;
clocks = <&gateclk 8>;
status = "disabled";
};
pcie@9,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
reg = <0x4800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 99>;
marvell,pcie-port = <2>;
marvell,pcie-lane = <0>;
clocks = <&gateclk 26>;
status = "disabled";
};
};
};
};
};
......@@ -45,9 +45,10 @@ cpu@1 {
};
soc {
internal-regs {
pinctrl {
compatible = "marvell,mv78260-pinctrl";
reg = <0xd0018000 0x38>;
reg = <0x18000 0x38>;
sdio_pins: sdio-pins {
marvell,pins = "mpp30", "mpp31", "mpp32",
......@@ -56,9 +57,9 @@ sdio_pins: sdio-pins {
};
};
gpio0: gpio@d0018100 {
gpio0: gpio@18100 {
compatible = "marvell,orion-gpio";
reg = <0xd0018100 0x40>;
reg = <0x18100 0x40>;
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
......@@ -67,9 +68,9 @@ gpio0: gpio@d0018100 {
interrupts = <82>, <83>, <84>, <85>;
};
gpio1: gpio@d0018140 {
gpio1: gpio@18140 {
compatible = "marvell,orion-gpio";
reg = <0xd0018140 0x40>;
reg = <0x18140 0x40>;
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
......@@ -78,9 +79,9 @@ gpio1: gpio@d0018140 {
interrupts = <87>, <88>, <89>, <90>;
};
gpio2: gpio@d0018180 {
gpio2: gpio@18180 {
compatible = "marvell,orion-gpio";
reg = <0xd0018180 0x40>;
reg = <0x18180 0x40>;
ngpios = <3>;
gpio-controller;
#gpio-cells = <2>;
......@@ -89,12 +90,135 @@ gpio2: gpio@d0018180 {
interrupts = <91>;
};
ethernet@d0034000 {
ethernet@34000 {
compatible = "marvell,armada-370-neta";
reg = <0xd0034000 0x2500>;
reg = <0x34000 0x2500>;
interrupts = <14>;
clocks = <&gateclk 1>;
status = "disabled";
};
/*
* MV78260 has 3 PCIe units Gen2.0: Two units can be
* configured as x4 or quad x1 lanes. One unit is
* x4/x1.
*/
pcie-controller {
compatible = "marvell,armada-xp-pcie";
status = "disabled";
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
bus-range = <0x00 0xff>;
ranges = <0x82000000 0 0x40000 0x40000 0 0x00002000 /* Port 0.0 registers */
0x82000000 0 0x42000 0x42000 0 0x00002000 /* Port 2.0 registers */
0x82000000 0 0x44000 0x44000 0 0x00002000 /* Port 0.1 registers */
0x82000000 0 0x48000 0x48000 0 0x00002000 /* Port 0.2 registers */
0x82000000 0 0x4c000 0x4c000 0 0x00002000 /* Port 0.3 registers */
0x82000000 0 0x80000 0x80000 0 0x00002000 /* Port 1.0 registers */
0x82000000 0 0x82000 0x82000 0 0x00002000 /* Port 3.0 registers */
0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */
0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */
pcie@1,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
reg = <0x0800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 58>;
marvell,pcie-port = <0>;
marvell,pcie-lane = <0>;
clocks = <&gateclk 5>;
status = "disabled";
};
pcie@2,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
reg = <0x1000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 59>;
marvell,pcie-port = <0>;
marvell,pcie-lane = <1>;
clocks = <&gateclk 6>;
status = "disabled";
};
pcie@3,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
reg = <0x1800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 60>;
marvell,pcie-port = <0>;
marvell,pcie-lane = <2>;
clocks = <&gateclk 7>;
status = "disabled";
};
pcie@4,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>;
reg = <0x2000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 61>;
marvell,pcie-port = <0>;
marvell,pcie-lane = <3>;
clocks = <&gateclk 8>;
status = "disabled";
};
pcie@9,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
reg = <0x4800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 99>;
marvell,pcie-port = <2>;
marvell,pcie-lane = <0>;
clocks = <&gateclk 26>;
status = "disabled";
};
pcie@10,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x82000 0 0x2000>;
reg = <0x5000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 103>;
marvell,pcie-port = <3>;
marvell,pcie-lane = <0>;
clocks = <&gateclk 27>;
status = "disabled";
};
};
};
};
};
......@@ -60,9 +60,10 @@ cpu@3 {
};
soc {
internal-regs {
pinctrl {
compatible = "marvell,mv78460-pinctrl";
reg = <0xd0018000 0x38>;
reg = <0x18000 0x38>;
sdio_pins: sdio-pins {
marvell,pins = "mpp30", "mpp31", "mpp32",
......@@ -71,9 +72,9 @@ sdio_pins: sdio-pins {
};
};
gpio0: gpio@d0018100 {
gpio0: gpio@18100 {
compatible = "marvell,orion-gpio";
reg = <0xd0018100 0x40>;
reg = <0x18100 0x40>;
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
......@@ -82,9 +83,9 @@ gpio0: gpio@d0018100 {
interrupts = <82>, <83>, <84>, <85>;
};
gpio1: gpio@d0018140 {
gpio1: gpio@18140 {
compatible = "marvell,orion-gpio";
reg = <0xd0018140 0x40>;
reg = <0x18140 0x40>;
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
......@@ -93,9 +94,9 @@ gpio1: gpio@d0018140 {
interrupts = <87>, <88>, <89>, <90>;
};
gpio2: gpio@d0018180 {
gpio2: gpio@18180 {
compatible = "marvell,orion-gpio";
reg = <0xd0018180 0x40>;
reg = <0x18180 0x40>;
ngpios = <3>;
gpio-controller;
#gpio-cells = <2>;
......@@ -104,12 +105,201 @@ gpio2: gpio@d0018180 {
interrupts = <91>;
};
ethernet@d0034000 {
ethernet@34000 {
compatible = "marvell,armada-370-neta";
reg = <0xd0034000 0x2500>;
reg = <0x34000 0x2500>;
interrupts = <14>;
clocks = <&gateclk 1>;
status = "disabled";
};
/*
* MV78460 has 4 PCIe units Gen2.0: Two units can be
* configured as x4 or quad x1 lanes. Two units are
* x4/x1.
*/
pcie-controller {
compatible = "marvell,armada-xp-pcie";
status = "disabled";
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
bus-range = <0x00 0xff>;
ranges = <0x82000000 0 0x40000 0x40000 0 0x00002000 /* Port 0.0 registers */
0x82000000 0 0x42000 0x42000 0 0x00002000 /* Port 2.0 registers */
0x82000000 0 0x44000 0x44000 0 0x00002000 /* Port 0.1 registers */
0x82000000 0 0x48000 0x48000 0 0x00002000 /* Port 0.2 registers */
0x82000000 0 0x4c000 0x4c000 0 0x00002000 /* Port 0.3 registers */
0x82000000 0 0x80000 0x80000 0 0x00002000 /* Port 1.0 registers */
0x82000000 0 0x82000 0x82000 0 0x00002000 /* Port 3.0 registers */
0x82000000 0 0x84000 0x84000 0 0x00002000 /* Port 1.1 registers */
0x82000000 0 0x88000 0x88000 0 0x00002000 /* Port 1.2 registers */
0x82000000 0 0x8c000 0x8c000 0 0x00002000 /* Port 1.3 registers */
0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */
0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */
pcie@1,0 {
device_type = "pci";
assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
reg = <0x0800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 58>;
marvell,pcie-port = <0>;
marvell,pcie-lane = <0>;
clocks = <&gateclk 5>;
status = "disabled";
};
pcie@2,0 {
device_type = "pci";
assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
reg = <0x1000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 59>;
marvell,pcie-port = <0>;
marvell,pcie-lane = <1>;
clocks = <&gateclk 6>;
status = "disabled";
};
pcie@3,0 {
device_type = "pci";
assigned-addresses = <0x82001800 0 0x48000 0 0x2000>;
reg = <0x1800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 60>;
marvell,pcie-port = <0>;
marvell,pcie-lane = <2>;
clocks = <&gateclk 7>;
status = "disabled";
};
pcie@4,0 {
device_type = "pci";
assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>;
reg = <0x2000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 61>;
marvell,pcie-port = <0>;
marvell,pcie-lane = <3>;
clocks = <&gateclk 8>;
status = "disabled";
};
pcie@5,0 {
device_type = "pci";
assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
reg = <0x2800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 62>;
marvell,pcie-port = <1>;
marvell,pcie-lane = <0>;
clocks = <&gateclk 9>;
status = "disabled";
};
pcie@6,0 {
device_type = "pci";
assigned-addresses = <0x82003000 0 0x84000 0 0x2000>;
reg = <0x3000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 63>;
marvell,pcie-port = <1>;
marvell,pcie-lane = <1>;
clocks = <&gateclk 10>;
status = "disabled";
};
pcie@7,0 {
device_type = "pci";
assigned-addresses = <0x82003800 0 0x88000 0 0x2000>;
reg = <0x3800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 64>;
marvell,pcie-port = <1>;
marvell,pcie-lane = <2>;
clocks = <&gateclk 11>;
status = "disabled";
};
pcie@8,0 {
device_type = "pci";
assigned-addresses = <0x82004000 0 0x8c000 0 0x2000>;
reg = <0x4000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 65>;
marvell,pcie-port = <1>;
marvell,pcie-lane = <3>;
clocks = <&gateclk 12>;
status = "disabled";
};
pcie@9,0 {
device_type = "pci";
assigned-addresses = <0x82004800 0 0x42000 0 0x2000>;
reg = <0x4800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 99>;
marvell,pcie-port = <2>;
marvell,pcie-lane = <0>;
clocks = <&gateclk 26>;
status = "disabled";
};
pcie@10,0 {
device_type = "pci";
assigned-addresses = <0x82005000 0 0x82000 0 0x2000>;
reg = <0x5000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
ranges;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 103>;
marvell,pcie-port = <3>;
marvell,pcie-lane = <0>;
clocks = <&gateclk 27>;
status = "disabled";
};
};
};
};
};
......@@ -23,15 +23,16 @@ chosen {
memory {
device_type = "memory";
reg = <0x00000000 0xC0000000>; /* 3 GB */
reg = <0 0x00000000 0 0xC0000000>; /* 3 GB */
};
soc {
serial@d0012000 {
internal-regs {
serial@12000 {
clock-frequency = <250000000>;
status = "okay";
};
serial@d0012100 {
serial@12100 {
clock-frequency = <250000000>;
status = "okay";
};
......@@ -96,31 +97,31 @@ phy3: ethernet-phy@3 {
};
};
ethernet@d0070000 {
ethernet@70000 {
status = "okay";
phy = <&phy0>;
phy-mode = "sgmii";
};
ethernet@d0074000 {
ethernet@74000 {
status = "okay";
phy = <&phy1>;
phy-mode = "sgmii";
};
ethernet@d0030000 {
ethernet@30000 {
status = "okay";
phy = <&phy2>;
phy-mode = "sgmii";
};
ethernet@d0034000 {
ethernet@34000 {
status = "okay";
phy = <&phy3>;
phy-mode = "sgmii";
};
i2c@d0011000 {
i2c@11000 {
status = "okay";
clock-frequency = <400000>;
};
i2c@d0011100 {
i2c@11100 {
status = "okay";
clock-frequency = <400000>;
......@@ -129,15 +130,54 @@ s35390a: s35390a@30 {
reg = <0x30>;
};
};
sata@d00a0000 {
sata@a0000 {
nr-ports = <2>;
status = "okay";
};
usb@d0050000 {
usb@50000 {
status = "okay";
};
usb@d0051000 {
usb@51000 {
status = "okay";
};
devbus-bootcs@10400 {
status = "okay";
ranges = <0 0xf0000000 0x8000000>; /* @addr 0xf000000, size 0x8000000 */
/* Device Bus parameters are required */
/* Read parameters */
devbus,bus-width = <8>;
devbus,turn-off-ps = <60000>;
devbus,badr-skew-ps = <0>;
devbus,acc-first-ps = <124000>;
devbus,acc-next-ps = <248000>;
devbus,rd-setup-ps = <0>;
devbus,rd-hold-ps = <0>;
/* Write parameters */
devbus,sync-enable = <0>;
devbus,wr-high-ps = <60000>;
devbus,wr-low-ps = <60000>;
devbus,ale-wr-ps = <60000>;
/* NOR 128 MiB */
nor@0 {
compatible = "cfi-flash";
reg = <0 0x8000000>;
bank-width = <2>;
};
};
pcie-controller {
status = "okay";
/* Internal mini-PCIe connector */
pcie@1,0 {
/* Port 0, Lane 0 */
status = "okay";
};
};
};
};
};
......@@ -22,83 +22,82 @@ / {
model = "Marvell Armada XP family SoC";
compatible = "marvell,armadaxp", "marvell,armada-370-xp";
soc {
internal-regs {
L2: l2-cache {
compatible = "marvell,aurora-system-cache";
reg = <0xd0008000 0x1000>;
reg = <0x08000 0x1000>;
cache-id-part = <0x100>;
wt-override;
};
mpic: interrupt-controller@d0020000 {
reg = <0xd0020a00 0x2d0>,
<0xd0021070 0x58>;
mpic: interrupt-controller@20000 {
reg = <0x20a00 0x2d0>, <0x21070 0x58>;
};
armada-370-xp-pmsu@d0022000 {
armada-370-xp-pmsu@22000 {
compatible = "marvell,armada-370-xp-pmsu";
reg = <0xd0022100 0x430>,
<0xd0020800 0x20>;
reg = <0x22100 0x430>, <0x20800 0x20>;
};
soc {
serial@d0012200 {
serial@12200 {
compatible = "snps,dw-apb-uart";
reg = <0xd0012200 0x100>;
reg = <0x12200 0x100>;
reg-shift = <2>;
interrupts = <43>;
reg-io-width = <1>;
status = "disabled";
};
serial@d0012300 {
serial@12300 {
compatible = "snps,dw-apb-uart";
reg = <0xd0012300 0x100>;
reg = <0x12300 0x100>;
reg-shift = <2>;
interrupts = <44>;
reg-io-width = <1>;
status = "disabled";
};
timer@d0020300 {
timer@20300 {
marvell,timer-25Mhz;
};
coreclk: mvebu-sar@d0018230 {
coreclk: mvebu-sar@18230 {
compatible = "marvell,armada-xp-core-clock";
reg = <0xd0018230 0x08>;
reg = <0x18230 0x08>;
#clock-cells = <1>;
};
cpuclk: clock-complex@d0018700 {
cpuclk: clock-complex@18700 {
#clock-cells = <1>;
compatible = "marvell,armada-xp-cpu-clock";
reg = <0xd0018700 0xA0>;
reg = <0x18700 0xA0>;
clocks = <&coreclk 1>;
};
gateclk: clock-gating-control@d0018220 {
gateclk: clock-gating-control@18220 {
compatible = "marvell,armada-xp-gating-clock";
reg = <0xd0018220 0x4>;
reg = <0x18220 0x4>;
clocks = <&coreclk 0>;
#clock-cells = <1>;
};
system-controller@d0018200 {
system-controller@18200 {
compatible = "marvell,armada-370-xp-system-controller";
reg = <0xd0018200 0x500>;
reg = <0x18200 0x500>;
};
ethernet@d0030000 {
ethernet@30000 {
compatible = "marvell,armada-370-neta";
reg = <0xd0030000 0x2500>;
reg = <0x30000 0x2500>;
interrupts = <12>;
clocks = <&gateclk 2>;
status = "disabled";
};
xor@d0060900 {
xor@60900 {
compatible = "marvell,orion-xor";
reg = <0xd0060900 0x100
0xd0060b00 0x100>;
reg = <0x60900 0x100
0x60b00 0x100>;
clocks = <&gateclk 22>;
status = "okay";
......@@ -115,10 +114,10 @@ xor11 {
};
};
xor@d00f0900 {
xor@f0900 {
compatible = "marvell,orion-xor";
reg = <0xd00F0900 0x100
0xd00F0B00 0x100>;
reg = <0xF0900 0x100
0xF0B00 0x100>;
clocks = <&gateclk 28>;
status = "okay";
......@@ -135,21 +134,28 @@ xor01 {
};
};
usb@d0050000 {
usb@50000 {
clocks = <&gateclk 18>;
};
usb@d0051000 {
usb@51000 {
clocks = <&gateclk 19>;
};
usb@d0052000 {
usb@52000 {
compatible = "marvell,orion-ehci";
reg = <0xd0052000 0x500>;
reg = <0x52000 0x500>;
interrupts = <47>;
clocks = <&gateclk 20>;
status = "disabled";
};
thermal@182b0 {
compatible = "marvell,armadaxp-thermal";
reg = <0x182b0 0x4
0x184d0 0x4>;
status = "okay";
};
};
};
};
......@@ -50,6 +50,11 @@ gate_clk: clock-gating-control@d0038 {
#clock-cells = <1>;
};
thermal: thermal@d001c {
compatible = "marvell,dove-thermal";
reg = <0xd001c 0x0c>, <0xd005c 0x08>;
};
uart0: serial@12000 {
compatible = "ns16550a";
reg = <0x12000 0x100>;
......
......@@ -49,6 +49,12 @@ pmx_sdio: pmx-sdio {
};
};
thermal@10078 {
compatible = "marvell,kirkwood-thermal";
reg = <0x10078 0x4>;
status = "okay";
};
i2c@11100 {
compatible = "marvell,mv64xxx-i2c";
reg = <0x11100 0x20>;
......
......@@ -77,6 +77,7 @@ serial@12000 {
};
nand@3000000 {
chip-delay = <40>;
status = "okay";
partition@0 {
......
......@@ -69,6 +69,10 @@ sata@80000 {
status = "okay";
nr-ports = <1>;
};
mvsdio@90000 {
status = "okay";
};
};
gpio-leds {
......
......@@ -96,11 +96,11 @@ pmx_led_health_brt_ctrl_2: pmx-led-health-brt-ctrl-2 {
marvell,function = "gpio";
};
pmx_led_rebuild_brt_ctrl_1: pmx-led-rebuild-brt-ctrl-1 {
marvell,pins = "mpp44";
marvell,pins = "mpp46";
marvell,function = "gpio";
};
pmx_led_rebuild_brt_ctrl_2: pmx-led-rebuild-brt-ctrl-2 {
marvell,pins = "mpp45";
marvell,pins = "mpp47";
marvell,function = "gpio";
};
......@@ -157,14 +157,14 @@ power_led {
gpios = <&gpio0 16 0>;
linux,default-trigger = "default-on";
};
health_led1 {
rebuild_led {
label = "status:white:rebuild_led";
gpios = <&gpio1 4 0>;
};
health_led {
label = "status:red:health_led";
gpios = <&gpio1 5 0>;
};
health_led2 {
label = "status:white:health_led";
gpios = <&gpio1 4 0>;
};
backup_led {
label = "status:blue:backup_led";
gpios = <&gpio0 15 0>;
......
......@@ -13,6 +13,9 @@ / {
compatible = "marvell,orion5x";
interrupt-parent = <&intc>;
aliases {
gpio0 = &gpio0;
};
intc: interrupt-controller {
compatible = "marvell,orion-intc", "marvell,intc";
interrupt-controller;
......@@ -32,7 +35,9 @@ gpio0: gpio@10100 {
#gpio-cells = <2>;
gpio-controller;
reg = <0x10100 0x40>;
ngpio = <32>;
ngpios = <32>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <6>, <7>, <8>, <9>;
};
......@@ -69,6 +74,20 @@ wdt@20300 {
status = "okay";
};
ehci@50000 {
compatible = "marvell,orion-ehci";
reg = <0x50000 0x1000>;
interrupts = <17>;
status = "disabled";
};
ehci@a0000 {
compatible = "marvell,orion-ehci";
reg = <0xa0000 0x1000>;
interrupts = <12>;
status = "disabled";
};
sata@80000 {
compatible = "marvell,orion-sata";
reg = <0x80000 0x5000>;
......@@ -86,12 +105,31 @@ i2c@11000 {
status = "disabled";
};
xor@60900 {
compatible = "marvell,orion-xor";
reg = <0x60900 0x100
0x60b00 0x100>;
status = "okay";
xor00 {
interrupts = <30>;
dmacap,memcpy;
dmacap,xor;
};
xor01 {
interrupts = <31>;
dmacap,memcpy;
dmacap,xor;
dmacap,memset;
};
};
crypto@90000 {
compatible = "marvell,orion-crypto";
reg = <0x90000 0x10000>,
<0xf2200000 0x800>;
reg-names = "regs", "sram";
interrupts = <22>;
interrupts = <28>;
status = "okay";
};
};
......
/*
* Skeleton device tree in the 64 bits version; the bare minimum
* needed to boot; just include and add a compatible value. The
* bootloader will typically populate the memory node.
*/
/ {
#address-cells = <2>;
#size-cells = <2>;
chosen { };
aliases { };
memory { device_type = "memory"; reg = <0 0>; };
};
......@@ -75,6 +75,8 @@ CONFIG_I2C_MV64XXX=y
CONFIG_SPI=y
CONFIG_SPI_ORION=y
# CONFIG_HWMON is not set
CONFIG_THERMAL=y
CONFIG_DOVE_THERMAL=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
......
......@@ -119,6 +119,8 @@ CONFIG_SPI=y
CONFIG_SPI_ORION=y
CONFIG_GPIO_SYSFS=y
# CONFIG_HWMON is not set
CONFIG_THERMAL=y
CONFIG_KIRKWOOD_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_ORION_WATCHDOG=y
CONFIG_HID_DRAGONRISE=y
......
......@@ -46,9 +46,16 @@ CONFIG_I2C_MV64XXX=y
CONFIG_MTD=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_M25P80=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_SERIAL_8250_DW=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
CONFIG_THERMAL=y
CONFIG_ARMADA_THERMAL=y
CONFIG_USB_SUPPORT=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
......@@ -65,6 +72,8 @@ CONFIG_RTC_DRV_S35390A=y
CONFIG_RTC_DRV_MV=y
CONFIG_DMADEVICES=y
CONFIG_MV_XOR=y
CONFIG_MEMORY=y
CONFIG_MVEBU_DEVBUS=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
......
......@@ -12,7 +12,7 @@
*/
#define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000
#define ARMADA_370_XP_REGS_VIRT_BASE 0xfeb00000
#define ARMADA_370_XP_REGS_VIRT_BASE 0xfec00000
.macro addruart, rp, rv, tmp
ldr \rp, =ARMADA_370_XP_REGS_PHYS_BASE
......
obj-y += common.o addr-map.o irq.o
obj-y += common.o irq.o
obj-$(CONFIG_DOVE_LEGACY) += mpp.o
obj-$(CONFIG_PCI) += pcie.o
obj-$(CONFIG_MACH_DOVE_DB) += dove-db-setup.o
......
/*
* arch/arm/mach-dove/addr-map.c
*
* Address map functions for Marvell Dove 88AP510 SoC
*
* 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/init.h>
#include <linux/mbus.h>
#include <linux/io.h>
#include <asm/mach/arch.h>
#include <asm/setup.h>
#include <mach/dove.h>
#include <plat/addr-map.h>
#include "common.h"
/*
* Generic Address Decode Windows bit settings
*/
#define TARGET_DDR 0x0
#define TARGET_BOOTROM 0x1
#define TARGET_CESA 0x3
#define TARGET_PCIE0 0x4
#define TARGET_PCIE1 0x8
#define TARGET_SCRATCHPAD 0xd
#define ATTR_CESA 0x01
#define ATTR_BOOTROM 0xfd
#define ATTR_DEV_SPI0_ROM 0xfe
#define ATTR_DEV_SPI1_ROM 0xfb
#define ATTR_PCIE_IO 0xe0
#define ATTR_PCIE_MEM 0xe8
#define ATTR_SCRATCHPAD 0x0
static inline void __iomem *ddr_map_sc(int i)
{
return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4));
}
/*
* Description of the windows needed by the platform code
*/
static struct __initdata orion_addr_map_cfg addr_map_cfg = {
.num_wins = 8,
.remappable_wins = 4,
.bridge_virt_base = BRIDGE_VIRT_BASE,
};
static const struct __initdata orion_addr_map_info addr_map_info[] = {
/*
* Windows for PCIe IO+MEM space.
*/
{ 0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE,
TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE
},
{ 1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE,
TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE
},
{ 2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE,
TARGET_PCIE0, ATTR_PCIE_MEM, -1
},
{ 3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE,
TARGET_PCIE1, ATTR_PCIE_MEM, -1
},
/*
* Window for CESA engine.
*/
{ 4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE,
TARGET_CESA, ATTR_CESA, -1
},
/*
* Window to the BootROM for Standby and Sleep Resume
*/
{ 5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE,
TARGET_BOOTROM, ATTR_BOOTROM, -1
},
/*
* Window to the PMU Scratch Pad space
*/
{ 6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE,
TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1
},
/* End marker */
{ -1, 0, 0, 0, 0, 0 }
};
void __init dove_setup_cpu_mbus(void)
{
int i;
int cs;
/*
* Disable, clear and configure windows.
*/
orion_config_wins(&addr_map_cfg, addr_map_info);
/*
* Setup MBUS dram target info.
*/
orion_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
for (i = 0, cs = 0; i < 2; i++) {
u32 map = readl(ddr_map_sc(i));
/*
* Chip select enabled?
*/
if (map & 1) {
struct mbus_dram_window *w;
w = &orion_mbus_dram_info.cs[cs++];
w->cs_index = i;
w->mbus_attr = 0; /* CS address decoding done inside */
/* the DDR controller, no need to */
/* provide attributes */
w->base = map & 0xff800000;
w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
}
}
orion_mbus_dram_info.num_cs = cs;
}
......@@ -64,7 +64,7 @@ static void __init dove_dt_init(void)
#ifdef CONFIG_CACHE_TAUROS2
tauros2_init(0);
#endif
dove_setup_cpu_mbus();
dove_setup_cpu_wins();
/* Setup root of clk tree */
dove_of_clk_init();
......
......@@ -224,6 +224,9 @@ void __init dove_i2c_init(void)
void __init dove_init_early(void)
{
orion_time_set_base(TIMER_VIRT_BASE);
mvebu_mbus_init("marvell,dove-mbus",
BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,
DOVE_MC_WINS_BASE, DOVE_MC_WINS_SZ);
}
static int __init dove_find_tclk(void)
......@@ -326,6 +329,40 @@ void __init dove_sdio1_init(void)
platform_device_register(&dove_sdio1);
}
void __init dove_setup_cpu_wins(void)
{
/*
* The PCIe windows will no longer be statically allocated
* here once Dove is migrated to the pci-mvebu driver.
*/
mvebu_mbus_add_window_remap_flags("pcie0.0",
DOVE_PCIE0_IO_PHYS_BASE,
DOVE_PCIE0_IO_SIZE,
DOVE_PCIE0_IO_BUS_BASE,
MVEBU_MBUS_PCI_IO);
mvebu_mbus_add_window_remap_flags("pcie1.0",
DOVE_PCIE1_IO_PHYS_BASE,
DOVE_PCIE1_IO_SIZE,
DOVE_PCIE1_IO_BUS_BASE,
MVEBU_MBUS_PCI_IO);
mvebu_mbus_add_window_remap_flags("pcie0.0",
DOVE_PCIE0_MEM_PHYS_BASE,
DOVE_PCIE0_MEM_SIZE,
MVEBU_MBUS_NO_REMAP,
MVEBU_MBUS_PCI_MEM);
mvebu_mbus_add_window_remap_flags("pcie1.0",
DOVE_PCIE1_MEM_PHYS_BASE,
DOVE_PCIE1_MEM_SIZE,
MVEBU_MBUS_NO_REMAP,
MVEBU_MBUS_PCI_MEM);
mvebu_mbus_add_window("cesa", DOVE_CESA_PHYS_BASE,
DOVE_CESA_SIZE);
mvebu_mbus_add_window("bootrom", DOVE_BOOTROM_PHYS_BASE,
DOVE_BOOTROM_SIZE);
mvebu_mbus_add_window("scratchpad", DOVE_SCRATCHPAD_PHYS_BASE,
DOVE_SCRATCHPAD_SIZE);
}
void __init dove_init(void)
{
pr_info("Dove 88AP510 SoC, TCLK = %d MHz.\n",
......@@ -334,7 +371,7 @@ void __init dove_init(void)
#ifdef CONFIG_CACHE_TAUROS2
tauros2_init(0);
#endif
dove_setup_cpu_mbus();
dove_setup_cpu_wins();
/* Setup root of clk tree */
dove_clk_init();
......
......@@ -23,7 +23,7 @@ void dove_map_io(void);
void dove_init(void);
void dove_init_early(void);
void dove_init_irq(void);
void dove_setup_cpu_mbus(void);
void dove_setup_cpu_wins(void);
void dove_ge00_init(struct mv643xx_eth_platform_data *eth_data);
void dove_sata_init(struct mv_sata_platform_data *sata_data);
#ifdef CONFIG_PCI
......
......@@ -77,6 +77,8 @@
/* North-South Bridge */
#define BRIDGE_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE + 0x20000)
#define BRIDGE_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x20000)
#define BRIDGE_WINS_BASE (BRIDGE_PHYS_BASE)
#define BRIDGE_WINS_SZ (0x80)
/* Cryptographic Engine */
#define DOVE_CRYPT_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE + 0x30000)
......@@ -168,6 +170,9 @@
#define DOVE_SSP_CLOCK_ENABLE (1 << 1)
#define DOVE_SSP_BPB_CLOCK_SRC_SSP (1 << 11)
/* Memory Controller */
#define DOVE_MC_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE + 0x00000)
#define DOVE_MC_WINS_BASE (DOVE_MC_PHYS_BASE + 0x100)
#define DOVE_MC_WINS_SZ (0x8)
#define DOVE_MC_VIRT_BASE (DOVE_NB_REGS_VIRT_BASE + 0x00000)
/* LCD Controller */
......
obj-y += common.o addr-map.o irq.o pcie.o mpp.o
obj-y += common.o irq.o pcie.o mpp.o
obj-$(CONFIG_MACH_DB88F6281_BP) += db88f6281-bp-setup.o
obj-$(CONFIG_MACH_RD88F6192_NAS) += rd88f6192-nas-setup.o
......
/*
* arch/arm/mach-kirkwood/addr-map.c
*
* Address map functions for Marvell Kirkwood SoCs
*
* 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/init.h>
#include <linux/mbus.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <plat/addr-map.h>
#include "common.h"
/*
* Generic Address Decode Windows bit settings
*/
#define TARGET_DEV_BUS 1
#define TARGET_SRAM 3
#define TARGET_PCIE 4
#define ATTR_DEV_SPI_ROM 0x1e
#define ATTR_DEV_BOOT 0x1d
#define ATTR_DEV_NAND 0x2f
#define ATTR_DEV_CS3 0x37
#define ATTR_DEV_CS2 0x3b
#define ATTR_DEV_CS1 0x3d
#define ATTR_DEV_CS0 0x3e
#define ATTR_PCIE_IO 0xe0
#define ATTR_PCIE_MEM 0xe8
#define ATTR_PCIE1_IO 0xd0
#define ATTR_PCIE1_MEM 0xd8
#define ATTR_SRAM 0x01
/*
* Description of the windows needed by the platform code
*/
static struct __initdata orion_addr_map_cfg addr_map_cfg = {
.num_wins = 8,
.remappable_wins = 4,
.bridge_virt_base = BRIDGE_VIRT_BASE,
};
static const struct __initdata orion_addr_map_info addr_map_info[] = {
/*
* Windows for PCIe IO+MEM space.
*/
{ 0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE,
TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE
},
{ 1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE
},
{ 2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE,
TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE
},
{ 3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE,
TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE
},
/*
* Window for NAND controller.
*/
{ 4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
TARGET_DEV_BUS, ATTR_DEV_NAND, -1
},
/*
* Window for SRAM.
*/
{ 5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE,
TARGET_SRAM, ATTR_SRAM, -1
},
/* End marker */
{ -1, 0, 0, 0, 0, 0 }
};
void __init kirkwood_setup_cpu_mbus(void)
{
/*
* Disable, clear and configure windows.
*/
orion_config_wins(&addr_map_cfg, addr_map_info);
/*
* Setup MBUS dram target info.
*/
orion_setup_cpu_mbus_target(&addr_map_cfg,
(void __iomem *) DDR_WINDOW_CPU_BASE);
}
......@@ -93,7 +93,7 @@ static void __init kirkwood_dt_init(void)
*/
writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
kirkwood_setup_cpu_mbus();
kirkwood_setup_wins();
kirkwood_l2_init();
......
......@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
#include <linux/platform_data/mmc-mvsdio.h>
#include "common.h"
static struct mv643xx_eth_platform_data guruplug_ge00_data = {
......@@ -24,10 +23,6 @@ static struct mv643xx_eth_platform_data guruplug_ge01_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(1),
};
static struct mvsdio_platform_data guruplug_mvsdio_data = {
/* unfortunately the CD signal has not been connected */
};
void __init guruplug_dt_init(void)
{
/*
......@@ -35,5 +30,4 @@ void __init guruplug_dt_init(void)
*/
kirkwood_ge00_init(&guruplug_ge00_data);
kirkwood_ge01_init(&guruplug_ge01_data);
kirkwood_sdio_init(&guruplug_mvsdio_data);
}
......@@ -20,10 +20,15 @@ static struct mv643xx_eth_platform_data iomega_ix2_200_ge00_data = {
.duplex = DUPLEX_FULL,
};
static struct mv643xx_eth_platform_data iomega_ix2_200_ge01_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(11),
};
void __init iomega_ix2_200_init(void)
{
/*
* Basic setup. Needs to be called early.
*/
kirkwood_ge01_init(&iomega_ix2_200_ge00_data);
kirkwood_ge00_init(&iomega_ix2_200_ge00_data);
kirkwood_ge01_init(&iomega_ix2_200_ge01_data);
}
......@@ -33,7 +33,6 @@
#include <linux/platform_data/usb-ehci-orion.h>
#include <plat/common.h>
#include <plat/time.h>
#include <plat/addr-map.h>
#include <linux/platform_data/dma-mv_xor.h>
#include "common.h"
......@@ -535,6 +534,9 @@ void __init kirkwood_init_early(void)
* the allocations won't fail.
*/
init_dma_coherent_pool_size(SZ_1M);
mvebu_mbus_init("marvell,kirkwood-mbus",
BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,
DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ);
}
int kirkwood_tclk;
......@@ -650,6 +652,38 @@ char * __init kirkwood_id(void)
}
}
void __init kirkwood_setup_wins(void)
{
/*
* The PCIe windows will no longer be statically allocated
* here once Kirkwood is migrated to the pci-mvebu driver.
*/
mvebu_mbus_add_window_remap_flags("pcie0.0",
KIRKWOOD_PCIE_IO_PHYS_BASE,
KIRKWOOD_PCIE_IO_SIZE,
KIRKWOOD_PCIE_IO_BUS_BASE,
MVEBU_MBUS_PCI_IO);
mvebu_mbus_add_window_remap_flags("pcie0.0",
KIRKWOOD_PCIE_MEM_PHYS_BASE,
KIRKWOOD_PCIE_MEM_SIZE,
MVEBU_MBUS_NO_REMAP,
MVEBU_MBUS_PCI_MEM);
mvebu_mbus_add_window_remap_flags("pcie1.0",
KIRKWOOD_PCIE1_IO_PHYS_BASE,
KIRKWOOD_PCIE1_IO_SIZE,
KIRKWOOD_PCIE1_IO_BUS_BASE,
MVEBU_MBUS_PCI_IO);
mvebu_mbus_add_window_remap_flags("pcie1.0",
KIRKWOOD_PCIE1_MEM_PHYS_BASE,
KIRKWOOD_PCIE1_MEM_SIZE,
MVEBU_MBUS_NO_REMAP,
MVEBU_MBUS_PCI_MEM);
mvebu_mbus_add_window("nand", KIRKWOOD_NAND_MEM_PHYS_BASE,
KIRKWOOD_NAND_MEM_SIZE);
mvebu_mbus_add_window("sram", KIRKWOOD_SRAM_PHYS_BASE,
KIRKWOOD_SRAM_SIZE);
}
void __init kirkwood_l2_init(void)
{
#ifdef CONFIG_CACHE_FEROCEON_L2
......@@ -675,7 +709,7 @@ void __init kirkwood_init(void)
*/
writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
kirkwood_setup_cpu_mbus();
kirkwood_setup_wins();
kirkwood_l2_init();
......
......@@ -30,7 +30,7 @@ void kirkwood_init(void);
void kirkwood_init_early(void);
void kirkwood_init_irq(void);
void kirkwood_setup_cpu_mbus(void);
void kirkwood_setup_wins(void);
void kirkwood_enable_pcie(void);
void kirkwood_pcie_id(u32 *dev, u32 *rev);
......
......@@ -53,6 +53,8 @@ static struct mv_sata_platform_data guruplug_sata_data = {
static struct mvsdio_platform_data guruplug_mvsdio_data = {
/* unfortunately the CD signal has not been connected */
.gpio_card_detect = -1,
.gpio_write_protect = -1,
};
static struct gpio_led guruplug_led_pins[] = {
......
......@@ -61,7 +61,8 @@
*/
#define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x00000)
#define DDR_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x00000)
#define DDR_WINDOW_CPU_BASE (DDR_VIRT_BASE + 0x1500)
#define DDR_WINDOW_CPU_BASE (DDR_PHYS_BASE + 0x1500)
#define DDR_WINDOW_CPU_SZ (0x20)
#define DDR_OPERATION_BASE (DDR_PHYS_BASE + 0x1418)
#define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x10000)
......@@ -80,6 +81,8 @@
#define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x20000)
#define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x20000)
#define BRIDGE_WINS_BASE (BRIDGE_PHYS_BASE)
#define BRIDGE_WINS_SZ (0x80)
#define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x30000)
......
......@@ -55,6 +55,7 @@ static struct mv_sata_platform_data openrd_sata_data = {
static struct mvsdio_platform_data openrd_mvsdio_data = {
.gpio_card_detect = 29, /* MPP29 used as SD card detect */
.gpio_write_protect = -1,
};
static unsigned int openrd_mpp_config[] __initdata = {
......
......@@ -17,7 +17,6 @@
#include <asm/mach/pci.h>
#include <plat/pcie.h>
#include <mach/bridge-regs.h>
#include <plat/addr-map.h>
#include "common.h"
static void kirkwood_enable_pcie_clk(const char *port)
......
......@@ -69,6 +69,7 @@ static struct mv_sata_platform_data rd88f6281_sata_data = {
static struct mvsdio_platform_data rd88f6281_mvsdio_data = {
.gpio_card_detect = 28,
.gpio_write_protect = -1,
};
static unsigned int rd88f6281_mpp_config[] __initdata = {
......
obj-y += common.o addr-map.o mpp.o irq.o pcie.o
obj-y += common.o mpp.o irq.o pcie.o
obj-$(CONFIG_MACH_DB78X00_BP) += db78x00-bp-setup.o
obj-$(CONFIG_MACH_RD78X00_MASA) += rd78x00-masa-setup.o
obj-$(CONFIG_MACH_TERASTATION_WXL) += buffalo-wxl-setup.o
/*
* arch/arm/mach-mv78xx0/addr-map.c
*
* Address map functions for Marvell MV78xx0 SoCs
*
* 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/init.h>
#include <linux/mbus.h>
#include <linux/io.h>
#include <plat/addr-map.h>
#include <mach/mv78xx0.h>
#include "common.h"
/*
* Generic Address Decode Windows bit settings
*/
#define TARGET_DEV_BUS 1
#define TARGET_PCIE0 4
#define TARGET_PCIE1 8
#define TARGET_PCIE(i) ((i) ? TARGET_PCIE1 : TARGET_PCIE0)
#define ATTR_DEV_SPI_ROM 0x1f
#define ATTR_DEV_BOOT 0x2f
#define ATTR_DEV_CS3 0x37
#define ATTR_DEV_CS2 0x3b
#define ATTR_DEV_CS1 0x3d
#define ATTR_DEV_CS0 0x3e
#define ATTR_PCIE_IO(l) (0xf0 & ~(0x10 << (l)))
#define ATTR_PCIE_MEM(l) (0xf8 & ~(0x10 << (l)))
/*
* CPU Address Decode Windows registers
*/
#define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4))
#define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4))
static void __init __iomem *win_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
{
/*
* Find the control register base address for this window.
*
* BRIDGE_VIRT_BASE points to the right (CPU0's or CPU1's)
* MBUS bridge depending on which CPU core we're running on,
* so we don't need to take that into account here.
*/
return (win < 8) ? WIN0_OFF(win) : WIN8_OFF(win);
}
/*
* Description of the windows needed by the platform code
*/
static struct orion_addr_map_cfg addr_map_cfg __initdata = {
.num_wins = 14,
.remappable_wins = 8,
.win_cfg_base = win_cfg_base,
};
void __init mv78xx0_setup_cpu_mbus(void)
{
/*
* Disable, clear and configure windows.
*/
orion_config_wins(&addr_map_cfg, NULL);
/*
* Setup MBUS dram target info.
*/
if (mv78xx0_core_index() == 0)
orion_setup_cpu_mbus_target(&addr_map_cfg,
(void __iomem *) DDR_WINDOW_CPU0_BASE);
else
orion_setup_cpu_mbus_target(&addr_map_cfg,
(void __iomem *) DDR_WINDOW_CPU1_BASE);
}
void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
int maj, int min)
{
orion_setup_cpu_win(&addr_map_cfg, window, base, size,
TARGET_PCIE(maj), ATTR_PCIE_IO(min), 0);
}
void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,
int maj, int min)
{
orion_setup_cpu_win(&addr_map_cfg, window, base, size,
TARGET_PCIE(maj), ATTR_PCIE_MEM(min), -1);
}
......@@ -334,6 +334,14 @@ void __init mv78xx0_uart3_init(void)
void __init mv78xx0_init_early(void)
{
orion_time_set_base(TIMER_VIRT_BASE);
if (mv78xx0_core_index() == 0)
mvebu_mbus_init("marvell,mv78xx0-mbus",
BRIDGE_WINS_CPU0_BASE, BRIDGE_WINS_SZ,
DDR_WINDOW_CPU0_BASE, DDR_WINDOW_CPU_SZ);
else
mvebu_mbus_init("marvell,mv78xx0-mbus",
BRIDGE_WINS_CPU1_BASE, BRIDGE_WINS_SZ,
DDR_WINDOW_CPU1_BASE, DDR_WINDOW_CPU_SZ);
}
void __init_refok mv78xx0_timer_init(void)
......@@ -397,8 +405,6 @@ void __init mv78xx0_init(void)
printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
printk("TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000);
mv78xx0_setup_cpu_mbus();
#ifdef CONFIG_CACHE_FEROCEON_L2
feroceon_l2_init(is_l2_writethrough());
#endif
......
......@@ -60,13 +60,18 @@
*/
#define BRIDGE_VIRT_BASE (MV78XX0_CORE_REGS_VIRT_BASE)
#define BRIDGE_PHYS_BASE (MV78XX0_CORE_REGS_PHYS_BASE)
#define BRIDGE_WINS_CPU0_BASE (MV78XX0_CORE0_REGS_PHYS_BASE)
#define BRIDGE_WINS_CPU1_BASE (MV78XX0_CORE1_REGS_PHYS_BASE)
#define BRIDGE_WINS_SZ (0xA000)
/*
* Register Map
*/
#define DDR_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x00000)
#define DDR_WINDOW_CPU0_BASE (DDR_VIRT_BASE + 0x1500)
#define DDR_WINDOW_CPU1_BASE (DDR_VIRT_BASE + 0x1570)
#define DDR_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x00000)
#define DDR_WINDOW_CPU0_BASE (DDR_PHYS_BASE + 0x1500)
#define DDR_WINDOW_CPU1_BASE (DDR_PHYS_BASE + 0x1570)
#define DDR_WINDOW_CPU_SZ (0x20)
#define DEV_BUS_PHYS_BASE (MV78XX0_REGS_PHYS_BASE + 0x10000)
#define DEV_BUS_VIRT_BASE (MV78XX0_REGS_VIRT_BASE + 0x10000)
......
......@@ -10,11 +10,11 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/mbus.h>
#include <video/vga.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
#include <plat/pcie.h>
#include <plat/addr-map.h>
#include <mach/mv78xx0.h>
#include "common.h"
......@@ -54,7 +54,6 @@ static void __init mv78xx0_pcie_preinit(void)
int i;
u32 size_each;
u32 start;
int win = 0;
pcie_io_space.name = "PCIe I/O Space";
pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0);
......@@ -72,6 +71,7 @@ static void __init mv78xx0_pcie_preinit(void)
start = MV78XX0_PCIE_MEM_PHYS_BASE;
for (i = 0; i < num_pcie_ports; i++) {
struct pcie_port *pp = pcie_port + i;
char winname[MVEBU_MBUS_MAX_WINNAME_SZ];
snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
"PCIe %d.%d MEM", pp->maj, pp->min);
......@@ -85,12 +85,17 @@ static void __init mv78xx0_pcie_preinit(void)
if (request_resource(&iomem_resource, &pp->res))
panic("can't allocate PCIe MEM sub-space");
mv78xx0_setup_pcie_mem_win(win + i + 8, pp->res.start,
resource_size(&pp->res),
snprintf(winname, sizeof(winname), "pcie%d.%d",
pp->maj, pp->min);
mv78xx0_setup_pcie_io_win(win + i, i * SZ_64K, SZ_64K,
pp->maj, pp->min);
mvebu_mbus_add_window_remap_flags(winname,
pp->res.start,
resource_size(&pp->res),
MVEBU_MBUS_NO_REMAP,
MVEBU_MBUS_PCI_MEM);
mvebu_mbus_add_window_remap_flags(winname,
i * SZ_64K, SZ_64K,
0, MVEBU_MBUS_PCI_IO);
}
}
......
......@@ -13,6 +13,8 @@ config ARCH_MVEBU
select MVEBU_CLK_CORE
select MVEBU_CLK_CPU
select MVEBU_CLK_GATING
select MVEBU_MBUS
select ZONE_DMA if ARM_LPAE
if ARCH_MVEBU
......
......@@ -5,6 +5,6 @@ AFLAGS_coherency_ll.o := -Wa,-march=armv7-a
obj-y += system-controller.o
obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o
obj-$(CONFIG_ARCH_MVEBU) += addr-map.o coherency.o coherency_ll.o pmsu.o irq-armada-370-xp.o
obj-$(CONFIG_ARCH_MVEBU) += coherency.o coherency_ll.o pmsu.o irq-armada-370-xp.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
/*
* Address map functions for Marvell 370 / XP SoCs
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mbus.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <plat/addr-map.h>
/*
* Generic Address Decode Windows bit settings
*/
#define ARMADA_XP_TARGET_DEV_BUS 1
#define ARMADA_XP_ATTR_DEV_BOOTROM 0x1D
#define ARMADA_XP_TARGET_ETH1 3
#define ARMADA_XP_TARGET_PCIE_0_2 4
#define ARMADA_XP_TARGET_ETH0 7
#define ARMADA_XP_TARGET_PCIE_1_3 8
#define ARMADA_370_TARGET_DEV_BUS 1
#define ARMADA_370_ATTR_DEV_BOOTROM 0x1D
#define ARMADA_370_TARGET_PCIE_0 4
#define ARMADA_370_TARGET_PCIE_1 8
#define ARMADA_WINDOW_8_PLUS_OFFSET 0x90
#define ARMADA_SDRAM_ADDR_DECODING_OFFSET 0x180
static const struct __initdata orion_addr_map_info
armada_xp_addr_map_info[] = {
/*
* Window for the BootROM, needed for SMP on Armada XP
*/
{ 0, 0xfff00000, SZ_1M, ARMADA_XP_TARGET_DEV_BUS,
ARMADA_XP_ATTR_DEV_BOOTROM, -1 },
/* End marker */
{ -1, 0, 0, 0, 0, 0 },
};
static const struct __initdata orion_addr_map_info
armada_370_addr_map_info[] = {
/* End marker */
{ -1, 0, 0, 0, 0, 0 },
};
static struct of_device_id of_addr_decoding_controller_table[] = {
{ .compatible = "marvell,armada-addr-decoding-controller" },
{ /* end of list */ },
};
static void __iomem *
armada_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
{
unsigned int offset;
/* The register layout is a bit annoying and the below code
* tries to cope with it.
* - At offset 0x0, there are the registers for the first 8
* windows, with 4 registers of 32 bits per window (ctrl,
* base, remap low, remap high)
* - Then at offset 0x80, there is a hole of 0x10 bytes for
* the internal registers base address and internal units
* sync barrier register.
* - Then at offset 0x90, there the registers for 12
* windows, with only 2 registers of 32 bits per window
* (ctrl, base).
*/
if (win < 8)
offset = (win << 4);
else
offset = ARMADA_WINDOW_8_PLUS_OFFSET + ((win - 8) << 3);
return cfg->bridge_virt_base + offset;
}
static struct __initdata orion_addr_map_cfg addr_map_cfg = {
.num_wins = 20,
.remappable_wins = 8,
.win_cfg_base = armada_cfg_base,
};
static int __init armada_setup_cpu_mbus(void)
{
struct device_node *np;
void __iomem *mbus_unit_addr_decoding_base;
void __iomem *sdram_addr_decoding_base;
np = of_find_matching_node(NULL, of_addr_decoding_controller_table);
if (!np)
return -ENODEV;
mbus_unit_addr_decoding_base = of_iomap(np, 0);
BUG_ON(!mbus_unit_addr_decoding_base);
sdram_addr_decoding_base =
mbus_unit_addr_decoding_base +
ARMADA_SDRAM_ADDR_DECODING_OFFSET;
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.
*/
if (of_machine_is_compatible("marvell,armadaxp"))
orion_config_wins(&addr_map_cfg, armada_xp_addr_map_info);
else if (of_machine_is_compatible("marvell,armada370"))
orion_config_wins(&addr_map_cfg, armada_370_addr_map_info);
else {
pr_err("Unsupported SoC\n");
return -EINVAL;
}
/*
* Setup MBUS dram target info.
*/
orion_setup_cpu_mbus_target(&addr_map_cfg,
sdram_addr_decoding_base);
return 0;
}
/* Using a early_initcall is needed so that this initialization gets
* done before the SMP initialization, which requires the BootROM to
* be remapped. */
early_initcall(armada_setup_cpu_mbus);
......@@ -19,6 +19,7 @@
#include <linux/time-armada-370-xp.h>
#include <linux/clk/mvebu.h>
#include <linux/dma-mapping.h>
#include <linux/mbus.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
......@@ -48,12 +49,29 @@ void __init armada_370_xp_timer_and_clk_init(void)
void __init armada_370_xp_init_early(void)
{
char *mbus_soc_name;
/*
* 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);
/*
* This initialization will be replaced by a DT-based
* initialization once the mvebu-mbus driver gains DT support.
*/
if (of_machine_is_compatible("marvell,armada370"))
mbus_soc_name = "marvell,armada370-mbus";
else
mbus_soc_name = "marvell,armadaxp-mbus";
mvebu_mbus_init(mbus_soc_name,
ARMADA_370_XP_MBUS_WINS_BASE,
ARMADA_370_XP_MBUS_WINS_SIZE,
ARMADA_370_XP_SDRAM_WINS_BASE,
ARMADA_370_XP_SDRAM_WINS_SIZE);
}
static void __init armada_370_xp_dt_init(void)
......
......@@ -16,9 +16,15 @@
#define __MACH_ARMADA_370_XP_H
#define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000
#define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfeb00000)
#define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfec00000)
#define ARMADA_370_XP_REGS_SIZE SZ_1M
/* These defines can go away once mvebu-mbus has a DT binding */
#define ARMADA_370_XP_MBUS_WINS_BASE (ARMADA_370_XP_REGS_PHYS_BASE + 0x20000)
#define ARMADA_370_XP_MBUS_WINS_SIZE 0x100
#define ARMADA_370_XP_SDRAM_WINS_BASE (ARMADA_370_XP_REGS_PHYS_BASE + 0x20180)
#define ARMADA_370_XP_SDRAM_WINS_SIZE 0x20
#ifdef CONFIG_SMP
#include <linux/cpumask.h>
......
......@@ -44,6 +44,8 @@
#define ARMADA_370_XP_MAX_PER_CPU_IRQS (28)
#define ARMADA_370_XP_TIMER0_PER_CPU_IRQ (5)
#define ACTIVE_DOORBELLS (8)
static DEFINE_RAW_SPINLOCK(irq_controller_lock);
......@@ -59,36 +61,26 @@ static struct irq_domain *armada_370_xp_mpic_domain;
*/
static void armada_370_xp_irq_mask(struct irq_data *d)
{
#ifdef CONFIG_SMP
irq_hw_number_t hwirq = irqd_to_hwirq(d);
if (hwirq > ARMADA_370_XP_MAX_PER_CPU_IRQS)
if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ)
writel(hwirq, main_int_base +
ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS);
else
writel(hwirq, per_cpu_int_base +
ARMADA_370_XP_INT_SET_MASK_OFFS);
#else
writel(irqd_to_hwirq(d),
per_cpu_int_base + ARMADA_370_XP_INT_SET_MASK_OFFS);
#endif
}
static void armada_370_xp_irq_unmask(struct irq_data *d)
{
#ifdef CONFIG_SMP
irq_hw_number_t hwirq = irqd_to_hwirq(d);
if (hwirq > ARMADA_370_XP_MAX_PER_CPU_IRQS)
if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ)
writel(hwirq, main_int_base +
ARMADA_370_XP_INT_SET_ENABLE_OFFS);
else
writel(hwirq, per_cpu_int_base +
ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
#else
writel(irqd_to_hwirq(d),
per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
#endif
}
#ifdef CONFIG_SMP
......@@ -144,10 +136,14 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
unsigned int virq, irq_hw_number_t hw)
{
armada_370_xp_irq_mask(irq_get_irq_data(virq));
if (hw != ARMADA_370_XP_TIMER0_PER_CPU_IRQ)
writel(hw, per_cpu_int_base +
ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
else
writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS);
irq_set_status_flags(virq, IRQ_LEVEL);
if (hw < ARMADA_370_XP_MAX_PER_CPU_IRQS) {
if (hw == ARMADA_370_XP_TIMER0_PER_CPU_IRQ) {
irq_set_percpu_devid(virq);
irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip,
handle_percpu_devid_irq);
......
......@@ -21,6 +21,7 @@
#include <linux/smp.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/mbus.h>
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
#include "common.h"
......@@ -109,6 +110,7 @@ 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);
mvebu_mbus_add_window("bootrom", 0xfff00000, SZ_1M);
}
struct smp_operations armada_xp_smp_ops __initdata = {
......
obj-y += common.o addr-map.o pci.o irq.o mpp.o
obj-y += common.o pci.o irq.o mpp.o
obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o
obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o
obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o
......
/*
* arch/arm/mach-orion5x/addr-map.c
*
* Address map functions for Marvell Orion 5x SoCs
*
* Maintainer: Tzachi Perelstein <tzachi@marvell.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/init.h>
#include <linux/mbus.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <plat/addr-map.h>
#include "common.h"
/*
* The Orion has fully programmable address map. There's a separate address
* map for each of the device _master_ interfaces, e.g. CPU, PCI, PCIe, USB,
* Gigabit Ethernet, DMA/XOR engines, etc. Each interface has its own
* address decode windows that allow it to access any of the Orion resources.
*
* CPU address decoding --
* Linux assumes that it is the boot loader that already setup the access to
* DDR and internal registers.
* Setup access to PCI and PCIe IO/MEM space is issued by this file.
* Setup access to various devices located on the device bus interface (e.g.
* flashes, RTC, etc) should be issued by machine-setup.c according to
* specific board population (by using orion5x_setup_*_win()).
*
* Non-CPU Masters address decoding --
* Unlike the CPU, we setup the access from Orion's master interfaces to DDR
* banks only (the typical use case).
* Setup access for each master to DDR is issued by platform device setup.
*/
/*
* Generic Address Decode Windows bit settings
*/
#define TARGET_DEV_BUS 1
#define TARGET_PCI 3
#define TARGET_PCIE 4
#define TARGET_SRAM 9
#define ATTR_PCIE_MEM 0x59
#define ATTR_PCIE_IO 0x51
#define ATTR_PCIE_WA 0x79
#define ATTR_PCI_MEM 0x59
#define ATTR_PCI_IO 0x51
#define ATTR_DEV_CS0 0x1e
#define ATTR_DEV_CS1 0x1d
#define ATTR_DEV_CS2 0x1b
#define ATTR_DEV_BOOT 0xf
#define ATTR_SRAM 0x0
static int __initdata win_alloc_count;
static int __init cpu_win_can_remap(const struct orion_addr_map_cfg *cfg,
const int win)
{
u32 dev, rev;
orion5x_pcie_id(&dev, &rev);
if ((dev == MV88F5281_DEV_ID && win < 4)
|| (dev == MV88F5182_DEV_ID && win < 2)
|| (dev == MV88F5181_DEV_ID && win < 2)
|| (dev == MV88F6183_DEV_ID && win < 4))
return 1;
return 0;
}
/*
* Description of the windows needed by the platform code
*/
static struct orion_addr_map_cfg addr_map_cfg __initdata = {
.num_wins = 8,
.cpu_win_can_remap = cpu_win_can_remap,
.bridge_virt_base = ORION5X_BRIDGE_VIRT_BASE,
};
static const struct __initdata orion_addr_map_info addr_map_info[] = {
/*
* Setup windows for PCI+PCIe IO+MEM space.
*/
{ 0, ORION5X_PCIE_IO_PHYS_BASE, ORION5X_PCIE_IO_SIZE,
TARGET_PCIE, ATTR_PCIE_IO, ORION5X_PCIE_IO_BUS_BASE
},
{ 1, ORION5X_PCI_IO_PHYS_BASE, ORION5X_PCI_IO_SIZE,
TARGET_PCI, ATTR_PCI_IO, ORION5X_PCI_IO_BUS_BASE
},
{ 2, ORION5X_PCIE_MEM_PHYS_BASE, ORION5X_PCIE_MEM_SIZE,
TARGET_PCIE, ATTR_PCIE_MEM, -1
},
{ 3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE,
TARGET_PCI, ATTR_PCI_MEM, -1
},
/* End marker */
{ -1, 0, 0, 0, 0, 0 }
};
void __init orion5x_setup_cpu_mbus_bridge(void)
{
/*
* Disable, clear and configure windows.
*/
orion_config_wins(&addr_map_cfg, addr_map_info);
win_alloc_count = 4;
/*
* Setup MBUS dram target info.
*/
orion_setup_cpu_mbus_target(&addr_map_cfg,
(void __iomem *) ORION5X_DDR_WINDOW_CPU_BASE);
}
void __init orion5x_setup_dev_boot_win(u32 base, u32 size)
{
orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
TARGET_DEV_BUS, ATTR_DEV_BOOT, -1);
}
void __init orion5x_setup_dev0_win(u32 base, u32 size)
{
orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
TARGET_DEV_BUS, ATTR_DEV_CS0, -1);
}
void __init orion5x_setup_dev1_win(u32 base, u32 size)
{
orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
TARGET_DEV_BUS, ATTR_DEV_CS1, -1);
}
void __init orion5x_setup_dev2_win(u32 base, u32 size)
{
orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
TARGET_DEV_BUS, ATTR_DEV_CS2, -1);
}
void __init orion5x_setup_pcie_wa_win(u32 base, u32 size)
{
orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
TARGET_PCIE, ATTR_PCIE_WA, -1);
}
void __init orion5x_setup_sram_win(void)
{
orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++,
ORION5X_SRAM_PHYS_BASE, ORION5X_SRAM_SIZE,
TARGET_SRAM, ATTR_SRAM, -1);
}
......@@ -41,7 +41,7 @@ static void __init orion5x_dt_init(void)
/*
* Setup Orion address map
*/
orion5x_setup_cpu_mbus_bridge();
orion5x_setup_wins();
/* Setup root of clk tree */
clk_init();
......
......@@ -34,7 +34,6 @@
#include <linux/platform_data/usb-ehci-orion.h>
#include <plat/time.h>
#include <plat/common.h>
#include <plat/addr-map.h>
#include "common.h"
/*****************************************************************************
......@@ -174,7 +173,8 @@ void __init orion5x_xor_init(void)
****************************************************************************/
static void __init orion5x_crypto_init(void)
{
orion5x_setup_sram_win();
mvebu_mbus_add_window("sram", ORION5X_SRAM_PHYS_BASE,
ORION5X_SRAM_SIZE);
orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE,
SZ_8K, IRQ_ORION5X_CESA);
}
......@@ -193,6 +193,9 @@ void __init orion5x_wdt_init(void)
****************************************************************************/
void __init orion5x_init_early(void)
{
u32 rev, dev;
const char *mbus_soc_name;
orion_time_set_base(TIMER_VIRT_BASE);
/*
......@@ -201,6 +204,46 @@ void __init orion5x_init_early(void)
* the allocations won't fail.
*/
init_dma_coherent_pool_size(SZ_1M);
/* Initialize the MBUS driver */
orion5x_pcie_id(&dev, &rev);
if (dev == MV88F5281_DEV_ID)
mbus_soc_name = "marvell,orion5x-88f5281-mbus";
else if (dev == MV88F5182_DEV_ID)
mbus_soc_name = "marvell,orion5x-88f5182-mbus";
else if (dev == MV88F5181_DEV_ID)
mbus_soc_name = "marvell,orion5x-88f5181-mbus";
else if (dev == MV88F6183_DEV_ID)
mbus_soc_name = "marvell,orion5x-88f6183-mbus";
else
mbus_soc_name = NULL;
mvebu_mbus_init(mbus_soc_name, ORION5X_BRIDGE_WINS_BASE,
ORION5X_BRIDGE_WINS_SZ,
ORION5X_DDR_WINS_BASE, ORION5X_DDR_WINS_SZ);
}
void orion5x_setup_wins(void)
{
/*
* The PCIe windows will no longer be statically allocated
* here once Orion5x is migrated to the pci-mvebu driver.
*/
mvebu_mbus_add_window_remap_flags("pcie0.0", ORION5X_PCIE_IO_PHYS_BASE,
ORION5X_PCIE_IO_SIZE,
ORION5X_PCIE_IO_BUS_BASE,
MVEBU_MBUS_PCI_IO);
mvebu_mbus_add_window_remap_flags("pcie0.0", ORION5X_PCIE_MEM_PHYS_BASE,
ORION5X_PCIE_MEM_SIZE,
MVEBU_MBUS_NO_REMAP,
MVEBU_MBUS_PCI_MEM);
mvebu_mbus_add_window_remap_flags("pci0.0", ORION5X_PCI_IO_PHYS_BASE,
ORION5X_PCI_IO_SIZE,
ORION5X_PCI_IO_BUS_BASE,
MVEBU_MBUS_PCI_IO);
mvebu_mbus_add_window_remap_flags("pci0.0", ORION5X_PCI_MEM_PHYS_BASE,
ORION5X_PCI_MEM_SIZE,
MVEBU_MBUS_NO_REMAP,
MVEBU_MBUS_PCI_MEM);
}
int orion5x_tclk;
......@@ -282,7 +325,7 @@ void __init orion5x_init(void)
/*
* Setup Orion address map
*/
orion5x_setup_cpu_mbus_bridge();
orion5x_setup_wins();
/* Setup root of clk tree */
clk_init();
......
......@@ -17,18 +17,7 @@ void clk_init(void);
extern int orion5x_tclk;
extern void orion5x_timer_init(void);
/*
* Enumerations and functions for Orion windows mapping. Used by Orion core
* functions to map its interfaces and by the machine-setup to map its on-
* board devices. Details in /mach-orion/addr-map.c
*/
void orion5x_setup_cpu_mbus_bridge(void);
void orion5x_setup_dev_boot_win(u32 base, u32 size);
void orion5x_setup_dev0_win(u32 base, u32 size);
void orion5x_setup_dev1_win(u32 base, u32 size);
void orion5x_setup_dev2_win(u32 base, u32 size);
void orion5x_setup_pcie_wa_win(u32 base, u32 size);
void orion5x_setup_sram_win(void);
void orion5x_setup_wins(void);
void orion5x_ehci0_init(void);
void orion5x_ehci1_init(void);
......
......@@ -317,7 +317,7 @@ static void __init d2net_init(void)
d2net_sata_power_init();
orion5x_sata_init(&d2net_sata_data);
orion5x_setup_dev_boot_win(D2NET_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", D2NET_NOR_BOOT_BASE,
D2NET_NOR_BOOT_SIZE);
platform_device_register(&d2net_nor_flash);
......
......@@ -340,16 +340,19 @@ static void __init db88f5281_init(void)
orion5x_uart0_init();
orion5x_uart1_init();
orion5x_setup_dev_boot_win(DB88F5281_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", DB88F5281_NOR_BOOT_BASE,
DB88F5281_NOR_BOOT_SIZE);
platform_device_register(&db88f5281_boot_flash);
orion5x_setup_dev0_win(DB88F5281_7SEG_BASE, DB88F5281_7SEG_SIZE);
mvebu_mbus_add_window("devbus-cs0", DB88F5281_7SEG_BASE,
DB88F5281_7SEG_SIZE);
orion5x_setup_dev1_win(DB88F5281_NOR_BASE, DB88F5281_NOR_SIZE);
mvebu_mbus_add_window("devbus-cs1", DB88F5281_NOR_BASE,
DB88F5281_NOR_SIZE);
platform_device_register(&db88f5281_nor_flash);
orion5x_setup_dev2_win(DB88F5281_NAND_BASE, DB88F5281_NAND_SIZE);
mvebu_mbus_add_window("devbus-cs2", DB88F5281_NAND_BASE,
DB88F5281_NAND_SIZE);
platform_device_register(&db88f5281_nand_flash);
i2c_register_board_info(0, &db88f5281_i2c_rtc, 1);
......
......@@ -611,7 +611,8 @@ static void __init dns323_init(void)
/* setup flash mapping
* CS3 holds a 8 MB Spansion S29GL064M90TFIR4
*/
orion5x_setup_dev_boot_win(DNS323_NOR_BOOT_BASE, DNS323_NOR_BOOT_SIZE);
mvebu_mbus_add_window("devbus-boot", DNS323_NOR_BOOT_BASE,
DNS323_NOR_BOOT_SIZE);
platform_device_register(&dns323_nor_flash);
/* Sort out LEDs, Buttons and i2c devices */
......
......@@ -154,7 +154,7 @@ void __init edmini_v2_init(void)
orion5x_ehci0_init();
orion5x_eth_init(&edmini_v2_eth_data);
orion5x_setup_dev_boot_win(EDMINI_V2_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", EDMINI_V2_NOR_BOOT_BASE,
EDMINI_V2_NOR_BOOT_SIZE);
platform_device_register(&edmini_v2_nor_flash);
......
......@@ -66,8 +66,10 @@
* Orion Registers Map
******************************************************************************/
#define ORION5X_DDR_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x00000)
#define ORION5X_DDR_WINS_BASE (ORION5X_DDR_PHYS_BASE + 0x1500)
#define ORION5X_DDR_WINS_SZ (0x10)
#define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x00000)
#define ORION5X_DDR_WINDOW_CPU_BASE (ORION5X_DDR_VIRT_BASE + 0x1500)
#define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x10000)
#define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x10000)
#define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE + (x))
......@@ -81,6 +83,8 @@
#define ORION5X_BRIDGE_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x20000)
#define ORION5X_BRIDGE_PHYS_BASE (ORION5X_REGS_PHYS_BASE + 0x20000)
#define ORION5X_BRIDGE_WINS_BASE (ORION5X_BRIDGE_PHYS_BASE)
#define ORION5X_BRIDGE_WINS_SZ (0x80)
#define ORION5X_PCI_VIRT_BASE (ORION5X_REGS_VIRT_BASE + 0x30000)
......
......@@ -359,12 +359,12 @@ static void __init kurobox_pro_init(void)
orion5x_uart1_init();
orion5x_xor_init();
orion5x_setup_dev_boot_win(KUROBOX_PRO_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", KUROBOX_PRO_NOR_BOOT_BASE,
KUROBOX_PRO_NOR_BOOT_SIZE);
platform_device_register(&kurobox_pro_nor_flash);
if (machine_is_kurobox_pro()) {
orion5x_setup_dev0_win(KUROBOX_PRO_NAND_BASE,
mvebu_mbus_add_window("devbus-cs0", KUROBOX_PRO_NAND_BASE,
KUROBOX_PRO_NAND_SIZE);
platform_device_register(&kurobox_pro_nand_flash);
}
......
......@@ -294,7 +294,7 @@ static void __init lschl_init(void)
orion5x_uart0_init();
orion5x_xor_init();
orion5x_setup_dev_boot_win(LSCHL_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", LSCHL_NOR_BOOT_BASE,
LSCHL_NOR_BOOT_SIZE);
platform_device_register(&lschl_nor_flash);
......
......@@ -243,7 +243,7 @@ static void __init ls_hgl_init(void)
orion5x_uart0_init();
orion5x_xor_init();
orion5x_setup_dev_boot_win(LS_HGL_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", LS_HGL_NOR_BOOT_BASE,
LS_HGL_NOR_BOOT_SIZE);
platform_device_register(&ls_hgl_nor_flash);
......
......@@ -244,7 +244,7 @@ static void __init lsmini_init(void)
orion5x_uart0_init();
orion5x_xor_init();
orion5x_setup_dev_boot_win(LSMINI_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", LSMINI_NOR_BOOT_BASE,
LSMINI_NOR_BOOT_SIZE);
platform_device_register(&lsmini_nor_flash);
......
......@@ -241,7 +241,8 @@ static void __init mss2_init(void)
orion5x_uart0_init();
orion5x_xor_init();
orion5x_setup_dev_boot_win(MSS2_NOR_BOOT_BASE, MSS2_NOR_BOOT_SIZE);
mvebu_mbus_add_window("devbus-boot", MSS2_NOR_BOOT_BASE,
MSS2_NOR_BOOT_SIZE);
platform_device_register(&mss2_nor_flash);
platform_device_register(&mss2_button_device);
......
......@@ -204,7 +204,8 @@ static void __init mv2120_init(void)
orion5x_uart0_init();
orion5x_xor_init();
orion5x_setup_dev_boot_win(MV2120_NOR_BOOT_BASE, MV2120_NOR_BOOT_SIZE);
mvebu_mbus_add_window("devbus-boot", MV2120_NOR_BOOT_BASE,
MV2120_NOR_BOOT_SIZE);
platform_device_register(&mv2120_nor_flash);
platform_device_register(&mv2120_button_device);
......
......@@ -397,7 +397,7 @@ static void __init net2big_init(void)
net2big_sata_power_init();
orion5x_sata_init(&net2big_sata_data);
orion5x_setup_dev_boot_win(NET2BIG_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", NET2BIG_NOR_BOOT_BASE,
NET2BIG_NOR_BOOT_SIZE);
platform_device_register(&net2big_nor_flash);
......
......@@ -157,8 +157,11 @@ static int __init pcie_setup(struct pci_sys_data *sys)
if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) {
printk(KERN_NOTICE "Applying Orion-1/Orion-NAS PCIe config "
"read transaction workaround\n");
orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE,
ORION5X_PCIE_WA_SIZE);
mvebu_mbus_add_window_remap_flags("pcie0.0",
ORION5X_PCIE_WA_PHYS_BASE,
ORION5X_PCIE_WA_SIZE,
MVEBU_MBUS_NO_REMAP,
MVEBU_MBUS_PCI_WA);
pcie_ops.read = pcie_rd_conf_wa;
}
......@@ -402,8 +405,9 @@ static void __init orion5x_pci_master_slave_enable(void)
orion5x_pci_hw_wr_conf(bus_nr, 0, func, reg, 4, val | 0x7);
}
static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram)
static void __init orion5x_setup_pci_wins(void)
{
const struct mbus_dram_target_info *dram = mv_mbus_dram_info();
u32 win_enable;
int bus;
int i;
......@@ -420,7 +424,7 @@ static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram)
bus = orion5x_pci_local_bus_nr();
for (i = 0; i < dram->num_cs; i++) {
struct mbus_dram_window *cs = dram->cs + i;
const struct mbus_dram_window *cs = dram->cs + i;
u32 func = PCI_CONF_FUNC_BAR_CS(cs->cs_index);
u32 reg;
u32 val;
......@@ -467,7 +471,7 @@ static int __init pci_setup(struct pci_sys_data *sys)
/*
* Point PCI unit MBUS decode windows to DRAM space.
*/
orion5x_setup_pci_wins(&orion_mbus_dram_info);
orion5x_setup_pci_wins();
/*
* Master + Slave enable
......
......@@ -123,7 +123,7 @@ static void __init rd88f5181l_fxo_init(void)
orion5x_eth_switch_init(&rd88f5181l_fxo_switch_plat_data, NO_IRQ);
orion5x_uart0_init();
orion5x_setup_dev_boot_win(RD88F5181L_FXO_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", RD88F5181L_FXO_NOR_BOOT_BASE,
RD88F5181L_FXO_NOR_BOOT_SIZE);
platform_device_register(&rd88f5181l_fxo_nor_boot_flash);
}
......
......@@ -130,7 +130,7 @@ static void __init rd88f5181l_ge_init(void)
orion5x_i2c_init();
orion5x_uart0_init();
orion5x_setup_dev_boot_win(RD88F5181L_GE_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", RD88F5181L_GE_NOR_BOOT_BASE,
RD88F5181L_GE_NOR_BOOT_SIZE);
platform_device_register(&rd88f5181l_ge_nor_boot_flash);
......
......@@ -264,10 +264,11 @@ static void __init rd88f5182_init(void)
orion5x_uart0_init();
orion5x_xor_init();
orion5x_setup_dev_boot_win(RD88F5182_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", RD88F5182_NOR_BOOT_BASE,
RD88F5182_NOR_BOOT_SIZE);
orion5x_setup_dev1_win(RD88F5182_NOR_BASE, RD88F5182_NOR_SIZE);
mvebu_mbus_add_window("devbus-cs1", RD88F5182_NOR_BASE,
RD88F5182_NOR_SIZE);
platform_device_register(&rd88f5182_nor_flash);
platform_device_register(&rd88f5182_gpio_leds);
......
......@@ -329,7 +329,7 @@ static void __init tsp2_init(void)
/*
* Configure peripherals.
*/
orion5x_setup_dev_boot_win(TSP2_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", TSP2_NOR_BOOT_BASE,
TSP2_NOR_BOOT_SIZE);
platform_device_register(&tsp2_nor_flash);
......
......@@ -286,7 +286,7 @@ static void __init qnap_ts209_init(void)
/*
* Configure peripherals.
*/
orion5x_setup_dev_boot_win(QNAP_TS209_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", QNAP_TS209_NOR_BOOT_BASE,
QNAP_TS209_NOR_BOOT_SIZE);
platform_device_register(&qnap_ts209_nor_flash);
......
......@@ -277,7 +277,7 @@ static void __init qnap_ts409_init(void)
/*
* Configure peripherals.
*/
orion5x_setup_dev_boot_win(QNAP_TS409_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", QNAP_TS409_NOR_BOOT_BASE,
QNAP_TS409_NOR_BOOT_SIZE);
platform_device_register(&qnap_ts409_nor_flash);
......
......@@ -127,7 +127,7 @@ static void __init wnr854t_init(void)
orion5x_eth_switch_init(&wnr854t_switch_plat_data, NO_IRQ);
orion5x_uart0_init();
orion5x_setup_dev_boot_win(WNR854T_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", WNR854T_NOR_BOOT_BASE,
WNR854T_NOR_BOOT_SIZE);
platform_device_register(&wnr854t_nor_flash);
}
......
......@@ -213,7 +213,7 @@ static void __init wrt350n_v2_init(void)
orion5x_eth_switch_init(&wrt350n_v2_switch_plat_data, NO_IRQ);
orion5x_uart0_init();
orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE,
mvebu_mbus_add_window("devbus-boot", WRT350N_V2_NOR_BOOT_BASE,
WRT350N_V2_NOR_BOOT_SIZE);
platform_device_register(&wrt350n_v2_nor_flash);
platform_device_register(&wrt350n_v2_leds);
......
......@@ -3,8 +3,6 @@
#
ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
obj-y += addr-map.o
orion-gpio-$(CONFIG_GENERIC_GPIO) += gpio.o
obj-$(CONFIG_PLAT_ORION_LEGACY) += irq.o pcie.o time.o common.o mpp.o
obj-$(CONFIG_PLAT_ORION_LEGACY) += $(orion-gpio-y)
/*
* arch/arm/plat-orion/addr-map.c
*
* Address map functions for Marvell Orion based SoCs
*
* 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/module.h>
#include <linux/init.h>
#include <linux/mbus.h>
#include <linux/io.h>
#include <plat/addr-map.h>
struct mbus_dram_target_info orion_mbus_dram_info;
const struct mbus_dram_target_info *mv_mbus_dram_info(void)
{
return &orion_mbus_dram_info;
}
EXPORT_SYMBOL_GPL(mv_mbus_dram_info);
/*
* DDR target is the same on all Orion platforms.
*/
#define TARGET_DDR 0
/*
* Helpers to get DDR bank info
*/
#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3))
#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3))
/*
* CPU Address Decode Windows registers
*/
#define WIN_CTRL_OFF 0x0000
#define WIN_BASE_OFF 0x0004
#define WIN_REMAP_LO_OFF 0x0008
#define WIN_REMAP_HI_OFF 0x000c
#define ATTR_HW_COHERENCY (0x1 << 4)
/*
* Default implementation
*/
static void __init __iomem *
orion_win_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
{
return cfg->bridge_virt_base + (win << 4);
}
/*
* Default implementation
*/
static int __init orion_cpu_win_can_remap(const struct orion_addr_map_cfg *cfg,
const int win)
{
if (win < cfg->remappable_wins)
return 1;
return 0;
}
void __init orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg,
const int win, const u32 base,
const u32 size, const u8 target,
const u8 attr, const int remap)
{
void __iomem *addr = cfg->win_cfg_base(cfg, win);
u32 ctrl, base_high, remap_addr;
if (win >= cfg->num_wins) {
printk(KERN_ERR "setup_cpu_win: trying to allocate window "
"%d when only %d allowed\n", win, cfg->num_wins);
}
base_high = base & 0xffff0000;
ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
writel(base_high, addr + WIN_BASE_OFF);
writel(ctrl, addr + WIN_CTRL_OFF);
if (cfg->cpu_win_can_remap(cfg, win)) {
if (remap < 0)
remap_addr = base;
else
remap_addr = remap;
writel(remap_addr & 0xffff0000, addr + WIN_REMAP_LO_OFF);
writel(0, addr + WIN_REMAP_HI_OFF);
}
}
/*
* Configure a number of windows.
*/
static void __init orion_setup_cpu_wins(const struct orion_addr_map_cfg * cfg,
const struct orion_addr_map_info *info)
{
while (info->win != -1) {
orion_setup_cpu_win(cfg, info->win, info->base, info->size,
info->target, info->attr, info->remap);
info++;
}
}
static void __init orion_disable_wins(const struct orion_addr_map_cfg * cfg)
{
void __iomem *addr;
int i;
for (i = 0; i < cfg->num_wins; i++) {
addr = cfg->win_cfg_base(cfg, i);
writel(0, addr + WIN_BASE_OFF);
writel(0, addr + WIN_CTRL_OFF);
if (cfg->cpu_win_can_remap(cfg, i)) {
writel(0, addr + WIN_REMAP_LO_OFF);
writel(0, addr + WIN_REMAP_HI_OFF);
}
}
}
/*
* Disable, clear and configure windows.
*/
void __init orion_config_wins(struct orion_addr_map_cfg * cfg,
const struct orion_addr_map_info *info)
{
if (!cfg->cpu_win_can_remap)
cfg->cpu_win_can_remap = orion_cpu_win_can_remap;
if (!cfg->win_cfg_base)
cfg->win_cfg_base = orion_win_cfg_base;
orion_disable_wins(cfg);
if (info)
orion_setup_cpu_wins(cfg, info);
}
/*
* Setup MBUS dram target info.
*/
void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
const void __iomem *ddr_window_cpu_base)
{
int i;
int cs;
orion_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
for (i = 0, cs = 0; i < 4; i++) {
u32 base = readl(ddr_window_cpu_base + DDR_BASE_CS_OFF(i));
u32 size = readl(ddr_window_cpu_base + DDR_SIZE_CS_OFF(i));
/*
* We only take care of entries for which the chip
* select is enabled, and that don't have high base
* address bits set (devices can only access the first
* 32 bits of the memory).
*/
if ((size & 1) && !(base & 0xF)) {
struct mbus_dram_window *w;
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;
}
}
orion_mbus_dram_info.num_cs = cs;
}
......@@ -439,6 +439,64 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
}
}
#ifdef CONFIG_DEBUG_FS
#include <linux/seq_file.h>
static void orion_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
struct orion_gpio_chip *ochip =
container_of(chip, struct orion_gpio_chip, chip);
u32 out, io_conf, blink, in_pol, data_in, cause, edg_msk, lvl_msk;
int i;
out = readl_relaxed(GPIO_OUT(ochip));
io_conf = readl_relaxed(GPIO_IO_CONF(ochip));
blink = readl_relaxed(GPIO_BLINK_EN(ochip));
in_pol = readl_relaxed(GPIO_IN_POL(ochip));
data_in = readl_relaxed(GPIO_DATA_IN(ochip));
cause = readl_relaxed(GPIO_EDGE_CAUSE(ochip));
edg_msk = readl_relaxed(GPIO_EDGE_MASK(ochip));
lvl_msk = readl_relaxed(GPIO_LEVEL_MASK(ochip));
for (i = 0; i < chip->ngpio; i++) {
const char *label;
u32 msk;
bool is_out;
label = gpiochip_is_requested(chip, i);
if (!label)
continue;
msk = 1 << i;
is_out = !(io_conf & msk);
seq_printf(s, " gpio-%-3d (%-20.20s)", chip->base + i, label);
if (is_out) {
seq_printf(s, " out %s %s\n",
out & msk ? "hi" : "lo",
blink & msk ? "(blink )" : "");
continue;
}
seq_printf(s, " in %s (act %s) - IRQ",
(data_in ^ in_pol) & msk ? "hi" : "lo",
in_pol & msk ? "lo" : "hi");
if (!((edg_msk | lvl_msk) & msk)) {
seq_printf(s, " disabled\n");
continue;
}
if (edg_msk & msk)
seq_printf(s, " edge ");
if (lvl_msk & msk)
seq_printf(s, " level");
seq_printf(s, " (%s)\n", cause & msk ? "pending" : "clear ");
}
}
#else
#define orion_gpio_dbg_show NULL
#endif
void __init orion_gpio_init(struct device_node *np,
int gpio_base, int ngpio,
void __iomem *base, int mask_offset,
......@@ -471,6 +529,7 @@ void __init orion_gpio_init(struct device_node *np,
#ifdef CONFIG_OF
ochip->chip.of_node = np;
#endif
ochip->chip.dbg_show = orion_gpio_dbg_show;
spin_lock_init(&ochip->lock);
ochip->base = (void __iomem *)base;
......
......@@ -120,12 +120,14 @@ void __init orion_pcie_reset(void __iomem *base)
* BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
* WIN[0-3] -> DRAM bank[0-3]
*/
static void __init orion_pcie_setup_wins(void __iomem *base,
struct mbus_dram_target_info *dram)
static void __init orion_pcie_setup_wins(void __iomem *base)
{
const struct mbus_dram_target_info *dram;
u32 size;
int i;
dram = mv_mbus_dram_info();
/*
* First, disable and clear BARs and windows.
*/
......@@ -150,7 +152,7 @@ static void __init orion_pcie_setup_wins(void __iomem *base,
*/
size = 0;
for (i = 0; i < dram->num_cs; i++) {
struct mbus_dram_window *cs = dram->cs + i;
const struct mbus_dram_window *cs = dram->cs + i;
writel(cs->base & 0xffff0000, base + PCIE_WIN04_BASE_OFF(i));
writel(0, base + PCIE_WIN04_REMAP_OFF(i));
......@@ -184,7 +186,7 @@ void __init orion_pcie_setup(void __iomem *base)
/*
* Point PCIe unit MBUS decode windows to DRAM space.
*/
orion_pcie_setup_wins(base, &orion_mbus_dram_info);
orion_pcie_setup_wins(base);
/*
* Master + slave enable.
......
......@@ -4,6 +4,13 @@
menu "Bus devices"
config MVEBU_MBUS
bool
depends on PLAT_ORION
help
Driver needed for the MBus configuration on Marvell EBU SoCs
(Kirkwood, Dove, Orion5x, MV78XX0 and Armada 370/XP).
config OMAP_OCP2SCP
tristate "OMAP OCP2SCP DRIVER"
depends on ARCH_OMAP2PLUS
......
......@@ -2,6 +2,7 @@
# Makefile for the bus drivers.
#
obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o
obj-$(CONFIG_OMAP_OCP2SCP) += omap-ocp2scp.o
# Interconnect bus driver for OMAP SoCs.
......
/*
* Address map functions for Marvell EBU SoCs (Kirkwood, Armada
* 370/XP, Dove, Orion5x and MV78xx0)
*
* 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 Marvell EBU SoCs have a configurable physical address space:
* the physical address at which certain devices (PCIe, NOR, NAND,
* etc.) sit can be configured. The configuration takes place through
* two sets of registers:
*
* - One to configure the access of the CPU to the devices. Depending
* on the families, there are between 8 and 20 configurable windows,
* each can be use to create a physical memory window that maps to a
* specific device. Devices are identified by a tuple (target,
* attribute).
*
* - One to configure the access to the CPU to the SDRAM. There are
* either 2 (for Dove) or 4 (for other families) windows to map the
* SDRAM into the physical address space.
*
* This driver:
*
* - Reads out the SDRAM address decoding windows at initialization
* time, and fills the mvebu_mbus_dram_info structure with these
* informations. The exported function mv_mbus_dram_info() allow
* device drivers to get those informations related to the SDRAM
* address decoding windows. This is because devices also have their
* own windows (configured through registers that are part of each
* device register space), and therefore the drivers for Marvell
* devices have to configure those device -> SDRAM windows to ensure
* that DMA works properly.
*
* - Provides an API for platform code or device drivers to
* dynamically add or remove address decoding windows for the CPU ->
* device accesses. This API is mvebu_mbus_add_window(),
* mvebu_mbus_add_window_remap_flags() and
* mvebu_mbus_del_window(). Since the (target, attribute) values
* differ from one SoC family to another, the API uses a 'const char
* *' string to identify devices, and this driver is responsible for
* knowing the mapping between the name of a device and its
* corresponding (target, attribute) in the current SoC family.
*
* - Provides a debugfs interface in /sys/kernel/debug/mvebu-mbus/ to
* see the list of CPU -> SDRAM windows and their configuration
* (file 'sdram') and the list of CPU -> devices windows and their
* configuration (file 'devices').
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mbus.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/debugfs.h>
/*
* DDR target is the same on all platforms.
*/
#define TARGET_DDR 0
/*
* CPU Address Decode Windows registers
*/
#define WIN_CTRL_OFF 0x0000
#define WIN_CTRL_ENABLE BIT(0)
#define WIN_CTRL_TGT_MASK 0xf0
#define WIN_CTRL_TGT_SHIFT 4
#define WIN_CTRL_ATTR_MASK 0xff00
#define WIN_CTRL_ATTR_SHIFT 8
#define WIN_CTRL_SIZE_MASK 0xffff0000
#define WIN_CTRL_SIZE_SHIFT 16
#define WIN_BASE_OFF 0x0004
#define WIN_BASE_LOW 0xffff0000
#define WIN_BASE_HIGH 0xf
#define WIN_REMAP_LO_OFF 0x0008
#define WIN_REMAP_LOW 0xffff0000
#define WIN_REMAP_HI_OFF 0x000c
#define ATTR_HW_COHERENCY (0x1 << 4)
#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3))
#define DDR_BASE_CS_HIGH_MASK 0xf
#define DDR_BASE_CS_LOW_MASK 0xff000000
#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3))
#define DDR_SIZE_ENABLED BIT(0)
#define DDR_SIZE_CS_MASK 0x1c
#define DDR_SIZE_CS_SHIFT 2
#define DDR_SIZE_MASK 0xff000000
#define DOVE_DDR_BASE_CS_OFF(n) ((n) << 4)
struct mvebu_mbus_mapping {
const char *name;
u8 target;
u8 attr;
u8 attrmask;
};
/*
* Masks used for the 'attrmask' field of mvebu_mbus_mapping. They
* allow to get the real attribute value, discarding the special bits
* used to select a PCI MEM region or a PCI WA region. This allows the
* debugfs code to reverse-match the name of a device from its
* target/attr values.
*
* For all devices except PCI, all bits of 'attr' must be
* considered. For most SoCs, only bit 3 should be ignored (it allows
* to select between PCI MEM and PCI I/O). On Orion5x however, there
* is the special bit 5 to select a PCI WA region.
*/
#define MAPDEF_NOMASK 0xff
#define MAPDEF_PCIMASK 0xf7
#define MAPDEF_ORIONPCIMASK 0xd7
/* Macro used to define one mvebu_mbus_mapping entry */
#define MAPDEF(__n, __t, __a, __m) \
{ .name = __n, .target = __t, .attr = __a, .attrmask = __m }
struct mvebu_mbus_state;
struct mvebu_mbus_soc_data {
unsigned int num_wins;
unsigned int num_remappable_wins;
unsigned int (*win_cfg_offset)(const int win);
void (*setup_cpu_target)(struct mvebu_mbus_state *s);
int (*show_cpu_target)(struct mvebu_mbus_state *s,
struct seq_file *seq, void *v);
const struct mvebu_mbus_mapping *map;
};
struct mvebu_mbus_state {
void __iomem *mbuswins_base;
void __iomem *sdramwins_base;
struct dentry *debugfs_root;
struct dentry *debugfs_sdram;
struct dentry *debugfs_devs;
const struct mvebu_mbus_soc_data *soc;
int hw_io_coherency;
};
static struct mvebu_mbus_state mbus_state;
static struct mbus_dram_target_info mvebu_mbus_dram_info;
const struct mbus_dram_target_info *mv_mbus_dram_info(void)
{
return &mvebu_mbus_dram_info;
}
EXPORT_SYMBOL_GPL(mv_mbus_dram_info);
/*
* Functions to manipulate the address decoding windows
*/
static void mvebu_mbus_read_window(struct mvebu_mbus_state *mbus,
int win, int *enabled, u64 *base,
u32 *size, u8 *target, u8 *attr,
u64 *remap)
{
void __iomem *addr = mbus->mbuswins_base +
mbus->soc->win_cfg_offset(win);
u32 basereg = readl(addr + WIN_BASE_OFF);
u32 ctrlreg = readl(addr + WIN_CTRL_OFF);
if (!(ctrlreg & WIN_CTRL_ENABLE)) {
*enabled = 0;
return;
}
*enabled = 1;
*base = ((u64)basereg & WIN_BASE_HIGH) << 32;
*base |= (basereg & WIN_BASE_LOW);
*size = (ctrlreg | ~WIN_CTRL_SIZE_MASK) + 1;
if (target)
*target = (ctrlreg & WIN_CTRL_TGT_MASK) >> WIN_CTRL_TGT_SHIFT;
if (attr)
*attr = (ctrlreg & WIN_CTRL_ATTR_MASK) >> WIN_CTRL_ATTR_SHIFT;
if (remap) {
if (win < mbus->soc->num_remappable_wins) {
u32 remap_low = readl(addr + WIN_REMAP_LO_OFF);
u32 remap_hi = readl(addr + WIN_REMAP_HI_OFF);
*remap = ((u64)remap_hi << 32) | remap_low;
} else
*remap = 0;
}
}
static void mvebu_mbus_disable_window(struct mvebu_mbus_state *mbus,
int win)
{
void __iomem *addr;
addr = mbus->mbuswins_base + mbus->soc->win_cfg_offset(win);
writel(0, addr + WIN_BASE_OFF);
writel(0, addr + WIN_CTRL_OFF);
if (win < mbus->soc->num_remappable_wins) {
writel(0, addr + WIN_REMAP_LO_OFF);
writel(0, addr + WIN_REMAP_HI_OFF);
}
}
/* Checks whether the given window number is available */
static int mvebu_mbus_window_is_free(struct mvebu_mbus_state *mbus,
const int win)
{
void __iomem *addr = mbus->mbuswins_base +
mbus->soc->win_cfg_offset(win);
u32 ctrl = readl(addr + WIN_CTRL_OFF);
return !(ctrl & WIN_CTRL_ENABLE);
}
/*
* Checks whether the given (base, base+size) area doesn't overlap an
* existing region
*/
static int mvebu_mbus_window_conflicts(struct mvebu_mbus_state *mbus,
phys_addr_t base, size_t size,
u8 target, u8 attr)
{
u64 end = (u64)base + size;
int win;
for (win = 0; win < mbus->soc->num_wins; win++) {
u64 wbase, wend;
u32 wsize;
u8 wtarget, wattr;
int enabled;
mvebu_mbus_read_window(mbus, win,
&enabled, &wbase, &wsize,
&wtarget, &wattr, NULL);
if (!enabled)
continue;
wend = wbase + wsize;
/*
* Check if the current window overlaps with the
* proposed physical range
*/
if ((u64)base < wend && end > wbase)
return 0;
/*
* Check if target/attribute conflicts
*/
if (target == wtarget && attr == wattr)
return 0;
}
return 1;
}
static int mvebu_mbus_find_window(struct mvebu_mbus_state *mbus,
phys_addr_t base, size_t size)
{
int win;
for (win = 0; win < mbus->soc->num_wins; win++) {
u64 wbase;
u32 wsize;
int enabled;
mvebu_mbus_read_window(mbus, win,
&enabled, &wbase, &wsize,
NULL, NULL, NULL);
if (!enabled)
continue;
if (base == wbase && size == wsize)
return win;
}
return -ENODEV;
}
static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus,
int win, phys_addr_t base, size_t size,
phys_addr_t remap, u8 target,
u8 attr)
{
void __iomem *addr = mbus->mbuswins_base +
mbus->soc->win_cfg_offset(win);
u32 ctrl, remap_addr;
ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) |
(attr << WIN_CTRL_ATTR_SHIFT) |
(target << WIN_CTRL_TGT_SHIFT) |
WIN_CTRL_ENABLE;
writel(base & WIN_BASE_LOW, addr + WIN_BASE_OFF);
writel(ctrl, addr + WIN_CTRL_OFF);
if (win < mbus->soc->num_remappable_wins) {
if (remap == MVEBU_MBUS_NO_REMAP)
remap_addr = base;
else
remap_addr = remap;
writel(remap_addr & WIN_REMAP_LOW, addr + WIN_REMAP_LO_OFF);
writel(0, addr + WIN_REMAP_HI_OFF);
}
return 0;
}
static int mvebu_mbus_alloc_window(struct mvebu_mbus_state *mbus,
phys_addr_t base, size_t size,
phys_addr_t remap, u8 target,
u8 attr)
{
int win;
if (remap == MVEBU_MBUS_NO_REMAP) {
for (win = mbus->soc->num_remappable_wins;
win < mbus->soc->num_wins; win++)
if (mvebu_mbus_window_is_free(mbus, win))
return mvebu_mbus_setup_window(mbus, win, base,
size, remap,
target, attr);
}
for (win = 0; win < mbus->soc->num_wins; win++)
if (mvebu_mbus_window_is_free(mbus, win))
return mvebu_mbus_setup_window(mbus, win, base, size,
remap, target, attr);
return -ENOMEM;
}
/*
* Debugfs debugging
*/
/* Common function used for Dove, Kirkwood, Armada 370/XP and Orion 5x */
static int mvebu_sdram_debug_show_orion(struct mvebu_mbus_state *mbus,
struct seq_file *seq, void *v)
{
int i;
for (i = 0; i < 4; i++) {
u32 basereg = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i));
u32 sizereg = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i));
u64 base;
u32 size;
if (!(sizereg & DDR_SIZE_ENABLED)) {
seq_printf(seq, "[%d] disabled\n", i);
continue;
}
base = ((u64)basereg & DDR_BASE_CS_HIGH_MASK) << 32;
base |= basereg & DDR_BASE_CS_LOW_MASK;
size = (sizereg | ~DDR_SIZE_MASK);
seq_printf(seq, "[%d] %016llx - %016llx : cs%d\n",
i, (unsigned long long)base,
(unsigned long long)base + size + 1,
(sizereg & DDR_SIZE_CS_MASK) >> DDR_SIZE_CS_SHIFT);
}
return 0;
}
/* Special function for Dove */
static int mvebu_sdram_debug_show_dove(struct mvebu_mbus_state *mbus,
struct seq_file *seq, void *v)
{
int i;
for (i = 0; i < 2; i++) {
u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i));
u64 base;
u32 size;
if (!(map & 1)) {
seq_printf(seq, "[%d] disabled\n", i);
continue;
}
base = map & 0xff800000;
size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
seq_printf(seq, "[%d] %016llx - %016llx : cs%d\n",
i, (unsigned long long)base,
(unsigned long long)base + size, i);
}
return 0;
}
static int mvebu_sdram_debug_show(struct seq_file *seq, void *v)
{
struct mvebu_mbus_state *mbus = &mbus_state;
return mbus->soc->show_cpu_target(mbus, seq, v);
}
static int mvebu_sdram_debug_open(struct inode *inode, struct file *file)
{
return single_open(file, mvebu_sdram_debug_show, inode->i_private);
}
static const struct file_operations mvebu_sdram_debug_fops = {
.open = mvebu_sdram_debug_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int mvebu_devs_debug_show(struct seq_file *seq, void *v)
{
struct mvebu_mbus_state *mbus = &mbus_state;
int win;
for (win = 0; win < mbus->soc->num_wins; win++) {
u64 wbase, wremap;
u32 wsize;
u8 wtarget, wattr;
int enabled, i;
const char *name;
mvebu_mbus_read_window(mbus, win,
&enabled, &wbase, &wsize,
&wtarget, &wattr, &wremap);
if (!enabled) {
seq_printf(seq, "[%02d] disabled\n", win);
continue;
}
for (i = 0; mbus->soc->map[i].name; i++)
if (mbus->soc->map[i].target == wtarget &&
mbus->soc->map[i].attr ==
(wattr & mbus->soc->map[i].attrmask))
break;
name = mbus->soc->map[i].name ?: "unknown";
seq_printf(seq, "[%02d] %016llx - %016llx : %s",
win, (unsigned long long)wbase,
(unsigned long long)(wbase + wsize), name);
if (win < mbus->soc->num_remappable_wins) {
seq_printf(seq, " (remap %016llx)\n",
(unsigned long long)wremap);
} else
seq_printf(seq, "\n");
}
return 0;
}
static int mvebu_devs_debug_open(struct inode *inode, struct file *file)
{
return single_open(file, mvebu_devs_debug_show, inode->i_private);
}
static const struct file_operations mvebu_devs_debug_fops = {
.open = mvebu_devs_debug_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
/*
* SoC-specific functions and definitions
*/
static unsigned int orion_mbus_win_offset(int win)
{
return win << 4;
}
static unsigned int armada_370_xp_mbus_win_offset(int win)
{
/* The register layout is a bit annoying and the below code
* tries to cope with it.
* - At offset 0x0, there are the registers for the first 8
* windows, with 4 registers of 32 bits per window (ctrl,
* base, remap low, remap high)
* - Then at offset 0x80, there is a hole of 0x10 bytes for
* the internal registers base address and internal units
* sync barrier register.
* - Then at offset 0x90, there the registers for 12
* windows, with only 2 registers of 32 bits per window
* (ctrl, base).
*/
if (win < 8)
return win << 4;
else
return 0x90 + ((win - 8) << 3);
}
static unsigned int mv78xx0_mbus_win_offset(int win)
{
if (win < 8)
return win << 4;
else
return 0x900 + ((win - 8) << 4);
}
static void __init
mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
{
int i;
int cs;
mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
for (i = 0, cs = 0; i < 4; i++) {
u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i));
u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i));
/*
* We only take care of entries for which the chip
* select is enabled, and that don't have high base
* address bits set (devices can only access the first
* 32 bits of the memory).
*/
if ((size & DDR_SIZE_ENABLED) &&
!(base & DDR_BASE_CS_HIGH_MASK)) {
struct mbus_dram_window *w;
w = &mvebu_mbus_dram_info.cs[cs++];
w->cs_index = i;
w->mbus_attr = 0xf & ~(1 << i);
if (mbus->hw_io_coherency)
w->mbus_attr |= ATTR_HW_COHERENCY;
w->base = base & DDR_BASE_CS_LOW_MASK;
w->size = (size | ~DDR_SIZE_MASK) + 1;
}
}
mvebu_mbus_dram_info.num_cs = cs;
}
static void __init
mvebu_mbus_dove_setup_cpu_target(struct mvebu_mbus_state *mbus)
{
int i;
int cs;
mvebu_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
for (i = 0, cs = 0; i < 2; i++) {
u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i));
/*
* Chip select enabled?
*/
if (map & 1) {
struct mbus_dram_window *w;
w = &mvebu_mbus_dram_info.cs[cs++];
w->cs_index = i;
w->mbus_attr = 0; /* CS address decoding done inside */
/* the DDR controller, no need to */
/* provide attributes */
w->base = map & 0xff800000;
w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
}
}
mvebu_mbus_dram_info.num_cs = cs;
}
static const struct mvebu_mbus_mapping armada_370_map[] = {
MAPDEF("bootrom", 1, 0xe0, MAPDEF_NOMASK),
MAPDEF("devbus-boot", 1, 0x2f, MAPDEF_NOMASK),
MAPDEF("devbus-cs0", 1, 0x3e, MAPDEF_NOMASK),
MAPDEF("devbus-cs1", 1, 0x3d, MAPDEF_NOMASK),
MAPDEF("devbus-cs2", 1, 0x3b, MAPDEF_NOMASK),
MAPDEF("devbus-cs3", 1, 0x37, MAPDEF_NOMASK),
MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
MAPDEF("pcie1.0", 8, 0xe0, MAPDEF_PCIMASK),
{},
};
static const struct mvebu_mbus_soc_data armada_370_mbus_data = {
.num_wins = 20,
.num_remappable_wins = 8,
.win_cfg_offset = armada_370_xp_mbus_win_offset,
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
.show_cpu_target = mvebu_sdram_debug_show_orion,
.map = armada_370_map,
};
static const struct mvebu_mbus_mapping armada_xp_map[] = {
MAPDEF("bootrom", 1, 0x1d, MAPDEF_NOMASK),
MAPDEF("devbus-boot", 1, 0x2f, MAPDEF_NOMASK),
MAPDEF("devbus-cs0", 1, 0x3e, MAPDEF_NOMASK),
MAPDEF("devbus-cs1", 1, 0x3d, MAPDEF_NOMASK),
MAPDEF("devbus-cs2", 1, 0x3b, MAPDEF_NOMASK),
MAPDEF("devbus-cs3", 1, 0x37, MAPDEF_NOMASK),
MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
MAPDEF("pcie0.1", 4, 0xd0, MAPDEF_PCIMASK),
MAPDEF("pcie0.2", 4, 0xb0, MAPDEF_PCIMASK),
MAPDEF("pcie0.3", 4, 0x70, MAPDEF_PCIMASK),
MAPDEF("pcie1.0", 8, 0xe0, MAPDEF_PCIMASK),
MAPDEF("pcie1.1", 8, 0xd0, MAPDEF_PCIMASK),
MAPDEF("pcie1.2", 8, 0xb0, MAPDEF_PCIMASK),
MAPDEF("pcie1.3", 8, 0x70, MAPDEF_PCIMASK),
MAPDEF("pcie2.0", 4, 0xf0, MAPDEF_PCIMASK),
MAPDEF("pcie3.0", 8, 0xf0, MAPDEF_PCIMASK),
{},
};
static const struct mvebu_mbus_soc_data armada_xp_mbus_data = {
.num_wins = 20,
.num_remappable_wins = 8,
.win_cfg_offset = armada_370_xp_mbus_win_offset,
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
.show_cpu_target = mvebu_sdram_debug_show_orion,
.map = armada_xp_map,
};
static const struct mvebu_mbus_mapping kirkwood_map[] = {
MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
MAPDEF("pcie1.0", 4, 0xd0, MAPDEF_PCIMASK),
MAPDEF("sram", 3, 0x01, MAPDEF_NOMASK),
MAPDEF("nand", 1, 0x2f, MAPDEF_NOMASK),
{},
};
static const struct mvebu_mbus_soc_data kirkwood_mbus_data = {
.num_wins = 8,
.num_remappable_wins = 4,
.win_cfg_offset = orion_mbus_win_offset,
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
.show_cpu_target = mvebu_sdram_debug_show_orion,
.map = kirkwood_map,
};
static const struct mvebu_mbus_mapping dove_map[] = {
MAPDEF("pcie0.0", 0x4, 0xe0, MAPDEF_PCIMASK),
MAPDEF("pcie1.0", 0x8, 0xe0, MAPDEF_PCIMASK),
MAPDEF("cesa", 0x3, 0x01, MAPDEF_NOMASK),
MAPDEF("bootrom", 0x1, 0xfd, MAPDEF_NOMASK),
MAPDEF("scratchpad", 0xd, 0x0, MAPDEF_NOMASK),
{},
};
static const struct mvebu_mbus_soc_data dove_mbus_data = {
.num_wins = 8,
.num_remappable_wins = 4,
.win_cfg_offset = orion_mbus_win_offset,
.setup_cpu_target = mvebu_mbus_dove_setup_cpu_target,
.show_cpu_target = mvebu_sdram_debug_show_dove,
.map = dove_map,
};
static const struct mvebu_mbus_mapping orion5x_map[] = {
MAPDEF("pcie0.0", 4, 0x51, MAPDEF_ORIONPCIMASK),
MAPDEF("pci0.0", 3, 0x51, MAPDEF_ORIONPCIMASK),
MAPDEF("devbus-boot", 1, 0x0f, MAPDEF_NOMASK),
MAPDEF("devbus-cs0", 1, 0x1e, MAPDEF_NOMASK),
MAPDEF("devbus-cs1", 1, 0x1d, MAPDEF_NOMASK),
MAPDEF("devbus-cs2", 1, 0x1b, MAPDEF_NOMASK),
MAPDEF("sram", 0, 0x00, MAPDEF_NOMASK),
{},
};
/*
* Some variants of Orion5x have 4 remappable windows, some other have
* only two of them.
*/
static const struct mvebu_mbus_soc_data orion5x_4win_mbus_data = {
.num_wins = 8,
.num_remappable_wins = 4,
.win_cfg_offset = orion_mbus_win_offset,
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
.show_cpu_target = mvebu_sdram_debug_show_orion,
.map = orion5x_map,
};
static const struct mvebu_mbus_soc_data orion5x_2win_mbus_data = {
.num_wins = 8,
.num_remappable_wins = 2,
.win_cfg_offset = orion_mbus_win_offset,
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
.show_cpu_target = mvebu_sdram_debug_show_orion,
.map = orion5x_map,
};
static const struct mvebu_mbus_mapping mv78xx0_map[] = {
MAPDEF("pcie0.0", 4, 0xe0, MAPDEF_PCIMASK),
MAPDEF("pcie0.1", 4, 0xd0, MAPDEF_PCIMASK),
MAPDEF("pcie0.2", 4, 0xb0, MAPDEF_PCIMASK),
MAPDEF("pcie0.3", 4, 0x70, MAPDEF_PCIMASK),
MAPDEF("pcie1.0", 8, 0xe0, MAPDEF_PCIMASK),
MAPDEF("pcie1.1", 8, 0xd0, MAPDEF_PCIMASK),
MAPDEF("pcie1.2", 8, 0xb0, MAPDEF_PCIMASK),
MAPDEF("pcie1.3", 8, 0x70, MAPDEF_PCIMASK),
MAPDEF("pcie2.0", 4, 0xf0, MAPDEF_PCIMASK),
MAPDEF("pcie3.0", 8, 0xf0, MAPDEF_PCIMASK),
{},
};
static const struct mvebu_mbus_soc_data mv78xx0_mbus_data = {
.num_wins = 14,
.num_remappable_wins = 8,
.win_cfg_offset = mv78xx0_mbus_win_offset,
.setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
.show_cpu_target = mvebu_sdram_debug_show_orion,
.map = mv78xx0_map,
};
/*
* The driver doesn't yet have a DT binding because the details of
* this DT binding still need to be sorted out. However, as a
* preparation, we already use of_device_id to match a SoC description
* string against the SoC specific details of this driver.
*/
static const struct of_device_id of_mvebu_mbus_ids[] = {
{ .compatible = "marvell,armada370-mbus",
.data = &armada_370_mbus_data, },
{ .compatible = "marvell,armadaxp-mbus",
.data = &armada_xp_mbus_data, },
{ .compatible = "marvell,kirkwood-mbus",
.data = &kirkwood_mbus_data, },
{ .compatible = "marvell,dove-mbus",
.data = &dove_mbus_data, },
{ .compatible = "marvell,orion5x-88f5281-mbus",
.data = &orion5x_4win_mbus_data, },
{ .compatible = "marvell,orion5x-88f5182-mbus",
.data = &orion5x_2win_mbus_data, },
{ .compatible = "marvell,orion5x-88f5181-mbus",
.data = &orion5x_2win_mbus_data, },
{ .compatible = "marvell,orion5x-88f6183-mbus",
.data = &orion5x_4win_mbus_data, },
{ .compatible = "marvell,mv78xx0-mbus",
.data = &mv78xx0_mbus_data, },
{ },
};
/*
* Public API of the driver
*/
int mvebu_mbus_add_window_remap_flags(const char *devname, phys_addr_t base,
size_t size, phys_addr_t remap,
unsigned int flags)
{
struct mvebu_mbus_state *s = &mbus_state;
u8 target, attr;
int i;
if (!s->soc->map)
return -ENODEV;
for (i = 0; s->soc->map[i].name; i++)
if (!strcmp(s->soc->map[i].name, devname))
break;
if (!s->soc->map[i].name) {
pr_err("mvebu-mbus: unknown device '%s'\n", devname);
return -ENODEV;
}
target = s->soc->map[i].target;
attr = s->soc->map[i].attr;
if (flags == MVEBU_MBUS_PCI_MEM)
attr |= 0x8;
else if (flags == MVEBU_MBUS_PCI_WA)
attr |= 0x28;
if (!mvebu_mbus_window_conflicts(s, base, size, target, attr)) {
pr_err("mvebu-mbus: cannot add window '%s', conflicts with another window\n",
devname);
return -EINVAL;
}
return mvebu_mbus_alloc_window(s, base, size, remap, target, attr);
}
int mvebu_mbus_add_window(const char *devname, phys_addr_t base, size_t size)
{
return mvebu_mbus_add_window_remap_flags(devname, base, size,
MVEBU_MBUS_NO_REMAP, 0);
}
int mvebu_mbus_del_window(phys_addr_t base, size_t size)
{
int win;
win = mvebu_mbus_find_window(&mbus_state, base, size);
if (win < 0)
return win;
mvebu_mbus_disable_window(&mbus_state, win);
return 0;
}
static __init int mvebu_mbus_debugfs_init(void)
{
struct mvebu_mbus_state *s = &mbus_state;
/*
* If no base has been initialized, doesn't make sense to
* register the debugfs entries. We may be on a multiplatform
* kernel that isn't running a Marvell EBU SoC.
*/
if (!s->mbuswins_base)
return 0;
s->debugfs_root = debugfs_create_dir("mvebu-mbus", NULL);
if (s->debugfs_root) {
s->debugfs_sdram = debugfs_create_file("sdram", S_IRUGO,
s->debugfs_root, NULL,
&mvebu_sdram_debug_fops);
s->debugfs_devs = debugfs_create_file("devices", S_IRUGO,
s->debugfs_root, NULL,
&mvebu_devs_debug_fops);
}
return 0;
}
fs_initcall(mvebu_mbus_debugfs_init);
int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base,
size_t mbuswins_size,
phys_addr_t sdramwins_phys_base,
size_t sdramwins_size)
{
struct mvebu_mbus_state *mbus = &mbus_state;
const struct of_device_id *of_id;
int win;
for (of_id = of_mvebu_mbus_ids; of_id->compatible; of_id++)
if (!strcmp(of_id->compatible, soc))
break;
if (!of_id->compatible) {
pr_err("mvebu-mbus: could not find a matching SoC family\n");
return -ENODEV;
}
mbus->soc = of_id->data;
mbus->mbuswins_base = ioremap(mbuswins_phys_base, mbuswins_size);
if (!mbus->mbuswins_base)
return -ENOMEM;
mbus->sdramwins_base = ioremap(sdramwins_phys_base, sdramwins_size);
if (!mbus->sdramwins_base) {
iounmap(mbus_state.mbuswins_base);
return -ENOMEM;
}
if (of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric"))
mbus->hw_io_coherency = 1;
for (win = 0; win < mbus->soc->num_wins; win++)
mvebu_mbus_disable_window(mbus, win);
mbus->soc->setup_cpu_target(mbus);
return 0;
}
......@@ -32,6 +32,20 @@ struct mbus_dram_target_info
} cs[4];
};
/* Flags for PCI/PCIe address decoding regions */
#define MVEBU_MBUS_PCI_IO 0x1
#define MVEBU_MBUS_PCI_MEM 0x2
#define MVEBU_MBUS_PCI_WA 0x3
/*
* Magic value that explicits that we don't need a remapping-capable
* address decoding window.
*/
#define MVEBU_MBUS_NO_REMAP (0xffffffff)
/* Maximum size of a mbus window name */
#define MVEBU_MBUS_MAX_WINNAME_SZ 32
/*
* The Marvell mbus is to be found only on SOCs from the Orion family
* at the moment. Provide a dummy stub for other architectures.
......@@ -44,4 +58,15 @@ static inline const struct mbus_dram_target_info *mv_mbus_dram_info(void)
return NULL;
}
#endif
#endif
int mvebu_mbus_add_window_remap_flags(const char *devname, phys_addr_t base,
size_t size, phys_addr_t remap,
unsigned int flags);
int mvebu_mbus_add_window(const char *devname, phys_addr_t base,
size_t size);
int mvebu_mbus_del_window(phys_addr_t base, size_t size);
int mvebu_mbus_init(const char *soc, phys_addr_t mbus_phys_base,
size_t mbus_size, phys_addr_t sdram_phys_base,
size_t sdram_size);
#endif /* __LINUX_MBUS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment