[U-Boot] [PATCH 01/15] arm64: mvebu: Rename db-88f7040 files to armada-8k

This moves some of the Armada DB-88F7040 board specific files to a more generic name: armada-8k. This is in preparation for the Armada-8k support which will be added soon. And since both platforms share most devices, lets also share most source files to not duplicate the code here.
Signed-off-by: Stefan Roese sr@denx.de Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- arch/arm/mach-mvebu/Kconfig | 10 +++++----- board/Marvell/mvebu_armada-8k/MAINTAINERS | 6 ++++++ board/Marvell/{mvebu_db-88f7040 => mvebu_armada-8k}/Makefile | 0 board/Marvell/{mvebu_db-88f7040 => mvebu_armada-8k}/board.c | 0 board/Marvell/mvebu_db-88f7040/MAINTAINERS | 6 ------ configs/mvebu_db-88f7040_defconfig | 4 +++- include/configs/{mvebu_db-88f7040.h => mvebu_armada-8k.h} | 6 +++--- 7 files changed, 17 insertions(+), 15 deletions(-) create mode 100644 board/Marvell/mvebu_armada-8k/MAINTAINERS rename board/Marvell/{mvebu_db-88f7040 => mvebu_armada-8k}/Makefile (100%) rename board/Marvell/{mvebu_db-88f7040 => mvebu_armada-8k}/board.c (100%) delete mode 100644 board/Marvell/mvebu_db-88f7040/MAINTAINERS rename include/configs/{mvebu_db-88f7040.h => mvebu_armada-8k.h} (97%)
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 6e8026b..7248fd7 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -77,8 +77,8 @@ config TARGET_DB_88F6820_AMC bool "Support DB-88F6820-AMC" select 88F6820
-config TARGET_MVEBU_DB_88F7040 - bool "Support DB-88F7040 Armada 7040" +config TARGET_MVEBU_ARMADA_8K + bool "Support Armada 7k/8k platforms" select ARMADA_8K
config TARGET_DB_MV784MP_GP @@ -105,7 +105,7 @@ config SYS_BOARD default "db-88f6720" if TARGET_DB_88F6720 default "db-88f6820-gp" if TARGET_DB_88F6820_GP default "db-88f6820-amc" if TARGET_DB_88F6820_AMC - default "mvebu_db-88f7040" if TARGET_MVEBU_DB_88F7040 + default "mvebu_armada-8k" if TARGET_MVEBU_ARMADA_8K default "db-mv784mp-gp" if TARGET_DB_MV784MP_GP default "ds414" if TARGET_DS414 default "maxbcm" if TARGET_MAXBCM @@ -117,7 +117,7 @@ config SYS_CONFIG_NAME default "db-88f6720" if TARGET_DB_88F6720 default "db-88f6820-gp" if TARGET_DB_88F6820_GP default "db-88f6820-amc" if TARGET_DB_88F6820_AMC - default "mvebu_db-88f7040" if TARGET_MVEBU_DB_88F7040 + default "mvebu_armada-8k" if TARGET_MVEBU_ARMADA_8K default "db-mv784mp-gp" if TARGET_DB_MV784MP_GP default "ds414" if TARGET_DS414 default "maxbcm" if TARGET_MAXBCM @@ -129,7 +129,7 @@ config SYS_VENDOR default "Marvell" if TARGET_DB_88F6720 default "Marvell" if TARGET_DB_88F6820_GP default "Marvell" if TARGET_DB_88F6820_AMC - default "Marvell" if TARGET_MVEBU_DB_88F7040 + default "Marvell" if TARGET_MVEBU_ARMADA_8K default "solidrun" if TARGET_CLEARFOG default "Synology" if TARGET_DS414
diff --git a/board/Marvell/mvebu_armada-8k/MAINTAINERS b/board/Marvell/mvebu_armada-8k/MAINTAINERS new file mode 100644 index 0000000..33923ba --- /dev/null +++ b/board/Marvell/mvebu_armada-8k/MAINTAINERS @@ -0,0 +1,6 @@ +MVEBU_ARMADA_8K BOARD +M: Stefan Roese sr@denx.de +S: Maintained +F: board/Marvell/mvebu_armada-8k/ +F: include/configs/mvebu_armada-8k.h +F: configs/mvebu_db-88f7040_defconfig diff --git a/board/Marvell/mvebu_db-88f7040/Makefile b/board/Marvell/mvebu_armada-8k/Makefile similarity index 100% rename from board/Marvell/mvebu_db-88f7040/Makefile rename to board/Marvell/mvebu_armada-8k/Makefile diff --git a/board/Marvell/mvebu_db-88f7040/board.c b/board/Marvell/mvebu_armada-8k/board.c similarity index 100% rename from board/Marvell/mvebu_db-88f7040/board.c rename to board/Marvell/mvebu_armada-8k/board.c diff --git a/board/Marvell/mvebu_db-88f7040/MAINTAINERS b/board/Marvell/mvebu_db-88f7040/MAINTAINERS deleted file mode 100644 index 820461b..0000000 --- a/board/Marvell/mvebu_db-88f7040/MAINTAINERS +++ /dev/null @@ -1,6 +0,0 @@ -MVEBU_DB_88F7040 BOARD -M: Stefan Roese sr@denx.de -S: Maintained -F: board/Marvell/mvebu_db-88f7040/ -F: include/configs/mvebu_db-88f7040.h -F: configs/mvebu_db-88f7040_defconfig diff --git a/configs/mvebu_db-88f7040_defconfig b/configs/mvebu_db-88f7040_defconfig index 81152cd..f153b9c 100644 --- a/configs/mvebu_db-88f7040_defconfig +++ b/configs/mvebu_db-88f7040_defconfig @@ -1,8 +1,9 @@ CONFIG_ARM=y CONFIG_ARCH_MVEBU=y CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_TARGET_MVEBU_DB_88F7040=y +CONFIG_TARGET_MVEBU_ARMADA_8K=y CONFIG_DEFAULT_DEVICE_TREE="armada-7040-db" +CONFIG_SMBIOS_PRODUCT_NAME="" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_SYS_CONSOLE_INFO_QUIET=y @@ -48,3 +49,4 @@ CONFIG_DM_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y +CONFIG_SMBIOS_MANUFACTURER="" diff --git a/include/configs/mvebu_db-88f7040.h b/include/configs/mvebu_armada-8k.h similarity index 97% rename from include/configs/mvebu_db-88f7040.h rename to include/configs/mvebu_armada-8k.h index 6feb8d7..3b35cb3 100644 --- a/include/configs/mvebu_db-88f7040.h +++ b/include/configs/mvebu_armada-8k.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: GPL-2.0+ */
-#ifndef _CONFIG_MVEBU_DB_88F7040_H -#define _CONFIG_MVEBU_DB_88F7040_H +#ifndef _CONFIG_MVEBU_ARMADA_8K_H +#define _CONFIG_MVEBU_ARMADA_8K_H
/* * High Level Configuration Options (easy to change) @@ -128,4 +128,4 @@ #define CONFIG_CMD_PART #define CONFIG_PARTITION_UUIDS
-#endif /* _CONFIG_MVEBU_DB_88F7040_H */ +#endif /* _CONFIG_MVEBU_ARMADA_8K_H */

Add the latest version of the DT files from the Linux kernel.
Signed-off-by: Stefan Roese sr@denx.de Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- arch/arm/dts/armada-8020.dtsi | 56 ++++++++ arch/arm/dts/armada-8040-db.dts | 150 +++++++++++++++++++++ arch/arm/dts/armada-8040.dtsi | 56 ++++++++ arch/arm/dts/armada-cp110-slave.dtsi | 249 +++++++++++++++++++++++++++++++++++ 4 files changed, 511 insertions(+) create mode 100644 arch/arm/dts/armada-8020.dtsi create mode 100644 arch/arm/dts/armada-8040-db.dts create mode 100644 arch/arm/dts/armada-8040.dtsi create mode 100644 arch/arm/dts/armada-cp110-slave.dtsi
diff --git a/arch/arm/dts/armada-8020.dtsi b/arch/arm/dts/armada-8020.dtsi new file mode 100644 index 0000000..048e5cf --- /dev/null +++ b/arch/arm/dts/armada-8020.dtsi @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 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 library 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 library 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 "AS IS", 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. + */ + +/* + * Device Tree file for the Armada 8020 SoC, made of an AP806 Dual and + * two CP110. + */ + +#include "armada-ap806-dual.dtsi" +#include "armada-cp110-master.dtsi" +#include "armada-cp110-slave.dtsi" + +/ { + model = "Marvell Armada 8020"; + compatible = "marvell,armada8020", "marvell,armada-ap806-dual", + "marvell,armada-ap806"; +}; diff --git a/arch/arm/dts/armada-8040-db.dts b/arch/arm/dts/armada-8040-db.dts new file mode 100644 index 0000000..6e6f182 --- /dev/null +++ b/arch/arm/dts/armada-8040-db.dts @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 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 library 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 library 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 "AS IS", 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. + */ + +/* + * Device Tree file for Marvell Armada 8040 Development board platform + */ + +#include "armada-8040.dtsi" + +/ { + model = "Marvell Armada 8040 DB board"; + compatible = "marvell,armada8040-db", "marvell,armada8040", + "marvell,armada-ap806-quad", "marvell,armada-ap806"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@00000000 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <100000>; +}; + +&spi0 { + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <10000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "U-Boot"; + reg = <0 0x200000>; + }; + partition@400000 { + label = "Filesystem"; + reg = <0x200000 0xce0000>; + }; + }; + }; +}; + +/* Accessible over the mini-USB CON9 connector on the main board */ +&uart0 { + status = "okay"; +}; + + +/* CON5 on CP0 expansion */ +&cpm_pcie2 { + status = "okay"; +}; + +&cpm_i2c0 { + status = "okay"; + clock-frequency = <100000>; +}; + +/* CON4 on CP0 expansion */ +&cpm_sata0 { + status = "okay"; +}; + +/* CON9 on CP0 expansion */ +&cpm_usb3_0 { + status = "okay"; +}; + +/* CON10 on CP0 expansion */ +&cpm_usb3_1 { + status = "okay"; +}; + +/* CON5 on CP1 expansion */ +&cps_pcie2 { + status = "okay"; +}; + +&cps_i2c0 { + status = "okay"; + clock-frequency = <100000>; +}; + +/* CON4 on CP1 expansion */ +&cps_sata0 { + status = "okay"; +}; + +/* CON9 on CP1 expansion */ +&cps_usb3_0 { + status = "okay"; +}; + +/* CON10 on CP1 expansion */ +&cps_usb3_1 { + status = "okay"; +}; diff --git a/arch/arm/dts/armada-8040.dtsi b/arch/arm/dts/armada-8040.dtsi new file mode 100644 index 0000000..9c1b28c --- /dev/null +++ b/arch/arm/dts/armada-8040.dtsi @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 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 library 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 library 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 "AS IS", 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. + */ + +/* + * Device Tree file for the Armada 8040 SoC, made of an AP806 Quad and + * two CP110. + */ + +#include "armada-ap806-quad.dtsi" +#include "armada-cp110-master.dtsi" +#include "armada-cp110-slave.dtsi" + +/ { + model = "Marvell Armada 8040"; + compatible = "marvell,armada8040", "marvell,armada-ap806-quad", + "marvell,armada-ap806"; +}; diff --git a/arch/arm/dts/armada-cp110-slave.dtsi b/arch/arm/dts/armada-cp110-slave.dtsi new file mode 100644 index 0000000..842fb33 --- /dev/null +++ b/arch/arm/dts/armada-cp110-slave.dtsi @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 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 library 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 library 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 "AS IS", 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. + */ + +/* + * Device Tree file for Marvell Armada CP110 Slave. + */ + +/ { + cp110-slave { + #address-cells = <2>; + #size-cells = <2>; + compatible = "simple-bus"; + interrupt-parent = <&gic>; + ranges; + + config-space { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + interrupt-parent = <&gic>; + ranges = <0x0 0x0 0xf4000000 0x2000000>; + + cps_syscon0: system-controller@440000 { + compatible = "marvell,cp110-system-controller0", + "syscon"; + reg = <0x440000 0x1000>; + #clock-cells = <2>; + core-clock-output-names = + "cps-apll", "cps-ppv2-core", "cps-eip", + "cps-core", "cps-nand-core"; + gate-clock-output-names = + "cps-audio", "cps-communit", "cps-nand", + "cps-ppv2", "cps-sdio", "cps-mg-domain", + "cps-mg-core", "cps-xor1", "cps-xor0", + "cps-gop-dp", "none", "cps-pcie_x10", + "cps-pcie_x11", "cps-pcie_x4", "cps-pcie-xor", + "cps-sata", "cps-sata-usb", "cps-main", + "cps-sd-mmc", "none", "none", + "cps-slow-io", "cps-usb3h0", "cps-usb3h1", + "cps-usb3dev", "cps-eip150", "cps-eip197"; + }; + + cps_sata0: sata@540000 { + compatible = "marvell,armada-8k-ahci"; + reg = <0x540000 0x30000>; + interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cps_syscon0 1 15>; + status = "disabled"; + }; + + cps_usb3_0: usb3@500000 { + compatible = "marvell,armada-8k-xhci", + "generic-xhci"; + reg = <0x500000 0x4000>; + dma-coherent; + interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cps_syscon0 1 22>; + status = "disabled"; + }; + + cps_usb3_1: usb3@510000 { + compatible = "marvell,armada-8k-xhci", + "generic-xhci"; + reg = <0x510000 0x4000>; + dma-coherent; + interrupts = <GIC_SPI 285 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cps_syscon0 1 23>; + status = "disabled"; + }; + + cps_xor0: xor@6a0000 { + compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; + reg = <0x6a0000 0x1000>, + <0x6b0000 0x1000>; + dma-coherent; + msi-parent = <&gic_v2m0>; + clocks = <&cps_syscon0 1 8>; + }; + + cps_xor1: xor@6c0000 { + compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; + reg = <0x6c0000 0x1000>, + <0x6d0000 0x1000>; + dma-coherent; + msi-parent = <&gic_v2m0>; + clocks = <&cps_syscon0 1 7>; + }; + + cps_spi0: spi@700600 { + compatible = "marvell,armada-380-spi"; + reg = <0x700600 0x50>; + #address-cells = <0x1>; + #size-cells = <0x0>; + cell-index = <1>; + clocks = <&cps_syscon0 0 3>; + status = "disabled"; + }; + + cps_spi1: spi@700680 { + compatible = "marvell,armada-380-spi"; + reg = <0x700680 0x50>; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <2>; + clocks = <&cps_syscon0 1 21>; + status = "disabled"; + }; + + cps_i2c0: i2c@701000 { + compatible = "marvell,mv78230-i2c"; + reg = <0x701000 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cps_syscon0 1 21>; + status = "disabled"; + }; + + cps_i2c1: i2c@701100 { + compatible = "marvell,mv78230-i2c"; + reg = <0x701100 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cps_syscon0 1 21>; + status = "disabled"; + }; + }; + + cps_pcie0: pcie@f4600000 { + compatible = "marvell,armada8k-pcie", "snps,dw-pcie"; + reg = <0 0xf4600000 0 0x10000>, + <0 0xfaf00000 0 0x80000>; + reg-names = "ctrl", "config"; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + dma-coherent; + msi-parent = <&gic_v2m0>; + + bus-range = <0 0xff>; + ranges = + /* downstream I/O */ + <0x81000000 0 0xfd000000 0 0xfd000000 0 0x10000 + /* non-prefetchable memory */ + 0x82000000 0 0xfa000000 0 0xfa000000 0 0xf00000>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>; + num-lanes = <1>; + clocks = <&cps_syscon0 1 13>; + status = "disabled"; + }; + + cps_pcie1: pcie@f4620000 { + compatible = "marvell,armada8k-pcie", "snps,dw-pcie"; + reg = <0 0xf4620000 0 0x10000>, + <0 0xfbf00000 0 0x80000>; + reg-names = "ctrl", "config"; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + dma-coherent; + msi-parent = <&gic_v2m0>; + + bus-range = <0 0xff>; + ranges = + /* downstream I/O */ + <0x81000000 0 0xfd010000 0 0xfd010000 0 0x10000 + /* non-prefetchable memory */ + 0x82000000 0 0xfb000000 0 0xfb000000 0 0xf00000>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>; + + num-lanes = <1>; + clocks = <&cps_syscon0 1 11>; + status = "disabled"; + }; + + cps_pcie2: pcie@f4640000 { + compatible = "marvell,armada8k-pcie", "snps,dw-pcie"; + reg = <0 0xf4640000 0 0x10000>, + <0 0xfcf00000 0 0x80000>; + reg-names = "ctrl", "config"; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + dma-coherent; + msi-parent = <&gic_v2m0>; + + bus-range = <0 0xff>; + ranges = + /* downstream I/O */ + <0x81000000 0 0xfd020000 0 0xfd020000 0 0x10000 + /* non-prefetchable memory */ + 0x82000000 0 0xfc000000 0 0xfc000000 0 0xf00000>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>; + + num-lanes = <1>; + clocks = <&cps_syscon0 1 12>; + status = "disabled"; + }; + }; +};

