diff options
427 files changed, 14211 insertions, 3337 deletions
diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt new file mode 100644 index 00000000000..bac4afa3b19 --- /dev/null +++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt @@ -0,0 +1,136 @@ +*** Reserved memory regions *** + +Reserved memory is specified as a node under the /reserved-memory node. +The operating system shall exclude reserved memory from normal usage +one can create child nodes describing particular reserved (excluded from +normal use) memory regions. Such memory regions are usually designed for +the special usage by various device drivers. + +Parameters for each memory region can be encoded into the device tree +with the following nodes: + +/reserved-memory node +--------------------- +#address-cells, #size-cells (required) - standard definition + - Should use the same values as the root node +ranges (required) - standard definition + - Should be empty + +/reserved-memory/ child nodes +----------------------------- +Each child of the reserved-memory node specifies one or more regions of +reserved memory. Each child node may either use a 'reg' property to +specify a specific range of reserved memory, or a 'size' property with +optional constraints to request a dynamically allocated block of memory. + +Following the generic-names recommended practice, node names should +reflect the purpose of the node (ie. "framebuffer" or "dma-pool"). Unit +address (@<address>) should be appended to the name if the node is a +static allocation. + +Properties: +Requires either a) or b) below. +a) static allocation + reg (required) - standard definition +b) dynamic allocation + size (required) - length based on parent's #size-cells + - Size in bytes of memory to reserve. + alignment (optional) - length based on parent's #size-cells + - Address boundary for alignment of allocation. + alloc-ranges (optional) - prop-encoded-array (address, length pairs). + - Specifies regions of memory that are + acceptable to allocate from. + +If both reg and size are present, then the reg property takes precedence +and size is ignored. + +Additional properties: +compatible (optional) - standard definition + - may contain the following strings: + - shared-dma-pool: This indicates a region of memory meant to be + used as a shared pool of DMA buffers for a set of devices. It can + be used by an operating system to instantiate the necessary pool + management subsystem if necessary. + - vendor specific string in the form <vendor>,[<device>-]<usage> +no-map (optional) - empty property + - Indicates the operating system must not create a virtual mapping + of the region as part of its standard mapping of system memory, + nor permit speculative access to it under any circumstances other + than under the control of the device driver using the region. +reusable (optional) - empty property + - The operating system can use the memory in this region with the + limitation that the device driver(s) owning the region need to be + able to reclaim it back. Typically that means that the operating + system can use that region to store volatile or cached data that + can be otherwise regenerated or migrated elsewhere. + +Linux implementation note: +- If a "linux,cma-default" property is present, then Linux will use the + region for the default pool of the contiguous memory allocator. + +- If a "linux,dma-default" property is present, then Linux will use the + region for the default pool of the consistent DMA allocator. + +Device node references to reserved memory +----------------------------------------- +Regions in the /reserved-memory node may be referenced by other device +nodes by adding a memory-region property to the device node. + +memory-region (optional) - phandle, specifier pairs to children of /reserved-memory + +Example +------- +This example defines 3 contiguous regions are defined for Linux kernel: +one default of all device drivers (named linux,cma@72000000 and 64MiB in size), +one dedicated to the framebuffer device (named framebuffer@78000000, 8MiB), and +one for multimedia processing (named multimedia-memory@77000000, 64MiB). + +/ { + #address-cells = <1>; + #size-cells = <1>; + + memory { + reg = <0x40000000 0x40000000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* global autoconfigured region for contiguous allocations */ + linux,cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x4000000>; + alignment = <0x2000>; + linux,cma-default; + }; + + display_reserved: framebuffer@78000000 { + reg = <0x78000000 0x800000>; + }; + + multimedia_reserved: multimedia@77000000 { + compatible = "acme,multimedia-memory"; + reg = <0x77000000 0x4000000>; + }; + }; + + /* ... */ + + fb0: video@12300000 { + memory-region = <&display_reserved>; + /* ... */ + }; + + scaler: scaler@12500000 { + memory-region = <&multimedia_reserved>; + /* ... */ + }; + + codec: codec@12600000 { + memory-region = <&multimedia_reserved>; + /* ... */ + }; +}; diff --git a/MAINTAINERS b/MAINTAINERS index f9ee4281d94..c77abba1e5b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -295,7 +295,9 @@ F: drivers/misc/stm32mp_fuse.c F: drivers/mmc/stm32_sdmmc2.c F: drivers/phy/phy-stm32-usbphyc.c F: drivers/pinctrl/pinctrl_stm32.c +F: drivers/power/pmic/stpmic1.c F: drivers/power/regulator/stm32-vrefbuf.c +F: drivers/power/regulator/stpmic1.c F: drivers/ram/stm32mp1/ F: drivers/misc/stm32_rcc.c F: drivers/reset/stm32-reset.c @@ -308,7 +310,7 @@ F: arch/arm/cpu/armv7/stv0991/ F: arch/arm/include/asm/arch-stv0991/ ARM SUNXI -M: Jagan Teki <jagan@openedev.com> +M: Jagan Teki <jagan@amarulasolutions.com> M: Maxime Ripard <maxime.ripard@bootlin.com> S: Maintained T: git git://git.denx.de/u-boot-sunxi.git @@ -689,14 +691,14 @@ T: git git://git.denx.de/u-boot-sh.git F: arch/sh/ SPI -M: Jagan Teki <jagan@openedev.com> +M: Jagan Teki <jagan@amarulasolutions.com> S: Maintained T: git git://git.denx.de/u-boot-spi.git F: drivers/spi/ F: include/spi* SPI-NOR -M: Jagan Teki <jagan@openedev.com> +M: Jagan Teki <jagan@amarulasolutions.com> M: Vignesh R <vigneshr@ti.com> S: Maintained F: drivers/mtd/spi/ @@ -945,11 +945,22 @@ ifneq ($(CONFIG_DM_USB)$(CONFIG_OF_CONTROL)$(CONFIG_BLK),yyy) @echo >&2 "====================================================" endif endif -ifeq ($(CONFIG_LIBATA)$(CONFIG_MVSATA_IDE),y) -ifneq ($(CONFIG_DM_SCSI),y) +ifeq ($(CONFIG_MVSATA_IDE),y) @echo >&2 "===================== WARNING ======================" - @echo >&2 "This board does not use CONFIG_DM_SCSI. Please update" - @echo >&2 "the storage controller to use CONFIG_DM_SCSI before the v2019.07 release." + @echo >&2 "This board does use CONFIG_MVSATA_IDE which is not" + @echo >&2 "ported to driver-model (DM) yet. Please update the storage" + @echo >&2 "controller driver to use CONFIG_AHCI before the v2019.07" + @echo >&2 "release." + @echo >&2 "Failure to update by the deadline may result in board removal." + @echo >&2 "See doc/driver-model/MIGRATION.txt for more info." + @echo >&2 "====================================================" +endif +ifeq ($(CONFIG_LIBATA),y) +ifneq ($(CONFIG_AHCI),y) + @echo >&2 "===================== WARNING ======================" + @echo >&2 "This board does use CONFIG_LIBATA but has CONFIG_AHCI not" + @echo >&2 "enabled. Please update the storage controller driver to use" + @echo >&2 "CONFIG_AHCI before the v2019.07 release." @echo >&2 "Failure to update by the deadline may result in board removal." @echo >&2 "See doc/driver-model/MIGRATION.txt for more info." @echo >&2 "====================================================" diff --git a/arch/arc/dts/axs10x_mb.dtsi b/arch/arc/dts/axs10x_mb.dtsi index dfc03810ca0..b5aacd5170e 100644 --- a/arch/arc/dts/axs10x_mb.dtsi +++ b/arch/arc/dts/axs10x_mb.dtsi @@ -71,7 +71,7 @@ clock-names = "spi_clk"; cs-gpio = <&cs_gpio 0>; spi_flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <4000000>; }; diff --git a/arch/arc/dts/hsdk.dts b/arch/arc/dts/hsdk.dts index f024b96925e..5e9ba054a4c 100644 --- a/arch/arc/dts/hsdk.dts +++ b/arch/arc/dts/hsdk.dts @@ -96,7 +96,7 @@ clock-names = "spi_clk"; cs-gpio = <&cs_gpio 0>; spi_flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <4000000>; }; diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 398dbef1cb8..4640f3b3bd3 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1403,11 +1403,15 @@ config ARCH_STM32MP select SYSRESET select SYS_THUMB_BUILD imply CMD_DM + imply CMD_POWEROFF + imply ENV_VARS_UBOOT_RUNTIME_CONFIG help Support for STM32MP SoC family developed by STMicroelectronics, MPUs based on ARM cortex A core - U-BOOT is running in DDR and SPL support is the unsecure First Stage - BootLoader (FSBL) + U-BOOT is running in DDR, loaded by the First Stage BootLoader (FSBL). + FSBL can be TF-A: Trusted Firmware for Cortex A, for trusted boot + chain. + SPL is the unsecure FSBL for the basic boot chain. config ARCH_ROCKCHIP bool "Support Rockchip SoCs" diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 65e0f66c789..8167cdb4e85 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -138,7 +138,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ armada-388-clearfog.dtb \ armada-388-gp.dtb \ armada-388-helios4.dtb \ - armada-385-amc.dtb \ + armada-385-db-88f6820-amc.dtb \ armada-385-turris-omnia.dtb \ armada-7040-db.dtb \ armada-7040-db-nand.dtb \ @@ -151,7 +151,8 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ armada-xp-theadorable.dtb \ armada-38x-controlcenterdc.dtb \ armada-385-atl-x530.dtb \ - armada-385-atl-x530DP.dtb + armada-385-atl-x530DP.dtb \ + armada-xp-db-xc3-24g4xg.dtb dtb-$(CONFIG_ARCH_UNIPHIER_LD11) += \ uniphier-ld11-global.dtb \ @@ -475,6 +476,7 @@ dtb-$(CONFIG_MACH_SUN50I) += \ sun50i-a64-amarula-relic.dtb \ sun50i-a64-bananapi-m64.dtb \ sun50i-a64-nanopi-a64.dtb \ + sun50i-a64-oceanic-5205-5inmfd.dtb \ sun50i-a64-olinuxino.dtb \ sun50i-a64-orangepi-win.dtb \ sun50i-a64-pine64-lts.dtb \ @@ -686,6 +688,8 @@ dtb-$(CONFIG_ARCH_ASPEED) += ast2500-evb.dtb dtb-$(CONFIG_ARCH_STI) += stih410-b2260.dtb dtb-$(CONFIG_TARGET_STM32MP1) += \ + stm32mp157a-dk1.dtb \ + stm32mp157c-dk2.dtb \ stm32mp157c-ed1.dtb \ stm32mp157c-ev1.dtb diff --git a/arch/arm/dts/am335x-brppt1-spi.dts b/arch/arm/dts/am335x-brppt1-spi.dts index 522ed509020..01ab74be5ed 100644 --- a/arch/arm/dts/am335x-brppt1-spi.dts +++ b/arch/arm/dts/am335x-brppt1-spi.dts @@ -169,7 +169,7 @@ spi_flash: spiflash@0 { u-boot,dm-spl; u-boot,dm-pre-reloc; - compatible = "spidev", "spi-flash"; + compatible = "spidev", "jedec,spi-nor"; spi-max-frequency = <24000000>; reg = <0>; }; diff --git a/arch/arm/dts/am437x-idk-evm.dts b/arch/arm/dts/am437x-idk-evm.dts index 28e3e1ba32a..19d1462d158 100644 --- a/arch/arm/dts/am437x-idk-evm.dts +++ b/arch/arm/dts/am437x-idk-evm.dts @@ -339,7 +339,7 @@ spi-max-frequency = <48000000>; m25p80@0 { - compatible = "mx66l51235l", "spi-flash"; + compatible = "mx66l51235l", "jedec,spi-nor"; spi-max-frequency = <48000000>; reg = <0>; spi-cpol; diff --git a/arch/arm/dts/am437x-sk-evm.dts b/arch/arm/dts/am437x-sk-evm.dts index 927d8d3e882..dc8fcde4586 100644 --- a/arch/arm/dts/am437x-sk-evm.dts +++ b/arch/arm/dts/am437x-sk-evm.dts @@ -568,7 +568,7 @@ spi-max-frequency = <48000000>; m25p80@0 { - compatible = "mx66l51235l","spi-flash"; + compatible = "mx66l51235l","jedec,spi-nor"; spi-max-frequency = <48000000>; reg = <0>; spi-cpol; diff --git a/arch/arm/dts/armada-370-xp.dtsi b/arch/arm/dts/armada-370-xp.dtsi index 0b2a78d3930..e4c35d4e98f 100644 --- a/arch/arm/dts/armada-370-xp.dtsi +++ b/arch/arm/dts/armada-370-xp.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Device Tree Include file for Marvell Armada 370 and Armada XP SoC * @@ -8,50 +9,10 @@ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> * Ben Dooks <ben.dooks@codethink.co.uk> * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This file is distributed in the hope that it will be useful - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * * This file contains the definitions that are common to the Armada * 370 and Armada XP SoC. */ -/include/ "skeleton64.dtsi" - #define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16)) / { @@ -86,7 +47,7 @@ pcie-mem-aperture = <0xf8000000 0x7e00000>; pcie-io-aperture = <0xffe00000 0x100000>; - devbus-bootcs { + devbus_bootcs: devbus-bootcs { compatible = "marvell,mvebu-devbus"; reg = <MBUS_ID(0xf0, 0x01) 0x10400 0x8>; ranges = <0 MBUS_ID(0x01, 0x2f) 0 0xffffffff>; @@ -96,7 +57,7 @@ status = "disabled"; }; - devbus-cs0 { + devbus_cs0: devbus-cs0 { compatible = "marvell,mvebu-devbus"; reg = <MBUS_ID(0xf0, 0x01) 0x10408 0x8>; ranges = <0 MBUS_ID(0x01, 0x3e) 0 0xffffffff>; @@ -106,7 +67,7 @@ status = "disabled"; }; - devbus-cs1 { + devbus_cs1: devbus-cs1 { compatible = "marvell,mvebu-devbus"; reg = <MBUS_ID(0xf0, 0x01) 0x10410 0x8>; ranges = <0 MBUS_ID(0x01, 0x3d) 0 0xffffffff>; @@ -116,7 +77,7 @@ status = "disabled"; }; - devbus-cs2 { + devbus_cs2: devbus-cs2 { compatible = "marvell,mvebu-devbus"; reg = <MBUS_ID(0xf0, 0x01) 0x10418 0x8>; ranges = <0 MBUS_ID(0x01, 0x3b) 0 0xffffffff>; @@ -126,7 +87,7 @@ status = "disabled"; }; - devbus-cs3 { + devbus_cs3: devbus-cs3 { compatible = "marvell,mvebu-devbus"; reg = <MBUS_ID(0xf0, 0x01) 0x10420 0x8>; ranges = <0 MBUS_ID(0x01, 0x37) 0 0xffffffff>; @@ -141,34 +102,13 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>; - u-boot,dm-pre-reloc; - rtc@10300 { + rtc: rtc@10300 { compatible = "marvell,orion-rtc"; reg = <0x10300 0x20>; interrupts = <50>; }; - spi0: spi@10600 { - reg = <0x10600 0x28>; - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - interrupts = <30>; - clocks = <&coreclk 0>; - status = "disabled"; - }; - - spi1: spi@10680 { - reg = <0x10680 0x28>; - #address-cells = <1>; - #size-cells = <0>; - cell-index = <1>; - interrupts = <92>; - clocks = <&coreclk 0>; - status = "disabled"; - }; - i2c0: i2c@11000 { compatible = "marvell,mv64xxx-i2c"; #address-cells = <1>; @@ -235,33 +175,38 @@ msi-controller; }; - coherency-fabric@20200 { + coherencyfab: coherency-fabric@20200 { compatible = "marvell,coherency-fabric"; reg = <0x20200 0xb0>, <0x21010 0x1c>; }; - timer@20300 { + timer: timer@20300 { reg = <0x20300 0x30>, <0x21040 0x30>; interrupts = <37>, <38>, <39>, <40>, <5>, <6>; }; - watchdog@20300 { + watchdog: watchdog@20300 { reg = <0x20300 0x34>, <0x20704 0x4>; }; - pmsu@22000 { + cpurst: cpurst@20800 { + compatible = "marvell,armada-370-cpu-reset"; + reg = <0x20800 0x8>; + }; + + pmsu: pmsu@22000 { compatible = "marvell,armada-370-pmsu"; reg = <0x22000 0x1000>; }; - usb@50000 { + usb0: usb@50000 { compatible = "marvell,orion-ehci"; reg = <0x50000 0x500>; interrupts = <45>; status = "disabled"; }; - usb@51000 { + usb1: usb@51000 { compatible = "marvell,orion-ehci"; reg = <0x51000 0x500>; interrupts = <46>; @@ -275,7 +220,7 @@ status = "disabled"; }; - mdio: mdio { + mdio: mdio@72004 { #address-cells = <1>; #size-cells = <0>; compatible = "marvell,orion-mdio"; @@ -290,7 +235,7 @@ status = "disabled"; }; - sata@a0000 { + sata: sata@a0000 { compatible = "marvell,armada-370-sata"; reg = <0xa0000 0x5000>; interrupts = <55>; @@ -309,7 +254,7 @@ status = "disabled"; }; - mvsdio@d4000 { + sdio: mvsdio@d4000 { compatible = "marvell,orion-sdio"; reg = <0xd4000 0x200>; interrupts = <54>; @@ -321,6 +266,42 @@ status = "disabled"; }; }; + + spi0: spi@10600 { + reg = <MBUS_ID(0xf0, 0x01) 0x10600 0x28>, /* control */ + <MBUS_ID(0x01, 0x1e) 0 0xffffffff>, /* CS0 */ + <MBUS_ID(0x01, 0x5e) 0 0xffffffff>, /* CS1 */ + <MBUS_ID(0x01, 0x9e) 0 0xffffffff>, /* CS2 */ + <MBUS_ID(0x01, 0xde) 0 0xffffffff>, /* CS3 */ + <MBUS_ID(0x01, 0x1f) 0 0xffffffff>, /* CS4 */ + <MBUS_ID(0x01, 0x5f) 0 0xffffffff>, /* CS5 */ + <MBUS_ID(0x01, 0x9f) 0 0xffffffff>, /* CS6 */ + <MBUS_ID(0x01, 0xdf) 0 0xffffffff>; /* CS7 */ + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + interrupts = <30>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + spi1: spi@10680 { + reg = <MBUS_ID(0xf0, 0x01) 0x10680 0x28>, /* control */ + <MBUS_ID(0x01, 0x1a) 0 0xffffffff>, /* CS0 */ + <MBUS_ID(0x01, 0x5a) 0 0xffffffff>, /* CS1 */ + <MBUS_ID(0x01, 0x9a) 0 0xffffffff>, /* CS2 */ + <MBUS_ID(0x01, 0xda) 0 0xffffffff>, /* CS3 */ + <MBUS_ID(0x01, 0x1b) 0 0xffffffff>, /* CS4 */ + <MBUS_ID(0x01, 0x5b) 0 0xffffffff>, /* CS5 */ + <MBUS_ID(0x01, 0x9b) 0 0xffffffff>, /* CS6 */ + <MBUS_ID(0x01, 0xdb) 0 0xffffffff>; /* CS7 */ + #address-cells = <1>; + #size-cells = <0>; + cell-index = <1>; + interrupts = <92>; + clocks = <&coreclk 0>; + status = "disabled"; + }; }; clocks { diff --git a/arch/arm/dts/armada-3720-db.dts b/arch/arm/dts/armada-3720-db.dts index 770c08aa7dd..1b219c423bd 100644 --- a/arch/arm/dts/armada-3720-db.dts +++ b/arch/arm/dts/armada-3720-db.dts @@ -131,7 +131,7 @@ spi-flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "st,m25p128", "spi-flash"; + compatible = "st,m25p128", "jedec,spi-nor"; reg = <0>; /* Chip select 0 */ spi-max-frequency = <50000000>; m25p,fast-read; diff --git a/arch/arm/dts/armada-3720-espressobin.dts b/arch/arm/dts/armada-3720-espressobin.dts index 7bfccb0435a..84e2c2adbae 100644 --- a/arch/arm/dts/armada-3720-espressobin.dts +++ b/arch/arm/dts/armada-3720-espressobin.dts @@ -118,7 +118,7 @@ spi-flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "st,m25p128", "spi-flash"; + compatible = "st,m25p128", "jedec,spi-nor"; reg = <0>; /* Chip select 0 */ spi-max-frequency = <50000000>; m25p,fast-read; diff --git a/arch/arm/dts/armada-3720-turris-mox.dts b/arch/arm/dts/armada-3720-turris-mox.dts index 14bec0977e9..c36a5b8895a 100644 --- a/arch/arm/dts/armada-3720-turris-mox.dts +++ b/arch/arm/dts/armada-3720-turris-mox.dts @@ -115,7 +115,7 @@ spi-flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "st,s25fl064l", "spi-flash"; + compatible = "st,s25fl064l", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <20000000>; m25p,fast-read; diff --git a/arch/arm/dts/armada-385-amc.dts b/arch/arm/dts/armada-385-amc.dts deleted file mode 100644 index c9ccbb57fff..00000000000 --- a/arch/arm/dts/armada-385-amc.dts +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Device Tree file for Marvell Armada 385 development board - * (DB-88F6820-AMC) - * - * Copyright (C) 2014 Marvell - * - * Gregory CLEMENT <gregory.clement@free-electrons.com> - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without - * any warranty of any kind, whether express or implied. - * - * 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. - */ - -/dts-v1/; -#include "armada-385.dtsi" -#include <dt-bindings/gpio/gpio.h> - -/ { - model = "Marvell Armada 385 AMC"; - compatible = "marvell,a385-amc", "marvell,armada385", "marvell,armada380"; - - chosen { - stdout-path = "serial0:115200n8"; - }; - - aliases { - ethernet0 = ð0; - ethernet1 = ð2; - i2c0 = &i2c0; - spi1 = &spi1; - }; - - memory { - device_type = "memory"; - reg = <0x00000000 0x80000000>; /* 2 GB */ - }; - - soc { - ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000 - MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>; - - internal-regs { - i2c@11000 { - clock-frequency = <100000>; - u-boot,i2c-slave-addr = <0x0>; - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins>; - status = "okay"; - }; - - serial@12000 { - /* - * Exported on the micro USB connector CON16 - * through an FTDI - */ - - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins>; - status = "okay"; - u-boot,dm-pre-reloc; - }; - - ethernet@34000 { - status = "okay"; - phy = <&phy1>; - phy-mode = "sgmii"; - }; - - usb@58000 { - status = "okay"; - }; - - ethernet@70000 { - pinctrl-names = "default"; - /* - * The Reference Clock 0 is used to provide a - * clock to the PHY - */ - pinctrl-0 = <&ge0_rgmii_pins>, <&ref_clk0_pins>; - status = "okay"; - phy = <&phy0>; - phy-mode = "rgmii-id"; - }; - - - mdio@72004 { - pinctrl-names = "default"; - pinctrl-0 = <&mdio_pins>; - - phy0: ethernet-phy@1 { - reg = <1>; - }; - - phy1: ethernet-phy@0 { - reg = <0>; - }; - }; - - flash@d0000 { - status = "okay"; - num-cs = <1>; - marvell,nand-keep-config; - marvell,nand-enable-arbiter; - nand-on-flash-bbt; - }; - }; - - pcie { - status = "okay"; - pcie@1,0 { - /* Port 0, Lane 0 */ - status = "okay"; - }; - - }; - }; -}; - -&spi1 { - pinctrl-names = "default"; - pinctrl-0 = <&spi1_pins>; - status = "okay"; - u-boot,dm-pre-reloc; - - spi-flash@0 { - u-boot,dm-pre-reloc; - #address-cells = <1>; - #size-cells = <1>; - compatible = "st,m25p128", "jedec,spi-nor", "spi-flash"; - reg = <0>; /* Chip select 0 */ - spi-max-frequency = <50000000>; - m25p,fast-read; - }; -}; - -&refclk { - clock-frequency = <20000000>; -}; diff --git a/arch/arm/dts/armada-385-atl-x530-u-boot.dtsi b/arch/arm/dts/armada-385-atl-x530-u-boot.dtsi index 7074a73537f..79b694cb84b 100644 --- a/arch/arm/dts/armada-385-atl-x530-u-boot.dtsi +++ b/arch/arm/dts/armada-385-atl-x530-u-boot.dtsi @@ -11,3 +11,7 @@ &uart0 { u-boot,dm-pre-reloc; }; + +&watchdog { + u-boot,dm-pre-reloc; +}; diff --git a/arch/arm/dts/armada-385-db-88f6820-amc.dts b/arch/arm/dts/armada-385-db-88f6820-amc.dts new file mode 100644 index 00000000000..59a425f6b15 --- /dev/null +++ b/arch/arm/dts/armada-385-db-88f6820-amc.dts @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Device Tree file for Marvell Armada 385 AMC board + * (DB-88F6820-AMC) + * + * Copyright (C) 2017 Allied Telesis Labs + */ + +/dts-v1/; +#include "armada-385.dtsi" + +#include <dt-bindings/gpio/gpio.h> + +/ { + model = "Marvell Armada 385 AMC"; + compatible = "marvell,a385-db-amc", "marvell,armada385", "marvell,armada380"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + ethernet0 = ð0; + ethernet1 = ð2; + i2c0 = &i2c0; + spi1 = &spi1; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x80000000>; /* 2GB */ + }; + + soc { + ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000 + MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>; + }; +}; + +&i2c0 { + u-boot,i2c-slave-addr = <0x0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + status = "okay"; +}; + +&uart0 { + /* + * Exported on the micro USB connector CON3 + * through an FTDI + */ + + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; + u-boot,dm-pre-reloc; +}; + + +ð0 { + pinctrl-names = "default"; + /* + * The Reference Clock 0 is used to provide a + * clock to the PHY + */ + pinctrl-0 = <&ge0_rgmii_pins>, <&ref_clk0_pins>; + status = "okay"; + phy = <&phy0>; + phy-mode = "rgmii-id"; +}; + +ð2 { + status = "okay"; + phy = <&phy1>; + phy-mode = "sgmii"; +}; + +&usb0 { + status = "okay"; +}; + + + +&mdio { + pinctrl-names = "default"; + pinctrl-0 = <&mdio_pins>; + + phy0: ethernet-phy@1 { + reg = <1>; + }; + + phy1: ethernet-phy@0 { + reg = <0>; + }; +}; + +&nand_controller { + status = "okay"; + marvell,nand-keep-config; + marvell,nand-enable-arbiter; + nand-on-flash-bbt; +}; + +&pciec { + status = "okay"; +}; + +&pcie1 { + /* Port 0, Lane 0 */ + status = "okay"; +}; + +&spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&spi1_pins>; + status = "okay"; + u-boot,dm-pre-reloc; + + spi-flash@0 { + u-boot,dm-pre-reloc; + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <50000000>; + m25p,fast-read; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + reg = <0x00000000 0x00100000>; + label = "u-boot"; + }; + partition@100000 { + reg = <0x00100000 0x00040000>; + label = "u-boot-env"; + }; + }; + }; +}; + +&refclk { + clock-frequency = <20000000>; +}; diff --git a/arch/arm/dts/armada-385-turris-omnia-u-boot.dtsi b/arch/arm/dts/armada-385-turris-omnia-u-boot.dtsi index 904429b9742..1b46797583d 100644 --- a/arch/arm/dts/armada-385-turris-omnia-u-boot.dtsi +++ b/arch/arm/dts/armada-385-turris-omnia-u-boot.dtsi @@ -42,7 +42,7 @@ u-boot,dm-pre-reloc; spi-flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; u-boot,dm-pre-reloc; diff --git a/arch/arm/dts/armada-38x-controlcenterdc.dts b/arch/arm/dts/armada-38x-controlcenterdc.dts index bad7c60f19c..5063a798df7 100644 --- a/arch/arm/dts/armada-38x-controlcenterdc.dts +++ b/arch/arm/dts/armada-38x-controlcenterdc.dts @@ -573,14 +573,14 @@ spi-flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "n25q016a", "spi-flash"; + compatible = "n25q016a", "jedec,spi-nor"; reg = <0>; /* Chip select 0 */ spi-max-frequency = <108000000>; }; spi-flash@1 { #address-cells = <1>; #size-cells = <1>; - compatible = "n25q128a11", "spi-flash"; + compatible = "n25q128a11", "jedec,spi-nor"; reg = <1>; /* Chip select 1 */ spi-max-frequency = <108000000>; u-boot,dm-pre-reloc; diff --git a/arch/arm/dts/armada-38x-solidrun-microsom.dtsi b/arch/arm/dts/armada-38x-solidrun-microsom.dtsi index 74f58de85c4..a2627223ce3 100644 --- a/arch/arm/dts/armada-38x-solidrun-microsom.dtsi +++ b/arch/arm/dts/armada-38x-solidrun-microsom.dtsi @@ -86,7 +86,7 @@ w25q32: spi-flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "w25q32", "jedec,spi-nor", "spi-flash"; + compatible = "w25q32", "jedec,spi-nor"; reg = <0>; /* Chip select 0 */ spi-max-frequency = <3000000>; status = "disabled"; diff --git a/arch/arm/dts/armada-8040-clearfog-gt-8k.dts b/arch/arm/dts/armada-8040-clearfog-gt-8k.dts index cdff44aca5a..720c95082b6 100644 --- a/arch/arm/dts/armada-8040-clearfog-gt-8k.dts +++ b/arch/arm/dts/armada-8040-clearfog-gt-8k.dts @@ -240,7 +240,7 @@ status = "okay"; spi-flash@0 { - compatible = "jedec,spi-nor", "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <10000000>; diff --git a/arch/arm/dts/armada-xp-98dx3236.dtsi b/arch/arm/dts/armada-xp-98dx3236.dtsi new file mode 100644 index 00000000000..5df1d1848db --- /dev/null +++ b/arch/arm/dts/armada-xp-98dx3236.dtsi @@ -0,0 +1,343 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree Include file for Marvell 98dx3236 family SoC + * + * Copyright (C) 2016 Allied Telesis Labs + * + * Contains definitions specific to the 98dx3236 SoC that are not + * common to all Armada XP SoCs. + */ + +#include "armada-370-xp.dtsi" + +/ { + #address-cells = <2>; + #size-cells = <2>; + + model = "Marvell 98DX3236 SoC"; + compatible = "marvell,armadaxp-98dx3236", "marvell,armada-370-xp"; + + aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + enable-method = "marvell,98dx3236-smp"; + + cpu@0 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <0>; + clocks = <&cpuclk 0>; + clock-latency = <1000000>; + }; + }; + + soc { + compatible = "marvell,armadaxp-mbus", "simple-bus"; + + ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000 + MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000 + MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000 + MBUS_ID(0x03, 0x00) 0 0 0xa8000000 0x4000000 + MBUS_ID(0x08, 0x00) 0 0 0xac000000 0x100000>; + + bootrom { + compatible = "marvell,bootrom"; + reg = <MBUS_ID(0x01, 0x1d) 0 0x100000>; + }; + + /* + * 98DX3236 has 1 x1 PCIe unit Gen2.0 + */ + pciec: pcie@82000000 { + compatible = "marvell,armada-xp-pcie"; + status = "disabled"; + device_type = "pci"; + + #address-cells = <3>; + #size-cells = <2>; + + msi-parent = <&mpic>; + bus-range = <0x00 0xff>; + + ranges = + <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */ + 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */ + 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */>; + + pcie1: pcie@1,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 + 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &mpic 58>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <0>; + clocks = <&gateclk 5>; + status = "disabled"; + }; + }; + + internal-regs { + sdramc: sdramc@1400 { + compatible = "marvell,armada-xp-sdram-controller"; + reg = <0x1400 0x500>; + }; + + L2: l2-cache@8000 { + compatible = "marvell,aurora-system-cache"; + reg = <0x08000 0x1000>; + cache-id-part = <0x100>; + cache-level = <2>; + cache-unified; + wt-override; + }; + + gpio0: gpio@18100 { + compatible = "marvell,orion-gpio"; + reg = <0x18100 0x40>; + ngpios = <32>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <82>, <83>, <84>, <85>; + }; + + /* does not exist */ + gpio1: gpio@18140 { + compatible = "marvell,orion-gpio"; + reg = <0x18140 0x40>; + status = "disabled"; + }; + + gpio2: gpio@18180 { /* rework some properties */ + compatible = "marvell,orion-gpio"; + reg = <0x18180 0x40>; + ngpios = <1>; /* only gpio #32 */ + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <87>; + }; + + systemc: system-controller@18200 { + compatible = "marvell,armada-370-xp-system-controller"; + reg = <0x18200 0x500>; + }; + + gateclk: clock-gating-control@18220 { + compatible = "marvell,mv98dx3236-gating-clock"; + reg = <0x18220 0x4>; + clocks = <&coreclk 0>; + #clock-cells = <1>; + }; + + cpuclk: clock-complex@18700 { + #clock-cells = <1>; + compatible = "marvell,mv98dx3236-cpu-clock"; + reg = <0x18700 0x24>, <0x1c054 0x10>; + clocks = <&coreclk 1>; + }; + + corediv-clock@18740 { + status = "disabled"; + }; + + cpu-config@21000 { + compatible = "marvell,armada-xp-cpu-config"; + reg = <0x21000 0x8>; + }; + + ethernet@70000 { + compatible = "marvell,armada-xp-neta"; + }; + + ethernet@74000 { + compatible = "marvell,armada-xp-neta"; + }; + + xor1: xor@f0800 { + compatible = "marvell,orion-xor"; + reg = <0xf0800 0x100 + 0xf0a00 0x100>; + clocks = <&gateclk 22>; + status = "okay"; + + xor10 { + interrupts = <51>; + dmacap,memcpy; + dmacap,xor; + }; + xor11 { + interrupts = <52>; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; + }; + + nand_controller: nand@d0000 { + clocks = <&dfx_coredivclk 0>; + }; + + xor0: xor@f0900 { + compatible = "marvell,orion-xor"; + reg = <0xF0900 0x100 + 0xF0B00 0x100>; + clocks = <&gateclk 28>; + status = "okay"; + + xor00 { + interrupts = <94>; + dmacap,memcpy; + dmacap,xor; + }; + xor01 { + interrupts = <95>; + dmacap,memcpy; + dmacap,xor; + dmacap,memset; + }; + }; + }; + + dfx: dfx-server@ac000000 { + compatible = "marvell,dfx-server", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 MBUS_ID(0x08, 0x00) 0 0x100000>; + reg = <MBUS_ID(0x08, 0x00) 0 0x100000>; + + thermal: thermal@f8078 { + compatible = "marvell,armada380-thermal"; + reg = <0xf8078 0x4>, <0xf8074 0x4>; + status = "okay"; + }; + + coreclk: mvebu-sar@f8204 { + compatible = "marvell,mv98dx3236-core-clock"; + reg = <0xf8204 0x4>; + #clock-cells = <1>; + }; + + dfx_coredivclk: corediv-clock@f8268 { + compatible = "marvell,mv98dx3236-corediv-clock"; + reg = <0xf8268 0xc>; + #clock-cells = <1>; + clocks = <&mainpll>; + clock-output-names = "nand"; + }; + }; + + switch: switch@a8000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 MBUS_ID(0x03, 0x00) 0 0x100000>; + + pp0: packet-processor@0 { + compatible = "marvell,prestera-98dx3236", "marvell,prestera"; + reg = <0 0x4000000>; + interrupts = <33>, <34>, <35>; + dfx = <&dfx>; + }; + }; + }; + + clocks { + /* 25 MHz reference crystal */ + refclk: oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + }; +}; + +&i2c0 { + compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; + reg = <0x11000 0x100>; +}; + +&i2c1 { + compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; + reg = <0x11100 0x100>; +}; + +&mpic { + reg = <0x20a00 0x2d0>, <0x21070 0x58>; +}; + +&rtc { + status = "disabled"; +}; + +&timer { + compatible = "marvell,armada-xp-timer"; + clocks = <&coreclk 2>, <&refclk>; + clock-names = "nbclk", "fixed"; +}; + +&watchdog { + compatible = "marvell,armada-xp-wdt"; + clocks = <&coreclk 2>, <&refclk>; + clock-names = "nbclk", "fixed"; +}; + +&cpurst { + reg = <0x20800 0x20>; +}; + +&usb0 { + clocks = <&gateclk 18>; +}; + +&usb1 { + clocks = <&gateclk 19>; +}; + +&pinctrl { + compatible = "marvell,98dx3236-pinctrl"; + + nand_pins: nand-pins { + marvell,pins = "mpp20", "mpp21", "mpp22", + "mpp23", "mpp24", "mpp25", + "mpp26", "mpp27", "mpp28", + "mpp29", "mpp30"; + marvell,function = "dev"; + }; + + nand_rb: nand-rb { + marvell,pins = "mpp19"; + marvell,function = "nand"; + }; + + spi0_pins: spi0-pins { + marvell,pins = "mpp0", "mpp1", + "mpp2", "mpp3"; + marvell,function = "spi0"; + }; +}; + +&spi0 { + compatible = "marvell,armada-xp-spi", "marvell,orion-spi"; + pinctrl-0 = <&spi0_pins>; + pinctrl-names = "default"; +}; + +&sdio { + status = "disabled"; +}; diff --git a/arch/arm/dts/armada-xp-98dx3336.dtsi b/arch/arm/dts/armada-xp-98dx3336.dtsi new file mode 100644 index 00000000000..1d9d8a8ea60 --- /dev/null +++ b/arch/arm/dts/armada-xp-98dx3336.dtsi @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree Include file for Marvell 98dx3336 family SoC + * + * Copyright (C) 2016 Allied Telesis Labs + * + * Contains definitions specific to the 98dx3236 SoC that are not + * common to all Armada XP SoCs. + */ + +#include "armada-xp-98dx3236.dtsi" + +/ { + model = "Marvell 98DX3336 SoC"; + compatible = "marvell,armadaxp-98dx3336", "marvell,armadaxp-98dx3236", "marvell,armada-370-xp"; + + cpus { + cpu@1 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <1>; + clocks = <&cpuclk 1>; + clock-latency = <1000000>; + }; + }; + + soc { + internal-regs { + resume@20980 { + compatible = "marvell,98dx3336-resume-ctrl"; + reg = <0x20980 0x10>; + }; + }; + }; +}; + +&pp0 { + compatible = "marvell,prestera-98dx3336", "marvell,prestera"; +}; diff --git a/arch/arm/dts/armada-xp-98dx4251.dtsi b/arch/arm/dts/armada-xp-98dx4251.dtsi new file mode 100644 index 00000000000..48ffdc72bfc --- /dev/null +++ b/arch/arm/dts/armada-xp-98dx4251.dtsi @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree Include file for Marvell 98dx4521 family SoC + * + * Copyright (C) 2016 Allied Telesis Labs + * + * Contains definitions specific to the 98dx4521 SoC that are not + * common to all Armada XP SoCs. + */ + +#include "armada-xp-98dx3236.dtsi" + +/ { + model = "Marvell 98DX4251 SoC"; + compatible = "marvell,armadaxp-98dx4251", "marvell,armadaxp-98dx3236", "marvell,armada-370-xp"; + + cpus { + cpu@1 { + device_type = "cpu"; + compatible = "marvell,sheeva-v7"; + reg = <1>; + clocks = <&cpuclk 1>; + clock-latency = <1000000>; + }; + }; + + soc { + internal-regs { + resume@20980 { + compatible = "marvell,98dx3336-resume-ctrl"; + reg = <0x20980 0x10>; + }; + }; + }; +}; + +&sdio { + status = "okay"; +}; + +&pinctrl { + compatible = "marvell,98dx4251-pinctrl"; + + sdio_pins: sdio-pins { + marvell,pins = "mpp5", "mpp6", "mpp7", + "mpp8", "mpp9", "mpp10"; + marvell,function = "sd0"; + }; +}; + +&pp0 { + compatible = "marvell,prestera-98dx4251", "marvell,prestera"; + interrupts = <33>, <34>, <35>, <36>; +}; diff --git a/arch/arm/dts/armada-xp-db-xc3-24g4xg-u-boot.dtsi b/arch/arm/dts/armada-xp-db-xc3-24g4xg-u-boot.dtsi new file mode 100644 index 00000000000..90cad85506d --- /dev/null +++ b/arch/arm/dts/armada-xp-db-xc3-24g4xg-u-boot.dtsi @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +&uart0 { + u-boot,dm-pre-reloc; +}; + +&nand_controller { + compatible="marvell,mvebu-pxa3xx-nand"; + status = "okay"; + label = "pxa3xx_nand-0"; + nand-rb = <0>; + marvell,nand-keep-config; + nand-on-flash-bbt; + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; +}; + +&spi0 { + u-boot,dm-pre-reloc; + + spi-flash@0 { + u-boot,dm-pre-reloc; + }; +}; diff --git a/arch/arm/dts/armada-xp-db-xc3-24g4xg.dts b/arch/arm/dts/armada-xp-db-xc3-24g4xg.dts new file mode 100644 index 00000000000..d4b52881e6f --- /dev/null +++ b/arch/arm/dts/armada-xp-db-xc3-24g4xg.dts @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree file for DB-XC3-24G4XG board + * + * Copyright (C) 2016 Allied Telesis Labs + * + * Based on armada-xp-db.dts + * + * Note: this Device Tree assumes that the bootloader has remapped the + * internal registers to 0xf1000000 (instead of the default + * 0xd0000000). The 0xf1000000 is the default used by the recent, + * DT-capable, U-Boot bootloaders provided by Marvell. Some earlier + * boards were delivered with an older version of the bootloader that + * left internal registers mapped at 0xd0000000. If you are in this + * situation, you should either update your bootloader (preferred + * solution) or the below Device Tree should be adjusted. + */ + +/dts-v1/; +#include "armada-xp-98dx3336.dtsi" +#include "armada-xp-db-xc3-24g4xg-u-boot.dtsi" + +/ { + model = "DB-XC3-24G4XG"; + compatible = "marvell,armadaxp-98dx3336", "marvell,armadaxp-mv78260", "marvell,armadaxp", "marvell,armada-370-xp"; + + chosen { + stdout-path = "serial0:115200n8"; + bootargs = "console=ttyS0,115200 earlyprintk"; + }; + + aliases { + spi0 = &spi0; + }; + + memory { + device_type = "memory"; + reg = <0 0x00000000 0 0x40000000>; /* 1 GB */ + }; +}; + +&L2 { + arm,parity-enable; + marvell,ecc-enable; +}; + +&devbus_bootcs { + status = "okay"; + + /* Device Bus parameters are required */ + + /* Read parameters */ + devbus,bus-width = <16>; + devbus,turn-off-ps = <60000>; + devbus,badr-skew-ps = <0>; + devbus,acc-first-ps = <124000>; + devbus,acc-next-ps = <248000>; + devbus,rd-setup-ps = <0>; + devbus,rd-hold-ps = <0>; + + /* Write parameters */ + devbus,sync-enable = <0>; + devbus,wr-high-ps = <60000>; + devbus,wr-low-ps = <60000>; + devbus,ale-wr-ps = <60000>; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&i2c0 { + clock-frequency = <100000>; + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash", "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <108000000>; + m25p,fast-read; + + partition@u-boot { + reg = <0x00000000 0x00100000>; + label = "u-boot"; + }; + partition@u-boot-env { + reg = <0x00100000 0x00040000>; + label = "u-boot-env"; + }; + partition@unused { + reg = <0x00140000 0x00ec0000>; + label = "unused"; + }; + + }; +}; diff --git a/arch/arm/dts/armada-xp-gp.dts b/arch/arm/dts/armada-xp-gp.dts index 27799d1254e..1139e9469a8 100644 --- a/arch/arm/dts/armada-xp-gp.dts +++ b/arch/arm/dts/armada-xp-gp.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Device Tree file for Marvell Armada XP development board * (DB-MV784MP-GP) @@ -8,44 +9,6 @@ * Gregory CLEMENT <gregory.clement@free-electrons.com> * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This file is distributed in the hope that it will be useful - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * * Note: this Device Tree assumes that the bootloader has remapped the * internal registers to 0xf1000000 (instead of the default * 0xd0000000). The 0xf1000000 is the default used by the recent, @@ -68,11 +31,7 @@ stdout-path = "serial0:115200n8"; }; - aliases { - spi0 = &spi0; - }; - - memory { + memory@0 { device_type = "memory"; /* * 8 GB of plug-in RAM modules by default.The amount @@ -98,7 +57,10 @@ soc { ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000 MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000 - MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000>; + MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000 + MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000 + MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000 + MBUS_ID(0x0c, 0x04) 0 0 0xf1200000 0x100000>; devbus-bootcs { status = "okay"; @@ -128,31 +90,9 @@ }; }; - pcie-controller { - status = "okay"; - - /* - * The 3 slots are physically present as - * standard PCIe slots on the board. - */ - pcie@1,0 { - /* Port 0, Lane 0 */ - status = "okay"; - }; - pcie@9,0 { - /* Port 2, Lane 0 */ - status = "okay"; - }; - pcie@10,0 { - /* Port 3, Lane 0 */ - status = "okay"; - }; - }; - internal-regs { serial@12000 { status = "okay"; - u-boot,dm-pre-reloc; }; serial@12100 { status = "okay"; @@ -177,43 +117,33 @@ status = "okay"; }; - mdio { - phy0: ethernet-phy@0 { - reg = <16>; - }; - - phy1: ethernet-phy@1 { - reg = <17>; - }; - - phy2: ethernet-phy@2 { - reg = <18>; - }; - - phy3: ethernet-phy@3 { - reg = <19>; - }; - }; - ethernet@70000 { status = "okay"; phy = <&phy0>; phy-mode = "qsgmii"; + buffer-manager = <&bm>; + bm,pool-long = <0>; }; ethernet@74000 { status = "okay"; phy = <&phy1>; phy-mode = "qsgmii"; + buffer-manager = <&bm>; + bm,pool-long = <1>; }; ethernet@30000 { status = "okay"; phy = <&phy2>; phy-mode = "qsgmii"; + buffer-manager = <&bm>; + bm,pool-long = <2>; }; ethernet@34000 { status = "okay"; phy = <&phy3>; phy-mode = "qsgmii"; + buffer-manager = <&bm>; + bm,pool-long = <3>; }; /* Front-side USB slot */ @@ -226,27 +156,72 @@ status = "okay"; }; - spi0: spi@10600 { + bm@c0000 { status = "okay"; - u-boot,dm-pre-reloc; - - spi-flash@0 { - u-boot,dm-pre-reloc; - #address-cells = <1>; - #size-cells = <1>; - compatible = "n25q128a13", "jedec,spi-nor"; - reg = <0>; /* Chip select 0 */ - spi-max-frequency = <108000000>; - }; }; nand@d0000 { status = "okay"; + label = "pxa3xx_nand-0"; num-cs = <1>; marvell,nand-keep-config; - marvell,nand-enable-arbiter; nand-on-flash-bbt; }; }; + + bm-bppi { + status = "okay"; + }; + }; +}; + +&pciec { + status = "okay"; + + /* + * The 3 slots are physically present as + * standard PCIe slots on the board. + */ + pcie@1,0 { + /* Port 0, Lane 0 */ + status = "okay"; + }; + pcie@9,0 { + /* Port 2, Lane 0 */ + status = "okay"; + }; + pcie@a,0 { + /* Port 3, Lane 0 */ + status = "okay"; + }; +}; + +&mdio { + phy0: ethernet-phy@0 { + reg = <16>; + }; + + phy1: ethernet-phy@1 { + reg = <17>; + }; + + phy2: ethernet-phy@2 { + reg = <18>; + }; + + phy3: ethernet-phy@3 { + reg = <19>; + }; +}; + +&spi0 { + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "n25q128a13", "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <108000000>; }; }; diff --git a/arch/arm/dts/armada-xp-maxbcm.dts b/arch/arm/dts/armada-xp-maxbcm.dts index d7d7f65c85f..921eb708625 100644 --- a/arch/arm/dts/armada-xp-maxbcm.dts +++ b/arch/arm/dts/armada-xp-maxbcm.dts @@ -225,18 +225,6 @@ status = "okay"; }; - spi0: spi@10600 { - status = "okay"; - - spi-flash@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "n25q128a13", "jedec,spi-nor"; - reg = <0>; /* Chip select 0 */ - spi-max-frequency = <108000000>; - }; - }; - nand@d0000 { status = "okay"; num-cs = <1>; @@ -247,3 +235,15 @@ }; }; }; + +&spi0 { + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "n25q128a13", "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <108000000>; + }; +}; diff --git a/arch/arm/dts/armada-xp-mv78230.dtsi b/arch/arm/dts/armada-xp-mv78230.dtsi index f6bab9fb20a..8558bf6bb54 100644 --- a/arch/arm/dts/armada-xp-mv78230.dtsi +++ b/arch/arm/dts/armada-xp-mv78230.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Device Tree Include file for Marvell Armada XP family SoC * @@ -5,44 +6,6 @@ * * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This file is distributed in the hope that it will be useful - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * * Contains definitions specific to the Armada XP MV78230 SoC that are not * common to all Armada XP SoCs. */ @@ -207,25 +170,33 @@ internal-regs { gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; - reg = <0x18100 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18100 0x40>, <0x181c0 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <82>, <83>, <84>, <85>; + clocks = <&coreclk 0>; }; gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; - reg = <0x18140 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18140 0x40>, <0x181c8 0x08>; + reg-names = "gpio", "pwm"; ngpios = <17>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <87>, <88>, <89>; + clocks = <&coreclk 0>; }; }; }; diff --git a/arch/arm/dts/armada-xp-mv78260.dtsi b/arch/arm/dts/armada-xp-mv78260.dtsi index d39231f69d9..2d85fe8ac32 100644 --- a/arch/arm/dts/armada-xp-mv78260.dtsi +++ b/arch/arm/dts/armada-xp-mv78260.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Device Tree Include file for Marvell Armada XP family SoC * @@ -5,44 +6,6 @@ * * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This file is distributed in the hope that it will be useful - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * * Contains definitions specific to the Armada XP MV78260 SoC that are not * common to all Armada XP SoCs. */ @@ -294,29 +257,38 @@ internal-regs { gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; - reg = <0x18100 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18100 0x40>, <0x181c0 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <82>, <83>, <84>, <85>; + clocks = <&coreclk 0>; }; gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; - reg = <0x18140 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18140 0x40>, <0x181c8 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <87>, <88>, <89>, <90>; + clocks = <&coreclk 0>; }; gpio2: gpio@18180 { - compatible = "marvell,orion-gpio"; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; reg = <0x18180 0x40>; ngpios = <3>; gpio-controller; diff --git a/arch/arm/dts/armada-xp-mv78460.dtsi b/arch/arm/dts/armada-xp-mv78460.dtsi index c642565d1bc..230a3fd36b3 100644 --- a/arch/arm/dts/armada-xp-mv78460.dtsi +++ b/arch/arm/dts/armada-xp-mv78460.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Device Tree Include file for Marvell Armada XP family SoC * @@ -5,44 +6,6 @@ * * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This file is distributed in the hope that it will be useful - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * * Contains definitions specific to the Armada XP MV78460 SoC that are not * common to all Armada XP SoCs. */ @@ -333,29 +296,38 @@ internal-regs { gpio0: gpio@18100 { - compatible = "marvell,orion-gpio"; - reg = <0x18100 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18100 0x40>, <0x181c0 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <82>, <83>, <84>, <85>; + clocks = <&coreclk 0>; }; gpio1: gpio@18140 { - compatible = "marvell,orion-gpio"; - reg = <0x18140 0x40>; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; + reg = <0x18140 0x40>, <0x181c8 0x08>; + reg-names = "gpio", "pwm"; ngpios = <32>; gpio-controller; #gpio-cells = <2>; + #pwm-cells = <2>; interrupt-controller; #interrupt-cells = <2>; interrupts = <87>, <88>, <89>, <90>; + clocks = <&coreclk 0>; }; gpio2: gpio@18180 { - compatible = "marvell,orion-gpio"; + compatible = "marvell,armada-370-gpio", + "marvell,orion-gpio"; reg = <0x18180 0x40>; ngpios = <3>; gpio-controller; diff --git a/arch/arm/dts/armada-xp-synology-ds414.dts b/arch/arm/dts/armada-xp-synology-ds414.dts index 0a60ddfa414..861967cd7e8 100644 --- a/arch/arm/dts/armada-xp-synology-ds414.dts +++ b/arch/arm/dts/armada-xp-synology-ds414.dts @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Device Tree file for Synology DS414 * * Copyright (C) 2014, Arnaud EBALARD <arno@natisbad.org> * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * * Note: this Device Tree assumes that the bootloader has remapped the * internal registers to 0xf1000000 (instead of the old 0xd0000000). * The 0xf1000000 is the default used by the recent, DT-capable, U-Boot @@ -42,36 +38,16 @@ spi0 = &spi0; }; - memory { + memory@0 { device_type = "memory"; reg = <0 0x00000000 0 0x40000000>; /* 1GB */ }; soc { ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000 - MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>; - - pcie-controller { - status = "okay"; - - /* - * Connected to Marvell 88SX7042 SATA-II controller - * handling the four disks. - */ - pcie@1,0 { - /* Port 0, Lane 0 */ - status = "okay"; - }; - - /* - * Connected to EtronTech EJ168A XHCI controller - * providing the two rear USB 3.0 ports. - */ - pcie@5,0 { - /* Port 1, Lane 0 */ - status = "okay"; - }; - }; + MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000 + MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000 + MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>; internal-regs { @@ -80,64 +56,6 @@ status = "disabled"; }; - spi0: spi@10600 { - status = "okay"; - u-boot,dm-pre-reloc; - - spi-flash@0 { - u-boot,dm-pre-reloc; - #address-cells = <1>; - #size-cells = <1>; - compatible = "micron,n25q064"; - reg = <0>; /* Chip select 0 */ - spi-max-frequency = <20000000>; - - /* - * Warning! - * - * Synology u-boot uses its compiled-in environment - * and it seems Synology did not care to change u-boot - * default configuration in order to allow saving a - * modified environment at a sensible location. So, - * if you do a 'saveenv' under u-boot, your modified - * environment will be saved at 1MB after the start - * of the flash, i.e. in the middle of the uImage. - * For that reason, it is strongly advised not to - * change the default environment, unless you know - * what you are doing. - */ - partition@00000000 { /* u-boot */ - label = "RedBoot"; - reg = <0x00000000 0x000d0000>; /* 832KB */ - }; - - partition@000c0000 { /* uImage */ - label = "zImage"; - reg = <0x000d0000 0x002d0000>; /* 2880KB */ - }; - - partition@003a0000 { /* uInitramfs */ - label = "rd.gz"; - reg = <0x003a0000 0x00430000>; /* 4250KB */ - }; - - partition@007d0000 { /* MAC address and serial number */ - label = "vendor"; - reg = <0x007d0000 0x00010000>; /* 64KB */ - }; - - partition@007e0000 { - label = "RedBoot config"; - reg = <0x007e0000 0x00010000>; /* 64KB */ - }; - - partition@007f0000 { - label = "FIS directory"; - reg = <0x007f0000 0x00010000>; /* 64KB */ - }; - }; - }; - i2c@11000 { clock-frequency = <400000>; status = "okay"; @@ -179,16 +97,6 @@ status = "okay"; }; - mdio { - phy0: ethernet-phy@0 { /* Marvell 88E1512 */ - reg = <0>; - }; - - phy1: ethernet-phy@1 { /* Marvell 88E1512 */ - reg = <1>; - }; - }; - ethernet@70000 { status = "okay"; pinctrl-0 = <&ge0_rgmii_pins>; @@ -215,7 +123,7 @@ &sata3_pwr_pin &sata4_pwr_pin>; pinctrl-names = "default"; - sata1_regulator: sata1-regulator { + sata1_regulator: sata1-regulator@1 { compatible = "regulator-fixed"; reg = <1>; regulator-name = "SATA1 Power"; @@ -228,7 +136,7 @@ gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>; }; - sata2_regulator: sata2-regulator { + sata2_regulator: sata2-regulator@2 { compatible = "regulator-fixed"; reg = <2>; regulator-name = "SATA2 Power"; @@ -241,7 +149,7 @@ gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>; }; - sata3_regulator: sata3-regulator { + sata3_regulator: sata3-regulator@3 { compatible = "regulator-fixed"; reg = <3>; regulator-name = "SATA3 Power"; @@ -254,7 +162,7 @@ gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>; }; - sata4_regulator: sata4-regulator { + sata4_regulator: sata4-regulator@4 { compatible = "regulator-fixed"; reg = <4>; regulator-name = "SATA4 Power"; @@ -269,6 +177,39 @@ }; }; +&pciec { + status = "okay"; + + /* + * Connected to Marvell 88SX7042 SATA-II controller + * handling the four disks. + */ + pcie@1,0 { + /* Port 0, Lane 0 */ + status = "okay"; + }; + + /* + * Connected to EtronTech EJ168A XHCI controller + * providing the two rear USB 3.0 ports. + */ + pcie@5,0 { + /* Port 1, Lane 0 */ + status = "okay"; + }; +}; + + +&mdio { + phy0: ethernet-phy@0 { /* Marvell 88E1512 */ + reg = <0>; + }; + + phy1: ethernet-phy@1 { /* Marvell 88E1512 */ + reg = <1>; + }; +}; + &pinctrl { sata1_pwr_pin: sata1-pwr-pin { marvell,pins = "mpp42"; @@ -335,3 +276,59 @@ marvell,function = "gpio"; }; }; + +&spi0 { + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "micron,n25q064", "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <20000000>; + + /* + * Warning! + * + * Synology u-boot uses its compiled-in environment + * and it seems Synology did not care to change u-boot + * default configuration in order to allow saving a + * modified environment at a sensible location. So, + * if you do a 'saveenv' under u-boot, your modified + * environment will be saved at 1MB after the start + * of the flash, i.e. in the middle of the uImage. + * For that reason, it is strongly advised not to + * change the default environment, unless you know + * what you are doing. + */ + partition@0 { /* u-boot */ + label = "RedBoot"; + reg = <0x00000000 0x000d0000>; /* 832KB */ + }; + + partition@c0000 { /* uImage */ + label = "zImage"; + reg = <0x000d0000 0x002d0000>; /* 2880KB */ + }; + + partition@3a0000 { /* uInitramfs */ + label = "rd.gz"; + reg = <0x003a0000 0x00430000>; /* 4250KB */ + }; + + partition@7d0000 { /* MAC address and serial number */ + label = "vendor"; + reg = <0x007d0000 0x00010000>; /* 64KB */ + }; + + partition@7e0000 { + label = "RedBoot config"; + reg = <0x007e0000 0x00010000>; /* 64KB */ + }; + + partition@7f0000 { + label = "FIS directory"; + reg = <0x007f0000 0x00010000>; /* 64KB */ + }; + }; +}; diff --git a/arch/arm/dts/armada-xp-theadorable.dts b/arch/arm/dts/armada-xp-theadorable.dts index 5695e9b7585..5b18d62c3c5 100644 --- a/arch/arm/dts/armada-xp-theadorable.dts +++ b/arch/arm/dts/armada-xp-theadorable.dts @@ -126,40 +126,6 @@ status = "okay"; }; - spi0: spi@10600 { - status = "okay"; - u-boot,dm-pre-reloc; - - spi-flash@0 { - u-boot,dm-pre-reloc; - #address-cells = <1>; - #size-cells = <1>; - compatible = "n25q128a13", "jedec,spi-nor", "spi-flash"; - reg = <0>; /* Chip select 0 */ - spi-max-frequency = <27777777>; - }; - - fpga@1 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "spi-generic-device"; - reg = <1>; /* Chip select 1 */ - spi-max-frequency = <27777777>; - }; - }; - - spi1: spi@10680 { - status = "okay"; - - fpga@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "spi-generic-device"; - reg = <0>; /* Chip select 0 */ - spi-max-frequency = <27777777>; - }; - }; - /* The LCD controller is only used on this board */ lcd0: lcd-controller@e0000 { compatible = "marvell,armada-xp-lcd"; @@ -188,6 +154,41 @@ }; }; +&spi0 { + status = "okay"; + u-boot,dm-pre-reloc; + + spi-flash@0 { + u-boot,dm-pre-reloc; + #address-cells = <1>; + #size-cells = <1>; + compatible = "n25q128a13", "jedec,spi-nor"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <27777777>; + }; + + fpga@1 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-generic-device"; + reg = <1>; /* Chip select 1 */ + spi-max-frequency = <27777777>; + }; +}; + +&spi1 { + status = "okay"; + + fpga@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-generic-device"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <27777777>; + }; +}; + + &pciec { status = "okay"; diff --git a/arch/arm/dts/armada-xp.dtsi b/arch/arm/dts/armada-xp.dtsi index 3fac39e41d7..d856d960227 100644 --- a/arch/arm/dts/armada-xp.dtsi +++ b/arch/arm/dts/armada-xp.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Device Tree Include file for Marvell Armada XP family SoC * @@ -8,44 +9,6 @@ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> * Ben Dooks <ben.dooks@codethink.co.uk> * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This file is distributed in the hope that it will be useful - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * * Contains definitions specific to the Armada XP SoC that are not * common to all Armada SoCs. */ @@ -53,6 +16,9 @@ #include "armada-370-xp.dtsi" / { + #address-cells = <2>; + #size-cells = <2>; + model = "Marvell Armada XP family SoC"; compatible = "marvell,armadaxp", "marvell,armada-370-xp"; @@ -71,12 +37,12 @@ }; internal-regs { - sdramc@1400 { + sdramc: sdramc@1400 { compatible = "marvell,armada-xp-sdram-controller"; reg = <0x1400 0x500>; }; - L2: l2-cache { + L2: l2-cache@8000 { compatible = "marvell,aurora-system-cache"; reg = <0x08000 0x1000>; cache-id-part = <0x100>; @@ -85,29 +51,6 @@ wt-override; }; - spi0: spi@10600 { - compatible = "marvell,armada-xp-spi", - "marvell,orion-spi"; - pinctrl-0 = <&spi0_pins>; - pinctrl-names = "default"; - }; - - spi1: spi@10680 { - compatible = "marvell,armada-xp-spi", - "marvell,orion-spi"; - }; - - - i2c0: i2c@11000 { - compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; - reg = <0x11000 0x100>; - }; - - i2c1: i2c@11100 { - compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; - reg = <0x11100 0x100>; - }; - uart2: serial@12200 { compatible = "snps,dw-apb-uart"; pinctrl-0 = <&uart2_pins>; @@ -132,7 +75,7 @@ status = "disabled"; }; - system-controller@18200 { + systemc: system-controller@18200 { compatible = "marvell,armada-370-xp-system-controller"; reg = <0x18200 0x500>; }; @@ -150,7 +93,7 @@ #clock-cells = <1>; }; - thermal@182b0 { + thermal: thermal@182b0 { compatible = "marvell,armadaxp-thermal"; reg = <0x182b0 0x4 0x184d0 0x4>; @@ -164,25 +107,9 @@ clocks = <&coreclk 1>; }; - interrupt-controller@20a00 { - reg = <0x20a00 0x2d0>, <0x21070 0x58>; - }; - - timer@20300 { - compatible = "marvell,armada-xp-timer"; - clocks = <&coreclk 2>, <&refclk>; - clock-names = "nbclk", "fixed"; - }; - - watchdog@20300 { - compatible = "marvell,armada-xp-wdt"; - clocks = <&coreclk 2>, <&refclk>; - clock-names = "nbclk", "fixed"; - }; - - cpurst@20800 { - compatible = "marvell,armada-370-cpu-reset"; - reg = <0x20800 0x20>; + cpu-config@21000 { + compatible = "marvell,armada-xp-cpu-config"; + reg = <0x21000 0x8>; }; eth2: ethernet@30000 { @@ -193,15 +120,7 @@ status = "disabled"; }; - usb@50000 { - clocks = <&gateclk 18>; - }; - - usb@51000 { - clocks = <&gateclk 19>; - }; - - usb@52000 { + usb2: usb@52000 { compatible = "marvell,orion-ehci"; reg = <0x52000 0x500>; interrupts = <47>; @@ -209,7 +128,7 @@ status = "disabled"; }; - xor@60900 { + xor1: xor@60900 { compatible = "marvell,orion-xor"; reg = <0x60900 0x100 0x60b00 0x100>; @@ -237,7 +156,27 @@ compatible = "marvell,armada-xp-neta"; }; - xor@f0900 { + cesa: crypto@90000 { + compatible = "marvell,armada-xp-crypto"; + reg = <0x90000 0x10000>; + reg-names = "regs"; + interrupts = <48>, <49>; + clocks = <&gateclk 23>, <&gateclk 23>; + clock-names = "cesa0", "cesa1"; + marvell,crypto-srams = <&crypto_sram0>, + <&crypto_sram1>; + marvell,crypto-sram-size = <0x800>; + }; + + bm: bm@c0000 { + compatible = "marvell,armada-380-neta-bm"; + reg = <0xc0000 0xac>; + clocks = <&gateclk 13>; + internal-mem = <&bm_bppi>; + status = "disabled"; + }; + + xor0: xor@f0900 { compatible = "marvell,orion-xor"; reg = <0xF0900 0x100 0xF0B00 0x100>; @@ -257,6 +196,35 @@ }; }; }; + + crypto_sram0: sa-sram0 { + compatible = "mmio-sram"; + reg = <MBUS_ID(0x09, 0x09) 0 0x800>; + clocks = <&gateclk 23>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 MBUS_ID(0x09, 0x09) 0 0x800>; + }; + + crypto_sram1: sa-sram1 { + compatible = "mmio-sram"; + reg = <MBUS_ID(0x09, 0x05) 0 0x800>; + clocks = <&gateclk 23>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 MBUS_ID(0x09, 0x05) 0 0x800>; + }; + + bm_bppi: bm-bppi { + compatible = "mmio-sram"; + reg = <MBUS_ID(0x0c, 0x04) 0 0x100000>; + ranges = <0 MBUS_ID(0x0c, 0x04) 0 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + clocks = <&gateclk 13>; + no-memory-wc; + status = "disabled"; + }; }; clocks { @@ -269,6 +237,44 @@ }; }; +&i2c0 { + compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; + reg = <0x11000 0x100>; +}; + +&i2c1 { + compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; + reg = <0x11100 0x100>; +}; + +&mpic { + reg = <0x20a00 0x2d0>, <0x21070 0x58>; +}; + +&timer { + compatible = "marvell,armada-xp-timer"; + clocks = <&coreclk 2>, <&refclk>; + clock-names = "nbclk", "fixed"; +}; + +&watchdog { + compatible = "marvell,armada-xp-wdt"; + clocks = <&coreclk 2>, <&refclk>; + clock-names = "nbclk", "fixed"; +}; + +&cpurst { + reg = <0x20800 0x20>; +}; + +&usb0 { + clocks = <&gateclk 18>; +}; + +&usb1 { + clocks = <&gateclk 19>; +}; + &pinctrl { ge0_gmii_pins: ge0-gmii-pins { marvell,pins = @@ -309,6 +315,12 @@ marvell,function = "spi0"; }; + spi1_pins: spi1-pins { + marvell,pins = "mpp13", "mpp14", + "mpp16", "mpp17"; + marvell,function = "spi1"; + }; + uart2_pins: uart2-pins { marvell,pins = "mpp42", "mpp43"; marvell,function = "uart2"; @@ -319,3 +331,15 @@ marvell,function = "uart3"; }; }; + +&spi0 { + compatible = "marvell,armada-xp-spi", "marvell,orion-spi"; + pinctrl-0 = <&spi0_pins>; + pinctrl-names = "default"; +}; + +&spi1 { + compatible = "marvell,armada-xp-spi", "marvell,orion-spi"; + pinctrl-0 = <&spi1_pins>; + pinctrl-names = "default"; +}; diff --git a/arch/arm/dts/at91-sama5d2_xplained.dts b/arch/arm/dts/at91-sama5d2_xplained.dts index 33064b390a6..c0708feeb7b 100644 --- a/arch/arm/dts/at91-sama5d2_xplained.dts +++ b/arch/arm/dts/at91-sama5d2_xplained.dts @@ -110,7 +110,7 @@ u-boot,dm-pre-reloc; spi_flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <50000000>; u-boot,dm-pre-reloc; diff --git a/arch/arm/dts/at91-sama5d4_xplained.dts b/arch/arm/dts/at91-sama5d4_xplained.dts index 58a0e60d184..7da5086865b 100644 --- a/arch/arm/dts/at91-sama5d4_xplained.dts +++ b/arch/arm/dts/at91-sama5d4_xplained.dts @@ -117,7 +117,7 @@ status = "okay"; spi_flash@0 { u-boot,dm-pre-reloc; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; }; diff --git a/arch/arm/dts/at91-sama5d4ek.dts b/arch/arm/dts/at91-sama5d4ek.dts index a5d75452cf3..c1d657814df 100644 --- a/arch/arm/dts/at91-sama5d4ek.dts +++ b/arch/arm/dts/at91-sama5d4ek.dts @@ -137,7 +137,7 @@ status = "okay"; spi_flash@0 { u-boot,dm-pre-reloc; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; }; diff --git a/arch/arm/dts/at91sam9n12ek.dts b/arch/arm/dts/at91sam9n12ek.dts index 888bda15aae..64a7abf639f 100644 --- a/arch/arm/dts/at91sam9n12ek.dts +++ b/arch/arm/dts/at91sam9n12ek.dts @@ -112,7 +112,7 @@ status = "okay"; cs-gpios = <&pioA 14 0>, <0>, <0>, <0>; spi_flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; }; diff --git a/arch/arm/dts/at91sam9x5ek.dtsi b/arch/arm/dts/at91sam9x5ek.dtsi index f2a532d605d..1f7f37b687c 100644 --- a/arch/arm/dts/at91sam9x5ek.dtsi +++ b/arch/arm/dts/at91sam9x5ek.dtsi @@ -121,7 +121,7 @@ status = "okay"; cs-gpios = <&pioA 14 0>, <0>, <0>, <0>; spi_flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; }; diff --git a/arch/arm/dts/bcm63158.dtsi b/arch/arm/dts/bcm63158.dtsi index 6a3fbc90939..4f41f627387 100644 --- a/arch/arm/dts/bcm63158.dtsi +++ b/arch/arm/dts/bcm63158.dtsi @@ -98,5 +98,85 @@ compatible = "wdt-reboot"; wdt = <&wdt1>; }; + + gpio0: gpio-controller@0xff800500 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff800500 0x0 0x4>, + <0x0 0xff800520 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio1: gpio-controller@0xff800504 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff800504 0x0 0x4>, + <0x0 0xff800524 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio2: gpio-controller@0xff800508 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff800508 0x0 0x4>, + <0x0 0xff800528 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio3: gpio-controller@0xff80050c { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff80050c 0x0 0x4>, + <0x0 0xff80052c 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio4: gpio-controller@0xff800510 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff800510 0x0 0x4>, + <0x0 0xff800530 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio5: gpio-controller@0xff800514 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff800514 0x0 0x4>, + <0x0 0xff800534 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio6: gpio-controller@0xff800518 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff800518 0x0 0x4>, + <0x0 0xff800538 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio7: gpio-controller@0xff80051c { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff80051c 0x0 0x4>, + <0x0 0xff80053c 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; }; }; diff --git a/arch/arm/dts/bcm6858.dtsi b/arch/arm/dts/bcm6858.dtsi index 23b80c67a64..5d5e64db081 100644 --- a/arch/arm/dts/bcm6858.dtsi +++ b/arch/arm/dts/bcm6858.dtsi @@ -98,5 +98,85 @@ compatible = "wdt-reboot"; wdt = <&wdt1>; }; + + gpio0: gpio-controller@0xff800500 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff800500 0x0 0x4>, + <0x0 0xff800520 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio1: gpio-controller@0xff800504 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff800504 0x0 0x4>, + <0x0 0xff800524 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio2: gpio-controller@0xff800508 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff800508 0x0 0x4>, + <0x0 0xff800528 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio3: gpio-controller@0xff80050c { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff80050c 0x0 0x4>, + <0x0 0xff80052c 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio4: gpio-controller@0xff800510 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff800510 0x0 0x4>, + <0x0 0xff800530 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio5: gpio-controller@0xff800514 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff800514 0x0 0x4>, + <0x0 0xff800534 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio6: gpio-controller@0xff800518 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff800518 0x0 0x4>, + <0x0 0xff800538 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio7: gpio-controller@0xff80051c { + compatible = "brcm,bcm6345-gpio"; + reg = <0x0 0xff80051c 0x0 0x4>, + <0x0 0xff80053c 0x0 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; }; }; diff --git a/arch/arm/dts/bcm963158.dts b/arch/arm/dts/bcm963158.dts index dc5afb5a24a..b5c825b052b 100644 --- a/arch/arm/dts/bcm963158.dts +++ b/arch/arm/dts/bcm963158.dts @@ -29,3 +29,35 @@ u-boot,dm-pre-reloc; status = "okay"; }; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; + +&gpio4 { + status = "okay"; +}; + +&gpio5 { + status = "okay"; +}; + +&gpio6 { + status = "okay"; +}; + +&gpio7 { + status = "okay"; +}; diff --git a/arch/arm/dts/bcm968580xref.dts b/arch/arm/dts/bcm968580xref.dts index 0c59f94710c..15febb030f1 100644 --- a/arch/arm/dts/bcm968580xref.dts +++ b/arch/arm/dts/bcm968580xref.dts @@ -29,3 +29,35 @@ u-boot,dm-pre-reloc; status = "okay"; }; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; + +&gpio4 { + status = "okay"; +}; + +&gpio5 { + status = "okay"; +}; + +&gpio6 { + status = "okay"; +}; + +&gpio7 { + status = "okay"; +}; diff --git a/arch/arm/dts/bk4r1.dts b/arch/arm/dts/bk4r1.dts index 866b80e0b0b..16c60268fba 100644 --- a/arch/arm/dts/bk4r1.dts +++ b/arch/arm/dts/bk4r1.dts @@ -32,7 +32,7 @@ qflash0: spi_flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <108000000>; reg = <0>; }; @@ -40,7 +40,7 @@ qflash1: spi_flash@1 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <66000000>; reg = <1>; }; diff --git a/arch/arm/dts/da850-evm-u-boot.dtsi b/arch/arm/dts/da850-evm-u-boot.dtsi index ab9368b9d3a..1683f3472e4 100644 --- a/arch/arm/dts/da850-evm-u-boot.dtsi +++ b/arch/arm/dts/da850-evm-u-boot.dtsi @@ -13,7 +13,7 @@ }; &flash { - compatible = "m25p64", "spi-flash"; + compatible = "m25p64", "jedec,spi-nor"; }; &mmc0 { diff --git a/arch/arm/dts/exynos5250-snow.dts b/arch/arm/dts/exynos5250-snow.dts index 7587dc0ff24..e41f2d3041e 100644 --- a/arch/arm/dts/exynos5250-snow.dts +++ b/arch/arm/dts/exynos5250-snow.dts @@ -232,7 +232,7 @@ spi@12d30000 { spi-max-frequency = <50000000>; firmware_storage_spi: flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; }; }; diff --git a/arch/arm/dts/exynos5250-spring.dts b/arch/arm/dts/exynos5250-spring.dts index c7553208ade..77e7a6b9e45 100644 --- a/arch/arm/dts/exynos5250-spring.dts +++ b/arch/arm/dts/exynos5250-spring.dts @@ -149,7 +149,7 @@ spi@12d30000 { spi-max-frequency = <50000000>; firmware_storage_spi: flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; }; }; diff --git a/arch/arm/dts/exynos5420-peach-pit.dts b/arch/arm/dts/exynos5420-peach-pit.dts index 4a96a18110a..a68c3b51746 100644 --- a/arch/arm/dts/exynos5420-peach-pit.dts +++ b/arch/arm/dts/exynos5420-peach-pit.dts @@ -257,7 +257,7 @@ spi@12d30000 { /* spi1 */ spi-max-frequency = <50000000>; firmware_storage_spi: flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; /* diff --git a/arch/arm/dts/fsl-ls1012a-2g5rdb.dts b/arch/arm/dts/fsl-ls1012a-2g5rdb.dts index cdd4ce45aaf..fecef88e080 100644 --- a/arch/arm/dts/fsl-ls1012a-2g5rdb.dts +++ b/arch/arm/dts/fsl-ls1012a-2g5rdb.dts @@ -27,7 +27,7 @@ qflash0: s25fl128s@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <20000000>; reg = <0>; }; diff --git a/arch/arm/dts/fsl-ls1012a-frdm.dtsi b/arch/arm/dts/fsl-ls1012a-frdm.dtsi index 9cb3de1d40c..a357793bfac 100644 --- a/arch/arm/dts/fsl-ls1012a-frdm.dtsi +++ b/arch/arm/dts/fsl-ls1012a-frdm.dtsi @@ -21,7 +21,7 @@ qflash0: s25fl128s@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <20000000>; reg = <0>; }; diff --git a/arch/arm/dts/fsl-ls1012a-frwy.dts b/arch/arm/dts/fsl-ls1012a-frwy.dts index a56909ab92f..7242af51e43 100644 --- a/arch/arm/dts/fsl-ls1012a-frwy.dts +++ b/arch/arm/dts/fsl-ls1012a-frwy.dts @@ -28,7 +28,7 @@ qflash0: w25q16dw@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <20000000>; reg = <0>; }; diff --git a/arch/arm/dts/fsl-ls1012a-qds.dtsi b/arch/arm/dts/fsl-ls1012a-qds.dtsi index 661af0e49e6..a330597b6c0 100644 --- a/arch/arm/dts/fsl-ls1012a-qds.dtsi +++ b/arch/arm/dts/fsl-ls1012a-qds.dtsi @@ -20,7 +20,7 @@ dflash0: n25q128a { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <1000000>; /* input clock */ }; @@ -28,7 +28,7 @@ dflash1: sst25wf040b { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <3500000>; reg = <1>; }; @@ -36,7 +36,7 @@ dflash2: en25s64 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <3500000>; reg = <2>; }; @@ -49,7 +49,7 @@ qflash0: s25fl128s@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <20000000>; reg = <0>; }; diff --git a/arch/arm/dts/fsl-ls1012a-rdb.dtsi b/arch/arm/dts/fsl-ls1012a-rdb.dtsi index 757e2eb3519..f053e789c25 100644 --- a/arch/arm/dts/fsl-ls1012a-rdb.dtsi +++ b/arch/arm/dts/fsl-ls1012a-rdb.dtsi @@ -21,7 +21,7 @@ qflash0: s25fl128s@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <20000000>; reg = <0>; }; diff --git a/arch/arm/dts/fsl-ls1043a-qds.dtsi b/arch/arm/dts/fsl-ls1043a-qds.dtsi index 3841aee11e4..70e1a6a53f1 100644 --- a/arch/arm/dts/fsl-ls1043a-qds.dtsi +++ b/arch/arm/dts/fsl-ls1043a-qds.dtsi @@ -24,7 +24,7 @@ dflash0: n25q128a { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <1000000>; /* input clock */ spi-cpol; spi-cpha; @@ -34,7 +34,7 @@ dflash1: sst25wf040b { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <3500000>; spi-cpol; spi-cpha; @@ -44,7 +44,7 @@ dflash2: en25s64 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <3500000>; spi-cpol; spi-cpha; @@ -59,7 +59,7 @@ qflash0: s25fl128s@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <20000000>; reg = <0>; }; diff --git a/arch/arm/dts/fsl-ls1043a-rdb.dts b/arch/arm/dts/fsl-ls1043a-rdb.dts index c42cad70348..721b158169d 100644 --- a/arch/arm/dts/fsl-ls1043a-rdb.dts +++ b/arch/arm/dts/fsl-ls1043a-rdb.dts @@ -26,7 +26,7 @@ dspiflash: n25q12a { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <1000000>; /* input clock */ }; diff --git a/arch/arm/dts/fsl-ls1046a-qds.dtsi b/arch/arm/dts/fsl-ls1046a-qds.dtsi index ada8a859b10..c95f44fc361 100644 --- a/arch/arm/dts/fsl-ls1046a-qds.dtsi +++ b/arch/arm/dts/fsl-ls1046a-qds.dtsi @@ -24,7 +24,7 @@ dflash0: n25q128a { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <1000000>; /* input clock */ spi-cpol; spi-cpha; @@ -34,7 +34,7 @@ dflash1: sst25wf040b { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <3500000>; spi-cpol; spi-cpha; @@ -44,7 +44,7 @@ dflash2: en25s64 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <3500000>; spi-cpol; spi-cpha; @@ -59,7 +59,7 @@ qflash0: s25fl128s@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <20000000>; reg = <0>; }; diff --git a/arch/arm/dts/fsl-ls1046a-rdb.dts b/arch/arm/dts/fsl-ls1046a-rdb.dts index ba30fd262ac..a05c9e9b9ea 100644 --- a/arch/arm/dts/fsl-ls1046a-rdb.dts +++ b/arch/arm/dts/fsl-ls1046a-rdb.dts @@ -26,7 +26,7 @@ qflash0: s25fs512s@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; }; @@ -34,7 +34,7 @@ qflash1: s25fs512s@1 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <1>; }; diff --git a/arch/arm/dts/fsl-ls1088a-qds.dts b/arch/arm/dts/fsl-ls1088a-qds.dts index 4ea451c1b6a..8fbb52f0e09 100644 --- a/arch/arm/dts/fsl-ls1088a-qds.dts +++ b/arch/arm/dts/fsl-ls1088a-qds.dts @@ -62,7 +62,7 @@ dflash0: n25q128a { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <1000000>; /* input clock */ }; @@ -70,7 +70,7 @@ dflash1: sst25wf040b { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <3500000>; reg = <1>; }; @@ -78,7 +78,7 @@ dflash2: en25s64 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <3500000>; reg = <2>; }; @@ -91,7 +91,7 @@ qflash0: s25fs512s@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; }; @@ -99,7 +99,7 @@ qflash1: s25fs512s@1 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <1>; }; diff --git a/arch/arm/dts/fsl-ls1088a-rdb.dts b/arch/arm/dts/fsl-ls1088a-rdb.dts index f30bbb7247c..765d1e3d74e 100644 --- a/arch/arm/dts/fsl-ls1088a-rdb.dts +++ b/arch/arm/dts/fsl-ls1088a-rdb.dts @@ -24,7 +24,7 @@ qflash0: s25fs512s@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; }; @@ -32,7 +32,7 @@ qflash1: s25fs512s@1 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <1>; }; diff --git a/arch/arm/dts/fsl-ls2080a-qds.dts b/arch/arm/dts/fsl-ls2080a-qds.dts index 39fbc1b79c1..2a0a5280d07 100644 --- a/arch/arm/dts/fsl-ls2080a-qds.dts +++ b/arch/arm/dts/fsl-ls2080a-qds.dts @@ -26,7 +26,7 @@ dflash0: n25q128a { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <3000000>; spi-cpol; spi-cpha; @@ -35,7 +35,7 @@ dflash1: sst25wf040b { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <3000000>; spi-cpol; spi-cpha; @@ -44,7 +44,7 @@ dflash2: en25s64 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <3000000>; spi-cpol; spi-cpha; @@ -59,7 +59,7 @@ qflash0: s25fs256s@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <20000000>; reg = <0>; }; diff --git a/arch/arm/dts/fsl-ls2080a-rdb.dts b/arch/arm/dts/fsl-ls2080a-rdb.dts index e7567cfa231..0a87caeba96 100644 --- a/arch/arm/dts/fsl-ls2080a-rdb.dts +++ b/arch/arm/dts/fsl-ls2080a-rdb.dts @@ -25,7 +25,7 @@ dflash0: n25q512a { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <3000000>; spi-cpol; spi-cpha; diff --git a/arch/arm/dts/fsl-ls2081a-rdb.dts b/arch/arm/dts/fsl-ls2081a-rdb.dts index 73e2683d59b..b0b7ef08a02 100644 --- a/arch/arm/dts/fsl-ls2081a-rdb.dts +++ b/arch/arm/dts/fsl-ls2081a-rdb.dts @@ -28,7 +28,7 @@ dflash0: n25q512a { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <3000000>; spi-cpol; spi-cpha; @@ -43,7 +43,7 @@ qflash0: s25fs512s@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; }; @@ -51,7 +51,7 @@ qflash1: s25fs512s@1 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <1>; }; diff --git a/arch/arm/dts/fsl-ls2088a-rdb-qspi.dts b/arch/arm/dts/fsl-ls2088a-rdb-qspi.dts index b6d4f0f6af1..bf97d138fc2 100644 --- a/arch/arm/dts/fsl-ls2088a-rdb-qspi.dts +++ b/arch/arm/dts/fsl-ls2088a-rdb-qspi.dts @@ -28,7 +28,7 @@ dflash0: n25q512a { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <3000000>; spi-cpol; spi-cpha; @@ -43,7 +43,7 @@ qflash0: s25fs512s@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; }; @@ -51,7 +51,7 @@ qflash1: s25fs512s@1 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <1>; }; diff --git a/arch/arm/dts/imx53-kp-u-boot.dtsi b/arch/arm/dts/imx53-kp-u-boot.dtsi new file mode 100644 index 00000000000..acab9b3657e --- /dev/null +++ b/arch/arm/dts/imx53-kp-u-boot.dtsi @@ -0,0 +1,10 @@ +/* + * Copyright 2019 + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + * + * SPDX-License-Identifier: GPL-2.0+ or X11 + */ + +&pmic { + u-boot,i2c-transaction-bytes = <3>; +}; diff --git a/arch/arm/dts/imx6sx-sabreauto-u-boot.dtsi b/arch/arm/dts/imx6sx-sabreauto-u-boot.dtsi index f5c68d707c3..549461df71e 100644 --- a/arch/arm/dts/imx6sx-sabreauto-u-boot.dtsi +++ b/arch/arm/dts/imx6sx-sabreauto-u-boot.dtsi @@ -7,10 +7,10 @@ num-cs = <2>; flash0: n25q256a@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; }; flash1: n25q256a@1 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; }; }; diff --git a/arch/arm/dts/imx6sx-sdb-u-boot.dtsi b/arch/arm/dts/imx6sx-sdb-u-boot.dtsi index 8e592cded9f..8f9236da0f3 100644 --- a/arch/arm/dts/imx6sx-sdb-u-boot.dtsi +++ b/arch/arm/dts/imx6sx-sdb-u-boot.dtsi @@ -7,10 +7,10 @@ num-cs = <2>; flash0: n25q256a@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; }; flash1: n25q256a@1 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; }; }; diff --git a/arch/arm/dts/imx6ul-14x14-evk-u-boot.dtsi b/arch/arm/dts/imx6ul-14x14-evk-u-boot.dtsi index db640d6e674..77cb461a215 100644 --- a/arch/arm/dts/imx6ul-14x14-evk-u-boot.dtsi +++ b/arch/arm/dts/imx6ul-14x14-evk-u-boot.dtsi @@ -5,6 +5,6 @@ &qspi { flash0: n25q256a@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; }; };
\ No newline at end of file diff --git a/arch/arm/dts/imx6ul-9x9-evk-u-boot.dtsi b/arch/arm/dts/imx6ul-9x9-evk-u-boot.dtsi index db640d6e674..77cb461a215 100644 --- a/arch/arm/dts/imx6ul-9x9-evk-u-boot.dtsi +++ b/arch/arm/dts/imx6ul-9x9-evk-u-boot.dtsi @@ -5,6 +5,6 @@ &qspi { flash0: n25q256a@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; }; };
\ No newline at end of file diff --git a/arch/arm/dts/imx6ull-14x14-evk.dts b/arch/arm/dts/imx6ull-14x14-evk.dts index 8a1b67d6bbf..9ebcfe1f4ea 100644 --- a/arch/arm/dts/imx6ull-14x14-evk.dts +++ b/arch/arm/dts/imx6ull-14x14-evk.dts @@ -455,7 +455,7 @@ #address-cells = <1>; #size-cells = <1>; /* compatible = "micron,n25q256a"; */ - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <29000000>; spi-nor,ddr-quad-read-dummy = <6>; reg = <0>; diff --git a/arch/arm/dts/imx7d-sdb-qspi-u-boot.dtsi b/arch/arm/dts/imx7d-sdb-qspi-u-boot.dtsi index 2ce6961096f..585af6d211f 100644 --- a/arch/arm/dts/imx7d-sdb-qspi-u-boot.dtsi +++ b/arch/arm/dts/imx7d-sdb-qspi-u-boot.dtsi @@ -5,6 +5,6 @@ &qspi1 { flash0: mx25l51245g@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; }; }; diff --git a/arch/arm/dts/keystone-k2e-evm.dts b/arch/arm/dts/keystone-k2e-evm.dts index 3be8b532525..9288df21ce1 100644 --- a/arch/arm/dts/keystone-k2e-evm.dts +++ b/arch/arm/dts/keystone-k2e-evm.dts @@ -123,7 +123,7 @@ nor_flash: n25q128a11@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "Micron,n25q128a11", "spi-flash"; + compatible = "Micron,n25q128a11", "jedec,spi-nor"; spi-max-frequency = <54000000>; m25p,fast-read; reg = <0>; diff --git a/arch/arm/dts/keystone-k2g-evm.dts b/arch/arm/dts/keystone-k2g-evm.dts index 4820c7e50da..7c5deef8083 100644 --- a/arch/arm/dts/keystone-k2g-evm.dts +++ b/arch/arm/dts/keystone-k2g-evm.dts @@ -74,7 +74,7 @@ spi_nor: flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; m25p,fast-read; reg = <0>; @@ -96,7 +96,7 @@ status = "okay"; flash0: m25p80@0 { - compatible = "s25fl512s","spi-flash"; + compatible = "s25fl512s","jedec,spi-nor"; reg = <0>; spi-tx-bus-width = <1>; spi-rx-bus-width = <4>; diff --git a/arch/arm/dts/keystone-k2g-ice.dts b/arch/arm/dts/keystone-k2g-ice.dts index b67332fed5b..ecca2dfac1a 100644 --- a/arch/arm/dts/keystone-k2g-ice.dts +++ b/arch/arm/dts/keystone-k2g-ice.dts @@ -39,7 +39,7 @@ status = "okay"; flash0: m25p80@0 { - compatible = "s25fl256s1", "spi-flash"; + compatible = "s25fl256s1", "jedec,spi-nor"; reg = <0>; spi-tx-bus-width = <1>; spi-rx-bus-width = <4>; diff --git a/arch/arm/dts/keystone-k2hk-evm.dts b/arch/arm/dts/keystone-k2hk-evm.dts index 76a675f1e46..84c58d75ada 100644 --- a/arch/arm/dts/keystone-k2hk-evm.dts +++ b/arch/arm/dts/keystone-k2hk-evm.dts @@ -151,7 +151,7 @@ nor_flash: n25q128a11@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "Micron,n25q128a11", "spi-flash"; + compatible = "Micron,n25q128a11", "jedec,spi-nor"; spi-max-frequency = <54000000>; m25p,fast-read; reg = <0>; diff --git a/arch/arm/dts/keystone-k2l-evm.dts b/arch/arm/dts/keystone-k2l-evm.dts index b5c56176bf6..91cefdf2aa9 100644 --- a/arch/arm/dts/keystone-k2l-evm.dts +++ b/arch/arm/dts/keystone-k2l-evm.dts @@ -100,7 +100,7 @@ nor_flash: n25q128a11@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "Micron,n25q128a11", "spi-flash"; + compatible = "Micron,n25q128a11", "jedec,spi-nor"; spi-max-frequency = <54000000>; m25p,fast-read; reg = <0>; diff --git a/arch/arm/dts/kirkwood-atl-sbx81lifkw.dts b/arch/arm/dts/kirkwood-atl-sbx81lifkw.dts index e5b1efa1415..4ae74f4316e 100644 --- a/arch/arm/dts/kirkwood-atl-sbx81lifkw.dts +++ b/arch/arm/dts/kirkwood-atl-sbx81lifkw.dts @@ -78,7 +78,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "st,m25p128", "jedec,spi-nor", "spi-flash"; + compatible = "st,m25p128", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <50000000>; mode = <0>; diff --git a/arch/arm/dts/kirkwood-atl-sbx81lifxcat.dts b/arch/arm/dts/kirkwood-atl-sbx81lifxcat.dts index c2344499362..6e3418f2461 100644 --- a/arch/arm/dts/kirkwood-atl-sbx81lifxcat.dts +++ b/arch/arm/dts/kirkwood-atl-sbx81lifxcat.dts @@ -92,7 +92,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "st,m25p128", "jedec,spi-nor", "spi-flash"; + compatible = "st,m25p128", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <50000000>; mode = <0>; diff --git a/arch/arm/dts/kirkwood-dreamplug.dts b/arch/arm/dts/kirkwood-dreamplug.dts index ccd74dd7fb3..e9eea22fc93 100644 --- a/arch/arm/dts/kirkwood-dreamplug.dts +++ b/arch/arm/dts/kirkwood-dreamplug.dts @@ -47,7 +47,7 @@ m25p40@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "mxicy,mx25l1606e", "jedec,spi-nor", "spi-flash"; + compatible = "mxicy,mx25l1606e", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <50000000>; mode = <0>; diff --git a/arch/arm/dts/kirkwood-lsxl.dtsi b/arch/arm/dts/kirkwood-lsxl.dtsi index 479a750d1d8..c99c0da0937 100644 --- a/arch/arm/dts/kirkwood-lsxl.dtsi +++ b/arch/arm/dts/kirkwood-lsxl.dtsi @@ -79,7 +79,7 @@ m25p40@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "m25p40", "jedec,spi-nor", "spi-flash"; + compatible = "m25p40", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <25000000>; mode = <0>; diff --git a/arch/arm/dts/kirkwood-netxbig.dtsi b/arch/arm/dts/kirkwood-netxbig.dtsi index 135ac8021c8..b5737026e24 100644 --- a/arch/arm/dts/kirkwood-netxbig.dtsi +++ b/arch/arm/dts/kirkwood-netxbig.dtsi @@ -32,7 +32,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "mxicy,mx25l4005a", "jedec,spi-nor", "spi-flash"; + compatible = "mxicy,mx25l4005a", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <20000000>; mode = <0>; diff --git a/arch/arm/dts/kirkwood-ns2-common.dtsi b/arch/arm/dts/kirkwood-ns2-common.dtsi index f997bb4df20..51530ea8662 100644 --- a/arch/arm/dts/kirkwood-ns2-common.dtsi +++ b/arch/arm/dts/kirkwood-ns2-common.dtsi @@ -30,7 +30,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "mxicy,mx25l4005a", "jedec,spi-nor", "spi-flash"; + compatible = "mxicy,mx25l4005a", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <20000000>; mode = <0>; diff --git a/arch/arm/dts/kirkwood-synology.dtsi b/arch/arm/dts/kirkwood-synology.dtsi index b80d8ee3709..c97ed29a0a0 100644 --- a/arch/arm/dts/kirkwood-synology.dtsi +++ b/arch/arm/dts/kirkwood-synology.dtsi @@ -201,7 +201,7 @@ m25p80@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "st,m25p80", "jedec,spi-nor", "spi-flash"; + compatible = "st,m25p80", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <20000000>; mode = <0>; diff --git a/arch/arm/dts/ls1021a-iot.dtsi b/arch/arm/dts/ls1021a-iot.dtsi index d27b6014207..44dd9b61d3f 100644 --- a/arch/arm/dts/ls1021a-iot.dtsi +++ b/arch/arm/dts/ls1021a-iot.dtsi @@ -27,7 +27,7 @@ qflash0: n25q128a13@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <20000000>; reg = <0>; }; @@ -40,7 +40,7 @@ dspiflash: at26df081a@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <16000000>; spi-cpol; spi-cpha; diff --git a/arch/arm/dts/ls1021a-qds.dtsi b/arch/arm/dts/ls1021a-qds.dtsi index f7783e51653..b12102abfa3 100644 --- a/arch/arm/dts/ls1021a-qds.dtsi +++ b/arch/arm/dts/ls1021a-qds.dtsi @@ -43,7 +43,7 @@ qflash0: s25fl128s@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <20000000>; reg = <0>; }; diff --git a/arch/arm/dts/ls1021a-twr.dtsi b/arch/arm/dts/ls1021a-twr.dtsi index 928e1002585..5d3275ced91 100644 --- a/arch/arm/dts/ls1021a-twr.dtsi +++ b/arch/arm/dts/ls1021a-twr.dtsi @@ -30,7 +30,7 @@ qflash0: n25q128a13@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <20000000>; reg = <0>; }; @@ -43,7 +43,7 @@ dspiflash: at26df081a@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <16000000>; spi-cpol; spi-cpha; diff --git a/arch/arm/dts/mt7629-rfb.dts b/arch/arm/dts/mt7629-rfb.dts index 95d10aa6d32..4612218a1eb 100644 --- a/arch/arm/dts/mt7629-rfb.dts +++ b/arch/arm/dts/mt7629-rfb.dts @@ -62,7 +62,7 @@ status = "okay"; spi-flash@0{ - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/omap5-u-boot.dtsi b/arch/arm/dts/omap5-u-boot.dtsi index 54a7285e6e1..1b1d765fae0 100644 --- a/arch/arm/dts/omap5-u-boot.dtsi +++ b/arch/arm/dts/omap5-u-boot.dtsi @@ -68,7 +68,7 @@ u-boot,dm-spl; m25p80@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; u-boot,dm-spl; }; }; diff --git a/arch/arm/dts/r8a77970-eagle-u-boot.dts b/arch/arm/dts/r8a77970-eagle-u-boot.dts index 5b17f1d1f0b..eb868eda414 100644 --- a/arch/arm/dts/r8a77970-eagle-u-boot.dts +++ b/arch/arm/dts/r8a77970-eagle-u-boot.dts @@ -44,7 +44,7 @@ flash0: spi-flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "s25fs512s", "spi-flash", "jedec,spi-nor"; + compatible = "s25fs512s", "jedec,spi-nor"; spi-max-frequency = <50000000>; spi-tx-bus-width = <1>; spi-rx-bus-width = <1>; diff --git a/arch/arm/dts/rk3288-veyron.dtsi b/arch/arm/dts/rk3288-veyron.dtsi index 49ba3f3f143..916dd486de0 100644 --- a/arch/arm/dts/rk3288-veyron.dtsi +++ b/arch/arm/dts/rk3288-veyron.dtsi @@ -307,7 +307,7 @@ spi_flash: spiflash@0 { u-boot,dm-pre-reloc; - compatible = "spidev", "spi-flash"; + compatible = "spidev", "jedec,spi-nor"; spi-max-frequency = <20000000>; /* Reduce for Dediprog em100 pro */ reg = <0>; }; diff --git a/arch/arm/dts/rk3368-lion.dts b/arch/arm/dts/rk3368-lion.dts index 5e578b175b5..28145420837 100644 --- a/arch/arm/dts/rk3368-lion.dts +++ b/arch/arm/dts/rk3368-lion.dts @@ -185,7 +185,7 @@ #size-cells = <0>; spiflash: w25q32dw@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <49500000>; spi-cpol; diff --git a/arch/arm/dts/rk3399-gru.dtsi b/arch/arm/dts/rk3399-gru.dtsi index df19263accb..4cdb4320b76 100644 --- a/arch/arm/dts/rk3399-gru.dtsi +++ b/arch/arm/dts/rk3399-gru.dtsi @@ -552,7 +552,7 @@ ap_i2c_audio: &i2c8 { spi_flash: spiflash@0 { u-boot,dm-pre-reloc; - compatible = "jedec,spi-nor", "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; /* May run faster once verified. */ diff --git a/arch/arm/dts/rk3399-puma.dtsi b/arch/arm/dts/rk3399-puma.dtsi index 8304f67192c..aec13a28f1a 100644 --- a/arch/arm/dts/rk3399-puma.dtsi +++ b/arch/arm/dts/rk3399-puma.dtsi @@ -658,7 +658,7 @@ spiflash: w25q32dw@0 { u-boot,dm-pre-reloc; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <49500000>; spi-cpol; diff --git a/arch/arm/dts/rv1108-evb.dts b/arch/arm/dts/rv1108-evb.dts index ccb9969da0e..c91776bc106 100644 --- a/arch/arm/dts/rv1108-evb.dts +++ b/arch/arm/dts/rv1108-evb.dts @@ -45,7 +45,7 @@ &sfc { status = "okay"; flash@0 { - compatible = "gd25q256","spi-flash"; + compatible = "gd25q256","jedec,spi-nor"; reg = <0>; spi-tx-bus-width = <1>; spi-rx-bus-width = <1>; diff --git a/arch/arm/dts/sama5d27_som1.dtsi b/arch/arm/dts/sama5d27_som1.dtsi index 9efcf635ad5..ea7540bcfcf 100644 --- a/arch/arm/dts/sama5d27_som1.dtsi +++ b/arch/arm/dts/sama5d27_som1.dtsi @@ -66,7 +66,7 @@ u-boot,dm-pre-reloc; spi_flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <50000000>; spi-rx-bus-width = <4>; diff --git a/arch/arm/dts/sama5d3xmb.dtsi b/arch/arm/dts/sama5d3xmb.dtsi index f9ef905ff54..c75b76aef2a 100644 --- a/arch/arm/dts/sama5d3xmb.dtsi +++ b/arch/arm/dts/sama5d3xmb.dtsi @@ -35,7 +35,7 @@ u-boot,dm-pre-reloc; spi_flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; u-boot,dm-pre-reloc; diff --git a/arch/arm/dts/sama5d3xmb_cmp.dtsi b/arch/arm/dts/sama5d3xmb_cmp.dtsi index 9792b2a9d08..5566fde5148 100644 --- a/arch/arm/dts/sama5d3xmb_cmp.dtsi +++ b/arch/arm/dts/sama5d3xmb_cmp.dtsi @@ -32,7 +32,7 @@ dmas = <0>, <0>; /* Do not use DMA for spi0 */ spi_flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; }; diff --git a/arch/arm/dts/socfpga_arria5_socdk-u-boot.dtsi b/arch/arm/dts/socfpga_arria5_socdk-u-boot.dtsi index c44d1ee2fa1..e75f2902c54 100644 --- a/arch/arm/dts/socfpga_arria5_socdk-u-boot.dtsi +++ b/arch/arm/dts/socfpga_arria5_socdk-u-boot.dtsi @@ -30,7 +30,7 @@ }; &flash { - compatible = "n25q00", "spi-flash"; + compatible = "n25q00", "jedec,spi-nor"; u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/socfpga_cyclone5_is1.dts b/arch/arm/dts/socfpga_cyclone5_is1.dts index b7054bfd5af..93e4d45ad2b 100644 --- a/arch/arm/dts/socfpga_cyclone5_is1.dts +++ b/arch/arm/dts/socfpga_cyclone5_is1.dts @@ -91,7 +91,7 @@ u-boot,dm-pre-reloc; #address-cells = <1>; #size-cells = <1>; - compatible = "n25q00", "spi-flash"; + compatible = "n25q00", "jedec,spi-nor"; reg = <0>; /* chip select */ spi-max-frequency = <100000000>; m25p,fast-read; diff --git a/arch/arm/dts/socfpga_cyclone5_socdk-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_socdk-u-boot.dtsi index 9436e0fa8b1..2fafd7e399d 100644 --- a/arch/arm/dts/socfpga_cyclone5_socdk-u-boot.dtsi +++ b/arch/arm/dts/socfpga_cyclone5_socdk-u-boot.dtsi @@ -34,7 +34,7 @@ }; &flash0 { - compatible = "n25q00", "spi-flash"; + compatible = "n25q00", "jedec,spi-nor"; u-boot,dm-pre-reloc; partition@qspi-boot { diff --git a/arch/arm/dts/socfpga_cyclone5_sockit-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_sockit-u-boot.dtsi index 648f1bd01d7..7ef30531f4a 100644 --- a/arch/arm/dts/socfpga_cyclone5_sockit-u-boot.dtsi +++ b/arch/arm/dts/socfpga_cyclone5_sockit-u-boot.dtsi @@ -30,7 +30,7 @@ }; &flash { - compatible = "n25q00", "spi-flash"; + compatible = "n25q00", "jedec,spi-nor"; u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/socfpga_cyclone5_socrates-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_socrates-u-boot.dtsi index 31bd1dba0ff..1003115cead 100644 --- a/arch/arm/dts/socfpga_cyclone5_socrates-u-boot.dtsi +++ b/arch/arm/dts/socfpga_cyclone5_socrates-u-boot.dtsi @@ -30,7 +30,7 @@ }; &flash { - compatible = "n25q256a", "spi-flash"; + compatible = "n25q256a", "jedec,spi-nor"; u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/socfpga_cyclone5_sr1500.dts b/arch/arm/dts/socfpga_cyclone5_sr1500.dts index 6a6c29be79b..1a18c4f3baf 100644 --- a/arch/arm/dts/socfpga_cyclone5_sr1500.dts +++ b/arch/arm/dts/socfpga_cyclone5_sr1500.dts @@ -99,7 +99,7 @@ u-boot,dm-pre-reloc; #address-cells = <1>; #size-cells = <1>; - compatible = "n25q00", "spi-flash"; + compatible = "n25q00", "jedec,spi-nor"; reg = <0>; /* chip select */ spi-max-frequency = <100000000>; m25p,fast-read; diff --git a/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi b/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi index 360b946ba23..e05ca8279a9 100644 --- a/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi +++ b/arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi @@ -29,11 +29,11 @@ u-boot,dm-pre-reloc; n25q128@0 { - compatible = "n25q128", "spi-flash"; + compatible = "n25q128", "jedec,spi-nor"; u-boot,dm-pre-reloc; }; n25q00@1 { - compatible = "n25q00", "spi-flash"; + compatible = "n25q00", "jedec,spi-nor"; u-boot,dm-pre-reloc; }; }; diff --git a/arch/arm/dts/stm32f746-disco.dts b/arch/arm/dts/stm32f746-disco.dts index 7ef33d63813..babd37f1c11 100644 --- a/arch/arm/dts/stm32f746-disco.dts +++ b/arch/arm/dts/stm32f746-disco.dts @@ -297,7 +297,7 @@ qflash0: n25q128a { #address-cells = <1>; #size-cells = <1>; - compatible = "micron,n25q128a13", "spi-flash"; + compatible = "micron,n25q128a13", "jedec,spi-nor"; spi-max-frequency = <108000000>; spi-tx-bus-width = <1>; spi-rx-bus-width = <1>; diff --git a/arch/arm/dts/stm32f769-disco.dts b/arch/arm/dts/stm32f769-disco.dts index 1e8ef742cea..a23d02d3008 100644 --- a/arch/arm/dts/stm32f769-disco.dts +++ b/arch/arm/dts/stm32f769-disco.dts @@ -246,7 +246,7 @@ qflash0: n25q128a { #address-cells = <1>; #size-cells = <1>; - compatible = "micron,n25q128a13", "spi-flash"; + compatible = "micron,n25q128a13", "jedec,spi-nor"; spi-max-frequency = <108000000>; spi-tx-bus-width = <1>; spi-rx-bus-width = <1>; diff --git a/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi new file mode 100644 index 00000000000..7d9b95ccf16 --- /dev/null +++ b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + * + * STM32MP157C DK1/DK2 BOARD configuration + * 1x DDR3L 4Gb, 16-bit, 533MHz. + * Reference used NT5CC256M16DP-DI from NANYA + * + * DDR type / Platform DDR3/3L + * freq 533MHz + * width 16 + * datasheet 0 = MT41J256M16-187 / DDR3-1066 bin G + * DDR density 4 + * timing mode optimized + * Scheduling/QoS options : type = 2 + * address mapping : RBC + * Tc > + 85C : N + */ +#define DDR_MEM_NAME "DDR3-1066/888 bin G 1x4Gb 533MHz v1.43" +#define DDR_MEM_SPEED 533 +#define DDR_MEM_SIZE 0x20000000 + +#define DDR_MSTR 0x00041401 +#define DDR_MRCTRL0 0x00000010 +#define DDR_MRCTRL1 0x00000000 +#define DDR_DERATEEN 0x00000000 +#define DDR_DERATEINT 0x00800000 +#define DDR_PWRCTL 0x00000000 +#define DDR_PWRTMG 0x00400010 +#define DDR_HWLPCTL 0x00000000 +#define DDR_RFSHCTL0 0x00210000 +#define DDR_RFSHCTL3 0x00000000 +#define DDR_RFSHTMG 0x0081008B +#define DDR_CRCPARCTL0 0x00000000 +#define DDR_DRAMTMG0 0x121B2414 +#define DDR_DRAMTMG1 0x000A041C +#define DDR_DRAMTMG2 0x0608090F +#define DDR_DRAMTMG3 0x0050400C +#define DDR_DRAMTMG4 0x08040608 +#define DDR_DRAMTMG5 0x06060403 +#define DDR_DRAMTMG6 0x02020002 +#define DDR_DRAMTMG7 0x00000202 +#define DDR_DRAMTMG8 0x00001005 +#define DDR_DRAMTMG14 0x000000A0 +#define DDR_ZQCTL0 0xC2000040 +#define DDR_DFITMG0 0x02060105 +#define DDR_DFITMG1 0x00000202 +#define DDR_DFILPCFG0 0x07000000 +#define DDR_DFIUPD0 0xC0400003 +#define DDR_DFIUPD1 0x00000000 +#define DDR_DFIUPD2 0x00000000 +#define DDR_DFIPHYMSTR 0x00000000 +#define DDR_ADDRMAP1 0x00070707 +#define DDR_ADDRMAP2 0x00000000 +#define DDR_ADDRMAP3 0x1F000000 +#define DDR_ADDRMAP4 0x00001F1F +#define DDR_ADDRMAP5 0x06060606 +#define DDR_ADDRMAP6 0x0F060606 +#define DDR_ADDRMAP9 0x00000000 +#define DDR_ADDRMAP10 0x00000000 +#define DDR_ADDRMAP11 0x00000000 +#define DDR_ODTCFG 0x06000600 +#define DDR_ODTMAP 0x00000001 +#define DDR_SCHED 0x00000C01 +#define DDR_SCHED1 0x00000000 +#define DDR_PERFHPR1 0x01000001 +#define DDR_PERFLPR1 0x08000200 +#define DDR_PERFWR1 0x08000400 +#define DDR_DBG0 0x00000000 +#define DDR_DBG1 0x00000000 +#define DDR_DBGCMD 0x00000000 +#define DDR_POISONCFG 0x00000000 +#define DDR_PCCFG 0x00000010 +#define DDR_PCFGR_0 0x00010000 +#define DDR_PCFGW_0 0x00000000 +#define DDR_PCFGQOS0_0 0x02100C03 +#define DDR_PCFGQOS1_0 0x00800100 +#define DDR_PCFGWQOS0_0 0x01100C03 +#define DDR_PCFGWQOS1_0 0x01000200 +#define DDR_PCFGR_1 0x00010000 +#define DDR_PCFGW_1 0x00000000 +#define DDR_PCFGQOS0_1 0x02100C03 +#define DDR_PCFGQOS1_1 0x00800040 +#define DDR_PCFGWQOS0_1 0x01100C03 +#define DDR_PCFGWQOS1_1 0x01000200 +#define DDR_PGCR 0x01442E02 +#define DDR_PTR0 0x0022AA5B +#define DDR_PTR1 0x04841104 +#define DDR_PTR2 0x042DA068 +#define DDR_ACIOCR 0x10400812 +#define DDR_DXCCR 0x00000C40 +#define DDR_DSGCR 0xF200001F +#define DDR_DCR 0x0000000B +#define DDR_DTPR0 0x38D488D0 +#define DDR_DTPR1 0x098B00D8 +#define DDR_DTPR2 0x10023600 +#define DDR_MR0 0x00000840 +#define DDR_MR1 0x00000000 +#define DDR_MR2 0x00000208 +#define DDR_MR3 0x00000000 +#define DDR_ODTCR 0x00010000 +#define DDR_ZQ0CR1 0x00000038 +#define DDR_DX0GCR 0x0000CE81 +#define DDR_DX0DLLCR 0x40000000 +#define DDR_DX0DQTR 0xFFFFFFFF +#define DDR_DX0DQSTR 0x3DB02000 +#define DDR_DX1GCR 0x0000CE81 +#define DDR_DX1DLLCR 0x40000000 +#define DDR_DX1DQTR 0xFFFFFFFF +#define DDR_DX1DQSTR 0x3DB02000 +#define DDR_DX2GCR 0x0000CE81 +#define DDR_DX2DLLCR 0x40000000 +#define DDR_DX2DQTR 0xFFFFFFFF +#define DDR_DX2DQSTR 0x3DB02000 +#define DDR_DX3GCR 0x0000CE81 +#define DDR_DX3DLLCR 0x40000000 +#define DDR_DX3DQTR 0xFFFFFFFF +#define DDR_DX3DQSTR 0x3DB02000 + +#include "stm32mp15-ddr.dtsi" diff --git a/arch/arm/dts/stm32mp157-pinctrl.dtsi b/arch/arm/dts/stm32mp157-pinctrl.dtsi index 85da5926551..c0698754861 100644 --- a/arch/arm/dts/stm32mp157-pinctrl.dtsi +++ b/arch/arm/dts/stm32mp157-pinctrl.dtsi @@ -148,6 +148,13 @@ gpio-ranges = <&pinctrl 0 160 8>; }; + adc12_usb_pwr_pins_a: adc12-usb-pwr-pins-0 { + pins { + pinmux = <STM32_PINMUX('A', 4, ANALOG)>, /* ADC12 in18 */ + <STM32_PINMUX('A', 5, ANALOG)>; /* ADC12 in19 */ + }; + }; + cec_pins_a: cec-0 { pins { pinmux = <STM32_PINMUX('A', 15, AF4)>; @@ -157,6 +164,52 @@ }; }; + ethernet0_rgmii_pins_a: rgmii-0 { + pins1 { + pinmux = <STM32_PINMUX('G', 5, AF11)>, /* ETH_RGMII_CLK125 */ + <STM32_PINMUX('G', 4, AF11)>, /* ETH_RGMII_GTX_CLK */ + <STM32_PINMUX('G', 13, AF11)>, /* ETH_RGMII_TXD0 */ + <STM32_PINMUX('G', 14, AF11)>, /* ETH_RGMII_TXD1 */ + <STM32_PINMUX('C', 2, AF11)>, /* ETH_RGMII_TXD2 */ + <STM32_PINMUX('E', 2, AF11)>, /* ETH_RGMII_TXD3 */ + <STM32_PINMUX('B', 11, AF11)>, /* ETH_RGMII_TX_CTL */ + <STM32_PINMUX('A', 2, AF11)>, /* ETH_MDIO */ + <STM32_PINMUX('C', 1, AF11)>; /* ETH_MDC */ + bias-disable; + drive-push-pull; + slew-rate = <3>; + }; + pins2 { + pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RGMII_RXD0 */ + <STM32_PINMUX('C', 5, AF11)>, /* ETH_RGMII_RXD1 */ + <STM32_PINMUX('B', 0, AF11)>, /* ETH_RGMII_RXD2 */ + <STM32_PINMUX('B', 1, AF11)>, /* ETH_RGMII_RXD3 */ + <STM32_PINMUX('A', 1, AF11)>, /* ETH_RGMII_RX_CLK */ + <STM32_PINMUX('A', 7, AF11)>; /* ETH_RGMII_RX_CTL */ + bias-disable; + }; + }; + + ethernet0_rgmii_pins_sleep_a: rgmii-sleep-0 { + pins1 { + pinmux = <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_RGMII_CLK125 */ + <STM32_PINMUX('G', 4, ANALOG)>, /* ETH_RGMII_GTX_CLK */ + <STM32_PINMUX('G', 13, ANALOG)>, /* ETH_RGMII_TXD0 */ + <STM32_PINMUX('G', 14, ANALOG)>, /* ETH_RGMII_TXD1 */ + <STM32_PINMUX('C', 2, ANALOG)>, /* ETH_RGMII_TXD2 */ + <STM32_PINMUX('E', 2, ANALOG)>, /* ETH_RGMII_TXD3 */ + <STM32_PINMUX('B', 11, ANALOG)>, /* ETH_RGMII_TX_CTL */ + <STM32_PINMUX('A', 2, ANALOG)>, /* ETH_MDIO */ + <STM32_PINMUX('C', 1, ANALOG)>, /* ETH_MDC */ + <STM32_PINMUX('C', 4, ANALOG)>, /* ETH_RGMII_RXD0 */ + <STM32_PINMUX('C', 5, ANALOG)>, /* ETH_RGMII_RXD1 */ + <STM32_PINMUX('B', 0, ANALOG)>, /* ETH_RGMII_RXD2 */ + <STM32_PINMUX('B', 1, ANALOG)>, /* ETH_RGMII_RXD3 */ + <STM32_PINMUX('A', 1, ANALOG)>, /* ETH_RGMII_RX_CLK */ + <STM32_PINMUX('A', 7, ANALOG)>; /* ETH_RGMII_RX_CTL */ + }; + }; + i2c1_pins_a: i2c1-0 { pins { pinmux = <STM32_PINMUX('D', 12, AF5)>, /* I2C1_SCL */ @@ -187,6 +240,19 @@ }; }; + m_can1_pins_a: m-can1-0 { + pins1 { + pinmux = <STM32_PINMUX('H', 13, AF9)>; /* CAN1_TX */ + slew-rate = <1>; + drive-push-pull; + bias-disable; + }; + pins2 { + pinmux = <STM32_PINMUX('I', 9, AF9)>; /* CAN1_RX */ + bias-disable; + }; + }; + pwm2_pins_a: pwm2-0 { pins { pinmux = <STM32_PINMUX('A', 3, AF1)>; /* TIM2_CH4 */ @@ -360,6 +426,21 @@ slew-rate = <0>; }; }; + + spi1_pins_a: spi1-0 { + pins1 { + pinmux = <STM32_PINMUX('Z', 0, AF5)>, /* SPI1_SCK */ + <STM32_PINMUX('Z', 2, AF5)>; /* SPI1_MOSI */ + bias-disable; + drive-push-pull; + slew-rate = <1>; + }; + + pins2 { + pinmux = <STM32_PINMUX('Z', 1, AF5)>; /* SPI1_MISO */ + bias-disable; + }; + }; }; }; }; diff --git a/arch/arm/dts/stm32mp157-u-boot.dtsi b/arch/arm/dts/stm32mp157-u-boot.dtsi index 90d13f35c46..ab6f673ea24 100644 --- a/arch/arm/dts/stm32mp157-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157-u-boot.dtsi @@ -17,6 +17,8 @@ gpio9 = &gpioj; gpio10 = &gpiok; gpio25 = &gpioz; + pinctrl0 = &pinctrl; + pinctrl1 = &pinctrl_z; }; config { @@ -39,6 +41,10 @@ }; }; +&bsec { + u-boot,dm-pre-reloc; +}; + &clk_hsi { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi new file mode 100644 index 00000000000..af7acfa0375 --- /dev/null +++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright : STMicroelectronics 2018 + */ + +#include <dt-bindings/clock/stm32mp1-clksrc.h> +#include "stm32mp157-u-boot.dtsi" +#include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi" + +/ { + aliases { + i2c3 = &i2c4; + mmc0 = &sdmmc1; + }; + config { + u-boot,boot-led = "heartbeat"; + u-boot,error-led = "error"; + st,adc_usb_pd = <&adc1 18>, <&adc1 19>; + }; + led { + red { + label = "error"; + gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; + default-state = "off"; + status = "okay"; + }; + + blue { + default-state = "on"; + }; + }; +}; + +&adc { + pinctrl-names = "default"; + pinctrl-0 = <&adc12_usb_pwr_pins_a>; + vdd-supply = <&vdd>; + vdda-supply = <&vdd>; + vref-supply = <&vrefbuf>; + status = "okay"; + adc1: adc@0 { + /* + * Type-C USB_PWR_CC1 & USB_PWR_CC2 on in18 & in19. + * Use at least 5 * RC time, e.g. 5 * (Rp + Rd) * C: + * 5 * (56 + 47kOhms) * 5pF => 2.5us. + * Use arbitrary margin here (e.g. 5µs). + */ + st,min-sample-time-nsecs = <5000>; + /* ANA0, ANA1, USB Type-C CC1 & CC2 */ + st,adc-channels = <0 1 18 19>; + status = "okay"; + }; +}; + +&clk_hse { + st,digbypass; +}; + +&i2c4 { + u-boot,dm-pre-reloc; +}; + +&i2c4_pins_a { + u-boot,dm-pre-reloc; + pins { + u-boot,dm-pre-reloc; + }; +}; + +&pmic { + u-boot,dm-pre-reloc; +}; + +&rcc { + st,clksrc = < + CLK_MPU_PLL1P + CLK_AXI_PLL2P + CLK_MCU_PLL3P + CLK_PLL12_HSE + CLK_PLL3_HSE + CLK_PLL4_HSE + CLK_RTC_LSE + CLK_MCO1_DISABLED + CLK_MCO2_DISABLED + >; + + st,clkdiv = < + 1 /*MPU*/ + 0 /*AXI*/ + 0 /*MCU*/ + 1 /*APB1*/ + 1 /*APB2*/ + 1 /*APB3*/ + 1 /*APB4*/ + 2 /*APB5*/ + 23 /*RTC*/ + 0 /*MCO1*/ + 0 /*MCO2*/ + >; + + st,pkcs = < + CLK_CKPER_HSE + CLK_FMC_ACLK + CLK_QSPI_ACLK + CLK_ETH_DISABLED + CLK_SDMMC12_PLL4P + CLK_DSI_DSIPLL + CLK_STGEN_HSE + CLK_USBPHY_HSE + CLK_SPI2S1_PLL3Q + CLK_SPI2S23_PLL3Q + CLK_SPI45_HSI + CLK_SPI6_HSI + CLK_I2C46_HSI + CLK_SDMMC3_PLL4P + CLK_USBO_USBPHY + CLK_ADC_CKPER + CLK_CEC_LSE + CLK_I2C12_HSI + CLK_I2C35_HSI + CLK_UART1_HSI + CLK_UART24_HSI + CLK_UART35_HSI + CLK_UART6_HSI + CLK_UART78_HSI + CLK_SPDIF_PLL4P + CLK_FDCAN_PLL4Q + CLK_SAI1_PLL3Q + CLK_SAI2_PLL3Q + CLK_SAI3_PLL3Q + CLK_SAI4_PLL3Q + CLK_RNG1_LSI + CLK_RNG2_LSI + CLK_LPTIM1_PCLK1 + CLK_LPTIM23_PCLK3 + CLK_LPTIM45_LSE + >; + + /* VCO = 1300.0 MHz => P = 650 (CPU) */ + pll1: st,pll@0 { + cfg = < 2 80 0 0 0 PQR(1,0,0) >; + frac = < 0x800 >; + u-boot,dm-pre-reloc; + }; + + /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ + pll2: st,pll@1 { + cfg = < 2 65 1 0 0 PQR(1,1,1) >; + frac = < 0x1400 >; + u-boot,dm-pre-reloc; + }; + + /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */ + pll3: st,pll@2 { + cfg = < 1 33 1 16 36 PQR(1,1,1) >; + frac = < 0x1a04 >; + u-boot,dm-pre-reloc; + }; + + /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */ + pll4: st,pll@3 { + cfg = < 3 98 5 7 7 PQR(1,1,1) >; + u-boot,dm-pre-reloc; + }; +}; + +&sdmmc1 { + u-boot,dm-spl; +}; + +&sdmmc1_b4_pins_a { + u-boot,dm-spl; + pins { + u-boot,dm-spl; + }; +}; + +&uart4 { + u-boot,dm-pre-reloc; +}; + +&uart4_pins_a { + u-boot,dm-pre-reloc; + pins1 { + u-boot,dm-pre-reloc; + }; + pins2 { + u-boot,dm-pre-reloc; + }; +}; + +&usbotg_hs { + usb1600; + hnp-srp-disable; +}; + +&v3v3 { + regulator-always-on; +}; diff --git a/arch/arm/dts/stm32mp157a-dk1.dts b/arch/arm/dts/stm32mp157a-dk1.dts new file mode 100644 index 00000000000..0882765d0c9 --- /dev/null +++ b/arch/arm/dts/stm32mp157a-dk1.dts @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics. + */ + +/dts-v1/; + +#include "stm32mp157c.dtsi" +#include "stm32mp157-pinctrl.dtsi" +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/mfd/st,stpmic1.h> + +/ { + model = "STMicroelectronics STM32MP157A-DK1 Discovery Board"; + compatible = "st,stm32mp157a-dk1", "st,stm32mp157"; + + aliases { + ethernet0 = ðernet0; + serial0 = &uart4; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@c0000000 { + reg = <0xc0000000 0x20000000>; + }; + + led { + compatible = "gpio-leds"; + blue { + label = "heartbeat"; + gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + default-state = "off"; + }; + }; +}; + +ðernet0 { + status = "okay"; + pinctrl-0 = <ðernet0_rgmii_pins_a>; + pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; + pinctrl-names = "default", "sleep"; + phy-mode = "rgmii"; + max-speed = <1000>; + phy-handle = <&phy0>; + + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + phy0: ethernet-phy@0 { + reg = <0>; + }; + }; +}; + +&i2c4 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c4_pins_a>; + i2c-scl-rising-time-ns = <185>; + i2c-scl-falling-time-ns = <20>; + status = "okay"; + /delete-property/dmas; + /delete-property/dma-names; + + pmic: stpmic@33 { + compatible = "st,stpmic1"; + reg = <0x33>; + interrupt-controller; + #interrupt-cells = <2>; + status = "okay"; + + st,main-control-register = <0x04>; + st,vin-control-register = <0xc0>; + st,usb-control-register = <0x20>; + + regulators { + compatible = "st,stpmic1-regulators"; + + ldo1-supply = <&v3v3>; + ldo3-supply = <&vdd_ddr>; + ldo6-supply = <&v3v3>; + pwr_sw1-supply = <&bst_out>; + pwr_sw2-supply = <&bst_out>; + + vddcore: buck1 { + regulator-name = "vddcore"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-initial-mode = <0>; + regulator-over-current-protection; + }; + + vdd_ddr: buck2 { + regulator-name = "vdd_ddr"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-initial-mode = <0>; + regulator-over-current-protection; + }; + + vdd: buck3 { + regulator-name = "vdd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + st,mask-reset; + regulator-initial-mode = <0>; + regulator-over-current-protection; + }; + + v3v3: buck4 { + regulator-name = "v3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-over-current-protection; + regulator-initial-mode = <0>; + }; + + v1v8_audio: ldo1 { + regulator-name = "v1v8_audio"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + interrupts = <IT_CURLIM_LDO1 0>; + }; + + v3v3_hdmi: ldo2 { + regulator-name = "v3v3_hdmi"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + interrupts = <IT_CURLIM_LDO2 0>; + }; + + vtt_ddr: ldo3 { + regulator-name = "vtt_ddr"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <750000>; + regulator-always-on; + regulator-over-current-protection; + }; + + vdd_usb: ldo4 { + regulator-name = "vdd_usb"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + interrupts = <IT_CURLIM_LDO4 0>; + }; + + vdda: ldo5 { + regulator-name = "vdda"; + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + interrupts = <IT_CURLIM_LDO5 0>; + regulator-boot-on; + }; + + v1v2_hdmi: ldo6 { + regulator-name = "v1v2_hdmi"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + interrupts = <IT_CURLIM_LDO6 0>; + + }; + + vref_ddr: vref_ddr { + regulator-name = "vref_ddr"; + regulator-always-on; + regulator-over-current-protection; + }; + + bst_out: boost { + regulator-name = "bst_out"; + interrupts = <IT_OCP_BOOST 0>; + }; + + vbus_otg: pwr_sw1 { + regulator-name = "vbus_otg"; + interrupts = <IT_OCP_OTG 0>; + regulator-active-discharge; + }; + + vbus_sw: pwr_sw2 { + regulator-name = "vbus_sw"; + interrupts = <IT_OCP_SWOUT 0>; + regulator-active-discharge; + }; + }; + + onkey { + compatible = "st,stpmic1-onkey"; + interrupts = <IT_PONKEY_F 0>, <IT_PONKEY_R 1>; + interrupt-names = "onkey-falling", "onkey-rising"; + status = "okay"; + }; + + watchdog { + compatible = "st,stpmic1-wdt"; + status = "disabled"; + }; + }; +}; + +&iwdg2 { + timeout-sec = <32>; + status = "okay"; +}; + +&pwr { + pwr-supply = <&vdd>; +}; + +&rng1 { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&sdmmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc1_b4_pins_a>; + broken-cd; + st,neg-edge; + bus-width = <4>; + vmmc-supply = <&v3v3>; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_pins_a>; + status = "okay"; +}; + +&usbh_ehci { + phys = <&usbphyc_port0>; + phy-names = "usb"; + status = "okay"; +}; + +&usbphyc { + vdd3v3-supply = <&vdd_usb>; + status = "okay"; +}; + +&vrefbuf { + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + vdda-supply = <&vdd>; + status = "okay"; +}; diff --git a/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi new file mode 100644 index 00000000000..06ef3a4095f --- /dev/null +++ b/arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright : STMicroelectronics 2018 + */ + +#include "stm32mp157a-dk1-u-boot.dtsi" diff --git a/arch/arm/dts/stm32mp157c-dk2.dts b/arch/arm/dts/stm32mp157c-dk2.dts new file mode 100644 index 00000000000..9a81d2d4728 --- /dev/null +++ b/arch/arm/dts/stm32mp157c-dk2.dts @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics. + */ + +/dts-v1/; + +#include "stm32mp157a-dk1.dts" + +/ { + model = "STMicroelectronics STM32MP157C-DK2 Discovery Board"; + compatible = "st,stm32mp157c-dk2", "st,stm32mp157"; +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + phy-dsi-supply = <®18>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dsi_in: endpoint { + remote-endpoint = <<dc_ep1_out>; + }; + }; + + port@1 { + reg = <1>; + dsi_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; + + panel@0 { + compatible = "orisetech,otm8009a"; + reg = <0>; + reset-gpios = <&gpioe 4 GPIO_ACTIVE_LOW>; + status = "okay"; + + port { + panel_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + }; +}; + +<dc { + status = "okay"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + ltdc_ep1_out: endpoint@1 { + reg = <1>; + remote-endpoint = <&dsi_in>; + }; + }; +}; diff --git a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi index 70bbf667042..55f99037b26 100644 --- a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi @@ -9,9 +9,14 @@ / { aliases { + i2c3 = &i2c4; mmc0 = &sdmmc1; mmc1 = &sdmmc2; - i2c3 = &i2c4; + }; + + config { + st,fastboot-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; + st,stm32prog-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>; }; led { @@ -43,14 +48,8 @@ st,digbypass; }; -&uart4_pins_a { +&i2c4 { u-boot,dm-pre-reloc; - pins1 { - u-boot,dm-pre-reloc; - }; - pins2 { - u-boot,dm-pre-reloc; - }; }; &i2c4_pins_a { @@ -60,14 +59,6 @@ }; }; -&uart4 { - u-boot,dm-pre-reloc; -}; - -&i2c4 { - u-boot,dm-pre-reloc; -}; - &pmic { u-boot,dm-pre-reloc; }; @@ -165,8 +156,6 @@ }; }; -/* SPL part **************************************/ -/* MMC1 boot */ &sdmmc1_b4_pins_a { u-boot,dm-spl; pins { @@ -185,7 +174,6 @@ u-boot,dm-spl; }; -/* MMC2 boot */ &sdmmc2_b4_pins_a { u-boot,dm-spl; pins { @@ -203,3 +191,17 @@ &sdmmc2 { u-boot,dm-spl; }; + +&uart4 { + u-boot,dm-pre-reloc; +}; + +&uart4_pins_a { + u-boot,dm-pre-reloc; + pins1 { + u-boot,dm-pre-reloc; + }; + pins2 { + u-boot,dm-pre-reloc; + }; +}; diff --git a/arch/arm/dts/stm32mp157c-ed1.dts b/arch/arm/dts/stm32mp157c-ed1.dts index 7a9b742d364..2664c9ce904 100644 --- a/arch/arm/dts/stm32mp157c-ed1.dts +++ b/arch/arm/dts/stm32mp157c-ed1.dts @@ -8,20 +8,24 @@ #include "stm32mp157c.dtsi" #include "stm32mp157-pinctrl.dtsi" #include <dt-bindings/gpio/gpio.h> -#include <dt-bindings/mfd/st,stpmu1.h> +#include <dt-bindings/mfd/st,stpmic1.h> / { model = "STMicroelectronics STM32MP157C eval daughter"; compatible = "st,stm32mp157c-ed1", "st,stm32mp157"; chosen { - stdout-path = "serial3:115200n8"; + stdout-path = "serial0:115200n8"; }; memory@c0000000 { reg = <0xC0000000 0x40000000>; }; + aliases { + serial0 = &uart4; + }; + sd_switch: regulator-sd_switch { compatible = "regulator-gpio"; regulator-name = "sd_switch"; @@ -36,15 +40,8 @@ }; }; -&rng1 { - status = "okay"; -}; - -&timers6 { +&hwspinlock { status = "okay"; - timer@5 { - status = "okay"; - }; }; &i2c4 { @@ -54,8 +51,8 @@ i2c-scl-falling-time-ns = <20>; status = "okay"; - pmic: stpmu1@33 { - compatible = "st,stpmu1"; + pmic: stpmic1@33 { + compatible = "st,stpmic1"; reg = <0x33>; interrupts = <0 2>; interrupt-parent = <&gpioa>; @@ -68,7 +65,7 @@ st,usb_control_register = <0x30>; regulators { - compatible = "st,stpmu1-regulators"; + compatible = "st,stpmic1-regulators"; ldo1-supply = <&v3v3>; ldo2-supply = <&v3v3>; @@ -321,10 +318,27 @@ }; }; +&iwdg2 { + timeout-sec = <32>; + status = "okay"; +}; + +&pinctrl { + hwlocks = <&hwspinlock 0>; +}; + &pwr { pwr-supply = <&vdd>; }; +&rng1 { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + &sdmmc1 { pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>; broken-cd; @@ -355,6 +369,13 @@ status = "okay"; }; +&timers6 { + status = "okay"; + timer@5 { + status = "okay"; + }; +}; + &uart4 { pinctrl-names = "default"; pinctrl-0 = <&uart4_pins_a>; @@ -365,14 +386,6 @@ usb33d-supply = <&usb33>; }; -&hwspinlock { - status = "okay"; -}; - -&pinctrl { - hwlocks = <&hwspinlock 0>; -}; - &usbphyc_port0 { phy-supply = <&vdd_usb>; vdda1v1-supply = <®11>; diff --git a/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi index 30b173478c6..8b92b1fa2ee 100644 --- a/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi @@ -7,29 +7,23 @@ / { aliases { - spi0 = &qspi; + gpio26 = &stmfx_pinctrl; i2c1 = &i2c2; i2c4 = &i2c5; + pinctrl2 = &stmfx_pinctrl; + spi0 = &qspi; }; }; &flash0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; + u-boot,dm-spl; }; &flash1 { - compatible = "spi-flash"; -}; - -&v3v3 { - regulator-always-on; -}; - -&usbotg_hs { - g-tx-fifo-size = <576>; + compatible = "jedec,spi-nor"; }; -/* SPL part **************************************/ &qspi { u-boot,dm-spl; }; @@ -61,7 +55,10 @@ }; }; -&flash0 { - u-boot,dm-spl; +&usbotg_hs { + g-tx-fifo-size = <576>; }; +&v3v3 { + regulator-always-on; +}; diff --git a/arch/arm/dts/stm32mp157c-ev1.dts b/arch/arm/dts/stm32mp157c-ev1.dts index 902a42bee29..a6ee37924fe 100644 --- a/arch/arm/dts/stm32mp157c-ev1.dts +++ b/arch/arm/dts/stm32mp157c-ev1.dts @@ -11,6 +11,21 @@ model = "STMicroelectronics STM32MP157C eval daughter on eval mother"; compatible = "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", "st,stm32mp157"; + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + serial0 = &uart4; + ethernet0 = ðernet0; + }; + + panel_backlight: panel-backlight { + compatible = "gpio-backlight"; + gpios = <&gpiod 13 GPIO_ACTIVE_LOW>; + default-on; + status = "okay"; + }; }; &cec { @@ -19,12 +34,88 @@ status = "okay"; }; +&dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dsi_in: endpoint { + remote-endpoint = <<dc_ep0_out>; + }; + }; + + port@1 { + reg = <1>; + dsi_out: endpoint { + remote-endpoint = <&dsi_panel_in>; + }; + }; + }; + + panel-dsi@0 { + compatible = "raydium,rm68200"; + reg = <0>; + reset-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>; + backlight = <&panel_backlight>; + status = "okay"; + + port { + dsi_panel_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + }; +}; + +ðernet0 { + status = "okay"; + pinctrl-0 = <ðernet0_rgmii_pins_a>; + pinctrl-1 = <ðernet0_rgmii_pins_sleep_a>; + pinctrl-names = "default", "sleep"; + phy-mode = "rgmii"; + max-speed = <1000>; + phy-handle = <&phy0>; + + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + phy0: ethernet-phy@0 { + reg = <0>; + }; + }; +}; + &i2c2 { pinctrl-names = "default"; pinctrl-0 = <&i2c2_pins_a>; i2c-scl-rising-time-ns = <185>; i2c-scl-falling-time-ns = <20>; status = "okay"; + + stmfx: stmfx@42 { + compatible = "st,stmfx-0300"; + reg = <0x42>; + interrupts = <8 IRQ_TYPE_EDGE_RISING>; + interrupt-parent = <&gpioi>; + vdd-supply = <&v3v3>; + + stmfx_pinctrl: stmfx-pin-controller { + compatible = "st,stmfx-0300-pinctrl"; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&stmfx_pinctrl 0 0 24>; + status = "disabled"; + }; + }; }; &i2c5 { @@ -35,6 +126,26 @@ status = "okay"; }; +<dc { + status = "okay"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + ltdc_ep0_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&dsi_in>; + }; + }; +}; + +&m_can1 { + pinctrl-names = "default"; + pinctrl-0 = <&m_can1_pins_a>; + status = "okay"; +}; + &qspi { pinctrl-names = "default"; pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>; @@ -60,6 +171,12 @@ }; }; +&spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&spi1_pins_a>; + status = "disabled"; +}; + &timers2 { status = "disabled"; pwm { @@ -106,6 +223,7 @@ &usbotg_hs { pinctrl-names = "default"; pinctrl-0 = <&usbotg_hs_pins_a>; + dr_mode = "peripheral"; phys = <&usbphyc_port1 0>; phy-names = "usb2-phy"; status = "okay"; diff --git a/arch/arm/dts/stm32mp157c.dtsi b/arch/arm/dts/stm32mp157c.dtsi index 37cadfa30c9..7eb4bee31cf 100644 --- a/arch/arm/dts/stm32mp157c.dtsi +++ b/arch/arm/dts/stm32mp157c.dtsi @@ -29,7 +29,7 @@ }; psci { - compatible = "arm,psci"; + compatible = "arm,psci-1.0"; method = "smc"; cpu_off = <0x84000002>; cpu_on = <0x84000003>; @@ -106,26 +106,6 @@ }; }; - pm_domain { - #address-cells = <1>; - #size-cells = <0>; - compatible = "st,stm32mp157c-pd"; - - pd_core_ret: core-ret-power-domain@1 { - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - #power-domain-cells = <0>; - label = "CORE-RETENTION"; - - pd_core: core-power-domain@2 { - reg = <2>; - #power-domain-cells = <0>; - label = "CORE"; - }; - }; - }; - soc { compatible = "simple-bus"; #address-cells = <1>; @@ -339,6 +319,34 @@ }; }; + spi2: spi@4000b000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32h7-spi"; + reg = <0x4000b000 0x400>; + interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc SPI2_K>; + resets = <&rcc SPI2_R>; + dmas = <&dmamux1 39 0x400 0x05>, + <&dmamux1 40 0x400 0x05>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + spi3: spi@4000c000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32h7-spi"; + reg = <0x4000c000 0x400>; + interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc SPI3_K>; + resets = <&rcc SPI3_R>; + dmas = <&dmamux1 61 0x400 0x05>, + <&dmamux1 62 0x400 0x05>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + usart2: serial@4000e000 { compatible = "st,stm32h7-uart"; reg = <0x4000e000 0x400>; @@ -522,6 +530,34 @@ status = "disabled"; }; + spi1: spi@44004000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32h7-spi"; + reg = <0x44004000 0x400>; + interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc SPI1_K>; + resets = <&rcc SPI1_R>; + dmas = <&dmamux1 37 0x400 0x05>, + <&dmamux1 38 0x400 0x05>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + spi4: spi@44005000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32h7-spi"; + reg = <0x44005000 0x400>; + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc SPI4_K>; + resets = <&rcc SPI4_R>; + dmas = <&dmamux1 83 0x400 0x05>, + <&dmamux1 84 0x400 0x05>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + timers15: timer@44006000 { #address-cells = <1>; #size-cells = <0>; @@ -584,6 +620,116 @@ }; }; + spi5: spi@44009000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32h7-spi"; + reg = <0x44009000 0x400>; + interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc SPI5_K>; + resets = <&rcc SPI5_R>; + dmas = <&dmamux1 85 0x400 0x05>, + <&dmamux1 86 0x400 0x05>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + dfsdm: dfsdm@4400d000 { + compatible = "st,stm32mp1-dfsdm"; + reg = <0x4400d000 0x800>; + clocks = <&rcc DFSDM_K>; + clock-names = "dfsdm"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + dfsdm0: filter@0 { + compatible = "st,stm32-dfsdm-adc"; + #io-channel-cells = <1>; + reg = <0>; + interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&dmamux1 101 0x400 0x01>; + dma-names = "rx"; + status = "disabled"; + }; + + dfsdm1: filter@1 { + compatible = "st,stm32-dfsdm-adc"; + #io-channel-cells = <1>; + reg = <1>; + interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&dmamux1 102 0x400 0x01>; + dma-names = "rx"; + status = "disabled"; + }; + + dfsdm2: filter@2 { + compatible = "st,stm32-dfsdm-adc"; + #io-channel-cells = <1>; + reg = <2>; + interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&dmamux1 103 0x400 0x01>; + dma-names = "rx"; + status = "disabled"; + }; + + dfsdm3: filter@3 { + compatible = "st,stm32-dfsdm-adc"; + #io-channel-cells = <1>; + reg = <3>; + interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&dmamux1 104 0x400 0x01>; + dma-names = "rx"; + status = "disabled"; + }; + + dfsdm4: filter@4 { + compatible = "st,stm32-dfsdm-adc"; + #io-channel-cells = <1>; + reg = <4>; + interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&dmamux1 91 0x400 0x01>; + dma-names = "rx"; + status = "disabled"; + }; + + dfsdm5: filter@5 { + compatible = "st,stm32-dfsdm-adc"; + #io-channel-cells = <1>; + reg = <5>; + interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&dmamux1 92 0x400 0x01>; + dma-names = "rx"; + status = "disabled"; + }; + }; + + m_can1: can@4400e000 { + compatible = "bosch,m_can"; + reg = <0x4400e000 0x400>, <0x44011000 0x2800>; + reg-names = "m_can", "message_ram"; + interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "int0", "int1"; + clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>; + clock-names = "hclk", "cclk"; + bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>; + status = "disabled"; + }; + + m_can2: can@4400f000 { + compatible = "bosch,m_can"; + reg = <0x4400f000 0x400>, <0x44011000 0x2800>; + reg-names = "m_can", "message_ram"; + interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "int0", "int1"; + clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>; + clock-names = "hclk", "cclk"; + bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>; + status = "disabled"; + }; + dma1: dma@48000000 { compatible = "st,stm32-dma"; reg = <0x48000000 0x400>; @@ -647,6 +793,8 @@ reg = <0x0>; interrupt-parent = <&adc>; interrupts = <0>; + dmas = <&dmamux1 9 0x400 0x01>; + dma-names = "rx"; status = "disabled"; }; @@ -656,6 +804,8 @@ reg = <0x100>; interrupt-parent = <&adc>; interrupts = <1>; + dmas = <&dmamux1 10 0x400 0x01>; + dma-names = "rx"; status = "disabled"; }; }; @@ -675,7 +825,7 @@ }; usbotg_hs: usb-otg@49000000 { - compatible = "st,stm32mp1-hsotg", "snps,dwc2"; + compatible = "snps,dwc2"; reg = <0x49000000 0x10000>; clocks = <&rcc USBO_K>; clock-names = "otg"; @@ -686,7 +836,6 @@ g-np-tx-fifo-size = <32>; g-tx-fifo-size = <128 128 64 64 64 64 32 32>; dr_mode = "otg"; - power-domains = <&pd_core>; status = "disabled"; }; @@ -753,8 +902,8 @@ reg = <0x5000d000 0x400>; }; - syscfg: system-config@50020000 { - compatible = "st,stm32-syscfg", "syscon"; + syscfg: syscon@50020000 { + compatible = "st,stm32mp157-syscfg", "syscon"; reg = <0x50020000 0x400>; }; @@ -853,6 +1002,18 @@ status = "disabled"; }; + hash1: hash@54002000 { + compatible = "st,stm32f756-hash"; + reg = <0x54002000 0x400>; + interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc HASH1>; + resets = <&rcc HASH1_R>; + dmas = <&mdma1 31 0x10 0x1000A02 0x0 0x0>; + dma-names = "in"; + dma-maxburst = <2>; + status = "disabled"; + }; + rng1: rng@54003000 { compatible = "st,stm32-rng"; reg = <0x54003000 0x400>; @@ -871,7 +1032,7 @@ dma-requests = <48>; }; - qspi: qspi@58003000 { + qspi: spi@58003000 { compatible = "st,stm32f469-qspi"; reg = <0x58003000 0x1000>, <0x70000000 0x10000000>; reg-names = "qspi", "qspi_mm"; @@ -915,6 +1076,36 @@ status = "disabled"; }; + stmmac_axi_config_0: stmmac-axi-config { + snps,wr_osr_lmt = <0x7>; + snps,rd_osr_lmt = <0x7>; + snps,blen = <0 0 0 0 16 8 4>; + }; + + ethernet0: ethernet@5800a000 { + compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; + reg = <0x5800a000 0x2000>; + reg-names = "stmmaceth"; + interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "macirq"; + clock-names = "stmmaceth", + "mac-clk-tx", + "mac-clk-rx", + "ethstp", + "syscfg-clk"; + clocks = <&rcc ETHMAC>, + <&rcc ETHTX>, + <&rcc ETHRX>, + <&rcc ETHSTP>, + <&rcc SYSCFG>; + st,syscon = <&syscfg 0x4>; + snps,mixed-burst; + snps,pbl = <2>; + snps,axi-config = <&stmmac_axi_config_0>; + snps,tso; + status = "disabled"; + }; + usbh_ohci: usbh-ohci@5800c000 { compatible = "generic-ohci"; reg = <0x5800c000 0x1000>; @@ -955,6 +1146,14 @@ status = "disabled"; }; + iwdg2: watchdog@5a002000 { + compatible = "st,stm32mp1-iwdg"; + reg = <0x5a002000 0x400>; + clocks = <&rcc IWDG2>, <&rcc CK_LSI>; + clock-names = "pclk", "lsi"; + status = "disabled"; + }; + usbphyc: usbphyc@5a006000 { #address-cells = <1>; #size-cells = <0>; @@ -983,6 +1182,20 @@ status = "disabled"; }; + spi6: spi@5c001000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32h7-spi"; + reg = <0x5c001000 0x400>; + interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc SPI6_K>; + resets = <&rcc SPI6_R>; + dmas = <&mdma1 34 0x0 0x40008 0x0 0x0>, + <&mdma1 35 0x0 0x40002 0x0 0x0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + i2c4: i2c@5c002000 { compatible = "st,stm32f7-i2c"; reg = <0x5c002000 0x400>; @@ -996,6 +1209,22 @@ status = "disabled"; }; + rtc: rtc@5c004000 { + compatible = "st,stm32mp1-rtc"; + reg = <0x5c004000 0x400>; + clocks = <&rcc RTCAPB>, <&rcc RTC>; + clock-names = "pclk", "rtc_ck"; + interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + bsec: nvmem@5c005000 { + compatible = "st,stm32mp15-bsec"; + reg = <0x5c005000 0x400>; + #address-cells = <1>; + #size-cells = <1>; + }; + i2c6: i2c@5c009000 { compatible = "st,stm32f7-i2c"; reg = <0x5c009000 0x400>; diff --git a/arch/arm/dts/stv0991.dts b/arch/arm/dts/stv0991.dts index 98bd5dfc70f..b04e89971c7 100644 --- a/arch/arm/dts/stv0991.dts +++ b/arch/arm/dts/stv0991.dts @@ -40,7 +40,7 @@ flash0: n25q32@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; /* chip select */ spi-max-frequency = <50000000>; m25p,fast-read; diff --git a/arch/arm/dts/sun50i-a64-oceanic-5205-5inmfd.dts b/arch/arm/dts/sun50i-a64-oceanic-5205-5inmfd.dts new file mode 100644 index 00000000000..6a2154525d1 --- /dev/null +++ b/arch/arm/dts/sun50i-a64-oceanic-5205-5inmfd.dts @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2019 Oceanic Systems (UK) Ltd. + * Copyright (C) 2019 Amarula Solutions B.V. + * Author: Jagan Teki <jagan@amarulasolutions.com> + */ + +/dts-v1/; + +#include "sun50i-a64-sopine.dtsi" + +/ { + model = "Oceanic 5205 5inMFD"; + compatible = "oceanic,5205-5inmfd", "allwinner,sun50i-a64"; + + aliases { + ethernet0 = &emac; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&emac { + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + phy-mode = "rgmii"; + phy-handle = <&ext_rgmii_phy>; + phy-supply = <®_dc1sw>; + allwinner,tx-delay-ps = <600>; + status = "okay"; +}; + +&mdio { + ext_rgmii_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; +}; + +&ohci0 { + status = "okay"; +}; + +®_dc1sw { + regulator-name = "vcc-phy"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pb_pins>; + status = "okay"; +}; + +&usb_otg { + dr_mode = "host"; + status = "okay"; +}; + +&usbphy { + status = "okay"; +}; diff --git a/arch/arm/dts/zynq-zed.dts b/arch/arm/dts/zynq-zed.dts index d2b7fc2c994..7a540b63f47 100644 --- a/arch/arm/dts/zynq-zed.dts +++ b/arch/arm/dts/zynq-zed.dts @@ -53,7 +53,7 @@ status = "okay"; num-cs = <1>; flash@0 { - compatible = "spansion,s25fl256s", "spi-flash"; + compatible = "spansion,s25fl256s", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <30000000>; m25p,fast-read; diff --git a/arch/arm/dts/zynqmp-zc1232-revA.dts b/arch/arm/dts/zynqmp-zc1232-revA.dts index 5c212ba468e..6117f83c474 100644 --- a/arch/arm/dts/zynqmp-zc1232-revA.dts +++ b/arch/arm/dts/zynqmp-zc1232-revA.dts @@ -41,7 +41,7 @@ &qspi { status = "okay"; flash@0 { - compatible = "m25p80", "spi-flash"; /* 32MB FIXME */ + compatible = "m25p80", "jedec,spi-nor"; /* 32MB FIXME */ #address-cells = <1>; #size-cells = <1>; reg = <0x0>; diff --git a/arch/arm/dts/zynqmp-zc1254-revA.dts b/arch/arm/dts/zynqmp-zc1254-revA.dts index 881aacc5825..6ac8346d23d 100644 --- a/arch/arm/dts/zynqmp-zc1254-revA.dts +++ b/arch/arm/dts/zynqmp-zc1254-revA.dts @@ -41,7 +41,7 @@ &qspi { status = "okay"; flash@0 { - compatible = "m25p80", "spi-flash"; /* 32MB */ + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ #address-cells = <1>; #size-cells = <1>; reg = <0x0>; diff --git a/arch/arm/dts/zynqmp-zc1275-revA.dts b/arch/arm/dts/zynqmp-zc1275-revA.dts index 7403f153e44..82c30a3fbef 100644 --- a/arch/arm/dts/zynqmp-zc1275-revA.dts +++ b/arch/arm/dts/zynqmp-zc1275-revA.dts @@ -41,7 +41,7 @@ &qspi { status = "okay"; flash@0 { - compatible = "m25p80", "spi-flash"; /* 32MB */ + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ #address-cells = <1>; #size-cells = <1>; reg = <0x0>; diff --git a/arch/arm/dts/zynqmp-zc1275-revB.dts b/arch/arm/dts/zynqmp-zc1275-revB.dts index 1a7975b551d..0473503afaf 100644 --- a/arch/arm/dts/zynqmp-zc1275-revB.dts +++ b/arch/arm/dts/zynqmp-zc1275-revB.dts @@ -42,7 +42,7 @@ &qspi { status = "okay"; flash@0 { - compatible = "m25p80", "spi-flash"; /* 32MB */ + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ #address-cells = <1>; #size-cells = <1>; reg = <0x0>; diff --git a/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts b/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts index 9768dfe0446..8824f5cc027 100644 --- a/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts +++ b/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts @@ -101,7 +101,7 @@ &qspi { status = "okay"; flash@0 { - compatible = "m25p80", "spi-flash"; /* Micron MT25QU512ABB8ESF */ + compatible = "m25p80", "jedec,spi-nor"; /* Micron MT25QU512ABB8ESF */ #address-cells = <1>; #size-cells = <1>; reg = <0x0>; diff --git a/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts b/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts index 9afbbb63b49..84c2904dc20 100644 --- a/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts +++ b/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts @@ -180,7 +180,7 @@ &qspi { status = "okay"; flash@0 { - compatible = "m25p80", "spi-flash"; /* 32MB */ + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ #address-cells = <1>; #size-cells = <1>; reg = <0x0>; diff --git a/arch/arm/dts/zynqmp-zcu102-revA.dts b/arch/arm/dts/zynqmp-zcu102-revA.dts index 0e96a361882..6e228717131 100644 --- a/arch/arm/dts/zynqmp-zcu102-revA.dts +++ b/arch/arm/dts/zynqmp-zcu102-revA.dts @@ -521,7 +521,7 @@ status = "okay"; is-dual = <1>; flash@0 { - compatible = "m25p80", "spi-flash"; /* 32MB */ + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ #address-cells = <1>; #size-cells = <1>; reg = <0x0>; diff --git a/arch/arm/dts/zynqmp-zcu104-revA.dts b/arch/arm/dts/zynqmp-zcu104-revA.dts index 431dff52fe6..c7a3cdcf61d 100644 --- a/arch/arm/dts/zynqmp-zcu104-revA.dts +++ b/arch/arm/dts/zynqmp-zcu104-revA.dts @@ -169,7 +169,7 @@ &qspi { status = "okay"; flash@0 { - compatible = "m25p80", "spi-flash"; /* n25q512a 128MiB */ + compatible = "m25p80", "jedec,spi-nor"; /* n25q512a 128MiB */ #address-cells = <1>; #size-cells = <1>; reg = <0x0>; diff --git a/arch/arm/dts/zynqmp-zcu104-revC.dts b/arch/arm/dts/zynqmp-zcu104-revC.dts index 623d2c96cda..7df16b047ce 100644 --- a/arch/arm/dts/zynqmp-zcu104-revC.dts +++ b/arch/arm/dts/zynqmp-zcu104-revC.dts @@ -176,7 +176,7 @@ &qspi { status = "okay"; flash@0 { - compatible = "m25p80", "spi-flash"; /* n25q512a 128MiB */ + compatible = "m25p80", "jedec,spi-nor"; /* n25q512a 128MiB */ #address-cells = <1>; #size-cells = <1>; reg = <0x0>; diff --git a/arch/arm/dts/zynqmp-zcu106-revA.dts b/arch/arm/dts/zynqmp-zcu106-revA.dts index 00f6e30ef34..9fd3953fb44 100644 --- a/arch/arm/dts/zynqmp-zcu106-revA.dts +++ b/arch/arm/dts/zynqmp-zcu106-revA.dts @@ -495,7 +495,7 @@ status = "okay"; is-dual = <1>; flash@0 { - compatible = "m25p80", "spi-flash"; /* 32MB */ + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ #address-cells = <1>; #size-cells = <1>; reg = <0x0>; diff --git a/arch/arm/dts/zynqmp-zcu111-revA.dts b/arch/arm/dts/zynqmp-zcu111-revA.dts index 58021be9bfd..2e28a3934fd 100644 --- a/arch/arm/dts/zynqmp-zcu111-revA.dts +++ b/arch/arm/dts/zynqmp-zcu111-revA.dts @@ -432,7 +432,7 @@ status = "okay"; is-dual = <1>; flash@0 { - compatible = "m25p80", "spi-flash"; /* 32MB */ + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ #address-cells = <1>; #size-cells = <1>; reg = <0x0>; diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h index 4baba38b004..8c916e8c752 100644 --- a/arch/arm/include/asm/arch-sunxi/spl.h +++ b/arch/arm/include/asm/arch-sunxi/spl.h @@ -28,6 +28,8 @@ #define SUNXI_BOOTED_FROM_NAND 1 #define SUNXI_BOOTED_FROM_MMC2 2 #define SUNXI_BOOTED_FROM_SPI 3 +#define SUNXI_BOOTED_FROM_MMC0_HIGH 0x10 +#define SUNXI_BOOTED_FROM_MMC2_HIGH 0x12 /* boot head definition from sun4i boot code */ struct boot_file_head { diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h index 3039e66bf9f..992a84152cf 100644 --- a/arch/arm/include/asm/gpio.h +++ b/arch/arm/include/asm/gpio.h @@ -1,5 +1,6 @@ #if !defined(CONFIG_ARCH_UNIPHIER) && !defined(CONFIG_ARCH_STI) && \ - !defined(CONFIG_ARCH_K3) + !defined(CONFIG_ARCH_K3) && !defined(CONFIG_ARCH_BCM6858) && \ + !defined(CONFIG_ARCH_BCM63158) #include <asm/arch/gpio.h> #endif #include <asm-generic/gpio.h> diff --git a/arch/arm/mach-kirkwood/cpu.c b/arch/arm/mach-kirkwood/cpu.c index d54de53f31d..8f8e3003854 100644 --- a/arch/arm/mach-kirkwood/cpu.c +++ b/arch/arm/mach-kirkwood/cpu.c @@ -46,69 +46,31 @@ unsigned int kw_winctrl_calcsize(unsigned int sizeval) return (0x0000ffff & j); } -/* - * kw_config_adr_windows - Configure address Windows - * - * There are 8 address windows supported by Kirkwood Soc to addess different - * devices. Each window can be configured for size, BAR and remap addr - * Below configuration is standard for most of the cases - * - * If remap function not used, remap_lo must be set as base - * - * Reference Documentation: - * Mbus-L to Mbus Bridge Registers Configuration. - * (Sec 25.1 and 25.3 of Datasheet) - */ -int kw_config_adr_windows(void) -{ - struct kwwin_registers *winregs = - (struct kwwin_registers *)KW_CPU_WIN_BASE; - +static struct mbus_win windows[] = { /* Window 0: PCIE MEM address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 256, KWCPU_TARGET_PCIE, - KWCPU_ATTR_PCIE_MEM, KWCPU_WIN_ENABLE), &winregs[0].ctrl); - - writel(KW_DEFADR_PCI_MEM, &winregs[0].base); - writel(KW_DEFADR_PCI_MEM, &winregs[0].remap_lo); - writel(0x0, &winregs[0].remap_hi); + { KW_DEFADR_PCI_MEM, 1024 * 1024 * 256, + KWCPU_TARGET_PCIE, KWCPU_ATTR_PCIE_MEM }, /* Window 1: PCIE IO address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_PCIE, - KWCPU_ATTR_PCIE_IO, KWCPU_WIN_ENABLE), &winregs[1].ctrl); - writel(KW_DEFADR_PCI_IO, &winregs[1].base); - writel(KW_DEFADR_PCI_IO_REMAP, &winregs[1].remap_lo); - writel(0x0, &winregs[1].remap_hi); + { KW_DEFADR_PCI_IO, 1024 * 64, + KWCPU_TARGET_PCIE, KWCPU_ATTR_PCIE_IO }, /* Window 2: NAND Flash address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, - KWCPU_ATTR_NANDFLASH, KWCPU_WIN_ENABLE), &winregs[2].ctrl); - writel(KW_DEFADR_NANDF, &winregs[2].base); - writel(KW_DEFADR_NANDF, &winregs[2].remap_lo); - writel(0x0, &winregs[2].remap_hi); + { KW_DEFADR_NANDF, 1024 * 1024 * 128, + KWCPU_TARGET_MEMORY, KWCPU_ATTR_NANDFLASH }, /* Window 3: SPI Flash address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, - KWCPU_ATTR_SPIFLASH, KWCPU_WIN_ENABLE), &winregs[3].ctrl); - writel(KW_DEFADR_SPIF, &winregs[3].base); - writel(KW_DEFADR_SPIF, &winregs[3].remap_lo); - writel(0x0, &winregs[3].remap_hi); + { KW_DEFADR_SPIF, 1024 * 1024 * 128, + KWCPU_TARGET_MEMORY, KWCPU_ATTR_SPIFLASH }, /* Window 4: BOOT Memory address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 1024 * 128, KWCPU_TARGET_MEMORY, - KWCPU_ATTR_BOOTROM, KWCPU_WIN_ENABLE), &winregs[4].ctrl); - writel(KW_DEFADR_BOOTROM, &winregs[4].base); + { KW_DEFADR_BOOTROM, 1024 * 1024 * 128, + KWCPU_TARGET_MEMORY, KWCPU_ATTR_BOOTROM }, /* Window 5: Security SRAM address space */ - writel(KWCPU_WIN_CTRL_DATA(1024 * 64, KWCPU_TARGET_SASRAM, - KWCPU_ATTR_SASRAM, KWCPU_WIN_ENABLE), &winregs[5].ctrl); - writel(KW_DEFADR_SASRAM, &winregs[5].base); - - /* Window 6-7: Disabled */ - writel(KWCPU_WIN_DISABLE, &winregs[6].ctrl); - writel(KWCPU_WIN_DISABLE, &winregs[7].ctrl); - - return 0; -} + { KW_DEFADR_SASRAM, 1024 * 64, + KWCPU_TARGET_SASRAM, KWCPU_ATTR_SASRAM }, +}; /* * SYSRSTn Duration Counter Support @@ -221,15 +183,13 @@ int arch_cpu_init(void) struct kwcpu_registers *cpureg = (struct kwcpu_registers *)KW_CPU_REG_BASE; - /* Linux expects` the internal registers to be at 0xf1000000 */ + /* Linux expects the internal registers to be at 0xf1000000 */ writel(KW_REGS_PHY_BASE, KW_OFFSET_REG); /* Enable and invalidate L2 cache in write through mode */ writel(readl(&cpureg->l2_cfg) | 0x18, &cpureg->l2_cfg); invalidate_l2_cache(); - kw_config_adr_windows(); - #ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8 /* * Configures the I/O voltage of the pads connected to Egigabit @@ -291,11 +251,13 @@ int arch_misc_init(void) temp |= (1 << 22); writefr_extra_feature_reg(temp); - icache_enable(); /* Change reset vector to address 0x0 */ temp = get_cr(); set_cr(temp & ~CR_V); + /* Configure mbus windows */ + mvebu_mbus_probe(windows, ARRAY_SIZE(windows)); + /* checks and execute resset to factory event */ kw_sysrst_check(); diff --git a/arch/arm/mach-kirkwood/include/mach/cpu.h b/arch/arm/mach-kirkwood/include/mach/cpu.h index 91d21518d85..ea42182cf9c 100644 --- a/arch/arm/mach-kirkwood/include/mach/cpu.h +++ b/arch/arm/mach-kirkwood/include/mach/cpu.h @@ -63,12 +63,18 @@ enum kwcpu_attrib { */ #define KW_DEFADR_PCI_MEM 0x90000000 #define KW_DEFADR_PCI_IO 0xC0000000 -#define KW_DEFADR_PCI_IO_REMAP 0xC0000000 #define KW_DEFADR_SASRAM 0xC8010000 #define KW_DEFADR_NANDF 0xD8000000 #define KW_DEFADR_SPIF 0xE8000000 #define KW_DEFADR_BOOTROM 0xF8000000 +struct mbus_win { + u32 base; + u32 size; + u8 target; + u8 attr; +}; + /* * read feroceon/sheeva core extra feature register * using co-proc instruction @@ -135,13 +141,16 @@ struct kwgpio_registers { u32 irq_level; }; +/* Needed for dynamic (board-specific) mbus configuration */ +extern struct mvebu_mbus_state mbus_state; + /* * functions */ unsigned int mvebu_sdram_bar(enum memory_bank bank); unsigned int mvebu_sdram_bs(enum memory_bank bank); void mvebu_sdram_size_adjust(enum memory_bank bank); -int kw_config_adr_windows(void); +int mvebu_mbus_probe(struct mbus_win windows[], int count); void mvebu_config_gpio(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val, unsigned int gpp0_oe, unsigned int gpp1_oe); int kw_config_mpp(unsigned int mpp0_7, unsigned int mpp8_15, diff --git a/arch/arm/mach-kirkwood/include/mach/soc.h b/arch/arm/mach-kirkwood/include/mach/soc.h index 227707ae4c9..1d7f2828cd3 100644 --- a/arch/arm/mach-kirkwood/include/mach/soc.h +++ b/arch/arm/mach-kirkwood/include/mach/soc.h @@ -31,7 +31,7 @@ #define KW_RTC_BASE (KW_REGISTER(0x10300)) #define KW_NANDF_BASE (KW_REGISTER(0x10418)) #define MVEBU_SPI_BASE (KW_REGISTER(0x10600)) -#define KW_CPU_WIN_BASE (KW_REGISTER(0x20000)) +#define MVEBU_CPU_WIN_BASE (KW_REGISTER(0x20000)) #define KW_CPU_REG_BASE (KW_REGISTER(0x20100)) #define MVEBU_TIMER_BASE (KW_REGISTER(0x20300)) #define KW_REG_PCIE_BASE (KW_REGISTER(0x40000)) diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 7dda04e0e34..f5fd60d7845 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -9,10 +9,10 @@ config ARMADA_32BIT select ARCH_MISC_INIT select BOARD_EARLY_INIT_F select CPU_V7A - select SPL_DM - select SPL_DM_SEQ_ALIAS - select SPL_OF_CONTROL - select SPL_SIMPLE_BUS + select SPL_DM if SPL + select SPL_DM_SEQ_ALIAS if SPL + select SPL_OF_CONTROL if SPL + select SPL_SIMPLE_BUS if SPL select SUPPORT_SPL config ARMADA_64BIT @@ -46,7 +46,7 @@ config ARMADA_8K # Armada PLL frequency (used for NAND clock generation) config SYS_MVEBU_PLL_CLOCK int - default "2000000000" if ARMADA_XP || ARMADA_3700 || ARMADA_8K + default "2000000000" if ARMADA_XP || ARMADA_3700 || ARMADA_8K || ARMADA_MSYS default "1000000000" if ARMADA_38X || ARMADA_375 # Armada XP/38x SoC types... @@ -63,6 +63,22 @@ config MV78460 bool select ARMADA_XP +config ARMADA_MSYS + bool + select ARMADA_32BIT + +config 98DX4251 + bool + select ARMADA_MSYS + +config 98DX3336 + bool + select ARMADA_MSYS + +config 98DX3236 + bool + select ARMADA_MSYS + config 88F6820 bool select ARMADA_38X @@ -136,6 +152,10 @@ config TARGET_X530 bool "Support Allied Telesis x530" select 88F6820 +config TARGET_DB_XC3_24G4XG + bool "Support DB-XC3-24G4XG" + select 98DX3336 + endchoice config SYS_BOARD @@ -154,6 +174,7 @@ config SYS_BOARD default "theadorable" if TARGET_THEADORABLE default "a38x" if TARGET_CONTROLCENTERDC default "x530" if TARGET_X530 + default "db-xc3-24g4xg" if TARGET_DB_XC3_24G4XG config SYS_CONFIG_NAME default "clearfog" if TARGET_CLEARFOG @@ -171,6 +192,7 @@ config SYS_CONFIG_NAME default "turris_mox" if TARGET_TURRIS_MOX default "controlcenterdc" if TARGET_CONTROLCENTERDC default "x530" if TARGET_X530 + default "db-xc3-24g4xg" if TARGET_DB_XC3_24G4XG config SYS_VENDOR default "Marvell" if TARGET_DB_MV784MP_GP @@ -179,6 +201,8 @@ config SYS_VENDOR default "Marvell" if TARGET_DB_88F6820_GP default "Marvell" if TARGET_DB_88F6820_AMC default "Marvell" if TARGET_MVEBU_ARMADA_8K + default "Marvell" if TARGET_DB_XC3_24G4XG + default "Marvell" if TARGET_MVEBU_DB_88F7040 default "solidrun" if TARGET_CLEARFOG default "kobol" if TARGET_HELIOS4 default "Synology" if TARGET_DS414 diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index ee2eca91348..02d3ce27ee7 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile @@ -14,6 +14,7 @@ ifdef CONFIG_KIRKWOOD obj-y = dram.o obj-y += gpio.o +obj-y += mbus.o obj-y += timer.o else # CONFIG_KIRKWOOD @@ -24,6 +25,7 @@ ifndef CONFIG_SPL_BUILD obj-$(CONFIG_ARMADA_375) += ../../../drivers/ddr/marvell/axp/xor.o obj-$(CONFIG_ARMADA_38X) += ../../../drivers/ddr/marvell/a38x/xor.o obj-$(CONFIG_ARMADA_XP) += ../../../drivers/ddr/marvell/axp/xor.o +obj-$(CONFIG_ARMADA_MSYS) += ../../../drivers/ddr/marvell/axp/xor.o obj-$(CONFIG_MVEBU_EFUSE) += efuse.o extra-y += kwbimage.cfg diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c index 919d05c88c7..c5b3df46aab 100644 --- a/arch/arm/mach-mvebu/cpu.c +++ b/arch/arm/mach-mvebu/cpu.c @@ -23,6 +23,11 @@ static struct mbus_win windows[] = { /* NOR */ { MBUS_BOOTROM_BASE, MBUS_BOOTROM_SIZE, CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_BOOTROM }, + +#ifdef CONFIG_ARMADA_MSYS + /* DFX */ + { MBUS_DFX_BASE, MBUS_DFX_SIZE, CPU_TARGET_DFX, 0 }, +#endif }; void lowlevel_init(void) @@ -121,6 +126,14 @@ static const struct sar_freq_modes sar_freq_tab[] = { { 0x13, 0x0, 2000, 1000, 933 }, { 0xff, 0xff, 0, 0, 0 } /* 0xff marks end of array */ }; +#elif defined(CONFIG_ARMADA_MSYS) +static const struct sar_freq_modes sar_freq_tab[] = { + { 0x0, 0x0, 400, 400, 400 }, + { 0x2, 0x0, 667, 333, 667 }, + { 0x3, 0x0, 800, 400, 800 }, + { 0x5, 0x0, 800, 400, 800 }, + { 0xff, 0xff, 0, 0, 0 } /* 0xff marks end of array */ +}; #else /* SAR frequency values for Armada XP */ static const struct sar_freq_modes sar_freq_tab[] = { @@ -144,7 +157,7 @@ void get_sar_freq(struct sar_freq_modes *sar_freq) u32 freq; int i; -#if defined(CONFIG_ARMADA_375) +#if defined(CONFIG_ARMADA_375) || defined(CONFIG_ARMADA_MSYS) val = readl(CONFIG_SAR2_REG); /* SAR - Sample At Reset */ #else val = readl(CONFIG_SAR_REG); /* SAR - Sample At Reset */ @@ -160,7 +173,7 @@ void get_sar_freq(struct sar_freq_modes *sar_freq) #endif for (i = 0; sar_freq_tab[i].val != 0xff; i++) { if (sar_freq_tab[i].val == freq) { -#if defined(CONFIG_ARMADA_375) || defined(CONFIG_ARMADA_38X) +#if defined(CONFIG_ARMADA_375) || defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_MSYS) *sar_freq = sar_freq_tab[i]; return; #else @@ -270,6 +283,20 @@ int print_cpuinfo(void) } } + if (mvebu_soc_family() == MVEBU_SOC_MSYS) { + switch (revid) { + case 3: + puts("A0"); + break; + case 4: + puts("A1"); + break; + default: + printf("?? (%x)", revid); + break; + } + } + get_sar_freq(&sar_freq); printf(" at %d MHz\n", sar_freq.p_clk); @@ -472,6 +499,8 @@ u32 mvebu_get_nand_clock(void) if (mvebu_soc_family() == MVEBU_SOC_A38X) reg = MVEBU_DFX_DIV_CLK_CTRL(1); + else if (mvebu_soc_family() == MVEBU_SOC_MSYS) + reg = MVEBU_DFX_DIV_CLK_CTRL(8); else reg = MVEBU_CORE_DIV_CLK_CTRL(1); @@ -501,7 +530,6 @@ int board_mmc_init(bd_t *bis) } #endif -#ifdef CONFIG_SCSI_AHCI_PLAT #define AHCI_VENDOR_SPECIFIC_0_ADDR 0xa0 #define AHCI_VENDOR_SPECIFIC_0_DATA 0xa4 @@ -545,11 +573,19 @@ static void ahci_mvebu_regret_option(void __iomem *base) writel(0x80, base + AHCI_VENDOR_SPECIFIC_0_DATA); } -void scsi_init(void) +int board_ahci_enable(void) { - printf("MVEBU SATA INIT\n"); ahci_mvebu_mbus_config((void __iomem *)MVEBU_SATA0_BASE); ahci_mvebu_regret_option((void __iomem *)MVEBU_SATA0_BASE); + + return 0; +} + +#ifdef CONFIG_SCSI_AHCI_PLAT +void scsi_init(void) +{ + printf("MVEBU SATA INIT\n"); + board_ahci_enable(); ahci_init((void __iomem *)MVEBU_SATA0_BASE); } #endif diff --git a/arch/arm/mach-mvebu/include/mach/config.h b/arch/arm/mach-mvebu/include/mach/config.h index 71c4f70efc9..bbcfcfd1419 100644 --- a/arch/arm/mach-mvebu/include/mach/config.h +++ b/arch/arm/mach-mvebu/include/mach/config.h @@ -17,7 +17,7 @@ #include <asm/arch/soc.h> #if defined(CONFIG_ARMADA_XP) || defined(CONFIG_ARMADA_375) \ - || defined(CONFIG_ARMADA_38X) + || defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_MSYS) /* * Set this for the common xor register definitions needed in dram.c * for A38x as well here. diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h index 9e23043a485..b9153d86c66 100644 --- a/arch/arm/mach-mvebu/include/mach/cpu.h +++ b/arch/arm/mach-mvebu/include/mach/cpu.h @@ -34,6 +34,7 @@ enum cpu_target { CPU_TARGET_PCIE02 = 0x4, CPU_TARGET_ETH01 = 0x7, CPU_TARGET_PCIE13 = 0x8, + CPU_TARGET_DFX = 0x8, CPU_TARGET_SASRAM = 0x9, CPU_TARGET_SATA01 = 0xa, /* A38X */ CPU_TARGET_NAND = 0xd, @@ -79,6 +80,8 @@ enum { #define MBUS_PCI_IO_SIZE (64 << 10) #define MBUS_SPI_BASE 0xF4000000 #define MBUS_SPI_SIZE (8 << 20) +#define MBUS_DFX_BASE 0xF6000000 +#define MBUS_DFX_SIZE (1 << 20) #define MBUS_BOOTROM_BASE 0xF8000000 #define MBUS_BOOTROM_SIZE (8 << 20) diff --git a/arch/arm/mach-mvebu/include/mach/soc.h b/arch/arm/mach-mvebu/include/mach/soc.h index 01577f469b0..f666ee24243 100644 --- a/arch/arm/mach-mvebu/include/mach/soc.h +++ b/arch/arm/mach-mvebu/include/mach/soc.h @@ -76,7 +76,11 @@ #define MVEBU_NAND_BASE (MVEBU_REGISTER(0xd0000)) #define MVEBU_SDIO_BASE (MVEBU_REGISTER(0xd8000)) #define MVEBU_LCD_BASE (MVEBU_REGISTER(0xe0000)) +#ifdef CONFIG_ARMADA_MSYS +#define MVEBU_DFX_BASE (MBUS_DFX_BASE) +#else #define MVEBU_DFX_BASE (MVEBU_REGISTER(0xe4000)) +#endif #define SOC_COHERENCY_FABRIC_CTRL_REG (MVEBU_REGISTER(0x20200)) #define MBUS_ERR_PROP_EN (1 << 8) @@ -96,9 +100,20 @@ #define SPI_PUP_EN BIT(5) #define MVEBU_CORE_DIV_CLK_CTRL(i) (MVEBU_CLOCK_BASE + ((i) * 0x8)) +#ifdef CONFIG_ARMADA_MSYS +#define MVEBU_DFX_DIV_CLK_CTRL(i) (MVEBU_DFX_BASE + 0xf8000 + 0x250 + ((i) * 0x4)) +#define NAND_ECC_DIVCKL_RATIO_OFFS 6 +#define NAND_ECC_DIVCKL_RATIO_MASK (0xF << NAND_ECC_DIVCKL_RATIO_OFFS) +#else #define MVEBU_DFX_DIV_CLK_CTRL(i) (MVEBU_DFX_BASE + 0x250 + ((i) * 0x4)) +#endif +#ifdef CONFIG_ARMADA_MSYS +#define NAND_ECC_DIVCKL_RATIO_OFFS 6 +#define NAND_ECC_DIVCKL_RATIO_MASK (0xF << NAND_ECC_DIVCKL_RATIO_OFFS) +#else #define NAND_ECC_DIVCKL_RATIO_OFFS 8 #define NAND_ECC_DIVCKL_RATIO_MASK (0x3F << NAND_ECC_DIVCKL_RATIO_OFFS) +#endif #define SDRAM_MAX_CS 4 #define SDRAM_ADDR_MASK 0xFF000000 @@ -149,6 +164,22 @@ #define BOOT_FROM_SPI 0x32 #define BOOT_FROM_MMC 0x30 #define BOOT_FROM_MMC_ALT 0x31 +#elif defined(CONFIG_ARMADA_MSYS) +/* SAR values for MSYS */ +#define CONFIG_SAR_REG (MBUS_DFX_BASE + 0xf8200) +#define CONFIG_SAR2_REG (MBUS_DFX_BASE + 0xf8204) + +#define SAR_CPU_FREQ_OFFS 18 +#define SAR_CPU_FREQ_MASK (0x7 << SAR_CPU_FREQ_OFFS) +#define SAR_BOOT_DEVICE_OFFS 11 +#define SAR_BOOT_DEVICE_MASK (0x7 << SAR_BOOT_DEVICE_OFFS) + +#define BOOT_DEV_SEL_OFFS 11 +#define BOOT_DEV_SEL_MASK (0x7 << BOOT_DEV_SEL_OFFS) + +#define BOOT_FROM_NAND 0x1 +#define BOOT_FROM_UART 0x2 +#define BOOT_FROM_SPI 0x3 #else /* SAR values for Armada XP */ #define CONFIG_SAR_REG (MVEBU_REGISTER(0x18230)) diff --git a/arch/arm/mach-mvebu/mbus.c b/arch/arm/mach-mvebu/mbus.c index df4c5cb2d71..c68e93ba100 100644 --- a/arch/arm/mach-mvebu/mbus.c +++ b/arch/arm/mach-mvebu/mbus.c @@ -344,6 +344,11 @@ static void mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus) } } mbus_dram_info.num_cs = cs; + +#if defined(CONFIG_ARMADA_MSYS) + /* Disable MBUS Err Prop - in order to avoid data aborts */ + clrbits_le32(mbus->mbuswins_base + 0x200, BIT(8)); +#endif } static const struct mvebu_mbus_soc_data @@ -405,6 +410,7 @@ int mvebu_mbus_del_window(phys_addr_t base, size_t size) return 0; } +#ifndef CONFIG_KIRKWOOD static void mvebu_mbus_get_lowest_base(struct mvebu_mbus_state *mbus, phys_addr_t *base) { @@ -451,6 +457,7 @@ static void mvebu_config_mbus_bridge(struct mvebu_mbus_state *mbus) val = (size / (64 << 10)) - 1; writel((val << 16) | 0x1, MBUS_BRIDGE_WIN_CTRL_REG); } +#endif int mbus_dt_setup_win(struct mvebu_mbus_state *mbus, u32 base, u32 size, u8 target, u8 attr) @@ -471,12 +478,14 @@ int mbus_dt_setup_win(struct mvebu_mbus_state *mbus, return -ENOMEM; } +#ifndef CONFIG_KIRKWOOD /* * Re-configure the mbus bridge registers each time this function * is called. Since it may get called from the board code in * later boot stages as well. */ mvebu_config_mbus_bridge(mbus); +#endif return 0; } diff --git a/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c b/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c index 569840ff471..c8c92988645 100644 --- a/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c +++ b/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c @@ -35,7 +35,7 @@ int pex_local_dev_num_set(u32 pex_if, u32 dev_num); #define ETM_MODULE_DETECT 2 #define PEX_MODE_GET(satr) ((satr & 0x6) >> 1) -#define PEX_CAPABILITY_GET(satr) (satr & 1) +#define PEX_CAPABILITY_GET(satr, port) ((satr >> port) & 1) #define MV_PEX_UNIT_TO_IF(pex_unit) ((pex_unit < 3) ? (pex_unit * 4) : 9) /* Static parametes */ @@ -176,7 +176,7 @@ u8 board_cpu_freq_get(void) return ((sar_msb & 0x100000) >> 17) | ((sar & 0xe00000) >> 21); } -__weak MV_BIN_SERDES_CFG *board_serdes_cfg_get(u8 pex_mode) +__weak MV_BIN_SERDES_CFG *board_serdes_cfg_get(void) { u32 board_id; u32 serdes_cfg_val = 0; /* default */ @@ -352,7 +352,7 @@ int serdes_phy_config(void) DEBUG_WR_REG(CPU_AVS_CONTROL2_REG, cpu_avs); } - info = board_serdes_cfg_get(PEX_MODE_GET(satr11)); + info = board_serdes_cfg_get(); if (info == NULL) { DEBUG_INIT_S("Hight speed PHY Error #1\n"); @@ -675,7 +675,7 @@ int serdes_phy_config(void) tmp |= (0x1 << 4); if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4) tmp |= (0x4 << 4); - if (0 == PEX_CAPABILITY_GET(satr11)) + if (0 == PEX_CAPABILITY_GET(satr11, pex_unit)) tmp |= 0x1; else tmp |= 0x2; diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig index 8a929fa9132..73aa3827122 100644 --- a/arch/arm/mach-stm32mp/Kconfig +++ b/arch/arm/mach-stm32mp/Kconfig @@ -17,7 +17,7 @@ config SPL select SPL_DM_RESET select SPL_SERIAL_SUPPORT select SPL_SYSCON - select SPL_DRIVERS_MISC_SUPPORT + imply SPL_DISPLAY_PRINT imply SPL_LIBDISK_SUPPORT config SYS_SOC @@ -25,18 +25,31 @@ config SYS_SOC config TARGET_STM32MP1 bool "Support stm32mp1xx" - select ARCH_SUPPORT_PSCI + select ARCH_SUPPORT_PSCI if !STM32MP1_TRUSTED select CPU_V7A - select CPU_V7_HAS_NONSEC + select CPU_V7_HAS_NONSEC if !STM32MP1_TRUSTED select CPU_V7_HAS_VIRT select PINCTRL_STM32 select STM32_RCC select STM32_RESET select SYS_ARCH_TIMER - select SYSRESET_SYSCON + imply SYSRESET_PSCI if STM32MP1_TRUSTED + imply SYSRESET_SYSCON if !STM32MP1_TRUSTED help target STMicroelectronics SOC STM32MP1 family + STM32MP157, STM32MP153 or STM32MP151 STMicroelectronics MPU with core ARMv7 + dual core A7 for STM32MP157/3, monocore for STM32MP151 + +config STM32MP1_TRUSTED + bool "Support trusted boot with TF-A" + default y if !SPL + select ARM_SMCCC + help + Say Y here to enable boot with TF-A + Trusted boot chain is : + BootRom => TF-A.stm32 (clock & DDR) => U-Boot.stm32 + TF-A monitor provides proprietary smc to manage secure devices config SYS_TEXT_BASE prompt "U-Boot base address" @@ -46,6 +59,9 @@ config SYS_TEXT_BASE when DDR driver is used: DDR + 1MB (0xC0100000) +config NR_DRAM_BANKS + default 1 + config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2 hex "Partition on MMC2 to use to load U-Boot from" depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION @@ -54,9 +70,6 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2 Partition on the second MMC to load U-Boot from when the MMC is being used in raw mode -source "board/st/stm32mp1/Kconfig" - -# currently activated for debug / should be deactivated for real product if DEBUG_UART config DEBUG_UART_BOARD_INIT @@ -71,4 +84,6 @@ config DEBUG_UART_CLOCK default 64000000 endif +source "board/st/stm32mp1/Kconfig" + endif diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile index f59ced5ee1b..1493914a110 100644 --- a/arch/arm/mach-stm32mp/Makefile +++ b/arch/arm/mach-stm32mp/Makefile @@ -11,6 +11,9 @@ ifdef CONFIG_SPL_BUILD obj-y += spl.o else obj-y += bsec.o +ifndef CONFIG_STM32MP1_TRUSTED +obj-$(CONFIG_SYSRESET) += cmd_poweroff.o +endif endif obj-$(CONFIG_ARMV7_PSCI) += psci.o obj-$(CONFIG_$(SPL_)DM_REGULATOR) += pwr_regulator.o diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c index d087a313892..9ed8d8c56c3 100644 --- a/arch/arm/mach-stm32mp/bsec.c +++ b/arch/arm/mach-stm32mp/bsec.c @@ -8,9 +8,12 @@ #include <misc.h> #include <asm/io.h> #include <linux/iopoll.h> +#include <asm/arch/stm32mp1_smc.h> +#include <linux/arm-smccc.h> #define BSEC_OTP_MAX_VALUE 95 +#ifndef CONFIG_STM32MP1_TRUSTED #define BSEC_TIMEOUT_US 10000 /* BSEC REGISTER OFFSET (base relative) */ @@ -168,7 +171,7 @@ static int bsec_shadow_register(u32 base, u32 otp) ret = bsec_power_safmem(base, true); if (ret) return ret; - power_up = 1; + power_up = true; } /* set BSEC_OTP_CTRL_OFF with the otp value*/ writel(otp | BSEC_READ, base + BSEC_OTP_CTRL_OFF); @@ -270,6 +273,7 @@ static int bsec_program_otp(long base, u32 val, u32 otp) return ret; } +#endif /* CONFIG_STM32MP1_TRUSTED */ /* BSEC MISC driver *******************************************************/ struct stm32mp_bsec_platdata { @@ -278,6 +282,11 @@ struct stm32mp_bsec_platdata { static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp) { +#ifdef CONFIG_STM32MP1_TRUSTED + return stm32_smc(STM32_SMC_BSEC, + STM32_SMC_READ_OTP, + otp, 0, val); +#else struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev); u32 tmp_data = 0; int ret; @@ -299,27 +308,46 @@ static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp) /* restore shadow value */ ret = bsec_write_shadow(plat->base, tmp_data, otp); return ret; +#endif } static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp) { +#ifdef CONFIG_STM32MP1_TRUSTED + return stm32_smc(STM32_SMC_BSEC, + STM32_SMC_READ_SHADOW, + otp, 0, val); +#else struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev); return bsec_read_shadow(plat->base, val, otp); +#endif } static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp) { +#ifdef CONFIG_STM32MP1_TRUSTED + return stm32_smc_exec(STM32_SMC_BSEC, + STM32_SMC_PROG_OTP, + otp, val); +#else struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev); return bsec_program_otp(plat->base, val, otp); +#endif } static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp) { +#ifdef CONFIG_STM32MP1_TRUSTED + return stm32_smc_exec(STM32_SMC_BSEC, + STM32_SMC_WRITE_SHADOW, + otp, val); +#else struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev); return bsec_write_shadow(plat->base, val, otp); +#endif } static int stm32mp_bsec_read(struct udevice *dev, int offset, @@ -405,8 +433,23 @@ static int stm32mp_bsec_ofdata_to_platdata(struct udevice *dev) return 0; } +#ifndef CONFIG_STM32MP1_TRUSTED +static int stm32mp_bsec_probe(struct udevice *dev) +{ + int otp; + struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev); + + /* update unlocked shadow for OTP cleared by the rom code */ + for (otp = 57; otp <= BSEC_OTP_MAX_VALUE; otp++) + if (!bsec_read_SR_lock(plat->base, otp)) + bsec_shadow_register(plat->base, otp); + + return 0; +} +#endif + static const struct udevice_id stm32mp_bsec_ids[] = { - { .compatible = "st,stm32mp-bsec" }, + { .compatible = "st,stm32mp15-bsec" }, {} }; @@ -417,14 +460,7 @@ U_BOOT_DRIVER(stm32mp_bsec) = { .ofdata_to_platdata = stm32mp_bsec_ofdata_to_platdata, .platdata_auto_alloc_size = sizeof(struct stm32mp_bsec_platdata), .ops = &stm32mp_bsec_ops, -}; - -/* bsec IP is not present in device tee, manage IP address by platdata */ -static struct stm32mp_bsec_platdata stm32_bsec_platdata = { - .base = STM32_BSEC_BASE, -}; - -U_BOOT_DEVICE(stm32mp_bsec) = { - .name = "stm32mp_bsec", - .platdata = &stm32_bsec_platdata, +#ifndef CONFIG_STM32MP1_TRUSTED + .probe = stm32mp_bsec_probe, +#endif }; diff --git a/arch/arm/mach-stm32mp/cmd_poweroff.c b/arch/arm/mach-stm32mp/cmd_poweroff.c new file mode 100644 index 00000000000..f54dd1daf23 --- /dev/null +++ b/arch/arm/mach-stm32mp/cmd_poweroff.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2019, STMicroelectronics - All Rights Reserved + */ + +#include <common.h> +#include <command.h> +#include <sysreset.h> + +int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int ret; + + puts("poweroff ...\n"); + mdelay(100); + + ret = sysreset_walk(SYSRESET_POWER); + + if (ret == -EINPROGRESS) + mdelay(1000); + + /*NOTREACHED when power off*/ + return CMD_RET_FAILURE; +} diff --git a/arch/arm/mach-stm32mp/config.mk b/arch/arm/mach-stm32mp/config.mk index f371aac75bd..403af2a225e 100644 --- a/arch/arm/mach-stm32mp/config.mk +++ b/arch/arm/mach-stm32mp/config.mk @@ -3,7 +3,20 @@ # Copyright (C) 2018, STMicroelectronics - All Rights Reserved # -ALL-$(CONFIG_SPL_BUILD) += u-boot-spl.stm32 +ifndef CONFIG_SPL +ALL-y += u-boot.stm32 +else +ifdef CONFIG_SPL_BUILD +ALL-y += u-boot-spl.stm32 +endif +endif + +MKIMAGEFLAGS_u-boot.stm32 = -T stm32image -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) + +u-boot.stm32: MKIMAGEOUTPUT = u-boot.stm32.log + +u-boot.stm32: u-boot.bin FORCE + $(call if_changed,mkimage) MKIMAGEFLAGS_u-boot-spl.stm32 = -T stm32image -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c index b8933587adb..7b4431c9c75 100644 --- a/arch/arm/mach-stm32mp/cpu.c +++ b/arch/arm/mach-stm32mp/cpu.c @@ -18,6 +18,7 @@ #define RCC_DBGCFGR (STM32_RCC_BASE + 0x080C) #define RCC_BDCR (STM32_RCC_BASE + 0x0140) #define RCC_MP_APB5ENSETR (STM32_RCC_BASE + 0x0208) +#define RCC_MP_AHB5ENSETR (STM32_RCC_BASE + 0x0210) #define RCC_BDCR_VSWRST BIT(31) #define RCC_BDCR_RTCSRC GENMASK(17, 16) #define RCC_DBGCFGR_DBGCKEN BIT(8) @@ -44,6 +45,9 @@ #define DBGMCU_IDC_REV_ID_MASK GENMASK(31, 16) #define DBGMCU_IDC_REV_ID_SHIFT 16 +/* GPIOZ registers */ +#define GPIOZ_SECCFGR 0x54004030 + /* boot interface from Bootrom * - boot instance = bit 31:16 * - boot device = bit 15:0 @@ -55,10 +59,32 @@ #define BOOTROM_INSTANCE_SHIFT 16 /* BSEC OTP index */ +#define BSEC_OTP_RPN 1 #define BSEC_OTP_SERIAL 13 +#define BSEC_OTP_PKG 16 #define BSEC_OTP_MAC 57 +/* Device Part Number (RPN) = OTP_DATA1 lower 8 bits */ +#define RPN_SHIFT 0 +#define RPN_MASK GENMASK(7, 0) + +/* Package = bit 27:29 of OTP16 + * - 100: LBGA448 (FFI) => AA = LFBGA 18x18mm 448 balls p. 0.8mm + * - 011: LBGA354 (LCI) => AB = LFBGA 16x16mm 359 balls p. 0.8mm + * - 010: TFBGA361 (FFC) => AC = TFBGA 12x12mm 361 balls p. 0.5mm + * - 001: TFBGA257 (LCC) => AD = TFBGA 10x10mm 257 balls p. 0.5mm + * - others: Reserved + */ +#define PKG_SHIFT 27 +#define PKG_MASK GENMASK(2, 0) + +#define PKG_AA_LBGA448 4 +#define PKG_AB_LBGA354 3 +#define PKG_AC_TFBGA361 2 +#define PKG_AD_TFBGA257 1 + #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) +#ifndef CONFIG_STM32MP1_TRUSTED static void security_init(void) { /* Disable the backup domain write protection */ @@ -113,7 +139,12 @@ static void security_init(void) * Bit 16 ITAMP1E: RTC power domain supply monitoring */ writel(0x0, TAMP_CR1); + + /* GPIOZ: deactivate the security */ + writel(BIT(0), RCC_MP_AHB5ENSETR); + writel(0x0, GPIOZ_SECCFGR); } +#endif /* CONFIG_STM32MP1_TRUSTED */ /* * Debug init @@ -127,13 +158,19 @@ static void dbgmcu_init(void) } #endif /* !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) */ -static u32 get_bootmode(void) +#if !defined(CONFIG_STM32MP1_TRUSTED) && \ + (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) +/* get bootmode from ROM code boot context: saved in TAMP register */ +static void update_bootmode(void) { u32 boot_mode; -#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) u32 bootrom_itf = readl(BOOTROM_PARAM_ADDR); u32 bootrom_device, bootrom_instance; + /* enable TAMP clock = RTCAPBEN */ + writel(BIT(8), RCC_MP_APB5ENSETR); + + /* read bootrom context */ bootrom_device = (bootrom_itf & BOOTROM_MODE_MASK) >> BOOTROM_MODE_SHIFT; bootrom_instance = @@ -147,12 +184,14 @@ static u32 get_bootmode(void) clrsetbits_le32(TAMP_BOOT_CONTEXT, TAMP_BOOT_MODE_MASK, boot_mode << TAMP_BOOT_MODE_SHIFT); -#else - /* read TAMP backup register */ - boot_mode = (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >> - TAMP_BOOT_MODE_SHIFT; +} #endif - return boot_mode; + +u32 get_bootmode(void) +{ + /* read bootmode from TAMP backup register */ + return (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >> + TAMP_BOOT_MODE_SHIFT; } /* @@ -167,16 +206,18 @@ int arch_cpu_init(void) #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) dbgmcu_init(); - +#ifndef CONFIG_STM32MP1_TRUSTED security_init(); + update_bootmode(); +#endif #endif - /* get bootmode from BootRom context: saved in TAMP register */ boot_mode = get_bootmode(); if ((boot_mode & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_UART) gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE; #if defined(CONFIG_DEBUG_UART) && \ + !defined(CONFIG_STM32MP1_TRUSTED) && \ (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) else debug_uart_init(); @@ -203,25 +244,94 @@ u32 get_cpu_rev(void) return (read_idc() & DBGMCU_IDC_REV_ID_MASK) >> DBGMCU_IDC_REV_ID_SHIFT; } +static u32 get_otp(int index, int shift, int mask) +{ + int ret; + struct udevice *dev; + u32 otp = 0; + + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_GET_DRIVER(stm32mp_bsec), + &dev); + + if (!ret) + ret = misc_read(dev, STM32_BSEC_SHADOW(index), + &otp, sizeof(otp)); + + return (otp >> shift) & mask; +} + +/* Get Device Part Number (RPN) from OTP */ +static u32 get_cpu_rpn(void) +{ + return get_otp(BSEC_OTP_RPN, RPN_SHIFT, RPN_MASK); +} + u32 get_cpu_type(void) { - return (read_idc() & DBGMCU_IDC_DEV_ID_MASK) >> DBGMCU_IDC_DEV_ID_SHIFT; + u32 id; + + id = (read_idc() & DBGMCU_IDC_DEV_ID_MASK) >> DBGMCU_IDC_DEV_ID_SHIFT; + + return (id << 16) | get_cpu_rpn(); +} + +/* Get Package options from OTP */ +static u32 get_cpu_package(void) +{ + return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK); } #if defined(CONFIG_DISPLAY_CPUINFO) int print_cpuinfo(void) { - char *cpu_s, *cpu_r; + char *cpu_s, *cpu_r, *pkg; + /* MPUs Part Numbers */ switch (get_cpu_type()) { - case CPU_STMP32MP15x: - cpu_s = "15x"; + case CPU_STM32MP157Cxx: + cpu_s = "157C"; + break; + case CPU_STM32MP157Axx: + cpu_s = "157A"; + break; + case CPU_STM32MP153Cxx: + cpu_s = "153C"; + break; + case CPU_STM32MP153Axx: + cpu_s = "153A"; + break; + case CPU_STM32MP151Cxx: + cpu_s = "151C"; + break; + case CPU_STM32MP151Axx: + cpu_s = "151A"; + break; + default: + cpu_s = "????"; + break; + } + + /* Package */ + switch (get_cpu_package()) { + case PKG_AA_LBGA448: + pkg = "AA"; + break; + case PKG_AB_LBGA354: + pkg = "AB"; + break; + case PKG_AC_TFBGA361: + pkg = "AC"; + break; + case PKG_AD_TFBGA257: + pkg = "AD"; break; default: - cpu_s = "?"; + pkg = "??"; break; } + /* REVISION */ switch (get_cpu_rev()) { case CPU_REVA: cpu_r = "A"; @@ -234,7 +344,7 @@ int print_cpuinfo(void) break; } - printf("CPU: STM32MP%s.%s\n", cpu_s, cpu_r); + printf("CPU: STM32MP%s%s Rev.%s\n", cpu_s, pkg, cpu_r); return 0; } @@ -242,20 +352,48 @@ int print_cpuinfo(void) static void setup_boot_mode(void) { + const u32 serial_addr[] = { + STM32_USART1_BASE, + STM32_USART2_BASE, + STM32_USART3_BASE, + STM32_UART4_BASE, + STM32_UART5_BASE, + STM32_USART6_BASE, + STM32_UART7_BASE, + STM32_UART8_BASE + }; char cmd[60]; u32 boot_ctx = readl(TAMP_BOOT_CONTEXT); u32 boot_mode = (boot_ctx & TAMP_BOOT_MODE_MASK) >> TAMP_BOOT_MODE_SHIFT; int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1; + u32 forced_mode = (boot_ctx & TAMP_BOOT_FORCED_MASK); + struct udevice *dev; + int alias; - pr_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d\n", - __func__, boot_ctx, boot_mode, instance); - + pr_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d forced=%x\n", + __func__, boot_ctx, boot_mode, instance, forced_mode); switch (boot_mode & TAMP_BOOT_DEVICE_MASK) { case BOOT_SERIAL_UART: - sprintf(cmd, "%d", instance); - env_set("boot_device", "uart"); + if (instance > ARRAY_SIZE(serial_addr)) + break; + /* serial : search associated alias in devicetree */ + sprintf(cmd, "serial@%x", serial_addr[instance]); + if (uclass_get_device_by_name(UCLASS_SERIAL, cmd, &dev)) + break; + if (fdtdec_get_alias_seq(gd->fdt_blob, "serial", + dev_of_offset(dev), &alias)) + break; + sprintf(cmd, "%d", alias); + env_set("boot_device", "serial"); env_set("boot_instance", cmd); + + /* restore console on uart when not used */ + if (gd->cur_serial_dev != dev) { + gd->flags &= ~(GD_FLG_SILENT | + GD_FLG_DISABLE_CONSOLE); + printf("serial boot with console enabled!\n"); + } break; case BOOT_SERIAL_USB: env_set("boot_device", "usb"); @@ -279,6 +417,36 @@ static void setup_boot_mode(void) pr_debug("unexpected boot mode = %x\n", boot_mode); break; } + + switch (forced_mode) { + case BOOT_FASTBOOT: + printf("Enter fastboot!\n"); + env_set("preboot", "env set preboot; fastboot 0"); + break; + case BOOT_STM32PROG: + env_set("boot_device", "usb"); + env_set("boot_instance", "0"); + break; + case BOOT_UMS_MMC0: + case BOOT_UMS_MMC1: + case BOOT_UMS_MMC2: + printf("Enter UMS!\n"); + instance = forced_mode - BOOT_UMS_MMC0; + sprintf(cmd, "env set preboot; ums 0 mmc %d", instance); + env_set("preboot", cmd); + break; + case BOOT_RECOVERY: + env_set("preboot", "env set preboot; run altbootcmd"); + break; + case BOOT_NORMAL: + break; + default: + pr_debug("unexpected forced boot mode = %x\n", forced_mode); + break; + } + + /* clear TAMP for next reboot */ + clrsetbits_le32(TAMP_BOOT_CONTEXT, TAMP_BOOT_FORCED_MASK, BOOT_NORMAL); } /* @@ -304,7 +472,7 @@ static int setup_mac_address(void) if (ret) return ret; - ret = misc_read(dev, BSEC_OTP_MAC * 4 + STM32_BSEC_OTP_OFFSET, + ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_MAC), otp, sizeof(otp)); if (ret < 0) return ret; @@ -342,12 +510,12 @@ static int setup_serial_number(void) if (ret) return ret; - ret = misc_read(dev, BSEC_OTP_SERIAL * 4 + STM32_BSEC_OTP_OFFSET, + ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_SERIAL), otp, sizeof(otp)); if (ret < 0) return ret; - sprintf(serial_string, "%08x%08x%08x", otp[0], otp[1], otp[2]); + sprintf(serial_string, "%08X%08X%08X", otp[0], otp[1], otp[2]); env_set("serial#", serial_string); return 0; diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h index 5d0bdca1787..c526c88e3ee 100644 --- a/arch/arm/mach-stm32mp/include/mach/stm32.h +++ b/arch/arm/mach-stm32mp/include/mach/stm32.h @@ -13,13 +13,10 @@ #define STM32_RCC_BASE 0x50000000 #define STM32_PWR_BASE 0x50001000 #define STM32_DBGMCU_BASE 0x50081000 -#define STM32_BSEC_BASE 0x5C005000 #define STM32_TZC_BASE 0x5C006000 #define STM32_ETZPC_BASE 0x5C007000 #define STM32_TAMP_BASE 0x5C00A000 -#ifdef CONFIG_DEBUG_UART_BASE -/* hardcoded value can be only used for DEBUG UART */ #define STM32_USART1_BASE 0x5C000000 #define STM32_USART2_BASE 0x4000E000 #define STM32_USART3_BASE 0x4000F000 @@ -28,7 +25,6 @@ #define STM32_USART6_BASE 0x44003000 #define STM32_UART7_BASE 0x40018000 #define STM32_UART8_BASE 0x40019000 -#endif #define STM32_SYSRAM_BASE 0x2FFC0000 #define STM32_SYSRAM_SIZE SZ_256K @@ -40,8 +36,10 @@ /* enumerated used to identify the SYSCON driver instance */ enum { STM32MP_SYSCON_UNKNOWN, - STM32MP_SYSCON_STGEN, + STM32MP_SYSCON_ETZPC, STM32MP_SYSCON_PWR, + STM32MP_SYSCON_STGEN, + STM32MP_SYSCON_SYSCFG, }; /* @@ -95,10 +93,25 @@ enum boot_device { #define TAMP_BOOT_MODE_SHIFT 8 #define TAMP_BOOT_DEVICE_MASK GENMASK(7, 4) #define TAMP_BOOT_INSTANCE_MASK GENMASK(3, 0) +#define TAMP_BOOT_FORCED_MASK GENMASK(7, 0) + +enum forced_boot_mode { + BOOT_NORMAL = 0x00, + BOOT_FASTBOOT = 0x01, + BOOT_RECOVERY = 0x02, + BOOT_STM32PROG = 0x03, + BOOT_UMS_MMC0 = 0x10, + BOOT_UMS_MMC1 = 0x11, + BOOT_UMS_MMC2 = 0x12, +}; /* offset used for BSEC driver: misc_read and misc_write */ #define STM32_BSEC_SHADOW_OFFSET 0x0 +#define STM32_BSEC_SHADOW(id) (STM32_BSEC_SHADOW_OFFSET + (id) * 4) #define STM32_BSEC_OTP_OFFSET 0x80000000 +#define STM32_BSEC_OTP(id) (STM32_BSEC_OTP_OFFSET + (id) * 4) + +#define BSEC_OTP_BOARD 59 #endif /* __ASSEMBLY__*/ #endif /* _MACH_STM32_H_ */ diff --git a/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h new file mode 100644 index 00000000000..8130546b273 --- /dev/null +++ b/arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* + * Copyright (C) 2019, STMicroelectronics - All Rights Reserved + */ + +#ifndef __STM32MP1_SMC_H__ +#define __STM32MP1_SMC_H__ + +#include <linux/arm-smccc.h> + +/* + * SMC function IDs for STM32 Service queries + * STM32 SMC services use the space between 0x82000000 and 0x8200FFFF + * like this is defined in SMC calling Convention by ARM + * for SiP (silicon Partner) + * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html + */ +#define STM32_SMC_VERSION 0x82000000 + +/* Secure Service access from Non-secure */ +#define STM32_SMC_BSEC 0x82001003 + +/* Service for BSEC */ +#define STM32_SMC_READ_SHADOW 0x01 +#define STM32_SMC_PROG_OTP 0x02 +#define STM32_SMC_WRITE_SHADOW 0x03 +#define STM32_SMC_READ_OTP 0x04 +#define STM32_SMC_READ_ALL 0x05 +#define STM32_SMC_WRITE_ALL 0x06 + +/* SMC error codes */ +#define STM32_SMC_OK 0x0 +#define STM32_SMC_NOT_SUPPORTED -1 +#define STM32_SMC_FAILED -2 +#define STM32_SMC_INVALID_PARAMS -3 + +#define stm32_smc_exec(svc, op, data1, data2) \ + stm32_smc(svc, op, data1, data2, NULL) + +#ifdef CONFIG_ARM_SMCCC +static inline u32 stm32_smc(u32 svc, u8 op, u32 data1, u32 data2, u32 *result) +{ + struct arm_smccc_res res; + + arm_smccc_smc(svc, op, data1, data2, 0, 0, 0, 0, &res); + + if (res.a0) { + pr_err("%s: Failed to exec in secure mode (err = %ld)\n", + __func__, res.a0); + return -EINVAL; + } + if (result) + *result = (u32)res.a1; + + return 0; +} +#else +static inline u32 stm32_smc(u32 svc, u8 op, u32 data1, u32 data2, u32 *result) +{ + return 0; +} +#endif + +#endif /* __STM32MP1_SMC_H__ */ diff --git a/arch/arm/mach-stm32mp/include/mach/sys_proto.h b/arch/arm/mach-stm32mp/include/mach/sys_proto.h index 41d4b40bcb4..71a3ba794d1 100644 --- a/arch/arm/mach-stm32mp/include/mach/sys_proto.h +++ b/arch/arm/mach-stm32mp/include/mach/sys_proto.h @@ -3,9 +3,15 @@ * Copyright (C) 2015-2017, STMicroelectronics - All Rights Reserved */ -#define CPU_STMP32MP15x 0x500 +/* ID = Device Version (bit31:16) + Device Part Number (RPN) (bit15:0)*/ +#define CPU_STM32MP157Cxx 0x05000000 +#define CPU_STM32MP157Axx 0x05000001 +#define CPU_STM32MP153Cxx 0x05000024 +#define CPU_STM32MP153Axx 0x05000025 +#define CPU_STM32MP151Cxx 0x0500002E +#define CPU_STM32MP151Axx 0x0500002F -/* return CPU_STMP32MPxx constants */ +/* return CPU_STMP32MP...Xxx constants */ u32 get_cpu_type(void); #define CPU_REVA 0x1000 @@ -13,3 +19,5 @@ u32 get_cpu_type(void); /* return CPU_REV constants */ u32 get_cpu_rev(void); +/* return boot mode */ +u32 get_bootmode(void); diff --git a/arch/arm/mach-stm32mp/psci.c b/arch/arm/mach-stm32mp/psci.c index 6ed2482080c..c2dff38c368 100644 --- a/arch/arm/mach-stm32mp/psci.c +++ b/arch/arm/mach-stm32mp/psci.c @@ -103,7 +103,13 @@ int __secure psci_affinity_info(u32 function_id, u32 target_affinity, int __secure psci_migrate_info_type(u32 function_id) { - /* Trusted OS is either not present or does not require migration */ + /* + * in Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf + * return 2 = Trusted OS is either not present or does not require + * migration, system of this type does not require the caller + * to use the MIGRATE function. + * MIGRATE function calls return NOT_SUPPORTED. + */ return 2; } diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c index 790973e8b6e..a3b0d6f3825 100644 --- a/arch/arm/mach-stm32mp/spl.c +++ b/arch/arm/mach-stm32mp/spl.c @@ -7,13 +7,14 @@ #include <dm.h> #include <spl.h> #include <asm/io.h> +#include <asm/arch/sys_proto.h> +#include <linux/libfdt.h> u32 spl_boot_device(void) { u32 boot_mode; - boot_mode = (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >> - TAMP_BOOT_MODE_SHIFT; + boot_mode = get_bootmode(); switch (boot_mode) { case BOOT_FLASH_SD_1: @@ -22,6 +23,21 @@ u32 spl_boot_device(void) case BOOT_FLASH_SD_2: case BOOT_FLASH_EMMC_2: return BOOT_DEVICE_MMC2; + case BOOT_SERIAL_UART_1: + case BOOT_SERIAL_UART_2: + case BOOT_SERIAL_UART_3: + case BOOT_SERIAL_UART_4: + case BOOT_SERIAL_UART_5: + case BOOT_SERIAL_UART_6: + case BOOT_SERIAL_UART_7: + case BOOT_SERIAL_UART_8: + return BOOT_DEVICE_UART; + case BOOT_SERIAL_USB_OTG: + return BOOT_DEVICE_USB; + case BOOT_FLASH_NAND_FMC: + return BOOT_DEVICE_NAND; + case BOOT_FLASH_NOR_QSPI: + return BOOT_DEVICE_SPI; } return BOOT_DEVICE_MMC1; @@ -44,6 +60,21 @@ int spl_boot_partition(const u32 boot_device) } } +#ifdef CONFIG_SPL_DISPLAY_PRINT +void spl_display_print(void) +{ + DECLARE_GLOBAL_DATA_PTR; + const char *model; + + /* same code than show_board_info() but not compiled for SPL + * see CONFIG_DISPLAY_BOARDINFO & common/board_info.c + */ + model = fdt_getprop(gd->fdt_blob, 0, "model", NULL); + if (model) + printf("Model: %s\n", model); +} +#endif + void board_init_f(ulong dummy) { struct udevice *dev; @@ -80,7 +111,7 @@ void board_init_f(ulong dummy) ret = uclass_get_device(UCLASS_RAM, 0, &dev); if (ret) { - debug("DRAM init failed: %d\n", ret); - return; + printf("DRAM init failed: %d\n", ret); + hang(); } } diff --git a/arch/arm/mach-stm32mp/syscon.c b/arch/arm/mach-stm32mp/syscon.c index eb7f435f10c..242f8340abb 100644 --- a/arch/arm/mach-stm32mp/syscon.c +++ b/arch/arm/mach-stm32mp/syscon.c @@ -9,10 +9,11 @@ #include <asm/arch/stm32.h> static const struct udevice_id stm32mp_syscon_ids[] = { - { .compatible = "st,stm32-stgen", - .data = STM32MP_SYSCON_STGEN }, - { .compatible = "st,stm32mp1-pwr", - .data = STM32MP_SYSCON_PWR }, + { .compatible = "st,stm32mp1-etzpc", .data = STM32MP_SYSCON_ETZPC }, + { .compatible = "st,stm32mp1-pwr", .data = STM32MP_SYSCON_PWR }, + { .compatible = "st,stm32-stgen", .data = STM32MP_SYSCON_STGEN }, + { .compatible = "st,stm32mp157-syscfg", + .data = STM32MP_SYSCON_SYSCFG }, { } }; diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 152deb04e90..8110f23ff67 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -426,10 +426,11 @@ endif config DRAM_ZQ int "sunxi dram zq value" - default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN8I + default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || \ + MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_A83T default 127 if MACH_SUN7I default 14779 if MACH_SUN8I_V3S - default 3881979 if MACH_SUN8I_R40 || MACH_SUN50I_H6 + default 3881979 if MACH_SUNXI_H3_H5 || MACH_SUN8I_R40 || MACH_SUN50I_H6 default 4145117 if MACH_SUN9I default 3881915 if MACH_SUN50I ---help--- @@ -438,6 +439,7 @@ config DRAM_ZQ config DRAM_ODT_EN bool "sunxi dram odt enable" default y if MACH_SUN8I_A23 + default y if MACH_SUNXI_H3_H5 default y if MACH_SUN8I_R40 default y if MACH_SUN50I default y if MACH_SUN50I_H6 diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index b74eaf2a0e4..c6dd7b8e54b 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -240,10 +240,12 @@ uint32_t sunxi_get_boot_device(void) boot_source = readb(SPL_ADDR + 0x28); switch (boot_source) { case SUNXI_BOOTED_FROM_MMC0: + case SUNXI_BOOTED_FROM_MMC0_HIGH: return BOOT_DEVICE_MMC1; case SUNXI_BOOTED_FROM_NAND: return BOOT_DEVICE_NAND; case SUNXI_BOOTED_FROM_MMC2: + case SUNXI_BOOTED_FROM_MMC2_HIGH: return BOOT_DEVICE_MMC2; case SUNXI_BOOTED_FROM_SPI: return BOOT_DEVICE_SPI; diff --git a/arch/arm/mach-sunxi/dram_sun8i_a33.c b/arch/arm/mach-sunxi/dram_sun8i_a33.c index 1da2727f987..5da01922bfa 100644 --- a/arch/arm/mach-sunxi/dram_sun8i_a33.c +++ b/arch/arm/mach-sunxi/dram_sun8i_a33.c @@ -152,7 +152,7 @@ static void auto_set_timing_para(struct dram_para *para) reg_val &= ~(0xff << 8); reg_val &= ~(0xff << 0); reg_val |= (0x33 << 8); - reg_val |= (0x8 << 0); + reg_val |= (0x10 << 0); writel(reg_val, &mctl_ctl->dramtmg8); /* Set phy interface time */ reg_val = (0x2 << 24) | (t_rdata_en << 16) | (0x1 << 8) diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile index 665d3cc8c1c..3522e6cdc82 100644 --- a/arch/mips/dts/Makefile +++ b/arch/mips/dts/Makefile @@ -5,6 +5,7 @@ dtb-$(CONFIG_ARCH_MT7620) += \ linkit-smart-7688.dtb dtb-$(CONFIG_TARGET_AP121) += ap121.dtb dtb-$(CONFIG_TARGET_AP143) += ap143.dtb +dtb-$(CONFIG_TARGET_AP152) += ap152.dtb dtb-$(CONFIG_TARGET_BOSTON) += img,boston.dtb dtb-$(CONFIG_TARGET_MALTA) += mti,malta.dtb dtb-$(CONFIG_TARGET_PIC32MZDASK) += pic32mzda_sk.dtb diff --git a/arch/mips/dts/ap121.dts b/arch/mips/dts/ap121.dts index 4ca1c704ca4..f30af502161 100644 --- a/arch/mips/dts/ap121.dts +++ b/arch/mips/dts/ap121.dts @@ -34,7 +34,7 @@ spi-flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; memory-map = <0x9f000000 0x00800000>; spi-max-frequency = <25000000>; reg = <0>; diff --git a/arch/mips/dts/ap143.dts b/arch/mips/dts/ap143.dts index 6aedd87db9a..93a098052c7 100644 --- a/arch/mips/dts/ap143.dts +++ b/arch/mips/dts/ap143.dts @@ -34,9 +34,14 @@ spi-flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; memory-map = <0x9f000000 0x00800000>; spi-max-frequency = <25000000>; reg = <0>; }; }; + +&gmac1 { + status = "okay"; + phy-mode = "rgmii"; +}; diff --git a/arch/mips/dts/ap152.dts b/arch/mips/dts/ap152.dts new file mode 100644 index 00000000000..1722290c731 --- /dev/null +++ b/arch/mips/dts/ap152.dts @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Rosy Song <rosysong@rosinson.com> + */ + +/dts-v1/; +#include "qca956x.dtsi" + +/ { + model = "AP152 Reference Board"; + compatible = "qca,ap152", "qca,qca956x"; + + aliases { + spi0 = &spi0; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&gmac0 { + phy-mode = "sgmii"; + status = "okay"; +}; + +&xtal { + clock-frequency = <25000000>; +}; + +&uart0 { + clock-frequency = <25000000>; + status = "okay"; +}; + +&spi0 { + spi-max-frequency = <25000000>; + status = "okay"; + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash"; + memory-map = <0x9f000000 0x01000000>; + spi-max-frequency = <25000000>; + reg = <0>; + }; +}; diff --git a/arch/mips/dts/brcm,bcm6838.dtsi b/arch/mips/dts/brcm,bcm6838.dtsi index b6f95591476..c060802e8a4 100644 --- a/arch/mips/dts/brcm,bcm6838.dtsi +++ b/arch/mips/dts/brcm,bcm6838.dtsi @@ -98,5 +98,32 @@ status = "disabled"; }; + + gpio_lo: gpio-controller@14e00100 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x14e00100 0x4>, <0x14e0012c 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio_mid0: gpio-controller@14e00104 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x14e00104 0x4>, <0x14e00130 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; + + gpio_mid1: gpio-controller@14e00108 { + compatible = "brcm,bcm6345-gpio"; + reg = <0x14e00108 0x4>, <0x14e00134 0x4>; + gpio-controller; + #gpio-cells = <2>; + + status = "disabled"; + }; }; }; diff --git a/arch/mips/dts/brcm,bcm968380gerg.dts b/arch/mips/dts/brcm,bcm968380gerg.dts index 513045ee051..98471e3894d 100644 --- a/arch/mips/dts/brcm,bcm968380gerg.dts +++ b/arch/mips/dts/brcm,bcm968380gerg.dts @@ -38,3 +38,15 @@ label = "bcm968380gerg:green:usb"; }; }; + +&gpio_lo { + status = "okay"; +}; + +&gpio_mid0 { + status = "okay"; +}; + +&gpio_mid1 { + status = "okay"; +}; diff --git a/arch/mips/dts/comtrend,ar-5315u.dts b/arch/mips/dts/comtrend,ar-5315u.dts index eb60aaa8d5f..28443b3b0fd 100644 --- a/arch/mips/dts/comtrend,ar-5315u.dts +++ b/arch/mips/dts/comtrend,ar-5315u.dts @@ -110,7 +110,7 @@ status = "okay"; spi-flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/dts/comtrend,ar-5387un.dts b/arch/mips/dts/comtrend,ar-5387un.dts index 03e3851ab15..12ace64621b 100644 --- a/arch/mips/dts/comtrend,ar-5387un.dts +++ b/arch/mips/dts/comtrend,ar-5387un.dts @@ -94,7 +94,7 @@ status = "okay"; spi-flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/dts/gardena-smart-gateway-mt7688.dts b/arch/mips/dts/gardena-smart-gateway-mt7688.dts index 75f6037e96a..eedde89dfd8 100644 --- a/arch/mips/dts/gardena-smart-gateway-mt7688.dts +++ b/arch/mips/dts/gardena-smart-gateway-mt7688.dts @@ -10,7 +10,7 @@ / { compatible = "gardena,smart-gateway-mt7688", "ralink,mt7628a-soc"; - model = "Gardena smart-Gateway-MT7688"; + model = "GARDENA smart Gateway (MT7688)"; aliases { serial0 = &uart0; @@ -97,7 +97,7 @@ spi-flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash", "jedec,spi-nor"; + compatible = "jedec,spi-nor"; spi-max-frequency = <40000000>; reg = <0>; }; diff --git a/arch/mips/dts/jr2_pcb110.dts b/arch/mips/dts/jr2_pcb110.dts index ddc30ff76a9..6562221794e 100644 --- a/arch/mips/dts/jr2_pcb110.dts +++ b/arch/mips/dts/jr2_pcb110.dts @@ -5,6 +5,7 @@ /dts-v1/; #include "mscc,jr2.dtsi" +#include <dt-bindings/mscc/jr2_data.h> / { model = "Jaguar2 Cu8-Sfp16 PCB110 Reference Board"; @@ -43,7 +44,7 @@ &spi0 { status = "okay"; spi-flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <18000000>; /* input clock */ reg = <0>; /* CS0 */ }; @@ -72,3 +73,78 @@ sgpio-ports = <0x3f00ffff>; gpio-ranges = <&sgpio2 0 0 96>; }; + +&mdio1 { + status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + }; + phy1: ethernet-phy@1 { + reg = <1>; + }; + phy2: ethernet-phy@2 { + reg = <2>; + }; + phy3: ethernet-phy@3 { + reg = <3>; + }; + phy4: ethernet-phy@4 { + reg = <4>; + }; + phy5: ethernet-phy@5 { + reg = <5>; + }; + phy6: ethernet-phy@6 { + reg = <6>; + }; + phy7: ethernet-phy@7 { + reg = <7>; + }; +}; + +&switch { + ethernet-ports { + + port0: port@0 { + reg = <0>; + phy-handle = <&phy0>; + phys = <&serdes_hsio 0 SERDES1G(1) PHY_MODE_SGMII>; + }; + port1: port@1 { + reg = <1>; + phy-handle = <&phy1>; + phys = <&serdes_hsio 1 SERDES1G(2) PHY_MODE_SGMII>; + }; + port2: port@2 { + reg = <2>; + phy-handle = <&phy2>; + phys = <&serdes_hsio 2 SERDES1G(3) PHY_MODE_SGMII>; + }; + port3: port@3 { + reg = <3>; + phy-handle = <&phy3>; + phys = <&serdes_hsio 3 SERDES1G(4) PHY_MODE_SGMII>; + }; + port4: port@4 { + reg = <4>; + phy-handle = <&phy4>; + phys = <&serdes_hsio 4 SERDES1G(5) PHY_MODE_SGMII>; + }; + port5: port@5 { + reg = <5>; + phy-handle = <&phy5>; + phys = <&serdes_hsio 5 SERDES1G(6) PHY_MODE_SGMII>; + }; + port6: port@6 { + reg = <6>; + phy-handle = <&phy6>; + phys = <&serdes_hsio 6 SERDES1G(7) PHY_MODE_SGMII>; + }; + port7: port@7 { + reg = <7>; + phy-handle = <&phy7>; + phys = <&serdes_hsio 7 SERDES1G(8) PHY_MODE_SGMII>; + }; + }; +}; diff --git a/arch/mips/dts/jr2_pcb111.dts b/arch/mips/dts/jr2_pcb111.dts index 4d411b6dc4e..74305a8f331 100644 --- a/arch/mips/dts/jr2_pcb111.dts +++ b/arch/mips/dts/jr2_pcb111.dts @@ -5,6 +5,7 @@ /dts-v1/; #include "mscc,jr2.dtsi" +#include <dt-bindings/mscc/jr2_data.h> / { model = "Jaguar2 Cu48 PCB111 Reference Board"; @@ -43,7 +44,7 @@ &spi0 { status = "okay"; spi-flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <18000000>; /* input clock */ reg = <0>; /* CS0 */ }; @@ -72,3 +73,402 @@ sgpio-ports = <0xff000000>; gpio-ranges = <&sgpio2 0 0 96>; }; + +&mdio1 { + status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + }; + phy1: ethernet-phy@1 { + reg = <1>; + }; + phy2: ethernet-phy@2 { + reg = <2>; + }; + phy3: ethernet-phy@3 { + reg = <3>; + }; + phy4: ethernet-phy@4 { + reg = <4>; + }; + phy5: ethernet-phy@5 { + reg = <5>; + }; + phy6: ethernet-phy@6 { + reg = <6>; + }; + phy7: ethernet-phy@7 { + reg = <7>; + }; + phy8: ethernet-phy@8 { + reg = <8>; + }; + phy9: ethernet-phy@9 { + reg = <9>; + }; + phy10: ethernet-phy@10 { + reg = <10>; + }; + phy11: ethernet-phy@11 { + reg = <11>; + }; + phy12: ethernet-phy@12 { + reg = <12>; + }; + phy13: ethernet-phy@13 { + reg = <13>; + }; + phy14: ethernet-phy@14 { + reg = <14>; + }; + phy15: ethernet-phy@15 { + reg = <15>; + }; + phy16: ethernet-phy@16 { + reg = <16>; + }; + phy17: ethernet-phy@17 { + reg = <17>; + }; + phy18: ethernet-phy@18 { + reg = <18>; + }; + phy19: ethernet-phy@19 { + reg = <19>; + }; + phy20: ethernet-phy@20 { + reg = <20>; + }; + phy21: ethernet-phy@21 { + reg = <21>; + }; + phy22: ethernet-phy@22 { + reg = <22>; + }; + phy23: ethernet-phy@23 { + reg = <23>; + }; +}; + +&mdio2 { + status = "okay"; + + phy24: ethernet-phy@24 { + reg = <0>; + }; + phy25: ethernet-phy@25 { + reg = <1>; + }; + phy26: ethernet-phy@26 { + reg = <2>; + }; + phy27: ethernet-phy@27 { + reg = <3>; + }; + phy28: ethernet-phy@28 { + reg = <4>; + }; + phy29: ethernet-phy@29 { + reg = <5>; + }; + phy30: ethernet-phy@30 { + reg = <6>; + }; + phy31: ethernet-phy@31 { + reg = <7>; + }; + phy32: ethernet-phy@32 { + reg = <8>; + }; + phy33: ethernet-phy@33 { + reg = <9>; + }; + phy34: ethernet-phy@34 { + reg = <10>; + }; + phy35: ethernet-phy@35 { + reg = <11>; + }; + phy36: ethernet-phy@36 { + reg = <12>; + }; + phy37: ethernet-phy@37 { + reg = <13>; + }; + phy38: ethernet-phy@38 { + reg = <14>; + }; + phy39: ethernet-phy@39 { + reg = <15>; + }; + phy40: ethernet-phy@40 { + reg = <16>; + }; + phy41: ethernet-phy@41 { + reg = <17>; + }; + phy42: ethernet-phy@42 { + reg = <18>; + }; + phy43: ethernet-phy@43 { + reg = <19>; + }; + phy44: ethernet-phy@44 { + reg = <20>; + }; + phy45: ethernet-phy@45 { + reg = <21>; + }; + phy46: ethernet-phy@46 { + reg = <22>; + }; + phy47: ethernet-phy@47 { + reg = <23>; + }; +}; + +&switch { + ethernet-ports { + port0: port@0 { + reg = <0>; + phy-handle = <&phy0>; + phys = <&serdes_hsio 0 SERDES6G(4) PHY_MODE_QSGMII>; + }; + port1: port@1 { + reg = <1>; + phy-handle = <&phy1>; + phys = <&serdes_hsio 1 0xff PHY_MODE_QSGMII>; + }; + port2: port@2 { + reg = <2>; + phy-handle = <&phy2>; + phys = <&serdes_hsio 2 0xff PHY_MODE_QSGMII>; + }; + port3: port@3 { + reg = <3>; + phy-handle = <&phy3>; + phys = <&serdes_hsio 3 0xff PHY_MODE_QSGMII>; + }; + port4: port@4 { + reg = <4>; + phy-handle = <&phy4>; + phys = <&serdes_hsio 4 SERDES6G(5) PHY_MODE_QSGMII>; + }; + port5: port@5 { + reg = <5>; + phy-handle = <&phy5>; + phys = <&serdes_hsio 5 0xff PHY_MODE_QSGMII>; + }; + port6: port@6 { + reg = <6>; + phy-handle = <&phy6>; + phys = <&serdes_hsio 6 0xff PHY_MODE_QSGMII>; + }; + port7: port@7 { + reg = <7>; + phy-handle = <&phy7>; + phys = <&serdes_hsio 7 0xff PHY_MODE_QSGMII>; + }; + port8: port@8 { + reg = <8>; + phy-handle = <&phy8>; + phys = <&serdes_hsio 8 SERDES6G(6) PHY_MODE_QSGMII>; + }; + port9: port@9 { + reg = <9>; + phy-handle = <&phy9>; + phys = <&serdes_hsio 9 0xff PHY_MODE_QSGMII>; + }; + port10: port@10 { + reg = <10>; + phy-handle = <&phy10>; + phys = <&serdes_hsio 10 0xff PHY_MODE_QSGMII>; + }; + port11: port@11 { + reg = <11>; + phy-handle = <&phy11>; + phys = <&serdes_hsio 11 0xff PHY_MODE_QSGMII>; + }; + port12: port@12 { + reg = <12>; + phy-handle = <&phy12>; + phys = <&serdes_hsio 12 SERDES6G(7) PHY_MODE_QSGMII>; + }; + port13: port@13 { + reg = <13>; + phy-handle = <&phy13>; + phys = <&serdes_hsio 13 0xff PHY_MODE_QSGMII>; + }; + port14: port@14 { + reg = <14>; + phy-handle = <&phy14>; + phys = <&serdes_hsio 14 0xff PHY_MODE_QSGMII>; + }; + port15: port@15 { + reg = <15>; + phy-handle = <&phy15>; + phys = <&serdes_hsio 15 0xff PHY_MODE_QSGMII>; + }; + port16: port@16 { + reg = <16>; + phy-handle = <&phy16>; + phys = <&serdes_hsio 16 SERDES6G(8) PHY_MODE_QSGMII>; + }; + port17: port@17 { + reg = <17>; + phy-handle = <&phy17>; + phys = <&serdes_hsio 17 0xff PHY_MODE_QSGMII>; + }; + port18: port@18 { + reg = <18>; + phy-handle = <&phy18>; + phys = <&serdes_hsio 18 0xff PHY_MODE_QSGMII>; + }; + port19: port@19 { + reg = <19>; + phy-handle = <&phy19>; + phys = <&serdes_hsio 19 0xff PHY_MODE_QSGMII>; + }; + port20: port@20 { + reg = <20>; + phy-handle = <&phy20>; + phys = <&serdes_hsio 20 SERDES6G(9) PHY_MODE_QSGMII>; + }; + port21: port@21 { + reg = <21>; + phy-handle = <&phy21>; + phys = <&serdes_hsio 21 0xff PHY_MODE_QSGMII>; + }; + port22: port@22 { + reg = <22>; + phy-handle = <&phy22>; + phys = <&serdes_hsio 22 0xff PHY_MODE_QSGMII>; + }; + port23: port@23 { + reg = <23>; + phy-handle = <&phy23>; + phys = <&serdes_hsio 23 0xff PHY_MODE_QSGMII>; + }; + port24: port@24 { + reg = <24>; + phy-handle = <&phy24>; + phys = <&serdes_hsio 24 SERDES6G(10) PHY_MODE_QSGMII>; + }; + port25: port@25 { + reg = <25>; + phy-handle = <&phy25>; + phys = <&serdes_hsio 25 0xff PHY_MODE_QSGMII>; + }; + port26: port@26 { + reg = <26>; + phy-handle = <&phy26>; + phys = <&serdes_hsio 26 0xff PHY_MODE_QSGMII>; + }; + port27: port@27 { + reg = <27>; + phy-handle = <&phy27>; + phys = <&serdes_hsio 27 0xff PHY_MODE_QSGMII>; + }; + port28: port@28 { + reg = <28>; + phy-handle = <&phy28>; + phys = <&serdes_hsio 28 SERDES6G(11) PHY_MODE_QSGMII>; + }; + port29: port@29 { + reg = <29>; + phy-handle = <&phy29>; + phys = <&serdes_hsio 29 0xff PHY_MODE_QSGMII>; + }; + port30: port@30 { + reg = <30>; + phy-handle = <&phy30>; + phys = <&serdes_hsio 30 0xff PHY_MODE_QSGMII>; + }; + port31: port@31 { + reg = <31>; + phy-handle = <&phy31>; + phys = <&serdes_hsio 31 0xff PHY_MODE_QSGMII>; + }; + port32: port@32 { + reg = <32>; + phy-handle = <&phy32>; + phys = <&serdes_hsio 32 SERDES6G(12) PHY_MODE_QSGMII>; + }; + port33: port@33 { + reg = <33>; + phy-handle = <&phy33>; + phys = <&serdes_hsio 33 0xff PHY_MODE_QSGMII>; + }; + port34: port@34 { + reg = <34>; + phy-handle = <&phy34>; + phys = <&serdes_hsio 34 0xff PHY_MODE_QSGMII>; + }; + port35: port@35 { + reg = <35>; + phy-handle = <&phy35>; + phys = <&serdes_hsio 35 0xff PHY_MODE_QSGMII>; + }; + port36: port@36 { + reg = <36>; + phy-handle = <&phy36>; + phys = <&serdes_hsio 36 SERDES6G(13) PHY_MODE_QSGMII>; + }; + port37: port@37 { + reg = <37>; + phy-handle = <&phy37>; + phys = <&serdes_hsio 37 0xff PHY_MODE_QSGMII>; + }; + port38: port@38 { + reg = <38>; + phy-handle = <&phy38>; + phys = <&serdes_hsio 38 0xff PHY_MODE_QSGMII>; + }; + port39: port@39 { + reg = <39>; + phy-handle = <&phy39>; + phys = <&serdes_hsio 39 0xff PHY_MODE_QSGMII>; + }; + port40: port@40 { + reg = <40>; + phy-handle = <&phy40>; + phys = <&serdes_hsio 40 SERDES6G(14) PHY_MODE_QSGMII>; + }; + port41: port@41 { + reg = <41>; + phy-handle = <&phy41>; + phys = <&serdes_hsio 41 0xff PHY_MODE_QSGMII>; + }; + port42: port@42 { + reg = <42>; + phy-handle = <&phy42>; + phys = <&serdes_hsio 42 0xff PHY_MODE_QSGMII>; + }; + port43: port@43 { + reg = <43>; + phy-handle = <&phy43>; + phys = <&serdes_hsio 43 0xff PHY_MODE_QSGMII>; + }; + port44: port@44 { + reg = <44>; + phy-handle = <&phy44>; + phys = <&serdes_hsio 44 SERDES6G(15) PHY_MODE_QSGMII>; + }; + port45: port@45 { + reg = <45>; + phy-handle = <&phy45>; + phys = <&serdes_hsio 45 0xff PHY_MODE_QSGMII>; + }; + port46: port@46 { + reg = <46>; + phy-handle = <&phy46>; + phys = <&serdes_hsio 46 0xff PHY_MODE_QSGMII>; + }; + port47: port@47 { + reg = <47>; + phy-handle = <&phy47>; + phys = <&serdes_hsio 47 0xff PHY_MODE_QSGMII>; + }; + }; +}; diff --git a/arch/mips/dts/linkit-smart-7688.dts b/arch/mips/dts/linkit-smart-7688.dts index c9db136f30f..bb104021747 100644 --- a/arch/mips/dts/linkit-smart-7688.dts +++ b/arch/mips/dts/linkit-smart-7688.dts @@ -38,7 +38,7 @@ spi-flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash", "jedec,spi-nor"; + compatible = "jedec,spi-nor"; spi-max-frequency = <25000000>; reg = <0>; }; diff --git a/arch/mips/dts/luton_pcb090.dts b/arch/mips/dts/luton_pcb090.dts index 315172b19c5..fe457bae9d5 100644 --- a/arch/mips/dts/luton_pcb090.dts +++ b/arch/mips/dts/luton_pcb090.dts @@ -48,7 +48,7 @@ &spi0 { status = "okay"; spi-flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <18000000>; /* input clock */ reg = <0>; /* CS0 */ spi-cs-high; diff --git a/arch/mips/dts/luton_pcb091.dts b/arch/mips/dts/luton_pcb091.dts index 9b4d628797e..f684cc8dd63 100644 --- a/arch/mips/dts/luton_pcb091.dts +++ b/arch/mips/dts/luton_pcb091.dts @@ -54,7 +54,7 @@ &spi0 { status = "okay"; spi-flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <18000000>; /* input clock */ reg = <0>; /* CS0 */ spi-cs-high; diff --git a/arch/mips/dts/mscc,jr2.dtsi b/arch/mips/dts/mscc,jr2.dtsi index 090092607b5..7f5a96fecdc 100644 --- a/arch/mips/dts/mscc,jr2.dtsi +++ b/arch/mips/dts/mscc,jr2.dtsi @@ -183,5 +183,121 @@ gpio-bank-name = "sgpio2_"; sgpio-clock = <0x14>; }; + + switch: switch@1010000 { + compatible = "mscc,vsc7454-switch"; + reg = <0x01040000 0x0100>, // VTSS_TO_DEV_0 + <0x01050000 0x0100>, // VTSS_TO_DEV_1 + <0x01060000 0x0100>, // VTSS_TO_DEV_2 + <0x01070000 0x0100>, // VTSS_TO_DEV_3 + <0x01080000 0x0100>, // VTSS_TO_DEV_4 + <0x01090000 0x0100>, // VTSS_TO_DEV_5 + <0x010a0000 0x0100>, // VTSS_TO_DEV_6 + <0x010b0000 0x0100>, // VTSS_TO_DEV_7 + <0x010c0000 0x0100>, // VTSS_TO_DEV_8 + <0x010d0000 0x0100>, // VTSS_TO_DEV_9 + <0x010e0000 0x0100>, // VTSS_TO_DEV_10 + <0x010f0000 0x0100>, // VTSS_TO_DEV_11 + <0x01100000 0x0100>, // VTSS_TO_DEV_12 + <0x01110000 0x0100>, // VTSS_TO_DEV_13 + <0x01120000 0x0100>, // VTSS_TO_DEV_14 + <0x01130000 0x0100>, // VTSS_TO_DEV_15 + <0x01140000 0x0100>, // VTSS_TO_DEV_16 + <0x01150000 0x0100>, // VTSS_TO_DEV_17 + <0x01160000 0x0100>, // VTSS_TO_DEV_18 + <0x01170000 0x0100>, // VTSS_TO_DEV_19 + <0x01180000 0x0100>, // VTSS_TO_DEV_20 + <0x01190000 0x0100>, // VTSS_TO_DEV_21 + <0x011a0000 0x0100>, // VTSS_TO_DEV_22 + <0x011b0000 0x0100>, // VTSS_TO_DEV_23 + <0x011c0000 0x0100>, // VTSS_TO_DEV_24 + <0x011d0000 0x0100>, // VTSS_TO_DEV_25 + <0x011e0000 0x0100>, // VTSS_TO_DEV_26 + <0x011f0000 0x0100>, // VTSS_TO_DEV_27 + <0x01200000 0x0100>, // VTSS_TO_DEV_28 + <0x01210000 0x0100>, // VTSS_TO_DEV_29 + <0x01220000 0x0100>, // VTSS_TO_DEV_30 + <0x01230000 0x0100>, // VTSS_TO_DEV_31 + <0x01240000 0x0100>, // VTSS_TO_DEV_32 + <0x01250000 0x0100>, // VTSS_TO_DEV_33 + <0x01260000 0x0100>, // VTSS_TO_DEV_34 + <0x01270000 0x0100>, // VTSS_TO_DEV_35 + <0x01280000 0x0100>, // VTSS_TO_DEV_36 + <0x01290000 0x0100>, // VTSS_TO_DEV_37 + <0x012a0000 0x0100>, // VTSS_TO_DEV_38 + <0x012b0000 0x0100>, // VTSS_TO_DEV_39 + <0x012c0000 0x0100>, // VTSS_TO_DEV_40 + <0x012d0000 0x0100>, // VTSS_TO_DEV_41 + <0x012e0000 0x0100>, // VTSS_TO_DEV_42 + <0x012f0000 0x0100>, // VTSS_TO_DEV_43 + <0x01300000 0x0100>, // VTSS_TO_DEV_44 + <0x01310000 0x0100>, // VTSS_TO_DEV_45 + <0x01320000 0x0100>, // VTSS_TO_DEV_46 + <0x01330000 0x0100>, // VTSS_TO_DEV_47 + <0x01f00000 0x100000>, // ANA_AC + <0x01d00000 0x100000>, // ANA_CL + <0x01e00000 0x100000>, // ANA_L2 + <0x01410000 0x10000>, // ASM + <0x01460000 0x10000>, // HSIO + <0x01420000 0x00000>, // LRN + <0x017d0000 0x10000>, // QFWD + <0x01020000 0x20000>, // QS + <0x017e0000 0x10000>, // QSYS + <0x01b00000 0x80000>; // REW + reg-names = "port0", "port1", "port2", "port3", "port4", + "port5", "port6", "port7", "port8", "port9", + "port10", "port11", "port12", "port13", + "port14", "port15", "port16", "port17", + "port18", "port19", "port20", "port21", + "port22", "port23", "port24", "port25", + "port26", "port27", "port28", "port29", + "port30", "port31", "port32", "port33", + "port34", "port35", "port36", "port37", + "port38", "port39", "port40", "port41", + "port42", "port43", "port44", "port45", + "port46", "port47", "ana_ac", "ana_cl", + "ana_l2", "asm", "hsio", "lrn", "qfwd", + "qs", "qsys", "rew"; + status = "okay"; + + ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + mdio0: mdio@010100c8 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mscc,jr2-miim"; + reg = <0x010100c8 0x24>; + status = "disabled"; + }; + + mdio1: mdio@010100ec { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mscc,jr2-miim"; + reg = <0x010100ec 0x24>; + status = "disabled"; + }; + + mdio2: mdio@01010110 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mscc,jr2-miim"; + reg = <0x01010110 0x24>; + status = "disabled"; + }; + + hsio: syscon@10d0000 { + compatible = "mscc,jr2-hsio", "syscon", "simple-mfd"; + reg = <0x10d0000 0x10000>; + + serdes_hsio: serdes_hsio { + compatible = "mscc,vsc7454-serdes"; + #phy-cells = <3>; + }; + }; }; }; diff --git a/arch/mips/dts/mscc,ocelot_pcb.dtsi b/arch/mips/dts/mscc,ocelot_pcb.dtsi index 90725d3b941..885b5643f7c 100644 --- a/arch/mips/dts/mscc,ocelot_pcb.dtsi +++ b/arch/mips/dts/mscc,ocelot_pcb.dtsi @@ -29,7 +29,7 @@ pinctrl-names = "default"; spi-flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <18000000>; /* input clock */ reg = <0>; /* CS0 */ }; diff --git a/arch/mips/dts/mscc,servalt.dtsi b/arch/mips/dts/mscc,servalt.dtsi index 4beb7a38d0c..45ae2de5e87 100644 --- a/arch/mips/dts/mscc,servalt.dtsi +++ b/arch/mips/dts/mscc,servalt.dtsi @@ -145,5 +145,45 @@ #gpio-cells = <2>; gpio-ranges = <&sgpio 0 0 128>; }; + + switch: switch@1010000 { + compatible = "mscc,vsc7437-switch"; + reg = <0x01030000 0x0100>, // VTSS_TO_DEV_0 + <0x01040000 0x0100>, // VTSS_TO_DEV_1 + <0x01f00000 0x100000>, // ANA_AC + <0x01d00000 0x100000>, // ANA_CL + <0x01e00000 0x100000>, // ANA_L2 + <0x01120000 0x10000>, // ASM + <0x01130000 0x00000>, // LRN + <0x017d0000 0x10000>, // QFWD + <0x01020000 0x20000>, // QS + <0x017e0000 0x10000>, // QSYS + <0x01b00000 0x80000>; // REW + reg-names = "port0", "port1", + "ana_ac", "ana_cl", "ana_l2", "asm", "lrn", + "qfwd", "qs", "qsys", "rew"; + status = "okay"; + + ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + mdio0: mdio@010100c4 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mscc,jr2-miim"; + reg = <0x010100c4 0x24>; + status = "disabled"; + }; + + mdio1: mdio@010100e8 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mscc,jr2-miim"; + reg = <0x010100e8 0x24>; + status = "disabled"; + }; }; }; diff --git a/arch/mips/dts/netgear,cg3100d.dts b/arch/mips/dts/netgear,cg3100d.dts index a3d4cd56a23..a42a0da2dd6 100644 --- a/arch/mips/dts/netgear,cg3100d.dts +++ b/arch/mips/dts/netgear,cg3100d.dts @@ -93,7 +93,7 @@ status = "okay"; spi-flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/dts/qca953x.dtsi b/arch/mips/dts/qca953x.dtsi index ba29ea287e2..90d34ddbbfb 100644 --- a/arch/mips/dts/qca953x.dtsi +++ b/arch/mips/dts/qca953x.dtsi @@ -65,6 +65,37 @@ status = "disabled"; }; + + gmac0: eth0@0x19000000 { + compatible = "qca,ag953x-mac"; + reg = <0x19000000 0x200>; + phy = <&phy4>; + phy-mode = "rmii"; + + status = "disabled"; + }; + + gmac1: eth1@0x1a000000 { + compatible = "qca,ag953x-mac"; + reg = <0x1a000000 0x200>; + phy = <&phy0>; + phy-mode = "rgmii"; + + status = "disabled"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@0 { + reg = <0>; + phy-mode = "rmii"; + }; + phy4: ethernet-phy@4 { + reg = <4>; + phy-mode = "rmii"; + }; + }; + }; }; spi0: spi@1f000000 { diff --git a/arch/mips/dts/qca956x.dtsi b/arch/mips/dts/qca956x.dtsi new file mode 100644 index 00000000000..6cb360b3f86 --- /dev/null +++ b/arch/mips/dts/qca956x.dtsi @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Rosy Song <rosysong@rosinson.com> + */ + +#include "skeleton.dtsi" + +/ { + compatible = "qca,qca956x"; + + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "mips,mips74Kc"; + reg = <0>; + }; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + xtal: xtal { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-output-names = "xtal"; + }; + }; + + ahb { + compatible = "simple-bus"; + ranges; + + #address-cells = <1>; + #size-cells = <1>; + + apb { + compatible = "simple-bus"; + ranges; + + #address-cells = <1>; + #size-cells = <1>; + + uart0: uart@18020000 { + compatible = "ns16550"; + reg = <0x18020000 0x20>; + reg-shift = <2>; + + status = "disabled"; + }; + + gmac0: eth@0x19000000 { + compatible = "qca,ag956x-mac"; + reg = <0x19000000 0x200>; + phy = <&phy0>; + phy-mode = "sgmii"; + + status = "disabled"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@0 { + reg = <0>; + }; + }; + }; + }; + + spi0: spi@1f000000 { + compatible = "qca,ar7100-spi"; + reg = <0x1f000000 0x10>; + + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; diff --git a/arch/mips/dts/sagem,f@st1704.dts b/arch/mips/dts/sagem,f@st1704.dts index ec6846dd9f2..98ed353f207 100644 --- a/arch/mips/dts/sagem,f@st1704.dts +++ b/arch/mips/dts/sagem,f@st1704.dts @@ -59,7 +59,7 @@ status = "okay"; spi-flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/dts/serval2_pcb112.dts b/arch/mips/dts/serval2_pcb112.dts index fe025f4c42a..5777a773b17 100644 --- a/arch/mips/dts/serval2_pcb112.dts +++ b/arch/mips/dts/serval2_pcb112.dts @@ -5,6 +5,7 @@ /dts-v1/; #include "mscc,jr2.dtsi" +#include <dt-bindings/mscc/jr2_data.h> / { model = "Serval2 NID PCB112 Reference Board"; @@ -43,7 +44,7 @@ &spi0 { status = "okay"; spi-flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <18000000>; /* input clock */ reg = <0>; /* CS0 */ }; @@ -58,3 +59,46 @@ status = "okay"; sgpio-ports = <0x3fe0ffff>; }; + +&mdio0 { + status = "okay"; + + phy16: ethernet-phy@16 { + reg = <16>; + }; + phy17: ethernet-phy@17 { + reg = <17>; + }; + phy18: ethernet-phy@18 { + reg = <18>; + }; + phy19: ethernet-phy@19 { + reg = <19>; + }; +}; + +&switch { + ethernet-ports { + + port0: port@0 { + reg = <24>; + phy-handle = <&phy16>; + phys = <&serdes_hsio 24 SERDES6G(0) PHY_MODE_SGMII>; + }; + port1: port@1 { + reg = <25>; + phy-handle = <&phy17>; + phys = <&serdes_hsio 25 SERDES6G(1) PHY_MODE_SGMII>; + }; + port2: port@2 { + reg = <26>; + phy-handle = <&phy18>; + phys = <&serdes_hsio 26 SERDES6G(2) PHY_MODE_SGMII>; + }; + port3: port@3 { + reg = <27>; + phy-handle = <&phy19>; + phys = <&serdes_hsio 27 SERDES6G(3) PHY_MODE_SGMII>; + }; + }; +}; diff --git a/arch/mips/dts/serval_pcb105.dts b/arch/mips/dts/serval_pcb105.dts index d0d6facba22..1598669447f 100644 --- a/arch/mips/dts/serval_pcb105.dts +++ b/arch/mips/dts/serval_pcb105.dts @@ -43,7 +43,7 @@ &spi0 { status = "okay"; spi-flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <18000000>; /* input clock */ reg = <0>; /* CS0 */ spi-cs-high; diff --git a/arch/mips/dts/serval_pcb106.dts b/arch/mips/dts/serval_pcb106.dts index 11982498d71..fb3524bb31e 100644 --- a/arch/mips/dts/serval_pcb106.dts +++ b/arch/mips/dts/serval_pcb106.dts @@ -43,7 +43,7 @@ &spi0 { status = "okay"; spi-flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <18000000>; /* input clock */ reg = <0>; /* CS0 */ spi-cs-high; diff --git a/arch/mips/dts/servalt_pcb116.dts b/arch/mips/dts/servalt_pcb116.dts index fb3331204b3..313b0998e6b 100644 --- a/arch/mips/dts/servalt_pcb116.dts +++ b/arch/mips/dts/servalt_pcb116.dts @@ -43,7 +43,7 @@ &spi0 { status = "okay"; spi-flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <18000000>; /* input clock */ reg = <0>; /* CS0 */ spi-cs-high; @@ -54,3 +54,28 @@ status = "okay"; sgpio-ports = <0x0000fe7f>; }; + +&mdio0 { + status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + }; + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; + +&switch { + ethernet-ports { + + port0: port@0 { + reg = <0>; + phy-handle = <&phy0>; + }; + port1: port@1 { + reg = <1>; + phy-handle = <&phy1>; + }; + }; +}; diff --git a/arch/mips/dts/tplink_wdr4300.dts b/arch/mips/dts/tplink_wdr4300.dts index 96cf0da5bfb..2bcad6d201b 100644 --- a/arch/mips/dts/tplink_wdr4300.dts +++ b/arch/mips/dts/tplink_wdr4300.dts @@ -35,7 +35,7 @@ spi-flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; memory-map = <0x1e000000 0x00800000>; spi-max-frequency = <25000000>; reg = <0>; diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index deca5189e33..35152cb3f64 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -215,23 +215,6 @@ static void linux_env_legacy(bootm_headers_t *images) } } -static int boot_reloc_ramdisk(bootm_headers_t *images) -{ - ulong rd_len = images->rd_end - images->rd_start; - - /* - * In case of legacy uImage's, relocation of ramdisk is already done - * by do_bootm_states() and should not repeated in 'bootm prep'. - */ - if (images->state & BOOTM_STATE_RAMDISK) { - debug("## Ramdisk already relocated\n"); - return 0; - } - - return boot_ramdisk_high(&images->lmb, images->rd_start, - rd_len, &images->initrd_start, &images->initrd_end); -} - static int boot_reloc_fdt(bootm_headers_t *images) { /* @@ -270,8 +253,6 @@ static int boot_setup_fdt(bootm_headers_t *images) static void boot_prep_linux(bootm_headers_t *images) { - boot_reloc_ramdisk(images); - if (CONFIG_IS_ENABLED(MIPS_BOOT_FDT) && images->ft_len) { boot_reloc_fdt(images); boot_setup_fdt(images); diff --git a/arch/mips/mach-ath79/Kconfig b/arch/mips/mach-ath79/Kconfig index bc86f591df8..bdb23b57658 100644 --- a/arch/mips/mach-ath79/Kconfig +++ b/arch/mips/mach-ath79/Kconfig @@ -33,6 +33,15 @@ config SOC_QCA953X help This supports QCA/Atheros qca953x family SOCs. +config SOC_QCA956X + bool + select MIPS_TUNE_74KC + select SUPPORTS_BIG_ENDIAN + select SUPPORTS_CPU_MIPS32_R1 + select SUPPORTS_CPU_MIPS32_R2 + help + This supports QCA/Atheros qca956x family SOCs. + choice prompt "Board select" @@ -44,6 +53,10 @@ config TARGET_AP143 bool "AP143 Reference Board" select SOC_QCA953X +config TARGET_AP152 + bool "AP152 Reference Board" + select SOC_QCA956X + config BOARD_TPLINK_WDR4300 bool "TP-Link WDR4300 Board" select SOC_AR934X @@ -52,6 +65,7 @@ endchoice source "board/qca/ap121/Kconfig" source "board/qca/ap143/Kconfig" +source "board/qca/ap152/Kconfig" source "board/tplink/wdr4300/Kconfig" endmenu diff --git a/arch/mips/mach-ath79/Makefile b/arch/mips/mach-ath79/Makefile index 7aa40c65d30..fbd40c02bec 100644 --- a/arch/mips/mach-ath79/Makefile +++ b/arch/mips/mach-ath79/Makefile @@ -7,3 +7,4 @@ obj-y += dram.o obj-$(CONFIG_SOC_AR933X) += ar933x/ obj-$(CONFIG_SOC_AR934X) += ar934x/ obj-$(CONFIG_SOC_QCA953X) += qca953x/ +obj-$(CONFIG_SOC_QCA956X) += qca956x/ diff --git a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h index 5d371bb5828..5888f6eb288 100644 --- a/arch/mips/mach-ath79/include/mach/ar71xx_regs.h +++ b/arch/mips/mach-ath79/include/mach/ar71xx_regs.h @@ -194,6 +194,9 @@ #define QCA956X_WMAC_BASE \ (AR71XX_APB_BASE + 0x00100000) #define QCA956X_WMAC_SIZE 0x20000 +#define QCA956X_RTC_BASE \ + (AR71XX_APB_BASE + 0x00107000) +#define QCA956X_RTC_SIZE 0x1000 #define QCA956X_EHCI0_BASE 0x1b000000 #define QCA956X_EHCI1_BASE 0x1b400000 #define QCA956X_EHCI_SIZE 0x200 @@ -201,6 +204,10 @@ (AR71XX_APB_BASE + 0x00070000) #define QCA956X_GMAC_SIZE 0x64 +#define QCA956X_SRIF_BASE \ + (AR71XX_APB_BASE + 0x00116000) +#define QCA956X_SRIF_SIZE 0x1000 + /* * DDR_CTRL block */ @@ -278,6 +285,18 @@ #define QCA953X_DDR_REG_CTL_CONF 0x108 #define QCA953X_DDR_REG_CONFIG3 0x15c +#define QCA956X_DDR_REG_TAP_CTRL2 0x24 +#define QCA956X_DDR_REG_TAP_CTRL3 0x28 +#define QCA956X_DDR_REG_DDR2_CONFIG 0xb8 +#define QCA956X_DDR_REG_DDR2_EMR2 0xbc +#define QCA956X_DDR_REG_DDR2_EMR3 0xc0 +#define QCA956X_DDR_REG_BURST 0xc4 +#define QCA956X_DDR_REG_BURST2 0xc8 +#define QCA956X_DDR_REG_TIMEOUT_MAX 0xcc +#define QCA956X_DDR_REG_FSM_WAIT_CTRL 0xe4 +#define QCA956X_DDR_REG_CTL_CONF 0x108 +#define QCA956X_DDR_REG_DDR3_CONFIG 0x15c + /* * PLL block */ @@ -519,6 +538,13 @@ #define QCA956X_PLL_DDR_CONFIG_REG 0x08 #define QCA956X_PLL_DDR_CONFIG1_REG 0x0c #define QCA956X_PLL_CLK_CTRL_REG 0x10 +#define QCA956X_PLL_SWITCH_CLK_CTRL_REG 0x28 +#define QCA956X_PLL_ETH_XMII_CTRL_REG 0x30 +#define QCA956X_PLL_DDR_DIT_FRAC_REG 0x38 +#define QCA956X_PLL_DDR_DIT2_FRAC_REG 0x3c +#define QCA956X_PLL_CPU_DIT_FRAC_REG 0x40 +#define QCA956X_PLL_CPU_DIT2_FRAC_REG 0x44 +#define QCA956X_PLL_ETH_SGMII_SERDES_REG 0x4c #define QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT 12 #define QCA956X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f @@ -528,7 +554,7 @@ #define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT 0 #define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK 0x1f #define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT 5 -#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK 0x3fff +#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK 0x1fff #define QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT 18 #define QCA956X_PLL_CPU_CONFIG1_NINT_MASK 0x1ff @@ -540,7 +566,7 @@ #define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT 0 #define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK 0x1f #define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT 5 -#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK 0x3fff +#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK 0x1fff #define QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT 18 #define QCA956X_PLL_DDR_CONFIG1_NINT_MASK 0x1ff @@ -756,6 +782,17 @@ #define QCA955X_RESET_MBOX BIT(1) #define QCA955X_RESET_I2S BIT(0) +#define QCA956X_RESET_EXTERNAL BIT(28) +#define QCA956X_RESET_FULL_CHIP BIT(24) +#define QCA956X_RESET_GE1_MDIO BIT(23) /* Reserved in datasheet */ +#define QCA956X_RESET_GE0_MDIO BIT(22) +#define QCA956X_RESET_GE1_MAC BIT(13) /* Reserved in datasheet */ +#define QCA956X_RESET_SGMII_ASSERT BIT(12) +#define QCA956X_RESET_GE0_MAC BIT(9) +#define QCA956X_RESET_SGMII BIT(8) +#define QCA956X_RESET_SGMII_ANALOG BIT(2) +#define QCA956X_RESET_SWITCH BIT(0) + #define AR933X_BOOTSTRAP_MDIO_GPIO_EN BIT(18) #define AR933X_BOOTSTRAP_DDR2 BIT(13) #define AR933X_BOOTSTRAP_EEPBUSY BIT(4) @@ -1099,8 +1136,12 @@ #define QCA953X_GPIO_IN_MUX_UART0_SIN 9 #define QCA953X_GPIO_IN_MUX_SPI_DATA_IN 8 +#define QCA956X_GPIO(x) BIT(x) +#define QCA956X_GPIO_MUX_MASK(x) (0xff << (x)) #define QCA956X_GPIO_OUT_MUX_GE0_MDO 32 #define QCA956X_GPIO_OUT_MUX_GE0_MDC 33 +#define QCA956X_GPIO_IN_MUX_UART0_SIN 0x12 +#define QCA956X_GPIO_OUT_MUX_UART0_SOUT 0x16 #define AR71XX_GPIO_COUNT 16 #define AR7240_GPIO_COUNT 18 @@ -1179,6 +1220,25 @@ #define QCA953X_SRIF_DPLL2_OUTDIV_SHIFT 13 #define QCA953X_SRIF_DPLL2_OUTDIV_MASK 0x7 +#define QCA956X_SRIF_BB_DPLL1_REG 0x180 +#define QCA956X_SRIF_BB_DPLL2_REG 0x184 +#define QCA956X_SRIF_BB_DPLL3_REG 0x188 + +#define QCA956X_SRIF_CPU_DPLL1_REG 0xf00 +#define QCA956X_SRIF_CPU_DPLL2_REG 0xf04 +#define QCA956X_SRIF_CPU_DPLL3_REG 0xf08 + +#define QCA956X_SRIF_DDR_DPLL1_REG 0xec0 +#define QCA956X_SRIF_DDR_DPLL2_REG 0xec4 +#define QCA956X_SRIF_DDR_DPLL3_REG 0xec8 + +#define QCA956X_SRIF_PCIE_DPLL1_REG 0xc80 +#define QCA956X_SRIF_PCIE_DPLL2_REG 0xc84 +#define QCA956X_SRIF_PCIE_DPLL3_REG 0xc88 + +#define QCA956X_SRIF_PMU1_REG 0xcc0 +#define QCA956X_SRIF_PMU2_REG 0xcc4 + /* * MII_CTRL block */ @@ -1261,4 +1321,17 @@ #define QCA955X_ETH_CFG_RGMII_EN BIT(0) #define QCA955X_ETH_CFG_GE0_SGMII BIT(6) +/* + * QCA956X GMAC Interface + */ + +#define QCA956X_GMAC_REG_ETH_CFG 0x00 +#define QCA956X_GMAC_REG_SGMII_RESET 0x14 +#define QCA956X_GMAC_REG_SGMII_SERDES 0x18 +#define QCA956X_GMAC_REG_MR_AN_CTRL 0x1c +#define QCA956X_GMAC_REG_SGMII_CONFIG 0x34 +#define QCA956X_GMAC_REG_SGMII_DEBUG 0x58 + +#define QCA956X_ETH_CFG_GE0_SGMII BIT(6) + #endif /* __ASM_AR71XX_H */ diff --git a/arch/mips/mach-ath79/include/mach/ath79.h b/arch/mips/mach-ath79/include/mach/ath79.h index 5de7a43f79e..0fde5079b16 100644 --- a/arch/mips/mach-ath79/include/mach/ath79.h +++ b/arch/mips/mach-ath79/include/mach/ath79.h @@ -2,6 +2,7 @@ /* * Atheros AR71XX/AR724X/AR913X common definitions * + * Copyright (C) 2018-2019 Rosy Song <rosysong@rosinson.com> * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com> * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> @@ -146,4 +147,6 @@ int ath79_usb_reset(void); void ar934x_pll_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz); void ar934x_ddr_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz); +void qca956x_pll_init(void); +void qca956x_ddr_init(void); #endif /* __ASM_MACH_ATH79_H */ diff --git a/arch/mips/mach-ath79/qca956x/Makefile b/arch/mips/mach-ath79/qca956x/Makefile new file mode 100644 index 00000000000..3f5fc0363f1 --- /dev/null +++ b/arch/mips/mach-ath79/qca956x/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-y += cpu.o +obj-y += clk.o +obj-y += ddr.o qca956x-ddr-tap.o diff --git a/arch/mips/mach-ath79/qca956x/clk.c b/arch/mips/mach-ath79/qca956x/clk.c new file mode 100644 index 00000000000..33a44cfff48 --- /dev/null +++ b/arch/mips/mach-ath79/qca956x/clk.c @@ -0,0 +1,419 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Rosy Song <rosysong@rosinson.com> + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/addrspace.h> +#include <asm/types.h> +#include <mach/ar71xx_regs.h> +#include <mach/ath79.h> +#include <wait_bit.h> + +#define PLL_SRIF_DPLL2_KI_LSB 29 +#define PLL_SRIF_DPLL2_KI_MASK 0x60000000 +#define PLL_SRIF_DPLL2_KI_SET(x) \ + (((x) << PLL_SRIF_DPLL2_KI_LSB) & PLL_SRIF_DPLL2_KI_MASK) +#define PLL_SRIF_DPLL2_KD_LSB 25 +#define PLL_SRIF_DPLL2_KD_MASK 0x1e000000 +#define PLL_SRIF_DPLL2_KD_SET(x) \ + (((x) << PLL_SRIF_DPLL2_KD_LSB) & PLL_SRIF_DPLL2_KD_MASK) +#define PLL_SRIF_DPLL2_PLL_PWD_LSB 22 +#define PLL_SRIF_DPLL2_PLL_PWD_MASK 0x00400000 +#define PLL_SRIF_DPLL2_PLL_PWD_SET(x) \ + (((x) << PLL_SRIF_DPLL2_PLL_PWD_LSB) & PLL_SRIF_DPLL2_PLL_PWD_MASK) +#define PLL_SRIF_DPLL2_OUTDIV_LSB 19 +#define PLL_SRIF_DPLL2_OUTDIV_MASK 0x00380000 +#define PLL_SRIF_DPLL2_OUTDIV_SET(x) \ + (((x) << PLL_SRIF_DPLL2_OUTDIV_LSB) & PLL_SRIF_DPLL2_OUTDIV_MASK) +#define PLL_SRIF_DPLL2_PHASE_SHIFT_LSB 12 +#define PLL_SRIF_DPLL2_PHASE_SHIFT_MASK 0x0007f000 +#define PLL_SRIF_DPLL2_PHASE_SHIFT_SET(x) \ + (((x) << PLL_SRIF_DPLL2_PHASE_SHIFT_LSB) & PLL_SRIF_DPLL2_PHASE_SHIFT_MASK) +#define CPU_PLL_CONFIG_PLLPWD_LSB 30 +#define CPU_PLL_CONFIG_PLLPWD_MASK 0x40000000 +#define CPU_PLL_CONFIG_PLLPWD_SET(x) \ + (((x) << CPU_PLL_CONFIG_PLLPWD_LSB) & CPU_PLL_CONFIG_PLLPWD_MASK) +#define CPU_PLL_CONFIG_OUTDIV_LSB 19 +#define CPU_PLL_CONFIG_OUTDIV_MASK 0x00380000 +#define CPU_PLL_CONFIG_OUTDIV_SET(x) \ + (((x) << CPU_PLL_CONFIG_OUTDIV_LSB) & CPU_PLL_CONFIG_OUTDIV_MASK) +#define CPU_PLL_CONFIG_RANGE_LSB 17 +#define CPU_PLL_CONFIG_RANGE_MASK 0x00060000 +#define CPU_PLL_CONFIG_RANGE_SET(x) \ + (((x) << CPU_PLL_CONFIG_RANGE_LSB) & CPU_PLL_CONFIG_RANGE_MASK) +#define CPU_PLL_CONFIG_REFDIV_LSB 12 +#define CPU_PLL_CONFIG_REFDIV_MASK 0x0001f000 +#define CPU_PLL_CONFIG_REFDIV_SET(x) \ + (((x) << CPU_PLL_CONFIG_REFDIV_LSB) & CPU_PLL_CONFIG_REFDIV_MASK) +#define CPU_PLL_CONFIG1_NINT_LSB 18 +#define CPU_PLL_CONFIG1_NINT_MASK 0x07fc0000 +#define CPU_PLL_CONFIG1_NINT_SET(x) \ + (((x) << CPU_PLL_CONFIG1_NINT_LSB) & CPU_PLL_CONFIG1_NINT_MASK) +#define CPU_PLL_DITHER1_DITHER_EN_LSB 31 +#define CPU_PLL_DITHER1_DITHER_EN_MASK 0x80000000 +#define CPU_PLL_DITHER1_DITHER_EN_SET(x) \ + (((x) << CPU_PLL_DITHER1_DITHER_EN_LSB) & CPU_PLL_DITHER1_DITHER_EN_MASK) +#define CPU_PLL_DITHER1_UPDATE_COUNT_LSB 24 +#define CPU_PLL_DITHER1_UPDATE_COUNT_MASK 0x3f000000 +#define CPU_PLL_DITHER1_UPDATE_COUNT_SET(x) \ + (((x) << CPU_PLL_DITHER1_UPDATE_COUNT_LSB) & CPU_PLL_DITHER1_UPDATE_COUNT_MASK) +#define CPU_PLL_DITHER1_NFRAC_STEP_LSB 18 +#define CPU_PLL_DITHER1_NFRAC_STEP_MASK 0x00fc0000 +#define CPU_PLL_DITHER1_NFRAC_STEP_SET(x) \ + (((x) << CPU_PLL_DITHER1_NFRAC_STEP_LSB) & CPU_PLL_DITHER1_NFRAC_STEP_MASK) +#define CPU_PLL_DITHER1_NFRAC_MIN_LSB 0 +#define CPU_PLL_DITHER1_NFRAC_MIN_MASK 0x0003ffff +#define CPU_PLL_DITHER1_NFRAC_MIN_SET(x) \ + (((x) << CPU_PLL_DITHER1_NFRAC_MIN_LSB) & CPU_PLL_DITHER1_NFRAC_MIN_MASK) +#define CPU_PLL_DITHER2_NFRAC_MAX_LSB 0 +#define CPU_PLL_DITHER2_NFRAC_MAX_MASK 0x0003ffff +#define CPU_PLL_DITHER2_NFRAC_MAX_SET(x) \ + (((x) << CPU_PLL_DITHER2_NFRAC_MAX_LSB) & CPU_PLL_DITHER2_NFRAC_MAX_MASK) +#define DDR_PLL_CONFIG_PLLPWD_LSB 30 +#define DDR_PLL_CONFIG_PLLPWD_MASK 0x40000000 +#define DDR_PLL_CONFIG_PLLPWD_SET(x) \ + (((x) << DDR_PLL_CONFIG_PLLPWD_LSB) & DDR_PLL_CONFIG_PLLPWD_MASK) +#define DDR_PLL_CONFIG_OUTDIV_LSB 23 +#define DDR_PLL_CONFIG_OUTDIV_MASK 0x03800000 +#define DDR_PLL_CONFIG_OUTDIV_SET(x) \ + (((x) << DDR_PLL_CONFIG_OUTDIV_LSB) & DDR_PLL_CONFIG_OUTDIV_MASK) +#define DDR_PLL_CONFIG_RANGE_LSB 21 +#define DDR_PLL_CONFIG_RANGE_MASK 0x00600000 +#define DDR_PLL_CONFIG_RANGE_SET(x) \ + (((x) << DDR_PLL_CONFIG_RANGE_LSB) & DDR_PLL_CONFIG_RANGE_MASK) +#define DDR_PLL_CONFIG_REFDIV_LSB 16 +#define DDR_PLL_CONFIG_REFDIV_MASK 0x001f0000 +#define DDR_PLL_CONFIG_REFDIV_SET(x) \ + (((x) << DDR_PLL_CONFIG_REFDIV_LSB) & DDR_PLL_CONFIG_REFDIV_MASK) +#define DDR_PLL_CONFIG1_NINT_LSB 18 +#define DDR_PLL_CONFIG1_NINT_MASK 0x07fc0000 +#define DDR_PLL_CONFIG1_NINT_SET(x) \ + (((x) << DDR_PLL_CONFIG1_NINT_LSB) & DDR_PLL_CONFIG1_NINT_MASK) +#define DDR_PLL_DITHER1_DITHER_EN_LSB 31 +#define DDR_PLL_DITHER1_DITHER_EN_MASK 0x80000000 +#define DDR_PLL_DITHER1_DITHER_EN_SET(x) \ + (((x) << DDR_PLL_DITHER1_DITHER_EN_LSB) & DDR_PLL_DITHER1_DITHER_EN_MASK) +#define DDR_PLL_DITHER1_UPDATE_COUNT_LSB 27 +#define DDR_PLL_DITHER1_UPDATE_COUNT_MASK 0x78000000 +#define DDR_PLL_DITHER1_UPDATE_COUNT_SET(x) \ + (((x) << DDR_PLL_DITHER1_UPDATE_COUNT_LSB) & DDR_PLL_DITHER1_UPDATE_COUNT_MASK) +#define DDR_PLL_DITHER1_NFRAC_STEP_LSB 20 +#define DDR_PLL_DITHER1_NFRAC_STEP_MASK 0x07f00000 +#define DDR_PLL_DITHER1_NFRAC_STEP_SET(x) \ + (((x) << DDR_PLL_DITHER1_NFRAC_STEP_LSB) & DDR_PLL_DITHER1_NFRAC_STEP_MASK) +#define DDR_PLL_DITHER1_NFRAC_MIN_LSB 0 +#define DDR_PLL_DITHER1_NFRAC_MIN_MASK 0x0003ffff +#define DDR_PLL_DITHER1_NFRAC_MIN_SET(x) \ + (((x) << DDR_PLL_DITHER1_NFRAC_MIN_LSB) & DDR_PLL_DITHER1_NFRAC_MIN_MASK) +#define DDR_PLL_DITHER2_NFRAC_MAX_LSB 0 +#define DDR_PLL_DITHER2_NFRAC_MAX_MASK 0x0003ffff +#define DDR_PLL_DITHER2_NFRAC_MAX_SET(x) \ + (((x) << DDR_PLL_DITHER2_NFRAC_MAX_LSB) & DDR_PLL_DITHER2_NFRAC_MAX_MASK) +#define CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_LSB 24 +#define CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_MASK 0x01000000 +#define CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_SET(x) \ + (((x) << CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_LSB) & CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_MASK) +#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_LSB 21 +#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_MASK 0x00200000 +#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_SET(x) \ + (((x) << CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_MASK) +#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_LSB 20 +#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_MASK 0x00100000 +#define CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_SET(x) \ + (((x) << CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_MASK) +#define CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_LSB 15 +#define CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_MASK 0x000f8000 +#define CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_SET(x) \ + (((x) << CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_LSB) & CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_MASK) +#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_LSB 10 +#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_MASK 0x00007c00 +#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_SET(x) \ + (((x) << CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_LSB) & CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_MASK) +#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_LSB 5 +#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_MASK 0x000003e0 +#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_SET(x) \ + (((x) << CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_MASK) +#define CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_LSB 4 +#define CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK 0x00000010 +#define CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(x) \ + (((x) << CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_LSB) & CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK) +#define CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_LSB 3 +#define CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK 0x00000008 +#define CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(x) \ + (((x) << CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_LSB) & CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK) +#define CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_LSB 2 +#define CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK 0x00000004 +#define CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(x) \ + (((x) << CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_LSB) & CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK) + +#define CPU_PLL_CONFIG1_NINT_VAL CPU_PLL_CONFIG1_NINT_SET(0x1f) +#define CPU_PLL_CONFIG_REF_DIV_VAL CPU_PLL_CONFIG_REFDIV_SET(0x1) +#define CPU_PLL_CONFIG_RANGE_VAL CPU_PLL_CONFIG_RANGE_SET(0) +#define CPU_PLL_CONFIG_OUT_DIV_VAL1 CPU_PLL_CONFIG_OUTDIV_SET(0) +#define CPU_PLL_CONFIG_OUT_DIV_VAL2 CPU_PLL_CONFIG_OUTDIV_SET(0) +#define CPU_PLL_DITHER1_VAL CPU_PLL_DITHER1_DITHER_EN_SET(0) | \ + CPU_PLL_DITHER1_NFRAC_MIN_SET(0) | \ + CPU_PLL_DITHER1_NFRAC_STEP_SET(0) | \ + CPU_PLL_DITHER1_UPDATE_COUNT_SET(0x0) +#define CPU_PLL_DITHER2_VAL CPU_PLL_DITHER2_NFRAC_MAX_SET(0x0) +#define DDR_PLL_CONFIG1_NINT_VAL DDR_PLL_CONFIG1_NINT_SET(0x1a) +#define DDR_PLL_CONFIG_REF_DIV_VAL DDR_PLL_CONFIG_REFDIV_SET(0x1) +#define DDR_PLL_CONFIG_RANGE_VAL DDR_PLL_CONFIG_RANGE_SET(0) +#define DDR_PLL_CONFIG_OUT_DIV_VAL1 DDR_PLL_CONFIG_OUTDIV_SET(0) +#define DDR_PLL_CONFIG_OUT_DIV_VAL2 DDR_PLL_CONFIG_OUTDIV_SET(0) +#define DDR_PLL_DITHER1_VAL DDR_PLL_DITHER1_DITHER_EN_SET(0) | \ + DDR_PLL_DITHER1_NFRAC_MIN_SET(0) | \ + DDR_PLL_DITHER1_NFRAC_STEP_SET(0) | \ + DDR_PLL_DITHER1_UPDATE_COUNT_SET(0x0) +#define DDR_PLL_DITHER2_VAL DDR_PLL_DITHER2_NFRAC_MAX_SET(0x0) +#define AHB_CLK_FROM_DDR CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_SET(0) +#define CPU_AND_DDR_CLK_FROM_DDR \ + CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_SET(0) +#define CPU_AND_DDR_CLK_FROM_CPU \ + CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_SET(0) +#define CPU_DDR_CLOCK_CONTROL_AHB_DIV_VAL \ + CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_SET(0x2) +#define CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV \ + CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_SET(0) +#define CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV \ + CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_SET(0) + +static inline void set_val(u32 _reg, u32 _mask, u32 _val) +{ + void __iomem *pll_regs = map_physmem(AR71XX_PLL_BASE, + AR71XX_PLL_SIZE, MAP_NOCACHE); + writel((readl(pll_regs + _reg) & (~(_mask))) | _val, pll_regs + _reg); +} + +#define cpu_pll_set(_mask, _val) \ + set_val(QCA956X_PLL_CPU_CONFIG_REG, _mask, _val) + +#define ddr_pll_set(_mask, _val) \ + set_val(QCA956X_PLL_DDR_CONFIG_REG, _mask, _val) + +#define cpu_ddr_control_set(_mask, _val) \ + set_val(QCA956X_PLL_CLK_CTRL_REG, _mask, _val) + +DECLARE_GLOBAL_DATA_PTR; + +static u32 qca956x_get_xtal(void) +{ + u32 val; + + val = ath79_get_bootstrap(); + if (val & QCA956X_BOOTSTRAP_REF_CLK_40) + return 40000000; + else + return 25000000; +} + +int get_serial_clock(void) +{ + return qca956x_get_xtal(); +} + +void qca956x_pll_init(void) +{ + void __iomem *srif_regs = map_physmem(QCA956X_SRIF_BASE, + QCA956X_SRIF_SIZE, MAP_NOCACHE); + void __iomem *pll_regs = map_physmem(AR71XX_PLL_BASE, + AR71XX_PLL_SIZE, MAP_NOCACHE); + + /* 8.16.2 Baseband DPLL2 */ + writel(PLL_SRIF_DPLL2_KI_SET(2) | PLL_SRIF_DPLL2_KD_SET(0xa) | + PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_OUTDIV_SET(1) | + PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6), srif_regs + QCA956X_SRIF_BB_DPLL2_REG); + + /* 8.16.2 PCIE DPLL2 */ + writel(PLL_SRIF_DPLL2_KI_SET(2) | PLL_SRIF_DPLL2_KD_SET(0xa) | + PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_OUTDIV_SET(3) | + PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6), srif_regs + QCA956X_SRIF_PCIE_DPLL2_REG); + + /* 8.16.2 DDR DPLL2 */ + writel(PLL_SRIF_DPLL2_KI_SET(2) | PLL_SRIF_DPLL2_KD_SET(0xa) | + PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6), + srif_regs + QCA956X_SRIF_DDR_DPLL2_REG); + + /* 8.16.2 CPU DPLL2 */ + writel(PLL_SRIF_DPLL2_KI_SET(1) | PLL_SRIF_DPLL2_KD_SET(7) | + PLL_SRIF_DPLL2_PLL_PWD_SET(1) | PLL_SRIF_DPLL2_PHASE_SHIFT_SET(6), + srif_regs + QCA956X_SRIF_CPU_DPLL2_REG); + + /* pll_bypass_set */ + cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK, + CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(1)); + cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK, + CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(1)); + cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK, + CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(1)); + + /* init_cpu_pll */ + cpu_pll_set(CPU_PLL_CONFIG_PLLPWD_MASK, CPU_PLL_CONFIG_PLLPWD_SET(1)); + cpu_pll_set(CPU_PLL_CONFIG_REFDIV_MASK, CPU_PLL_CONFIG_REF_DIV_VAL); + cpu_pll_set(CPU_PLL_CONFIG_RANGE_MASK, CPU_PLL_CONFIG_RANGE_VAL); + cpu_pll_set(CPU_PLL_CONFIG_OUTDIV_MASK, CPU_PLL_CONFIG_OUT_DIV_VAL1); + set_val(QCA956X_PLL_CPU_CONFIG1_REG, CPU_PLL_CONFIG1_NINT_MASK, \ + CPU_PLL_CONFIG1_NINT_VAL); + + /* init_ddr_pll */ + ddr_pll_set(DDR_PLL_CONFIG_PLLPWD_MASK, DDR_PLL_CONFIG_PLLPWD_SET(1)); + ddr_pll_set(DDR_PLL_CONFIG_REFDIV_MASK, DDR_PLL_CONFIG_REF_DIV_VAL); + ddr_pll_set(DDR_PLL_CONFIG_RANGE_MASK, DDR_PLL_CONFIG_RANGE_VAL); + ddr_pll_set(DDR_PLL_CONFIG_OUTDIV_MASK, DDR_PLL_CONFIG_OUT_DIV_VAL1); + set_val(QCA956X_PLL_DDR_CONFIG1_REG, DDR_PLL_CONFIG1_NINT_MASK, + DDR_PLL_CONFIG1_NINT_VAL); + + /* init_ahb_pll */ + writel(CPU_DDR_CLOCK_CONTROL_AHB_DIV_VAL | AHB_CLK_FROM_DDR | + CPU_AND_DDR_CLK_FROM_DDR | CPU_AND_DDR_CLK_FROM_CPU | + CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV | CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV | + CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(1) | + CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(1) | + CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(1), pll_regs + QCA956X_PLL_CLK_CTRL_REG); + + /* ddr_pll_dither_unset */ + writel(DDR_PLL_DITHER1_VAL, pll_regs + QCA956X_PLL_DDR_DIT_FRAC_REG); + writel(DDR_PLL_DITHER2_VAL, pll_regs + QCA956X_PLL_DDR_DIT2_FRAC_REG); + + /* cpu_pll_dither_unset */ + writel(CPU_PLL_DITHER1_VAL, pll_regs + QCA956X_PLL_CPU_DIT_FRAC_REG); + writel(CPU_PLL_DITHER2_VAL, pll_regs + QCA956X_PLL_CPU_DIT2_FRAC_REG); + + /* pll_pwd_unset */ + cpu_pll_set(CPU_PLL_CONFIG_PLLPWD_MASK, CPU_PLL_CONFIG_PLLPWD_SET(0)); + ddr_pll_set(DDR_PLL_CONFIG_PLLPWD_MASK, DDR_PLL_CONFIG_PLLPWD_SET(0)); + + /* outdiv_unset */ + cpu_pll_set(CPU_PLL_CONFIG_OUTDIV_MASK, CPU_PLL_CONFIG_OUT_DIV_VAL2); + ddr_pll_set(DDR_PLL_CONFIG_OUTDIV_MASK, DDR_PLL_CONFIG_OUT_DIV_VAL2); + + /* pll_bypass_unset */ + cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK, + CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(0)); + cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK, + CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(0)); + cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK, + CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(0)); + + while (readl(pll_regs + QCA956X_PLL_CPU_CONFIG_REG) & 0x8000000) + /* NOP */; + + while (readl(pll_regs + QCA956X_PLL_DDR_CONFIG_REG) & 0x8000000) + /* NOP */; +} + +int get_clocks(void) +{ + void __iomem *regs; + u32 ref_rate, cpu_rate, ddr_rate, ahb_rate; + u32 out_div, ref_div, postdiv, nint, hfrac, lfrac, clk_ctrl; + u32 pll, cpu_pll, ddr_pll, misc; + + /* + * QCA956x timer init workaround has to be applied right before setting + * up the clock. Else, there will be no jiffies + */ + regs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE, + MAP_NOCACHE); + misc = readl(regs + AR71XX_RESET_REG_MISC_INT_ENABLE); + misc |= MISC_INT_MIPS_SI_TIMERINT_MASK; + writel(misc, regs + AR71XX_RESET_REG_MISC_INT_ENABLE); + + regs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE, + MAP_NOCACHE); + pll = readl(regs + QCA956X_PLL_CPU_CONFIG_REG); + out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & + QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK; + ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) & + QCA956X_PLL_CPU_CONFIG_REFDIV_MASK; + + pll = readl(regs + QCA956X_PLL_CPU_CONFIG1_REG); + nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) & + QCA956X_PLL_CPU_CONFIG1_NINT_MASK; + hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) & + QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK; + lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) & + QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK; + + ref_rate = qca956x_get_xtal(); + + cpu_pll = nint * ref_rate / ref_div; + cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); + cpu_pll += (hfrac >> 13) * ref_rate / ref_div; + cpu_pll /= (1 << out_div); + + pll = readl(regs + QCA956X_PLL_DDR_CONFIG_REG); + out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & + QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK; + ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) & + QCA956X_PLL_DDR_CONFIG_REFDIV_MASK; + pll = readl(regs + QCA956X_PLL_DDR_CONFIG1_REG); + nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) & + QCA956X_PLL_DDR_CONFIG1_NINT_MASK; + hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) & + QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK; + lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) & + QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK; + + ddr_pll = nint * ref_rate / ref_div; + ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); + ddr_pll += (hfrac >> 13) * ref_rate / ref_div; + ddr_pll /= (1 << out_div); + + clk_ctrl = readl(regs + QCA956X_PLL_CLK_CTRL_REG); + + postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & + QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; + + if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS) + cpu_rate = ref_rate; + else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL) + cpu_rate = ddr_pll / (postdiv + 1); + else + cpu_rate = cpu_pll / (postdiv + 1); + + postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & + QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; + + if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS) + ddr_rate = ref_rate; + else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL) + ddr_rate = cpu_pll / (postdiv + 1); + else + ddr_rate = ddr_pll / (postdiv + 1); + + postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & + QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; + + if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS) + ahb_rate = ref_rate; + else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) + ahb_rate = ddr_pll / (postdiv + 1); + else + ahb_rate = cpu_pll / (postdiv + 1); + + gd->cpu_clk = cpu_rate; + gd->mem_clk = ddr_rate; + gd->bus_clk = ahb_rate; + + debug("cpu_clk=%u, ddr_clk=%u, bus_clk=%u\n", + cpu_rate, ddr_rate, ahb_rate); + + return 0; +} + +ulong get_bus_freq(ulong dummy) +{ + if (!gd->bus_clk) + get_clocks(); + return gd->bus_clk; +} + +ulong get_ddr_freq(ulong dummy) +{ + if (!gd->mem_clk) + get_clocks(); + return gd->mem_clk; +} diff --git a/arch/mips/mach-ath79/qca956x/cpu.c b/arch/mips/mach-ath79/qca956x/cpu.c new file mode 100644 index 00000000000..08a8c84e72d --- /dev/null +++ b/arch/mips/mach-ath79/qca956x/cpu.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Rosy Song <rosysong@rosinson.com> + */ + +#include <common.h> + +/* The lowlevel_init() is not needed on QCA956X */ +void lowlevel_init(void) {} diff --git a/arch/mips/mach-ath79/qca956x/ddr.c b/arch/mips/mach-ath79/qca956x/ddr.c new file mode 100644 index 00000000000..fb2230430c6 --- /dev/null +++ b/arch/mips/mach-ath79/qca956x/ddr.c @@ -0,0 +1,308 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Rosy Song <rosysong@rosinson.com> + * + * Based on QSDK + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/addrspace.h> +#include <asm/types.h> +#include <mach/ar71xx_regs.h> +#include <mach/ath79.h> + +#define DDR_FSM_WAIT_CTRL_VAL 0xa12 +#define DDR_CTL_CONFIG_SRAM_TSEL_LSB 30 +#define DDR_CTL_CONFIG_SRAM_TSEL_MASK 0xc0000000 +#define DDR_CTL_CONFIG_SRAM_TSEL_SET(x) \ + (((x) << DDR_CTL_CONFIG_SRAM_TSEL_LSB) & DDR_CTL_CONFIG_SRAM_TSEL_MASK) +#define DDR_CTL_CONFIG_GE0_SRAM_SYNC_LSB 20 +#define DDR_CTL_CONFIG_GE0_SRAM_SYNC_MASK 0x00100000 +#define DDR_CTL_CONFIG_GE0_SRAM_SYNC_SET(x) \ + (((x) << DDR_CTL_CONFIG_GE0_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_GE0_SRAM_SYNC_MASK) +#define DDR_CTL_CONFIG_GE1_SRAM_SYNC_LSB 19 +#define DDR_CTL_CONFIG_GE1_SRAM_SYNC_MASK 0x00080000 +#define DDR_CTL_CONFIG_GE1_SRAM_SYNC_SET(x) \ + (((x) << DDR_CTL_CONFIG_GE1_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_GE1_SRAM_SYNC_MASK) +#define DDR_CTL_CONFIG_USB_SRAM_SYNC_LSB 18 +#define DDR_CTL_CONFIG_USB_SRAM_SYNC_MASK 0x00040000 +#define DDR_CTL_CONFIG_USB_SRAM_SYNC_SET(x) \ + (((x) << DDR_CTL_CONFIG_USB_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_USB_SRAM_SYNC_MASK) +#define DDR_CTL_CONFIG_PCIE_SRAM_SYNC_LSB 17 +#define DDR_CTL_CONFIG_PCIE_SRAM_SYNC_MASK 0x00020000 +#define DDR_CTL_CONFIG_PCIE_SRAM_SYNC_SET(x) \ + (((x) << DDR_CTL_CONFIG_PCIE_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_PCIE_SRAM_SYNC_MASK) +#define DDR_CTL_CONFIG_WMAC_SRAM_SYNC_LSB 16 +#define DDR_CTL_CONFIG_WMAC_SRAM_SYNC_MASK 0x00010000 +#define DDR_CTL_CONFIG_WMAC_SRAM_SYNC_SET(x) \ + (((x) << DDR_CTL_CONFIG_WMAC_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_WMAC_SRAM_SYNC_MASK) +#define DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_LSB 15 +#define DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_MASK 0x00008000 +#define DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_SET(x) \ + (((x) << DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_MASK) +#define DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_LSB 14 +#define DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_MASK 0x00004000 +#define DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_SET(x) \ + (((x) << DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_LSB) & DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_MASK) +#define DDR_CTL_CONFIG_PAD_DDR2_SEL_LSB 6 +#define DDR_CTL_CONFIG_PAD_DDR2_SEL_MASK 0x00000040 +#define DDR_CTL_CONFIG_PAD_DDR2_SEL_SET(x) \ + (((x) << DDR_CTL_CONFIG_PAD_DDR2_SEL_LSB) & DDR_CTL_CONFIG_PAD_DDR2_SEL_MASK) +#define DDR_CTL_CONFIG_CPU_DDR_SYNC_LSB 2 +#define DDR_CTL_CONFIG_CPU_DDR_SYNC_MASK 0x00000004 +#define DDR_CTL_CONFIG_CPU_DDR_SYNC_SET(x) \ + (((x) << DDR_CTL_CONFIG_CPU_DDR_SYNC_LSB) & DDR_CTL_CONFIG_CPU_DDR_SYNC_MASK) +#define DDR_CTL_CONFIG_HALF_WIDTH_LSB 1 +#define DDR_CTL_CONFIG_HALF_WIDTH_MASK 0x00000002 +#define DDR_CTL_CONFIG_HALF_WIDTH_SET(x) \ + (((x) << DDR_CTL_CONFIG_HALF_WIDTH_LSB) & DDR_CTL_CONFIG_HALF_WIDTH_MASK) +#define DDR_CONFIG_CAS_LATENCY_MSB_LSB 31 +#define DDR_CONFIG_CAS_LATENCY_MSB_MASK 0x80000000 +#define DDR_CONFIG_CAS_LATENCY_MSB_SET(x) \ + (((x) << DDR_CONFIG_CAS_LATENCY_MSB_LSB) & DDR_CONFIG_CAS_LATENCY_MSB_MASK) +#define DDR_CONFIG_OPEN_PAGE_LSB 30 +#define DDR_CONFIG_OPEN_PAGE_MASK 0x40000000 +#define DDR_CONFIG_OPEN_PAGE_SET(x) \ + (((x) << DDR_CONFIG_OPEN_PAGE_LSB) & DDR_CONFIG_OPEN_PAGE_MASK) +#define DDR_CONFIG_CAS_LATENCY_LSB 27 +#define DDR_CONFIG_CAS_LATENCY_MASK 0x38000000 +#define DDR_CONFIG_CAS_LATENCY_SET(x) \ + (((x) << DDR_CONFIG_CAS_LATENCY_LSB) & DDR_CONFIG_CAS_LATENCY_MASK) +#define DDR_CONFIG_TMRD_LSB 23 +#define DDR_CONFIG_TMRD_MASK 0x07800000 +#define DDR_CONFIG_TMRD_SET(x) \ + (((x) << DDR_CONFIG_TMRD_LSB) & DDR_CONFIG_TMRD_MASK) +#define DDR_CONFIG_TRFC_LSB 17 +#define DDR_CONFIG_TRFC_MASK 0x007e0000 +#define DDR_CONFIG_TRFC_SET(x) \ + (((x) << DDR_CONFIG_TRFC_LSB) & DDR_CONFIG_TRFC_MASK) +#define DDR_CONFIG_TRRD_LSB 13 +#define DDR_CONFIG_TRRD_MASK 0x0001e000 +#define DDR_CONFIG_TRRD_SET(x) \ + (((x) << DDR_CONFIG_TRRD_LSB) & DDR_CONFIG_TRRD_MASK) +#define DDR_CONFIG_TRP_LSB 9 +#define DDR_CONFIG_TRP_MASK 0x00001e00 +#define DDR_CONFIG_TRP_SET(x) \ + (((x) << DDR_CONFIG_TRP_LSB) & DDR_CONFIG_TRP_MASK) +#define DDR_CONFIG_TRCD_LSB 5 +#define DDR_CONFIG_TRCD_MASK 0x000001e0 +#define DDR_CONFIG_TRCD_SET(x) \ + (((x) << DDR_CONFIG_TRCD_LSB) & DDR_CONFIG_TRCD_MASK) +#define DDR_CONFIG_TRAS_LSB 0 +#define DDR_CONFIG_TRAS_MASK 0x0000001f +#define DDR_CONFIG_TRAS_SET(x) \ + (((x) << DDR_CONFIG_TRAS_LSB) & DDR_CONFIG_TRAS_MASK) +#define DDR_CONFIG2_HALF_WIDTH_LOW_LSB 31 +#define DDR_CONFIG2_HALF_WIDTH_LOW_MASK 0x80000000 +#define DDR_CONFIG2_HALF_WIDTH_LOW_SET(x) \ + (((x) << DDR_CONFIG2_HALF_WIDTH_LOW_LSB) & DDR_CONFIG2_HALF_WIDTH_LOW_MASK) +#define DDR_CONFIG2_SWAP_A26_A27_LSB 30 +#define DDR_CONFIG2_SWAP_A26_A27_MASK 0x40000000 +#define DDR_CONFIG2_SWAP_A26_A27_SET(x) \ + (((x) << DDR_CONFIG2_SWAP_A26_A27_LSB) & DDR_CONFIG2_SWAP_A26_A27_MASK) +#define DDR_CONFIG2_GATE_OPEN_LATENCY_LSB 26 +#define DDR_CONFIG2_GATE_OPEN_LATENCY_MASK 0x3c000000 +#define DDR_CONFIG2_GATE_OPEN_LATENCY_SET(x) \ + (((x) << DDR_CONFIG2_GATE_OPEN_LATENCY_LSB) & DDR_CONFIG2_GATE_OPEN_LATENCY_MASK) +#define DDR_CONFIG2_TWTR_LSB 21 +#define DDR_CONFIG2_TWTR_MASK 0x03e00000 +#define DDR_CONFIG2_TWTR_SET(x) \ + (((x) << DDR_CONFIG2_TWTR_LSB) & DDR_CONFIG2_TWTR_MASK) +#define DDR_CONFIG2_TRTP_LSB 17 +#define DDR_CONFIG2_TRTP_MASK 0x001e0000 +#define DDR_CONFIG2_TRTP_SET(x) \ + (((x) << DDR_CONFIG2_TRTP_LSB) & DDR_CONFIG2_TRTP_MASK) +#define DDR_CONFIG2_TRTW_LSB 12 +#define DDR_CONFIG2_TRTW_MASK 0x0001f000 +#define DDR_CONFIG2_TRTW_SET(x) \ + (((x) << DDR_CONFIG2_TRTW_LSB) & DDR_CONFIG2_TRTW_MASK) +#define DDR_CONFIG2_TWR_LSB 8 +#define DDR_CONFIG2_TWR_MASK 0x00000f00 +#define DDR_CONFIG2_TWR_SET(x) \ + (((x) << DDR_CONFIG2_TWR_LSB) & DDR_CONFIG2_TWR_MASK) +#define DDR_CONFIG2_CKE_LSB 7 +#define DDR_CONFIG2_CKE_MASK 0x00000080 +#define DDR_CONFIG2_CKE_SET(x) \ + (((x) << DDR_CONFIG2_CKE_LSB) & DDR_CONFIG2_CKE_MASK) +#define DDR_CONFIG2_CNTL_OE_EN_LSB 5 +#define DDR_CONFIG2_CNTL_OE_EN_MASK 0x00000020 +#define DDR_CONFIG2_CNTL_OE_EN_SET(x) \ + (((x) << DDR_CONFIG2_CNTL_OE_EN_LSB) & DDR_CONFIG2_CNTL_OE_EN_MASK) +#define DDR_CONFIG2_BURST_LENGTH_LSB 0 +#define DDR_CONFIG2_BURST_LENGTH_MASK 0x0000000f +#define DDR_CONFIG2_BURST_LENGTH_SET(x) \ + (((x) << DDR_CONFIG2_BURST_LENGTH_LSB) & DDR_CONFIG2_BURST_LENGTH_MASK) +#define RST_BOOTSTRAP_ADDRESS 0x180600b0 +#define PMU2_SWREGMSB_LSB 22 +#define PMU2_SWREGMSB_MASK 0xffc00000 +#define PMU2_SWREGMSB_SET(x) \ + (((x) << PMU2_SWREGMSB_LSB) & PMU2_SWREGMSB_MASK) +#define PMU2_PGM_LSB 21 +#define PMU2_PGM_MASK 0x00200000 +#define PMU2_PGM_SET(x) \ + (((x) << PMU2_PGM_LSB) & PMU2_PGM_MASK) + +#define CPU_DDR_SYNC_MODE DDR_CTL_CONFIG_CPU_DDR_SYNC_SET(0) + +/* +* DDR2 DDR1 +* 0x40c3 25MHz 0x4186 25Mhz +* 0x4138 40MHz 0x4270 40Mhz +*/ +#define CFG_DDR2_REFRESH_VAL 0x40c3 +#define CFG_DDR2_CONFIG_VAL DDR_CONFIG_CAS_LATENCY_MSB_SET(0x1) | \ + DDR_CONFIG_OPEN_PAGE_SET(0x1) | DDR_CONFIG_CAS_LATENCY_SET(0x4) | \ + DDR_CONFIG_TMRD_SET(0x6) | DDR_CONFIG_TRFC_SET(0x16) | \ + DDR_CONFIG_TRRD_SET(0x7) | DDR_CONFIG_TRP_SET(0xb) | \ + DDR_CONFIG_TRCD_SET(0xb) | DDR_CONFIG_TRAS_SET(0) +#define CFG_DDR2_CONFIG2_VAL DDR_CONFIG2_HALF_WIDTH_LOW_SET(0x1) | \ + DDR_CONFIG2_SWAP_A26_A27_SET(0x0) | DDR_CONFIG2_GATE_OPEN_LATENCY_SET(0xa) | \ + DDR_CONFIG2_TWTR_SET(0x16) | DDR_CONFIG2_TRTP_SET(0xa) | \ + DDR_CONFIG2_TRTW_SET(0xe) | DDR_CONFIG2_TWR_SET(0x2) | \ + DDR_CONFIG2_CKE_SET(0x1) | DDR_CONFIG2_CNTL_OE_EN_SET(0x1) | \ + DDR_CONFIG2_BURST_LENGTH_SET(0x8) + +#define CFG_DDR2_CONFIG3_VAL 0x0000000e +#define CFG_DDR2_EXT_MODE_VAL1 0x782 +#define CFG_DDR2_EXT_MODE_VAL2 0x402 +#define CFG_DDR2_MODE_VAL_INIT 0xb53 +#define CFG_DDR2_MODE_VAL 0xa53 +#define CFG_DDR2_TAP_VAL 0x10 +#define CFG_DDR2_EN_TWL_VAL 0x00001e91 +#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16 0xffff + +#define CFG_DDR_CTL_CONFIG DDR_CTL_CONFIG_SRAM_TSEL_SET(0x1) | \ + DDR_CTL_CONFIG_GE0_SRAM_SYNC_SET(0x1) | \ + DDR_CTL_CONFIG_GE1_SRAM_SYNC_SET(0x1) | \ + DDR_CTL_CONFIG_USB_SRAM_SYNC_SET(0x1) | \ + DDR_CTL_CONFIG_PCIE_SRAM_SYNC_SET(0x1) | \ + DDR_CTL_CONFIG_WMAC_SRAM_SYNC_SET(0x1) | \ + DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_SET(0x1) | \ + DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_SET(0x1) + +DECLARE_GLOBAL_DATA_PTR; + +void qca956x_ddr_init(void) +{ + u32 ddr_config, ddr_config2, ddr_config3, mod_val, \ + mod_val_init, cycle_val, tap_val, ctl_config; + void __iomem *ddr_regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE, + MAP_NOCACHE); + void __iomem *srif_regs = map_physmem(QCA956X_SRIF_BASE, QCA956X_SRIF_SIZE, + MAP_NOCACHE); + + ddr_config = CFG_DDR2_CONFIG_VAL; + ddr_config2 = CFG_DDR2_CONFIG2_VAL; + ddr_config3 = CFG_DDR2_CONFIG3_VAL; + mod_val_init = CFG_DDR2_MODE_VAL_INIT; + mod_val = CFG_DDR2_MODE_VAL; + tap_val = CFG_DDR2_TAP_VAL; + cycle_val = CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16; + ctl_config = CFG_DDR_CTL_CONFIG | DDR_CTL_CONFIG_PAD_DDR2_SEL_SET(0x1) | + DDR_CTL_CONFIG_HALF_WIDTH_SET(0x1) | CPU_DDR_SYNC_MODE; + + writel(0x10, ddr_regs + AR71XX_DDR_REG_CONTROL); + udelay(10); + + writel(0x20, ddr_regs + AR71XX_DDR_REG_CONTROL); + udelay(10); + + writel(ctl_config, ddr_regs + QCA956X_DDR_REG_CTL_CONF); + udelay(10); + + writel(cycle_val, ddr_regs + AR71XX_DDR_REG_RD_CYCLE); + udelay(100); + + writel(0x74444444, ddr_regs + QCA956X_DDR_REG_BURST); + udelay(100); + + writel(0x44444444, ddr_regs + QCA956X_DDR_REG_BURST2); + udelay(100); + + writel(DDR_FSM_WAIT_CTRL_VAL, ddr_regs + QCA956X_DDR_REG_FSM_WAIT_CTRL); + udelay(100); + + writel(0xfffff, ddr_regs + QCA956X_DDR_REG_TIMEOUT_MAX); + udelay(100); + + writel(ddr_config, ddr_regs + AR71XX_DDR_REG_CONFIG); + udelay(100); + + writel(ddr_config2, ddr_regs + AR71XX_DDR_REG_CONFIG2); + udelay(100); + + writel(ddr_config3, ddr_regs + QCA956X_DDR_REG_DDR3_CONFIG); + udelay(100); + + writel(CFG_DDR2_EN_TWL_VAL, ddr_regs + QCA956X_DDR_REG_DDR2_CONFIG); + udelay(100); + + writel(ddr_config2 | 0x80, ddr_regs + AR71XX_DDR_REG_CONFIG2); /* CKE Enable */ + udelay(100); + + writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL); /* Precharge */ + udelay(10); + + writel(0, ddr_regs + QCA956X_DDR_REG_DDR2_EMR2); + writel(0x10, ddr_regs + AR71XX_DDR_REG_CONTROL); /* EMR2 */ + udelay(10); + + writel(0, ddr_regs + QCA956X_DDR_REG_DDR2_EMR3); + writel(0x20, ddr_regs + AR71XX_DDR_REG_CONTROL); /* EMR3 */ + udelay(10); + + /* EMR DLL enable, Reduced Driver Impedance control, Differential DQS disabled */ + writel(CFG_DDR2_EXT_MODE_VAL2, ddr_regs + AR71XX_DDR_REG_EMR); + udelay(100); + + writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL); /* EMR write */ + udelay(10); + + writel(mod_val_init, ddr_regs + AR71XX_DDR_REG_MODE); + udelay(1000); + + writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL); /* MR Write */ + udelay(10); + + writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL); /* Precharge */ + udelay(10); + + writel(0x4, ddr_regs + AR71XX_DDR_REG_CONTROL); /* Auto Refresh */ + udelay(10); + + writel(0x4, ddr_regs + AR71XX_DDR_REG_CONTROL); /* Auto Refresh */ + udelay(10); + + /* Issue MRS to remove DLL out-of-reset */ + writel(mod_val, ddr_regs + AR71XX_DDR_REG_MODE); + udelay(100); + + writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL); /* MR write */ + udelay(100); + + writel(CFG_DDR2_EXT_MODE_VAL1, ddr_regs + AR71XX_DDR_REG_EMR); + udelay(100); + + writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL); /* EMR write */ + udelay(100); + + writel(CFG_DDR2_EXT_MODE_VAL2, ddr_regs + AR71XX_DDR_REG_EMR); + udelay(100); + + writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL); /* EMR write */ + udelay(100); + + writel(CFG_DDR2_REFRESH_VAL, ddr_regs + AR71XX_DDR_REG_REFRESH); + udelay(100); + + writel(tap_val, ddr_regs + AR71XX_DDR_REG_TAP_CTRL0); + writel(tap_val, ddr_regs + AR71XX_DDR_REG_TAP_CTRL1); + writel(tap_val, ddr_regs + QCA956X_DDR_REG_TAP_CTRL2); + writel(tap_val, ddr_regs + QCA956X_DDR_REG_TAP_CTRL3); + + writel(0x633c8176, srif_regs + QCA956X_SRIF_PMU1_REG); + /* Set DDR2 Voltage to 1.8 volts */ + writel(PMU2_SWREGMSB_SET(0x40) | PMU2_PGM_SET(0x1), + srif_regs + QCA956X_SRIF_PMU2_REG); +} diff --git a/arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S b/arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S new file mode 100644 index 00000000000..db54b575fbc --- /dev/null +++ b/arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S @@ -0,0 +1,193 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Rosy Song <rosysong@rosinson.com> + * + * Based on QSDK + */ + +#include <config.h> +#include <asm/asm.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <mach/ar71xx_regs.h> + + .set noreorder + +LEAF(ddr_tap_tuning) + li a0, 0xbd001f00 + sw zero, 0x0(a0) /* Place where the tap values are saved and used for SWEEP */ + sw zero, 0x4(a0) /* Place where the number of passing taps are saved. */ + sw zero, 0x14(a0) /* Place where the last pass tap value is stored */ + li a1, 0xaa55aa55 /* Indicates that the First pass tap value is not found */ + sw a1, 0x10(a0) /* Place where the First pass tap value is stored */ + nop + + li a0, CKSEG1ADDR(AR71XX_RESET_BASE) /* RESET_BASE_ADDRESS */ + lw a1, 0x1c(a0) /* Reading the RST_RESET_ADDRESS */ + li a2, 0x08000000 /* Setting the RST_RESET_RTC_RESET */ + or a1, a1, a2 + sw a1, 0x1c(a0) + + li a3, 0xffffffff + xor a2, a2, a3 + and a1, a1, a2 + sw a1, 0x1c(a0) /* Taking the RTC out of RESET */ + nop + + li a0, CKSEG1ADDR(QCA956X_RTC_BASE) /* RTC_BASE_ADDRESS */ + li a1, 0x1 + sw a1, 0x0040(a0) /* RTC_SYNC_RESET_ADDRESS */ + + li a2, 0x2 + +_poll_for_RTC_ON: + lw a1, 0x0044(a0) /* RTC_SYNC_STATUS_ADDRESS */ + and a1, a2, a1 + bne a1, a2, _poll_for_RTC_ON + nop + +_CHANGE_TAPS: + li t0, 0xbd001f00 /* Read the current value of the TAP for programming */ + lw t1, 0x0(t0) + li t2, 0x00000000 + or t3, t1, t2 + + li t0, 0xb8000000 /* DDR_BASE_ADDRESS */ + sw t3, 0x1c(t0) /* TAP_CONTROL_0_ADDRESS */ + sw t3, 0x20(t0) /* TAP_CONTROL_1_ADDRESS */ + sw t3, 0x24(t0) /* TAP_CONTROL_2_ADDRESS */ + sw t3, 0x28(t0) /* TAP_CONTROL_3_ADDRESS */ + + li t1, 0x00000010 /* Running the test 8 times */ + sw t1, 0x0068(t0) /* PERF_COMP_ADDR_1_ADDRESS */ + + li t1, 0xfa5de83f /* 4 Row Address Bits, 4 Column Address Bits, 2 BA bits */ + sw t1, 0x002c(t0) /* PERF_MASK_ADDR_0_ADDRESS */ + + li t1, 0x0000ffff + sw t1, 0x0070(t0) /* PERF_COMP_AHB_GE0_1_ADDRESS */ + + li t1, 0x0000ffff + sw t1, 0x0040(t0) /* PERF_COMP_AHB_GE1_0_ADDRESS */ + + li t1, 0x0000ffff + sw t1, 0x0078(t0) /* PERF_COMP_AHB_GE1_1_ADDRESS */ + + li t1, 0x0000ffff + sw t1, 0x0034(t0) /* PERF_MASK_AHB_GE0_0_ADDRESS */ + + li t1, 0x0000ffff + sw t1, 0x006c(t0) /* PERF_MASK_AHB_GE0_1_ADDRESS */ + + li t1, 0x0000ffff + sw t1, 0x003c(t0) /* PERF_MASK_AHB_GE1_0_ADDRESS */ + + li t1, 0x0000ffff + sw t1, 0x0074(t0) /* PERF_MASK_AHB_GE1_1_ADDRESS */ + + li t1, 0x0000ffff + sw t1, 0x0038(t0) /* PERF_COMP_AHB_GE0_0_ADDRESS */ + + li t1, 0x00000001 + sw t1, 0x011c(t0) /* DDR_BIST_ADDRESS */ + + li t2, 0x1 + +_bist_done_poll: + lw t1, 0x0120(t0) /* DDR_BIST_STATUS_ADDRESS */ + and t1, t1, t2 + bne t1, t2, _bist_done_poll + nop + + lw t1, 0x0120(t0) /* DDR_BIST_STATUS_ADDRESS */ + li t4, 0x000001fe + and t2, t1, t4 + srl t2, t2, 0x1 /* no. of Pass Runs */ + + li t5, 0x00000000 + sw t5, 0x011c(t0) /* DDR_BIST_ADDRESS - Stop the DDR BIST test */ + + li t5, 0x0001fe00 + and t5, t5, t1 + bnez t5, _iterate_tap /* This is a redundant compare but nevertheless - Comparing the FAILS */ + nop + + lw t1, 0x0068(t0) /* PERF_COMP_ADDR_1_ADDRESS */ + li t3, 0x000001fe + and t3, t3, t1 + srl t3, t3, 0x1 /* No. of runs in the config register. */ + bne t3, t2, _iterate_tap + nop + +pass_tap: + li t0, 0xbd001f00 + lw t1, 0x4(t0) + addiu t1, t1, 0x1 + sw t1, 0x4(t0) + + li t0, 0xbd001f10 + lw t1, 0x0(t0) + li t2, 0xaa55aa55 + beq t1, t2, _first_pass + nop + + li t0, 0xbd001f00 + lw t1, 0x0(t0) + li t0, 0xbd001f10 + sw t1, 0x4(t0) + nop + b _iterate_tap + nop + +_first_pass: + li t0, 0xbd001f00 + lw t1, 0x0(t0) + li t0, 0xbd001f10 + sw t1, 0x0(t0) + sw t1, 0x4(t0) + nop + +_iterate_tap: + li t0, 0xbd001f00 + lw t1, 0x0(t0) + li t2, 0x3f + beq t1, t2, _STOP_TEST + nop + + addiu t1, t1, 0x1 + sw t1, 0x0(t0) + nop + b _CHANGE_TAPS + nop + +_STOP_TEST: + li t0, 0xbd001f00 + lw t1, 0x4(t0) + bnez t1, _load_center_tap + nop + + li t3, 0x8 /* Default Tap to be used */ + b _load_tap_into_reg + nop + +_load_center_tap: + li t0, 0xbd001f10 + lw t1, 0x0(t0) + lw t2, 0x4(t0) + add t3, t1, t2 + srl t3, t3, 0x1 + li t4, 0x3f + and t3, t3, t4 + +_load_tap_into_reg: + li t0, 0xb8000000 + sw t3, 0x1c(t0) /* TAP_CONTROL_0_ADDRESS */ + sw t3, 0x20(t0) /* TAP_CONTROL_1_ADDRESS */ + sw t3, 0x24(t0) /* TAP_CONTROL_2_ADDRESS */ + sw t3, 0x28(t0) /* TAP_CONTROL_3_ADDRESS */ + + nop + jr ra + nop + END(ddr_tap_tuning) diff --git a/arch/mips/mach-ath79/reset.c b/arch/mips/mach-ath79/reset.c index 6a94d886f94..0ab3ab6383c 100644 --- a/arch/mips/mach-ath79/reset.c +++ b/arch/mips/mach-ath79/reset.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com> + * Copyright (C) 2018-2019 Rosy Song <rosysong@rosinson.com> */ #include <common.h> @@ -11,6 +12,44 @@ #include <mach/ath79.h> #include <mach/ar71xx_regs.h> +/* QCA956X ETH_SGMII_SERDES Registers */ +#define SGMII_SERDES_RES_CALIBRATION_LSB 23 +#define SGMII_SERDES_RES_CALIBRATION_MASK 0x07800000 +#define SGMII_SERDES_RES_CALIBRATION_SET(x) \ + (((x) << SGMII_SERDES_RES_CALIBRATION_LSB) & SGMII_SERDES_RES_CALIBRATION_MASK) +#define SGMII_SERDES_CDR_BW_LSB 1 +#define SGMII_SERDES_CDR_BW_MASK 0x00000006 +#define SGMII_SERDES_CDR_BW_SET(x) \ + (((x) << SGMII_SERDES_CDR_BW_LSB) & SGMII_SERDES_CDR_BW_MASK) +#define SGMII_SERDES_TX_DR_CTRL_LSB 4 +#define SGMII_SERDES_TX_DR_CTRL_MASK 0x00000070 +#define SGMII_SERDES_TX_DR_CTRL_SET(x) \ + (((x) << SGMII_SERDES_TX_DR_CTRL_LSB) & SGMII_SERDES_TX_DR_CTRL_MASK) +#define SGMII_SERDES_PLL_BW_LSB 8 +#define SGMII_SERDES_PLL_BW_MASK 0x00000100 +#define SGMII_SERDES_PLL_BW_SET(x) \ + (((x) << SGMII_SERDES_PLL_BW_LSB) & SGMII_SERDES_PLL_BW_MASK) +#define SGMII_SERDES_EN_SIGNAL_DETECT_LSB 16 +#define SGMII_SERDES_EN_SIGNAL_DETECT_MASK 0x00010000 +#define SGMII_SERDES_EN_SIGNAL_DETECT_SET(x) \ + (((x) << SGMII_SERDES_EN_SIGNAL_DETECT_LSB) & SGMII_SERDES_EN_SIGNAL_DETECT_MASK) +#define SGMII_SERDES_FIBER_SDO_LSB 17 +#define SGMII_SERDES_FIBER_SDO_MASK 0x00020000 +#define SGMII_SERDES_FIBER_SDO_SET(x) \ + (((x) << SGMII_SERDES_FIBER_SDO_LSB) & SGMII_SERDES_FIBER_SDO_MASK) +#define SGMII_SERDES_VCO_REG_LSB 27 +#define SGMII_SERDES_VCO_REG_MASK 0x78000000 +#define SGMII_SERDES_VCO_REG_SET(x) \ + (((x) << SGMII_SERDES_VCO_REG_LSB) & SGMII_SERDES_VCO_REG_MASK) +#define SGMII_SERDES_VCO_FAST_LSB 9 +#define SGMII_SERDES_VCO_FAST_MASK 0x00000200 +#define SGMII_SERDES_VCO_FAST_GET(x) \ + (((x) & SGMII_SERDES_VCO_FAST_MASK) >> SGMII_SERDES_VCO_FAST_LSB) +#define SGMII_SERDES_VCO_SLOW_LSB 10 +#define SGMII_SERDES_VCO_SLOW_MASK 0x00000400 +#define SGMII_SERDES_VCO_SLOW_GET(x) \ + (((x) & SGMII_SERDES_VCO_SLOW_MASK) >> SGMII_SERDES_VCO_SLOW_LSB) + void _machine_restart(void) { void __iomem *base; @@ -152,6 +191,236 @@ static int eth_init_qca953x(void) return 0; } +static int qca956x_sgmii_cal(void) +{ + int i; + u32 reg, rev_sgmii_val; + u32 vco_fast, vco_slow; + u32 start_val = 0, end_val = 0; + void __iomem *gregs = map_physmem(AR71XX_MII_BASE, AR71XX_MII_SIZE, + MAP_NOCACHE); + void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE, + MAP_NOCACHE); + void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE, + MAP_NOCACHE); + const u32 mask = QCA956X_RESET_SGMII_ASSERT | QCA956X_RESET_SGMII; + + writel(BIT(2) | BIT(0), pregs + QCA956X_PLL_ETH_SGMII_SERDES_REG); + + reg = readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES); + vco_fast = SGMII_SERDES_VCO_FAST_GET(reg); + vco_slow = SGMII_SERDES_VCO_SLOW_GET(reg); + + /* Set resistor calibration from 0000 to 1111 */ + for (i = 0; i < 0x10; i++) { + reg = (readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES) & + ~SGMII_SERDES_RES_CALIBRATION_MASK) | + SGMII_SERDES_RES_CALIBRATION_SET(i); + writel(reg, gregs + QCA956X_GMAC_REG_SGMII_SERDES); + + udelay(50); + + reg = readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES); + if (vco_fast != SGMII_SERDES_VCO_FAST_GET(reg) || + vco_slow != SGMII_SERDES_VCO_SLOW_GET(reg)) { + if (start_val == 0) { + start_val = i; + end_val = i; + } else { + end_val = i; + } + } + vco_fast = SGMII_SERDES_VCO_FAST_GET(reg); + vco_slow = SGMII_SERDES_VCO_SLOW_GET(reg); + } + + if (start_val == 0) + rev_sgmii_val = 0x7; + else + rev_sgmii_val = (start_val + end_val) >> 1; + + writel((readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES) & + ~SGMII_SERDES_RES_CALIBRATION_MASK) | + SGMII_SERDES_RES_CALIBRATION_SET(rev_sgmii_val), + gregs + QCA956X_GMAC_REG_SGMII_SERDES); + + writel(BIT(2) | BIT(0), pregs + QCA956X_PLL_ETH_SGMII_SERDES_REG); + + reg = readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES); + writel(SGMII_SERDES_CDR_BW_SET(3) | SGMII_SERDES_TX_DR_CTRL_SET(1) | + SGMII_SERDES_PLL_BW_SET(1) | SGMII_SERDES_EN_SIGNAL_DETECT_SET(1) | + SGMII_SERDES_FIBER_SDO_SET(1) | SGMII_SERDES_VCO_REG_SET(3) | reg, + gregs + QCA956X_GMAC_REG_SGMII_SERDES); + + setbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask); + mdelay(1); + clrbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask); + mdelay(1); + + while (!(readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES) & BIT(15))) + /* NOP */; + + return 0; +} + +static int qca956x_sgmii_setup(void) +{ + int i; + u32 s = 0, reg = 0; + u32 _regs[] = { + BIT(4), /* HW_RX_125M_N */ + BIT(2), /* RX_125M_N */ + BIT(3), /* TX_125M_N */ + BIT(0), /* RX_CLK_N */ + BIT(1), /* TX_CLK_N */ + }; + void __iomem *gregs = map_physmem(AR71XX_MII_BASE, AR71XX_MII_SIZE, + MAP_NOCACHE); + + /* Force sgmii mode */ + writel(BIT(6) | BIT(15) | BIT(8), gregs + QCA956X_GMAC_REG_MR_AN_CTRL); + udelay(10); + writel(0x2 | BIT(5) | (0x2 << 6), gregs + QCA956X_GMAC_REG_SGMII_CONFIG); + + /* SGMII reset sequence sugguest by qca systems team. */ + writel(0, gregs + QCA956X_GMAC_REG_SGMII_RESET); + for (i = 0; i < ARRAY_SIZE(_regs); i++) { + reg |= _regs[i]; + writel(reg, gregs + QCA956X_GMAC_REG_SGMII_RESET); + } + + writel(readl(gregs + QCA956X_GMAC_REG_MR_AN_CTRL) & ~BIT(15), + gregs + QCA956X_GMAC_REG_MR_AN_CTRL); + + /* + * WARNING: Across resets SGMII link status goes to weird state. + * if 0xb8070058 (SGMII_DEBUG Register) reads other than 0xf or 0x10 + * for sure we are in bad state. + * Issue a PHY RESET in MR_AN_CONTROL_ADDRESS to keep going. + */ + i = 0; + s = (readl(gregs + QCA956X_GMAC_REG_SGMII_DEBUG) & 0xff); + while (!(s == 0xf || s == 0x10)) { + writel(readl(gregs + QCA956X_GMAC_REG_MR_AN_CTRL) | BIT(15), + gregs + QCA956X_GMAC_REG_MR_AN_CTRL); + udelay(100); + writel(readl(gregs + QCA956X_GMAC_REG_MR_AN_CTRL) & ~BIT(15), + gregs + QCA956X_GMAC_REG_MR_AN_CTRL); + if (i++ == 10) + break; + s = (readl(gregs + QCA956X_GMAC_REG_SGMII_DEBUG) & 0xff); + } + + return 0; +} + +static int qca956x_s17_reset(void) +{ + void __iomem *regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE, + MAP_NOCACHE); + void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE, + MAP_NOCACHE); + const u32 mask = QCA956X_RESET_SGMII_ASSERT | QCA956X_RESET_SGMII | + QCA956X_RESET_EXTERNAL | QCA956X_RESET_SGMII_ANALOG | + QCA956X_RESET_SWITCH; + /* Bits(Reserved in datasheet) should be set to 1 */ + const u32 mask_r = QCA956X_RESET_SGMII_ASSERT | QCA956X_RESET_SGMII | + QCA956X_RESET_EXTERNAL; + + setbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask); + mdelay(1); + clrbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask_r); + mdelay(1); + + /* Reset s17 switch(GPIO11) SYS_RST_L */ + writel(readl(regs + AR71XX_GPIO_REG_OE) & ~BIT(11), + regs + AR71XX_GPIO_REG_OE); + udelay(100); + + writel(readl(regs + AR71XX_GPIO_REG_OUT) & ~BIT(11), + regs + AR71XX_GPIO_REG_OUT); + udelay(100); + writel(readl(regs + AR71XX_GPIO_REG_OUT) | BIT(11), + regs + AR71XX_GPIO_REG_OUT); + + return 0; +} + +static int qca956x_init_mdio(void) +{ + u32 reg; + void __iomem *regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE, + MAP_NOCACHE); + void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE, + MAP_NOCACHE); + const u32 mask = QCA956X_RESET_GE0_MDIO | QCA956X_RESET_GE0_MAC | + QCA956X_RESET_GE1_MDIO | QCA956X_RESET_GE1_MAC; + + setbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask); + mdelay(1); + clrbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask); + mdelay(1); + + /* GPIO4 as MDI */ + reg = readl(regs + QCA956X_GPIO_REG_IN_ENABLE3); + reg &= ~(0xff << 16); + reg |= (0x4 << 16); + writel(reg, regs + QCA956X_GPIO_REG_IN_ENABLE3); + + /* GPIO4 as MDO */ + reg = readl(regs + QCA956X_GPIO_REG_OUT_FUNC1); + reg &= ~0xff; + reg |= 0x20; + writel(reg, regs + QCA956X_GPIO_REG_OUT_FUNC1); + + /* Init MDC(GPIO3) / MDIO(GPIO4) */ + reg = readl(regs + AR71XX_GPIO_REG_OE); + reg &= ~BIT(4); + writel(reg, regs + AR71XX_GPIO_REG_OE); + udelay(100); + + reg = readl(regs + AR71XX_GPIO_REG_OE); + reg &= ~BIT(3); + writel(reg, regs + AR71XX_GPIO_REG_OE); + udelay(100); + + /* GPIO3 as MDI */ + reg = readl(regs + QCA956X_GPIO_REG_OUT_FUNC0); + reg &= ~(0xff << 24); + reg |= (0x21 << 24); + writel(reg, regs + QCA956X_GPIO_REG_OUT_FUNC0); + + return 0; +} + +static int eth_init_qca956x(void) +{ + void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE, + MAP_NOCACHE); + void __iomem *gregs = map_physmem(AR71XX_MII_BASE, AR71XX_MII_SIZE, + MAP_NOCACHE); + + qca956x_sgmii_cal(); + qca956x_s17_reset(); + qca956x_init_mdio(); + + if (ath79_get_bootstrap() & QCA956X_BOOTSTRAP_REF_CLK_40) + writel(0x45500, pregs + QCA956X_PLL_SWITCH_CLK_CTRL_REG); + else + writel(0xc5200, pregs + QCA956X_PLL_SWITCH_CLK_CTRL_REG); + + qca956x_sgmii_setup(); + + writel((3 << 16) | (3 << 14) | (1 << 0) | (1 << 6), + gregs + QCA956X_GMAC_REG_ETH_CFG); + + writel((1 << 31) | (2 << 28) | (2 << 26) | (1 << 25), + pregs + QCA956X_PLL_ETH_XMII_CTRL_REG); + mdelay(1); + + return 0; +} + int ath79_eth_reset(void) { /* @@ -164,6 +433,8 @@ int ath79_eth_reset(void) return eth_init_ar934x(); if (soc_is_qca953x()) return eth_init_qca953x(); + if (soc_is_qca956x()) + return eth_init_qca956x(); return -EINVAL; } diff --git a/arch/mips/mach-mscc/include/mach/servalt/servalt_devcpu_gcb.h b/arch/mips/mach-mscc/include/mach/servalt/servalt_devcpu_gcb.h index f6e724588a9..493eaad1df7 100644 --- a/arch/mips/mach-mscc/include/mach/servalt/servalt_devcpu_gcb.h +++ b/arch/mips/mach-mscc/include/mach/servalt/servalt_devcpu_gcb.h @@ -17,4 +17,6 @@ #define GPIO_GPIO_ALT(x) (0x74 + 4 * (x)) #define GPIO_GPIO_ALT1(x) (0x7c + 4 * (x)) +#define GCB_PHY_CFG 0x118 + #endif diff --git a/arch/mips/mach-mt7620/Kconfig b/arch/mips/mach-mt7620/Kconfig index 4ebcb4b053c..a9834439993 100644 --- a/arch/mips/mach-mt7620/Kconfig +++ b/arch/mips/mach-mt7620/Kconfig @@ -22,12 +22,12 @@ choice prompt "Board select" config BOARD_GARDENA_SMART_GATEWAY_MT7688 - bool "Gardena Smart Gateway" + bool "GARDENA smart Gateway" depends on SOC_MT7620 select BOARD_LATE_INIT select SUPPORTS_BOOT_RAM help - Gardena Smart Gateway boards have a MT7688 SoC with 128 MiB of RAM + GARDENA smart Gateway boards have a MT7688 SoC with 128 MiB of RAM and 8 MiB of flash (SPI NOR) and additional SPI NAND storage. config BOARD_LINKIT_SMART_7688 diff --git a/arch/nds32/dts/ae3xx.dts b/arch/nds32/dts/ae3xx.dts index 272eb3359ab..7bba2a2bf09 100644 --- a/arch/nds32/dts/ae3xx.dts +++ b/arch/nds32/dts/ae3xx.dts @@ -93,7 +93,7 @@ clocks = <&spiclk>; interrupts = <3 4>; flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; spi-cpol; diff --git a/arch/riscv/dts/ae350_32.dts b/arch/riscv/dts/ae350_32.dts index 2ec01a5ce79..cb6ee13f16d 100644 --- a/arch/riscv/dts/ae350_32.dts +++ b/arch/riscv/dts/ae350_32.dts @@ -256,7 +256,7 @@ interrupts = <4 4>; interrupt-parent = <&plic0>; flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; spi-cpol; diff --git a/arch/riscv/dts/ae350_64.dts b/arch/riscv/dts/ae350_64.dts index cde5cdeff83..705491a8e4d 100644 --- a/arch/riscv/dts/ae350_64.dts +++ b/arch/riscv/dts/ae350_64.dts @@ -256,7 +256,7 @@ interrupts = <4 4>; interrupt-parent = <&plic0>; flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; spi-cpol; diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 87d8e5bcc98..8b2d6451c64 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -493,6 +493,7 @@ compatible = "denx,u-boot-probe-test"; first-syscon = <&syscon0>; second-sys-ctrl = <&another_system_controller>; + third-syscon = <&syscon2>; }; }; @@ -578,7 +579,7 @@ cs-gpios = <0>, <&gpio_a 0>; spi.bin@0 { reg = <0>; - compatible = "spansion,m25p16", "spi-flash"; + compatible = "spansion,m25p16", "jedec,spi-nor"; spi-max-frequency = <40000000>; sandbox,filename = "spi.bin"; }; @@ -597,7 +598,7 @@ 0x38 8>; }; - syscon@2 { + syscon2: syscon@2 { compatible = "simple-mfd", "syscon"; reg = <0x40 5 0x48 6 diff --git a/arch/sandbox/include/asm/sdl.h b/arch/sandbox/include/asm/sdl.h index 1027b59e732..c45dbddd700 100644 --- a/arch/sandbox/include/asm/sdl.h +++ b/arch/sandbox/include/asm/sdl.h @@ -104,7 +104,7 @@ static inline int sandbox_sdl_sound_start(uint frequency) return -ENODEV; } -int sandbox_sdl_sound_play(const void *data, uint count) +static inline int sandbox_sdl_sound_play(const void *data, uint count) { return -ENODEV; } @@ -114,7 +114,7 @@ static inline int sandbox_sdl_sound_stop(void) return -ENODEV; } -int sandbox_sdl_sound_init(int rate, int channels) +static inline int sandbox_sdl_sound_init(int rate, int channels) { return -ENODEV; } diff --git a/arch/sandbox/include/asm/types.h b/arch/sandbox/include/asm/types.h index 7cd56b41474..c1a5d2af828 100644 --- a/arch/sandbox/include/asm/types.h +++ b/arch/sandbox/include/asm/types.h @@ -18,21 +18,21 @@ typedef unsigned short umode_t; /* * Number of bits in a C 'long' on this architecture. */ -#ifdef CONFIG_PHYS64 +#ifdef CONFIG_PHYS_64BIT #define BITS_PER_LONG 64 -#else /* CONFIG_PHYS64 */ +#else /* CONFIG_PHYS_64BIT */ #define BITS_PER_LONG 32 -#endif /* CONFIG_PHYS64 */ +#endif /* CONFIG_PHYS_64BIT */ -#ifdef CONFIG_PHYS64 +#ifdef CONFIG_PHYS_64BIT typedef unsigned long long dma_addr_t; typedef u64 phys_addr_t; typedef u64 phys_size_t; -#else /* CONFIG_PHYS64 */ +#else /* CONFIG_PHYS_64BIT */ typedef unsigned long dma_addr_t; typedef u32 phys_addr_t; typedef u32 phys_size_t; -#endif /* CONFIG_PHYS64 */ +#endif /* CONFIG_PHYS_64BIT */ #endif /* __KERNEL__ */ diff --git a/arch/sandbox/lib/pci_io.c b/arch/sandbox/lib/pci_io.c index 5039973cd7a..01822c60695 100644 --- a/arch/sandbox/lib/pci_io.c +++ b/arch/sandbox/lib/pci_io.c @@ -34,7 +34,7 @@ int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp, return 0; } - debug("%s: failed: addr=%x\n", __func__, paddr); + debug("%s: failed: addr=%pap\n", __func__, &paddr); return -ENOSYS; } diff --git a/arch/x86/dts/bayleybay.dts b/arch/x86/dts/bayleybay.dts index 291dc07ff60..d0168e88dbd 100644 --- a/arch/x86/dts/bayleybay.dts +++ b/arch/x86/dts/bayleybay.dts @@ -175,7 +175,7 @@ #size-cells = <1>; reg = <0>; compatible = "winbond,w25q64dw", - "spi-flash"; + "jedec,spi-nor"; memory-map = <0xff800000 0x00800000>; rw-mrc-cache { label = "rw-mrc-cache"; diff --git a/arch/x86/dts/baytrail_som-db5800-som-6867.dts b/arch/x86/dts/baytrail_som-db5800-som-6867.dts index 4e8a761ce87..5abbc66ce98 100644 --- a/arch/x86/dts/baytrail_som-db5800-som-6867.dts +++ b/arch/x86/dts/baytrail_som-db5800-som-6867.dts @@ -199,7 +199,7 @@ #size-cells = <1>; reg = <0>; compatible = "macronix,mx25l6405d", - "spi-flash"; + "jedec,spi-nor"; memory-map = <0xff800000 0x00800000>; rw-mrc-cache { label = "rw-mrc-cache"; diff --git a/arch/x86/dts/cherryhill.dts b/arch/x86/dts/cherryhill.dts index 39e2d2fa4b2..37146fde2ba 100644 --- a/arch/x86/dts/cherryhill.dts +++ b/arch/x86/dts/cherryhill.dts @@ -147,7 +147,7 @@ #address-cells = <1>; #size-cells = <1>; reg = <0>; - compatible = "macronix,mx25u6435f", "spi-flash"; + compatible = "macronix,mx25u6435f", "jedec,spi-nor"; memory-map = <0xff800000 0x00800000>; rw-mrc-cache { label = "rw-mrc-cache"; diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts index c5653feac72..09488f13b58 100644 --- a/arch/x86/dts/chromebook_link.dts +++ b/arch/x86/dts/chromebook_link.dts @@ -429,7 +429,7 @@ u-boot,dm-pre-reloc; reg = <0>; compatible = "winbond,w25q64", - "spi-flash"; + "jedec,spi-nor"; memory-map = <0xff800000 0x00800000>; rw-mrc-cache { label = "rw-mrc-cache"; diff --git a/arch/x86/dts/chromebook_samus.dts b/arch/x86/dts/chromebook_samus.dts index ad687ce2cc3..35211ed81b1 100644 --- a/arch/x86/dts/chromebook_samus.dts +++ b/arch/x86/dts/chromebook_samus.dts @@ -567,7 +567,7 @@ #address-cells = <1>; reg = <0>; compatible = "winbond,w25q64", - "spi-flash"; + "jedec,spi-nor"; memory-map = <0xff800000 0x00800000>; rw-mrc-cache { label = "rw-mrc-cache"; diff --git a/arch/x86/dts/chromebox_panther.dts b/arch/x86/dts/chromebox_panther.dts index f56e482944b..bcd4c4d9c1b 100644 --- a/arch/x86/dts/chromebox_panther.dts +++ b/arch/x86/dts/chromebox_panther.dts @@ -47,7 +47,7 @@ #address-cells = <1>; reg = <0>; compatible = "winbond,w25q64", - "spi-flash"; + "jedec,spi-nor"; memory-map = <0xff800000 0x00800000>; rw-mrc-cache { label = "rw-mrc-cache"; diff --git a/arch/x86/dts/conga-qeval20-qa3-e3845.dts b/arch/x86/dts/conga-qeval20-qa3-e3845.dts index 5884dbc277d..70b8c045193 100644 --- a/arch/x86/dts/conga-qeval20-qa3-e3845.dts +++ b/arch/x86/dts/conga-qeval20-qa3-e3845.dts @@ -186,7 +186,7 @@ #size-cells = <1>; reg = <0>; compatible = "stmicro,n25q064a", - "spi-flash"; + "jedec,spi-nor"; memory-map = <0xff800000 0x00800000>; rw-mrc-cache { label = "rw-mrc-cache"; diff --git a/arch/x86/dts/cougarcanyon2.dts b/arch/x86/dts/cougarcanyon2.dts index 9801790083f..c6ba811e059 100644 --- a/arch/x86/dts/cougarcanyon2.dts +++ b/arch/x86/dts/cougarcanyon2.dts @@ -154,7 +154,7 @@ spi-flash@0 { reg = <0>; - compatible = "winbond,w25q64bv", "spi-flash"; + compatible = "winbond,w25q64bv", "jedec,spi-nor"; memory-map = <0xff800000 0x00800000>; }; }; diff --git a/arch/x86/dts/crownbay.dts b/arch/x86/dts/crownbay.dts index 8938a94e770..f492c35875b 100644 --- a/arch/x86/dts/crownbay.dts +++ b/arch/x86/dts/crownbay.dts @@ -224,7 +224,7 @@ spi-flash@0 { reg = <0>; compatible = "sst,25vf016b", - "spi-flash"; + "jedec,spi-nor"; memory-map = <0xffe00000 0x00200000>; }; }; diff --git a/arch/x86/dts/dfi-bt700.dtsi b/arch/x86/dts/dfi-bt700.dtsi index 51d33e772fc..e9930cb0436 100644 --- a/arch/x86/dts/dfi-bt700.dtsi +++ b/arch/x86/dts/dfi-bt700.dtsi @@ -197,7 +197,7 @@ #size-cells = <1>; reg = <0>; compatible = "stmicro,n25q064a", - "spi-flash"; + "jedec,spi-nor"; memory-map = <0xff800000 0x00800000>; rw-mrc-cache { label = "rw-mrc-cache"; diff --git a/arch/x86/dts/galileo.dts b/arch/x86/dts/galileo.dts index 3a5d168268d..5de4568679a 100644 --- a/arch/x86/dts/galileo.dts +++ b/arch/x86/dts/galileo.dts @@ -139,7 +139,7 @@ #address-cells = <1>; reg = <0>; compatible = "winbond,w25q64", - "spi-flash"; + "jedec,spi-nor"; memory-map = <0xff800000 0x00800000>; rw-mrc-cache { label = "rw-mrc-cache"; diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts index 6c65fb9611c..f4cdb2c3cd2 100644 --- a/arch/x86/dts/minnowmax.dts +++ b/arch/x86/dts/minnowmax.dts @@ -199,7 +199,7 @@ #size-cells = <1>; reg = <0>; compatible = "stmicro,n25q064a", - "spi-flash"; + "jedec,spi-nor"; memory-map = <0xff800000 0x00800000>; rw-mrc-cache { label = "rw-mrc-cache"; diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c index c7f6479a0cf..c21d2f3ffa6 100644 --- a/board/CZ.NIC/turris_omnia/turris_omnia.c +++ b/board/CZ.NIC/turris_omnia/turris_omnia.c @@ -379,7 +379,7 @@ int board_init(void) puts("Cannot find Armada 385 watchdog!\n"); } else { puts("Enabling Armada 385 watchdog.\n"); - wdt_start(watchdog_dev, (u32) 25000000 * 120, 0); + wdt_start(watchdog_dev, 120000, 0); } # endif diff --git a/board/Marvell/db-xc3-24g4xg/.gitignore b/board/Marvell/db-xc3-24g4xg/.gitignore new file mode 100644 index 00000000000..775b9346b85 --- /dev/null +++ b/board/Marvell/db-xc3-24g4xg/.gitignore @@ -0,0 +1 @@ +kwbimage.cfg diff --git a/board/Marvell/db-xc3-24g4xg/MAINTAINERS b/board/Marvell/db-xc3-24g4xg/MAINTAINERS new file mode 100644 index 00000000000..2b27e48181b --- /dev/null +++ b/board/Marvell/db-xc3-24g4xg/MAINTAINERS @@ -0,0 +1,7 @@ +DB-XC3-24G4XG BOARD +M: Chris Packham <chris.packham@alliedtelesis.co.nz> +S: Maintained +F: board/Marvell/db-xc3-24g4xg/ +F: include/configs/db-xc3-24g4xg.h +F: configs/db-xc3-24g4xg_defconfig +F: arch/arm/dts/armada-xp-db-xc3-24g4xg.dts diff --git a/board/Marvell/db-xc3-24g4xg/Makefile b/board/Marvell/db-xc3-24g4xg/Makefile new file mode 100644 index 00000000000..4dd57902d47 --- /dev/null +++ b/board/Marvell/db-xc3-24g4xg/Makefile @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2015 Stefan Roese <sr@denx.de> + +obj-y := db-xc3-24g4xg.o +extra-y := kwbimage.cfg + +quiet_cmd_sed = SED $@ + cmd_sed = sed $(SEDFLAGS_$(@F)) $< >$(dir $<)$(@F) + +SEDFLAGS_kwbimage.cfg =-e "s|^BINARY.*|BINARY $(srctree)/$(@D)/binary.0 0000005b 00000068|" +$(src)/kwbimage.cfg: $(src)/kwbimage.cfg.in include/autoconf.mk \ + include/config/auto.conf + $(call if_changed,sed) diff --git a/board/Marvell/db-xc3-24g4xg/README b/board/Marvell/db-xc3-24g4xg/README new file mode 100644 index 00000000000..5e479b433e4 --- /dev/null +++ b/board/Marvell/db-xc3-24g4xg/README @@ -0,0 +1,4 @@ +To generate binary.0 from Marvell's bin_hdr.elf use the following command + + arm-softfloat-linux-gnueabi-objcopy -S -O binary bin_hdr.elf \ + board/Marvell/db-xc3-24g4xg/binary.0 diff --git a/board/Marvell/db-xc3-24g4xg/binary.0 b/board/Marvell/db-xc3-24g4xg/binary.0 new file mode 100644 index 00000000000..8dd687286a0 --- /dev/null +++ b/board/Marvell/db-xc3-24g4xg/binary.0 @@ -0,0 +1,11 @@ +-------- +WARNING: +-------- +This file should contain the bin_hdr generated by the original Marvell +U-Boot implementation. As this is currently not included in this +U-Boot version, we have added this placeholder, so that the U-Boot +image can be generated without errors. + +If you have a known to be working bin_hdr for your board, then you +just need to replace this text file here with the binary header +and recompile U-Boot. diff --git a/board/Marvell/db-xc3-24g4xg/db-xc3-24g4xg.c b/board/Marvell/db-xc3-24g4xg/db-xc3-24g4xg.c new file mode 100644 index 00000000000..cae428ffd06 --- /dev/null +++ b/board/Marvell/db-xc3-24g4xg/db-xc3-24g4xg.c @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2015 Stefan Roese <sr@denx.de> + */ + +#include <common.h> +#include <i2c.h> +#include <asm/gpio.h> +#include <linux/mbus.h> +#include <linux/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/soc.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * These values and defines are taken from the Marvell U-Boot version + * "u-boot-2013.01-2016_T1.0.eng_drop_v6" + */ +#define DB_DX_AC3_GPP_OUT_ENA_LOW (~(BIT(0) | BIT(2) | BIT(3) | BIT(4) | BIT(6) | BIT(12) \ + | BIT(13) | BIT(16) | BIT(17) | BIT(20) | BIT(29) | BIT(30))) +#define DB_DX_AC3_GPP_OUT_ENA_MID (~(0)) +#define DB_DX_AC3_GPP_OUT_VAL_LOW (BIT(0) | BIT(2) | BIT(3) | BIT(4) | BIT(6) | BIT(12) \ + | BIT(13) | BIT(16) | BIT(17) | BIT(20) | BIT(29) | BIT(30)) +#define DB_DX_AC3_GPP_OUT_VAL_MID 0x0 +#define DB_DX_AC3_GPP_POL_LOW 0x0 +#define DB_DX_AC3_GPP_POL_MID 0x0 + +int board_early_init_f(void) +{ + /* Configure MPP */ + writel(0x00142222, MVEBU_MPP_BASE + 0x00); + writel(0x11122000, MVEBU_MPP_BASE + 0x04); + writel(0x44444004, MVEBU_MPP_BASE + 0x08); + writel(0x14444444, MVEBU_MPP_BASE + 0x0c); + writel(0x00000001, MVEBU_MPP_BASE + 0x10); + + /* Set GPP Out value */ + writel(DB_DX_AC3_GPP_OUT_VAL_LOW, MVEBU_GPIO0_BASE + 0x00); + writel(DB_DX_AC3_GPP_OUT_VAL_MID, MVEBU_GPIO1_BASE + 0x00); + + /* Set GPP Polarity */ + writel(DB_DX_AC3_GPP_POL_LOW, MVEBU_GPIO0_BASE + 0x0c); + writel(DB_DX_AC3_GPP_POL_MID, MVEBU_GPIO1_BASE + 0x0c); + + /* Set GPP Out Enable */ + writel(DB_DX_AC3_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04); + writel(DB_DX_AC3_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04); + + return 0; +} + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100; + + return 0; +} + +#ifdef CONFIG_DISPLAY_BOARDINFO +int checkboard(void) +{ + puts("Board: " CONFIG_SYS_BOARD "\n"); + + return 0; +} +#endif diff --git a/board/Marvell/db-xc3-24g4xg/kwbimage.cfg.in b/board/Marvell/db-xc3-24g4xg/kwbimage.cfg.in new file mode 100644 index 00000000000..b8bb7a6eb75 --- /dev/null +++ b/board/Marvell/db-xc3-24g4xg/kwbimage.cfg.in @@ -0,0 +1,12 @@ +# +# Copyright (C) 2014 Stefan Roese <sr@denx.de> +# + +# Armada XP uses version 1 image format +VERSION 1 + +# Boot Media configurations +BOOT_FROM spi + +# Binary Header (bin_hdr) with DDR3 training code +BINARY board/Marvell/db-xc3-24g4xg/binary.0 0000005b 00000068 diff --git a/board/Synology/ds414/ds414.c b/board/Synology/ds414/ds414.c index eb3694ea6e7..d23e97c9b91 100644 --- a/board/Synology/ds414/ds414.c +++ b/board/Synology/ds414/ds414.c @@ -115,14 +115,14 @@ MV_DRAM_MODES *ddr3_get_static_ddr_mode(void) return &ds414_ddr_modes[0]; } -MV_BIN_SERDES_CFG *board_serdes_cfg_get(u8 pex_mode) +MV_BIN_SERDES_CFG *board_serdes_cfg_get(void) { return &ds414_serdes_cfg[0]; } u8 board_sat_r_get(u8 dev_num, u8 reg) { - return (0x1 << 1 | 1); + return 0xf; /* All PEX ports support PCIe Gen2 */ } int board_early_init_f(void) diff --git a/board/alliedtelesis/x530/x530.c b/board/alliedtelesis/x530/x530.c index d7d1942fe68..6934fd80173 100644 --- a/board/alliedtelesis/x530/x530.c +++ b/board/alliedtelesis/x530/x530.c @@ -7,6 +7,7 @@ #include <command.h> #include <dm.h> #include <i2c.h> +#include <wdt.h> #include <asm/gpio.h> #include <linux/mbus.h> #include <linux/io.h> @@ -24,6 +25,10 @@ DECLARE_GLOBAL_DATA_PTR; #define CONFIG_NVS_LOCATION 0xf4800000 #define CONFIG_NVS_SIZE (512 << 10) +#ifdef CONFIG_WATCHDOG +static struct udevice *watchdog_dev; +#endif + static struct serdes_map board_serdes_map[] = { {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0}, {DEFAULT_SERDES, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0}, @@ -75,6 +80,10 @@ struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) int board_early_init_f(void) { +#ifdef CONFIG_WATCHDOG + watchdog_dev = NULL; +#endif + /* Configure MPP */ writel(0x00001111, MVEBU_MPP_BASE + 0x00); writel(0x00000000, MVEBU_MPP_BASE + 0x04); @@ -88,6 +97,17 @@ int board_early_init_f(void) return 0; } +void spl_board_init(void) +{ +#ifdef CONFIG_WATCHDOG + int ret; + + ret = uclass_get_device(UCLASS_WDT, 0, &watchdog_dev); + if (!ret) + wdt_start(watchdog_dev, 120000, 0); +#endif +} + int board_init(void) { /* address of boot parameters */ @@ -100,9 +120,37 @@ int board_init(void) /* DEV_READYn is not needed for NVS, ignore it when accessing CS1 */ writel(0x00004001, MVEBU_DEV_BUS_BASE + 0xc8); + spl_board_init(); + return 0; } +void arch_preboot_os(void) +{ +#ifdef CONFIG_WATCHDOG + wdt_stop(watchdog_dev); +#endif +} + +#ifdef CONFIG_WATCHDOG +void watchdog_reset(void) +{ + static ulong next_reset = 0; + ulong now; + + if (!watchdog_dev) + return; + + now = timer_get_us(); + + /* Do not reset the watchdog too often */ + if (now > next_reset) { + wdt_reset(watchdog_dev); + next_reset = now + 1000; + } +} +#endif + static int led_7seg_init(unsigned int segments) { int node; diff --git a/board/maxbcm/maxbcm.c b/board/maxbcm/maxbcm.c index e8f8f7ba5b4..395904f8c87 100644 --- a/board/maxbcm/maxbcm.c +++ b/board/maxbcm/maxbcm.c @@ -95,7 +95,7 @@ MV_DRAM_MODES *ddr3_get_static_ddr_mode(void) return &maxbcm_ddr_modes[0]; } -MV_BIN_SERDES_CFG *board_serdes_cfg_get(u8 pex_mode) +MV_BIN_SERDES_CFG *board_serdes_cfg_get(void) { return &maxbcm_serdes_cfg[0]; } diff --git a/board/mscc/jr2/jr2.c b/board/mscc/jr2/jr2.c index 58a4a04162b..6e5ef4c97f4 100644 --- a/board/mscc/jr2/jr2.c +++ b/board/mscc/jr2/jr2.c @@ -6,6 +6,7 @@ #include <common.h> #include <asm/io.h> #include <led.h> +#include <miiphy.h> enum { BOARD_TYPE_PCB110 = 0xAABBCE00, @@ -64,6 +65,28 @@ static void vcoreiii_gpio_set_alternate(int gpio, int mode) } } +int board_phy_config(struct phy_device *phydev) +{ + if (gd->board_type == BOARD_TYPE_PCB110 || + gd->board_type == BOARD_TYPE_PCB112) { + phy_write(phydev, 0, 31, 0x10); + phy_write(phydev, 0, 18, 0x80F0); + while (phy_read(phydev, 0, 18) & 0x8000) + ; + phy_write(phydev, 0, 31, 0); + } + if (gd->board_type == BOARD_TYPE_PCB111) { + phy_write(phydev, 0, 31, 0x10); + phy_write(phydev, 0, 18, 0x80A0); + while (phy_read(phydev, 0, 18) & 0x8000) + ; + phy_write(phydev, 0, 14, 0x800); + phy_write(phydev, 0, 31, 0); + } + + return 0; +} + void board_debug_uart_init(void) { /* too early for the pinctrl driver, so configure the UART pins here */ diff --git a/board/qca/ap152/Kconfig b/board/qca/ap152/Kconfig new file mode 100644 index 00000000000..f6ad498e85c --- /dev/null +++ b/board/qca/ap152/Kconfig @@ -0,0 +1,15 @@ +if TARGET_AP152 + +config SYS_VENDOR + default "qca" + +config SYS_BOARD + default "ap152" + +config SYS_CONFIG_NAME + default "ap152" + +config SYS_TEXT_BASE + default 0x9f000000 + +endif diff --git a/board/qca/ap152/MAINTAINERS b/board/qca/ap152/MAINTAINERS new file mode 100644 index 00000000000..785ec2766d1 --- /dev/null +++ b/board/qca/ap152/MAINTAINERS @@ -0,0 +1,6 @@ +AP152 BOARD +M: Rosy Song <rosysong@rosinson.com> +S: Maintained +F: board/qca/ap152/ +F: include/configs/ap152.h +F: configs/ap152_defconfig diff --git a/board/qca/ap152/Makefile b/board/qca/ap152/Makefile new file mode 100644 index 00000000000..4270afa1291 --- /dev/null +++ b/board/qca/ap152/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-y = ap152.o diff --git a/board/qca/ap152/ap152.c b/board/qca/ap152/ap152.c new file mode 100644 index 00000000000..30cd56563b9 --- /dev/null +++ b/board/qca/ap152/ap152.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Rosy Song <rosysong@rosinson.com> + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/addrspace.h> +#include <asm/types.h> +#include <mach/ar71xx_regs.h> +#include <mach/ddr.h> +#include <mach/ath79.h> +#include <debug_uart.h> + +#define RST_RESET_RTC_RESET_LSB 27 +#define RST_RESET_RTC_RESET_MASK 0x08000000 +#define RST_RESET_RTC_RESET_SET(x) \ + (((x) << RST_RESET_RTC_RESET_LSB) & RST_RESET_RTC_RESET_MASK) + +#ifdef CONFIG_DEBUG_UART_BOARD_INIT +void board_debug_uart_init(void) +{ + void __iomem *regs; + u32 val; + + regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE, + MAP_NOCACHE); + + /* UART : RX18, TX22 done + * GPIO18 as input, GPIO22 as output + */ + val = readl(regs + AR71XX_GPIO_REG_OE); + val |= QCA956X_GPIO(18); + val &= ~QCA956X_GPIO(22); + writel(val, regs + AR71XX_GPIO_REG_OE); + + /* + * Enable GPIO22 as UART0_SOUT + */ + val = readl(regs + QCA956X_GPIO_REG_OUT_FUNC5); + val &= ~QCA956X_GPIO_MUX_MASK(16); + val |= QCA956X_GPIO_OUT_MUX_UART0_SOUT << 16; + writel(val, regs + QCA956X_GPIO_REG_OUT_FUNC5); + + /* + * Enable GPIO18 as UART0_SIN + */ + val = readl(regs + QCA956X_GPIO_REG_IN_ENABLE0); + val &= ~QCA956X_GPIO_MUX_MASK(8); + val |= QCA956X_GPIO_IN_MUX_UART0_SIN << 8; + writel(val, regs + QCA956X_GPIO_REG_IN_ENABLE0); + + /* + * Enable GPIO22 output + */ + val = readl(regs + AR71XX_GPIO_REG_OUT); + val |= QCA956X_GPIO(22); + writel(val, regs + AR71XX_GPIO_REG_OUT); +} +#endif + +int board_early_init_f(void) +{ + u32 reg; + void __iomem *rst_regs = map_physmem(AR71XX_RESET_BASE, + AR71XX_RESET_SIZE, MAP_NOCACHE); + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + /* CPU:775, DDR:650, AHB:258 */ + qca956x_pll_init(); + qca956x_ddr_init(); +#endif + + /* Take WMAC out of reset */ + reg = readl(rst_regs + QCA956X_RESET_REG_RESET_MODULE); + reg &= (~RST_RESET_RTC_RESET_SET(1)); + writel(reg, rst_regs + QCA956X_RESET_REG_RESET_MODULE); + + ath79_eth_reset(); + return 0; +} diff --git a/board/solidrun/clearfog/README b/board/solidrun/clearfog/README index a7bc0d4e23f..0b0e98de90a 100644 --- a/board/solidrun/clearfog/README +++ b/board/solidrun/clearfog/README @@ -17,6 +17,29 @@ $ sudo dd if=u-boot-spl.kwb of=/dev/sdX bs=512 seek=1 Please use the correct device node for your setup instead of "/dev/sdX" here! +Install U-Boot on eMMC: +----------------------- + +The ROM loads the bootloader from eMMC first boot partition at offset 0. This +is unlike load from SD card that is at offset 512. As a result, the offset of +the main U-Boot image on the eMMC boot partition changes. Set +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR to 0x140 for SPL to load U-Boot from +the correct location. + +To make SPL load the main U-Boot image from the eMMC boot partition enable +eMMC boot acknowledgement and boot partition with the following U-Boot +command: + + mmc partconf 0 1 1 0 + +Install U-Boot on eMMC boot partition from Linux running on Clearfog: + + echo 0 > /sys/block/mmcblk0boot0/force_ro + dd if=u-boot-spl.kwb of=/dev/mmcblk0boot0 + +Note that the SD card is not accessible when the Clearfog SOM has eMMC. +Consider initial boot from UART (see below). + Boot selection: --------------- diff --git a/board/st/stm32mp1/MAINTAINERS b/board/st/stm32mp1/MAINTAINERS index 48d8fd2c3f2..0a2eddbe03d 100644 --- a/board/st/stm32mp1/MAINTAINERS +++ b/board/st/stm32mp1/MAINTAINERS @@ -2,7 +2,8 @@ STM32MP1 BOARD M: Patrick Delaunay <patrick.delaunay@st.com> L: uboot-stm32@st-md-mailman.stormreply.com (moderated for non-subscribers) S: Maintained +F: arch/arm/dts/stm32mp157* F: board/st/stm32mp1 -F: include/configs/stm32mp1.h F: configs/stm32mp15_basic_defconfig -F: arch/arm/dts/stm32mp157* +F: configs/stm32mp15_trusted_defconfig +F: include/configs/stm32mp1.h diff --git a/board/st/stm32mp1/README b/board/st/stm32mp1/README index 174e6db1484..1cd3534ae4e 100644 --- a/board/st/stm32mp1/README +++ b/board/st/stm32mp1/README @@ -28,14 +28,15 @@ Everything is supported in Linux but U-Boot is limited to: And the necessary drivers 1. I2C -2. STPMU1 -2. STPMU1 (PMIC and regulator) +2. STPMIC1 (PMIC and regulator) 3. Clock, Reset, Sysreset 4. Fuse Currently the following boards are supported: + stm32mp157c-ev1 + stm32mp157c-ed1 ++ stm32mp157a-dk1 ++ stm32mp157c-dk2 3. Boot Sequences ================= @@ -45,15 +46,22 @@ BootRom => FSBL in SYSRAM => SSBL in DDR => OS (Linux Kernel) with FSBL = First Stage Bootloader SSBL = Second Stage Bootloader -One boot configuration is supported: +2 boot configurations are supported: - The "Basic" boot chain (defconfig_file : stm32mp15_basic_defconfig) +1) The "Trusted" boot chain (defconfig_file : stm32mp15_trusted_defconfig) + BootRom => FSBL = Trusted Firmware-A (TF-A) => SSBL = U-Boot + TF-A performs a full initialization of Secure peripherals and installs a + secure monitor. + U-Boot is running in normal world and uses TF-A monitor + to access to secure resources + +2) The "Basic" boot chain (defconfig_file : stm32mp15_basic_defconfig) BootRom => FSBL = U-Boot SPL => SSBL = U-Boot SPL has limited security initialisation U-Boot is running in secure mode and provide a secure monitor to the kernel with only PSCI support (Power State Coordination Interface defined by ARM) -All the STM32MP1 board supported by U-Boot use the same generic board +All the STM32MP1 boards supported by U-Boot use the same generic board stm32mp1 which support all the bootable devices. Each board is configurated only with the associated device tree. @@ -64,12 +72,18 @@ Each board is configurated only with the associated device tree. You need to select the appropriate device tree for your board, the supported device trees for stm32mp157 are: -+ ev1: eval board with pmic stpmu1 (ev1 = mother board + daughter ed1) ++ ev1: eval board with pmic stpmic1 (ev1 = mother board + daughter ed1) dts: stm32mp157c-ev1 -+ ed1: daughter board with pmic stpmu1 ++ ed1: daughter board with pmic stpmic1 dts: stm32mp157c-ed1 ++ dk1: Discovery board + dts: stm32mp157a-dk1 + ++ dk2: Discovery board = dk1 with a BT/WiFI combo and a DSI panel + dts: stm32mp157c-dk2 + 5. Build Procedure ================== @@ -90,12 +104,14 @@ the supported device trees for stm32mp157 are: # export KBUILD_OUTPUT=/path/to/output for example: use one output directory for each configuration + # export KBUILD_OUTPUT=stm32mp15_trusted # export KBUILD_OUTPUT=stm32mp15_basic -4. Configure the U-Boot: +4. Configure U-Boot: # make <defconfig_file> + - For trusted boot mode : "stm32mp15_trusted_defconfig" - For basic boot mode: "stm32mp15_basic_defconfig" 5. Configure the device-tree and build the U-Boot image: @@ -104,16 +120,26 @@ the supported device trees for stm32mp157 are: example: - basic boot on ev1 + a) trusted boot on ev1 + # export KBUILD_OUTPUT=stm32mp15_trusted + # make stm32mp15_trusted_defconfig + # make DEVICE_TREE=stm32mp157c-ev1 all + + b) basic boot on ev1 # export KBUILD_OUTPUT=stm32mp15_basic # make stm32mp15_basic_defconfig # make DEVICE_TREE=stm32mp157c-ev1 all - basic boot on ed1 + c) basic boot on ed1 # export KBUILD_OUTPUT=stm32mp15_basic # make stm32mp15_basic_defconfig # make DEVICE_TREE=stm32mp157c-ed1 all + d) basic boot on dk2 + # export KBUILD_OUTPUT=stm32mp15_basic + # make stm32mp15_basic_defconfig + # make DEVICE_TREE=stm32mp157c-dk2 all + 6. Output files BootRom and TF-A expect binaries with STM32 image header @@ -122,6 +148,11 @@ the supported device trees for stm32mp157 are: So in the output directory (selected by KBUILD_OUTPUT), you can found the needed files: + a) For Trusted boot + + FSBL = tf-a.stm32 (provided by TF-A compilation) + + SSBL = u-boot.stm32 + + b) For Basic boot + FSBL = spl/u-boot-spl.stm32 + SSBL = u-boot.img @@ -135,13 +166,22 @@ You can select the boot mode, on the board ed1 with the switch SW1 ----------------------------------- Reserved 0 0 0 NOR 0 0 1 - SD-Card 1 1 1 SD-Card 1 0 1 eMMC 0 1 0 NAND 0 1 1 Recovery 1 1 0 Recovery 0 0 0 +- on board DK1/DK2 with the switch SW1 : BOOT0, BOOT2 + (BOOT1 forced to 0, NOR not supported) + + -------------------------- + Boot Mode BOOT2 BOOT0 + -------------------------- + Reserved 1 0 + SD-Card 1 1 + Recovery 0 0 + Recovery is a boot from serial link (UART/USB) and it is used with STM32CubeProgrammer tool to load executable in RAM and to update the flash devices available on the board (NOR/NAND/eMMC/SDCARD). @@ -158,14 +198,14 @@ The minimal requirements for STMP32MP1 boot up to U-Boot are: - one ssbl partition for U-Boot Then the minimal GPT partition is: - ----- ------- --------- ------------- - | Num | Name | Size | Content | - ----- ------- -------- -------------- + ----- ------- --------- -------------- + | Num | Name | Size | Content | + ----- ------- -------- --------------- | 1 | fsbl1 | 256 KiB | TF-A or SPL | | 2 | fsbl2 | 256 KiB | TF-A or SPL | - | 3 | ssbl | enought | U-Boot | - | * | - | - | Boot/Rootfs| - ----- ------- --------- ------------- + | 3 | ssbl | enought | U-Boot | + | * | - | - | Boot/Rootfs | + ----- ------- --------- -------------- (*) add bootable partition for extlinux.conf following Generic Distribution @@ -189,7 +229,7 @@ for example: with gpt table with 128 entries you can add other partitions for kernel one partition rootfs for example: - -n 3:5154: -c 4:rootfs + -n 4:5154: -c 4:rootfs \ c) copy the FSBL (2 times) and SSBL file on the correct partition. in this example in partition 1 to 3 @@ -199,6 +239,11 @@ for example: with gpt table with 128 entries # dd if=u-boot-spl.stm32 of=/dev/mmcblk0p2 # dd if=u-boot.img of=/dev/mmcblk0p3 + for trusted boot mode : + # dd if=tf-a.stm32 of=/dev/mmcblk0p1 + # dd if=tf-a.stm32 of=/dev/mmcblk0p2 + # dd if=u-boot.stm32 of=/dev/mmcblk0p3 + To boot from SDCard, select BootPinMode = 1 1 1 and reset. 8. Prepare eMMC @@ -208,7 +253,7 @@ You can use U-Boot to copy binary in eMMC. In the next example, you need to boot from SDCARD and the images (u-boot-spl.stm32, u-boot.img) are presents on SDCARD (mmc 0) in ext4 partition 4 (bootfs). -To boot from SDCard, select BootPinMode = 1 1 1 and reset. +To boot from SDCard, select BootPinMode = 1 0 1 and reset. Then you update the eMMC with the next U-Boot command : @@ -227,7 +272,7 @@ b) copy SPL on eMMC on firts boot partition # mmc write ${fileaddr} 0 200 # mmc partconf 1 1 1 0 -b) copy U-Boot in first GPT partition of eMMC +c) copy U-Boot in first GPT partition of eMMC # ext4load mmc 0:4 0xC0000000 u-boot.img # mmc dev 1 diff --git a/board/st/stm32mp1/board.c b/board/st/stm32mp1/board.c index 5f31ea99f59..5c1acca20d7 100644 --- a/board/st/stm32mp1/board.c +++ b/board/st/stm32mp1/board.c @@ -8,7 +8,7 @@ #include <asm/io.h> #include <asm/arch/ddr.h> #include <power/pmic.h> -#include <power/stpmu1.h> +#include <power/stpmic1.h> #ifdef CONFIG_DEBUG_UART_BOARD_INIT void board_debug_uart_init(void) @@ -37,64 +37,65 @@ void board_debug_uart_init(void) } #endif -#ifdef CONFIG_PMIC_STPMU1 +#ifdef CONFIG_PMIC_STPMIC1 int board_ddr_power_init(void) { struct udevice *dev; int ret; ret = uclass_get_device_by_driver(UCLASS_PMIC, - DM_GET_DRIVER(pmic_stpmu1), &dev); + DM_GET_DRIVER(pmic_stpmic1), &dev); if (ret) /* No PMIC on board */ return 0; - /* Set LDO3 to sync mode */ - ret = pmic_reg_read(dev, STPMU1_LDOX_CTRL_REG(STPMU1_LDO3)); + /* VTT = Set LDO3 to sync mode */ + ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3)); if (ret < 0) return ret; - ret &= ~STPMU1_LDO3_MODE; - ret &= ~STPMU1_LDO12356_OUTPUT_MASK; - ret |= STPMU1_LDO3_DDR_SEL << STPMU1_LDO12356_OUTPUT_SHIFT; + ret &= ~STPMIC1_LDO3_MODE; + ret &= ~STPMIC1_LDO12356_VOUT_MASK; + ret |= STPMIC1_LDO_VOUT(STPMIC1_LDO3_DDR_SEL); - ret = pmic_reg_write(dev, STPMU1_LDOX_CTRL_REG(STPMU1_LDO3), + ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), ret); if (ret < 0) return ret; - /* Set BUCK2 to 1.35V */ + /* VDD_DDR = Set BUCK2 to 1.35V */ ret = pmic_clrsetbits(dev, - STPMU1_BUCKX_CTRL_REG(STPMU1_BUCK2), - STPMU1_BUCK_OUTPUT_MASK, - STPMU1_BUCK2_1350000V); + STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), + STPMIC1_BUCK_VOUT_MASK, + STPMIC1_BUCK2_1350000V); if (ret < 0) return ret; - /* Enable BUCK2 and VREF */ + /* Enable VDD_DDR = BUCK2 */ ret = pmic_clrsetbits(dev, - STPMU1_BUCKX_CTRL_REG(STPMU1_BUCK2), - STPMU1_BUCK_EN, STPMU1_BUCK_EN); + STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2), + STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA); if (ret < 0) return ret; - mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS); + mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); - ret = pmic_clrsetbits(dev, STPMU1_VREF_CTRL_REG, - STPMU1_VREF_EN, STPMU1_VREF_EN); + /* Enable VREF */ + ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR, + STPMIC1_VREF_ENA, STPMIC1_VREF_ENA); if (ret < 0) return ret; - mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS); + mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); /* Enable LDO3 */ ret = pmic_clrsetbits(dev, - STPMU1_LDOX_CTRL_REG(STPMU1_LDO3), - STPMU1_LDO_EN, STPMU1_LDO_EN); + STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3), + STPMIC1_LDO_ENA, STPMIC1_LDO_ENA); if (ret < 0) return ret; - mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS); + mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); return 0; } diff --git a/board/st/stm32mp1/spl.c b/board/st/stm32mp1/spl.c index f3db0d63853..a7844f244bc 100644 --- a/board/st/stm32mp1/spl.c +++ b/board/st/stm32mp1/spl.c @@ -11,22 +11,22 @@ #include <asm/io.h> #include <post.h> #include <power/pmic.h> -#include <power/stpmu1.h> +#include <power/stpmic1.h> #include <asm/arch/ddr.h> void spl_board_init(void) { /* Keep vdd on during the reset cycle */ -#if defined(CONFIG_PMIC_STPMU1) && defined(CONFIG_SPL_POWER_SUPPORT) +#if defined(CONFIG_PMIC_STPMIC1) && defined(CONFIG_SPL_POWER_SUPPORT) struct udevice *dev; int ret; ret = uclass_get_device_by_driver(UCLASS_PMIC, - DM_GET_DRIVER(pmic_stpmu1), &dev); + DM_GET_DRIVER(pmic_stpmic1), &dev); if (!ret) pmic_clrsetbits(dev, - STPMU1_MASK_RESET_BUCK, - STPMU1_MASK_RESET_BUCK3, - STPMU1_MASK_RESET_BUCK3); + STPMIC1_BUCKS_MRST_CR, + STPMIC1_MRST_BUCK(STPMIC1_BUCK3), + STPMIC1_MRST_BUCK(STPMIC1_BUCK3)); #endif } diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 54feca0ecff..24d299ac33b 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -2,20 +2,57 @@ /* * Copyright (C) 2018, STMicroelectronics - All Rights Reserved */ -#include <config.h> #include <common.h> -#include <led.h> +#include <adc.h> +#include <config.h> #include <clk.h> #include <dm.h> #include <generic-phy.h> +#include <led.h> +#include <misc.h> #include <phy.h> #include <reset.h> +#include <syscon.h> #include <usb.h> -#include <asm/arch/stm32.h> #include <asm/io.h> +#include <asm/gpio.h> +#include <asm/arch/stm32.h> #include <power/regulator.h> #include <usb/dwc2_udc.h> +/* SYSCFG registers */ +#define SYSCFG_BOOTR 0x00 +#define SYSCFG_PMCSETR 0x04 +#define SYSCFG_IOCTRLSETR 0x18 +#define SYSCFG_ICNR 0x1C +#define SYSCFG_CMPCR 0x20 +#define SYSCFG_CMPENSETR 0x24 +#define SYSCFG_PMCCLRR 0x44 + +#define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0) +#define SYSCFG_BOOTR_BOOTPD_SHIFT 4 + +#define SYSCFG_IOCTRLSETR_HSLVEN_TRACE BIT(0) +#define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI BIT(1) +#define SYSCFG_IOCTRLSETR_HSLVEN_ETH BIT(2) +#define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC BIT(3) +#define SYSCFG_IOCTRLSETR_HSLVEN_SPI BIT(4) + +#define SYSCFG_CMPCR_SW_CTRL BIT(1) +#define SYSCFG_CMPCR_READY BIT(8) + +#define SYSCFG_CMPENSETR_MPU_EN BIT(0) + +#define SYSCFG_PMCSETR_ETH_CLK_SEL BIT(16) +#define SYSCFG_PMCSETR_ETH_REF_CLK_SEL BIT(17) + +#define SYSCFG_PMCSETR_ETH_SELMII BIT(20) + +#define SYSCFG_PMCSETR_ETH_SEL_MASK GENMASK(23, 21) +#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII (0 << 21) +#define SYSCFG_PMCSETR_ETH_SEL_RGMII (1 << 21) +#define SYSCFG_PMCSETR_ETH_SEL_RMII (4 << 21) + /* * Get a global data pointer */ @@ -26,6 +63,98 @@ DECLARE_GLOBAL_DATA_PTR; #define STM32MP_GGPIO 0x38 #define STM32MP_GGPIO_VBUS_SENSING BIT(21) +#define USB_WARNING_LOW_THRESHOLD_UV 660000 +#define USB_START_LOW_THRESHOLD_UV 1230000 +#define USB_START_HIGH_THRESHOLD_UV 2100000 + +int checkboard(void) +{ + int ret; + char *mode; + u32 otp; + struct udevice *dev; + const char *fdt_compat; + int fdt_compat_len; + + if (IS_ENABLED(CONFIG_STM32MP1_TRUSTED)) + mode = "trusted"; + else + mode = "basic"; + + printf("Board: stm32mp1 in %s mode", mode); + fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible", + &fdt_compat_len); + if (fdt_compat && fdt_compat_len) + printf(" (%s)", fdt_compat); + puts("\n"); + + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_GET_DRIVER(stm32mp_bsec), + &dev); + + if (!ret) + ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD), + &otp, sizeof(otp)); + if (!ret && otp) { + printf("Board: MB%04x Var%d Rev.%c-%02d\n", + otp >> 16, + (otp >> 12) & 0xF, + ((otp >> 8) & 0xF) - 1 + 'A', + otp & 0xF); + } + + return 0; +} + +static void board_key_check(void) +{ +#if defined(CONFIG_FASTBOOT) || defined(CONFIG_CMD_STM32PROG) + ofnode node; + struct gpio_desc gpio; + enum forced_boot_mode boot_mode = BOOT_NORMAL; + + node = ofnode_path("/config"); + if (!ofnode_valid(node)) { + debug("%s: no /config node?\n", __func__); + return; + } +#ifdef CONFIG_FASTBOOT + if (gpio_request_by_name_nodev(node, "st,fastboot-gpios", 0, + &gpio, GPIOD_IS_IN)) { + debug("%s: could not find a /config/st,fastboot-gpios\n", + __func__); + } else { + if (dm_gpio_get_value(&gpio)) { + puts("Fastboot key pressed, "); + boot_mode = BOOT_FASTBOOT; + } + + dm_gpio_free(NULL, &gpio); + } +#endif +#ifdef CONFIG_CMD_STM32PROG + if (gpio_request_by_name_nodev(node, "st,stm32prog-gpios", 0, + &gpio, GPIOD_IS_IN)) { + debug("%s: could not find a /config/st,stm32prog-gpios\n", + __func__); + } else { + if (dm_gpio_get_value(&gpio)) { + puts("STM32Programmer key pressed, "); + boot_mode = BOOT_STM32PROG; + } + dm_gpio_free(NULL, &gpio); + } +#endif + + if (boot_mode != BOOT_NORMAL) { + puts("entering download mode...\n"); + clrsetbits_le32(TAMP_BOOT_CONTEXT, + TAMP_BOOT_FORCED_MASK, + boot_mode); + } +#endif +} + static struct dwc2_plat_otg_data stm32mp_otg_data = { .usb_gusbcfg = STM32MP_GUSBCFG, }; @@ -170,6 +299,145 @@ clk_err: return ret; } +static int get_led(struct udevice **dev, char *led_string) +{ + char *led_name; + int ret; + + led_name = fdtdec_get_config_string(gd->fdt_blob, led_string); + if (!led_name) { + pr_debug("%s: could not find %s config string\n", + __func__, led_string); + return -ENOENT; + } + ret = led_get_by_label(led_name, dev); + if (ret) { + debug("%s: get=%d\n", __func__, ret); + return ret; + } + + return 0; +} + +static int setup_led(enum led_state_t cmd) +{ + struct udevice *dev; + int ret; + + ret = get_led(&dev, "u-boot,boot-led"); + if (ret) + return ret; + + ret = led_set_state(dev, cmd); + return ret; +} + +static int board_check_usb_power(void) +{ + struct ofnode_phandle_args adc_args; + struct udevice *adc; + struct udevice *led; + ofnode node; + unsigned int raw; + int max_uV = 0; + int ret, uV, adc_count; + u8 i, nb_blink; + + node = ofnode_path("/config"); + if (!ofnode_valid(node)) { + debug("%s: no /config node?\n", __func__); + return -ENOENT; + } + + /* + * Retrieve the ADC channels devices and get measurement + * for each of them + */ + adc_count = ofnode_count_phandle_with_args(node, "st,adc_usb_pd", + "#io-channel-cells"); + if (adc_count < 0) { + if (adc_count == -ENOENT) + return 0; + + pr_err("%s: can't find adc channel (%d)\n", __func__, + adc_count); + + return adc_count; + } + + for (i = 0; i < adc_count; i++) { + if (ofnode_parse_phandle_with_args(node, "st,adc_usb_pd", + "#io-channel-cells", 0, i, + &adc_args)) { + pr_debug("%s: can't find /config/st,adc_usb_pd\n", + __func__); + return 0; + } + + ret = uclass_get_device_by_ofnode(UCLASS_ADC, adc_args.node, + &adc); + + if (ret) { + pr_err("%s: Can't get adc device(%d)\n", __func__, + ret); + return ret; + } + + ret = adc_channel_single_shot(adc->name, adc_args.args[0], + &raw); + if (ret) { + pr_err("%s: single shot failed for %s[%d]!\n", + __func__, adc->name, adc_args.args[0]); + return ret; + } + /* Convert to uV */ + if (!adc_raw_to_uV(adc, raw, &uV)) { + if (uV > max_uV) + max_uV = uV; + pr_debug("%s: %s[%02d] = %u, %d uV\n", __func__, + adc->name, adc_args.args[0], raw, uV); + } else { + pr_err("%s: Can't get uV value for %s[%d]\n", + __func__, adc->name, adc_args.args[0]); + } + } + + /* + * If highest value is inside 1.23 Volts and 2.10 Volts, that means + * board is plugged on an USB-C 3A power supply and boot process can + * continue. + */ + if (max_uV > USB_START_LOW_THRESHOLD_UV && + max_uV < USB_START_HIGH_THRESHOLD_UV) + return 0; + + /* Display warning message and make u-boot,error-led blinking */ + pr_err("\n*******************************************\n"); + + if (max_uV < USB_WARNING_LOW_THRESHOLD_UV) { + pr_err("* WARNING 500mA power supply detected *\n"); + nb_blink = 2; + } else { + pr_err("* WARNING 1.5A power supply detected *\n"); + nb_blink = 3; + } + + pr_err("* Current too low, use a 3A power supply! *\n"); + pr_err("*******************************************\n\n"); + + ret = get_led(&led, "u-boot,error-led"); + if (ret) + return ret; + + for (i = 0; i < nb_blink * 2; i++) { + led_set_state(led, LEDST_TOGGLE); + mdelay(125); + } + led_set_state(led, LEDST_ON); + + return 0; +} + int board_usb_cleanup(int index, enum usb_init_type init) { /* Reset usbotg */ @@ -180,19 +448,146 @@ int board_usb_cleanup(int index, enum usb_init_type init) return 0; } -int board_late_init(void) +static void sysconf_init(void) { - return 0; +#ifndef CONFIG_STM32MP1_TRUSTED + u8 *syscfg; +#ifdef CONFIG_DM_REGULATOR + struct udevice *pwr_dev; + struct udevice *pwr_reg; + struct udevice *dev; + int ret; + u32 otp = 0; +#endif + u32 bootr; + + syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); + + /* interconnect update : select master using the port 1 */ + /* LTDC = AXI_M9 */ + /* GPU = AXI_M8 */ + /* today information is hardcoded in U-Boot */ + writel(BIT(9), syscfg + SYSCFG_ICNR); + + /* disable Pull-Down for boot pin connected to VDD */ + bootr = readl(syscfg + SYSCFG_BOOTR); + bootr &= ~(SYSCFG_BOOTR_BOOT_MASK << SYSCFG_BOOTR_BOOTPD_SHIFT); + bootr |= (bootr & SYSCFG_BOOTR_BOOT_MASK) << SYSCFG_BOOTR_BOOTPD_SHIFT; + writel(bootr, syscfg + SYSCFG_BOOTR); + +#ifdef CONFIG_DM_REGULATOR + /* High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI + * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection. + * The customer will have to disable this for low frequencies + * or if AFMUX is selected but the function not used, typically for + * TRACE. Otherwise, impact on power consumption. + * + * WARNING: + * enabling High Speed mode while VDD>2.7V + * with the OTP product_below_2v5 (OTP 18, BIT 13) + * erroneously set to 1 can damage the IC! + * => U-Boot set the register only if VDD < 2.7V (in DT) + * but this value need to be consistent with board design + */ + ret = syscon_get_by_driver_data(STM32MP_SYSCON_PWR, &pwr_dev); + if (!ret) { + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_GET_DRIVER(stm32mp_bsec), + &dev); + if (ret) { + pr_err("Can't find stm32mp_bsec driver\n"); + return; + } + + ret = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4); + if (!ret) + otp = otp & BIT(13); + + /* get VDD = pwr-supply */ + ret = device_get_supply_regulator(pwr_dev, "pwr-supply", + &pwr_reg); + + /* check if VDD is Low Voltage */ + if (!ret) { + if (regulator_get_value(pwr_reg) < 2700000) { + writel(SYSCFG_IOCTRLSETR_HSLVEN_TRACE | + SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI | + SYSCFG_IOCTRLSETR_HSLVEN_ETH | + SYSCFG_IOCTRLSETR_HSLVEN_SDMMC | + SYSCFG_IOCTRLSETR_HSLVEN_SPI, + syscfg + SYSCFG_IOCTRLSETR); + + if (!otp) + pr_err("product_below_2v5=0: HSLVEN protected by HW\n"); + } else { + if (otp) + pr_err("product_below_2v5=1: HSLVEN update is destructive, no update as VDD>2.7V\n"); + } + } else { + debug("VDD unknown"); + } + } +#endif + + /* activate automatic I/O compensation + * warning: need to ensure CSI enabled and ready in clock driver + */ + writel(SYSCFG_CMPENSETR_MPU_EN, syscfg + SYSCFG_CMPENSETR); + + while (!(readl(syscfg + SYSCFG_CMPCR) & SYSCFG_CMPCR_READY)) + ; + clrbits_le32(syscfg + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); +#endif } /* board dependent setup after realloc */ int board_init(void) { + struct udevice *dev; + /* address of boot parameters */ gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100; + /* probe all PINCTRL for hog */ + for (uclass_first_device(UCLASS_PINCTRL, &dev); + dev; + uclass_next_device(&dev)) { + pr_debug("probe pincontrol = %s\n", dev->name); + } + + board_key_check(); + + sysconf_init(); + if (IS_ENABLED(CONFIG_LED)) led_default_state(); return 0; } + +int board_late_init(void) +{ +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + const void *fdt_compat; + int fdt_compat_len; + + fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible", + &fdt_compat_len); + if (fdt_compat && fdt_compat_len) { + if (strncmp(fdt_compat, "st,", 3) != 0) + env_set("board_name", fdt_compat); + else + env_set("board_name", fdt_compat + 3); + } +#endif + + /* for DK1/DK2 boards */ + board_check_usb_power(); + + return 0; +} + +void board_quiesce_devices(void) +{ + setup_led(LEDST_OFF); +} diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 8e2f90fc68c..338f374e56e 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -341,6 +341,11 @@ M: FUKAUMI Naoki <naobsd@gmail.com> S: Maintained F: configs/Nintendo_NES_Classic_Edition_defconfig +OCEANIC 5205 5INMFD BOARD +M: Jagan Teki <jagan@amarulasolutions.com> +S: Maintained +F: configs/oceanic_5205_5inmfd_defconfig + OLIMEX A20-SOM204 BOARD M: Stefan Mavrodiev <stefan@olimex.com> S: Maintained @@ -348,7 +353,7 @@ F: configs/A20-Olimex-SOM204-EVB_defconfig F: configs/A20-Olimex-SOM204-EVB-eMMC_defconfig ORANGEPI LITE2 BOARD -M: Jagan Teki <jagan@openedev.com> +M: Jagan Teki <jagan@amarulasolutions.com> S: Maintained F: configs/orangepi_lite2_defconfig diff --git a/board/theadorable/theadorable.c b/board/theadorable/theadorable.c index dd6def5e6e7..d42350319cc 100644 --- a/board/theadorable/theadorable.c +++ b/board/theadorable/theadorable.c @@ -1,11 +1,15 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (C) 2015-2016 Stefan Roese <sr@denx.de> + * Copyright (C) 2015-2019 Stefan Roese <sr@denx.de> */ #include <common.h> +#include <console.h> #include <i2c.h> #include <pci.h> +#if !defined(CONFIG_SPL_BUILD) +#include <bootcount.h> +#endif #include <asm/gpio.h> #include <asm/io.h> #include <asm/arch/cpu.h> @@ -42,6 +46,7 @@ DECLARE_GLOBAL_DATA_PTR; #define STM_I2C_BUS 1 #define STM_I2C_ADDR 0x27 #define REBOOT_DELAY 1000 /* reboot-delay in ms */ +#define ABORT_TIMEOUT 3000 /* 3 seconds reboot abort timeout */ /* DDR3 static configuration */ static MV_DRAM_MC_INIT ddr3_theadorable[MV_MAX_DDR3_STATIC_SIZE] = { @@ -127,15 +132,15 @@ MV_DRAM_MODES *ddr3_get_static_ddr_mode(void) return &board_ddr_modes[0]; } -MV_BIN_SERDES_CFG *board_serdes_cfg_get(u8 pex_mode) +MV_BIN_SERDES_CFG *board_serdes_cfg_get(void) { return &theadorable_serdes_cfg[0]; } u8 board_sat_r_get(u8 dev_num, u8 reg) { - /* Bit 0 enables PCI 2.0 link capabilities instead of PCI 1.x */ - return 0x01; + /* Bit x enables PCI 2.0 link capabilities instead of PCI 1.x */ + return 0xe; /* PEX port 0 is PCIe Gen1, PEX port 1..3 PCIe Gen2 */ } int board_early_init_f(void) @@ -218,7 +223,7 @@ int board_eth_init(bd_t *bis) } #endif -#ifdef CONFIG_BOARD_LATE_INIT +#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_BOARD_LATE_INIT) int board_late_init(void) { pci_dev_t bdf; @@ -232,6 +237,7 @@ int board_late_init(void) */ bdf = pci_find_device(PCI_VENDOR_ID_PLX, 0x8619, 0); if (bdf == -1) { + unsigned long start_time = get_timer(0); u8 i2c_buf[8]; int ret; @@ -239,6 +245,28 @@ int board_late_init(void) bootcount = bootcount_load(); printf("Failed to find PLX PEX-switch (bootcount=%ld)\n", bootcount); + + /* + * The user can exit this boot-loop in the error case by + * hitting Ctrl-C. So wait some time for this key here. + */ + printf("Continue booting with Ctrl-C, otherwise rebooting\n"); + do { + /* Handle control-c and timeouts */ + if (ctrlc()) { + printf("PEX error boot-loop aborted!\n"); + return 0; + } + } while (get_timer(start_time) < ABORT_TIMEOUT); + + + /* + * At this stage the bootcounter has not been incremented + * yet. We need to do this manually here to get an actually + * working bootcounter in this error case. + */ + bootcount_inc(); + if (bootcount > PEX_SWITCH_NOT_FOUNT_LIMIT) { printf("Issuing power-switch via uC!\n"); diff --git a/cmd/Kconfig b/cmd/Kconfig index 0b07b3b9d77..2bdbfcb3d09 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1101,6 +1101,12 @@ config CMD_VIRTIO help VirtIO block device support +config CMD_WDT + bool "wdt" + depends on WDT + help + This provides commands to control the watchdog timer devices. + config CMD_AXI bool "axi" depends on AXI diff --git a/cmd/Makefile b/cmd/Makefile index acb85f49fba..6b1c6b094e6 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -142,6 +142,7 @@ obj-$(CONFIG_CMD_UBIFS) += ubifs.o obj-$(CONFIG_CMD_UNIVERSE) += universe.o obj-$(CONFIG_CMD_UNZIP) += unzip.o obj-$(CONFIG_CMD_VIRTIO) += virtio.o +obj-$(CONFIG_CMD_WDT) += wdt.o obj-$(CONFIG_CMD_LZMADEC) += lzmadec.o obj-$(CONFIG_CMD_USB) += usb.o disk.o @@ -81,14 +81,13 @@ static int do_spi_flash_probe(int argc, char * const argv[]) { unsigned int bus = CONFIG_SF_DEFAULT_BUS; unsigned int cs = CONFIG_SF_DEFAULT_CS; + /* In DM mode, defaults speed and mode will be taken from DT */ unsigned int speed = CONFIG_SF_DEFAULT_SPEED; unsigned int mode = CONFIG_SF_DEFAULT_MODE; char *endp; #ifdef CONFIG_DM_SPI_FLASH struct udevice *new, *bus_dev; int ret; - /* In DM mode defaults will be taken from DT */ - speed = 0, mode = 0; #else struct spi_flash *new; #endif diff --git a/cmd/wdt.c b/cmd/wdt.c new file mode 100644 index 00000000000..647d9899b43 --- /dev/null +++ b/cmd/wdt.c @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Watchdog commands + * + * Copyright (c) 2019 Michael Walle <michael@walle.cc> + */ + +#include <common.h> +#include <command.h> +#include <dm.h> +#include <wdt.h> + +static struct udevice *currdev; + +static int do_wdt_list(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct udevice *dev; + struct uclass *uc; + int ret; + + ret = uclass_get(UCLASS_WDT, &uc); + if (ret) + return CMD_RET_FAILURE; + + uclass_foreach_dev(dev, uc) + printf("%s (%s)\n", dev->name, dev->driver->name); + + return CMD_RET_SUCCESS; +} + +static int do_wdt_dev(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + + if (argc > 1) { + ret = uclass_get_device_by_name(UCLASS_WDT, argv[1], &currdev); + if (ret) { + printf("Can't get the watchdog timer: %s\n", argv[1]); + return CMD_RET_FAILURE; + } + } else { + if (!currdev) { + printf("No watchdog timer device set!\n"); + return CMD_RET_FAILURE; + } + printf("dev: %s\n", currdev->name); + } + + return CMD_RET_SUCCESS; +} + +static int check_currdev(void) +{ + if (!currdev) { + printf("No device set, use 'wdt dev' first\n"); + return CMD_RET_FAILURE; + } + return 0; +} + +static int do_wdt_start(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + u64 timeout; + ulong flags = 0; + + if (argc < 2) + return CMD_RET_USAGE; + + ret = check_currdev(); + if (ret) + return ret; + + timeout = simple_strtoull(argv[1], NULL, 0); + if (argc > 2) + flags = simple_strtoul(argv[2], NULL, 0); + + ret = wdt_start(currdev, timeout, flags); + if (ret == -ENOSYS) { + printf("Starting watchdog timer not supported.\n"); + return CMD_RET_FAILURE; + } else if (ret) { + printf("Starting watchdog timer failed (%d)\n", ret); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +static int do_wdt_stop(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + + ret = check_currdev(); + if (ret) + return ret; + + ret = wdt_stop(currdev); + if (ret == -ENOSYS) { + printf("Stopping watchdog timer not supported.\n"); + return CMD_RET_FAILURE; + } else if (ret) { + printf("Stopping watchdog timer failed (%d)\n", ret); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +static int do_wdt_reset(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + + ret = check_currdev(); + if (ret) + return ret; + + ret = wdt_reset(currdev); + if (ret == -ENOSYS) { + printf("Resetting watchdog timer not supported.\n"); + return CMD_RET_FAILURE; + } else if (ret) { + printf("Resetting watchdog timer failed (%d)\n", ret); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +static int do_wdt_expire(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + ulong flags = 0; + + ret = check_currdev(); + if (ret) + return ret; + + if (argc > 1) + flags = simple_strtoul(argv[1], NULL, 0); + + ret = wdt_expire_now(currdev, flags); + if (ret == -ENOSYS) { + printf("Expiring watchdog timer not supported.\n"); + return CMD_RET_FAILURE; + } else if (ret) { + printf("Expiring watchdog timer failed (%d)\n", ret); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +static char wdt_help_text[] = + "list - list watchdog devices\n" + "wdt dev [<name>] - get/set current watchdog device\n" + "wdt start <timeout ms> [flags] - start watchdog timer\n" + "wdt stop - stop watchdog timer\n" + "wdt reset - reset watchdog timer\n" + "wdt expire [flags] - expire watchdog timer immediately\n"; + +U_BOOT_CMD_WITH_SUBCMDS(wdt, "Watchdog sub-system", wdt_help_text, + U_BOOT_SUBCMD_MKENT(list, 1, 1, do_wdt_list), + U_BOOT_SUBCMD_MKENT(dev, 2, 1, do_wdt_dev), + U_BOOT_SUBCMD_MKENT(start, 3, 1, do_wdt_start), + U_BOOT_SUBCMD_MKENT(stop, 1, 1, do_wdt_stop), + U_BOOT_SUBCMD_MKENT(reset, 1, 1, do_wdt_reset), + U_BOOT_SUBCMD_MKENT(expire, 2, 1, do_wdt_expire)); diff --git a/common/fdt_support.c b/common/fdt_support.c index 42583e3ed8c..ab08a0114fe 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -456,12 +456,6 @@ int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks) if (!banks) return 0; - for (i = 0; i < banks; i++) - if (start[i] == 0 && size[i] == 0) - break; - - banks = i; - len = fdt_pack_reg(blob, tmp, start, size, banks); err = fdt_setprop(blob, nodeoffset, "reg", tmp, len); diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c index 8cd4830a39b..9b74473377f 100644 --- a/common/spl/spl_spi.c +++ b/common/spl/spl_spi.c @@ -77,6 +77,8 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, /* * Load U-Boot image from SPI flash into RAM + * In DM mode: defaults speed and mode will be + * taken from DT when available */ flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 020f0d4117f..cc99c6be072 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -145,6 +145,12 @@ static void usb_kbd_put_queue(struct usb_kbd_pdata *data, char c) data->usb_kbd_buffer[data->usb_in_pointer] = c; } +static void usb_kbd_put_sequence(struct usb_kbd_pdata *data, char *s) +{ + for (; *s; s++) + usb_kbd_put_queue(data, *s); +} + /* * Set the LEDs. Since this is used in the irq routine, the control job is * issued with a timeout of 0. This means, that the job is queued without @@ -235,9 +241,25 @@ static int usb_kbd_translate(struct usb_kbd_pdata *data, unsigned char scancode, } /* Report keycode if any */ - if (keycode) { + if (keycode) debug("%c", keycode); + + switch (keycode) { + case 0x0e: /* Down arrow key */ + usb_kbd_put_sequence(data, "\e[B"); + break; + case 0x10: /* Up arrow key */ + usb_kbd_put_sequence(data, "\e[A"); + break; + case 0x06: /* Right arrow key */ + usb_kbd_put_sequence(data, "\e[C"); + break; + case 0x02: /* Left arrow key */ + usb_kbd_put_sequence(data, "\e[D"); + break; + default: usb_kbd_put_queue(data, keycode); + break; } return 0; diff --git a/configs/ap152_defconfig b/configs/ap152_defconfig new file mode 100644 index 00000000000..21cb6eb7424 --- /dev/null +++ b/configs/ap152_defconfig @@ -0,0 +1,49 @@ +CONFIG_MIPS=y +CONFIG_SYS_TEXT_BASE=0x9F000000 +CONFIG_SYS_MALLOC_F_LEN=0x800 +CONFIG_SYS_CACHE_SIZE_AUTO=y +CONFIG_DEBUG_UART_BOARD_INIT=y +CONFIG_DEBUG_UART_BASE=0xb8020000 +CONFIG_DEBUG_UART_CLOCK=25000000 +CONFIG_ARCH_ATH79=y +CONFIG_TARGET_AP152=y +CONFIG_DEBUG_UART=y +CONFIG_BOOTDELAY=3 +CONFIG_USE_BOOTARGS=y +CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/mtdblock2 rootfstype=squashfs" +CONFIG_DISPLAY_CPUINFO=y +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_SYS_PROMPT="ap152 # " +# CONFIG_CMD_BDI is not set +# CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_EXPORTENV is not set +# CONFIG_CMD_IMPORTENV is not set +# CONFIG_CMD_EDITENV is not set +# CONFIG_CMD_CRC32 is not set +CONFIG_CMD_MEMTEST=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_MTDPARTS=y +CONFIG_MTDIDS_DEFAULT="nor0=spi-flash.0" +CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-flash.0:256k(u-boot),64k(u-boot-env),6336k(rootfs),1472k(uImage),64k(ART)" +# CONFIG_ISO_PARTITION is not set +CONFIG_DEFAULT_DEVICE_TREE="ap152" +CONFIG_ENV_IS_IN_SPI_FLASH=y +# CONFIG_NET is not set +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_DATAFLASH=y +CONFIG_SPI_FLASH_MTD=y +CONFIG_PINCTRL=y +CONFIG_DM_SERIAL=y +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_ATH79_SPI=y +CONFIG_LZMA=y diff --git a/configs/bananapi_m2_plus_h3_defconfig b/configs/bananapi_m2_plus_h3_defconfig index 597618fb900..4e4734655fc 100644 --- a/configs/bananapi_m2_plus_h3_defconfig +++ b/configs/bananapi_m2_plus_h3_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=672 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y CONFIG_MACPWR="PD6" CONFIG_MMC_SUNXI_SLOT_EXTRA=2 CONFIG_NR_DRAM_BANKS=1 diff --git a/configs/bananapi_m2_plus_h5_defconfig b/configs/bananapi_m2_plus_h5_defconfig index e7c10dbdf2d..29dd892d7f0 100644 --- a/configs/bananapi_m2_plus_h5_defconfig +++ b/configs/bananapi_m2_plus_h5_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN50I_H5=y CONFIG_DRAM_CLK=672 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y CONFIG_MACPWR="PD6" CONFIG_MMC_SUNXI_SLOT_EXTRA=2 CONFIG_NR_DRAM_BANKS=1 diff --git a/configs/bananapi_m2_zero_defconfig b/configs/bananapi_m2_zero_defconfig index 91302eb49cf..8546674b239 100644 --- a/configs/bananapi_m2_zero_defconfig +++ b/configs/bananapi_m2_zero_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=408 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y CONFIG_MMC0_CD_PIN="" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/bcm963158_ram_defconfig b/configs/bcm963158_ram_defconfig index fc55e98550a..5659249fdf3 100644 --- a/configs/bcm963158_ram_defconfig +++ b/configs/bcm963158_ram_defconfig @@ -20,6 +20,7 @@ CONFIG_CMD_BOOTEFI_SELFTEST=y # CONFIG_CMD_LZMADEC is not set # CONFIG_CMD_UNZIP is not set # CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y CONFIG_CMD_CACHE=y CONFIG_DOS_PARTITION=y CONFIG_ISO_PARTITION=y @@ -28,6 +29,8 @@ CONFIG_DEFAULT_DEVICE_TREE="bcm963158" # CONFIG_NET is not set CONFIG_BLK=y CONFIG_CLK=y +CONFIG_DM_GPIO=y +CONFIG_BCM6345_GPIO=y # CONFIG_MMC is not set CONFIG_SPECIFY_CONSOLE_INDEX=y # CONFIG_SPL_SERIAL_PRESENT is not set diff --git a/configs/bcm968380gerg_ram_defconfig b/configs/bcm968380gerg_ram_defconfig index 61661bd756c..fa9dc85d638 100644 --- a/configs/bcm968380gerg_ram_defconfig +++ b/configs/bcm968380gerg_ram_defconfig @@ -24,6 +24,7 @@ CONFIG_CMD_LICENSE=y # CONFIG_CMD_CRC32 is not set CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y # CONFIG_CMD_LOADS is not set # CONFIG_CMD_MISC is not set CONFIG_DEFAULT_DEVICE_TREE="brcm,bcm968380gerg" @@ -31,6 +32,7 @@ CONFIG_DEFAULT_DEVICE_TREE="brcm,bcm968380gerg" # CONFIG_DM_DEVICE_REMOVE is not set CONFIG_HAVE_BLOCK_DEVICE=y CONFIG_DM_GPIO=y +CONFIG_BCM6345_GPIO=y CONFIG_LED=y CONFIG_LED_BCM6328=y CONFIG_LED_BLINK=y diff --git a/configs/bcm968580xref_ram_defconfig b/configs/bcm968580xref_ram_defconfig index e8cb3a0d2a9..456ece72d5c 100644 --- a/configs/bcm968580xref_ram_defconfig +++ b/configs/bcm968580xref_ram_defconfig @@ -15,6 +15,7 @@ CONFIG_SUPPORT_RAW_INITRD=y CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_HUSH_PARSER=y CONFIG_CMD_BOOTEFI_SELFTEST=y +CONFIG_CMD_GPIO=y CONFIG_DOS_PARTITION=y CONFIG_ISO_PARTITION=y CONFIG_EFI_PARTITION=y @@ -22,6 +23,8 @@ CONFIG_DEFAULT_DEVICE_TREE="bcm968580xref" # CONFIG_NET is not set CONFIG_BLK=y CONFIG_CLK=y +CONFIG_DM_GPIO=y +CONFIG_BCM6345_GPIO=y # CONFIG_MMC is not set CONFIG_SPECIFY_CONSOLE_INDEX=y # CONFIG_SPL_SERIAL_PRESENT is not set diff --git a/configs/da850_am18xxevm_defconfig b/configs/da850_am18xxevm_defconfig index b8c16baf9a9..419224104af 100644 --- a/configs/da850_am18xxevm_defconfig +++ b/configs/da850_am18xxevm_defconfig @@ -39,10 +39,6 @@ CONFIG_SPL_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="da850-evm" CONFIG_SPL_OF_PLATDATA=y CONFIG_ENV_IS_IN_SPI_FLASH=y -CONFIG_USE_ENV_SPI_MAX_HZ=y -CONFIG_ENV_SPI_MAX_HZ=0 -CONFIG_USE_ENV_SPI_MODE=y -CONFIG_ENV_SPI_MODE=0 CONFIG_DM=y CONFIG_SPL_DM=y CONFIG_DA8XX_GPIO=y diff --git a/configs/da850evm_defconfig b/configs/da850evm_defconfig index 4083dcbae69..4b09ba10a67 100644 --- a/configs/da850evm_defconfig +++ b/configs/da850evm_defconfig @@ -43,10 +43,6 @@ CONFIG_OF_CONTROL=y CONFIG_SPL_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="da850-evm" CONFIG_ENV_IS_IN_SPI_FLASH=y -CONFIG_USE_ENV_SPI_MAX_HZ=y -CONFIG_ENV_SPI_MAX_HZ=0 -CONFIG_USE_ENV_SPI_MODE=y -CONFIG_ENV_SPI_MODE=0 CONFIG_DM=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y diff --git a/configs/db-88f6820-amc_defconfig b/configs/db-88f6820-amc_defconfig index dcf2a25395e..e8ba5184c4d 100644 --- a/configs/db-88f6820-amc_defconfig +++ b/configs/db-88f6820-amc_defconfig @@ -41,7 +41,7 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_EFI_PARTITION=y # CONFIG_PARTITION_UUIDS is not set # CONFIG_SPL_PARTITION_UUIDS is not set -CONFIG_DEFAULT_DEVICE_TREE="armada-385-amc" +CONFIG_DEFAULT_DEVICE_TREE="armada-385-db-88f6820-amc" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_USE_ENV_SPI_MAX_HZ=y CONFIG_ENV_SPI_MAX_HZ=50000000 diff --git a/configs/db-mv784mp-gp_defconfig b/configs/db-mv784mp-gp_defconfig index 98e47ee9563..078bd230504 100644 --- a/configs/db-mv784mp-gp_defconfig +++ b/configs/db-mv784mp-gp_defconfig @@ -46,6 +46,7 @@ CONFIG_USE_ENV_SPI_MAX_HZ=y CONFIG_ENV_SPI_MAX_HZ=50000000 CONFIG_SPL_OF_TRANSLATE=y CONFIG_SATA_MV=y +CONFIG_BLK=y # CONFIG_MMC is not set CONFIG_NAND=y CONFIG_NAND_PXA3XX=y diff --git a/configs/db-xc3-24g4xg_defconfig b/configs/db-xc3-24g4xg_defconfig new file mode 100644 index 00000000000..0285ccaa365 --- /dev/null +++ b/configs/db-xc3-24g4xg_defconfig @@ -0,0 +1,55 @@ +CONFIG_ARM=y +CONFIG_ARCH_MVEBU=y +CONFIG_SYS_TEXT_BASE=0x00800000 +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_TARGET_DB_XC3_24G4XG=y +CONFIG_BUILD_TARGET="u-boot.kwb" +CONFIG_SYS_CONSOLE_INFO_QUIET=y +CONFIG_CMD_MEMTEST=y +CONFIG_SYS_ALT_MEMTEST=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_I2C=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_DHCP=y +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_CMD_UBI=y +CONFIG_DEFAULT_DEVICE_TREE="armada-xp-db-xc3-24g4xg" +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_BLK=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_MVTWSI=y +# CONFIG_MMC is not set +CONFIG_MTD=y +CONFIG_MTD_DEVICE=y +CONFIG_NAND=y +CONFIG_NAND_PXA3XX=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_SST=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_PCI=y +CONFIG_PCI_MVEBU=y +CONFIG_SYS_NS16550=y +CONFIG_KIRKWOOD_SPI=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_ASIX=y +CONFIG_USB_ETHER_RTL8152=y +CONFIG_USB_ETHER_SMSC95XX=y diff --git a/configs/dns325_defconfig b/configs/dns325_defconfig index 5a766981603..ba8b053680b 100644 --- a/configs/dns325_defconfig +++ b/configs/dns325_defconfig @@ -30,6 +30,7 @@ CONFIG_DEFAULT_DEVICE_TREE="kirkwood-dns325" CONFIG_ENV_IS_IN_NAND=y CONFIG_DM=y CONFIG_MVSATA_IDE=y +CONFIG_BLK=y # CONFIG_MMC is not set CONFIG_MVGBE=y CONFIG_MII=y @@ -37,5 +38,6 @@ CONFIG_DM_RTC=y CONFIG_RTC_MV=y CONFIG_SYS_NS16550=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y diff --git a/configs/dreamplug_defconfig b/configs/dreamplug_defconfig index 8202848ebf7..eae36f9c0eb 100644 --- a/configs/dreamplug_defconfig +++ b/configs/dreamplug_defconfig @@ -27,6 +27,7 @@ CONFIG_USE_ENV_SPI_MAX_HZ=y CONFIG_ENV_SPI_MAX_HZ=50000000 CONFIG_DM=y CONFIG_MVSATA_IDE=y +CONFIG_BLK=y # CONFIG_MMC is not set CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y @@ -40,5 +41,6 @@ CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_KIRKWOOD_SPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y diff --git a/configs/ds109_defconfig b/configs/ds109_defconfig index 29d5f98d76c..22996e893d6 100644 --- a/configs/ds109_defconfig +++ b/configs/ds109_defconfig @@ -22,6 +22,7 @@ CONFIG_USE_ENV_SPI_MAX_HZ=y CONFIG_ENV_SPI_MAX_HZ=50000000 CONFIG_DM=y CONFIG_MVSATA_IDE=y +CONFIG_BLK=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_MVTWSI=y # CONFIG_MMC is not set @@ -37,5 +38,6 @@ CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_KIRKWOOD_SPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_FS_EXT4=y diff --git a/configs/ds414_defconfig b/configs/ds414_defconfig index 62cad538883..9e936494b2b 100644 --- a/configs/ds414_defconfig +++ b/configs/ds414_defconfig @@ -43,6 +43,7 @@ CONFIG_USE_ENV_SPI_MAX_HZ=y CONFIG_ENV_SPI_MAX_HZ=50000000 CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_OF_TRANSLATE=y +CONFIG_BLK=y # CONFIG_MMC is not set CONFIG_MTD_DEVICE=y CONFIG_SPI_FLASH=y diff --git a/configs/emlid_neutis_n5_devboard_defconfig b/configs/emlid_neutis_n5_devboard_defconfig index 3df0ca13f04..19e8d792556 100644 --- a/configs/emlid_neutis_n5_devboard_defconfig +++ b/configs/emlid_neutis_n5_devboard_defconfig @@ -4,6 +4,7 @@ CONFIG_SPL=y CONFIG_MACH_SUN50I_H5=y CONFIG_DRAM_CLK=408 CONFIG_DRAM_ZQ=3881977 +# CONFIG_DRAM_ODT_EN is not set CONFIG_MMC_SUNXI_SLOT_EXTRA=2 CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set diff --git a/configs/goflexhome_defconfig b/configs/goflexhome_defconfig index c04bf0ea574..568b74fd830 100644 --- a/configs/goflexhome_defconfig +++ b/configs/goflexhome_defconfig @@ -31,6 +31,7 @@ CONFIG_DEFAULT_DEVICE_TREE="kirkwood-goflexnet" CONFIG_ENV_IS_IN_NAND=y CONFIG_DM=y CONFIG_MVSATA_IDE=y +CONFIG_BLK=y # CONFIG_MMC is not set CONFIG_MVGBE=y CONFIG_MII=y @@ -38,5 +39,6 @@ CONFIG_DM_RTC=y CONFIG_RTC_MV=y CONFIG_SYS_NS16550=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y diff --git a/configs/guruplug_defconfig b/configs/guruplug_defconfig index 9998e48ab9c..8ae7e20bafd 100644 --- a/configs/guruplug_defconfig +++ b/configs/guruplug_defconfig @@ -31,6 +31,7 @@ CONFIG_DEFAULT_DEVICE_TREE="kirkwood-guruplug-server-plus" CONFIG_ENV_IS_IN_NAND=y CONFIG_DM=y CONFIG_MVSATA_IDE=y +CONFIG_BLK=y # CONFIG_MMC is not set CONFIG_MVGBE=y CONFIG_MII=y @@ -38,6 +39,7 @@ CONFIG_DM_RTC=y CONFIG_RTC_MV=y CONFIG_SYS_NS16550=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y CONFIG_LZMA=y diff --git a/configs/libretech_all_h3_cc_h2_plus_defconfig b/configs/libretech_all_h3_cc_h2_plus_defconfig index 8f3144895c6..3bccd604291 100644 --- a/configs/libretech_all_h3_cc_h2_plus_defconfig +++ b/configs/libretech_all_h3_cc_h2_plus_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=672 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y CONFIG_MMC_SUNXI_SLOT_EXTRA=2 CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set diff --git a/configs/libretech_all_h3_cc_h3_defconfig b/configs/libretech_all_h3_cc_h3_defconfig index e5e0f593a7d..c00ab01fdda 100644 --- a/configs/libretech_all_h3_cc_h3_defconfig +++ b/configs/libretech_all_h3_cc_h3_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=672 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y CONFIG_MMC_SUNXI_SLOT_EXTRA=2 CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set diff --git a/configs/libretech_all_h3_cc_h5_defconfig b/configs/libretech_all_h3_cc_h5_defconfig index e4a93bde481..5843f34325b 100644 --- a/configs/libretech_all_h3_cc_h5_defconfig +++ b/configs/libretech_all_h3_cc_h5_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN50I_H5=y CONFIG_DRAM_CLK=672 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y CONFIG_MMC_SUNXI_SLOT_EXTRA=2 CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set diff --git a/configs/linkit-smart-7688-ram_defconfig b/configs/linkit-smart-7688-ram_defconfig index 2d3ab7e35c3..649db0f67d0 100644 --- a/configs/linkit-smart-7688-ram_defconfig +++ b/configs/linkit-smart-7688-ram_defconfig @@ -20,17 +20,22 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_GPIO=y # CONFIG_CMD_LOADS is not set +CONFIG_CMD_MTD=y +CONFIG_CMD_PART=y CONFIG_CMD_SF=y CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y CONFIG_CMD_TIME=y +CONFIG_CMD_FS_GENERIC=y +# CONFIG_DOS_PARTITION is not set CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set -CONFIG_HAVE_BLOCK_DEVICE=y +CONFIG_BLK=y CONFIG_CLK=y CONFIG_LED=y CONFIG_LED_BLINK=y @@ -46,6 +51,7 @@ CONFIG_PHYLIB=y CONFIG_PHY_FIXED=y CONFIG_MT7628_ETH=y CONFIG_PHY=y +CONFIG_MT76X8_USB_PHY=y CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y @@ -54,5 +60,12 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_STORAGE=y +CONFIG_FS_EXT4=y +CONFIG_FS_FAT=y CONFIG_LZMA=y CONFIG_LZO=y diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig index ad34aaf640c..41aa900e562 100644 --- a/configs/linkit-smart-7688_defconfig +++ b/configs/linkit-smart-7688_defconfig @@ -24,17 +24,22 @@ CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_GPIO=y # CONFIG_CMD_LOADS is not set +CONFIG_CMD_MTD=y +CONFIG_CMD_PART=y CONFIG_CMD_SF=y CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y CONFIG_CMD_TIME=y +CONFIG_CMD_FS_GENERIC=y +# CONFIG_DOS_PARTITION is not set CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set -CONFIG_HAVE_BLOCK_DEVICE=y +CONFIG_BLK=y CONFIG_CLK=y CONFIG_LED=y CONFIG_LED_BLINK=y @@ -50,6 +55,7 @@ CONFIG_PHYLIB=y CONFIG_PHY_FIXED=y CONFIG_MT7628_ETH=y CONFIG_PHY=y +CONFIG_MT76X8_USB_PHY=y CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y @@ -58,5 +64,12 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_STORAGE=y +CONFIG_FS_EXT4=y +CONFIG_FS_FAT=y CONFIG_LZMA=y CONFIG_LZO=y diff --git a/configs/lschlv2_defconfig b/configs/lschlv2_defconfig index 16d9c9226f0..c550798bcd4 100644 --- a/configs/lschlv2_defconfig +++ b/configs/lschlv2_defconfig @@ -16,7 +16,7 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_MISC_INIT_R=y # CONFIG_DISPLAY_BOARDINFO is not set # CONFIG_CMD_FLASH is not set -CONFIG_CMD_IDE=y +CONFIG_CMD_SATA=y CONFIG_CMD_SF=y CONFIG_CMD_SPI=y CONFIG_CMD_USB=y @@ -26,7 +26,8 @@ CONFIG_DEFAULT_DEVICE_TREE="kirkwood-lschlv2" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y -CONFIG_MVSATA_IDE=y +CONFIG_SATA_MV=y +CONFIG_BLK=y # CONFIG_MMC is not set CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y @@ -39,4 +40,5 @@ CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_KIRKWOOD_SPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/lsxhl_defconfig b/configs/lsxhl_defconfig index b6eba4a4ba1..efcce455a48 100644 --- a/configs/lsxhl_defconfig +++ b/configs/lsxhl_defconfig @@ -16,7 +16,7 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_MISC_INIT_R=y # CONFIG_DISPLAY_BOARDINFO is not set # CONFIG_CMD_FLASH is not set -CONFIG_CMD_IDE=y +CONFIG_CMD_SATA=y CONFIG_CMD_SF=y CONFIG_CMD_SPI=y CONFIG_CMD_USB=y @@ -26,7 +26,8 @@ CONFIG_DEFAULT_DEVICE_TREE="kirkwood-lsxhl" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y -CONFIG_MVSATA_IDE=y +CONFIG_SATA_MV=y +CONFIG_BLK=y # CONFIG_MMC is not set CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y @@ -39,4 +40,5 @@ CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_KIRKWOOD_SPI=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/mscc_jr2_defconfig b/configs/mscc_jr2_defconfig index 95562b7cd85..d6e4bd4f9ac 100644 --- a/configs/mscc_jr2_defconfig +++ b/configs/mscc_jr2_defconfig @@ -28,7 +28,10 @@ CONFIG_CMD_MEMTEST=y CONFIG_CMD_GPIO=y CONFIG_CMD_SF=y CONFIG_CMD_SPI=y -# CONFIG_CMD_NET is not set +CONFIG_CMD_DHCP=y +# CONFIG_NET_TFTP_VARS is not set +# CONFIG_CMD_NFS is not set +CONFIG_CMD_PING=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=spi_flash" CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:1m(UBoot),256k(Env),256k(Env.bk)" @@ -38,10 +41,6 @@ CONFIG_OF_LIST="jr2_pcb110 jr2_pcb111 serval2_pcb112" CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y CONFIG_ENV_IS_IN_SPI_FLASH=y -CONFIG_USE_ENV_SPI_MAX_HZ=y -CONFIG_ENV_SPI_MAX_HZ=0 -CONFIG_USE_ENV_SPI_MODE=y -CONFIG_ENV_SPI_MODE=0 CONFIG_NET_RANDOM_ETHADDR=y CONFIG_CLK=y CONFIG_DM_GPIO=y @@ -66,3 +65,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_LZMA=y +CONFIG_MSCC_JR2_SWITCH=y diff --git a/configs/mscc_luton_defconfig b/configs/mscc_luton_defconfig index 162a5142489..0fdd9b8f3f7 100644 --- a/configs/mscc_luton_defconfig +++ b/configs/mscc_luton_defconfig @@ -44,10 +44,6 @@ CONFIG_OF_LIST="luton_pcb090 luton_pcb091" CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y CONFIG_ENV_IS_IN_SPI_FLASH=y -CONFIG_USE_ENV_SPI_MAX_HZ=y -CONFIG_ENV_SPI_MAX_HZ=0 -CONFIG_USE_ENV_SPI_MODE=y -CONFIG_ENV_SPI_MODE=0 CONFIG_NET_RANDOM_ETHADDR=y CONFIG_CLK=y CONFIG_DM_GPIO=y diff --git a/configs/mscc_ocelot_defconfig b/configs/mscc_ocelot_defconfig index b0dcfaf2df8..edc476d143f 100644 --- a/configs/mscc_ocelot_defconfig +++ b/configs/mscc_ocelot_defconfig @@ -43,10 +43,6 @@ CONFIG_OF_LIST="ocelot_pcb120 ocelot_pcb123" CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y CONFIG_ENV_IS_IN_SPI_FLASH=y -CONFIG_USE_ENV_SPI_MAX_HZ=y -CONFIG_ENV_SPI_MAX_HZ=0 -CONFIG_USE_ENV_SPI_MODE=y -CONFIG_ENV_SPI_MODE=0 CONFIG_NET_RANDOM_ETHADDR=y CONFIG_CLK=y CONFIG_DM_GPIO=y diff --git a/configs/mscc_serval_defconfig b/configs/mscc_serval_defconfig index f2c95632bd0..146188bb0c9 100644 --- a/configs/mscc_serval_defconfig +++ b/configs/mscc_serval_defconfig @@ -35,10 +35,6 @@ CONFIG_OF_LIST="serval_pcb106 serval_pcb105" CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y CONFIG_ENV_IS_IN_SPI_FLASH=y -CONFIG_USE_ENV_SPI_MAX_HZ=y -CONFIG_ENV_SPI_MAX_HZ=0 -CONFIG_USE_ENV_SPI_MODE=y -CONFIG_ENV_SPI_MODE=0 CONFIG_NET_RANDOM_ETHADDR=y CONFIG_CLK=y CONFIG_DM_GPIO=y diff --git a/configs/mscc_servalt_defconfig b/configs/mscc_servalt_defconfig index 027aaa44d56..924cf6ad013 100644 --- a/configs/mscc_servalt_defconfig +++ b/configs/mscc_servalt_defconfig @@ -24,7 +24,6 @@ CONFIG_CMD_MEMTEST=y CONFIG_CMD_GPIO=y CONFIG_CMD_SF=y CONFIG_CMD_SPI=y -# CONFIG_CMD_NET is not set CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=spi_flash" CONFIG_MTDPARTS_DEFAULT="mtdparts=spi_flash:1m(UBoot),256k(Env),256k(Env.bk)" @@ -33,10 +32,6 @@ CONFIG_DEFAULT_DEVICE_TREE="servalt_pcb116" CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y CONFIG_ENV_IS_IN_SPI_FLASH=y -CONFIG_USE_ENV_SPI_MAX_HZ=y -CONFIG_ENV_SPI_MAX_HZ=0 -CONFIG_USE_ENV_SPI_MODE=y -CONFIG_ENV_SPI_MODE=0 CONFIG_NET_RANDOM_ETHADDR=y CONFIG_CLK=y CONFIG_DM_GPIO=y @@ -59,3 +54,8 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_LZMA=y +CONFIG_CMD_DHCP=y +# CONFIG_NET_TFTP_VARS is not set +# CONFIG_CMD_NFS is not set +CONFIG_CMD_PING=y +CONFIG_MSCC_SERVALT_SWITCH=y diff --git a/configs/nanopi_m1_defconfig b/configs/nanopi_m1_defconfig index b3a7870ea9a..af7fa0b20b2 100644 --- a/configs/nanopi_m1_defconfig +++ b/configs/nanopi_m1_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=408 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/nanopi_m1_plus_defconfig b/configs/nanopi_m1_plus_defconfig index b83cdf2e1cc..84e152546b6 100644 --- a/configs/nanopi_m1_plus_defconfig +++ b/configs/nanopi_m1_plus_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=408 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y CONFIG_MMC0_CD_PIN="PH13" CONFIG_MMC_SUNXI_SLOT_EXTRA=2 CONFIG_NR_DRAM_BANKS=1 diff --git a/configs/nanopi_neo2_defconfig b/configs/nanopi_neo2_defconfig index 9de893adfaf..2d44135bbc7 100644 --- a/configs/nanopi_neo2_defconfig +++ b/configs/nanopi_neo2_defconfig @@ -4,6 +4,7 @@ CONFIG_SPL=y CONFIG_MACH_SUN50I_H5=y CONFIG_DRAM_CLK=672 CONFIG_DRAM_ZQ=3881977 +# CONFIG_DRAM_ODT_EN is not set CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/nanopi_neo_air_defconfig b/configs/nanopi_neo_air_defconfig index 33f9c0746c1..bd099c8d671 100644 --- a/configs/nanopi_neo_air_defconfig +++ b/configs/nanopi_neo_air_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=408 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y # CONFIG_VIDEO_DE2 is not set CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set diff --git a/configs/nanopi_neo_defconfig b/configs/nanopi_neo_defconfig index 40f5bd176e5..074b172061f 100644 --- a/configs/nanopi_neo_defconfig +++ b/configs/nanopi_neo_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=408 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y # CONFIG_VIDEO_DE2 is not set CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set diff --git a/configs/nanopi_neo_plus2_defconfig b/configs/nanopi_neo_plus2_defconfig index 88c76a55e53..11cb8f61b03 100644 --- a/configs/nanopi_neo_plus2_defconfig +++ b/configs/nanopi_neo_plus2_defconfig @@ -4,6 +4,7 @@ CONFIG_SPL=y CONFIG_MACH_SUN50I_H5=y CONFIG_DRAM_CLK=408 CONFIG_DRAM_ZQ=3881977 +# CONFIG_DRAM_ODT_EN is not set CONFIG_MACPWR="PD6" CONFIG_MMC_SUNXI_SLOT_EXTRA=2 CONFIG_NR_DRAM_BANKS=1 diff --git a/configs/nas220_defconfig b/configs/nas220_defconfig index 6bd308bb826..a244b8d6916 100644 --- a/configs/nas220_defconfig +++ b/configs/nas220_defconfig @@ -31,6 +31,7 @@ CONFIG_DEFAULT_DEVICE_TREE="kirkwood-blackarmor-nas220" CONFIG_ENV_IS_IN_NAND=y CONFIG_DM=y CONFIG_MVSATA_IDE=y +CONFIG_BLK=y # CONFIG_MMC is not set CONFIG_MVGBE=y CONFIG_MII=y @@ -38,5 +39,6 @@ CONFIG_DM_RTC=y CONFIG_RTC_MV=y CONFIG_SYS_NS16550=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y diff --git a/configs/oceanic_5205_5inmfd_defconfig b/configs/oceanic_5205_5inmfd_defconfig new file mode 100644 index 00000000000..34fe6f52735 --- /dev/null +++ b/configs/oceanic_5205_5inmfd_defconfig @@ -0,0 +1,20 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_SPL=y +CONFIG_MACH_SUN50I=y +CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y +CONFIG_SUNXI_DRAM_LPDDR3_STOCK=y +CONFIG_DRAM_CLK=552 +CONFIG_DRAM_ZQ=3881949 +CONFIG_MMC0_CD_PIN="" +CONFIG_SPL_SPI_SUNXI=y +CONFIG_NR_DRAM_BANKS=1 +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_SPL_DOS_PARTITION is not set +# CONFIG_SPL_EFI_PARTITION is not set +CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-oceanic-5205-5inmfd" +CONFIG_SUN8I_EMAC=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y +CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y diff --git a/configs/orangepi_2_defconfig b/configs/orangepi_2_defconfig index ab6566e49a8..ce3cc8352cf 100644 --- a/configs/orangepi_2_defconfig +++ b/configs/orangepi_2_defconfig @@ -4,8 +4,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=672 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y CONFIG_USB1_VBUS_PIN="PG13" CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set diff --git a/configs/orangepi_lite_defconfig b/configs/orangepi_lite_defconfig index 1092a852503..490f5a3aae4 100644 --- a/configs/orangepi_lite_defconfig +++ b/configs/orangepi_lite_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=672 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/orangepi_one_defconfig b/configs/orangepi_one_defconfig index 404fdd91197..949fc5d40f7 100644 --- a/configs/orangepi_one_defconfig +++ b/configs/orangepi_one_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=672 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/orangepi_pc2_defconfig b/configs/orangepi_pc2_defconfig index ad837382c8e..a5bac5b2926 100644 --- a/configs/orangepi_pc2_defconfig +++ b/configs/orangepi_pc2_defconfig @@ -4,6 +4,7 @@ CONFIG_SPL=y CONFIG_MACH_SUN50I_H5=y CONFIG_DRAM_CLK=672 CONFIG_DRAM_ZQ=3881977 +# CONFIG_DRAM_ODT_EN is not set CONFIG_MACPWR="PD6" CONFIG_SPL_SPI_SUNXI=y CONFIG_NR_DRAM_BANKS=1 diff --git a/configs/orangepi_pc_defconfig b/configs/orangepi_pc_defconfig index de11df755e4..79d623719e3 100644 --- a/configs/orangepi_pc_defconfig +++ b/configs/orangepi_pc_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=624 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_SPL_I2C_SUPPORT=y diff --git a/configs/orangepi_pc_plus_defconfig b/configs/orangepi_pc_plus_defconfig index ce26cfaf9b5..31e9bcf0b3f 100644 --- a/configs/orangepi_pc_plus_defconfig +++ b/configs/orangepi_pc_plus_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=624 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y CONFIG_MMC_SUNXI_SLOT_EXTRA=2 CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set diff --git a/configs/orangepi_plus2e_defconfig b/configs/orangepi_plus2e_defconfig index b0813e4e10b..f31fd28a4f6 100644 --- a/configs/orangepi_plus2e_defconfig +++ b/configs/orangepi_plus2e_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=672 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y CONFIG_MACPWR="PD6" CONFIG_MMC_SUNXI_SLOT_EXTRA=2 CONFIG_NR_DRAM_BANKS=1 diff --git a/configs/orangepi_plus_defconfig b/configs/orangepi_plus_defconfig index 05023737a95..8a9ea272c3c 100644 --- a/configs/orangepi_plus_defconfig +++ b/configs/orangepi_plus_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=672 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y CONFIG_MACPWR="PD6" CONFIG_MMC_SUNXI_SLOT_EXTRA=2 CONFIG_USB1_VBUS_PIN="PG13" diff --git a/configs/orangepi_prime_defconfig b/configs/orangepi_prime_defconfig index 20ae6df5a0d..0d64eebc099 100644 --- a/configs/orangepi_prime_defconfig +++ b/configs/orangepi_prime_defconfig @@ -4,6 +4,7 @@ CONFIG_SPL=y CONFIG_MACH_SUN50I_H5=y CONFIG_DRAM_CLK=672 CONFIG_DRAM_ZQ=3881977 +# CONFIG_DRAM_ODT_EN is not set CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/orangepi_r1_defconfig b/configs/orangepi_r1_defconfig index 05c3b08b766..6492d8580c1 100644 --- a/configs/orangepi_r1_defconfig +++ b/configs/orangepi_r1_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=624 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y # CONFIG_VIDEO_DE2 is not set CONFIG_SPL_SPI_SUNXI=y CONFIG_NR_DRAM_BANKS=1 diff --git a/configs/orangepi_zero_defconfig b/configs/orangepi_zero_defconfig index 44fc18b7b1e..b881a848317 100644 --- a/configs/orangepi_zero_defconfig +++ b/configs/orangepi_zero_defconfig @@ -3,8 +3,6 @@ CONFIG_ARCH_SUNXI=y CONFIG_SPL=y CONFIG_MACH_SUN8I_H3=y CONFIG_DRAM_CLK=624 -CONFIG_DRAM_ZQ=3881979 -CONFIG_DRAM_ODT_EN=y # CONFIG_VIDEO_DE2 is not set CONFIG_SPL_SPI_SUNXI=y CONFIG_NR_DRAM_BANKS=1 diff --git a/configs/orangepi_zero_plus2_defconfig b/configs/orangepi_zero_plus2_defconfig index e62b3cb1504..ab0d12e750a 100644 --- a/configs/orangepi_zero_plus2_defconfig +++ b/configs/orangepi_zero_plus2_defconfig @@ -4,6 +4,7 @@ CONFIG_SPL=y CONFIG_MACH_SUN50I_H5=y CONFIG_DRAM_CLK=672 CONFIG_DRAM_ZQ=3881977 +# CONFIG_DRAM_ODT_EN is not set CONFIG_MMC0_CD_PIN="PH13" CONFIG_MMC_SUNXI_SLOT_EXTRA=2 CONFIG_NR_DRAM_BANKS=1 diff --git a/configs/orangepi_zero_plus_defconfig b/configs/orangepi_zero_plus_defconfig index cc8b8c7f9ab..37ca6dff374 100644 --- a/configs/orangepi_zero_plus_defconfig +++ b/configs/orangepi_zero_plus_defconfig @@ -4,6 +4,7 @@ CONFIG_SPL=y CONFIG_MACH_SUN50I_H5=y CONFIG_DRAM_CLK=624 CONFIG_DRAM_ZQ=3881977 +# CONFIG_DRAM_ODT_EN is not set CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/pine64-lts_defconfig b/configs/pine64-lts_defconfig index fd3cdeec858..a8331377872 100644 --- a/configs/pine64-lts_defconfig +++ b/configs/pine64-lts_defconfig @@ -16,4 +16,5 @@ CONFIG_NR_DRAM_BANKS=1 CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-pine64-lts" CONFIG_SUN8I_EMAC=y CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index da4bdced310..c04ecd915ae 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -194,6 +194,7 @@ CONFIG_CMD_DHRYSTONE=y CONFIG_TPM=y CONFIG_LZ4=y CONFIG_ERRNO_STR=y +CONFIG_TEST_FDTDEC=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 193e41896cb..bb508a8d02e 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -215,6 +215,7 @@ CONFIG_CMD_DHRYSTONE=y CONFIG_TPM=y CONFIG_LZ4=y CONFIG_ERRNO_STR=y +CONFIG_TEST_FDTDEC=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y diff --git a/configs/sheevaplug_defconfig b/configs/sheevaplug_defconfig index 04b00cdea9d..ec527fceb6f 100644 --- a/configs/sheevaplug_defconfig +++ b/configs/sheevaplug_defconfig @@ -39,6 +39,7 @@ CONFIG_DM_RTC=y CONFIG_RTC_MV=y CONFIG_SYS_NS16550=y CONFIG_USB=y +CONFIG_DM_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y CONFIG_LZMA=y diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig index d20b2ab3508..6781adb81e7 100644 --- a/configs/stm32mp15_basic_defconfig +++ b/configs/stm32mp15_basic_defconfig @@ -1,11 +1,12 @@ CONFIG_ARM=y CONFIG_ARCH_STM32MP=y -CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_SYS_MALLOC_F_LEN=0x3000 CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL=y CONFIG_TARGET_STM32MP1=y CONFIG_DISTRO_DEFAULTS=y -CONFIG_NR_DRAM_BANKS=1 +CONFIG_FIT=y +CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=3 CONFIG_SPL_I2C_SUPPORT=y @@ -18,8 +19,10 @@ CONFIG_SYS_PROMPT="STM32MP> " # CONFIG_CMD_EXPORTENV is not set # CONFIG_CMD_IMPORTENV is not set CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MEMTEST=y CONFIG_CMD_ADC=y CONFIG_CMD_CLK=y +CONFIG_CMD_DFU=y CONFIG_CMD_FUSE=y CONFIG_CMD_GPIO=y CONFIG_CMD_GPT=y @@ -27,12 +30,21 @@ CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y CONFIG_CMD_USB=y CONFIG_CMD_USB_MASS_STORAGE=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_TIMER=y CONFIG_CMD_PMIC=y CONFIG_CMD_REGULATOR=y CONFIG_CMD_EXT4_WRITE=y # CONFIG_SPL_DOS_PARTITION is not set CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" CONFIG_STM32_ADC=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0xC0000000 +CONFIG_FASTBOOT_BUF_SIZE=0x02000000 +CONFIG_FASTBOOT_USB_DEV=1 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=1 CONFIG_DM_HWSPINLOCK=y CONFIG_HWSPINLOCK_STM32=y CONFIG_DM_I2C=y @@ -43,15 +55,16 @@ CONFIG_DM_MMC=y CONFIG_STM32_SDMMC2=y CONFIG_PHY=y CONFIG_PHY_STM32_USBPHYC=y -# CONFIG_PINCTRL_FULL is not set +CONFIG_PINCONF=y # CONFIG_SPL_PINCTRL_FULL is not set +CONFIG_PINCTRL_STMFX=y CONFIG_DM_PMIC=y # CONFIG_SPL_PMIC_CHILDREN is not set -CONFIG_PMIC_STPMU1=y +CONFIG_PMIC_STPMIC1=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y CONFIG_DM_REGULATOR_STM32_VREFBUF=y -CONFIG_DM_REGULATOR_STPMU1=y +CONFIG_DM_REGULATOR_STPMIC1=y CONFIG_SERIAL_RX_BUFFER=y CONFIG_STM32_SERIAL=y CONFIG_USB=y @@ -64,4 +77,3 @@ CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics" CONFIG_USB_GADGET_VENDOR_NUM=0x0483 CONFIG_USB_GADGET_PRODUCT_NUM=0x5720 CONFIG_USB_GADGET_DWC2_OTG=y -CONFIG_USB_GADGET_DOWNLOAD=y diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig new file mode 100644 index 00000000000..a050cee6918 --- /dev/null +++ b/configs/stm32mp15_trusted_defconfig @@ -0,0 +1,70 @@ +CONFIG_ARM=y +CONFIG_ARCH_STM32MP=y +CONFIG_SYS_MALLOC_F_LEN=0x3000 +CONFIG_TARGET_STM32MP1=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_FIT=y +CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" +CONFIG_SYS_PROMPT="STM32MP> " +# CONFIG_CMD_BOOTD is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_EXPORTENV is not set +# CONFIG_CMD_IMPORTENV is not set +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MEMTEST=y +CONFIG_CMD_ADC=y +CONFIG_CMD_CLK=y +CONFIG_CMD_DFU=y +CONFIG_CMD_FUSE=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_TIMER=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" +CONFIG_STM32_ADC=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0xC0000000 +CONFIG_FASTBOOT_BUF_SIZE=0x02000000 +CONFIG_FASTBOOT_USB_DEV=1 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=1 +CONFIG_DM_HWSPINLOCK=y +CONFIG_HWSPINLOCK_STM32=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_STM32F7=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_DM_MMC=y +CONFIG_STM32_SDMMC2=y +CONFIG_PHY=y +CONFIG_PHY_STM32_USBPHYC=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_STMFX=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_STPMIC1=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_DM_REGULATOR_STM32_VREFBUF=y +CONFIG_DM_REGULATOR_STPMIC1=y +CONFIG_SERIAL_RX_BUFFER=y +CONFIG_STM32_SERIAL=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_DWC2=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics" +CONFIG_USB_GADGET_VENDOR_NUM=0x0483 +CONFIG_USB_GADGET_PRODUCT_NUM=0x5720 +CONFIG_USB_GADGET_DWC2_OTG=y diff --git a/configs/theadorable_debug_defconfig b/configs/theadorable_debug_defconfig index fb9307aaf58..3736aec537d 100644 --- a/configs/theadorable_debug_defconfig +++ b/configs/theadorable_debug_defconfig @@ -51,6 +51,7 @@ CONFIG_ENV_SPI_MAX_HZ=50000000 CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_OF_TRANSLATE=y CONFIG_SATA_MV=y +CONFIG_BLK=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_RAM=y CONFIG_FPGA_ALTERA=y diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig index c406b257533..85f214148a8 100644 --- a/configs/turris_omnia_defconfig +++ b/configs/turris_omnia_defconfig @@ -43,6 +43,7 @@ CONFIG_ATSHA204A=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_MV=y CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_SPANSION=y CONFIG_PHY_MARVELL=y CONFIG_PHY_GIGE=y CONFIG_MVNETA=y diff --git a/configs/x530_defconfig b/configs/x530_defconfig index cd18e9eb454..c893c44452b 100644 --- a/configs/x530_defconfig +++ b/configs/x530_defconfig @@ -19,6 +19,8 @@ CONFIG_SILENT_CONSOLE=y CONFIG_SILENT_U_BOOT_ONLY=y CONFIG_SILENT_CONSOLE_UPDATE_ON_RELOC=y CONFIG_MISC_INIT_R=y +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_WATCHDOG_SUPPORT=y CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_GPIO=y @@ -72,3 +74,6 @@ CONFIG_USB_STORAGE=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_ETHER_ASIX88179=y +CONFIG_WATCHDOG=y +CONFIG_WDT=y +CONFIG_WDT_ORION=y diff --git a/doc/README.chromium b/doc/README.chromium index 45eaeced2da..096bc4f1f7f 100644 --- a/doc/README.chromium +++ b/doc/README.chromium @@ -1,239 +1,177 @@ -Running U-Boot from coreboot on Chromebooks -=========================================== +Chromium OS Support in U-Boot +============================= -U-Boot can be used as a secondary boot loader in a few situations such as from -UEFI and coreboot (see README.x86). Recent Chromebooks use coreboot even on -ARM platforms to start up the machine. +Introduction +------------ -This document aims to provide a guide to booting U-Boot on a Chromebook. It -is only a starting point, and there are many guides on the interwebs. But -placing this information in the U-Boot tree should make it easier to find for -those who use U-Boot habitually. +This describes how to use U-Boot with Chromium OS. Several options are +available: -Most of these platforms are supported by U-Boot natively, but it is risky to -replace the ROM unless you have a servo board and cable to restore it with. + - Running U-Boot from the 'altfw' feature, which is available on selected + Chromebooks from 2019 onwards (initially Grunt). Press '1' from the + developer-mode screen to get into U-Boot. See here for details: + https://sites.google.com/a/chromium.org/dev/chromium-os/poking-around-your-chrome-os-device?pli=1 + - Running U-Boot from the disk partition. This involves signing U-Boot and + placing it on the disk, for booting as a 'kernel'. See + README.chromium-chainload for information on this. This is the only + option on non-U-Boot Chromebooks from 2013 to 2018 and is somewhat + more involved. -For all of these the standard U-Boot build instructions apply. For example on -ARM: + - Running U-Boot with Chromium OS verified boot. This allows U-Boot to be + used instead of either or both of depthcharge (a bootloader which forked + from U-Boot in 2013) and coreboot. See below for more information on + this. - sudo apt install gcc-arm-linux-gnueabi - mkdir b - make O=b/nyan_big CROSS_COMPILE=arm-linux-gnueabi- nyan-big_defconfig all -You can obtain the vbutil_kernel utility here: +U-Boot with Chromium OS verified boot +------------------------------------- - https://drive.google.com/open?id=0B7WYZbZ9zd-3dHlVVXo4VXE2T0U +To obtain: + git clone https://github.com/sglass68/u-boot.git + cd u-boot + git checkout cros-master -Snow (Samsung ARM Chromebook) ------------------------------ +To build for sandbox: -See here: + UB=/tmp/b/chromeos_sandbox # U-Boot build directory + CROS=/home/sglass/cosarm # Chromium OS directory + make O=$UB/chromeos_sandbox_defconfig + make O=$UB -j20 -s VBOOT_SOURCE=$CROS/src/platform/vboot_reference \ + MAKEFLAGS_VBOOT=DEBUG=1 QUIET=1 -https://www.chromium.org/chromium-os/firmware-porting-guide/using-nv-u-boot-on-the-samsung-arm-chromebook +Replace sandbox with another supported target. +This produces $UB/image.bin which contains the firmware binaries in a SPI +flash image. -Nyan-big --------- - -Compiled based on information here: -https://lists.denx.de/pipermail/u-boot/2015-March/209530.html -https://git.collabora.com/cgit/user/tomeu/u-boot.git/commit/?h=nyan-big -https://lists.denx.de/pipermail/u-boot/2017-May/289491.html -https://github.com/chromeos-nvidia-androidtv/gnu-linux-on-acer-chromebook-13#copy-data-to-the-sd-card - -1. Build U-Boot - - mkdir b - make -j8 O=b/nyan-big CROSS_COMPILE=arm-linux-gnueabi- nyan-big_defconfig all - - -2. Select a .its file - -Select something from doc/chromium which matches your board, or create your -own. - -Note that the device tree node is required, even though it is not actually -used by U-Boot. This is because the Chromebook expects to pass it to the -kernel, and crashes if it is not present. - - -3. Build and sign an image - - ./b/nyan-big/tools/mkimage -f doc/chromium/nyan-big.its u-boot-chromium.fit - echo test >dummy.txt - vbutil_kernel --arch arm --keyblock doc/chromium/devkeys/kernel.keyblock \ - --signprivate doc/chromium/devkeys/kernel_data_key.vbprivk \ - --version 1 --config dummy.txt --vmlinuz u-boot-chromium.fit \ - --bootloader dummy.txt --pack u-boot.kpart - - -4. Prepare an SD card - - DISK=/dev/sdc # Replace with your actual SD card device - sudo cgpt create $DISK - sudo cgpt add -b 34 -s 32768 -P 1 -S 1 -t kernel $DISK - sudo cgpt add -b 32802 -s 2000000 -t rootfs $DISK - sudo gdisk $DISK # Enter command 'w' to write a protective MBR to the disk - - -5. Write U-Boot to the SD card +To run on sandbox: - sudo dd if=u-boot.kpart of=/dev/sdc1; sync + $UB/tpl/u-boot-tpl -d $UB/u-boot.dtb.out \ + -L6 -c "host bind 0 $CROS/src/build/images/cheza/latest/chromiumos_image.bin; vboot go auto" \ + -l -w -s state.dtb -r +To run on other boards: + Install image.bin in the SPI flash of your device + Boot your system -6. Start it up -Reboot the device in dev mode. Make sure that you have USB booting enabled. To -do this, login as root (via Ctrl-Alt-forward_arrow) and type -'enable_dev_usb_boot'. You only need to do this once. +Sandbox +------- -Reboot the device with the SD card inserted. Press Clrl-U at the developer -mode screen. It should show something like the following on the display: +Most Chromium OS development with U-Boot is undertaken using sandbox. There is +a sandbox target available (chromeos_sandbox) which allows running U-Boot on +a Linux machine completion with emulations of the display, TPM, disk, etc. - U-Boot 2017.07-00637-g242eb42-dirty (May 22 2017 - 06:14:21 -0600) +Running sandbox starts TPL, which contains the first phase of vboot, providing +a device tree and binding a Chromium OS disk image for use to find kernels +(any Chromium OS image will do). It also saves driver state between U-Boot +phases into state.dtb and will automatically ensure that memory is shared +between all phases. TPL will jump to SPL and then on to U-Boot proper. - Model: Acer Chromebook 13 CB5-311 - Board: Google/NVIDIA Nyan-big, ID: 1 +It is possible to run with debugging on, e.g. - Net: No ethernet found. - Hit any key to stop autoboot: 0 - Tegra124 (Nyan-big) # + gdb --args $UB/tpl/u-boot-tpl -d .... +Breakpoints can be set in any U-Boot phase. Overall this is a good debugging +environment for new verified-boot features. -7. Known problems -On the serial console the word MMC is chopped at the start of the line: +Samus +----- -C: sdhci@700b0000: 2, sdhci@700b0400: 1, sdhci@700b0600: 0 +Basic support is available for samus, using the chromeos_samus target. If you +have an em100, use: -This is likely due to some problem with change-over of the serial driver -during relocation (or perhaps updating the clock setup in board_init()). + sudo em100 -s -c W25Q128FW -d $UB/image.bin -t -r +to write the image and then boot samus (Power-Refresh). -9. Notes -To check that you copied the u-boot.its file correctly, use these commands. -You should see that the data at 0x100 in u-boot-chromium.fit is the first few -bytes of U-Boot: +Boot flow +--------- - hd u-boot-chromium.fit |head -20 - ... - 00000100 b8 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5 |................| +Verified boot starts in TPL, which selects the A or B SPL, which in turn selects +the A or B U-Boot. Then this jumps to the selected kernel. If anything goes +wrong, the device reboots and the recovery SPL and U-Boot are used instead. - hd b/nyan-big/u-boot.bin |head - 00000000 b8 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5 |................| +More details are available here: + https://www.chromium.org/chromium-os/chromiumos-design-docs/firmware-boot-and-recovery -The 'data' property of the FIT is set up to start at offset 0x100 bytes into -the file. The change to CONFIG_SYS_TEXT_BASE is also an offset of 0x100 bytes -from the load address. If this changes, you either need to modify U-Boot to be -fully relocatable, or expect it to hang. +New uclasses +------------ -chromebook_jerry ----------------- +Several uclasses are provided in cros/: -The instruction are similar to those for Nyan with changes as noted below: + UCLASS_CROS_AUX_FW Chrome OS auxiliary firmware + UCLASS_CROS_FWSTORE Chrome OS firmware storage + UCLASS_CROS_NVDATA Chrome OS non-volatile data device + UCLASS_CROS_VBOOT_EC Chrome OS vboot EC operations + UCLASS_CROS_VBOOT_FLAG Chrome OS verified boot flag -1. Patch U-Boot +The existing UCLASS_CROS_EC is also used. -Open include/configs/rk3288_common.h -Change: - -#define CONFIG_SYS_TEXT_BASE 0x00100000 - -to: - -#define CONFIG_SYS_TEXT_BASE 0x02000100 - - - -2. Build U-Boot - - mkdir b - make -j8 O=b/chromebook_jerry CROSS_COMPILE=arm-linux-gnueabi- \ - chromebook_jerry_defconfig all - - -3. See above - -4. Build and sign an image - - ./b/chromebook_jerry/tools/mkimage -f doc/chromium/chromebook_jerry.its \ - u-boot-chromium.fit - echo test >dummy.txt - vbutil_kernel --arch arm --keyblock doc/chromium/devkeys/kernel.keyblock \ - --signprivate doc/chromium/devkeys/kernel_data_key.vbprivk \ - --version 1 --config dummy.txt --vmlinuz u-boot-chromium.fit \ - --bootloader dummy.txt --pack u-boot.kpart - - -5. See above +Commands +-------- -6. See above +A new 'vboot' command is provided to run particular vboot stages. The most +useful command is 'vboot go auto', which continues where the last stage left +off. -7. Start it up +Note that TPL and SPL do not supports commands as yet, so the vboot code is +called directly from the SPL boot devices (BOOT_DEVICE_CROS_VBOOT). See +cros_load_image_tpl() and cros_load_image_spl() which both call +vboot_run_auto(). -Reboot the device in dev mode. Make sure that you have USB booting enabled. To -do this, login as root (via Ctrl-Alt-forward_arrow) and type -'enable_dev_usb_boot'. You only need to do this once. -Reboot the device with the SD card inserted. Press Clrl-U at the developer -mode screen. It should show something like the following on the display: +Config options +-------------- - U-Boot 2017.05-00649-g72acdbf-dirty (May 29 2017 - 14:57:05 -0600) +The main option is CONFIG_CHROMEOS, which enables a wide array of other options +so that the required features are present. - Model: Google Jerry - Net: Net Initialization Skipped - No ethernet found. - Hit any key to stop autoboot: 0 +Device-tree config +------------------ -8. Known problems +Various options are available which control the operation of verified boot. +See cros/dts/bindings/config.txt for details. Most config is handled at run- +time, although build-time config (with Kconfig) could also be added fairly +easily. -None as yet. +Porting to other hardware +------------------------- -9. Notes +A basic port to samus (Chromebook Pixel 2015) is in a basic working state, +using the chromeos_samus target. Patches will likely be forthcoming in early +2019. Ports to an ARM board and coreboot (for x86 Chromebooks) are in the +dreaming state. -None as yet. +Tests +----- -Other notes -=========== +Chromium OS firmware has a very limited set of tests. The tests that originally +existed in U-Boot were not brought over to coreboot or depthcharge. -flashrom --------- +The U-Boot tests ('make check') do operate, but at present there are no +Chromium OS tests available. These will hopefully come together over time. Of +course the above sandbox feature provides a sort of functional test and can +detecte problems that affect the flow or particular vboot features. - Used to make a backup of your firmware, or to replace it. - See: https://www.chromium.org/chromium-os/packages/cros-flashrom +TO DO +----- +- Support for booting from coreboot (patches expected March 2019) +- Support for booting from an ARM board, e.g. bob -coreboot --------- -Coreboot itself is not designed to actually boot an OS. Instead, a program -called Depthcharge is used. This originally came out of U-Boot and was then -heavily hacked and modified such that is is almost unrecognisable. It does -include a very small part of the U-Boot command-line interface but is not -usable as a general-purpose boot loader. - -In addition, it has a very unusual design in that it does not do device init -itself, but instead relies on coreboot. This is similar to (in U-Boot) having -a SPI driver with an empty probe() method, relying on whatever was set up -beforehand. It can be quite hard to figure out between these two code bases -what settings are actually used. When chain-loading into U-Boot we must be -careful to reinit anything that U-Boot expects. If not, some peripherals (or -the whole machine) may not work. This makes the process of chainloading more -complicated than it could be on some platforms. - -Finally, it supports only a subset of the U-Boot's FIT format. In particular -it uses a fixed address to load the FIT and does not support load/exec -addresses. This means that U-Boot must be able to boot from whatever -address Depthcharge happens to use (it is the CONFIG_KERNEL_START setting -in Depthcharge). In practice this means that the data in the kernel@1 FIT node -(see above) must start at the same address as U-Boot's CONFIG_SYS_TEXT_BASE. +Simon Glass +sjg@chromium.org +7 October 2018 diff --git a/doc/README.chromium-chainload b/doc/README.chromium-chainload new file mode 100644 index 00000000000..45eaeced2da --- /dev/null +++ b/doc/README.chromium-chainload @@ -0,0 +1,239 @@ +Running U-Boot from coreboot on Chromebooks +=========================================== + +U-Boot can be used as a secondary boot loader in a few situations such as from +UEFI and coreboot (see README.x86). Recent Chromebooks use coreboot even on +ARM platforms to start up the machine. + +This document aims to provide a guide to booting U-Boot on a Chromebook. It +is only a starting point, and there are many guides on the interwebs. But +placing this information in the U-Boot tree should make it easier to find for +those who use U-Boot habitually. + +Most of these platforms are supported by U-Boot natively, but it is risky to +replace the ROM unless you have a servo board and cable to restore it with. + + +For all of these the standard U-Boot build instructions apply. For example on +ARM: + + sudo apt install gcc-arm-linux-gnueabi + mkdir b + make O=b/nyan_big CROSS_COMPILE=arm-linux-gnueabi- nyan-big_defconfig all + +You can obtain the vbutil_kernel utility here: + + https://drive.google.com/open?id=0B7WYZbZ9zd-3dHlVVXo4VXE2T0U + + +Snow (Samsung ARM Chromebook) +----------------------------- + +See here: + +https://www.chromium.org/chromium-os/firmware-porting-guide/using-nv-u-boot-on-the-samsung-arm-chromebook + + +Nyan-big +-------- + +Compiled based on information here: +https://lists.denx.de/pipermail/u-boot/2015-March/209530.html +https://git.collabora.com/cgit/user/tomeu/u-boot.git/commit/?h=nyan-big +https://lists.denx.de/pipermail/u-boot/2017-May/289491.html +https://github.com/chromeos-nvidia-androidtv/gnu-linux-on-acer-chromebook-13#copy-data-to-the-sd-card + +1. Build U-Boot + + mkdir b + make -j8 O=b/nyan-big CROSS_COMPILE=arm-linux-gnueabi- nyan-big_defconfig all + + +2. Select a .its file + +Select something from doc/chromium which matches your board, or create your +own. + +Note that the device tree node is required, even though it is not actually +used by U-Boot. This is because the Chromebook expects to pass it to the +kernel, and crashes if it is not present. + + +3. Build and sign an image + + ./b/nyan-big/tools/mkimage -f doc/chromium/nyan-big.its u-boot-chromium.fit + echo test >dummy.txt + vbutil_kernel --arch arm --keyblock doc/chromium/devkeys/kernel.keyblock \ + --signprivate doc/chromium/devkeys/kernel_data_key.vbprivk \ + --version 1 --config dummy.txt --vmlinuz u-boot-chromium.fit \ + --bootloader dummy.txt --pack u-boot.kpart + + +4. Prepare an SD card + + DISK=/dev/sdc # Replace with your actual SD card device + sudo cgpt create $DISK + sudo cgpt add -b 34 -s 32768 -P 1 -S 1 -t kernel $DISK + sudo cgpt add -b 32802 -s 2000000 -t rootfs $DISK + sudo gdisk $DISK # Enter command 'w' to write a protective MBR to the disk + + +5. Write U-Boot to the SD card + + sudo dd if=u-boot.kpart of=/dev/sdc1; sync + + +6. Start it up + +Reboot the device in dev mode. Make sure that you have USB booting enabled. To +do this, login as root (via Ctrl-Alt-forward_arrow) and type +'enable_dev_usb_boot'. You only need to do this once. + +Reboot the device with the SD card inserted. Press Clrl-U at the developer +mode screen. It should show something like the following on the display: + + U-Boot 2017.07-00637-g242eb42-dirty (May 22 2017 - 06:14:21 -0600) + + Model: Acer Chromebook 13 CB5-311 + Board: Google/NVIDIA Nyan-big, ID: 1 + + Net: No ethernet found. + Hit any key to stop autoboot: 0 + Tegra124 (Nyan-big) # + + +7. Known problems + +On the serial console the word MMC is chopped at the start of the line: + +C: sdhci@700b0000: 2, sdhci@700b0400: 1, sdhci@700b0600: 0 + +This is likely due to some problem with change-over of the serial driver +during relocation (or perhaps updating the clock setup in board_init()). + + +9. Notes + +To check that you copied the u-boot.its file correctly, use these commands. +You should see that the data at 0x100 in u-boot-chromium.fit is the first few +bytes of U-Boot: + + hd u-boot-chromium.fit |head -20 + ... + 00000100 b8 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5 |................| + + hd b/nyan-big/u-boot.bin |head + 00000000 b8 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5 |................| + + +The 'data' property of the FIT is set up to start at offset 0x100 bytes into +the file. The change to CONFIG_SYS_TEXT_BASE is also an offset of 0x100 bytes +from the load address. If this changes, you either need to modify U-Boot to be +fully relocatable, or expect it to hang. + + +chromebook_jerry +---------------- + +The instruction are similar to those for Nyan with changes as noted below: + +1. Patch U-Boot + +Open include/configs/rk3288_common.h + +Change: + +#define CONFIG_SYS_TEXT_BASE 0x00100000 + +to: + +#define CONFIG_SYS_TEXT_BASE 0x02000100 + + + +2. Build U-Boot + + mkdir b + make -j8 O=b/chromebook_jerry CROSS_COMPILE=arm-linux-gnueabi- \ + chromebook_jerry_defconfig all + + +3. See above + +4. Build and sign an image + + ./b/chromebook_jerry/tools/mkimage -f doc/chromium/chromebook_jerry.its \ + u-boot-chromium.fit + echo test >dummy.txt + vbutil_kernel --arch arm --keyblock doc/chromium/devkeys/kernel.keyblock \ + --signprivate doc/chromium/devkeys/kernel_data_key.vbprivk \ + --version 1 --config dummy.txt --vmlinuz u-boot-chromium.fit \ + --bootloader dummy.txt --pack u-boot.kpart + + +5. See above + +6. See above + +7. Start it up + +Reboot the device in dev mode. Make sure that you have USB booting enabled. To +do this, login as root (via Ctrl-Alt-forward_arrow) and type +'enable_dev_usb_boot'. You only need to do this once. + +Reboot the device with the SD card inserted. Press Clrl-U at the developer +mode screen. It should show something like the following on the display: + + U-Boot 2017.05-00649-g72acdbf-dirty (May 29 2017 - 14:57:05 -0600) + + Model: Google Jerry + Net: Net Initialization Skipped + No ethernet found. + Hit any key to stop autoboot: 0 + + +8. Known problems + +None as yet. + + +9. Notes + +None as yet. + + +Other notes +=========== + +flashrom +-------- + + Used to make a backup of your firmware, or to replace it. + + See: https://www.chromium.org/chromium-os/packages/cros-flashrom + + +coreboot +-------- + +Coreboot itself is not designed to actually boot an OS. Instead, a program +called Depthcharge is used. This originally came out of U-Boot and was then +heavily hacked and modified such that is is almost unrecognisable. It does +include a very small part of the U-Boot command-line interface but is not +usable as a general-purpose boot loader. + +In addition, it has a very unusual design in that it does not do device init +itself, but instead relies on coreboot. This is similar to (in U-Boot) having +a SPI driver with an empty probe() method, relying on whatever was set up +beforehand. It can be quite hard to figure out between these two code bases +what settings are actually used. When chain-loading into U-Boot we must be +careful to reinit anything that U-Boot expects. If not, some peripherals (or +the whole machine) may not work. This makes the process of chainloading more +complicated than it could be on some platforms. + +Finally, it supports only a subset of the U-Boot's FIT format. In particular +it uses a fixed address to load the FIT and does not support load/exec +addresses. This means that U-Boot must be able to boot from whatever +address Depthcharge happens to use (it is the CONFIG_KERNEL_START setting +in Depthcharge). In practice this means that the data in the kernel@1 FIT node +(see above) must start at the same address as U-Boot's CONFIG_SYS_TEXT_BASE. diff --git a/doc/device-tree-bindings/i2c/i2c.txt b/doc/device-tree-bindings/i2c/i2c.txt index de818d4713f..9698e4899b5 100644 --- a/doc/device-tree-bindings/i2c/i2c.txt +++ b/doc/device-tree-bindings/i2c/i2c.txt @@ -12,6 +12,10 @@ property which allows the chip offset length to be selected. Optional properties: - u-boot,i2c-offset-len - length of chip offset in bytes. If omitted the default value of 1 is used. +- u-boot,i2c-transaction-bytes - the length of single I2C transaction on + the bus. Some devices require more than single byte transmission + (e.g. mc34708 mfd). This information is necessary to correctly + initialize (put into idle state) I2C bus after soft reset. - gpios = <sda ...>, <scl ...>; pinctrl-names = "default", "gpio"; pinctrl-0 = <&i2c_xfer>; @@ -28,6 +32,7 @@ i2c4: i2c@12ca0000 { compatible = "google,cros-ec"; i2c-max-frequency = <100000>; u-boot,i2c-offset-len = <0>; + u-boot,i2c-transaction-bytes = <3>; ec-interrupt = <&gpx1 6 GPIO_ACTIVE_LOW>; }; }; diff --git a/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt b/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt new file mode 100644 index 00000000000..70e76be2a3f --- /dev/null +++ b/doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt @@ -0,0 +1,59 @@ +STMicroelectronics Flexible Memory Controller 2 (FMC2) +NAND Interface + +Required properties: +- compatible: Should be one of: + * st,stm32mp15-fmc2 +- reg: NAND flash controller memory areas. + First region contains the register location. + Regions 2 to 4 respectively contain the data, command, + and address space for CS0. + Regions 5 to 7 contain the same areas for CS1. +- interrupts: The interrupt number +- pinctrl-0: Standard Pinctrl phandle (see: pinctrl/pinctrl-bindings.txt) +- clocks: The clock needed by the NAND flash controller + +Optional properties: +- resets: Reference to a reset controller asserting the FMC controller +- dmas: DMA specifiers (see: dma/stm32-mdma.txt) +- dma-names: Must be "tx", "rx" and "ecc" + +Optional children nodes: +Children nodes represent the available NAND chips. + +Optional properties: +- nand-on-flash-bbt: see nand.txt +- nand-ecc-strength: see nand.txt +- nand-ecc-step-size: see nand.txt + +The following ECC strength and step size are currently supported: + - nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Hamming) + - nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4) + - nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8) (default) + +Example: + + fmc: nand-controller@58002000 { + compatible = "st,stm32mp15-fmc2"; + reg = <0x58002000 0x1000>, + <0x80000000 0x1000>, + <0x88010000 0x1000>, + <0x88020000 0x1000>, + <0x81000000 0x1000>, + <0x89010000 0x1000>, + <0x89020000 0x1000>; + interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc FMC_K>; + resets = <&rcc FMC_R>; + pinctrl-names = "default"; + pinctrl-0 = <&fmc_pins_a>; + #address-cells = <1>; + #size-cells = <0>; + + nand@0 { + reg = <0>; + nand-on-flash-bbt; + #address-cells = <1>; + #size-cells = <1>; + }; + }; diff --git a/doc/device-tree-bindings/pinctrl/atmel,at91-pio4-pinctrl.txt b/doc/device-tree-bindings/pinctrl/atmel,at91-pio4-pinctrl.txt index a1b559668ff..a376c6fba5d 100644 --- a/doc/device-tree-bindings/pinctrl/atmel,at91-pio4-pinctrl.txt +++ b/doc/device-tree-bindings/pinctrl/atmel,at91-pio4-pinctrl.txt @@ -42,7 +42,7 @@ Example: status = "okay"; spi_flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <50000000>; }; diff --git a/doc/device-tree-bindings/spi/spi-atcspi200.txt b/doc/device-tree-bindings/spi/spi-atcspi200.txt index 9c0630b5003..e67b3425f0d 100644 --- a/doc/device-tree-bindings/spi/spi-atcspi200.txt +++ b/doc/device-tree-bindings/spi/spi-atcspi200.txt @@ -28,7 +28,7 @@ Example: clocks = <&spiclk>; interrupts = <3 4>; flash@0 { - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <50000000>; reg = <0>; spi-cpol; diff --git a/doc/device-tree-bindings/spi/spi-stm32-qspi.txt b/doc/device-tree-bindings/spi/spi-stm32-qspi.txt index 6c7da1d76c1..cec3e1250ce 100644 --- a/doc/device-tree-bindings/spi/spi-stm32-qspi.txt +++ b/doc/device-tree-bindings/spi/spi-stm32-qspi.txt @@ -29,7 +29,7 @@ Example: qflash0: n25q128a { #address-cells = <1>; #size-cells = <1>; - compatible = "micron,n25q128a13", "spi-flash"; + compatible = "micron,n25q128a13", "jedec,spi-nor"; spi-max-frequency = <108000000>; spi-tx-bus-width = <4>; spi-rx-bus-width = <4>; diff --git a/doc/git-mailrc b/doc/git-mailrc index b75ebab02ba..f989792e8d3 100644 --- a/doc/git-mailrc +++ b/doc/git-mailrc @@ -24,9 +24,8 @@ alias dinh Dinh Nguyen <dinguyen@kernel.org> alias hs Heiko Schocher <hs@denx.de> alias iwamatsu Nobuhiro Iwamatsu <iwamatsu@nigauri.org> alias jaehoon Jaehoon Chung <jh80.chung@samsung.com> -alias jagan Jagan Teki <jagan@openedev.com> +alias jagan Jagan Teki <jagan@amarulasolutions.com> alias jhersh Joe Hershberger <joe.hershberger@ni.com> -alias luka Luka Perkov <luka.perkov@sartura.hr> alias lukma Lukasz Majewski <lukma@denx.de> alias macpaul Macpaul Lin <macpaul@andestech.com> alias marex Marek Vasut <marex@denx.de> @@ -35,7 +34,6 @@ alias masahiro Masahiro Yamada <yamada.masahiro@socionext.com> alias mateusz Mateusz Kulikowski <mateusz.kulikowski@gmail.com> alias maxime Maxime Ripard <maxime.ripard@free-electrons.com> alias monstr Michal Simek <monstr@monstr.eu> -alias prafulla Prafulla Wadaskar <prafulla@marvell.com> alias prom Minkyu Kang <mk7.kang@samsung.com> alias ptomsich Philipp Tomsich <philipp.tomsich@theobroma-systems.com> alias sbabic Stefano Babic <sbabic@denx.de> @@ -56,7 +54,7 @@ alias arm uboot, aaribaud, trini alias at91 uboot, abiessmann alias davinci ti alias imx uboot, sbabic -alias kirkwood uboot, prafulla, luka, stroese +alias kirkwood uboot, stroese alias omap ti alias pxa uboot, marex alias rmobile uboot, iwamatsu diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 49a056e9416..7ebee75c0a5 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -81,7 +81,9 @@ config MVSATA_IDE config SATA_MV bool "Enable Marvell SATA controller driver support" + select AHCI select LIBATA + depends on BLK help Enable this driver to support the SATA controller found in some Marvell SoCs. diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c index 6e3f17ee276..48a9d00d147 100644 --- a/drivers/ata/ahci_mvebu.c +++ b/drivers/ata/ahci_mvebu.c @@ -44,6 +44,7 @@ static int mvebu_ahci_probe(struct udevice *dev) } static const struct udevice_id mvebu_ahci_ids[] = { + { .compatible = "marvell,armada-380-ahci" }, { .compatible = "marvell,armada-3700-ahci" }, { .compatible = "marvell,armada-8k-ahci" }, { } diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index a168196fd4d..2a630d46c14 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -3,7 +3,7 @@ * Copyright (C) Excito Elektronik i SkÃ¥ne AB, 2010. * Author: Tor Krill <tor@excito.com> * - * Copyright (C) 2015 Stefan Roese <sr@denx.de> + * Copyright (C) 2015, 2019 Stefan Roese <sr@denx.de> */ /* @@ -32,6 +32,10 @@ */ #include <common.h> +#include <ahci.h> +#include <dm.h> +#include <dm/device-internal.h> +#include <dm/lists.h> #include <fis.h> #include <libata.h> #include <malloc.h> @@ -40,11 +44,10 @@ #include <asm/io.h> #include <linux/mbus.h> +#include <asm/arch/soc.h> #if defined(CONFIG_KIRKWOOD) -#include <asm/arch/kirkwood.h> #define SATAHC_BASE KW_SATA_BASE #else -#include <asm/arch/soc.h> #define SATAHC_BASE MVEBU_AXP_SATA_BASE #endif @@ -214,8 +217,8 @@ struct crqb { #define CRQB_SECTCOUNT_COUNT_EXP_MASK (0xff << 8) #define CRQB_SECTCOUNT_COUNT_EXP_SHIFT 8 -#define MVSATA_WIN_CONTROL(w) (MVEBU_AXP_SATA_BASE + 0x30 + ((w) << 4)) -#define MVSATA_WIN_BASE(w) (MVEBU_AXP_SATA_BASE + 0x34 + ((w) << 4)) +#define MVSATA_WIN_CONTROL(w) (SATAHC_BASE + 0x30 + ((w) << 4)) +#define MVSATA_WIN_BASE(w) (SATAHC_BASE + 0x34 + ((w) << 4)) struct eprd { u32 phyaddr_low; @@ -256,6 +259,7 @@ struct mv_priv { u16 pio; u16 mwdma; u16 udma; + int dev_nr; void *crqb_alloc; struct crqb *request; @@ -278,9 +282,9 @@ static int ata_wait_register(u32 *addr, u32 mask, u32 val, u32 timeout_msec) } /* Cut from sata_mv in linux kernel */ -static int mv_stop_edma_engine(int port) +static int mv_stop_edma_engine(struct udevice *dev, int port) { - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; + struct mv_priv *priv = dev_get_platdata(dev); int i; /* Disable eDMA. The disable bit auto clears. */ @@ -299,9 +303,9 @@ static int mv_stop_edma_engine(int port) return -1; } -static int mv_start_edma_engine(int port) +static int mv_start_edma_engine(struct udevice *dev, int port) { - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; + struct mv_priv *priv = dev_get_platdata(dev); u32 tmp; /* Check preconditions */ @@ -351,12 +355,12 @@ static int mv_start_edma_engine(int port) return 0; } -static int mv_reset_channel(int port) +static int mv_reset_channel(struct udevice *dev, int port) { - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; + struct mv_priv *priv = dev_get_platdata(dev); /* Make sure edma is stopped */ - mv_stop_edma_engine(port); + mv_stop_edma_engine(dev, port); out_le32(priv->regbase + EDMA_CMD, EDMA_CMD_ATARST); udelay(25); /* allow reset propagation */ @@ -366,11 +370,11 @@ static int mv_reset_channel(int port) return 0; } -static void mv_reset_port(int port) +static void mv_reset_port(struct udevice *dev, int port) { - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; + struct mv_priv *priv = dev_get_platdata(dev); - mv_reset_channel(port); + mv_reset_channel(dev, port); out_le32(priv->regbase + EDMA_CMD, 0x0); out_le32(priv->regbase + EDMA_CFG, 0x101f); @@ -392,9 +396,9 @@ static void mv_reset_one_hc(void) out_le32(SATAHC_BASE + SATAHC_ICR, 0x00); } -static int probe_port(int port) +static int probe_port(struct udevice *dev, int port) { - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; + struct mv_priv *priv = dev_get_platdata(dev); int tries, tries2, set15 = 0; u32 tmp; @@ -446,7 +450,7 @@ static int probe_port(int port) tmp &= ~SIR_CFG_GEN2EN; out_le32(priv->regbase + SIR_ICFG, tmp); - mv_reset_channel(port); + mv_reset_channel(dev, port); } } @@ -455,9 +459,9 @@ static int probe_port(int port) } /* Get request queue in pointer */ -static int get_reqip(int port) +static int get_reqip(struct udevice *dev, int port) { - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; + struct mv_priv *priv = dev_get_platdata(dev); u32 tmp; tmp = in_le32(priv->regbase + EDMA_RQIPR) & EDMA_RQIPR_IPMASK; @@ -466,9 +470,9 @@ static int get_reqip(int port) return tmp; } -static void set_reqip(int port, int reqin) +static void set_reqip(struct udevice *dev, int port, int reqin) { - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; + struct mv_priv *priv = dev_get_platdata(dev); u32 tmp; tmp = in_le32(priv->regbase + EDMA_RQIPR) & ~EDMA_RQIPR_IPMASK; @@ -477,17 +481,17 @@ static void set_reqip(int port, int reqin) } /* Get next available slot, ignoring possible overwrite */ -static int get_next_reqip(int port) +static int get_next_reqip(struct udevice *dev, int port) { - int slot = get_reqip(port); + int slot = get_reqip(dev, port); slot = (slot + 1) % REQUEST_QUEUE_SIZE; return slot; } /* Get response queue in pointer */ -static int get_rspip(int port) +static int get_rspip(struct udevice *dev, int port) { - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; + struct mv_priv *priv = dev_get_platdata(dev); u32 tmp; tmp = in_le32(priv->regbase + EDMA_RSIPR) & EDMA_RSIPR_IPMASK; @@ -497,9 +501,9 @@ static int get_rspip(int port) } /* Get response queue out pointer */ -static int get_rspop(int port) +static int get_rspop(struct udevice *dev, int port) { - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; + struct mv_priv *priv = dev_get_platdata(dev); u32 tmp; tmp = in_le32(priv->regbase + EDMA_RSOPR) & EDMA_RSOPR_OPMASK; @@ -508,15 +512,15 @@ static int get_rspop(int port) } /* Get next response queue pointer */ -static int get_next_rspop(int port) +static int get_next_rspop(struct udevice *dev, int port) { - return (get_rspop(port) + 1) % RESPONSE_QUEUE_SIZE; + return (get_rspop(dev, port) + 1) % RESPONSE_QUEUE_SIZE; } /* Set response queue pointer */ -static void set_rspop(int port, int reqin) +static void set_rspop(struct udevice *dev, int port, int reqin) { - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; + struct mv_priv *priv = dev_get_platdata(dev); u32 tmp; tmp = in_le32(priv->regbase + EDMA_RSOPR) & ~EDMA_RSOPR_OPMASK; @@ -525,7 +529,8 @@ static void set_rspop(int port, int reqin) out_le32(priv->regbase + EDMA_RSOPR, tmp); } -static int wait_dma_completion(int port, int index, u32 timeout_msec) +static int wait_dma_completion(struct udevice *dev, int port, int index, + u32 timeout_msec) { u32 tmp, res; @@ -538,13 +543,13 @@ static int wait_dma_completion(int port, int index, u32 timeout_msec) return res; } -static void process_responses(int port) +static void process_responses(struct udevice *dev, int port) { #ifdef DEBUG - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; + struct mv_priv *priv = dev_get_platdata(dev); #endif u32 tmp; - u32 outind = get_rspop(port); + u32 outind = get_rspop(dev, port); /* Ack interrupts */ tmp = in_le32(SATAHC_BASE + SATAHC_ICR); @@ -555,20 +560,21 @@ static void process_responses(int port) tmp &= ~(BIT(4)); out_le32(SATAHC_BASE + SATAHC_ICR, tmp); - while (get_rspip(port) != outind) { + while (get_rspip(dev, port) != outind) { #ifdef DEBUG debug("Response index %d flags %08x on port %d\n", outind, priv->response[outind].flags, port); #endif - outind = get_next_rspop(port); - set_rspop(port, outind); + outind = get_next_rspop(dev, port); + set_rspop(dev, port, outind); } } -static int mv_ata_exec_ata_cmd(int port, struct sata_fis_h2d *cfis, +static int mv_ata_exec_ata_cmd(struct udevice *dev, int port, + struct sata_fis_h2d *cfis, u8 *buffer, u32 len, u32 iswrite) { - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; + struct mv_priv *priv = dev_get_platdata(dev); struct crqb *req; int slot; u32 start; @@ -579,7 +585,7 @@ static int mv_ata_exec_ata_cmd(int port, struct sata_fis_h2d *cfis, } /* Initialize request */ - slot = get_reqip(port); + slot = get_reqip(dev, port); memset(&priv->request[slot], 0, sizeof(struct crqb)); req = &priv->request[slot]; @@ -633,16 +639,16 @@ static int mv_ata_exec_ata_cmd(int port, struct sata_fis_h2d *cfis, start + ALIGN(sizeof(*req), ARCH_DMA_MINALIGN)); /* Trigger operation */ - slot = get_next_reqip(port); - set_reqip(port, slot); + slot = get_next_reqip(dev, port); + set_reqip(dev, port, slot); /* Wait for completion */ - if (wait_dma_completion(port, slot, 10000)) { + if (wait_dma_completion(dev, port, slot, 10000)) { printf("ATA operation timed out\n"); return -1; } - process_responses(port); + process_responses(dev, port); /* Invalidate data on read */ if (buffer && len) { @@ -654,7 +660,8 @@ static int mv_ata_exec_ata_cmd(int port, struct sata_fis_h2d *cfis, return len; } -static u32 mv_sata_rw_cmd_ext(int port, lbaint_t start, u32 blkcnt, +static u32 mv_sata_rw_cmd_ext(struct udevice *dev, int port, lbaint_t start, + u32 blkcnt, u8 *buffer, int is_write) { struct sata_fis_h2d cfis; @@ -678,14 +685,14 @@ static u32 mv_sata_rw_cmd_ext(int port, lbaint_t start, u32 blkcnt, cfis.sector_count_exp = (blkcnt >> 8) & 0xff; cfis.sector_count = blkcnt & 0xff; - res = mv_ata_exec_ata_cmd(port, &cfis, buffer, ATA_SECT_SIZE * blkcnt, - is_write); + res = mv_ata_exec_ata_cmd(dev, port, &cfis, buffer, + ATA_SECT_SIZE * blkcnt, is_write); return res >= 0 ? blkcnt : res; } -static u32 mv_sata_rw_cmd(int port, lbaint_t start, u32 blkcnt, u8 *buffer, - int is_write) +static u32 mv_sata_rw_cmd(struct udevice *dev, int port, lbaint_t start, + u32 blkcnt, u8 *buffer, int is_write) { struct sata_fis_h2d cfis; lbaint_t block; @@ -705,20 +712,21 @@ static u32 mv_sata_rw_cmd(int port, lbaint_t start, u32 blkcnt, u8 *buffer, cfis.lba_low = block & 0xff; cfis.sector_count = (u8)(blkcnt & 0xff); - res = mv_ata_exec_ata_cmd(port, &cfis, buffer, ATA_SECT_SIZE * blkcnt, - is_write); + res = mv_ata_exec_ata_cmd(dev, port, &cfis, buffer, + ATA_SECT_SIZE * blkcnt, is_write); return res >= 0 ? blkcnt : res; } -static u32 ata_low_level_rw(int dev, lbaint_t blknr, lbaint_t blkcnt, - void *buffer, int is_write) +static u32 ata_low_level_rw(struct udevice *dev, int port, lbaint_t blknr, + lbaint_t blkcnt, void *buffer, int is_write) { + struct blk_desc *desc = dev_get_uclass_platdata(dev); lbaint_t start, blks; u8 *addr; int max_blks; - debug("%s: %ld %ld\n", __func__, blknr, blkcnt); + debug("%s: " LBAFU " " LBAFU "\n", __func__, blknr, blkcnt); start = blknr; blks = blkcnt; @@ -727,22 +735,22 @@ static u32 ata_low_level_rw(int dev, lbaint_t blknr, lbaint_t blkcnt, max_blks = MV_ATA_MAX_SECTORS; do { if (blks > max_blks) { - if (sata_dev_desc[dev].lba48) { - mv_sata_rw_cmd_ext(dev, start, max_blks, addr, - is_write); + if (desc->lba48) { + mv_sata_rw_cmd_ext(dev, port, start, max_blks, + addr, is_write); } else { - mv_sata_rw_cmd(dev, start, max_blks, addr, - is_write); + mv_sata_rw_cmd(dev, port, start, max_blks, + addr, is_write); } start += max_blks; blks -= max_blks; addr += ATA_SECT_SIZE * max_blks; } else { - if (sata_dev_desc[dev].lba48) { - mv_sata_rw_cmd_ext(dev, start, blks, addr, + if (desc->lba48) { + mv_sata_rw_cmd_ext(dev, port, start, blks, addr, is_write); } else { - mv_sata_rw_cmd(dev, start, blks, addr, + mv_sata_rw_cmd(dev, port, start, blks, addr, is_write); } start += blks; @@ -754,11 +762,11 @@ static u32 ata_low_level_rw(int dev, lbaint_t blknr, lbaint_t blkcnt, return blkcnt; } -static int mv_ata_exec_ata_cmd_nondma(int port, +static int mv_ata_exec_ata_cmd_nondma(struct udevice *dev, int port, struct sata_fis_h2d *cfis, u8 *buffer, u32 len, u32 iswrite) { - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; + struct mv_priv *priv = dev_get_platdata(dev); int i; u16 *tp; @@ -791,7 +799,7 @@ static int mv_ata_exec_ata_cmd_nondma(int port, return len; } -static int mv_sata_identify(int port, u16 *id) +static int mv_sata_identify(struct udevice *dev, int port, u16 *id) { struct sata_fis_h2d h2d; @@ -803,13 +811,13 @@ static int mv_sata_identify(int port, u16 *id) /* Give device time to get operational */ mdelay(10); - return mv_ata_exec_ata_cmd_nondma(port, &h2d, (u8 *)id, + return mv_ata_exec_ata_cmd_nondma(dev, port, &h2d, (u8 *)id, ATA_ID_WORDS * 2, READ_CMD); } -static void mv_sata_xfer_mode(int port, u16 *id) +static void mv_sata_xfer_mode(struct udevice *dev, int port, u16 *id) { - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; + struct mv_priv *priv = dev_get_platdata(dev); priv->pio = id[ATA_ID_PIO_MODES]; priv->mwdma = id[ATA_ID_MWDMA_MODES]; @@ -818,9 +826,9 @@ static void mv_sata_xfer_mode(int port, u16 *id) priv->udma); } -static void mv_sata_set_features(int port) +static void mv_sata_set_features(struct udevice *dev, int port) { - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; + struct mv_priv *priv = dev_get_platdata(dev); struct sata_fis_h2d cfis; u8 udma_cap; @@ -842,53 +850,7 @@ static void mv_sata_set_features(int port) if (udma_cap == ATA_UDMA3) cfis.sector_count = XFER_UDMA_3; - mv_ata_exec_ata_cmd_nondma(port, &cfis, NULL, 0, READ_CMD); -} - -int mv_sata_spin_down(int dev) -{ - struct sata_fis_h2d cfis; - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[dev].priv; - - if (priv->link == 0) { - debug("No device on port: %d\n", dev); - return 1; - } - - memset(&cfis, 0, sizeof(struct sata_fis_h2d)); - - cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D; - cfis.command = ATA_CMD_STANDBY; - - return mv_ata_exec_ata_cmd_nondma(dev, &cfis, NULL, 0, READ_CMD); -} - -int mv_sata_spin_up(int dev) -{ - struct sata_fis_h2d cfis; - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[dev].priv; - - if (priv->link == 0) { - debug("No device on port: %d\n", dev); - return 1; - } - - memset(&cfis, 0, sizeof(struct sata_fis_h2d)); - - cfis.fis_type = SATA_FIS_TYPE_REGISTER_H2D; - cfis.command = ATA_CMD_IDLE; - - return mv_ata_exec_ata_cmd_nondma(dev, &cfis, NULL, 0, READ_CMD); -} - -ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer) -{ - return ata_low_level_rw(dev, blknr, blkcnt, buffer, READ_CMD); -} - -ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer) -{ - return ata_low_level_rw(dev, blknr, blkcnt, (void *)buffer, WRITE_CMD); + mv_ata_exec_ata_cmd_nondma(dev, port, &cfis, NULL, 0, READ_CMD); } /* @@ -916,25 +878,17 @@ static void mvsata_ide_conf_mbus_windows(void) } } -int init_sata(int dev) +static int sata_mv_init_sata(struct udevice *dev, int port) { - struct mv_priv *priv; + struct mv_priv *priv = dev_get_platdata(dev); - debug("Initialize sata dev: %d\n", dev); + debug("Initialize sata dev: %d\n", port); - if (dev < 0 || dev >= CONFIG_SYS_SATA_MAX_DEVICE) { - printf("Invalid sata device %d\n", dev); + if (port < 0 || port >= CONFIG_SYS_SATA_MAX_DEVICE) { + printf("Invalid sata device %d\n", port); return -1; } - priv = (struct mv_priv *)malloc(sizeof(struct mv_priv)); - if (!priv) { - printf("Failed to allocate memory for private sata data\n"); - return -ENOMEM; - } - - memset((void *)priv, 0, sizeof(struct mv_priv)); - /* Allocate and align request buffer */ priv->crqb_alloc = malloc(sizeof(struct crqb) * REQUEST_QUEUE_SIZE + CRQB_ALIGN); @@ -959,11 +913,9 @@ int init_sata(int dev) priv->response = (struct crpb *)(((u32) priv->crpb_alloc + CRPB_ALIGN) & ~(CRPB_ALIGN - 1)); - sata_dev_desc[dev].priv = (void *)priv; - - sprintf(priv->name, "SATA%d", dev); + sprintf(priv->name, "SATA%d", port); - priv->regbase = dev == 0 ? SATA0_BASE : SATA1_BASE; + priv->regbase = port == 0 ? SATA0_BASE : SATA1_BASE; if (!hw_init) { debug("Initialize sata hw\n"); @@ -972,9 +924,9 @@ int init_sata(int dev) mvsata_ide_conf_mbus_windows(); } - mv_reset_port(dev); + mv_reset_port(dev, port); - if (probe_port(dev)) { + if (probe_port(dev, port)) { priv->link = 0; return -ENODEV; } @@ -983,19 +935,15 @@ int init_sata(int dev) return 0; } -int reset_sata(int dev) -{ - return 0; -} - -int scan_sata(int port) +static int sata_mv_scan_sata(struct udevice *dev, int port) { + struct blk_desc *desc = dev_get_uclass_platdata(dev); + struct mv_priv *priv = dev_get_platdata(dev); unsigned char serial[ATA_ID_SERNO_LEN + 1]; unsigned char firmware[ATA_ID_FW_REV_LEN + 1]; unsigned char product[ATA_ID_PROD_LEN + 1]; u64 n_sectors; u16 *id; - struct mv_priv *priv = (struct mv_priv *)sata_dev_desc[port].priv; if (!priv->link) return -ENODEV; @@ -1006,7 +954,7 @@ int scan_sata(int port) return -ENOMEM; } - mv_sata_identify(port, id); + mv_sata_identify(dev, port, id); ata_swap_buf_le16(id, ATA_ID_WORDS); #ifdef DEBUG ata_dump_id(id); @@ -1014,23 +962,23 @@ int scan_sata(int port) /* Serial number */ ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial)); - memcpy(sata_dev_desc[port].product, serial, sizeof(serial)); + memcpy(desc->product, serial, sizeof(serial)); /* Firmware version */ ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware)); - memcpy(sata_dev_desc[port].revision, firmware, sizeof(firmware)); + memcpy(desc->revision, firmware, sizeof(firmware)); /* Product model */ ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product)); - memcpy(sata_dev_desc[port].vendor, product, sizeof(product)); + memcpy(desc->vendor, product, sizeof(product)); /* Total sectors */ n_sectors = ata_id_n_sectors(id); - sata_dev_desc[port].lba = n_sectors; + desc->lba = n_sectors; /* Check if support LBA48 */ if (ata_id_has_lba48(id)) { - sata_dev_desc[port].lba48 = 1; + desc->lba48 = 1; debug("Device support LBA48\n"); } @@ -1038,13 +986,111 @@ int scan_sata(int port) priv->queue_depth = ata_id_queue_depth(id); /* Get the xfer mode from device */ - mv_sata_xfer_mode(port, id); + mv_sata_xfer_mode(dev, port, id); /* Set the xfer mode to highest speed */ - mv_sata_set_features(port); + mv_sata_set_features(dev, port); /* Start up */ - mv_start_edma_engine(port); + mv_start_edma_engine(dev, port); + + return 0; +} + +static ulong sata_mv_read(struct udevice *blk, lbaint_t blknr, + lbaint_t blkcnt, void *buffer) +{ + struct mv_priv *priv = dev_get_platdata(blk); + + return ata_low_level_rw(blk, priv->dev_nr, blknr, blkcnt, + buffer, READ_CMD); +} + +static ulong sata_mv_write(struct udevice *blk, lbaint_t blknr, + lbaint_t blkcnt, const void *buffer) +{ + struct mv_priv *priv = dev_get_platdata(blk); + + return ata_low_level_rw(blk, priv->dev_nr, blknr, blkcnt, + (void *)buffer, WRITE_CMD); +} + +static const struct blk_ops sata_mv_blk_ops = { + .read = sata_mv_read, + .write = sata_mv_write, +}; + +U_BOOT_DRIVER(sata_mv_driver) = { + .name = "sata_mv_blk", + .id = UCLASS_BLK, + .ops = &sata_mv_blk_ops, + .platdata_auto_alloc_size = sizeof(struct mv_priv), +}; + +static int sata_mv_probe(struct udevice *dev) +{ + const void *blob = gd->fdt_blob; + int node = dev_of_offset(dev); + struct mv_priv *priv; + struct udevice *blk; + int nr_ports; + int ret; + int i; + + /* Get number of ports of this SATA controller */ + nr_ports = min(fdtdec_get_int(blob, node, "nr-ports", -1), + CONFIG_SYS_SATA_MAX_DEVICE); + + for (i = 0; i < nr_ports; i++) { + ret = blk_create_devicef(dev, "sata_mv_blk", "blk", + IF_TYPE_SATA, -1, 512, 0, &blk); + if (ret) { + debug("Can't create device\n"); + return ret; + } + + priv = dev_get_platdata(blk); + priv->dev_nr = i; + + /* Init SATA port */ + ret = sata_mv_init_sata(blk, i); + if (ret) { + debug("%s: Failed to init bus\n", __func__); + return ret; + } + + /* Scan SATA port */ + ret = sata_mv_scan_sata(blk, i); + if (ret) { + debug("%s: Failed to scan bus\n", __func__); + return ret; + } + } + + return 0; +} + +static int sata_mv_scan(struct udevice *dev) +{ + /* Nothing to do here */ return 0; } + +static const struct udevice_id sata_mv_ids[] = { + { .compatible = "marvell,armada-370-sata" }, + { .compatible = "marvell,orion-sata" }, + { } +}; + +struct ahci_ops sata_mv_ahci_ops = { + .scan = sata_mv_scan, +}; + +U_BOOT_DRIVER(sata_mv_ahci) = { + .name = "sata_mv_ahci", + .id = UCLASS_AHCI, + .of_match = sata_mv_ids, + .ops = &sata_mv_ahci_ops, + .probe = sata_mv_probe, +}; diff --git a/drivers/clk/altera/clk-arria10.c b/drivers/clk/altera/clk-arria10.c index 612a1718dcb..179869df45f 100644 --- a/drivers/clk/altera/clk-arria10.c +++ b/drivers/clk/altera/clk-arria10.c @@ -254,7 +254,8 @@ static int socfpga_a10_clk_bind(struct udevice *dev) fdt_node_check_compatible(fdt, offset, "fixed-clock")) continue; - if (pre_reloc_only && !dm_fdt_pre_reloc(fdt, offset)) + if (pre_reloc_only && + !dm_ofnode_pre_reloc(offset_to_ofnode(offset))) continue; ret = device_bind_driver_to_node(dev, "clk-a10", name, diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index 7cfbabc96d3..6b55ec59d6d 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -61,7 +61,7 @@ int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name) offset > 0; offset = fdt_next_subnode(fdt, offset)) { if (pre_reloc_only && - !dm_fdt_pre_reloc(fdt, offset)) + !dm_ofnode_pre_reloc(offset_to_ofnode(offset))) continue; /* * If this node has "compatible" property, this is not diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c index aebc6f0a34c..24859fd054e 100644 --- a/drivers/clk/clk_stm32mp1.c +++ b/drivers/clk/clk_stm32mp1.c @@ -15,10 +15,12 @@ #include <dt-bindings/clock/stm32mp1-clks.h> #include <dt-bindings/clock/stm32mp1-clksrc.h> +#ifndef CONFIG_STM32MP1_TRUSTED #if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) /* activate clock tree initialization in the driver */ #define STM32MP1_CLOCK_TREE_INIT #endif +#endif #define MAX_HSI_HZ 64000000 diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 0e584c12dc8..785f5c3acf7 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -254,14 +254,13 @@ int ofnode_read_size(ofnode node, const char *propname) fdt_addr_t ofnode_get_addr_index(ofnode node, int index) { int na, ns; - fdt_size_t size; if (ofnode_is_np(node)) { const __be32 *prop_val; uint flags; prop_val = of_get_address(ofnode_to_np(node), index, - (u64 *)&size, &flags); + NULL, &flags); if (!prop_val) return FDT_ADDR_T_NONE; @@ -278,7 +277,7 @@ fdt_addr_t ofnode_get_addr_index(ofnode node, int index) ns = ofnode_read_simple_size_cells(ofnode_get_parent(node)); return fdtdec_get_addr_size_fixed(gd->fdt_blob, ofnode_to_offset(node), "reg", - index, na, ns, &size, true); + index, na, ns, NULL, true); } return FDT_ADDR_T_NONE; @@ -700,18 +699,18 @@ int ofnode_read_simple_size_cells(ofnode node) bool ofnode_pre_reloc(ofnode node) { +#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_TPL_BUILD) + /* for SPL and TPL the remaining nodes after the fdtgrep 1st pass + * had property dm-pre-reloc or u-boot,dm-spl/tpl. + * They are removed in final dtb (fdtgrep 2nd pass) + */ + return true; +#else if (ofnode_read_bool(node, "u-boot,dm-pre-reloc")) return true; if (ofnode_read_bool(node, "u-boot,dm-pre-proper")) return true; -#ifdef CONFIG_TPL_BUILD - if (ofnode_read_bool(node, "u-boot,dm-tpl")) - return true; -#elif defined(CONFIG_SPL_BUILD) - if (ofnode_read_bool(node, "u-boot,dm-spl")) - return true; -#else /* * In regular builds individual spl and tpl handling both * count as handled pre-relocation for later second init. @@ -719,9 +718,9 @@ bool ofnode_pre_reloc(ofnode node) if (ofnode_read_bool(node, "u-boot,dm-spl") || ofnode_read_bool(node, "u-boot,dm-tpl")) return true; -#endif return false; +#endif } int ofnode_read_resource(ofnode node, uint index, struct resource *res) diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c index afac6d6e37e..5bb38e329cb 100644 --- a/drivers/core/syscon-uclass.c +++ b/drivers/core/syscon-uclass.c @@ -57,18 +57,64 @@ static int syscon_pre_probe(struct udevice *dev) #endif } +static int syscon_probe_by_ofnode(ofnode node, struct udevice **devp) +{ + struct udevice *dev, *parent; + int ret; + + /* found node with "syscon" compatible, not bounded to SYSCON UCLASS */ + if (!ofnode_device_is_compatible(node, "syscon")) { + dev_dbg(dev, "invalid compatible for syscon device\n"); + return -EINVAL; + } + + /* bound to driver with same ofnode or to root if not found */ + if (device_find_global_by_ofnode(node, &parent)) + parent = dm_root(); + + /* force bound to syscon class */ + ret = device_bind_driver_to_node(parent, "syscon", + ofnode_get_name(node), + node, &dev); + if (ret) { + dev_dbg(dev, "unable to bound syscon device\n"); + return ret; + } + ret = device_probe(dev); + if (ret) { + dev_dbg(dev, "unable to probe syscon device\n"); + return ret; + } + + *devp = dev; + return 0; +} + struct regmap *syscon_regmap_lookup_by_phandle(struct udevice *dev, const char *name) { struct udevice *syscon; struct regmap *r; + u32 phandle; + ofnode node; int err; err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, name, &syscon); if (err) { - dev_dbg(dev, "unable to find syscon device\n"); - return ERR_PTR(err); + /* found node with "syscon" compatible, not bounded to SYSCON */ + err = ofnode_read_u32(dev_ofnode(dev), name, &phandle); + if (err) + return ERR_PTR(err); + + node = ofnode_get_by_phandle(phandle); + if (!ofnode_valid(node)) { + dev_dbg(dev, "unable to find syscon device\n"); + return ERR_PTR(-EINVAL); + } + err = syscon_probe_by_ofnode(node, &syscon); + if (err) + return ERR_PTR(-ENODEV); } r = syscon_get_regmap(syscon); @@ -152,29 +198,18 @@ U_BOOT_DRIVER(generic_syscon) = { */ struct regmap *syscon_node_to_regmap(ofnode node) { - struct udevice *dev, *parent; - int ret; - - if (!uclass_get_device_by_ofnode(UCLASS_SYSCON, node, &dev)) - return syscon_get_regmap(dev); - - if (!ofnode_device_is_compatible(node, "syscon")) - return ERR_PTR(-EINVAL); + struct udevice *dev; + struct regmap *r; - /* bound to driver with same ofnode or to root if not found */ - if (device_find_global_by_ofnode(node, &parent)) - parent = dm_root(); + if (uclass_get_device_by_ofnode(UCLASS_SYSCON, node, &dev)) + if (syscon_probe_by_ofnode(node, &dev)) + return ERR_PTR(-ENODEV); - /* force bound to syscon class */ - ret = device_bind_driver_to_node(parent, "syscon", - ofnode_get_name(node), - node, &dev); - if (ret) - return ERR_PTR(ret); - - ret = device_probe(dev); - if (ret) - return ERR_PTR(ret); + r = syscon_get_regmap(dev); + if (!r) { + dev_dbg(dev, "unable to find regmap\n"); + return ERR_PTR(-ENODEV); + } - return syscon_get_regmap(dev); + return r; } diff --git a/drivers/core/util.c b/drivers/core/util.c index 27a68487034..96e47dc7070 100644 --- a/drivers/core/util.c +++ b/drivers/core/util.c @@ -31,42 +31,18 @@ int list_count_items(struct list_head *head) return count; } -bool dm_fdt_pre_reloc(const void *blob, int offset) -{ - if (fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL)) - return true; - -#ifdef CONFIG_TPL_BUILD - if (fdt_getprop(blob, offset, "u-boot,dm-tpl", NULL)) - return true; -#elif defined(CONFIG_SPL_BUILD) - if (fdt_getprop(blob, offset, "u-boot,dm-spl", NULL)) - return true; -#else - /* - * In regular builds individual spl and tpl handling both - * count as handled pre-relocation for later second init. - */ - if (fdt_getprop(blob, offset, "u-boot,dm-spl", NULL) || - fdt_getprop(blob, offset, "u-boot,dm-tpl", NULL)) - return true; -#endif - - return false; -} - bool dm_ofnode_pre_reloc(ofnode node) { +#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_TPL_BUILD) + /* for SPL and TPL the remaining nodes after the fdtgrep 1st pass + * had property dm-pre-reloc or u-boot,dm-spl/tpl. + * They are removed in final dtb (fdtgrep 2nd pass) + */ + return true; +#else if (ofnode_read_bool(node, "u-boot,dm-pre-reloc")) return true; -#ifdef CONFIG_TPL_BUILD - if (ofnode_read_bool(node, "u-boot,dm-tpl")) - return true; -#elif defined(CONFIG_SPL_BUILD) - if (ofnode_read_bool(node, "u-boot,dm-spl")) - return true; -#else /* * In regular builds individual spl and tpl handling both * count as handled pre-relocation for later second init. @@ -74,7 +50,7 @@ bool dm_ofnode_pre_reloc(ofnode node) if (ofnode_read_bool(node, "u-boot,dm-spl") || ofnode_read_bool(node, "u-boot,dm-tpl")) return true; -#endif return false; +#endif } diff --git a/drivers/ddr/marvell/axp/xor_regs.h b/drivers/ddr/marvell/axp/xor_regs.h index db5c4196739..d779e564189 100644 --- a/drivers/ddr/marvell/axp/xor_regs.h +++ b/drivers/ddr/marvell/axp/xor_regs.h @@ -13,7 +13,11 @@ #define XOR_UNIT(chan) ((chan) >> 1) #define XOR_CHAN(chan) ((chan) & 1) +#ifdef CONFIG_ARMADA_MSYS +#define MV_XOR_REGS_OFFSET(unit) (0xF0800) +#else #define MV_XOR_REGS_OFFSET(unit) (0x60900) +#endif #define MV_XOR_REGS_BASE(unit) (MV_XOR_REGS_OFFSET(unit)) /* XOR Engine Control Register Map */ diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c index 1d3c192cfe5..e7bd1b2350f 100644 --- a/drivers/dma/bcm6348-iudma.c +++ b/drivers/dma/bcm6348-iudma.c @@ -324,6 +324,9 @@ static int bcm6348_iudma_receive(struct dma *dma, void **dst, void *metadata) struct bcm6348_dma_desc *dma_desc = dma_desc = ch_priv->dma_ring; int ret; + if (!ch_priv->running) + return -EINVAL; + /* get dma ring descriptor address */ dma_desc += ch_priv->desc_id; @@ -369,6 +372,9 @@ static int bcm6348_iudma_send(struct dma *dma, void *src, size_t len, struct bcm6348_dma_desc *dma_desc; uint16_t status; + if (!ch_priv->running) + return -EINVAL; + /* flush cache */ bcm6348_iudma_fdc(src, len); diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b103180cf37..b3e4ecc50e1 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -23,7 +23,7 @@ config ALTERA_PIO config BCM6345_GPIO bool "BCM6345 GPIO driver" - depends on DM_GPIO && ARCH_BMIPS + depends on DM_GPIO && (ARCH_BMIPS || ARCH_BCM6858 || ARCH_BCM63158) help This driver supports the GPIO banks on BCM6345 SoCs. diff --git a/drivers/gpio/bcm6345_gpio.c b/drivers/gpio/bcm6345_gpio.c index d1f6cfa8405..71a978cf407 100644 --- a/drivers/gpio/bcm6345_gpio.c +++ b/drivers/gpio/bcm6345_gpio.c @@ -22,7 +22,7 @@ static int bcm6345_gpio_get_value(struct udevice *dev, unsigned offset) { struct bcm6345_gpio_priv *priv = dev_get_priv(dev); - return !!(readl_be(priv->reg_data) & BIT(offset)); + return !!(readl(priv->reg_data) & BIT(offset)); } static int bcm6345_gpio_set_value(struct udevice *dev, unsigned offset, @@ -31,9 +31,9 @@ static int bcm6345_gpio_set_value(struct udevice *dev, unsigned offset, struct bcm6345_gpio_priv *priv = dev_get_priv(dev); if (value) - setbits_be32(priv->reg_data, BIT(offset)); + setbits_32(priv->reg_data, BIT(offset)); else - clrbits_be32(priv->reg_data, BIT(offset)); + clrbits_32(priv->reg_data, BIT(offset)); return 0; } @@ -42,9 +42,9 @@ static int bcm6345_gpio_set_direction(void __iomem *dirout, unsigned offset, bool input) { if (input) - clrbits_be32(dirout, BIT(offset)); + clrbits_32(dirout, BIT(offset)); else - setbits_be32(dirout, BIT(offset)); + setbits_32(dirout, BIT(offset)); return 0; } @@ -70,7 +70,7 @@ static int bcm6345_gpio_get_function(struct udevice *dev, unsigned offset) { struct bcm6345_gpio_priv *priv = dev_get_priv(dev); - if (readl_be(priv->reg_dirout) & BIT(offset)) + if (readl(priv->reg_dirout) & BIT(offset)) return GPIOF_OUTPUT; else return GPIOF_INPUT; diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index 49e23a0a4bf..e47abf18333 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -593,6 +593,29 @@ int i2c_chip_ofdata_to_platdata(struct udevice *dev, struct dm_i2c_chip *chip) } #endif +static int i2c_pre_probe(struct udevice *dev) +{ +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) + struct dm_i2c_bus *i2c = dev_get_uclass_priv(dev); + unsigned int max = 0; + ofnode node; + int ret; + + i2c->max_transaction_bytes = 0; + dev_for_each_subnode(node, dev) { + ret = ofnode_read_u32(node, + "u-boot,i2c-transaction-bytes", + &max); + if (!ret && max > i2c->max_transaction_bytes) + i2c->max_transaction_bytes = max; + } + + debug("%s: I2C bus: %s max transaction bytes: %d\n", __func__, + dev->name, i2c->max_transaction_bytes); +#endif + return 0; +} + static int i2c_post_probe(struct udevice *dev) { #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) @@ -674,6 +697,7 @@ UCLASS_DRIVER(i2c) = { .post_bind = i2c_post_bind, .init = i2c_uclass_init, .priv_auto_alloc_size = sizeof(struct i2c_priv), + .pre_probe = i2c_pre_probe, .post_probe = i2c_post_probe, .per_device_auto_alloc_size = sizeof(struct dm_i2c_bus), .per_child_platdata_auto_alloc_size = sizeof(struct dm_i2c_chip), diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig index b0da67ce2c6..68f15261be7 100644 --- a/drivers/i2c/muxes/Kconfig +++ b/drivers/i2c/muxes/Kconfig @@ -29,11 +29,12 @@ config I2C_MUX_PCA954x tristate "TI PCA954x I2C Mux/switches" depends on I2C_MUX help - If you say yes here you get support for the TI PCA954x - I2C mux/switch devices. It is x width I2C multiplexer which enables to - partitioning I2C bus and connect multiple devices with the same address - to the same I2C controller where driver handles proper routing to - target i2c device. PCA9544 and PCA9548 are supported. + If you say yes here you get support for the TI PCA954x I2C mux/switch + devices. It is x width I2C multiplexer which enables to partitioning + I2C bus and connect multiple devices with the same address to the same + I2C controller where driver handles proper routing to target i2c + device. Supported chips are PCA9543, PCA9544, PCA9547, PCA9548 and + PCA9646. config I2C_MUX_GPIO tristate "GPIO-based I2C multiplexer" diff --git a/drivers/i2c/muxes/pca954x.c b/drivers/i2c/muxes/pca954x.c index bd4e9abe5f3..a630ce991d0 100644 --- a/drivers/i2c/muxes/pca954x.c +++ b/drivers/i2c/muxes/pca954x.c @@ -15,6 +15,7 @@ DECLARE_GLOBAL_DATA_PTR; enum pca_type { + PCA9543, PCA9544, PCA9547, PCA9548, @@ -22,7 +23,7 @@ enum pca_type { }; struct chip_desc { - u8 enable; + u8 enable; /* Enable mask in ctl register (used for muxes only) */ enum muxtype { pca954x_ismux = 0, pca954x_isswi, @@ -37,6 +38,10 @@ struct pca954x_priv { }; static const struct chip_desc chips[] = { + [PCA9543] = { + .muxtype = pca954x_isswi, + .width = 2, + }, [PCA9544] = { .enable = 0x4, .muxtype = pca954x_ismux, @@ -48,12 +53,10 @@ static const struct chip_desc chips[] = { .width = 8, }, [PCA9548] = { - .enable = 0x8, .muxtype = pca954x_isswi, .width = 8, }, [PCA9646] = { - .enable = 0x0, .muxtype = pca954x_isswi, .width = 4, }, @@ -89,6 +92,7 @@ static const struct i2c_mux_ops pca954x_ops = { }; static const struct udevice_id pca954x_ids[] = { + { .compatible = "nxp,pca9543", .data = PCA9543 }, { .compatible = "nxp,pca9544", .data = PCA9544 }, { .compatible = "nxp,pca9547", .data = PCA9547 }, { .compatible = "nxp,pca9548", .data = PCA9548 }, diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index 9999d9fe5e4..5420afbc8e0 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -354,9 +354,10 @@ int i2c_idle_bus(struct mxc_i2c_bus *i2c_bus) int i2c_idle_bus(struct mxc_i2c_bus *i2c_bus) { struct udevice *bus = i2c_bus->bus; + struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus); struct gpio_desc *scl_gpio = &i2c_bus->scl_gpio; struct gpio_desc *sda_gpio = &i2c_bus->sda_gpio; - int sda, scl; + int sda, scl, idle_sclks; int i, ret = 0; ulong elapsed, start_time; @@ -380,8 +381,22 @@ int i2c_idle_bus(struct mxc_i2c_bus *i2c_bus) if ((sda & scl) == 1) goto exit; /* Bus is idle already */ + /* + * In most cases it is just enough to generate 8 + 1 SCLK + * clocks to recover I2C slave device from 'stuck' state + * (when for example SW reset was performed, in the middle of + * I2C transmission). + * + * However, there are devices which send data in packets of + * N bytes (N > 1). In such case we do need N * 8 + 1 SCLK + * clocks. + */ + idle_sclks = 8 + 1; + + if (i2c->max_transaction_bytes > 0) + idle_sclks = i2c->max_transaction_bytes * 8 + 1; /* Send high and low on the SCL line */ - for (i = 0; i < 9; i++) { + for (i = 0; i < idle_sclks; i++) { dm_gpio_set_dir_flags(scl_gpio, GPIOD_IS_OUT); dm_gpio_set_value(scl_gpio, 0); udelay(50); diff --git a/drivers/misc/i2c_eeprom.c b/drivers/misc/i2c_eeprom.c index 29ad87c1d7b..f25d0540075 100644 --- a/drivers/misc/i2c_eeprom.c +++ b/drivers/misc/i2c_eeprom.c @@ -5,6 +5,7 @@ #include <common.h> #include <linux/err.h> +#include <linux/kernel.h> #include <dm.h> #include <i2c.h> #include <i2c_eeprom.h> @@ -38,7 +39,24 @@ static int i2c_eeprom_std_read(struct udevice *dev, int offset, uint8_t *buf, static int i2c_eeprom_std_write(struct udevice *dev, int offset, const uint8_t *buf, int size) { - return -ENODEV; + struct i2c_eeprom *priv = dev_get_priv(dev); + int ret; + + while (size > 0) { + int write_size = min_t(int, size, priv->pagesize); + + ret = dm_i2c_write(dev, offset, buf, write_size); + if (ret) + return ret; + + offset += write_size; + buf += write_size; + size -= write_size; + + udelay(10000); + } + + return 0; } static const struct i2c_eeprom_ops i2c_eeprom_std_ops = { @@ -50,6 +68,12 @@ static int i2c_eeprom_std_ofdata_to_platdata(struct udevice *dev) { struct i2c_eeprom *priv = dev_get_priv(dev); u64 data = dev_get_driver_data(dev); + u32 pagesize; + + if (dev_read_u32(dev, "pagesize", &pagesize) == 0) { + priv->pagesize = pagesize; + return 0; + } /* 6 bit -> page size of up to 2^63 (should be sufficient) */ priv->pagewidth = data & 0x3F; diff --git a/drivers/misc/stm32mp_fuse.c b/drivers/misc/stm32mp_fuse.c index 33943a231b1..8dc246b0dbe 100644 --- a/drivers/misc/stm32mp_fuse.c +++ b/drivers/misc/stm32mp_fuse.c @@ -9,8 +9,10 @@ #include <errno.h> #include <dm/device.h> #include <dm/uclass.h> +#include <power/stpmic1.h> #define STM32MP_OTP_BANK 0 +#define STM32MP_NVM_BANK 1 /* * The 'fuse' command API @@ -34,6 +36,13 @@ int fuse_read(u32 bank, u32 word, u32 *val) ret = 0; break; +#ifdef CONFIG_PMIC_STPMIC1 + case STM32MP_NVM_BANK: + *val = 0; + ret = stpmic1_shadow_read_byte(word, (u8 *)val); + break; +#endif /* CONFIG_PMIC_STPMIC1 */ + default: printf("stm32mp %s: wrong value for bank %i\n", __func__, bank); ret = -EINVAL; @@ -62,6 +71,12 @@ int fuse_prog(u32 bank, u32 word, u32 val) ret = 0; break; +#ifdef CONFIG_PMIC_STPMIC1 + case STM32MP_NVM_BANK: + ret = stpmic1_nvm_write_byte(word, (u8 *)&val); + break; +#endif /* CONFIG_PMIC_STPMIC1 */ + default: printf("stm32mp %s: wrong value for bank %i\n", __func__, bank); ret = -EINVAL; @@ -89,6 +104,13 @@ int fuse_sense(u32 bank, u32 word, u32 *val) ret = 0; break; +#ifdef CONFIG_PMIC_STPMIC1 + case STM32MP_NVM_BANK: + *val = 0; + ret = stpmic1_nvm_read_byte(word, (u8 *)val); + break; +#endif /* CONFIG_PMIC_STPMIC1 */ + default: printf("stm32mp %s: wrong value for bank %i\n", __func__, bank); ret = -EINVAL; @@ -117,6 +139,12 @@ int fuse_override(u32 bank, u32 word, u32 val) ret = 0; break; +#ifdef CONFIG_PMIC_STPMIC1 + case STM32MP_NVM_BANK: + ret = stpmic1_shadow_write_byte(word, (u8 *)&val); + break; +#endif /* CONFIG_PMIC_STPMIC1 */ + default: printf("stm32mp %s: wrong value for bank %i\n", __func__, bank); diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index cb7ca38d074..89ac8229f58 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -1051,13 +1051,13 @@ static int mtd_check_oob_ops(struct mtd_info *mtd, loff_t offs, return -EINVAL; if (ops->ooblen) { - u64 maxooblen; + size_t maxooblen; if (ops->ooboffs >= mtd_oobavail(mtd, ops)) return -EINVAL; - maxooblen = ((mtd_div_by_ws(mtd->size, mtd) - - mtd_div_by_ws(offs, mtd)) * + maxooblen = ((size_t)(mtd_div_by_ws(mtd->size, mtd) - + mtd_div_by_ws(offs, mtd)) * mtd_oobavail(mtd, ops)) - ops->ooboffs; if (ops->ooblen > maxooblen) return -EINVAL; diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 7f76e5ecef4..dc087ab641e 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -256,6 +256,17 @@ config NAND_ZYNQ_USE_BOOTLOADER1_TIMINGS This flag prevent U-boot reconfigure NAND flash controller and reuse the NAND timing from 1st stage bootloader. +config NAND_STM32_FMC2 + bool "Support for NAND controller on STM32MP SoCs" + depends on ARCH_STM32MP + select SYS_NAND_SELF_INIT + imply CMD_NAND + help + Enables support for NAND Flash chips on SoCs containing the FMC2 + NAND controller. This controller is found on STM32MP SoCs. + The controller supports a maximum 8k page size and supports + a maximum 8-bit correction error per sector of 512 bytes. + comment "Generic NAND options" config SYS_NAND_BLOCK_SIZE diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index c61e3f38391..b10e718d150 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -65,6 +65,7 @@ obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o obj-$(CONFIG_NAND_PLAT) += nand_plat.o obj-$(CONFIG_NAND_SUNXI) += sunxi_nand.o obj-$(CONFIG_NAND_ZYNQ) += zynq_nand.o +obj-$(CONFIG_NAND_STM32_FMC2) += stm32_fmc2_nand.o else # minimal SPL drivers diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c new file mode 100644 index 00000000000..2bb749d7f73 --- /dev/null +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c @@ -0,0 +1,1092 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) STMicroelectronics 2019 + * Author: Christophe Kerello <christophe.kerello@st.com> + */ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <nand.h> +#include <reset.h> +#include <linux/iopoll.h> +#include <linux/ioport.h> + +/* Bad block marker length */ +#define FMC2_BBM_LEN 2 + +/* ECC step size */ +#define FMC2_ECC_STEP_SIZE 512 + +/* Command delay */ +#define FMC2_RB_DELAY_US 30 + +/* Max chip enable */ +#define FMC2_MAX_CE 2 + +/* Timings */ +#define FMC2_THIZ 1 +#define FMC2_TIO 8000 +#define FMC2_TSYNC 3000 +#define FMC2_PCR_TIMING_MASK 0xf +#define FMC2_PMEM_PATT_TIMING_MASK 0xff + +/* FMC2 Controller Registers */ +#define FMC2_BCR1 0x0 +#define FMC2_PCR 0x80 +#define FMC2_SR 0x84 +#define FMC2_PMEM 0x88 +#define FMC2_PATT 0x8c +#define FMC2_HECCR 0x94 +#define FMC2_BCHISR 0x254 +#define FMC2_BCHICR 0x258 +#define FMC2_BCHPBR1 0x260 +#define FMC2_BCHPBR2 0x264 +#define FMC2_BCHPBR3 0x268 +#define FMC2_BCHPBR4 0x26c +#define FMC2_BCHDSR0 0x27c +#define FMC2_BCHDSR1 0x280 +#define FMC2_BCHDSR2 0x284 +#define FMC2_BCHDSR3 0x288 +#define FMC2_BCHDSR4 0x28c + +/* Register: FMC2_BCR1 */ +#define FMC2_BCR1_FMC2EN BIT(31) + +/* Register: FMC2_PCR */ +#define FMC2_PCR_PWAITEN BIT(1) +#define FMC2_PCR_PBKEN BIT(2) +#define FMC2_PCR_PWID_MASK GENMASK(5, 4) +#define FMC2_PCR_PWID(x) (((x) & 0x3) << 4) +#define FMC2_PCR_PWID_BUSWIDTH_8 0 +#define FMC2_PCR_PWID_BUSWIDTH_16 1 +#define FMC2_PCR_ECCEN BIT(6) +#define FMC2_PCR_ECCALG BIT(8) +#define FMC2_PCR_TCLR_MASK GENMASK(12, 9) +#define FMC2_PCR_TCLR(x) (((x) & 0xf) << 9) +#define FMC2_PCR_TCLR_DEFAULT 0xf +#define FMC2_PCR_TAR_MASK GENMASK(16, 13) +#define FMC2_PCR_TAR(x) (((x) & 0xf) << 13) +#define FMC2_PCR_TAR_DEFAULT 0xf +#define FMC2_PCR_ECCSS_MASK GENMASK(19, 17) +#define FMC2_PCR_ECCSS(x) (((x) & 0x7) << 17) +#define FMC2_PCR_ECCSS_512 1 +#define FMC2_PCR_ECCSS_2048 3 +#define FMC2_PCR_BCHECC BIT(24) +#define FMC2_PCR_WEN BIT(25) + +/* Register: FMC2_SR */ +#define FMC2_SR_NWRF BIT(6) + +/* Register: FMC2_PMEM */ +#define FMC2_PMEM_MEMSET(x) (((x) & 0xff) << 0) +#define FMC2_PMEM_MEMWAIT(x) (((x) & 0xff) << 8) +#define FMC2_PMEM_MEMHOLD(x) (((x) & 0xff) << 16) +#define FMC2_PMEM_MEMHIZ(x) (((x) & 0xff) << 24) +#define FMC2_PMEM_DEFAULT 0x0a0a0a0a + +/* Register: FMC2_PATT */ +#define FMC2_PATT_ATTSET(x) (((x) & 0xff) << 0) +#define FMC2_PATT_ATTWAIT(x) (((x) & 0xff) << 8) +#define FMC2_PATT_ATTHOLD(x) (((x) & 0xff) << 16) +#define FMC2_PATT_ATTHIZ(x) (((x) & 0xff) << 24) +#define FMC2_PATT_DEFAULT 0x0a0a0a0a + +/* Register: FMC2_BCHISR */ +#define FMC2_BCHISR_DERF BIT(1) +#define FMC2_BCHISR_EPBRF BIT(4) + +/* Register: FMC2_BCHICR */ +#define FMC2_BCHICR_CLEAR_IRQ GENMASK(4, 0) + +/* Register: FMC2_BCHDSR0 */ +#define FMC2_BCHDSR0_DUE BIT(0) +#define FMC2_BCHDSR0_DEF BIT(1) +#define FMC2_BCHDSR0_DEN_MASK GENMASK(7, 4) +#define FMC2_BCHDSR0_DEN_SHIFT 4 + +/* Register: FMC2_BCHDSR1 */ +#define FMC2_BCHDSR1_EBP1_MASK GENMASK(12, 0) +#define FMC2_BCHDSR1_EBP2_MASK GENMASK(28, 16) +#define FMC2_BCHDSR1_EBP2_SHIFT 16 + +/* Register: FMC2_BCHDSR2 */ +#define FMC2_BCHDSR2_EBP3_MASK GENMASK(12, 0) +#define FMC2_BCHDSR2_EBP4_MASK GENMASK(28, 16) +#define FMC2_BCHDSR2_EBP4_SHIFT 16 + +/* Register: FMC2_BCHDSR3 */ +#define FMC2_BCHDSR3_EBP5_MASK GENMASK(12, 0) +#define FMC2_BCHDSR3_EBP6_MASK GENMASK(28, 16) +#define FMC2_BCHDSR3_EBP6_SHIFT 16 + +/* Register: FMC2_BCHDSR4 */ +#define FMC2_BCHDSR4_EBP7_MASK GENMASK(12, 0) +#define FMC2_BCHDSR4_EBP8_MASK GENMASK(28, 16) +#define FMC2_BCHDSR4_EBP8_SHIFT 16 + +#define FMC2_NSEC_PER_SEC 1000000000L + +enum stm32_fmc2_ecc { + FMC2_ECC_HAM = 1, + FMC2_ECC_BCH4 = 4, + FMC2_ECC_BCH8 = 8 +}; + +struct stm32_fmc2_timings { + u8 tclr; + u8 tar; + u8 thiz; + u8 twait; + u8 thold_mem; + u8 tset_mem; + u8 thold_att; + u8 tset_att; +}; + +struct stm32_fmc2_nand { + struct nand_chip chip; + struct stm32_fmc2_timings timings; + int ncs; + int cs_used[FMC2_MAX_CE]; +}; + +static inline struct stm32_fmc2_nand *to_fmc2_nand(struct nand_chip *chip) +{ + return container_of(chip, struct stm32_fmc2_nand, chip); +} + +struct stm32_fmc2_nfc { + struct nand_hw_control base; + struct stm32_fmc2_nand nand; + struct nand_ecclayout ecclayout; + void __iomem *io_base; + void __iomem *data_base[FMC2_MAX_CE]; + void __iomem *cmd_base[FMC2_MAX_CE]; + void __iomem *addr_base[FMC2_MAX_CE]; + struct clk clk; + + u8 cs_assigned; + int cs_sel; +}; + +static inline struct stm32_fmc2_nfc *to_stm32_nfc(struct nand_hw_control *base) +{ + return container_of(base, struct stm32_fmc2_nfc, base); +} + +/* Timings configuration */ +static void stm32_fmc2_timings_init(struct nand_chip *chip) +{ + struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nand *nand = to_fmc2_nand(chip); + struct stm32_fmc2_timings *timings = &nand->timings; + u32 pcr = readl(fmc2->io_base + FMC2_PCR); + u32 pmem, patt; + + /* Set tclr/tar timings */ + pcr &= ~FMC2_PCR_TCLR_MASK; + pcr |= FMC2_PCR_TCLR(timings->tclr); + pcr &= ~FMC2_PCR_TAR_MASK; + pcr |= FMC2_PCR_TAR(timings->tar); + + /* Set tset/twait/thold/thiz timings in common bank */ + pmem = FMC2_PMEM_MEMSET(timings->tset_mem); + pmem |= FMC2_PMEM_MEMWAIT(timings->twait); + pmem |= FMC2_PMEM_MEMHOLD(timings->thold_mem); + pmem |= FMC2_PMEM_MEMHIZ(timings->thiz); + + /* Set tset/twait/thold/thiz timings in attribut bank */ + patt = FMC2_PATT_ATTSET(timings->tset_att); + patt |= FMC2_PATT_ATTWAIT(timings->twait); + patt |= FMC2_PATT_ATTHOLD(timings->thold_att); + patt |= FMC2_PATT_ATTHIZ(timings->thiz); + + writel(pcr, fmc2->io_base + FMC2_PCR); + writel(pmem, fmc2->io_base + FMC2_PMEM); + writel(patt, fmc2->io_base + FMC2_PATT); +} + +/* Controller configuration */ +static void stm32_fmc2_setup(struct nand_chip *chip) +{ + struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + u32 pcr = readl(fmc2->io_base + FMC2_PCR); + + /* Configure ECC algorithm (default configuration is Hamming) */ + pcr &= ~FMC2_PCR_ECCALG; + pcr &= ~FMC2_PCR_BCHECC; + if (chip->ecc.strength == FMC2_ECC_BCH8) { + pcr |= FMC2_PCR_ECCALG; + pcr |= FMC2_PCR_BCHECC; + } else if (chip->ecc.strength == FMC2_ECC_BCH4) { + pcr |= FMC2_PCR_ECCALG; + } + + /* Set buswidth */ + pcr &= ~FMC2_PCR_PWID_MASK; + if (chip->options & NAND_BUSWIDTH_16) + pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_BUSWIDTH_16); + + /* Set ECC sector size */ + pcr &= ~FMC2_PCR_ECCSS_MASK; + pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_512); + + writel(pcr, fmc2->io_base + FMC2_PCR); +} + +/* Select target */ +static void stm32_fmc2_select_chip(struct mtd_info *mtd, int chipnr) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nand *nand = to_fmc2_nand(chip); + + if (chipnr < 0 || chipnr >= nand->ncs) + return; + + if (nand->cs_used[chipnr] == fmc2->cs_sel) + return; + + fmc2->cs_sel = nand->cs_used[chipnr]; + chip->IO_ADDR_R = fmc2->data_base[fmc2->cs_sel]; + chip->IO_ADDR_W = fmc2->data_base[fmc2->cs_sel]; + + /* FMC2 setup routine */ + stm32_fmc2_setup(chip); + + /* Apply timings */ + stm32_fmc2_timings_init(chip); +} + +/* Set bus width to 16-bit or 8-bit */ +static void stm32_fmc2_set_buswidth_16(struct stm32_fmc2_nfc *fmc2, bool set) +{ + u32 pcr = readl(fmc2->io_base + FMC2_PCR); + + pcr &= ~FMC2_PCR_PWID_MASK; + if (set) + pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_BUSWIDTH_16); + writel(pcr, fmc2->io_base + FMC2_PCR); +} + +/* Enable/disable ECC */ +static void stm32_fmc2_set_ecc(struct stm32_fmc2_nfc *fmc2, bool enable) +{ + u32 pcr = readl(fmc2->io_base + FMC2_PCR); + + pcr &= ~FMC2_PCR_ECCEN; + if (enable) + pcr |= FMC2_PCR_ECCEN; + writel(pcr, fmc2->io_base + FMC2_PCR); +} + +/* Clear irq sources in case of bch is used */ +static inline void stm32_fmc2_clear_bch_irq(struct stm32_fmc2_nfc *fmc2) +{ + writel(FMC2_BCHICR_CLEAR_IRQ, fmc2->io_base + FMC2_BCHICR); +} + +/* Send command and address cycles */ +static void stm32_fmc2_cmd_ctrl(struct mtd_info *mtd, int cmd, + unsigned int ctrl) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_CLE) { + writeb(cmd, fmc2->cmd_base[fmc2->cs_sel]); + return; + } + + writeb(cmd, fmc2->addr_base[fmc2->cs_sel]); +} + +/* + * Enable ECC logic and reset syndrome/parity bits previously calculated + * Syndrome/parity bits is cleared by setting the ECCEN bit to 0 + */ +static void stm32_fmc2_hwctl(struct mtd_info *mtd, int mode) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + + stm32_fmc2_set_ecc(fmc2, false); + + if (chip->ecc.strength != FMC2_ECC_HAM) { + u32 pcr = readl(fmc2->io_base + FMC2_PCR); + + if (mode == NAND_ECC_WRITE) + pcr |= FMC2_PCR_WEN; + else + pcr &= ~FMC2_PCR_WEN; + writel(pcr, fmc2->io_base + FMC2_PCR); + + stm32_fmc2_clear_bch_irq(fmc2); + } + + stm32_fmc2_set_ecc(fmc2, true); +} + +/* + * ECC Hamming calculation + * ECC is 3 bytes for 512 bytes of data (supports error correction up to + * max of 1-bit) + */ +static int stm32_fmc2_ham_calculate(struct mtd_info *mtd, const u8 *data, + u8 *ecc) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + u32 heccr, sr; + int ret; + + ret = readl_poll_timeout(fmc2->io_base + FMC2_SR, sr, + sr & FMC2_SR_NWRF, 10000); + if (ret < 0) { + pr_err("Ham timeout\n"); + return ret; + } + + heccr = readl(fmc2->io_base + FMC2_HECCR); + + ecc[0] = heccr; + ecc[1] = heccr >> 8; + ecc[2] = heccr >> 16; + + /* Disable ecc */ + stm32_fmc2_set_ecc(fmc2, false); + + return 0; +} + +static int stm32_fmc2_ham_correct(struct mtd_info *mtd, u8 *dat, + u8 *read_ecc, u8 *calc_ecc) +{ + u8 bit_position = 0, b0, b1, b2; + u32 byte_addr = 0, b; + u32 i, shifting = 1; + + /* Indicate which bit and byte is faulty (if any) */ + b0 = read_ecc[0] ^ calc_ecc[0]; + b1 = read_ecc[1] ^ calc_ecc[1]; + b2 = read_ecc[2] ^ calc_ecc[2]; + b = b0 | (b1 << 8) | (b2 << 16); + + /* No errors */ + if (likely(!b)) + return 0; + + /* Calculate bit position */ + for (i = 0; i < 3; i++) { + switch (b % 4) { + case 2: + bit_position += shifting; + case 1: + break; + default: + return -EBADMSG; + } + shifting <<= 1; + b >>= 2; + } + + /* Calculate byte position */ + shifting = 1; + for (i = 0; i < 9; i++) { + switch (b % 4) { + case 2: + byte_addr += shifting; + case 1: + break; + default: + return -EBADMSG; + } + shifting <<= 1; + b >>= 2; + } + + /* Flip the bit */ + dat[byte_addr] ^= (1 << bit_position); + + return 1; +} + +/* + * ECC BCH calculation and correction + * ECC is 7/13 bytes for 512 bytes of data (supports error correction up to + * max of 4-bit/8-bit) + */ + +static int stm32_fmc2_bch_calculate(struct mtd_info *mtd, const u8 *data, + u8 *ecc) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + u32 bchpbr, bchisr; + int ret; + + /* Wait until the BCH code is ready */ + ret = readl_poll_timeout(fmc2->io_base + FMC2_BCHISR, bchisr, + bchisr & FMC2_BCHISR_EPBRF, 10000); + if (ret < 0) { + pr_err("Bch timeout\n"); + return ret; + } + + /* Read parity bits */ + bchpbr = readl(fmc2->io_base + FMC2_BCHPBR1); + ecc[0] = bchpbr; + ecc[1] = bchpbr >> 8; + ecc[2] = bchpbr >> 16; + ecc[3] = bchpbr >> 24; + + bchpbr = readl(fmc2->io_base + FMC2_BCHPBR2); + ecc[4] = bchpbr; + ecc[5] = bchpbr >> 8; + ecc[6] = bchpbr >> 16; + + if (chip->ecc.strength == FMC2_ECC_BCH8) { + ecc[7] = bchpbr >> 24; + + bchpbr = readl(fmc2->io_base + FMC2_BCHPBR3); + ecc[8] = bchpbr; + ecc[9] = bchpbr >> 8; + ecc[10] = bchpbr >> 16; + ecc[11] = bchpbr >> 24; + + bchpbr = readl(fmc2->io_base + FMC2_BCHPBR4); + ecc[12] = bchpbr; + } + + /* Disable ecc */ + stm32_fmc2_set_ecc(fmc2, false); + + return 0; +} + +/* BCH algorithm correction */ +static int stm32_fmc2_bch_correct(struct mtd_info *mtd, u8 *dat, + u8 *read_ecc, u8 *calc_ecc) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + u32 bchdsr0, bchdsr1, bchdsr2, bchdsr3, bchdsr4, bchisr; + u16 pos[8]; + int i, ret, den, eccsize = chip->ecc.size; + unsigned int nb_errs = 0; + + /* Wait until the decoding error is ready */ + ret = readl_poll_timeout(fmc2->io_base + FMC2_BCHISR, bchisr, + bchisr & FMC2_BCHISR_DERF, 10000); + if (ret < 0) { + pr_err("Bch timeout\n"); + return ret; + } + + bchdsr0 = readl(fmc2->io_base + FMC2_BCHDSR0); + bchdsr1 = readl(fmc2->io_base + FMC2_BCHDSR1); + bchdsr2 = readl(fmc2->io_base + FMC2_BCHDSR2); + bchdsr3 = readl(fmc2->io_base + FMC2_BCHDSR3); + bchdsr4 = readl(fmc2->io_base + FMC2_BCHDSR4); + + /* Disable ECC */ + stm32_fmc2_set_ecc(fmc2, false); + + /* No errors found */ + if (likely(!(bchdsr0 & FMC2_BCHDSR0_DEF))) + return 0; + + /* Too many errors detected */ + if (unlikely(bchdsr0 & FMC2_BCHDSR0_DUE)) + return -EBADMSG; + + pos[0] = bchdsr1 & FMC2_BCHDSR1_EBP1_MASK; + pos[1] = (bchdsr1 & FMC2_BCHDSR1_EBP2_MASK) >> FMC2_BCHDSR1_EBP2_SHIFT; + pos[2] = bchdsr2 & FMC2_BCHDSR2_EBP3_MASK; + pos[3] = (bchdsr2 & FMC2_BCHDSR2_EBP4_MASK) >> FMC2_BCHDSR2_EBP4_SHIFT; + pos[4] = bchdsr3 & FMC2_BCHDSR3_EBP5_MASK; + pos[5] = (bchdsr3 & FMC2_BCHDSR3_EBP6_MASK) >> FMC2_BCHDSR3_EBP6_SHIFT; + pos[6] = bchdsr4 & FMC2_BCHDSR4_EBP7_MASK; + pos[7] = (bchdsr4 & FMC2_BCHDSR4_EBP8_MASK) >> FMC2_BCHDSR4_EBP8_SHIFT; + + den = (bchdsr0 & FMC2_BCHDSR0_DEN_MASK) >> FMC2_BCHDSR0_DEN_SHIFT; + for (i = 0; i < den; i++) { + if (pos[i] < eccsize * 8) { + __change_bit(pos[i], (unsigned long *)dat); + nb_errs++; + } + } + + return nb_errs; +} + +static int stm32_fmc2_read_page(struct mtd_info *mtd, + struct nand_chip *chip, u8 *buf, + int oob_required, int page) +{ + int i, s, stat, eccsize = chip->ecc.size; + int eccbytes = chip->ecc.bytes; + int eccsteps = chip->ecc.steps; + int eccstrength = chip->ecc.strength; + u8 *p = buf; + u8 *ecc_calc = chip->buffers->ecccalc; + u8 *ecc_code = chip->buffers->ecccode; + unsigned int max_bitflips = 0; + + for (i = mtd->writesize + FMC2_BBM_LEN, s = 0; s < eccsteps; + s++, i += eccbytes, p += eccsize) { + chip->ecc.hwctl(mtd, NAND_ECC_READ); + + /* Read the nand page sector (512 bytes) */ + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, s * eccsize, -1); + chip->read_buf(mtd, p, eccsize); + + /* Read the corresponding ECC bytes */ + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, i, -1); + chip->read_buf(mtd, ecc_code, eccbytes); + + /* Correct the data */ + stat = chip->ecc.correct(mtd, p, ecc_code, ecc_calc); + if (stat == -EBADMSG) + /* Check for empty pages with bitflips */ + stat = nand_check_erased_ecc_chunk(p, eccsize, + ecc_code, eccbytes, + NULL, 0, + eccstrength); + + if (stat < 0) { + mtd->ecc_stats.failed++; + } else { + mtd->ecc_stats.corrected += stat; + max_bitflips = max_t(unsigned int, max_bitflips, stat); + } + } + + /* Read oob */ + if (oob_required) { + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1); + chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); + } + + return max_bitflips; +} + +/* Controller initialization */ +static void stm32_fmc2_init(struct stm32_fmc2_nfc *fmc2) +{ + u32 pcr = readl(fmc2->io_base + FMC2_PCR); + u32 bcr1 = readl(fmc2->io_base + FMC2_BCR1); + + /* Set CS used to undefined */ + fmc2->cs_sel = -1; + + /* Enable wait feature and nand flash memory bank */ + pcr |= FMC2_PCR_PWAITEN; + pcr |= FMC2_PCR_PBKEN; + + /* Set buswidth to 8 bits mode for identification */ + pcr &= ~FMC2_PCR_PWID_MASK; + + /* ECC logic is disabled */ + pcr &= ~FMC2_PCR_ECCEN; + + /* Default mode */ + pcr &= ~FMC2_PCR_ECCALG; + pcr &= ~FMC2_PCR_BCHECC; + pcr &= ~FMC2_PCR_WEN; + + /* Set default ECC sector size */ + pcr &= ~FMC2_PCR_ECCSS_MASK; + pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_2048); + + /* Set default tclr/tar timings */ + pcr &= ~FMC2_PCR_TCLR_MASK; + pcr |= FMC2_PCR_TCLR(FMC2_PCR_TCLR_DEFAULT); + pcr &= ~FMC2_PCR_TAR_MASK; + pcr |= FMC2_PCR_TAR(FMC2_PCR_TAR_DEFAULT); + + /* Enable FMC2 controller */ + bcr1 |= FMC2_BCR1_FMC2EN; + + writel(bcr1, fmc2->io_base + FMC2_BCR1); + writel(pcr, fmc2->io_base + FMC2_PCR); + writel(FMC2_PMEM_DEFAULT, fmc2->io_base + FMC2_PMEM); + writel(FMC2_PATT_DEFAULT, fmc2->io_base + FMC2_PATT); +} + +/* Controller timings */ +static void stm32_fmc2_calc_timings(struct nand_chip *chip, + const struct nand_sdr_timings *sdrt) +{ + struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nand *nand = to_fmc2_nand(chip); + struct stm32_fmc2_timings *tims = &nand->timings; + unsigned long hclk = clk_get_rate(&fmc2->clk); + unsigned long hclkp = FMC2_NSEC_PER_SEC / (hclk / 1000); + int tar, tclr, thiz, twait, tset_mem, tset_att, thold_mem, thold_att; + + tar = hclkp; + if (tar < sdrt->tAR_min) + tar = sdrt->tAR_min; + tims->tar = DIV_ROUND_UP(tar, hclkp) - 1; + if (tims->tar > FMC2_PCR_TIMING_MASK) + tims->tar = FMC2_PCR_TIMING_MASK; + + tclr = hclkp; + if (tclr < sdrt->tCLR_min) + tclr = sdrt->tCLR_min; + tims->tclr = DIV_ROUND_UP(tclr, hclkp) - 1; + if (tims->tclr > FMC2_PCR_TIMING_MASK) + tims->tclr = FMC2_PCR_TIMING_MASK; + + tims->thiz = FMC2_THIZ; + thiz = (tims->thiz + 1) * hclkp; + + /* + * tWAIT > tRP + * tWAIT > tWP + * tWAIT > tREA + tIO + */ + twait = hclkp; + if (twait < sdrt->tRP_min) + twait = sdrt->tRP_min; + if (twait < sdrt->tWP_min) + twait = sdrt->tWP_min; + if (twait < sdrt->tREA_max + FMC2_TIO) + twait = sdrt->tREA_max + FMC2_TIO; + tims->twait = DIV_ROUND_UP(twait, hclkp); + if (tims->twait == 0) + tims->twait = 1; + else if (tims->twait > FMC2_PMEM_PATT_TIMING_MASK) + tims->twait = FMC2_PMEM_PATT_TIMING_MASK; + + /* + * tSETUP_MEM > tCS - tWAIT + * tSETUP_MEM > tALS - tWAIT + * tSETUP_MEM > tDS - (tWAIT - tHIZ) + */ + tset_mem = hclkp; + if (sdrt->tCS_min > twait && (tset_mem < sdrt->tCS_min - twait)) + tset_mem = sdrt->tCS_min - twait; + if (sdrt->tALS_min > twait && (tset_mem < sdrt->tALS_min - twait)) + tset_mem = sdrt->tALS_min - twait; + if (twait > thiz && (sdrt->tDS_min > twait - thiz) && + (tset_mem < sdrt->tDS_min - (twait - thiz))) + tset_mem = sdrt->tDS_min - (twait - thiz); + tims->tset_mem = DIV_ROUND_UP(tset_mem, hclkp); + if (tims->tset_mem == 0) + tims->tset_mem = 1; + else if (tims->tset_mem > FMC2_PMEM_PATT_TIMING_MASK) + tims->tset_mem = FMC2_PMEM_PATT_TIMING_MASK; + + /* + * tHOLD_MEM > tCH + * tHOLD_MEM > tREH - tSETUP_MEM + * tHOLD_MEM > max(tRC, tWC) - (tSETUP_MEM + tWAIT) + */ + thold_mem = hclkp; + if (thold_mem < sdrt->tCH_min) + thold_mem = sdrt->tCH_min; + if (sdrt->tREH_min > tset_mem && + (thold_mem < sdrt->tREH_min - tset_mem)) + thold_mem = sdrt->tREH_min - tset_mem; + if ((sdrt->tRC_min > tset_mem + twait) && + (thold_mem < sdrt->tRC_min - (tset_mem + twait))) + thold_mem = sdrt->tRC_min - (tset_mem + twait); + if ((sdrt->tWC_min > tset_mem + twait) && + (thold_mem < sdrt->tWC_min - (tset_mem + twait))) + thold_mem = sdrt->tWC_min - (tset_mem + twait); + tims->thold_mem = DIV_ROUND_UP(thold_mem, hclkp); + if (tims->thold_mem == 0) + tims->thold_mem = 1; + else if (tims->thold_mem > FMC2_PMEM_PATT_TIMING_MASK) + tims->thold_mem = FMC2_PMEM_PATT_TIMING_MASK; + + /* + * tSETUP_ATT > tCS - tWAIT + * tSETUP_ATT > tCLS - tWAIT + * tSETUP_ATT > tALS - tWAIT + * tSETUP_ATT > tRHW - tHOLD_MEM + * tSETUP_ATT > tDS - (tWAIT - tHIZ) + */ + tset_att = hclkp; + if (sdrt->tCS_min > twait && (tset_att < sdrt->tCS_min - twait)) + tset_att = sdrt->tCS_min - twait; + if (sdrt->tCLS_min > twait && (tset_att < sdrt->tCLS_min - twait)) + tset_att = sdrt->tCLS_min - twait; + if (sdrt->tALS_min > twait && (tset_att < sdrt->tALS_min - twait)) + tset_att = sdrt->tALS_min - twait; + if (sdrt->tRHW_min > thold_mem && + (tset_att < sdrt->tRHW_min - thold_mem)) + tset_att = sdrt->tRHW_min - thold_mem; + if (twait > thiz && (sdrt->tDS_min > twait - thiz) && + (tset_att < sdrt->tDS_min - (twait - thiz))) + tset_att = sdrt->tDS_min - (twait - thiz); + tims->tset_att = DIV_ROUND_UP(tset_att, hclkp); + if (tims->tset_att == 0) + tims->tset_att = 1; + else if (tims->tset_att > FMC2_PMEM_PATT_TIMING_MASK) + tims->tset_att = FMC2_PMEM_PATT_TIMING_MASK; + + /* + * tHOLD_ATT > tALH + * tHOLD_ATT > tCH + * tHOLD_ATT > tCLH + * tHOLD_ATT > tCOH + * tHOLD_ATT > tDH + * tHOLD_ATT > tWB + tIO + tSYNC - tSETUP_MEM + * tHOLD_ATT > tADL - tSETUP_MEM + * tHOLD_ATT > tWH - tSETUP_MEM + * tHOLD_ATT > tWHR - tSETUP_MEM + * tHOLD_ATT > tRC - (tSETUP_ATT + tWAIT) + * tHOLD_ATT > tWC - (tSETUP_ATT + tWAIT) + */ + thold_att = hclkp; + if (thold_att < sdrt->tALH_min) + thold_att = sdrt->tALH_min; + if (thold_att < sdrt->tCH_min) + thold_att = sdrt->tCH_min; + if (thold_att < sdrt->tCLH_min) + thold_att = sdrt->tCLH_min; + if (thold_att < sdrt->tCOH_min) + thold_att = sdrt->tCOH_min; + if (thold_att < sdrt->tDH_min) + thold_att = sdrt->tDH_min; + if ((sdrt->tWB_max + FMC2_TIO + FMC2_TSYNC > tset_mem) && + (thold_att < sdrt->tWB_max + FMC2_TIO + FMC2_TSYNC - tset_mem)) + thold_att = sdrt->tWB_max + FMC2_TIO + FMC2_TSYNC - tset_mem; + if (sdrt->tADL_min > tset_mem && + (thold_att < sdrt->tADL_min - tset_mem)) + thold_att = sdrt->tADL_min - tset_mem; + if (sdrt->tWH_min > tset_mem && + (thold_att < sdrt->tWH_min - tset_mem)) + thold_att = sdrt->tWH_min - tset_mem; + if (sdrt->tWHR_min > tset_mem && + (thold_att < sdrt->tWHR_min - tset_mem)) + thold_att = sdrt->tWHR_min - tset_mem; + if ((sdrt->tRC_min > tset_att + twait) && + (thold_att < sdrt->tRC_min - (tset_att + twait))) + thold_att = sdrt->tRC_min - (tset_att + twait); + if ((sdrt->tWC_min > tset_att + twait) && + (thold_att < sdrt->tWC_min - (tset_att + twait))) + thold_att = sdrt->tWC_min - (tset_att + twait); + tims->thold_att = DIV_ROUND_UP(thold_att, hclkp); + if (tims->thold_att == 0) + tims->thold_att = 1; + else if (tims->thold_att > FMC2_PMEM_PATT_TIMING_MASK) + tims->thold_att = FMC2_PMEM_PATT_TIMING_MASK; +} + +static int stm32_fmc2_setup_interface(struct mtd_info *mtd, int chipnr, + const struct nand_data_interface *conf) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + const struct nand_sdr_timings *sdrt; + + sdrt = nand_get_sdr_timings(conf); + if (IS_ERR(sdrt)) + return PTR_ERR(sdrt); + + if (chipnr == NAND_DATA_IFACE_CHECK_ONLY) + return 0; + + stm32_fmc2_calc_timings(chip, sdrt); + + /* Apply timings */ + stm32_fmc2_timings_init(chip); + + return 0; +} + +/* NAND callbacks setup */ +static void stm32_fmc2_nand_callbacks_setup(struct nand_chip *chip) +{ + chip->ecc.hwctl = stm32_fmc2_hwctl; + + /* + * Specific callbacks to read/write a page depending on + * the algo used (Hamming, BCH). + */ + if (chip->ecc.strength == FMC2_ECC_HAM) { + /* Hamming is used */ + chip->ecc.calculate = stm32_fmc2_ham_calculate; + chip->ecc.correct = stm32_fmc2_ham_correct; + chip->ecc.bytes = chip->options & NAND_BUSWIDTH_16 ? 4 : 3; + chip->ecc.options |= NAND_ECC_GENERIC_ERASED_CHECK; + return; + } + + /* BCH is used */ + chip->ecc.read_page = stm32_fmc2_read_page; + chip->ecc.calculate = stm32_fmc2_bch_calculate; + chip->ecc.correct = stm32_fmc2_bch_correct; + + if (chip->ecc.strength == FMC2_ECC_BCH8) + chip->ecc.bytes = chip->options & NAND_BUSWIDTH_16 ? 14 : 13; + else + chip->ecc.bytes = chip->options & NAND_BUSWIDTH_16 ? 8 : 7; +} + +/* FMC2 caps */ +static int stm32_fmc2_calc_ecc_bytes(int step_size, int strength) +{ + /* Hamming */ + if (strength == FMC2_ECC_HAM) + return 4; + + /* BCH8 */ + if (strength == FMC2_ECC_BCH8) + return 14; + + /* BCH4 */ + return 8; +} + +NAND_ECC_CAPS_SINGLE(stm32_fmc2_ecc_caps, stm32_fmc2_calc_ecc_bytes, + FMC2_ECC_STEP_SIZE, + FMC2_ECC_HAM, FMC2_ECC_BCH4, FMC2_ECC_BCH8); + +/* FMC2 probe */ +static int stm32_fmc2_parse_child(struct stm32_fmc2_nfc *fmc2, + ofnode node) +{ + struct stm32_fmc2_nand *nand = &fmc2->nand; + u32 cs[FMC2_MAX_CE]; + int ret, i; + + if (!ofnode_get_property(node, "reg", &nand->ncs)) + return -EINVAL; + + nand->ncs /= sizeof(u32); + if (!nand->ncs) { + pr_err("Invalid reg property size\n"); + return -EINVAL; + } + + ret = ofnode_read_u32_array(node, "reg", cs, nand->ncs); + if (ret < 0) { + pr_err("Could not retrieve reg property\n"); + return -EINVAL; + } + + for (i = 0; i < nand->ncs; i++) { + if (cs[i] > FMC2_MAX_CE) { + pr_err("Invalid reg value: %d\n", + nand->cs_used[i]); + return -EINVAL; + } + + if (fmc2->cs_assigned & BIT(cs[i])) { + pr_err("Cs already assigned: %d\n", + nand->cs_used[i]); + return -EINVAL; + } + + fmc2->cs_assigned |= BIT(cs[i]); + nand->cs_used[i] = cs[i]; + } + + nand->chip.flash_node = ofnode_to_offset(node); + + return 0; +} + +static int stm32_fmc2_parse_dt(struct udevice *dev, + struct stm32_fmc2_nfc *fmc2) +{ + ofnode child; + int ret, nchips = 0; + + dev_for_each_subnode(child, dev) + nchips++; + + if (!nchips) { + pr_err("NAND chip not defined\n"); + return -EINVAL; + } + + if (nchips > 1) { + pr_err("Too many NAND chips defined\n"); + return -EINVAL; + } + + dev_for_each_subnode(child, dev) { + ret = stm32_fmc2_parse_child(fmc2, child); + if (ret) + return ret; + } + + return 0; +} + +static int stm32_fmc2_probe(struct udevice *dev) +{ + struct stm32_fmc2_nfc *fmc2 = dev_get_priv(dev); + struct stm32_fmc2_nand *nand = &fmc2->nand; + struct nand_chip *chip = &nand->chip; + struct mtd_info *mtd = &chip->mtd; + struct nand_ecclayout *ecclayout; + struct resource resource; + struct reset_ctl reset; + int oob_index, chip_cs, mem_region, ret, i; + + spin_lock_init(&fmc2->controller.lock); + init_waitqueue_head(&fmc2->controller.wq); + + ret = stm32_fmc2_parse_dt(dev, fmc2); + if (ret) + return ret; + + /* Get resources */ + ret = dev_read_resource(dev, 0, &resource); + if (ret) { + pr_err("Resource io_base not found"); + return ret; + } + fmc2->io_base = (void __iomem *)resource.start; + + for (chip_cs = 0, mem_region = 1; chip_cs < FMC2_MAX_CE; + chip_cs++, mem_region += 3) { + if (!(fmc2->cs_assigned & BIT(chip_cs))) + continue; + + ret = dev_read_resource(dev, mem_region, &resource); + if (ret) { + pr_err("Resource data_base not found for cs%d", + chip_cs); + return ret; + } + fmc2->data_base[chip_cs] = (void __iomem *)resource.start; + + ret = dev_read_resource(dev, mem_region + 1, &resource); + if (ret) { + pr_err("Resource cmd_base not found for cs%d", + chip_cs); + return ret; + } + fmc2->cmd_base[chip_cs] = (void __iomem *)resource.start; + + ret = dev_read_resource(dev, mem_region + 2, &resource); + if (ret) { + pr_err("Resource addr_base not found for cs%d", + chip_cs); + return ret; + } + fmc2->addr_base[chip_cs] = (void __iomem *)resource.start; + } + + /* Enable the clock */ + ret = clk_get_by_index(dev, 0, &fmc2->clk); + if (ret) + return ret; + + ret = clk_enable(&fmc2->clk); + if (ret) + return ret; + + /* Reset */ + ret = reset_get_by_index(dev, 0, &reset); + if (!ret) { + reset_assert(&reset); + udelay(2); + reset_deassert(&reset); + } + + /* FMC2 init routine */ + stm32_fmc2_init(fmc2); + + chip->controller = &fmc2->base; + chip->select_chip = stm32_fmc2_select_chip; + chip->setup_data_interface = stm32_fmc2_setup_interface; + chip->cmd_ctrl = stm32_fmc2_cmd_ctrl; + chip->chip_delay = FMC2_RB_DELAY_US; + chip->options |= NAND_BUSWIDTH_AUTO | NAND_NO_SUBPAGE_WRITE | + NAND_USE_BOUNCE_BUFFER; + + /* Default ECC settings */ + chip->ecc.mode = NAND_ECC_HW; + chip->ecc.size = FMC2_ECC_STEP_SIZE; + chip->ecc.strength = FMC2_ECC_BCH8; + + /* Scan to find existence of the device */ + ret = nand_scan_ident(mtd, nand->ncs, NULL); + if (ret) + return ret; + + /* + * Only NAND_ECC_HW mode is actually supported + * Hamming => ecc.strength = 1 + * BCH4 => ecc.strength = 4 + * BCH8 => ecc.strength = 8 + * ECC sector size = 512 + */ + if (chip->ecc.mode != NAND_ECC_HW) { + pr_err("Nand_ecc_mode is not well defined in the DT\n"); + return -EINVAL; + } + + ret = nand_check_ecc_caps(chip, &stm32_fmc2_ecc_caps, + mtd->oobsize - FMC2_BBM_LEN); + if (ret) { + pr_err("No valid ECC settings set\n"); + return ret; + } + + if (chip->bbt_options & NAND_BBT_USE_FLASH) + chip->bbt_options |= NAND_BBT_NO_OOB; + + /* NAND callbacks setup */ + stm32_fmc2_nand_callbacks_setup(chip); + + /* Define ECC layout */ + ecclayout = &fmc2->ecclayout; + ecclayout->eccbytes = chip->ecc.bytes * + (mtd->writesize / chip->ecc.size); + oob_index = FMC2_BBM_LEN; + for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) + ecclayout->eccpos[i] = oob_index; + ecclayout->oobfree->offset = oob_index; + ecclayout->oobfree->length = mtd->oobsize - ecclayout->oobfree->offset; + chip->ecc.layout = ecclayout; + + /* Configure bus width to 16-bit */ + if (chip->options & NAND_BUSWIDTH_16) + stm32_fmc2_set_buswidth_16(fmc2, true); + + /* Scan the device to fill MTD data-structures */ + ret = nand_scan_tail(mtd); + if (ret) + return ret; + + return nand_register(0, mtd); +} + +static const struct udevice_id stm32_fmc2_match[] = { + { .compatible = "st,stm32mp15-fmc2" }, + { /* Sentinel */ } +}; + +U_BOOT_DRIVER(stm32_fmc2_nand) = { + .name = "stm32_fmc2_nand", + .id = UCLASS_MTD, + .of_match = stm32_fmc2_match, + .probe = stm32_fmc2_probe, + .priv_auto_alloc_size = sizeof(struct stm32_fmc2_nfc), +}; + +void board_nand_init(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_MTD, + DM_GET_DRIVER(stm32_fmc2_nand), + &dev); + if (ret && ret != -ENODEV) + pr_err("Failed to initialize STM32 FMC2 NAND controller. (error %d)\n", + ret); +} diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c index 0bade208084..3681c5eed9a 100644 --- a/drivers/mtd/nand/spi/gigadevice.c +++ b/drivers/mtd/nand/spi/gigadevice.c @@ -12,12 +12,11 @@ #endif #include <linux/mtd/spinand.h> -#define SPINAND_MFR_GIGADEVICE 0xc8 +#define SPINAND_MFR_GIGADEVICE 0xC8 +#define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4) +#define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4) -#define GIGADEVICE_STATUS_ECC_MASK GENMASK(5, 4) -#define GIGADEVICE_STATUS_ECC_NO_BITFLIPS (0 << 4) -#define GIGADEVICE_STATUS_ECC_1TO7_BITFLIPS (1 << 4) -#define GIGADEVICE_STATUS_ECC_8_BITFLIPS (3 << 4) +#define GD5FXGQ4XEXXG_REG_STATUS2 0xf0 static SPINAND_OP_VARIANTS(read_cache_variants, SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), @@ -35,8 +34,8 @@ static SPINAND_OP_VARIANTS(update_cache_variants, SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), SPINAND_PROG_LOAD(false, 0, NULL, 0)); -static int gd5f1gq4u_ooblayout_ecc(struct mtd_info *mtd, int section, - struct mtd_oob_region *region) +static int gd5fxgq4xexxg_ooblayout_ecc(struct mtd_info *mtd, int section, + struct mtd_oob_region *region) { if (section) return -ERANGE; @@ -47,38 +46,49 @@ static int gd5f1gq4u_ooblayout_ecc(struct mtd_info *mtd, int section, return 0; } -static int gd5f1gq4u_ooblayout_free(struct mtd_info *mtd, int section, - struct mtd_oob_region *region) +static int gd5fxgq4xexxg_ooblayout_free(struct mtd_info *mtd, int section, + struct mtd_oob_region *region) { if (section) return -ERANGE; - /* Reserve 2 bytes for the BBM. */ - region->offset = 2; - region->length = 62; + /* Reserve 1 bytes for the BBM. */ + region->offset = 1; + region->length = 63; return 0; } -static const struct mtd_ooblayout_ops gd5f1gq4u_ooblayout = { - .ecc = gd5f1gq4u_ooblayout_ecc, - .free = gd5f1gq4u_ooblayout_free, -}; - -static int gd5f1gq4u_ecc_get_status(struct spinand_device *spinand, - u8 status) +static int gd5fxgq4xexxg_ecc_get_status(struct spinand_device *spinand, + u8 status) { - if (status) - debug("%s (%d): status=%02x\n", __func__, __LINE__, status); + u8 status2; + struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQ4XEXXG_REG_STATUS2, + &status2); + int ret; - switch (status & GIGADEVICE_STATUS_ECC_MASK) { + switch (status & STATUS_ECC_MASK) { case STATUS_ECC_NO_BITFLIPS: return 0; - case GIGADEVICE_STATUS_ECC_1TO7_BITFLIPS: - return 7; - - case GIGADEVICE_STATUS_ECC_8_BITFLIPS: + case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS: + /* + * Read status2 register to determine a more fine grained + * bit error status + */ + ret = spi_mem_exec_op(spinand->slave, &op); + if (ret) + return ret; + + /* + * 4 ... 7 bits are flipped (1..4 can't be detected, so + * report the maximum of 4 in this case + */ + /* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */ + return ((status & STATUS_ECC_MASK) >> 2) | + ((status2 & STATUS_ECC_MASK) >> 4); + + case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS: return 8; case STATUS_ECC_UNCOR_ERROR: @@ -91,16 +101,21 @@ static int gd5f1gq4u_ecc_get_status(struct spinand_device *spinand, return -EINVAL; } +static const struct mtd_ooblayout_ops gd5fxgq4xexxg_ooblayout = { + .ecc = gd5fxgq4xexxg_ooblayout_ecc, + .free = gd5fxgq4xexxg_ooblayout_free, +}; + static const struct spinand_info gigadevice_spinand_table[] = { - SPINAND_INFO("GD5F1GQ4UC", 0xd1, + SPINAND_INFO("GD5F1GQ4UExxG", 0xd1, NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), - NAND_ECCREQ(8, 2048), + NAND_ECCREQ(8, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&gd5f1gq4u_ooblayout, - gd5f1gq4u_ecc_get_status)), + SPINAND_ECCINFO(&gd5fxgq4xexxg_ooblayout, + gd5fxgq4xexxg_ecc_get_status)), }; static int gigadevice_spinand_detect(struct spinand_device *spinand) @@ -109,8 +124,8 @@ static int gigadevice_spinand_detect(struct spinand_device *spinand) int ret; /* - * Gigadevice SPI NAND read ID need a dummy byte, - * so the first byte in raw_id is dummy. + * For GD NANDs, There is an address byte needed to shift in before IDs + * are read out, so the first byte in raw_id is dummy. */ if (id[1] != SPINAND_MFR_GIGADEVICE) return 0; diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig index 5671bca24a0..d3b007a731d 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -62,6 +62,9 @@ config SF_DEFAULT_MODE The default mode may be provided by the platform to handle the common case when only a single serial flash is present on the system. + Not used for boot with device tree; the SPI driver reads + speed and mode from platdata values computed from + available node. config SF_DEFAULT_SPEED int "SPI Flash default speed in Hz" @@ -71,6 +74,9 @@ config SF_DEFAULT_SPEED The default speed may be provided by the platform to handle the common case when only a single serial flash is present on the system. + Not used for boot with device tree; the SPI driver reads + speed and mode from platdata values computed from + available node. if SPI_FLASH diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 7f1378f4946..73297e1a0a5 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -166,7 +166,6 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = { }; static const struct udevice_id spi_flash_std_ids[] = { - { .compatible = "spi-flash" }, { .compatible = "jedec,spi-nor" }, { } }; diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index b7f07338779..c4e2f6a08fa 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -524,8 +524,11 @@ static int read_bar(struct spi_nor *nor, const struct flash_info *info) */ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) { - u8 buf[SPI_NOR_MAX_ADDR_WIDTH]; - int i; + struct spi_mem_op op = + SPI_MEM_OP(SPI_MEM_OP_CMD(nor->erase_opcode, 1), + SPI_MEM_OP_ADDR(nor->addr_width, addr, 1), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_NO_DATA); if (nor->erase) return nor->erase(nor, addr); @@ -534,12 +537,7 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) * Default implementation, if driver doesn't have a specialized HW * control */ - for (i = nor->addr_width - 1; i >= 0; i--) { - buf[i] = addr & 0xff; - addr >>= 8; - } - - return nor->write_reg(nor, nor->erase_opcode, buf, nor->addr_width); + return spi_mem_exec_op(nor->spi, &op); } /* diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c index 3215e2431dc..ec929760eee 100644 --- a/drivers/mtd/spi/spi-nor-ids.c +++ b/drivers/mtd/spi/spi-nor-ids.c @@ -106,6 +106,11 @@ const struct flash_info spi_nor_ids[] = { SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, + { + INFO("gd25lq128", 0xc86018, 0, 64 * 1024, 256, + SECT_4K | SPI_NOR_DUAL_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, #endif #ifdef CONFIG_SPI_FLASH_ISSI /* ISSI */ /* ISSI */ @@ -142,6 +147,7 @@ const struct flash_info spi_nor_ids[] = { { INFO("mx25l25655e", 0xc22619, 0, 64 * 1024, 512, 0) }, { INFO("mx66l51235l", 0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, { INFO("mx66u51235f", 0xc2253a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, + { INFO("mx66u2g45g", 0xc2253c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, { INFO("mx66l1g45g", 0xc2201b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { INFO("mx25l1633e", 0xc22415, 0, 64 * 1024, 32, SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | SECT_4K) }, #endif @@ -187,6 +193,7 @@ const struct flash_info spi_nor_ids[] = { { INFO("s25fl116k", 0x014015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { INFO("s25fl164k", 0x014017, 0, 64 * 1024, 128, SECT_4K) }, { INFO("s25fl208k", 0x014014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ) }, + { INFO("s25fl064l", 0x016017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, { INFO("s25fl128l", 0x016018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, #endif #ifdef CONFIG_SPI_FLASH_SST /* SST */ diff --git a/drivers/net/ag7xxx.c b/drivers/net/ag7xxx.c index 8146c3170e1..7f1dee4b3e4 100644 --- a/drivers/net/ag7xxx.c +++ b/drivers/net/ag7xxx.c @@ -3,6 +3,7 @@ * Atheros AR71xx / AR9xxx GMAC driver * * Copyright (C) 2016 Marek Vasut <marex@denx.de> + * Copyright (C) 2019 Rosy Song <rosysong@rosinson.com> */ #include <common.h> @@ -23,6 +24,8 @@ DECLARE_GLOBAL_DATA_PTR; enum ag7xxx_model { AG7XXX_MODEL_AG933X, AG7XXX_MODEL_AG934X, + AG7XXX_MODEL_AG953X, + AG7XXX_MODEL_AG956X }; /* MAC Configuration 1 */ @@ -99,8 +102,29 @@ enum ag7xxx_model { /* Rx Status */ #define AG7XXX_ETH_DMA_RX_STATUS 0x194 +/* Custom register at 0x1805002C */ +#define AG7XXX_ETH_XMII 0x2C +#define AG7XXX_ETH_XMII_TX_INVERT BIT(31) +#define AG7XXX_ETH_XMII_RX_DELAY_LSB 28 +#define AG7XXX_ETH_XMII_RX_DELAY_MASK 0x30000000 +#define AG7XXX_ETH_XMII_RX_DELAY_SET(x) \ + (((x) << AG7XXX_ETH_XMII_RX_DELAY_LSB) & AG7XXX_ETH_XMII_RX_DELAY_MASK) +#define AG7XXX_ETH_XMII_TX_DELAY_LSB 26 +#define AG7XXX_ETH_XMII_TX_DELAY_MASK 0x0c000000 +#define AG7XXX_ETH_XMII_TX_DELAY_SET(x) \ + (((x) << AG7XXX_ETH_XMII_TX_DELAY_LSB) & AG7XXX_ETH_XMII_TX_DELAY_MASK) +#define AG7XXX_ETH_XMII_GIGE BIT(25) + /* Custom register at 0x18070000 */ #define AG7XXX_GMAC_ETH_CFG 0x00 +#define AG7XXX_ETH_CFG_RXDV_DELAY_LSB 16 +#define AG7XXX_ETH_CFG_RXDV_DELAY_MASK 0x00030000 +#define AG7XXX_ETH_CFG_RXDV_DELAY_SET(x) \ + (((x) << AG7XXX_ETH_CFG_RXDV_DELAY_LSB) & AG7XXX_ETH_CFG_RXDV_DELAY_MASK) +#define AG7XXX_ETH_CFG_RXD_DELAY_LSB 14 +#define AG7XXX_ETH_CFG_RXD_DELAY_MASK 0x0000c000 +#define AG7XXX_ETH_CFG_RXD_DELAY_SET(x) \ + (((x) << AG7XXX_ETH_CFG_RXD_DELAY_LSB) & AG7XXX_ETH_CFG_RXD_DELAY_MASK) #define AG7XXX_ETH_CFG_SW_PHY_ADDR_SWAP BIT(8) #define AG7XXX_ETH_CFG_SW_PHY_SWAP BIT(7) #define AG7XXX_ETH_CFG_SW_ONLY_MODE BIT(6) @@ -197,24 +221,33 @@ static int ag7xxx_switch_reg_read(struct mii_dev *bus, int reg, u32 *val) u32 reg_addr; u32 phy_temp; u32 reg_temp; + u32 reg_temp_w = (reg & 0xfffffffc) >> 1; u16 rv = 0; int ret; - if (priv->model == AG7XXX_MODEL_AG933X) { + if (priv->model == AG7XXX_MODEL_AG933X || + priv->model == AG7XXX_MODEL_AG953X) { phy_addr = 0x1f; reg_addr = 0x10; - } else if (priv->model == AG7XXX_MODEL_AG934X) { + } else if (priv->model == AG7XXX_MODEL_AG934X || + priv->model == AG7XXX_MODEL_AG956X) { phy_addr = 0x18; reg_addr = 0x00; } else return -EINVAL; - ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, reg >> 9); + if (priv->model == AG7XXX_MODEL_AG956X) + ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, (reg >> 9) & 0x1ff); + else + ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, reg >> 9); if (ret) return ret; phy_temp = ((reg >> 6) & 0x7) | 0x10; - reg_temp = (reg >> 1) & 0x1e; + if (priv->model == AG7XXX_MODEL_AG956X) + reg_temp = reg_temp_w & 0x1f; + else + reg_temp = (reg >> 1) & 0x1e; *val = 0; ret = ag7xxx_switch_read(bus, phy_temp, reg_temp | 0, &rv); @@ -222,7 +255,13 @@ static int ag7xxx_switch_reg_read(struct mii_dev *bus, int reg, u32 *val) return ret; *val |= rv; - ret = ag7xxx_switch_read(bus, phy_temp, reg_temp | 1, &rv); + if (priv->model == AG7XXX_MODEL_AG956X) { + phy_temp = (((reg_temp_w + 1) >> 5) & 0x7) | 0x10; + reg_temp = (reg_temp_w + 1) & 0x1f; + ret = ag7xxx_switch_read(bus, phy_temp, reg_temp, &rv); + } else { + ret = ag7xxx_switch_read(bus, phy_temp, reg_temp | 1, &rv); + } if (ret < 0) return ret; *val |= (rv << 16); @@ -237,23 +276,34 @@ static int ag7xxx_switch_reg_write(struct mii_dev *bus, int reg, u32 val) u32 reg_addr; u32 phy_temp; u32 reg_temp; + u32 reg_temp_w = (reg & 0xfffffffc) >> 1; int ret; - if (priv->model == AG7XXX_MODEL_AG933X) { + if (priv->model == AG7XXX_MODEL_AG933X || + priv->model == AG7XXX_MODEL_AG953X) { phy_addr = 0x1f; reg_addr = 0x10; - } else if (priv->model == AG7XXX_MODEL_AG934X) { + } else if (priv->model == AG7XXX_MODEL_AG934X || + priv->model == AG7XXX_MODEL_AG956X) { phy_addr = 0x18; reg_addr = 0x00; } else return -EINVAL; - ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, reg >> 9); + if (priv->model == AG7XXX_MODEL_AG956X) + ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, (reg >> 9) & 0x1ff); + else + ret = ag7xxx_switch_write(bus, phy_addr, reg_addr, reg >> 9); if (ret) return ret; - phy_temp = ((reg >> 6) & 0x7) | 0x10; - reg_temp = (reg >> 1) & 0x1e; + if (priv->model == AG7XXX_MODEL_AG956X) { + reg_temp = (reg_temp_w + 1) & 0x1f; + phy_temp = (((reg_temp_w + 1) >> 5) & 0x7) | 0x10; + } else { + phy_temp = ((reg >> 6) & 0x7) | 0x10; + reg_temp = (reg >> 1) & 0x1e; + } /* * The switch on AR933x has some special register behavior, which @@ -272,10 +322,18 @@ static int ag7xxx_switch_reg_write(struct mii_dev *bus, int reg, u32 val) if (ret < 0) return ret; } else { - ret = ag7xxx_switch_write(bus, phy_temp, reg_temp | 1, val >> 16); + if (priv->model == AG7XXX_MODEL_AG956X) + ret = ag7xxx_switch_write(bus, phy_temp, reg_temp, val >> 16); + else + ret = ag7xxx_switch_write(bus, phy_temp, reg_temp | 1, val >> 16); if (ret < 0) return ret; + if (priv->model == AG7XXX_MODEL_AG956X) { + phy_temp = ((reg_temp_w >> 5) & 0x7) | 0x10; + reg_temp = reg_temp_w & 0x1f; + } + ret = ag7xxx_switch_write(bus, phy_temp, reg_temp | 0, val & 0xffff); if (ret < 0) return ret; @@ -598,10 +656,19 @@ static int ag7xxx_mii_setup(struct udevice *dev) return 0; } - if (priv->model == AG7XXX_MODEL_AG934X) { - writel(AG7XXX_ETH_MII_MGMT_CFG_RESET | 0x4, + if (priv->model == AG7XXX_MODEL_AG934X) + reg = 0x4; + else if (priv->model == AG7XXX_MODEL_AG953X) + reg = 0x2; + else if (priv->model == AG7XXX_MODEL_AG956X) + reg = 0x7; + + if (priv->model == AG7XXX_MODEL_AG934X || + priv->model == AG7XXX_MODEL_AG953X || + priv->model == AG7XXX_MODEL_AG956X) { + writel(AG7XXX_ETH_MII_MGMT_CFG_RESET | reg, priv->regs + AG7XXX_ETH_MII_MGMT_CFG); - writel(0x4, priv->regs + AG7XXX_ETH_MII_MGMT_CFG); + writel(reg, priv->regs + AG7XXX_ETH_MII_MGMT_CFG); return 0; } @@ -698,14 +765,126 @@ static int ag933x_phy_setup_lan(struct udevice *dev) return 0; } +static int ag953x_phy_setup_wan(struct udevice *dev) +{ + int ret; + u32 reg = 0; + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + + /* Set wan port connect to GE0 */ + ret = ag7xxx_switch_reg_read(priv->bus, 0x8, ®); + if (ret) + return ret; + + ret = ag7xxx_switch_reg_write(priv->bus, 0x8, reg | BIT(28)); + if (ret) + return ret; + + /* Configure switch port 4 (GMAC0) */ + ret = ag7xxx_switch_write(priv->bus, 4, MII_BMCR, 0x9000); + if (ret) + return ret; + + return 0; +} + +static int ag953x_phy_setup_lan(struct udevice *dev) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + int i, ret; + u32 reg = 0; + + /* Reset the switch */ + ret = ag7xxx_switch_reg_read(priv->bus, 0, ®); + if (ret) + return ret; + + ret = ag7xxx_switch_reg_write(priv->bus, 0, reg | BIT(31)); + if (ret) + return ret; + + do { + ret = ag7xxx_switch_reg_read(priv->bus, 0, ®); + if (ret) + return ret; + } while (reg & BIT(31)); + + ret = ag7xxx_switch_reg_write(priv->bus, 0x100, 0x4e); + if (ret) + return ret; + + /* Set GMII mode */ + ret = ag7xxx_switch_reg_read(priv->bus, 0x4, ®); + if (ret) + return ret; + + ret = ag7xxx_switch_reg_write(priv->bus, 0x4, reg | BIT(6)); + if (ret) + return ret; + + /* Configure switch ports 0...4 (GMAC1) */ + for (i = 0; i < 5; i++) { + ret = ag7xxx_switch_write(priv->bus, i, MII_BMCR, 0x9000); + if (ret) + return ret; + } + + for (i = 0; i < 5; i++) { + ret = ag7xxx_switch_reg_write(priv->bus, (i + 2) * 0x100, BIT(9)); + if (ret) + return ret; + } + + /* QM Control */ + ret = ag7xxx_switch_reg_write(priv->bus, 0x38, 0xc000050e); + if (ret) + return ret; + + /* Disable Atheros header */ + ret = ag7xxx_switch_reg_write(priv->bus, 0x104, 0x4004); + if (ret) + return ret; + + /* Tag priority mapping */ + ret = ag7xxx_switch_reg_write(priv->bus, 0x70, 0xfa50); + if (ret) + return ret; + + /* Enable ARP packets to the CPU */ + ret = ag7xxx_switch_reg_read(priv->bus, 0x5c, ®); + if (ret) + return ret; + + ret = ag7xxx_switch_reg_write(priv->bus, 0x5c, reg | 0x100000); + if (ret) + return ret; + + /* Enable broadcast packets to the CPU */ + ret = ag7xxx_switch_reg_read(priv->bus, 0x2c, ®); + if (ret) + return ret; + + ret = ag7xxx_switch_reg_write(priv->bus, 0x2c, reg | BIT(25) | BIT(26)); + if (ret) + return ret; + + return 0; +} + static int ag933x_phy_setup_reset_set(struct udevice *dev, int port) { struct ar7xxx_eth_priv *priv = dev_get_priv(dev); int ret; - ret = ag7xxx_mdio_write(priv->bus, port, 0, MII_ADVERTISE, - ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | - ADVERTISE_PAUSE_ASYM); + if (priv->model == AG7XXX_MODEL_AG953X || + priv->model == AG7XXX_MODEL_AG956X) { + ret = ag7xxx_switch_write(priv->bus, port, MII_ADVERTISE, + ADVERTISE_ALL); + } else { + ret = ag7xxx_mdio_write(priv->bus, port, 0, MII_ADVERTISE, + ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | + ADVERTISE_PAUSE_ASYM); + } if (ret) return ret; @@ -714,8 +893,18 @@ static int ag933x_phy_setup_reset_set(struct udevice *dev, int port) ADVERTISE_1000FULL); if (ret) return ret; + } else if (priv->model == AG7XXX_MODEL_AG956X) { + ret = ag7xxx_switch_write(priv->bus, port, MII_CTRL1000, + ADVERTISE_1000FULL); + if (ret) + return ret; } + if (priv->model == AG7XXX_MODEL_AG953X || + priv->model == AG7XXX_MODEL_AG956X) + return ag7xxx_switch_write(priv->bus, port, MII_BMCR, + BMCR_ANENABLE | BMCR_RESET); + return ag7xxx_mdio_write(priv->bus, port, 0, MII_BMCR, BMCR_ANENABLE | BMCR_RESET); } @@ -724,13 +913,24 @@ static int ag933x_phy_setup_reset_fin(struct udevice *dev, int port) { struct ar7xxx_eth_priv *priv = dev_get_priv(dev); int ret; + u16 reg; - do { - ret = ag7xxx_mdio_read(priv->bus, port, 0, MII_BMCR); - if (ret < 0) - return ret; - mdelay(10); - } while (ret & BMCR_RESET); + if (priv->model == AG7XXX_MODEL_AG953X || + priv->model == AG7XXX_MODEL_AG956X) { + do { + ret = ag7xxx_switch_read(priv->bus, port, MII_BMCR, ®); + if (ret < 0) + return ret; + mdelay(10); + } while (reg & BMCR_RESET); + } else { + do { + ret = ag7xxx_mdio_read(priv->bus, port, 0, MII_BMCR); + if (ret < 0) + return ret; + mdelay(10); + } while (ret & BMCR_RESET); + } return 0; } @@ -739,10 +939,13 @@ static int ag933x_phy_setup_common(struct udevice *dev) { struct ar7xxx_eth_priv *priv = dev_get_priv(dev); int i, ret, phymax; + u16 reg; if (priv->model == AG7XXX_MODEL_AG933X) phymax = 4; - else if (priv->model == AG7XXX_MODEL_AG934X) + else if (priv->model == AG7XXX_MODEL_AG934X || + priv->model == AG7XXX_MODEL_AG953X || + priv->model == AG7XXX_MODEL_AG956X) phymax = 5; else return -EINVAL; @@ -757,7 +960,10 @@ static int ag933x_phy_setup_common(struct udevice *dev) return ret; /* Read out link status */ - ret = ag7xxx_mdio_read(priv->bus, phymax, 0, MII_MIPSCR); + if (priv->model == AG7XXX_MODEL_AG953X) + ret = ag7xxx_switch_read(priv->bus, phymax, MII_MIPSCR, ®); + else + ret = ag7xxx_mdio_read(priv->bus, phymax, 0, MII_MIPSCR); if (ret < 0) return ret; @@ -779,7 +985,11 @@ static int ag933x_phy_setup_common(struct udevice *dev) for (i = 0; i < phymax; i++) { /* Read out link status */ - ret = ag7xxx_mdio_read(priv->bus, i, 0, MII_MIPSCR); + if (priv->model == AG7XXX_MODEL_AG953X || + priv->model == AG7XXX_MODEL_AG956X) + ret = ag7xxx_switch_read(priv->bus, i, MII_MIPSCR, ®); + else + ret = ag7xxx_mdio_read(priv->bus, i, 0, MII_MIPSCR); if (ret < 0) return ret; } @@ -841,6 +1051,63 @@ static int ag934x_phy_setup(struct udevice *dev) return 0; } +static int ag956x_phy_setup(struct udevice *dev) +{ + struct ar7xxx_eth_priv *priv = dev_get_priv(dev); + int i, ret; + u32 reg, ctrl; + + ret = ag7xxx_switch_reg_read(priv->bus, 0x0, ®); + if (ret) + return ret; + if ((reg & 0xffff) >= 0x1301) + ctrl = 0xc74164de; + else + ctrl = 0xc74164d0; + + ret = ag7xxx_switch_reg_write(priv->bus, 0x4, BIT(7)); + if (ret) + return ret; + + ret = ag7xxx_switch_reg_write(priv->bus, 0xe0, ctrl); + if (ret) + return ret; + + ret = ag7xxx_switch_reg_write(priv->bus, 0x624, 0x7f7f7f7f); + if (ret) + return ret; + + /* + * Values suggested by the switch team when s17 in sgmii + * configuration. 0x10(S17_PWS_REG) = 0x602613a0 + */ + ret = ag7xxx_switch_reg_write(priv->bus, 0x10, 0x602613a0); + if (ret) + return ret; + + ret = ag7xxx_switch_reg_write(priv->bus, 0x7c, 0x0000007e); + if (ret) + return ret; + + /* AR8337/AR8334 v1.0 fixup */ + ret = ag7xxx_switch_reg_read(priv->bus, 0, ®); + if (ret) + return ret; + if ((reg & 0xffff) == 0x1301) { + for (i = 0; i < 5; i++) { + /* Turn on Gigabit clock */ + ret = ag7xxx_switch_write(priv->bus, i, 0x1d, 0x3d); + if (ret) + return ret; + ret = ag7xxx_switch_write(priv->bus, i, 0x1e, 0x6820); + if (ret) + return ret; + } + } + + return 0; +} + static int ag7xxx_mac_probe(struct udevice *dev) { struct ar7xxx_eth_priv *priv = dev_get_priv(dev); @@ -858,8 +1125,15 @@ static int ag7xxx_mac_probe(struct udevice *dev) ret = ag933x_phy_setup_wan(dev); else ret = ag933x_phy_setup_lan(dev); + } else if (priv->model == AG7XXX_MODEL_AG953X) { + if (priv->interface == PHY_INTERFACE_MODE_RMII) + ret = ag953x_phy_setup_wan(dev); + else + ret = ag953x_phy_setup_lan(dev); } else if (priv->model == AG7XXX_MODEL_AG934X) { ret = ag934x_phy_setup(dev); + } else if (priv->model == AG7XXX_MODEL_AG956X) { + ret = ag956x_phy_setup(dev); } else { return -EINVAL; } @@ -997,6 +1271,8 @@ static int ag7xxx_eth_ofdata_to_platdata(struct udevice *dev) static const struct udevice_id ag7xxx_eth_ids[] = { { .compatible = "qca,ag933x-mac", .data = AG7XXX_MODEL_AG933X }, { .compatible = "qca,ag934x-mac", .data = AG7XXX_MODEL_AG934X }, + { .compatible = "qca,ag953x-mac", .data = AG7XXX_MODEL_AG953X }, + { .compatible = "qca,ag956x-mac", .data = AG7XXX_MODEL_AG956X }, { } }; diff --git a/drivers/net/mscc_eswitch/Kconfig b/drivers/net/mscc_eswitch/Kconfig index 88e5a97c4bf..6359d0b6101 100644 --- a/drivers/net/mscc_eswitch/Kconfig +++ b/drivers/net/mscc_eswitch/Kconfig @@ -15,3 +15,17 @@ config MSCC_LUTON_SWITCH select PHYLIB help This driver supports the Luton network switch device. + +config MSCC_JR2_SWITCH + bool "Jaguar2 switch driver" + depends on DM_ETH && ARCH_MSCC + select PHYLIB + help + This driver supports the Jaguar2 network switch device. + +config MSCC_SERVALT_SWITCH + bool "Servalt switch driver" + depends on DM_ETH && ARCH_MSCC + select PHYLIB + help + This driver supports the Servalt network switch device. diff --git a/drivers/net/mscc_eswitch/Makefile b/drivers/net/mscc_eswitch/Makefile index 751a839a5f0..bffd8ec77b0 100644 --- a/drivers/net/mscc_eswitch/Makefile +++ b/drivers/net/mscc_eswitch/Makefile @@ -1,3 +1,5 @@ obj-$(CONFIG_MSCC_OCELOT_SWITCH) += ocelot_switch.o mscc_miim.o mscc_xfer.o mscc_mac_table.o obj-$(CONFIG_MSCC_LUTON_SWITCH) += luton_switch.o mscc_miim.o mscc_xfer.o mscc_mac_table.o +obj-$(CONFIG_MSCC_JR2_SWITCH) += jr2_switch.o mscc_xfer.o +obj-$(CONFIG_MSCC_SERVALT_SWITCH) += servalt_switch.o mscc_xfer.o diff --git a/drivers/net/mscc_eswitch/jr2_switch.c b/drivers/net/mscc_eswitch/jr2_switch.c new file mode 100644 index 00000000000..60d408f1c75 --- /dev/null +++ b/drivers/net/mscc_eswitch/jr2_switch.c @@ -0,0 +1,1075 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <common.h> +#include <config.h> +#include <dm.h> +#include <dm/of_access.h> +#include <dm/of_addr.h> +#include <fdt_support.h> +#include <linux/io.h> +#include <linux/ioport.h> +#include <miiphy.h> +#include <net.h> +#include <wait_bit.h> + +#include <dt-bindings/mscc/jr2_data.h> +#include "mscc_xfer.h" + +#define GCB_MIIM_MII_STATUS 0x0 +#define GCB_MIIM_STAT_BUSY BIT(3) +#define GCB_MIIM_MII_CMD 0x8 +#define GCB_MIIM_MII_CMD_SCAN BIT(0) +#define GCB_MIIM_MII_CMD_OPR_WRITE BIT(1) +#define GCB_MIIM_MII_CMD_OPR_READ BIT(2) +#define GCB_MIIM_MII_CMD_SINGLE_SCAN BIT(3) +#define GCB_MIIM_MII_CMD_WRDATA(x) ((x) << 4) +#define GCB_MIIM_MII_CMD_REGAD(x) ((x) << 20) +#define GCB_MIIM_MII_CMD_PHYAD(x) ((x) << 25) +#define GCB_MIIM_MII_CMD_VLD BIT(31) +#define GCB_MIIM_DATA 0xC +#define GCB_MIIM_DATA_ERROR (0x3 << 16) + +#define ANA_AC_RAM_CTRL_RAM_INIT 0x94358 +#define ANA_AC_STAT_GLOBAL_CFG_PORT_RESET 0x94370 + +#define ANA_CL_PORT_VLAN_CFG(x) (0x24018 + 0xc8 * (x)) +#define ANA_CL_PORT_VLAN_CFG_AWARE_ENA BIT(19) +#define ANA_CL_PORT_VLAN_CFG_POP_CNT(x) ((x) << 17) + +#define ANA_L2_COMMON_FWD_CFG 0x8a2a8 +#define ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA BIT(6) + +#define ASM_CFG_STAT_CFG 0x3508 +#define ASM_CFG_PORT(x) (0x36c4 + 0x4 * (x)) +#define ASM_CFG_PORT_NO_PREAMBLE_ENA BIT(8) +#define ASM_CFG_PORT_INJ_FORMAT_CFG(x) ((x) << 1) +#define ASM_RAM_CTRL_RAM_INIT 0x39b8 + +#define DEV_DEV_CFG_DEV_RST_CTRL 0x0 +#define DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(x) ((x) << 20) +#define DEV_MAC_CFG_MAC_ENA 0x1c +#define DEV_MAC_CFG_MAC_ENA_RX_ENA BIT(4) +#define DEV_MAC_CFG_MAC_ENA_TX_ENA BIT(0) +#define DEV_MAC_CFG_MAC_IFG 0x34 +#define DEV_MAC_CFG_MAC_IFG_TX_IFG(x) ((x) << 8) +#define DEV_MAC_CFG_MAC_IFG_RX_IFG2(x) ((x) << 4) +#define DEV_MAC_CFG_MAC_IFG_RX_IFG1(x) (x) +#define DEV_PCS1G_CFG_PCS1G_CFG 0x40 +#define DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA BIT(0) +#define DEV_PCS1G_CFG_PCS1G_MODE 0x44 +#define DEV_PCS1G_CFG_PCS1G_SD 0x48 +#define DEV_PCS1G_CFG_PCS1G_ANEG 0x4c +#define DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(x) ((x) << 16) + +#define DSM_RAM_CTRL_RAM_INIT 0x8 + +#define HSIO_ANA_SERDES1G_DES_CFG 0xac +#define HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(x) ((x) << 1) +#define HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(x) ((x) << 5) +#define HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(x) ((x) << 8) +#define HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(x) ((x) << 13) +#define HSIO_ANA_SERDES1G_IB_CFG 0xb0 +#define HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(x) (x) +#define HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(x) ((x) << 6) +#define HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP BIT(9) +#define HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV BIT(11) +#define HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM BIT(13) +#define HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(x) ((x) << 19) +#define HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(x) ((x) << 24) +#define HSIO_ANA_SERDES1G_OB_CFG 0xb4 +#define HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(x) (x) +#define HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(x) ((x) << 4) +#define HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(x) ((x) << 10) +#define HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(x) ((x) << 13) +#define HSIO_ANA_SERDES1G_OB_CFG_SLP(x) ((x) << 17) +#define HSIO_ANA_SERDES1G_SER_CFG 0xb8 +#define HSIO_ANA_SERDES1G_COMMON_CFG 0xbc +#define HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE BIT(0) +#define HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE BIT(18) +#define HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST BIT(31) +#define HSIO_ANA_SERDES1G_PLL_CFG 0xc0 +#define HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA BIT(7) +#define HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(x) ((x) << 8) +#define HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2 BIT(21) +#define HSIO_DIG_SERDES1G_DFT_CFG0 0xc8 +#define HSIO_DIG_SERDES1G_TP_CFG 0xd4 +#define HSIO_DIG_SERDES1G_MISC_CFG 0xdc +#define HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST BIT(0) +#define HSIO_MCB_SERDES1G_CFG 0xe8 +#define HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT BIT(31) +#define HSIO_MCB_SERDES1G_CFG_ADDR(x) (x) + +#define HSIO_ANA_SERDES6G_DES_CFG 0x11c +#define HSIO_ANA_SERDES6G_DES_CFG_SWAP_ANA BIT(0) +#define HSIO_ANA_SERDES6G_DES_CFG_BW_ANA(x) ((x) << 1) +#define HSIO_ANA_SERDES6G_DES_CFG_SWAP_HYST BIT(4) +#define HSIO_ANA_SERDES6G_DES_CFG_BW_HYST(x) ((x) << 5) +#define HSIO_ANA_SERDES6G_DES_CFG_CPMD_SEL(x) ((x) << 8) +#define HSIO_ANA_SERDES6G_DES_CFG_MBTR_CTRL(x) ((x) << 10) +#define HSIO_ANA_SERDES6G_DES_CFG_PHS_CTRL(x) ((x) << 13) +#define HSIO_ANA_SERDES6G_IB_CFG 0x120 +#define HSIO_ANA_SERDES6G_IB_CFG_REG_ENA BIT(0) +#define HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA BIT(1) +#define HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA BIT(2) +#define HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(x) ((x) << 3) +#define HSIO_ANA_SERDES6G_IB_CFG_CONCUR BIT(4) +#define HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA BIT(5) +#define HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(x) ((x) << 7) +#define HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(x) ((x) << 9) +#define HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(x) ((x) << 11) +#define HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(x) ((x) << 13) +#define HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(x) ((x) << 15) +#define HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(x) ((x) << 18) +#define HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(x) ((x) << 20) +#define HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(x) ((x) << 24) +#define HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL BIT(28) +#define HSIO_ANA_SERDES6G_IB_CFG_SOFSI(x) ((x) << 29) +#define HSIO_ANA_SERDES6G_IB_CFG1 0x124 +#define HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET BIT(4) +#define HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP BIT(5) +#define HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID BIT(6) +#define HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP BIT(7) +#define HSIO_ANA_SERDES6G_IB_CFG1_SCALY(x) ((x) << 8) +#define HSIO_ANA_SERDES6G_IB_CFG1_TSDET(x) ((x) << 12) +#define HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(x) ((x) << 17) +#define HSIO_ANA_SERDES6G_IB_CFG2 0x128 +#define HSIO_ANA_SERDES6G_IB_CFG2_UREG(x) (x) +#define HSIO_ANA_SERDES6G_IB_CFG2_UMAX(x) ((x) << 3) +#define HSIO_ANA_SERDES6G_IB_CFG2_TCALV(x) ((x) << 5) +#define HSIO_ANA_SERDES6G_IB_CFG2_OCALS(x) ((x) << 10) +#define HSIO_ANA_SERDES6G_IB_CFG2_OINFS(x) ((x) << 16) +#define HSIO_ANA_SERDES6G_IB_CFG2_OINFI(x) ((x) << 22) +#define HSIO_ANA_SERDES6G_IB_CFG2_TINFV(x) ((x) << 27) +#define HSIO_ANA_SERDES6G_IB_CFG3 0x12c +#define HSIO_ANA_SERDES6G_IB_CFG3_INI_OFFSET(x) (x) +#define HSIO_ANA_SERDES6G_IB_CFG3_INI_LP(x) ((x) << 6) +#define HSIO_ANA_SERDES6G_IB_CFG3_INI_MID(x) ((x) << 12) +#define HSIO_ANA_SERDES6G_IB_CFG3_INI_HP(x) ((x) << 18) +#define HSIO_ANA_SERDES6G_IB_CFG4 0x130 +#define HSIO_ANA_SERDES6G_IB_CFG4_MAX_OFFSET(x) (x) +#define HSIO_ANA_SERDES6G_IB_CFG4_MAX_LP(x) ((x) << 6) +#define HSIO_ANA_SERDES6G_IB_CFG4_MAX_MID(x) ((x) << 12) +#define HSIO_ANA_SERDES6G_IB_CFG4_MAX_HP(x) ((x) << 18) +#define HSIO_ANA_SERDES6G_IB_CFG5 0x134 +#define HSIO_ANA_SERDES6G_IB_CFG4_MIN_OFFSET(x) (x) +#define HSIO_ANA_SERDES6G_IB_CFG4_MIN_LP(x) ((x) << 6) +#define HSIO_ANA_SERDES6G_IB_CFG4_MIN_MID(x) ((x) << 12) +#define HSIO_ANA_SERDES6G_IB_CFG4_MIN_HP(x) ((x) << 18) +#define HSIO_ANA_SERDES6G_OB_CFG 0x138 +#define HSIO_ANA_SERDES6G_OB_CFG_RESISTOR_CTRL(x) (x) +#define HSIO_ANA_SERDES6G_OB_CFG_SR(x) ((x) << 4) +#define HSIO_ANA_SERDES6G_OB_CFG_SR_H BIT(8) +#define HSIO_ANA_SERDES6G_OB_CFG_SEL_RCTRL BIT(9) +#define HSIO_ANA_SERDES6G_OB_CFG_R_COR BIT(10) +#define HSIO_ANA_SERDES6G_OB_CFG_POST1(x) ((x) << 11) +#define HSIO_ANA_SERDES6G_OB_CFG_R_ADJ_PDR BIT(16) +#define HSIO_ANA_SERDES6G_OB_CFG_R_ADJ_MUX BIT(17) +#define HSIO_ANA_SERDES6G_OB_CFG_PREC(x) ((x) << 18) +#define HSIO_ANA_SERDES6G_OB_CFG_POST0(x) ((x) << 23) +#define HSIO_ANA_SERDES6G_OB_CFG_POL BIT(29) +#define HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(x) ((x) << 30) +#define HSIO_ANA_SERDES6G_OB_CFG_IDLE BIT(31) +#define HSIO_ANA_SERDES6G_OB_CFG1 0x13c +#define HSIO_ANA_SERDES6G_OB_CFG1_LEV(x) (x) +#define HSIO_ANA_SERDES6G_OB_CFG1_ENA_CAS(x) ((x) << 6) +#define HSIO_ANA_SERDES6G_SER_CFG 0x140 +#define HSIO_ANA_SERDES6G_COMMON_CFG 0x144 +#define HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(x) (x) +#define HSIO_ANA_SERDES6G_COMMON_CFG_QRATE(x) (x << 2) +#define HSIO_ANA_SERDES6G_COMMON_CFG_ENA_LANE BIT(14) +#define HSIO_ANA_SERDES6G_COMMON_CFG_SYS_RST BIT(16) +#define HSIO_ANA_SERDES6G_PLL_CFG 0x148 +#define HSIO_ANA_SERDES6G_PLL_CFG_ROT_FRQ BIT(0) +#define HSIO_ANA_SERDES6G_PLL_CFG_ROT_DIR BIT(1) +#define HSIO_ANA_SERDES6G_PLL_CFG_RB_DATA_SEL BIT(2) +#define HSIO_ANA_SERDES6G_PLL_CFG_FSM_OOR_RECAL_ENA BIT(3) +#define HSIO_ANA_SERDES6G_PLL_CFG_FSM_FORCE_SET_ENA BIT(4) +#define HSIO_ANA_SERDES6G_PLL_CFG_FSM_ENA BIT(5) +#define HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(x) ((x) << 6) +#define HSIO_ANA_SERDES6G_PLL_CFG_ENA_ROT BIT(14) +#define HSIO_ANA_SERDES6G_PLL_CFG_DIV4 BIT(15) +#define HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(x) ((x) << 16) +#define HSIO_DIG_SERDES6G_MISC_CFG 0x108 +#define HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST BIT(0) +#define HSIO_MCB_SERDES6G_CFG 0x168 +#define HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT BIT(31) +#define HSIO_MCB_SERDES6G_CFG_ADDR(x) (x) +#define HSIO_HW_CFGSTAT_HW_CFG 0x16c + +#define LRN_COMMON_ACCESS_CTRL 0x0 +#define LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT BIT(0) +#define LRN_COMMON_MAC_ACCESS_CFG0 0x4 +#define LRN_COMMON_MAC_ACCESS_CFG1 0x8 +#define LRN_COMMON_MAC_ACCESS_CFG2 0xc +#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(x) (x) +#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(x) ((x) << 12) +#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD BIT(15) +#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED BIT(16) +#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY BIT(23) +#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(x) ((x) << 24) + +#define QFWD_SYSTEM_SWITCH_PORT_MODE(x) (0x4 * (x)) +#define QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA BIT(17) + +#define QS_XTR_GRP_CFG(x) (0x0 + 4 * (x)) +#define QS_INJ_GRP_CFG(x) (0x24 + (x) * 4) + +#define QSYS_SYSTEM_RESET_CFG 0xf0 +#define QSYS_CALCFG_CAL_AUTO(x) (0x3d4 + 4 * (x)) +#define QSYS_CALCFG_CAL_CTRL 0x3e8 +#define QSYS_CALCFG_CAL_CTRL_CAL_MODE(x) ((x) << 11) +#define QSYS_RAM_CTRL_RAM_INIT 0x3ec + +#define REW_RAM_CTRL_RAM_INIT 0x53528 + +#define VOP_RAM_CTRL_RAM_INIT 0x43638 + +#define XTR_VALID_BYTES(x) (4 - ((x) & 3)) +#define MAC_VID 0 +#define CPU_PORT 53 +#define IFH_LEN 7 +#define JR2_BUF_CELL_SZ 60 +#define ETH_ALEN 6 +#define PGID_BROADCAST 510 +#define PGID_UNICAST 511 + +static const char * const regs_names[] = { + "port0", "port1", "port2", "port3", "port4", "port5", "port6", "port7", + "port8", "port9", "port10", "port11", "port12", "port13", "port14", + "port15", "port16", "port17", "port18", "port19", "port20", "port21", + "port22", "port23", "port24", "port25", "port26", "port27", "port28", + "port29", "port30", "port31", "port32", "port33", "port34", "port35", + "port36", "port37", "port38", "port39", "port40", "port41", "port42", + "port43", "port44", "port45", "port46", "port47", + "ana_ac", "ana_cl", "ana_l2", "asm", "hsio", "lrn", + "qfwd", "qs", "qsys", "rew", +}; + +#define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1 +#define MAX_PORT 48 + +enum jr2_ctrl_regs { + ANA_AC = MAX_PORT, + ANA_CL, + ANA_L2, + ASM, + HSIO, + LRN, + QFWD, + QS, + QSYS, + REW, +}; + +#define JR2_MIIM_BUS_COUNT 3 + +struct jr2_phy_port_t { + size_t phy_addr; + struct mii_dev *bus; + u8 serdes_index; + u8 phy_mode; +}; + +struct jr2_private { + void __iomem *regs[REGS_NAMES_COUNT]; + struct mii_dev *bus[JR2_MIIM_BUS_COUNT]; + struct jr2_phy_port_t ports[MAX_PORT]; +}; + +struct jr2_miim_dev { + void __iomem *regs; + phys_addr_t miim_base; + unsigned long miim_size; + struct mii_dev *bus; +}; + +static const unsigned long jr2_regs_qs[] = { + [MSCC_QS_XTR_RD] = 0x8, + [MSCC_QS_XTR_FLUSH] = 0x18, + [MSCC_QS_XTR_DATA_PRESENT] = 0x1c, + [MSCC_QS_INJ_WR] = 0x2c, + [MSCC_QS_INJ_CTRL] = 0x34, +}; + +static struct jr2_miim_dev miim[JR2_MIIM_BUS_COUNT]; +static int miim_count = -1; + +static int mscc_miim_wait_ready(struct jr2_miim_dev *miim) +{ + unsigned long deadline; + u32 val; + + deadline = timer_get_us() + 250000; + + do { + val = readl(miim->regs + GCB_MIIM_MII_STATUS); + } while (timer_get_us() <= deadline && (val & GCB_MIIM_STAT_BUSY)); + + if (val & GCB_MIIM_STAT_BUSY) + return -ETIMEDOUT; + + return 0; +} + +static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg) +{ + struct jr2_miim_dev *miim = (struct jr2_miim_dev *)bus->priv; + u32 val; + int ret; + + ret = mscc_miim_wait_ready(miim); + if (ret) + goto out; + + writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) | + GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ, + miim->regs + GCB_MIIM_MII_CMD); + + ret = mscc_miim_wait_ready(miim); + if (ret) + goto out; + + val = readl(miim->regs + GCB_MIIM_DATA); + if (val & GCB_MIIM_DATA_ERROR) { + ret = -EIO; + goto out; + } + + ret = val & 0xFFFF; + out: + return ret; +} + +static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg, + u16 val) +{ + struct jr2_miim_dev *miim = (struct jr2_miim_dev *)bus->priv; + int ret; + + ret = mscc_miim_wait_ready(miim); + if (ret < 0) + goto out; + + writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) | + GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) | + GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD); + + out: + return ret; +} + +static struct mii_dev *jr2_mdiobus_init(phys_addr_t miim_base, + unsigned long miim_size) +{ + struct mii_dev *bus; + + bus = mdio_alloc(); + if (!bus) + return NULL; + + ++miim_count; + sprintf(bus->name, "miim-bus%d", miim_count); + + miim[miim_count].regs = ioremap(miim_base, miim_size); + miim[miim_count].miim_base = miim_base; + miim[miim_count].miim_size = miim_size; + bus->priv = &miim[miim_count]; + bus->read = mscc_miim_read; + bus->write = mscc_miim_write; + + if (mdio_register(bus)) + return NULL; + + miim[miim_count].bus = bus; + return bus; +} + +static void jr2_cpu_capture_setup(struct jr2_private *priv) +{ + /* ASM: No preamble and IFH prefix on CPU injected frames */ + writel(ASM_CFG_PORT_NO_PREAMBLE_ENA | + ASM_CFG_PORT_INJ_FORMAT_CFG(1), + priv->regs[ASM] + ASM_CFG_PORT(CPU_PORT)); + + /* Set Manual injection via DEVCPU_QS registers for CPU queue 0 */ + writel(0x5, priv->regs[QS] + QS_INJ_GRP_CFG(0)); + + /* Set Manual extraction via DEVCPU_QS registers for CPU queue 0 */ + writel(0x7, priv->regs[QS] + QS_XTR_GRP_CFG(0)); + + /* Enable CPU port for any frame transfer */ + setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(CPU_PORT), + QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA); + + /* Send a copy to CPU when found as forwarding entry */ + setbits_le32(priv->regs[ANA_L2] + ANA_L2_COMMON_FWD_CFG, + ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA); +} + +static void jr2_port_init(struct jr2_private *priv, int port) +{ + void __iomem *regs = priv->regs[port]; + + /* Enable PCS */ + writel(DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA, + regs + DEV_PCS1G_CFG_PCS1G_CFG); + + /* Disable Signal Detect */ + writel(0, regs + DEV_PCS1G_CFG_PCS1G_SD); + + /* Enable MAC RX and TX */ + writel(DEV_MAC_CFG_MAC_ENA_RX_ENA | + DEV_MAC_CFG_MAC_ENA_TX_ENA, + regs + DEV_MAC_CFG_MAC_ENA); + + /* Clear sgmii_mode_ena */ + writel(0, regs + DEV_PCS1G_CFG_PCS1G_MODE); + + /* + * Clear sw_resolve_ena(bit 0) and set adv_ability to + * something meaningful just in case + */ + writel(DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(0x20), + regs + DEV_PCS1G_CFG_PCS1G_ANEG); + + /* Set MAC IFG Gaps */ + writel(DEV_MAC_CFG_MAC_IFG_TX_IFG(4) | + DEV_MAC_CFG_MAC_IFG_RX_IFG1(5) | + DEV_MAC_CFG_MAC_IFG_RX_IFG2(1), + regs + DEV_MAC_CFG_MAC_IFG); + + /* Set link speed and release all resets */ + writel(DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(2), + regs + DEV_DEV_CFG_DEV_RST_CTRL); + + /* Make VLAN aware for CPU traffic */ + writel(ANA_CL_PORT_VLAN_CFG_AWARE_ENA | + ANA_CL_PORT_VLAN_CFG_POP_CNT(1) | + MAC_VID, + priv->regs[ANA_CL] + ANA_CL_PORT_VLAN_CFG(port)); + + /* Enable CPU port for any frame transfer */ + setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(port), + QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA); +} + +static void serdes6g_write(void __iomem *base, u32 addr) +{ + u32 data; + + writel(HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT | + HSIO_MCB_SERDES6G_CFG_ADDR(addr), + base + HSIO_MCB_SERDES6G_CFG); + + do { + data = readl(base + HSIO_MCB_SERDES6G_CFG); + } while (data & HSIO_MCB_SERDES6G_CFG_WR_ONE_SHOT); +} + +static void serdes6g_setup(void __iomem *base, uint32_t addr, + phy_interface_t interface) +{ + u32 ib_if_mode = 0; + u32 ib_qrate = 0; + u32 ib_cal_ena = 0; + u32 ib1_tsdet = 0; + u32 ob_lev = 0; + u32 ob_ena_cas = 0; + u32 ob_ena1v_mode = 0; + u32 des_bw_ana = 0; + u32 pll_fsm_ctrl_data = 0; + + switch (interface) { + case PHY_INTERFACE_MODE_SGMII: + ib_if_mode = 1; + ib_qrate = 1; + ib_cal_ena = 1; + ib1_tsdet = 3; + ob_lev = 48; + ob_ena_cas = 2; + ob_ena1v_mode = 1; + des_bw_ana = 3; + pll_fsm_ctrl_data = 60; + break; + case PHY_INTERFACE_MODE_QSGMII: + ib_if_mode = 3; + ib1_tsdet = 16; + ob_lev = 24; + des_bw_ana = 5; + pll_fsm_ctrl_data = 120; + break; + default: + pr_err("Interface not supported\n"); + return; + } + + if (interface == PHY_INTERFACE_MODE_QSGMII) + writel(0xfff, base + HSIO_HW_CFGSTAT_HW_CFG); + + writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(3), + base + HSIO_ANA_SERDES6G_COMMON_CFG); + writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(120) | + HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3), + base + HSIO_ANA_SERDES6G_PLL_CFG); + writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA | + HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA | + HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA | + HSIO_ANA_SERDES6G_IB_CFG_CONCUR | + HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) | + HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) | + HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) | + HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) | + HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) | + HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL | + HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1), + base + HSIO_ANA_SERDES6G_IB_CFG); + writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET | + HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP | + HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID | + HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP | + HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) | + HSIO_ANA_SERDES6G_IB_CFG1_TSDET(3) | + HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8), + base + HSIO_ANA_SERDES6G_IB_CFG1); + writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST, + base + HSIO_DIG_SERDES6G_MISC_CFG); + + serdes6g_write(base, addr); + + writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA | + HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA | + HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA | + HSIO_ANA_SERDES6G_IB_CFG_CONCUR | + HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) | + HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) | + HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) | + HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) | + HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) | + HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL | + HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1), + base + HSIO_ANA_SERDES6G_IB_CFG); + writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET | + HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP | + HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID | + HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP | + HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) | + HSIO_ANA_SERDES6G_IB_CFG1_TSDET(16) | + HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8), + base + HSIO_ANA_SERDES6G_IB_CFG1); + + writel(0x0, base + HSIO_ANA_SERDES6G_SER_CFG); + writel(HSIO_ANA_SERDES6G_COMMON_CFG_IF_MODE(ib_if_mode) | + HSIO_ANA_SERDES6G_COMMON_CFG_QRATE(ib_qrate) | + HSIO_ANA_SERDES6G_COMMON_CFG_ENA_LANE | + HSIO_ANA_SERDES6G_COMMON_CFG_SYS_RST, + base + HSIO_ANA_SERDES6G_COMMON_CFG); + writel(HSIO_DIG_SERDES6G_MISC_CFG_LANE_RST, + base + HSIO_DIG_SERDES6G_MISC_CFG); + + writel(HSIO_ANA_SERDES6G_OB_CFG_RESISTOR_CTRL(1) | + HSIO_ANA_SERDES6G_OB_CFG_SR(7) | + HSIO_ANA_SERDES6G_OB_CFG_SR_H | + HSIO_ANA_SERDES6G_OB_CFG_ENA1V_MODE(ob_ena1v_mode) | + HSIO_ANA_SERDES6G_OB_CFG_POL, base + HSIO_ANA_SERDES6G_OB_CFG); + writel(HSIO_ANA_SERDES6G_OB_CFG1_LEV(ob_lev) | + HSIO_ANA_SERDES6G_OB_CFG1_ENA_CAS(ob_ena_cas), + base + HSIO_ANA_SERDES6G_OB_CFG1); + + writel(HSIO_ANA_SERDES6G_DES_CFG_BW_ANA(des_bw_ana) | + HSIO_ANA_SERDES6G_DES_CFG_BW_HYST(5) | + HSIO_ANA_SERDES6G_DES_CFG_MBTR_CTRL(2) | + HSIO_ANA_SERDES6G_DES_CFG_PHS_CTRL(6), + base + HSIO_ANA_SERDES6G_DES_CFG); + writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) | + HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3), + base + HSIO_ANA_SERDES6G_PLL_CFG); + + serdes6g_write(base, addr); + + /* set pll_fsm_ena = 1 */ + writel(HSIO_ANA_SERDES6G_PLL_CFG_FSM_ENA | + HSIO_ANA_SERDES6G_PLL_CFG_FSM_CTRL_DATA(pll_fsm_ctrl_data) | + HSIO_ANA_SERDES6G_PLL_CFG_ENA_OFFS(3), + base + HSIO_ANA_SERDES6G_PLL_CFG); + + serdes6g_write(base, addr); + + /* wait 20ms for pll bringup */ + mdelay(20); + + /* start IB calibration by setting ib_cal_ena and clearing lane_rst */ + writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA | + HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA | + HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA | + HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(ib_cal_ena) | + HSIO_ANA_SERDES6G_IB_CFG_CONCUR | + HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) | + HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(0) | + HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) | + HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) | + HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) | + HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL | + HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1), + base + HSIO_ANA_SERDES6G_IB_CFG); + writel(0x0, base + HSIO_DIG_SERDES6G_MISC_CFG); + + serdes6g_write(base, addr); + + /* wait 60 for calibration */ + mdelay(60); + + /* set ib_tsdet and ib_reg_pat_sel_offset back to correct values */ + writel(HSIO_ANA_SERDES6G_IB_CFG_REG_ENA | + HSIO_ANA_SERDES6G_IB_CFG_EQZ_ENA | + HSIO_ANA_SERDES6G_IB_CFG_SAM_ENA | + HSIO_ANA_SERDES6G_IB_CFG_CAL_ENA(ib_cal_ena) | + HSIO_ANA_SERDES6G_IB_CFG_CONCUR | + HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_ENA | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_OFF(0) | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_LP(2) | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_MID(1) | + HSIO_ANA_SERDES6G_IB_CFG_REG_PAT_SEL_HP(1) | + HSIO_ANA_SERDES6G_IB_CFG_SIG_DET_CLK_SEL(7) | + HSIO_ANA_SERDES6G_IB_CFG_TERM_MODE_SEL(1) | + HSIO_ANA_SERDES6G_IB_CFG_ICML_ADJ(5) | + HSIO_ANA_SERDES6G_IB_CFG_RTRM_ADJ(13) | + HSIO_ANA_SERDES6G_IB_CFG_VBULK_SEL | + HSIO_ANA_SERDES6G_IB_CFG_SOFSI(1), + base + HSIO_ANA_SERDES6G_IB_CFG); + writel(HSIO_ANA_SERDES6G_IB_CFG1_FILT_OFFSET | + HSIO_ANA_SERDES6G_IB_CFG1_FILT_LP | + HSIO_ANA_SERDES6G_IB_CFG1_FILT_MID | + HSIO_ANA_SERDES6G_IB_CFG1_FILT_HP | + HSIO_ANA_SERDES6G_IB_CFG1_SCALY(15) | + HSIO_ANA_SERDES6G_IB_CFG1_TSDET(ib1_tsdet) | + HSIO_ANA_SERDES6G_IB_CFG1_TJTAG(8), + base + HSIO_ANA_SERDES6G_IB_CFG1); + + serdes6g_write(base, addr); +} + +static void serdes1g_write(void __iomem *base, u32 addr) +{ + u32 data; + + writel(HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT | + HSIO_MCB_SERDES1G_CFG_ADDR(addr), + base + HSIO_MCB_SERDES1G_CFG); + + do { + data = readl(base + HSIO_MCB_SERDES1G_CFG); + } while (data & HSIO_MCB_SERDES1G_CFG_WR_ONE_SHOT); +} + +static void serdes1g_setup(void __iomem *base, uint32_t addr, + phy_interface_t interface) +{ + writel(0x0, base + HSIO_ANA_SERDES1G_SER_CFG); + writel(0x0, base + HSIO_DIG_SERDES1G_TP_CFG); + writel(0x0, base + HSIO_DIG_SERDES1G_DFT_CFG0); + writel(HSIO_ANA_SERDES1G_OB_CFG_RESISTOR_CTRL(1) | + HSIO_ANA_SERDES1G_OB_CFG_VCM_CTRL(4) | + HSIO_ANA_SERDES1G_OB_CFG_CMM_BIAS_CTRL(2) | + HSIO_ANA_SERDES1G_OB_CFG_AMP_CTRL(12) | + HSIO_ANA_SERDES1G_OB_CFG_SLP(3), + base + HSIO_ANA_SERDES1G_OB_CFG); + writel(HSIO_ANA_SERDES1G_IB_CFG_RESISTOR_CTRL(13) | + HSIO_ANA_SERDES1G_IB_CFG_EQ_GAIN(2) | + HSIO_ANA_SERDES1G_IB_CFG_ENA_OFFSET_COMP | + HSIO_ANA_SERDES1G_IB_CFG_ENA_DETLEV | + HSIO_ANA_SERDES1G_IB_CFG_ENA_CMV_TERM | + HSIO_ANA_SERDES1G_IB_CFG_DET_LEV(3) | + HSIO_ANA_SERDES1G_IB_CFG_ACJTAG_HYST(1), + base + HSIO_ANA_SERDES1G_IB_CFG); + writel(HSIO_ANA_SERDES1G_DES_CFG_BW_HYST(7) | + HSIO_ANA_SERDES1G_DES_CFG_BW_ANA(6) | + HSIO_ANA_SERDES1G_DES_CFG_MBTR_CTRL(2) | + HSIO_ANA_SERDES1G_DES_CFG_PHS_CTRL(6), + base + HSIO_ANA_SERDES1G_DES_CFG); + writel(HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST, + base + HSIO_DIG_SERDES1G_MISC_CFG); + writel(HSIO_ANA_SERDES1G_PLL_CFG_FSM_ENA | + HSIO_ANA_SERDES1G_PLL_CFG_FSM_CTRL_DATA(0xc8) | + HSIO_ANA_SERDES1G_PLL_CFG_ENA_RC_DIV2, + base + HSIO_ANA_SERDES1G_PLL_CFG); + writel(HSIO_ANA_SERDES1G_COMMON_CFG_IF_MODE | + HSIO_ANA_SERDES1G_COMMON_CFG_ENA_LANE | + HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST, + base + HSIO_ANA_SERDES1G_COMMON_CFG); + + serdes1g_write(base, addr); + + setbits_le32(base + HSIO_ANA_SERDES1G_COMMON_CFG, + HSIO_ANA_SERDES1G_COMMON_CFG_SYS_RST); + + serdes1g_write(base, addr); + + clrbits_le32(base + HSIO_DIG_SERDES1G_MISC_CFG, + HSIO_DIG_SERDES1G_MISC_CFG_LANE_RST); + + serdes1g_write(base, addr); +} + +static int ram_init(u32 val, void __iomem *addr) +{ + writel(val, addr); + + if (wait_for_bit_le32(addr, BIT(1), false, 2000, false)) { + printf("Timeout in memory reset, reg = 0x%08x\n", val); + return 1; + } + + return 0; +} + +static int jr2_switch_init(struct jr2_private *priv) +{ + /* Initialize memories */ + ram_init(0x3, priv->regs[QSYS] + QSYS_RAM_CTRL_RAM_INIT); + ram_init(0x3, priv->regs[ASM] + ASM_RAM_CTRL_RAM_INIT); + ram_init(0x3, priv->regs[ANA_AC] + ANA_AC_RAM_CTRL_RAM_INIT); + ram_init(0x3, priv->regs[REW] + REW_RAM_CTRL_RAM_INIT); + + /* Reset counters */ + writel(0x1, priv->regs[ANA_AC] + ANA_AC_STAT_GLOBAL_CFG_PORT_RESET); + writel(0x1, priv->regs[ASM] + ASM_CFG_STAT_CFG); + + /* Enable switch-core and queue system */ + writel(0x1, priv->regs[QSYS] + QSYS_SYSTEM_RESET_CFG); + + return 0; +} + +static void jr2_switch_config(struct jr2_private *priv) +{ + writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(0)); + writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(1)); + writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(2)); + writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO(3)); + + writel(readl(priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL) | + QSYS_CALCFG_CAL_CTRL_CAL_MODE(8), + priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL); +} + +static int jr2_initialize(struct jr2_private *priv) +{ + int ret, i; + + /* Initialize switch memories, enable core */ + ret = jr2_switch_init(priv); + if (ret) + return ret; + + jr2_switch_config(priv); + + for (i = 0; i < MAX_PORT; i++) + jr2_port_init(priv, i); + + jr2_cpu_capture_setup(priv); + + return 0; +} + +static inline int jr2_vlant_wait_for_completion(struct jr2_private *priv) +{ + if (wait_for_bit_le32(priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL, + LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT, + false, 2000, false)) + return -ETIMEDOUT; + + return 0; +} + +static int jr2_mac_table_add(struct jr2_private *priv, + const unsigned char mac[ETH_ALEN], int pgid) +{ + u32 macl = 0, mach = 0; + + /* + * Set the MAC address to handle and the vlan associated in a format + * understood by the hardware. + */ + mach |= MAC_VID << 16; + mach |= ((u32)mac[0]) << 8; + mach |= ((u32)mac[1]) << 0; + macl |= ((u32)mac[2]) << 24; + macl |= ((u32)mac[3]) << 16; + macl |= ((u32)mac[4]) << 8; + macl |= ((u32)mac[5]) << 0; + + writel(mach, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG0); + writel(macl, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG1); + + writel(LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(pgid) | + LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(0x3) | + LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY | + LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(0) | + LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD | + LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED, + priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG2); + + writel(LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT, + priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL); + + return jr2_vlant_wait_for_completion(priv); +} + +static int jr2_write_hwaddr(struct udevice *dev) +{ + struct jr2_private *priv = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_platdata(dev); + + return jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST); +} + +static void serdes_setup(struct jr2_private *priv) +{ + size_t mask; + int i = 0; + + for (i = 0; i < MAX_PORT; ++i) { + if (!priv->ports[i].bus || priv->ports[i].serdes_index == 0xff) + continue; + + mask = BIT(priv->ports[i].serdes_index); + if (priv->ports[i].serdes_index < SERDES1G_MAX) { + serdes1g_setup(priv->regs[HSIO], mask, + priv->ports[i].phy_mode); + } else { + mask >>= SERDES6G(0); + serdes6g_setup(priv->regs[HSIO], mask, + priv->ports[i].phy_mode); + } + } +} + +static int jr2_start(struct udevice *dev) +{ + struct jr2_private *priv = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_platdata(dev); + const unsigned char mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, + 0xff }; + int ret; + + ret = jr2_initialize(priv); + if (ret) + return ret; + + /* Set MAC address tables entries for CPU redirection */ + ret = jr2_mac_table_add(priv, mac, PGID_BROADCAST); + if (ret) + return ret; + + ret = jr2_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST); + if (ret) + return ret; + + serdes_setup(priv); + + return 0; +} + +static void jr2_stop(struct udevice *dev) +{ +} + +static int jr2_send(struct udevice *dev, void *packet, int length) +{ + struct jr2_private *priv = dev_get_priv(dev); + u32 ifh[IFH_LEN]; + u32 *buf = packet; + + memset(ifh, '\0', IFH_LEN); + + /* Set DST PORT_MASK */ + ifh[0] = htonl(0); + ifh[1] = htonl(0x1FFFFF); + ifh[2] = htonl(~0); + /* Set DST_MODE to INJECT and UPDATE_FCS */ + ifh[5] = htonl(0x4c0); + + return mscc_send(priv->regs[QS], jr2_regs_qs, + ifh, IFH_LEN, buf, length); +} + +static int jr2_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct jr2_private *priv = dev_get_priv(dev); + u32 *rxbuf = (u32 *)net_rx_packets[0]; + int byte_cnt = 0; + + byte_cnt = mscc_recv(priv->regs[QS], jr2_regs_qs, rxbuf, IFH_LEN, + false); + + *packetp = net_rx_packets[0]; + + return byte_cnt; +} + +static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size) +{ + int i = 0; + + for (i = 0; i < JR2_MIIM_BUS_COUNT; ++i) + if (miim[i].miim_base == base && miim[i].miim_size == size) + return miim[i].bus; + + return NULL; +} + +static void add_port_entry(struct jr2_private *priv, size_t index, + size_t phy_addr, struct mii_dev *bus, + u8 serdes_index, u8 phy_mode) +{ + priv->ports[index].phy_addr = phy_addr; + priv->ports[index].bus = bus; + priv->ports[index].serdes_index = serdes_index; + priv->ports[index].phy_mode = phy_mode; +} + +static int jr2_probe(struct udevice *dev) +{ + struct jr2_private *priv = dev_get_priv(dev); + int i; + int ret; + struct resource res; + fdt32_t faddr; + phys_addr_t addr_base; + unsigned long addr_size; + ofnode eth_node, node, mdio_node; + size_t phy_addr; + struct mii_dev *bus; + struct ofnode_phandle_args phandle; + struct phy_device *phy; + + if (!priv) + return -EINVAL; + + /* Get registers and map them to the private structure */ + for (i = 0; i < ARRAY_SIZE(regs_names); i++) { + priv->regs[i] = dev_remap_addr_name(dev, regs_names[i]); + if (!priv->regs[i]) { + debug + ("Error can't get regs base addresses for %s\n", + regs_names[i]); + return -ENOMEM; + } + } + + /* Initialize miim buses */ + memset(&miim, 0x0, sizeof(struct jr2_miim_dev) * JR2_MIIM_BUS_COUNT); + + /* iterate all the ports and find out on which bus they are */ + i = 0; + eth_node = dev_read_first_subnode(dev); + for (node = ofnode_first_subnode(eth_node); + ofnode_valid(node); + node = ofnode_next_subnode(node)) { + if (ofnode_read_resource(node, 0, &res)) + return -ENOMEM; + i = res.start; + + ret = ofnode_parse_phandle_with_args(node, "phy-handle", NULL, + 0, 0, &phandle); + if (ret) + continue; + + /* Get phy address on mdio bus */ + if (ofnode_read_resource(phandle.node, 0, &res)) + return -ENOMEM; + phy_addr = res.start; + + /* Get mdio node */ + mdio_node = ofnode_get_parent(phandle.node); + + if (ofnode_read_resource(mdio_node, 0, &res)) + return -ENOMEM; + faddr = cpu_to_fdt32(res.start); + + addr_base = ofnode_translate_address(mdio_node, &faddr); + addr_size = res.end - res.start; + + /* If the bus is new then create a new bus */ + if (!get_mdiobus(addr_base, addr_size)) + priv->bus[miim_count] = + jr2_mdiobus_init(addr_base, addr_size); + + /* Connect mdio bus with the port */ + bus = get_mdiobus(addr_base, addr_size); + + /* Get serdes info */ + ret = ofnode_parse_phandle_with_args(node, "phys", NULL, + 3, 0, &phandle); + if (ret) + return -ENOMEM; + + add_port_entry(priv, i, phy_addr, bus, phandle.args[1], + phandle.args[2]); + } + + for (i = 0; i < MAX_PORT; i++) { + if (!priv->ports[i].bus) + continue; + + phy = phy_connect(priv->ports[i].bus, + priv->ports[i].phy_addr, dev, + PHY_INTERFACE_MODE_NONE); + if (phy) + board_phy_config(phy); + } + + return 0; +} + +static int jr2_remove(struct udevice *dev) +{ + struct jr2_private *priv = dev_get_priv(dev); + int i; + + for (i = 0; i < JR2_MIIM_BUS_COUNT; i++) { + mdio_unregister(priv->bus[i]); + mdio_free(priv->bus[i]); + } + + return 0; +} + +static const struct eth_ops jr2_ops = { + .start = jr2_start, + .stop = jr2_stop, + .send = jr2_send, + .recv = jr2_recv, + .write_hwaddr = jr2_write_hwaddr, +}; + +static const struct udevice_id mscc_jr2_ids[] = { + {.compatible = "mscc,vsc7454-switch" }, + { /* Sentinel */ } +}; + +U_BOOT_DRIVER(jr2) = { + .name = "jr2-switch", + .id = UCLASS_ETH, + .of_match = mscc_jr2_ids, + .probe = jr2_probe, + .remove = jr2_remove, + .ops = &jr2_ops, + .priv_auto_alloc_size = sizeof(struct jr2_private), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), +}; diff --git a/drivers/net/mscc_eswitch/ocelot_switch.c b/drivers/net/mscc_eswitch/ocelot_switch.c index bf08c35ba04..815c2da2646 100644 --- a/drivers/net/mscc_eswitch/ocelot_switch.c +++ b/drivers/net/mscc_eswitch/ocelot_switch.c @@ -142,18 +142,16 @@ static const unsigned long ocelot_regs_ana_table[] = { static struct mscc_miim_dev miim[NUM_PHY]; -static int mscc_miim_reset(struct mii_dev *bus) +static void mscc_phy_reset(void) { - struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv; - - if (miim->phy_regs) { - writel(0, miim->phy_regs + PHY_CFG); - writel(PHY_CFG_RST | PHY_CFG_COMMON_RST - | PHY_CFG_ENA, miim->phy_regs + PHY_CFG); - mdelay(500); + writel(0, miim[INTERNAL].phy_regs + PHY_CFG); + writel(PHY_CFG_RST | PHY_CFG_COMMON_RST + | PHY_CFG_ENA, miim[INTERNAL].phy_regs + PHY_CFG); + if (wait_for_bit_le32(miim[INTERNAL].phy_regs + PHY_STAT, + PHY_STAT_SUPERVISOR_COMPLETE, + true, 2000, false)) { + pr_err("Timeout in phy reset\n"); } - - return 0; } /* For now only setup the internal mdio bus */ @@ -194,7 +192,6 @@ static struct mii_dev *ocelot_mdiobus_init(struct udevice *dev) miim[INTERNAL].phy_regs = ioremap(phy_base[PHY], phy_size[PHY]); miim[INTERNAL].regs = ioremap(phy_base[MIIM], phy_size[MIIM]); bus->priv = &miim[INTERNAL]; - bus->reset = mscc_miim_reset; bus->read = mscc_miim_read; bus->write = mscc_miim_write; @@ -210,13 +207,8 @@ __weak void mscc_switch_reset(void) static void ocelot_stop(struct udevice *dev) { - struct ocelot_private *priv = dev_get_priv(dev); - int i; - mscc_switch_reset(); - for (i = 0; i < NUM_PHY; i++) - if (priv->bus[i]) - mscc_miim_reset(priv->bus[i]); + mscc_phy_reset(); } static void ocelot_cpu_capture_setup(struct ocelot_private *priv) @@ -473,6 +465,7 @@ static int ocelot_probe(struct udevice *dev) } priv->bus[INTERNAL] = ocelot_mdiobus_init(dev); + mscc_phy_reset(); for (i = 0; i < 4; i++) { phy_connect(priv->bus[INTERNAL], i, dev, diff --git a/drivers/net/mscc_eswitch/servalt_switch.c b/drivers/net/mscc_eswitch/servalt_switch.c new file mode 100644 index 00000000000..995c62309d2 --- /dev/null +++ b/drivers/net/mscc_eswitch/servalt_switch.c @@ -0,0 +1,622 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2019 Microsemi Corporation + */ + +#include <common.h> +#include <config.h> +#include <dm.h> +#include <dm/of_access.h> +#include <dm/of_addr.h> +#include <fdt_support.h> +#include <linux/io.h> +#include <linux/ioport.h> +#include <miiphy.h> +#include <net.h> +#include <wait_bit.h> + +#include "mscc_xfer.h" + +#define GCB_MIIM_MII_STATUS 0x0 +#define GCB_MIIM_STAT_BUSY BIT(3) +#define GCB_MIIM_MII_CMD 0x8 +#define GCB_MIIM_MII_CMD_OPR_WRITE BIT(1) +#define GCB_MIIM_MII_CMD_OPR_READ BIT(2) +#define GCB_MIIM_MII_CMD_WRDATA(x) ((x) << 4) +#define GCB_MIIM_MII_CMD_REGAD(x) ((x) << 20) +#define GCB_MIIM_MII_CMD_PHYAD(x) ((x) << 25) +#define GCB_MIIM_MII_CMD_VLD BIT(31) +#define GCB_MIIM_DATA 0xC +#define GCB_MIIM_DATA_ERROR (0x3 << 16) + +#define PHY_CFG 0x0 +#define PHY_CFG_ENA 0x3 +#define PHY_CFG_COMMON_RST BIT(2) +#define PHY_CFG_RST (0x3 << 3) +#define PHY_STAT 0x4 +#define PHY_STAT_SUPERVISOR_COMPLETE BIT(0) + +#define ANA_AC_RAM_CTRL_RAM_INIT 0x14fdc +#define ANA_AC_STAT_GLOBAL_CFG_PORT_RESET 0x15474 + +#define ANA_CL_PORT_VLAN_CFG(x) (0xa018 + 0xc8 * (x)) +#define ANA_CL_PORT_VLAN_CFG_AWARE_ENA BIT(19) +#define ANA_CL_PORT_VLAN_CFG_POP_CNT(x) ((x) << 17) + +#define ANA_L2_COMMON_FWD_CFG 0x18498 +#define ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA BIT(6) + +#define ASM_CFG_STAT_CFG 0xb08 +#define ASM_CFG_PORT(x) (0xb74 + 0x4 * (x)) +#define ASM_CFG_PORT_NO_PREAMBLE_ENA BIT(8) +#define ASM_CFG_PORT_INJ_FORMAT_CFG(x) ((x) << 1) +#define ASM_RAM_CTRL_RAM_INIT 0xbfc + +#define DEV_DEV_CFG_DEV_RST_CTRL 0x0 +#define DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(x) ((x) << 20) +#define DEV_MAC_CFG_MAC_ENA 0x24 +#define DEV_MAC_CFG_MAC_ENA_RX_ENA BIT(4) +#define DEV_MAC_CFG_MAC_ENA_TX_ENA BIT(0) +#define DEV_MAC_CFG_MAC_IFG 0x3c +#define DEV_MAC_CFG_MAC_IFG_TX_IFG(x) ((x) << 8) +#define DEV_MAC_CFG_MAC_IFG_RX_IFG2(x) ((x) << 4) +#define DEV_MAC_CFG_MAC_IFG_RX_IFG1(x) (x) +#define DEV_PCS1G_CFG_PCS1G_CFG 0x48 +#define DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA BIT(0) +#define DEV_PCS1G_CFG_PCS1G_MODE 0x4c +#define DEV_PCS1G_CFG_PCS1G_SD 0x50 +#define DEV_PCS1G_CFG_PCS1G_ANEG 0x54 +#define DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(x) ((x) << 16) + +#define LRN_COMMON_ACCESS_CTRL 0x0 +#define LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT BIT(0) +#define LRN_COMMON_MAC_ACCESS_CFG0 0x4 +#define LRN_COMMON_MAC_ACCESS_CFG1 0x8 +#define LRN_COMMON_MAC_ACCESS_CFG2 0xc +#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(x) (x) +#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(x) ((x) << 12) +#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD BIT(15) +#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED BIT(16) +#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY BIT(23) +#define LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(x) ((x) << 24) + +#define QFWD_SYSTEM_SWITCH_PORT_MODE(x) (0x4400 + 0x4 * (x)) +#define QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA BIT(17) + +#define QS_XTR_GRP_CFG(x) (4 * (x)) +#define QS_INJ_GRP_CFG(x) (0x24 + (x) * 4) + +#define QSYS_SYSTEM_RESET_CFG 0x1048 +#define QSYS_CALCFG_CAL_AUTO 0x1134 +#define QSYS_CALCFG_CAL_CTRL 0x113c +#define QSYS_CALCFG_CAL_CTRL_CAL_MODE(x) ((x) << 11) +#define QSYS_RAM_CTRL_RAM_INIT 0x1140 + +#define REW_RAM_CTRL_RAM_INIT 0xFFF4 + +#define MAC_VID 0 +#define CPU_PORT 11 +#define IFH_LEN 7 +#define ETH_ALEN 6 +#define PGID_BROADCAST 50 +#define PGID_UNICAST 51 + +static const char * const regs_names[] = { + "port0", "port1", + "ana_ac", "ana_cl", "ana_l2", "asm", "lrn", "qfwd", "qs", "qsys", "rew", +}; + +#define REGS_NAMES_COUNT ARRAY_SIZE(regs_names) + 1 +#define MAX_PORT 2 + +enum servalt_ctrl_regs { + ANA_AC = MAX_PORT, + ANA_CL, + ANA_L2, + ASM, + LRN, + QFWD, + QS, + QSYS, + REW, +}; + +#define SERVALT_MIIM_BUS_COUNT 2 + +struct servalt_phy_port_t { + size_t phy_addr; + struct mii_dev *bus; +}; + +struct servalt_private { + void __iomem *regs[REGS_NAMES_COUNT]; + struct mii_dev *bus[SERVALT_MIIM_BUS_COUNT]; + struct servalt_phy_port_t ports[MAX_PORT]; +}; + +struct mscc_miim_dev { + void __iomem *regs; + phys_addr_t miim_base; + unsigned long miim_size; + struct mii_dev *bus; +}; + +static const unsigned long servalt_regs_qs[] = { + [MSCC_QS_XTR_RD] = 0x8, + [MSCC_QS_XTR_FLUSH] = 0x18, + [MSCC_QS_XTR_DATA_PRESENT] = 0x1c, + [MSCC_QS_INJ_WR] = 0x2c, + [MSCC_QS_INJ_CTRL] = 0x34, +}; + +static struct mscc_miim_dev miim[SERVALT_MIIM_BUS_COUNT]; +static int miim_count = -1; + +static int mscc_miim_wait_ready(struct mscc_miim_dev *miim) +{ + return wait_for_bit_le32(miim->regs + GCB_MIIM_MII_STATUS, + GCB_MIIM_STAT_BUSY, false, 250, false); +} + +static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg) +{ + struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv; + u32 val; + int ret; + + ret = mscc_miim_wait_ready(miim); + if (ret) + goto out; + + writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) | + GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ, + miim->regs + GCB_MIIM_MII_CMD); + + ret = mscc_miim_wait_ready(miim); + if (ret) + goto out; + + val = readl(miim->regs + GCB_MIIM_DATA); + if (val & GCB_MIIM_DATA_ERROR) { + ret = -EIO; + goto out; + } + + ret = val & 0xFFFF; +out: + return ret; +} + +static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg, + u16 val) +{ + struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv; + int ret; + + ret = mscc_miim_wait_ready(miim); + if (ret < 0) + goto out; + + writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) | + GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) | + GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD); + +out: + return ret; +} + +static struct mii_dev *servalt_mdiobus_init(phys_addr_t miim_base, + unsigned long miim_size) +{ + struct mii_dev *bus; + + bus = mdio_alloc(); + if (!bus) + return NULL; + + ++miim_count; + sprintf(bus->name, "miim-bus%d", miim_count); + + miim[miim_count].regs = ioremap(miim_base, miim_size); + miim[miim_count].miim_base = miim_base; + miim[miim_count].miim_size = miim_size; + bus->priv = &miim[miim_count]; + bus->read = mscc_miim_read; + bus->write = mscc_miim_write; + + if (mdio_register(bus)) + return NULL; + + miim[miim_count].bus = bus; + return bus; +} + +static void mscc_phy_reset(void) +{ + writel(0, BASE_DEVCPU_GCB + GCB_PHY_CFG + PHY_CFG); + writel(PHY_CFG_RST | PHY_CFG_COMMON_RST + | PHY_CFG_ENA, BASE_DEVCPU_GCB + GCB_PHY_CFG + PHY_CFG); + if (wait_for_bit_le32((const void *)(BASE_DEVCPU_GCB + GCB_PHY_CFG) + + PHY_STAT, PHY_STAT_SUPERVISOR_COMPLETE, + true, 2000, false)) { + pr_err("Timeout in phy reset\n"); + } +} + +static void servalt_cpu_capture_setup(struct servalt_private *priv) +{ + /* ASM: No preamble and IFH prefix on CPU injected frames */ + writel(ASM_CFG_PORT_NO_PREAMBLE_ENA | + ASM_CFG_PORT_INJ_FORMAT_CFG(1), + priv->regs[ASM] + ASM_CFG_PORT(CPU_PORT)); + + /* Set Manual injection via DEVCPU_QS registers for CPU queue 0 */ + writel(0x5, priv->regs[QS] + QS_INJ_GRP_CFG(0)); + + /* Set Manual extraction via DEVCPU_QS registers for CPU queue 0 */ + writel(0x7, priv->regs[QS] + QS_XTR_GRP_CFG(0)); + + /* Enable CPU port for any frame transfer */ + setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(CPU_PORT), + QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA); + + /* Send a copy to CPU when found as forwarding entry */ + setbits_le32(priv->regs[ANA_L2] + ANA_L2_COMMON_FWD_CFG, + ANA_L2_COMMON_FWD_CFG_CPU_DMAC_COPY_ENA); +} + +static void servalt_port_init(struct servalt_private *priv, int port) +{ + void __iomem *regs = priv->regs[port]; + + /* Enable PCS */ + writel(DEV_PCS1G_CFG_PCS1G_CFG_PCS_ENA, + regs + DEV_PCS1G_CFG_PCS1G_CFG); + + /* Disable Signal Detect */ + writel(0, regs + DEV_PCS1G_CFG_PCS1G_SD); + + /* Enable MAC RX and TX */ + writel(DEV_MAC_CFG_MAC_ENA_RX_ENA | + DEV_MAC_CFG_MAC_ENA_TX_ENA, + regs + DEV_MAC_CFG_MAC_ENA); + + /* Clear sgmii_mode_ena */ + writel(0, regs + DEV_PCS1G_CFG_PCS1G_MODE); + + /* + * Clear sw_resolve_ena(bit 0) and set adv_ability to + * something meaningful just in case + */ + writel(DEV_PCS1G_CFG_PCS1G_ANEG_ADV_ABILITY(0x20), + regs + DEV_PCS1G_CFG_PCS1G_ANEG); + + /* Set MAC IFG Gaps */ + writel(DEV_MAC_CFG_MAC_IFG_TX_IFG(4) | + DEV_MAC_CFG_MAC_IFG_RX_IFG1(5) | + DEV_MAC_CFG_MAC_IFG_RX_IFG2(1), + regs + DEV_MAC_CFG_MAC_IFG); + + /* Set link speed and release all resets */ + writel(DEV_DEV_CFG_DEV_RST_CTRL_SPEED_SEL(2), + regs + DEV_DEV_CFG_DEV_RST_CTRL); + + /* Make VLAN aware for CPU traffic */ + writel(ANA_CL_PORT_VLAN_CFG_AWARE_ENA | + ANA_CL_PORT_VLAN_CFG_POP_CNT(1) | + MAC_VID, + priv->regs[ANA_CL] + ANA_CL_PORT_VLAN_CFG(port)); + + /* Enable CPU port for any frame transfer */ + setbits_le32(priv->regs[QFWD] + QFWD_SYSTEM_SWITCH_PORT_MODE(port), + QFWD_SYSTEM_SWITCH_PORT_MODE_PORT_ENA); +} + +static int ram_init(u32 val, void __iomem *addr) +{ + writel(val, addr); + + if (wait_for_bit_le32(addr, BIT(1), false, 2000, false)) { + printf("Timeout in memory reset, reg = 0x%08x\n", val); + return 1; + } + + return 0; +} + +static int servalt_switch_init(struct servalt_private *priv) +{ + /* Initialize memories */ + ram_init(0x3, priv->regs[QSYS] + QSYS_RAM_CTRL_RAM_INIT); + ram_init(0x3, priv->regs[ASM] + ASM_RAM_CTRL_RAM_INIT); + ram_init(0x3, priv->regs[ANA_AC] + ANA_AC_RAM_CTRL_RAM_INIT); + ram_init(0x3, priv->regs[REW] + REW_RAM_CTRL_RAM_INIT); + + /* Reset counters */ + writel(0x1, priv->regs[ANA_AC] + ANA_AC_STAT_GLOBAL_CFG_PORT_RESET); + writel(0x1, priv->regs[ASM] + ASM_CFG_STAT_CFG); + + /* Enable switch-core and queue system */ + writel(0x1, priv->regs[QSYS] + QSYS_SYSTEM_RESET_CFG); + + return 0; +} + +static void servalt_switch_config(struct servalt_private *priv) +{ + writel(0x55555555, priv->regs[QSYS] + QSYS_CALCFG_CAL_AUTO); + + writel(readl(priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL) | + QSYS_CALCFG_CAL_CTRL_CAL_MODE(8), + priv->regs[QSYS] + QSYS_CALCFG_CAL_CTRL); +} + +static int servalt_initialize(struct servalt_private *priv) +{ + int ret, i; + + /* Initialize switch memories, enable core */ + ret = servalt_switch_init(priv); + if (ret) + return ret; + + servalt_switch_config(priv); + + for (i = 0; i < MAX_PORT; i++) + servalt_port_init(priv, i); + + servalt_cpu_capture_setup(priv); + + return 0; +} + +static inline +int servalt_vlant_wait_for_completion(struct servalt_private *priv) +{ + if (wait_for_bit_le32(priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL, + LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT, + false, 2000, false)) + return -ETIMEDOUT; + + return 0; +} + +static int servalt_mac_table_add(struct servalt_private *priv, + const unsigned char mac[ETH_ALEN], int pgid) +{ + u32 macl = 0, mach = 0; + + /* + * Set the MAC address to handle and the vlan associated in a format + * understood by the hardware. + */ + mach |= MAC_VID << 16; + mach |= ((u32)mac[0]) << 8; + mach |= ((u32)mac[1]) << 0; + macl |= ((u32)mac[2]) << 24; + macl |= ((u32)mac[3]) << 16; + macl |= ((u32)mac[4]) << 8; + macl |= ((u32)mac[5]) << 0; + + writel(mach, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG0); + writel(macl, priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG1); + + writel(LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_ADDR(pgid) | + LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_TYPE(0x3) | + LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_COPY | + LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_CPU_QU(0) | + LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_VLD | + LRN_COMMON_MAC_ACCESS_CFG2_MAC_ENTRY_LOCKED, + priv->regs[LRN] + LRN_COMMON_MAC_ACCESS_CFG2); + + writel(LRN_COMMON_ACCESS_CTRL_MAC_TABLE_ACCESS_SHOT, + priv->regs[LRN] + LRN_COMMON_ACCESS_CTRL); + + return servalt_vlant_wait_for_completion(priv); +} + +static int servalt_write_hwaddr(struct udevice *dev) +{ + struct servalt_private *priv = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_platdata(dev); + + return servalt_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST); +} + +static int servalt_start(struct udevice *dev) +{ + struct servalt_private *priv = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_platdata(dev); + const unsigned char mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, + 0xff }; + int ret; + + ret = servalt_initialize(priv); + if (ret) + return ret; + + /* Set MAC address tables entries for CPU redirection */ + ret = servalt_mac_table_add(priv, mac, PGID_BROADCAST); + if (ret) + return ret; + + ret = servalt_mac_table_add(priv, pdata->enetaddr, PGID_UNICAST); + if (ret) + return ret; + + return 0; +} + +static void servalt_stop(struct udevice *dev) +{ +} + +static int servalt_send(struct udevice *dev, void *packet, int length) +{ + struct servalt_private *priv = dev_get_priv(dev); + u32 ifh[IFH_LEN]; + u32 *buf = packet; + + memset(ifh, '\0', IFH_LEN * 4); + + /* Set DST PORT_MASK */ + ifh[0] = htonl(0); + ifh[1] = htonl(0x1FFFFF); + ifh[2] = htonl(~0); + /* Set DST_MODE to INJECT and UPDATE_FCS */ + ifh[5] = htonl(0x4c0); + + return mscc_send(priv->regs[QS], servalt_regs_qs, + ifh, IFH_LEN, buf, length); +} + +static int servalt_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct servalt_private *priv = dev_get_priv(dev); + u32 *rxbuf = (u32 *)net_rx_packets[0]; + int byte_cnt = 0; + + byte_cnt = mscc_recv(priv->regs[QS], servalt_regs_qs, rxbuf, IFH_LEN, + false); + + *packetp = net_rx_packets[0]; + + return byte_cnt; +} + +static struct mii_dev *get_mdiobus(phys_addr_t base, unsigned long size) +{ + int i = 0; + + for (i = 0; i < SERVALT_MIIM_BUS_COUNT; ++i) + if (miim[i].miim_base == base && miim[i].miim_size == size) + return miim[i].bus; + + return NULL; +} + +static void add_port_entry(struct servalt_private *priv, size_t index, + size_t phy_addr, struct mii_dev *bus) +{ + priv->ports[index].phy_addr = phy_addr; + priv->ports[index].bus = bus; +} + +static int servalt_probe(struct udevice *dev) +{ + struct servalt_private *priv = dev_get_priv(dev); + int i; + struct resource res; + fdt32_t faddr; + phys_addr_t addr_base; + unsigned long addr_size; + ofnode eth_node, node, mdio_node; + size_t phy_addr; + struct mii_dev *bus; + struct ofnode_phandle_args phandle; + + if (!priv) + return -EINVAL; + + /* Get registers and map them to the private structure */ + for (i = 0; i < ARRAY_SIZE(regs_names); i++) { + priv->regs[i] = dev_remap_addr_name(dev, regs_names[i]); + if (!priv->regs[i]) { + debug + ("Error can't get regs base addresses for %s\n", + regs_names[i]); + return -ENOMEM; + } + } + + /* Initialize miim buses */ + memset(&miim, 0x0, sizeof(struct mscc_miim_dev) * + SERVALT_MIIM_BUS_COUNT); + + /* iterate all the ports and find out on which bus they are */ + i = 0; + eth_node = dev_read_first_subnode(dev); + for (node = ofnode_first_subnode(eth_node); + ofnode_valid(node); + node = ofnode_next_subnode(node)) { + if (ofnode_read_resource(node, 0, &res)) + return -ENOMEM; + i = res.start; + + ofnode_parse_phandle_with_args(node, "phy-handle", NULL, 0, 0, + &phandle); + + /* Get phy address on mdio bus */ + if (ofnode_read_resource(phandle.node, 0, &res)) + return -ENOMEM; + phy_addr = res.start; + + /* Get mdio node */ + mdio_node = ofnode_get_parent(phandle.node); + + if (ofnode_read_resource(mdio_node, 0, &res)) + return -ENOMEM; + faddr = cpu_to_fdt32(res.start); + + addr_base = ofnode_translate_address(mdio_node, &faddr); + addr_size = res.end - res.start; + + /* If the bus is new then create a new bus */ + if (!get_mdiobus(addr_base, addr_size)) + priv->bus[miim_count] = + servalt_mdiobus_init(addr_base, addr_size); + + /* Connect mdio bus with the port */ + bus = get_mdiobus(addr_base, addr_size); + add_port_entry(priv, i, phy_addr, bus); + } + + mscc_phy_reset(); + + for (i = 0; i < MAX_PORT; i++) { + if (!priv->ports[i].bus) + continue; + + phy_connect(priv->ports[i].bus, priv->ports[i].phy_addr, dev, + PHY_INTERFACE_MODE_NONE); + } + + return 0; +} + +static int servalt_remove(struct udevice *dev) +{ + struct servalt_private *priv = dev_get_priv(dev); + int i; + + for (i = 0; i < SERVALT_MIIM_BUS_COUNT; i++) { + mdio_unregister(priv->bus[i]); + mdio_free(priv->bus[i]); + } + + return 0; +} + +static const struct eth_ops servalt_ops = { + .start = servalt_start, + .stop = servalt_stop, + .send = servalt_send, + .recv = servalt_recv, + .write_hwaddr = servalt_write_hwaddr, +}; + +static const struct udevice_id mscc_servalt_ids[] = { + {.compatible = "mscc,vsc7437-switch" }, + { /* Sentinel */ } +}; + +U_BOOT_DRIVER(servalt) = { + .name = "servalt-switch", + .id = UCLASS_ETH, + .of_match = mscc_servalt_ids, + .probe = servalt_probe, + .remove = servalt_remove, + .ops = &servalt_ops, + .priv_auto_alloc_size = sizeof(struct servalt_private), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), +}; diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 32bbf41dd1f..102fb91fffd 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -174,4 +174,12 @@ config KEYSTONE_USB_PHY This PHY is found on some Keystone (K2) devices supporting USB. +config MT76X8_USB_PHY + bool "MediaTek MT76x8 (7628/88) USB PHY support" + depends on PHY + help + Support the USB PHY in MT76x8 SoCs + + This PHY is found on MT76x8 devices supporting USB. + endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 099551d6930..b55917bce1a 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -19,3 +19,4 @@ obj-$(CONFIG_MESON_GXL_USB_PHY) += meson-gxl-usb2.o meson-gxl-usb3.o obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o obj-$(CONFIG_OMAP_USB2_PHY) += omap-usb2-phy.o obj-$(CONFIG_KEYSTONE_USB_PHY) += keystone-usb-phy.o +obj-$(CONFIG_MT76X8_USB_PHY) += mt76x8-usb-phy.o diff --git a/drivers/phy/mt76x8-usb-phy.c b/drivers/phy/mt76x8-usb-phy.c new file mode 100644 index 00000000000..268da8ef6c9 --- /dev/null +++ b/drivers/phy/mt76x8-usb-phy.c @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Stefan Roese <sr@denx.de> + * + * Derived from linux/drivers/phy/ralink/phy-ralink-usb.c + * Copyright (C) 2017 John Crispin <john@phrozen.org> + */ + +#include <common.h> +#include <dm.h> +#include <generic-phy.h> +#include <regmap.h> +#include <reset-uclass.h> +#include <syscon.h> +#include <asm/io.h> + +#define RT_SYSC_REG_SYSCFG1 0x014 +#define RT_SYSC_REG_CLKCFG1 0x030 +#define RT_SYSC_REG_USB_PHY_CFG 0x05c + +#define OFS_U2_PHY_AC0 0x800 +#define OFS_U2_PHY_AC1 0x804 +#define OFS_U2_PHY_AC2 0x808 +#define OFS_U2_PHY_ACR0 0x810 +#define OFS_U2_PHY_ACR1 0x814 +#define OFS_U2_PHY_ACR2 0x818 +#define OFS_U2_PHY_ACR3 0x81C +#define OFS_U2_PHY_ACR4 0x820 +#define OFS_U2_PHY_AMON0 0x824 +#define OFS_U2_PHY_DCR0 0x860 +#define OFS_U2_PHY_DCR1 0x864 +#define OFS_U2_PHY_DTM0 0x868 +#define OFS_U2_PHY_DTM1 0x86C + +#define RT_RSTCTRL_UDEV BIT(25) +#define RT_RSTCTRL_UHST BIT(22) +#define RT_SYSCFG1_USB0_HOST_MODE BIT(10) + +#define MT7620_CLKCFG1_UPHY0_CLK_EN BIT(25) +#define MT7620_CLKCFG1_UPHY1_CLK_EN BIT(22) +#define RT_CLKCFG1_UPHY1_CLK_EN BIT(20) +#define RT_CLKCFG1_UPHY0_CLK_EN BIT(18) + +#define USB_PHY_UTMI_8B60M BIT(1) +#define UDEV_WAKEUP BIT(0) + +struct mt76x8_usb_phy { + u32 clk; + void __iomem *base; + struct regmap *sysctl; +}; + +static void u2_phy_w32(struct mt76x8_usb_phy *phy, u32 val, u32 reg) +{ + writel(val, phy->base + reg); +} + +static u32 u2_phy_r32(struct mt76x8_usb_phy *phy, u32 reg) +{ + return readl(phy->base + reg); +} + +static void mt76x8_usb_phy_init(struct mt76x8_usb_phy *phy) +{ + u2_phy_r32(phy, OFS_U2_PHY_AC2); + u2_phy_r32(phy, OFS_U2_PHY_ACR0); + u2_phy_r32(phy, OFS_U2_PHY_DCR0); + + u2_phy_w32(phy, 0x00ffff02, OFS_U2_PHY_DCR0); + u2_phy_r32(phy, OFS_U2_PHY_DCR0); + u2_phy_w32(phy, 0x00555502, OFS_U2_PHY_DCR0); + u2_phy_r32(phy, OFS_U2_PHY_DCR0); + u2_phy_w32(phy, 0x00aaaa02, OFS_U2_PHY_DCR0); + u2_phy_r32(phy, OFS_U2_PHY_DCR0); + u2_phy_w32(phy, 0x00000402, OFS_U2_PHY_DCR0); + u2_phy_r32(phy, OFS_U2_PHY_DCR0); + u2_phy_w32(phy, 0x0048086a, OFS_U2_PHY_AC0); + u2_phy_w32(phy, 0x4400001c, OFS_U2_PHY_AC1); + u2_phy_w32(phy, 0xc0200000, OFS_U2_PHY_ACR3); + u2_phy_w32(phy, 0x02000000, OFS_U2_PHY_DTM0); +} + +static int mt76x8_usb_phy_power_on(struct phy *_phy) +{ + struct mt76x8_usb_phy *phy = dev_get_priv(_phy->dev); + u32 t; + + /* enable the phy */ + regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1, + phy->clk, phy->clk); + + /* setup host mode */ + regmap_update_bits(phy->sysctl, RT_SYSC_REG_SYSCFG1, + RT_SYSCFG1_USB0_HOST_MODE, + RT_SYSCFG1_USB0_HOST_MODE); + + /* + * The SDK kernel had a delay of 100ms. however on device + * testing showed that 10ms is enough + */ + mdelay(10); + + if (phy->base) + mt76x8_usb_phy_init(phy); + + /* print some status info */ + regmap_read(phy->sysctl, RT_SYSC_REG_USB_PHY_CFG, &t); + printf("remote usb device wakeup %s\n", + (t & UDEV_WAKEUP) ? "enabled" : "disabled"); + if (t & USB_PHY_UTMI_8B60M) + printf("UTMI 8bit 60MHz\n"); + else + printf("UTMI 16bit 30MHz\n"); + + return 0; +} + +static int mt76x8_usb_phy_power_off(struct phy *_phy) +{ + struct mt76x8_usb_phy *phy = dev_get_priv(_phy->dev); + + /* disable the phy */ + regmap_update_bits(phy->sysctl, RT_SYSC_REG_CLKCFG1, + phy->clk, 0); + + return 0; +} + +static int mt76x8_usb_phy_probe(struct udevice *dev) +{ + struct mt76x8_usb_phy *phy = dev_get_priv(dev); + + phy->sysctl = syscon_regmap_lookup_by_phandle(dev, "ralink,sysctl"); + if (IS_ERR(phy->sysctl)) + return PTR_ERR(phy->sysctl); + + phy->base = dev_read_addr_ptr(dev); + if (!phy->base) + return -EINVAL; + + return 0; +} + +static struct phy_ops mt76x8_usb_phy_ops = { + .power_on = mt76x8_usb_phy_power_on, + .power_off = mt76x8_usb_phy_power_off, +}; + +static const struct udevice_id mt76x8_usb_phy_ids[] = { + { .compatible = "mediatek,mt7628-usbphy" }, + { } +}; + +U_BOOT_DRIVER(mt76x8_usb_phy) = { + .name = "mt76x8_usb_phy", + .id = UCLASS_PHY, + .of_match = mt76x8_usb_phy_ids, + .ops = &mt76x8_usb_phy_ops, + .probe = mt76x8_usb_phy_probe, + .priv_auto_alloc_size = sizeof(struct mt76x8_usb_phy), +}; diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index be709f73d7d..a0ac167d145 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -209,6 +209,25 @@ config PINCTRL_STM32 the GPIO definitions and pin control functions for each available multiplex function. +config PINCTRL_STMFX + bool "STMicroelectronics STMFX I2C GPIO expander pinctrl driver" + depends on DM && PINCTRL_FULL + help + I2C driver for STMicroelectronics Multi-Function eXpander (STMFX) + GPIO expander. + Supports pin multiplexing control on stm32 SoCs. + + The driver is controlled by a device tree node which contains both + the GPIO definitions and pin control functions for each available + multiplex function. + +config SPL_PINCTRL_STMFX + bool "STMicroelectronics STMFX I2C GPIO expander pinctrl driver in SPL" + depends on SPL_PINCTRL_FULL + help + This option is an SPL-variant of the SPL_PINCTRL_STMFX option. + See the help of PINCTRL_STMFX for details. + config ASPEED_AST2500_PINCTRL bool "Aspeed AST2500 pin control driver" depends on DM && PINCTRL_GENERIC && ASPEED_AST2500 diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index e2c2b159d8c..4b080b74dcd 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -22,4 +22,5 @@ obj-$(CONFIG_ARCH_MVEBU) += mvebu/ obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o obj-$(CONFIG_PINCTRL_STI) += pinctrl-sti.o obj-$(CONFIG_PINCTRL_STM32) += pinctrl_stm32.o +obj-$(CONFIG_$(SPL_)PINCTRL_STMFX) += pinctrl-stmfx.o obj-y += broadcom/ diff --git a/drivers/pinctrl/ath79/Makefile b/drivers/pinctrl/ath79/Makefile index 1daa2123a14..c7d1e44882e 100644 --- a/drivers/pinctrl/ath79/Makefile +++ b/drivers/pinctrl/ath79/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0+ obj-$(CONFIG_PINCTRL_AR933X) += pinctrl_ar933x.o -obj-$(CONFIG_PINCTRL_QCA953x) += pinctrl_qca953x.o +obj-$(CONFIG_PINCTRL_QCA953X) += pinctrl_qca953x.o diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c new file mode 100644 index 00000000000..5431df9813a --- /dev/null +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -0,0 +1,431 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + * + * Driver for STMicroelectronics Multi-Function eXpander (STMFX) GPIO expander + * based on Linux driver : pinctrl/pinctrl-stmfx.c + */ +#include <common.h> +#include <dm.h> +#include <i2c.h> +#include <asm/gpio.h> +#include <dm/device.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <dm/pinctrl.h> +#include <linux/bitfield.h> +#include <power/regulator.h> + +/* STMFX pins = GPIO[15:0] + aGPIO[7:0] */ +#define STMFX_MAX_GPIO 16 +#define STMFX_MAX_AGPIO 8 + +/* General */ +#define STMFX_REG_CHIP_ID 0x00 /* R */ +#define STMFX_REG_FW_VERSION_MSB 0x01 /* R */ +#define STMFX_REG_FW_VERSION_LSB 0x02 /* R */ +#define STMFX_REG_SYS_CTRL 0x40 /* RW */ + +/* MFX boot time is around 10ms, so after reset, we have to wait this delay */ +#define STMFX_BOOT_TIME_MS 10 + +/* GPIOs expander */ +/* GPIO_STATE1 0x10, GPIO_STATE2 0x11, GPIO_STATE3 0x12 */ +#define STMFX_REG_GPIO_STATE 0x10 /* R */ +/* GPIO_DIR1 0x60, GPIO_DIR2 0x61, GPIO_DIR3 0x63 */ +#define STMFX_REG_GPIO_DIR 0x60 /* RW */ +/* GPIO_TYPE1 0x64, GPIO_TYPE2 0x65, GPIO_TYPE3 0x66 */ +#define STMFX_REG_GPIO_TYPE 0x64 /* RW */ +/* GPIO_PUPD1 0x68, GPIO_PUPD2 0x69, GPIO_PUPD3 0x6A */ +#define STMFX_REG_GPIO_PUPD 0x68 /* RW */ +/* GPO_SET1 0x6C, GPO_SET2 0x6D, GPO_SET3 0x6E */ +#define STMFX_REG_GPO_SET 0x6C /* RW */ +/* GPO_CLR1 0x70, GPO_CLR2 0x71, GPO_CLR3 0x72 */ +#define STMFX_REG_GPO_CLR 0x70 /* RW */ + +/* STMFX_REG_CHIP_ID bitfields */ +#define STMFX_REG_CHIP_ID_MASK GENMASK(7, 0) + +/* STMFX_REG_SYS_CTRL bitfields */ +#define STMFX_REG_SYS_CTRL_GPIO_EN BIT(0) +#define STMFX_REG_SYS_CTRL_ALTGPIO_EN BIT(3) +#define STMFX_REG_SYS_CTRL_SWRST BIT(7) + +#define NR_GPIO_REGS 3 +#define NR_GPIOS_PER_REG 8 +#define get_reg(offset) ((offset) / NR_GPIOS_PER_REG) +#define get_shift(offset) ((offset) % NR_GPIOS_PER_REG) +#define get_mask(offset) (BIT(get_shift(offset))) + +struct stmfx_pinctrl { + struct udevice *gpio; +}; + +static int stmfx_read(struct udevice *dev, uint offset) +{ + return dm_i2c_reg_read(dev_get_parent(dev), offset); +} + +static int stmfx_write(struct udevice *dev, uint offset, unsigned int val) +{ + return dm_i2c_reg_write(dev_get_parent(dev), offset, val); +} + +static int stmfx_gpio_get(struct udevice *dev, unsigned int offset) +{ + u32 reg = STMFX_REG_GPIO_STATE + get_reg(offset); + u32 mask = get_mask(offset); + int ret; + + ret = stmfx_read(dev, reg); + + return ret < 0 ? ret : !!(ret & mask); +} + +static int stmfx_gpio_set(struct udevice *dev, unsigned int offset, int value) +{ + u32 reg = value ? STMFX_REG_GPO_SET : STMFX_REG_GPO_CLR; + u32 mask = get_mask(offset); + + return stmfx_write(dev, reg + get_reg(offset), mask); +} + +static int stmfx_gpio_get_function(struct udevice *dev, unsigned int offset) +{ + u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset); + u32 mask = get_mask(offset); + int ret; + + ret = stmfx_read(dev, reg); + + if (ret < 0) + return ret; + /* On stmfx, gpio pins direction is (0)input, (1)output. */ + + return ret & mask ? GPIOF_OUTPUT : GPIOF_INPUT; +} + +static int stmfx_gpio_direction_input(struct udevice *dev, unsigned int offset) +{ + u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset); + u32 mask = get_mask(offset); + int ret; + + ret = stmfx_read(dev, reg); + if (ret < 0) + return ret; + + ret &= ~mask; + + return stmfx_write(dev, reg, ret & ~mask); +} + +static int stmfx_gpio_direction_output(struct udevice *dev, + unsigned int offset, int value) +{ + u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset); + u32 mask = get_mask(offset); + int ret; + + ret = stmfx_gpio_set(dev, offset, value); + if (ret < 0) + return ret; + + ret = stmfx_read(dev, reg); + if (ret < 0) + return ret; + + return stmfx_write(dev, reg, ret | mask); +} + +static int stmfx_gpio_probe(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct ofnode_phandle_args args; + u8 sys_ctrl; + + uc_priv->bank_name = "stmfx"; + uc_priv->gpio_count = STMFX_MAX_GPIO + STMFX_MAX_AGPIO; + if (!dev_read_phandle_with_args(dev, "gpio-ranges", + NULL, 3, 0, &args)) { + uc_priv->gpio_count = args.args[2]; + } + + /* enable GPIO function */ + sys_ctrl = STMFX_REG_SYS_CTRL_GPIO_EN; + if (uc_priv->gpio_count > STMFX_MAX_GPIO) + sys_ctrl |= STMFX_REG_SYS_CTRL_ALTGPIO_EN; + stmfx_write(dev, STMFX_REG_SYS_CTRL, sys_ctrl); + + return 0; +} + +static const struct dm_gpio_ops stmfx_gpio_ops = { + .set_value = stmfx_gpio_set, + .get_value = stmfx_gpio_get, + .get_function = stmfx_gpio_get_function, + .direction_input = stmfx_gpio_direction_input, + .direction_output = stmfx_gpio_direction_output, +}; + +U_BOOT_DRIVER(stmfx_gpio) = { + .name = "stmfx-gpio", + .id = UCLASS_GPIO, + .probe = stmfx_gpio_probe, + .ops = &stmfx_gpio_ops, +}; + +#if CONFIG_IS_ENABLED(PINCONF) +static const struct pinconf_param stmfx_pinctrl_conf_params[] = { + { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, + { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 0 }, + { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 0 }, + { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 0 }, + { "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 }, + { "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 }, + { "output-high", PIN_CONFIG_OUTPUT, 1 }, + { "output-low", PIN_CONFIG_OUTPUT, 0 }, +}; + +static int stmfx_pinctrl_set_pupd(struct udevice *dev, + unsigned int pin, u32 pupd) +{ + u8 reg = STMFX_REG_GPIO_PUPD + get_reg(pin); + u32 mask = get_mask(pin); + int ret; + + ret = stmfx_read(dev, reg); + if (ret < 0) + return ret; + ret = (ret & ~mask) | (pupd ? mask : 0); + + return stmfx_write(dev, reg, ret); +} + +static int stmfx_pinctrl_set_type(struct udevice *dev, + unsigned int pin, u32 type) +{ + u8 reg = STMFX_REG_GPIO_TYPE + get_reg(pin); + u32 mask = get_mask(pin); + int ret; + + ret = stmfx_read(dev, reg); + if (ret < 0) + return ret; + ret = (ret & ~mask) | (type ? mask : 0); + + return stmfx_write(dev, reg, ret); +} + +static int stmfx_pinctrl_conf_set(struct udevice *dev, unsigned int pin, + unsigned int param, unsigned int arg) +{ + int ret, dir; + struct stmfx_pinctrl *plat = dev_get_platdata(dev); + + dir = stmfx_gpio_get_function(plat->gpio, pin); + + if (dir < 0) + return dir; + + switch (param) { + case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_DOWN: + ret = stmfx_pinctrl_set_pupd(dev, pin, 0); + break; + case PIN_CONFIG_BIAS_PULL_UP: + ret = stmfx_pinctrl_set_pupd(dev, pin, 1); + break; + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + if (dir == GPIOF_OUTPUT) + ret = stmfx_pinctrl_set_type(dev, pin, 1); + else + ret = stmfx_pinctrl_set_type(dev, pin, 0); + break; + case PIN_CONFIG_DRIVE_PUSH_PULL: + if (dir == GPIOF_OUTPUT) + ret = stmfx_pinctrl_set_type(dev, pin, 0); + else + ret = stmfx_pinctrl_set_type(dev, pin, 1); + break; + case PIN_CONFIG_OUTPUT: + ret = stmfx_gpio_direction_output(plat->gpio, pin, arg); + break; + default: + return -ENOTSUPP; + } + + return ret; +} +#endif + +static int stmfx_pinctrl_get_pins_count(struct udevice *dev) +{ + struct stmfx_pinctrl *plat = dev_get_platdata(dev); + struct gpio_dev_priv *uc_priv; + + uc_priv = dev_get_uclass_priv(plat->gpio); + + return uc_priv->gpio_count; +} + +/* + * STMFX pins[15:0] are called "gpio[15:0]" + * and STMFX pins[23:16] are called "agpio[7:0]" + */ +#define MAX_PIN_NAME_LEN 7 +static char pin_name[MAX_PIN_NAME_LEN]; +static const char *stmfx_pinctrl_get_pin_name(struct udevice *dev, + unsigned int selector) +{ + if (selector < STMFX_MAX_GPIO) + snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector); + else + snprintf(pin_name, MAX_PIN_NAME_LEN, "agpio%u", selector - 16); + return pin_name; +} + +static int stmfx_pinctrl_get_pin_muxing(struct udevice *dev, + unsigned int selector, + char *buf, int size) +{ + struct stmfx_pinctrl *plat = dev_get_platdata(dev); + int func; + + func = stmfx_gpio_get_function(plat->gpio, selector); + if (func < 0) + return func; + + snprintf(buf, size, "%s", func == GPIOF_INPUT ? "input" : "output"); + + return 0; +} + +static int stmfx_pinctrl_bind(struct udevice *dev) +{ + struct stmfx_pinctrl *plat = dev_get_platdata(dev); + + return device_bind_driver_to_node(dev->parent, + "stmfx-gpio", "stmfx-gpio", + dev_ofnode(dev), &plat->gpio); +}; + +static int stmfx_pinctrl_probe(struct udevice *dev) +{ + struct stmfx_pinctrl *plat = dev_get_platdata(dev); + + return device_probe(plat->gpio); +}; + +const struct pinctrl_ops stmfx_pinctrl_ops = { + .get_pins_count = stmfx_pinctrl_get_pins_count, + .get_pin_name = stmfx_pinctrl_get_pin_name, + .set_state = pinctrl_generic_set_state, + .get_pin_muxing = stmfx_pinctrl_get_pin_muxing, +#if CONFIG_IS_ENABLED(PINCONF) + .pinconf_set = stmfx_pinctrl_conf_set, + .pinconf_num_params = ARRAY_SIZE(stmfx_pinctrl_conf_params), + .pinconf_params = stmfx_pinctrl_conf_params, +#endif +}; + +static const struct udevice_id stmfx_pinctrl_match[] = { + { .compatible = "st,stmfx-0300-pinctrl", }, +}; + +U_BOOT_DRIVER(stmfx_pinctrl) = { + .name = "stmfx-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(stmfx_pinctrl_match), + .bind = stmfx_pinctrl_bind, + .probe = stmfx_pinctrl_probe, + .ops = &stmfx_pinctrl_ops, + .platdata_auto_alloc_size = sizeof(struct stmfx_pinctrl), +}; + +static int stmfx_chip_init(struct udevice *dev) +{ + u8 id; + u8 version[2]; + int ret; + struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); + + id = dm_i2c_reg_read(dev, STMFX_REG_CHIP_ID); + if (id < 0) { + dev_err(dev, "error reading chip id: %d\n", id); + return ret; + } + /* + * Check that ID is the complement of the I2C address: + * STMFX I2C address follows the 7-bit format (MSB), that's why + * client->addr is shifted. + * + * STMFX_I2C_ADDR| STMFX | Linux + * input pin | I2C device address | I2C device address + *--------------------------------------------------------- + * 0 | b: 1000 010x h:0x84 | 0x42 + * 1 | b: 1000 011x h:0x86 | 0x43 + */ + if (FIELD_GET(STMFX_REG_CHIP_ID_MASK, ~id) != (chip->chip_addr << 1)) { + dev_err(dev, "unknown chip id: %#x\n", id); + return -EINVAL; + } + + ret = dm_i2c_read(dev, STMFX_REG_FW_VERSION_MSB, + version, sizeof(version)); + if (ret) { + dev_err(dev, "error reading fw version: %d\n", ret); + return ret; + } + + dev_info(dev, "STMFX id: %#x, fw version: %x.%02x\n", + id, version[0], version[1]); + + ret = dm_i2c_reg_read(dev, STMFX_REG_SYS_CTRL); + + if (ret < 0) + return ret; + + ret = dm_i2c_reg_write(dev, STMFX_REG_SYS_CTRL, + ret | STMFX_REG_SYS_CTRL_SWRST); + if (ret) + return ret; + + mdelay(STMFX_BOOT_TIME_MS); + + return ret; +} + +static int stmfx_probe(struct udevice *dev) +{ + struct udevice *vdd; + int ret; + + ret = device_get_supply_regulator(dev, "vdd-supply", &vdd); + if (ret && ret != -ENOENT) { + dev_err(dev, "vdd regulator error:%d\n", ret); + return ret; + } + if (!ret) { + ret = regulator_set_enable(vdd, true); + if (ret) { + dev_err(dev, "vdd enable failed: %d\n", ret); + return ret; + } + } + + return stmfx_chip_init(dev); +} + +static const struct udevice_id stmfx_match[] = { + { .compatible = "st,stmfx-0300", }, +}; + +U_BOOT_DRIVER(stmfx) = { + .name = "stmfx", + .id = UCLASS_I2C_GENERIC, + .of_match = of_match_ptr(stmfx_match), + .probe = stmfx_probe, + .bind = dm_scan_fdt_dev, +}; diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c index 0e3260afd1e..0e6c559d5ef 100644 --- a/drivers/pinctrl/pinctrl-uclass.c +++ b/drivers/pinctrl/pinctrl-uclass.c @@ -27,28 +27,6 @@ int pinctrl_decode_pin_config(const void *blob, int node) return flags; } -/* - * TODO: this function is temporary for v2019.01. - * It should be renamed to pinctrl_decode_pin_config(), - * the original pinctrl_decode_pin_config() function should - * be removed and all callers of the original function should - * be migrated to use the new one. - */ -int pinctrl_decode_pin_config_dm(struct udevice *dev) -{ - int pinconfig = 0; - - if (dev->uclass->uc_drv->id != UCLASS_PINCONFIG) - return -EINVAL; - - if (dev_read_bool(dev, "bias-pull-up")) - pinconfig |= 1 << PIN_CONFIG_BIAS_PULL_UP; - else if (dev_read_bool(dev, "bias-pull-down")) - pinconfig |= 1 << PIN_CONFIG_BIAS_PULL_DOWN; - - return pinconfig; -} - #if CONFIG_IS_ENABLED(PINCTRL_FULL) /** * pinctrl_config_one() - apply pinctrl settings for a single node @@ -149,6 +127,9 @@ static int pinconfig_post_bind(struct udevice *dev) ofnode_get_property(node, "compatible", &ret); if (ret >= 0) continue; + /* If this node has "gpio-controller" property, skip */ + if (ofnode_read_bool(node, "gpio-controller")) + continue; if (ret != -FDT_ERR_NOTFOUND) return ret; @@ -201,11 +182,14 @@ static int pinctrl_select_state_simple(struct udevice *dev) int ret; /* - * For simplicity, assume the first device of PINCTRL uclass - * is the correct one. This is most likely OK as there is - * usually only one pinctrl device on the system. + * For most system, there is only one pincontroller device. But in + * case of multiple pincontroller devices, probe the one with sequence + * number 0 (defined by alias) to avoid race condition. */ - ret = uclass_get_device(UCLASS_PINCTRL, 0, &pctldev); + ret = uclass_get_device_by_seq(UCLASS_PINCTRL, 0, &pctldev); + if (ret) + /* if not found, get the first one */ + ret = uclass_get_device(UCLASS_PINCTRL, 0, &pctldev); if (ret) return ret; diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 8cf60ebcf3d..b0cd2603543 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -231,10 +231,10 @@ config DM_PMIC_TPS65910 DC-DC converter, 8 LDOs and a RTC. This driver binds the SMPS and LDO pmic children. -config PMIC_STPMU1 - bool "Enable support for STMicroelectronics STPMU1 PMIC" +config PMIC_STPMIC1 + bool "Enable support for STMicroelectronics STPMIC1 PMIC" depends on DM_PMIC && DM_I2C ---help--- - The STPMU1 PMIC provides 4 BUCKs, 6 LDOs, 1 VREF and 2 power switches. + The STPMIC1 PMIC provides 4 BUCKs, 6 LDOs, 1 VREF and 2 power switches. It is accessed via an I2C interface. The device is used with STM32MP1 SoCs. This driver implements register read/write operations. diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 637352ab2b7..ce250cb1555 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -23,7 +23,7 @@ obj-$(CONFIG_DM_PMIC_TPS65910) += pmic_tps65910_dm.o obj-$(CONFIG_$(SPL_)PMIC_PALMAS) += palmas.o obj-$(CONFIG_$(SPL_)PMIC_LP873X) += lp873x.o obj-$(CONFIG_$(SPL_)PMIC_LP87565) += lp87565.o -obj-$(CONFIG_PMIC_STPMU1) += stpmu1.o +obj-$(CONFIG_PMIC_STPMIC1) += stpmic1.o obj-$(CONFIG_POWER_LTC3676) += pmic_ltc3676.o obj-$(CONFIG_POWER_MAX77696) += pmic_max77696.o diff --git a/drivers/power/pmic/stpmic1.c b/drivers/power/pmic/stpmic1.c new file mode 100644 index 00000000000..65296c5fc3a --- /dev/null +++ b/drivers/power/pmic/stpmic1.c @@ -0,0 +1,255 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <i2c.h> +#include <sysreset.h> +#include <dm/device.h> +#include <dm/lists.h> +#include <power/pmic.h> +#include <power/stpmic1.h> + +#define STPMIC1_NUM_OF_REGS 0x100 + +#define STPMIC1_NVM_SIZE 8 +#define STPMIC1_NVM_POLL_TIMEOUT 100000 +#define STPMIC1_NVM_START_ADDRESS 0xf8 + +enum pmic_nvm_op { + SHADOW_READ, + SHADOW_WRITE, + NVM_READ, + NVM_WRITE, +}; + +#if CONFIG_IS_ENABLED(DM_REGULATOR) +static const struct pmic_child_info stpmic1_children_info[] = { + { .prefix = "ldo", .driver = "stpmic1_ldo" }, + { .prefix = "buck", .driver = "stpmic1_buck" }, + { .prefix = "vref_ddr", .driver = "stpmic1_vref_ddr" }, + { .prefix = "pwr_sw", .driver = "stpmic1_pwr_sw" }, + { .prefix = "boost", .driver = "stpmic1_boost" }, + { }, +}; +#endif /* DM_REGULATOR */ + +static int stpmic1_reg_count(struct udevice *dev) +{ + return STPMIC1_NUM_OF_REGS; +} + +static int stpmic1_write(struct udevice *dev, uint reg, const uint8_t *buff, + int len) +{ + int ret; + + ret = dm_i2c_write(dev, reg, buff, len); + if (ret) + dev_err(dev, "%s: failed to write register %#x :%d", + __func__, reg, ret); + + return ret; +} + +static int stpmic1_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +{ + int ret; + + ret = dm_i2c_read(dev, reg, buff, len); + if (ret) + dev_err(dev, "%s: failed to read register %#x : %d", + __func__, reg, ret); + + return ret; +} + +static int stpmic1_bind(struct udevice *dev) +{ +#if CONFIG_IS_ENABLED(DM_REGULATOR) + ofnode regulators_node; + int children; + + regulators_node = dev_read_subnode(dev, "regulators"); + if (!ofnode_valid(regulators_node)) { + dev_dbg(dev, "regulators subnode not found!"); + return -ENXIO; + } + dev_dbg(dev, "found regulators subnode\n"); + + children = pmic_bind_children(dev, regulators_node, + stpmic1_children_info); + if (!children) + dev_dbg(dev, "no child found\n"); +#endif /* DM_REGULATOR */ + + if (CONFIG_IS_ENABLED(SYSRESET)) + return device_bind_driver(dev, "stpmic1-sysreset", + "stpmic1-sysreset", NULL); + + return 0; +} + +static struct dm_pmic_ops stpmic1_ops = { + .reg_count = stpmic1_reg_count, + .read = stpmic1_read, + .write = stpmic1_write, +}; + +static const struct udevice_id stpmic1_ids[] = { + { .compatible = "st,stpmic1" }, + { } +}; + +U_BOOT_DRIVER(pmic_stpmic1) = { + .name = "stpmic1_pmic", + .id = UCLASS_PMIC, + .of_match = stpmic1_ids, + .bind = stpmic1_bind, + .ops = &stpmic1_ops, +}; + +#ifndef CONFIG_SPL_BUILD +static int stpmic1_nvm_rw(u8 addr, u8 *buf, int buf_len, enum pmic_nvm_op op) +{ + struct udevice *dev; + unsigned long timeout; + u8 cmd = STPMIC1_NVM_CMD_READ; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_PMIC, + DM_GET_DRIVER(pmic_stpmic1), &dev); + if (ret) + /* No PMIC on power discrete board */ + return -EOPNOTSUPP; + + if (addr < STPMIC1_NVM_START_ADDRESS) + return -EACCES; + + if (op == SHADOW_READ) + return pmic_read(dev, addr, buf, buf_len); + + if (op == SHADOW_WRITE) + return pmic_write(dev, addr, buf, buf_len); + + if (op == NVM_WRITE) { + cmd = STPMIC1_NVM_CMD_PROGRAM; + + ret = pmic_write(dev, addr, buf, buf_len); + if (ret < 0) + return ret; + } + + ret = pmic_reg_read(dev, STPMIC1_NVM_CR); + if (ret < 0) + return ret; + + ret = pmic_reg_write(dev, STPMIC1_NVM_CR, ret | cmd); + if (ret < 0) + return ret; + + timeout = timer_get_us() + STPMIC1_NVM_POLL_TIMEOUT; + for (;;) { + ret = pmic_reg_read(dev, STPMIC1_NVM_SR); + if (ret < 0) + return ret; + + if (!(ret & STPMIC1_NVM_BUSY)) + break; + + if (time_after(timer_get_us(), timeout)) + break; + } + + if (ret & STPMIC1_NVM_BUSY) + return -ETIMEDOUT; + + if (op == NVM_READ) { + ret = pmic_read(dev, addr, buf, buf_len); + if (ret < 0) + return ret; + } + + return 0; +} + +int stpmic1_shadow_read_byte(u8 addr, u8 *buf) +{ + return stpmic1_nvm_rw(addr, buf, 1, SHADOW_READ); +} + +int stpmic1_shadow_write_byte(u8 addr, u8 *buf) +{ + return stpmic1_nvm_rw(addr, buf, 1, SHADOW_WRITE); +} + +int stpmic1_nvm_read_byte(u8 addr, u8 *buf) +{ + return stpmic1_nvm_rw(addr, buf, 1, NVM_READ); +} + +int stpmic1_nvm_write_byte(u8 addr, u8 *buf) +{ + return stpmic1_nvm_rw(addr, buf, 1, NVM_WRITE); +} + +int stpmic1_nvm_read_all(u8 *buf, int buf_len) +{ + if (buf_len != STPMIC1_NVM_SIZE) + return -EINVAL; + + return stpmic1_nvm_rw(STPMIC1_NVM_START_ADDRESS, + buf, buf_len, NVM_READ); +} + +int stpmic1_nvm_write_all(u8 *buf, int buf_len) +{ + if (buf_len != STPMIC1_NVM_SIZE) + return -EINVAL; + + return stpmic1_nvm_rw(STPMIC1_NVM_START_ADDRESS, + buf, buf_len, NVM_WRITE); +} +#endif /* CONFIG_SPL_BUILD */ + +#ifdef CONFIG_SYSRESET +static int stpmic1_sysreset_request(struct udevice *dev, enum sysreset_t type) +{ + struct udevice *pmic_dev; + int ret; + + if (type != SYSRESET_POWER) + return -EPROTONOSUPPORT; + + ret = uclass_get_device_by_driver(UCLASS_PMIC, + DM_GET_DRIVER(pmic_stpmic1), + &pmic_dev); + + if (ret) + return -EOPNOTSUPP; + + ret = pmic_reg_read(pmic_dev, STPMIC1_MAIN_CR); + if (ret < 0) + return ret; + + ret = pmic_reg_write(pmic_dev, STPMIC1_MAIN_CR, + ret | STPMIC1_SWOFF | STPMIC1_RREQ_EN); + if (ret < 0) + return ret; + + return -EINPROGRESS; +} + +static struct sysreset_ops stpmic1_sysreset_ops = { + .request = stpmic1_sysreset_request, +}; + +U_BOOT_DRIVER(stpmic1_sysreset) = { + .name = "stpmic1-sysreset", + .id = UCLASS_SYSRESET, + .ops = &stpmic1_sysreset_ops, +}; +#endif diff --git a/drivers/power/pmic/stpmu1.c b/drivers/power/pmic/stpmu1.c deleted file mode 100644 index 47af0123328..00000000000 --- a/drivers/power/pmic/stpmu1.c +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -/* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved - */ - -#include <common.h> -#include <dm.h> -#include <errno.h> -#include <i2c.h> -#include <power/pmic.h> -#include <power/stpmu1.h> - -#define STMPU1_NUM_OF_REGS 0x100 - -#ifndef CONFIG_SPL_BUILD -static const struct pmic_child_info stpmu1_children_info[] = { - { .prefix = "ldo", .driver = "stpmu1_ldo" }, - { .prefix = "buck", .driver = "stpmu1_buck" }, - { .prefix = "vref_ddr", .driver = "stpmu1_vref_ddr" }, - { .prefix = "pwr_sw", .driver = "stpmu1_pwr_sw" }, - { .prefix = "boost", .driver = "stpmu1_boost" }, - { }, -}; -#endif /* CONFIG_SPL_BUILD */ - -static int stpmu1_reg_count(struct udevice *dev) -{ - return STMPU1_NUM_OF_REGS; -} - -static int stpmu1_write(struct udevice *dev, uint reg, const uint8_t *buff, - int len) -{ - int ret; - - ret = dm_i2c_write(dev, reg, buff, len); - if (ret) - dev_err(dev, "%s: failed to write register %#x :%d", - __func__, reg, ret); - - return ret; -} - -static int stpmu1_read(struct udevice *dev, uint reg, uint8_t *buff, int len) -{ - int ret; - - ret = dm_i2c_read(dev, reg, buff, len); - if (ret) - dev_err(dev, "%s: failed to read register %#x : %d", - __func__, reg, ret); - - return ret; -} - -static int stpmu1_bind(struct udevice *dev) -{ -#ifndef CONFIG_SPL_BUILD - ofnode regulators_node; - int children; - - regulators_node = dev_read_subnode(dev, "regulators"); - if (!ofnode_valid(regulators_node)) { - dev_dbg(dev, "regulators subnode not found!\n"); - return -ENXIO; - } - dev_dbg(dev, "found regulators subnode\n"); - - children = pmic_bind_children(dev, regulators_node, - stpmu1_children_info); - if (!children) - dev_dbg(dev, "no child found\n"); -#endif /* CONFIG_SPL_BUILD */ - - return 0; -} - -static struct dm_pmic_ops stpmu1_ops = { - .reg_count = stpmu1_reg_count, - .read = stpmu1_read, - .write = stpmu1_write, -}; - -static const struct udevice_id stpmu1_ids[] = { - { .compatible = "st,stpmu1" }, - { } -}; - -U_BOOT_DRIVER(pmic_stpmu1) = { - .name = "stpmu1_pmic", - .id = UCLASS_PMIC, - .of_match = stpmu1_ids, - .bind = stpmu1_bind, - .ops = &stpmu1_ops, -}; diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index 3ed0dd2264a..72dfc48981a 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -244,11 +244,17 @@ config DM_REGULATOR_TPS65910 regulator types of the TPS65910 (BUCK, BOOST and LDO). It implements the get/set api for value and enable. -config DM_REGULATOR_STPMU1 - bool "Enable driver for STPMU1 regulators" - depends on DM_REGULATOR && PMIC_STPMU1 +config DM_REGULATOR_STPMIC1 + bool "Enable driver for STPMIC1 regulators" + depends on DM_REGULATOR && PMIC_STPMIC1 ---help--- - Enable support for the regulator functions of the STPMU1 PMIC. The + Enable support for the regulator functions of the STPMIC1 PMIC. The driver implements get/set api for the various BUCKS and LDOs supported by the PMIC device. This driver is controlled by a device tree node which includes voltage limits. + +config SPL_DM_REGULATOR_STPMIC1 + bool "Enable driver for STPMIC1 regulators in SPL" + depends on SPL_DM_REGULATOR && PMIC_STPMIC1 + help + Enable support for the regulator functions of the STPMIC1 PMIC in SPL. diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile index f617ce723a9..8c1506c88ed 100644 --- a/drivers/power/regulator/Makefile +++ b/drivers/power/regulator/Makefile @@ -24,4 +24,4 @@ obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP873X) += lp873x_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP87565) += lp87565_regulator.o obj-$(CONFIG_$(SPL_)DM_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o obj-$(CONFIG_DM_REGULATOR_TPS65910) += tps65910_regulator.o -obj-$(CONFIG_$(SPL_)DM_REGULATOR_STPMU1) += stpmu1.o +obj-$(CONFIG_$(SPL_)DM_REGULATOR_STPMIC1) += stpmic1.o diff --git a/drivers/power/regulator/stpmic1.c b/drivers/power/regulator/stpmic1.c new file mode 100644 index 00000000000..50ef2a21d18 --- /dev/null +++ b/drivers/power/regulator/stpmic1.c @@ -0,0 +1,672 @@ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +/* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + * Author: Christophe Kerello <christophe.kerello@st.com> + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <power/pmic.h> +#include <power/regulator.h> +#include <power/stpmic1.h> + +struct stpmic1_range { + int min_uv; + int min_sel; + int max_sel; + int step; +}; + +struct stpmic1_output { + const struct stpmic1_range *ranges; + int nbranges; +}; + +#define STPMIC1_MODE(_id, _val, _name) { \ + .id = _id, \ + .register_value = _val, \ + .name = _name, \ +} + +#define STPMIC1_RANGE(_min_uv, _min_sel, _max_sel, _step) { \ + .min_uv = _min_uv, \ + .min_sel = _min_sel, \ + .max_sel = _max_sel, \ + .step = _step, \ +} + +#define STPMIC1_OUTPUT(_ranges, _nbranges) { \ + .ranges = _ranges, \ + .nbranges = _nbranges, \ +} + +static int stpmic1_output_find_uv(int sel, + const struct stpmic1_output *output) +{ + const struct stpmic1_range *range; + int i; + + for (i = 0, range = output->ranges; + i < output->nbranges; i++, range++) { + if (sel >= range->min_sel && sel <= range->max_sel) + return range->min_uv + + (sel - range->min_sel) * range->step; + } + + return -EINVAL; +} + +static int stpmic1_output_find_sel(int uv, + const struct stpmic1_output *output) +{ + const struct stpmic1_range *range; + int i; + + for (i = 0, range = output->ranges; + i < output->nbranges; i++, range++) { + if (uv == range->min_uv && !range->step) + return range->min_sel; + + if (uv >= range->min_uv && + uv <= range->min_uv + + (range->max_sel - range->min_sel) * range->step) + return range->min_sel + + (uv - range->min_uv) / range->step; + } + + return -EINVAL; +} + +/* + * BUCK regulators + */ + +static const struct stpmic1_range buck1_ranges[] = { + STPMIC1_RANGE(725000, 0, 4, 0), + STPMIC1_RANGE(725000, 5, 36, 25000), + STPMIC1_RANGE(1500000, 37, 63, 0), +}; + +static const struct stpmic1_range buck2_ranges[] = { + STPMIC1_RANGE(1000000, 0, 17, 0), + STPMIC1_RANGE(1050000, 18, 19, 0), + STPMIC1_RANGE(1100000, 20, 21, 0), + STPMIC1_RANGE(1150000, 22, 23, 0), + STPMIC1_RANGE(1200000, 24, 25, 0), + STPMIC1_RANGE(1250000, 26, 27, 0), + STPMIC1_RANGE(1300000, 28, 29, 0), + STPMIC1_RANGE(1350000, 30, 31, 0), + STPMIC1_RANGE(1400000, 32, 33, 0), + STPMIC1_RANGE(1450000, 34, 35, 0), + STPMIC1_RANGE(1500000, 36, 63, 0), +}; + +static const struct stpmic1_range buck3_ranges[] = { + STPMIC1_RANGE(1000000, 0, 19, 0), + STPMIC1_RANGE(1100000, 20, 23, 0), + STPMIC1_RANGE(1200000, 24, 27, 0), + STPMIC1_RANGE(1300000, 28, 31, 0), + STPMIC1_RANGE(1400000, 32, 35, 0), + STPMIC1_RANGE(1500000, 36, 55, 100000), + STPMIC1_RANGE(3400000, 56, 63, 0), +}; + +static const struct stpmic1_range buck4_ranges[] = { + STPMIC1_RANGE(600000, 0, 27, 25000), + STPMIC1_RANGE(1300000, 28, 29, 0), + STPMIC1_RANGE(1350000, 30, 31, 0), + STPMIC1_RANGE(1400000, 32, 33, 0), + STPMIC1_RANGE(1450000, 34, 35, 0), + STPMIC1_RANGE(1500000, 36, 60, 100000), + STPMIC1_RANGE(3900000, 61, 63, 0), +}; + +/* BUCK: 1,2,3,4 - voltage ranges */ +static const struct stpmic1_output buck_voltage_range[] = { + STPMIC1_OUTPUT(buck1_ranges, ARRAY_SIZE(buck1_ranges)), + STPMIC1_OUTPUT(buck2_ranges, ARRAY_SIZE(buck2_ranges)), + STPMIC1_OUTPUT(buck3_ranges, ARRAY_SIZE(buck3_ranges)), + STPMIC1_OUTPUT(buck4_ranges, ARRAY_SIZE(buck4_ranges)), +}; + +/* BUCK modes */ +static const struct dm_regulator_mode buck_modes[] = { + STPMIC1_MODE(STPMIC1_PREG_MODE_HP, STPMIC1_PREG_MODE_HP, "HP"), + STPMIC1_MODE(STPMIC1_PREG_MODE_LP, STPMIC1_PREG_MODE_LP, "LP"), +}; + +static int stpmic1_buck_get_uv(struct udevice *dev, int buck) +{ + int sel; + + sel = pmic_reg_read(dev, STPMIC1_BUCKX_MAIN_CR(buck)); + if (sel < 0) + return sel; + + sel &= STPMIC1_BUCK_VOUT_MASK; + sel >>= STPMIC1_BUCK_VOUT_SHIFT; + + return stpmic1_output_find_uv(sel, &buck_voltage_range[buck]); +} + +static int stpmic1_buck_get_value(struct udevice *dev) +{ + return stpmic1_buck_get_uv(dev->parent, dev->driver_data - 1); +} + +static int stpmic1_buck_set_value(struct udevice *dev, int uv) +{ + int sel, buck = dev->driver_data - 1; + + sel = stpmic1_output_find_sel(uv, &buck_voltage_range[buck]); + if (sel < 0) + return sel; + + return pmic_clrsetbits(dev->parent, + STPMIC1_BUCKX_MAIN_CR(buck), + STPMIC1_BUCK_VOUT_MASK, + sel << STPMIC1_BUCK_VOUT_SHIFT); +} + +static int stpmic1_buck_get_enable(struct udevice *dev) +{ + int ret; + + ret = pmic_reg_read(dev->parent, + STPMIC1_BUCKX_MAIN_CR(dev->driver_data - 1)); + if (ret < 0) + return false; + + return ret & STPMIC1_BUCK_ENA ? true : false; +} + +static int stpmic1_buck_set_enable(struct udevice *dev, bool enable) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + int delay = enable ? STPMIC1_DEFAULT_START_UP_DELAY_MS : + STPMIC1_DEFAULT_STOP_DELAY_MS; + int ret, uv; + + /* if regulator is already in the wanted state, nothing to do */ + if (stpmic1_buck_get_enable(dev) == enable) + return 0; + + if (enable) { + uc_pdata = dev_get_uclass_platdata(dev); + uv = stpmic1_buck_get_value(dev); + if (uv < uc_pdata->min_uV || uv > uc_pdata->max_uV) + stpmic1_buck_set_value(dev, uc_pdata->min_uV); + } + + ret = pmic_clrsetbits(dev->parent, + STPMIC1_BUCKX_MAIN_CR(dev->driver_data - 1), + STPMIC1_BUCK_ENA, enable ? STPMIC1_BUCK_ENA : 0); + mdelay(delay); + + return ret; +} + +static int stpmic1_buck_get_mode(struct udevice *dev) +{ + int ret; + + ret = pmic_reg_read(dev->parent, + STPMIC1_BUCKX_MAIN_CR(dev->driver_data - 1)); + if (ret < 0) + return ret; + + return ret & STPMIC1_BUCK_PREG_MODE ? STPMIC1_PREG_MODE_LP : + STPMIC1_PREG_MODE_HP; +} + +static int stpmic1_buck_set_mode(struct udevice *dev, int mode) +{ + return pmic_clrsetbits(dev->parent, + STPMIC1_BUCKX_MAIN_CR(dev->driver_data - 1), + STPMIC1_BUCK_PREG_MODE, + mode ? STPMIC1_BUCK_PREG_MODE : 0); +} + +static int stpmic1_buck_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + + if (!dev->driver_data || dev->driver_data > STPMIC1_MAX_BUCK) + return -EINVAL; + + uc_pdata = dev_get_uclass_platdata(dev); + + uc_pdata->type = REGULATOR_TYPE_BUCK; + uc_pdata->mode = (struct dm_regulator_mode *)buck_modes; + uc_pdata->mode_count = ARRAY_SIZE(buck_modes); + + return 0; +} + +static const struct dm_regulator_ops stpmic1_buck_ops = { + .get_value = stpmic1_buck_get_value, + .set_value = stpmic1_buck_set_value, + .get_enable = stpmic1_buck_get_enable, + .set_enable = stpmic1_buck_set_enable, + .get_mode = stpmic1_buck_get_mode, + .set_mode = stpmic1_buck_set_mode, +}; + +U_BOOT_DRIVER(stpmic1_buck) = { + .name = "stpmic1_buck", + .id = UCLASS_REGULATOR, + .ops = &stpmic1_buck_ops, + .probe = stpmic1_buck_probe, +}; + +/* + * LDO regulators + */ + +static const struct stpmic1_range ldo12_ranges[] = { + STPMIC1_RANGE(1700000, 0, 7, 0), + STPMIC1_RANGE(1700000, 8, 24, 100000), + STPMIC1_RANGE(3300000, 25, 31, 0), +}; + +static const struct stpmic1_range ldo3_ranges[] = { + STPMIC1_RANGE(1700000, 0, 7, 0), + STPMIC1_RANGE(1700000, 8, 24, 100000), + STPMIC1_RANGE(3300000, 25, 30, 0), + /* Sel 31 is special case when LDO3 is in mode sync_source (BUCK2/2) */ +}; + +static const struct stpmic1_range ldo5_ranges[] = { + STPMIC1_RANGE(1700000, 0, 7, 0), + STPMIC1_RANGE(1700000, 8, 30, 100000), + STPMIC1_RANGE(3900000, 31, 31, 0), +}; + +static const struct stpmic1_range ldo6_ranges[] = { + STPMIC1_RANGE(900000, 0, 24, 100000), + STPMIC1_RANGE(3300000, 25, 31, 0), +}; + +/* LDO: 1,2,3,4,5,6 - voltage ranges */ +static const struct stpmic1_output ldo_voltage_range[] = { + STPMIC1_OUTPUT(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)), + STPMIC1_OUTPUT(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)), + STPMIC1_OUTPUT(ldo3_ranges, ARRAY_SIZE(ldo3_ranges)), + STPMIC1_OUTPUT(NULL, 0), + STPMIC1_OUTPUT(ldo5_ranges, ARRAY_SIZE(ldo5_ranges)), + STPMIC1_OUTPUT(ldo6_ranges, ARRAY_SIZE(ldo6_ranges)), +}; + +/* LDO modes */ +static const struct dm_regulator_mode ldo_modes[] = { + STPMIC1_MODE(STPMIC1_LDO_MODE_NORMAL, + STPMIC1_LDO_MODE_NORMAL, "NORMAL"), + STPMIC1_MODE(STPMIC1_LDO_MODE_BYPASS, + STPMIC1_LDO_MODE_BYPASS, "BYPASS"), + STPMIC1_MODE(STPMIC1_LDO_MODE_SINK_SOURCE, + STPMIC1_LDO_MODE_SINK_SOURCE, "SINK SOURCE"), +}; + +static int stpmic1_ldo_get_value(struct udevice *dev) +{ + int sel, ldo = dev->driver_data - 1; + + sel = pmic_reg_read(dev->parent, STPMIC1_LDOX_MAIN_CR(ldo)); + if (sel < 0) + return sel; + + /* ldo4 => 3,3V */ + if (ldo == STPMIC1_LDO4) + return STPMIC1_LDO4_UV; + + sel &= STPMIC1_LDO12356_VOUT_MASK; + sel >>= STPMIC1_LDO12356_VOUT_SHIFT; + + /* ldo3, sel = 31 => BUCK2/2 */ + if (ldo == STPMIC1_LDO3 && sel == STPMIC1_LDO3_DDR_SEL) + return stpmic1_buck_get_uv(dev->parent, STPMIC1_BUCK2) / 2; + + return stpmic1_output_find_uv(sel, &ldo_voltage_range[ldo]); +} + +static int stpmic1_ldo_set_value(struct udevice *dev, int uv) +{ + int sel, ldo = dev->driver_data - 1; + + /* ldo4 => not possible */ + if (ldo == STPMIC1_LDO4) + return -EINVAL; + + sel = stpmic1_output_find_sel(uv, &ldo_voltage_range[ldo]); + if (sel < 0) + return sel; + + return pmic_clrsetbits(dev->parent, + STPMIC1_LDOX_MAIN_CR(ldo), + STPMIC1_LDO12356_VOUT_MASK, + sel << STPMIC1_LDO12356_VOUT_SHIFT); +} + +static int stpmic1_ldo_get_enable(struct udevice *dev) +{ + int ret; + + ret = pmic_reg_read(dev->parent, + STPMIC1_LDOX_MAIN_CR(dev->driver_data - 1)); + if (ret < 0) + return false; + + return ret & STPMIC1_LDO_ENA ? true : false; +} + +static int stpmic1_ldo_set_enable(struct udevice *dev, bool enable) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + int delay = enable ? STPMIC1_DEFAULT_START_UP_DELAY_MS : + STPMIC1_DEFAULT_STOP_DELAY_MS; + int ret, uv; + + /* if regulator is already in the wanted state, nothing to do */ + if (stpmic1_ldo_get_enable(dev) == enable) + return 0; + + if (enable) { + uc_pdata = dev_get_uclass_platdata(dev); + uv = stpmic1_ldo_get_value(dev); + if (uv < uc_pdata->min_uV || uv > uc_pdata->max_uV) + stpmic1_ldo_set_value(dev, uc_pdata->min_uV); + } + + ret = pmic_clrsetbits(dev->parent, + STPMIC1_LDOX_MAIN_CR(dev->driver_data - 1), + STPMIC1_LDO_ENA, enable ? STPMIC1_LDO_ENA : 0); + mdelay(delay); + + return ret; +} + +static int stpmic1_ldo_get_mode(struct udevice *dev) +{ + int ret, ldo = dev->driver_data - 1; + + if (ldo != STPMIC1_LDO3) + return -EINVAL; + + ret = pmic_reg_read(dev->parent, STPMIC1_LDOX_MAIN_CR(ldo)); + if (ret < 0) + return ret; + + if (ret & STPMIC1_LDO3_MODE) + return STPMIC1_LDO_MODE_BYPASS; + + ret &= STPMIC1_LDO12356_VOUT_MASK; + ret >>= STPMIC1_LDO12356_VOUT_SHIFT; + + return ret == STPMIC1_LDO3_DDR_SEL ? STPMIC1_LDO_MODE_SINK_SOURCE : + STPMIC1_LDO_MODE_NORMAL; +} + +static int stpmic1_ldo_set_mode(struct udevice *dev, int mode) +{ + int ret, ldo = dev->driver_data - 1; + + if (ldo != STPMIC1_LDO3) + return -EINVAL; + + ret = pmic_reg_read(dev->parent, STPMIC1_LDOX_MAIN_CR(ldo)); + if (ret < 0) + return ret; + + switch (mode) { + case STPMIC1_LDO_MODE_SINK_SOURCE: + ret &= ~STPMIC1_LDO12356_VOUT_MASK; + ret |= STPMIC1_LDO3_DDR_SEL << STPMIC1_LDO12356_VOUT_SHIFT; + case STPMIC1_LDO_MODE_NORMAL: + ret &= ~STPMIC1_LDO3_MODE; + break; + case STPMIC1_LDO_MODE_BYPASS: + ret |= STPMIC1_LDO3_MODE; + break; + } + + return pmic_reg_write(dev->parent, STPMIC1_LDOX_MAIN_CR(ldo), ret); +} + +static int stpmic1_ldo_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + + if (!dev->driver_data || dev->driver_data > STPMIC1_MAX_LDO) + return -EINVAL; + + uc_pdata = dev_get_uclass_platdata(dev); + + uc_pdata->type = REGULATOR_TYPE_LDO; + if (dev->driver_data - 1 == STPMIC1_LDO3) { + uc_pdata->mode = (struct dm_regulator_mode *)ldo_modes; + uc_pdata->mode_count = ARRAY_SIZE(ldo_modes); + } else { + uc_pdata->mode_count = 0; + } + + return 0; +} + +static const struct dm_regulator_ops stpmic1_ldo_ops = { + .get_value = stpmic1_ldo_get_value, + .set_value = stpmic1_ldo_set_value, + .get_enable = stpmic1_ldo_get_enable, + .set_enable = stpmic1_ldo_set_enable, + .get_mode = stpmic1_ldo_get_mode, + .set_mode = stpmic1_ldo_set_mode, +}; + +U_BOOT_DRIVER(stpmic1_ldo) = { + .name = "stpmic1_ldo", + .id = UCLASS_REGULATOR, + .ops = &stpmic1_ldo_ops, + .probe = stpmic1_ldo_probe, +}; + +/* + * VREF DDR regulator + */ + +static int stpmic1_vref_ddr_get_value(struct udevice *dev) +{ + /* BUCK2/2 */ + return stpmic1_buck_get_uv(dev->parent, STPMIC1_BUCK2) / 2; +} + +static int stpmic1_vref_ddr_get_enable(struct udevice *dev) +{ + int ret; + + ret = pmic_reg_read(dev->parent, STPMIC1_REFDDR_MAIN_CR); + if (ret < 0) + return false; + + return ret & STPMIC1_VREF_ENA ? true : false; +} + +static int stpmic1_vref_ddr_set_enable(struct udevice *dev, bool enable) +{ + int delay = enable ? STPMIC1_DEFAULT_START_UP_DELAY_MS : + STPMIC1_DEFAULT_STOP_DELAY_MS; + int ret; + + /* if regulator is already in the wanted state, nothing to do */ + if (stpmic1_vref_ddr_get_enable(dev) == enable) + return 0; + + ret = pmic_clrsetbits(dev->parent, STPMIC1_REFDDR_MAIN_CR, + STPMIC1_VREF_ENA, enable ? STPMIC1_VREF_ENA : 0); + mdelay(delay); + + return ret; +} + +static int stpmic1_vref_ddr_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + + uc_pdata = dev_get_uclass_platdata(dev); + + uc_pdata->type = REGULATOR_TYPE_FIXED; + uc_pdata->mode_count = 0; + + return 0; +} + +static const struct dm_regulator_ops stpmic1_vref_ddr_ops = { + .get_value = stpmic1_vref_ddr_get_value, + .get_enable = stpmic1_vref_ddr_get_enable, + .set_enable = stpmic1_vref_ddr_set_enable, +}; + +U_BOOT_DRIVER(stpmic1_vref_ddr) = { + .name = "stpmic1_vref_ddr", + .id = UCLASS_REGULATOR, + .ops = &stpmic1_vref_ddr_ops, + .probe = stpmic1_vref_ddr_probe, +}; + +/* + * BOOST regulator + */ + +static int stpmic1_boost_get_enable(struct udevice *dev) +{ + int ret; + + ret = pmic_reg_read(dev->parent, STPMIC1_BST_SW_CR); + if (ret < 0) + return false; + + return ret & STPMIC1_BST_ON ? true : false; +} + +static int stpmic1_boost_set_enable(struct udevice *dev, bool enable) +{ + int ret; + + ret = pmic_reg_read(dev->parent, STPMIC1_BST_SW_CR); + if (ret < 0) + return ret; + + if (!enable && ret & STPMIC1_PWR_SW_ON) + return -EINVAL; + + /* if regulator is already in the wanted state, nothing to do */ + if (!!(ret & STPMIC1_BST_ON) == enable) + return 0; + + ret = pmic_clrsetbits(dev->parent, STPMIC1_BST_SW_CR, + STPMIC1_BST_ON, + enable ? STPMIC1_BST_ON : 0); + if (enable) + mdelay(STPMIC1_USB_BOOST_START_UP_DELAY_MS); + + return ret; +} + +static int stpmic1_boost_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + + uc_pdata = dev_get_uclass_platdata(dev); + + uc_pdata->type = REGULATOR_TYPE_FIXED; + uc_pdata->mode_count = 0; + + return 0; +} + +static const struct dm_regulator_ops stpmic1_boost_ops = { + .get_enable = stpmic1_boost_get_enable, + .set_enable = stpmic1_boost_set_enable, +}; + +U_BOOT_DRIVER(stpmic1_boost) = { + .name = "stpmic1_boost", + .id = UCLASS_REGULATOR, + .ops = &stpmic1_boost_ops, + .probe = stpmic1_boost_probe, +}; + +/* + * USB power switch + */ + +static int stpmic1_pwr_sw_get_enable(struct udevice *dev) +{ + uint mask = 1 << dev->driver_data; + int ret; + + ret = pmic_reg_read(dev->parent, STPMIC1_BST_SW_CR); + if (ret < 0) + return false; + + return ret & mask ? true : false; +} + +static int stpmic1_pwr_sw_set_enable(struct udevice *dev, bool enable) +{ + uint mask = 1 << dev->driver_data; + int delay = enable ? STPMIC1_DEFAULT_START_UP_DELAY_MS : + STPMIC1_DEFAULT_STOP_DELAY_MS; + int ret; + + ret = pmic_reg_read(dev->parent, STPMIC1_BST_SW_CR); + if (ret < 0) + return ret; + + /* if regulator is already in the wanted state, nothing to do */ + if (!!(ret & mask) == enable) + return 0; + + /* Boost management */ + if (enable && !(ret & STPMIC1_BST_ON)) { + pmic_clrsetbits(dev->parent, STPMIC1_BST_SW_CR, + STPMIC1_BST_ON, STPMIC1_BST_ON); + mdelay(STPMIC1_USB_BOOST_START_UP_DELAY_MS); + } else if (!enable && ret & STPMIC1_BST_ON && + (ret & STPMIC1_PWR_SW_ON) != STPMIC1_PWR_SW_ON) { + pmic_clrsetbits(dev->parent, STPMIC1_BST_SW_CR, + STPMIC1_BST_ON, 0); + } + + ret = pmic_clrsetbits(dev->parent, STPMIC1_BST_SW_CR, + mask, enable ? mask : 0); + mdelay(delay); + + return ret; +} + +static int stpmic1_pwr_sw_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + + if (!dev->driver_data || dev->driver_data > STPMIC1_MAX_PWR_SW) + return -EINVAL; + + uc_pdata = dev_get_uclass_platdata(dev); + + uc_pdata->type = REGULATOR_TYPE_FIXED; + uc_pdata->mode_count = 0; + + return 0; +} + +static const struct dm_regulator_ops stpmic1_pwr_sw_ops = { + .get_enable = stpmic1_pwr_sw_get_enable, + .set_enable = stpmic1_pwr_sw_set_enable, +}; + +U_BOOT_DRIVER(stpmic1_pwr_sw) = { + .name = "stpmic1_pwr_sw", + .id = UCLASS_REGULATOR, + .ops = &stpmic1_pwr_sw_ops, + .probe = stpmic1_pwr_sw_probe, +}; diff --git a/drivers/power/regulator/stpmu1.c b/drivers/power/regulator/stpmu1.c deleted file mode 100644 index 6eb2420b6bc..00000000000 --- a/drivers/power/regulator/stpmu1.c +++ /dev/null @@ -1,671 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause -/* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved - * Author: Christophe Kerello <christophe.kerello@st.com> - */ - -#include <common.h> -#include <dm.h> -#include <errno.h> -#include <power/pmic.h> -#include <power/regulator.h> -#include <power/stpmu1.h> - -struct stpmu1_range { - int min_uv; - int min_sel; - int max_sel; - int step; -}; - -struct stpmu1_output_range { - const struct stpmu1_range *ranges; - int nbranges; -}; - -#define STPMU1_MODE(_id, _val, _name) { \ - .id = _id, \ - .register_value = _val, \ - .name = _name, \ -} - -#define STPMU1_RANGE(_min_uv, _min_sel, _max_sel, _step) { \ - .min_uv = _min_uv, \ - .min_sel = _min_sel, \ - .max_sel = _max_sel, \ - .step = _step, \ -} - -#define STPMU1_OUTPUT_RANGE(_ranges, _nbranges) { \ - .ranges = _ranges, \ - .nbranges = _nbranges, \ -} - -static int stpmu1_output_find_uv(int sel, - const struct stpmu1_output_range *output_range) -{ - const struct stpmu1_range *range; - int i; - - for (i = 0, range = output_range->ranges; - i < output_range->nbranges; i++, range++) { - if (sel >= range->min_sel && sel <= range->max_sel) - return range->min_uv + - (sel - range->min_sel) * range->step; - } - - return -EINVAL; -} - -static int stpmu1_output_find_sel(int uv, - const struct stpmu1_output_range *output_range) -{ - const struct stpmu1_range *range; - int i; - - for (i = 0, range = output_range->ranges; - i < output_range->nbranges; i++, range++) { - if (uv == range->min_uv && !range->step) - return range->min_sel; - - if (uv >= range->min_uv && - uv <= range->min_uv + - (range->max_sel - range->min_sel) * range->step) - return range->min_sel + - (uv - range->min_uv) / range->step; - } - - return -EINVAL; -} - -/* - * BUCK regulators - */ - -static const struct stpmu1_range buck1_ranges[] = { - STPMU1_RANGE(600000, 0, 30, 25000), - STPMU1_RANGE(1350000, 31, 63, 0), -}; - -static const struct stpmu1_range buck2_ranges[] = { - STPMU1_RANGE(1000000, 0, 17, 0), - STPMU1_RANGE(1050000, 18, 19, 0), - STPMU1_RANGE(1100000, 20, 21, 0), - STPMU1_RANGE(1150000, 22, 23, 0), - STPMU1_RANGE(1200000, 24, 25, 0), - STPMU1_RANGE(1250000, 26, 27, 0), - STPMU1_RANGE(1300000, 28, 29, 0), - STPMU1_RANGE(1350000, 30, 31, 0), - STPMU1_RANGE(1400000, 32, 33, 0), - STPMU1_RANGE(1450000, 34, 35, 0), - STPMU1_RANGE(1500000, 36, 63, 0), -}; - -static const struct stpmu1_range buck3_ranges[] = { - STPMU1_RANGE(1000000, 0, 19, 0), - STPMU1_RANGE(1100000, 20, 23, 0), - STPMU1_RANGE(1200000, 24, 27, 0), - STPMU1_RANGE(1300000, 28, 31, 0), - STPMU1_RANGE(1400000, 32, 35, 0), - STPMU1_RANGE(1500000, 36, 55, 100000), - STPMU1_RANGE(3400000, 56, 63, 0), -}; - -static const struct stpmu1_range buck4_ranges[] = { - STPMU1_RANGE(600000, 0, 27, 25000), - STPMU1_RANGE(1300000, 28, 29, 0), - STPMU1_RANGE(1350000, 30, 31, 0), - STPMU1_RANGE(1400000, 32, 33, 0), - STPMU1_RANGE(1450000, 34, 35, 0), - STPMU1_RANGE(1500000, 36, 60, 100000), - STPMU1_RANGE(3900000, 61, 63, 0), -}; - -/* BUCK: 1,2,3,4 - voltage ranges */ -static const struct stpmu1_output_range buck_voltage_range[] = { - STPMU1_OUTPUT_RANGE(buck1_ranges, ARRAY_SIZE(buck1_ranges)), - STPMU1_OUTPUT_RANGE(buck2_ranges, ARRAY_SIZE(buck2_ranges)), - STPMU1_OUTPUT_RANGE(buck3_ranges, ARRAY_SIZE(buck3_ranges)), - STPMU1_OUTPUT_RANGE(buck4_ranges, ARRAY_SIZE(buck4_ranges)), -}; - -/* BUCK modes */ -static const struct dm_regulator_mode buck_modes[] = { - STPMU1_MODE(STPMU1_BUCK_MODE_HP, STPMU1_BUCK_MODE_HP, "HP"), - STPMU1_MODE(STPMU1_BUCK_MODE_LP, STPMU1_BUCK_MODE_LP, "LP"), -}; - -static int stpmu1_buck_get_uv(struct udevice *dev, int buck) -{ - int sel; - - sel = pmic_reg_read(dev, STPMU1_BUCKX_CTRL_REG(buck)); - if (sel < 0) - return sel; - - sel &= STPMU1_BUCK_OUTPUT_MASK; - sel >>= STPMU1_BUCK_OUTPUT_SHIFT; - - return stpmu1_output_find_uv(sel, &buck_voltage_range[buck]); -} - -static int stpmu1_buck_get_value(struct udevice *dev) -{ - return stpmu1_buck_get_uv(dev->parent, dev->driver_data - 1); -} - -static int stpmu1_buck_set_value(struct udevice *dev, int uv) -{ - int sel, buck = dev->driver_data - 1; - - sel = stpmu1_output_find_sel(uv, &buck_voltage_range[buck]); - if (sel < 0) - return sel; - - return pmic_clrsetbits(dev->parent, - STPMU1_BUCKX_CTRL_REG(buck), - STPMU1_BUCK_OUTPUT_MASK, - sel << STPMU1_BUCK_OUTPUT_SHIFT); -} - -static int stpmu1_buck_get_enable(struct udevice *dev) -{ - int ret; - - ret = pmic_reg_read(dev->parent, - STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1)); - if (ret < 0) - return false; - - return ret & STPMU1_BUCK_EN ? true : false; -} - -static int stpmu1_buck_set_enable(struct udevice *dev, bool enable) -{ - struct dm_regulator_uclass_platdata *uc_pdata; - int delay = enable ? STPMU1_DEFAULT_START_UP_DELAY_MS : - STPMU1_DEFAULT_STOP_DELAY_MS; - int ret, uv; - - /* if regulator is already in the wanted state, nothing to do */ - if (stpmu1_buck_get_enable(dev) == enable) - return 0; - - if (enable) { - uc_pdata = dev_get_uclass_platdata(dev); - uv = stpmu1_buck_get_value(dev); - if ((uv < uc_pdata->min_uV) || (uv > uc_pdata->max_uV)) - stpmu1_buck_set_value(dev, uc_pdata->min_uV); - } - - ret = pmic_clrsetbits(dev->parent, - STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1), - STPMU1_BUCK_EN, enable ? STPMU1_BUCK_EN : 0); - mdelay(delay); - - return ret; -} - -static int stpmu1_buck_get_mode(struct udevice *dev) -{ - int ret; - - ret = pmic_reg_read(dev->parent, - STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1)); - if (ret < 0) - return ret; - - return ret & STPMU1_BUCK_MODE ? STPMU1_BUCK_MODE_LP : - STPMU1_BUCK_MODE_HP; -} - -static int stpmu1_buck_set_mode(struct udevice *dev, int mode) -{ - return pmic_clrsetbits(dev->parent, - STPMU1_BUCKX_CTRL_REG(dev->driver_data - 1), - STPMU1_BUCK_MODE, - mode ? STPMU1_BUCK_MODE : 0); -} - -static int stpmu1_buck_probe(struct udevice *dev) -{ - struct dm_regulator_uclass_platdata *uc_pdata; - - if (!dev->driver_data || dev->driver_data > STPMU1_MAX_BUCK) - return -EINVAL; - - uc_pdata = dev_get_uclass_platdata(dev); - - uc_pdata->type = REGULATOR_TYPE_BUCK; - uc_pdata->mode = (struct dm_regulator_mode *)buck_modes; - uc_pdata->mode_count = ARRAY_SIZE(buck_modes); - - return 0; -} - -static const struct dm_regulator_ops stpmu1_buck_ops = { - .get_value = stpmu1_buck_get_value, - .set_value = stpmu1_buck_set_value, - .get_enable = stpmu1_buck_get_enable, - .set_enable = stpmu1_buck_set_enable, - .get_mode = stpmu1_buck_get_mode, - .set_mode = stpmu1_buck_set_mode, -}; - -U_BOOT_DRIVER(stpmu1_buck) = { - .name = "stpmu1_buck", - .id = UCLASS_REGULATOR, - .ops = &stpmu1_buck_ops, - .probe = stpmu1_buck_probe, -}; - -/* - * LDO regulators - */ - -static const struct stpmu1_range ldo12_ranges[] = { - STPMU1_RANGE(1700000, 0, 7, 0), - STPMU1_RANGE(1700000, 8, 24, 100000), - STPMU1_RANGE(3300000, 25, 31, 0), -}; - -static const struct stpmu1_range ldo3_ranges[] = { - STPMU1_RANGE(1700000, 0, 7, 0), - STPMU1_RANGE(1700000, 8, 24, 100000), - STPMU1_RANGE(3300000, 25, 30, 0), - /* Sel 31 is special case when LDO3 is in mode sync_source (BUCK2/2) */ -}; - -static const struct stpmu1_range ldo5_ranges[] = { - STPMU1_RANGE(1700000, 0, 7, 0), - STPMU1_RANGE(1700000, 8, 30, 100000), - STPMU1_RANGE(3900000, 31, 31, 0), -}; - -static const struct stpmu1_range ldo6_ranges[] = { - STPMU1_RANGE(900000, 0, 24, 100000), - STPMU1_RANGE(3300000, 25, 31, 0), -}; - -/* LDO: 1,2,3,4,5,6 - voltage ranges */ -static const struct stpmu1_output_range ldo_voltage_range[] = { - STPMU1_OUTPUT_RANGE(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)), - STPMU1_OUTPUT_RANGE(ldo12_ranges, ARRAY_SIZE(ldo12_ranges)), - STPMU1_OUTPUT_RANGE(ldo3_ranges, ARRAY_SIZE(ldo3_ranges)), - STPMU1_OUTPUT_RANGE(NULL, 0), - STPMU1_OUTPUT_RANGE(ldo5_ranges, ARRAY_SIZE(ldo5_ranges)), - STPMU1_OUTPUT_RANGE(ldo6_ranges, ARRAY_SIZE(ldo6_ranges)), -}; - -/* LDO modes */ -static const struct dm_regulator_mode ldo_modes[] = { - STPMU1_MODE(STPMU1_LDO_MODE_NORMAL, - STPMU1_LDO_MODE_NORMAL, "NORMAL"), - STPMU1_MODE(STPMU1_LDO_MODE_BYPASS, - STPMU1_LDO_MODE_BYPASS, "BYPASS"), - STPMU1_MODE(STPMU1_LDO_MODE_SINK_SOURCE, - STPMU1_LDO_MODE_SINK_SOURCE, "SINK SOURCE"), -}; - -static int stpmu1_ldo_get_value(struct udevice *dev) -{ - int sel, ldo = dev->driver_data - 1; - - sel = pmic_reg_read(dev->parent, STPMU1_LDOX_CTRL_REG(ldo)); - if (sel < 0) - return sel; - - /* ldo4 => 3,3V */ - if (ldo == STPMU1_LDO4) - return STPMU1_LDO4_UV; - - sel &= STPMU1_LDO12356_OUTPUT_MASK; - sel >>= STPMU1_LDO12356_OUTPUT_SHIFT; - - /* ldo3, sel = 31 => BUCK2/2 */ - if (ldo == STPMU1_LDO3 && sel == STPMU1_LDO3_DDR_SEL) - return stpmu1_buck_get_uv(dev->parent, STPMU1_BUCK2) / 2; - - return stpmu1_output_find_uv(sel, &ldo_voltage_range[ldo]); -} - -static int stpmu1_ldo_set_value(struct udevice *dev, int uv) -{ - int sel, ldo = dev->driver_data - 1; - - /* ldo4 => not possible */ - if (ldo == STPMU1_LDO4) - return -EINVAL; - - sel = stpmu1_output_find_sel(uv, &ldo_voltage_range[ldo]); - if (sel < 0) - return sel; - - return pmic_clrsetbits(dev->parent, - STPMU1_LDOX_CTRL_REG(ldo), - STPMU1_LDO12356_OUTPUT_MASK, - sel << STPMU1_LDO12356_OUTPUT_SHIFT); -} - -static int stpmu1_ldo_get_enable(struct udevice *dev) -{ - int ret; - - ret = pmic_reg_read(dev->parent, - STPMU1_LDOX_CTRL_REG(dev->driver_data - 1)); - if (ret < 0) - return false; - - return ret & STPMU1_LDO_EN ? true : false; -} - -static int stpmu1_ldo_set_enable(struct udevice *dev, bool enable) -{ - struct dm_regulator_uclass_platdata *uc_pdata; - int delay = enable ? STPMU1_DEFAULT_START_UP_DELAY_MS : - STPMU1_DEFAULT_STOP_DELAY_MS; - int ret, uv; - - /* if regulator is already in the wanted state, nothing to do */ - if (stpmu1_ldo_get_enable(dev) == enable) - return 0; - - if (enable) { - uc_pdata = dev_get_uclass_platdata(dev); - uv = stpmu1_ldo_get_value(dev); - if ((uv < uc_pdata->min_uV) || (uv > uc_pdata->max_uV)) - stpmu1_ldo_set_value(dev, uc_pdata->min_uV); - } - - ret = pmic_clrsetbits(dev->parent, - STPMU1_LDOX_CTRL_REG(dev->driver_data - 1), - STPMU1_LDO_EN, enable ? STPMU1_LDO_EN : 0); - mdelay(delay); - - return ret; -} - -static int stpmu1_ldo_get_mode(struct udevice *dev) -{ - int ret, ldo = dev->driver_data - 1; - - if (ldo != STPMU1_LDO3) - return -EINVAL; - - ret = pmic_reg_read(dev->parent, STPMU1_LDOX_CTRL_REG(ldo)); - if (ret < 0) - return ret; - - if (ret & STPMU1_LDO3_MODE) - return STPMU1_LDO_MODE_BYPASS; - - ret &= STPMU1_LDO12356_OUTPUT_MASK; - ret >>= STPMU1_LDO12356_OUTPUT_SHIFT; - - return ret == STPMU1_LDO3_DDR_SEL ? STPMU1_LDO_MODE_SINK_SOURCE : - STPMU1_LDO_MODE_NORMAL; -} - -static int stpmu1_ldo_set_mode(struct udevice *dev, int mode) -{ - int ret, ldo = dev->driver_data - 1; - - if (ldo != STPMU1_LDO3) - return -EINVAL; - - ret = pmic_reg_read(dev->parent, STPMU1_LDOX_CTRL_REG(ldo)); - if (ret < 0) - return ret; - - switch (mode) { - case STPMU1_LDO_MODE_SINK_SOURCE: - ret &= ~STPMU1_LDO12356_OUTPUT_MASK; - ret |= STPMU1_LDO3_DDR_SEL << STPMU1_LDO12356_OUTPUT_SHIFT; - case STPMU1_LDO_MODE_NORMAL: - ret &= ~STPMU1_LDO3_MODE; - break; - case STPMU1_LDO_MODE_BYPASS: - ret |= STPMU1_LDO3_MODE; - break; - } - - return pmic_reg_write(dev->parent, STPMU1_LDOX_CTRL_REG(ldo), ret); -} - -static int stpmu1_ldo_probe(struct udevice *dev) -{ - struct dm_regulator_uclass_platdata *uc_pdata; - - if (!dev->driver_data || dev->driver_data > STPMU1_MAX_LDO) - return -EINVAL; - - uc_pdata = dev_get_uclass_platdata(dev); - - uc_pdata->type = REGULATOR_TYPE_LDO; - if (dev->driver_data - 1 == STPMU1_LDO3) { - uc_pdata->mode = (struct dm_regulator_mode *)ldo_modes; - uc_pdata->mode_count = ARRAY_SIZE(ldo_modes); - } else { - uc_pdata->mode_count = 0; - } - - return 0; -} - -static const struct dm_regulator_ops stpmu1_ldo_ops = { - .get_value = stpmu1_ldo_get_value, - .set_value = stpmu1_ldo_set_value, - .get_enable = stpmu1_ldo_get_enable, - .set_enable = stpmu1_ldo_set_enable, - .get_mode = stpmu1_ldo_get_mode, - .set_mode = stpmu1_ldo_set_mode, -}; - -U_BOOT_DRIVER(stpmu1_ldo) = { - .name = "stpmu1_ldo", - .id = UCLASS_REGULATOR, - .ops = &stpmu1_ldo_ops, - .probe = stpmu1_ldo_probe, -}; - -/* - * VREF DDR regulator - */ - -static int stpmu1_vref_ddr_get_value(struct udevice *dev) -{ - /* BUCK2/2 */ - return stpmu1_buck_get_uv(dev->parent, STPMU1_BUCK2) / 2; -} - -static int stpmu1_vref_ddr_get_enable(struct udevice *dev) -{ - int ret; - - ret = pmic_reg_read(dev->parent, STPMU1_VREF_CTRL_REG); - if (ret < 0) - return false; - - return ret & STPMU1_VREF_EN ? true : false; -} - -static int stpmu1_vref_ddr_set_enable(struct udevice *dev, bool enable) -{ - int delay = enable ? STPMU1_DEFAULT_START_UP_DELAY_MS : - STPMU1_DEFAULT_STOP_DELAY_MS; - int ret; - - /* if regulator is already in the wanted state, nothing to do */ - if (stpmu1_vref_ddr_get_enable(dev) == enable) - return 0; - - ret = pmic_clrsetbits(dev->parent, STPMU1_VREF_CTRL_REG, - STPMU1_VREF_EN, enable ? STPMU1_VREF_EN : 0); - mdelay(delay); - - return ret; -} - -static int stpmu1_vref_ddr_probe(struct udevice *dev) -{ - struct dm_regulator_uclass_platdata *uc_pdata; - - uc_pdata = dev_get_uclass_platdata(dev); - - uc_pdata->type = REGULATOR_TYPE_FIXED; - uc_pdata->mode_count = 0; - - return 0; -} - -static const struct dm_regulator_ops stpmu1_vref_ddr_ops = { - .get_value = stpmu1_vref_ddr_get_value, - .get_enable = stpmu1_vref_ddr_get_enable, - .set_enable = stpmu1_vref_ddr_set_enable, -}; - -U_BOOT_DRIVER(stpmu1_vref_ddr) = { - .name = "stpmu1_vref_ddr", - .id = UCLASS_REGULATOR, - .ops = &stpmu1_vref_ddr_ops, - .probe = stpmu1_vref_ddr_probe, -}; - -/* - * BOOST regulator - */ - -static int stpmu1_boost_get_enable(struct udevice *dev) -{ - int ret; - - ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG); - if (ret < 0) - return false; - - return ret & STPMU1_USB_BOOST_EN ? true : false; -} - -static int stpmu1_boost_set_enable(struct udevice *dev, bool enable) -{ - int ret; - - ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG); - if (ret < 0) - return ret; - - if (!enable && ret & STPMU1_USB_PWR_SW_EN) - return -EINVAL; - - /* if regulator is already in the wanted state, nothing to do */ - if (!!(ret & STPMU1_USB_BOOST_EN) == enable) - return 0; - - ret = pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG, - STPMU1_USB_BOOST_EN, - enable ? STPMU1_USB_BOOST_EN : 0); - if (enable) - mdelay(STPMU1_USB_BOOST_START_UP_DELAY_MS); - - return ret; -} - -static int stpmu1_boost_probe(struct udevice *dev) -{ - struct dm_regulator_uclass_platdata *uc_pdata; - - uc_pdata = dev_get_uclass_platdata(dev); - - uc_pdata->type = REGULATOR_TYPE_FIXED; - uc_pdata->mode_count = 0; - - return 0; -} - -static const struct dm_regulator_ops stpmu1_boost_ops = { - .get_enable = stpmu1_boost_get_enable, - .set_enable = stpmu1_boost_set_enable, -}; - -U_BOOT_DRIVER(stpmu1_boost) = { - .name = "stpmu1_boost", - .id = UCLASS_REGULATOR, - .ops = &stpmu1_boost_ops, - .probe = stpmu1_boost_probe, -}; - -/* - * USB power switch - */ - -static int stpmu1_pwr_sw_get_enable(struct udevice *dev) -{ - uint mask = 1 << dev->driver_data; - int ret; - - ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG); - if (ret < 0) - return false; - - return ret & mask ? true : false; -} - -static int stpmu1_pwr_sw_set_enable(struct udevice *dev, bool enable) -{ - uint mask = 1 << dev->driver_data; - int delay = enable ? STPMU1_DEFAULT_START_UP_DELAY_MS : - STPMU1_DEFAULT_STOP_DELAY_MS; - int ret; - - ret = pmic_reg_read(dev->parent, STPMU1_USB_CTRL_REG); - if (ret < 0) - return ret; - - /* if regulator is already in the wanted state, nothing to do */ - if (!!(ret & mask) == enable) - return 0; - - /* Boost management */ - if (enable && !(ret & STPMU1_USB_BOOST_EN)) { - pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG, - STPMU1_USB_BOOST_EN, STPMU1_USB_BOOST_EN); - mdelay(STPMU1_USB_BOOST_START_UP_DELAY_MS); - } else if (!enable && ret & STPMU1_USB_BOOST_EN && - (ret & STPMU1_USB_PWR_SW_EN) != STPMU1_USB_PWR_SW_EN) { - pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG, - STPMU1_USB_BOOST_EN, 0); - } - - ret = pmic_clrsetbits(dev->parent, STPMU1_USB_CTRL_REG, - mask, enable ? mask : 0); - mdelay(delay); - - return ret; -} - -static int stpmu1_pwr_sw_probe(struct udevice *dev) -{ - struct dm_regulator_uclass_platdata *uc_pdata; - - if (!dev->driver_data || dev->driver_data > STPMU1_MAX_PWR_SW) - return -EINVAL; - - uc_pdata = dev_get_uclass_platdata(dev); - - uc_pdata->type = REGULATOR_TYPE_FIXED; - uc_pdata->mode_count = 0; - - return 0; -} - -static const struct dm_regulator_ops stpmu1_pwr_sw_ops = { - .get_enable = stpmu1_pwr_sw_get_enable, - .set_enable = stpmu1_pwr_sw_set_enable, -}; - -U_BOOT_DRIVER(stpmu1_pwr_sw) = { - .name = "stpmu1_pwr_sw", - .id = UCLASS_REGULATOR, - .ops = &stpmu1_pwr_sw_ops, - .probe = stpmu1_pwr_sw_probe, -}; diff --git a/drivers/ram/stm32mp1/stm32mp1_ram.c b/drivers/ram/stm32mp1/stm32mp1_ram.c index bd497a3021d..e45a3b2658a 100644 --- a/drivers/ram/stm32mp1/stm32mp1_ram.c +++ b/drivers/ram/stm32mp1/stm32mp1_ram.c @@ -157,7 +157,8 @@ static int stm32mp1_ddr_probe(struct udevice *dev) priv->info.base = STM32_DDR_BASE; -#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) +#if !defined(CONFIG_STM32MP1_TRUSTED) && \ + (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) priv->info.size = 0; return stm32mp1_ddr_setup(dev); #else diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 098372e0932..a700f240adf 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -222,8 +222,7 @@ config SPI_SUNXI config STM32_QSPI bool "STM32F7 QSPI driver" - depends on STM32F7 - imply SPI_FLASH_BAR + depends on STM32F7 || ARCH_STM32MP help Enable the STM32F7 Quad-SPI (QSPI) driver. This driver can be used to access the SPI NOR flash chips on platforms embedding diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index 11fce9c4fe5..efdb178450e 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -256,7 +256,7 @@ static int cadence_spi_xfer(struct udevice *dev, unsigned int bitlen, break; case CQSPI_INDIRECT_WRITE: err = cadence_qspi_apb_indirect_write_setup - (plat, priv->cmd_len, cmd_buf); + (plat, priv->cmd_len, dm_plat->mode, cmd_buf); if (!err) { err = cadence_qspi_apb_indirect_write_execute (plat, data_bytes, dout); diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index 055900def00..b4914071308 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -60,7 +60,7 @@ int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat, int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat, unsigned int rxlen, u8 *rxbuf); int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat, - unsigned int cmdlen, const u8 *cmdbuf); + unsigned int cmdlen, unsigned int tx_width, const u8 *cmdbuf); int cadence_qspi_apb_indirect_write_execute(struct cadence_spi_platdata *plat, unsigned int txlen, const u8 *txbuf); diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index a8af3520303..55a7501913a 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -77,6 +77,7 @@ #define CQSPI_REG_WR_INSTR 0x08 #define CQSPI_REG_WR_INSTR_OPCODE_LSB 0 +#define CQSPI_REG_WR_INSTR_TYPE_DATA_LSB 16 #define CQSPI_REG_DELAY 0x0C #define CQSPI_REG_DELAY_TSLCH_LSB 0 @@ -686,7 +687,7 @@ failrd: /* Opcode + Address (3/4 bytes) */ int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat, - unsigned int cmdlen, const u8 *cmdbuf) + unsigned int cmdlen, unsigned int tx_width, const u8 *cmdbuf) { unsigned int reg; unsigned int addr_bytes = cmdlen > 4 ? 4 : 3; @@ -702,6 +703,10 @@ int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat, /* Configure the opcode */ reg = cmdbuf[0] << CQSPI_REG_WR_INSTR_OPCODE_LSB; + + if (tx_width & SPI_TX_QUAD) + reg |= CQSPI_INST_TYPE_QUAD << CQSPI_REG_WR_INSTR_TYPE_DATA_LSB; + writel(reg, plat->regbase + CQSPI_REG_WR_INSTR); /* Setup write address. */ diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c index 764c94215e7..a68a51945e4 100644 --- a/drivers/spi/fsl_dspi.c +++ b/drivers/spi/fsl_dspi.c @@ -273,7 +273,18 @@ static int dspi_xfer(struct fsl_dspi_priv *priv, uint cs, unsigned int bitlen, if (len > 1) { int tmp_len = len - 1; while (tmp_len--) { - if (dout != NULL) { + if ((dout != NULL) && (din != NULL)) { + if (priv->charbit == 16) { + dspi_tx(priv, ctrl, *spi_wr16++); + *spi_rd16++ = dspi_rx(priv); + } + else { + dspi_tx(priv, ctrl, *spi_wr++); + *spi_rd++ = dspi_rx(priv); + } + } + + else if (dout != NULL) { if (priv->charbit == 16) dspi_tx(priv, ctrl, *spi_wr16++); else @@ -281,7 +292,7 @@ static int dspi_xfer(struct fsl_dspi_priv *priv, uint cs, unsigned int bitlen, dspi_rx(priv); } - if (din != NULL) { + else if (din != NULL) { dspi_tx(priv, ctrl, DSPI_IDLE_VAL); if (priv->charbit == 16) *spi_rd16++ = dspi_rx(priv); @@ -297,7 +308,18 @@ static int dspi_xfer(struct fsl_dspi_priv *priv, uint cs, unsigned int bitlen, ctrl &= ~DSPI_TFR_CONT; if (len) { - if (dout != NULL) { + if ((dout != NULL) && (din != NULL)) { + if (priv->charbit == 16) { + dspi_tx(priv, ctrl, *spi_wr16++); + *spi_rd16++ = dspi_rx(priv); + } + else { + dspi_tx(priv, ctrl, *spi_wr++); + *spi_rd++ = dspi_rx(priv); + } + } + + else if (dout != NULL) { if (priv->charbit == 16) dspi_tx(priv, ctrl, *spi_wr16); else @@ -305,7 +327,7 @@ static int dspi_xfer(struct fsl_dspi_priv *priv, uint cs, unsigned int bitlen, dspi_rx(priv); } - if (din != NULL) { + else if (din != NULL) { dspi_tx(priv, ctrl, DSPI_IDLE_VAL); if (priv->charbit == 16) *spi_rd16 = dspi_rx(priv); diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 1bb0987edb7..b86eee75bcb 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -214,7 +214,7 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) if (ret < 0) return ret; - if (ops->mem_ops) { + if (ops->mem_ops && ops->mem_ops->exec_op) { #ifndef __UBOOT__ /* * Flush the message queue before executing our SPI memory diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index 2bc289a74cc..88cb2a12622 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -328,7 +328,9 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, } plat = dev_get_parent_platdata(dev); - if (!speed) { + + /* get speed and mode from platdata when available */ + if (plat->max_hz) { speed = plat->max_hz; mode = plat->mode; } diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c index 8b60d7c3b22..bb1067ff4a9 100644 --- a/drivers/spi/stm32_qspi.c +++ b/drivers/spi/stm32_qspi.c @@ -9,15 +9,11 @@ #include <common.h> #include <clk.h> -#include <dm.h> -#include <errno.h> -#include <malloc.h> #include <reset.h> -#include <spi.h> -#include <spi_flash.h> -#include <asm/io.h> -#include <asm/arch/stm32.h> +#include <spi-mem.h> +#include <linux/iopoll.h> #include <linux/ioport.h> +#include <linux/sizes.h> struct stm32_qspi_regs { u32 cr; /* 0x00 */ @@ -45,8 +41,7 @@ struct stm32_qspi_regs { #define STM32_QSPI_CR_SSHIFT BIT(4) #define STM32_QSPI_CR_DFM BIT(6) #define STM32_QSPI_CR_FSEL BIT(7) -#define STM32_QSPI_CR_FTHRES_MASK GENMASK(4, 0) -#define STM32_QSPI_CR_FTHRES_SHIFT (8) +#define STM32_QSPI_CR_FTHRES_SHIFT 8 #define STM32_QSPI_CR_TEIE BIT(16) #define STM32_QSPI_CR_TCIE BIT(17) #define STM32_QSPI_CR_FTIE BIT(18) @@ -55,16 +50,16 @@ struct stm32_qspi_regs { #define STM32_QSPI_CR_APMS BIT(22) #define STM32_QSPI_CR_PMM BIT(23) #define STM32_QSPI_CR_PRESCALER_MASK GENMASK(7, 0) -#define STM32_QSPI_CR_PRESCALER_SHIFT (24) +#define STM32_QSPI_CR_PRESCALER_SHIFT 24 /* * QUADSPI device configuration register */ #define STM32_QSPI_DCR_CKMODE BIT(0) #define STM32_QSPI_DCR_CSHT_MASK GENMASK(2, 0) -#define STM32_QSPI_DCR_CSHT_SHIFT (8) +#define STM32_QSPI_DCR_CSHT_SHIFT 8 #define STM32_QSPI_DCR_FSIZE_MASK GENMASK(4, 0) -#define STM32_QSPI_DCR_FSIZE_SHIFT (16) +#define STM32_QSPI_DCR_FSIZE_SHIFT 16 /* * QUADSPI status register @@ -75,8 +70,6 @@ struct stm32_qspi_regs { #define STM32_QSPI_SR_SMF BIT(3) #define STM32_QSPI_SR_TOF BIT(4) #define STM32_QSPI_SR_BUSY BIT(5) -#define STM32_QSPI_SR_FLEVEL_MASK GENMASK(5, 0) -#define STM32_QSPI_SR_FLEVEL_SHIFT (8) /* * QUADSPI flag clear register @@ -92,388 +85,276 @@ struct stm32_qspi_regs { #define STM32_QSPI_CCR_DDRM BIT(31) #define STM32_QSPI_CCR_DHHC BIT(30) #define STM32_QSPI_CCR_SIOO BIT(28) -#define STM32_QSPI_CCR_FMODE_SHIFT (26) -#define STM32_QSPI_CCR_DMODE_SHIFT (24) -#define STM32_QSPI_CCR_DCYC_SHIFT (18) -#define STM32_QSPI_CCR_DCYC_MASK GENMASK(4, 0) -#define STM32_QSPI_CCR_ABSIZE_SHIFT (16) -#define STM32_QSPI_CCR_ABMODE_SHIFT (14) -#define STM32_QSPI_CCR_ADSIZE_SHIFT (12) -#define STM32_QSPI_CCR_ADMODE_SHIFT (10) -#define STM32_QSPI_CCR_IMODE_SHIFT (8) -#define STM32_QSPI_CCR_INSTRUCTION_MASK GENMASK(7, 0) - -enum STM32_QSPI_CCR_IMODE { - STM32_QSPI_CCR_IMODE_NONE = 0, - STM32_QSPI_CCR_IMODE_ONE_LINE = 1, - STM32_QSPI_CCR_IMODE_TWO_LINE = 2, - STM32_QSPI_CCR_IMODE_FOUR_LINE = 3, -}; - -enum STM32_QSPI_CCR_ADMODE { - STM32_QSPI_CCR_ADMODE_NONE = 0, - STM32_QSPI_CCR_ADMODE_ONE_LINE = 1, - STM32_QSPI_CCR_ADMODE_TWO_LINE = 2, - STM32_QSPI_CCR_ADMODE_FOUR_LINE = 3, -}; - -enum STM32_QSPI_CCR_ADSIZE { - STM32_QSPI_CCR_ADSIZE_8BIT = 0, - STM32_QSPI_CCR_ADSIZE_16BIT = 1, - STM32_QSPI_CCR_ADSIZE_24BIT = 2, - STM32_QSPI_CCR_ADSIZE_32BIT = 3, -}; - -enum STM32_QSPI_CCR_ABMODE { - STM32_QSPI_CCR_ABMODE_NONE = 0, - STM32_QSPI_CCR_ABMODE_ONE_LINE = 1, - STM32_QSPI_CCR_ABMODE_TWO_LINE = 2, - STM32_QSPI_CCR_ABMODE_FOUR_LINE = 3, -}; - -enum STM32_QSPI_CCR_ABSIZE { - STM32_QSPI_CCR_ABSIZE_8BIT = 0, - STM32_QSPI_CCR_ABSIZE_16BIT = 1, - STM32_QSPI_CCR_ABSIZE_24BIT = 2, - STM32_QSPI_CCR_ABSIZE_32BIT = 3, -}; - -enum STM32_QSPI_CCR_DMODE { - STM32_QSPI_CCR_DMODE_NONE = 0, - STM32_QSPI_CCR_DMODE_ONE_LINE = 1, - STM32_QSPI_CCR_DMODE_TWO_LINE = 2, - STM32_QSPI_CCR_DMODE_FOUR_LINE = 3, -}; - -enum STM32_QSPI_CCR_FMODE { - STM32_QSPI_CCR_IND_WRITE = 0, - STM32_QSPI_CCR_IND_READ = 1, - STM32_QSPI_CCR_AUTO_POLL = 2, - STM32_QSPI_CCR_MEM_MAP = 3, -}; - -/* default SCK frequency, unit: HZ */ -#define STM32_QSPI_DEFAULT_SCK_FREQ 108000000 - -#define STM32_MAX_NORCHIP 2 - -struct stm32_qspi_platdata { - u32 base; - u32 memory_map; - u32 max_hz; +#define STM32_QSPI_CCR_FMODE_SHIFT 26 +#define STM32_QSPI_CCR_DMODE_SHIFT 24 +#define STM32_QSPI_CCR_DCYC_SHIFT 18 +#define STM32_QSPI_CCR_ABSIZE_SHIFT 16 +#define STM32_QSPI_CCR_ABMODE_SHIFT 14 +#define STM32_QSPI_CCR_ADSIZE_SHIFT 12 +#define STM32_QSPI_CCR_ADMODE_SHIFT 10 +#define STM32_QSPI_CCR_IMODE_SHIFT 8 + +#define STM32_QSPI_CCR_IND_WRITE 0 +#define STM32_QSPI_CCR_IND_READ 1 +#define STM32_QSPI_CCR_MEM_MAP 3 + +#define STM32_QSPI_MAX_MMAP_SZ SZ_256M +#define STM32_QSPI_MAX_CHIP 2 + +#define STM32_QSPI_FIFO_TIMEOUT_US 30000 +#define STM32_QSPI_CMD_TIMEOUT_US 1000000 +#define STM32_BUSY_TIMEOUT_US 100000 +#define STM32_ABT_TIMEOUT_US 100000 + +struct stm32_qspi_flash { + u32 cr; + u32 dcr; + bool initialized; }; struct stm32_qspi_priv { struct stm32_qspi_regs *regs; + struct stm32_qspi_flash flash[STM32_QSPI_MAX_CHIP]; + void __iomem *mm_base; + resource_size_t mm_size; ulong clock_rate; - u32 max_hz; - u32 mode; - - u32 command; - u32 address; - u32 dummycycles; -#define CMD_HAS_ADR BIT(24) -#define CMD_HAS_DUMMY BIT(25) -#define CMD_HAS_DATA BIT(26) + int cs_used; }; -static void _stm32_qspi_disable(struct stm32_qspi_priv *priv) +static int _stm32_qspi_wait_for_not_busy(struct stm32_qspi_priv *priv) { - clrbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN); -} + u32 sr; + int ret; -static void _stm32_qspi_enable(struct stm32_qspi_priv *priv) -{ - setbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN); -} + ret = readl_poll_timeout(&priv->regs->sr, sr, + !(sr & STM32_QSPI_SR_BUSY), + STM32_BUSY_TIMEOUT_US); + if (ret) + pr_err("busy timeout (stat:%#x)\n", sr); -static void _stm32_qspi_wait_for_not_busy(struct stm32_qspi_priv *priv) -{ - while (readl(&priv->regs->sr) & STM32_QSPI_SR_BUSY) - ; + return ret; } -static void _stm32_qspi_wait_for_complete(struct stm32_qspi_priv *priv) +static int _stm32_qspi_wait_cmd(struct stm32_qspi_priv *priv, + const struct spi_mem_op *op) { - while (!(readl(&priv->regs->sr) & STM32_QSPI_SR_TCF)) - ; -} + u32 sr; + int ret; -static void _stm32_qspi_wait_for_ftf(struct stm32_qspi_priv *priv) -{ - while (!(readl(&priv->regs->sr) & STM32_QSPI_SR_FTF)) - ; -} + if (!op->data.nbytes) + return _stm32_qspi_wait_for_not_busy(priv); -static void _stm32_qspi_set_flash_size(struct stm32_qspi_priv *priv, u32 size) -{ - u32 fsize = fls(size) - 1; + ret = readl_poll_timeout(&priv->regs->sr, sr, + sr & STM32_QSPI_SR_TCF, + STM32_QSPI_CMD_TIMEOUT_US); + if (ret) { + pr_err("cmd timeout (stat:%#x)\n", sr); + } else if (readl(&priv->regs->sr) & STM32_QSPI_SR_TEF) { + pr_err("transfer error (stat:%#x)\n", sr); + ret = -EIO; + } - clrsetbits_le32(&priv->regs->dcr, - STM32_QSPI_DCR_FSIZE_MASK << STM32_QSPI_DCR_FSIZE_SHIFT, - fsize << STM32_QSPI_DCR_FSIZE_SHIFT); + /* clear flags */ + writel(STM32_QSPI_FCR_CTCF | STM32_QSPI_FCR_CTEF, &priv->regs->fcr); + + return ret; } -static void _stm32_qspi_set_cs(struct stm32_qspi_priv *priv, unsigned int cs) +static void _stm32_qspi_read_fifo(u8 *val, void __iomem *addr) { - clrsetbits_le32(&priv->regs->cr, STM32_QSPI_CR_FSEL, - cs ? STM32_QSPI_CR_FSEL : 0); + *val = readb(addr); } -static unsigned int _stm32_qspi_gen_ccr(struct stm32_qspi_priv *priv, u8 fmode) +static void _stm32_qspi_write_fifo(u8 *val, void __iomem *addr) { - unsigned int ccr_reg = 0; - u8 imode, admode, dmode; - u32 mode = priv->mode; - u32 cmd = (priv->command & STM32_QSPI_CCR_INSTRUCTION_MASK); - - imode = STM32_QSPI_CCR_IMODE_ONE_LINE; - admode = STM32_QSPI_CCR_ADMODE_ONE_LINE; - dmode = STM32_QSPI_CCR_DMODE_ONE_LINE; - - if ((priv->command & CMD_HAS_ADR) && (priv->command & CMD_HAS_DATA)) { - if (fmode == STM32_QSPI_CCR_IND_WRITE) { - if (mode & SPI_TX_QUAD) - dmode = STM32_QSPI_CCR_DMODE_FOUR_LINE; - else if (mode & SPI_TX_DUAL) - dmode = STM32_QSPI_CCR_DMODE_TWO_LINE; - } else if ((fmode == STM32_QSPI_CCR_MEM_MAP) || - (fmode == STM32_QSPI_CCR_IND_READ)) { - if (mode & SPI_RX_QUAD) - dmode = STM32_QSPI_CCR_DMODE_FOUR_LINE; - else if (mode & SPI_RX_DUAL) - dmode = STM32_QSPI_CCR_DMODE_TWO_LINE; - } - } - - if (priv->command & CMD_HAS_DATA) - ccr_reg |= (dmode << STM32_QSPI_CCR_DMODE_SHIFT); - - if (priv->command & CMD_HAS_DUMMY) - ccr_reg |= ((priv->dummycycles & STM32_QSPI_CCR_DCYC_MASK) - << STM32_QSPI_CCR_DCYC_SHIFT); - - if (priv->command & CMD_HAS_ADR) { - ccr_reg |= (STM32_QSPI_CCR_ADSIZE_24BIT - << STM32_QSPI_CCR_ADSIZE_SHIFT); - ccr_reg |= (admode << STM32_QSPI_CCR_ADMODE_SHIFT); - } - - ccr_reg |= (fmode << STM32_QSPI_CCR_FMODE_SHIFT); - ccr_reg |= (imode << STM32_QSPI_CCR_IMODE_SHIFT); - ccr_reg |= cmd; - - return ccr_reg; + writeb(*val, addr); } -static void _stm32_qspi_enable_mmap(struct stm32_qspi_priv *priv, - struct spi_flash *flash) +static int _stm32_qspi_poll(struct stm32_qspi_priv *priv, + const struct spi_mem_op *op) { - unsigned int ccr_reg; + void (*fifo)(u8 *val, void __iomem *addr); + u32 len = op->data.nbytes, sr; + u8 *buf; + int ret; - priv->command = flash->read_opcode | CMD_HAS_ADR | CMD_HAS_DATA - | CMD_HAS_DUMMY; - priv->dummycycles = flash->read_dummy; + if (op->data.dir == SPI_MEM_DATA_IN) { + fifo = _stm32_qspi_read_fifo; + buf = op->data.buf.in; - ccr_reg = _stm32_qspi_gen_ccr(priv, STM32_QSPI_CCR_MEM_MAP); + } else { + fifo = _stm32_qspi_write_fifo; + buf = (u8 *)op->data.buf.out; + } - _stm32_qspi_wait_for_not_busy(priv); + while (len--) { + ret = readl_poll_timeout(&priv->regs->sr, sr, + sr & STM32_QSPI_SR_FTF, + STM32_QSPI_FIFO_TIMEOUT_US); + if (ret) { + pr_err("fifo timeout (len:%d stat:%#x)\n", len, sr); + return ret; + } - writel(ccr_reg, &priv->regs->ccr); + fifo(buf++, &priv->regs->dr); + } - priv->dummycycles = 0; + return 0; } -static void _stm32_qspi_disable_mmap(struct stm32_qspi_priv *priv) +static int stm32_qspi_mm(struct stm32_qspi_priv *priv, + const struct spi_mem_op *op) { - setbits_le32(&priv->regs->cr, STM32_QSPI_CR_ABORT); -} + memcpy_fromio(op->data.buf.in, priv->mm_base + op->addr.val, + op->data.nbytes); -static void _stm32_qspi_set_xfer_length(struct stm32_qspi_priv *priv, - u32 length) -{ - writel(length - 1, &priv->regs->dlr); + return 0; } -static void _stm32_qspi_start_xfer(struct stm32_qspi_priv *priv, u32 cr_reg) +static int _stm32_qspi_tx(struct stm32_qspi_priv *priv, + const struct spi_mem_op *op, + u8 mode) { - writel(cr_reg, &priv->regs->ccr); + if (!op->data.nbytes) + return 0; + + if (mode == STM32_QSPI_CCR_MEM_MAP) + return stm32_qspi_mm(priv, op); - if (priv->command & CMD_HAS_ADR) - writel(priv->address, &priv->regs->ar); + return _stm32_qspi_poll(priv, op); } -static int _stm32_qspi_xfer(struct stm32_qspi_priv *priv, - struct spi_flash *flash, unsigned int bitlen, - const u8 *dout, u8 *din, unsigned long flags) +static int _stm32_qspi_get_mode(u8 buswidth) { - unsigned int words = bitlen / 8; - u32 ccr_reg; - int i; + if (buswidth == 4) + return 3; - if (flags & SPI_XFER_MMAP) { - _stm32_qspi_enable_mmap(priv, flash); - return 0; - } else if (flags & SPI_XFER_MMAP_END) { - _stm32_qspi_disable_mmap(priv); - return 0; - } - - if (bitlen == 0) - return -1; + return buswidth; +} - if (bitlen % 8) { - debug("spi_xfer: Non byte aligned SPI transfer\n"); - return -1; - } +static int stm32_qspi_exec_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + struct stm32_qspi_priv *priv = dev_get_priv(slave->dev->parent); + u32 cr, ccr, addr_max; + u8 mode = STM32_QSPI_CCR_IND_WRITE; + int timeout, ret; + + debug("%s: cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n", + __func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth, + op->dummy.buswidth, op->data.buswidth, + op->addr.val, op->data.nbytes); + + ret = _stm32_qspi_wait_for_not_busy(priv); + if (ret) + return ret; - if (dout && din) { - debug("spi_xfer: QSPI cannot have data in and data out set\n"); - return -1; - } + addr_max = op->addr.val + op->data.nbytes + 1; - if (!dout && (flags & SPI_XFER_BEGIN)) { - debug("spi_xfer: QSPI transfer must begin with command\n"); - return -1; + if (op->data.dir == SPI_MEM_DATA_IN && op->data.nbytes) { + if (addr_max < priv->mm_size && op->addr.buswidth) + mode = STM32_QSPI_CCR_MEM_MAP; + else + mode = STM32_QSPI_CCR_IND_READ; } - if (dout) { - if (flags & SPI_XFER_BEGIN) { - /* data is command */ - priv->command = dout[0] | CMD_HAS_DATA; - if (words >= 4) { - /* address is here too */ - priv->address = (dout[1] << 16) | - (dout[2] << 8) | dout[3]; - priv->command |= CMD_HAS_ADR; - } - - if (words > 4) { - /* rest is dummy bytes */ - priv->dummycycles = (words - 4) * 8; - priv->command |= CMD_HAS_DUMMY; - } - - if (flags & SPI_XFER_END) { - /* command without data */ - priv->command &= ~(CMD_HAS_DATA); - } - } - - if (flags & SPI_XFER_END) { - ccr_reg = _stm32_qspi_gen_ccr(priv, - STM32_QSPI_CCR_IND_WRITE); - - _stm32_qspi_wait_for_not_busy(priv); - - if (priv->command & CMD_HAS_DATA) - _stm32_qspi_set_xfer_length(priv, words); - - _stm32_qspi_start_xfer(priv, ccr_reg); - - debug("%s: write: ccr:0x%08x adr:0x%08x\n", - __func__, priv->regs->ccr, priv->regs->ar); - - if (priv->command & CMD_HAS_DATA) { - _stm32_qspi_wait_for_ftf(priv); - - debug("%s: words:%d data:", __func__, words); + if (op->data.nbytes) + writel(op->data.nbytes - 1, &priv->regs->dlr); - i = 0; - while (words > i) { - writeb(dout[i], &priv->regs->dr); - debug("%02x ", dout[i]); - i++; - } - debug("\n"); + ccr = (mode << STM32_QSPI_CCR_FMODE_SHIFT); + ccr |= op->cmd.opcode; + ccr |= (_stm32_qspi_get_mode(op->cmd.buswidth) + << STM32_QSPI_CCR_IMODE_SHIFT); - _stm32_qspi_wait_for_complete(priv); - } else { - _stm32_qspi_wait_for_not_busy(priv); - } - } - } else if (din) { - ccr_reg = _stm32_qspi_gen_ccr(priv, STM32_QSPI_CCR_IND_READ); + if (op->addr.nbytes) { + ccr |= ((op->addr.nbytes - 1) << STM32_QSPI_CCR_ADSIZE_SHIFT); + ccr |= (_stm32_qspi_get_mode(op->addr.buswidth) + << STM32_QSPI_CCR_ADMODE_SHIFT); + } - _stm32_qspi_wait_for_not_busy(priv); + if (op->dummy.buswidth && op->dummy.nbytes) + ccr |= (op->dummy.nbytes * 8 / op->dummy.buswidth + << STM32_QSPI_CCR_DCYC_SHIFT); - _stm32_qspi_set_xfer_length(priv, words); + if (op->data.nbytes) + ccr |= (_stm32_qspi_get_mode(op->data.buswidth) + << STM32_QSPI_CCR_DMODE_SHIFT); - _stm32_qspi_start_xfer(priv, ccr_reg); + writel(ccr, &priv->regs->ccr); - debug("%s: read: ccr:0x%08x adr:0x%08x len:%d\n", __func__, - priv->regs->ccr, priv->regs->ar, priv->regs->dlr); + if (op->addr.nbytes && mode != STM32_QSPI_CCR_MEM_MAP) + writel(op->addr.val, &priv->regs->ar); - debug("%s: data:", __func__); + ret = _stm32_qspi_tx(priv, op, mode); + /* + * Abort in: + * -error case + * -read memory map: prefetching must be stopped if we read the last + * byte of device (device size - fifo size). like device size is not + * knows, the prefetching is always stop. + */ + if (ret || mode == STM32_QSPI_CCR_MEM_MAP) + goto abort; - i = 0; - while (words > i) { - din[i] = readb(&priv->regs->dr); - debug("%02x ", din[i]); - i++; - } - debug("\n"); - } + /* Wait end of tx in indirect mode */ + ret = _stm32_qspi_wait_cmd(priv, op); + if (ret) + goto abort; return 0; -} - -static int stm32_qspi_ofdata_to_platdata(struct udevice *bus) -{ - struct resource res_regs, res_mem; - struct stm32_qspi_platdata *plat = bus->platdata; - int ret; - ret = dev_read_resource_byname(bus, "qspi", &res_regs); - if (ret) { - debug("Error: can't get regs base addresses(ret = %d)!\n", ret); - return -ENOMEM; - } - ret = dev_read_resource_byname(bus, "qspi_mm", &res_mem); - if (ret) { - debug("Error: can't get mmap base address(ret = %d)!\n", ret); - return -ENOMEM; - } +abort: + setbits_le32(&priv->regs->cr, STM32_QSPI_CR_ABORT); - plat->max_hz = dev_read_u32_default(bus, "spi-max-frequency", - STM32_QSPI_DEFAULT_SCK_FREQ); + /* Wait clear of abort bit by hw */ + timeout = readl_poll_timeout(&priv->regs->cr, cr, + !(cr & STM32_QSPI_CR_ABORT), + STM32_ABT_TIMEOUT_US); - plat->base = res_regs.start; - plat->memory_map = res_mem.start; + writel(STM32_QSPI_FCR_CTCF, &priv->regs->fcr); - debug("%s: regs=<0x%x> mapped=<0x%x>, max-frequency=%d\n", - __func__, - plat->base, - plat->memory_map, - plat->max_hz - ); + if (ret || timeout) + pr_err("%s ret:%d abort timeout:%d\n", __func__, ret, timeout); - return 0; + return ret; } static int stm32_qspi_probe(struct udevice *bus) { - struct stm32_qspi_platdata *plat = dev_get_platdata(bus); struct stm32_qspi_priv *priv = dev_get_priv(bus); - struct dm_spi_bus *dm_spi_bus; + struct resource res; struct clk clk; struct reset_ctl reset_ctl; int ret; - dm_spi_bus = bus->uclass_priv; + ret = dev_read_resource_byname(bus, "qspi", &res); + if (ret) { + dev_err(bus, "can't get regs base addresses(ret = %d)!\n", ret); + return ret; + } - dm_spi_bus->max_hz = plat->max_hz; + priv->regs = (struct stm32_qspi_regs *)res.start; - priv->regs = (struct stm32_qspi_regs *)(uintptr_t)plat->base; + ret = dev_read_resource_byname(bus, "qspi_mm", &res); + if (ret) { + dev_err(bus, "can't get mmap base address(ret = %d)!\n", ret); + return ret; + } - priv->max_hz = plat->max_hz; + priv->mm_base = (void __iomem *)res.start; + + priv->mm_size = resource_size(&res); + if (priv->mm_size > STM32_QSPI_MAX_MMAP_SZ) + return -EINVAL; + + debug("%s: regs=<0x%p> mapped=<0x%p> mapped_size=<0x%lx>\n", + __func__, priv->regs, priv->mm_base, priv->mm_size); ret = clk_get_by_index(bus, 0, &clk); if (ret < 0) return ret; ret = clk_enable(&clk); - if (ret) { dev_err(bus, "failed to enable clock\n"); return ret; @@ -499,78 +380,68 @@ static int stm32_qspi_probe(struct udevice *bus) reset_deassert(&reset_ctl); } + priv->cs_used = -1; + setbits_le32(&priv->regs->cr, STM32_QSPI_CR_SSHIFT); - return 0; -} + /* Set dcr fsize to max address */ + setbits_le32(&priv->regs->dcr, + STM32_QSPI_DCR_FSIZE_MASK << STM32_QSPI_DCR_FSIZE_SHIFT); -static int stm32_qspi_remove(struct udevice *bus) -{ return 0; } static int stm32_qspi_claim_bus(struct udevice *dev) { - struct stm32_qspi_priv *priv; - struct udevice *bus; - struct spi_flash *flash; - struct dm_spi_slave_platdata *slave_plat; + struct stm32_qspi_priv *priv = dev_get_priv(dev->parent); + struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); - bus = dev->parent; - priv = dev_get_priv(bus); - flash = dev_get_uclass_priv(dev); - slave_plat = dev_get_parent_platdata(dev); - - if (slave_plat->cs >= STM32_MAX_NORCHIP) + if (slave_plat->cs >= STM32_QSPI_MAX_CHIP) return -ENODEV; - _stm32_qspi_set_cs(priv, slave_plat->cs); - - _stm32_qspi_set_flash_size(priv, flash->size); + if (priv->cs_used != slave_plat->cs) { + struct stm32_qspi_flash *flash = &priv->flash[slave_plat->cs]; - _stm32_qspi_enable(priv); + priv->cs_used = slave_plat->cs; - return 0; -} + if (flash->initialized) { + /* Set the configuration: speed + cs */ + writel(flash->cr, &priv->regs->cr); + writel(flash->dcr, &priv->regs->dcr); + } else { + /* Set chip select */ + clrsetbits_le32(&priv->regs->cr, STM32_QSPI_CR_FSEL, + priv->cs_used ? STM32_QSPI_CR_FSEL : 0); -static int stm32_qspi_release_bus(struct udevice *dev) -{ - struct stm32_qspi_priv *priv; - struct udevice *bus; + /* Save the configuration: speed + cs */ + flash->cr = readl(&priv->regs->cr); + flash->dcr = readl(&priv->regs->dcr); - bus = dev->parent; - priv = dev_get_priv(bus); + flash->initialized = true; + } + } - _stm32_qspi_disable(priv); + setbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN); return 0; } -static int stm32_qspi_xfer(struct udevice *dev, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) +static int stm32_qspi_release_bus(struct udevice *dev) { - struct stm32_qspi_priv *priv; - struct udevice *bus; - struct spi_flash *flash; + struct stm32_qspi_priv *priv = dev_get_priv(dev->parent); - bus = dev->parent; - priv = dev_get_priv(bus); - flash = dev_get_uclass_priv(dev); + clrbits_le32(&priv->regs->cr, STM32_QSPI_CR_EN); - return _stm32_qspi_xfer(priv, flash, bitlen, (const u8 *)dout, - (u8 *)din, flags); + return 0; } static int stm32_qspi_set_speed(struct udevice *bus, uint speed) { - struct stm32_qspi_platdata *plat = bus->platdata; struct stm32_qspi_priv *priv = dev_get_priv(bus); u32 qspi_clk = priv->clock_rate; u32 prescaler = 255; u32 csht; - - if (speed > plat->max_hz) - speed = plat->max_hz; + int ret; if (speed > 0) { prescaler = DIV_ROUND_UP(qspi_clk, speed) - 1; @@ -583,7 +454,9 @@ static int stm32_qspi_set_speed(struct udevice *bus, uint speed) csht = DIV_ROUND_UP((5 * qspi_clk) / (prescaler + 1), 100000000); csht = (csht - 1) & STM32_QSPI_DCR_CSHT_MASK; - _stm32_qspi_wait_for_not_busy(priv); + ret = _stm32_qspi_wait_for_not_busy(priv); + if (ret) + return ret; clrsetbits_le32(&priv->regs->cr, STM32_QSPI_CR_PRESCALER_MASK << @@ -603,8 +476,11 @@ static int stm32_qspi_set_speed(struct udevice *bus, uint speed) static int stm32_qspi_set_mode(struct udevice *bus, uint mode) { struct stm32_qspi_priv *priv = dev_get_priv(bus); + int ret; - _stm32_qspi_wait_for_not_busy(priv); + ret = _stm32_qspi_wait_for_not_busy(priv); + if (ret) + return ret; if ((mode & SPI_CPHA) && (mode & SPI_CPOL)) setbits_le32(&priv->regs->dcr, STM32_QSPI_DCR_CKMODE); @@ -616,20 +492,6 @@ static int stm32_qspi_set_mode(struct udevice *bus, uint mode) if (mode & SPI_CS_HIGH) return -ENODEV; - if (mode & SPI_RX_QUAD) - priv->mode |= SPI_RX_QUAD; - else if (mode & SPI_RX_DUAL) - priv->mode |= SPI_RX_DUAL; - else - priv->mode &= ~(SPI_RX_QUAD | SPI_RX_DUAL); - - if (mode & SPI_TX_QUAD) - priv->mode |= SPI_TX_QUAD; - else if (mode & SPI_TX_DUAL) - priv->mode |= SPI_TX_DUAL; - else - priv->mode &= ~(SPI_TX_QUAD | SPI_TX_DUAL); - debug("%s: regs=%p, mode=%d rx: ", __func__, priv->regs, mode); if (mode & SPI_RX_QUAD) @@ -649,12 +511,16 @@ static int stm32_qspi_set_mode(struct udevice *bus, uint mode) return 0; } +static const struct spi_controller_mem_ops stm32_qspi_mem_ops = { + .exec_op = stm32_qspi_exec_op, +}; + static const struct dm_spi_ops stm32_qspi_ops = { .claim_bus = stm32_qspi_claim_bus, .release_bus = stm32_qspi_release_bus, - .xfer = stm32_qspi_xfer, .set_speed = stm32_qspi_set_speed, .set_mode = stm32_qspi_set_mode, + .mem_ops = &stm32_qspi_mem_ops, }; static const struct udevice_id stm32_qspi_ids[] = { @@ -664,13 +530,10 @@ static const struct udevice_id stm32_qspi_ids[] = { }; U_BOOT_DRIVER(stm32_qspi) = { - .name = "stm32_qspi", - .id = UCLASS_SPI, + .name = "stm32_qspi", + .id = UCLASS_SPI, .of_match = stm32_qspi_ids, - .ops = &stm32_qspi_ops, - .ofdata_to_platdata = stm32_qspi_ofdata_to_platdata, - .platdata_auto_alloc_size = sizeof(struct stm32_qspi_platdata), + .ops = &stm32_qspi_ops, .priv_auto_alloc_size = sizeof(struct stm32_qspi_priv), - .probe = stm32_qspi_probe, - .remove = stm32_qspi_remove, + .probe = stm32_qspi_probe, }; diff --git a/drivers/sysreset/sysreset_syscon.c b/drivers/sysreset/sysreset_syscon.c index 34506402ac3..3fb39b9952e 100644 --- a/drivers/sysreset/sysreset_syscon.c +++ b/drivers/sysreset/sysreset_syscon.c @@ -36,20 +36,9 @@ static struct sysreset_ops syscon_reboot_ops = { int syscon_reboot_probe(struct udevice *dev) { struct syscon_reboot_priv *priv = dev_get_priv(dev); - int err; - u32 phandle; - ofnode node; - err = ofnode_read_u32(dev_ofnode(dev), "regmap", &phandle); - if (err) - return err; - - node = ofnode_get_by_phandle(phandle); - if (!ofnode_valid(node)) - return -EINVAL; - - priv->regmap = syscon_node_to_regmap(node); - if (!priv->regmap) { + priv->regmap = syscon_regmap_lookup_by_phandle(dev, "regmap"); + if (IS_ERR(priv->regmap)) { pr_err("unable to find regmap\n"); return -ENODEV; } diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 2eac4b63813..43412873c98 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -120,7 +120,7 @@ config CONSOLE_TRUETYPE_SIZE config SYS_WHITE_ON_BLACK bool "Display console as white on a black background" - default y if ARCH_AT91 || ARCH_EXYNOS || ARCH_ROCKCHIP || TEGRA || X86 + default y if ARCH_AT91 || ARCH_EXYNOS || ARCH_ROCKCHIP || TEGRA || X86 || ARCH_SUNXI help Normally the display is black on a white background, Enable this option to invert this, i.e. white on a black background. This can be diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c index 2cfa510d5f7..7f01ee94242 100644 --- a/drivers/video/console_normal.c +++ b/drivers/video/console_normal.c @@ -84,7 +84,8 @@ static int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y, return -EAGAIN; for (row = 0; row < VIDEO_FONT_HEIGHT; row++) { - uchar bits = video_fontdata[ch * VIDEO_FONT_HEIGHT + row]; + unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row; + uchar bits = video_fontdata[idx]; switch (vid_priv->bpix) { #ifdef CONFIG_VIDEO_BPP8 diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c index f076570335b..71a5c5efba3 100644 --- a/drivers/video/console_rotate.c +++ b/drivers/video/console_rotate.c @@ -90,7 +90,7 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch) int i, col; int mask = 0x80; void *line; - uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT; + uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT; line = vid_priv->fb + (VID_TO_PIXEL(x_frac) + 1) * vid_priv->line_length - (y + 1) * pbytes; @@ -222,7 +222,8 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch) VIDEO_FONT_WIDTH - 1) * VNBYTES(vid_priv->bpix); for (row = 0; row < VIDEO_FONT_HEIGHT; row++) { - uchar bits = video_fontdata[ch * VIDEO_FONT_HEIGHT + row]; + unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row; + uchar bits = video_fontdata[idx]; switch (vid_priv->bpix) { #ifdef CONFIG_VIDEO_BPP8 @@ -348,7 +349,7 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch) void *line = vid_priv->fb + (vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1) * vid_priv->line_length + y * pbytes; - uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT; + uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT; if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac) return -EAGAIN; diff --git a/drivers/video/pwm_backlight.c b/drivers/video/pwm_backlight.c index bd733f5f1ca..a587977c225 100644 --- a/drivers/video/pwm_backlight.c +++ b/drivers/video/pwm_backlight.c @@ -39,6 +39,12 @@ struct pwm_backlight_priv { struct udevice *pwm; uint channel; uint period_ns; + /* + * the polarity of one PWM + * 0: normal polarity + * 1: inverted polarity + */ + bool polarity; u32 *levels; int num_levels; uint default_level; @@ -57,7 +63,10 @@ static int set_pwm(struct pwm_backlight_priv *priv) (priv->max_level - priv->min_level + 1); ret = pwm_set_config(priv->pwm, priv->channel, priv->period_ns, duty_cycle); + if (ret) + return log_ret(ret); + ret = pwm_set_invert(priv->pwm, priv->channel, priv->polarity); return log_ret(ret); } @@ -202,6 +211,8 @@ static int pwm_backlight_ofdata_to_platdata(struct udevice *dev) return log_msg_ret("Not enough arguments to pwm\n", -EINVAL); priv->channel = args.args[0]; priv->period_ns = args.args[1]; + if (args.args_count > 2) + priv->polarity = args.args[2]; index = dev_read_u32_default(dev, "default-brightness-level", 255); cell = dev_read_prop(dev, "brightness-levels", &len); diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 2ca19d40491..c31303b56ed 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -259,6 +259,43 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) priv->escape = 0; switch (ch) { + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': { + int row, col, num; + char *s = priv->escape_buf; + + /* + * Cursor up/down: [%dA, [%dB, [%dE, [%dF + * Cursor left/right: [%dD, [%dC + */ + s++; /* [ */ + s = parsenum(s, &num); + if (num == 0) /* No digit in sequence ... */ + num = 1; /* ... means "move by 1". */ + + get_cursor_position(priv, &row, &col); + if (ch == 'A' || ch == 'F') + row -= num; + if (ch == 'C') + col += num; + if (ch == 'D') + col -= num; + if (ch == 'B' || ch == 'E') + row += num; + if (ch == 'E' || ch == 'F') + col = 0; + if (col < 0) + col = 0; + if (row < 0) + row = 0; + /* Right and bottom overflows are handled in the callee. */ + set_cursor_position(priv, row, col); + break; + } case 'H': case 'f': { int row, col; @@ -309,6 +346,25 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) } break; } + case 'K': { + struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); + int mode; + + /* + * Clear (parts of) current line + * [0K - clear line to end + * [2K - clear entire line + */ + parsenum(priv->escape_buf + 1, &mode); + + if (mode == 2) { + int row, col; + + get_cursor_position(priv, &row, &col); + vidconsole_set_row(dev, row, vid_priv->colour_bg); + } + break; + } case 'm': { struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); char *s = priv->escape_buf; @@ -360,6 +416,13 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) vid_priv->colour_fg = vid_console_color( vid_priv, vid_priv->fg_col_idx); break; + case 7: + /* reverse video */ + vid_priv->colour_fg = vid_console_color( + vid_priv, vid_priv->bg_col_idx); + vid_priv->colour_bg = vid_console_color( + vid_priv, vid_priv->fg_col_idx); + break; case 30 ... 37: /* foreground color */ vid_priv->fg_col_idx &= ~7; @@ -368,9 +431,11 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) vid_priv, vid_priv->fg_col_idx); break; case 40 ... 47: - /* background color */ + /* background color, also mask the bold bit */ + vid_priv->bg_col_idx &= ~0xf; + vid_priv->bg_col_idx |= val - 40; vid_priv->colour_bg = vid_console_color( - vid_priv, val - 40); + vid_priv, vid_priv->bg_col_idx); break; default: /* ignore unsupported SGR parameter */ @@ -392,6 +457,32 @@ error: priv->escape = 0; } +/* Put that actual character on the screen (using the CP437 code page). */ +static int vidconsole_output_glyph(struct udevice *dev, char ch) +{ + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); + int ret; + + /* + * Failure of this function normally indicates an unsupported + * colour depth. Check this and return an error to help with + * diagnosis. + */ + ret = vidconsole_putc_xy(dev, priv->xcur_frac, priv->ycur, ch); + if (ret == -EAGAIN) { + vidconsole_newline(dev); + ret = vidconsole_putc_xy(dev, priv->xcur_frac, priv->ycur, ch); + } + if (ret < 0) + return ret; + priv->xcur_frac += ret; + priv->last_ch = ch; + if (priv->xcur_frac >= priv->xsize_frac) + vidconsole_newline(dev); + + return 0; +} + int vidconsole_put_char(struct udevice *dev, char ch) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); @@ -429,23 +520,9 @@ int vidconsole_put_char(struct udevice *dev, char ch) priv->last_ch = 0; break; default: - /* - * Failure of this function normally indicates an unsupported - * colour depth. Check this and return an error to help with - * diagnosis. - */ - ret = vidconsole_putc_xy(dev, priv->xcur_frac, priv->ycur, ch); - if (ret == -EAGAIN) { - vidconsole_newline(dev); - ret = vidconsole_putc_xy(dev, priv->xcur_frac, - priv->ycur, ch); - } + ret = vidconsole_output_glyph(dev, ch); if (ret < 0) return ret; - priv->xcur_frac += ret; - priv->last_ch = ch; - if (priv->xcur_frac >= priv->xsize_frac) - vidconsole_newline(dev); break; } diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index f307cf243bd..14aac88d6d2 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -136,6 +136,7 @@ void video_set_default_colors(struct udevice *dev, bool invert) back = temp; } priv->fg_col_idx = fore; + priv->bg_col_idx = back; priv->colour_fg = vid_console_color(priv, fore); priv->colour_bg = vid_console_color(priv, back); } diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 34e78beb2a6..9d7f503b698 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -97,6 +97,7 @@ config WDT_BCM6345 config WDT_ORION bool "Orion watchdog timer support" depends on WDT + select CLK help Select this to enable Orion watchdog timer, which can be found on some Marvell Armada chips. diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c index a0df02d1038..885821d562e 100644 --- a/drivers/watchdog/orion_wdt.c +++ b/drivers/watchdog/orion_wdt.c @@ -14,7 +14,9 @@ #include <common.h> #include <dm.h> +#include <clk.h> #include <wdt.h> +#include <linux/kernel.h> #include <asm/io.h> #include <asm/arch/cpu.h> #include <asm/arch/soc.h> @@ -27,6 +29,8 @@ struct orion_wdt_priv { void __iomem *rstout; void __iomem *rstout_mask; u32 timeout; + unsigned long clk_rate; + struct clk clk; }; #define RSTOUT_ENABLE_BIT BIT(8) @@ -44,17 +48,18 @@ static int orion_wdt_reset(struct udevice *dev) struct orion_wdt_priv *priv = dev_get_priv(dev); /* Reload watchdog duration */ - writel(priv->timeout, priv->reg + priv->wdt_counter_offset); + writel(priv->clk_rate * priv->timeout, + priv->reg + priv->wdt_counter_offset); return 0; } -static int orion_wdt_start(struct udevice *dev, u64 timeout, ulong flags) +static int orion_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) { struct orion_wdt_priv *priv = dev_get_priv(dev); u32 reg; - priv->timeout = (u32) timeout; + priv->timeout = DIV_ROUND_UP(timeout_ms, 1000); /* Enable the fixed watchdog clock input */ reg = readl(priv->reg + TIMER_CTRL); @@ -62,7 +67,8 @@ static int orion_wdt_start(struct udevice *dev, u64 timeout, ulong flags) writel(reg, priv->reg + TIMER_CTRL); /* Set watchdog duration */ - writel(priv->timeout, priv->reg + priv->wdt_counter_offset); + writel(priv->clk_rate * priv->timeout, + priv->reg + priv->wdt_counter_offset); /* Clear the watchdog expiration bit */ reg = readl(priv->reg + TIMER_A370_STATUS); @@ -114,9 +120,7 @@ static inline bool save_reg_from_ofdata(struct udevice *dev, int index, fdt_addr_t addr; fdt_size_t off; - addr = fdtdec_get_addr_size_auto_noparent( - gd->fdt_blob, dev_of_offset(dev), "reg", index, &off, true); - + addr = devfdt_get_addr_size_index(dev, index, &off); if (addr == FDT_ADDR_T_NONE) return false; @@ -149,9 +153,18 @@ err: static int orion_wdt_probe(struct udevice *dev) { + struct orion_wdt_priv *priv = dev_get_priv(dev); + int ret; + debug("%s: Probing wdt%u\n", __func__, dev->seq); orion_wdt_stop(dev); + ret = clk_get_by_name(dev, "fixed", &priv->clk); + if (!ret) + priv->clk_rate = clk_get_rate(&priv->clk); + else + priv->clk_rate = 25000000; + return 0; } diff --git a/dts/Kconfig b/dts/Kconfig index a5f30c8fd03..c9ab66cccc8 100644 --- a/dts/Kconfig +++ b/dts/Kconfig @@ -291,10 +291,10 @@ config SPL_MULTI_DTB_FIT_USER_DEF_ADDR config OF_SPL_REMOVE_PROPS string "List of device tree properties to drop for SPL" depends on SPL_OF_CONTROL - default "interrupt-parent" if SPL_PINCTRL && SPL_CLK - default "clocks clock-names interrupt-parent" if SPL_PINCTRL - default "pinctrl-0 pinctrl-names interrupt-parent" if SPL_CLK - default "pinctrl-0 pinctrl-names clocks clock-names interrupt-parent" + default "interrupt-parent interrupts" if SPL_PINCTRL && SPL_CLK + default "clocks clock-names interrupt-parent interrupts" if SPL_PINCTRL + default "pinctrl-0 pinctrl-names interrupt-parent interrupts" if SPL_CLK + default "pinctrl-0 pinctrl-names clocks clock-names interrupt-parent interrupts" help Since SPL normally runs in a reduced memory space, the device tree is cut down to only what is needed to load and start U-Boot. Only diff --git a/include/configs/ap152.h b/include/configs/ap152.h new file mode 100644 index 00000000000..c948a440541 --- /dev/null +++ b/include/configs/ap152.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018 Rosy Song <rosysong@rosinson.com> + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define CONFIG_SYS_HZ 1000 +#define CONFIG_SYS_MHZ 375 +#define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000) + +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE + +#define CONFIG_SYS_MALLOC_LEN 0x40000 +#define CONFIG_SYS_BOOTPARAMS_LEN 0x20000 + +#define CONFIG_SYS_SDRAM_BASE 0x80000000 +#define CONFIG_SYS_LOAD_ADDR 0x81000000 + +#define CONFIG_SYS_INIT_RAM_ADDR 0xbd000000 +#define CONFIG_SYS_INIT_RAM_SIZE 0x2000 +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE - 1) + +/* + * Serial Port + */ +#define CONFIG_SYS_NS16550_CLK 25000000 +#define CONFIG_SYS_BAUDRATE_TABLE \ + {9600, 19200, 38400, 57600, 115200} + +#define CONFIG_BOOTCOMMAND "sf probe;" \ + "mtdparts default;" \ + "bootm 0x9f060000" + +#define CONFIG_ENV_SPI_MAX_HZ 25000000 +#define CONFIG_ENV_OFFSET 0x40000 +#define CONFIG_ENV_SECT_SIZE 0x10000 +#define CONFIG_ENV_SIZE 0x10000 + +/* Miscellaneous configurable options */ + +/* + * Diagnostics + */ +#define CONFIG_SYS_MEMTEST_START 0x80100000 +#define CONFIG_SYS_MEMTEST_END 0x83f00000 + +#endif /* __CONFIG_H */ diff --git a/include/configs/clearfog.h b/include/configs/clearfog.h index c51cf284502..9f8d3cc9e5e 100644 --- a/include/configs/clearfog.h +++ b/include/configs/clearfog.h @@ -21,8 +21,6 @@ * Commands configuration */ -/* SPI NOR flash default params, used by sf commands */ - /* * SDIO/MMC Card Configuration */ diff --git a/include/configs/db-88f6720.h b/include/configs/db-88f6720.h index 55968c2749e..63194d58a29 100644 --- a/include/configs/db-88f6720.h +++ b/include/configs/db-88f6720.h @@ -32,8 +32,6 @@ #define CONFIG_EHCI_IS_TDI #define CONFIG_USB_MAX_CONTROLLER_COUNT 3 -/* SPI NOR flash default params, used by sf commands */ - /* Environment in SPI NOR flash */ #define CONFIG_ENV_OFFSET (1 << 20) /* 1MiB in */ #define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */ diff --git a/include/configs/db-88f6820-amc.h b/include/configs/db-88f6820-amc.h index f1bdc2d3e74..2fdc8450292 100644 --- a/include/configs/db-88f6820-amc.h +++ b/include/configs/db-88f6820-amc.h @@ -16,8 +16,6 @@ * Commands configuration */ -/* SPI NOR flash default params, used by sf commands */ - /* USB/EHCI configuration */ #define CONFIG_EHCI_IS_TDI diff --git a/include/configs/db-88f6820-gp.h b/include/configs/db-88f6820-gp.h index d378052a8f7..ec2405bbb45 100644 --- a/include/configs/db-88f6820-gp.h +++ b/include/configs/db-88f6820-gp.h @@ -24,12 +24,6 @@ #define CONFIG_SYS_I2C_SPEED 100000 /* - * SPI Flash configuration for the environemnt access - */ - -/* SPI NOR flash default params, used by sf commands */ - -/* * SDIO/MMC Card Configuration */ #define CONFIG_SYS_MMC_BASE MVEBU_SDIO_BASE diff --git a/include/configs/db-mv784mp-gp.h b/include/configs/db-mv784mp-gp.h index b78dbcb6b94..1f9d24b19b9 100644 --- a/include/configs/db-mv784mp-gp.h +++ b/include/configs/db-mv784mp-gp.h @@ -29,8 +29,6 @@ #define CONFIG_EHCI_IS_TDI #define CONFIG_USB_MAX_CONTROLLER_COUNT 3 -/* SPI NOR flash default params, used by sf commands */ - /* Environment in SPI NOR flash */ #define CONFIG_ENV_OFFSET (1 << 20) /* 1MiB in */ #define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */ diff --git a/include/configs/db-xc3-24g4xg.h b/include/configs/db-xc3-24g4xg.h new file mode 100644 index 00000000000..0f75ad71859 --- /dev/null +++ b/include/configs/db-xc3-24g4xg.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2014 Stefan Roese <sr@denx.de> + */ + +#ifndef _CONFIG_DB_XC3_24G4G_H +#define _CONFIG_DB_XC3_24G4G_H + +/* + * High Level Configuration Options (easy to change) + */ + +#define CONFIG_SYS_KWD_CONFIG $(CONFIG_BOARDDIR)/kwbimage.cfg +#define CONFIG_SYS_TCLK 200000000 /* 200MHz */ + +/* USB/EHCI configuration */ +#define CONFIG_EHCI_IS_TDI + +/* Environment in SPI NOR flash */ +#define CONFIG_ENV_OFFSET (1 << 20) /* 1MiB in */ +#define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */ +#define CONFIG_ENV_SECT_SIZE (256 << 10) /* 256KiB sectors */ + +/* NAND */ +#define CONFIG_SYS_NAND_USE_FLASH_BBT +#define CONFIG_SYS_NAND_ONFI_DETECTION + +/* Keep device tree and initrd in lower memory so the kernel can access them */ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "fdt_high=0x10000000\0" \ + "initrd_high=0x10000000\0" + +/* + * mv-common.h should be defined after CMD configs since it used them + * to enable certain macros + */ +#include "mv-common.h" +#undef CONFIG_SYS_MAXARGS +#define CONFIG_SYS_MAXARGS 96 + +#endif /* _CONFIG_DB_XC3_24G4G_H */ diff --git a/include/configs/ds414.h b/include/configs/ds414.h index 275a2b47880..192c055c5cc 100644 --- a/include/configs/ds414.h +++ b/include/configs/ds414.h @@ -28,8 +28,6 @@ #define CONFIG_SYS_I2C_SLAVE 0x0 #define CONFIG_SYS_I2C_SPEED 100000 -/* SPI NOR flash default params, used by sf commands */ - /* Environment in SPI NOR flash */ #define CONFIG_ENV_OFFSET 0x7E0000 /* RedBoot config partition in DTS */ #define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */ diff --git a/include/configs/helios4.h b/include/configs/helios4.h index df4d8bcb3bb..b2badab15ea 100644 --- a/include/configs/helios4.h +++ b/include/configs/helios4.h @@ -23,8 +23,6 @@ * Commands configuration */ -/* SPI NOR flash default params, used by sf commands */ - /* * SDIO/MMC Card Configuration */ diff --git a/include/configs/lsxl.h b/include/configs/lsxl.h index 72e62658d0c..55c4e633254 100644 --- a/include/configs/lsxl.h +++ b/include/configs/lsxl.h @@ -76,9 +76,9 @@ "kernel_addr=0x00800000\0" \ "ramdisk_addr=0x01000000\0" \ "fdt_addr=0x00ff0000\0" \ - "bootcmd_legacy=ide reset " \ - "&& load ide ${hdpart} ${kernel_addr} /uImage.buffalo " \ - "&& load ide ${hdpart} ${ramdisk_addr} /initrd.buffalo "\ + "bootcmd_legacy=sata init " \ + "&& load sata ${hdpart} ${kernel_addr} /uImage.buffalo "\ + "&& load sata ${hdpart} ${ramdisk_addr} /initrd.buffalo "\ "&& bootm ${kernel_addr} ${ramdisk_addr}\0" \ "bootcmd_net=bootp ${kernel_addr} vmlinuz " \ "&& tftpboot ${ramdisk_addr} initrd.img " \ @@ -86,11 +86,11 @@ "&& tftpboot ${fdt_addr} " CONFIG_FDTFILE " " \ "&& bootz ${kernel_addr} " \ "${ramdisk_addr}:${ramdisk_len} ${fdt_addr}\0" \ - "bootcmd_hdd=ide reset " \ - "&& load ide ${hdpart} ${kernel_addr} /vmlinuz " \ - "&& load ide ${hdpart} ${ramdisk_addr} /initrd.img " \ + "bootcmd_hdd=sata init " \ + "&& load sata ${hdpart} ${kernel_addr} /vmlinuz " \ + "&& load sata ${hdpart} ${ramdisk_addr} /initrd.img " \ "&& setenv ramdisk_len ${filesize} " \ - "&& load ide ${hdpart} ${fdt_addr} /dtb " \ + "&& load sata ${hdpart} ${fdt_addr} /dtb " \ "&& bootz ${kernel_addr} " \ "${ramdisk_addr}:${ramdisk_len} ${fdt_addr}\0" \ "bootcmd_usb=usb start " \ @@ -131,13 +131,10 @@ #undef CONFIG_RESET_PHY_R #endif /* CONFIG_CMD_NET */ -#ifdef CONFIG_IDE -#undef CONFIG_SYS_IDE_MAXBUS -#define CONFIG_SYS_IDE_MAXBUS 1 -#undef CONFIG_SYS_IDE_MAXDEVICE -#define CONFIG_SYS_IDE_MAXDEVICE 1 -#define CONFIG_SYS_ATA_IDE0_OFFSET MV_SATA_PORT0_OFFSET +#ifdef CONFIG_SATA +#define CONFIG_SYS_SATA_MAX_DEVICE 1 #define CONFIG_SYS_64BIT_LBA +#define CONFIG_LBA48 #endif #endif /* _CONFIG_LSXL_H */ diff --git a/include/configs/mvebu_armada-8k.h b/include/configs/mvebu_armada-8k.h index f4972b64dcb..b28f3b94085 100644 --- a/include/configs/mvebu_armada-8k.h +++ b/include/configs/mvebu_armada-8k.h @@ -49,10 +49,6 @@ /* End of 16M scrubbed by training in bootrom */ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + 0xFF0000) -/* - * SPI Flash configuration - */ - #define CONFIG_ENV_OFFSET 0x180000 /* as Marvell U-Boot version */ #define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */ #define CONFIG_ENV_SECT_SIZE (64 << 10) /* 64KiB sectors */ diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h index 701298cab88..737dfd6a5c2 100644 --- a/include/configs/stm32mp1.h +++ b/include/configs/stm32mp1.h @@ -10,17 +10,17 @@ #include <linux/sizes.h> #include <asm/arch/stm32.h> -#define CONFIG_PREBOOT - /* * Number of clock ticks in 1 sec */ #define CONFIG_SYS_HZ 1000 +#ifndef CONFIG_STM32MP1_TRUSTED /* PSCI support */ #define CONFIG_ARMV7_PSCI_1_0 #define CONFIG_ARMV7_SECURE_BASE STM32_SYSRAM_BASE #define CONFIG_ARMV7_SECURE_MAX_SIZE STM32_SYSRAM_SIZE +#endif /* * malloc() pool size @@ -53,6 +53,9 @@ #define CONFIG_SETUP_MEMORY_TAGS #define CONFIG_INITRD_TAG +/* Extend size of kernel image for uncompression */ +#define CONFIG_SYS_BOOTM_LEN SZ_32M + /* SPL support */ #ifdef CONFIG_SPL /* BOOTROM load address */ @@ -69,36 +72,65 @@ STM32_SYSRAM_SIZE) #endif /* #ifdef CONFIG_SPL */ +#define CONFIG_SYS_MEMTEST_START STM32_DDR_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + SZ_64M) +#define CONFIG_SYS_MEMTEST_SCRATCH (CONFIG_SYS_MEMTEST_END + 4) + /*MMC SD*/ #define CONFIG_SYS_MMC_MAX_DEVICE 3 #define CONFIG_SUPPORT_EMMC_BOOT -#if !defined(CONFIG_SPL) || !defined(CONFIG_SPL_BUILD) +/*****************************************************************************/ +#ifdef CONFIG_DISTRO_DEFAULTS +/*****************************************************************************/ + +#if !defined(CONFIG_SPL_BUILD) #define BOOT_TARGET_DEVICES(func) \ func(MMC, mmc, 1) \ func(MMC, mmc, 0) \ func(MMC, mmc, 2) +/* + * bootcmd for stm32mp1: + * for serial/usb: execute the stm32prog command + * for mmc boot (eMMC, SD card), boot only on the same device + * for nand boot, boot with on ubifs partition on nand + * for nor boot, use the default order + */ +#define CONFIG_PREBOOT -#include <config_distro_bootcmd.h> +#define STM32MP_BOOTCMD "bootcmd_stm32mp=" \ + "echo \"Boot over ${boot_device}${boot_instance}!\";" \ + "if test ${boot_device} = serial || test ${boot_device} = usb;" \ + "then stm32prog ${boot_device} ${boot_instance}; " \ + "else " \ + "if test ${boot_device} = mmc;" \ + "then env set boot_targets \"mmc${boot_instance}\"; fi;" \ + "if test ${boot_device} = nand;" \ + "then env set boot_targets ubifs0; fi;" \ + "run distro_bootcmd;" \ + "fi;\0" -#define STM32MP_PREBOOT \ - "echo \"Boot over ${boot_device}${boot_instance}!\"; " \ - "if test \"${boot_device}\" = \"mmc\"; then " \ - "env set boot_targets \"mmc${boot_instance}\"; "\ - "fi;" +#include <config_distro_bootcmd.h> +/* + * memory layout for 32M uncompressed/compressed kernel, + * 1M fdt, 1M script, 1M pxe and 1M for splashimage + * and the ramdisk at the end. + */ #define CONFIG_EXTRA_ENV_SETTINGS \ - "scriptaddr=0xC0000000\0" \ - "pxefile_addr_r=0xC0000000\0" \ - "kernel_addr_r=0xC1000000\0" \ - "fdt_addr_r=0xC4000000\0" \ - "ramdisk_addr_r=0xC4100000\0" \ + "kernel_addr_r=0xc2000000\0" \ + "fdt_addr_r=0xc4000000\0" \ + "scriptaddr=0xc4100000\0" \ + "pxefile_addr_r=0xc4200000\0" \ + "splashimage=0xc4300000\0" \ + "ramdisk_addr_r=0xc4400000\0" \ "fdt_high=0xffffffff\0" \ "initrd_high=0xffffffff\0" \ - "preboot=" STM32MP_PREBOOT "\0" \ + STM32MP_BOOTCMD \ BOOTENV #endif /* ifndef CONFIG_SPL_BUILD */ +#endif /* ifdef CONFIG_DISTRO_DEFAULTS*/ #endif /* __CONFIG_H */ diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index b01d1c3c843..ee18260be69 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -449,7 +449,6 @@ extern int soft_i2c_gpio_scl; "stdout=serial,vga\0" \ "stderr=serial,vga\0" #elif CONFIG_DM_VIDEO -#define CONFIG_SYS_WHITE_ON_BLACK #define CONSOLE_STDOUT_SETTINGS \ "stdout=serial,vidconsole\0" \ "stderr=serial,vidconsole\0" diff --git a/include/configs/theadorable.h b/include/configs/theadorable.h index 59b2546f0b4..cd92835112d 100644 --- a/include/configs/theadorable.h +++ b/include/configs/theadorable.h @@ -39,8 +39,6 @@ #define CONFIG_EHCI_IS_TDI #define CONFIG_USB_MAX_CONTROLLER_COUNT 3 -/* SPI NOR flash default params, used by sf commands */ - /* Environment in SPI NOR flash */ #define CONFIG_ENV_OFFSET (1 << 20) /* 1MiB in */ #define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */ diff --git a/include/configs/turris_mox.h b/include/configs/turris_mox.h index 5d5394e3e53..0de40eddcb5 100644 --- a/include/configs/turris_mox.h +++ b/include/configs/turris_mox.h @@ -63,10 +63,6 @@ #define CONFIG_I2C_MV #define CONFIG_SYS_I2C_SLAVE 0x0 -/* - * SPI Flash configuration - */ - /* Environment in SPI NOR flash */ #define CONFIG_ENV_OFFSET 0x180000 /* as Marvell U-Boot version */ #define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */ diff --git a/include/configs/turris_omnia.h b/include/configs/turris_omnia.h index 038f6398eb6..c7805cf36bf 100644 --- a/include/configs/turris_omnia.h +++ b/include/configs/turris_omnia.h @@ -34,9 +34,6 @@ # define CONFIG_WATCHDOG #endif -/* SPI NOR flash default params, used by sf commands */ -#define CONFIG_SPI_FLASH_SPANSION - /* * SDIO/MMC Card Configuration */ diff --git a/include/configs/vcoreiii.h b/include/configs/vcoreiii.h index 2840c7b815b..8c68372026e 100644 --- a/include/configs/vcoreiii.h +++ b/include/configs/vcoreiii.h @@ -10,7 +10,7 @@ /* Onboard devices */ -#define CONFIG_SYS_MALLOC_LEN 0x100000 +#define CONFIG_SYS_MALLOC_LEN 0x1F0000 #define CONFIG_SYS_LOAD_ADDR 0x00100000 #define CONFIG_SYS_INIT_SP_OFFSET 0x400000 @@ -27,7 +27,7 @@ #if defined(CONFIG_ENV_IS_IN_SPI_FLASH) && !defined(CONFIG_ENV_OFFSET) #define CONFIG_ENV_OFFSET (1024 * 1024) -#define CONFIG_ENV_SIZE (256 * 1024) +#define CONFIG_ENV_SIZE (8 * 1024) #define CONFIG_ENV_SECT_SIZE (256 * 1024) #define CONFIG_SYS_REDUNDAND_ENVIRONMENT diff --git a/include/dm/pinctrl.h b/include/dm/pinctrl.h index ff2b82e7c25..63a7d55b888 100644 --- a/include/dm/pinctrl.h +++ b/include/dm/pinctrl.h @@ -355,18 +355,6 @@ int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph); int pinctrl_decode_pin_config(const void *blob, int node); /** - * pinctrl_decode_pin_config_dm() - decode pin configuration flags - * - * This decodes some of the PIN_CONFIG values into flags, with each value - * being (1 << pin_cfg). This does not support things with values like the - * slew rate. - * - * @pinconfig: Pinconfig udevice - * @return decoded flag value, or -ve on error - */ -int pinctrl_decode_pin_config_dm(struct udevice *dev); - -/** * pinctrl_get_gpio_mux() - get the mux value for a particular GPIO * * This allows the raw mux value for a GPIO to be obtained. It is diff --git a/include/dm/util.h b/include/dm/util.h index 9ff6531d1b2..60d3b93decd 100644 --- a/include/dm/util.h +++ b/include/dm/util.h @@ -40,32 +40,6 @@ static inline void dm_dump_devres(void) #endif /** - * Check if a dt node should be or was bound before relocation. - * - * Devicetree nodes can be marked as needed to be bound - * in the loader stages via special devicetree properties. - * - * Before relocation this function can be used to check if nodes - * are required in either SPL or TPL stages. - * - * After relocation and jumping into the real U-Boot binary - * it is possible to determine if a node was bound in one of - * SPL/TPL stages. - * - * There are 3 settings currently in use - * - - * - u-boot,dm-pre-reloc: legacy and indicates any of TPL or SPL - * Existing platforms only use it to indicate nodes needed in - * SPL. Should probably be replaced by u-boot,dm-spl for - * existing platforms. - * @blob: devicetree - * @offset: node offset - * - * Returns true if node is needed in SPL/TL, false otherwise. - */ -bool dm_fdt_pre_reloc(const void *blob, int offset); - -/** * Check if an of node should be or was bound before relocation. * * Devicetree nodes can be marked as needed to be bound diff --git a/include/dt-bindings/mfd/st,stpmic1.h b/include/dt-bindings/mfd/st,stpmic1.h new file mode 100644 index 00000000000..b2d6c83462a --- /dev/null +++ b/include/dt-bindings/mfd/st,stpmic1.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) STMicroelectronics 2018 - All Rights Reserved + * Author: Philippe Peurichard <philippe.peurichard@st.com>, + * Pascal Paillet <p.paillet@st.com> for STMicroelectronics. + */ + +#ifndef __DT_BINDINGS_STPMIC1_H__ +#define __DT_BINDINGS_STPMIC1_H__ + +/* IRQ definitions */ +#define IT_PONKEY_F 0 +#define IT_PONKEY_R 1 +#define IT_WAKEUP_F 2 +#define IT_WAKEUP_R 3 +#define IT_VBUS_OTG_F 4 +#define IT_VBUS_OTG_R 5 +#define IT_SWOUT_F 6 +#define IT_SWOUT_R 7 + +#define IT_CURLIM_BUCK1 8 +#define IT_CURLIM_BUCK2 9 +#define IT_CURLIM_BUCK3 10 +#define IT_CURLIM_BUCK4 11 +#define IT_OCP_OTG 12 +#define IT_OCP_SWOUT 13 +#define IT_OCP_BOOST 14 +#define IT_OVP_BOOST 15 + +#define IT_CURLIM_LDO1 16 +#define IT_CURLIM_LDO2 17 +#define IT_CURLIM_LDO3 18 +#define IT_CURLIM_LDO4 19 +#define IT_CURLIM_LDO5 20 +#define IT_CURLIM_LDO6 21 +#define IT_SHORT_SWOTG 22 +#define IT_SHORT_SWOUT 23 + +#define IT_TWARN_F 24 +#define IT_TWARN_R 25 +#define IT_VINLOW_F 26 +#define IT_VINLOW_R 27 +#define IT_SWIN_F 30 +#define IT_SWIN_R 31 + +#endif /* __DT_BINDINGS_STPMIC1_H__ */ diff --git a/include/dt-bindings/mfd/st,stpmu1.h b/include/dt-bindings/mfd/st,stpmu1.h deleted file mode 100644 index 81982ebe2c2..00000000000 --- a/include/dt-bindings/mfd/st,stpmu1.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of stpmu1 pmic driver - * - * Copyright (C) 2017, STMicroelectronics - All Rights Reserved - * Author: Pascal Paillet <p.paillet@st.com> for STMicroelectronics. - * - * License type: GPLv2 - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef __DT_BINDINGS_STPMU1_H__ -#define __DT_BINDINGS_STPMU1_H__ - -/* IRQ definitions */ -#define IT_PONKEY_F 0 -#define IT_PONKEY_R 1 -#define IT_WAKEUP_F 2 -#define IT_WAKEUP_R 3 -#define IT_VBUS_OTG_F 4 -#define IT_VBUS_OTG_R 5 -#define IT_SWOUT_F 6 -#define IT_SWOUT_R 7 - -#define IT_CURLIM_BUCK1 8 -#define IT_CURLIM_BUCK2 9 -#define IT_CURLIM_BUCK3 10 -#define IT_CURLIM_BUCK4 11 -#define IT_OCP_OTG 12 -#define IT_OCP_SWOUT 13 -#define IT_OCP_BOOST 14 -#define IT_OVP_BOOST 15 - -#define IT_CURLIM_LDO1 16 -#define IT_CURLIM_LDO2 17 -#define IT_CURLIM_LDO3 18 -#define IT_CURLIM_LDO4 19 -#define IT_CURLIM_LDO5 20 -#define IT_CURLIM_LDO6 21 -#define IT_SHORT_SWOTG 22 -#define IT_SHORT_SWOUT 23 - -#define IT_TWARN_F 24 -#define IT_TWARN_R 25 -#define IT_VINLOW_F 26 -#define IT_VINLOW_R 27 -#define IT_SWIN_F 30 -#define IT_SWIN_R 31 - -#endif /* __DT_BINDINGS_STPMU1_H__ */ diff --git a/include/dt-bindings/mscc/jr2_data.h b/include/dt-bindings/mscc/jr2_data.h new file mode 100644 index 00000000000..2f06fc5c5de --- /dev/null +++ b/include/dt-bindings/mscc/jr2_data.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#ifndef _JR2_DATA_H_ +#define _JR2_DATA_H_ + +#define SERDES1G(x) (x) +#define SERDES1G_MAX SERDES1G(10) +#define SERDES6G(x) (SERDES1G_MAX + 1 + (x)) +#define SERDES6G_MAX SERDES6G(17) +#define SERDES_MAX (SERDES6G_MAX + 1) + +/* similar with phy_interface_t */ +#define PHY_MODE_SGMII 2 +#define PHY_MODE_QSGMII 4 + +#endif diff --git a/include/fdtdec.h b/include/fdtdec.h index ad00f79f203..266c58271f0 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -23,15 +23,44 @@ */ typedef phys_addr_t fdt_addr_t; typedef phys_size_t fdt_size_t; + +static inline fdt32_t fdt_addr_unpack(fdt_addr_t addr, fdt32_t *upper) +{ + if (upper) +#ifdef CONFIG_PHYS_64BIT + *upper = addr >> 32; +#else + *upper = 0; +#endif + + return addr; +} + +static inline fdt32_t fdt_size_unpack(fdt_size_t size, fdt32_t *upper) +{ + if (upper) +#ifdef CONFIG_PHYS_64BIT + *upper = size >> 32; +#else + *upper = 0; +#endif + + return size; +} + #ifdef CONFIG_PHYS_64BIT #define FDT_ADDR_T_NONE (-1U) #define fdt_addr_to_cpu(reg) be64_to_cpu(reg) #define fdt_size_to_cpu(reg) be64_to_cpu(reg) +#define cpu_to_fdt_addr(reg) cpu_to_be64(reg) +#define cpu_to_fdt_size(reg) cpu_to_be64(reg) typedef fdt64_t fdt_val_t; #else #define FDT_ADDR_T_NONE (-1U) #define fdt_addr_to_cpu(reg) be32_to_cpu(reg) #define fdt_size_to_cpu(reg) be32_to_cpu(reg) +#define cpu_to_fdt_addr(reg) cpu_to_be32(reg) +#define cpu_to_fdt_size(reg) cpu_to_be32(reg) typedef fdt32_t fdt_val_t; #endif @@ -992,6 +1021,146 @@ int fdtdec_setup_memory_banksize_fdt(const void *blob); int fdtdec_setup_memory_banksize(void); /** + * fdtdec_set_phandle() - sets the phandle of a given node + * + * @param blob FDT blob + * @param node offset in the FDT blob of the node whose phandle is to + * be set + * @param phandle phandle to set for the given node + * @return 0 on success or a negative error code on failure + */ +int fdtdec_set_phandle(void *blob, int node, uint32_t phandle); + +/** + * fdtdec_add_reserved_memory() - add or find a reserved-memory node + * + * If a reserved-memory node already exists for the given carveout, a phandle + * for that node will be returned. Otherwise a new node will be created and a + * phandle corresponding to it will be returned. + * + * See Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt + * for details on how to use reserved memory regions. + * + * As an example, consider the following code snippet: + * + * struct fdt_memory fb = { + * .start = 0x92cb3000, + * .end = 0x934b2fff, + * }; + * uint32_t phandle; + * + * fdtdec_add_reserved_memory(fdt, "framebuffer", &fb, &phandle); + * + * This results in the following subnode being added to the top-level + * /reserved-memory node: + * + * reserved-memory { + * #address-cells = <0x00000002>; + * #size-cells = <0x00000002>; + * ranges; + * + * framebuffer@92cb3000 { + * reg = <0x00000000 0x92cb3000 0x00000000 0x00800000>; + * phandle = <0x0000004d>; + * }; + * }; + * + * If the top-level /reserved-memory node does not exist, it will be created. + * The phandle returned from the function call can be used to reference this + * reserved memory region from other nodes. + * + * See fdtdec_set_carveout() for a more elaborate example. + * + * @param blob FDT blob + * @param basename base name of the node to create + * @param carveout information about the carveout region + * @param phandlep return location for the phandle of the carveout region + * @return 0 on success or a negative error code on failure + */ +int fdtdec_add_reserved_memory(void *blob, const char *basename, + const struct fdt_memory *carveout, + uint32_t *phandlep); + +/** + * fdtdec_get_carveout() - reads a carveout from an FDT + * + * Reads information about a carveout region from an FDT. The carveout is a + * referenced by its phandle that is read from a given property in a given + * node. + * + * @param blob FDT blob + * @param node name of a node + * @param name name of the property in the given node that contains + * the phandle for the carveout + * @param index index of the phandle for which to read the carveout + * @param carveout return location for the carveout information + * @return 0 on success or a negative error code on failure + */ +int fdtdec_get_carveout(const void *blob, const char *node, const char *name, + unsigned int index, struct fdt_memory *carveout); + +/** + * fdtdec_set_carveout() - sets a carveout region for a given node + * + * Sets a carveout region for a given node. If a reserved-memory node already + * exists for the carveout, the phandle for that node will be reused. If no + * such node exists, a new one will be created and a phandle to it stored in + * a specified property of the given node. + * + * As an example, consider the following code snippet: + * + * const char *node = "/host1x@50000000/dc@54240000"; + * struct fdt_memory fb = { + * .start = 0x92cb3000, + * .end = 0x934b2fff, + * }; + * + * fdtdec_set_carveout(fdt, node, "memory-region", 0, "framebuffer", &fb); + * + * dc@54200000 is a display controller and was set up by the bootloader to + * scan out the framebuffer specified by "fb". This would cause the following + * reserved memory region to be added: + * + * reserved-memory { + * #address-cells = <0x00000002>; + * #size-cells = <0x00000002>; + * ranges; + * + * framebuffer@92cb3000 { + * reg = <0x00000000 0x92cb3000 0x00000000 0x00800000>; + * phandle = <0x0000004d>; + * }; + * }; + * + * A "memory-region" property will also be added to the node referenced by the + * offset parameter. + * + * host1x@50000000 { + * ... + * + * dc@54240000 { + * ... + * memory-region = <0x0000004d>; + * ... + * }; + * + * ... + * }; + * + * @param blob FDT blob + * @param node name of the node to add the carveout to + * @param prop_name name of the property in which to store the phandle of + * the carveout + * @param index index of the phandle to store + * @param name base name of the reserved-memory node to create + * @param carveout information about the carveout to add + * @return 0 on success or a negative error code on failure + */ +int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name, + unsigned int index, const char *name, + const struct fdt_memory *carveout); + +/** * Set up the device tree ready for use */ int fdtdec_setup(void); diff --git a/include/i2c.h b/include/i2c.h index ccffc195527..a5c760c711e 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -68,9 +68,11 @@ struct dm_i2c_chip { * I2C bus udevice. * * @speed_hz: Bus speed in hertz (typically 100000) + * @max_transaction_bytes: Maximal size of single I2C transfer */ struct dm_i2c_bus { int speed_hz; + int max_transaction_bytes; }; /* diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index cd1f557a2f3..e3549f0a461 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -392,7 +392,7 @@ static inline void mtd_set_ooblayout(struct mtd_info *mtd, mtd->ooblayout = ooblayout; } -static inline int mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops) +static inline u32 mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops) { return ops->mode == MTD_OPS_AUTO_OOB ? mtd->oobavail : mtd->oobsize; } diff --git a/include/power/stpmic1.h b/include/power/stpmic1.h new file mode 100644 index 00000000000..0e6721d852a --- /dev/null +++ b/include/power/stpmic1.h @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + */ + +#ifndef __PMIC_STPMIC1_H_ +#define __PMIC_STPMIC1_H_ + +#define STPMIC1_MAIN_CR 0x10 +#define STPMIC1_BUCKS_MRST_CR 0x18 +#define STPMIC1_LDOS_MRST_CR 0x1a +#define STPMIC1_BUCKX_MAIN_CR(buck) (0x20 + (buck)) +#define STPMIC1_REFDDR_MAIN_CR 0x24 +#define STPMIC1_LDOX_MAIN_CR(ldo) (0x25 + (ldo)) +#define STPMIC1_BST_SW_CR 0x40 +#define STPMIC1_NVM_SR 0xb8 +#define STPMIC1_NVM_CR 0xb9 + +/* Main PMIC Control Register (MAIN_CR) */ +#define STPMIC1_SWOFF BIT(0) +#define STPMIC1_RREQ_EN BIT(1) + +/* BUCKS_MRST_CR */ +#define STPMIC1_MRST_BUCK(buck) BIT(buck) +#define STPMIC1_MRST_BUCK_ALL GENMASK(3, 0) + +/* LDOS_MRST_CR */ +#define STPMIC1_MRST_LDO(ldo) BIT(ldo) +#define STPMIC1_MRST_LDO_ALL GENMASK(6, 0) + +/* BUCKx_MAIN_CR (x=1...4) */ +#define STPMIC1_BUCK_ENA BIT(0) +#define STPMIC1_BUCK_PREG_MODE BIT(1) +#define STPMIC1_BUCK_VOUT_MASK GENMASK(7, 2) +#define STPMIC1_BUCK_VOUT_SHIFT 2 +#define STPMIC1_BUCK_VOUT(sel) (sel << STPMIC1_BUCK_VOUT_SHIFT) + +#define STPMIC1_BUCK2_1200000V STPMIC1_BUCK_VOUT(24) +#define STPMIC1_BUCK2_1350000V STPMIC1_BUCK_VOUT(30) + +#define STPMIC1_BUCK3_1800000V STPMIC1_BUCK_VOUT(39) + +/* REFDDR_MAIN_CR */ +#define STPMIC1_VREF_ENA BIT(0) + +/* LDOX_MAIN_CR */ +#define STPMIC1_LDO_ENA BIT(0) +#define STPMIC1_LDO12356_VOUT_MASK GENMASK(6, 2) +#define STPMIC1_LDO12356_VOUT_SHIFT 2 +#define STPMIC1_LDO_VOUT(sel) (sel << STPMIC1_LDO12356_VOUT_SHIFT) + +#define STPMIC1_LDO3_MODE BIT(7) +#define STPMIC1_LDO3_DDR_SEL 31 +#define STPMIC1_LDO3_1800000 STPMIC1_LDO_VOUT(9) + +#define STPMIC1_LDO4_UV 3300000 + +/* BST_SW_CR */ +#define STPMIC1_BST_ON BIT(0) +#define STPMIC1_VBUSOTG_ON BIT(1) +#define STPMIC1_SWOUT_ON BIT(2) +#define STPMIC1_PWR_SW_ON (STPMIC1_VBUSOTG_ON | STPMIC1_SWOUT_ON) + +/* NVM_SR */ +#define STPMIC1_NVM_BUSY BIT(0) + +/* NVM_CR */ +#define STPMIC1_NVM_CMD_PROGRAM 1 +#define STPMIC1_NVM_CMD_READ 2 + +/* Timeout */ +#define STPMIC1_DEFAULT_START_UP_DELAY_MS 1 +#define STPMIC1_DEFAULT_STOP_DELAY_MS 5 +#define STPMIC1_USB_BOOST_START_UP_DELAY_MS 10 + +enum { + STPMIC1_BUCK1, + STPMIC1_BUCK2, + STPMIC1_BUCK3, + STPMIC1_BUCK4, + STPMIC1_MAX_BUCK, +}; + +enum { + STPMIC1_PREG_MODE_HP, + STPMIC1_PREG_MODE_LP, +}; + +enum { + STPMIC1_LDO1, + STPMIC1_LDO2, + STPMIC1_LDO3, + STPMIC1_LDO4, + STPMIC1_LDO5, + STPMIC1_LDO6, + STPMIC1_MAX_LDO, +}; + +enum { + STPMIC1_LDO_MODE_NORMAL, + STPMIC1_LDO_MODE_BYPASS, + STPMIC1_LDO_MODE_SINK_SOURCE, +}; + +enum { + STPMIC1_PWR_SW1, + STPMIC1_PWR_SW2, + STPMIC1_MAX_PWR_SW, +}; + +int stpmic1_shadow_read_byte(u8 addr, u8 *buf); +int stpmic1_shadow_write_byte(u8 addr, u8 *buf); +int stpmic1_nvm_read_byte(u8 addr, u8 *buf); +int stpmic1_nvm_write_byte(u8 addr, u8 *buf); +int stpmic1_nvm_read_all(u8 *buf, int buf_len); +int stpmic1_nvm_write_all(u8 *buf, int buf_len); +#endif diff --git a/include/power/stpmu1.h b/include/power/stpmu1.h deleted file mode 100644 index 5906fbf832b..00000000000 --- a/include/power/stpmu1.h +++ /dev/null @@ -1,85 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ -/* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved - */ - -#ifndef __PMIC_STPMU1_H_ -#define __PMIC_STPMU1_H_ - -#define STPMU1_MASK_RESET_BUCK 0x18 -#define STPMU1_BUCKX_CTRL_REG(buck) (0x20 + (buck)) -#define STPMU1_VREF_CTRL_REG 0x24 -#define STPMU1_LDOX_CTRL_REG(ldo) (0x25 + (ldo)) -#define STPMU1_USB_CTRL_REG 0x40 -#define STPMU1_NVM_USER_STATUS_REG 0xb8 -#define STPMU1_NVM_USER_CONTROL_REG 0xb9 - -#define STPMU1_MASK_RESET_BUCK3 BIT(2) - -#define STPMU1_BUCK_EN BIT(0) -#define STPMU1_BUCK_MODE BIT(1) -#define STPMU1_BUCK_OUTPUT_MASK GENMASK(7, 2) -#define STPMU1_BUCK_OUTPUT_SHIFT 2 -#define STPMU1_BUCK2_1200000V (24 << STPMU1_BUCK_OUTPUT_SHIFT) -#define STPMU1_BUCK2_1350000V (30 << STPMU1_BUCK_OUTPUT_SHIFT) -#define STPMU1_BUCK3_1800000V (39 << STPMU1_BUCK_OUTPUT_SHIFT) - -#define STPMU1_VREF_EN BIT(0) - -#define STPMU1_LDO_EN BIT(0) -#define STPMU1_LDO12356_OUTPUT_MASK GENMASK(6, 2) -#define STPMU1_LDO12356_OUTPUT_SHIFT 2 -#define STPMU1_LDO3_MODE BIT(7) -#define STPMU1_LDO3_DDR_SEL 31 -#define STPMU1_LDO3_1800000 (9 << STPMU1_LDO12356_OUTPUT_SHIFT) -#define STPMU1_LDO4_UV 3300000 - -#define STPMU1_USB_BOOST_EN BIT(0) -#define STPMU1_USB_PWR_SW_EN GENMASK(2, 1) - -#define STPMU1_NVM_USER_CONTROL_PROGRAM BIT(0) -#define STPMU1_NVM_USER_CONTROL_READ BIT(1) - -#define STPMU1_NVM_USER_STATUS_BUSY BIT(0) -#define STPMU1_NVM_USER_STATUS_ERROR BIT(1) - -#define STPMU1_DEFAULT_START_UP_DELAY_MS 1 -#define STPMU1_DEFAULT_STOP_DELAY_MS 5 -#define STPMU1_USB_BOOST_START_UP_DELAY_MS 10 - -enum { - STPMU1_BUCK1, - STPMU1_BUCK2, - STPMU1_BUCK3, - STPMU1_BUCK4, - STPMU1_MAX_BUCK, -}; - -enum { - STPMU1_BUCK_MODE_HP, - STPMU1_BUCK_MODE_LP, -}; - -enum { - STPMU1_LDO1, - STPMU1_LDO2, - STPMU1_LDO3, - STPMU1_LDO4, - STPMU1_LDO5, - STPMU1_LDO6, - STPMU1_MAX_LDO, -}; - -enum { - STPMU1_LDO_MODE_NORMAL, - STPMU1_LDO_MODE_BYPASS, - STPMU1_LDO_MODE_SINK_SOURCE, -}; - -enum { - STPMU1_PWR_SW1, - STPMU1_PWR_SW2, - STPMU1_MAX_PWR_SW, -}; - -#endif diff --git a/include/spi.h b/include/spi.h index 92427e5f329..378594163b8 100644 --- a/include/spi.h +++ b/include/spi.h @@ -496,14 +496,15 @@ int spi_find_bus_and_cs(int busnum, int cs, struct udevice **busp, * device and slave device. * * If no such slave exists, and drv_name is not NULL, then a new slave device - * is automatically bound on this chip select. + * is automatically bound on this chip select with requested speed and mode. * - * Ths new slave device is probed ready for use with the given speed and mode. + * Ths new slave device is probed ready for use with the speed and mode + * from platdata when available or the requested values. * * @busnum: SPI bus number * @cs: Chip select to look for - * @speed: SPI speed to use for this slave - * @mode: SPI mode to use for this slave + * @speed: SPI speed to use for this slave when not available in platdata + * @mode: SPI mode to use for this slave when not available in platdata * @drv_name: Name of driver to attach to this chip select * @dev_name: Name of the new device thus created * @busp: Returns bus device diff --git a/include/video.h b/include/video.h index 1d57b48b173..485071d0723 100644 --- a/include/video.h +++ b/include/video.h @@ -70,6 +70,7 @@ enum video_log2_bpp { * the LCD is updated * @cmap: Colour map for 8-bit-per-pixel displays * @fg_col_idx: Foreground color code (bit 3 = bold, bit 0-2 = color) + * @bg_col_idx: Background color code (bit 3 = bold, bit 0-2 = color) */ struct video_priv { /* Things set up by the driver: */ @@ -92,6 +93,7 @@ struct video_priv { bool flush_dcache; ushort *cmap; u8 fg_col_idx; + u8 bg_col_idx; }; /* Placeholder - there are no video operations at present */ diff --git a/lib/Kconfig b/lib/Kconfig index 8fe5d85a050..2120216593e 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -436,4 +436,8 @@ source lib/efi/Kconfig source lib/efi_loader/Kconfig source lib/optee/Kconfig +config TEST_FDTDEC + bool "enable fdtdec test" + depends on OF_LIBFDT + endmenu diff --git a/lib/fdtdec.c b/lib/fdtdec.c index a51dc5e9867..9c9c3023473 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -45,7 +45,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(SAMSUNG_EXYNOS_TMU, "samsung,exynos-tmu"), COMPAT(SAMSUNG_EXYNOS_MIPI_DSI, "samsung,exynos-mipi-dsi"), COMPAT(SAMSUNG_EXYNOS_DWMMC, "samsung,exynos-dwmmc"), - COMPAT(GENERIC_SPI_FLASH, "spi-flash"), + COMPAT(GENERIC_SPI_FLASH, "jedec,spi-nor"), COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"), COMPAT(INTEL_MICROCODE, "intel,microcode"), COMPAT(INTEL_QRK_MRC, "intel,quark-mrc"), @@ -1261,6 +1261,231 @@ __weak void *board_fdt_blob_setup(void) } #endif +int fdtdec_set_phandle(void *blob, int node, uint32_t phandle) +{ + fdt32_t value = cpu_to_fdt32(phandle); + + return fdt_setprop(blob, node, "phandle", &value, sizeof(value)); +} + +static int fdtdec_init_reserved_memory(void *blob) +{ + int na, ns, node, err; + fdt32_t value; + + /* inherit #address-cells and #size-cells from the root node */ + na = fdt_address_cells(blob, 0); + ns = fdt_size_cells(blob, 0); + + node = fdt_add_subnode(blob, 0, "reserved-memory"); + if (node < 0) + return node; + + err = fdt_setprop(blob, node, "ranges", NULL, 0); + if (err < 0) + return err; + + value = cpu_to_fdt32(ns); + + err = fdt_setprop(blob, node, "#size-cells", &value, sizeof(value)); + if (err < 0) + return err; + + value = cpu_to_fdt32(na); + + err = fdt_setprop(blob, node, "#address-cells", &value, sizeof(value)); + if (err < 0) + return err; + + return node; +} + +int fdtdec_add_reserved_memory(void *blob, const char *basename, + const struct fdt_memory *carveout, + uint32_t *phandlep) +{ + fdt32_t cells[4] = {}, *ptr = cells; + uint32_t upper, lower, phandle; + int parent, node, na, ns, err; + char name[64]; + + /* create an empty /reserved-memory node if one doesn't exist */ + parent = fdt_path_offset(blob, "/reserved-memory"); + if (parent < 0) { + parent = fdtdec_init_reserved_memory(blob); + if (parent < 0) + return parent; + } + + /* only 1 or 2 #address-cells and #size-cells are supported */ + na = fdt_address_cells(blob, parent); + if (na < 1 || na > 2) + return -FDT_ERR_BADNCELLS; + + ns = fdt_size_cells(blob, parent); + if (ns < 1 || ns > 2) + return -FDT_ERR_BADNCELLS; + + /* find a matching node and return the phandle to that */ + fdt_for_each_subnode(node, blob, parent) { + const char *name = fdt_get_name(blob, node, NULL); + phys_addr_t addr, size; + + addr = fdtdec_get_addr_size(blob, node, "reg", &size); + if (addr == FDT_ADDR_T_NONE) { + debug("failed to read address/size for %s\n", name); + continue; + } + + if (addr == carveout->start && (addr + size) == carveout->end) { + *phandlep = fdt_get_phandle(blob, node); + return 0; + } + } + + /* + * Unpack the start address and generate the name of the new node + * base on the basename and the unit-address. + */ + lower = fdt_addr_unpack(carveout->start, &upper); + + if (na > 1 && upper > 0) + snprintf(name, sizeof(name), "%s@%x,%x", basename, upper, + lower); + else { + if (upper > 0) { + debug("address %08x:%08x exceeds addressable space\n", + upper, lower); + return -FDT_ERR_BADVALUE; + } + + snprintf(name, sizeof(name), "%s@%x", basename, lower); + } + + node = fdt_add_subnode(blob, parent, name); + if (node < 0) + return node; + + err = fdt_generate_phandle(blob, &phandle); + if (err < 0) + return err; + + err = fdtdec_set_phandle(blob, node, phandle); + if (err < 0) + return err; + + /* store one or two address cells */ + if (na > 1) + *ptr++ = cpu_to_fdt32(upper); + + *ptr++ = cpu_to_fdt32(lower); + + /* store one or two size cells */ + lower = fdt_size_unpack(carveout->end - carveout->start + 1, &upper); + + if (ns > 1) + *ptr++ = cpu_to_fdt32(upper); + + *ptr++ = cpu_to_fdt32(lower); + + err = fdt_setprop(blob, node, "reg", cells, (na + ns) * sizeof(*cells)); + if (err < 0) + return err; + + /* return the phandle for the new node for the caller to use */ + if (phandlep) + *phandlep = phandle; + + return 0; +} + +int fdtdec_get_carveout(const void *blob, const char *node, const char *name, + unsigned int index, struct fdt_memory *carveout) +{ + const fdt32_t *prop; + uint32_t phandle; + int offset, len; + fdt_size_t size; + + offset = fdt_path_offset(blob, node); + if (offset < 0) + return offset; + + prop = fdt_getprop(blob, offset, name, &len); + if (!prop) { + debug("failed to get %s for %s\n", name, node); + return -FDT_ERR_NOTFOUND; + } + + if ((len % sizeof(phandle)) != 0) { + debug("invalid phandle property\n"); + return -FDT_ERR_BADPHANDLE; + } + + if (len < (sizeof(phandle) * (index + 1))) { + debug("invalid phandle index\n"); + return -FDT_ERR_BADPHANDLE; + } + + phandle = fdt32_to_cpu(prop[index]); + + offset = fdt_node_offset_by_phandle(blob, phandle); + if (offset < 0) { + debug("failed to find node for phandle %u\n", phandle); + return offset; + } + + carveout->start = fdtdec_get_addr_size_auto_noparent(blob, offset, + "reg", 0, &size, + true); + if (carveout->start == FDT_ADDR_T_NONE) { + debug("failed to read address/size from \"reg\" property\n"); + return -FDT_ERR_NOTFOUND; + } + + carveout->end = carveout->start + size - 1; + + return 0; +} + +int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name, + unsigned int index, const char *name, + const struct fdt_memory *carveout) +{ + uint32_t phandle; + int err, offset; + fdt32_t value; + + /* XXX implement support for multiple phandles */ + if (index > 0) { + debug("invalid index %u\n", index); + return -FDT_ERR_BADOFFSET; + } + + err = fdtdec_add_reserved_memory(blob, name, carveout, &phandle); + if (err < 0) { + debug("failed to add reserved memory: %d\n", err); + return err; + } + + offset = fdt_path_offset(blob, node); + if (offset < 0) { + debug("failed to find offset for node %s: %d\n", node, offset); + return offset; + } + + value = cpu_to_fdt32(phandle); + + err = fdt_setprop(blob, offset, prop_name, &value, sizeof(value)); + if (err < 0) { + debug("failed to set %s property for node %s: %d\n", prop_name, + node, err); + return err; + } + + return 0; +} + int fdtdec_setup(void) { #if CONFIG_IS_ENABLED(OF_CONTROL) diff --git a/lib/fdtdec_test.c b/lib/fdtdec_test.c index a82e27de942..f6defe16c5a 100644 --- a/lib/fdtdec_test.c +++ b/lib/fdtdec_test.c @@ -15,48 +15,28 @@ /* The size of our test fdt blob */ #define FDT_SIZE (16 * 1024) -/** - * Check if an operation failed, and if so, print an error - * - * @param oper_name Name of operation - * @param err Error code to check - * - * @return 0 if ok, -1 if there was an error - */ -static int fdt_checkerr(const char *oper_name, int err) -{ - if (err) { - printf("%s: %s: %s\n", __func__, oper_name, fdt_strerror(err)); - return -1; - } +#define CHECK(op) ({ \ + int err = op; \ + if (err < 0) { \ + printf("%s: %s: %s\n", __func__, #op, \ + fdt_strerror(err)); \ + return err; \ + } \ + \ + err; \ + }) - return 0; -} +#define CHECKVAL(op, expected) ({ \ + int err = op; \ + if (err != expected) { \ + printf("%s: %s: expected %d, but returned %d\n",\ + __func__, #op, expected, err); \ + return err; \ + } \ + \ + err; \ + }) -/** - * Check the result of an operation and if incorrect, print an error - * - * @param oper_name Name of operation - * @param expected Expected value - * @param value Actual value - * - * @return 0 if ok, -1 if there was an error - */ -static int checkval(const char *oper_name, int expected, int value) -{ - if (expected != value) { - printf("%s: %s: expected %d, but returned %d\n", __func__, - oper_name, expected, value); - return -1; - } - - return 0; -} - -#define CHECK(op) if (fdt_checkerr(#op, op)) return -1 -#define CHECKVAL(op, expected) \ - if (checkval(#op, expected, op)) \ - return -1 #define CHECKOK(op) CHECKVAL(op, 0) /* maximum number of nodes / aliases to generate */ @@ -79,7 +59,9 @@ static int make_fdt(void *fdt, int size, const char *aliases, { char name[20], value[20]; const char *s; +#if defined(DEBUG) && defined(CONFIG_SANDBOX) int fd; +#endif CHECK(fdt_create(fdt, size)); CHECK(fdt_finish_reservemap(fdt)); @@ -136,7 +118,7 @@ static int run_test(const char *aliases, const char *nodes, const char *expect) CHECKVAL(make_fdt(blob, FDT_SIZE, aliases, nodes), 0); CHECKVAL(fdtdec_find_aliases_for_id(blob, "i2c", COMPAT_UNKNOWN, - list, ARRAY_SIZE(list)), strlen(expect)); + list, ARRAY_SIZE(list)), (int)strlen(expect)); /* Check we got the right ones */ for (i = 0, s = expect; *s; s++, i++) { @@ -159,6 +141,156 @@ static int run_test(const char *aliases, const char *nodes, const char *expect) return 0; } +static int make_fdt_carveout_device(void *fdt, uint32_t na, uint32_t ns) +{ + const char *basename = "/display"; + struct fdt_memory carveout = { +#ifdef CONFIG_PHYS_64BIT + .start = 0x180000000, + .end = 0x18fffffff, +#else + .start = 0x80000000, + .end = 0x8fffffff, +#endif + }; + fdt32_t cells[4], *ptr = cells; + uint32_t upper, lower; + char name[32]; + int offset; + + /* store one or two address cells */ + lower = fdt_addr_unpack(carveout.start, &upper); + + if (na > 1 && upper > 0) + snprintf(name, sizeof(name), "%s@%x,%x", basename, upper, + lower); + else + snprintf(name, sizeof(name), "%s@%x", basename, lower); + + if (na > 1) + *ptr++ = cpu_to_fdt32(upper); + + *ptr++ = cpu_to_fdt32(lower); + + /* store one or two size cells */ + lower = fdt_size_unpack(carveout.end - carveout.start + 1, &upper); + + if (ns > 1) + *ptr++ = cpu_to_fdt32(upper); + + *ptr++ = cpu_to_fdt32(lower); + + offset = CHECK(fdt_add_subnode(fdt, 0, name + 1)); + CHECK(fdt_setprop(fdt, offset, "reg", cells, (na + ns) * sizeof(*cells))); + + return fdtdec_set_carveout(fdt, name, "memory-region", 0, + "framebuffer", &carveout); +} + +static int check_fdt_carveout(void *fdt, uint32_t address_cells, + uint32_t size_cells) +{ +#ifdef CONFIG_PHYS_64BIT + const char *name = "/display@1,80000000"; + const struct fdt_memory expected = { + .start = 0x180000000, + .end = 0x18fffffff, + }; +#else + const char *name = "/display@80000000"; + const struct fdt_memory expected = { + .start = 0x80000000, + .end = 0x8fffffff, + }; +#endif + struct fdt_memory carveout; + + printf("carveout: %pap-%pap na=%u ns=%u: ", &expected.start, + &expected.end, address_cells, size_cells); + + CHECK(fdtdec_get_carveout(fdt, name, "memory-region", 0, &carveout)); + + if ((carveout.start != expected.start) || + (carveout.end != expected.end)) { + printf("carveout: %pap-%pap, expected %pap-%pap\n", + &carveout.start, &carveout.end, + &expected.start, &expected.end); + return 1; + } + + printf("pass\n"); + return 0; +} + +static int make_fdt_carveout(void *fdt, int size, uint32_t address_cells, + uint32_t size_cells) +{ + fdt32_t na = cpu_to_fdt32(address_cells); + fdt32_t ns = cpu_to_fdt32(size_cells); +#if defined(DEBUG) && defined(CONFIG_SANDBOX) + char filename[512]; + int fd; +#endif + int err; + + CHECK(fdt_create(fdt, size)); + CHECK(fdt_finish_reservemap(fdt)); + CHECK(fdt_begin_node(fdt, "")); + CHECK(fdt_property(fdt, "#address-cells", &na, sizeof(na))); + CHECK(fdt_property(fdt, "#size-cells", &ns, sizeof(ns))); + CHECK(fdt_end_node(fdt)); + CHECK(fdt_finish(fdt)); + CHECK(fdt_pack(fdt)); + + CHECK(fdt_open_into(fdt, fdt, FDT_SIZE)); + + err = make_fdt_carveout_device(fdt, address_cells, size_cells); + +#if defined(DEBUG) && defined(CONFIG_SANDBOX) + snprintf(filename, sizeof(filename), "/tmp/fdtdec-carveout-%u-%u.dtb", + address_cells, size_cells); + + fd = os_open(filename, OS_O_CREAT | OS_O_WRONLY); + if (fd < 0) { + printf("could not open .dtb file to write\n"); + goto out; + } + + os_write(fd, fdt, size); + os_close(fd); + +out: +#endif + return err; +} + +static int check_carveout(void) +{ + void *fdt; + + fdt = malloc(FDT_SIZE); + if (!fdt) { + printf("%s: out of memory\n", __func__); + return 1; + } + +#ifndef CONFIG_PHYS_64BIT + CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 1, 1), 0); + CHECKOK(check_fdt_carveout(fdt, 1, 1)); + CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 1, 2), 0); + CHECKOK(check_fdt_carveout(fdt, 1, 2)); +#else + CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 1, 1), -FDT_ERR_BADVALUE); + CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 1, 2), -FDT_ERR_BADVALUE); +#endif + CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 2, 1), 0); + CHECKOK(check_fdt_carveout(fdt, 2, 1)); + CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 2, 2), 0); + CHECKOK(check_fdt_carveout(fdt, 2, 2)); + + return 0; +} + static int do_test_fdtdec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { @@ -200,6 +332,8 @@ static int do_test_fdtdec(cmd_tbl_t *cmdtp, int flag, int argc, CHECKOK(run_test("2a 1a 0a", "a", " a")); CHECKOK(run_test("0a 1a 2a", "a", "a")); + CHECKOK(check_carveout()); + printf("Test passed\n"); return 0; } diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c index b6ca4e0b0c3..693de9aa5ad 100644 --- a/lib/libfdt/fdt_ro.c +++ b/lib/libfdt/fdt_ro.c @@ -73,6 +73,37 @@ uint32_t fdt_get_max_phandle(const void *fdt) return 0; } +int fdt_generate_phandle(const void *fdt, uint32_t *phandle) +{ + uint32_t max = 0; + int offset = -1; + + while (true) { + uint32_t value; + + offset = fdt_next_node(fdt, offset, NULL); + if (offset < 0) { + if (offset == -FDT_ERR_NOTFOUND) + break; + + return offset; + } + + value = fdt_get_phandle(fdt, offset); + + if (value > max) + max = value; + } + + if (max == FDT_MAX_PHANDLE) + return -FDT_ERR_NOPHANDLES; + + if (phandle) + *phandle = max + 1; + + return 0; +} + int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) { FDT_CHECK_HEADER(fdt); diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 1b6c154d8d7..2403825dc98 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -457,7 +457,6 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, return device_path_string(buf, end, ptr, field_width, precision, flags); #endif -#ifdef CONFIG_CMD_NET case 'a': flags |= SPECIAL | ZEROPAD; @@ -469,6 +468,7 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, break; } break; +#ifdef CONFIG_CMD_NET case 'm': flags |= SPECIAL; /* Fallthrough */ diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 70de9bb13a6..de67677f61a 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -525,4 +525,5 @@ quiet_cmd_fdtgrep = FDTGREP $@ cmd_fdtgrep = $(objtree)/tools/fdtgrep $(fdtgrep_props) -RT $< \ -n /chosen -n /config -O dtb | \ $(objtree)/tools/fdtgrep -r -O dtb - -o $@ \ + -P u-boot,dm-pre-reloc -P u-boot,dm-spl -P u-boot,dm-tpl \ $(addprefix -P ,$(subst $\",,$(CONFIG_OF_SPL_REMOVE_PROPS))) diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c index dfb3236da38..dc499884e4d 100644 --- a/scripts/dtc/libfdt/fdt_ro.c +++ b/scripts/dtc/libfdt/fdt_ro.c @@ -115,6 +115,37 @@ uint32_t fdt_get_max_phandle(const void *fdt) return 0; } +int fdt_generate_phandle(const void *fdt, uint32_t *phandle) +{ + uint32_t max = 0; + int offset = -1; + + while (true) { + uint32_t value; + + offset = fdt_next_node(fdt, offset, NULL); + if (offset < 0) { + if (offset == -FDT_ERR_NOTFOUND) + break; + + return offset; + } + + value = fdt_get_phandle(fdt, offset); + + if (value > max) + max = value; + } + + if (max == FDT_MAX_PHANDLE) + return -FDT_ERR_NOPHANDLES; + + if (phandle) + *phandle = max + 1; + + return 0; +} + int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) { FDT_CHECK_HEADER(fdt); diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h index fd73688f9e9..cf86ddba881 100644 --- a/scripts/dtc/libfdt/libfdt.h +++ b/scripts/dtc/libfdt/libfdt.h @@ -139,6 +139,10 @@ #define FDT_ERR_MAX 17 +/* constants */ +#define FDT_MAX_PHANDLE 0xfffffffe + /* Valid values for phandles range from 1 to 2^32-2. */ + /**********************************************************************/ /* Low-level functions (you probably don't need these) */ /**********************************************************************/ @@ -314,6 +318,21 @@ const char *fdt_string(const void *fdt, int stroffset); uint32_t fdt_get_max_phandle(const void *fdt); /** + * fdt_generate_phandle - return a new, unused phandle for a device tree blob + * @fdt: pointer to the device tree blob + * @phandle: return location for the new phandle + * + * Walks the device tree blob and looks for the highest phandle value. On + * success, the new, unused phandle value (one higher than the previously + * highest phandle value in the device tree blob) will be returned in the + * @phandle parameter. + * + * Returns: + * 0 on success or a negative error-code on failure + */ +int fdt_generate_phandle(const void *fdt, uint32_t *phandle); + +/** * fdt_num_mem_rsv - retrieve the number of memory reserve map entries * @fdt: pointer to the device tree blob * diff --git a/scripts/dtc/libfdt/libfdt_env.h b/scripts/dtc/libfdt/libfdt_env.h index bd247462877..3ff9e286307 100644 --- a/scripts/dtc/libfdt/libfdt_env.h +++ b/scripts/dtc/libfdt/libfdt_env.h @@ -52,6 +52,7 @@ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <stdbool.h> #include <stddef.h> #include <stdint.h> #include <stdlib.h> diff --git a/test/dm/syscon.c b/test/dm/syscon.c index a294dda02e7..0ff9da7ec63 100644 --- a/test/dm/syscon.c +++ b/test/dm/syscon.c @@ -67,6 +67,13 @@ static int dm_test_syscon_by_phandle(struct unit_test_state *uts) ut_assert(!IS_ERR(map)); ut_asserteq(4, map->range_count); + ut_assertok_ptr(syscon_regmap_lookup_by_phandle(dev, + "third-syscon")); + map = syscon_regmap_lookup_by_phandle(dev, "third-syscon"); + ut_assert(map); + ut_assert(!IS_ERR(map)); + ut_asserteq(4, map->range_count); + ut_assert(IS_ERR(syscon_regmap_lookup_by_phandle(dev, "not-present"))); return 0; diff --git a/tools/kwbimage.c b/tools/kwbimage.c index a88a3830c0c..dffaf9043a0 100644 --- a/tools/kwbimage.c +++ b/tools/kwbimage.c @@ -1273,6 +1273,13 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params, e = image_find_option(IMAGE_CFG_DEBUG); if (e) main_hdr->flags = e->debug ? 0x1 : 0; + e = image_find_option(IMAGE_CFG_BINARY); + if (e) { + char *s = strrchr(e->binary.file, '/'); + + if (strcmp(s, "/binary.0") == 0) + main_hdr->destaddr = cpu_to_le32(params->addr); + } #if defined(CONFIG_KWB_SECURE) if (image_get_csk_index() >= 0) { diff --git a/tools/mkimage.c b/tools/mkimage.c index 2899adff810..d1e1a6743d1 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -403,14 +403,21 @@ int main(int argc, char **argv) exit (EXIT_FAILURE); } - /* - * scan through mkimage registry for all supported image types - * and verify the input image file header for match - * Print the image information for matched image type - * Returns the error code if not matched - */ - retval = imagetool_verify_print_header_by_type(ptr, &sbuf, - tparams, ¶ms); + if (params.fflag) { + /* + * Verifies the header format based on the expected header for image + * type in tparams + */ + retval = imagetool_verify_print_header_by_type(ptr, &sbuf, + tparams, ¶ms); + } else { + /** + * When listing the image, we are not given the image type. Simply check all + * image types to find one that matches our header + */ + retval = imagetool_verify_print_header(ptr, &sbuf, + tparams, ¶ms); + } (void) munmap((void *)ptr, sbuf.st_size); (void) close (ifd); |