diff options
Diffstat (limited to 'arch')
27 files changed, 1554 insertions, 373 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 52b300d483..dd9cac91e7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -117,8 +117,14 @@ config ARCH_MVEBU select OF_CONTROL select OF_SEPARATE select DM + select DM_ETH select DM_SERIAL + select DM_SPI + select DM_SPI_FLASH + select SPL_DM select SPL_DM_SEQ_ALIAS + select SPL_OF_CONTROL + select SPL_SIMPLE_BUS config TARGET_DEVKIT3250 bool "Support devkit3250" @@ -770,8 +776,6 @@ source "board/BuR/kwb/Kconfig" source "board/BuR/tseries/Kconfig" source "board/CarMediaLab/flea3/Kconfig" source "board/Marvell/aspenite/Kconfig" -source "board/Marvell/db-88f6820-gp/Kconfig" -source "board/Marvell/db-mv784mp-gp/Kconfig" source "board/Marvell/gplugd/Kconfig" source "board/armadeus/apf27/Kconfig" source "board/armltd/vexpress/Kconfig" @@ -810,7 +814,6 @@ source "board/h2200/Kconfig" source "board/hisilicon/hikey/Kconfig" source "board/imx31_phycore/Kconfig" source "board/isee/igep0033/Kconfig" -source "board/maxbcm/Kconfig" source "board/mpl/vcma9/Kconfig" source "board/olimex/mx23_olinuxino/Kconfig" source "board/phytec/pcm051/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 18283d1d35..3d15673213 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -49,7 +49,7 @@ machine-$(CONFIG_ARCH_HIGHBANK) += highbank machine-$(CONFIG_ARCH_KEYSTONE) += keystone # TODO: rename CONFIG_KIRKWOOD -> CONFIG_ARCH_KIRKWOOD machine-$(CONFIG_KIRKWOOD) += kirkwood -machine-$(CONFIG_ARMADA_XP) += mvebu +machine-$(CONFIG_ARCH_MVEBU) += mvebu # TODO: rename CONFIG_TEGRA -> CONFIG_ARCH_TEGRA # TODO: rename CONFIG_ORION5X -> CONFIG_ARCH_ORION5X machine-$(CONFIG_ORION5X) += orion5x diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 0bcd316375..64b8371141 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -48,8 +48,11 @@ dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \ tegra210-p2571.dtb dtb-$(CONFIG_ARCH_MVEBU) += \ + armada-388-clearfog.dtb \ armada-388-gp.dtb \ - armada-xp-gp.dtb + armada-xp-gp.dtb \ + armada-xp-maxbcm.dtb \ + armada-xp-synology-ds414.dtb dtb-$(CONFIG_ARCH_UNIPHIER) += \ uniphier-ph1-ld4-ref.dtb \ diff --git a/arch/arm/dts/armada-370-xp.dtsi b/arch/arm/dts/armada-370-xp.dtsi index a718866ba5..0b2a78d393 100644 --- a/arch/arm/dts/armada-370-xp.dtsi +++ b/arch/arm/dts/armada-370-xp.dtsi @@ -141,6 +141,7 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>; + u-boot,dm-pre-reloc; rtc@10300 { compatible = "marvell,orion-rtc"; diff --git a/arch/arm/dts/armada-388-clearfog.dts b/arch/arm/dts/armada-388-clearfog.dts new file mode 100644 index 0000000000..b2dfd56435 --- /dev/null +++ b/arch/arm/dts/armada-388-clearfog.dts @@ -0,0 +1,509 @@ +/* + * Device Tree file for SolidRun Clearfog revision A1 rev 2.0 (88F6828) + * + * Copyright (C) 2015 Russell King + * + * This board is in development; the contents of this file work with + * the A1 rev 2.0 of the board, which does not represent final + * production board. Things will change, don't expect this file to + * remain compatible info the future. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include <dt-bindings/input/input.h> +#include <dt-bindings/gpio/gpio.h> +#include "armada-388.dtsi" + +/ { + model = "SolidRun Clearfog A1"; + compatible = "solidrun,clearfog-a1", "marvell,armada388", + "marvell,armada385", "marvell,armada380"; + + aliases { + /* So that mvebu u-boot can update the MAC addresses */ + ethernet1 = ð0; + ethernet2 = ð1; + ethernet3 = ð2; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x10000000>; /* 256 MB */ + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + soc { + ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000 + MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000 + MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000 + MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>; + + internal-regs { + ethernet@30000 { + mac-address = [00 50 43 02 02 02]; + phy-mode = "sgmii"; + status = "okay"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + ethernet@34000 { + mac-address = [00 50 43 02 02 03]; + managed = "in-band-status"; + phy-mode = "sgmii"; + status = "okay"; + }; + + ethernet@70000 { + mac-address = [00 50 43 02 02 01]; + pinctrl-0 = <&ge0_rgmii_pins>; + pinctrl-names = "default"; + phy = <&phy_dedicated>; + phy-mode = "rgmii-id"; + status = "okay"; + }; + + i2c@11000 { + /* Is there anything on this? */ + clock-frequency = <100000>; + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "default"; + status = "okay"; + + /* + * PCA9655 GPIO expander, up to 1MHz clock. + * 0-CON3 CLKREQ# + * 1-CON3 PERST# + * 2-CON2 PERST# + * 3-CON3 W_DISABLE + * 4-CON2 CLKREQ# + * 5-USB3 overcurrent + * 6-USB3 power + * 7-CON2 W_DISABLE + * 8-JP4 P1 + * 9-JP4 P4 + * 10-JP4 P5 + * 11-m.2 DEVSLP + * 12-SFP_LOS + * 13-SFP_TX_FAULT + * 14-SFP_TX_DISABLE + * 15-SFP_MOD_DEF0 + */ + expander0: gpio-expander@20 { + /* + * This is how it should be: + * compatible = "onnn,pca9655", + * "nxp,pca9555"; + * but you can't do this because of + * the way I2C works. + */ + compatible = "nxp,pca9555"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x20>; + + pcie1_0_clkreq { + gpio-hog; + gpios = <0 GPIO_ACTIVE_LOW>; + input; + line-name = "pcie1.0-clkreq"; + }; + pcie1_0_w_disable { + gpio-hog; + gpios = <3 GPIO_ACTIVE_LOW>; + output-low; + line-name = "pcie1.0-w-disable"; + }; + pcie2_0_clkreq { + gpio-hog; + gpios = <4 GPIO_ACTIVE_LOW>; + input; + line-name = "pcie2.0-clkreq"; + }; + pcie2_0_w_disable { + gpio-hog; + gpios = <7 GPIO_ACTIVE_LOW>; + output-low; + line-name = "pcie2.0-w-disable"; + }; + usb3_ilimit { + gpio-hog; + gpios = <5 GPIO_ACTIVE_LOW>; + input; + line-name = "usb3-current-limit"; + }; + usb3_power { + gpio-hog; + gpios = <6 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "usb3-power"; + }; + m2_devslp { + gpio-hog; + gpios = <11 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "m.2 devslp"; + }; + }; + + /* The MCP3021 is 100kHz clock only */ + mikrobus_adc: mcp3021@4c { + compatible = "microchip,mcp3021"; + reg = <0x4c>; + }; + + /* Also something at 0x64 */ + }; + + i2c@11100 { + /* + * Routed to SFP, mikrobus, and PCIe. + * SFP limits this to 100kHz, and requires + * an AT24C01A/02/04 with address pins tied + * low, which takes addresses 0x50 and 0x51. + * Mikrobus doesn't specify beyond an I2C + * bus being present. + * PCIe uses ARP to assign addresses, or + * 0x63-0x64. + */ + clock-frequency = <100000>; + pinctrl-0 = <&clearfog_i2c1_pins>; + pinctrl-names = "default"; + status = "okay"; + }; + + mdio@72004 { + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; + + phy_dedicated: ethernet-phy@0 { + /* + * Annoyingly, the marvell phy driver + * configures the LED register, rather + * than preserving reset-loaded setting. + * We undo that rubbish here. + */ + marvell,reg-init = <3 16 0 0x101e>; + reg = <0>; + }; + }; + + pinctrl@18000 { + clearfog_dsa0_clk_pins: clearfog-dsa0-clk-pins { + marvell,pins = "mpp46"; + marvell,function = "ref"; + }; + clearfog_dsa0_pins: clearfog-dsa0-pins { + marvell,pins = "mpp23", "mpp41"; + marvell,function = "gpio"; + }; + clearfog_i2c1_pins: i2c1-pins { + /* SFP, PCIe, mSATA, mikrobus */ + marvell,pins = "mpp26", "mpp27"; + marvell,function = "i2c1"; + }; + clearfog_sdhci_cd_pins: clearfog-sdhci-cd-pins { + marvell,pins = "mpp20"; + marvell,function = "gpio"; + }; + clearfog_sdhci_pins: clearfog-sdhci-pins { + marvell,pins = "mpp21", "mpp28", + "mpp37", "mpp38", + "mpp39", "mpp40"; + marvell,function = "sd0"; + }; + clearfog_spi1_cs_pins: spi1-cs-pins { + marvell,pins = "mpp55"; + marvell,function = "spi1"; + }; + mikro_pins: mikro-pins { + /* int: mpp22 rst: mpp29 */ + marvell,pins = "mpp22", "mpp29"; + marvell,function = "gpio"; + }; + mikro_spi_pins: mikro-spi-pins { + marvell,pins = "mpp43"; + marvell,function = "spi1"; + }; + mikro_uart_pins: mikro-uart-pins { + marvell,pins = "mpp24", "mpp25"; + marvell,function = "ua1"; + }; + rear_button_pins: rear-button-pins { + marvell,pins = "mpp34"; + marvell,function = "gpio"; + }; + }; + + rtc@a3800 { + /* + * If the rtc doesn't work, run "date reset" + * twice in u-boot. + */ + status = "okay"; + }; + + sata@a8000 { + /* pinctrl? */ + status = "okay"; + }; + + sata@e0000 { + /* pinctrl? */ + status = "okay"; + }; + + sdhci@d8000 { + bus-width = <4>; + cd-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; + no-1-8-v; + pinctrl-0 = <&clearfog_sdhci_pins + &clearfog_sdhci_cd_pins>; + pinctrl-names = "default"; + status = "okay"; + vmmc = <®_3p3v>; + wp-inverted; + }; + + serial@12000 { + pinctrl-0 = <&uart0_pins>; + pinctrl-names = "default"; + status = "okay"; + u-boot,dm-pre-reloc; + }; + + serial@12100 { + /* mikrobus uart */ + pinctrl-0 = <&mikro_uart_pins>; + pinctrl-names = "default"; + status = "okay"; + }; + + spi@10680 { + /* + * We don't seem to have the W25Q32 on the + * A1 Rev 2.0 boards, so disable SPI. + * CS0: W25Q32 (doesn't appear to be present) + * CS1: + * CS2: mikrobus + */ + pinctrl-0 = <&spi1_pins &clearfog_spi1_cs_pins &mikro_spi_pins>; + pinctrl-names = "default"; + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "w25q32", "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <3000000>; + status = "disabled"; + }; + }; + + usb3@f8000 { + status = "okay"; + }; + }; + + pcie-controller { + status = "okay"; + /* + * The two PCIe units are accessible through + * the mini-PCIe connectors on the board. + */ + pcie@2,0 { + /* Port 1, Lane 0. CONN3, nearest power. */ + reset-gpios = <&expander0 1 GPIO_ACTIVE_LOW>; + status = "okay"; + }; + pcie@3,0 { + /* Port 2, Lane 0. CONN2, nearest CPU. */ + reset-gpios = <&expander0 2 GPIO_ACTIVE_LOW>; + status = "okay"; + }; + }; + }; + + sfp: sfp { + compatible = "sff,sfp"; + i2c-bus = <&i2c1>; + los-gpio = <&expander0 12 GPIO_ACTIVE_HIGH>; + moddef0-gpio = <&expander0 15 GPIO_ACTIVE_LOW>; + sfp,ethernet = <ð2>; + tx-disable-gpio = <&expander0 14 GPIO_ACTIVE_HIGH>; + tx-fault-gpio = <&expander0 13 GPIO_ACTIVE_HIGH>; + }; + + dsa@0 { + compatible = "marvell,dsa"; + dsa,ethernet = <ð1>; + dsa,mii-bus = <&mdio>; + pinctrl-0 = <&clearfog_dsa0_clk_pins &clearfog_dsa0_pins>; + pinctrl-names = "default"; + #address-cells = <2>; + #size-cells = <0>; + + switch@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4 0>; + + port@0 { + reg = <0>; + label = "lan1"; + }; + + port@1 { + reg = <1>; + label = "lan2"; + }; + + port@2 { + reg = <2>; + label = "lan3"; + }; + + port@3 { + reg = <3>; + label = "lan4"; + }; + + port@4 { + reg = <4>; + label = "lan5"; + }; + + port@5 { + reg = <5>; + label = "cpu"; + }; + + port@6 { + /* 88E1512 external phy */ + reg = <6>; + label = "lan6"; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-0 = <&rear_button_pins>; + pinctrl-names = "default"; + + button_0 { + /* The rear SW3 button */ + label = "Rear Button"; + gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; + linux,can-disable; + linux,code = <BTN_0>; + }; + }; +}; + +/* ++#define A38x_CUSTOMER_BOARD_1_MPP16_23 0x00400011 +MPP18: gpio ? (pca9655 int?) +MPP19: gpio ? (clkreq?) +MPP20: gpio ? (sd0 detect) +MPP21: sd0:cmd x sd0 +MPP22: gpio x mikro int +MPP23: gpio x switch irq ++#define A38x_CUSTOMER_BOARD_1_MPP24_31 0x22043333 +MPP24: ua1:rxd x mikro rx +MPP25: ua1:txd x mikro tx +MPP26: i2c1:sck x mikro sck +MPP27: i2c1:sda x mikro sda +MPP28: sd0:clk x sd0 +MPP29: gpio x mikro rst +MPP30: ge1:txd2 ? (config) +MPP31: ge1:txd3 ? (config) ++#define A38x_CUSTOMER_BOARD_1_MPP32_39 0x44400002 +MPP32: ge1:txctl ? (unused) +MPP33: gpio ? (pic_com0) +MPP34: gpio x rear button (pic_com1) +MPP35: gpio ? (pic_com2) +MPP36: gpio ? (unused) +MPP37: sd0:d3 x sd0 +MPP38: sd0:d0 x sd0 +MPP39: sd0:d1 x sd0 ++#define A38x_CUSTOMER_BOARD_1_MPP40_47 0x41144004 +MPP40: sd0:d2 x sd0 +MPP41: gpio x switch reset +MPP42: gpio ? sw1-1 +MPP43: spi1:cs2 x mikro cs +MPP44: sata3:prsnt ? (unused) +MPP45: ref:clk_out0 ? +MPP46: ref:clk_out1 x switch clk +MPP47: 4 ? (unused) ++#define A38x_CUSTOMER_BOARD_1_MPP48_55 0x40333333 +MPP48: tdm:pclk +MPP49: tdm:fsync +MPP50: tdm:drx +MPP51: tdm:dtx +MPP52: tdm:int +MPP53: tdm:rst +MPP54: gpio ? (pwm) +MPP55: spi1:cs1 x slic ++#define A38x_CUSTOMER_BOARD_1_MPP56_63 0x00004444 +MPP56: spi1:mosi x mikro mosi +MPP57: spi1:sck x mikro sck +MPP58: spi1:miso x mikro miso +MPP59: spi1:cs0 x w25q32 +*/ diff --git a/arch/arm/dts/armada-388-gp.dts b/arch/arm/dts/armada-388-gp.dts index fd4f6fd8a2..7bc878f5a9 100644 --- a/arch/arm/dts/armada-388-gp.dts +++ b/arch/arm/dts/armada-388-gp.dts @@ -51,6 +51,12 @@ stdout-path = "serial0:115200n8"; }; + aliases { + ethernet0 = ð0; + ethernet1 = ð1; + spi0 = &spi0; + }; + memory { device_type = "memory"; reg = <0x00000000 0x80000000>; /* 2 GB */ @@ -65,8 +71,10 @@ pinctrl-names = "default"; pinctrl-0 = <&spi0_pins>; status = "okay"; + u-boot,dm-pre-reloc; spi-flash@0 { + u-boot,dm-pre-reloc; #address-cells = <1>; #size-cells = <1>; compatible = "st,m25p128", "jedec,spi-nor"; @@ -122,6 +130,7 @@ pinctrl-names = "default"; pinctrl-0 = <&uart0_pins>; status = "okay"; + u-boot,dm-pre-reloc; }; /* GE1 CON15 */ diff --git a/arch/arm/dts/armada-38x.dtsi b/arch/arm/dts/armada-38x.dtsi index 04ecfe6e2b..dc8a1a66c1 100644 --- a/arch/arm/dts/armada-38x.dtsi +++ b/arch/arm/dts/armada-38x.dtsi @@ -70,6 +70,7 @@ soc { compatible = "marvell,armada380-mbus", "simple-bus"; + u-boot,dm-pre-reloc; #address-cells = <2>; #size-cells = <1>; controller = <&mbusc>; @@ -134,6 +135,7 @@ internal-regs { compatible = "simple-bus"; + u-boot,dm-pre-reloc; #address-cells = <1>; #size-cells = <1>; ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>; diff --git a/arch/arm/dts/armada-xp-gp.dts b/arch/arm/dts/armada-xp-gp.dts index bf724ca96a..27799d1254 100644 --- a/arch/arm/dts/armada-xp-gp.dts +++ b/arch/arm/dts/armada-xp-gp.dts @@ -68,6 +68,10 @@ stdout-path = "serial0:115200n8"; }; + aliases { + spi0 = &spi0; + }; + memory { device_type = "memory"; /* @@ -148,6 +152,7 @@ internal-regs { serial@12000 { status = "okay"; + u-boot,dm-pre-reloc; }; serial@12100 { status = "okay"; @@ -223,8 +228,10 @@ spi0: spi@10600 { status = "okay"; + u-boot,dm-pre-reloc; spi-flash@0 { + u-boot,dm-pre-reloc; #address-cells = <1>; #size-cells = <1>; compatible = "n25q128a13", "jedec,spi-nor"; diff --git a/arch/arm/dts/armada-xp-maxbcm.dts b/arch/arm/dts/armada-xp-maxbcm.dts new file mode 100644 index 0000000000..d7d7f65c85 --- /dev/null +++ b/arch/arm/dts/armada-xp-maxbcm.dts @@ -0,0 +1,249 @@ +/* + * Device Tree file for Marvell Armada XP maxbcm board + * + * Copyright (C) 2013-2014 Marvell + * + * Lior Amsalem <alior@marvell.com> + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Note: this Device Tree assumes that the bootloader has remapped the + * internal registers to 0xf1000000 (instead of the default + * 0xd0000000). The 0xf1000000 is the default used by the recent, + * DT-capable, U-Boot bootloaders provided by Marvell. Some earlier + * boards were delivered with an older version of the bootloader that + * left internal registers mapped at 0xd0000000. If you are in this + * situation, you should either update your bootloader (preferred + * solution) or the below Device Tree should be adjusted. + */ + +/dts-v1/; +#include <dt-bindings/gpio/gpio.h> +#include "armada-xp-mv78460.dtsi" + +/ { + model = "Marvell Armada XP MAXBCM"; + compatible = "marvell,axp-gp", "marvell,armadaxp-mv78460", "marvell,armadaxp", "marvell,armada-370-xp"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + spi0 = &spi0; + }; + + memory { + device_type = "memory"; + /* + * 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. However, memory between + * 0xF0000000 to 0xFFFFFFFF cannot be used, as it is + * the address range used for I/O (internal registers, + * MBus windows). + */ + reg = <0x00000000 0x00000000 0x00000000 0xf0000000>, + <0x00000001 0x00000000 0x00000001 0x00000000>; + }; + + cpus { + pm_pic { + ctrl-gpios = <&gpio0 16 GPIO_ACTIVE_LOW>, + <&gpio0 17 GPIO_ACTIVE_LOW>, + <&gpio0 18 GPIO_ACTIVE_LOW>; + }; + }; + + soc { + ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000 + MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000 + MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000>; + + devbus-bootcs { + status = "okay"; + + /* Device Bus parameters are required */ + + /* Read parameters */ + devbus,bus-width = <16>; + 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"; + }; + }; + + internal-regs { + serial@12000 { + status = "okay"; + u-boot,dm-pre-reloc; + }; + serial@12100 { + status = "okay"; + }; + serial@12200 { + status = "okay"; + }; + serial@12300 { + status = "okay"; + }; + pinctrl { + pinctrl-0 = <&pic_pins>; + pinctrl-names = "default"; + pic_pins: pic-pins-0 { + marvell,pins = "mpp16", "mpp17", + "mpp18"; + marvell,function = "gpio"; + }; + }; + sata@a0000 { + nr-ports = <2>; + status = "okay"; + }; + + mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; + + phy1: ethernet-phy@1 { + reg = <1>; + }; + + phy2: ethernet-phy@2 { + reg = <2>; + }; + + phy3: ethernet-phy@3 { + reg = <3>; + }; + }; + + ethernet@70000 { + status = "okay"; + phy = <&phy0>; + phy-mode = "sgmii"; + }; + ethernet@74000 { + status = "okay"; + phy = <&phy1>; + phy-mode = "sgmii"; + }; + ethernet@30000 { + status = "okay"; + phy = <&phy2>; + phy-mode = "sgmii"; + }; + ethernet@34000 { + status = "okay"; + phy = <&phy3>; + phy-mode = "sgmii"; + }; + + /* Front-side USB slot */ + usb@50000 { + status = "okay"; + }; + + /* Back-side USB slot */ + usb@51000 { + status = "okay"; + }; + + spi0: spi@10600 { + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "n25q128a13", "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <108000000>; + }; + }; + + nand@d0000 { + status = "okay"; + num-cs = <1>; + marvell,nand-keep-config; + marvell,nand-enable-arbiter; + nand-on-flash-bbt; + }; + }; + }; +}; diff --git a/arch/arm/dts/armada-xp-synology-ds414.dts b/arch/arm/dts/armada-xp-synology-ds414.dts new file mode 100644 index 0000000000..0a60ddfa41 --- /dev/null +++ b/arch/arm/dts/armada-xp-synology-ds414.dts @@ -0,0 +1,337 @@ +/* + * Device Tree file for Synology DS414 + * + * Copyright (C) 2014, Arnaud EBALARD <arno@natisbad.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Note: this Device Tree assumes that the bootloader has remapped the + * internal registers to 0xf1000000 (instead of the old 0xd0000000). + * The 0xf1000000 is the default used by the recent, DT-capable, U-Boot + * bootloaders provided by Marvell. It is used in recent versions of + * DSM software provided by Synology. Nonetheless, some earlier boards + * were delivered with an older version of u-boot that left internal + * registers mapped at 0xd0000000. If you have such a device you will + * not be able to directly boot a kernel based on this Device Tree. In + * that case, the preferred solution is to update your bootloader (e.g. + * by upgrading to latest version of DSM, or building a new one and + * installing it from u-boot prompt) or adjust the Devive Tree + * (s/0xf1000000/0xd0000000/ in 'ranges' below). + */ + +/dts-v1/; + +#include <dt-bindings/input/input.h> +#include <dt-bindings/gpio/gpio.h> +#include "armada-xp-mv78230.dtsi" + +/ { + model = "Synology DS414"; + compatible = "synology,ds414", "marvell,armadaxp-mv78230", + "marvell,armadaxp", "marvell,armada-370-xp"; + + chosen { + bootargs = "console=ttyS0,115200 earlyprintk"; + stdout-path = &uart0; + }; + + aliases { + spi0 = &spi0; + }; + + memory { + device_type = "memory"; + reg = <0 0x00000000 0 0x40000000>; /* 1GB */ + }; + + soc { + ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000 + MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>; + + pcie-controller { + status = "okay"; + + /* + * Connected to Marvell 88SX7042 SATA-II controller + * handling the four disks. + */ + pcie@1,0 { + /* Port 0, Lane 0 */ + status = "okay"; + }; + + /* + * Connected to EtronTech EJ168A XHCI controller + * providing the two rear USB 3.0 ports. + */ + pcie@5,0 { + /* Port 1, Lane 0 */ + status = "okay"; + }; + }; + + internal-regs { + + /* RTC is provided by Seiko S-35390A below */ + rtc@10300 { + status = "disabled"; + }; + + spi0: spi@10600 { + status = "okay"; + u-boot,dm-pre-reloc; + + spi-flash@0 { + u-boot,dm-pre-reloc; + #address-cells = <1>; + #size-cells = <1>; + compatible = "micron,n25q064"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <20000000>; + + /* + * Warning! + * + * Synology u-boot uses its compiled-in environment + * and it seems Synology did not care to change u-boot + * default configuration in order to allow saving a + * modified environment at a sensible location. So, + * if you do a 'saveenv' under u-boot, your modified + * environment will be saved at 1MB after the start + * of the flash, i.e. in the middle of the uImage. + * For that reason, it is strongly advised not to + * change the default environment, unless you know + * what you are doing. + */ + partition@00000000 { /* u-boot */ + label = "RedBoot"; + reg = <0x00000000 0x000d0000>; /* 832KB */ + }; + + partition@000c0000 { /* uImage */ + label = "zImage"; + reg = <0x000d0000 0x002d0000>; /* 2880KB */ + }; + + partition@003a0000 { /* uInitramfs */ + label = "rd.gz"; + reg = <0x003a0000 0x00430000>; /* 4250KB */ + }; + + partition@007d0000 { /* MAC address and serial number */ + label = "vendor"; + reg = <0x007d0000 0x00010000>; /* 64KB */ + }; + + partition@007e0000 { + label = "RedBoot config"; + reg = <0x007e0000 0x00010000>; /* 64KB */ + }; + + partition@007f0000 { + label = "FIS directory"; + reg = <0x007f0000 0x00010000>; /* 64KB */ + }; + }; + }; + + i2c@11000 { + clock-frequency = <400000>; + status = "okay"; + + s35390a: s35390a@30 { + compatible = "sii,s35390a"; + reg = <0x30>; + }; + }; + + /* Connected to a header on device's PCB. This + * provides the main console for the device. + * + * Warning: the device may not boot with a 3.3V + * USB-serial converter connected when the power + * button is pressed. The converter needs to be + * connected a few seconds after pressing the + * power button. This is possibly due to UART0_TXD + * pin being sampled at reset (bit 0 of SAR). + */ + serial@12000 { + status = "okay"; + u-boot,dm-pre-reloc; + }; + + /* Connected to a Microchip PIC16F883 for power control */ + serial@12100 { + status = "okay"; + }; + + poweroff@12100 { + compatible = "synology,power-off"; + reg = <0x12100 0x100>; + clocks = <&coreclk 0>; + }; + + /* Front USB 2.0 port */ + usb@50000 { + status = "okay"; + }; + + mdio { + phy0: ethernet-phy@0 { /* Marvell 88E1512 */ + reg = <0>; + }; + + phy1: ethernet-phy@1 { /* Marvell 88E1512 */ + reg = <1>; + }; + }; + + ethernet@70000 { + status = "okay"; + pinctrl-0 = <&ge0_rgmii_pins>; + pinctrl-names = "default"; + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; + + ethernet@74000 { + pinctrl-0 = <&ge1_rgmii_pins>; + pinctrl-names = "default"; + status = "okay"; + phy = <&phy0>; + phy-mode = "rgmii-id"; + }; + }; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&sata1_pwr_pin &sata2_pwr_pin + &sata3_pwr_pin &sata4_pwr_pin>; + pinctrl-names = "default"; + + sata1_regulator: sata1-regulator { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "SATA1 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + startup-delay-us = <2000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>; + }; + + sata2_regulator: sata2-regulator { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "SATA2 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + startup-delay-us = <4000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>; + }; + + sata3_regulator: sata3-regulator { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "SATA3 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + startup-delay-us = <6000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>; + }; + + sata4_regulator: sata4-regulator { + compatible = "regulator-fixed"; + reg = <4>; + regulator-name = "SATA4 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + startup-delay-us = <8000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&pinctrl { + sata1_pwr_pin: sata1-pwr-pin { + marvell,pins = "mpp42"; + marvell,function = "gpio"; + }; + + sata2_pwr_pin: sata2-pwr-pin { + marvell,pins = "mpp44"; + marvell,function = "gpio"; + }; + + sata3_pwr_pin: sata3-pwr-pin { + marvell,pins = "mpp45"; + marvell,function = "gpio"; + }; + + sata4_pwr_pin: sata4-pwr-pin { + marvell,pins = "mpp46"; + marvell,function = "gpio"; + }; + + sata1_pres_pin: sata1-pres-pin { + marvell,pins = "mpp34"; + marvell,function = "gpio"; + }; + + sata2_pres_pin: sata2-pres-pin { + marvell,pins = "mpp35"; + marvell,function = "gpio"; + }; + + sata3_pres_pin: sata3-pres-pin { + marvell,pins = "mpp40"; + marvell,function = "gpio"; + }; + + sata4_pres_pin: sata4-pres-pin { + marvell,pins = "mpp41"; + marvell,function = "gpio"; + }; + + syno_id_bit0_pin: syno-id-bit0-pin { + marvell,pins = "mpp26"; + marvell,function = "gpio"; + }; + + syno_id_bit1_pin: syno-id-bit1-pin { + marvell,pins = "mpp28"; + marvell,function = "gpio"; + }; + + syno_id_bit2_pin: syno-id-bit2-pin { + marvell,pins = "mpp29"; + marvell,function = "gpio"; + }; + + fan1_alarm_pin: fan1-alarm-pin { + marvell,pins = "mpp33"; + marvell,function = "gpio"; + }; + + fan2_alarm_pin: fan2-alarm-pin { + marvell,pins = "mpp32"; + marvell,function = "gpio"; + }; +}; diff --git a/arch/arm/dts/armada-xp.dtsi b/arch/arm/dts/armada-xp.dtsi index 3de9b761cc..3fac39e41d 100644 --- a/arch/arm/dts/armada-xp.dtsi +++ b/arch/arm/dts/armada-xp.dtsi @@ -63,6 +63,7 @@ soc { compatible = "marvell,armadaxp-mbus", "simple-bus"; + u-boot,dm-pre-reloc; bootrom { compatible = "marvell,bootrom"; diff --git a/arch/arm/mach-kirkwood/include/mach/config.h b/arch/arm/mach-kirkwood/include/mach/config.h index d049395036..0c4309ff00 100644 --- a/arch/arm/mach-kirkwood/include/mach/config.h +++ b/arch/arm/mach-kirkwood/include/mach/config.h @@ -135,4 +135,9 @@ #define CONFIG_SYS_I2C_SPEED 100000 #endif +/* Use common timer */ +#define CONFIG_SYS_TIMER_COUNTS_DOWN +#define CONFIG_SYS_TIMER_COUNTER (MVEBU_TIMER_BASE + 0x14) +#define CONFIG_SYS_TIMER_RATE CONFIG_SYS_TCLK + #endif /* _KW_CONFIG_H */ diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 79ff0e8278..b9628462ea 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -1,31 +1,74 @@ if ARCH_MVEBU +config ARMADA_38X + bool + +config ARMADA_XP + bool + +config MV78230 + bool + select ARMADA_XP + +config MV78260 + bool + select ARMADA_XP + +config MV78460 + bool + select ARMADA_XP + +config DB_88F6820_GP + bool + select ARMADA_38X + choice prompt "Marvell MVEBU (Armada XP/38x) board select" optional +config TARGET_CLEARFOG + bool "Support ClearFog" + select DB_88F6820_GP + config TARGET_DB_88F6820_GP bool "Support DB-88F6820-GP" + select DB_88F6820_GP config TARGET_DB_MV784MP_GP bool "Support db-mv784mp-gp" + select MV78460 + +config TARGET_DS414 + bool "Support Synology DS414" + select MV78230 config TARGET_MAXBCM bool "Support maxbcm" + select MV78460 endchoice -config SYS_SOC - default "mvebu" +config SYS_BOARD + default "clearfog" if TARGET_CLEARFOG + default "db-88f6820-gp" if TARGET_DB_88F6820_GP + default "db-mv784mp-gp" if TARGET_DB_MV784MP_GP + default "ds414" if TARGET_DS414 + default "maxbcm" if TARGET_MAXBCM -config MVEBU_BOOTROM_UARTBOOT - bool "Use kwboot to boot via BootROM xmodem protocol" - help - This option provides support for booting via the Marvell - xmodem protocol, used by the kwboot tool. +config SYS_CONFIG_NAME + default "clearfog" if TARGET_CLEARFOG + default "db-88f6820-gp" if TARGET_DB_88F6820_GP + default "db-mv784mp-gp" if TARGET_DB_MV784MP_GP + default "ds414" if TARGET_DS414 + default "maxbcm" if TARGET_MAXBCM - Please don't forget to configure the boot device in - the board specific kwbimage.cfg file this way: - BOOT_FROM uart +config SYS_VENDOR + default "Marvell" if TARGET_DB_MV784MP_GP + default "Marvell" if TARGET_DB_88F6820_GP + default "solidrun" if TARGET_CLEARFOG + default "Synology" if TARGET_DS414 + +config SYS_SOC + default "mvebu" endif diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index 21c56a4d96..b96b81bd39 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile @@ -15,8 +15,8 @@ else obj-y = cpu.o obj-y += dram.o ifndef CONFIG_SPL_BUILD -obj-$(CONFIG_SYS_MVEBU_DDR_A38X) += ../../../drivers/ddr/marvell/a38x/xor.o -obj-$(CONFIG_SYS_MVEBU_DDR_AXP) += ../../../drivers/ddr/marvell/axp/xor.o +obj-$(CONFIG_ARMADA_38X) += ../../../drivers/ddr/marvell/a38x/xor.o +obj-$(CONFIG_ARMADA_XP) += ../../../drivers/ddr/marvell/axp/xor.o endif obj-y += gpio.o obj-y += mbus.o @@ -24,7 +24,7 @@ obj-y += timer.o obj-$(CONFIG_SPL_BUILD) += spl.o obj-$(CONFIG_SPL_BUILD) += lowlevel_spl.o -obj-$(CONFIG_SYS_MVEBU_DDR_A38X) += serdes/a38x/ -obj-$(CONFIG_SYS_MVEBU_DDR_AXP) += serdes/axp/ +obj-$(CONFIG_ARMADA_38X) += serdes/a38x/ +obj-$(CONFIG_ARMADA_XP) += serdes/axp/ endif diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c index 895ad929b1..30b175c646 100644 --- a/arch/arm/mach-mvebu/cpu.c +++ b/arch/arm/mach-mvebu/cpu.c @@ -1,11 +1,10 @@ /* - * Copyright (C) 2014-2015 Stefan Roese <sr@denx.de> + * Copyright (C) 2014-2016 Stefan Roese <sr@denx.de> * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> -#include <netdev.h> #include <ahci.h> #include <linux/mbus.h> #include <asm/io.h> @@ -50,25 +49,106 @@ int mvebu_soc_family(void) { u16 devid = (readl(MVEBU_REG_PCIE_DEVID) >> 16) & 0xffff; - if (devid == SOC_MV78460_ID) + switch (devid) { + case SOC_MV78230_ID: + case SOC_MV78260_ID: + case SOC_MV78460_ID: return MVEBU_SOC_AXP; - - if (devid == SOC_88F6810_ID || devid == SOC_88F6820_ID || - devid == SOC_88F6828_ID) + case SOC_88F6810_ID: + case SOC_88F6820_ID: + case SOC_88F6828_ID: return MVEBU_SOC_A38X; - + } return MVEBU_SOC_UNKNOWN; } #if defined(CONFIG_DISPLAY_CPUINFO) + +#if defined(CONFIG_ARMADA_38X) +/* SAR frequency values for Armada 38x */ +static const struct sar_freq_modes sar_freq_tab[] = { + { 0x0, 0x0, 666, 333, 333 }, + { 0x2, 0x0, 800, 400, 400 }, + { 0x4, 0x0, 1066, 533, 533 }, + { 0x6, 0x0, 1200, 600, 600 }, + { 0x8, 0x0, 1332, 666, 666 }, + { 0xc, 0x0, 1600, 800, 800 }, + { 0xff, 0xff, 0, 0, 0 } /* 0xff marks end of array */ +}; +#else +/* SAR frequency values for Armada XP */ +static const struct sar_freq_modes sar_freq_tab[] = { + { 0xa, 0x5, 800, 400, 400 }, + { 0x1, 0x5, 1066, 533, 533 }, + { 0x2, 0x5, 1200, 600, 600 }, + { 0x2, 0x9, 1200, 600, 400 }, + { 0x3, 0x5, 1333, 667, 667 }, + { 0x4, 0x5, 1500, 750, 750 }, + { 0x4, 0x9, 1500, 750, 500 }, + { 0xb, 0x9, 1600, 800, 533 }, + { 0xb, 0xa, 1600, 800, 640 }, + { 0xb, 0x5, 1600, 800, 800 }, + { 0xff, 0xff, 0, 0, 0 } /* 0xff marks end of array */ +}; +#endif + +void get_sar_freq(struct sar_freq_modes *sar_freq) +{ + u32 val; + u32 freq; + int i; + + val = readl(CONFIG_SAR_REG); /* SAR - Sample At Reset */ + freq = (val & SAR_CPU_FREQ_MASK) >> SAR_CPU_FREQ_OFFS; +#if !defined(CONFIG_ARMADA_38X) + /* + * Shift CPU0 clock frequency select bit from SAR2 register + * into correct position + */ + freq |= ((readl(CONFIG_SAR2_REG) & SAR2_CPU_FREQ_MASK) + >> SAR2_CPU_FREQ_OFFS) << 3; +#endif + for (i = 0; sar_freq_tab[i].val != 0xff; i++) { + if (sar_freq_tab[i].val == freq) { +#if defined(CONFIG_ARMADA_38X) + *sar_freq = sar_freq_tab[i]; + return; +#else + int k; + u8 ffc; + + ffc = (val & SAR_FFC_FREQ_MASK) >> + SAR_FFC_FREQ_OFFS; + for (k = i; sar_freq_tab[k].ffc != 0xff; k++) { + if (sar_freq_tab[k].ffc == ffc) { + *sar_freq = sar_freq_tab[k]; + return; + } + } + i = k; +#endif + } + } + + /* SAR value not found, return 0 for frequencies */ + *sar_freq = sar_freq_tab[i - 1]; +} + int print_cpuinfo(void) { u16 devid = (readl(MVEBU_REG_PCIE_DEVID) >> 16) & 0xffff; u8 revid = readl(MVEBU_REG_PCIE_REVID) & 0xff; + struct sar_freq_modes sar_freq; puts("SoC: "); switch (devid) { + case SOC_MV78230_ID: + puts("MV78230-"); + break; + case SOC_MV78260_ID: + puts("MV78260-"); + break; case SOC_MV78460_ID: puts("MV78460-"); break; @@ -89,13 +169,13 @@ int print_cpuinfo(void) if (mvebu_soc_family() == MVEBU_SOC_AXP) { switch (revid) { case 1: - puts("A0\n"); + puts("A0"); break; case 2: - puts("B0\n"); + puts("B0"); break; default: - printf("?? (%x)\n", revid); + printf("?? (%x)", revid); break; } } @@ -103,17 +183,20 @@ int print_cpuinfo(void) if (mvebu_soc_family() == MVEBU_SOC_A38X) { switch (revid) { case MV_88F68XX_Z1_ID: - puts("Z1\n"); + puts("Z1"); break; case MV_88F68XX_A0_ID: - puts("A0\n"); + puts("A0"); break; default: - printf("?? (%x)\n", revid); + printf("?? (%x)", revid); break; } } + get_sar_freq(&sar_freq); + printf(" at %d MHz\n", sar_freq.p_clk); + return 0; } #endif /* CONFIG_DISPLAY_CPUINFO */ @@ -199,10 +282,10 @@ static void setup_usb_phys(void) clrsetbits_le32(MV_USB_PHY_PLL_REG(1), 0x3ff, 0x605); /* Power up PLL and PHY channel */ - clrsetbits_le32(MV_USB_PHY_PLL_REG(2), 0, BIT(9)); + setbits_le32(MV_USB_PHY_PLL_REG(2), BIT(9)); /* Assert VCOCAL_START */ - clrsetbits_le32(MV_USB_PHY_PLL_REG(1), 0, BIT(21)); + setbits_le32(MV_USB_PHY_PLL_REG(1), BIT(21)); mdelay(1); @@ -211,18 +294,20 @@ static void setup_usb_phys(void) */ for (dev = 0; dev < 3; dev++) { - clrsetbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 3), 0, BIT(15)); + setbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 3), BIT(15)); /* Assert REG_RCAL_START in channel REG 1 */ - clrsetbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 1), 0, BIT(12)); + setbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 1), BIT(12)); udelay(40); - clrsetbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 1), BIT(12), 0); + clrbits_le32(MV_USB_X3_PHY_CHANNEL(dev, 1), BIT(12)); } } +/* + * This function is not called from the SPL U-Boot version + */ int arch_cpu_init(void) { -#if !defined(CONFIG_SPL_BUILD) struct pl310_regs *const pl310 = (struct pl310_regs *)CONFIG_SYS_PL310_BASE; @@ -233,27 +318,26 @@ int arch_cpu_init(void) * still locked to cache. */ mmu_disable(); -#endif /* Linux expects the internal registers to be at 0xf1000000 */ writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG); set_cbar(SOC_REGS_PHY_BASE + 0xC000); -#if !defined(CONFIG_SPL_BUILD) /* * From this stage on, the SoC detection is working. As we have * configured the internal register base to the value used * in the macros / defines in the U-Boot header (soc.h). */ - /* - * To fully release / unlock this area from cache, we need - * to flush all caches and disable the L2 cache. - */ - icache_disable(); - dcache_disable(); - clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); -#endif + if (mvebu_soc_family() == MVEBU_SOC_A38X) { + /* + * To fully release / unlock this area from cache, we need + * to flush all caches and disable the L2 cache. + */ + icache_disable(); + dcache_disable(); + clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); + } /* * We need to call mvebu_mbus_probe() before calling @@ -326,30 +410,6 @@ int arch_misc_init(void) } #endif /* CONFIG_ARCH_MISC_INIT */ -#ifdef CONFIG_MVNETA -int cpu_eth_init(bd_t *bis) -{ - u32 enet_base[] = { MVEBU_EGIGA0_BASE, MVEBU_EGIGA1_BASE, - MVEBU_EGIGA2_BASE, MVEBU_EGIGA3_BASE }; - u8 phy_addr[] = CONFIG_PHY_ADDR; - int i; - - /* - * Only Armada XP supports all 4 ethernet interfaces. A38x has - * slightly different base addresses for its 2-3 interfaces. - */ - if (mvebu_soc_family() != MVEBU_SOC_AXP) { - enet_base[1] = MVEBU_EGIGA2_BASE; - enet_base[2] = MVEBU_EGIGA3_BASE; - } - - for (i = 0; i < ARRAY_SIZE(phy_addr); i++) - mvneta_initialize(bis, enet_base[i], i, phy_addr[i]); - - return 0; -} -#endif - #ifdef CONFIG_MV_SDHCI int board_mmc_init(bd_t *bis) { @@ -413,20 +473,43 @@ void scsi_init(void) } #endif -#ifndef CONFIG_SYS_DCACHE_OFF void enable_caches(void) { - struct pl310_regs *const pl310 = - (struct pl310_regs *)CONFIG_SYS_PL310_BASE; - - /* First disable L2 cache - may still be enable from BootROM */ - if (mvebu_soc_family() == MVEBU_SOC_A38X) - clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); - /* Avoid problem with e.g. neta ethernet driver */ invalidate_dcache_all(); /* Enable D-cache. I-cache is already enabled in start.S */ dcache_enable(); } -#endif + +void v7_outer_cache_enable(void) +{ + if (mvebu_soc_family() == MVEBU_SOC_AXP) { + struct pl310_regs *const pl310 = + (struct pl310_regs *)CONFIG_SYS_PL310_BASE; + u32 u; + + /* The L2 cache is already disabled at this point */ + + /* + * For Aurora cache in no outer mode, enable via the CP15 + * coprocessor broadcasting of cache commands to L2. + */ + asm volatile("mrc p15, 1, %0, c15, c2, 0" : "=r" (u)); + u |= BIT(8); /* Set the FW bit */ + asm volatile("mcr p15, 1, %0, c15, c2, 0" : : "r" (u)); + + isb(); + + /* Enable the L2 cache */ + setbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); + } +} + +void v7_outer_cache_disable(void) +{ + struct pl310_regs *const pl310 = + (struct pl310_regs *)CONFIG_SYS_PL310_BASE; + + clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); +} diff --git a/arch/arm/mach-mvebu/dram.c b/arch/arm/mach-mvebu/dram.c index ddc5b7ee3e..a8ec5ea21b 100644 --- a/arch/arm/mach-mvebu/dram.c +++ b/arch/arm/mach-mvebu/dram.c @@ -12,11 +12,8 @@ #include <asm/arch/cpu.h> #include <asm/arch/soc.h> -#ifdef CONFIG_SYS_MVEBU_DDR_A38X -#include "../../../drivers/ddr/marvell/axp/xor.h" -#include "../../../drivers/ddr/marvell/axp/xor_regs.h" -#endif -#ifdef CONFIG_SYS_MVEBU_DDR_AXP +#if defined(CONFIG_ARCH_MVEBU) +/* Use common XOR definitions for A3x and AXP */ #include "../../../drivers/ddr/marvell/axp/xor.h" #include "../../../drivers/ddr/marvell/axp/xor_regs.h" #endif @@ -112,7 +109,7 @@ void mvebu_sdram_size_adjust(enum memory_bank bank) mvebu_sdram_bs_set(bank, size); } -#if defined(CONFIG_SYS_MVEBU_DDR_A38X) || defined(CONFIG_SYS_MVEBU_DDR_AXP) +#if defined(CONFIG_ARCH_MVEBU) static u32 xor_ctrl_save; static u32 xor_base_save; static u32 xor_mask_save; @@ -292,11 +289,18 @@ void dram_init_banksize(void) } } +#if defined(CONFIG_ARCH_MVEBU) void board_add_ram_info(int use_default) { + struct sar_freq_modes sar_freq; + + get_sar_freq(&sar_freq); + printf(" (%d MHz, ", sar_freq.d_clk); + if (ecc_enabled()) - printf(" (ECC"); + printf("ECC"); else - printf(" (ECC not"); + printf("ECC not"); printf(" enabled)"); } +#endif diff --git a/arch/arm/mach-mvebu/include/mach/config.h b/arch/arm/mach-mvebu/include/mach/config.h index 1d49cab7fd..cc1fc5f9d4 100644 --- a/arch/arm/mach-mvebu/include/mach/config.h +++ b/arch/arm/mach-mvebu/include/mach/config.h @@ -17,12 +17,22 @@ #include <asm/arch/soc.h> -#if defined(CONFIG_ARMADA_XP) +#if defined(CONFIG_ARMADA_XP) || defined(CONFIG_ARMADA_38X) +/* + * Set this for the common xor register definitions needed in dram.c + * for A38x as well here. + */ #define MV88F78X60 /* for the DDR training bin_hdr code */ #endif #define CONFIG_SYS_CACHELINE_SIZE 32 +#define CONFIG_SYS_L2_PL310 + +#ifdef CONFIG_SPL_BUILD +#define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */ +#endif + /* * By default kwbimage.cfg from board specific folder is used * If for some board, different configuration file need to be used, @@ -47,8 +57,7 @@ * SPI Flash configuration */ #ifdef CONFIG_CMD_SF -#define CONFIG_HARD_SPI 1 -#define CONFIG_KIRKWOOD_SPI 1 +#define CONFIG_KIRKWOOD_SPI #ifndef CONFIG_ENV_SPI_BUS # define CONFIG_ENV_SPI_BUS 0 #endif @@ -60,6 +69,9 @@ #endif #endif +/* Needed for SPI NOR booting in SPL */ +#define CONFIG_DM_SEQ_ALIAS 1 + /* * Ethernet Driver configuration */ @@ -85,9 +97,9 @@ #define CONFIG_SYS_I2C_SPEED 100000 #endif -/* Common SPL configuration */ -#ifndef CONFIG_SPL_LDSCRIPT -#define CONFIG_SPL_LDSCRIPT "arch/arm/mach-mvebu/u-boot-spl.lds" -#endif +/* Use common timer */ +#define CONFIG_SYS_TIMER_COUNTS_DOWN +#define CONFIG_SYS_TIMER_COUNTER (MVEBU_TIMER_BASE + 0x14) +#define CONFIG_SYS_TIMER_RATE 25000000 #endif /* __MVEBU_CONFIG_H */ diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h index 5e8bf0c4ce..47f45c1512 100644 --- a/arch/arm/mach-mvebu/include/mach/cpu.h +++ b/arch/arm/mach-mvebu/include/mach/cpu.h @@ -106,6 +106,14 @@ struct kwgpio_registers { u32 irq_level; }; +struct sar_freq_modes { + u8 val; + u8 ffc; /* Fabric Frequency Configuration */ + u32 p_clk; + u32 nb_clk; + u32 d_clk; +}; + /* Needed for dynamic (board-specific) mbus configuration */ extern struct mvebu_mbus_state mbus_state; @@ -123,6 +131,8 @@ void return_to_bootrom(void); int mv_sdh_init(unsigned long regbase, u32 max_clk, u32 min_clk, u32 quirks); +void get_sar_freq(struct sar_freq_modes *sar_freq); + /* * Highspeed SERDES PHY config init, ported from bin_hdr * to mainline U-Boot diff --git a/arch/arm/mach-mvebu/include/mach/soc.h b/arch/arm/mach-mvebu/include/mach/soc.h index 22abde080e..cb216bc2cc 100644 --- a/arch/arm/mach-mvebu/include/mach/soc.h +++ b/arch/arm/mach-mvebu/include/mach/soc.h @@ -11,6 +11,8 @@ #ifndef _MVEBU_SOC_H #define _MVEBU_SOC_H +#define SOC_MV78230_ID 0x7823 +#define SOC_MV78260_ID 0x7826 #define SOC_MV78460_ID 0x7846 #define SOC_88F6810_ID 0x6810 #define SOC_88F6820_ID 0x6820 @@ -33,10 +35,11 @@ #define INTREG_BASE_ADDR_REG (INTREG_BASE + 0x20080) #if defined(CONFIG_SPL_BUILD) /* - * On A38x switching the regs base address without running from - * SDRAM doesn't seem to work. So let the SPL still use the - * default base address and switch to the new address in the - * main u-boot later. + * The SPL U-Boot version still runs with the default + * address for the internal registers, configured by + * the BootROM. Only the main U-Boot version uses the + * new internal register base address, that also is + * required for the Linux kernel. */ #define SOC_REGS_PHY_BASE 0xd0000000 #else @@ -47,10 +50,7 @@ #define MVEBU_SDRAM_SCRATCH (MVEBU_REGISTER(0x01504)) #define MVEBU_L2_CACHE_BASE (MVEBU_REGISTER(0x08000)) #define CONFIG_SYS_PL310_BASE MVEBU_L2_CACHE_BASE -#define MVEBU_SPI_BASE (MVEBU_REGISTER(0x10600)) #define MVEBU_TWSI_BASE (MVEBU_REGISTER(0x11000)) -#define MVEBU_UART0_BASE (MVEBU_REGISTER(0x12000)) -#define MVEBU_UART1_BASE (MVEBU_REGISTER(0x12100)) #define MVEBU_MPP_BASE (MVEBU_REGISTER(0x18000)) #define MVEBU_GPIO0_BASE (MVEBU_REGISTER(0x18100)) #define MVEBU_GPIO1_BASE (MVEBU_REGISTER(0x18140)) @@ -60,13 +60,9 @@ #define MVEBU_CPU_WIN_BASE (MVEBU_REGISTER(0x20000)) #define MVEBU_SDRAM_BASE (MVEBU_REGISTER(0x20180)) #define MVEBU_TIMER_BASE (MVEBU_REGISTER(0x20300)) -#define MVEBU_EGIGA2_BASE (MVEBU_REGISTER(0x30000)) -#define MVEBU_EGIGA3_BASE (MVEBU_REGISTER(0x34000)) #define MVEBU_REG_PCIE_BASE (MVEBU_REGISTER(0x40000)) #define MVEBU_AXP_USB_BASE (MVEBU_REGISTER(0x50000)) #define MVEBU_USB20_BASE (MVEBU_REGISTER(0x58000)) -#define MVEBU_EGIGA0_BASE (MVEBU_REGISTER(0x70000)) -#define MVEBU_EGIGA1_BASE (MVEBU_REGISTER(0x74000)) #define MVEBU_AXP_SATA_BASE (MVEBU_REGISTER(0xa0000)) #define MVEBU_SATA0_BASE (MVEBU_REGISTER(0xa8000)) #define MVEBU_NAND_BASE (MVEBU_REGISTER(0xd0000)) @@ -101,4 +97,49 @@ #define MVCPU_WIN_ENABLE CPU_WIN_ENABLE #define MVCPU_WIN_DISABLE CPU_WIN_DISABLE +#define COMPHY_REFCLK_ALIGNMENT (MVEBU_REGISTER(0x182f8)) + +/* BootROM error register (also includes some status infos) */ +#define CONFIG_BOOTROM_ERR_REG (MVEBU_REGISTER(0x182d0)) +#define BOOTROM_ERR_MODE_OFFS 28 +#define BOOTROM_ERR_MODE_MASK (0xf << BOOTROM_ERR_MODE_OFFS) +#define BOOTROM_ERR_MODE_UART 0x6 + +#if defined(CONFIG_ARMADA_38X) +/* SAR values for Armada 38x */ +#define CONFIG_SAR_REG (MVEBU_REGISTER(0x18600)) + +#define SAR_CPU_FREQ_OFFS 10 +#define SAR_CPU_FREQ_MASK (0x1f << SAR_CPU_FREQ_OFFS) +#define SAR_BOOT_DEVICE_OFFS 4 +#define SAR_BOOT_DEVICE_MASK (0x1f << SAR_BOOT_DEVICE_OFFS) + +#define BOOT_DEV_SEL_OFFS 4 +#define BOOT_DEV_SEL_MASK (0x3f << BOOT_DEV_SEL_OFFS) + +#define BOOT_FROM_UART 0x28 +#define BOOT_FROM_SPI 0x32 +#define BOOT_FROM_MMC 0x30 +#define BOOT_FROM_MMC_ALT 0x31 +#else +/* SAR values for Armada XP */ +#define CONFIG_SAR_REG (MVEBU_REGISTER(0x18230)) +#define CONFIG_SAR2_REG (MVEBU_REGISTER(0x18234)) + +#define SAR_CPU_FREQ_OFFS 21 +#define SAR_CPU_FREQ_MASK (0x7 << SAR_CPU_FREQ_OFFS) +#define SAR_FFC_FREQ_OFFS 24 +#define SAR_FFC_FREQ_MASK (0xf << SAR_FFC_FREQ_OFFS) +#define SAR2_CPU_FREQ_OFFS 20 +#define SAR2_CPU_FREQ_MASK (0x1 << SAR2_CPU_FREQ_OFFS) +#define SAR_BOOT_DEVICE_OFFS 5 +#define SAR_BOOT_DEVICE_MASK (0xf << SAR_BOOT_DEVICE_OFFS) + +#define BOOT_DEV_SEL_OFFS 5 +#define BOOT_DEV_SEL_MASK (0xf << BOOT_DEV_SEL_OFFS) + +#define BOOT_FROM_UART 0x2 +#define BOOT_FROM_SPI 0x3 +#endif + #endif /* _MVEBU_SOC_H */ diff --git a/arch/arm/mach-mvebu/lowlevel_spl.S b/arch/arm/mach-mvebu/lowlevel_spl.S index 2e2181ecea..49e0b906d5 100644 --- a/arch/arm/mach-mvebu/lowlevel_spl.S +++ b/arch/arm/mach-mvebu/lowlevel_spl.S @@ -5,7 +5,6 @@ #include <config.h> #include <linux/linkage.h> -#ifdef CONFIG_MVEBU_BOOTROM_UARTBOOT ENTRY(save_boot_params) stmfd sp!, {r0 - r12, lr} /* @ save registers on stack */ ldr r12, =CONFIG_SPL_BOOTROM_SAVE @@ -19,11 +18,6 @@ ENTRY(return_to_bootrom) mov r0, #0x0 /* @ return value: 0x0 NO_ERR */ ldmfd sp!, {r0 - r12, pc} /* @ restore regs and return */ ENDPROC(return_to_bootrom) -#else -ENTRY(save_boot_params) - b save_boot_params_ret -ENDPROC(save_boot_params) -#endif /* * cache_inv - invalidate Cache line diff --git a/arch/arm/mach-mvebu/mbus.c b/arch/arm/mach-mvebu/mbus.c index 346278e1be..df263bc3b3 100644 --- a/arch/arm/mach-mvebu/mbus.c +++ b/arch/arm/mach-mvebu/mbus.c @@ -491,7 +491,7 @@ int mvebu_mbus_probe(struct mbus_win windows[], int count) #if defined(CONFIG_KIRKWOOD) mbus_state.soc = &kirkwood_mbus_data; #endif -#if defined(CONFIG_ARMADA_XP) +#if defined(CONFIG_ARCH_MVEBU) mbus_state.soc = &armada_370_xp_mbus_data; #endif diff --git a/arch/arm/mach-mvebu/serdes/axp/board_env_spec.h b/arch/arm/mach-mvebu/serdes/axp/board_env_spec.h index 36e0ed80f0..c8d9485b7b 100644 --- a/arch/arm/mach-mvebu/serdes/axp/board_env_spec.h +++ b/arch/arm/mach-mvebu/serdes/axp/board_env_spec.h @@ -32,7 +32,7 @@ #define BOARD_ID_BASE 0x0 /* New board ID numbers */ -#define DB_88F78XX0_BP_ID (BOARD_ID_BASE) +#define DB_88F78XX0_BP_ID (BOARD_ID_BASE + 1) #define RD_78460_SERVER_ID (DB_88F78XX0_BP_ID + 1) #define DB_78X60_PCAC_ID (RD_78460_SERVER_ID + 1) #define FPGA_88F78XX0_ID (DB_78X60_PCAC_ID + 1) @@ -44,7 +44,7 @@ #define DB_784MP_GP_ID (RD_78460_SERVER_REV2_ID + 1) #define RD_78460_CUSTOMER_ID (DB_784MP_GP_ID + 1) #define MV_MAX_BOARD_ID (RD_78460_CUSTOMER_ID + 1) -#define INVALID_BAORD_ID 0xFFFFFFFF +#define INVALID_BOARD_ID 0xFFFFFFFF /* Sample at Reset */ #define MPP_SAMPLE_AT_RESET(id) (0x18230 + (id * 4)) diff --git a/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c b/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c index 702273aee1..afc0cefda3 100644 --- a/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c +++ b/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c @@ -75,16 +75,24 @@ static u32 board_id_get(void) #endif } -static u8 board_sat_r_get(u8 dev_num, u8 reg) +__weak u8 board_sat_r_get(u8 dev_num, u8 reg) { u8 data; u8 *dev; u32 board_id = board_id_get(); int ret; - i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); - switch (board_id) { + case DB_78X60_AMC_ID: + case DB_78X60_PCAC_REV2_ID: + case RD_78460_CUSTOMER_ID: + case RD_78460_SERVER_ID: + case RD_78460_SERVER_REV2_ID: + case DB_78X60_PCAC_ID: + return (0x1 << 1) | 1; + case FPGA_88F78XX0_ID: + case RD_78460_NAS_ID: + return (0x0 << 1) | 1; case DB_784MP_GP_ID: dev = rd78460gp_twsi_dev; @@ -94,15 +102,12 @@ static u8 board_sat_r_get(u8 dev_num, u8 reg) dev = db88f78xx0rev2_twsi_dev; break; - case DB_78X60_PCAC_ID: - case FPGA_88F78XX0_ID: - case DB_78X60_PCAC_REV2_ID: - case RD_78460_SERVER_REV2_ID: default: return 0; } /* Read MPP module ID */ + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); ret = i2c_read(dev[dev_num], 0, 1, (u8 *)&data, 1); if (ret) return MV_ERROR; @@ -190,8 +195,17 @@ __weak MV_BIN_SERDES_CFG *board_serdes_cfg_get(u8 pex_mode) u16 ctrl_model_get(void) { - /* Right now only MV78460 supported */ + /* + * SoC version can't be autodetected. So we need to rely on a define + * from the config system here. + */ +#if defined(CONFIG_MV78230) + return MV_78230_DEV_ID; +#elif defined(CONFIG_MV78260) + return MV_78260_DEV_ID; +#else return MV_78460_DEV_ID; +#endif } u32 get_line_cfg(u32 line_num, MV_BIN_SERDES_CFG *info) @@ -202,6 +216,20 @@ u32 get_line_cfg(u32 line_num, MV_BIN_SERDES_CFG *info) return (info->line8_15 >> ((line_num - 8) << 2)) & 0xF; } +static int serdes_max_lines_get(void) +{ + switch (ctrl_model_get()) { + case MV_78230_DEV_ID: + return 7; + case MV_78260_DEV_ID: + return 12; + case MV_78460_DEV_ID: + return 16; + } + + return 0; +} + int serdes_phy_config(void) { int status = MV_OK; @@ -221,39 +249,19 @@ int serdes_phy_config(void) u8 device_rev; u32 rx_high_imp_mode; u16 ctrl_mode; - u32 board_id = board_id_get(); u32 pex_if; u32 pex_if_num; /* - * TODO: - * Right now we only support the MV78460 with 16 serdes lines + * Get max. serdes lines count */ - max_serdes_lines = 16; + max_serdes_lines = serdes_max_lines_get(); if (max_serdes_lines == 0) return MV_OK; - switch (board_id) { - case DB_78X60_AMC_ID: - case DB_78X60_PCAC_REV2_ID: - case RD_78460_CUSTOMER_ID: - case RD_78460_SERVER_ID: - case RD_78460_SERVER_REV2_ID: - case DB_78X60_PCAC_ID: - satr11 = (0x1 << 1) | 1; - break; - case FPGA_88F78XX0_ID: - case RD_78460_NAS_ID: - satr11 = (0x0 << 1) | 1; - break; - case DB_88F78XX0_BP_REV2_ID: - case DB_784MP_GP_ID: - case DB_88F78XX0_BP_ID: - satr11 = board_sat_r_get(1, 1); - if ((u8) MV_ERROR == (u8) satr11) - return MV_ERROR; - break; - } + satr11 = board_sat_r_get(1, 1); + if ((u8) MV_ERROR == (u8) satr11) + return MV_ERROR; board_modules_scan(); memset(addr, 0, sizeof(addr)); @@ -1356,19 +1364,19 @@ int serdes_phy_config(void) pex_if, PEX_DEVICE_AND_VENDOR_ID)); devId &= 0xFFFF; devId |= ((ctrl_mode << 16) & 0xffff0000); - DEBUG_INIT_S("Update Device ID PEX"); - DEBUG_INIT_D(pex_if, 1); - DEBUG_INIT_D(devId, 8); - DEBUG_INIT_S("\n"); + DEBUG_INIT_FULL_S("Update Device ID PEX"); + DEBUG_INIT_FULL_D(pex_if, 1); + DEBUG_INIT_FULL_D(devId, 8); + DEBUG_INIT_FULL_S("\n"); reg_write(PEX_CFG_DIRECT_ACCESS (pex_if, PEX_DEVICE_AND_VENDOR_ID), devId); if ((pex_if < 8) && (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4)) pex_if += 3; } - DEBUG_INIT_S("Update PEX Device ID 0x"); - DEBUG_INIT_D(ctrl_mode, 4); - DEBUG_INIT_S("0\n"); + DEBUG_INIT_FULL_S("Update PEX Device ID 0x"); + DEBUG_INIT_FULL_D(ctrl_mode, 4); + DEBUG_INIT_FULL_S("0\n"); } tmp = reg_read(PEX_DBG_STATUS_REG(0)); DEBUG_RD_REG(PEX_DBG_STATUS_REG(0), tmp); diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c index 0ab729aa5d..0879873b97 100644 --- a/arch/arm/mach-mvebu/spl.c +++ b/arch/arm/mach-mvebu/spl.c @@ -1,10 +1,13 @@ /* - * Copyright (C) 2014 Stefan Roese <sr@denx.de> + * Copyright (C) 2014-2016 Stefan Roese <sr@denx.de> * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <dm.h> +#include <debug_uart.h> +#include <fdtdec.h> #include <spl.h> #include <asm/io.h> #include <asm/arch/cpu.h> @@ -12,14 +15,45 @@ DECLARE_GLOBAL_DATA_PTR; -u32 spl_boot_device(void) +static u32 get_boot_device(void) { -#if defined(CONFIG_SPL_SPI_FLASH_SUPPORT) - return BOOT_DEVICE_SPI; -#endif -#if defined(CONFIG_SPL_MMC_SUPPORT) - return BOOT_DEVICE_MMC1; + u32 val; + u32 boot_device; + + /* + * First check, if UART boot-mode is active. This can only + * be done, via the bootrom error register. Here the + * MSB marks if the UART mode is active. + */ + val = readl(CONFIG_BOOTROM_ERR_REG); + boot_device = (val & BOOTROM_ERR_MODE_MASK) >> BOOTROM_ERR_MODE_OFFS; + debug("BOOTROM_REG=0x%08x boot_device=0x%x\n", val, boot_device); + if (boot_device == BOOTROM_ERR_MODE_UART) + return BOOT_DEVICE_UART; + + /* + * Now check the SAR register for the strapped boot-device + */ + val = readl(CONFIG_SAR_REG); /* SAR - Sample At Reset */ + boot_device = (val & BOOT_DEV_SEL_MASK) >> BOOT_DEV_SEL_OFFS; + debug("SAR_REG=0x%08x boot_device=0x%x\n", val, boot_device); + switch (boot_device) { +#ifdef CONFIG_SPL_MMC_SUPPORT + case BOOT_FROM_MMC: + case BOOT_FROM_MMC_ALT: + return BOOT_DEVICE_MMC1; #endif + case BOOT_FROM_UART: + return BOOT_DEVICE_UART; + case BOOT_FROM_SPI: + default: + return BOOT_DEVICE_SPI; + }; +} + +u32 spl_boot_device(void) +{ + return get_boot_device(); } #ifdef CONFIG_SPL_MMC_SUPPORT @@ -31,18 +65,7 @@ u32 spl_boot_mode(void) void board_init_f(ulong dummy) { -#ifndef CONFIG_MVEBU_BOOTROM_UARTBOOT - /* - * Only call arch_cpu_init() when not returning to the - * Marvell BootROM, which is done when booting via - * the xmodem protocol (kwboot tool). Otherwise the - * internal register will get remapped and the BootROM - * can't continue to run correctly. - */ - - /* Linux expects the internal registers to be at 0xf1000000 */ - arch_cpu_init(); -#endif + int ret; /* * Pin muxing needs to be done before UART output, since @@ -51,6 +74,27 @@ void board_init_f(ulong dummy) */ board_early_init_f(); + /* Example code showing how to enable the debug UART on MVEBU */ +#ifdef EARLY_UART + /* + * Debug UART can be used from here if required: + * + * debug_uart_init(); + * printch('a'); + * printhex8(0x1234); + * printascii("string"); + */ +#endif + + ret = spl_init(); + if (ret) { + debug("spl_init() failed: %d\n", ret); + hang(); + } + + /* Use special translation offset for SPL */ + dm_set_translation_offset(0xd0000000 - 0xf1000000); + preloader_console_init(); timer_init(); @@ -61,7 +105,6 @@ void board_init_f(ulong dummy) /* Setup DDR */ ddr3_init(); -#ifdef CONFIG_MVEBU_BOOTROM_UARTBOOT /* * Return to the BootROM to continue the Marvell xmodem * UART boot protocol. As initiated by the kwboot tool. @@ -73,6 +116,6 @@ void board_init_f(ulong dummy) * need to return to the BootROM to enable this xmodem * UART download. */ - return_to_bootrom(); -#endif + if (get_boot_device() == BOOT_DEVICE_UART) + return_to_bootrom(); } diff --git a/arch/arm/mach-mvebu/timer.c b/arch/arm/mach-mvebu/timer.c index 5449a8926c..f5c2eaa808 100644 --- a/arch/arm/mach-mvebu/timer.c +++ b/arch/arm/mach-mvebu/timer.c @@ -2,6 +2,8 @@ * Copyright (C) Marvell International Ltd. and its affiliates * Written-by: Prafulla Wadaskar <prafulla@marvell.com> * + * Copyright (C) 2015 Stefan Roese <sr@denx.de> + * * SPDX-License-Identifier: GPL-2.0+ */ @@ -9,108 +11,14 @@ #include <asm/io.h> #include <asm/arch/soc.h> -#define UBOOT_CNTR 0 /* counter to use for U-Boot timer */ - -/* - * ARM Timers Registers Map - */ -#define CNTMR_CTRL_REG &tmr_regs->ctrl -#define CNTMR_RELOAD_REG(tmrnum) &tmr_regs->tmr[tmrnum].reload -#define CNTMR_VAL_REG(tmrnum) &tmr_regs->tmr[tmrnum].val - -/* - * ARM Timers Control Register - * CPU_TIMERS_CTRL_REG (CTCR) - */ -#define CTCR_ARM_TIMER_EN_OFFS(cntr) (cntr * 2) -#define CTCR_ARM_TIMER_EN(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS(cntr)) - -#define CTCR_ARM_TIMER_AUTO_OFFS(cntr) ((cntr * 2) + 1) -#define CTCR_ARM_TIMER_AUTO_EN(cntr) (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr)) - -/* Only Armada XP have the 25MHz enable bit (Kirkwood doesn't) */ -#if defined(CONFIG_ARMADA_XP) -#define CTCR_ARM_TIMER_25MHZ_OFFS(cntr) (cntr + 11) -#define CTCR_ARM_TIMER_25MHZ(cntr) (1 << CTCR_ARM_TIMER_25MHZ_OFFS(cntr)) -#else -#define CTCR_ARM_TIMER_25MHZ(cntr) 0 -#endif - -#define TIMER_LOAD_VAL 0xffffffff - -#define timestamp gd->arch.tbl -#define lastdec gd->arch.lastinc - -static int init_done __attribute__((section(".data"))) = 0; - -/* Timer reload and current value registers */ -struct kwtmr_val { - u32 reload; /* Timer reload reg */ - u32 val; /* Timer value reg */ -}; - -/* Timer registers */ -struct kwtmr_registers { - u32 ctrl; /* Timer control reg */ - u32 pad[3]; - struct kwtmr_val tmr[4]; - u32 wdt_reload; - u32 wdt_val; -}; - DECLARE_GLOBAL_DATA_PTR; -static struct kwtmr_registers *tmr_regs = - (struct kwtmr_registers *)MVEBU_TIMER_BASE; - -static inline ulong read_timer(void) -{ - return readl(CNTMR_VAL_REG(UBOOT_CNTR)) / (CONFIG_SYS_TCLK / 1000); -} - -ulong get_timer_masked(void) -{ - ulong now = read_timer(); - - if (lastdec >= now) { - /* normal mode */ - timestamp += lastdec - now; - } else { - /* we have an overflow ... */ - timestamp += lastdec + - (TIMER_LOAD_VAL / (CONFIG_SYS_TCLK / 1000)) - now; - } - lastdec = now; +#define TIMER_LOAD_VAL 0xffffffff - return timestamp; -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -void __udelay(unsigned long usec) -{ - uint current; - ulong delayticks; - - current = readl(CNTMR_VAL_REG(UBOOT_CNTR)); - delayticks = (usec * (CONFIG_SYS_TCLK / 1000000)); - - if (current < delayticks) { - delayticks -= current; - while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) < current) ; - while ((TIMER_LOAD_VAL - delayticks) < - readl(CNTMR_VAL_REG(UBOOT_CNTR))) ; - } else { - while (readl(CNTMR_VAL_REG(UBOOT_CNTR)) > - (current - delayticks)) ; - } -} +static int init_done __attribute__((section(".data"))) = 0; /* - * init the counter + * Timer initialization */ int timer_init(void) { @@ -120,35 +28,15 @@ int timer_init(void) init_done = 1; /* load value into timer */ - writel(TIMER_LOAD_VAL, CNTMR_RELOAD_REG(UBOOT_CNTR)); - writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR)); + writel(TIMER_LOAD_VAL, MVEBU_TIMER_BASE + 0x10); + writel(TIMER_LOAD_VAL, MVEBU_TIMER_BASE + 0x14); +#if defined(CONFIG_ARCH_MVEBU) + /* On Armada XP / 38x ..., the 25MHz clock source needs to be enabled */ + setbits_le32(MVEBU_TIMER_BASE + 0x00, BIT(11)); +#endif /* enable timer in auto reload mode */ - clrsetbits_le32(CNTMR_CTRL_REG, CTCR_ARM_TIMER_25MHZ(UBOOT_CNTR), - CTCR_ARM_TIMER_EN(UBOOT_CNTR) | - CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR)); - - /* init the timestamp and lastdec value */ - lastdec = read_timer(); - timestamp = 0; + setbits_le32(MVEBU_TIMER_BASE + 0x00, 0x3); return 0; } - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - return (ulong)CONFIG_SYS_HZ; -} diff --git a/arch/arm/mach-mvebu/u-boot-spl.lds b/arch/arm/mach-mvebu/u-boot-spl.lds deleted file mode 100644 index eee1db49ee..0000000000 --- a/arch/arm/mach-mvebu/u-boot-spl.lds +++ /dev/null @@ -1,57 +0,0 @@ -/* - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> - * - * (C) Copyright 2010 - * Texas Instruments, <www.ti.com> - * Aneesh V <aneesh@ti.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\ - LENGTH = CONFIG_SPL_MAX_SIZE } -MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ - LENGTH = CONFIG_SPL_BSS_MAX_SIZE } - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - .text : - { - __start = .; - arch/arm/cpu/armv7/start.o (.text*) - *(.text*) - *(.vectors) - } >.sram - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram - - . = ALIGN(4); - .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram - - . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*_i2c_*))); - } >.sram - - . = ALIGN(4); - __image_copy_end = .; - - .end : - { - *(.__end) - } - - .bss : - { - . = ALIGN(4); - __bss_start = .; - *(.bss*) - . = ALIGN(4); - __bss_end = .; - } >.sdram -} diff --git a/arch/arm/mvebu-common/Makefile b/arch/arm/mvebu-common/Makefile deleted file mode 100644 index de243feaab..0000000000 --- a/arch/arm/mvebu-common/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# -# (C) Copyright 2009 -# Marvell Semiconductor <www.marvell.com> -# Written-by: Prafulla Wadaskar <prafulla@marvell.com> -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y = dram.o -obj-y += gpio.o -obj-$(CONFIG_ARMADA_XP) += mbus.o -obj-y += timer.o - -obj-y += serdes/ |