This patch uses of_machine_is_compatible() to detect the board at runtime and only configured the I2C IO expander for the xHCI power / reset on the DB-88F7040 board. As this code will be used by other Armada-7k/8k ports, its necessary to use this runtime detection here.
Signed-off-by: Stefan Roese sr@denx.de Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- board/Marvell/mvebu_armada-8k/board.c | 146 ++++++++++++++++++---------------- 1 file changed, 78 insertions(+), 68 deletions(-)
diff --git a/board/Marvell/mvebu_armada-8k/board.c b/board/Marvell/mvebu_armada-8k/board.c index 48bd55c..7d1b5d9 100644 --- a/board/Marvell/mvebu_armada-8k/board.c +++ b/board/Marvell/mvebu_armada-8k/board.c @@ -5,6 +5,7 @@ */
#include <common.h> +#include <dm.h> #include <i2c.h> #include <asm/io.h> #include <asm/arch/cpu.h> @@ -12,6 +13,11 @@
DECLARE_GLOBAL_DATA_PTR;
+/* + * Information specific to the DB-88F7040 eval board. We strive to use + * DT for such platform specfic configurations. At some point, this + * might be removed here and implemented via DT. + */ /* IO expander I2C device */ #define I2C_IO_EXP_ADDR 0x21 #define I2C_IO_CFG_REG_0 0x6 @@ -44,45 +50,47 @@ int board_xhci_config(void) int ret; u8 buf[8];
- /* Configure IO exander PCA9555: 7bit address 0x21 */ - ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev); - if (ret) { - printf("Cannot find PCA9555: %d\n", ret); - return 0; - } - - /* - * Read configuration (direction) and set VBUS pin as output - * (reset pin = output) - */ - ret = dm_i2c_read(dev, I2C_IO_CFG_REG_0, buf, 1); - if (ret) { - printf("Failed to read IO expander value via I2C\n"); - return -EIO; - } - buf[0] &= ~I2C_IO_REG_VBUS; - buf[0] &= ~I2C_IO_REG_CL; - ret = dm_i2c_write(dev, I2C_IO_CFG_REG_0, buf, 1); - if (ret) { - printf("Failed to set IO expander via I2C\n"); - return -EIO; - } - - /* Read output value and configure it */ - ret = dm_i2c_read(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); - if (ret) { - printf("Failed to read IO expander value via I2C\n"); - return -EIO; + if (of_machine_is_compatible("marvell,armada7040-db")) { + /* Configure IO exander PCA9555: 7bit address 0x21 */ + ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev); + if (ret) { + printf("Cannot find PCA9555: %d\n", ret); + return 0; + } + + /* + * Read configuration (direction) and set VBUS pin as output + * (reset pin = output) + */ + ret = dm_i2c_read(dev, I2C_IO_CFG_REG_0, buf, 1); + if (ret) { + printf("Failed to read IO expander value via I2C\n"); + return -EIO; + } + buf[0] &= ~I2C_IO_REG_VBUS; + buf[0] &= ~I2C_IO_REG_CL; + ret = dm_i2c_write(dev, I2C_IO_CFG_REG_0, buf, 1); + if (ret) { + printf("Failed to set IO expander via I2C\n"); + return -EIO; + } + + /* Read output value and configure it */ + ret = dm_i2c_read(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); + if (ret) { + printf("Failed to read IO expander value via I2C\n"); + return -EIO; + } + buf[0] &= ~I2C_IO_REG_VBUS; + buf[0] |= I2C_IO_REG_CL; + ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); + if (ret) { + printf("Failed to set IO expander via I2C\n"); + return -EIO; + } + + mdelay(500); /* required delay to let output value settle */ } - buf[0] &= ~I2C_IO_REG_VBUS; - buf[0] |= I2C_IO_REG_CL; - ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); - if (ret) { - printf("Failed to set IO expander via I2C\n"); - return -EIO; - } - - mdelay(500); /* required delay to let output value settle */
return 0; } @@ -93,38 +101,40 @@ int board_xhci_enable(void) int ret; u8 buf[8];
- /* - * This function enables all USB ports simultaniously, - * it only needs to get called once - */ - if (usb_enabled) - return 0; - - /* Configure IO exander PCA9555: 7bit address 0x21 */ - ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev); - if (ret) { - printf("Cannot find PCA9555: %d\n", ret); - return 0; - } - - /* Read VBUS output value */ - ret = dm_i2c_read(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); - if (ret) { - printf("Failed to read IO expander value via I2C\n"); - return -EIO; + if (of_machine_is_compatible("marvell,armada7040-db")) { + /* + * This function enables all USB ports simultaniously, + * it only needs to get called once + */ + if (usb_enabled) + return 0; + + /* Configure IO exander PCA9555: 7bit address 0x21 */ + ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev); + if (ret) { + printf("Cannot find PCA9555: %d\n", ret); + return 0; + } + + /* Read VBUS output value */ + ret = dm_i2c_read(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); + if (ret) { + printf("Failed to read IO expander value via I2C\n"); + return -EIO; + } + + /* Enable VBUS power: Set output value of VBUS pin as enabled */ + buf[0] |= I2C_IO_REG_VBUS; + ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); + if (ret) { + printf("Failed to set IO expander via I2C\n"); + return -EIO; + } + + mdelay(500); /* required delay to let output value settle */ + usb_enabled = 1; }
- /* Enable VBUS power: Set output value of VBUS pin as enabled */ - buf[0] |= I2C_IO_REG_VBUS; - ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); - if (ret) { - printf("Failed to set IO expander via I2C\n"); - return -EIO; - } - - mdelay(500); /* required delay to let output value settle */ - usb_enabled = 1; - return 0; }

To enable access to the slave CP its memory needs to be added to the MMU memory map.
Signed-off-by: Stefan Roese sr@denx.de Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- arch/arm/mach-mvebu/armada8k/cpu.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-mvebu/armada8k/cpu.c b/arch/arm/mach-mvebu/armada8k/cpu.c index 036430c..f8e69d6 100644 --- a/arch/arm/mach-mvebu/armada8k/cpu.c +++ b/arch/arm/mach-mvebu/armada8k/cpu.c @@ -39,7 +39,7 @@ static struct mm_region mvebu_mem_map[] = { PTE_BLOCK_NON_SHARE }, { - /* SRAM, MMIO regions - CP110 region */ + /* SRAM, MMIO regions - CP110 master region */ .phys = 0xf2000000UL, .virt = 0xf2000000UL, .size = 0x02000000UL, /* 32MiB internal registers */ @@ -47,6 +47,14 @@ static struct mm_region mvebu_mem_map[] = { PTE_BLOCK_NON_SHARE }, { + /* SRAM, MMIO regions - CP110 slave region */ + .phys = 0xf4000000UL, + .virt = 0xf4000000UL, + .size = 0x02000000UL, /* 32MiB internal registers */ + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE + }, + { /* List terminator */ 0, }

This patch adds the necessary files to support the Marvell Armada 8k devel board. Most board specfic files are shared with the Armada 7k boards under the name "armada-8k*". So only minimal changes are necessary to add this basic board support (except the DT files of course).
Signed-off-by: Stefan Roese sr@denx.de Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- arch/arm/dts/Makefile | 1 + board/Marvell/mvebu_armada-8k/MAINTAINERS | 1 + configs/mvebu_db-88f8040_defconfig | 52 +++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 configs/mvebu_db-88f8040_defconfig
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 836a8c4..5c66340 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -73,6 +73,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ armada-388-gp.dtb \ armada-385-amc.dtb \ armada-7040-db.dtb \ + armada-8040-db.dtb \ armada-xp-gp.dtb \ armada-xp-maxbcm.dtb \ armada-xp-synology-ds414.dtb \ diff --git a/board/Marvell/mvebu_armada-8k/MAINTAINERS b/board/Marvell/mvebu_armada-8k/MAINTAINERS index 33923ba..e0b965d 100644 --- a/board/Marvell/mvebu_armada-8k/MAINTAINERS +++ b/board/Marvell/mvebu_armada-8k/MAINTAINERS @@ -4,3 +4,4 @@ S: Maintained F: board/Marvell/mvebu_armada-8k/ F: include/configs/mvebu_armada-8k.h F: configs/mvebu_db-88f7040_defconfig +F: configs/mvebu_db-88f8040_defconfig diff --git a/configs/mvebu_db-88f8040_defconfig b/configs/mvebu_db-88f8040_defconfig new file mode 100644 index 0000000..eccb0f0 --- /dev/null +++ b/configs/mvebu_db-88f8040_defconfig @@ -0,0 +1,52 @@ +CONFIG_ARM=y +CONFIG_ARCH_MVEBU=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_TARGET_MVEBU_ARMADA_8K=y +CONFIG_DEFAULT_DEVICE_TREE="armada-8040-db" +CONFIG_SMBIOS_PRODUCT_NAME="" +CONFIG_AHCI=y +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_DISPLAY_CPUINFO is not set +# CONFIG_DISPLAY_BOARDINFO is not set +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_I2C=y +CONFIG_CMD_USB=y +# CONFIG_CMD_FPGA is not set +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_BLOCK_CACHE=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_MVTWSI=y +CONFIG_MISC=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_PHYLIB=y +CONFIG_MVEBU_COMPHY_SUPPORT=y +# CONFIG_SPL_SERIAL_PRESENT is not set +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_BASE=0xf0512000 +CONFIG_DEBUG_UART_CLOCK=200000000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_SYS_NS16550=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_SMBIOS_MANUFACTURER=""

Since the cp110 slave also has comphy DT nodes, the names need to be renamed to avoid a name clash. Lets use the common naming scheme: "cpm_xxx" for master and "cps_xxx" for slave.
Signed-off-by: Stefan Roese sr@denx.de Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- arch/arm/dts/armada-7040-db.dts | 6 +++--- arch/arm/dts/armada-cp110-master.dtsi | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/dts/armada-7040-db.dts b/arch/arm/dts/armada-7040-db.dts index 7d0059a..b8fe5a9 100644 --- a/arch/arm/dts/armada-7040-db.dts +++ b/arch/arm/dts/armada-7040-db.dts @@ -152,7 +152,7 @@ status = "okay"; };
-&comphy_cp110 { +&cpm_comphy { phy0 { phy-type = <PHY_TYPE_SGMII2>; phy-speed = <PHY_SPEED_3_125G>; @@ -184,10 +184,10 @@ }; };
-&utmi0 { +&cpm_utmi0 { status = "okay"; };
-&utmi1 { +&cpm_utmi1 { status = "okay"; }; diff --git a/arch/arm/dts/armada-cp110-master.dtsi b/arch/arm/dts/armada-cp110-master.dtsi index 7da98bf..422d754 100644 --- a/arch/arm/dts/armada-cp110-master.dtsi +++ b/arch/arm/dts/armada-cp110-master.dtsi @@ -149,7 +149,7 @@ status = "disabled"; };
- comphy_cp110: comphy@441000 { + cpm_comphy: comphy@441000 { compatible = "marvell,mvebu-comphy", "marvell,comphy-cp110"; reg = <0x441000 0x8>, <0x120000 0x8>; @@ -157,7 +157,7 @@ max-lanes = <6>; };
- utmi0: utmi@580000 { + cpm_utmi0: utmi@580000 { compatible = "marvell,mvebu-utmi-2.6.0"; reg = <0x580000 0x1000>, /* utmi-unit */ <0x440420 0x4>, /* usb-cfg */ @@ -166,7 +166,7 @@ status = "disabled"; };
- utmi1: utmi@581000 { + cpm_utmi1: utmi@581000 { compatible = "marvell,mvebu-utmi-2.6.0"; reg = <0x581000 0x1000>, /* utmi-unit */ <0x440420 0x4>, /* usb-cfg */

This patch adds the COMPHY and UTMI device tree nodes to the cp110-slave dtsi file for the Armada 8K.
Signed-off-by: Stefan Roese sr@denx.de Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- arch/arm/dts/armada-cp110-slave.dtsi | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/arch/arm/dts/armada-cp110-slave.dtsi b/arch/arm/dts/armada-cp110-slave.dtsi index 842fb33..a7f77b9 100644 --- a/arch/arm/dts/armada-cp110-slave.dtsi +++ b/arch/arm/dts/armada-cp110-slave.dtsi @@ -44,6 +44,8 @@ * Device Tree file for Marvell Armada CP110 Slave. */
+#include <dt-bindings/comphy/comphy_data.h> + / { cp110-slave { #address-cells = <2>; @@ -164,6 +166,23 @@ clocks = <&cps_syscon0 1 21>; status = "disabled"; }; + + cps_comphy: comphy@441000 { + compatible = "marvell,mvebu-comphy", "marvell,comphy-cp110"; + reg = <0x441000 0x8>, + <0x120000 0x8>; + mux-bitcount = <4>; + max-lanes = <6>; + }; + + cps_utmi0: utmi@580000 { + compatible = "marvell,mvebu-utmi-2.6.0"; + reg = <0x580000 0x1000>, /* utmi-unit */ + <0x440420 0x4>, /* usb-cfg */ + <0x440440 0x4>; /* utmi-cfg */ + utmi-port = <UTMI_PHY_TO_USB_HOST0>; + status = "disabled"; + }; };
cps_pcie0: pcie@f4600000 {

This patch adds the COMPHY device tree configuration to the DT file for the Marvell DB-88F8040 devel board.
Signed-off-by: Stefan Roese sr@denx.de Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- arch/arm/dts/armada-8040-db.dts | 84 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+)
diff --git a/arch/arm/dts/armada-8040-db.dts b/arch/arm/dts/armada-8040-db.dts index 6e6f182..4978092 100644 --- a/arch/arm/dts/armada-8040-db.dts +++ b/arch/arm/dts/armada-8040-db.dts @@ -148,3 +148,87 @@ &cps_usb3_1 { status = "okay"; }; + +&cpm_comphy { + /* + * Serdes Configuration: + * Lane 0: SGMII2 + * Lane 1: USB3_HOST0 + * Lane 2: KR (10G) + * Lane 3: SATA1 + * Lane 4: USB3_HOST1 + * Lane 5: PEX2x1 + */ + phy0 { + phy-type = <PHY_TYPE_SGMII2>; + phy-speed = <PHY_SPEED_3_125G>; + }; + + phy1 { + phy-type = <PHY_TYPE_USB3_HOST0>; + }; + + phy2 { + phy-type = <PHY_TYPE_KR>; + }; + + phy3 { + phy-type = <PHY_TYPE_SATA1>; + }; + + phy4 { + phy-type = <PHY_TYPE_USB3_HOST1>; + }; + + phy5 { + phy-type = <PHY_TYPE_PEX2>; + }; +}; + +&cps_comphy { + /* + * Serdes Configuration: + * Lane 0: SGMII2 + * Lane 1: USB3_HOST0 + * Lane 2: KR (10G) + * Lane 3: SATA1 + * Lane 4: Unconnected + * Lane 5: PEX2x1 + */ + phy0 { + phy-type = <PHY_TYPE_SGMII2>; + phy-speed = <PHY_SPEED_3_125G>; + }; + + phy1 { + phy-type = <PHY_TYPE_USB3_HOST0>; + }; + + phy2 { + phy-type = <PHY_TYPE_KR>; + }; + + phy3 { + phy-type = <PHY_TYPE_SATA1>; + }; + + phy4 { + phy-type = <PHY_TYPE_UNCONNECTED>; + }; + + phy5 { + phy-type = <PHY_TYPE_PEX2>; + }; +}; + +&cpm_utmi0 { + status = "okay"; +}; + +&cpm_utmi1 { + status = "okay"; +}; + +&cps_utmi0 { + status = "okay"; +};

Add I2C and SPI aliases to enable usage in U-Boot. Otherwise U-Boot will not be able to use the SPI NOR chip for environment storage and use "i2c dev 0" to select this I2C bus.
Signed-off-by: Stefan Roese sr@denx.de Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- arch/arm/dts/armada-8040-db.dts | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/arm/dts/armada-8040-db.dts b/arch/arm/dts/armada-8040-db.dts index 4978092..7fb674b 100644 --- a/arch/arm/dts/armada-8040-db.dts +++ b/arch/arm/dts/armada-8040-db.dts @@ -55,6 +55,11 @@ stdout-path = "serial0:115200n8"; };
+ aliases { + i2c0 = &cpm_i2c0; + spi0 = &spi0; + }; + memory@00000000 { device_type = "memory"; reg = <0x0 0x0 0x0 0x80000000>;

The Armada8k implements 2 CPs (communication processors) and the 2nd CP also is equipped with a COMPHY controller. This patch now loops over all enabled MISC devices (CP110) enabled in the DT to initialize all CPs.
Signed-off-by: Stefan Roese sr@denx.de Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- arch/arm/mach-mvebu/arm64-common.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c index 7055a81..1fc2ff2 100644 --- a/arch/arm/mach-mvebu/arm64-common.c +++ b/arch/arm/mach-mvebu/arm64-common.c @@ -109,12 +109,20 @@ int arch_early_init_r(void) { struct udevice *dev; int ret; - - /* Call the comphy code via the MISC uclass driver */ - ret = uclass_get_device(UCLASS_MISC, 0, &dev); - if (ret) { - debug("COMPHY init failed: %d\n", ret); - return -ENODEV; + int i; + + /* + * Loop over all MISC uclass drivers to call the comphy code + * and init all CP110 devices enabled in the DT + */ + i = 0; + while (1) { + /* Call the comphy code via the MISC uclass driver */ + ret = uclass_get_device(UCLASS_MISC, i++, &dev); + + /* We're done, once no further CP110 device is found */ + if (ret) + break; }
/* Cause the SATA device to do its early init */

With the support for the Armada 8k, a 2nd COMPHY controller now needs to get supported from the CP110 slave controller. This patch adds support for this 2nd contoller in the COMPHY driver.
Signed-off-by: Stefan Roese sr@denx.de Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- drivers/phy/marvell/comphy.h | 2 +- drivers/phy/marvell/comphy_core.c | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/phy/marvell/comphy.h b/drivers/phy/marvell/comphy.h index df5b7d5..0a15692 100644 --- a/drivers/phy/marvell/comphy.h +++ b/drivers/phy/marvell/comphy.h @@ -69,7 +69,7 @@ (0x3 << DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET)
#define MAX_LANE_OPTIONS 10 -#define MAX_UTMI_PHY_COUNT 2 +#define MAX_UTMI_PHY_COUNT 3
struct comphy_mux_options { u32 type; diff --git a/drivers/phy/marvell/comphy_core.c b/drivers/phy/marvell/comphy_core.c index 651397d..bc2508b 100644 --- a/drivers/phy/marvell/comphy_core.c +++ b/drivers/phy/marvell/comphy_core.c @@ -112,6 +112,7 @@ static int comphy_probe(struct udevice *dev) struct comphy_map comphy_map_data[MAX_LANE_OPTIONS]; int subnode; int lane; + int last_idx = 0;
/* Save base addresses for later use */ chip_cfg->comphy_base_addr = (void *)dev_get_addr_index(dev, 0); @@ -178,10 +179,20 @@ static int comphy_probe(struct udevice *dev) /* PHY power UP sequence */ chip_cfg->ptr_comphy_chip_init(chip_cfg, comphy_map_data); /* PHY print SerDes status */ + if (of_machine_is_compatible("marvell,armada8040")) + printf("Comphy chip #%d:\n", chip_cfg->comphy_index); comphy_print(chip_cfg, comphy_map_data);
- /* Initialize dedicated PHYs (not muxed SerDes lanes) */ - comphy_dedicated_phys_init(); + /* + * Only run the dedicated PHY init code once, in the last PHY init call + */ + if (of_machine_is_compatible("marvell,armada8040")) + last_idx = 1; + + if (chip_cfg->comphy_index == last_idx) { + /* Initialize dedicated PHYs (not muxed SerDes lanes) */ + comphy_dedicated_phys_init(); + }
return 0; }

From: Shadi Ammouri shadi@marvell.com
This patch adds a driver for the PCIe controller integrated in the Marvell Armada-8K SoC. This controller is based on the DesignWare IP core.
The original version was written by Shadi and Yehuda. I ported this driver to the latest mainline U-Boot version with DM support.
Tested on the Marvell DB-88F8040 Armada-8K eval board.
Signed-off-by: Shadi Ammouri shadi@marvell.com Signed-off-by: Yehuda Yitschak yehuday@marvell.com Signed-off-by: Stefan Roese sr@denx.de Cc: Simon Glass sjg@chromium.org Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- drivers/pci/Kconfig | 10 ++ drivers/pci/Makefile | 1 + drivers/pci/pcie_dw_mvebu.c | 415 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 426 insertions(+) create mode 100644 drivers/pci/pcie_dw_mvebu.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index b8376b4..ff2c370 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -33,6 +33,16 @@ config PCI_PNP help Enable PCI memory and I/O space resource allocation and assignment.
+config PCIE_DW_MVEBU + bool "Enable Armada-8K PCIe driver (DesignWare core)" + default n + depends on DM_PCI + depends on ARMADA_8K + help + Say Y here if you want to enable PCIe controller support on + Armada-8K SoCs. The PCIe controller on Armada-8K is based on + DesignWare hardware. + config PCI_SANDBOX bool "Sandbox PCI support" depends on SANDBOX && DM_PCI diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 9583e91..86717a4 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -30,5 +30,6 @@ obj-$(CONFIG_SH7780_PCI) +=pci_sh7780.o obj-$(CONFIG_PCI_TEGRA) += pci_tegra.o obj-$(CONFIG_TSI108_PCI) += tsi108_pci.o obj-$(CONFIG_WINBOND_83C553) += w83c553f.o +obj-$(CONFIG_PCIE_DW_MVEBU) += pcie_dw_mvebu.o obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o diff --git a/drivers/pci/pcie_dw_mvebu.c b/drivers/pci/pcie_dw_mvebu.c new file mode 100644 index 0000000..dd5ba34 --- /dev/null +++ b/drivers/pci/pcie_dw_mvebu.c @@ -0,0 +1,415 @@ +/* + * Copyright (C) 2015 Marvell International Ltd. + * + * Copyright (C) 2016 Stefan Roese sr@denx.de + * + * Based on: + * - drivers/pci/pcie_imx.c + * - drivers/pci/pci_mvebu.c + * - drivers/pci/pcie_xilinx.c + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <pci.h> +#include <asm/io.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* PCI Config space registers */ +#define PCIE_CONFIG_BAR0 0x10 +#define PCIE_LINK_STATUS_REG 0x80 +#define PCIE_LINK_STATUS_SPEED_OFF 16 +#define PCIE_LINK_STATUS_SPEED_MASK 0xf +#define PCIE_LINK_STATUS_WIDTH_OFF 20 +#define PCIE_LINK_STATUS_WIDTH_MASK 0xf + +/* Resizable bar capability registers */ +#define RESIZABLE_BAR_CAP 0x250 +#define RESIZABLE_BAR_CTL0 0x254 +#define RESIZABLE_BAR_CTL1 0x258 + +/* iATU registers */ +#define PCIE_ATU_VIEWPORT 0x900 +#define PCIE_ATU_REGION_INBOUND (0x1 << 31) +#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31) +#define PCIE_ATU_REGION_INDEX1 (0x1 << 0) +#define PCIE_ATU_REGION_INDEX0 (0x0 << 0) +#define PCIE_ATU_CR1 0x904 +#define PCIE_ATU_TYPE_MEM (0x0 << 0) +#define PCIE_ATU_TYPE_IO (0x2 << 0) +#define PCIE_ATU_TYPE_CFG0 (0x4 << 0) +#define PCIE_ATU_TYPE_CFG1 (0x5 << 0) +#define PCIE_ATU_CR2 0x908 +#define PCIE_ATU_ENABLE (0x1 << 31) +#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30) +#define PCIE_ATU_LOWER_BASE 0x90C +#define PCIE_ATU_UPPER_BASE 0x910 +#define PCIE_ATU_LIMIT 0x914 +#define PCIE_ATU_LOWER_TARGET 0x918 +#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24) +#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19) +#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) +#define PCIE_ATU_UPPER_TARGET 0x91C + +#define PCIE_LINK_CAPABILITY 0x7C +#define PCIE_LINK_CTL_2 0xA0 +#define TARGET_LINK_SPEED_MASK 0xF +#define LINK_SPEED_GEN_1 0x1 +#define LINK_SPEED_GEN_2 0x2 +#define LINK_SPEED_GEN_3 0x3 + +#define PCIE_GEN3_RELATED 0x890 +#define GEN3_EQU_DISABLE (1 << 16) +#define GEN3_ZRXDC_NON_COMP (1 << 0) + +#define PCIE_GEN3_EQU_CTRL 0x8A8 +#define GEN3_EQU_EVAL_2MS_DISABLE (1 << 5) + +#define PCIE_ROOT_COMPLEX_MODE_MASK (0xF << 4) + +#define PCIE_LINK_UP_TIMEOUT_MS 100 + +#define PCIE_GLOBAL_CONTROL 0x8000 +#define PCIE_APP_LTSSM_EN (1 << 2) +#define PCIE_DEVICE_TYPE_OFFSET (4) +#define PCIE_DEVICE_TYPE_MASK (0xF) +#define PCIE_DEVICE_TYPE_EP (0x0) /* Endpoint */ +#define PCIE_DEVICE_TYPE_LEP (0x1) /* Legacy endpoint */ +#define PCIE_DEVICE_TYPE_RC (0x4) /* Root complex */ + +#define PCIE_GLOBAL_STATUS 0x8008 +#define PCIE_GLB_STS_RDLH_LINK_UP (1 << 1) +#define PCIE_GLB_STS_PHY_LINK_UP (1 << 9) + +#define PCIE_ARCACHE_TRC 0x8050 +#define PCIE_AWCACHE_TRC 0x8054 +#define ARCACHE_SHAREABLE_CACHEABLE 0x3511 +#define AWCACHE_SHAREABLE_CACHEABLE 0x5311 + +#define LINK_SPEED_GEN_1 0x1 +#define LINK_SPEED_GEN_2 0x2 +#define LINK_SPEED_GEN_3 0x3 + +struct pcie_dw_mvebu { + struct pci_controller hose; + void *ctrl_base; + void *cfg_base; + fdt_size_t cfg_size; + int first_busno; +}; + +static int pcie_dw_get_link_speed(void *regs_base) +{ + return ((readl(regs_base + PCIE_LINK_STATUS_REG)) >> + PCIE_LINK_STATUS_SPEED_OFF) & PCIE_LINK_STATUS_SPEED_MASK; +} + +static int pcie_dw_get_link_width(void *regs_base) +{ + return ((readl(regs_base + PCIE_LINK_STATUS_REG)) >> + PCIE_LINK_STATUS_WIDTH_OFF) & PCIE_LINK_STATUS_WIDTH_MASK; +} + +static uintptr_t set_cfg_address(struct pcie_dw_mvebu *pcie, + pci_dev_t d, int where) +{ + uintptr_t va_address; + + /* + * Region #0 is used for Outbound CFG space access. + * Direction = Outbound + * Region Index = 0 + */ + writel(0, pcie->ctrl_base + PCIE_ATU_VIEWPORT); + + if (PCI_BUS(d) == (pcie->first_busno + 1)) + /* For local bus, change TLP Type field to 4. */ + writel(PCIE_ATU_TYPE_CFG0, pcie->ctrl_base + PCIE_ATU_CR1); + else + /* Otherwise, change TLP Type field to 5. */ + writel(PCIE_ATU_TYPE_CFG1, pcie->ctrl_base + PCIE_ATU_CR1); + + if (PCI_BUS(d) == pcie->first_busno) { + /* Accessing root port configuration space. */ + va_address = (uintptr_t)pcie->ctrl_base; + } else { + writel(d << 8, pcie->ctrl_base + PCIE_ATU_LOWER_TARGET); + va_address = (uintptr_t)pcie->cfg_base; + } + + va_address += (where & ~0x3); + + return va_address; +} + +static int pcie_dw_addr_valid(pci_dev_t d, int first_busno) +{ + if ((PCI_BUS(d) == first_busno) && (PCI_DEV(d) > 0)) + return 0; + if ((PCI_BUS(d) == first_busno + 1) && (PCI_DEV(d) > 0)) + return 0; + + return 1; +} + +static int pcie_dw_mvebu_read_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong *valuep, + enum pci_size_t size) +{ + struct pcie_dw_mvebu *pcie = dev_get_priv(bus); + uintptr_t va_address; + ulong value; + + debug("PCIE CFG read: (b,d,f)=(%2d,%2d,%2d) ", + PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); + + if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) { + debug("- out of range\n"); + *valuep = pci_get_ff(size); + return 0; + } + + va_address = set_cfg_address(pcie, bdf, offset); + + value = readl(va_address); + + debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value); + *valuep = pci_conv_32_to_size(value, offset, size); + + return 0; +} + +static int pcie_dw_mvebu_write_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + struct pcie_dw_mvebu *pcie = dev_get_priv(bus); + uintptr_t va_address; + ulong old; + + debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ", + PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); + debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value); + + if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) { + debug("- out of range\n"); + return 0; + } + + va_address = set_cfg_address(pcie, bdf, offset); + + old = readl(va_address); + value = pci_conv_size_to_32(old, value, offset, size); + writel(value, va_address); + + return 0; +} + +static void pcie_dw_configure(void *regs_base, u32 cap_speed) +{ + u32 reg; + + /* TODO: need to read the serdes speed from the dts + and according to it configure the PCIe gen */ + + /* Set link to GEN 3 */ + reg = readl(regs_base + PCIE_LINK_CTL_2); + reg &= ~TARGET_LINK_SPEED_MASK; + reg |= cap_speed; + writel(reg, regs_base + PCIE_LINK_CTL_2); + + reg = readl(regs_base + PCIE_LINK_CAPABILITY); + reg &= ~TARGET_LINK_SPEED_MASK; + reg |= cap_speed; + writel(reg, regs_base + PCIE_LINK_CAPABILITY); + + reg = readl(regs_base + PCIE_GEN3_EQU_CTRL); + reg |= GEN3_EQU_EVAL_2MS_DISABLE; + writel(reg, regs_base + PCIE_GEN3_EQU_CTRL); +} + +static int is_link_up(void *regs_base) +{ + u32 mask = PCIE_GLB_STS_RDLH_LINK_UP | PCIE_GLB_STS_PHY_LINK_UP; + u32 reg; + + reg = readl(regs_base + PCIE_GLOBAL_STATUS); + if ((reg & mask) == mask) + return 1; + + return 0; +} + +static int wait_link_up(void *regs_base) +{ + unsigned long timeout; + + timeout = get_timer(0) + PCIE_LINK_UP_TIMEOUT_MS; + while (!is_link_up(regs_base)) { + if (get_timer(0) > timeout) + return 0; + }; + + return 1; +} + +static int pcie_dw_mvebu_pcie_link_up(void *regs_base, u32 cap_speed) +{ + u32 reg; + + if (!is_link_up(regs_base)) { + /* Disable LTSSM state machine to enable configuration */ + reg = readl(regs_base + PCIE_GLOBAL_CONTROL); + reg &= ~(PCIE_APP_LTSSM_EN); + writel(reg, regs_base + PCIE_GLOBAL_CONTROL); + } + + reg = readl(regs_base + PCIE_GLOBAL_CONTROL); + reg &= ~(PCIE_DEVICE_TYPE_MASK << PCIE_DEVICE_TYPE_OFFSET); + reg |= (PCIE_DEVICE_TYPE_RC << PCIE_DEVICE_TYPE_OFFSET); + writel(reg, regs_base + PCIE_GLOBAL_CONTROL); + + /* Set the PCIe master AXI attributes */ + writel(ARCACHE_SHAREABLE_CACHEABLE, regs_base + PCIE_ARCACHE_TRC); + writel(AWCACHE_SHAREABLE_CACHEABLE, regs_base + PCIE_AWCACHE_TRC); + + /* DW pre link configurations */ + pcie_dw_configure(regs_base, cap_speed); + + if (!is_link_up(regs_base)) { + /* Configuration done. Start LTSSM */ + reg = readl(regs_base + PCIE_GLOBAL_CONTROL); + reg |= PCIE_APP_LTSSM_EN; + writel(reg, regs_base + PCIE_GLOBAL_CONTROL); + } + + /* Check that link was established */ + if (!wait_link_up(regs_base)) + return 0; + + /* + * Link can be established in Gen 1. still need to wait + * till MAC nagaotiation is completed + */ + udelay(100); + + return 1; +} + +/* + * iATU region setup + */ +static int pcie_dw_regions_setup(struct pcie_dw_mvebu *pcie) +{ + /* + * Region #0 is used for Outbound CFG space access. + * Direction = Outbound + * Region Index = 0 + */ + writel(0, pcie->ctrl_base + PCIE_ATU_VIEWPORT); + + writel((u32)(uintptr_t)pcie->cfg_base, pcie->ctrl_base + + PCIE_ATU_LOWER_BASE); + writel(0, pcie->ctrl_base + PCIE_ATU_UPPER_BASE); + writel((u32)(uintptr_t)pcie->cfg_base + pcie->cfg_size, + pcie->ctrl_base + PCIE_ATU_LIMIT); + + writel(0, pcie->ctrl_base + PCIE_ATU_LOWER_TARGET); + writel(0, pcie->ctrl_base + PCIE_ATU_UPPER_TARGET); + writel(PCIE_ATU_TYPE_CFG0, pcie->ctrl_base + PCIE_ATU_CR1); + writel(PCIE_ATU_ENABLE, pcie->ctrl_base + PCIE_ATU_CR2); + + return 0; +} + +static void pcie_dw_set_host_bars(void *regs_base) +{ + u32 size = gd->ram_size; + u64 max_size; + u32 reg; + u32 bar0; + + /* Verify the maximal BAR size */ + reg = readl(regs_base + RESIZABLE_BAR_CAP); + max_size = 1ULL << (5 + (reg + (1 << 4))); + + if (size > max_size) { + size = max_size; + printf("Warning: PCIe BARs can't map all DRAM space\n"); + } + + /* Set the BAR base and size towards DDR */ + bar0 = CONFIG_SYS_SDRAM_BASE & ~0xf; + bar0 |= PCI_BASE_ADDRESS_MEM_TYPE_32; + writel(CONFIG_SYS_SDRAM_BASE, regs_base + PCIE_CONFIG_BAR0); + + reg = ((size >> 20) - 1) << 12; + writel(size, regs_base + RESIZABLE_BAR_CTL0); +} + +static int pcie_dw_mvebu_probe(struct udevice *dev) +{ + struct pcie_dw_mvebu *pcie = dev_get_priv(dev); + + pcie->first_busno = dev->seq; + + /* Don't register host if link is down */ + if (!pcie_dw_mvebu_pcie_link_up(pcie->ctrl_base, LINK_SPEED_GEN_3)) { + printf("PCIE-%d: Link down\n", dev->seq); + return -ENODEV; + } + + printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n", dev->seq, + pcie_dw_get_link_speed(pcie->ctrl_base), + pcie_dw_get_link_width(pcie->ctrl_base), pcie->hose.first_busno); + + pcie_dw_regions_setup(pcie); + pcie_dw_set_host_bars(pcie->ctrl_base); + + return 0; +} + +static int pcie_dw_mvebu_ofdata_to_platdata(struct udevice *dev) +{ + struct pcie_dw_mvebu *pcie = dev_get_priv(dev); + + pcie->ctrl_base = (void *)dev_get_addr_index(dev, 0); + if (IS_ERR(pcie->ctrl_base)) + return PTR_ERR(pcie->ctrl_base); + + /* + * We need to know the size for the cfg space as well from the + * DT "reg" property. dev_get_addr_index() doesn't provide this + * size, so we need to use a different method to acquire the + * address and size here. + */ + pcie->cfg_base = (void *)fdtdec_get_addr_size_auto_noparent( + gd->fdt_blob, dev->of_offset, "reg", 1, &pcie->cfg_size, true); + if (pcie->cfg_base == NULL) + return -ENODEV; + + return 0; +} + +static const struct dm_pci_ops pcie_dw_mvebu_ops = { + .read_config = pcie_dw_mvebu_read_config, + .write_config = pcie_dw_mvebu_write_config, +}; + +static const struct udevice_id pcie_dw_mvebu_ids[] = { + { .compatible = "marvell,armada8k-pcie" }, + { } +}; + +U_BOOT_DRIVER(pcie_dw_mvebu) = { + .name = "pcie_dw_mvebu", + .id = UCLASS_PCI, + .of_match = pcie_dw_mvebu_ids, + .ops = &pcie_dw_mvebu_ops, + .ofdata_to_platdata = pcie_dw_mvebu_ofdata_to_platdata, + .probe = pcie_dw_mvebu_probe, + .priv_auto_alloc_size = sizeof(struct pcie_dw_mvebu), +};

Hi,
On 15 November 2016 at 02:08, Stefan Roese sr@denx.de wrote:
From: Shadi Ammouri shadi@marvell.com
This patch adds a driver for the PCIe controller integrated in the Marvell Armada-8K SoC. This controller is based on the DesignWare IP core.
The original version was written by Shadi and Yehuda. I ported this driver to the latest mainline U-Boot version with DM support.
Tested on the Marvell DB-88F8040 Armada-8K eval board.
Signed-off-by: Shadi Ammouri shadi@marvell.com Signed-off-by: Yehuda Yitschak yehuday@marvell.com Signed-off-by: Stefan Roese sr@denx.de Cc: Simon Glass sjg@chromium.org Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com
drivers/pci/Kconfig | 10 ++ drivers/pci/Makefile | 1 + drivers/pci/pcie_dw_mvebu.c | 415 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 426 insertions(+) create mode 100644 drivers/pci/pcie_dw_mvebu.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index b8376b4..ff2c370 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -33,6 +33,16 @@ config PCI_PNP help Enable PCI memory and I/O space resource allocation and assignment.
+config PCIE_DW_MVEBU
bool "Enable Armada-8K PCIe driver (DesignWare core)"
default n
depends on DM_PCI
depends on ARMADA_8K
help
Say Y here if you want to enable PCIe controller support on
Armada-8K SoCs. The PCIe controller on Armada-8K is based on
DesignWare hardware.
config PCI_SANDBOX bool "Sandbox PCI support" depends on SANDBOX && DM_PCI diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 9583e91..86717a4 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -30,5 +30,6 @@ obj-$(CONFIG_SH7780_PCI) +=pci_sh7780.o obj-$(CONFIG_PCI_TEGRA) += pci_tegra.o obj-$(CONFIG_TSI108_PCI) += tsi108_pci.o obj-$(CONFIG_WINBOND_83C553) += w83c553f.o +obj-$(CONFIG_PCIE_DW_MVEBU) += pcie_dw_mvebu.o obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o diff --git a/drivers/pci/pcie_dw_mvebu.c b/drivers/pci/pcie_dw_mvebu.c new file mode 100644 index 0000000..dd5ba34 --- /dev/null +++ b/drivers/pci/pcie_dw_mvebu.c @@ -0,0 +1,415 @@ +/*
- Copyright (C) 2015 Marvell International Ltd.
- Copyright (C) 2016 Stefan Roese sr@denx.de
- Based on:
- drivers/pci/pcie_imx.c
- drivers/pci/pci_mvebu.c
- drivers/pci/pcie_xilinx.c
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <dm.h> +#include <pci.h> +#include <asm/io.h>
+DECLARE_GLOBAL_DATA_PTR;
+/* PCI Config space registers */ +#define PCIE_CONFIG_BAR0 0x10 +#define PCIE_LINK_STATUS_REG 0x80 +#define PCIE_LINK_STATUS_SPEED_OFF 16 +#define PCIE_LINK_STATUS_SPEED_MASK 0xf +#define PCIE_LINK_STATUS_WIDTH_OFF 20 +#define PCIE_LINK_STATUS_WIDTH_MASK 0xf
+/* Resizable bar capability registers */ +#define RESIZABLE_BAR_CAP 0x250 +#define RESIZABLE_BAR_CTL0 0x254 +#define RESIZABLE_BAR_CTL1 0x258
+/* iATU registers */ +#define PCIE_ATU_VIEWPORT 0x900 +#define PCIE_ATU_REGION_INBOUND (0x1 << 31) +#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31) +#define PCIE_ATU_REGION_INDEX1 (0x1 << 0) +#define PCIE_ATU_REGION_INDEX0 (0x0 << 0) +#define PCIE_ATU_CR1 0x904 +#define PCIE_ATU_TYPE_MEM (0x0 << 0) +#define PCIE_ATU_TYPE_IO (0x2 << 0) +#define PCIE_ATU_TYPE_CFG0 (0x4 << 0) +#define PCIE_ATU_TYPE_CFG1 (0x5 << 0) +#define PCIE_ATU_CR2 0x908 +#define PCIE_ATU_ENABLE (0x1 << 31) +#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30) +#define PCIE_ATU_LOWER_BASE 0x90C +#define PCIE_ATU_UPPER_BASE 0x910 +#define PCIE_ATU_LIMIT 0x914 +#define PCIE_ATU_LOWER_TARGET 0x918 +#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24) +#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19) +#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) +#define PCIE_ATU_UPPER_TARGET 0x91C
+#define PCIE_LINK_CAPABILITY 0x7C +#define PCIE_LINK_CTL_2 0xA0 +#define TARGET_LINK_SPEED_MASK 0xF +#define LINK_SPEED_GEN_1 0x1 +#define LINK_SPEED_GEN_2 0x2 +#define LINK_SPEED_GEN_3 0x3
+#define PCIE_GEN3_RELATED 0x890 +#define GEN3_EQU_DISABLE (1 << 16) +#define GEN3_ZRXDC_NON_COMP (1 << 0)
+#define PCIE_GEN3_EQU_CTRL 0x8A8 +#define GEN3_EQU_EVAL_2MS_DISABLE (1 << 5)
+#define PCIE_ROOT_COMPLEX_MODE_MASK (0xF << 4)
+#define PCIE_LINK_UP_TIMEOUT_MS 100
+#define PCIE_GLOBAL_CONTROL 0x8000 +#define PCIE_APP_LTSSM_EN (1 << 2) +#define PCIE_DEVICE_TYPE_OFFSET (4) +#define PCIE_DEVICE_TYPE_MASK (0xF) +#define PCIE_DEVICE_TYPE_EP (0x0) /* Endpoint */ +#define PCIE_DEVICE_TYPE_LEP (0x1) /* Legacy endpoint */ +#define PCIE_DEVICE_TYPE_RC (0x4) /* Root complex */
+#define PCIE_GLOBAL_STATUS 0x8008 +#define PCIE_GLB_STS_RDLH_LINK_UP (1 << 1) +#define PCIE_GLB_STS_PHY_LINK_UP (1 << 9)
+#define PCIE_ARCACHE_TRC 0x8050 +#define PCIE_AWCACHE_TRC 0x8054 +#define ARCACHE_SHAREABLE_CACHEABLE 0x3511 +#define AWCACHE_SHAREABLE_CACHEABLE 0x5311
+#define LINK_SPEED_GEN_1 0x1 +#define LINK_SPEED_GEN_2 0x2 +#define LINK_SPEED_GEN_3 0x3
+struct pcie_dw_mvebu {
struct pci_controller hose;
Why is this here? It should be accessible with dev_get_uclass_priv(bus).
void *ctrl_base;
It would be nice if this were a C struct rather than offsets.
void *cfg_base;
fdt_size_t cfg_size;
int first_busno;
What are these two for? Needs comments.
+};
+static int pcie_dw_get_link_speed(void *regs_base) +{
return ((readl(regs_base + PCIE_LINK_STATUS_REG)) >>
PCIE_LINK_STATUS_SPEED_OFF) & PCIE_LINK_STATUS_SPEED_MASK;
I suggest making the MASK a shifted value, so that you mask and then shift.
+}
+static int pcie_dw_get_link_width(void *regs_base) +{
return ((readl(regs_base + PCIE_LINK_STATUS_REG)) >>
PCIE_LINK_STATUS_WIDTH_OFF) & PCIE_LINK_STATUS_WIDTH_MASK;
+}
+static uintptr_t set_cfg_address(struct pcie_dw_mvebu *pcie,
pci_dev_t d, int where)
Function comment? Much of this file could do with function comments.
+{
uintptr_t va_address;
/*
* Region #0 is used for Outbound CFG space access.
* Direction = Outbound
* Region Index = 0
*/
writel(0, pcie->ctrl_base + PCIE_ATU_VIEWPORT);
if (PCI_BUS(d) == (pcie->first_busno + 1))
/* For local bus, change TLP Type field to 4. */
writel(PCIE_ATU_TYPE_CFG0, pcie->ctrl_base + PCIE_ATU_CR1);
else
/* Otherwise, change TLP Type field to 5. */
writel(PCIE_ATU_TYPE_CFG1, pcie->ctrl_base + PCIE_ATU_CR1);
if (PCI_BUS(d) == pcie->first_busno) {
/* Accessing root port configuration space. */
va_address = (uintptr_t)pcie->ctrl_base;
} else {
writel(d << 8, pcie->ctrl_base + PCIE_ATU_LOWER_TARGET);
va_address = (uintptr_t)pcie->cfg_base;
}
va_address += (where & ~0x3);
return va_address;
+}
+static int pcie_dw_addr_valid(pci_dev_t d, int first_busno) +{
if ((PCI_BUS(d) == first_busno) && (PCI_DEV(d) > 0))
return 0;
if ((PCI_BUS(d) == first_busno + 1) && (PCI_DEV(d) > 0))
return 0;
return 1;
+}
+static int pcie_dw_mvebu_read_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong *valuep,
enum pci_size_t size)
+{
struct pcie_dw_mvebu *pcie = dev_get_priv(bus);
uintptr_t va_address;
ulong value;
debug("PCIE CFG read: (b,d,f)=(%2d,%2d,%2d) ",
PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) {
debug("- out of range\n");
*valuep = pci_get_ff(size);
return 0;
}
va_address = set_cfg_address(pcie, bdf, offset);
value = readl(va_address);
debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value);
*valuep = pci_conv_32_to_size(value, offset, size);
return 0;
+}
+static int pcie_dw_mvebu_write_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong value,
enum pci_size_t size)
+{
struct pcie_dw_mvebu *pcie = dev_get_priv(bus);
uintptr_t va_address;
ulong old;
debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ",
PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value);
if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) {
debug("- out of range\n");
return 0;
}
va_address = set_cfg_address(pcie, bdf, offset);
old = readl(va_address);
value = pci_conv_size_to_32(old, value, offset, size);
writel(value, va_address);
return 0;
+}
+static void pcie_dw_configure(void *regs_base, u32 cap_speed) +{
u32 reg;
/* TODO: need to read the serdes speed from the dts
and according to it configure the PCIe gen */
/* * TODO(email): .. * ... */
/* Set link to GEN 3 */
reg = readl(regs_base + PCIE_LINK_CTL_2);
reg &= ~TARGET_LINK_SPEED_MASK;
reg |= cap_speed;
writel(reg, regs_base + PCIE_LINK_CTL_2);
clrsetbits_le32()
reg = readl(regs_base + PCIE_LINK_CAPABILITY);
reg &= ~TARGET_LINK_SPEED_MASK;
reg |= cap_speed;
writel(reg, regs_base + PCIE_LINK_CAPABILITY);
reg = readl(regs_base + PCIE_GEN3_EQU_CTRL);
reg |= GEN3_EQU_EVAL_2MS_DISABLE;
writel(reg, regs_base + PCIE_GEN3_EQU_CTRL);
setbits_le32()
+}
+static int is_link_up(void *regs_base)
const void? It would be better as a struct though
+{
u32 mask = PCIE_GLB_STS_RDLH_LINK_UP | PCIE_GLB_STS_PHY_LINK_UP;
u32 reg;
reg = readl(regs_base + PCIE_GLOBAL_STATUS);
if ((reg & mask) == mask)
return 1;
return 0;
+}
+static int wait_link_up(void *regs_base)
Better to return 0 if OK, -ETIMEDOUT if not.
+{
unsigned long timeout;
timeout = get_timer(0) + PCIE_LINK_UP_TIMEOUT_MS;
while (!is_link_up(regs_base)) {
if (get_timer(0) > timeout)
return 0;
};
return 1;
+}
+static int pcie_dw_mvebu_pcie_link_up(void *regs_base, u32 cap_speed)
Better to return 0 if OK, -ve error if not
+{
u32 reg;
if (!is_link_up(regs_base)) {
/* Disable LTSSM state machine to enable configuration */
reg = readl(regs_base + PCIE_GLOBAL_CONTROL);
reg &= ~(PCIE_APP_LTSSM_EN);
writel(reg, regs_base + PCIE_GLOBAL_CONTROL);
}
reg = readl(regs_base + PCIE_GLOBAL_CONTROL);
reg &= ~(PCIE_DEVICE_TYPE_MASK << PCIE_DEVICE_TYPE_OFFSET);
reg |= (PCIE_DEVICE_TYPE_RC << PCIE_DEVICE_TYPE_OFFSET);
writel(reg, regs_base + PCIE_GLOBAL_CONTROL);
/* Set the PCIe master AXI attributes */
writel(ARCACHE_SHAREABLE_CACHEABLE, regs_base + PCIE_ARCACHE_TRC);
writel(AWCACHE_SHAREABLE_CACHEABLE, regs_base + PCIE_AWCACHE_TRC);
/* DW pre link configurations */
(regs_base, cap_speed);
if (!is_link_up(regs_base)) {
/* Configuration done. Start LTSSM */
reg = readl(regs_base + PCIE_GLOBAL_CONTROL);
reg |= PCIE_APP_LTSSM_EN;
writel(reg, regs_base + PCIE_GLOBAL_CONTROL);
}
/* Check that link was established */
if (!wait_link_up(regs_base))
return 0;
/*
* Link can be established in Gen 1. still need to wait
* till MAC nagaotiation is completed
*/
udelay(100);
return 1;
+}
+/*
- iATU region setup
- */
+static int pcie_dw_regions_setup(struct pcie_dw_mvebu *pcie) +{
/*
* Region #0 is used for Outbound CFG space access.
* Direction = Outbound
* Region Index = 0
*/
writel(0, pcie->ctrl_base + PCIE_ATU_VIEWPORT);
writel((u32)(uintptr_t)pcie->cfg_base, pcie->ctrl_base
+ PCIE_ATU_LOWER_BASE);
writel(0, pcie->ctrl_base + PCIE_ATU_UPPER_BASE);
writel((u32)(uintptr_t)pcie->cfg_base + pcie->cfg_size,
pcie->ctrl_base + PCIE_ATU_LIMIT);
writel(0, pcie->ctrl_base + PCIE_ATU_LOWER_TARGET);
writel(0, pcie->ctrl_base + PCIE_ATU_UPPER_TARGET);
writel(PCIE_ATU_TYPE_CFG0, pcie->ctrl_base + PCIE_ATU_CR1);
writel(PCIE_ATU_ENABLE, pcie->ctrl_base + PCIE_ATU_CR2);
return 0;
+}
+static void pcie_dw_set_host_bars(void *regs_base) +{
u32 size = gd->ram_size;
u64 max_size;
u32 reg;
u32 bar0;
/* Verify the maximal BAR size */
reg = readl(regs_base + RESIZABLE_BAR_CAP);
max_size = 1ULL << (5 + (reg + (1 << 4)));
if (size > max_size) {
size = max_size;
printf("Warning: PCIe BARs can't map all DRAM space\n");
Isn't this an error? If so I suggest returning it.
}
/* Set the BAR base and size towards DDR */
bar0 = CONFIG_SYS_SDRAM_BASE & ~0xf;
bar0 |= PCI_BASE_ADDRESS_MEM_TYPE_32;
writel(CONFIG_SYS_SDRAM_BASE, regs_base + PCIE_CONFIG_BAR0);
reg = ((size >> 20) - 1) << 12;
writel(size, regs_base + RESIZABLE_BAR_CTL0);
+}
+static int pcie_dw_mvebu_probe(struct udevice *dev) +{
struct pcie_dw_mvebu *pcie = dev_get_priv(dev);
pcie->first_busno = dev->seq;
OK I see what that variable is now. But please comment it at the top.
/* Don't register host if link is down */
if (!pcie_dw_mvebu_pcie_link_up(pcie->ctrl_base, LINK_SPEED_GEN_3)) {
printf("PCIE-%d: Link down\n", dev->seq);
return -ENODEV;
}
printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n", dev->seq,
pcie_dw_get_link_speed(pcie->ctrl_base),
pcie_dw_get_link_width(pcie->ctrl_base), pcie->hose.first_busno);
pcie_dw_regions_setup(pcie);
pcie_dw_set_host_bars(pcie->ctrl_base);
return 0;
+}
+static int pcie_dw_mvebu_ofdata_to_platdata(struct udevice *dev) +{
struct pcie_dw_mvebu *pcie = dev_get_priv(dev);
pcie->ctrl_base = (void *)dev_get_addr_index(dev, 0);
if (IS_ERR(pcie->ctrl_base))
return PTR_ERR(pcie->ctrl_base);
/*
* We need to know the size for the cfg space as well from the
* DT "reg" property. dev_get_addr_index() doesn't provide this
* size, so we need to use a different method to acquire the
* address and size here.
*/
pcie->cfg_base = (void *)fdtdec_get_addr_size_auto_noparent(
gd->fdt_blob, dev->of_offset, "reg", 1, &pcie->cfg_size, true);
This function returns FDT_ADDR_T_NONE on failure. Do we need to add a dev_get_addr_size()?
if (pcie->cfg_base == NULL)
return -ENODEV;
return 0;
+}
+static const struct dm_pci_ops pcie_dw_mvebu_ops = {
.read_config = pcie_dw_mvebu_read_config,
.write_config = pcie_dw_mvebu_write_config,
+};
+static const struct udevice_id pcie_dw_mvebu_ids[] = {
{ .compatible = "marvell,armada8k-pcie" },
{ }
+};
+U_BOOT_DRIVER(pcie_dw_mvebu) = {
.name = "pcie_dw_mvebu",
.id = UCLASS_PCI,
.of_match = pcie_dw_mvebu_ids,
.ops = &pcie_dw_mvebu_ops,
.ofdata_to_platdata = pcie_dw_mvebu_ofdata_to_platdata,
.probe = pcie_dw_mvebu_probe,
.priv_auto_alloc_size = sizeof(struct pcie_dw_mvebu),
+};
2.10.2
Regards, Simon

Hi Simon,
On 18.11.2016 02:14, Simon Glass wrote:
On 15 November 2016 at 02:08, Stefan Roese sr@denx.de wrote:
From: Shadi Ammouri shadi@marvell.com
This patch adds a driver for the PCIe controller integrated in the Marvell Armada-8K SoC. This controller is based on the DesignWare IP core.
The original version was written by Shadi and Yehuda. I ported this driver to the latest mainline U-Boot version with DM support.
Tested on the Marvell DB-88F8040 Armada-8K eval board.
Signed-off-by: Shadi Ammouri shadi@marvell.com Signed-off-by: Yehuda Yitschak yehuday@marvell.com Signed-off-by: Stefan Roese sr@denx.de Cc: Simon Glass sjg@chromium.org Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com
drivers/pci/Kconfig | 10 ++ drivers/pci/Makefile | 1 + drivers/pci/pcie_dw_mvebu.c | 415 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 426 insertions(+) create mode 100644 drivers/pci/pcie_dw_mvebu.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index b8376b4..ff2c370 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -33,6 +33,16 @@ config PCI_PNP help Enable PCI memory and I/O space resource allocation and assignment.
+config PCIE_DW_MVEBU
bool "Enable Armada-8K PCIe driver (DesignWare core)"
default n
depends on DM_PCI
depends on ARMADA_8K
help
Say Y here if you want to enable PCIe controller support on
Armada-8K SoCs. The PCIe controller on Armada-8K is based on
DesignWare hardware.
config PCI_SANDBOX bool "Sandbox PCI support" depends on SANDBOX && DM_PCI diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 9583e91..86717a4 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -30,5 +30,6 @@ obj-$(CONFIG_SH7780_PCI) +=pci_sh7780.o obj-$(CONFIG_PCI_TEGRA) += pci_tegra.o obj-$(CONFIG_TSI108_PCI) += tsi108_pci.o obj-$(CONFIG_WINBOND_83C553) += w83c553f.o +obj-$(CONFIG_PCIE_DW_MVEBU) += pcie_dw_mvebu.o obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o diff --git a/drivers/pci/pcie_dw_mvebu.c b/drivers/pci/pcie_dw_mvebu.c new file mode 100644 index 0000000..dd5ba34 --- /dev/null +++ b/drivers/pci/pcie_dw_mvebu.c @@ -0,0 +1,415 @@ +/*
- Copyright (C) 2015 Marvell International Ltd.
- Copyright (C) 2016 Stefan Roese sr@denx.de
- Based on:
- drivers/pci/pcie_imx.c
- drivers/pci/pci_mvebu.c
- drivers/pci/pcie_xilinx.c
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <dm.h> +#include <pci.h> +#include <asm/io.h>
+DECLARE_GLOBAL_DATA_PTR;
+/* PCI Config space registers */ +#define PCIE_CONFIG_BAR0 0x10 +#define PCIE_LINK_STATUS_REG 0x80 +#define PCIE_LINK_STATUS_SPEED_OFF 16 +#define PCIE_LINK_STATUS_SPEED_MASK 0xf +#define PCIE_LINK_STATUS_WIDTH_OFF 20 +#define PCIE_LINK_STATUS_WIDTH_MASK 0xf
+/* Resizable bar capability registers */ +#define RESIZABLE_BAR_CAP 0x250 +#define RESIZABLE_BAR_CTL0 0x254 +#define RESIZABLE_BAR_CTL1 0x258
+/* iATU registers */ +#define PCIE_ATU_VIEWPORT 0x900 +#define PCIE_ATU_REGION_INBOUND (0x1 << 31) +#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31) +#define PCIE_ATU_REGION_INDEX1 (0x1 << 0) +#define PCIE_ATU_REGION_INDEX0 (0x0 << 0) +#define PCIE_ATU_CR1 0x904 +#define PCIE_ATU_TYPE_MEM (0x0 << 0) +#define PCIE_ATU_TYPE_IO (0x2 << 0) +#define PCIE_ATU_TYPE_CFG0 (0x4 << 0) +#define PCIE_ATU_TYPE_CFG1 (0x5 << 0) +#define PCIE_ATU_CR2 0x908 +#define PCIE_ATU_ENABLE (0x1 << 31) +#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30) +#define PCIE_ATU_LOWER_BASE 0x90C +#define PCIE_ATU_UPPER_BASE 0x910 +#define PCIE_ATU_LIMIT 0x914 +#define PCIE_ATU_LOWER_TARGET 0x918 +#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24) +#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19) +#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) +#define PCIE_ATU_UPPER_TARGET 0x91C
+#define PCIE_LINK_CAPABILITY 0x7C +#define PCIE_LINK_CTL_2 0xA0 +#define TARGET_LINK_SPEED_MASK 0xF +#define LINK_SPEED_GEN_1 0x1 +#define LINK_SPEED_GEN_2 0x2 +#define LINK_SPEED_GEN_3 0x3
+#define PCIE_GEN3_RELATED 0x890 +#define GEN3_EQU_DISABLE (1 << 16) +#define GEN3_ZRXDC_NON_COMP (1 << 0)
+#define PCIE_GEN3_EQU_CTRL 0x8A8 +#define GEN3_EQU_EVAL_2MS_DISABLE (1 << 5)
+#define PCIE_ROOT_COMPLEX_MODE_MASK (0xF << 4)
+#define PCIE_LINK_UP_TIMEOUT_MS 100
+#define PCIE_GLOBAL_CONTROL 0x8000 +#define PCIE_APP_LTSSM_EN (1 << 2) +#define PCIE_DEVICE_TYPE_OFFSET (4) +#define PCIE_DEVICE_TYPE_MASK (0xF) +#define PCIE_DEVICE_TYPE_EP (0x0) /* Endpoint */ +#define PCIE_DEVICE_TYPE_LEP (0x1) /* Legacy endpoint */ +#define PCIE_DEVICE_TYPE_RC (0x4) /* Root complex */
+#define PCIE_GLOBAL_STATUS 0x8008 +#define PCIE_GLB_STS_RDLH_LINK_UP (1 << 1) +#define PCIE_GLB_STS_PHY_LINK_UP (1 << 9)
+#define PCIE_ARCACHE_TRC 0x8050 +#define PCIE_AWCACHE_TRC 0x8054 +#define ARCACHE_SHAREABLE_CACHEABLE 0x3511 +#define AWCACHE_SHAREABLE_CACHEABLE 0x5311
+#define LINK_SPEED_GEN_1 0x1 +#define LINK_SPEED_GEN_2 0x2 +#define LINK_SPEED_GEN_3 0x3
+struct pcie_dw_mvebu {
struct pci_controller hose;
Why is this here? It should be accessible with dev_get_uclass_priv(bus).
Changed for v2.
void *ctrl_base;
It would be nice if this were a C struct rather than offsets.
If I'm not mistaken, we're moving away from using C structs in U-Boot as its done in Linux as well.
void *cfg_base;
fdt_size_t cfg_size;
int first_busno;
What are these two for? Needs comments.
Will add in v2.
+};
+static int pcie_dw_get_link_speed(void *regs_base) +{
return ((readl(regs_base + PCIE_LINK_STATUS_REG)) >>
PCIE_LINK_STATUS_SPEED_OFF) & PCIE_LINK_STATUS_SPEED_MASK;
I suggest making the MASK a shifted value, so that you mask and then shift.
Yes, thats cleaner. Will change in v2.
+}
+static int pcie_dw_get_link_width(void *regs_base) +{
return ((readl(regs_base + PCIE_LINK_STATUS_REG)) >>
PCIE_LINK_STATUS_WIDTH_OFF) & PCIE_LINK_STATUS_WIDTH_MASK;
+}
+static uintptr_t set_cfg_address(struct pcie_dw_mvebu *pcie,
pci_dev_t d, int where)
Function comment? Much of this file could do with function comments.
Sure. Let me see, what I can come up with in v2.
+{
uintptr_t va_address;
/*
* Region #0 is used for Outbound CFG space access.
* Direction = Outbound
* Region Index = 0
*/
writel(0, pcie->ctrl_base + PCIE_ATU_VIEWPORT);
if (PCI_BUS(d) == (pcie->first_busno + 1))
/* For local bus, change TLP Type field to 4. */
writel(PCIE_ATU_TYPE_CFG0, pcie->ctrl_base + PCIE_ATU_CR1);
else
/* Otherwise, change TLP Type field to 5. */
writel(PCIE_ATU_TYPE_CFG1, pcie->ctrl_base + PCIE_ATU_CR1);
if (PCI_BUS(d) == pcie->first_busno) {
/* Accessing root port configuration space. */
va_address = (uintptr_t)pcie->ctrl_base;
} else {
writel(d << 8, pcie->ctrl_base + PCIE_ATU_LOWER_TARGET);
va_address = (uintptr_t)pcie->cfg_base;
}
va_address += (where & ~0x3);
return va_address;
+}
+static int pcie_dw_addr_valid(pci_dev_t d, int first_busno) +{
if ((PCI_BUS(d) == first_busno) && (PCI_DEV(d) > 0))
return 0;
if ((PCI_BUS(d) == first_busno + 1) && (PCI_DEV(d) > 0))
return 0;
return 1;
+}
+static int pcie_dw_mvebu_read_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong *valuep,
enum pci_size_t size)
+{
struct pcie_dw_mvebu *pcie = dev_get_priv(bus);
uintptr_t va_address;
ulong value;
debug("PCIE CFG read: (b,d,f)=(%2d,%2d,%2d) ",
PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) {
debug("- out of range\n");
*valuep = pci_get_ff(size);
return 0;
}
va_address = set_cfg_address(pcie, bdf, offset);
value = readl(va_address);
debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value);
*valuep = pci_conv_32_to_size(value, offset, size);
return 0;
+}
+static int pcie_dw_mvebu_write_config(struct udevice *bus, pci_dev_t bdf,
uint offset, ulong value,
enum pci_size_t size)
+{
struct pcie_dw_mvebu *pcie = dev_get_priv(bus);
uintptr_t va_address;
ulong old;
debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ",
PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value);
if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) {
debug("- out of range\n");
return 0;
}
va_address = set_cfg_address(pcie, bdf, offset);
old = readl(va_address);
value = pci_conv_size_to_32(old, value, offset, size);
writel(value, va_address);
return 0;
+}
+static void pcie_dw_configure(void *regs_base, u32 cap_speed) +{
u32 reg;
/* TODO: need to read the serdes speed from the dts
and according to it configure the PCIe gen */
/*
- TODO(email): ..
- ...
*/
Okay.
/* Set link to GEN 3 */
reg = readl(regs_base + PCIE_LINK_CTL_2);
reg &= ~TARGET_LINK_SPEED_MASK;
reg |= cap_speed;
writel(reg, regs_base + PCIE_LINK_CTL_2);
clrsetbits_le32()
Okay.
reg = readl(regs_base + PCIE_LINK_CAPABILITY);
reg &= ~TARGET_LINK_SPEED_MASK;
reg |= cap_speed;
writel(reg, regs_base + PCIE_LINK_CAPABILITY);
reg = readl(regs_base + PCIE_GEN3_EQU_CTRL);
reg |= GEN3_EQU_EVAL_2MS_DISABLE;
writel(reg, regs_base + PCIE_GEN3_EQU_CTRL);
setbits_le32()
Okay.
+}
+static int is_link_up(void *regs_base)
const void? It would be better as a struct though
Again, I really think that we are moving away from the "old" U-Boot rule to use structs and are more and more going with offsets as macros - exactly what the kernel promotes.
+{
u32 mask = PCIE_GLB_STS_RDLH_LINK_UP | PCIE_GLB_STS_PHY_LINK_UP;
u32 reg;
reg = readl(regs_base + PCIE_GLOBAL_STATUS);
if ((reg & mask) == mask)
return 1;
return 0;
+}
+static int wait_link_up(void *regs_base)
Better to return 0 if OK, -ETIMEDOUT if not.
The function is named "is_link_up()", so returning "1" for "true" makes the calling code clearer for my taste. I can change the function to use "bool" instead of "int" and use "false / true" as well if you prefer this.
+{
unsigned long timeout;
timeout = get_timer(0) + PCIE_LINK_UP_TIMEOUT_MS;
while (!is_link_up(regs_base)) {
if (get_timer(0) > timeout)
return 0;
};
return 1;
+}
+static int pcie_dw_mvebu_pcie_link_up(void *regs_base, u32 cap_speed)
Better to return 0 if OK, -ve error if not
Changing this function to 0 / -ETIMEDOUT makes more sense in this function in contrast to the one above, IMHO. But this makes the use of these functions inconsistant.
+{
u32 reg;
if (!is_link_up(regs_base)) {
/* Disable LTSSM state machine to enable configuration */
reg = readl(regs_base + PCIE_GLOBAL_CONTROL);
reg &= ~(PCIE_APP_LTSSM_EN);
writel(reg, regs_base + PCIE_GLOBAL_CONTROL);
}
reg = readl(regs_base + PCIE_GLOBAL_CONTROL);
reg &= ~(PCIE_DEVICE_TYPE_MASK << PCIE_DEVICE_TYPE_OFFSET);
reg |= (PCIE_DEVICE_TYPE_RC << PCIE_DEVICE_TYPE_OFFSET);
writel(reg, regs_base + PCIE_GLOBAL_CONTROL);
/* Set the PCIe master AXI attributes */
writel(ARCACHE_SHAREABLE_CACHEABLE, regs_base + PCIE_ARCACHE_TRC);
writel(AWCACHE_SHAREABLE_CACHEABLE, regs_base + PCIE_AWCACHE_TRC);
/* DW pre link configurations */
(regs_base, cap_speed);
if (!is_link_up(regs_base)) {
/* Configuration done. Start LTSSM */
reg = readl(regs_base + PCIE_GLOBAL_CONTROL);
reg |= PCIE_APP_LTSSM_EN;
writel(reg, regs_base + PCIE_GLOBAL_CONTROL);
}
/* Check that link was established */
if (!wait_link_up(regs_base))
return 0;
/*
* Link can be established in Gen 1. still need to wait
* till MAC nagaotiation is completed
*/
udelay(100);
return 1;
+}
+/*
- iATU region setup
- */
+static int pcie_dw_regions_setup(struct pcie_dw_mvebu *pcie) +{
/*
* Region #0 is used for Outbound CFG space access.
* Direction = Outbound
* Region Index = 0
*/
writel(0, pcie->ctrl_base + PCIE_ATU_VIEWPORT);
writel((u32)(uintptr_t)pcie->cfg_base, pcie->ctrl_base
+ PCIE_ATU_LOWER_BASE);
writel(0, pcie->ctrl_base + PCIE_ATU_UPPER_BASE);
writel((u32)(uintptr_t)pcie->cfg_base + pcie->cfg_size,
pcie->ctrl_base + PCIE_ATU_LIMIT);
writel(0, pcie->ctrl_base + PCIE_ATU_LOWER_TARGET);
writel(0, pcie->ctrl_base + PCIE_ATU_UPPER_TARGET);
writel(PCIE_ATU_TYPE_CFG0, pcie->ctrl_base + PCIE_ATU_CR1);
writel(PCIE_ATU_ENABLE, pcie->ctrl_base + PCIE_ATU_CR2);
return 0;
+}
+static void pcie_dw_set_host_bars(void *regs_base) +{
u32 size = gd->ram_size;
u64 max_size;
u32 reg;
u32 bar0;
/* Verify the maximal BAR size */
reg = readl(regs_base + RESIZABLE_BAR_CAP);
max_size = 1ULL << (5 + (reg + (1 << 4)));
if (size > max_size) {
size = max_size;
printf("Warning: PCIe BARs can't map all DRAM space\n");
Isn't this an error? If so I suggest returning it.
No, its a warning as the message explains. The PCIe drivers should still be able to work correctly, AFAICTO. If later tests show that this is a problem which needs to get addresses, I'll come back and will either return with error here or add the missing fixes.
}
/* Set the BAR base and size towards DDR */
bar0 = CONFIG_SYS_SDRAM_BASE & ~0xf;
bar0 |= PCI_BASE_ADDRESS_MEM_TYPE_32;
writel(CONFIG_SYS_SDRAM_BASE, regs_base + PCIE_CONFIG_BAR0);
reg = ((size >> 20) - 1) << 12;
writel(size, regs_base + RESIZABLE_BAR_CTL0);
+}
+static int pcie_dw_mvebu_probe(struct udevice *dev) +{
struct pcie_dw_mvebu *pcie = dev_get_priv(dev);
pcie->first_busno = dev->seq;
OK I see what that variable is now. But please comment it at the top.
Will do.
/* Don't register host if link is down */
if (!pcie_dw_mvebu_pcie_link_up(pcie->ctrl_base, LINK_SPEED_GEN_3)) {
printf("PCIE-%d: Link down\n", dev->seq);
return -ENODEV;
}
printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n", dev->seq,
pcie_dw_get_link_speed(pcie->ctrl_base),
pcie_dw_get_link_width(pcie->ctrl_base), pcie->hose.first_busno);
pcie_dw_regions_setup(pcie);
pcie_dw_set_host_bars(pcie->ctrl_base);
return 0;
+}
+static int pcie_dw_mvebu_ofdata_to_platdata(struct udevice *dev) +{
struct pcie_dw_mvebu *pcie = dev_get_priv(dev);
pcie->ctrl_base = (void *)dev_get_addr_index(dev, 0);
if (IS_ERR(pcie->ctrl_base))
return PTR_ERR(pcie->ctrl_base);
/*
* We need to know the size for the cfg space as well from the
* DT "reg" property. dev_get_addr_index() doesn't provide this
* size, so we need to use a different method to acquire the
* address and size here.
*/
pcie->cfg_base = (void *)fdtdec_get_addr_size_auto_noparent(
gd->fdt_blob, dev->of_offset, "reg", 1, &pcie->cfg_size, true);
This function returns FDT_ADDR_T_NONE on failure. Do we need to add a dev_get_addr_size()?
Yes, this might be better. Let me see if I can cook up a patch for such a new function.
Thanks for your review, Stefan

From: Shadi Ammouri shadi@marvell.com
This patch adds a driver for the PCIe controller integrated in the Marvell Armada-8K SoC. This controller is based on the DesignWare IP core.
The original version was written by Shadi and Yehuda. I ported this driver to the latest mainline U-Boot version with DM support.
Tested on the Marvell DB-88F8040 Armada-8K eval board.
Signed-off-by: Shadi Ammouri shadi@marvell.com Signed-off-by: Yehuda Yitschak yehuday@marvell.com Signed-off-by: Stefan Roese sr@denx.de Cc: Simon Glass sjg@chromium.org Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- v2: - Removed host struct from private data struct - Added comments to structs and functions - Moved shift into the macro for PCIE_LINK_STATUS_SPEED_MASK and PCIE_LINK_STATUS_WIDTH_MASK - Added Email addresses to ToDo statement - Used clrsetbits_le32(9 where applicable - Added const to register base pointer - Used new core function dev_get_addr_size_index() to retrieve addr and size - Added code to configure the PCIe root complex device as PCI bridge device
drivers/pci/Kconfig | 10 + drivers/pci/Makefile | 1 + drivers/pci/pcie_dw_mvebu.c | 535 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 546 insertions(+) create mode 100644 drivers/pci/pcie_dw_mvebu.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index b8376b4..ff2c370 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -33,6 +33,16 @@ config PCI_PNP help Enable PCI memory and I/O space resource allocation and assignment.
+config PCIE_DW_MVEBU + bool "Enable Armada-8K PCIe driver (DesignWare core)" + default n + depends on DM_PCI + depends on ARMADA_8K + help + Say Y here if you want to enable PCIe controller support on + Armada-8K SoCs. The PCIe controller on Armada-8K is based on + DesignWare hardware. + config PCI_SANDBOX bool "Sandbox PCI support" depends on SANDBOX && DM_PCI diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 9583e91..86717a4 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -30,5 +30,6 @@ obj-$(CONFIG_SH7780_PCI) +=pci_sh7780.o obj-$(CONFIG_PCI_TEGRA) += pci_tegra.o obj-$(CONFIG_TSI108_PCI) += tsi108_pci.o obj-$(CONFIG_WINBOND_83C553) += w83c553f.o +obj-$(CONFIG_PCIE_DW_MVEBU) += pcie_dw_mvebu.o obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o diff --git a/drivers/pci/pcie_dw_mvebu.c b/drivers/pci/pcie_dw_mvebu.c new file mode 100644 index 0000000..890a265 --- /dev/null +++ b/drivers/pci/pcie_dw_mvebu.c @@ -0,0 +1,535 @@ +/* + * Copyright (C) 2015 Marvell International Ltd. + * + * Copyright (C) 2016 Stefan Roese sr@denx.de + * + * Based on: + * - drivers/pci/pcie_imx.c + * - drivers/pci/pci_mvebu.c + * - drivers/pci/pcie_xilinx.c + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <pci.h> +#include <asm/io.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* PCI Config space registers */ +#define PCIE_CONFIG_BAR0 0x10 +#define PCIE_LINK_STATUS_REG 0x80 +#define PCIE_LINK_STATUS_SPEED_OFF 16 +#define PCIE_LINK_STATUS_SPEED_MASK (0xf << PCIE_LINK_STATUS_SPEED_OFF) +#define PCIE_LINK_STATUS_WIDTH_OFF 20 +#define PCIE_LINK_STATUS_WIDTH_MASK (0xf << PCIE_LINK_STATUS_WIDTH_OFF) + +/* Resizable bar capability registers */ +#define RESIZABLE_BAR_CAP 0x250 +#define RESIZABLE_BAR_CTL0 0x254 +#define RESIZABLE_BAR_CTL1 0x258 + +/* iATU registers */ +#define PCIE_ATU_VIEWPORT 0x900 +#define PCIE_ATU_REGION_INBOUND (0x1 << 31) +#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31) +#define PCIE_ATU_REGION_INDEX1 (0x1 << 0) +#define PCIE_ATU_REGION_INDEX0 (0x0 << 0) +#define PCIE_ATU_CR1 0x904 +#define PCIE_ATU_TYPE_MEM (0x0 << 0) +#define PCIE_ATU_TYPE_IO (0x2 << 0) +#define PCIE_ATU_TYPE_CFG0 (0x4 << 0) +#define PCIE_ATU_TYPE_CFG1 (0x5 << 0) +#define PCIE_ATU_CR2 0x908 +#define PCIE_ATU_ENABLE (0x1 << 31) +#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30) +#define PCIE_ATU_LOWER_BASE 0x90C +#define PCIE_ATU_UPPER_BASE 0x910 +#define PCIE_ATU_LIMIT 0x914 +#define PCIE_ATU_LOWER_TARGET 0x918 +#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24) +#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19) +#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) +#define PCIE_ATU_UPPER_TARGET 0x91C + +#define PCIE_LINK_CAPABILITY 0x7C +#define PCIE_LINK_CTL_2 0xA0 +#define TARGET_LINK_SPEED_MASK 0xF +#define LINK_SPEED_GEN_1 0x1 +#define LINK_SPEED_GEN_2 0x2 +#define LINK_SPEED_GEN_3 0x3 + +#define PCIE_GEN3_RELATED 0x890 +#define GEN3_EQU_DISABLE (1 << 16) +#define GEN3_ZRXDC_NON_COMP (1 << 0) + +#define PCIE_GEN3_EQU_CTRL 0x8A8 +#define GEN3_EQU_EVAL_2MS_DISABLE (1 << 5) + +#define PCIE_ROOT_COMPLEX_MODE_MASK (0xF << 4) + +#define PCIE_LINK_UP_TIMEOUT_MS 100 + +#define PCIE_GLOBAL_CONTROL 0x8000 +#define PCIE_APP_LTSSM_EN (1 << 2) +#define PCIE_DEVICE_TYPE_OFFSET (4) +#define PCIE_DEVICE_TYPE_MASK (0xF) +#define PCIE_DEVICE_TYPE_EP (0x0) /* Endpoint */ +#define PCIE_DEVICE_TYPE_LEP (0x1) /* Legacy endpoint */ +#define PCIE_DEVICE_TYPE_RC (0x4) /* Root complex */ + +#define PCIE_GLOBAL_STATUS 0x8008 +#define PCIE_GLB_STS_RDLH_LINK_UP (1 << 1) +#define PCIE_GLB_STS_PHY_LINK_UP (1 << 9) + +#define PCIE_ARCACHE_TRC 0x8050 +#define PCIE_AWCACHE_TRC 0x8054 +#define ARCACHE_SHAREABLE_CACHEABLE 0x3511 +#define AWCACHE_SHAREABLE_CACHEABLE 0x5311 + +#define LINK_SPEED_GEN_1 0x1 +#define LINK_SPEED_GEN_2 0x2 +#define LINK_SPEED_GEN_3 0x3 + +/** + * struct pcie_dw_mvebu - MVEBU DW PCIe controller state + * + * @ctrl_base: The base address of the register space + * @cfg_base: The base address of the configuration space + * @cfg_size: The size of the configuration space which is needed + * as it gets written into the PCIE_ATU_LIMIT register + * @first_busno: This driver supports multiple PCIe controllers. + * first_busno stores the bus number of the PCIe root-port + * number which may vary depending on the PCIe setup + * (PEX switches etc). + */ +struct pcie_dw_mvebu { + void *ctrl_base; + void *cfg_base; + fdt_size_t cfg_size; + int first_busno; +}; + +static int pcie_dw_get_link_speed(const void *regs_base) +{ + return (readl(regs_base + PCIE_LINK_STATUS_REG) & + PCIE_LINK_STATUS_SPEED_MASK) >> PCIE_LINK_STATUS_SPEED_OFF; +} + +static int pcie_dw_get_link_width(const void *regs_base) +{ + return (readl(regs_base + PCIE_LINK_STATUS_REG) & + PCIE_LINK_STATUS_WIDTH_MASK) >> PCIE_LINK_STATUS_WIDTH_OFF; +} + +/** + * set_cfg_address() - Configure the PCIe controller config space access + * + * @pcie: Pointer to the PCI controller state + * @d: PCI device to access + * @where: Offset in the configuration space + * + * Configures the PCIe controller to access the configuration space of + * a specific PCIe device and returns the address to use for this + * access. + * + * Return: Address that can be used to access the configation space + * of the requested device / offset + */ +static uintptr_t set_cfg_address(struct pcie_dw_mvebu *pcie, + pci_dev_t d, uint where) +{ + uintptr_t va_address; + + /* + * Region #0 is used for Outbound CFG space access. + * Direction = Outbound + * Region Index = 0 + */ + writel(0, pcie->ctrl_base + PCIE_ATU_VIEWPORT); + + if (PCI_BUS(d) == (pcie->first_busno + 1)) + /* For local bus, change TLP Type field to 4. */ + writel(PCIE_ATU_TYPE_CFG0, pcie->ctrl_base + PCIE_ATU_CR1); + else + /* Otherwise, change TLP Type field to 5. */ + writel(PCIE_ATU_TYPE_CFG1, pcie->ctrl_base + PCIE_ATU_CR1); + + if (PCI_BUS(d) == pcie->first_busno) { + /* Accessing root port configuration space. */ + va_address = (uintptr_t)pcie->ctrl_base; + } else { + writel(d << 8, pcie->ctrl_base + PCIE_ATU_LOWER_TARGET); + va_address = (uintptr_t)pcie->cfg_base; + } + + va_address += where & ~0x3; + + return va_address; +} + +/** + * pcie_dw_addr_valid() - Check for valid bus address + * + * @d: The PCI device to access + * @first_busno: Bus number of the PCIe controller root complex + * + * Return 1 (true) if the PCI device can be accessed by this controller. + * + * Return: 1 on valid, 0 on invalid + */ +static int pcie_dw_addr_valid(pci_dev_t d, int first_busno) +{ + if ((PCI_BUS(d) == first_busno) && (PCI_DEV(d) > 0)) + return 0; + if ((PCI_BUS(d) == first_busno + 1) && (PCI_DEV(d) > 0)) + return 0; + + return 1; +} + +/** + * pcie_dw_mvebu_read_config() - Read from configuration space + * + * @bus: Pointer to the PCI bus + * @bdf: Identifies the PCIe device to access + * @offset: The offset into the device's configuration space + * @valuep: A pointer at which to store the read value + * @size: Indicates the size of access to perform + * + * Read a value of size @size from offset @offset within the configuration + * space of the device identified by the bus, device & function numbers in @bdf + * on the PCI bus @bus. + * + * Return: 0 on success + */ +static int pcie_dw_mvebu_read_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong *valuep, + enum pci_size_t size) +{ + struct pcie_dw_mvebu *pcie = dev_get_priv(bus); + uintptr_t va_address; + ulong value; + + debug("PCIE CFG read: (b,d,f)=(%2d,%2d,%2d) ", + PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); + + if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) { + debug("- out of range\n"); + *valuep = pci_get_ff(size); + return 0; + } + + va_address = set_cfg_address(pcie, bdf, offset); + + value = readl(va_address); + + debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value); + *valuep = pci_conv_32_to_size(value, offset, size); + + return 0; +} + +/** + * pcie_dw_mvebu_write_config() - Write to configuration space + * + * @bus: Pointer to the PCI bus + * @bdf: Identifies the PCIe device to access + * @offset: The offset into the device's configuration space + * @value: The value to write + * @size: Indicates the size of access to perform + * + * Write the value @value of size @size from offset @offset within the + * configuration space of the device identified by the bus, device & function + * numbers in @bdf on the PCI bus @bus. + * + * Return: 0 on success + */ +static int pcie_dw_mvebu_write_config(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + struct pcie_dw_mvebu *pcie = dev_get_priv(bus); + uintptr_t va_address; + ulong old; + + debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ", + PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); + debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value); + + if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) { + debug("- out of range\n"); + return 0; + } + + va_address = set_cfg_address(pcie, bdf, offset); + + old = readl(va_address); + value = pci_conv_size_to_32(old, value, offset, size); + writel(value, va_address); + + return 0; +} + +/** + * pcie_dw_configure() - Configure link capabilities and speed + * + * @regs_base: A pointer to the PCIe controller registers + * @cap_speed: The capabilities and speed to configure + * + * Configure the link capabilities and speed in the PCIe root complex. + */ +static void pcie_dw_configure(const void *regs_base, u32 cap_speed) +{ + /* + * TODO (shadi@marvell.com, sr@denx.de): + * Need to read the serdes speed from the dts and according to it + * configure the PCIe gen + */ + + /* Set link to GEN 3 */ + clrsetbits_le32(regs_base + PCIE_LINK_CTL_2, + TARGET_LINK_SPEED_MASK, cap_speed); + clrsetbits_le32(regs_base + PCIE_LINK_CAPABILITY, + TARGET_LINK_SPEED_MASK, cap_speed); + setbits_le32(regs_base + PCIE_GEN3_EQU_CTRL, GEN3_EQU_EVAL_2MS_DISABLE); +} + +/** + * is_link_up() - Return the link state + * + * @regs_base: A pointer to the PCIe controller registers + * + * Return: 1 (true) for active line and 0 (false) for no link + */ +static int is_link_up(const void *regs_base) +{ + u32 mask = PCIE_GLB_STS_RDLH_LINK_UP | PCIE_GLB_STS_PHY_LINK_UP; + u32 reg; + + reg = readl(regs_base + PCIE_GLOBAL_STATUS); + if ((reg & mask) == mask) + return 1; + + return 0; +} + +/** + * wait_link_up() - Wait for the link to come up + * + * @regs_base: A pointer to the PCIe controller registers + * + * Return: 1 (true) for active line and 0 (false) for no link (timeout) + */ +static int wait_link_up(const void *regs_base) +{ + unsigned long timeout; + + timeout = get_timer(0) + PCIE_LINK_UP_TIMEOUT_MS; + while (!is_link_up(regs_base)) { + if (get_timer(0) > timeout) + return 0; + }; + + return 1; +} + +/** + * pcie_dw_mvebu_pcie_link_up() - Configure the PCIe root port + * + * @regs_base: A pointer to the PCIe controller registers + * @cap_speed: The capabilities and speed to configure + * + * Configure the PCIe controller root complex depending on the + * requested link capabilities and speed. + * + * Return: 1 (true) for active line and 0 (false) for no link + */ +static int pcie_dw_mvebu_pcie_link_up(const void *regs_base, u32 cap_speed) +{ + if (!is_link_up(regs_base)) { + /* Disable LTSSM state machine to enable configuration */ + clrbits_le32(regs_base + PCIE_GLOBAL_CONTROL, + PCIE_APP_LTSSM_EN); + } + + clrsetbits_le32(regs_base + PCIE_GLOBAL_CONTROL, + PCIE_DEVICE_TYPE_MASK << PCIE_DEVICE_TYPE_OFFSET, + PCIE_DEVICE_TYPE_RC << PCIE_DEVICE_TYPE_OFFSET); + + /* Set the PCIe master AXI attributes */ + writel(ARCACHE_SHAREABLE_CACHEABLE, regs_base + PCIE_ARCACHE_TRC); + writel(AWCACHE_SHAREABLE_CACHEABLE, regs_base + PCIE_AWCACHE_TRC); + + /* DW pre link configurations */ + pcie_dw_configure(regs_base, cap_speed); + + if (!is_link_up(regs_base)) { + /* Configuration done. Start LTSSM */ + setbits_le32(regs_base + PCIE_GLOBAL_CONTROL, + PCIE_APP_LTSSM_EN); + } + + /* Check that link was established */ + if (!wait_link_up(regs_base)) + return 0; + + /* + * Link can be established in Gen 1. still need to wait + * till MAC nagaotiation is completed + */ + udelay(100); + + return 1; +} + +/** + * pcie_dw_regions_setup() - iATU region setup + * + * @pcie: Pointer to the PCI controller state + * + * Configure the iATU regions in the PCIe controller for outbound access. + */ +static void pcie_dw_regions_setup(struct pcie_dw_mvebu *pcie) +{ + /* + * Region #0 is used for Outbound CFG space access. + * Direction = Outbound + * Region Index = 0 + */ + writel(0, pcie->ctrl_base + PCIE_ATU_VIEWPORT); + + writel((u32)(uintptr_t)pcie->cfg_base, pcie->ctrl_base + + PCIE_ATU_LOWER_BASE); + writel(0, pcie->ctrl_base + PCIE_ATU_UPPER_BASE); + writel((u32)(uintptr_t)pcie->cfg_base + pcie->cfg_size, + pcie->ctrl_base + PCIE_ATU_LIMIT); + + writel(0, pcie->ctrl_base + PCIE_ATU_LOWER_TARGET); + writel(0, pcie->ctrl_base + PCIE_ATU_UPPER_TARGET); + writel(PCIE_ATU_TYPE_CFG0, pcie->ctrl_base + PCIE_ATU_CR1); + writel(PCIE_ATU_ENABLE, pcie->ctrl_base + PCIE_ATU_CR2); +} + +/** + * pcie_dw_set_host_bars() - Configure the host BARs + * + * @regs_base: A pointer to the PCIe controller registers + * + * Configure the host BARs of the PCIe controller root port so that + * PCI(e) devices may access the system memory. + */ +static void pcie_dw_set_host_bars(const void *regs_base) +{ + u32 size = gd->ram_size; + u64 max_size; + u32 reg; + u32 bar0; + + /* Verify the maximal BAR size */ + reg = readl(regs_base + RESIZABLE_BAR_CAP); + max_size = 1ULL << (5 + (reg + (1 << 4))); + + if (size > max_size) { + size = max_size; + printf("Warning: PCIe BARs can't map all DRAM space\n"); + } + + /* Set the BAR base and size towards DDR */ + bar0 = CONFIG_SYS_SDRAM_BASE & ~0xf; + bar0 |= PCI_BASE_ADDRESS_MEM_TYPE_32; + writel(CONFIG_SYS_SDRAM_BASE, regs_base + PCIE_CONFIG_BAR0); + + reg = ((size >> 20) - 1) << 12; + writel(size, regs_base + RESIZABLE_BAR_CTL0); +} + +/** + * pcie_dw_mvebu_probe() - Probe the PCIe bus for active link + * + * @dev: A pointer to the device being operated on + * + * Probe for an active link on the PCIe bus and configure the controller + * to enable this port. + * + * Return: 0 on success, else -ENODEV + */ +static int pcie_dw_mvebu_probe(struct udevice *dev) +{ + struct pcie_dw_mvebu *pcie = dev_get_priv(dev); + struct udevice *ctlr = pci_get_controller(dev); + struct pci_controller *hose = dev_get_uclass_priv(ctlr); + + pcie->first_busno = dev->seq; + + /* Don't register host if link is down */ + if (!pcie_dw_mvebu_pcie_link_up(pcie->ctrl_base, LINK_SPEED_GEN_3)) { + printf("PCIE-%d: Link down\n", dev->seq); + return -ENODEV; + } + + printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n", dev->seq, + pcie_dw_get_link_speed(pcie->ctrl_base), + pcie_dw_get_link_width(pcie->ctrl_base), hose->first_busno); + + pcie_dw_regions_setup(pcie); + + /* Set the CLASS_REV of RC CFG header to PCI_CLASS_BRIDGE_PCI */ + clrsetbits_le32(pcie->ctrl_base + PCI_CLASS_REVISION, + 0xffff << 16, PCI_CLASS_BRIDGE_PCI << 16); + + pcie_dw_set_host_bars(pcie->ctrl_base); + + return 0; +} + +/** + * pcie_dw_mvebu_ofdata_to_platdata() - Translate from DT to device state + * + * @dev: A pointer to the device being operated on + * + * Translate relevant data from the device tree pertaining to device @dev into + * state that the driver will later make use of. This state is stored in the + * device's private data structure. + * + * Return: 0 on success, else -EINVAL + */ +static int pcie_dw_mvebu_ofdata_to_platdata(struct udevice *dev) +{ + struct pcie_dw_mvebu *pcie = dev_get_priv(dev); + + /* Get the controller base address */ + pcie->ctrl_base = (void *)dev_get_addr_index(dev, 0); + if (pcie->ctrl_base == FDT_ADDR_T_NONE) + return -EINVAL; + + /* Get the config space base address and size */ + pcie->cfg_base = (void *)dev_get_addr_size_index(dev, 1, + &pcie->cfg_size); + if (pcie->cfg_base == FDT_ADDR_T_NONE) + return -EINVAL; + + return 0; +} + +static const struct dm_pci_ops pcie_dw_mvebu_ops = { + .read_config = pcie_dw_mvebu_read_config, + .write_config = pcie_dw_mvebu_write_config, +}; + +static const struct udevice_id pcie_dw_mvebu_ids[] = { + { .compatible = "marvell,armada8k-pcie" }, + { } +}; + +U_BOOT_DRIVER(pcie_dw_mvebu) = { + .name = "pcie_dw_mvebu", + .id = UCLASS_PCI, + .of_match = pcie_dw_mvebu_ids, + .ops = &pcie_dw_mvebu_ops, + .ofdata_to_platdata = pcie_dw_mvebu_ofdata_to_platdata, + .probe = pcie_dw_mvebu_probe, + .priv_auto_alloc_size = sizeof(struct pcie_dw_mvebu), +};

On 28 November 2016 at 05:38, Stefan Roese sr@denx.de wrote:
From: Shadi Ammouri shadi@marvell.com
This patch adds a driver for the PCIe controller integrated in the Marvell Armada-8K SoC. This controller is based on the DesignWare IP core.
The original version was written by Shadi and Yehuda. I ported this driver to the latest mainline U-Boot version with DM support.
Tested on the Marvell DB-88F8040 Armada-8K eval board.
Signed-off-by: Shadi Ammouri shadi@marvell.com Signed-off-by: Yehuda Yitschak yehuday@marvell.com Signed-off-by: Stefan Roese sr@denx.de Cc: Simon Glass sjg@chromium.org Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com
v2:
- Removed host struct from private data struct
- Added comments to structs and functions
- Moved shift into the macro for PCIE_LINK_STATUS_SPEED_MASK and PCIE_LINK_STATUS_WIDTH_MASK
- Added Email addresses to ToDo statement
- Used clrsetbits_le32(9 where applicable
- Added const to register base pointer
- Used new core function dev_get_addr_size_index() to retrieve addr and size
- Added code to configure the PCIe root complex device as PCI bridge device
drivers/pci/Kconfig | 10 + drivers/pci/Makefile | 1 + drivers/pci/pcie_dw_mvebu.c | 535 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 546 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

Hi Simon,
On 03.12.2016 05:26, Simon Glass wrote:
On 28 November 2016 at 05:38, Stefan Roese sr@denx.de wrote:
From: Shadi Ammouri shadi@marvell.com
This patch adds a driver for the PCIe controller integrated in the Marvell Armada-8K SoC. This controller is based on the DesignWare IP core.
The original version was written by Shadi and Yehuda. I ported this driver to the latest mainline U-Boot version with DM support.
Tested on the Marvell DB-88F8040 Armada-8K eval board.
Signed-off-by: Shadi Ammouri shadi@marvell.com Signed-off-by: Yehuda Yitschak yehuday@marvell.com Signed-off-by: Stefan Roese sr@denx.de Cc: Simon Glass sjg@chromium.org Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com
v2:
- Removed host struct from private data struct
- Added comments to structs and functions
- Moved shift into the macro for PCIE_LINK_STATUS_SPEED_MASK and PCIE_LINK_STATUS_WIDTH_MASK
- Added Email addresses to ToDo statement
- Used clrsetbits_le32(9 where applicable
- Added const to register base pointer
- Used new core function dev_get_addr_size_index() to retrieve addr and size
- Added code to configure the PCIe root complex device as PCI bridge device
drivers/pci/Kconfig | 10 + drivers/pci/Makefile | 1 + drivers/pci/pcie_dw_mvebu.c | 535 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 546 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
Thanks.
I would like to integrate this PCIE driver in my next mvebu pull request, introducing the Armada 8K support. But it depends on the DM patch "dm: core: Add dev_get_addr_size_index() to retrieve addr and size". What is your plan with this one? Will you pull this patch soon? Or should I pull it with my mvebu patch series?
Thanks, Stefan

Hi Stefan,
On 3 December 2016 at 02:20, Stefan Roese sr@denx.de wrote:
Hi Simon,
On 03.12.2016 05:26, Simon Glass wrote:
On 28 November 2016 at 05:38, Stefan Roese sr@denx.de wrote:
From: Shadi Ammouri shadi@marvell.com
This patch adds a driver for the PCIe controller integrated in the Marvell Armada-8K SoC. This controller is based on the DesignWare IP core.
The original version was written by Shadi and Yehuda. I ported this driver to the latest mainline U-Boot version with DM support.
Tested on the Marvell DB-88F8040 Armada-8K eval board.
Signed-off-by: Shadi Ammouri shadi@marvell.com Signed-off-by: Yehuda Yitschak yehuday@marvell.com Signed-off-by: Stefan Roese sr@denx.de Cc: Simon Glass sjg@chromium.org Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com
v2:
- Removed host struct from private data struct
- Added comments to structs and functions
- Moved shift into the macro for PCIE_LINK_STATUS_SPEED_MASK and PCIE_LINK_STATUS_WIDTH_MASK
- Added Email addresses to ToDo statement
- Used clrsetbits_le32(9 where applicable
- Added const to register base pointer
- Used new core function dev_get_addr_size_index() to retrieve addr and size
- Added code to configure the PCIe root complex device as PCI bridge device
drivers/pci/Kconfig | 10 + drivers/pci/Makefile | 1 + drivers/pci/pcie_dw_mvebu.c | 535 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 546 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
Thanks.
I would like to integrate this PCIE driver in my next mvebu pull request, introducing the Armada 8K support. But it depends on the DM patch "dm: core: Add dev_get_addr_size_index() to retrieve addr and size". What is your plan with this one? Will you pull this patch soon? Or should I pull it with my mvebu patch series?
I did have a second set of patches including this. So I've pushed it into dm/master and sent an updated pull request.
Regards, Simon

On 03.12.2016 19:31, Simon Glass wrote:
On 03.12.2016 05:26, Simon Glass wrote:
On 28 November 2016 at 05:38, Stefan Roese sr@denx.de wrote:
From: Shadi Ammouri shadi@marvell.com
This patch adds a driver for the PCIe controller integrated in the Marvell Armada-8K SoC. This controller is based on the DesignWare IP core.
The original version was written by Shadi and Yehuda. I ported this driver to the latest mainline U-Boot version with DM support.
Tested on the Marvell DB-88F8040 Armada-8K eval board.
Signed-off-by: Shadi Ammouri shadi@marvell.com Signed-off-by: Yehuda Yitschak yehuday@marvell.com Signed-off-by: Stefan Roese sr@denx.de Cc: Simon Glass sjg@chromium.org Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com
v2:
- Removed host struct from private data struct
- Added comments to structs and functions
- Moved shift into the macro for PCIE_LINK_STATUS_SPEED_MASK and PCIE_LINK_STATUS_WIDTH_MASK
- Added Email addresses to ToDo statement
- Used clrsetbits_le32(9 where applicable
- Added const to register base pointer
- Used new core function dev_get_addr_size_index() to retrieve addr and size
- Added code to configure the PCIe root complex device as PCI bridge device
drivers/pci/Kconfig | 10 + drivers/pci/Makefile | 1 + drivers/pci/pcie_dw_mvebu.c | 535 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 546 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
Thanks.
I would like to integrate this PCIE driver in my next mvebu pull request, introducing the Armada 8K support. But it depends on the DM patch "dm: core: Add dev_get_addr_size_index() to retrieve addr and size". What is your plan with this one? Will you pull this patch soon? Or should I pull it with my mvebu patch series?
I did have a second set of patches including this. So I've pushed it into dm/master and sent an updated pull request.
Thanks Simon!

To use the PCIe driver, its controller memory and the PCIe regions need to get mapped in the MMU. Otherwise these areas can't be accessed.
Signed-off-by: Stefan Roese sr@denx.de Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- arch/arm/mach-mvebu/armada8k/cpu.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/arch/arm/mach-mvebu/armada8k/cpu.c b/arch/arm/mach-mvebu/armada8k/cpu.c index f8e69d6..2719d68 100644 --- a/arch/arm/mach-mvebu/armada8k/cpu.c +++ b/arch/arm/mach-mvebu/armada8k/cpu.c @@ -55,6 +55,14 @@ static struct mm_region mvebu_mem_map[] = { PTE_BLOCK_NON_SHARE }, { + /* PCI regions */ + .phys = 0xf8000000UL, + .virt = 0xf8000000UL, + .size = 0x08000000UL, /* 128MiB PCI space (master & slave) */ + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE + }, + { /* List terminator */ 0, }

This patch adds PCI support to the Marvell Armada-8K devel board. Additionally the Intel E1000 ethernet driver is enabled so that network support is available on this board, even without the internal network interfaces being supported (yet).
Signed-off-by: Stefan Roese sr@denx.de Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- configs/mvebu_db-88f8040_defconfig | 3 +++ include/configs/mvebu_armada-8k.h | 8 ++++++++ 2 files changed, 11 insertions(+)
diff --git a/configs/mvebu_db-88f8040_defconfig b/configs/mvebu_db-88f8040_defconfig index eccb0f0..61d58b5 100644 --- a/configs/mvebu_db-88f8040_defconfig +++ b/configs/mvebu_db-88f8040_defconfig @@ -36,6 +36,9 @@ CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_PHYLIB=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCIE_DW_MVEBU=y CONFIG_MVEBU_COMPHY_SUPPORT=y # CONFIG_SPL_SERIAL_PRESENT is not set CONFIG_DEBUG_UART=y diff --git a/include/configs/mvebu_armada-8k.h b/include/configs/mvebu_armada-8k.h index 3b35cb3..8ab5bbe 100644 --- a/include/configs/mvebu_armada-8k.h +++ b/include/configs/mvebu_armada-8k.h @@ -128,4 +128,12 @@ #define CONFIG_CMD_PART #define CONFIG_PARTITION_UUIDS
+/* + * PCI configuration + */ +#ifdef CONFIG_PCIE_DW_MVEBU +#define CONFIG_E1000 +#define CONFIG_CMD_PCI +#endif + #endif /* _CONFIG_MVEBU_ARMADA_8K_H */

Not all memory is mapped in the MMU. So we need to restrict the memory size so that U-Boot does not try to access it. Also, the internal registers are located at 0xf000.0000 - 0xffff.ffff. Currently only 2GiB are mapped for system memory. This is what we pass to the U-Boot subsystem here.
Signed-off-by: Stefan Roese sr@denx.de Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com --- arch/arm/mach-mvebu/arm64-common.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c index 1fc2ff2..8f02655 100644 --- a/arch/arm/mach-mvebu/arm64-common.c +++ b/arch/arm/mach-mvebu/arm64-common.c @@ -17,6 +17,23 @@ DECLARE_GLOBAL_DATA_PTR;
/* + * Not all memory is mapped in the MMU. So we need to restrict the + * memory size so that U-Boot does not try to access it. Also, the + * internal registers are located at 0xf000.0000 - 0xffff.ffff. + * Currently only 2GiB are mapped for system memory. This is what + * we pass to the U-Boot subsystem here. + */ +#define USABLE_RAM_SIZE 0x80000000 + +ulong board_get_usable_ram_top(ulong total_size) +{ + if (gd->ram_size > USABLE_RAM_SIZE) + return USABLE_RAM_SIZE; + + return gd->ram_size; +} + +/* * On ARMv8, MBus is not configured in U-Boot. To enable compilation * of the already implemented drivers, lets add a dummy version of * this function so that linking does not fail.

On 15.11.2016 10:08, Stefan Roese wrote:
This moves some of the Armada DB-88F7040 board specific files to a more generic name: armada-8k. This is in preparation for the Armada-8k support which will be added soon. And since both platforms share most devices, lets also share most source files to not duplicate the code here.
Signed-off-by: Stefan Roese sr@denx.de Cc: Nadav Haklai nadavh@marvell.com Cc: Neta Zur Hershkovits neta@marvell.com Cc: Kostya Porotchkin kostap@marvell.com Cc: Omri Itach omrii@marvell.com Cc: Igal Liberman igall@marvell.com Cc: Haim Boot hayim@marvell.com Cc: Hanna Hawa hannah@marvell.com
The whole patchset is:
Applied to u-boot-marvell/master.
Thanks, Stefan
participants (3)
-
Simon Glass
-
Stefan Roese
-
Stefan Roese