]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-spi
authorTom Rini <trini@konsulko.com>
Sun, 14 Apr 2019 04:03:06 +0000 (00:03 -0400)
committerTom Rini <trini@konsulko.com>
Sun, 14 Apr 2019 04:03:06 +0000 (00:03 -0400)
Conflicts:
arch/arm/dts/armada-385-amc.dts
arch/arm/dts/armada-xp-theadorable.dts
arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi

Signed-off-by: Tom Rini <trini@konsulko.com>
366 files changed:
Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt [new file with mode: 0644]
MAINTAINERS
Makefile
arch/arm/Kconfig
arch/arm/dts/Makefile
arch/arm/dts/am335x-guardian-u-boot.dtsi [new file with mode: 0644]
arch/arm/dts/am335x-guardian.dts [new file with mode: 0644]
arch/arm/dts/armada-370-xp.dtsi
arch/arm/dts/armada-385-amc.dts [deleted file]
arch/arm/dts/armada-385-atl-x530-u-boot.dtsi
arch/arm/dts/armada-385-db-88f6820-amc.dts [new file with mode: 0644]
arch/arm/dts/armada-xp-98dx3236.dtsi [new file with mode: 0644]
arch/arm/dts/armada-xp-98dx3336.dtsi [new file with mode: 0644]
arch/arm/dts/armada-xp-98dx4251.dtsi [new file with mode: 0644]
arch/arm/dts/armada-xp-db-xc3-24g4xg-u-boot.dtsi [new file with mode: 0644]
arch/arm/dts/armada-xp-db-xc3-24g4xg.dts [new file with mode: 0644]
arch/arm/dts/armada-xp-gp.dts
arch/arm/dts/armada-xp-maxbcm.dts
arch/arm/dts/armada-xp-mv78230.dtsi
arch/arm/dts/armada-xp-mv78260.dtsi
arch/arm/dts/armada-xp-mv78460.dtsi
arch/arm/dts/armada-xp-synology-ds414.dts
arch/arm/dts/armada-xp-theadorable.dts
arch/arm/dts/armada-xp.dtsi
arch/arm/dts/bcm63158.dtsi
arch/arm/dts/bcm6858.dtsi
arch/arm/dts/bcm963158.dts
arch/arm/dts/bcm968580xref.dts
arch/arm/dts/da850-evm-u-boot.dtsi
arch/arm/dts/dra7.dtsi
arch/arm/dts/dra71-evm.dts
arch/arm/dts/imx53-kp-u-boot.dtsi [new file with mode: 0644]
arch/arm/dts/k3-am65-wakeup.dtsi
arch/arm/dts/k3-am654-base-board-u-boot.dtsi
arch/arm/dts/keystone-k2g-evm.dts
arch/arm/dts/keystone-k2g-ice.dts
arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi [new file with mode: 0644]
arch/arm/dts/stm32mp157-pinctrl.dtsi
arch/arm/dts/stm32mp157-u-boot.dtsi
arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi [new file with mode: 0644]
arch/arm/dts/stm32mp157a-dk1.dts [new file with mode: 0644]
arch/arm/dts/stm32mp157c-dk2-u-boot.dtsi [new file with mode: 0644]
arch/arm/dts/stm32mp157c-dk2.dts [new file with mode: 0644]
arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi
arch/arm/dts/stm32mp157c-ed1.dts
arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi
arch/arm/dts/stm32mp157c-ev1.dts
arch/arm/dts/stm32mp157c.dtsi
arch/arm/dts/sun50i-a64-oceanic-5205-5inmfd.dts [new file with mode: 0644]
arch/arm/include/asm/arch-am33xx/ddr_defs.h
arch/arm/include/asm/arch-sunxi/spl.h
arch/arm/include/asm/gpio.h
arch/arm/mach-k3/am6_init.c
arch/arm/mach-k3/common.c
arch/arm/mach-k3/include/mach/sys_proto.h
arch/arm/mach-keystone/Kconfig
arch/arm/mach-keystone/include/mach/hardware-k2g.h
arch/arm/mach-keystone/include/mach/mux-k2g.h
arch/arm/mach-kirkwood/cpu.c
arch/arm/mach-kirkwood/include/mach/cpu.h
arch/arm/mach-kirkwood/include/mach/soc.h
arch/arm/mach-mvebu/Kconfig
arch/arm/mach-mvebu/Makefile
arch/arm/mach-mvebu/cpu.c
arch/arm/mach-mvebu/include/mach/config.h
arch/arm/mach-mvebu/include/mach/cpu.h
arch/arm/mach-mvebu/include/mach/soc.h
arch/arm/mach-mvebu/mbus.c
arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/am33xx/Kconfig
arch/arm/mach-stm32mp/Kconfig
arch/arm/mach-stm32mp/Makefile
arch/arm/mach-stm32mp/bsec.c
arch/arm/mach-stm32mp/cmd_poweroff.c [new file with mode: 0644]
arch/arm/mach-stm32mp/config.mk
arch/arm/mach-stm32mp/cpu.c
arch/arm/mach-stm32mp/include/mach/stm32.h
arch/arm/mach-stm32mp/include/mach/stm32mp1_smc.h [new file with mode: 0644]
arch/arm/mach-stm32mp/include/mach/sys_proto.h
arch/arm/mach-stm32mp/psci.c
arch/arm/mach-stm32mp/spl.c
arch/arm/mach-stm32mp/syscon.c
arch/arm/mach-sunxi/Kconfig
arch/arm/mach-sunxi/board.c
arch/arm/mach-sunxi/dram_sun8i_a33.c
arch/mips/dts/Makefile
arch/mips/dts/ap143.dts
arch/mips/dts/ap152.dts [new file with mode: 0644]
arch/mips/dts/brcm,bcm6838.dtsi
arch/mips/dts/brcm,bcm968380gerg.dts
arch/mips/dts/gardena-smart-gateway-mt7688.dts
arch/mips/dts/jr2_pcb110.dts
arch/mips/dts/jr2_pcb111.dts
arch/mips/dts/mscc,jr2.dtsi
arch/mips/dts/mscc,servalt.dtsi
arch/mips/dts/qca953x.dtsi
arch/mips/dts/qca956x.dtsi [new file with mode: 0644]
arch/mips/dts/serval2_pcb112.dts
arch/mips/dts/servalt_pcb116.dts
arch/mips/lib/bootm.c
arch/mips/mach-ath79/Kconfig
arch/mips/mach-ath79/Makefile
arch/mips/mach-ath79/include/mach/ar71xx_regs.h
arch/mips/mach-ath79/include/mach/ath79.h
arch/mips/mach-ath79/qca956x/Makefile [new file with mode: 0644]
arch/mips/mach-ath79/qca956x/clk.c [new file with mode: 0644]
arch/mips/mach-ath79/qca956x/cpu.c [new file with mode: 0644]
arch/mips/mach-ath79/qca956x/ddr.c [new file with mode: 0644]
arch/mips/mach-ath79/qca956x/qca956x-ddr-tap.S [new file with mode: 0644]
arch/mips/mach-ath79/reset.c
arch/mips/mach-mscc/include/mach/servalt/servalt_devcpu_gcb.h
arch/mips/mach-mt7620/Kconfig
arch/sandbox/dts/test.dts
arch/sandbox/include/asm/sdl.h
arch/sandbox/include/asm/types.h
arch/sandbox/lib/pci_io.c
board/CZ.NIC/turris_omnia/turris_omnia.c
board/Marvell/db-xc3-24g4xg/.gitignore [new file with mode: 0644]
board/Marvell/db-xc3-24g4xg/MAINTAINERS [new file with mode: 0644]
board/Marvell/db-xc3-24g4xg/Makefile [new file with mode: 0644]
board/Marvell/db-xc3-24g4xg/README [new file with mode: 0644]
board/Marvell/db-xc3-24g4xg/binary.0 [new file with mode: 0644]
board/Marvell/db-xc3-24g4xg/db-xc3-24g4xg.c [new file with mode: 0644]
board/Marvell/db-xc3-24g4xg/kwbimage.cfg.in [new file with mode: 0644]
board/Synology/ds414/ds414.c
board/alliedtelesis/x530/x530.c
board/bosch/guardian/Kconfig [new file with mode: 0644]
board/bosch/guardian/MAINTAINERS [new file with mode: 0644]
board/bosch/guardian/Makefile [new file with mode: 0644]
board/bosch/guardian/board.c [new file with mode: 0644]
board/bosch/guardian/board.h [new file with mode: 0644]
board/bosch/guardian/mux.c [new file with mode: 0644]
board/davinci/da8xxevm/da850evm.c
board/davinci/da8xxevm/u-boot-spl-da850evm.lds
board/logicpd/am3517evm/am3517evm.c
board/maxbcm/maxbcm.c
board/mscc/jr2/jr2.c
board/qca/ap152/Kconfig [new file with mode: 0644]
board/qca/ap152/MAINTAINERS [new file with mode: 0644]
board/qca/ap152/Makefile [new file with mode: 0644]
board/qca/ap152/ap152.c [new file with mode: 0644]
board/solidrun/clearfog/README
board/st/stm32mp1/MAINTAINERS
board/st/stm32mp1/README
board/st/stm32mp1/board.c
board/st/stm32mp1/spl.c
board/st/stm32mp1/stm32mp1.c
board/sunxi/MAINTAINERS
board/theadorable/theadorable.c
board/ti/am335x/board.c
board/ti/am65x/evm.c
board/ti/dra7xx/evm.c
board/ti/dra7xx/mux_data.h
board/ti/ks2_evm/board_k2g.c
board/ti/ks2_evm/mux-k2g.h
cmd/Kconfig
cmd/Makefile
cmd/wdt.c [new file with mode: 0644]
common/fdt_support.c
configs/am335x_evm_defconfig
configs/am335x_guardian_defconfig [new file with mode: 0644]
configs/am57xx_evm_defconfig
configs/am65x_evm_a53_defconfig
configs/ap152_defconfig [new file with mode: 0644]
configs/bananapi_m2_plus_h3_defconfig
configs/bananapi_m2_plus_h5_defconfig
configs/bananapi_m2_zero_defconfig
configs/bcm963158_ram_defconfig
configs/bcm968380gerg_ram_defconfig
configs/bcm968580xref_ram_defconfig
configs/da850evm_defconfig
configs/da850evm_nand_defconfig
configs/db-88f6820-amc_defconfig
configs/db-mv784mp-gp_defconfig
configs/db-xc3-24g4xg_defconfig [new file with mode: 0644]
configs/dns325_defconfig
configs/dra7xx_evm_defconfig
configs/dra7xx_hs_evm_defconfig
configs/dreamplug_defconfig
configs/ds109_defconfig
configs/ds414_defconfig
configs/emlid_neutis_n5_devboard_defconfig
configs/goflexhome_defconfig
configs/guruplug_defconfig
configs/k2e_evm_defconfig
configs/k2e_hs_evm_defconfig
configs/k2g_evm_defconfig
configs/k2g_hs_evm_defconfig
configs/k2hk_evm_defconfig
configs/k2hk_hs_evm_defconfig
configs/k2l_evm_defconfig
configs/k2l_hs_evm_defconfig
configs/libretech_all_h3_cc_h2_plus_defconfig
configs/libretech_all_h3_cc_h3_defconfig
configs/libretech_all_h3_cc_h5_defconfig
configs/linkit-smart-7688-ram_defconfig
configs/linkit-smart-7688_defconfig
configs/lschlv2_defconfig
configs/lsxhl_defconfig
configs/mscc_jr2_defconfig
configs/mscc_servalt_defconfig
configs/nanopi_m1_defconfig
configs/nanopi_m1_plus_defconfig
configs/nanopi_neo2_defconfig
configs/nanopi_neo_air_defconfig
configs/nanopi_neo_defconfig
configs/nanopi_neo_plus2_defconfig
configs/nas220_defconfig
configs/oceanic_5205_5inmfd_defconfig [new file with mode: 0644]
configs/orangepi_2_defconfig
configs/orangepi_lite_defconfig
configs/orangepi_one_defconfig
configs/orangepi_pc2_defconfig
configs/orangepi_pc_defconfig
configs/orangepi_pc_plus_defconfig
configs/orangepi_plus2e_defconfig
configs/orangepi_plus_defconfig
configs/orangepi_prime_defconfig
configs/orangepi_r1_defconfig
configs/orangepi_zero_defconfig
configs/orangepi_zero_plus2_defconfig
configs/orangepi_zero_plus_defconfig
configs/pine64-lts_defconfig
configs/sandbox64_defconfig
configs/sandbox_defconfig
configs/sheevaplug_defconfig
configs/stm32mp15_basic_defconfig
configs/stm32mp15_trusted_defconfig [new file with mode: 0644]
configs/theadorable_debug_defconfig
configs/turris_omnia_defconfig
configs/x530_defconfig
doc/README.chromium
doc/README.chromium-chainload [new file with mode: 0644]
doc/device-tree-bindings/i2c/i2c.txt
doc/device-tree-bindings/mtd/stm32-fmc2-nand.txt [new file with mode: 0644]
doc/git-mailrc
drivers/Kconfig
drivers/ata/Kconfig
drivers/ata/ahci_mvebu.c
drivers/ata/sata_mv.c
drivers/clk/altera/clk-arria10.c
drivers/clk/at91/pmc.c
drivers/clk/clk_stm32mp1.c
drivers/core/ofnode.c
drivers/core/syscon-uclass.c
drivers/core/util.c
drivers/ddr/marvell/axp/xor_regs.h
drivers/dma/Kconfig
drivers/dma/Makefile
drivers/dma/bcm6348-iudma.c
drivers/dma/ti/Kconfig [new file with mode: 0644]
drivers/dma/ti/Makefile [new file with mode: 0644]
drivers/dma/ti/k3-udma-hwdef.h [new file with mode: 0644]
drivers/dma/ti/k3-udma.c [new file with mode: 0644]
drivers/firmware/ti_sci.c
drivers/firmware/ti_sci.h
drivers/gpio/Kconfig
drivers/gpio/bcm6345_gpio.c
drivers/i2c/i2c-uclass.c
drivers/i2c/muxes/Kconfig
drivers/i2c/muxes/pca954x.c
drivers/i2c/mxc_i2c.c
drivers/misc/i2c_eeprom.c
drivers/misc/stm32mp_fuse.c
drivers/mmc/omap_hsmmc.c
drivers/mtd/nand/raw/Kconfig
drivers/mtd/nand/raw/Makefile
drivers/mtd/nand/raw/stm32_fmc2_nand.c [new file with mode: 0644]
drivers/net/ag7xxx.c
drivers/net/mscc_eswitch/Kconfig
drivers/net/mscc_eswitch/Makefile
drivers/net/mscc_eswitch/jr2_switch.c [new file with mode: 0644]
drivers/net/mscc_eswitch/ocelot_switch.c
drivers/net/mscc_eswitch/servalt_switch.c [new file with mode: 0644]
drivers/net/ti/cpsw-common.c
drivers/net/ti/cpsw.c
drivers/net/ti/keystone_net.c
drivers/phy/Kconfig
drivers/phy/Makefile
drivers/phy/mt76x8-usb-phy.c [new file with mode: 0644]
drivers/pinctrl/Kconfig
drivers/pinctrl/Makefile
drivers/pinctrl/ath79/Makefile
drivers/pinctrl/pinctrl-stmfx.c [new file with mode: 0644]
drivers/pinctrl/pinctrl-uclass.c
drivers/power/pmic/Kconfig
drivers/power/pmic/Makefile
drivers/power/pmic/stpmic1.c [new file with mode: 0644]
drivers/power/pmic/stpmu1.c [deleted file]
drivers/power/regulator/Kconfig
drivers/power/regulator/Makefile
drivers/power/regulator/pbias_regulator.c
drivers/power/regulator/stpmic1.c [new file with mode: 0644]
drivers/power/regulator/stpmu1.c [deleted file]
drivers/ram/stm32mp1/stm32mp1_ram.c
drivers/soc/Kconfig [new file with mode: 0644]
drivers/soc/Makefile
drivers/soc/keystone/Makefile [deleted file]
drivers/soc/ti/Kconfig [new file with mode: 0644]
drivers/soc/ti/Makefile [new file with mode: 0644]
drivers/soc/ti/k3-navss-ringacc.c [new file with mode: 0644]
drivers/soc/ti/keystone_serdes.c [moved from drivers/soc/keystone/keystone_serdes.c with 100% similarity]
drivers/spi/Kconfig
drivers/spi/stm32_qspi.c
drivers/sysreset/sysreset_syscon.c
drivers/watchdog/Kconfig
drivers/watchdog/orion_wdt.c
dts/Kconfig
env/nand.c
include/configs/am335x_guardian.h [new file with mode: 0644]
include/configs/ap152.h [new file with mode: 0644]
include/configs/clearfog.h
include/configs/da850evm.h
include/configs/db-88f6720.h
include/configs/db-88f6820-amc.h
include/configs/db-88f6820-gp.h
include/configs/db-mv784mp-gp.h
include/configs/db-xc3-24g4xg.h [new file with mode: 0644]
include/configs/dra7xx_evm.h
include/configs/ds414.h
include/configs/helios4.h
include/configs/k2e_evm.h
include/configs/k2g_evm.h
include/configs/k2hk_evm.h
include/configs/k2l_evm.h
include/configs/lsxl.h
include/configs/mvebu_armada-8k.h
include/configs/omapl138_lcdk.h
include/configs/stm32mp1.h
include/configs/theadorable.h
include/configs/ti_armv7_keystone2.h
include/configs/ti_omap5_common.h
include/configs/turris_mox.h
include/configs/turris_omnia.h
include/configs/vcoreiii.h
include/cpsw.h
include/dm/pinctrl.h
include/dm/util.h
include/dt-bindings/dma/k3-udma.h [new file with mode: 0644]
include/dt-bindings/mfd/st,stpmic1.h [new file with mode: 0644]
include/dt-bindings/mfd/st,stpmu1.h [deleted file]
include/dt-bindings/mscc/jr2_data.h [new file with mode: 0644]
include/environment/ti/nand.h [new file with mode: 0644]
include/fdtdec.h
include/i2c.h
include/linux/soc/ti/cppi5.h [new file with mode: 0644]
include/linux/soc/ti/k3-navss-ringacc.h [new file with mode: 0644]
include/linux/soc/ti/ti-udma.h [new file with mode: 0644]
include/linux/soc/ti/ti_sci_protocol.h
include/net.h
include/power/stpmic1.h [new file with mode: 0644]
include/power/stpmu1.h [deleted file]
lib/Kconfig
lib/fdtdec.c
lib/fdtdec_test.c
lib/libfdt/fdt_ro.c
lib/vsprintf.c
scripts/Makefile.lib
scripts/config_whitelist.txt
scripts/dtc/libfdt/fdt_ro.c
scripts/dtc/libfdt/libfdt.h
scripts/dtc/libfdt/libfdt_env.h
test/dm/syscon.c
tools/kwbimage.c
tools/mkimage.c

diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
new file mode 100644 (file)
index 0000000..bac4afa
--- /dev/null
@@ -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>;
+               /* ... */
+       };
+};
index 1598dc866ecba4ab0952f290d14b548de27bd6cf..c77abba1e5bebaf8cb06904c9b2006b03ac70f48 100644 (file)
@@ -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
index 9709e7638648b210d77c320e706e2f3e891bb0a1..2824a6e159440c9475d76fdfcdf40915dfa03b80 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -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 "===================================================="
index 4a23e327dfb486e041038ae3c34f53bec65a87d2..4640f3b3bd34d0c66f7669ecaf9aea0c141a7c72 100644 (file)
@@ -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"
@@ -1464,6 +1468,21 @@ config TI_SECURE_DEVICE
          authenticated) and the code. See the doc/README.ti-secure
          file for further details.
 
+if AM43XX || AM33XX || OMAP54XX || ARCH_KEYSTONE
+config ISW_ENTRY_ADDR
+       hex "Address in memory or XIP address of bootloader entry point"
+       default 0x402F4000 if AM43XX
+       default 0x402F0400 if AM33XX
+       default 0x40301350 if OMAP54XX
+       help
+         After any reset, the boot ROM searches the boot media for a valid
+         boot image. For non-XIP devices, the ROM then copies the image into
+         internal memory. For all boot modes, after the ROM processes the
+         boot image it eventually computes the entry point address depending
+         on the device type (secure/non-secure), boot media (xip/non-xip) and
+         image headers.
+endif
+
 source "arch/arm/mach-aspeed/Kconfig"
 
 source "arch/arm/mach-at91/Kconfig"
@@ -1563,6 +1582,7 @@ source "arch/arm/cpu/armv8/Kconfig"
 source "arch/arm/mach-imx/Kconfig"
 
 source "board/bosch/shc/Kconfig"
+source "board/bosch/guardian/Kconfig"
 source "board/CarMediaLab/flea3/Kconfig"
 source "board/Marvell/aspenite/Kconfig"
 source "board/Marvell/gplugd/Kconfig"
index 86a01c2c7025921a096123e3e85e159647a20482..8167cdb4e85620aa8c42447507b72f318103cceb 100644 (file)
@@ -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 \
@@ -251,7 +252,8 @@ dtb-$(CONFIG_AM33XX) += \
        am335x-pdu001.dtb \
        am335x-chiliboard.dtb \
        am335x-sl50.dtb \
-       am335x-base0033.dtb
+       am335x-base0033.dtb \
+       am335x-guardian.dtb
 dtb-$(CONFIG_AM43XX) += am437x-gp-evm.dtb am437x-sk-evm.dtb    \
        am43x-epos-evm.dtb \
        am437x-idk-evm.dtb \
@@ -474,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 \
@@ -685,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-guardian-u-boot.dtsi b/arch/arm/dts/am335x-guardian-u-boot.dtsi
new file mode 100644 (file)
index 0000000..156b9b0
--- /dev/null
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 EETS GmbH - https://www.eets.ch/
+ * Copyright (C) 2018 Robert Bosch Power Tools GmbH
+ */
+
+/ {
+       ocp {
+               u-boot,dm-pre-reloc;
+       };
+};
+
+&l4_wkup {
+       u-boot,dm-pre-reloc;
+};
+
+&mmc1 {
+       u-boot,dm-pre-reloc;
+};
+
+&mmc1_pins {
+       u-boot,dm-pre-reloc;
+};
+
+&rtc {
+       clocks = <&l4_per_clkctrl AM3_CLKDIV32K_CLKCTRL 0>;
+       clock-names = "int-clk";
+};
+
+&scm {
+       u-boot,dm-pre-reloc;
+};
+
+&uart0 {
+       u-boot,dm-pre-reloc;
+};
+
+&uart0_pins {
+       u-boot,dm-pre-reloc;
+};
+
+&usb {
+       u-boot,dm-pre-reloc;
+};
+
+&usb_ctrl_mod {
+       u-boot,dm-pre-reloc;
+};
+
+&usb0 {
+       u-boot,dm-pre-reloc;
+};
+
+&usb0_phy {
+       u-boot,dm-pre-reloc;
+};
+
+&am33xx_pinmux {
+       u-boot,dm-pre-reloc;
+
+       lcd0_pins: pinmux_lcd0_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x908, PIN_OUTPUT_PULLUP   | MUX_MODE7)
+               >;
+       };
+};
diff --git a/arch/arm/dts/am335x-guardian.dts b/arch/arm/dts/am335x-guardian.dts
new file mode 100644 (file)
index 0000000..f3f022c
--- /dev/null
@@ -0,0 +1,509 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2018 Robert Bosch Power Tools GmbH
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       model = "Bosch AM335x Guardian";
+       compatible = "bosch,am335x-guardian", "ti,am33xx";
+
+       chosen {
+               stdout-path = &uart0;
+               tick-timer = &timer2;
+       };
+
+       cpus {
+               cpu@0 {
+                       cpu0-supply = <&dcdc2_reg>;
+               };
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0x10000000>; /* 256 MB */
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&gpio_keys_pins>;
+
+               button21 {
+                       label = "guardian-power-button";
+                       linux,code = <KEY_POWER>;
+                       gpios = <&gpio2 21 0>;
+                       wakeup-source;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&leds_pins>;
+
+               led1 {
+                       label = "green:heartbeat";
+                       gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+                       default-state = "off";
+               };
+
+               led2 {
+                       label = "green:mmc0";
+                       gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "mmc0";
+                       default-state = "off";
+               };
+       };
+
+       panel {
+               compatible = "ti,tilcdc,panel";
+               pinctrl-names = "default", "sleep";
+               pinctrl-0 = <&lcd_pins_default &lcd_disen_pins>;
+               pinctrl-1 = <&lcd_pins_sleep>;
+
+               display-timings {
+                       320x240 {
+                               hactive         = <320>;
+                               vactive         = <240>;
+                               hback-porch     = <68>;
+                               hfront-porch    = <20>;
+                               hsync-len       = <1>;
+                               vback-porch     = <18>;
+                               vfront-porch    = <4>;
+                               vsync-len       = <1>;
+                               clock-frequency = <9000000>;
+                               hsync-active    = <0>;
+                               vsync-active    = <0>;
+                       };
+               };
+               panel-info {
+                       ac-bias           = <255>;
+                       ac-bias-intrpt    = <0>;
+                       dma-burst-sz      = <16>;
+                       bpp               = <24>;
+                       bus-width         = <16>;
+                       fdd               = <0x80>;
+                       sync-edge         = <0>;
+                       sync-ctrl         = <1>;
+                       raster-order      = <0>;
+                       fifo-th           = <0>;
+               };
+
+       };
+
+       pwm7: dmtimer-pwm {
+               compatible = "ti,omap-dmtimer-pwm";
+               ti,timers = <&timer7>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&dmtimer7_pins>;
+       };
+
+       vmmcsd_fixed: regulator-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vmmcsd_fixed";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
+
+&cppi41dma  {
+       status = "okay";
+};
+
+&elm {
+       status = "okay";
+};
+
+&gpmc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&nandflash_pins>;
+       ranges = <0 0 0x08000000 0x1000000>;  /* CS0: 16MB for NAND */
+       status = "okay";
+
+       nand@0,0 {
+               compatible = "ti,omap2-nand";
+               reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+               interrupt-parent = <&gpmc>;
+               interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+                            <1 IRQ_TYPE_NONE>; /* termcount */
+               rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
+               ti,nand-ecc-opt = "bch16";
+               ti,elm-id = <&elm>;
+               nand-bus-width = <8>;
+               gpmc,device-width = <1>;
+               gpmc,sync-clk-ps = <0>;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <44>;
+               gpmc,cs-wr-off-ns = <44>;
+               gpmc,adv-on-ns = <6>;
+               gpmc,adv-rd-off-ns = <34>;
+               gpmc,adv-wr-off-ns = <44>;
+               gpmc,we-on-ns = <0>;
+               gpmc,we-off-ns = <40>;
+               gpmc,oe-on-ns = <0>;
+               gpmc,oe-off-ns = <54>;
+               gpmc,access-ns = <64>;
+               gpmc,rd-cycle-ns = <82>;
+               gpmc,wr-cycle-ns = <82>;
+               gpmc,bus-turnaround-ns = <0>;
+               gpmc,cycle2cycle-delay-ns = <0>;
+               gpmc,clk-activation-ns = <0>;
+               gpmc,wr-access-ns = <40>;
+               gpmc,wr-data-mux-bus-ns = <0>;
+
+               /*
+                * MTD partition table
+                *
+                * All SPL-* partitions are sized to minimal length which can
+                * be independently programmable. For NAND flash this is equal
+                * to size of erase-block.
+                */
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               partition@0 {
+                       label = "SPL";
+                       reg = <0x0 0x40000>;
+               };
+
+               partition@1 {
+                       label = "SPL.backup1";
+                       reg = <0x40000  0x40000>;
+               };
+
+               partition@2 {
+                       label = "SPL.backup2";
+                       reg = <0x80000  0x40000>;
+               };
+
+               partition@3 {
+                       label = "SPL.backup3";
+                       reg = <0xc0000  0x40000>;
+               };
+
+               partition@4 {
+                       label = "u-boot";
+                       reg = <0x100000 0x100000>;
+               };
+
+               partition@5 {
+                       label = "u-boot.backup1";
+                       reg = <0x200000 0x100000>;
+               };
+
+               partition@6 {
+                       label = "u-boot-env";
+                       reg = <0x300000 0x40000>;
+               };
+
+               partition@7 {
+                       label = "u-boot-env.backup1";
+                       reg = <0x340000 0x40000>;
+               };
+
+               partition@8 {
+                       label = "UBI";
+                       reg = <0x380000 0x1fc80000>;
+               };
+       };
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+       clock-frequency = <400000>;
+       status = "okay";
+
+       tps: tps@24 {
+               reg = <0x24>;
+       };
+};
+
+&lcdc {
+       blue-and-red-wiring = "crossed";
+       status = "okay";
+};
+
+&mmc1 {
+       bus-width = <0x4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&vmmcsd_fixed>;
+       status = "okay";
+};
+
+&rtc {
+       clocks = <&clk_32768_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>;
+       clock-names = "ext-clk", "int-clk";
+       system-power-controller;
+};
+
+&spi0 {
+       ti,pindir-d0-out-d1-in;
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi0_pins>;
+       status = "okay";
+};
+
+/include/ "tps65217.dtsi"
+
+&tps {
+       ti,pmic-shutdown-controller;
+       interrupt-parent = <&intc>;
+       interrupts = <7>; /* NMI */
+
+       backlight {
+               isel = <1>;  /* 1 - ISET1, 2 ISET2 */
+               fdim = <100>; /* TPS65217_BL_FDIM_100HZ */
+               default-brightness = <100>;
+       };
+
+       regulators {
+               dcdc1_reg: regulator@0 {
+                       regulator-name = "vdds_dpr";
+                       regulator-always-on;
+               };
+
+               dcdc2_reg: regulator@1 {
+                       regulator-name = "vdd_mpu";
+                       regulator-min-microvolt = <925000>;
+                       regulator-max-microvolt = <1351500>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               dcdc3_reg: regulator@2 {
+                       regulator-name = "vdd_core";
+                       regulator-min-microvolt = <925000>;
+                       regulator-max-microvolt = <1150000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               ldo1_reg: regulator@3 {
+                       regulator-name = "vio,vrtc,vdds";
+                       regulator-always-on;
+               };
+
+               ldo2_reg: regulator@4 {
+                       regulator-name = "vdd_3v3aux";
+                       regulator-always-on;
+               };
+
+               ldo3_reg: regulator@5 {
+                       regulator-name = "vdd_1v8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               ldo4_reg: regulator@6 {
+                       regulator-name = "vdd_3v3a";
+                       regulator-always-on;
+               };
+       };
+};
+
+&tscadc {
+       status = "okay";
+
+       adc {
+               ti,adc-channels = <0 1 2 3 4 5 6>;
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins>;
+       status = "okay";
+};
+
+&usb {
+       status = "okay";
+};
+
+&usb_ctrl_mod {
+       status = "okay";
+};
+
+&usb0 {
+       dr_mode = "peripheral";
+       status = "okay";
+};
+
+&usb0_phy {
+       status = "okay";
+};
+
+&usb1 {
+       dr_mode = "host";
+       status = "okay";
+};
+
+&usb1_phy {
+       status = "okay";
+};
+
+&am33xx_pinmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&clkout2_pin &gpio_pins>;
+
+       clkout2_pin: pinmux_clkout2_pin {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x9b4, PIN_OUTPUT_PULLDOWN | MUX_MODE3)
+               >;
+       };
+
+       dmtimer7_pins: pinmux_dmtimer7_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x968, PIN_OUTPUT | MUX_MODE5)
+               >;
+       };
+
+       gpio_keys_pins: pinmux_gpio_keys_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x940, PIN_INPUT | MUX_MODE7)
+               >;
+       };
+
+       gpio_pins: pinmux_gpio_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x928, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x990, PIN_OUTPUT | MUX_MODE7)
+               >;
+       };
+
+       i2c0_pins: pinmux_i2c0_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0)
+                       AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0)
+               >;
+       };
+
+       lcd_disen_pins: pinmux_lcd_disen_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x9a4, PIN_OUTPUT_PULLUP | SLEWCTRL_SLOW | MUX_MODE7)
+               >;
+       };
+
+       lcd_pins_default: pinmux_lcd_pins_default {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x820, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+                       AM33XX_IOPAD(0x824, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+                       AM33XX_IOPAD(0x828, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+                       AM33XX_IOPAD(0x82c, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+                       AM33XX_IOPAD(0x830, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+                       AM33XX_IOPAD(0x834, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+                       AM33XX_IOPAD(0x838, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+                       AM33XX_IOPAD(0x83c, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+                       AM33XX_IOPAD(0x8a0, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8a4, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8a8, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8ac, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8b0, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8b4, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8b8, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8bc, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8c0, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8c4, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8c8, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8cc, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8d0, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8d4, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8d8, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8dc, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8e0, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8e4, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8e8, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+                       AM33XX_IOPAD(0x8ec, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+               >;
+       };
+
+       lcd_pins_sleep: pinmux_lcd_pins_sleep {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x8a0, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8a4, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8a8, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8ac, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8b0, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8b4, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8b8, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8bc, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8c0, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8c4, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8c8, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8cc, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8d0, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8d4, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8d8, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8dc, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8e0, PIN_INPUT_PULLDOWN | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8e4, PIN_INPUT_PULLDOWN | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8e8, PIN_INPUT_PULLDOWN | SLEWCTRL_SLOW | MUX_MODE7)
+                       AM33XX_IOPAD(0x8ec, PIN_INPUT_PULLDOWN | SLEWCTRL_SLOW | MUX_MODE7)
+               >;
+       };
+
+       leds_pins: pinmux_leds_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x868, PIN_OUTPUT | MUX_MODE7)
+                       AM33XX_IOPAD(0x86c, PIN_OUTPUT | MUX_MODE7)
+               >;
+       };
+
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0)
+                       AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0)
+                       AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0)
+                       AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0)
+                       AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0)
+                       AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0)
+                       AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7)
+               >;
+       };
+
+       spi0_pins: pinmux_spi0_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x950, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+                       AM33XX_IOPAD(0x954, PIN_OUTPUT_PULLUP | MUX_MODE0)
+                       AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE0)
+                       AM33XX_IOPAD(0x95c, PIN_OUTPUT_PULLUP | MUX_MODE0)
+               >;
+       };
+
+       uart0_pins: pinmux_uart0_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)
+                       AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+               >;
+       };
+
+       nandflash_pins: pinmux_nandflash_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x800, PIN_INPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x804, PIN_INPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x808, PIN_INPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x80c, PIN_INPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x810, PIN_INPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x814, PIN_INPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x818, PIN_INPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x81c, PIN_INPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x870, PIN_INPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x874, PIN_OUTPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0)
+                       AM33XX_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE0)
+               >;
+       };
+};
index 0b2a78d393010fbdbfb400ddad63a4dba2d9ff18..e4c35d4e98f4d3078fd2266c1332cbfeae44030b 100644 (file)
@@ -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>;
                        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>;
                        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>;
                        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>;
                        #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>;
                                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>;
                                status = "disabled";
                        };
 
-                       mdio: mdio {
+                       mdio: mdio@72004 {
                                #address-cells = <1>;
                                #size-cells = <0>;
                                compatible = "marvell,orion-mdio";
                                status = "disabled";
                        };
 
-                       sata@a0000 {
+                       sata: sata@a0000 {
                                compatible = "marvell,armada-370-sata";
                                reg = <0xa0000 0x5000>;
                                interrupts = <55>;
                                status = "disabled";
                        };
 
-                       mvsdio@d4000 {
+                       sdio: mvsdio@d4000 {
                                compatible = "marvell,orion-sdio";
                                reg = <0xd4000 0x200>;
                                interrupts = <54>;
                                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-385-amc.dts b/arch/arm/dts/armada-385-amc.dts
deleted file mode 100644 (file)
index d292851..0000000
+++ /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 = &eth0;
-               ethernet1 = &eth2;
-               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";
-               reg = <0>; /* Chip select 0 */
-               spi-max-frequency = <50000000>;
-               m25p,fast-read;
-       };
-};
-
-&refclk {
-       clock-frequency = <20000000>;
-};
index 7074a73537fa739a82a24d6aaa2890dbb271ae64..79b694cb84bce0935936d3a150576e8c9d1083c9 100644 (file)
@@ -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 (file)
index 0000000..59a425f
--- /dev/null
@@ -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 = &eth0;
+               ethernet1 = &eth2;
+               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;
+};
+
+
+&eth0 {
+       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";
+};
+
+&eth2 {
+       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-xp-98dx3236.dtsi b/arch/arm/dts/armada-xp-98dx3236.dtsi
new file mode 100644 (file)
index 0000000..5df1d18
--- /dev/null
@@ -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 (file)
index 0000000..1d9d8a8
--- /dev/null
@@ -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 (file)
index 0000000..48ffdc7
--- /dev/null
@@ -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 (file)
index 0000000..90cad85
--- /dev/null
@@ -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 (file)
index 0000000..d4b5288
--- /dev/null
@@ -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";
+               };
+
+       };
+};
index 27799d1254eadc1f9056a17184195449c5cd8624..1139e9469a83792efc102ff2c8dd375d1c5591b3 100644 (file)
@@ -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,
                stdout-path = "serial0:115200n8";
        };
 
-       aliases {
-               spi0 = &spi0;
-       };
-
-       memory {
+       memory@0 {
                device_type = "memory";
                /*
                  * 8 GB of plug-in RAM modules by default.The amount
        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";
                        };
                };
 
-               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";
                                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 */
                                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>;
        };
 };
index d7d7f65c85fec623f7a66fcd4efdc12fa0216d47..921eb708625433ca6f3d471c67d67f9c02ae392d 100644 (file)
                                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>;
                };
        };
 };
+
+&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>;
+       };
+};
index f6bab9fb20a908e305e5c84ca296c9ed22e37dc6..8558bf6bb54c603c16b8a5a987c991413e3297c8 100644 (file)
@@ -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.
  */
 
                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>;
                        };
                };
        };
index d39231f69d9a960f011e27f44974d2afe2f270c3..2d85fe8ac327296420e1050228e88fa0df48d79a 100644 (file)
@@ -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.
  */
 
                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;
index c642565d1bc68119dfa5c470fdc7e4d0c63865b0..230a3fd36b3048937c760784ec2fd619f49f9bdb 100644 (file)
@@ -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.
  */
 
                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;
index 0a60ddfa4149ee75da08ef732bf5699544c7131c..861967cd7e8728124f0e336819bf4c034b930a56 100644 (file)
@@ -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
                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 {
 
                                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";
                                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>;
                             &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";
                        gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>;
                };
 
-               sata2_regulator: sata2-regulator {
+               sata2_regulator: sata2-regulator@2 {
                        compatible = "regulator-fixed";
                        reg = <2>;
                        regulator-name = "SATA2 Power";
                        gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
                };
 
-               sata3_regulator: sata3-regulator {
+               sata3_regulator: sata3-regulator@3 {
                        compatible = "regulator-fixed";
                        reg = <3>;
                        regulator-name = "SATA3 Power";
                        gpio = <&gpio1 13 GPIO_ACTIVE_HIGH>;
                };
 
-               sata4_regulator: sata4-regulator {
+               sata4_regulator: sata4-regulator@4 {
                        compatible = "regulator-fixed";
                        reg = <4>;
                        regulator-name = "SATA4 Power";
        };
 };
 
+&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";
                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 */
+               };
+       };
+};
index b0f6c2bafe5a89a2bf3b7386c40a480320ab6faa..5b18d62c3c5f1d22040421aaf5133abb7a3907ff 100644 (file)
                                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";
-                                       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";
        };
 };
 
+&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";
 
index 3fac39e41d789199947a3927bf7c4630ea14c275..d856d96022727a7802fcd71c5b526a309d0a0bda 100644 (file)
@@ -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";
 
                };
 
                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>;
                                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>;
                                status = "disabled";
                        };
 
-                       system-controller@18200 {
+                       systemc: system-controller@18200 {
                                compatible = "marvell,armada-370-xp-system-controller";
                                reg = <0x18200 0x500>;
                        };
                                #clock-cells = <1>;
                        };
 
-                       thermal@182b0 {
+                       thermal: thermal@182b0 {
                                compatible = "marvell,armadaxp-thermal";
                                reg = <0x182b0 0x4
                                        0x184d0 0x4>;
                                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 {
                                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>;
                                status = "disabled";
                        };
 
-                       xor@60900 {
+                       xor1: xor@60900 {
                                compatible = "marvell,orion-xor";
                                reg = <0x60900 0x100
                                       0x60b00 0x100>;
                                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>;
                                };
                        };
                };
+
+               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 {
        };
 };
 
+&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 =
                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";
                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";
+};
index 6a3fbc90939b22cdba221b1d601293fce511e453..4f41f6273872c2f228c4f2c6af42f62e64fe0d1a 100644 (file)
                        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";
+               };
        };
 };
index 23b80c67a64a6db77569c86851220693a0c736bc..5d5e64db0812ff0c0caf190976cd62c778fefc26 100644 (file)
                        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";
+               };
        };
 };
index dc5afb5a24afa4641891f421266ff841c7cf09ea..b5c825b052bc3181de2634d8729acc55f15a716d 100644 (file)
        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";
+};
index 0c59f94710c97925d9e05b6390c42be3f80d3a5f..15febb030f11f9e1c384399905f95fab454335b5 100644 (file)
        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";
+};
index 360e79e68d41d94e776d00791028ce8f401ad76e..1683f3472e4dfc51bd0a21240b46fe85bf791d74 100644 (file)
@@ -6,6 +6,24 @@
  * Copyright (C) Adam Ford
  */
 
+/ {
+       soc@1c00000 {
+               u-boot,dm-spl;
+       };
+};
+
 &flash {
        compatible = "m25p64", "jedec,spi-nor";
 };
+
+&mmc0 {
+       u-boot,dm-spl;
+};
+
+&serial2 {
+       u-boot,dm-spl;
+};
+
+&spi1 {
+       u-boot,dm-spl;
+};
index 0f982d8b44addc3a201d84128112a492e5823ff1..fd1aea0b1b1617b6c4fa08d03c13204c6da61334 100644 (file)
                                                pbias_mmc_reg: pbias_mmc_omap5 {
                                                        regulator-name = "pbias_mmc_omap5";
                                                        regulator-min-microvolt = <1800000>;
-                                                       regulator-max-microvolt = <3000000>;
+                                                       regulator-max-microvolt = <3300000>;
                                                };
                                        };
 
index 41c9132eb550d07dd686a85eda0296bbfad0b6f7..64363f75c01ad507ce40c32bd2e4a756190a608e 100644 (file)
 
                regulator-name = "vddshv8";
                regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <3000000>;
+               regulator-max-microvolt = <3300000>;
                regulator-boot-on;
                vin-supply = <&evm_5v0>;
 
                gpios = <&gpio7 11 GPIO_ACTIVE_HIGH>;
                states = <1800000 0x0
-                         3000000 0x1>;
+                         3300000 0x1>;
        };
 
        evm_1v8_sw: fixedregulator-evm_1v8 {
diff --git a/arch/arm/dts/imx53-kp-u-boot.dtsi b/arch/arm/dts/imx53-kp-u-boot.dtsi
new file mode 100644 (file)
index 0000000..acab9b3
--- /dev/null
@@ -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>;
+};
index 8d7b47f9dfbf4e43f15b821c92649b594788103a..1f591ef8bb9e0e9a95a43e1380dd21c1e6f6e217 100644 (file)
@@ -7,7 +7,7 @@
 
 &cbass_wakeup {
        dmsc: dmsc {
-               compatible = "ti,k2g-sci";
+               compatible = "ti,am654-sci";
                ti,host-id = <12>;
                #address-cells = <1>;
                #size-cells = <1>;
index 143eb6d63092bb9c7e1f2a3dde85b0d165abe543..c5d23d0203abc755eea97b7b90405033ec9ce339 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/pinctrl/k3-am65.h>
+#include <dt-bindings/dma/k3-udma.h>
 
 / {
        chosen {
                pinctrl-single,register-width = <32>;
                pinctrl-single,function-mask = <0xffffffff>;
        };
+
+       navss_mcu: navss-mcu {
+               compatible = "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               ti,sci-dev-id = <119>;
+
+               mcu_ringacc: ringacc@2b800000 {
+                       compatible = "ti,am654-navss-ringacc";
+                       reg =   <0x0 0x2b800000 0x0 0x400000>,
+                               <0x0 0x2b000000 0x0 0x400000>,
+                               <0x0 0x28590000 0x0 0x100>,
+                               <0x0 0x2a500000 0x0 0x40000>;
+                       reg-names = "rt", "fifos",
+                                   "proxy_gcfg", "proxy_target";
+                       ti,num-rings = <286>;
+                       ti,sci-rm-range-gp-rings = <0x2>; /* GP ring range */
+                       ti,dma-ring-reset-quirk;
+                       ti,sci = <&dmsc>;
+                       ti,sci-dev-id = <195>;
+               };
+
+               mcu_udmap: udmap@285c0000 {
+                       compatible = "ti,k3-navss-udmap";
+                       reg =   <0x0 0x285c0000 0x0 0x100>,
+                               <0x0 0x2a800000 0x0 0x40000>,
+                               <0x0 0x2aa00000 0x0 0x40000>;
+                       reg-names = "gcfg", "rchanrt", "tchanrt";
+                       #dma-cells = <3>;
+
+                       ti,ringacc = <&mcu_ringacc>;
+                       ti,psil-base = <0x6000>;
+
+                       ti,sci = <&dmsc>;
+                       ti,sci-dev-id = <194>;
+
+                       ti,sci-rm-range-tchan = <0x1>, /* TX_HCHAN */
+                                               <0x2>; /* TX_CHAN */
+                       ti,sci-rm-range-rchan = <0x3>, /* RX_HCHAN */
+                                               <0x4>; /* RX_CHAN */
+                       ti,sci-rm-range-rflow = <0x5>; /* GP RFLOW */
+                       dma-coherent;
+               };
+       };
 };
 
 &cbass_wakeup {
index d91869f2c2b65775b3766ae208f426fd50ab48d3..7c5deef8083f399a2ab80cb1ca35270af8052bd9 100644 (file)
@@ -29,7 +29,6 @@
        status = "okay";
        ethphy0: ethernet-phy@0 {
                reg = <0>;
-               phy-mode = "rgmii-id";
        };
 };
 
index 680dfee0713ca76fbd04054eb984fcfe72051ed9..ecca2dfac1ad4d4d85f6afa10bc5d9b82c0f4e4c 100644 (file)
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "keystone-k2g.dtsi"
+#include <dt-bindings/net/ti-dp83867.h>
 
 / {
        compatible = "ti,k2g-ice", "ti,k2g", "ti,keystone";
                };
        };
 };
+
+&qmss {
+       status = "okay";
+};
+
+&knav_dmas {
+       status = "okay";
+};
+
+&netcp {
+       pinctrl-names = "default";
+       //pinctrl-0 = <&emac_pins>;
+       status = "okay";
+};
+
+&mdio {
+       pinctrl-names = "default";
+       //pinctrl-0 = <&mdio_pins>;
+       status = "okay";
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+               ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+               ti,tx-internal-delay = <DP83867_RGMIIDCTL_250_PS>;
+               ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>;
+               ti,min-output-impedance;
+               ti,dp83867-rxctrl-strap-quirk;
+       };
+};
+
+&gbe0 {
+       phy-handle = <&ethphy0>;
+       phy-mode = "rgmii-id";
+       status = "okay";
+};
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 (file)
index 0000000..7d9b95c
--- /dev/null
@@ -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"
index 85da5926551c608124ae54288c5762d147517aae..c06987548612083159bf7bb3d7fbd3539f35b5cf 100644 (file)
                                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)>;
                                };
                        };
 
+                       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 */
                                };
                        };
 
+                       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 */
                                        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;
+                               };
+                       };
                };
        };
 };
index 90d13f35c4622f61f3f38b10c2b36caa4949d0dd..ab6f673ea24c78885550618e9e9f1a32102e8cd1 100644 (file)
@@ -17,6 +17,8 @@
                gpio9 = &gpioj;
                gpio10 = &gpiok;
                gpio25 = &gpioz;
+               pinctrl0 = &pinctrl;
+               pinctrl1 = &pinctrl_z;
        };
 
        config {
        };
 };
 
+&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 (file)
index 0000000..af7acfa
--- /dev/null
@@ -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 (file)
index 0000000..0882765
--- /dev/null
@@ -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 = &ethernet0;
+               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";
+               };
+       };
+};
+
+&ethernet0 {
+       status = "okay";
+       pinctrl-0 = <&ethernet0_rgmii_pins_a>;
+       pinctrl-1 = <&ethernet0_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 (file)
index 0000000..06ef3a4
--- /dev/null
@@ -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 (file)
index 0000000..9a81d2d
--- /dev/null
@@ -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 = <&reg18>;
+
+       ports {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               port@0 {
+                       reg = <0>;
+                       dsi_in: endpoint {
+                               remote-endpoint = <&ltdc_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>;
+                       };
+               };
+       };
+};
+
+&ltdc {
+       status = "okay";
+
+       port {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ltdc_ep1_out: endpoint@1 {
+                       reg = <1>;
+                       remote-endpoint = <&dsi_in>;
+               };
+       };
+};
index 70bbf66704262ba55eb4b2cb8a8d5369e58acfa9..55f99037b2683d94223c5f1d7e467b0d7cfdc79f 100644 (file)
@@ -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 {
        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 {
        };
 };
 
-&uart4 {
-       u-boot,dm-pre-reloc;
-};
-
-&i2c4 {
-       u-boot,dm-pre-reloc;
-};
-
 &pmic {
        u-boot,dm-pre-reloc;
 };
        };
 };
 
-/* SPL part **************************************/
-/* MMC1 boot */
 &sdmmc1_b4_pins_a {
        u-boot,dm-spl;
        pins {
        u-boot,dm-spl;
 };
 
-/* MMC2 boot */
 &sdmmc2_b4_pins_a {
        u-boot,dm-spl;
        pins {
 &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;
+       };
+};
index 7a9b742d364ff0b7bc146efd5f18f74ede97f1d5..2664c9ce904d07b410602b53fb277571c4882d7e 100644 (file)
@@ -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";
        };
 };
 
-&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>;
        };
 };
 
+&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;
        status = "okay";
 };
 
+&timers6 {
+       status = "okay";
+       timer@5 {
+               status = "okay";
+       };
+};
+
 &uart4 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart4_pins_a>;
        usb33d-supply = <&usb33>;
 };
 
-&hwspinlock {
-       status = "okay";
-};
-
-&pinctrl {
-       hwlocks = <&hwspinlock 0>;
-};
-
 &usbphyc_port0 {
        phy-supply = <&vdd_usb>;
        vdda1v1-supply = <&reg11>;
index 409f983fb2ea672c4fb542eb553ddc62a187fc02..8b92b1fa2eeea286f1ce7728906517e57b9bafde 100644 (file)
@@ -7,29 +7,23 @@
 
 / {
        aliases {
-               spi0 = &qspi;
+               gpio26 = &stmfx_pinctrl;
                i2c1 = &i2c2;
                i2c4 = &i2c5;
+               pinctrl2 = &stmfx_pinctrl;
+               spi0 = &qspi;
        };
 };
 
 &flash0 {
        compatible = "jedec,spi-nor";
+       u-boot,dm-spl;
 };
 
 &flash1 {
        compatible = "jedec,spi-nor";
 };
 
-&v3v3 {
-       regulator-always-on;
-};
-
-&usbotg_hs {
-       g-tx-fifo-size = <576>;
-};
-
-/* SPL part **************************************/
 &qspi {
        u-boot,dm-spl;
 };
        };
 };
 
-&flash0 {
-       u-boot,dm-spl;
+&usbotg_hs {
+       g-tx-fifo-size = <576>;
 };
 
+&v3v3 {
+       regulator-always-on;
+};
index 902a42bee290a9e9b90576faf1e8a115e9e5f6e6..a6ee37924fe18fe574add7271b21358dfd678376 100644 (file)
        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 = &ethernet0;
+       };
+
+       panel_backlight: panel-backlight {
+               compatible = "gpio-backlight";
+               gpios = <&gpiod 13 GPIO_ACTIVE_LOW>;
+               default-on;
+               status = "okay";
+       };
 };
 
 &cec {
        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 = <&ltdc_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>;
+                       };
+               };
+       };
+};
+
+&ethernet0 {
+       status = "okay";
+       pinctrl-0 = <&ethernet0_rgmii_pins_a>;
+       pinctrl-1 = <&ethernet0_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 {
        status = "okay";
 };
 
+&ltdc {
+       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>;
        };
 };
 
+&spi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi1_pins_a>;
+       status = "disabled";
+};
+
 &timers2 {
        status = "disabled";
        pwm {
 &usbotg_hs {
        pinctrl-names = "default";
        pinctrl-0 = <&usbotg_hs_pins_a>;
+       dr_mode = "peripheral";
        phys = <&usbphyc_port1 0>;
        phy-names = "usb2-phy";
        status = "okay";
index 37cadfa30c90ff6d11875e06b549ced37855a81a..7eb4bee31cfcacc08d1bcc2f75d440286c9302fb 100644 (file)
@@ -29,7 +29,7 @@
        };
 
        psci {
-               compatible = "arm,psci";
+               compatible = "arm,psci-1.0";
                method = "smc";
                cpu_off = <0x84000002>;
                cpu_on = <0x84000003>;
                };
        };
 
-       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>;
                        };
                };
 
+               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>;
                        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>;
                        };
                };
 
+               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>;
                                reg = <0x0>;
                                interrupt-parent = <&adc>;
                                interrupts = <0>;
+                               dmas = <&dmamux1 9 0x400 0x01>;
+                               dma-names = "rx";
                                status = "disabled";
                        };
 
                                reg = <0x100>;
                                interrupt-parent = <&adc>;
                                interrupts = <1>;
+                               dmas = <&dmamux1 10 0x400 0x01>;
+                               dma-names = "rx";
                                status = "disabled";
                        };
                };
                };
 
                usbotg_hs: usb-otg@49000000 {
-                       compatible = "st,stm32mp1-hsotg", "snps,dwc2";
+                       compatible = "snps,dwc2";
                        reg = <0x49000000 0x10000>;
                        clocks = <&rcc USBO_K>;
                        clock-names = "otg";
                        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";
                };
 
                        reg = <0x5000d000 0x400>;
                };
 
-               syscfg: system-config@50020000 {
-                       compatible = "st,stm32-syscfg", "syscon";
+               syscfg: syscon@50020000 {
+                       compatible = "st,stm32mp157-syscfg", "syscon";
                        reg = <0x50020000 0x400>;
                };
 
                        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>;
                        dma-requests = <48>;
                };
 
-               qspi: qspi@58003000 {
+               qspi: spi@58003000 {
                        compatible = "st,stm32f469-qspi";
                        reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
                        reg-names = "qspi", "qspi_mm";
                        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>;
                        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>;
                        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>;
                        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/sun50i-a64-oceanic-5205-5inmfd.dts b/arch/arm/dts/sun50i-a64-oceanic-5205-5inmfd.dts
new file mode 100644 (file)
index 0000000..6a21545
--- /dev/null
@@ -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 = <&reg_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";
+};
+
+&reg_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";
+};
index d8ddecc0bd2f4a9356164196116ee2d53cebe8ff..15a5b641ffa259d3f525520bc2efec1e4e47702a 100644 (file)
 #define MT41K128MJT187E_PHY_FIFO_WE            0x100
 #define MT41K128MJT187E_IOCTRL_VALUE           0x18B
 
+/* Micron MT41K128M16JT-125 IT:K (256 MB) at 400MHz */
+#define MT41K128M16JT125K_EMIF_READ_LATENCY     0x07
+#define MT41K128M16JT125K_EMIF_TIM1             0x0AAAD4DB
+#define MT41K128M16JT125K_EMIF_TIM2             0x2A437FDA
+#define MT41K128M16JT125K_EMIF_TIM3             0x501F83FF
+#define MT41K128M16JT125K_EMIF_SDCFG            0x61A052B2
+#define MT41K128M16JT125K_EMIF_SDREF            0x00000C30
+#define MT41K128M16JT125K_ZQ_CFG                0x50074BE4
+#define MT41K128M16JT125K_RATIO                 0x80
+#define MT41K128M16JT125K_INVERT_CLKOUT         0x0
+#define MT41K128M16JT125K_RD_DQS                0x38
+#define MT41K128M16JT125K_WR_DQS                0x46
+#define MT41K128M16JT125K_PHY_WR_DATA           0x7D
+#define MT41K128M16JT125K_PHY_FIFO_WE           0x9B
+#define MT41K128M16JT125K_IOCTRL_VALUE          0x18B
+
 /* Micron MT41J64M16JT-125 */
 #define MT41J64MJT125_EMIF_SDCFG               0x61C04A32
 
index 4baba38b0045c4e327355c2a7d59f70fda748e50..8c916e8c752994199ea84397c072c8bb8117d685 100644 (file)
@@ -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 {
index 3039e66bf9f2250117d075667a3f3dea5f108607..992a84152cfae333edd0606912e6e1533276714b 100644 (file)
@@ -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>
index a5553190b431e7292452aeed154cc4540e3e2f80..77cd15f388c40cb68b006dd27f9bd2d040ae3f53 100644 (file)
@@ -83,10 +83,8 @@ void board_init_f(ulong dummy)
 
 #ifdef CONFIG_K3_AM654_DDRSS
        ret = uclass_get_device(UCLASS_RAM, 0, &dev);
-       if (ret) {
-               printf("DRAM init failed: %d\n", ret);
-               return;
-       }
+       if (ret)
+               panic("DRAM init failed: %d\n", ret);
 #endif
 }
 
index 5909bbfa8f5ac5dce697c496edec86aa2543a457..03f01d07eacf7c551f234c873a0d8a78a4e3e0ce 100644 (file)
 #include "common.h"
 #include <dm.h>
 #include <remoteproc.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+#include <fdt_support.h>
+
+struct ti_sci_handle *get_ti_sci_handle(void)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = uclass_get_device_by_name(UCLASS_FIRMWARE, "dmsc", &dev);
+       if (ret)
+               panic("Failed to get SYSFW (%d)\n", ret);
+
+       return (struct ti_sci_handle *)ti_sci_get_handle_from_sysfw(dev);
+}
 
 #ifdef CONFIG_SYS_K3_SPL_ATF
 void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
@@ -42,3 +56,77 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
                asm volatile("wfe");
 }
 #endif
+
+#if defined(CONFIG_OF_LIBFDT)
+int fdt_fixup_msmc_ram(void *blob, char *parent_path, char *node_name)
+{
+       u64 msmc_start = 0, msmc_end = 0, msmc_size, reg[2];
+       struct ti_sci_handle *ti_sci = get_ti_sci_handle();
+       int ret, node, subnode, len, prev_node;
+       u32 range[4], addr, size;
+       const fdt32_t *sub_reg;
+
+       ti_sci->ops.core_ops.query_msmc(ti_sci, &msmc_start, &msmc_end);
+       msmc_size = msmc_end - msmc_start + 1;
+       debug("%s: msmc_start = 0x%llx, msmc_size = 0x%llx\n", __func__,
+             msmc_start, msmc_size);
+
+       /* find or create "msmc_sram node */
+       ret = fdt_path_offset(blob, parent_path);
+       if (ret < 0)
+               return ret;
+
+       node = fdt_find_or_add_subnode(blob, ret, node_name);
+       if (node < 0)
+               return node;
+
+       ret = fdt_setprop_string(blob, node, "compatible", "mmio-sram");
+       if (ret < 0)
+               return ret;
+
+       reg[0] = cpu_to_fdt64(msmc_start);
+       reg[1] = cpu_to_fdt64(msmc_size);
+       ret = fdt_setprop(blob, node, "reg", reg, sizeof(reg));
+       if (ret < 0)
+               return ret;
+
+       fdt_setprop_cell(blob, node, "#address-cells", 1);
+       fdt_setprop_cell(blob, node, "#size-cells", 1);
+
+       range[0] = 0;
+       range[1] = cpu_to_fdt32(msmc_start >> 32);
+       range[2] = cpu_to_fdt32(msmc_start & 0xffffffff);
+       range[3] = cpu_to_fdt32(msmc_size);
+       ret = fdt_setprop(blob, node, "ranges", range, sizeof(range));
+       if (ret < 0)
+               return ret;
+
+       subnode = fdt_first_subnode(blob, node);
+       prev_node = 0;
+
+       /* Look for invalid subnodes and delete them */
+       while (subnode >= 0) {
+               sub_reg = fdt_getprop(blob, subnode, "reg", &len);
+               addr = fdt_read_number(sub_reg, 1);
+               sub_reg++;
+               size = fdt_read_number(sub_reg, 1);
+               debug("%s: subnode = %d, addr = 0x%x. size = 0x%x\n", __func__,
+                     subnode, addr, size);
+               if (addr + size > msmc_size ||
+                   !strncmp(fdt_get_name(blob, subnode, &len), "sysfw", 5) ||
+                   !strncmp(fdt_get_name(blob, subnode, &len), "l3cache", 7)) {
+                       fdt_del_node(blob, subnode);
+                       debug("%s: deleting subnode %d\n", __func__, subnode);
+                       if (!prev_node)
+                               subnode = fdt_first_subnode(blob, node);
+                       else
+                               subnode = fdt_next_subnode(blob, prev_node);
+               } else {
+                       prev_node = subnode;
+                       subnode = fdt_next_subnode(blob, prev_node);
+               }
+       }
+
+       return 0;
+}
+#endif
index 0b2007981a498648742bcdf3185f49cda5e72955..018725b4d128fbafd46df8317ac52c5be333201c 100644 (file)
@@ -10,5 +10,6 @@
 void sdelay(unsigned long loops);
 u32 wait_on_value(u32 read_bit_mask, u32 match_value, void *read_addr,
                  u32 bound);
-
+struct ti_sci_handle *get_ti_sci_handle(void);
+int fdt_fixup_msmc_ram(void *blob, char *parent_path, char *node_name);
 #endif
index d24596eccb0dfd7a94ef6622242e005907c5c21a..e06eba5aea1fb25c27528559326f1514855ef607 100644 (file)
@@ -9,18 +9,24 @@ config TARGET_K2HK_EVM
        select SPL_BOARD_INIT if SPL
        select CMD_DDR3
        imply DM_I2C
+       imply SOC_TI
+       imply TI_KEYSTONE_SERDES
 
 config TARGET_K2E_EVM
        bool "TI Keystone 2 Edison EVM"
        select SPL_BOARD_INIT if SPL
        select CMD_DDR3
        imply DM_I2C
+       imply SOC_TI
+       imply TI_KEYSTONE_SERDES
 
 config TARGET_K2L_EVM
        bool "TI Keystone 2 Lamar EVM"
        select SPL_BOARD_INIT if SPL
        select CMD_DDR3
        imply DM_I2C
+       imply SOC_TI
+       imply TI_KEYSTONE_SERDES
 
 config TARGET_K2G_EVM
        bool "TI Keystone 2 Galileo EVM"
@@ -29,6 +35,8 @@ config TARGET_K2G_EVM
         select TI_I2C_BOARD_DETECT
        select CMD_DDR3
        imply DM_I2C
+       imply SOC_TI
+       imply TI_KEYSTONE_SERDES
 
 endchoice
 
index 8b902641ec9ac84cf0add25555451448512cea0f..971c081bb3c3b9303ae05ab3fcacf1162280366f 100644 (file)
 
 #define K2G_GPIO0_BASE                 0X02603000
 #define K2G_GPIO1_BASE                 0X0260a000
+#define K2G_GPIO0_BANK0_BASE           K2G_GPIO0_BASE + 0x10
 #define K2G_GPIO1_BANK2_BASE           K2G_GPIO1_BASE + 0x38
 #define K2G_GPIO_DIR_OFFSET            0x0
+#define K2G_GPIO_OUTDATA_OFFSET                0x4
 #define K2G_GPIO_SETDATA_OFFSET                0x8
+#define K2G_GPIO_CLRDATA_OFFSET                0xC
 
 /* BOOTCFG RESETMUX8 */
 #define KS2_RSTMUX8                    (KS2_DEVICE_STATE_CTRL_BASE + 0x328)
index 809b72d5bf9dd08dc3eab825b0d5e9f03b6f9d15..67d47f8172167ea30423c0bff401793bbb537d43 100644 (file)
 #define PIN_PTU        (1 << 17) /* pull up */
 #define PIN_PTD        (0 << 17) /* pull down */
 
+#define BUFFER_CLASS_B (0 << 19)
+#define BUFFER_CLASS_C (1 << 19)
+#define BUFFER_CLASS_D (2 << 19)
+#define BUFFER_CLASS_E (3 << 19)
+
 #define MODE(m)        ((m) & 0x7)
 #define MAX_PIN_N      260
 
index d54de53f31dc049c785bd3ca7c043aa790f02f56..8f8e3003854c213d7b04c2e974058230f90b605b 100644 (file)
@@ -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();
 
index 91d21518d852fd816fc344dc796dbc9c8c10339c..ea42182cf9c609332bc5d88c5c829f28468a9f07 100644 (file)
@@ -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,
index 227707ae4c95c7afd47313766f268298951c5a79..1d7f2828cd38288d2937ea81756faad65c7406ef 100644 (file)
@@ -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))
index 7dda04e0e34e11f24c2218e76a9ecc12647f8c66..f5fd60d784560336ddd4170e10ffaff83f0c8f8c 100644 (file)
@@ -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
index ee2eca91348483fbd0f81ee990ae211ddb8ffd4c..02d3ce27ee74189ac0d156f39b56a98a0764d24f 100644 (file)
@@ -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
index 919d05c88c7724113c512e53ae5f97a427dba1c0..c5b3df46aab765076a19fa6b43e67366f7e92156 100644 (file)
@@ -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
index 71c4f70efc9e56b0cde72e5b636f735ed9cee539..bbcfcfd1419b01464ce688001d57ed04a715410f 100644 (file)
@@ -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.
index 9e23043a4857bc9ba91ffd00f6e12e3e29ffb069..b9153d86c669378242dc791eeb10c0c00cd4a644 100644 (file)
@@ -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)
 
index 01577f469b0e6bbc44a486ce59fa4639e612a816..f666ee24243b4cd06ced9b5291c2488d1e43fb03 100644 (file)
 #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)
 #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
 #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))
index df4c5cb2d71825dfd128a83090e6dd4e72de3644..c68e93ba10070e17ac2c4e2acea754abbf8f91a6 100644 (file)
@@ -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;
 }
index 569840ff47186da2b38c2ce7f83c50479f7e4c1b..c8c92988645f27e4f6c02f8f3cd9c72408b28983 100644 (file)
@@ -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;
index 1cac4437d72c9d6c3d13ae988622495ebfa2ccc3..d29f1ca0b58b250f817681f53a7bd57d60a51a67 100644 (file)
@@ -167,21 +167,6 @@ config TI_SECURE_EMIF_PROTECTED_REGION_SIZE
          using hardware memory firewalls. This value must be smaller than the
          TI_SECURE_EMIF_TOTAL_REGION_SIZE value.
 
-if AM43XX || AM33XX || OMAP54XX
-config ISW_ENTRY_ADDR
-       hex "Address in memory or XIP address of bootloader entry point"
-       default 0x402F4000 if AM43XX
-       default 0x402F0400 if AM33XX
-       default 0x40301350 if OMAP54XX
-       help
-         After any reset, the boot ROM searches the boot media for a valid
-         boot image. For non-XIP devices, the ROM then copies the image into
-         internal memory. For all boot modes, after the ROM processes the
-         boot image it eventually computes the entry point address depending
-         on the device type (secure/non-secure), boot media (xip/non-xip) and
-         image headers.
-endif
-
 source "arch/arm/mach-omap2/omap3/Kconfig"
 
 source "arch/arm/mach-omap2/omap4/Kconfig"
index 85ea8946b0fd1a2f1808222d8c44a285c9f8f02e..500df1aa11d1990b7a1180de46299477c8e26068 100644 (file)
@@ -87,6 +87,13 @@ config TARGET_AM335X_SHC
        imply CMD_DM
        imply CMD_SPL
 
+config TARGET_AM335X_GUARDIAN
+       bool "Support am335x based guardian board from bosch"
+       select DM
+       select DM_SERIAL
+       select DM_GPIO
+       select DM_USB
+
 config TARGET_AM335X_SL50
        bool "Support am335x_sl50"
        select BOARD_LATE_INIT
index 8a929fa91322dc3252932f874ab715541242d629..73aa382712268ddcb14477e651e7f6b31b0566d6 100644 (file)
@@ -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
index f59ced5ee1b1a5904328b4f8b4ee24903675b55c..1493914a110d3cc8be870017cc71521383a68dc8 100644 (file)
@@ -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
index d087a313892603fbc3a7868807a2fd86982aba70..9ed8d8c56c3c4c811eeef7b75867de1b8b7853eb 100644 (file)
@@ -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 (file)
index 0000000..f54dd1d
--- /dev/null
@@ -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;
+}
index f371aac75bde48fd3025908ced7fb300ed1542fd..403af2a225e69ea025634543c324eb13a95ad75b 100644 (file)
@@ -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)
 
index b8933587adb37eb951abd97fcd68db3142892b96..7b4431c9c75cf3035a6fc7d0bb189907f259ecfb 100644 (file)
@@ -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
 #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;
index 5d0bdca1787d6c7c853ced6cbf13d06ec9fa08f7..c526c88e3ee9caf25558c66c80d976c8bacdb37b 100644 (file)
 #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
 /* 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 (file)
index 0000000..8130546
--- /dev/null
@@ -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__ */
index 41d4b40bcb4fccb0975cf4a78285465ec73230b6..71a3ba794d11b8f90b61bf5bb23ea3229798dfbe 100644 (file)
@@ -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);
index 6ed2482080c1dcf578c1dc073388451c4151256f..c2dff38c368c9f6c540651157212015d14519cc9 100644 (file)
@@ -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;
 }
 
index 790973e8b6e9101bcfb9a10f896f36c68776c8cc..a3b0d6f38252a63a4e564e86e4adb1f6aaf52a2f 100644 (file)
@@ -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();
        }
 }
index eb7f435f10caefbdc9b7ee14952a9504c3da2ea8..242f8340abb459d1ff492c9401a19d1b99fdd575 100644 (file)
@@ -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 },
        { }
 };
 
index 152deb04e9003d28aef086eade0dd8fb449b2897..8110f23ff67d89911846785f3c9a6543fa736d91 100644 (file)
@@ -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
index b74eaf2a0e474836ae776869dd1a3265a0a664ee..c6dd7b8e54b05c74c04394064cdb7d6139ec7a03 100644 (file)
@@ -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;
index 1da2727f987420acdb164a3d5693d4ddcfe3efa0..5da01922bfaf69034ae4a8ebc24c18a1f9bde127 100644 (file)
@@ -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)
index 665d3cc8c1ca71d81aaebfdfa9a5513a317c4fd3..3522e6cdc82e5662424569a471d3202a11ce082f 100644 (file)
@@ -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
index 82bf637410b05d550814b97174935a7c2d379a45..93a098052c79de37b8492a585b24fddb36c3cdd4 100644 (file)
@@ -40,3 +40,8 @@
                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 (file)
index 0000000..1722290
--- /dev/null
@@ -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>;
+       };
+};
index b6f95591476d8ac32901d4ad258dc92948130300..c060802e8a450bf0085ad75610b67a02c0b2e8c1 100644 (file)
 
                        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";
+               };
        };
 };
index 513045ee0519d81c28dda66da06c99a478d8c65a..98471e3894de4fa2544dfbd525fd9b17c0ac279f 100644 (file)
                label = "bcm968380gerg:green:usb";
        };
 };
+
+&gpio_lo {
+       status = "okay";
+};
+
+&gpio_mid0 {
+       status = "okay";
+};
+
+&gpio_mid1 {
+       status = "okay";
+};
index 2f2cfdd9f967f609ecf8ea7e71ad4e37222bf9b4..eedde89dfd8a719cf3647ef0e1c7704c66ec0822 100644 (file)
@@ -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;
index 1e123978e39c23252a447e9c1e9ad53b2df7e4b9..6562221794e170a4345217f90d6ee3e9d4cab0d8 100644 (file)
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 #include "mscc,jr2.dtsi"
+#include <dt-bindings/mscc/jr2_data.h>
 
 / {
        model = "Jaguar2 Cu8-Sfp16 PCB110 Reference Board";
        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>;
+               };
+       };
+};
index fcd8455407fa23a8b55da8584effbed2f7291773..74305a8f3310730487259eb9c5ede0b62e488345 100644 (file)
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 #include "mscc,jr2.dtsi"
+#include <dt-bindings/mscc/jr2_data.h>
 
 / {
        model = "Jaguar2 Cu48 PCB111 Reference Board";
        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>;
+               };
+       };
+};
index 090092607b52010247acf05ec0fed439aad6082c..7f5a96fecdc625b307beaed8470d26d404af3c86 100644 (file)
                        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>;
+                       };
+               };
        };
 };
index 4beb7a38d0cedaf59acd8fa06c2e42302c3b301f..45ae2de5e876a1420294a9314fce7625b2e6e07b 100644 (file)
                        #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";
+               };
        };
 };
index ba29ea287e2bab3dfaddd3b6fdd2ac9740d7c4eb..90d34ddbbfbcabdf8829e68fd002ccbfa3e8979a 100644 (file)
 
                                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 (file)
index 0000000..6cb360b
--- /dev/null
@@ -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>;
+               };
+       };
+};
index 2921c449dc9264ef47dabd0998f08c2c1fc1d94c..5777a773b1716b01b7447008a5a75e6801e50ff3 100644 (file)
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 #include "mscc,jr2.dtsi"
+#include <dt-bindings/mscc/jr2_data.h>
 
 / {
        model = "Serval2 NID PCB112 Reference Board";
        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>;
+               };
+       };
+};
index 4de3e25164fd82a3fd08f2bba7a3af0fb042e634..313b0998e6bfefbdbd27b61774f377c34212b26f 100644 (file)
        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>;
+               };
+       };
+};
index deca5189e33f93c285c7cc68596e9a4c916187c3..35152cb3f64afe122c1defb58b40fa006fe38d8a 100644 (file)
@@ -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);
index bc86f591df83a342f85440d59709cdfa1be8fc37..bdb23b57658fb77bee2681943f9cf4f1785b5a49 100644 (file)
@@ -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
index 7aa40c65d3005be867f1b2257ec515ed946b2040..fbd40c02becb9f4123426b66709ceeffbff21589 100644 (file)
@@ -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/
index 5d371bb5828d013898a78c45085f036d213b19a3..5888f6eb288d303cb9fb1a3dc312141e76e1c58c 100644 (file)
 #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
        (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
  */
 #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
  */
 #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
 #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
 
 #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
 
 #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)
 #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
 #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
  */
 #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 */
index 5de7a43f79ead4e0f0c39a1f0635920b78294f98..0fde5079b16780c5da07dededcc0fd518af9ded7 100644 (file)
@@ -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 (file)
index 0000000..3f5fc03
--- /dev/null
@@ -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 (file)
index 0000000..33a44cf
--- /dev/null
@@ -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 (file)
index 0000000..08a8c84
--- /dev/null
@@ -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 (file)
index 0000000..fb22304
--- /dev/null
@@ -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 (file)
index 0000000..db54b57
--- /dev/null
@@ -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)
index 6a94d886f94ff7832fc8ef3a2fd1598391c8d57a..0ab3ab6383c8cb33b8f5eecb24d30e4fd2de9b77 100644 (file)
@@ -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>
 #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;
 }
index f6e724588a9c5fcb0b4617719e418a7352228ea1..493eaad1df7fdc4e93b4e6ebd12032944070850b 100644 (file)
@@ -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
index 4ebcb4b053cb16a08c549309d46ea9440268d7ac..a9834439993de448bd132a8edade956fe0ea9885 100644 (file)
@@ -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
index 54c4c196abe47e06d46cc06d4bf277a3b462a93a..8b2d6451c64375cf7d10b509c54fda8e8216a931 100644 (file)
                        compatible = "denx,u-boot-probe-test";
                        first-syscon = <&syscon0>;
                        second-sys-ctrl = <&another_system_controller>;
+                       third-syscon = <&syscon2>;
                };
        };
 
                        0x38 8>;
        };
 
-       syscon@2 {
+       syscon2: syscon@2 {
                compatible = "simple-mfd", "syscon";
                reg = <0x40 5
                        0x48 6
index 1027b59e7326b8d99e5748ceb514e1dff4460452..c45dbddd70003dfda2571cd343075bc307f31642 100644 (file)
@@ -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;
 }
index 7cd56b41474fdc9387602cfee8e65e5db5c305b4..c1a5d2af8285b879fdfd30f831d42f333c5fe913 100644 (file)
@@ -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__ */
 
index 5039973cd7aff9e2c4aa365be5879725d99ea132..01822c606956cb04e74fd425afca688f2c331cb4 100644 (file)
@@ -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;
 }
 
index c7f6479a0cf040e4bedcc8cb3f680aad6e875492..c21d2f3ffa67f8304f470dbead2aa20fbd53059d 100644 (file)
@@ -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 (file)
index 0000000..775b934
--- /dev/null
@@ -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 (file)
index 0000000..2b27e48
--- /dev/null
@@ -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 (file)
index 0000000..4dd5790
--- /dev/null
@@ -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 (file)
index 0000000..5e479b4
--- /dev/null
@@ -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 (file)
index 0000000..8dd6872
--- /dev/null
@@ -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 (file)
index 0000000..cae428f
--- /dev/null
@@ -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 (file)
index 0000000..b8bb7a6
--- /dev/null
@@ -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
index eb3694ea6e7c23eae75a3008b2cd01700513e149..d23e97c9b9165b3aafe2f8983538a4d1a7d73275 100644 (file)
@@ -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)
index d7d1942fe686aa59138894cff4a881c4a879e8eb..6934fd80173072c8ef5d1bf0624ff8819d7845ed 100644 (file)
@@ -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/bosch/guardian/Kconfig b/board/bosch/guardian/Kconfig
new file mode 100644 (file)
index 0000000..1417da6
--- /dev/null
@@ -0,0 +1,15 @@
+if TARGET_AM335X_GUARDIAN
+
+config SYS_BOARD
+       default "guardian"
+
+config SYS_VENDOR
+       default "bosch"
+
+config SYS_SOC
+       default "am33xx"
+
+config SYS_CONFIG_NAME
+       default "am335x_guardian"
+
+endif
diff --git a/board/bosch/guardian/MAINTAINERS b/board/bosch/guardian/MAINTAINERS
new file mode 100644 (file)
index 0000000..8d16ec0
--- /dev/null
@@ -0,0 +1,6 @@
+Guardian BOARD
+M:     Sjoerd Simons <sjoerd.simons@collabora.co.uk>
+S:     Maintained
+F:     board/bosch/guardian/
+F:     include/configs/am335x_guardian.h
+F:     configs/am335x_guardian_defconfig
diff --git a/board/bosch/guardian/Makefile b/board/bosch/guardian/Makefile
new file mode 100644 (file)
index 0000000..11625c9
--- /dev/null
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier:     GPL-2.0+
+#
+# Makefile
+#
+# Copyright (C) 2018 Robert Bosch Power Tools GmbH
+#
+
+ifeq ($(CONFIG_SKIP_LOWLEVEL_INIT),)
+obj-y  := mux.o
+endif
+
+obj-y  += board.o
diff --git a/board/bosch/guardian/board.c b/board/bosch/guardian/board.c
new file mode 100644 (file)
index 0000000..86ab180
--- /dev/null
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * board.c
+ *
+ * Board functions for Bosch Guardian
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ * Copyright (C) 2018 Robert Bosch Power Tools GmbH
+ */
+
+#include <common.h>
+#include <cpsw.h>
+#include <dm.h>
+#include <environment.h>
+#include <environment.h>
+#include <errno.h>
+#include <i2c.h>
+#include <miiphy.h>
+#include <panel.h>
+#include <power/tps65217.h>
+#include <power/tps65910.h>
+#include <spl.h>
+#include <watchdog.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/mmc_host_def.h>
+#include <asm/arch/omap.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/emif.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include "board.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
+
+static const struct ddr_data ddr3_data = {
+       .datardsratio0 = MT41K128M16JT125K_RD_DQS,
+       .datawdsratio0 = MT41K128M16JT125K_WR_DQS,
+       .datafwsratio0 = MT41K128M16JT125K_PHY_FIFO_WE,
+       .datawrsratio0 = MT41K128M16JT125K_PHY_WR_DATA,
+};
+
+static const struct cmd_control ddr3_cmd_ctrl_data = {
+       .cmd0csratio = MT41K128M16JT125K_RATIO,
+       .cmd0iclkout = MT41K128M16JT125K_INVERT_CLKOUT,
+
+       .cmd1csratio = MT41K128M16JT125K_RATIO,
+       .cmd1iclkout = MT41K128M16JT125K_INVERT_CLKOUT,
+
+       .cmd2csratio = MT41K128M16JT125K_RATIO,
+       .cmd2iclkout = MT41K128M16JT125K_INVERT_CLKOUT,
+};
+
+static struct emif_regs ddr3_emif_reg_data = {
+       .sdram_config = MT41K128M16JT125K_EMIF_SDCFG,
+       .ref_ctrl = MT41K128M16JT125K_EMIF_SDREF,
+       .sdram_tim1 = MT41K128M16JT125K_EMIF_TIM1,
+       .sdram_tim2 = MT41K128M16JT125K_EMIF_TIM2,
+       .sdram_tim3 = MT41K128M16JT125K_EMIF_TIM3,
+       .zq_config = MT41K128M16JT125K_ZQ_CFG,
+       .emif_ddr_phy_ctlr_1 = MT41K128M16JT125K_EMIF_READ_LATENCY,
+};
+
+#define OSC    (V_OSCK / 1000000)
+const struct dpll_params dpll_ddr = {
+               400, OSC - 1, 1, -1, -1, -1, -1};
+
+void am33xx_spl_board_init(void)
+{
+       int mpu_vdd;
+       int usb_cur_lim;
+
+       /* Get the frequency */
+       dpll_mpu_opp100.m = am335x_get_efuse_mpu_max_freq(cdev);
+
+       if (i2c_probe(TPS65217_CHIP_PM))
+               return;
+
+       /*
+        * Increase USB current limit to 1300mA or 1800mA and set
+        * the MPU voltage controller as needed.
+        */
+       if (dpll_mpu_opp100.m == MPUPLL_M_1000) {
+               usb_cur_lim = TPS65217_USB_INPUT_CUR_LIMIT_1800MA;
+               mpu_vdd = TPS65217_DCDC_VOLT_SEL_1325MV;
+       } else {
+               usb_cur_lim = TPS65217_USB_INPUT_CUR_LIMIT_1300MA;
+               mpu_vdd = TPS65217_DCDC_VOLT_SEL_1275MV;
+       }
+
+       if (tps65217_reg_write(TPS65217_PROT_LEVEL_NONE,
+                              TPS65217_POWER_PATH,
+                              usb_cur_lim,
+                              TPS65217_USB_INPUT_CUR_LIMIT_MASK))
+               puts("tps65217_reg_write failure\n");
+
+       /* Set DCDC3 (CORE) voltage to 1.125V */
+       if (tps65217_voltage_update(TPS65217_DEFDCDC3,
+                                   TPS65217_DCDC_VOLT_SEL_1125MV)) {
+               puts("tps65217_voltage_update failure\n");
+               return;
+       }
+
+       /* Set CORE Frequencies to OPP100 */
+       do_setup_dpll(&dpll_core_regs, &dpll_core_opp100);
+
+       /* Set DCDC2 (MPU) voltage */
+       if (tps65217_voltage_update(TPS65217_DEFDCDC2, mpu_vdd)) {
+               puts("tps65217_voltage_update failure\n");
+               return;
+       }
+
+       /*
+        * Set LDO3 to 1.8V and LDO4 to 3.3V
+        */
+       if (tps65217_reg_write(TPS65217_PROT_LEVEL_2,
+                              TPS65217_DEFLS1,
+                              TPS65217_LDO_VOLTAGE_OUT_1_8,
+                              TPS65217_LDO_MASK))
+               puts("tps65217_reg_write failure\n");
+
+       if (tps65217_reg_write(TPS65217_PROT_LEVEL_2,
+                              TPS65217_DEFLS2,
+                              TPS65217_LDO_VOLTAGE_OUT_3_3,
+                              TPS65217_LDO_MASK))
+               puts("tps65217_reg_write failure\n");
+
+       /* Set MPU Frequency to what we detected now that voltages are set */
+       do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100);
+}
+
+const struct dpll_params *get_dpll_ddr_params(void)
+{
+       enable_i2c0_pin_mux();
+       i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
+
+       return &dpll_ddr;
+}
+
+void set_uart_mux_conf(void)
+{
+       enable_uart0_pin_mux();
+}
+
+void set_mux_conf_regs(void)
+{
+       enable_board_pin_mux();
+}
+
+const struct ctrl_ioregs ioregs = {
+       .cm0ioctl               = MT41K128M16JT125K_IOCTRL_VALUE,
+       .cm1ioctl               = MT41K128M16JT125K_IOCTRL_VALUE,
+       .cm2ioctl               = MT41K128M16JT125K_IOCTRL_VALUE,
+       .dt0ioctl               = MT41K128M16JT125K_IOCTRL_VALUE,
+       .dt1ioctl               = MT41K128M16JT125K_IOCTRL_VALUE,
+};
+
+void sdram_init(void)
+{
+       config_ddr(400, &ioregs,
+                  &ddr3_data,
+                  &ddr3_cmd_ctrl_data,
+                  &ddr3_emif_reg_data, 0);
+}
+#endif
+
+int board_init(void)
+{
+#if defined(CONFIG_HW_WATCHDOG)
+       hw_watchdog_init();
+#endif
+
+       gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+
+#ifdef CONFIG_NAND
+       gpmc_init();
+#endif
+       return 0;
+}
diff --git a/board/bosch/guardian/board.h b/board/bosch/guardian/board.h
new file mode 100644 (file)
index 0000000..b301caf
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * board.h
+ *
+ * Board header for Bosch Guardian
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ * Copyright (C) 2018 Robert Bosch Power Tools GmbH
+ */
+
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+void enable_uart0_pin_mux(void);
+void enable_i2c0_pin_mux(void);
+void enable_board_pin_mux(void);
+#endif
diff --git a/board/bosch/guardian/mux.c b/board/bosch/guardian/mux.c
new file mode 100644 (file)
index 0000000..708c3e7
--- /dev/null
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * mux.c
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ * Copyright (C) 2018 Robert Bosch Power Tools GmbH
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+#include "board.h"
+
+static struct module_pin_mux uart0_pin_mux[] = {
+       {OFFSET(uart0_rxd), (MODE(0) | PULLUP_EN | RXACTIVE)},
+       {OFFSET(uart0_txd), (MODE(0) | PULLUDEN)},
+       {-1},
+};
+
+static struct module_pin_mux i2c0_pin_mux[] = {
+       {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL)},
+       {OFFSET(i2c0_scl), (MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL)},
+       {-1},
+};
+
+static struct module_pin_mux adc_voltages_en[] = {
+       {OFFSET(mcasp0_ahclkx), (MODE(7) | PULLUP_EN)},
+       {-1},
+};
+
+static struct module_pin_mux asp_power_en[] = {
+       {OFFSET(mcasp0_aclkx), (MODE(7) | PULLUP_EN)},
+       {-1},
+};
+
+static struct module_pin_mux switch_off_3v6_pin_mux[] = {
+       {OFFSET(mii1_txd0), (MODE(7) | PULLUP_EN)},
+       /*
+        * The uart1 lines are made floating inputs, based on the Guardian
+        * A2 Sample Power Supply Schematics
+        */
+       {OFFSET(uart1_rxd), (MODE(7) | PULLUDDIS)},
+       {OFFSET(uart1_txd), (MODE(7) | PULLUDDIS)},
+       {-1},
+};
+
+#ifdef CONFIG_NAND
+static struct module_pin_mux nand_pin_mux[] = {
+       {OFFSET(gpmc_ad0),      (MODE(0) | PULLUDDIS | RXACTIVE)},
+       {OFFSET(gpmc_ad1),      (MODE(0) | PULLUDDIS | RXACTIVE)},
+       {OFFSET(gpmc_ad2),      (MODE(0) | PULLUDDIS | RXACTIVE)},
+       {OFFSET(gpmc_ad3),      (MODE(0) | PULLUDDIS | RXACTIVE)},
+       {OFFSET(gpmc_ad4),      (MODE(0) | PULLUDDIS | RXACTIVE)},
+       {OFFSET(gpmc_ad5),      (MODE(0) | PULLUDDIS | RXACTIVE)},
+       {OFFSET(gpmc_ad6),      (MODE(0) | PULLUDDIS | RXACTIVE)},
+       {OFFSET(gpmc_ad7),      (MODE(0) | PULLUDDIS | RXACTIVE)},
+#ifdef CONFIG_SYS_NAND_BUSWIDTH_16BIT
+       {OFFSET(gpmc_ad8),      (MODE(0) | PULLUDDIS | RXACTIVE)},
+       {OFFSET(gpmc_ad9),      (MODE(0) | PULLUDDIS | RXACTIVE)},
+       {OFFSET(gpmc_ad10),     (MODE(0) | PULLUDDIS | RXACTIVE)},
+       {OFFSET(gpmc_ad11),     (MODE(0) | PULLUDDIS | RXACTIVE)},
+       {OFFSET(gpmc_ad12),     (MODE(0) | PULLUDDIS | RXACTIVE)},
+       {OFFSET(gpmc_ad13),     (MODE(0) | PULLUDDIS | RXACTIVE)},
+       {OFFSET(gpmc_ad14),     (MODE(0) | PULLUDDIS | RXACTIVE)},
+       {OFFSET(gpmc_ad15),     (MODE(0) | PULLUDDIS | RXACTIVE)},
+#endif
+       {OFFSET(gpmc_wait0),    (MODE(0) | PULLUP_EN | RXACTIVE)},
+       {OFFSET(gpmc_wpn),      (MODE(7) | PULLUP_EN)},
+       {OFFSET(gpmc_csn0),     (MODE(0) | PULLUP_EN)},
+       {OFFSET(gpmc_wen),      (MODE(0) | PULLDOWN_EN)},
+       {OFFSET(gpmc_oen_ren),  (MODE(0) | PULLDOWN_EN)},
+       {OFFSET(gpmc_advn_ale), (MODE(0) | PULLDOWN_EN)},
+       {OFFSET(gpmc_be0n_cle), (MODE(0) | PULLDOWN_EN)},
+       {-1},
+};
+#endif
+
+void enable_uart0_pin_mux(void)
+{
+       configure_module_pin_mux(uart0_pin_mux);
+}
+
+void enable_i2c0_pin_mux(void)
+{
+       configure_module_pin_mux(i2c0_pin_mux);
+}
+
+void enable_board_pin_mux(void)
+{
+#ifdef CONFIG_NAND
+       configure_module_pin_mux(nand_pin_mux);
+#endif
+       configure_module_pin_mux(adc_voltages_en);
+       configure_module_pin_mux(asp_power_en);
+       configure_module_pin_mux(switch_off_3v6_pin_mux);
+}
index b0b29b3887f54eb69d70be2a92357561a03f2a10..e8ec553f99ef124f7be1dd6d32301d8b847a1095 100644 (file)
@@ -49,33 +49,6 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #define CFG_MAC_ADDR_OFFSET    (flash->size - SZ_64K)
 
-#ifdef CONFIG_SPL_BUILD
-#include <ns16550.h>
-#include <dm/platform_data/spi_davinci.h>
-
-static const struct ns16550_platdata da850evm_serial = {
-       .base = DAVINCI_UART2_BASE,
-       .reg_shift = 2,
-       .clock = 150000000,
-       .fcr = UART_FCR_DEFVAL,
-};
-
-U_BOOT_DEVICE(da850evm_uart) = {
-       .name = "ns16550_serial",
-       .platdata = &da850evm_serial,
-};
-
-static const struct davinci_spi_platdata davinci_spi_data = {
-        .regs = (struct davinci_spi_regs *)0x01f0e000,
-        .num_cs = 4,
-};
-
-U_BOOT_DEVICE(davinci_spi) = {
-        .name = "davinci_spi",
-        .platdata = &davinci_spi_data,
-};
-#endif
-
 #ifdef CONFIG_MAC_ADDR_IN_SPIFLASH
 static int get_mac_addr(u8 *addr)
 {
index 7b5fab7756cb524ee545a14555cd266d83a9b499..8f04911306bc4127cea744fefcf73f9056e0630e 100644 (file)
@@ -10,6 +10,9 @@
 MEMORY { .sram : ORIGIN = IMAGE_TEXT_BASE,\
                LENGTH = CONFIG_SPL_MAX_FOOTPRINT }
 
+MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
+                LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
 OUTPUT_ARCH(arm)
 ENTRY(_start)
@@ -42,6 +45,15 @@ SECTIONS
                __rel_dyn_end = .;
        } >.sram
 
+       __image_copy_end = .;
+
+       .end :
+       {
+               *(.__end)
+       }
+
+       _image_binary_end = .;
+
        .bss :
        {
                . = ALIGN(4);
@@ -49,12 +61,5 @@ SECTIONS
                *(.bss*)
                . = ALIGN(4);
                __bss_end = .;
-       } >.sram
-
-       __image_copy_end = .;
-
-       .end :
-       {
-               *(.__end)
-       }
+       } >.sdram
 }
index 6f728398c38dff1c6b8301574b2c9e6fb0cc225b..10031a48018fc9b13960fe0094756a0ee6b2ac78 100644 (file)
@@ -37,6 +37,15 @@ DECLARE_GLOBAL_DATA_PTR;
 #define CPGMACSS_SW_RST                (1 << 1)
 #define PHY_GPIO               30
 
+#if defined(CONFIG_SPL_BUILD)
+#if defined(CONFIG_SPL_OS_BOOT)
+int spl_start_uboot(void)
+{
+       /* break into full u-boot on 'c' */
+       return serial_tstc() && serial_getc() == 'c';
+}
+#endif
+#endif
 
 /*
  * Routine: board_init
index e8f8f7ba5b4775826ec4a190f46f74804f50625e..395904f8c87861648c214156c785736c6812e0f4 100644 (file)
@@ -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];
 }
index 58a4a04162b2e371bf8f5ef2be7d3159d1b579a4..6e5ef4c97f47e48fd9b07b0d76a7b7f837d6612e 100644 (file)
@@ -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 (file)
index 0000000..f6ad498
--- /dev/null
@@ -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 (file)
index 0000000..785ec27
--- /dev/null
@@ -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 (file)
index 0000000..4270afa
--- /dev/null
@@ -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 (file)
index 0000000..30cd565
--- /dev/null
@@ -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;
+}
index a7bc0d4e23fbe5946edd448830bc476e5ddd72a6..0b0e98de90a0b8905efe922b74d795b6ccf9780a 100644 (file)
@@ -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:
 ---------------
 
index 48d8fd2c3f2caf23583fc6410baf40fa0f1656ad..0a2eddbe03d87b6d1f8066c823303abc5fbf8845 100644 (file)
@@ -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
index 174e6db1484a60a363805c7731ba317d73f0472a..1cd3534ae4e7289a6dfaf4f8b9a15fc052f7a6a7 100644 (file)
@@ -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
index 5f31ea99f597d0ac0b02ce665250aafd066295ed..5c1acca20d79dd3213357d99f99b02a09affe550 100644 (file)
@@ -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;
 }
index f3db0d638539c8316037784fd6f765c8a356cbcb..a7844f244bc5ad5ef0fce871298060bedc9541bd 100644 (file)
 #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
 }
index 54feca0ecff5c3e9189824e316de0a2526fe1ab3..24d299ac33bddf7803ce129e23d12aee85793dc0 100644 (file)
@@ -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);
+}
index 8dd0da4aeb655230f0ab3205dd1702ec2b0ce469..338f374e56ee543e8e43e1608d111a8cec24f803 100644 (file)
@@ -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
index dd6def5e6e7910aea9d1ea0b96fbfcb5f6a4797a..d42350319cc4f2c9905443a143135a4c191ffc3c 100644 (file)
@@ -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");
 
index d67f94ad47baec593946f51f4beffe9384915af8..2c32b92d940667916250585ca34b976cc51a562c 100644 (file)
@@ -875,157 +875,55 @@ int board_late_init(void)
 }
 #endif
 
-#ifndef CONFIG_DM_ETH
-
-#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
-       (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
-static void cpsw_control(int enabled)
-{
-       /* VTP can be added here */
-
-       return;
-}
-
-static struct cpsw_slave_data cpsw_slaves[] = {
+/* CPSW platdata */
+#if !CONFIG_IS_ENABLED(OF_CONTROL)
+struct cpsw_slave_data slave_data[] = {
        {
-               .slave_reg_ofs  = 0x208,
-               .sliver_reg_ofs = 0xd80,
-               .phy_addr       = 0,
+               .slave_reg_ofs  = CPSW_SLAVE0_OFFSET,
+               .sliver_reg_ofs = CPSW_SLIVER0_OFFSET,
+               .phy_addr       = 0,
        },
        {
-               .slave_reg_ofs  = 0x308,
-               .sliver_reg_ofs = 0xdc0,
-               .phy_addr       = 1,
+               .slave_reg_ofs  = CPSW_SLAVE1_OFFSET,
+               .sliver_reg_ofs = CPSW_SLIVER1_OFFSET,
+               .phy_addr       = 1,
        },
 };
 
-static struct cpsw_platform_data cpsw_data = {
-       .mdio_base              = CPSW_MDIO_BASE,
+struct cpsw_platform_data am335_eth_data = {
        .cpsw_base              = CPSW_BASE,
-       .mdio_div               = 0xff,
+       .version                = CPSW_CTRL_VERSION_2,
+       .bd_ram_ofs             = CPSW_BD_OFFSET,
+       .ale_reg_ofs            = CPSW_ALE_OFFSET,
+       .cpdma_reg_ofs          = CPSW_CPDMA_OFFSET,
+       .mdio_div               = CPSW_MDIO_DIV,
+       .host_port_reg_ofs      = CPSW_HOST_PORT_OFFSET,
        .channels               = 8,
-       .cpdma_reg_ofs          = 0x800,
-       .slaves                 = 1,
-       .slave_data             = cpsw_slaves,
-       .ale_reg_ofs            = 0xd00,
+       .slaves                 = 2,
+       .slave_data             = slave_data,
        .ale_entries            = 1024,
-       .host_port_reg_ofs      = 0x108,
-       .hw_stats_reg_ofs       = 0x900,
        .bd_ram_ofs             = 0x2000,
-       .mac_control            = (1 << 5),
-       .control                = cpsw_control,
-       .host_port_num          = 0,
-       .version                = CPSW_CTRL_VERSION_2,
+       .mac_control            = 0x20,
+       .active_slave           = 0,
+       .mdio_base              = 0x4a101000,
+       .gmii_sel               = 0x44e10650,
+       .phy_sel_compat         = "ti,am3352-cpsw-phy-sel",
+       .syscon_addr            = 0x44e10630,
+       .macid_sel_compat       = "cpsw,am33xx",
 };
-#endif
-
-#if ((defined(CONFIG_SPL_ETH_SUPPORT) || defined(CONFIG_SPL_USB_ETHER)) &&\
-       defined(CONFIG_SPL_BUILD)) || \
-       ((defined(CONFIG_DRIVER_TI_CPSW) || \
-         defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET)) && \
-        !defined(CONFIG_SPL_BUILD))
 
-/*
- * This function will:
- * Read the eFuse for MAC addresses, and set ethaddr/eth1addr/usbnet_devaddr
- * in the environment
- * Perform fixups to the PHY present on certain boards.  We only need this
- * function in:
- * - SPL with either CPSW or USB ethernet support
- * - Full U-Boot, with either CPSW or USB ethernet
- * Build in only these cases to avoid warnings about unused variables
- * when we build an SPL that has neither option but full U-Boot will.
- */
-int board_eth_init(bd_t *bis)
-{
-       int rv, n = 0;
-#if defined(CONFIG_USB_ETHER) && \
-       (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_USB_ETHER))
-       uint8_t mac_addr[6];
-       uint32_t mac_hi, mac_lo;
-
-       /*
-        * use efuse mac address for USB ethernet as we know that
-        * both CPSW and USB ethernet will never be active at the same time
-        */
-       mac_lo = readl(&cdev->macid0l);
-       mac_hi = readl(&cdev->macid0h);
-       mac_addr[0] = mac_hi & 0xFF;
-       mac_addr[1] = (mac_hi & 0xFF00) >> 8;
-       mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
-       mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
-       mac_addr[4] = mac_lo & 0xFF;
-       mac_addr[5] = (mac_lo & 0xFF00) >> 8;
-#endif
-
-
-#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
-       (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
-
-#ifdef CONFIG_DRIVER_TI_CPSW
-       if (board_is_bone() || board_is_bone_lt() || board_is_bben() ||
-           board_is_idk()) {
-               writel(MII_MODE_ENABLE, &cdev->miisel);
-               cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if =
-                               PHY_INTERFACE_MODE_MII;
-       } else if (board_is_icev2()) {
-               writel(RMII_MODE_ENABLE | RMII_CHIPCKL_ENABLE, &cdev->miisel);
-               cpsw_slaves[0].phy_if = PHY_INTERFACE_MODE_RMII;
-               cpsw_slaves[1].phy_if = PHY_INTERFACE_MODE_RMII;
-               cpsw_slaves[0].phy_addr = 1;
-               cpsw_slaves[1].phy_addr = 3;
-       } else {
-               writel((RGMII_MODE_ENABLE | RGMII_INT_DELAY), &cdev->miisel);
-               cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if =
-                               PHY_INTERFACE_MODE_RGMII;
-       }
-
-       rv = cpsw_register(&cpsw_data);
-       if (rv < 0)
-               printf("Error %d registering CPSW switch\n", rv);
-       else
-               n += rv;
-#endif
+struct eth_pdata cpsw_pdata = {
+       .iobase = 0x4a100000,
+       .phy_interface = 0,
+       .priv_pdata = &am335_eth_data,
+};
 
-       /*
-        *
-        * CPSW RGMII Internal Delay Mode is not supported in all PVT
-        * operating points.  So we must set the TX clock delay feature
-        * in the AR8051 PHY.  Since we only support a single ethernet
-        * device in U-Boot, we only do this for the first instance.
-        */
-#define AR8051_PHY_DEBUG_ADDR_REG      0x1d
-#define AR8051_PHY_DEBUG_DATA_REG      0x1e
-#define AR8051_DEBUG_RGMII_CLK_DLY_REG 0x5
-#define AR8051_RGMII_TX_CLK_DLY                0x100
-
-       if (board_is_evm_sk() || board_is_gp_evm() || board_is_bben()) {
-               const char *devname;
-               devname = miiphy_get_current_dev();
-
-               miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_ADDR_REG,
-                               AR8051_DEBUG_RGMII_CLK_DLY_REG);
-               miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_DATA_REG,
-                               AR8051_RGMII_TX_CLK_DLY);
-       }
-#endif
-#if defined(CONFIG_USB_ETHER) && \
-       (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_USB_ETHER))
-       if (is_valid_ethaddr(mac_addr))
-               eth_env_set_enetaddr("usbnet_devaddr", mac_addr);
-
-       rv = usb_eth_initialize(bis);
-       if (rv < 0)
-               printf("Error %d registering USB_ETHER\n", rv);
-       else
-               n += rv;
-#endif
-       return n;
-}
+U_BOOT_DEVICE(am335x_eth) = {
+       .name = "eth_cpsw",
+       .platdata = &cpsw_pdata,
+};
 #endif
 
-#endif /* CONFIG_DM_ETH */
-
 #ifdef CONFIG_SPL_LOAD_FIT
 int board_fit_config_name_match(const char *name)
 {
index 784b2b0191d49e3e9adae36cc04d593638f293ae..52f5d6b11e3a7a2b797afc01a50993d15a67d533 100644 (file)
@@ -10,6 +10,7 @@
 #include <common.h>
 #include <asm/io.h>
 #include <spl.h>
+#include <asm/arch/sys_proto.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -66,3 +67,16 @@ int board_fit_config_name_match(const char *name)
        return -1;
 }
 #endif
+
+#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
+int ft_board_setup(void *blob, bd_t *bd)
+{
+       int ret;
+
+       ret = fdt_fixup_msmc_ram(blob, "/interconnect@100000", "sram@70000000");
+       if (ret)
+               printf("%s: fixing up msmc ram failed %d\n", __func__, ret);
+
+       return ret;
+}
+#endif
index 060c47103261da9a209d395812d57dd27b3096cf..179adc2fff0ec97eb07abc120346a56128485600 100644 (file)
@@ -27,6 +27,7 @@
 #include <environment.h>
 #include <dwc3-uboot.h>
 #include <dwc3-omap-uboot.h>
+#include <i2c.h>
 #include <ti-usb-phy-uboot.h>
 #include <miiphy.h>
 
@@ -55,6 +56,10 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #define SYSINFO_BOARD_NAME_MAX_LEN     37
 
+/* I2C I/O Expander */
+#define NAND_PCF8575_ADDR      0x21
+#define NAND_PCF8575_I2C_BUS_NUM       0
+
 const struct omap_sysinfo sysinfo = {
        "Board: UNKNOWN(DRA7 EVM) REV UNKNOWN\n"
 };
@@ -777,6 +782,44 @@ void set_muxconf_regs(void)
                     early_padconf, ARRAY_SIZE(early_padconf));
 }
 
+#if defined(CONFIG_NAND)
+static int nand_sw_detect(void)
+{
+       int rc;
+       uchar data[2];
+       struct udevice *dev;
+
+       rc = i2c_get_chip_for_busnum(NAND_PCF8575_I2C_BUS_NUM,
+                                    NAND_PCF8575_ADDR, 0, &dev);
+       if (rc)
+               return -1;
+
+       rc = dm_i2c_read(dev, 0, (uint8_t *)&data, sizeof(data));
+       if (rc)
+               return -1;
+
+       /* We are only interested in P10 and P11 on PCF8575 which is equal to
+        * bits 8 and 9.
+        */
+       data[1] = data[1] & 0x3;
+
+       /* Ensure only P11 is set and P10 is cleared. This ensures only
+        * NAND (P10) is configured and not NOR (P11) which are both low
+        * true signals. NAND and NOR settings should not be enabled at
+        * the same time.
+        */
+       if (data[1] == 0x2)
+               return 0;
+
+       return -1;
+}
+#else
+int nand_sw_detect(void)
+{
+       return -1;
+}
+#endif
+
 #ifdef CONFIG_IODELAY_RECALIBRATION
 void recalibrate_iodelay(void)
 {
@@ -796,6 +839,19 @@ void recalibrate_iodelay(void)
                        npads = ARRAY_SIZE(dra71x_core_padconf_array);
                        iodelay = dra71_iodelay_cfg_array;
                        niodelays = ARRAY_SIZE(dra71_iodelay_cfg_array);
+                       /* If SW8 on the EVM is set to enable NAND then
+                        * overwrite the pins used by VOUT3 with NAND.
+                        */
+                       if (!nand_sw_detect()) {
+                               delta_pads = dra71x_nand_padconf_array;
+                               delta_npads =
+                                       ARRAY_SIZE(dra71x_nand_padconf_array);
+                       } else {
+                               delta_pads = dra71x_vout3_padconf_array;
+                               delta_npads =
+                                       ARRAY_SIZE(dra71x_vout3_padconf_array);
+                       }
+
                } else if (board_is_dra72x_revc_or_later()) {
                        delta_pads = dra72x_rgmii_padconf_array_revc;
                        delta_npads =
index f1f6bd5316757168933844ef57a861e134ce5e96..75da5cb608f5a6aa6d7b6f29dcf6eaf2ebe3678f 100644 (file)
@@ -220,22 +220,6 @@ const struct pad_conf_entry dra72x_rgmii_padconf_array_revc[] = {
 };
 
 const struct pad_conf_entry dra71x_core_padconf_array[] = {
-       {GPMC_AD0, (M3 | PIN_INPUT)},   /* gpmc_ad0.vout3_d0 */
-       {GPMC_AD1, (M3 | PIN_INPUT)},   /* gpmc_ad1.vout3_d1 */
-       {GPMC_AD2, (M3 | PIN_INPUT)},   /* gpmc_ad2.vout3_d2 */
-       {GPMC_AD3, (M3 | PIN_INPUT)},   /* gpmc_ad3.vout3_d3 */
-       {GPMC_AD4, (M3 | PIN_INPUT)},   /* gpmc_ad4.vout3_d4 */
-       {GPMC_AD5, (M3 | PIN_INPUT)},   /* gpmc_ad5.vout3_d5 */
-       {GPMC_AD6, (M3 | PIN_INPUT)},   /* gpmc_ad6.vout3_d6 */
-       {GPMC_AD7, (M3 | PIN_INPUT)},   /* gpmc_ad7.vout3_d7 */
-       {GPMC_AD8, (M3 | PIN_INPUT)},   /* gpmc_ad8.vout3_d8 */
-       {GPMC_AD9, (M3 | PIN_INPUT)},   /* gpmc_ad9.vout3_d9 */
-       {GPMC_AD10, (M3 | PIN_INPUT)},  /* gpmc_ad10.vout3_d10 */
-       {GPMC_AD11, (M3 | PIN_INPUT)},  /* gpmc_ad11.vout3_d11 */
-       {GPMC_AD12, (M3 | PIN_INPUT)},  /* gpmc_ad12.vout3_d12 */
-       {GPMC_AD13, (M3 | PIN_INPUT)},  /* gpmc_ad13.vout3_d13 */
-       {GPMC_AD14, (M3 | PIN_INPUT)},  /* gpmc_ad14.vout3_d14 */
-       {GPMC_AD15, (M3 | PIN_INPUT)},  /* gpmc_ad15.vout3_d15 */
        {GPMC_A0, (M3 | PIN_INPUT_PULLDOWN)},   /* gpmc_a0.vout3_d16 */
        {GPMC_A1, (M3 | PIN_INPUT_PULLDOWN)},   /* gpmc_a1.vout3_d17 */
        {GPMC_A2, (M3 | PIN_INPUT_PULLDOWN)},   /* gpmc_a2.vout3_d18 */
@@ -370,6 +354,50 @@ const struct pad_conf_entry dra71x_core_padconf_array[] = {
        {WAKEUP3, (M1 | PULL_ENA | PULL_UP)},   /* Wakeup3.sys_nirq1 */
 };
 
+const struct pad_conf_entry dra71x_vout3_padconf_array[] = {
+       {GPMC_AD0, (M3 | PIN_INPUT)},   /* gpmc_ad0.vout3_d0 */
+       {GPMC_AD1, (M3 | PIN_INPUT)},   /* gpmc_ad1.vout3_d1 */
+       {GPMC_AD2, (M3 | PIN_INPUT)},   /* gpmc_ad2.vout3_d2 */
+       {GPMC_AD3, (M3 | PIN_INPUT)},   /* gpmc_ad3.vout3_d3 */
+       {GPMC_AD4, (M3 | PIN_INPUT)},   /* gpmc_ad4.vout3_d4 */
+       {GPMC_AD5, (M3 | PIN_INPUT)},   /* gpmc_ad5.vout3_d5 */
+       {GPMC_AD6, (M3 | PIN_INPUT)},   /* gpmc_ad6.vout3_d6 */
+       {GPMC_AD7, (M3 | PIN_INPUT)},   /* gpmc_ad7.vout3_d7 */
+       {GPMC_AD8, (M3 | PIN_INPUT)},   /* gpmc_ad8.vout3_d8 */
+       {GPMC_AD9, (M3 | PIN_INPUT)},   /* gpmc_ad9.vout3_d9 */
+       {GPMC_AD10, (M3 | PIN_INPUT)},  /* gpmc_ad10.vout3_d10 */
+       {GPMC_AD11, (M3 | PIN_INPUT)},  /* gpmc_ad11.vout3_d11 */
+       {GPMC_AD12, (M3 | PIN_INPUT)},  /* gpmc_ad12.vout3_d12 */
+       {GPMC_AD13, (M3 | PIN_INPUT)},  /* gpmc_ad13.vout3_d13 */
+       {GPMC_AD14, (M3 | PIN_INPUT)},  /* gpmc_ad14.vout3_d14 */
+       {GPMC_AD15, (M3 | PIN_INPUT)},  /* gpmc_ad15.vout3_d15 */
+};
+
+const struct pad_conf_entry dra71x_nand_padconf_array[] = {
+       {GPMC_AD0, (M0 | PIN_INPUT)},   /* gpmc_ad0.gpmc_ad0 */
+       {GPMC_AD1, (M0 | PIN_INPUT)},   /* gpmc_ad1.gpmc_ad1 */
+       {GPMC_AD2, (M0 | PIN_INPUT)},   /* gpmc_ad2.gpmc_ad2 */
+       {GPMC_AD3, (M0 | PIN_INPUT)},   /* gpmc_ad3.gpmc_ad3 */
+       {GPMC_AD4, (M0 | PIN_INPUT)},   /* gpmc_ad4.gpmc_ad4 */
+       {GPMC_AD5, (M0 | PIN_INPUT)},   /* gpmc_ad5.gpmc_ad5 */
+       {GPMC_AD6, (M0 | PIN_INPUT)},   /* gpmc_ad6.gpmc_ad6 */
+       {GPMC_AD7, (M0 | PIN_INPUT)},   /* gpmc_ad7.gpmc_ad7 */
+       {GPMC_AD8, (M0 | PIN_INPUT)},   /* gpmc_ad8.gpmc_ad8 */
+       {GPMC_AD9, (M0 | PIN_INPUT)},   /* gpmc_ad9.gpmc_ad9 */
+       {GPMC_AD10, (M0 | PIN_INPUT)},  /* gpmc_ad10.gpmc_ad10 */
+       {GPMC_AD11, (M0 | PIN_INPUT)},  /* gpmc_ad11.gpmc_ad11 */
+       {GPMC_AD12, (M0 | PIN_INPUT)},  /* gpmc_ad12.gpmc_ad12 */
+       {GPMC_AD13, (M0 | PIN_INPUT)},  /* gpmc_ad13.gpmc_ad13 */
+       {GPMC_AD14, (M0 | PIN_INPUT)},  /* gpmc_ad14.gpmc_ad14 */
+       {GPMC_AD15, (M0 | PIN_INPUT)},  /* gpmc_ad15.gpmc_ad15 */
+       {GPMC_CS0, (M0 | PIN_INPUT_PULLUP)},    /* gpmc_cs0.gpmc_cs0 */
+       {GPMC_ADVN_ALE, (M0 | PIN_INPUT_PULLDOWN)},     /* gpmc_advn_ale.gpmc_advn_ale */
+       {GPMC_OEN_REN, (M0 | PIN_INPUT_PULLUP)},        /* gpmc_oen_ren.gpmc_oen_ren */
+       {GPMC_WEN, (M0 | PIN_INPUT_PULLUP)},    /* gpmc_wen.gpmc_wen */
+       {GPMC_BEN0, (M0 | PIN_INPUT_PULLDOWN)}, /* gpmc_ben0.gpmc_ben0 */
+       {GPMC_WAIT0, (M0 | PIN_INPUT_PULLUP | SLEWCONTROL)},    /* gpmc_wait0.gpmc_wait0 */
+};
+
 const struct pad_conf_entry early_padconf[] = {
        {UART1_RXD, (PIN_INPUT_SLEW | M0)}, /* UART1_RXD */
        {UART1_TXD, (PIN_INPUT_SLEW | M0)}, /* UART1_TXD */
index 39a782e47960ee13412e2864cdef788c8d5b3c9c..6d0fc21c67acc29f05b411fd608633a327ed0de4 100644 (file)
@@ -315,6 +315,21 @@ int embedded_dtb_select(void)
                             BIT(9));
                setbits_le32(K2G_GPIO1_BANK2_BASE + K2G_GPIO_SETDATA_OFFSET,
                             BIT(9));
+       } else if (board_is_k2g_ice()) {
+               /* GBE Phy workaround. For Phy to latch the input
+                * configuration, a GPIO reset is asserted at the
+                * Phy reset pin to latch configuration correctly after SoC
+                * reset. GPIO0 Pin 10 (Ball AA20) is used for this on ICE
+                * board. Just do a low to high transition.
+                */
+               clrbits_le32(K2G_GPIO0_BANK0_BASE + K2G_GPIO_DIR_OFFSET,
+                            BIT(10));
+               setbits_le32(K2G_GPIO0_BANK0_BASE + K2G_GPIO_CLRDATA_OFFSET,
+                            BIT(10));
+               /* Delay just to get a transition to high */
+               udelay(100);
+               setbits_le32(K2G_GPIO0_BANK0_BASE + K2G_GPIO_SETDATA_OFFSET,
+                            BIT(10));
        }
 
        return 0;
index 706fb7e83817a126c44d8d92424e01389d05e238..89c49f9e4fcde8ee42e309fe2ba37643bc4252a7 100644 (file)
@@ -125,21 +125,23 @@ struct pin_cfg k2g_evm_pin_cfg[] = {
        { 70,   MODE(0) },      /* SOC_MMC1_SDWP */
        { 71,   MODE(0) },      /* MMC1POW TP124 */
 
-       /* RGMII */
-       { 72,   MODE(1) | PIN_IEN },    /* SOC_RGMII_RXCLK */
-       { 77,   MODE(1) | PIN_IEN },    /* SOC_RGMII_RXD3 */
-       { 78,   MODE(1) | PIN_IEN },    /* SOC_RGMII_RXD2 */
-       { 79,   MODE(1) | PIN_IEN },    /* SOC_RGMII_RXD1 */
-       { 80,   MODE(1) | PIN_IEN },    /* SOC_RGMII_RXD0 */
-       { 81,   MODE(1) | PIN_IEN },    /* SOC_RGMII_RXCTL */
-       { 85,   MODE(1) },      /* SOC_RGMII_TXCLK */
-       { 91,   MODE(1) },      /* SOC_RGMII_TXD3 */
-       { 92,   MODE(1) },      /* SOC_RGMII_TXD2 */
-       { 93,   MODE(1) },      /* SOC_RGMII_TXD1 */
-       { 94,   MODE(1) },      /* SOC_RGMII_TXD0 */
-       { 95,   MODE(1) },      /* SOC_RGMII_TXCTL */
-       { 98,   MODE(0) },      /* SOC_MDIO_DATA */
-       { 99,   MODE(0) },      /* SOC_MDIO_CLK */
+               /* EMAC */
+       { 79,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_RXD1 */
+       { 78,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_RXD2 */
+       { 77,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_RXD3 */
+       { 80,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_RXD0 */
+       { 94,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_TXD0 */
+       { 93,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_TXD1 */
+       { 92,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_TXD2 */
+       { 91,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_TXD3 */
+       { 85,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_TXC */
+       { 95,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_TXCTL */
+       { 72,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_RXC */
+       { 81,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_RXCTL */
+
+       /* MDIO */
+       { 99,   BUFFER_CLASS_B | PIN_PDIS | MODE(0) },  /* MDIO_CLK */
+       { 98,   BUFFER_CLASS_B | PIN_PDIS | MODE(0) },  /* MDIO_DATA */
 
        /* PWM */
        { 73,   MODE(4) },      /* SOC_EHRPWM3A */
@@ -346,6 +348,25 @@ struct pin_cfg k2g_ice_evm_pin_cfg[] = {
        { 133,  MODE(0) },      /* SOC_QSPI_D2 */
        { 134,  MODE(0) },      /* SOC_QSPI_D3 */
        { 135,  MODE(0) },      /* SOC_QSPI_CSN0 */
+
+       /* EMAC */
+       { 79,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_RXD1 */
+       { 78,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_RXD2 */
+       { 77,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_RXD3 */
+       { 80,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_RXD0 */
+       { 94,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_TXD0 */
+       { 93,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_TXD1 */
+       { 92,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_TXD2 */
+       { 91,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_TXD3 */
+       { 85,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_TXC */
+       { 95,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_TXCTL */
+       { 72,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_RXC */
+       { 81,   BUFFER_CLASS_D | PIN_PDIS | MODE(1) },  /* RGMII_RXCTL */
+
+       /* MDIO */
+       { 99,   BUFFER_CLASS_B | PIN_PDIS | MODE(0) },  /* MDIO_CLK */
+       { 98,   BUFFER_CLASS_B | PIN_PDIS | MODE(0) },  /* MDIO_DATA */
+
        { MAX_PIN_N, }
 };
 
index 0b07b3b9d777c246bfcd413337396fdd5db20dca..2bdbfcb3d09106a2c5b500e68ae0564a321dce1a 100644 (file)
@@ -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
index acb85f49fba87cc00774e419afdb2b1ab192a9e2..6b1c6b094e6daf610fadcc2ec700ce22b4878217 100644 (file)
@@ -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
diff --git a/cmd/wdt.c b/cmd/wdt.c
new file mode 100644 (file)
index 0000000..647d989
--- /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));
index 42583e3ed8c895d5b2b081bccc846be48d17bde4..ab08a0114feea8f2b726fd50829fc58cf92b72dd 100644 (file)
@@ -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);
index a6a237f7839bd58b06ac4fe98b725e685d9023da..a396a3931050f83d6843b53a453797234e70c2f5 100644 (file)
@@ -7,14 +7,16 @@ CONFIG_DISTRO_DEFAULTS=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_OF_BOARD_SETUP=y
 CONFIG_BOOTCOMMAND="if test ${boot_fit} -eq 1; then run update_to_fit; fi; run findfdt; run init_console; run envboot; run distro_bootcmd"
+CONFIG_LOGLEVEL=3
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 CONFIG_VERSION_VARIABLE=y
 CONFIG_ARCH_MISC_INIT=y
+CONFIG_SPL_ETH_SUPPORT=y
 # CONFIG_SPL_FS_EXT4 is not set
 CONFIG_SPL_MTD_SUPPORT=y
 CONFIG_SPL_MUSB_NEW_SUPPORT=y
 CONFIG_SPL_NET_SUPPORT=y
-CONFIG_SPL_NET_VCI_STRING="AM33xx U-Boot SPL"
+CONFIG_SPL_NET_VCI_STRING="AM335x U-Boot SPL"
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_USB_GADGET=y
 CONFIG_SPL_USB_ETHER=y
@@ -31,6 +33,7 @@ CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-evm"
 CONFIG_OF_LIST="am335x-evm am335x-bone am335x-boneblack am335x-evmsk am335x-bonegreen am335x-icev2"
 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_SPL_ENV_IS_NOWHERE=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_NAND=y
@@ -39,6 +42,7 @@ CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_DM_I2C=y
 CONFIG_MISC=y
 CONFIG_DM_MMC=y
+# CONFIG_MMC_HW_PARTITIONING is not set
 CONFIG_MMC_OMAP_HS=y
 CONFIG_NAND=y
 CONFIG_DM_SPI_FLASH=y
@@ -46,7 +50,6 @@ CONFIG_SPI_FLASH=y
 CONFIG_SF_DEFAULT_SPEED=24000000
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_DM_ETH=y
-CONFIG_PHY_GIGE=y
 CONFIG_MII=y
 CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SPI=y
@@ -70,3 +73,4 @@ CONFIG_USB_ETHER=y
 CONFIG_DYNAMIC_CRC_TABLE=y
 CONFIG_RSA=y
 CONFIG_LZO=y
+# CONFIG_OF_LIBFDT_OVERLAY is not set
diff --git a/configs/am335x_guardian_defconfig b/configs/am335x_guardian_defconfig
new file mode 100644 (file)
index 0000000..c25a1a9
--- /dev/null
@@ -0,0 +1,90 @@
+CONFIG_ARM=y
+CONFIG_ARCH_OMAP2PLUS=y
+CONFIG_SPL_GPIO_SUPPORT=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_AM33XX=y
+CONFIG_TARGET_AM335X_GUARDIAN=y
+CONFIG_SPL_MMC_SUPPORT=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_SPL=y
+CONFIG_SPL_LIBDISK_SUPPORT=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_BOOTSTAGE_STASH_ADDR=0x0
+CONFIG_CONSOLE_MUX=y
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+CONFIG_VERSION_VARIABLE=y
+CONFIG_ARCH_MISC_INIT=y
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SPL_ENV_SUPPORT=y
+CONFIG_SPL_ETH_SUPPORT=y
+CONFIG_SPL_I2C_SUPPORT=y
+CONFIG_SPL_MUSB_NEW_SUPPORT=y
+CONFIG_SPL_NET_SUPPORT=y
+CONFIG_SPL_NET_VCI_STRING="Guardian U-Boot SPL"
+CONFIG_SPL_POWER_SUPPORT=y
+CONFIG_SPL_USB_GADGET=y
+CONFIG_SPL_USB_ETHER=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
+CONFIG_SPL_YMODEM_SUPPORT=y
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n"
+CONFIG_AUTOBOOT_DELAY_STR="d"
+CONFIG_AUTOBOOT_STOP_STR=" "
+CONFIG_CMD_SPL=y
+CONFIG_CMD_SPL_NAND_OFS=0x0
+CONFIG_CMD_ASKENV=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_NAND=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDPARTS_DEFAULT="mtdparts=nand.0:256k(SPL),256k(SPL.backup1),256k(SPL.backup2),256k(SPL.backup3),1m(u-boot),1m(u-boot.backup1),256k(u-boot-env),256k(u-boot-env.backup1),-(UBI)"
+CONFIG_CMD_UBI=y
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_ISO_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="am335x-guardian"
+CONFIG_ENV_IS_IN_NAND=y
+CONFIG_SPL_ENV_IS_NOWHERE=y
+CONFIG_SPL_DM=y
+CONFIG_BOOTCOUNT_LIMIT=y
+CONFIG_BOOTCOUNT_ENV=y
+CONFIG_MISC=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_OMAP_HS=y
+CONFIG_MTD=y
+CONFIG_NAND=y
+CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
+CONFIG_SYS_NAND_U_BOOT_OFFS=0x100000
+CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND=0x200000
+CONFIG_MTD_UBI_FASTMAP=y
+CONFIG_PHYLIB=y
+CONFIG_DM_ETH=y
+CONFIG_PHY=y
+CONFIG_NOP_PHY=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_SPL_DM_USB_GADGET=y
+CONFIG_USB_MUSB_HOST=y
+CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_TI=y
+CONFIG_USB_MUSB_DSPS=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
+CONFIG_USB_GADGET_VENDOR_NUM=0x0451
+CONFIG_USB_GADGET_PRODUCT_NUM=0xd022
+CONFIG_USB_ETHER=y
+CONFIG_FAT_WRITE=y
index 3d710202251bc9599ee56e63526278ed53513f35..e5de83386f3a3d0ebfe54b73d9a04b1feb32d592 100644 (file)
@@ -40,9 +40,13 @@ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SPL_SYSCON=y
+CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_DWC_AHCI=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
+CONFIG_DFU_SF=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
index 8f6fd25531b425d0e32e7ca3f76c91a08c4b2785..724b4bc09ff5550b7f0725804ab7af47d5f4790b 100644 (file)
@@ -15,6 +15,7 @@ CONFIG_DISTRO_DEFAULTS=y
 CONFIG_NR_DRAM_BANKS=2
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL_LOAD_FIT=y
+CONFIG_OF_BOARD_SETUP=y
 CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run get_kern_${boot}; run get_fdt_${boot}; run run_kern"
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
@@ -48,10 +49,11 @@ CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_CLK_TI_SCI=y
+CONFIG_DMA_CHANNELS=y
+CONFIG_TI_K3_NAVSS_UDMA=y
 CONFIG_TI_SCI_PROTOCOL=y
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
-CONFIG_MISC=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_K3_ARASAN=y
@@ -67,5 +69,6 @@ CONFIG_REMOTEPROC_K3=y
 CONFIG_DM_RESET=y
 CONFIG_RESET_TI_SCI=y
 CONFIG_DM_SERIAL=y
+CONFIG_SOC_TI=y
 CONFIG_SYSRESET=y
 CONFIG_SYSRESET_TI_SCI=y
diff --git a/configs/ap152_defconfig b/configs/ap152_defconfig
new file mode 100644 (file)
index 0000000..21cb6eb
--- /dev/null
@@ -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
index 597618fb900bfd4e42039734852ba1f606289c37..4e4734655fc9d1c891a1d7c8127d236a4af1271f 100644 (file)
@@ -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
index e7c10dbdf2d0c94c96e9286dc41dfaf2b63df803..29dd892d7f07f333ed7c08a12739b1440457d6ea 100644 (file)
@@ -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
index 91302eb49cf880a1e8a42e1ca2447ac6dd5b5b6a..8546674b2395a4c9ba060ee3dd7d3869e3d722ab 100644 (file)
@@ -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
index fc55e98550a2f1dc6aa199c04a07882045e5ca4e..5659249fdf3d692fbc154a6a4d0669e3fb0bc071 100644 (file)
@@ -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
index 61661bd756c7ef8de95e2dcef83f8ff0be71d6c4..fa9dc85d638d42da5fa5c3b89c6b7b11671a9d7b 100644 (file)
@@ -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
index e8cb3a0d2a9bcc4d304bfbf0e58929445bc71afd..456ece72d5cbbe970eaa71da8c9a9c3721aaa1ad 100644 (file)
@@ -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
index 41dae05fb904e5e446415c62ed2664a3c8227c4a..4b09ba10a6758292ff7eaa278c8c74fbbc93cd51 100644 (file)
@@ -1,4 +1,5 @@
 CONFIG_ARM=y
+CONFIG_SYS_THUMB_BUILD=y
 CONFIG_ARCH_DAVINCI=y
 CONFIG_SYS_TEXT_BASE=0xc1080000
 CONFIG_TARGET_DA850EVM=y
@@ -13,6 +14,7 @@ CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_NR_DRAM_BANKS=1
 CONFIG_SYS_EXTRA_OPTIONS="MAC_ADDR_IN_SPIFLASH"
 CONFIG_BOOTDELAY=3
+CONFIG_DEFAULT_FDT_FILE="da850-evm.dtb"
 CONFIG_MISC_INIT_R=y
 CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_CPUINFO is not set
@@ -20,6 +22,7 @@ CONFIG_VERSION_VARIABLE=y
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="U-Boot > "
@@ -39,10 +42,11 @@ CONFIG_CMD_DIAG=y
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="da850-evm"
-CONFIG_SPL_OF_PLATDATA=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_DM_GPIO=y
 CONFIG_DA8XX_GPIO=y
 CONFIG_DM_I2C=y
index 48b7c2a97a115d32a6f4997757f1987710df8967..af5ba813c27936bc3dd5abef3c726a566c8e6517 100644 (file)
@@ -1,4 +1,5 @@
 CONFIG_ARM=y
+CONFIG_SYS_THUMB_BUILD=y
 CONFIG_ARCH_DAVINCI=y
 CONFIG_SYS_TEXT_BASE=0xc1080000
 CONFIG_TARGET_DA850EVM=y
@@ -12,12 +13,14 @@ CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_SYS_EXTRA_OPTIONS="MAC_ADDR_IN_SPIFLASH"
 CONFIG_BOOTDELAY=3
+CONFIG_DEFAULT_FDT_FILE="da850-evm.dtb"
 CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_NAND_SUPPORT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_HUSH_PARSER=y
@@ -37,13 +40,15 @@ CONFIG_CMD_DIAG=y
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="da850-evm"
-CONFIG_SPL_OF_PLATDATA=y
 CONFIG_ENV_IS_IN_NAND=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_DM_GPIO=y
 CONFIG_DA8XX_GPIO=y
 CONFIG_DM_I2C=y
+CONFIG_DM_MMC=y
 CONFIG_NAND=y
 CONFIG_NAND_DAVINCI=y
 CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
index dcf2a25395e22714e83106beb9f3acda27aaa961..e8ba5184c4d7f86622d158b53f1d93d150eaa6ef 100644 (file)
@@ -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
index 98e47ee956361c7ecd0fac20f93340efe5b94519..078bd230504eef4e4fd101bc37e51c4cd08df2b0 100644 (file)
@@ -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 (file)
index 0000000..0285cca
--- /dev/null
@@ -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
index 5a766981603a3e22f74c5612b1e797a5b9121155..ba8b053680b9df42ae3cfc32a6fa89aa789cd508 100644 (file)
@@ -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
index 598a2a380f36816b76d859c9528c6c69fad94197..072582c865d49033c96e77b05a91cfe9327784b6 100644 (file)
@@ -23,12 +23,15 @@ CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_DMA_SUPPORT=y
-# CONFIG_SPL_NAND_SUPPORT is not set
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_CMD_SPL=y
 # CONFIG_CMD_FLASH is not set
+CONFIG_CMD_NAND=y
 # CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nand0=nand.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=nand.0:256k(NAND.SPL),256k(NAND.SPL.backup1),256k(NAND.SPL.backup2),256k(NAND.SPL.backup3),256k(NAND.u-boot-spl-os),2m(NAND.u-boot),128k(NAND.u-boot-env),128k(NAND.u-boot-env.backup1),8m(NAND.kernel),-(NAND.file-system)"
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="dra7-evm"
@@ -66,6 +69,8 @@ CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
 CONFIG_SPL_MMC_HS200_SUPPORT=y
 CONFIG_MMC_OMAP_HS=y
+CONFIG_NAND=y
+CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SF_DEFAULT_MODE=0
index d8541542448986c88e7a3000403e89efab3941a1..60329c71e47b223ee6336753d22b059c25aa7014 100644 (file)
@@ -32,7 +32,10 @@ CONFIG_SPL_DMA_SUPPORT=y
 # CONFIG_SPL_NAND_SUPPORT is not set
 CONFIG_SPL_SPI_LOAD=y
 # CONFIG_CMD_FLASH is not set
-# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_NAND=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nand0=nand.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=nand.0:256k(NAND.SPL),256k(NAND.SPL.backup1),256k(NAND.SPL.backup2),256k(NAND.SPL.backup3),256k(NAND.u-boot-spl-os),2m(NAND.u-boot),128k(NAND.u-boot-env),128k(NAND.u-boot-env.backup1),8m(NAND.kernel),-(NAND.file-system)"
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="dra7-evm"
@@ -70,6 +73,8 @@ CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_HS200_SUPPORT=y
 CONFIG_SPL_MMC_HS200_SUPPORT=y
 CONFIG_MMC_OMAP_HS=y
+CONFIG_NAND=y
+CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
 CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SF_DEFAULT_MODE=0
index 8202848ebf72018dfcc7e4673f63f3a1a283a8b8..eae36f9c0eb39e9a0b92a42a2a50d79d26b9dd55 100644 (file)
@@ -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
index 29d5f98d76cbf73f2e9f9cce4099b000a04701d2..22996e893d6b75cb84ed2512d0cf03037c879be5 100644 (file)
@@ -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
index 62cad538883b57b8ff27a1024e65df9ffbc4dc24..9e936494b2b1c0c0096c57b87eb53e58ed7d1e1a 100644 (file)
@@ -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
index 3df0ca13f04dcfb5aa1f3c0e7dc86b5b35fb6a56..19e8d792556c471e30ebe11b2d6f0ce3bbfb938e 100644 (file)
@@ -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
index c04bf0ea57429a7907e704948116927f12c57690..568b74fd830601ede429e5d69fd0967c8d21be1b 100644 (file)
@@ -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
index 9998e48ab9c26e71ffc8a9f93cd48e79133fbead..8ae7e20bafd9620199a62bf1fca92048e3e1437e 100644 (file)
@@ -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
index 6123daded330ed3343a5fdd6e6b319da8f3151b5..fb006dcda96c3a6fb98c63f8ba047194e137ea26 100644 (file)
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_KEYSTONE=y
+CONFIG_ISW_ENTRY_ADDR=0xC100000
 CONFIG_SYS_TEXT_BASE=0xC000000
 CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
index 11c9fda985df040705eb7f8512dbdec58b8f9c91..449e66452ea6c12e18ca7ebd4196bac2dc95ef39 100644 (file)
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_KEYSTONE=y
+CONFIG_ISW_ENTRY_ADDR=0xC100000
 CONFIG_TI_SECURE_DEVICE=y
 CONFIG_SYS_TEXT_BASE=0xC000060
 CONFIG_TI_COMMON_CMD_OPTIONS=y
index 4ff9c138c0296851e5a15a42b472da026a631f93..38db43e1c03b735b4f34c1bcef1a0c47f27479d6 100644 (file)
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_KEYSTONE=y
+CONFIG_ISW_ENTRY_ADDR=0xC0A0000
 CONFIG_SYS_TEXT_BASE=0xC000000
 CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
@@ -72,3 +73,4 @@ CONFIG_USB_DWC3_GENERIC=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_USB_FUNCTION_SDP=y
+CONFIG_PHY_TI=y
index 990c7f6317e1ee98b6f5bddd5ca852989d73f185..9c7e3ca3ec009d73391949535699cecf52d9b165 100644 (file)
@@ -1,6 +1,7 @@
 CONFIG_ARM=y
 CONFIG_ARCH_KEYSTONE=y
 CONFIG_TI_SECURE_DEVICE=y
+CONFIG_ISW_ENTRY_ADDR=0xC0A0000
 CONFIG_SYS_TEXT_BASE=0xC000060
 CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_TARGET_K2G_EVM=y
index 6835874384215cea4c26eab3c389935293174337..39aa9336f40f1d68f201811c80735a96efab109f 100644 (file)
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_KEYSTONE=y
+CONFIG_ISW_ENTRY_ADDR=0xC200000
 CONFIG_SYS_TEXT_BASE=0xC000000
 CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
index e14f901fb77452e4d48a5a9dccf14fc57a0f4be9..94bc70a82d22960af144470b36f439d817f74e49 100644 (file)
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_KEYSTONE=y
+CONFIG_ISW_ENTRY_ADDR=0xC200000
 CONFIG_TI_SECURE_DEVICE=y
 CONFIG_SYS_TEXT_BASE=0xC000060
 CONFIG_TI_COMMON_CMD_OPTIONS=y
index 0e2f73acd97a410f230cf70204e3f7457133a06a..c37a0ce5194e36d724ea4808b1f5fc13119a5b43 100644 (file)
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_KEYSTONE=y
+CONFIG_ISW_ENTRY_ADDR=0xC100000
 CONFIG_SYS_TEXT_BASE=0xC000000
 CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
index 1f7a93e5a95b718de921bf180929366738a426ea..443758cab576d598d9aa87bb6e1c3c2572b6de33 100644 (file)
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_KEYSTONE=y
+CONFIG_ISW_ENTRY_ADDR=0xC100000
 CONFIG_TI_SECURE_DEVICE=y
 CONFIG_SYS_TEXT_BASE=0xC000060
 CONFIG_TI_COMMON_CMD_OPTIONS=y
index 8f3144895c6d3ee317f99fccd82958a22a67b84f..3bccd6042910153a2aa548a4a24f6e38e38a7b83 100644 (file)
@@ -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
index e5e0f593a7db2304184942f55932e6b403a7c2ef..c00ab01fdda47ff659d15332602649faf3daf802 100644 (file)
@@ -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
index e4a93bde481fda817845d7befb79a5ae57182cf6..5843f34325b50698e8d679d86fa19ecede211a90 100644 (file)
@@ -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
index 2d3ab7e35c3ca0cdabf821e13d141842f8034164..649db0f67d01075aac9067290a910480c6af2017 100644 (file)
@@ -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
index ad34aaf640c41b157e684e7b1c4b5d61b6d8d80d..41aa900e562f142b50641a64d56f169fb2689a33 100644 (file)
@@ -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
index 16d9c9226f020ed5339fb9b3f9d057c3f8d3cf73..c550798bcd4a9e609376ffdad7ca3da32024b0ee 100644 (file)
@@ -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
index b6eba4a4ba12490b0c2029bc44a58717bf292b08..efcce455a4871495a5b9c3af17fb202d198ac42b 100644 (file)
@@ -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
index 9276df22a5a52f93eea6336d7c077eb8b7a3e48d..d6e4bd4f9ac1c5177a831f78c81c38f3571ebe3b 100644 (file)
@@ -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)"
@@ -62,3 +65,4 @@ CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
 CONFIG_LZMA=y
+CONFIG_MSCC_JR2_SWITCH=y
index a450f48018957ca8f6563462eab5057d1080f698..924cf6ad013fe6051b31e348140a329f6e7060ec 100644 (file)
@@ -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)"
@@ -55,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
index b3a7870ea9a643f88036dd54efef090657b3feb7..af7fa0b20b2cfd491424c2a4d78d55acc9238b97 100644 (file)
@@ -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
index b83cdf2e1ccdd1ba27ca00eee07fe78727c38f4f..84e152546b67b4da40f02170c3bc0045e2d6470c 100644 (file)
@@ -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
index 9de893adfaf9a84504409100d23eda163aed1d7c..2d44135bbc73bb2d11fcf2784eaeda76c2938327 100644 (file)
@@ -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
index 33f9c0746c16bb8a4979d78e00c7c58535b6b64a..bd099c8d671791ff5db2ef47477f833b3071ab8d 100644 (file)
@@ -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
index 40f5bd176e59fbe2eb38a344fc0d93eeaf0c5155..074b172061faacbd3580024fbb0485dd8d117dc2 100644 (file)
@@ -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
index 88c76a55e53f489731f91b8da7160a5e27f053aa..11cb8f61b03d4ef4f60d33de4fe95fb25defdd7b 100644 (file)
@@ -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
index 6bd308bb826431252b3b33aeeb650ae626ff2e9e..a244b8d69168ff76dd63ef7fdfc73451d8f43357 100644 (file)
@@ -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 (file)
index 0000000..34fe6f5
--- /dev/null
@@ -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
index ab6566e49a8bc5afa6641e50ea6767ac2e2808fd..ce3cc8352cfc0b72fe773d8906e544c96790d2da 100644 (file)
@@ -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
index 1092a852503a9cdad69ff306e7609a8ecf541ea6..490f5a3aae4d14d15c2be5ede072f2d3b5a344ea 100644 (file)
@@ -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
index 404fdd91197b4b94819478d2201eec3503a81de9..949fc5d40f7760942855477be685691bc838fc6c 100644 (file)
@@ -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
index ad837382c8e835ad0084c9fc0159bd89b78a8efe..a5bac5b2926f7bea9df225d7415ec37008a656e6 100644 (file)
@@ -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
index de11df755e4ee6dcd5b1595f2c93a54fa8b19cea..79d623719e30d1b336d00b6a37e7b3da8969cd3a 100644 (file)
@@ -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
index ce26cfaf9b558977b4db686a1b920efe69e49869..31e9bcf0b3f1cfa4979fcc041501c229a790f131 100644 (file)
@@ -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
index b0813e4e10b0882cc898c4052479e6cfcbae3acb..f31fd28a4f67882913f92123a341e262d394e964 100644 (file)
@@ -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
index 05023737a956de392de1407c15c0e1661fea05ad..8a9ea272c3c1e3888a1358d5423a923bfb1e6833 100644 (file)
@@ -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"
index 20ae6df5a0d41e7beabde72643c3cf404726e54c..0d64eebc099d57931f267fa9e2f525294da528a1 100644 (file)
@@ -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
index 05c3b08b766e911f5801383813b931802c7dacc8..6492d8580c16af23db136838a08b5f4bdc9113d9 100644 (file)
@@ -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
index 44fc18b7b1ed8a1bac8797975748a9e5e741f6ff..b881a84831790c740900f540628bf7e45a43acca 100644 (file)
@@ -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
index e62b3cb15041cfdf0f97b10c2e1980d18f4523ee..ab0d12e750a306a621c59188e7ae3a696854ba37 100644 (file)
@@ -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
index cc8b8c7f9ab9d89f05438f204f004b4932aba9ed..37ca6dff374f008273c160027affe1b95e8e5d0e 100644 (file)
@@ -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
index fd3cdeec8585b1347973d37330b187dbadfbfc51..a8331377872696174fc9207ad4da3b99a960a70a 100644 (file)
@@ -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
index da4bdced3105445f3caba065ae8e6e61a9996b93..c04ecd915ae70c57deff3fa7563f0c3f36331f48 100644 (file)
@@ -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
index 193e41896cb7aee5b00634ba3b7dcc86025554c9..bb508a8d02e25ebc55a419ef2f6a6e705edbe4fb 100644 (file)
@@ -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
index 04b00cdea9d4643eb5968a6b023c6c839a7b2826..ec527fceb6f579e3a30cf2e6dfc3996b38266ccf 100644 (file)
@@ -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
index d20b2ab350841910ff4279e9a3f1eb13c9ee5f9e..6781adb81e738a3f46e232eea9ceabca98b7df80 100644 (file)
@@ -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 (file)
index 0000000..a050cee
--- /dev/null
@@ -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
index fb9307aaf58014f2b7f0fd5ea34c60ecaa654132..3736aec537dbd13324b2c466b8b3c02f802659f6 100644 (file)
@@ -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
index c406b257533e4bae66497cb39b0ef53823967aa8..85f214148a8ebcd2e4214e1474964621212ecf80 100644 (file)
@@ -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
index cd18e9eb454b61539ad17d6f318a8484c32058ec..c893c44452b185153dc8854494c32754d780bc93 100644 (file)
@@ -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
index 45eaeced2dac049a76dae77bced3cca5c494cd19..096bc4f1f7f0f16a9cb4bdae9bb716bfb4efb4f7 100644 (file)
-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 (file)
index 0000000..45eaece
--- /dev/null
@@ -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.
index de818d4713f0c6f77f6a63ed0eb315ec5e66e746..9698e4899b54c8135a863e78ef1cdca74a2bb9b5 100644 (file)
@@ -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 (file)
index 0000000..70e76be
--- /dev/null
@@ -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>;
+               };
+       };
index 9cf180779c87832c3de678a5cd8c3accab080671..f989792e8d3ff85cb59edd4e815f5a6925cdf373 100644 (file)
@@ -26,7 +26,6 @@ alias iwamatsu       Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
 alias jaehoon        Jaehoon Chung <jh80.chung@samsung.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
index f24351ac4f1d2d5e72a9dbfad86f15aa7eb608ec..e6702eced46c26acf411dfc7ab39dee9d1bba262 100644 (file)
@@ -98,6 +98,8 @@ source "drivers/smem/Kconfig"
 
 source "drivers/sound/Kconfig"
 
+source "drivers/soc/Kconfig"
+
 source "drivers/spi/Kconfig"
 
 source "drivers/spmi/Kconfig"
index 49a056e9416a55333004d03c6e5d27ea63261267..7ebee75c0a5ba82c4befa854f6d8488c148ce70e 100644 (file)
@@ -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.
index 6e3f17ee276d9c19c69c3058205c2a2c20a02a4a..48a9d00d1479c174d8dd97fb42f38ade24b3a743 100644 (file)
@@ -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" },
        { }
index a168196fd4d2868f71986472e3cfec770da3df51..2a630d46c142f97da1c3a8ff4f5c3a62512cf5ba 100644 (file)
@@ -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>
  */
 
 /*
  */
 
 #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>
 #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,
+};
index 612a1718dcb5c9667a598ff2332b2b5f479e7585..179869df45f7b1407633361af964de8999f520ab 100644 (file)
@@ -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,
index 7cfbabc96d3482d46f1217bfda51dd601d1981f4..6b55ec59d6dfdd6456e26ddb3cd38ef8d6d8f861 100644 (file)
@@ -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
index aebc6f0a34c400ceef4fecf8d9636e3fc18c4e63..24859fd054eec8812726eed3a98472fef97d9a1d 100644 (file)
 #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
 
index 0e584c12dc88323d60273780f48b7fc83521d1d1..785f5c3acf7a7bb06a7986fdcdac699c71eca33f 100644 (file)
@@ -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)
index afac6d6e37ee3247ca59f7e23edf6e85673b9276..5bb38e329cb847c3201e5a5c0f925f3a99856364 100644 (file)
@@ -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;
 }
index 27a68487034e182331ece2ed2244ebf685bd5a79..96e47dc70709d473c134b4dc6427bc98035ff427 100644 (file)
@@ -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
 }
index db5c41967393a261ce2d02455e1fd127a8f82269..d779e564189a68a5ef49ec4cf005aa690843b6d8 100644 (file)
 #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 */
index 1820676d7a18d089571c7c4f38fc1b996604e82c..4f37ba7d35eb9776f7a8aff341693e40eff432bd 100644 (file)
@@ -57,4 +57,6 @@ config APBH_DMA_BURST8
 
 endif
 
+source "drivers/dma/ti/Kconfig"
+
 endmenu # menu "DMA Support"
index b5f9147e0a54a0868f4ab639c4495a5c02885ff1..afab324461b906c560e139b8e811bacc8ca70cd3 100644 (file)
@@ -13,3 +13,5 @@ obj-$(CONFIG_SANDBOX_DMA) += sandbox-dma-test.o
 obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o
 obj-$(CONFIG_TI_EDMA3) += ti-edma3.o
 obj-$(CONFIG_DMA_LPC32XX) += lpc32xx_dma.o
+
+obj-y += ti/
index 1d3c192cfe5bb983bcd49168d3f1b558c20bac5f..e7bd1b2350f48f4bb83581edb768c5a75d6b2d81 100644 (file)
@@ -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/dma/ti/Kconfig b/drivers/dma/ti/Kconfig
new file mode 100644 (file)
index 0000000..3d54983
--- /dev/null
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+if ARCH_K3
+
+config TI_K3_NAVSS_UDMA
+        bool "Texas Instruments UDMA"
+        depends on ARCH_K3
+        select DMA
+        select TI_K3_NAVSS_RINGACC
+        select TI_K3_NAVSS_PSILCFG
+        default n
+        help
+          Support for UDMA used in K3 devices.
+endif
diff --git a/drivers/dma/ti/Makefile b/drivers/dma/ti/Makefile
new file mode 100644 (file)
index 0000000..de2f9ac
--- /dev/null
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-$(CONFIG_TI_K3_NAVSS_UDMA) += k3-udma.o
diff --git a/drivers/dma/ti/k3-udma-hwdef.h b/drivers/dma/ti/k3-udma-hwdef.h
new file mode 100644 (file)
index 0000000..c88399a
--- /dev/null
@@ -0,0 +1,184 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ *  Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
+ *
+ *
+ * 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.
+ *
+ */
+
+#ifndef K3_NAVSS_UDMA_HWDEF_H_
+#define K3_NAVSS_UDMA_HWDEF_H_
+
+#define UDMA_PSIL_DST_THREAD_ID_OFFSET 0x8000
+
+/* Global registers */
+#define UDMA_REV_REG                   0x0
+#define UDMA_PERF_CTL_REG              0x4
+#define UDMA_EMU_CTL_REG               0x8
+#define UDMA_PSIL_TO_REG               0x10
+#define UDMA_UTC_CTL_REG               0x1c
+#define UDMA_CAP_REG(i)                        (0x20 + (i * 4))
+#define UDMA_RX_FLOW_ID_FW_OES_REG     0x80
+#define UDMA_RX_FLOW_ID_FW_STATUS_REG  0x88
+
+/* RX Flow regs */
+#define UDMA_RFLOW_RFA_REG             0x0
+#define UDMA_RFLOW_RFB_REG             0x4
+#define UDMA_RFLOW_RFC_REG             0x8
+#define UDMA_RFLOW_RFD_REG             0xc
+#define UDMA_RFLOW_RFE_REG             0x10
+#define UDMA_RFLOW_RFF_REG             0x14
+#define UDMA_RFLOW_RFG_REG             0x18
+#define UDMA_RFLOW_RFH_REG             0x1c
+
+#define UDMA_RFLOW_REG(x) (UDMA_RFLOW_RF##x##_REG)
+
+/* TX chan regs */
+#define UDMA_TCHAN_TCFG_REG            0x0
+#define UDMA_TCHAN_TCREDIT_REG         0x4
+#define UDMA_TCHAN_TCQ_REG             0x14
+#define UDMA_TCHAN_TOES_REG(i)         (0x20 + (i) * 4)
+#define UDMA_TCHAN_TEOES_REG           0x60
+#define UDMA_TCHAN_TPRI_CTRL_REG       0x64
+#define UDMA_TCHAN_THREAD_ID_REG       0x68
+#define UDMA_TCHAN_TFIFO_DEPTH_REG     0x70
+#define UDMA_TCHAN_TST_SCHED_REG       0x80
+
+/* RX chan regs */
+#define UDMA_RCHAN_RCFG_REG            0x0
+#define UDMA_RCHAN_RCQ_REG             0x14
+#define UDMA_RCHAN_ROES_REG(i)         (0x20 + (i) * 4)
+#define UDMA_RCHAN_REOES_REG           0x60
+#define UDMA_RCHAN_RPRI_CTRL_REG       0x64
+#define UDMA_RCHAN_THREAD_ID_REG       0x68
+#define UDMA_RCHAN_RST_SCHED_REG       0x80
+#define UDMA_RCHAN_RFLOW_RNG_REG       0xf0
+
+/* TX chan RT regs */
+#define UDMA_TCHAN_RT_CTL_REG          0x0
+#define UDMA_TCHAN_RT_SWTRIG_REG       0x8
+#define UDMA_TCHAN_RT_STDATA_REG       0x80
+
+#define UDMA_TCHAN_RT_PEERn_REG(i)     (0x200 + (i * 0x4))
+#define UDMA_TCHAN_RT_PEER_STATIC_TR_XY_REG    \
+       UDMA_TCHAN_RT_PEERn_REG(0)      /* PSI-L: 0x400 */
+#define UDMA_TCHAN_RT_PEER_STATIC_TR_Z_REG     \
+       UDMA_TCHAN_RT_PEERn_REG(1)      /* PSI-L: 0x401 */
+#define UDMA_TCHAN_RT_PEER_BCNT_REG            \
+       UDMA_TCHAN_RT_PEERn_REG(4)      /* PSI-L: 0x404 */
+#define UDMA_TCHAN_RT_PEER_RT_EN_REG           \
+       UDMA_TCHAN_RT_PEERn_REG(8)      /* PSI-L: 0x408 */
+
+#define UDMA_TCHAN_RT_PCNT_REG         0x400
+#define UDMA_TCHAN_RT_BCNT_REG         0x408
+#define UDMA_TCHAN_RT_SBCNT_REG                0x410
+
+/* RX chan RT regs */
+#define UDMA_RCHAN_RT_CTL_REG          0x0
+#define UDMA_RCHAN_RT_SWTRIG_REG       0x8
+#define UDMA_RCHAN_RT_STDATA_REG       0x80
+
+#define UDMA_RCHAN_RT_PEERn_REG(i)     (0x200 + (i * 0x4))
+#define UDMA_RCHAN_RT_PEER_STATIC_TR_XY_REG    \
+       UDMA_RCHAN_RT_PEERn_REG(0)      /* PSI-L: 0x400 */
+#define UDMA_RCHAN_RT_PEER_STATIC_TR_Z_REG     \
+       UDMA_RCHAN_RT_PEERn_REG(1)      /* PSI-L: 0x401 */
+#define UDMA_RCHAN_RT_PEER_BCNT_REG            \
+       UDMA_RCHAN_RT_PEERn_REG(4)      /* PSI-L: 0x404 */
+#define UDMA_RCHAN_RT_PEER_RT_EN_REG           \
+       UDMA_RCHAN_RT_PEERn_REG(8)      /* PSI-L: 0x408 */
+
+#define UDMA_RCHAN_RT_PCNT_REG         0x400
+#define UDMA_RCHAN_RT_BCNT_REG         0x408
+#define UDMA_RCHAN_RT_SBCNT_REG                0x410
+
+/* UDMA_TCHAN_TCFG_REG/UDMA_RCHAN_RCFG_REG */
+#define UDMA_CHAN_CFG_PAUSE_ON_ERR             BIT(31)
+#define UDMA_TCHAN_CFG_FILT_EINFO              BIT(30)
+#define UDMA_TCHAN_CFG_FILT_PSWORDS            BIT(29)
+#define UDMA_CHAN_CFG_ATYPE_MASK               GENMASK(25, 24)
+#define UDMA_CHAN_CFG_ATYPE_SHIFT              24
+#define UDMA_CHAN_CFG_CHAN_TYPE_MASK           GENMASK(19, 16)
+#define UDMA_CHAN_CFG_CHAN_TYPE_SHIFT          16
+/*
+ * PBVR - using pass by value rings
+ * PBRR - using pass by reference rings
+ * 3RDP - Third Party DMA
+ * BC - Block Copy
+ * SB - single buffer packet mode enabled
+ */
+#define UDMA_CHAN_CFG_CHAN_TYPE_PACKET_PBRR \
+       (2 << UDMA_CHAN_CFG_CHAN_TYPE_SHIFT)
+#define UDMA_CHAN_CFG_CHAN_TYPE_PACKET_SB_PBRR \
+       (3 << UDMA_CHAN_CFG_CHAN_TYPE_SHIFT)
+#define UDMA_CHAN_CFG_CHAN_TYPE_3RDP_PBRR \
+       (10 << UDMA_CHAN_CFG_CHAN_TYPE_SHIFT)
+#define UDMA_CHAN_CFG_CHAN_TYPE_3RDP_PBVR \
+       (11 << UDMA_CHAN_CFG_CHAN_TYPE_SHIFT)
+#define UDMA_CHAN_CFG_CHAN_TYPE_3RDP_BC_PBRR \
+       (12 << UDMA_CHAN_CFG_CHAN_TYPE_SHIFT)
+#define UDMA_RCHAN_CFG_IGNORE_SHORT            BIT(15)
+#define UDMA_RCHAN_CFG_IGNORE_LONG             BIT(14)
+#define UDMA_TCHAN_CFG_SUPR_TDPKT              BIT(8)
+#define UDMA_CHAN_CFG_FETCH_SIZE_MASK          GENMASK(6, 0)
+#define UDMA_CHAN_CFG_FETCH_SIZE_SHIFT         0
+
+/* UDMA_TCHAN_RT_CTL_REG/UDMA_RCHAN_RT_CTL_REG */
+#define UDMA_CHAN_RT_CTL_EN    BIT(31)
+#define UDMA_CHAN_RT_CTL_TDOWN BIT(30)
+#define UDMA_CHAN_RT_CTL_PAUSE BIT(29)
+#define UDMA_CHAN_RT_CTL_FTDOWN        BIT(28)
+#define UDMA_CHAN_RT_CTL_ERROR BIT(0)
+
+/* UDMA_TCHAN_RT_PEER_RT_EN_REG/UDMA_RCHAN_RT_PEER_RT_EN_REG (PSI-L: 0x408) */
+#define UDMA_PEER_RT_EN_ENABLE         BIT(31)
+#define UDMA_PEER_RT_EN_TEARDOWN       BIT(30)
+#define UDMA_PEER_RT_EN_PAUSE          BIT(29)
+#define UDMA_PEER_RT_EN_FLUSH          BIT(28)
+#define UDMA_PEER_RT_EN_IDLE           BIT(1)
+
+/* RX Flow reg RFA */
+#define UDMA_RFLOW_RFA_EINFO                   BIT(30)
+#define UDMA_RFLOW_RFA_PSINFO                  BIT(29)
+#define UDMA_RFLOW_RFA_ERR_HANDLING            BIT(28)
+#define UDMA_RFLOW_RFA_DESC_TYPE_MASK          GENMASK(27, 26)
+#define UDMA_RFLOW_RFA_DESC_TYPE_SHIFT         26
+#define UDMA_RFLOW_RFA_PS_LOC                  BIT(25)
+#define UDMA_RFLOW_RFA_SOP_OFF_MASK            GENMASK(24, 16)
+#define UDMA_RFLOW_RFA_SOP_OFF_SHIFT           16
+#define UDMA_RFLOW_RFA_DEST_QNUM_MASK          GENMASK(15, 0)
+#define UDMA_RFLOW_RFA_DEST_QNUM_SHIFT         0
+
+/* RX Flow reg RFC */
+#define UDMA_RFLOW_RFC_SRC_TAG_HI_SEL_SHIFT    28
+#define UDMA_RFLOW_RFC_SRC_TAG_LO_SEL_SHIFT    24
+#define UDMA_RFLOW_RFC_DST_TAG_HI_SEL_SHIFT    20
+#define UDMA_RFLOW_RFC_DST_TAG_LO_SE_SHIFT     16
+
+/*
+ * UDMA_TCHAN_RT_PEER_STATIC_TR_XY_REG /
+ * UDMA_RCHAN_RT_PEER_STATIC_TR_XY_REG
+ */
+#define PDMA_STATIC_TR_X_MASK          GENMASK(26, 24)
+#define PDMA_STATIC_TR_X_SHIFT         (24)
+#define PDMA_STATIC_TR_Y_MASK          GENMASK(11, 0)
+#define PDMA_STATIC_TR_Y_SHIFT         (0)
+
+#define PDMA_STATIC_TR_Y(x)    \
+       (((x) << PDMA_STATIC_TR_Y_SHIFT) & PDMA_STATIC_TR_Y_MASK)
+#define PDMA_STATIC_TR_X(x)    \
+       (((x) << PDMA_STATIC_TR_X_SHIFT) & PDMA_STATIC_TR_X_MASK)
+
+/*
+ * UDMA_TCHAN_RT_PEER_STATIC_TR_Z_REG /
+ * UDMA_RCHAN_RT_PEER_STATIC_TR_Z_REG
+ */
+#define PDMA_STATIC_TR_Z_MASK          GENMASK(11, 0)
+#define PDMA_STATIC_TR_Z_SHIFT         (0)
+#define PDMA_STATIC_TR_Z(x)    \
+       (((x) << PDMA_STATIC_TR_Z_SHIFT) & PDMA_STATIC_TR_Z_MASK)
+
+#endif /* K3_NAVSS_UDMA_HWDEF_H_ */
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
new file mode 100644 (file)
index 0000000..f78a01a
--- /dev/null
@@ -0,0 +1,1730 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
+ *  Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ */
+#define pr_fmt(fmt) "udma: " fmt
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <malloc.h>
+#include <asm/dma-mapping.h>
+#include <dm.h>
+#include <dm/read.h>
+#include <dm/of_access.h>
+#include <dma.h>
+#include <dma-uclass.h>
+#include <linux/delay.h>
+#include <dt-bindings/dma/k3-udma.h>
+#include <linux/soc/ti/k3-navss-ringacc.h>
+#include <linux/soc/ti/cppi5.h>
+#include <linux/soc/ti/ti-udma.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+
+#include "k3-udma-hwdef.h"
+
+#if BITS_PER_LONG == 64
+#define RINGACC_RING_USE_PROXY (0)
+#else
+#define RINGACC_RING_USE_PROXY (1)
+#endif
+
+struct udma_chan;
+
+enum udma_mmr {
+       MMR_GCFG = 0,
+       MMR_RCHANRT,
+       MMR_TCHANRT,
+       MMR_LAST,
+};
+
+static const char * const mmr_names[] = {
+       "gcfg", "rchanrt", "tchanrt"
+};
+
+struct udma_tchan {
+       void __iomem *reg_rt;
+
+       int id;
+       struct k3_nav_ring *t_ring; /* Transmit ring */
+       struct k3_nav_ring *tc_ring; /* Transmit Completion ring */
+};
+
+struct udma_rchan {
+       void __iomem *reg_rt;
+
+       int id;
+       struct k3_nav_ring *fd_ring; /* Free Descriptor ring */
+       struct k3_nav_ring *r_ring; /* Receive ring*/
+};
+
+struct udma_rflow {
+       int id;
+};
+
+struct udma_dev {
+       struct device *dev;
+       void __iomem *mmrs[MMR_LAST];
+
+       struct k3_nav_ringacc *ringacc;
+
+       u32 features;
+
+       int tchan_cnt;
+       int echan_cnt;
+       int rchan_cnt;
+       int rflow_cnt;
+       unsigned long *tchan_map;
+       unsigned long *rchan_map;
+       unsigned long *rflow_map;
+
+       struct udma_tchan *tchans;
+       struct udma_rchan *rchans;
+       struct udma_rflow *rflows;
+
+       struct udma_chan *channels;
+       u32 psil_base;
+
+       u32 ch_count;
+       const struct ti_sci_handle *tisci;
+       const struct ti_sci_rm_udmap_ops *tisci_udmap_ops;
+       const struct ti_sci_rm_psil_ops *tisci_psil_ops;
+       u32  tisci_dev_id;
+       u32  tisci_navss_dev_id;
+       bool is_coherent;
+};
+
+struct udma_chan {
+       struct udma_dev *ud;
+       char name[20];
+
+       struct udma_tchan *tchan;
+       struct udma_rchan *rchan;
+       struct udma_rflow *rflow;
+
+       u32 bcnt; /* number of bytes completed since the start of the channel */
+
+       bool pkt_mode; /* TR or packet */
+       bool needs_epib; /* EPIB is needed for the communication or not */
+       u32 psd_size; /* size of Protocol Specific Data */
+       u32 metadata_size; /* (needs_epib ? 16:0) + psd_size */
+       int slave_thread_id;
+       u32 src_thread;
+       u32 dst_thread;
+       u32 static_tr_type;
+
+       u32 id;
+       enum dma_direction dir;
+
+       struct cppi5_host_desc_t *desc_tx;
+       u32 hdesc_size;
+       bool in_use;
+       void    *desc_rx;
+       u32     num_rx_bufs;
+       u32     desc_rx_cur;
+
+};
+
+#define UDMA_CH_1000(ch)               (ch * 0x1000)
+#define UDMA_CH_100(ch)                        (ch * 0x100)
+#define UDMA_CH_40(ch)                 (ch * 0x40)
+
+#ifdef PKTBUFSRX
+#define UDMA_RX_DESC_NUM PKTBUFSRX
+#else
+#define UDMA_RX_DESC_NUM 4
+#endif
+
+/* Generic register access functions */
+static inline u32 udma_read(void __iomem *base, int reg)
+{
+       u32 v;
+
+       v = __raw_readl(base + reg);
+       pr_debug("READL(32): v(%08X)<--reg(%p)\n", v, base + reg);
+       return v;
+}
+
+static inline void udma_write(void __iomem *base, int reg, u32 val)
+{
+       pr_debug("WRITEL(32): v(%08X)-->reg(%p)\n", val, base + reg);
+       __raw_writel(val, base + reg);
+}
+
+static inline void udma_update_bits(void __iomem *base, int reg,
+                                   u32 mask, u32 val)
+{
+       u32 tmp, orig;
+
+       orig = udma_read(base, reg);
+       tmp = orig & ~mask;
+       tmp |= (val & mask);
+
+       if (tmp != orig)
+               udma_write(base, reg, tmp);
+}
+
+/* TCHANRT */
+static inline u32 udma_tchanrt_read(struct udma_tchan *tchan, int reg)
+{
+       if (!tchan)
+               return 0;
+       return udma_read(tchan->reg_rt, reg);
+}
+
+static inline void udma_tchanrt_write(struct udma_tchan *tchan,
+                                     int reg, u32 val)
+{
+       if (!tchan)
+               return;
+       udma_write(tchan->reg_rt, reg, val);
+}
+
+/* RCHANRT */
+static inline u32 udma_rchanrt_read(struct udma_rchan *rchan, int reg)
+{
+       if (!rchan)
+               return 0;
+       return udma_read(rchan->reg_rt, reg);
+}
+
+static inline void udma_rchanrt_write(struct udma_rchan *rchan,
+                                     int reg, u32 val)
+{
+       if (!rchan)
+               return;
+       udma_write(rchan->reg_rt, reg, val);
+}
+
+static inline int udma_navss_psil_pair(struct udma_dev *ud, u32 src_thread,
+                                      u32 dst_thread)
+{
+       dst_thread |= UDMA_PSIL_DST_THREAD_ID_OFFSET;
+       return ud->tisci_psil_ops->pair(ud->tisci,
+                                       ud->tisci_navss_dev_id,
+                                       src_thread, dst_thread);
+}
+
+static inline int udma_navss_psil_unpair(struct udma_dev *ud, u32 src_thread,
+                                        u32 dst_thread)
+{
+       dst_thread |= UDMA_PSIL_DST_THREAD_ID_OFFSET;
+       return ud->tisci_psil_ops->unpair(ud->tisci,
+                                         ud->tisci_navss_dev_id,
+                                         src_thread, dst_thread);
+}
+
+static inline char *udma_get_dir_text(enum dma_direction dir)
+{
+       switch (dir) {
+       case DMA_DEV_TO_MEM:
+               return "DEV_TO_MEM";
+       case DMA_MEM_TO_DEV:
+               return "MEM_TO_DEV";
+       case DMA_MEM_TO_MEM:
+               return "MEM_TO_MEM";
+       case DMA_DEV_TO_DEV:
+               return "DEV_TO_DEV";
+       default:
+               break;
+       }
+
+       return "invalid";
+}
+
+static inline bool udma_is_chan_running(struct udma_chan *uc)
+{
+       u32 trt_ctl = 0;
+       u32 rrt_ctl = 0;
+
+       switch (uc->dir) {
+       case DMA_DEV_TO_MEM:
+               rrt_ctl = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_CTL_REG);
+               pr_debug("%s: rrt_ctl: 0x%08x (peer: 0x%08x)\n",
+                        __func__, rrt_ctl,
+                        udma_rchanrt_read(uc->rchan,
+                                          UDMA_RCHAN_RT_PEER_RT_EN_REG));
+               break;
+       case DMA_MEM_TO_DEV:
+               trt_ctl = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_CTL_REG);
+               pr_debug("%s: trt_ctl: 0x%08x (peer: 0x%08x)\n",
+                        __func__, trt_ctl,
+                        udma_tchanrt_read(uc->tchan,
+                                          UDMA_TCHAN_RT_PEER_RT_EN_REG));
+               break;
+       case DMA_MEM_TO_MEM:
+               trt_ctl = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_CTL_REG);
+               rrt_ctl = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_CTL_REG);
+               break;
+       default:
+               break;
+       }
+
+       if (trt_ctl & UDMA_CHAN_RT_CTL_EN || rrt_ctl & UDMA_CHAN_RT_CTL_EN)
+               return true;
+
+       return false;
+}
+
+static int udma_is_coherent(struct udma_chan *uc)
+{
+       return uc->ud->is_coherent;
+}
+
+static int udma_pop_from_ring(struct udma_chan *uc, dma_addr_t *addr)
+{
+       struct k3_nav_ring *ring = NULL;
+       int ret = -ENOENT;
+
+       switch (uc->dir) {
+       case DMA_DEV_TO_MEM:
+               ring = uc->rchan->r_ring;
+               break;
+       case DMA_MEM_TO_DEV:
+               ring = uc->tchan->tc_ring;
+               break;
+       case DMA_MEM_TO_MEM:
+               ring = uc->tchan->tc_ring;
+               break;
+       default:
+               break;
+       }
+
+       if (ring && k3_nav_ringacc_ring_get_occ(ring))
+               ret = k3_nav_ringacc_ring_pop(ring, addr);
+
+       return ret;
+}
+
+static void udma_reset_rings(struct udma_chan *uc)
+{
+       struct k3_nav_ring *ring1 = NULL;
+       struct k3_nav_ring *ring2 = NULL;
+
+       switch (uc->dir) {
+       case DMA_DEV_TO_MEM:
+               ring1 = uc->rchan->fd_ring;
+               ring2 = uc->rchan->r_ring;
+               break;
+       case DMA_MEM_TO_DEV:
+               ring1 = uc->tchan->t_ring;
+               ring2 = uc->tchan->tc_ring;
+               break;
+       case DMA_MEM_TO_MEM:
+               ring1 = uc->tchan->t_ring;
+               ring2 = uc->tchan->tc_ring;
+               break;
+       default:
+               break;
+       }
+
+       if (ring1)
+               k3_nav_ringacc_ring_reset_dma(ring1, 0);
+       if (ring2)
+               k3_nav_ringacc_ring_reset(ring2);
+}
+
+static void udma_reset_counters(struct udma_chan *uc)
+{
+       u32 val;
+
+       if (uc->tchan) {
+               val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_BCNT_REG);
+               udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_BCNT_REG, val);
+
+               val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_SBCNT_REG);
+               udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_SBCNT_REG, val);
+
+               val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_PCNT_REG);
+               udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_PCNT_REG, val);
+
+               val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_PEER_BCNT_REG);
+               udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_PEER_BCNT_REG, val);
+       }
+
+       if (uc->rchan) {
+               val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_BCNT_REG);
+               udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_BCNT_REG, val);
+
+               val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_SBCNT_REG);
+               udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_SBCNT_REG, val);
+
+               val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_PCNT_REG);
+               udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_PCNT_REG, val);
+
+               val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_PEER_BCNT_REG);
+               udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_PEER_BCNT_REG, val);
+       }
+
+       uc->bcnt = 0;
+}
+
+static inline int udma_stop_hard(struct udma_chan *uc)
+{
+       pr_debug("%s: ENTER (chan%d)\n", __func__, uc->id);
+
+       switch (uc->dir) {
+       case DMA_DEV_TO_MEM:
+               udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_PEER_RT_EN_REG, 0);
+               udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_CTL_REG, 0);
+               break;
+       case DMA_MEM_TO_DEV:
+               udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_CTL_REG, 0);
+               udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_PEER_RT_EN_REG, 0);
+               break;
+       case DMA_MEM_TO_MEM:
+               udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_CTL_REG, 0);
+               udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_CTL_REG, 0);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int udma_start(struct udma_chan *uc)
+{
+       /* Channel is already running, no need to proceed further */
+       if (udma_is_chan_running(uc))
+               goto out;
+
+       pr_debug("%s: chan:%d dir:%s (static_tr_type: %d)\n",
+                __func__, uc->id, udma_get_dir_text(uc->dir),
+                uc->static_tr_type);
+
+       /* Make sure that we clear the teardown bit, if it is set */
+       udma_stop_hard(uc);
+
+       /* Reset all counters */
+       udma_reset_counters(uc);
+
+       switch (uc->dir) {
+       case DMA_DEV_TO_MEM:
+               udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_CTL_REG,
+                                  UDMA_CHAN_RT_CTL_EN);
+
+               /* Enable remote */
+               udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_PEER_RT_EN_REG,
+                                  UDMA_PEER_RT_EN_ENABLE);
+
+               pr_debug("%s(rx): RT_CTL:0x%08x PEER RT_ENABLE:0x%08x\n",
+                        __func__,
+                        udma_rchanrt_read(uc->rchan,
+                                          UDMA_RCHAN_RT_CTL_REG),
+                        udma_rchanrt_read(uc->rchan,
+                                          UDMA_RCHAN_RT_PEER_RT_EN_REG));
+               break;
+       case DMA_MEM_TO_DEV:
+               /* Enable remote */
+               udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_PEER_RT_EN_REG,
+                                  UDMA_PEER_RT_EN_ENABLE);
+
+               udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_CTL_REG,
+                                  UDMA_CHAN_RT_CTL_EN);
+
+               pr_debug("%s(tx): RT_CTL:0x%08x PEER RT_ENABLE:0x%08x\n",
+                        __func__,
+                        udma_rchanrt_read(uc->rchan,
+                                          UDMA_TCHAN_RT_CTL_REG),
+                        udma_rchanrt_read(uc->rchan,
+                                          UDMA_TCHAN_RT_PEER_RT_EN_REG));
+               break;
+       case DMA_MEM_TO_MEM:
+               udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_CTL_REG,
+                                  UDMA_CHAN_RT_CTL_EN);
+               udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_CTL_REG,
+                                  UDMA_CHAN_RT_CTL_EN);
+
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       pr_debug("%s: DONE chan:%d\n", __func__, uc->id);
+out:
+       return 0;
+}
+
+static inline void udma_stop_mem2dev(struct udma_chan *uc, bool sync)
+{
+       int i = 0;
+       u32 val;
+
+       udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_CTL_REG,
+                          UDMA_CHAN_RT_CTL_EN |
+                          UDMA_CHAN_RT_CTL_TDOWN);
+
+       val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_CTL_REG);
+
+       while (sync && (val & UDMA_CHAN_RT_CTL_EN)) {
+               val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_CTL_REG);
+               udelay(1);
+               if (i > 1000) {
+                       printf(" %s TIMEOUT !\n", __func__);
+                       break;
+               }
+               i++;
+       }
+
+       val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_PEER_RT_EN_REG);
+       if (val & UDMA_PEER_RT_EN_ENABLE)
+               printf("%s: peer not stopped TIMEOUT !\n", __func__);
+}
+
+static inline void udma_stop_dev2mem(struct udma_chan *uc, bool sync)
+{
+       int i = 0;
+       u32 val;
+
+       udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_PEER_RT_EN_REG,
+                          UDMA_PEER_RT_EN_ENABLE |
+                          UDMA_PEER_RT_EN_TEARDOWN);
+
+       val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_CTL_REG);
+
+       while (sync && (val & UDMA_CHAN_RT_CTL_EN)) {
+               val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_CTL_REG);
+               udelay(1);
+               if (i > 1000) {
+                       printf("%s TIMEOUT !\n", __func__);
+                       break;
+               }
+               i++;
+       }
+
+       val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_PEER_RT_EN_REG);
+       if (val & UDMA_PEER_RT_EN_ENABLE)
+               printf("%s: peer not stopped TIMEOUT !\n", __func__);
+}
+
+static inline int udma_stop(struct udma_chan *uc)
+{
+       pr_debug("%s: chan:%d dir:%s\n",
+                __func__, uc->id, udma_get_dir_text(uc->dir));
+
+       udma_reset_counters(uc);
+       switch (uc->dir) {
+       case DMA_DEV_TO_MEM:
+               udma_stop_dev2mem(uc, true);
+               break;
+       case DMA_MEM_TO_DEV:
+               udma_stop_mem2dev(uc, true);
+               break;
+       case DMA_MEM_TO_MEM:
+               udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_CTL_REG, 0);
+               udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_CTL_REG, 0);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static void udma_poll_completion(struct udma_chan *uc, dma_addr_t *paddr)
+{
+       int i = 1;
+
+       while (udma_pop_from_ring(uc, paddr)) {
+               udelay(1);
+               if (!(i % 1000000))
+                       printf(".");
+               i++;
+       }
+}
+
+#define UDMA_RESERVE_RESOURCE(res)                                     \
+static struct udma_##res *__udma_reserve_##res(struct udma_dev *ud,    \
+                                              int id)                  \
+{                                                                      \
+       if (id >= 0) {                                                  \
+               if (test_bit(id, ud->res##_map)) {                      \
+                       dev_err(ud->dev, "res##%d is in use\n", id);    \
+                       return ERR_PTR(-ENOENT);                        \
+               }                                                       \
+       } else {                                                        \
+               id = find_first_zero_bit(ud->res##_map, ud->res##_cnt); \
+               if (id == ud->res##_cnt) {                              \
+                       return ERR_PTR(-ENOENT);                        \
+               }                                                       \
+       }                                                               \
+                                                                       \
+       __set_bit(id, ud->res##_map);                                   \
+       return &ud->res##s[id];                                         \
+}
+
+UDMA_RESERVE_RESOURCE(tchan);
+UDMA_RESERVE_RESOURCE(rchan);
+UDMA_RESERVE_RESOURCE(rflow);
+
+static int udma_get_tchan(struct udma_chan *uc)
+{
+       struct udma_dev *ud = uc->ud;
+
+       if (uc->tchan) {
+               dev_dbg(ud->dev, "chan%d: already have tchan%d allocated\n",
+                       uc->id, uc->tchan->id);
+               return 0;
+       }
+
+       uc->tchan = __udma_reserve_tchan(ud, -1);
+       if (IS_ERR(uc->tchan))
+               return PTR_ERR(uc->tchan);
+
+       pr_debug("chan%d: got tchan%d\n", uc->id, uc->tchan->id);
+
+       if (udma_is_chan_running(uc)) {
+               dev_warn(ud->dev, "chan%d: tchan%d is running!\n", uc->id,
+                        uc->tchan->id);
+               udma_stop(uc);
+               if (udma_is_chan_running(uc))
+                       dev_err(ud->dev, "chan%d: won't stop!\n", uc->id);
+       }
+
+       return 0;
+}
+
+static int udma_get_rchan(struct udma_chan *uc)
+{
+       struct udma_dev *ud = uc->ud;
+
+       if (uc->rchan) {
+               dev_dbg(ud->dev, "chan%d: already have rchan%d allocated\n",
+                       uc->id, uc->rchan->id);
+               return 0;
+       }
+
+       uc->rchan = __udma_reserve_rchan(ud, -1);
+       if (IS_ERR(uc->rchan))
+               return PTR_ERR(uc->rchan);
+
+       pr_debug("chan%d: got rchan%d\n", uc->id, uc->rchan->id);
+
+       if (udma_is_chan_running(uc)) {
+               dev_warn(ud->dev, "chan%d: rchan%d is running!\n", uc->id,
+                        uc->rchan->id);
+               udma_stop(uc);
+               if (udma_is_chan_running(uc))
+                       dev_err(ud->dev, "chan%d: won't stop!\n", uc->id);
+       }
+
+       return 0;
+}
+
+static int udma_get_chan_pair(struct udma_chan *uc)
+{
+       struct udma_dev *ud = uc->ud;
+       int chan_id, end;
+
+       if ((uc->tchan && uc->rchan) && uc->tchan->id == uc->rchan->id) {
+               dev_info(ud->dev, "chan%d: already have %d pair allocated\n",
+                        uc->id, uc->tchan->id);
+               return 0;
+       }
+
+       if (uc->tchan) {
+               dev_err(ud->dev, "chan%d: already have tchan%d allocated\n",
+                       uc->id, uc->tchan->id);
+               return -EBUSY;
+       } else if (uc->rchan) {
+               dev_err(ud->dev, "chan%d: already have rchan%d allocated\n",
+                       uc->id, uc->rchan->id);
+               return -EBUSY;
+       }
+
+       /* Can be optimized, but let's have it like this for now */
+       end = min(ud->tchan_cnt, ud->rchan_cnt);
+       for (chan_id = 0; chan_id < end; chan_id++) {
+               if (!test_bit(chan_id, ud->tchan_map) &&
+                   !test_bit(chan_id, ud->rchan_map))
+                       break;
+       }
+
+       if (chan_id == end)
+               return -ENOENT;
+
+       __set_bit(chan_id, ud->tchan_map);
+       __set_bit(chan_id, ud->rchan_map);
+       uc->tchan = &ud->tchans[chan_id];
+       uc->rchan = &ud->rchans[chan_id];
+
+       pr_debug("chan%d: got t/rchan%d pair\n", uc->id, chan_id);
+
+       if (udma_is_chan_running(uc)) {
+               dev_warn(ud->dev, "chan%d: t/rchan%d pair is running!\n",
+                        uc->id, chan_id);
+               udma_stop(uc);
+               if (udma_is_chan_running(uc))
+                       dev_err(ud->dev, "chan%d: won't stop!\n", uc->id);
+       }
+
+       return 0;
+}
+
+static int udma_get_rflow(struct udma_chan *uc, int flow_id)
+{
+       struct udma_dev *ud = uc->ud;
+
+       if (uc->rflow) {
+               dev_dbg(ud->dev, "chan%d: already have rflow%d allocated\n",
+                       uc->id, uc->rflow->id);
+               return 0;
+       }
+
+       if (!uc->rchan)
+               dev_warn(ud->dev, "chan%d: does not have rchan??\n", uc->id);
+
+       uc->rflow = __udma_reserve_rflow(ud, flow_id);
+       if (IS_ERR(uc->rflow))
+               return PTR_ERR(uc->rflow);
+
+       pr_debug("chan%d: got rflow%d\n", uc->id, uc->rflow->id);
+       return 0;
+}
+
+static void udma_put_rchan(struct udma_chan *uc)
+{
+       struct udma_dev *ud = uc->ud;
+
+       if (uc->rchan) {
+               dev_dbg(ud->dev, "chan%d: put rchan%d\n", uc->id,
+                       uc->rchan->id);
+               __clear_bit(uc->rchan->id, ud->rchan_map);
+               uc->rchan = NULL;
+       }
+}
+
+static void udma_put_tchan(struct udma_chan *uc)
+{
+       struct udma_dev *ud = uc->ud;
+
+       if (uc->tchan) {
+               dev_dbg(ud->dev, "chan%d: put tchan%d\n", uc->id,
+                       uc->tchan->id);
+               __clear_bit(uc->tchan->id, ud->tchan_map);
+               uc->tchan = NULL;
+       }
+}
+
+static void udma_put_rflow(struct udma_chan *uc)
+{
+       struct udma_dev *ud = uc->ud;
+
+       if (uc->rflow) {
+               dev_dbg(ud->dev, "chan%d: put rflow%d\n", uc->id,
+                       uc->rflow->id);
+               __clear_bit(uc->rflow->id, ud->rflow_map);
+               uc->rflow = NULL;
+       }
+}
+
+static void udma_free_tx_resources(struct udma_chan *uc)
+{
+       if (!uc->tchan)
+               return;
+
+       k3_nav_ringacc_ring_free(uc->tchan->t_ring);
+       k3_nav_ringacc_ring_free(uc->tchan->tc_ring);
+       uc->tchan->t_ring = NULL;
+       uc->tchan->tc_ring = NULL;
+
+       udma_put_tchan(uc);
+}
+
+static int udma_alloc_tx_resources(struct udma_chan *uc)
+{
+       struct k3_nav_ring_cfg ring_cfg;
+       struct udma_dev *ud = uc->ud;
+       int ret;
+
+       ret = udma_get_tchan(uc);
+       if (ret)
+               return ret;
+
+       uc->tchan->t_ring = k3_nav_ringacc_request_ring(
+                               ud->ringacc, uc->tchan->id,
+                               RINGACC_RING_USE_PROXY);
+       if (!uc->tchan->t_ring) {
+               ret = -EBUSY;
+               goto err_tx_ring;
+       }
+
+       uc->tchan->tc_ring = k3_nav_ringacc_request_ring(
+                               ud->ringacc, -1, RINGACC_RING_USE_PROXY);
+       if (!uc->tchan->tc_ring) {
+               ret = -EBUSY;
+               goto err_txc_ring;
+       }
+
+       memset(&ring_cfg, 0, sizeof(ring_cfg));
+       ring_cfg.size = 16;
+       ring_cfg.elm_size = K3_NAV_RINGACC_RING_ELSIZE_8;
+       ring_cfg.mode = K3_NAV_RINGACC_RING_MODE_MESSAGE;
+
+       ret = k3_nav_ringacc_ring_cfg(uc->tchan->t_ring, &ring_cfg);
+       ret |= k3_nav_ringacc_ring_cfg(uc->tchan->tc_ring, &ring_cfg);
+
+       if (ret)
+               goto err_ringcfg;
+
+       return 0;
+
+err_ringcfg:
+       k3_nav_ringacc_ring_free(uc->tchan->tc_ring);
+       uc->tchan->tc_ring = NULL;
+err_txc_ring:
+       k3_nav_ringacc_ring_free(uc->tchan->t_ring);
+       uc->tchan->t_ring = NULL;
+err_tx_ring:
+       udma_put_tchan(uc);
+
+       return ret;
+}
+
+static void udma_free_rx_resources(struct udma_chan *uc)
+{
+       if (!uc->rchan)
+               return;
+
+       k3_nav_ringacc_ring_free(uc->rchan->fd_ring);
+       k3_nav_ringacc_ring_free(uc->rchan->r_ring);
+       uc->rchan->fd_ring = NULL;
+       uc->rchan->r_ring = NULL;
+
+       udma_put_rflow(uc);
+       udma_put_rchan(uc);
+}
+
+static int udma_alloc_rx_resources(struct udma_chan *uc)
+{
+       struct k3_nav_ring_cfg ring_cfg;
+       struct udma_dev *ud = uc->ud;
+       int fd_ring_id;
+       int ret;
+
+       ret = udma_get_rchan(uc);
+       if (ret)
+               return ret;
+
+       /* For MEM_TO_MEM we don't need rflow or rings */
+       if (uc->dir == DMA_MEM_TO_MEM)
+               return 0;
+
+       ret = udma_get_rflow(uc, uc->rchan->id);
+       if (ret) {
+               ret = -EBUSY;
+               goto err_rflow;
+       }
+
+       fd_ring_id = ud->tchan_cnt + ud->echan_cnt + uc->rchan->id;
+
+       uc->rchan->fd_ring = k3_nav_ringacc_request_ring(
+                               ud->ringacc, fd_ring_id,
+                               RINGACC_RING_USE_PROXY);
+       if (!uc->rchan->fd_ring) {
+               ret = -EBUSY;
+               goto err_rx_ring;
+       }
+
+       uc->rchan->r_ring = k3_nav_ringacc_request_ring(
+                               ud->ringacc, -1, RINGACC_RING_USE_PROXY);
+       if (!uc->rchan->r_ring) {
+               ret = -EBUSY;
+               goto err_rxc_ring;
+       }
+
+       memset(&ring_cfg, 0, sizeof(ring_cfg));
+       ring_cfg.size = 16;
+       ring_cfg.elm_size = K3_NAV_RINGACC_RING_ELSIZE_8;
+       ring_cfg.mode = K3_NAV_RINGACC_RING_MODE_MESSAGE;
+
+       ret = k3_nav_ringacc_ring_cfg(uc->rchan->fd_ring, &ring_cfg);
+       ret |= k3_nav_ringacc_ring_cfg(uc->rchan->r_ring, &ring_cfg);
+
+       if (ret)
+               goto err_ringcfg;
+
+       return 0;
+
+err_ringcfg:
+       k3_nav_ringacc_ring_free(uc->rchan->r_ring);
+       uc->rchan->r_ring = NULL;
+err_rxc_ring:
+       k3_nav_ringacc_ring_free(uc->rchan->fd_ring);
+       uc->rchan->fd_ring = NULL;
+err_rx_ring:
+       udma_put_rflow(uc);
+err_rflow:
+       udma_put_rchan(uc);
+
+       return ret;
+}
+
+static int udma_alloc_tchan_sci_req(struct udma_chan *uc)
+{
+       struct udma_dev *ud = uc->ud;
+       int tc_ring = k3_nav_ringacc_get_ring_id(uc->tchan->tc_ring);
+       struct ti_sci_msg_rm_udmap_tx_ch_cfg req;
+       u32 mode;
+       int ret;
+
+       if (uc->pkt_mode)
+               mode = TI_SCI_RM_UDMAP_CHAN_TYPE_PKT_PBRR;
+       else
+               mode = TI_SCI_RM_UDMAP_CHAN_TYPE_3RDP_BCOPY_PBRR;
+
+       req.valid_params = TI_SCI_MSG_VALUE_RM_UDMAP_CH_CHAN_TYPE_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_CH_FETCH_SIZE_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_CH_CQ_QNUM_VALID;
+       req.nav_id = ud->tisci_dev_id;
+       req.index = uc->tchan->id;
+       req.tx_chan_type = mode;
+       if (uc->dir == DMA_MEM_TO_MEM)
+               req.tx_fetch_size = sizeof(struct cppi5_desc_hdr_t) >> 2;
+       else
+               req.tx_fetch_size = cppi5_hdesc_calc_size(uc->needs_epib,
+                                                         uc->psd_size,
+                                                         0) >> 2;
+       req.txcq_qnum = tc_ring;
+
+       ret = ud->tisci_udmap_ops->tx_ch_cfg(ud->tisci, &req);
+       if (ret)
+               dev_err(ud->dev, "tisci tx alloc failed %d\n", ret);
+
+       return ret;
+}
+
+static int udma_alloc_rchan_sci_req(struct udma_chan *uc)
+{
+       struct udma_dev *ud = uc->ud;
+       int fd_ring = k3_nav_ringacc_get_ring_id(uc->rchan->fd_ring);
+       int rx_ring = k3_nav_ringacc_get_ring_id(uc->rchan->r_ring);
+       int tc_ring = k3_nav_ringacc_get_ring_id(uc->tchan->tc_ring);
+       struct ti_sci_msg_rm_udmap_rx_ch_cfg req = { 0 };
+       struct ti_sci_msg_rm_udmap_flow_cfg flow_req = { 0 };
+       u32 mode;
+       int ret;
+
+       if (uc->pkt_mode)
+               mode = TI_SCI_RM_UDMAP_CHAN_TYPE_PKT_PBRR;
+       else
+               mode = TI_SCI_RM_UDMAP_CHAN_TYPE_3RDP_BCOPY_PBRR;
+
+       req.valid_params = TI_SCI_MSG_VALUE_RM_UDMAP_CH_FETCH_SIZE_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_CH_CQ_QNUM_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_CH_CHAN_TYPE_VALID;
+       req.nav_id = ud->tisci_dev_id;
+       req.index = uc->rchan->id;
+       req.rx_chan_type = mode;
+       if (uc->dir == DMA_MEM_TO_MEM) {
+               req.rx_fetch_size = sizeof(struct cppi5_desc_hdr_t) >> 2;
+               req.rxcq_qnum = tc_ring;
+       } else {
+               req.rx_fetch_size = cppi5_hdesc_calc_size(uc->needs_epib,
+                                                         uc->psd_size,
+                                                         0) >> 2;
+               req.rxcq_qnum = rx_ring;
+       }
+       if (uc->rflow->id != uc->rchan->id && uc->dir != DMA_MEM_TO_MEM) {
+               req.flowid_start = uc->rflow->id;
+               req.flowid_cnt = 1;
+               req.valid_params |=
+                       TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_START_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_CNT_VALID;
+       }
+
+       ret = ud->tisci_udmap_ops->rx_ch_cfg(ud->tisci, &req);
+       if (ret) {
+               dev_err(ud->dev, "tisci rx %u cfg failed %d\n",
+                       uc->rchan->id, ret);
+               return ret;
+       }
+       if (uc->dir == DMA_MEM_TO_MEM)
+               return ret;
+
+       flow_req.valid_params =
+                       TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_EINFO_PRESENT_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_PSINFO_PRESENT_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_ERROR_HANDLING_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_DESC_TYPE_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_DEST_QNUM_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_SRC_TAG_HI_SEL_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_SRC_TAG_LO_SEL_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_DEST_TAG_HI_SEL_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_DEST_TAG_LO_SEL_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_FDQ0_SZ0_QNUM_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_FDQ1_QNUM_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_FDQ2_QNUM_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_FDQ3_QNUM_VALID |
+                       TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_PS_LOCATION_VALID;
+
+       flow_req.nav_id = ud->tisci_dev_id;
+       flow_req.flow_index = uc->rflow->id;
+
+       if (uc->needs_epib)
+               flow_req.rx_einfo_present = 1;
+       else
+               flow_req.rx_einfo_present = 0;
+
+       if (uc->psd_size)
+               flow_req.rx_psinfo_present = 1;
+       else
+               flow_req.rx_psinfo_present = 0;
+
+       flow_req.rx_error_handling = 0;
+       flow_req.rx_desc_type = 0;
+       flow_req.rx_dest_qnum = rx_ring;
+       flow_req.rx_src_tag_hi_sel = 2;
+       flow_req.rx_src_tag_lo_sel = 4;
+       flow_req.rx_dest_tag_hi_sel = 5;
+       flow_req.rx_dest_tag_lo_sel = 4;
+       flow_req.rx_fdq0_sz0_qnum = fd_ring;
+       flow_req.rx_fdq1_qnum = fd_ring;
+       flow_req.rx_fdq2_qnum = fd_ring;
+       flow_req.rx_fdq3_qnum = fd_ring;
+       flow_req.rx_ps_location = 0;
+
+       ret = ud->tisci_udmap_ops->rx_flow_cfg(ud->tisci, &flow_req);
+       if (ret)
+               dev_err(ud->dev, "tisci rx %u flow %u cfg failed %d\n",
+                       uc->rchan->id, uc->rflow->id, ret);
+
+       return ret;
+}
+
+static int udma_alloc_chan_resources(struct udma_chan *uc)
+{
+       struct udma_dev *ud = uc->ud;
+       int ret;
+
+       pr_debug("%s: chan:%d as %s\n",
+                __func__, uc->id, udma_get_dir_text(uc->dir));
+
+       switch (uc->dir) {
+       case DMA_MEM_TO_MEM:
+               /* Non synchronized - mem to mem type of transfer */
+               ret = udma_get_chan_pair(uc);
+               if (ret)
+                       return ret;
+
+               ret = udma_alloc_tx_resources(uc);
+               if (ret)
+                       goto err_free_res;
+
+               ret = udma_alloc_rx_resources(uc);
+               if (ret)
+                       goto err_free_res;
+
+               uc->src_thread = ud->psil_base + uc->tchan->id;
+               uc->dst_thread = (ud->psil_base + uc->rchan->id) | 0x8000;
+               break;
+       case DMA_MEM_TO_DEV:
+               /* Slave transfer synchronized - mem to dev (TX) trasnfer */
+               ret = udma_alloc_tx_resources(uc);
+               if (ret)
+                       goto err_free_res;
+
+               uc->src_thread = ud->psil_base + uc->tchan->id;
+               uc->dst_thread = uc->slave_thread_id;
+               if (!(uc->dst_thread & 0x8000))
+                       uc->dst_thread |= 0x8000;
+
+               break;
+       case DMA_DEV_TO_MEM:
+               /* Slave transfer synchronized - dev to mem (RX) trasnfer */
+               ret = udma_alloc_rx_resources(uc);
+               if (ret)
+                       goto err_free_res;
+
+               uc->src_thread = uc->slave_thread_id;
+               uc->dst_thread = (ud->psil_base + uc->rchan->id) | 0x8000;
+
+               break;
+       default:
+               /* Can not happen */
+               pr_debug("%s: chan:%d invalid direction (%u)\n",
+                        __func__, uc->id, uc->dir);
+               return -EINVAL;
+       }
+
+       /* We have channel indexes and rings */
+       if (uc->dir == DMA_MEM_TO_MEM) {
+               ret = udma_alloc_tchan_sci_req(uc);
+               if (ret)
+                       goto err_free_res;
+
+               ret = udma_alloc_rchan_sci_req(uc);
+               if (ret)
+                       goto err_free_res;
+       } else {
+               /* Slave transfer */
+               if (uc->dir == DMA_MEM_TO_DEV) {
+                       ret = udma_alloc_tchan_sci_req(uc);
+                       if (ret)
+                               goto err_free_res;
+               } else {
+                       ret = udma_alloc_rchan_sci_req(uc);
+                       if (ret)
+                               goto err_free_res;
+               }
+       }
+
+       /* PSI-L pairing */
+       ret = udma_navss_psil_pair(ud, uc->src_thread, uc->dst_thread);
+       if (ret) {
+               dev_err(ud->dev, "k3_nav_psil_request_link fail\n");
+               goto err_free_res;
+       }
+
+       return 0;
+
+err_free_res:
+       udma_free_tx_resources(uc);
+       udma_free_rx_resources(uc);
+       uc->slave_thread_id = -1;
+       return ret;
+}
+
+static void udma_free_chan_resources(struct udma_chan *uc)
+{
+       /* Some configuration to UDMA-P channel: disable, reset, whatever */
+
+       /* Release PSI-L pairing */
+       udma_navss_psil_unpair(uc->ud, uc->src_thread, uc->dst_thread);
+
+       /* Reset the rings for a new start */
+       udma_reset_rings(uc);
+       udma_free_tx_resources(uc);
+       udma_free_rx_resources(uc);
+
+       uc->slave_thread_id = -1;
+       uc->dir = DMA_MEM_TO_MEM;
+}
+
+static int udma_get_mmrs(struct udevice *dev)
+{
+       struct udma_dev *ud = dev_get_priv(dev);
+       int i;
+
+       for (i = 0; i < MMR_LAST; i++) {
+               ud->mmrs[i] = (uint32_t *)devfdt_get_addr_name(dev,
+                               mmr_names[i]);
+               if (!ud->mmrs[i])
+                       return -EINVAL;
+       }
+
+       return 0;
+}
+
+#define UDMA_MAX_CHANNELS      192
+
+static int udma_probe(struct udevice *dev)
+{
+       struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+       struct udma_dev *ud = dev_get_priv(dev);
+       int i, ret;
+       u32 cap2, cap3;
+       struct udevice *tmp;
+       struct udevice *tisci_dev = NULL;
+
+       ret = udma_get_mmrs(dev);
+       if (ret)
+               return ret;
+
+       ret = uclass_get_device_by_phandle(UCLASS_MISC, dev,
+                                          "ti,ringacc", &tmp);
+       ud->ringacc = dev_get_priv(tmp);
+       if (IS_ERR(ud->ringacc))
+               return PTR_ERR(ud->ringacc);
+
+       ud->psil_base = dev_read_u32_default(dev, "ti,psil-base", 0);
+       if (!ud->psil_base) {
+               dev_info(dev,
+                        "Missing ti,psil-base property, using %d.\n", ret);
+               return -EINVAL;
+       }
+
+       ret = uclass_get_device_by_name(UCLASS_FIRMWARE, "dmsc", &tisci_dev);
+       if (ret) {
+               debug("TISCI RA RM get failed (%d)\n", ret);
+               ud->tisci = NULL;
+               return 0;
+       }
+       ud->tisci = (struct ti_sci_handle *)
+                        (ti_sci_get_handle_from_sysfw(tisci_dev));
+
+       ret = dev_read_u32_default(dev, "ti,sci", 0);
+       if (!ret) {
+               dev_err(dev, "TISCI RA RM disabled\n");
+               ud->tisci = NULL;
+       }
+
+       if (ud->tisci) {
+               ofnode navss_ofnode = ofnode_get_parent(dev_ofnode(dev));
+
+               ud->tisci_dev_id = -1;
+               ret = dev_read_u32(dev, "ti,sci-dev-id", &ud->tisci_dev_id);
+               if (ret) {
+                       dev_err(dev, "ti,sci-dev-id read failure %d\n", ret);
+                       return ret;
+               }
+
+               ud->tisci_navss_dev_id = -1;
+               ret = ofnode_read_u32(navss_ofnode, "ti,sci-dev-id",
+                                     &ud->tisci_navss_dev_id);
+               if (ret) {
+                       dev_err(dev, "navss sci-dev-id read failure %d\n", ret);
+                       return ret;
+               }
+
+               ud->tisci_udmap_ops = &ud->tisci->ops.rm_udmap_ops;
+               ud->tisci_psil_ops = &ud->tisci->ops.rm_psil_ops;
+       }
+
+       ud->is_coherent = dev_read_bool(dev, "dma-coherent");
+
+       cap2 = udma_read(ud->mmrs[MMR_GCFG], 0x28);
+       cap3 = udma_read(ud->mmrs[MMR_GCFG], 0x2c);
+
+       ud->rflow_cnt = cap3 & 0x3fff;
+       ud->tchan_cnt = cap2 & 0x1ff;
+       ud->echan_cnt = (cap2 >> 9) & 0x1ff;
+       ud->rchan_cnt = (cap2 >> 18) & 0x1ff;
+       ud->ch_count  = ud->tchan_cnt + ud->rchan_cnt;
+
+       dev_info(dev,
+                "Number of channels: %u (tchan: %u, echan: %u, rchan: %u dev-id %u)\n",
+                ud->ch_count, ud->tchan_cnt, ud->echan_cnt, ud->rchan_cnt,
+                ud->tisci_dev_id);
+       dev_info(dev, "Number of rflows: %u\n", ud->rflow_cnt);
+
+       ud->channels = devm_kcalloc(dev, ud->ch_count, sizeof(*ud->channels),
+                                   GFP_KERNEL);
+       ud->tchan_map = devm_kcalloc(dev, BITS_TO_LONGS(ud->tchan_cnt),
+                                    sizeof(unsigned long), GFP_KERNEL);
+       ud->tchans = devm_kcalloc(dev, ud->tchan_cnt,
+                                 sizeof(*ud->tchans), GFP_KERNEL);
+       ud->rchan_map = devm_kcalloc(dev, BITS_TO_LONGS(ud->rchan_cnt),
+                                    sizeof(unsigned long), GFP_KERNEL);
+       ud->rchans = devm_kcalloc(dev, ud->rchan_cnt,
+                                 sizeof(*ud->rchans), GFP_KERNEL);
+       ud->rflow_map = devm_kcalloc(dev, BITS_TO_LONGS(ud->rflow_cnt),
+                                    sizeof(unsigned long), GFP_KERNEL);
+       ud->rflows = devm_kcalloc(dev, ud->rflow_cnt,
+                                 sizeof(*ud->rflows), GFP_KERNEL);
+
+       if (!ud->channels || !ud->tchan_map || !ud->rchan_map ||
+           !ud->rflow_map || !ud->tchans || !ud->rchans || !ud->rflows)
+               return -ENOMEM;
+
+       for (i = 0; i < ud->tchan_cnt; i++) {
+               struct udma_tchan *tchan = &ud->tchans[i];
+
+               tchan->id = i;
+               tchan->reg_rt = ud->mmrs[MMR_TCHANRT] + UDMA_CH_1000(i);
+       }
+
+       for (i = 0; i < ud->rchan_cnt; i++) {
+               struct udma_rchan *rchan = &ud->rchans[i];
+
+               rchan->id = i;
+               rchan->reg_rt = ud->mmrs[MMR_RCHANRT] + UDMA_CH_1000(i);
+       }
+
+       for (i = 0; i < ud->rflow_cnt; i++) {
+               struct udma_rflow *rflow = &ud->rflows[i];
+
+               rflow->id = i;
+       }
+
+       for (i = 0; i < ud->ch_count; i++) {
+               struct udma_chan *uc = &ud->channels[i];
+
+               uc->ud = ud;
+               uc->id = i;
+               uc->slave_thread_id = -1;
+               uc->tchan = NULL;
+               uc->rchan = NULL;
+               uc->dir = DMA_MEM_TO_MEM;
+               sprintf(uc->name, "UDMA chan%d\n", i);
+               if (!i)
+                       uc->in_use = true;
+       }
+
+       pr_debug("UDMA(rev: 0x%08x) CAP0-3: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+                udma_read(ud->mmrs[MMR_GCFG], 0),
+                udma_read(ud->mmrs[MMR_GCFG], 0x20),
+                udma_read(ud->mmrs[MMR_GCFG], 0x24),
+                udma_read(ud->mmrs[MMR_GCFG], 0x28),
+                udma_read(ud->mmrs[MMR_GCFG], 0x2c));
+
+       uc_priv->supported = DMA_SUPPORTS_MEM_TO_MEM | DMA_SUPPORTS_MEM_TO_DEV;
+
+       return ret;
+}
+
+static int *udma_prep_dma_memcpy(struct udma_chan *uc, dma_addr_t dest,
+                                dma_addr_t src, size_t len)
+{
+       u32 tc_ring_id = k3_nav_ringacc_get_ring_id(uc->tchan->tc_ring);
+       struct cppi5_tr_type15_t *tr_req;
+       int num_tr;
+       size_t tr_size = sizeof(struct cppi5_tr_type15_t);
+       u16 tr0_cnt0, tr0_cnt1, tr1_cnt0;
+       unsigned long dummy;
+       void *tr_desc;
+       size_t desc_size;
+
+       if (len < SZ_64K) {
+               num_tr = 1;
+               tr0_cnt0 = len;
+               tr0_cnt1 = 1;
+       } else {
+               unsigned long align_to = __ffs(src | dest);
+
+               if (align_to > 3)
+                       align_to = 3;
+               /*
+                * Keep simple: tr0: SZ_64K-alignment blocks,
+                *              tr1: the remaining
+                */
+               num_tr = 2;
+               tr0_cnt0 = (SZ_64K - BIT(align_to));
+               if (len / tr0_cnt0 >= SZ_64K) {
+                       dev_err(uc->ud->dev, "size %zu is not supported\n",
+                               len);
+                       return NULL;
+               }
+
+               tr0_cnt1 = len / tr0_cnt0;
+               tr1_cnt0 = len % tr0_cnt0;
+       }
+
+       desc_size = cppi5_trdesc_calc_size(num_tr, tr_size);
+       tr_desc = dma_alloc_coherent(desc_size, &dummy);
+       if (!tr_desc)
+               return NULL;
+       memset(tr_desc, 0, desc_size);
+
+       cppi5_trdesc_init(tr_desc, num_tr, tr_size, 0, 0);
+       cppi5_desc_set_pktids(tr_desc, uc->id, 0x3fff);
+       cppi5_desc_set_retpolicy(tr_desc, 0, tc_ring_id);
+
+       tr_req = tr_desc + tr_size;
+
+       cppi5_tr_init(&tr_req[0].flags, CPPI5_TR_TYPE15, false, true,
+                     CPPI5_TR_EVENT_SIZE_COMPLETION, 1);
+       cppi5_tr_csf_set(&tr_req[0].flags, CPPI5_TR_CSF_SUPR_EVT);
+
+       tr_req[0].addr = src;
+       tr_req[0].icnt0 = tr0_cnt0;
+       tr_req[0].icnt1 = tr0_cnt1;
+       tr_req[0].icnt2 = 1;
+       tr_req[0].icnt3 = 1;
+       tr_req[0].dim1 = tr0_cnt0;
+
+       tr_req[0].daddr = dest;
+       tr_req[0].dicnt0 = tr0_cnt0;
+       tr_req[0].dicnt1 = tr0_cnt1;
+       tr_req[0].dicnt2 = 1;
+       tr_req[0].dicnt3 = 1;
+       tr_req[0].ddim1 = tr0_cnt0;
+
+       if (num_tr == 2) {
+               cppi5_tr_init(&tr_req[1].flags, CPPI5_TR_TYPE15, false, true,
+                             CPPI5_TR_EVENT_SIZE_COMPLETION, 0);
+               cppi5_tr_csf_set(&tr_req[1].flags, CPPI5_TR_CSF_SUPR_EVT);
+
+               tr_req[1].addr = src + tr0_cnt1 * tr0_cnt0;
+               tr_req[1].icnt0 = tr1_cnt0;
+               tr_req[1].icnt1 = 1;
+               tr_req[1].icnt2 = 1;
+               tr_req[1].icnt3 = 1;
+
+               tr_req[1].daddr = dest + tr0_cnt1 * tr0_cnt0;
+               tr_req[1].dicnt0 = tr1_cnt0;
+               tr_req[1].dicnt1 = 1;
+               tr_req[1].dicnt2 = 1;
+               tr_req[1].dicnt3 = 1;
+       }
+
+       cppi5_tr_csf_set(&tr_req[num_tr - 1].flags, CPPI5_TR_CSF_EOP);
+
+       if (!udma_is_coherent(uc)) {
+               flush_dcache_range((u64)tr_desc,
+                                  ALIGN((u64)tr_desc + desc_size,
+                                        ARCH_DMA_MINALIGN));
+       }
+
+       k3_nav_ringacc_ring_push(uc->tchan->t_ring, &tr_desc);
+
+       return 0;
+}
+
+static int udma_transfer(struct udevice *dev, int direction,
+                        void *dst, void *src, size_t len)
+{
+       struct udma_dev *ud = dev_get_priv(dev);
+       /* Channel0 is reserved for memcpy */
+       struct udma_chan *uc = &ud->channels[0];
+       dma_addr_t paddr = 0;
+       int ret;
+
+       ret = udma_alloc_chan_resources(uc);
+       if (ret)
+               return ret;
+
+       udma_prep_dma_memcpy(uc, (dma_addr_t)dst, (dma_addr_t)src, len);
+       udma_start(uc);
+       udma_poll_completion(uc, &paddr);
+       udma_stop(uc);
+
+       udma_free_chan_resources(uc);
+       return 0;
+}
+
+static int udma_request(struct dma *dma)
+{
+       struct udma_dev *ud = dev_get_priv(dma->dev);
+       struct udma_chan *uc;
+       unsigned long dummy;
+       int ret;
+
+       if (dma->id >= (ud->rchan_cnt + ud->tchan_cnt)) {
+               dev_err(dma->dev, "invalid dma ch_id %lu\n", dma->id);
+               return -EINVAL;
+       }
+
+       uc = &ud->channels[dma->id];
+       ret = udma_alloc_chan_resources(uc);
+       if (ret) {
+               dev_err(dma->dev, "alloc dma res failed %d\n", ret);
+               return -EINVAL;
+       }
+
+       uc->hdesc_size = cppi5_hdesc_calc_size(uc->needs_epib,
+                                              uc->psd_size, 0);
+       uc->hdesc_size = ALIGN(uc->hdesc_size, ARCH_DMA_MINALIGN);
+
+       if (uc->dir == DMA_MEM_TO_DEV) {
+               uc->desc_tx = dma_alloc_coherent(uc->hdesc_size, &dummy);
+               memset(uc->desc_tx, 0, uc->hdesc_size);
+       } else {
+               uc->desc_rx = dma_alloc_coherent(
+                               uc->hdesc_size * UDMA_RX_DESC_NUM, &dummy);
+               memset(uc->desc_rx, 0, uc->hdesc_size * UDMA_RX_DESC_NUM);
+       }
+
+       uc->in_use = true;
+       uc->desc_rx_cur = 0;
+       uc->num_rx_bufs = 0;
+
+       return 0;
+}
+
+static int udma_free(struct dma *dma)
+{
+       struct udma_dev *ud = dev_get_priv(dma->dev);
+       struct udma_chan *uc;
+
+       if (dma->id >= (ud->rchan_cnt + ud->tchan_cnt)) {
+               dev_err(dma->dev, "invalid dma ch_id %lu\n", dma->id);
+               return -EINVAL;
+       }
+       uc = &ud->channels[dma->id];
+
+       if (udma_is_chan_running(uc))
+               udma_stop(uc);
+       udma_free_chan_resources(uc);
+
+       uc->in_use = false;
+
+       return 0;
+}
+
+static int udma_enable(struct dma *dma)
+{
+       struct udma_dev *ud = dev_get_priv(dma->dev);
+       struct udma_chan *uc;
+       int ret;
+
+       if (dma->id >= (ud->rchan_cnt + ud->tchan_cnt)) {
+               dev_err(dma->dev, "invalid dma ch_id %lu\n", dma->id);
+               return -EINVAL;
+       }
+       uc = &ud->channels[dma->id];
+
+       ret = udma_start(uc);
+
+       return ret;
+}
+
+static int udma_disable(struct dma *dma)
+{
+       struct udma_dev *ud = dev_get_priv(dma->dev);
+       struct udma_chan *uc;
+       int ret = 0;
+
+       if (dma->id >= (ud->rchan_cnt + ud->tchan_cnt)) {
+               dev_err(dma->dev, "invalid dma ch_id %lu\n", dma->id);
+               return -EINVAL;
+       }
+       uc = &ud->channels[dma->id];
+
+       if (udma_is_chan_running(uc))
+               ret = udma_stop(uc);
+       else
+               dev_err(dma->dev, "%s not running\n", __func__);
+
+       return ret;
+}
+
+static int udma_send(struct dma *dma, void *src, size_t len, void *metadata)
+{
+       struct udma_dev *ud = dev_get_priv(dma->dev);
+       struct cppi5_host_desc_t *desc_tx;
+       dma_addr_t dma_src = (dma_addr_t)src;
+       struct ti_udma_drv_packet_data packet_data = { 0 };
+       dma_addr_t paddr;
+       struct udma_chan *uc;
+       u32 tc_ring_id;
+       int ret;
+
+       if (!metadata)
+               packet_data = *((struct ti_udma_drv_packet_data *)metadata);
+
+       if (dma->id >= (ud->rchan_cnt + ud->tchan_cnt)) {
+               dev_err(dma->dev, "invalid dma ch_id %lu\n", dma->id);
+               return -EINVAL;
+       }
+       uc = &ud->channels[dma->id];
+
+       if (uc->dir != DMA_MEM_TO_DEV)
+               return -EINVAL;
+
+       tc_ring_id = k3_nav_ringacc_get_ring_id(uc->tchan->tc_ring);
+
+       desc_tx = uc->desc_tx;
+
+       cppi5_hdesc_reset_hbdesc(desc_tx);
+
+       cppi5_hdesc_init(desc_tx,
+                        uc->needs_epib ? CPPI5_INFO0_HDESC_EPIB_PRESENT : 0,
+                        uc->psd_size);
+       cppi5_hdesc_set_pktlen(desc_tx, len);
+       cppi5_hdesc_attach_buf(desc_tx, dma_src, len, dma_src, len);
+       cppi5_desc_set_pktids(&desc_tx->hdr, uc->id, 0x3fff);
+       cppi5_desc_set_retpolicy(&desc_tx->hdr, 0, tc_ring_id);
+       /* pass below information from caller */
+       cppi5_hdesc_set_pkttype(desc_tx, packet_data.pkt_type);
+       cppi5_desc_set_tags_ids(&desc_tx->hdr, 0, packet_data.dest_tag);
+
+       if (!udma_is_coherent(uc)) {
+               flush_dcache_range((u64)dma_src,
+                                  ALIGN((u64)dma_src + len,
+                                        ARCH_DMA_MINALIGN));
+               flush_dcache_range((u64)desc_tx,
+                                  ALIGN((u64)desc_tx + uc->hdesc_size,
+                                        ARCH_DMA_MINALIGN));
+       }
+
+       ret = k3_nav_ringacc_ring_push(uc->tchan->t_ring, &uc->desc_tx);
+       if (ret) {
+               dev_err(dma->dev, "TX dma push fail ch_id %lu %d\n",
+                       dma->id, ret);
+               return ret;
+       }
+
+       udma_poll_completion(uc, &paddr);
+
+       return 0;
+}
+
+static int udma_receive(struct dma *dma, void **dst, void *metadata)
+{
+       struct udma_dev *ud = dev_get_priv(dma->dev);
+       struct cppi5_host_desc_t *desc_rx;
+       dma_addr_t buf_dma;
+       struct udma_chan *uc;
+       u32 buf_dma_len, pkt_len;
+       u32 port_id = 0;
+       int ret;
+
+       if (dma->id >= (ud->rchan_cnt + ud->tchan_cnt)) {
+               dev_err(dma->dev, "invalid dma ch_id %lu\n", dma->id);
+               return -EINVAL;
+       }
+       uc = &ud->channels[dma->id];
+
+       if (uc->dir != DMA_DEV_TO_MEM)
+               return -EINVAL;
+       if (!uc->num_rx_bufs)
+               return -EINVAL;
+
+       ret = k3_nav_ringacc_ring_pop(uc->rchan->r_ring, &desc_rx);
+       if (ret && ret != -ENODATA) {
+               dev_err(dma->dev, "rx dma fail ch_id:%lu %d\n", dma->id, ret);
+               return ret;
+       } else if (ret == -ENODATA) {
+               return 0;
+       }
+
+       /* invalidate cache data */
+       if (!udma_is_coherent(uc)) {
+               invalidate_dcache_range((ulong)desc_rx,
+                                       (ulong)(desc_rx + uc->hdesc_size));
+       }
+
+       cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len);
+       pkt_len = cppi5_hdesc_get_pktlen(desc_rx);
+
+       /* invalidate cache data */
+       if (!udma_is_coherent(uc)) {
+               invalidate_dcache_range((ulong)buf_dma,
+                                       (ulong)(buf_dma + buf_dma_len));
+       }
+
+       cppi5_desc_get_tags_ids(&desc_rx->hdr, &port_id, NULL);
+
+       *dst = (void *)buf_dma;
+       uc->num_rx_bufs--;
+
+       return pkt_len;
+}
+
+static int udma_of_xlate(struct dma *dma, struct ofnode_phandle_args *args)
+{
+       struct udma_dev *ud = dev_get_priv(dma->dev);
+       struct udma_chan *uc = &ud->channels[0];
+       ofnode chconf_node, slave_node;
+       char prop[50];
+       u32 val;
+
+       for (val = 0; val < ud->ch_count; val++) {
+               uc = &ud->channels[val];
+               if (!uc->in_use)
+                       break;
+       }
+
+       if (val == ud->ch_count)
+               return -EBUSY;
+
+       uc->dir = DMA_DEV_TO_MEM;
+       if (args->args[2] == UDMA_DIR_TX)
+               uc->dir = DMA_MEM_TO_DEV;
+
+       slave_node = ofnode_get_by_phandle(args->args[0]);
+       if (!ofnode_valid(slave_node)) {
+               dev_err(ud->dev, "slave node is missing\n");
+               return -EINVAL;
+       }
+
+       snprintf(prop, sizeof(prop), "ti,psil-config%u", args->args[1]);
+       chconf_node = ofnode_find_subnode(slave_node, prop);
+       if (!ofnode_valid(chconf_node)) {
+               dev_err(ud->dev, "Channel configuration node is missing\n");
+               return -EINVAL;
+       }
+
+       if (!ofnode_read_u32(chconf_node, "linux,udma-mode", &val)) {
+               if (val == UDMA_PKT_MODE)
+                       uc->pkt_mode = true;
+       }
+
+       if (!ofnode_read_u32(chconf_node, "statictr-type", &val))
+               uc->static_tr_type = val;
+
+       uc->needs_epib = ofnode_read_bool(chconf_node, "ti,needs-epib");
+       if (!ofnode_read_u32(chconf_node, "ti,psd-size", &val))
+               uc->psd_size = val;
+       uc->metadata_size = (uc->needs_epib ? 16 : 0) + uc->psd_size;
+
+       if (ofnode_read_u32(slave_node, "ti,psil-base", &val)) {
+               dev_err(ud->dev, "ti,psil-base is missing\n");
+               return -EINVAL;
+       }
+
+       uc->slave_thread_id = val + args->args[1];
+
+       dma->id = uc->id;
+       pr_debug("Allocated dma chn:%lu epib:%d psdata:%u meta:%u thread_id:%x\n",
+                dma->id, uc->needs_epib,
+                uc->psd_size, uc->metadata_size,
+                uc->slave_thread_id);
+
+       return 0;
+}
+
+int udma_prepare_rcv_buf(struct dma *dma, void *dst, size_t size)
+{
+       struct udma_dev *ud = dev_get_priv(dma->dev);
+       struct cppi5_host_desc_t *desc_rx;
+       dma_addr_t dma_dst;
+       struct udma_chan *uc;
+       u32 desc_num;
+
+       if (dma->id >= (ud->rchan_cnt + ud->tchan_cnt)) {
+               dev_err(dma->dev, "invalid dma ch_id %lu\n", dma->id);
+               return -EINVAL;
+       }
+       uc = &ud->channels[dma->id];
+
+       if (uc->dir != DMA_DEV_TO_MEM)
+               return -EINVAL;
+
+       if (uc->num_rx_bufs >= UDMA_RX_DESC_NUM)
+               return -EINVAL;
+
+       desc_num = uc->desc_rx_cur % UDMA_RX_DESC_NUM;
+       desc_rx = uc->desc_rx + (desc_num * uc->hdesc_size);
+       dma_dst = (dma_addr_t)dst;
+
+       cppi5_hdesc_reset_hbdesc(desc_rx);
+
+       cppi5_hdesc_init(desc_rx,
+                        uc->needs_epib ? CPPI5_INFO0_HDESC_EPIB_PRESENT : 0,
+                        uc->psd_size);
+       cppi5_hdesc_set_pktlen(desc_rx, size);
+       cppi5_hdesc_attach_buf(desc_rx, dma_dst, size, dma_dst, size);
+
+       if (!udma_is_coherent(uc)) {
+               flush_dcache_range((u64)desc_rx,
+                                  ALIGN((u64)desc_rx + uc->hdesc_size,
+                                        ARCH_DMA_MINALIGN));
+       }
+
+       k3_nav_ringacc_ring_push(uc->rchan->fd_ring, &desc_rx);
+
+       uc->num_rx_bufs++;
+       uc->desc_rx_cur++;
+
+       return 0;
+}
+
+static const struct dma_ops udma_ops = {
+       .transfer       = udma_transfer,
+       .of_xlate       = udma_of_xlate,
+       .request        = udma_request,
+       .free           = udma_free,
+       .enable         = udma_enable,
+       .disable        = udma_disable,
+       .send           = udma_send,
+       .receive        = udma_receive,
+       .prepare_rcv_buf = udma_prepare_rcv_buf,
+};
+
+static const struct udevice_id udma_ids[] = {
+       { .compatible = "ti,k3-navss-udmap" },
+       { }
+};
+
+U_BOOT_DRIVER(ti_edma3) = {
+       .name   = "ti-udma",
+       .id     = UCLASS_DMA,
+       .of_match = udma_ids,
+       .ops    = &udma_ops,
+       .probe  = udma_probe,
+       .priv_auto_alloc_size = sizeof(struct udma_dev),
+};
index 91481260411aa5a0b7f13ad823089f98a1da2236..d47d22fff3e4661e36bbbd876f1cd10815257411 100644 (file)
@@ -12,6 +12,7 @@
 #include <errno.h>
 #include <mailbox.h>
 #include <dm/device.h>
+#include <linux/compat.h>
 #include <linux/err.h>
 #include <linux/soc/ti/k3-sec-proxy.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
@@ -31,16 +32,37 @@ struct ti_sci_xfer {
        u8 rx_len;
 };
 
+/**
+ * struct ti_sci_rm_type_map - Structure representing TISCI Resource
+ *                             management representation of dev_ids.
+ * @dev_id:    TISCI device ID
+ * @type:      Corresponding id as identified by TISCI RM.
+ *
+ * Note: This is used only as a work around for using RM range apis
+ *     for AM654 SoC. For future SoCs dev_id will be used as type
+ *     for RM range APIs. In order to maintain ABI backward compatibility
+ *     type is not being changed for AM654 SoC.
+ */
+struct ti_sci_rm_type_map {
+       u32 dev_id;
+       u16 type;
+};
+
 /**
  * struct ti_sci_desc - Description of SoC integration
- * @host_id:           Host identifier representing the compute entity
- * @max_rx_timeout_us: Timeout for communication with SoC (in Microseconds)
- * @max_msg_size:      Maximum size of data per message that can be handled.
+ * @default_host_id:   Host identifier representing the compute entity
+ * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds)
+ * @max_msgs: Maximum number of messages that can be pending
+ *               simultaneously in the system
+ * @max_msg_size: Maximum size of data per message that can be handled.
+ * @rm_type_map: RM resource type mapping structure.
  */
 struct ti_sci_desc {
-       u8 host_id;
-       int max_rx_timeout_us;
+       u8 default_host_id;
+       int max_rx_timeout_ms;
+       int max_msgs;
        int max_msg_size;
+       struct ti_sci_rm_type_map *rm_type_map;
 };
 
 /**
@@ -136,7 +158,7 @@ static inline int ti_sci_get_response(struct ti_sci_info *info,
        int ret;
 
        /* Receive the response */
-       ret = mbox_recv(chan, msg, info->desc->max_rx_timeout_us);
+       ret = mbox_recv(chan, msg, info->desc->max_rx_timeout_ms);
        if (ret) {
                dev_err(info->dev, "%s: Message receive failed. ret = %d\n",
                        __func__, ret);
@@ -1441,6 +1463,199 @@ static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle)
        return ret;
 }
 
+static int ti_sci_get_resource_type(struct ti_sci_info *info, u16 dev_id,
+                                   u16 *type)
+{
+       struct ti_sci_rm_type_map *rm_type_map = info->desc->rm_type_map;
+       bool found = false;
+       int i;
+
+       /* If map is not provided then assume dev_id is used as type */
+       if (!rm_type_map) {
+               *type = dev_id;
+               return 0;
+       }
+
+       for (i = 0; rm_type_map[i].dev_id; i++) {
+               if (rm_type_map[i].dev_id == dev_id) {
+                       *type = rm_type_map[i].type;
+                       found = true;
+                       break;
+               }
+       }
+
+       if (!found)
+               return -EINVAL;
+
+       return 0;
+}
+
+/**
+ * ti_sci_get_resource_range - Helper to get a range of resources assigned
+ *                            to a host. Resource is uniquely identified by
+ *                            type and subtype.
+ * @handle:            Pointer to TISCI handle.
+ * @dev_id:            TISCI device ID.
+ * @subtype:           Resource assignment subtype that is being requested
+ *                     from the given device.
+ * @s_host:            Host processor ID to which the resources are allocated
+ * @range_start:       Start index of the resource range
+ * @range_num:         Number of resources in the range
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
+                                    u32 dev_id, u8 subtype, u8 s_host,
+                                    u16 *range_start, u16 *range_num)
+{
+       struct ti_sci_msg_resp_get_resource_range *resp;
+       struct ti_sci_msg_req_get_resource_range req;
+       struct ti_sci_xfer *xfer;
+       struct ti_sci_info *info;
+       u16 type;
+       int ret = 0;
+
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       if (!handle)
+               return -EINVAL;
+
+       info = handle_to_ti_sci_info(handle);
+
+       xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_RESOURCE_RANGE,
+                                    TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                    (u32 *)&req, sizeof(req), sizeof(*resp));
+       if (IS_ERR(xfer)) {
+               ret = PTR_ERR(xfer);
+               dev_err(dev, "Message alloc failed(%d)\n", ret);
+               return ret;
+       }
+
+       ret = ti_sci_get_resource_type(info, dev_id, &type);
+       if (ret) {
+               dev_err(dev, "rm type lookup failed for %u\n", dev_id);
+               goto fail;
+       }
+
+       req.secondary_host = s_host;
+       req.type = type & MSG_RM_RESOURCE_TYPE_MASK;
+       req.subtype = subtype & MSG_RM_RESOURCE_SUBTYPE_MASK;
+
+       ret = ti_sci_do_xfer(info, xfer);
+       if (ret) {
+               dev_err(dev, "Mbox send fail %d\n", ret);
+               goto fail;
+       }
+
+       resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->tx_message.buf;
+       if (!ti_sci_is_response_ack(resp)) {
+               ret = -ENODEV;
+       } else if (!resp->range_start && !resp->range_num) {
+               ret = -ENODEV;
+       } else {
+               *range_start = resp->range_start;
+               *range_num = resp->range_num;
+       };
+
+fail:
+       return ret;
+}
+
+/**
+ * ti_sci_cmd_get_resource_range - Get a range of resources assigned to host
+ *                                that is same as ti sci interface host.
+ * @handle:            Pointer to TISCI handle.
+ * @dev_id:            TISCI device ID.
+ * @subtype:           Resource assignment subtype that is being requested
+ *                     from the given device.
+ * @range_start:       Start index of the resource range
+ * @range_num:         Number of resources in the range
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_get_resource_range(const struct ti_sci_handle *handle,
+                                        u32 dev_id, u8 subtype,
+                                        u16 *range_start, u16 *range_num)
+{
+       return ti_sci_get_resource_range(handle, dev_id, subtype,
+                                        TI_SCI_IRQ_SECONDARY_HOST_INVALID,
+                                        range_start, range_num);
+}
+
+/**
+ * ti_sci_cmd_get_resource_range_from_shost - Get a range of resources
+ *                                           assigned to a specified host.
+ * @handle:            Pointer to TISCI handle.
+ * @dev_id:            TISCI device ID.
+ * @subtype:           Resource assignment subtype that is being requested
+ *                     from the given device.
+ * @s_host:            Host processor ID to which the resources are allocated
+ * @range_start:       Start index of the resource range
+ * @range_num:         Number of resources in the range
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static
+int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle,
+                                            u32 dev_id, u8 subtype, u8 s_host,
+                                            u16 *range_start, u16 *range_num)
+{
+       return ti_sci_get_resource_range(handle, dev_id, subtype, s_host,
+                                        range_start, range_num);
+}
+
+/**
+ * ti_sci_cmd_query_msmc() - Command to query currently available msmc memory
+ * @handle:            pointer to TI SCI handle
+ * @msms_start:                MSMC start as returned by tisci
+ * @msmc_end:          MSMC end as returned by tisci
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_query_msmc(const struct ti_sci_handle *handle,
+                                u64 *msmc_start, u64 *msmc_end)
+{
+       struct ti_sci_msg_resp_query_msmc *resp;
+       struct ti_sci_msg_hdr req;
+       struct ti_sci_info *info;
+       struct ti_sci_xfer *xfer;
+       int ret = 0;
+
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       if (!handle)
+               return -EINVAL;
+
+       info = handle_to_ti_sci_info(handle);
+
+       xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_QUERY_MSMC,
+                                    TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                    (u32 *)&req, sizeof(req), sizeof(*resp));
+       if (IS_ERR(xfer)) {
+               ret = PTR_ERR(xfer);
+               dev_err(info->dev, "Message alloc failed(%d)\n", ret);
+               return ret;
+       }
+
+       ret = ti_sci_do_xfer(info, xfer);
+       if (ret) {
+               dev_err(dev, "Mbox send fail %d\n", ret);
+               return ret;
+       }
+
+       resp = (struct ti_sci_msg_resp_query_msmc *)xfer->tx_message.buf;
+
+       if (!ti_sci_is_response_ack(resp))
+               return -ENODEV;
+
+       *msmc_start = ((u64)resp->msmc_start_high << TISCI_ADDR_HIGH_SHIFT) |
+                       resp->msmc_start_low;
+       *msmc_end = ((u64)resp->msmc_end_high << TISCI_ADDR_HIGH_SHIFT) |
+                       resp->msmc_end_low;
+
+       return ret;
+}
+
 /**
  * ti_sci_cmd_proc_request() - Command to request a physical processor control
  * @handle:    Pointer to TI SCI handle
@@ -1803,6 +2018,416 @@ static int ti_sci_cmd_get_proc_boot_status(const struct ti_sci_handle *handle,
        return ret;
 }
 
+/**
+ * ti_sci_cmd_ring_config() - configure RA ring
+ * @handle:    pointer to TI SCI handle
+ * @valid_params: Bitfield defining validity of ring configuration parameters.
+ * @nav_id: Device ID of Navigator Subsystem from which the ring is allocated
+ * @index: Ring index.
+ * @addr_lo: The ring base address lo 32 bits
+ * @addr_hi: The ring base address hi 32 bits
+ * @count: Number of ring elements.
+ * @mode: The mode of the ring
+ * @size: The ring element size.
+ * @order_id: Specifies the ring's bus order ID.
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ *
+ * See @ti_sci_msg_rm_ring_cfg_req for more info.
+ */
+static int ti_sci_cmd_ring_config(const struct ti_sci_handle *handle,
+                                 u32 valid_params, u16 nav_id, u16 index,
+                                 u32 addr_lo, u32 addr_hi, u32 count,
+                                 u8 mode, u8 size, u8 order_id)
+{
+       struct ti_sci_msg_rm_ring_cfg_resp *resp;
+       struct ti_sci_msg_rm_ring_cfg_req req;
+       struct ti_sci_xfer *xfer;
+       struct ti_sci_info *info;
+       int ret = 0;
+
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       if (!handle)
+               return -EINVAL;
+
+       info = handle_to_ti_sci_info(handle);
+
+       xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_RM_RING_CFG,
+                                    TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                    (u32 *)&req, sizeof(req), sizeof(*resp));
+       if (IS_ERR(xfer)) {
+               ret = PTR_ERR(xfer);
+               dev_err(info->dev, "RM_RA:Message config failed(%d)\n", ret);
+               return ret;
+       }
+       req.valid_params = valid_params;
+       req.nav_id = nav_id;
+       req.index = index;
+       req.addr_lo = addr_lo;
+       req.addr_hi = addr_hi;
+       req.count = count;
+       req.mode = mode;
+       req.size = size;
+       req.order_id = order_id;
+
+       ret = ti_sci_do_xfer(info, xfer);
+       if (ret) {
+               dev_err(info->dev, "RM_RA:Mbox config send fail %d\n", ret);
+               goto fail;
+       }
+
+       resp = (struct ti_sci_msg_rm_ring_cfg_resp *)xfer->tx_message.buf;
+
+       ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
+
+fail:
+       dev_dbg(info->dev, "RM_RA:config ring %u ret:%d\n", index, ret);
+       return ret;
+}
+
+/**
+ * ti_sci_cmd_ring_get_config() - get RA ring configuration
+ * @handle:    pointer to TI SCI handle
+ * @nav_id: Device ID of Navigator Subsystem from which the ring is allocated
+ * @index: Ring index.
+ * @addr_lo: returns ring's base address lo 32 bits
+ * @addr_hi: returns ring's base address hi 32 bits
+ * @count: returns number of ring elements.
+ * @mode: returns mode of the ring
+ * @size: returns ring element size.
+ * @order_id: returns ring's bus order ID.
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ *
+ * See @ti_sci_msg_rm_ring_get_cfg_req for more info.
+ */
+static int ti_sci_cmd_ring_get_config(const struct ti_sci_handle *handle,
+                                     u32 nav_id, u32 index, u8 *mode,
+                                     u32 *addr_lo, u32 *addr_hi,
+                                     u32 *count, u8 *size, u8 *order_id)
+{
+       struct ti_sci_msg_rm_ring_get_cfg_resp *resp;
+       struct ti_sci_msg_rm_ring_get_cfg_req req;
+       struct ti_sci_xfer *xfer;
+       struct ti_sci_info *info;
+       int ret = 0;
+
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       if (!handle)
+               return -EINVAL;
+
+       info = handle_to_ti_sci_info(handle);
+
+       xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_RM_RING_GET_CFG,
+                                    TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                    (u32 *)&req, sizeof(req), sizeof(*resp));
+       if (IS_ERR(xfer)) {
+               ret = PTR_ERR(xfer);
+               dev_err(info->dev,
+                       "RM_RA:Message get config failed(%d)\n", ret);
+               return ret;
+       }
+       req.nav_id = nav_id;
+       req.index = index;
+
+       ret = ti_sci_do_xfer(info, xfer);
+       if (ret) {
+               dev_err(info->dev, "RM_RA:Mbox get config send fail %d\n", ret);
+               goto fail;
+       }
+
+       resp = (struct ti_sci_msg_rm_ring_get_cfg_resp *)xfer->tx_message.buf;
+
+       if (!ti_sci_is_response_ack(resp)) {
+               ret = -ENODEV;
+       } else {
+               if (mode)
+                       *mode = resp->mode;
+               if (addr_lo)
+                       *addr_lo = resp->addr_lo;
+               if (addr_hi)
+                       *addr_hi = resp->addr_hi;
+               if (count)
+                       *count = resp->count;
+               if (size)
+                       *size = resp->size;
+               if (order_id)
+                       *order_id = resp->order_id;
+       };
+
+fail:
+       dev_dbg(info->dev, "RM_RA:get config ring %u ret:%d\n", index, ret);
+       return ret;
+}
+
+static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle,
+                                  u32 nav_id, u32 src_thread, u32 dst_thread)
+{
+       struct ti_sci_msg_hdr *resp;
+       struct ti_sci_msg_psil_pair req;
+       struct ti_sci_xfer *xfer;
+       struct ti_sci_info *info;
+       int ret = 0;
+
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       if (!handle)
+               return -EINVAL;
+
+       info = handle_to_ti_sci_info(handle);
+
+       xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_RM_PSIL_PAIR,
+                                    TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                    (u32 *)&req, sizeof(req), sizeof(*resp));
+       if (IS_ERR(xfer)) {
+               ret = PTR_ERR(xfer);
+               dev_err(info->dev, "RM_PSIL:Message alloc failed(%d)\n", ret);
+               return ret;
+       }
+       req.nav_id = nav_id;
+       req.src_thread = src_thread;
+       req.dst_thread = dst_thread;
+
+       ret = ti_sci_do_xfer(info, xfer);
+       if (ret) {
+               dev_err(info->dev, "RM_PSIL:Mbox send fail %d\n", ret);
+               goto fail;
+       }
+
+       resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
+       ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
+
+fail:
+       dev_dbg(info->dev, "RM_PSIL: nav: %u link pair %u->%u ret:%u\n",
+               nav_id, src_thread, dst_thread, ret);
+       return ret;
+}
+
+static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle,
+                                    u32 nav_id, u32 src_thread, u32 dst_thread)
+{
+       struct ti_sci_msg_hdr *resp;
+       struct ti_sci_msg_psil_unpair req;
+       struct ti_sci_xfer *xfer;
+       struct ti_sci_info *info;
+       int ret = 0;
+
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       if (!handle)
+               return -EINVAL;
+
+       info = handle_to_ti_sci_info(handle);
+
+       xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_RM_PSIL_UNPAIR,
+                                    TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                    (u32 *)&req, sizeof(req), sizeof(*resp));
+       if (IS_ERR(xfer)) {
+               ret = PTR_ERR(xfer);
+               dev_err(info->dev, "RM_PSIL:Message alloc failed(%d)\n", ret);
+               return ret;
+       }
+       req.nav_id = nav_id;
+       req.src_thread = src_thread;
+       req.dst_thread = dst_thread;
+
+       ret = ti_sci_do_xfer(info, xfer);
+       if (ret) {
+               dev_err(info->dev, "RM_PSIL:Mbox send fail %d\n", ret);
+               goto fail;
+       }
+
+       resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
+       ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
+
+fail:
+       dev_dbg(info->dev, "RM_PSIL: link unpair %u->%u ret:%u\n",
+               src_thread, dst_thread, ret);
+       return ret;
+}
+
+static int ti_sci_cmd_rm_udmap_tx_ch_cfg(
+                       const struct ti_sci_handle *handle,
+                       const struct ti_sci_msg_rm_udmap_tx_ch_cfg *params)
+{
+       struct ti_sci_msg_rm_udmap_tx_ch_cfg_resp *resp;
+       struct ti_sci_msg_rm_udmap_tx_ch_cfg_req req;
+       struct ti_sci_xfer *xfer;
+       struct ti_sci_info *info;
+       int ret = 0;
+
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       if (!handle)
+               return -EINVAL;
+
+       info = handle_to_ti_sci_info(handle);
+
+       xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_RM_UDMAP_TX_CH_CFG,
+                                    TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                    (u32 *)&req, sizeof(req), sizeof(*resp));
+       if (IS_ERR(xfer)) {
+               ret = PTR_ERR(xfer);
+               dev_err(info->dev, "Message TX_CH_CFG alloc failed(%d)\n", ret);
+               return ret;
+       }
+       req.valid_params = params->valid_params;
+       req.nav_id = params->nav_id;
+       req.index = params->index;
+       req.tx_pause_on_err = params->tx_pause_on_err;
+       req.tx_filt_einfo = params->tx_filt_einfo;
+       req.tx_filt_pswords = params->tx_filt_pswords;
+       req.tx_atype = params->tx_atype;
+       req.tx_chan_type = params->tx_chan_type;
+       req.tx_supr_tdpkt = params->tx_supr_tdpkt;
+       req.tx_fetch_size = params->tx_fetch_size;
+       req.tx_credit_count = params->tx_credit_count;
+       req.txcq_qnum = params->txcq_qnum;
+       req.tx_priority = params->tx_priority;
+       req.tx_qos = params->tx_qos;
+       req.tx_orderid = params->tx_orderid;
+       req.fdepth = params->fdepth;
+       req.tx_sched_priority = params->tx_sched_priority;
+
+       ret = ti_sci_do_xfer(info, xfer);
+       if (ret) {
+               dev_err(info->dev, "Mbox send TX_CH_CFG fail %d\n", ret);
+               goto fail;
+       }
+
+       resp =
+             (struct ti_sci_msg_rm_udmap_tx_ch_cfg_resp *)xfer->tx_message.buf;
+       ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
+
+fail:
+       dev_dbg(info->dev, "TX_CH_CFG: chn %u ret:%u\n", params->index, ret);
+       return ret;
+}
+
+static int ti_sci_cmd_rm_udmap_rx_ch_cfg(
+                       const struct ti_sci_handle *handle,
+                       const struct ti_sci_msg_rm_udmap_rx_ch_cfg *params)
+{
+       struct ti_sci_msg_rm_udmap_rx_ch_cfg_resp *resp;
+       struct ti_sci_msg_rm_udmap_rx_ch_cfg_req req;
+       struct ti_sci_xfer *xfer;
+       struct ti_sci_info *info;
+       int ret = 0;
+
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       if (!handle)
+               return -EINVAL;
+
+       info = handle_to_ti_sci_info(handle);
+
+       xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_RM_UDMAP_RX_CH_CFG,
+                                    TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                    (u32 *)&req, sizeof(req), sizeof(*resp));
+       if (IS_ERR(xfer)) {
+               ret = PTR_ERR(xfer);
+               dev_err(info->dev, "Message RX_CH_CFG alloc failed(%d)\n", ret);
+               return ret;
+       }
+
+       req.valid_params = params->valid_params;
+       req.nav_id = params->nav_id;
+       req.index = params->index;
+       req.rx_fetch_size = params->rx_fetch_size;
+       req.rxcq_qnum = params->rxcq_qnum;
+       req.rx_priority = params->rx_priority;
+       req.rx_qos = params->rx_qos;
+       req.rx_orderid = params->rx_orderid;
+       req.rx_sched_priority = params->rx_sched_priority;
+       req.flowid_start = params->flowid_start;
+       req.flowid_cnt = params->flowid_cnt;
+       req.rx_pause_on_err = params->rx_pause_on_err;
+       req.rx_atype = params->rx_atype;
+       req.rx_chan_type = params->rx_chan_type;
+       req.rx_ignore_short = params->rx_ignore_short;
+       req.rx_ignore_long = params->rx_ignore_long;
+
+       ret = ti_sci_do_xfer(info, xfer);
+       if (ret) {
+               dev_err(info->dev, "Mbox send RX_CH_CFG fail %d\n", ret);
+               goto fail;
+       }
+
+       resp =
+             (struct ti_sci_msg_rm_udmap_rx_ch_cfg_resp *)xfer->tx_message.buf;
+       ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
+
+fail:
+       dev_dbg(info->dev, "RX_CH_CFG: chn %u ret:%d\n", params->index, ret);
+       return ret;
+}
+
+static int ti_sci_cmd_rm_udmap_rx_flow_cfg(
+                       const struct ti_sci_handle *handle,
+                       const struct ti_sci_msg_rm_udmap_flow_cfg *params)
+{
+       struct ti_sci_msg_rm_udmap_flow_cfg_resp *resp;
+       struct ti_sci_msg_rm_udmap_flow_cfg_req req;
+       struct ti_sci_xfer *xfer;
+       struct ti_sci_info *info;
+       int ret = 0;
+
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       if (!handle)
+               return -EINVAL;
+
+       info = handle_to_ti_sci_info(handle);
+
+       xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_RM_UDMAP_FLOW_CFG,
+                                    TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                    (u32 *)&req, sizeof(req), sizeof(*resp));
+       if (IS_ERR(xfer)) {
+               ret = PTR_ERR(xfer);
+               dev_err(dev, "RX_FL_CFG: Message alloc failed(%d)\n", ret);
+               return ret;
+       }
+
+       req.valid_params = params->valid_params;
+       req.nav_id = params->nav_id;
+       req.flow_index = params->flow_index;
+       req.rx_einfo_present = params->rx_einfo_present;
+       req.rx_psinfo_present = params->rx_psinfo_present;
+       req.rx_error_handling = params->rx_error_handling;
+       req.rx_desc_type = params->rx_desc_type;
+       req.rx_sop_offset = params->rx_sop_offset;
+       req.rx_dest_qnum = params->rx_dest_qnum;
+       req.rx_src_tag_hi = params->rx_src_tag_hi;
+       req.rx_src_tag_lo = params->rx_src_tag_lo;
+       req.rx_dest_tag_hi = params->rx_dest_tag_hi;
+       req.rx_dest_tag_lo = params->rx_dest_tag_lo;
+       req.rx_src_tag_hi_sel = params->rx_src_tag_hi_sel;
+       req.rx_src_tag_lo_sel = params->rx_src_tag_lo_sel;
+       req.rx_dest_tag_hi_sel = params->rx_dest_tag_hi_sel;
+       req.rx_dest_tag_lo_sel = params->rx_dest_tag_lo_sel;
+       req.rx_fdq0_sz0_qnum = params->rx_fdq0_sz0_qnum;
+       req.rx_fdq1_qnum = params->rx_fdq1_qnum;
+       req.rx_fdq2_qnum = params->rx_fdq2_qnum;
+       req.rx_fdq3_qnum = params->rx_fdq3_qnum;
+       req.rx_ps_location = params->rx_ps_location;
+
+       ret = ti_sci_do_xfer(info, xfer);
+       if (ret) {
+               dev_err(dev, "RX_FL_CFG: Mbox send fail %d\n", ret);
+               goto fail;
+       }
+
+       resp =
+              (struct ti_sci_msg_rm_udmap_flow_cfg_resp *)xfer->tx_message.buf;
+       ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
+
+fail:
+       dev_dbg(info->dev, "RX_FL_CFG: %u ret:%d\n", params->flow_index, ret);
+       return ret;
+}
+
 /*
  * ti_sci_setup_ops() - Setup the operations structures
  * @info:      pointer to TISCI pointer
@@ -1814,7 +2439,11 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
        struct ti_sci_dev_ops *dops = &ops->dev_ops;
        struct ti_sci_clk_ops *cops = &ops->clk_ops;
        struct ti_sci_core_ops *core_ops = &ops->core_ops;
+       struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops;
        struct ti_sci_proc_ops *pops = &ops->proc_ops;
+       struct ti_sci_rm_ringacc_ops *rops = &ops->rm_ring_ops;
+       struct ti_sci_rm_psil_ops *psilops = &ops->rm_psil_ops;
+       struct ti_sci_rm_udmap_ops *udmap_ops = &ops->rm_udmap_ops;
 
        bops->board_config = ti_sci_cmd_set_board_config;
        bops->board_config_rm = ti_sci_cmd_set_board_config_rm;
@@ -1849,6 +2478,11 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
        cops->get_freq = ti_sci_cmd_clk_get_freq;
 
        core_ops->reboot_device = ti_sci_cmd_core_reboot;
+       core_ops->query_msmc = ti_sci_cmd_query_msmc;
+
+       rm_core_ops->get_range = ti_sci_cmd_get_resource_range;
+       rm_core_ops->get_range_from_shost =
+               ti_sci_cmd_get_resource_range_from_shost;
 
        pops->proc_request = ti_sci_cmd_proc_request;
        pops->proc_release = ti_sci_cmd_proc_release;
@@ -1857,6 +2491,16 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
        pops->set_proc_boot_ctrl = ti_sci_cmd_set_proc_boot_ctrl;
        pops->proc_auth_boot_image = ti_sci_cmd_proc_auth_boot_image;
        pops->get_proc_boot_status = ti_sci_cmd_get_proc_boot_status;
+
+       rops->config = ti_sci_cmd_ring_config;
+       rops->get_config = ti_sci_cmd_ring_get_config;
+
+       psilops->pair = ti_sci_cmd_rm_psil_pair;
+       psilops->unpair = ti_sci_cmd_rm_psil_unpair;
+
+       udmap_ops->tx_ch_cfg = ti_sci_cmd_rm_udmap_tx_ch_cfg;
+       udmap_ops->rx_ch_cfg = ti_sci_cmd_rm_udmap_rx_ch_cfg;
+       udmap_ops->rx_flow_cfg = ti_sci_cmd_rm_udmap_rx_flow_cfg;
 }
 
 /**
@@ -1969,7 +2613,7 @@ static int ti_sci_of_to_info(struct udevice *dev, struct ti_sci_info *info)
        }
 
        info->host_id = dev_read_u32_default(dev, "ti,host-id",
-                                            info->desc->host_id);
+                                            info->desc->default_host_id);
 
        info->is_secure = dev_read_bool(dev, "ti,secure-host");
 
@@ -2009,17 +2653,164 @@ static int ti_sci_probe(struct udevice *dev)
        return ret;
 }
 
+/*
+ * ti_sci_get_free_resource() - Get a free resource from TISCI resource.
+ * @res:       Pointer to the TISCI resource
+ *
+ * Return: resource num if all went ok else TI_SCI_RESOURCE_NULL.
+ */
+u16 ti_sci_get_free_resource(struct ti_sci_resource *res)
+{
+       u16 set, free_bit;
+
+       for (set = 0; set < res->sets; set++) {
+               free_bit = find_first_zero_bit(res->desc[set].res_map,
+                                              res->desc[set].num);
+               if (free_bit != res->desc[set].num) {
+                       set_bit(free_bit, res->desc[set].res_map);
+                       return res->desc[set].start + free_bit;
+               }
+       }
+
+       return TI_SCI_RESOURCE_NULL;
+}
+
+/**
+ * ti_sci_release_resource() - Release a resource from TISCI resource.
+ * @res:       Pointer to the TISCI resource
+ */
+void ti_sci_release_resource(struct ti_sci_resource *res, u16 id)
+{
+       u16 set;
+
+       for (set = 0; set < res->sets; set++) {
+               if (res->desc[set].start <= id &&
+                   (res->desc[set].num + res->desc[set].start) > id)
+                       clear_bit(id - res->desc[set].start,
+                                 res->desc[set].res_map);
+       }
+}
+
+/**
+ * devm_ti_sci_get_of_resource() - Get a TISCI resource assigned to a device
+ * @handle:    TISCI handle
+ * @dev:       Device pointer to which the resource is assigned
+ * @of_prop:   property name by which the resource are represented
+ *
+ * Note: This function expects of_prop to be in the form of tuples
+ *     <type, subtype>. Allocates and initializes ti_sci_resource structure
+ *     for each of_prop. Client driver can directly call
+ *     ti_sci_(get_free, release)_resource apis for handling the resource.
+ *
+ * Return: Pointer to ti_sci_resource if all went well else appropriate
+ *        error pointer.
+ */
+struct ti_sci_resource *
+devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
+                           struct udevice *dev, u32 dev_id, char *of_prop)
+{
+       u32 resource_subtype;
+       u16 resource_type;
+       struct ti_sci_resource *res;
+       int sets, i, ret;
+       u32 *temp;
+
+       res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
+       if (!res)
+               return ERR_PTR(-ENOMEM);
+
+       sets = dev_read_size(dev, of_prop);
+       if (sets < 0) {
+               dev_err(dev, "%s resource type ids not available\n", of_prop);
+               return ERR_PTR(sets);
+       }
+       temp = malloc(sets);
+       sets /= sizeof(u32);
+       res->sets = sets;
+
+       res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc),
+                                GFP_KERNEL);
+       if (!res->desc)
+               return ERR_PTR(-ENOMEM);
+
+       ret = ti_sci_get_resource_type(handle_to_ti_sci_info(handle), dev_id,
+                                      &resource_type);
+       if (ret) {
+               dev_err(dev, "No valid resource type for %u\n", dev_id);
+               return ERR_PTR(-EINVAL);
+       }
+
+       ret = dev_read_u32_array(dev, of_prop, temp, res->sets);
+       if (ret)
+               return ERR_PTR(-EINVAL);
+
+       for (i = 0; i < res->sets; i++) {
+               resource_subtype = temp[i];
+               ret = handle->ops.rm_core_ops.get_range(handle, dev_id,
+                                                       resource_subtype,
+                                                       &res->desc[i].start,
+                                                       &res->desc[i].num);
+               if (ret) {
+                       dev_err(dev, "type %d subtype %d not allocated for host %d\n",
+                               resource_type, resource_subtype,
+                               handle_to_ti_sci_info(handle)->host_id);
+                       return ERR_PTR(ret);
+               }
+
+               dev_dbg(dev, "res type = %d, subtype = %d, start = %d, num = %d\n",
+                       resource_type, resource_subtype, res->desc[i].start,
+                       res->desc[i].num);
+
+               res->desc[i].res_map =
+                       devm_kzalloc(dev, BITS_TO_LONGS(res->desc[i].num) *
+                                    sizeof(*res->desc[i].res_map), GFP_KERNEL);
+               if (!res->desc[i].res_map)
+                       return ERR_PTR(-ENOMEM);
+       }
+
+       return res;
+}
+
+/* Description for K2G */
+static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
+       .default_host_id = 2,
+       /* Conservative duration */
+       .max_rx_timeout_ms = 10000,
+       /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
+       .max_msgs = 20,
+       .max_msg_size = 64,
+       .rm_type_map = NULL,
+};
+
+static struct ti_sci_rm_type_map ti_sci_am654_rm_type_map[] = {
+       {.dev_id = 56, .type = 0x00b}, /* GIC_IRQ */
+       {.dev_id = 179, .type = 0x000}, /* MAIN_NAV_UDMASS_IA0 */
+       {.dev_id = 187, .type = 0x009}, /* MAIN_NAV_RA */
+       {.dev_id = 188, .type = 0x006}, /* MAIN_NAV_UDMAP */
+       {.dev_id = 194, .type = 0x007}, /* MCU_NAV_UDMAP */
+       {.dev_id = 195, .type = 0x00a}, /* MCU_NAV_RA */
+       {.dev_id = 0, .type = 0x000}, /* end of table */
+};
+
 /* Description for AM654 */
-static const struct ti_sci_desc ti_sci_sysfw_am654_desc = {
-       .host_id = 4,
-       .max_rx_timeout_us = 1000000,
+static const struct ti_sci_desc ti_sci_pmmc_am654_desc = {
+       .default_host_id = 12,
+       /* Conservative duration */
+       .max_rx_timeout_ms = 10000,
+       /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
+       .max_msgs = 20,
        .max_msg_size = 60,
+       .rm_type_map = ti_sci_am654_rm_type_map,
 };
 
 static const struct udevice_id ti_sci_ids[] = {
        {
                .compatible = "ti,k2g-sci",
-               .data = (ulong)&ti_sci_sysfw_am654_desc
+               .data = (ulong)&ti_sci_pmmc_k2g_desc
+       },
+       {
+               .compatible = "ti,am654-sci",
+               .data = (ulong)&ti_sci_pmmc_am654_desc
        },
        { /* Sentinel */ },
 };
index 81591fb0c71f784094ce6e31d694e2ba1eeffce9..2d87cdd2cf96a0d66c31bdb6cee9f9acf97c5cb2 100644 (file)
@@ -25,6 +25,7 @@
 #define TI_SCI_MSG_BOARD_CONFIG_RM     0x000c
 #define TI_SCI_MSG_BOARD_CONFIG_SECURITY  0x000d
 #define TI_SCI_MSG_BOARD_CONFIG_PM     0x000e
+#define TISCI_MSG_QUERY_MSMC           0x0020
 
 /* Device requests */
 #define TI_SCI_MSG_SET_DEVICE_STATE    0x0200
 #define TISCI_MSG_PROC_AUTH_BOOT_IMIAGE        0xc120
 #define TISCI_MSG_GET_PROC_BOOT_STATUS 0xc400
 
+/* Resource Management Requests */
+#define TI_SCI_MSG_GET_RESOURCE_RANGE  0x1500
+
+/* NAVSS resource management */
+/* Ringacc requests */
+#define TI_SCI_MSG_RM_RING_CFG                 0x1110
+#define TI_SCI_MSG_RM_RING_GET_CFG             0x1111
+
+/* PSI-L requests */
+#define TI_SCI_MSG_RM_PSIL_PAIR                        0x1280
+#define TI_SCI_MSG_RM_PSIL_UNPAIR              0x1281
+
+#define TI_SCI_MSG_RM_UDMAP_TX_ALLOC           0x1200
+#define TI_SCI_MSG_RM_UDMAP_TX_FREE            0x1201
+#define TI_SCI_MSG_RM_UDMAP_RX_ALLOC           0x1210
+#define TI_SCI_MSG_RM_UDMAP_RX_FREE            0x1211
+#define TI_SCI_MSG_RM_UDMAP_FLOW_CFG           0x1220
+#define TI_SCI_MSG_RM_UDMAP_OPT_FLOW_CFG       0x1221
+
+#define TISCI_MSG_RM_UDMAP_TX_CH_CFG           0x1205
+#define TISCI_MSG_RM_UDMAP_TX_CH_GET_CFG       0x1206
+#define TISCI_MSG_RM_UDMAP_RX_CH_CFG           0x1215
+#define TISCI_MSG_RM_UDMAP_RX_CH_GET_CFG       0x1216
+#define TISCI_MSG_RM_UDMAP_FLOW_CFG            0x1230
+#define TISCI_MSG_RM_UDMAP_FLOW_SIZE_THRESH_CFG        0x1231
+#define TISCI_MSG_RM_UDMAP_FLOW_GET_CFG                0x1232
+#define TISCI_MSG_RM_UDMAP_FLOW_SIZE_THRESH_GET_CFG    0x1233
+
 /**
  * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses
  * @type:      Type of messages: One of TI_SCI_MSG* values
@@ -133,6 +162,24 @@ struct ti_sci_msg_board_config {
        u16 boardcfg_size;
 } __packed;
 
+/**
+ * struct ti_sci_msg_resp_query_msmc - Query msmc message response structure
+ * @hdr:               Generic Header
+ * @msmc_start_low:    Lower 32 bit of msmc start
+ * @msmc_start_high:   Upper 32 bit of msmc start
+ * @msmc_end_low:      Lower 32 bit of msmc end
+ * @msmc_end_high:     Upper 32 bit of msmc end
+ *
+ * Response to a generic message with message type TISCI_MSG_QUERY_MSMC
+ */
+struct ti_sci_msg_resp_query_msmc {
+       struct ti_sci_msg_hdr hdr;
+       u32 msmc_start_low;
+       u32 msmc_start_high;
+       u32 msmc_end_low;
+       u32 msmc_end_high;
+} __packed;
+
 /**
  * struct ti_sci_msg_req_set_device_state - Set the desired state of the device
  * @hdr:               Generic header
@@ -505,6 +552,45 @@ struct ti_sci_msg_resp_get_clock_freq {
        u64 freq_hz;
 } __packed;
 
+#define TI_SCI_IRQ_SECONDARY_HOST_INVALID      0xff
+
+/**
+ * struct ti_sci_msg_req_get_resource_range - Request to get a host's assigned
+ *                                           range of resources.
+ * @hdr:               Generic Header
+ * @type:              Unique resource assignment type
+ * @subtype:           Resource assignment subtype within the resource type.
+ * @secondary_host:    Host processing entity to which the resources are
+ *                     allocated. This is required only when the destination
+ *                     host id id different from ti sci interface host id,
+ *                     else TI_SCI_IRQ_SECONDARY_HOST_INVALID can be passed.
+ *
+ * Request type is TI_SCI_MSG_GET_RESOURCE_RANGE. Responded with requested
+ * resource range which is of type TI_SCI_MSG_GET_RESOURCE_RANGE.
+ */
+struct ti_sci_msg_req_get_resource_range {
+       struct ti_sci_msg_hdr hdr;
+#define MSG_RM_RESOURCE_TYPE_MASK      GENMASK(9, 0)
+#define MSG_RM_RESOURCE_SUBTYPE_MASK   GENMASK(5, 0)
+       u16 type;
+       u8 subtype;
+       u8 secondary_host;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_get_resource_range - Response to resource get range.
+ * @hdr:               Generic Header
+ * @range_start:       Start index of the resource range.
+ * @range_num:         Number of resources in the range.
+ *
+ * Response to request TI_SCI_MSG_GET_RESOURCE_RANGE.
+ */
+struct ti_sci_msg_resp_get_resource_range {
+       struct ti_sci_msg_hdr hdr;
+       u16 range_start;
+       u16 range_num;
+} __packed;
+
 #define TISCI_ADDR_LOW_MASK            GENMASK_ULL(31, 0)
 #define TISCI_ADDR_HIGH_MASK           GENMASK_ULL(63, 32)
 #define TISCI_ADDR_HIGH_SHIFT          32
@@ -677,4 +763,579 @@ struct ti_sci_msg_resp_get_proc_boot_status {
        u32 status_flags;
 } __packed;
 
+/**
+ * struct ti_sci_msg_rm_ring_cfg_req - Configure a Navigator Subsystem ring
+ *
+ * Configures the non-real-time registers of a Navigator Subsystem ring.
+ * @hdr:       Generic Header
+ * @valid_params: Bitfield defining validity of ring configuration parameters.
+ *     The ring configuration fields are not valid, and will not be used for
+ *     ring configuration, if their corresponding valid bit is zero.
+ *     Valid bit usage:
+ *     0 - Valid bit for @tisci_msg_rm_ring_cfg_req addr_lo
+ *     1 - Valid bit for @tisci_msg_rm_ring_cfg_req addr_hi
+ *     2 - Valid bit for @tisci_msg_rm_ring_cfg_req count
+ *     3 - Valid bit for @tisci_msg_rm_ring_cfg_req mode
+ *     4 - Valid bit for @tisci_msg_rm_ring_cfg_req size
+ *     5 - Valid bit for @tisci_msg_rm_ring_cfg_req order_id
+ * @nav_id: Device ID of Navigator Subsystem from which the ring is allocated
+ * @index: ring index to be configured.
+ * @addr_lo: 32 LSBs of ring base address to be programmed into the ring's
+ *     RING_BA_LO register
+ * @addr_hi: 16 MSBs of ring base address to be programmed into the ring's
+ *     RING_BA_HI register.
+ * @count: Number of ring elements. Must be even if mode is CREDENTIALS or QM
+ *     modes.
+ * @mode: Specifies the mode the ring is to be configured.
+ * @size: Specifies encoded ring element size. To calculate the encoded size use
+ *     the formula (log2(size_bytes) - 2), where size_bytes cannot be
+ *     greater than 256.
+ * @order_id: Specifies the ring's bus order ID.
+ */
+struct ti_sci_msg_rm_ring_cfg_req {
+       struct ti_sci_msg_hdr hdr;
+       u32 valid_params;
+       u16 nav_id;
+       u16 index;
+       u32 addr_lo;
+       u32 addr_hi;
+       u32 count;
+       u8 mode;
+       u8 size;
+       u8 order_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_rm_ring_cfg_resp - Response to configuring a ring.
+ *
+ * @hdr:       Generic Header
+ */
+struct ti_sci_msg_rm_ring_cfg_resp {
+       struct ti_sci_msg_hdr hdr;
+} __packed;
+
+/**
+ * struct ti_sci_msg_rm_ring_get_cfg_req - Get RA ring's configuration
+ *
+ * Gets the configuration of the non-real-time register fields of a ring.  The
+ * host, or a supervisor of the host, who owns the ring must be the requesting
+ * host.  The values of the non-real-time registers are returned in
+ * @ti_sci_msg_rm_ring_get_cfg_resp.
+ *
+ * @hdr: Generic Header
+ * @nav_id: Device ID of Navigator Subsystem from which the ring is allocated
+ * @index: ring index.
+ */
+struct ti_sci_msg_rm_ring_get_cfg_req {
+       struct ti_sci_msg_hdr hdr;
+       u16 nav_id;
+       u16 index;
+} __packed;
+
+/**
+ * struct ti_sci_msg_rm_ring_get_cfg_resp -  Ring get configuration response
+ *
+ * Response received by host processor after RM has handled
+ * @ti_sci_msg_rm_ring_get_cfg_req. The response contains the ring's
+ * non-real-time register values.
+ *
+ * @hdr: Generic Header
+ * @addr_lo: Ring 32 LSBs of base address
+ * @addr_hi: Ring 16 MSBs of base address.
+ * @count: Ring number of elements.
+ * @mode: Ring mode.
+ * @size: encoded Ring element size
+ * @order_id: ing order ID.
+ */
+struct ti_sci_msg_rm_ring_get_cfg_resp {
+       struct ti_sci_msg_hdr hdr;
+       u32 addr_lo;
+       u32 addr_hi;
+       u32 count;
+       u8 mode;
+       u8 size;
+       u8 order_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_psil_pair - Pairs a PSI-L source thread to a destination
+ *                              thread
+ * @hdr:       Generic Header
+ * @nav_id:    SoC Navigator Subsystem device ID whose PSI-L config proxy is
+ *             used to pair the source and destination threads.
+ * @src_thread:        PSI-L source thread ID within the PSI-L System thread map.
+ *
+ * UDMAP transmit channels mapped to source threads will have their
+ * TCHAN_THRD_ID register programmed with the destination thread if the pairing
+ * is successful.
+
+ * @dst_thread: PSI-L destination thread ID within the PSI-L System thread map.
+ * PSI-L destination threads start at index 0x8000.  The request is NACK'd if
+ * the destination thread is not greater than or equal to 0x8000.
+ *
+ * UDMAP receive channels mapped to destination threads will have their
+ * RCHAN_THRD_ID register programmed with the source thread if the pairing
+ * is successful.
+ *
+ * Request type is TI_SCI_MSG_RM_PSIL_PAIR, response is a generic ACK or NACK
+ * message.
+ */
+struct ti_sci_msg_psil_pair {
+       struct ti_sci_msg_hdr hdr;
+       u32 nav_id;
+       u32 src_thread;
+       u32 dst_thread;
+} __packed;
+
+/**
+ * struct ti_sci_msg_psil_unpair - Unpairs a PSI-L source thread from a
+ *                                destination thread
+ * @hdr:       Generic Header
+ * @nav_id:    SoC Navigator Subsystem device ID whose PSI-L config proxy is
+ *             used to unpair the source and destination threads.
+ * @src_thread:        PSI-L source thread ID within the PSI-L System thread map.
+ *
+ * UDMAP transmit channels mapped to source threads will have their
+ * TCHAN_THRD_ID register cleared if the unpairing is successful.
+ *
+ * @dst_thread: PSI-L destination thread ID within the PSI-L System thread map.
+ * PSI-L destination threads start at index 0x8000.  The request is NACK'd if
+ * the destination thread is not greater than or equal to 0x8000.
+ *
+ * UDMAP receive channels mapped to destination threads will have their
+ * RCHAN_THRD_ID register cleared if the unpairing is successful.
+ *
+ * Request type is TI_SCI_MSG_RM_PSIL_UNPAIR, response is a generic ACK or NACK
+ * message.
+ */
+struct ti_sci_msg_psil_unpair {
+       struct ti_sci_msg_hdr hdr;
+       u32 nav_id;
+       u32 src_thread;
+       u32 dst_thread;
+} __packed;
+
+/**
+ * Configures a Navigator Subsystem UDMAP transmit channel
+ *
+ * Configures the non-real-time registers of a Navigator Subsystem UDMAP
+ * transmit channel.  The channel index must be assigned to the host defined
+ * in the TISCI header via the RM board configuration resource assignment
+ * range list.
+ *
+ * @hdr: Generic Header
+ *
+ * @valid_params: Bitfield defining validity of tx channel configuration
+ * parameters. The tx channel configuration fields are not valid, and will not
+ * be used for ch configuration, if their corresponding valid bit is zero.
+ * Valid bit usage:
+ *    0 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_pause_on_err
+ *    1 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_atype
+ *    2 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_chan_type
+ *    3 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_fetch_size
+ *    4 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::txcq_qnum
+ *    5 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_priority
+ *    6 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_qos
+ *    7 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_orderid
+ *    8 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_sched_priority
+ *    9 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_filt_einfo
+ *   10 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_filt_pswords
+ *   11 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_supr_tdpkt
+ *   12 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::tx_credit_count
+ *   13 - Valid bit for @ref ti_sci_msg_rm_udmap_tx_ch_cfg::fdepth
+ *
+ * @nav_id: SoC device ID of Navigator Subsystem where tx channel is located
+ *
+ * @index: UDMAP transmit channel index.
+ *
+ * @tx_pause_on_err: UDMAP transmit channel pause on error configuration to
+ * be programmed into the tx_pause_on_err field of the channel's TCHAN_TCFG
+ * register.
+ *
+ * @tx_filt_einfo: UDMAP transmit channel extended packet information passing
+ * configuration to be programmed into the tx_filt_einfo field of the
+ * channel's TCHAN_TCFG register.
+ *
+ * @tx_filt_pswords: UDMAP transmit channel protocol specific word passing
+ * configuration to be programmed into the tx_filt_pswords field of the
+ * channel's TCHAN_TCFG register.
+ *
+ * @tx_atype: UDMAP transmit channel non Ring Accelerator access pointer
+ * interpretation configuration to be programmed into the tx_atype field of
+ * the channel's TCHAN_TCFG register.
+ *
+ * @tx_chan_type: UDMAP transmit channel functional channel type and work
+ * passing mechanism configuration to be programmed into the tx_chan_type
+ * field of the channel's TCHAN_TCFG register.
+ *
+ * @tx_supr_tdpkt: UDMAP transmit channel teardown packet generation suppression
+ * configuration to be programmed into the tx_supr_tdpkt field of the channel's
+ * TCHAN_TCFG register.
+ *
+ * @tx_fetch_size: UDMAP transmit channel number of 32-bit descriptor words to
+ * fetch configuration to be programmed into the tx_fetch_size field of the
+ * channel's TCHAN_TCFG register.  The user must make sure to set the maximum
+ * word count that can pass through the channel for any allowed descriptor type.
+ *
+ * @tx_credit_count: UDMAP transmit channel transfer request credit count
+ * configuration to be programmed into the count field of the TCHAN_TCREDIT
+ * register.  Specifies how many credits for complete TRs are available.
+ *
+ * @txcq_qnum: UDMAP transmit channel completion queue configuration to be
+ * programmed into the txcq_qnum field of the TCHAN_TCQ register. The specified
+ * completion queue must be assigned to the host, or a subordinate of the host,
+ * requesting configuration of the transmit channel.
+ *
+ * @tx_priority: UDMAP transmit channel transmit priority value to be programmed
+ * into the priority field of the channel's TCHAN_TPRI_CTRL register.
+ *
+ * @tx_qos: UDMAP transmit channel transmit qos value to be programmed into the
+ * qos field of the channel's TCHAN_TPRI_CTRL register.
+ *
+ * @tx_orderid: UDMAP transmit channel bus order id value to be programmed into
+ * the orderid field of the channel's TCHAN_TPRI_CTRL register.
+ *
+ * @fdepth: UDMAP transmit channel FIFO depth configuration to be programmed
+ * into the fdepth field of the TCHAN_TFIFO_DEPTH register. Sets the number of
+ * Tx FIFO bytes which are allowed to be stored for the channel. Check the UDMAP
+ * section of the TRM for restrictions regarding this parameter.
+ *
+ * @tx_sched_priority: UDMAP transmit channel tx scheduling priority
+ * configuration to be programmed into the priority field of the channel's
+ * TCHAN_TST_SCHED register.
+ */
+struct ti_sci_msg_rm_udmap_tx_ch_cfg_req {
+       struct ti_sci_msg_hdr hdr;
+       u32 valid_params;
+       u16 nav_id;
+       u16 index;
+       u8 tx_pause_on_err;
+       u8 tx_filt_einfo;
+       u8 tx_filt_pswords;
+       u8 tx_atype;
+       u8 tx_chan_type;
+       u8 tx_supr_tdpkt;
+       u16 tx_fetch_size;
+       u8 tx_credit_count;
+       u16 txcq_qnum;
+       u8 tx_priority;
+       u8 tx_qos;
+       u8 tx_orderid;
+       u16 fdepth;
+       u8 tx_sched_priority;
+} __packed;
+
+/**
+ *  Response to configuring a UDMAP transmit channel.
+ *
+ * @hdr: Standard TISCI header
+ */
+struct ti_sci_msg_rm_udmap_tx_ch_cfg_resp {
+       struct ti_sci_msg_hdr hdr;
+} __packed;
+
+/**
+ * Configures a Navigator Subsystem UDMAP receive channel
+ *
+ * Configures the non-real-time registers of a Navigator Subsystem UDMAP
+ * receive channel.  The channel index must be assigned to the host defined
+ * in the TISCI header via the RM board configuration resource assignment
+ * range list.
+ *
+ * @hdr: Generic Header
+ *
+ * @valid_params: Bitfield defining validity of rx channel configuration
+ * parameters.
+ * The rx channel configuration fields are not valid, and will not be used for
+ * ch configuration, if their corresponding valid bit is zero.
+ * Valid bit usage:
+ *    0 - Valid bit for @ti_sci_msg_rm_udmap_rx_ch_cfg_req::rx_pause_on_err
+ *    1 - Valid bit for @ti_sci_msg_rm_udmap_rx_ch_cfg_req::rx_atype
+ *    2 - Valid bit for @ti_sci_msg_rm_udmap_rx_ch_cfg_req::rx_chan_type
+ *    3 - Valid bit for @ti_sci_msg_rm_udmap_rx_ch_cfg_req::rx_fetch_size
+ *    4 - Valid bit for @ti_sci_msg_rm_udmap_rx_ch_cfg_req::rxcq_qnum
+ *    5 - Valid bit for @ti_sci_msg_rm_udmap_rx_ch_cfg_req::rx_priority
+ *    6 - Valid bit for @ti_sci_msg_rm_udmap_rx_ch_cfg_req::rx_qos
+ *    7 - Valid bit for @ti_sci_msg_rm_udmap_rx_ch_cfg_req::rx_orderid
+ *    8 - Valid bit for @ti_sci_msg_rm_udmap_rx_ch_cfg_req::rx_sched_priority
+ *    9 - Valid bit for @ti_sci_msg_rm_udmap_rx_ch_cfg_req::flowid_start
+ *   10 - Valid bit for @ti_sci_msg_rm_udmap_rx_ch_cfg_req::flowid_cnt
+ *   11 - Valid bit for @ti_sci_msg_rm_udmap_rx_ch_cfg_req::rx_ignore_short
+ *   12 - Valid bit for @ti_sci_msg_rm_udmap_rx_ch_cfg_req::rx_ignore_long
+ *
+ * @nav_id: SoC device ID of Navigator Subsystem where rx channel is located
+ *
+ * @index: UDMAP receive channel index.
+ *
+ * @rx_fetch_size: UDMAP receive channel number of 32-bit descriptor words to
+ * fetch configuration to be programmed into the rx_fetch_size field of the
+ * channel's RCHAN_RCFG register.
+ *
+ * @rxcq_qnum: UDMAP receive channel completion queue configuration to be
+ * programmed into the rxcq_qnum field of the RCHAN_RCQ register.
+ * The specified completion queue must be assigned to the host, or a subordinate
+ * of the host, requesting configuration of the receive channel.
+ *
+ * @rx_priority: UDMAP receive channel receive priority value to be programmed
+ * into the priority field of the channel's RCHAN_RPRI_CTRL register.
+ *
+ * @rx_qos: UDMAP receive channel receive qos value to be programmed into the
+ * qos field of the channel's RCHAN_RPRI_CTRL register.
+ *
+ * @rx_orderid: UDMAP receive channel bus order id value to be programmed into
+ * the orderid field of the channel's RCHAN_RPRI_CTRL register.
+ *
+ * @rx_sched_priority: UDMAP receive channel rx scheduling priority
+ * configuration to be programmed into the priority field of the channel's
+ * RCHAN_RST_SCHED register.
+ *
+ * @flowid_start: UDMAP receive channel additional flows starting index
+ * configuration to program into the flow_start field of the RCHAN_RFLOW_RNG
+ * register. Specifies the starting index for flow IDs the receive channel is to
+ * make use of beyond the default flow. flowid_start and @ref flowid_cnt must be
+ * set as valid and configured together. The starting flow ID set by
+ * @ref flowid_cnt must be a flow index within the Navigator Subsystem's subset
+ * of flows beyond the default flows statically mapped to receive channels.
+ * The additional flows must be assigned to the host, or a subordinate of the
+ * host, requesting configuration of the receive channel.
+ *
+ * @flowid_cnt: UDMAP receive channel additional flows count configuration to
+ * program into the flowid_cnt field of the RCHAN_RFLOW_RNG register.
+ * This field specifies how many flow IDs are in the additional contiguous range
+ * of legal flow IDs for the channel.  @ref flowid_start and flowid_cnt must be
+ * set as valid and configured together. Disabling the valid_params field bit
+ * for flowid_cnt indicates no flow IDs other than the default are to be
+ * allocated and used by the receive channel. @ref flowid_start plus flowid_cnt
+ * cannot be greater than the number of receive flows in the receive channel's
+ * Navigator Subsystem.  The additional flows must be assigned to the host, or a
+ * subordinate of the host, requesting configuration of the receive channel.
+ *
+ * @rx_pause_on_err: UDMAP receive channel pause on error configuration to be
+ * programmed into the rx_pause_on_err field of the channel's RCHAN_RCFG
+ * register.
+ *
+ * @rx_atype: UDMAP receive channel non Ring Accelerator access pointer
+ * interpretation configuration to be programmed into the rx_atype field of the
+ * channel's RCHAN_RCFG register.
+ *
+ * @rx_chan_type: UDMAP receive channel functional channel type and work passing
+ * mechanism configuration to be programmed into the rx_chan_type field of the
+ * channel's RCHAN_RCFG register.
+ *
+ * @rx_ignore_short: UDMAP receive channel short packet treatment configuration
+ * to be programmed into the rx_ignore_short field of the RCHAN_RCFG register.
+ *
+ * @rx_ignore_long: UDMAP receive channel long packet treatment configuration to
+ * be programmed into the rx_ignore_long field of the RCHAN_RCFG register.
+ */
+struct ti_sci_msg_rm_udmap_rx_ch_cfg_req {
+       struct ti_sci_msg_hdr hdr;
+       u32 valid_params;
+       u16 nav_id;
+       u16 index;
+       u16 rx_fetch_size;
+       u16 rxcq_qnum;
+       u8 rx_priority;
+       u8 rx_qos;
+       u8 rx_orderid;
+       u8 rx_sched_priority;
+       u16 flowid_start;
+       u16 flowid_cnt;
+       u8 rx_pause_on_err;
+       u8 rx_atype;
+       u8 rx_chan_type;
+       u8 rx_ignore_short;
+       u8 rx_ignore_long;
+} __packed;
+
+/**
+ * Response to configuring a UDMAP receive channel.
+ *
+ * @hdr: Standard TISCI header
+ */
+struct ti_sci_msg_rm_udmap_rx_ch_cfg_resp {
+       struct ti_sci_msg_hdr hdr;
+} __packed;
+
+/**
+ * Configures a Navigator Subsystem UDMAP receive flow
+ *
+ * Configures a Navigator Subsystem UDMAP receive flow's registers.
+ * Configuration does not include the flow registers which handle size-based
+ * free descriptor queue routing.
+ *
+ * The flow index must be assigned to the host defined in the TISCI header via
+ * the RM board configuration resource assignment range list.
+ *
+ * @hdr: Standard TISCI header
+ *
+ * @valid_params
+ * Bitfield defining validity of rx flow configuration parameters.  The
+ * rx flow configuration fields are not valid, and will not be used for flow
+ * configuration, if their corresponding valid bit is zero.  Valid bit usage:
+ *     0 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_einfo_present
+ *     1 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_psinfo_present
+ *     2 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_error_handling
+ *     3 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_desc_type
+ *     4 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_sop_offset
+ *     5 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_dest_qnum
+ *     6 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_src_tag_hi
+ *     7 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_src_tag_lo
+ *     8 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_dest_tag_hi
+ *     9 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_dest_tag_lo
+ *    10 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_src_tag_hi_sel
+ *    11 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_src_tag_lo_sel
+ *    12 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_dest_tag_hi_sel
+ *    13 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_dest_tag_lo_sel
+ *    14 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_fdq0_sz0_qnum
+ *    15 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_fdq1_sz0_qnum
+ *    16 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_fdq2_sz0_qnum
+ *    17 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_fdq3_sz0_qnum
+ *    18 - Valid bit for @tisci_msg_rm_udmap_flow_cfg_req::rx_ps_location
+ *
+ * @nav_id: SoC device ID of Navigator Subsystem from which the receive flow is
+ * allocated
+ *
+ * @flow_index: UDMAP receive flow index for non-optional configuration.
+ *
+ * @rx_einfo_present:
+ * UDMAP receive flow extended packet info present configuration to be
+ * programmed into the rx_einfo_present field of the flow's RFLOW_RFA register.
+ *
+ * @rx_psinfo_present:
+ * UDMAP receive flow PS words present configuration to be programmed into the
+ * rx_psinfo_present field of the flow's RFLOW_RFA register.
+ *
+ * @rx_error_handling:
+ * UDMAP receive flow error handling configuration to be programmed into the
+ * rx_error_handling field of the flow's RFLOW_RFA register.
+ *
+ * @rx_desc_type:
+ * UDMAP receive flow descriptor type configuration to be programmed into the
+ * rx_desc_type field field of the flow's RFLOW_RFA register.
+ *
+ * @rx_sop_offset:
+ * UDMAP receive flow start of packet offset configuration to be programmed
+ * into the rx_sop_offset field of the RFLOW_RFA register.  See the UDMAP
+ * section of the TRM for more information on this setting.  Valid values for
+ * this field are 0-255 bytes.
+ *
+ * @rx_dest_qnum:
+ * UDMAP receive flow destination queue configuration to be programmed into the
+ * rx_dest_qnum field of the flow's RFLOW_RFA register.  The specified
+ * destination queue must be valid within the Navigator Subsystem and must be
+ * owned by the host, or a subordinate of the host, requesting allocation and
+ * configuration of the receive flow.
+ *
+ * @rx_src_tag_hi:
+ * UDMAP receive flow source tag high byte constant configuration to be
+ * programmed into the rx_src_tag_hi field of the flow's RFLOW_RFB register.
+ * See the UDMAP section of the TRM for more information on this setting.
+ *
+ * @rx_src_tag_lo:
+ * UDMAP receive flow source tag low byte constant configuration to be
+ * programmed into the rx_src_tag_lo field of the flow's RFLOW_RFB register.
+ * See the UDMAP section of the TRM for more information on this setting.
+ *
+ * @rx_dest_tag_hi:
+ * UDMAP receive flow destination tag high byte constant configuration to be
+ * programmed into the rx_dest_tag_hi field of the flow's RFLOW_RFB register.
+ * See the UDMAP section of the TRM for more information on this setting.
+ *
+ * @rx_dest_tag_lo:
+ * UDMAP receive flow destination tag low byte constant configuration to be
+ * programmed into the rx_dest_tag_lo field of the flow's RFLOW_RFB register.
+ * See the UDMAP section of the TRM for more information on this setting.
+ *
+ * @rx_src_tag_hi_sel:
+ * UDMAP receive flow source tag high byte selector configuration to be
+ * programmed into the rx_src_tag_hi_sel field of the RFLOW_RFC register.  See
+ * the UDMAP section of the TRM for more information on this setting.
+ *
+ * @rx_src_tag_lo_sel:
+ * UDMAP receive flow source tag low byte selector configuration to be
+ * programmed into the rx_src_tag_lo_sel field of the RFLOW_RFC register.  See
+ * the UDMAP section of the TRM for more information on this setting.
+ *
+ * @rx_dest_tag_hi_sel:
+ * UDMAP receive flow destination tag high byte selector configuration to be
+ * programmed into the rx_dest_tag_hi_sel field of the RFLOW_RFC register.  See
+ * the UDMAP section of the TRM for more information on this setting.
+ *
+ * @rx_dest_tag_lo_sel:
+ * UDMAP receive flow destination tag low byte selector configuration to be
+ * programmed into the rx_dest_tag_lo_sel field of the RFLOW_RFC register.  See
+ * the UDMAP section of the TRM for more information on this setting.
+ *
+ * @rx_fdq0_sz0_qnum:
+ * UDMAP receive flow free descriptor queue 0 configuration to be programmed
+ * into the rx_fdq0_sz0_qnum field of the flow's RFLOW_RFD register.  See the
+ * UDMAP section of the TRM for more information on this setting. The specified
+ * free queue must be valid within the Navigator Subsystem and must be owned
+ * by the host, or a subordinate of the host, requesting allocation and
+ * configuration of the receive flow.
+ *
+ * @rx_fdq1_qnum:
+ * UDMAP receive flow free descriptor queue 1 configuration to be programmed
+ * into the rx_fdq1_qnum field of the flow's RFLOW_RFD register.  See the
+ * UDMAP section of the TRM for more information on this setting.  The specified
+ * free queue must be valid within the Navigator Subsystem and must be owned
+ * by the host, or a subordinate of the host, requesting allocation and
+ * configuration of the receive flow.
+ *
+ * @rx_fdq2_qnum:
+ * UDMAP receive flow free descriptor queue 2 configuration to be programmed
+ * into the rx_fdq2_qnum field of the flow's RFLOW_RFE register.  See the
+ * UDMAP section of the TRM for more information on this setting.  The specified
+ * free queue must be valid within the Navigator Subsystem and must be owned
+ * by the host, or a subordinate of the host, requesting allocation and
+ * configuration of the receive flow.
+ *
+ * @rx_fdq3_qnum:
+ * UDMAP receive flow free descriptor queue 3 configuration to be programmed
+ * into the rx_fdq3_qnum field of the flow's RFLOW_RFE register.  See the
+ * UDMAP section of the TRM for more information on this setting.  The specified
+ * free queue must be valid within the Navigator Subsystem and must be owned
+ * by the host, or a subordinate of the host, requesting allocation and
+ * configuration of the receive flow.
+ *
+ * @rx_ps_location:
+ * UDMAP receive flow PS words location configuration to be programmed into the
+ * rx_ps_location field of the flow's RFLOW_RFA register.
+ */
+struct ti_sci_msg_rm_udmap_flow_cfg_req {
+       struct ti_sci_msg_hdr hdr;
+       u32 valid_params;
+       u16 nav_id;
+       u16 flow_index;
+       u8 rx_einfo_present;
+       u8 rx_psinfo_present;
+       u8 rx_error_handling;
+       u8 rx_desc_type;
+       u16 rx_sop_offset;
+       u16 rx_dest_qnum;
+       u8 rx_src_tag_hi;
+       u8 rx_src_tag_lo;
+       u8 rx_dest_tag_hi;
+       u8 rx_dest_tag_lo;
+       u8 rx_src_tag_hi_sel;
+       u8 rx_src_tag_lo_sel;
+       u8 rx_dest_tag_hi_sel;
+       u8 rx_dest_tag_lo_sel;
+       u16 rx_fdq0_sz0_qnum;
+       u16 rx_fdq1_qnum;
+       u16 rx_fdq2_qnum;
+       u16 rx_fdq3_qnum;
+       u8 rx_ps_location;
+} __packed;
+
+/**
+ *  Response to configuring a Navigator Subsystem UDMAP receive flow
+ *
+ * @hdr: Standard TISCI header
+ */
+struct ti_sci_msg_rm_udmap_flow_cfg_resp {
+       struct ti_sci_msg_hdr hdr;
+} __packed;
+
 #endif /* __TI_SCI_H */
index b103180cf3778f103575d7a7d740525993070a78..b3e4ecc50e1e23b5a66e152b5e6acd2359645f74 100644 (file)
@@ -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.
 
index d1f6cfa8405d6f0e4ae9ff184f8fc3dfa37e7904..71a978cf4077880b18ecef073b166c5e4ef34d84 100644 (file)
@@ -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;
index 49e23a0a4bf20d1662abfecf30cfe90c843bed59..e47abf18333f4452b31c8662e4160358ab4b575f 100644 (file)
@@ -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),
index b0da67ce2c6b592009fb52200a30e39d19f11eaa..68f15261be771ca24fbe2d1c19776d69e4daf9af 100644 (file)
@@ -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"
index bd4e9abe5f3c0ca6d913aed522e3dcc868ff6e25..a630ce991d04e3c5407e0a1bc23add78af2a442c 100644 (file)
@@ -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 },
index 9999d9fe5e4bd01fd5155a307b91017f0328eabe..5420afbc8e0de91b7f7529a94217ca1c2643dd52 100644 (file)
@@ -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);
index 29ad87c1d7b4b865e8c8170e8f83541f4da5ccd4..f25d0540075d55db29ba8eb256034146fbcd24a7 100644 (file)
@@ -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;
index 33943a231b1008e935f741e7de9e35cd88d03f4f..8dc246b0dbe8292fc2991634f61d1a1203407252 100644 (file)
@@ -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);
index 826a39fad7256703471df372f14179b2db4f8a44..133cdc135278884798ddd8c83f0012c516704437 100644 (file)
@@ -264,7 +264,7 @@ static unsigned char mmc_board_init(struct mmc *mmc)
        !CONFIG_IS_ENABLED(DM_REGULATOR)
        /* PBIAS config needed for MMC1 only */
        if (mmc_get_blk_desc(mmc)->devnum == 0)
-               vmmc_pbias_config(LDO_VOLT_3V0);
+               vmmc_pbias_config(LDO_VOLT_3V3);
 #endif
 
        return 0;
@@ -418,7 +418,7 @@ static void omap_hsmmc_conf_bus_power(struct mmc *mmc, uint signal_voltage)
 
        switch (signal_voltage) {
        case MMC_SIGNAL_VOLTAGE_330:
-               hctl |= SDVS_3V0;
+               hctl |= SDVS_3V3;
                break;
        case MMC_SIGNAL_VOLTAGE_180:
                hctl |= SDVS_1V8;
@@ -514,10 +514,9 @@ static int omap_hsmmc_set_signal_voltage(struct mmc *mmc)
                return -EINVAL;
 
        if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
-               /* Use 3.0V rather than 3.3V */
-               mv = 3000;
-               capa_mask = VS30_3V0SUP;
-               palmas_ldo_volt = LDO_VOLT_3V0;
+               mv = 3300;
+               capa_mask = VS33_3V3SUP;
+               palmas_ldo_volt = LDO_VOLT_3V3;
        } else if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
                capa_mask = VS18_1V8SUP;
                palmas_ldo_volt = LDO_VOLT_1V8;
@@ -556,13 +555,13 @@ static uint32_t omap_hsmmc_set_capabilities(struct mmc *mmc)
        val = readl(&mmc_base->capa);
 
        if (priv->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) {
-               val |= (VS30_3V0SUP | VS18_1V8SUP);
+               val |= (VS33_3V3SUP | VS18_1V8SUP);
        } else if (priv->controller_flags & OMAP_HSMMC_NO_1_8_V) {
-               val |= VS30_3V0SUP;
+               val |= VS33_3V3SUP;
                val &= ~VS18_1V8SUP;
        } else {
                val |= VS18_1V8SUP;
-               val &= ~VS30_3V0SUP;
+               val &= ~VS33_3V3SUP;
        }
 
        writel(val, &mmc_base->capa);
@@ -842,11 +841,11 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)
 
 #if CONFIG_IS_ENABLED(DM_MMC)
        reg_val = omap_hsmmc_set_capabilities(mmc);
-       omap_hsmmc_conf_bus_power(mmc, (reg_val & VS30_3V0SUP) ?
+       omap_hsmmc_conf_bus_power(mmc, (reg_val & VS33_3V3SUP) ?
                          MMC_SIGNAL_VOLTAGE_330 : MMC_SIGNAL_VOLTAGE_180);
 #else
        writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl);
-       writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP,
+       writel(readl(&mmc_base->capa) | VS33_3V3SUP | VS18_1V8SUP,
                &mmc_base->capa);
 #endif
 
index 7f76e5ecef4fd20f039cc3760be27dd6a42a6460..dc087ab641e6d3e4087a1062972bcb6905d89140 100644 (file)
@@ -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
index c61e3f38391aeb9027fd1599805d91e88c7eb2a9..b10e718d150c2d1afc8cb7ec480e614333d41795 100644 (file)
@@ -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 (file)
index 0000000..2bb749d
--- /dev/null
@@ -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);
+}
index 8146c3170e1643e293cb2e22d0e06fbed00718eb..7f1dee4b3e4d5b9e6a5b35cf34dde9f6136f05a0 100644 (file)
@@ -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, &reg);
+       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, &reg);
+       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, &reg);
+               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, &reg);
+       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, &reg);
+       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, &reg);
+       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, &reg);
+                       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, &reg);
+               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, &reg);
+               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, &reg);
+       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, &reg);
+       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 },
        { }
 };
 
index 88e5a97c4bfa982ae16c726b4d40d2c3f9cb9836..6359d0b61015915b7a0f63cdff9bd056e77fed3f 100644 (file)
@@ -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.
index 751a839a5f00b1208f60a808b8f1552a876d5299..bffd8ec77b0f6a11f00c12db1df91ac9b3f6be24 100644 (file)
@@ -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 (file)
index 0000000..60d408f
--- /dev/null
@@ -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),
+};
index bf08c35ba04ffc8297926c1acd55755ee6c72f54..815c2da26469c54ff26388316b8ad7081bf19e5c 100644 (file)
@@ -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 (file)
index 0000000..995c623
--- /dev/null
@@ -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),
+};
index 6c8ddbd93618b913e9c2eec08032f671b049f438..ac12cfe9b86bd989777943915c5e1f34f94d7a00 100644 (file)
@@ -16,35 +16,11 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #define CTRL_MAC_REG(offset, id) ((offset) + 0x8 * (id))
 
-static int davinci_emac_3517_get_macid(struct udevice *dev, u16 offset,
-                                      int slave, u8 *mac_addr)
+static void davinci_emac_3517_get_macid(u32 addr, u8 *mac_addr)
 {
-       void *fdt = (void *)gd->fdt_blob;
-       int node = dev_of_offset(dev);
-       u32 macid_lsb;
-       u32 macid_msb;
-       fdt32_t gmii = 0;
-       int syscon;
-       u32 addr;
-
-       syscon = fdtdec_lookup_phandle(fdt, node, "syscon");
-       if (syscon < 0) {
-               pr_err("Syscon offset not found\n");
-               return -ENOENT;
-       }
-
-       addr = (u32)map_physmem(fdt_translate_address(fdt, syscon, &gmii),
-                               sizeof(u32), MAP_NOCACHE);
-       if (addr == FDT_ADDR_T_NONE) {
-               pr_err("Not able to get syscon address to get mac efuse address\n");
-               return -ENOENT;
-       }
-
-       addr += CTRL_MAC_REG(offset, slave);
-
        /* try reading mac address from efuse */
-       macid_lsb = readl(addr);
-       macid_msb = readl(addr + 4);
+       u32 macid_lsb = readl(addr);
+       u32 macid_msb = readl(addr + 4);
 
        mac_addr[0] = (macid_msb >> 16) & 0xff;
        mac_addr[1] = (macid_msb >> 8)  & 0xff;
@@ -52,20 +28,62 @@ static int davinci_emac_3517_get_macid(struct udevice *dev, u16 offset,
        mac_addr[3] = (macid_lsb >> 16) & 0xff;
        mac_addr[4] = (macid_lsb >> 8)  & 0xff;
        mac_addr[5] = macid_lsb & 0xff;
+}
 
-       return 0;
+static void cpsw_am33xx_cm_get_macid(u32 addr, u8 *mac_addr)
+{
+       /* try reading mac address from efuse */
+       u32 macid_lo = readl(addr);
+       u32 macid_hi = readl(addr + 4);
+
+       mac_addr[5] = (macid_lo >> 8) & 0xff;
+       mac_addr[4] = macid_lo & 0xff;
+       mac_addr[3] = (macid_hi >> 24) & 0xff;
+       mac_addr[2] = (macid_hi >> 16) & 0xff;
+       mac_addr[1] = (macid_hi >> 8) & 0xff;
+       mac_addr[0] = macid_hi & 0xff;
+}
+
+void ti_cm_get_macid(struct udevice *dev, struct cpsw_platform_data *data,
+                    u8 *mac_addr)
+{
+       if (!strcmp(data->macid_sel_compat, "cpsw,am33xx"))
+               cpsw_am33xx_cm_get_macid(data->syscon_addr, mac_addr);
+       else if (!strcmp(data->macid_sel_compat, "davinci,emac"))
+               davinci_emac_3517_get_macid(data->syscon_addr, mac_addr);
 }
 
-static int cpsw_am33xx_cm_get_macid(struct udevice *dev, u16 offset, int slave,
-                                   u8 *mac_addr)
+int ti_cm_get_macid_addr(struct udevice *dev, int slave,
+                        struct cpsw_platform_data *data)
 {
        void *fdt = (void *)gd->fdt_blob;
        int node = dev_of_offset(dev);
-       u32 macid_lo;
-       u32 macid_hi;
        fdt32_t gmii = 0;
        int syscon;
-       u32 addr;
+       u16 offset;
+
+       if (of_machine_is_compatible("ti,dm8148")) {
+               offset = 0x630;
+               data->macid_sel_compat = "cpsw,am33xx";
+       } else if (of_machine_is_compatible("ti,am33xx")) {
+               offset = 0x630;
+               data->macid_sel_compat = "cpsw,am33xx";
+       } else if (device_is_compatible(dev, "ti,am3517-emac")) {
+               offset = 0x110;
+               data->macid_sel_compat = "davinci,emac";
+       } else if (device_is_compatible(dev, "ti,dm816-emac")) {
+               offset = 0x30;
+               data->macid_sel_compat = "cpsw,am33xx";
+       } else if (of_machine_is_compatible("ti,am43")) {
+               offset = 0x630;
+               data->macid_sel_compat = "cpsw,am33xx";
+       } else if (of_machine_is_compatible("ti,dra7")) {
+               offset = 0x514;
+               data->macid_sel_compat = "davinci,emac";
+       } else {
+               dev_err(dev, "incompatible machine/device type for reading mac address\n");
+               return -ENOENT;
+       }
 
        syscon = fdtdec_lookup_phandle(fdt, node, "syscon");
        if (syscon < 0) {
@@ -73,49 +91,16 @@ static int cpsw_am33xx_cm_get_macid(struct udevice *dev, u16 offset, int slave,
                return -ENOENT;
        }
 
-       addr = (u32)map_physmem(fdt_translate_address(fdt, syscon, &gmii),
-                               sizeof(u32), MAP_NOCACHE);
-       if (addr == FDT_ADDR_T_NONE) {
+       data->syscon_addr = (u32)map_physmem(fdt_translate_address(fdt, syscon,
+                                                                  &gmii),
+                                            sizeof(u32), MAP_NOCACHE);
+       if (data->syscon_addr == FDT_ADDR_T_NONE) {
                pr_err("Not able to get syscon address to get mac efuse address\n");
                return -ENOENT;
        }
 
-       addr += CTRL_MAC_REG(offset, slave);
-
-       /* try reading mac address from efuse */
-       macid_lo = readl(addr);
-       macid_hi = readl(addr + 4);
-
-       mac_addr[5] = (macid_lo >> 8) & 0xff;
-       mac_addr[4] = macid_lo & 0xff;
-       mac_addr[3] = (macid_hi >> 24) & 0xff;
-       mac_addr[2] = (macid_hi >> 16) & 0xff;
-       mac_addr[1] = (macid_hi >> 8) & 0xff;
-       mac_addr[0] = macid_hi & 0xff;
+       data->syscon_addr += CTRL_MAC_REG(offset, slave);
 
        return 0;
-}
-
-int ti_cm_get_macid(struct udevice *dev, int slave, u8 *mac_addr)
-{
-       if (of_machine_is_compatible("ti,dm8148"))
-               return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr);
-
-       if (of_machine_is_compatible("ti,am33xx"))
-               return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr);
-
-       if (device_is_compatible(dev, "ti,am3517-emac"))
-               return davinci_emac_3517_get_macid(dev, 0x110, slave, mac_addr);
-
-       if (device_is_compatible(dev, "ti,dm816-emac"))
-               return cpsw_am33xx_cm_get_macid(dev, 0x30, slave, mac_addr);
-
-       if (of_machine_is_compatible("ti,am43"))
-               return cpsw_am33xx_cm_get_macid(dev, 0x630, slave, mac_addr);
-
-       if (of_machine_is_compatible("ti,dra7"))
-               return davinci_emac_3517_get_macid(dev, 0x514, slave, mac_addr);
 
-       dev_err(dev, "incompatible machine/device type for reading mac address\n");
-       return -ENOENT;
 }
index f5fd02efe1af47b398f684e6e1c5b9577b0656c6..20ddb44dd89460989d1f16d0e2b01c6f110fc38a 100644 (file)
@@ -33,24 +33,6 @@ DECLARE_GLOBAL_DATA_PTR;
 #define GIGABITEN              BIT(7)
 #define FULLDUPLEXEN           BIT(0)
 #define MIIEN                  BIT(15)
-
-/* reg offset */
-#define CPSW_HOST_PORT_OFFSET  0x108
-#define CPSW_SLAVE0_OFFSET     0x208
-#define CPSW_SLAVE1_OFFSET     0x308
-#define CPSW_SLAVE_SIZE                0x100
-#define CPSW_CPDMA_OFFSET      0x800
-#define CPSW_HW_STATS          0x900
-#define CPSW_STATERAM_OFFSET   0xa00
-#define CPSW_CPTS_OFFSET       0xc00
-#define CPSW_ALE_OFFSET                0xd00
-#define CPSW_SLIVER0_OFFSET    0xd80
-#define CPSW_SLIVER1_OFFSET    0xdc0
-#define CPSW_BD_OFFSET         0x2000
-#define CPSW_MDIO_DIV          0xff
-
-#define AM335X_GMII_SEL_OFFSET 0x630
-
 /* DMA Registers */
 #define CPDMA_TXCONTROL                0x004
 #define CPDMA_RXCONTROL                0x014
@@ -209,10 +191,10 @@ struct cpdma_chan {
 #define chan_read_ptr(chan, fld)       ((void *)__raw_readl((chan)->fld))
 
 #define for_active_slave(slave, priv) \
-       slave = (priv)->slaves + (priv)->data.active_slave; if (slave)
+       slave = (priv)->slaves + ((priv)->data)->active_slave; if (slave)
 #define for_each_slave(slave, priv) \
        for (slave = (priv)->slaves; slave != (priv)->slaves + \
-                               (priv)->data.slaves; slave++)
+                               ((priv)->data)->slaves; slave++)
 
 struct cpsw_priv {
 #ifdef CONFIG_DM_ETH
@@ -220,7 +202,7 @@ struct cpsw_priv {
 #else
        struct eth_device               *dev;
 #endif
-       struct cpsw_platform_data       data;
+       struct cpsw_platform_data       *data;
        int                             host_port;
 
        struct cpsw_regs                *regs;
@@ -327,7 +309,7 @@ static int cpsw_ale_match_addr(struct cpsw_priv *priv, const u8 *addr)
        u32 ale_entry[ALE_ENTRY_WORDS];
        int type, idx;
 
-       for (idx = 0; idx < priv->data.ale_entries; idx++) {
+       for (idx = 0; idx < priv->data->ale_entries; idx++) {
                u8 entry_addr[6];
 
                cpsw_ale_read(priv, idx, ale_entry);
@@ -346,7 +328,7 @@ static int cpsw_ale_match_free(struct cpsw_priv *priv)
        u32 ale_entry[ALE_ENTRY_WORDS];
        int type, idx;
 
-       for (idx = 0; idx < priv->data.ale_entries; idx++) {
+       for (idx = 0; idx < priv->data->ale_entries; idx++) {
                cpsw_ale_read(priv, idx, ale_entry);
                type = cpsw_ale_get_entry_type(ale_entry);
                if (type == ALE_TYPE_FREE)
@@ -360,7 +342,7 @@ static int cpsw_ale_find_ageable(struct cpsw_priv *priv)
        u32 ale_entry[ALE_ENTRY_WORDS];
        int type, idx;
 
-       for (idx = 0; idx < priv->data.ale_entries; idx++) {
+       for (idx = 0; idx < priv->data->ale_entries; idx++) {
                cpsw_ale_read(priv, idx, ale_entry);
                type = cpsw_ale_get_entry_type(ale_entry);
                if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
@@ -500,7 +482,7 @@ static int cpsw_slave_update_link(struct cpsw_slave *slave,
                *link = phy->link;
 
        if (phy->link) { /* link up */
-               mac_control = priv->data.mac_control;
+               mac_control = priv->data->mac_control;
                if (phy->speed == 1000)
                        mac_control |= GIGABITEN;
                if (phy->duplex == DUPLEX_FULL)
@@ -710,7 +692,7 @@ static int _cpsw_init(struct cpsw_priv *priv, u8 *enetaddr)
        priv->desc_free = &priv->descs[0];
 
        /* initialize channels */
-       if (priv->data.version == CPSW_CTRL_VERSION_2) {
+       if (priv->data->version == CPSW_CTRL_VERSION_2) {
                memset(&priv->rx_chan, 0, sizeof(struct cpdma_chan));
                priv->rx_chan.hdp       = priv->dma_regs + CPDMA_RXHDP_VER2;
                priv->rx_chan.cp        = priv->dma_regs + CPDMA_RXCP_VER2;
@@ -733,8 +715,8 @@ static int _cpsw_init(struct cpsw_priv *priv, u8 *enetaddr)
        /* clear dma state */
        setbit_and_wait_for_clear32(priv->dma_regs + CPDMA_SOFTRESET);
 
-       if (priv->data.version == CPSW_CTRL_VERSION_2) {
-               for (i = 0; i < priv->data.channels; i++) {
+       if (priv->data->version == CPSW_CTRL_VERSION_2) {
+               for (i = 0; i < priv->data->channels; i++) {
                        __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER2 + 4
                                        * i);
                        __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4
@@ -747,7 +729,7 @@ static int _cpsw_init(struct cpsw_priv *priv, u8 *enetaddr)
                                        * i);
                }
        } else {
-               for (i = 0; i < priv->data.channels; i++) {
+               for (i = 0; i < priv->data->channels; i++) {
                        __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER1 + 4
                                        * i);
                        __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4
@@ -843,7 +825,7 @@ static void cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
                            struct cpsw_priv *priv)
 {
        void                    *regs = priv->regs;
-       struct cpsw_slave_data  *data = priv->data.slave_data + slave_num;
+       struct cpsw_slave_data  *data = priv->data->slave_data + slave_num;
        slave->slave_num = slave_num;
        slave->data     = data;
        slave->regs     = regs + data->slave_reg_ofs;
@@ -879,7 +861,7 @@ static int cpsw_phy_init(struct cpsw_priv *priv, struct cpsw_slave *slave)
 
 static void cpsw_phy_addr_update(struct cpsw_priv *priv)
 {
-       struct cpsw_platform_data *data = &priv->data;
+       struct cpsw_platform_data *data = priv->data;
        u16 alive = cpsw_mdio_get_alive(priv->bus);
        int active = data->active_slave;
        int new_addr = ffs(alive) - 1;
@@ -899,7 +881,7 @@ static void cpsw_phy_addr_update(struct cpsw_priv *priv)
 int _cpsw_register(struct cpsw_priv *priv)
 {
        struct cpsw_slave       *slave;
-       struct cpsw_platform_data *data = &priv->data;
+       struct cpsw_platform_data *data = priv->data;
        void                    *regs = (void *)data->cpsw_base;
 
        priv->slaves = malloc(sizeof(struct cpsw_slave) * data->slaves);
@@ -988,7 +970,7 @@ int cpsw_register(struct cpsw_platform_data *data)
        }
 
        priv->dev = dev;
-       priv->data = *data;
+       priv->data = data;
 
        strcpy(dev->name, "cpsw");
        dev->iobase     = 0;
@@ -1048,16 +1030,6 @@ static void cpsw_eth_stop(struct udevice *dev)
        return _cpsw_halt(priv);
 }
 
-
-static int cpsw_eth_probe(struct udevice *dev)
-{
-       struct cpsw_priv *priv = dev_get_priv(dev);
-
-       priv->dev = dev;
-
-       return _cpsw_register(priv);
-}
-
 static const struct eth_ops cpsw_eth_ops = {
        .start          = cpsw_eth_start,
        .send           = cpsw_eth_send,
@@ -1079,9 +1051,9 @@ static void cpsw_gmii_sel_am3352(struct cpsw_priv *priv,
        u32 mask;
        u32 mode = 0;
        bool rgmii_id = false;
-       int slave = priv->data.active_slave;
+       int slave = priv->data->active_slave;
 
-       reg = readl(priv->data.gmii_sel);
+       reg = readl(priv->data->gmii_sel);
 
        switch (phy_mode) {
        case PHY_INTERFACE_MODE_RMII:
@@ -1107,7 +1079,7 @@ static void cpsw_gmii_sel_am3352(struct cpsw_priv *priv,
        mask = GMII_SEL_MODE_MASK << (slave * 2) | BIT(slave + 6);
        mode <<= slave * 2;
 
-       if (priv->data.rmii_clock_external) {
+       if (priv->data->rmii_clock_external) {
                if (slave == 0)
                        mode |= AM33XX_GMII_SEL_RMII1_IO_CLK_EN;
                else
@@ -1124,7 +1096,7 @@ static void cpsw_gmii_sel_am3352(struct cpsw_priv *priv,
        reg &= ~mask;
        reg |= mode;
 
-       writel(reg, priv->data.gmii_sel);
+       writel(reg, priv->data->gmii_sel);
 }
 
 static void cpsw_gmii_sel_dra7xx(struct cpsw_priv *priv,
@@ -1133,9 +1105,9 @@ static void cpsw_gmii_sel_dra7xx(struct cpsw_priv *priv,
        u32 reg;
        u32 mask;
        u32 mode = 0;
-       int slave = priv->data.active_slave;
+       int slave = priv->data->active_slave;
 
-       reg = readl(priv->data.gmii_sel);
+       reg = readl(priv->data->gmii_sel);
 
        switch (phy_mode) {
        case PHY_INTERFACE_MODE_RMII:
@@ -1168,13 +1140,13 @@ static void cpsw_gmii_sel_dra7xx(struct cpsw_priv *priv,
                return;
        }
 
-       if (priv->data.rmii_clock_external)
+       if (priv->data->rmii_clock_external)
                dev_err(priv->dev, "RMII External clock is not supported\n");
 
        reg &= ~mask;
        reg |= mode;
 
-       writel(reg, priv->data.gmii_sel);
+       writel(reg, priv->data->gmii_sel);
 }
 
 static void cpsw_phy_sel(struct cpsw_priv *priv, const char *compat,
@@ -1188,13 +1160,28 @@ static void cpsw_phy_sel(struct cpsw_priv *priv, const char *compat,
                cpsw_gmii_sel_dra7xx(priv, phy_mode);
 }
 
+static int cpsw_eth_probe(struct udevice *dev)
+{
+       struct cpsw_priv *priv = dev_get_priv(dev);
+       struct eth_pdata *pdata = dev_get_platdata(dev);
+
+       priv->dev = dev;
+       priv->data = pdata->priv_pdata;
+       ti_cm_get_macid(dev, priv->data, pdata->enetaddr);
+       /* Select phy interface in control module */
+       cpsw_phy_sel(priv, priv->data->phy_sel_compat,
+                    pdata->phy_interface);
+
+       return _cpsw_register(priv);
+}
+
+#if CONFIG_IS_ENABLED(OF_CONTROL)
 static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
 {
        struct eth_pdata *pdata = dev_get_platdata(dev);
-       struct cpsw_priv *priv = dev_get_priv(dev);
+       struct cpsw_platform_data *data;
        struct gpio_desc *mode_gpios;
        const char *phy_mode;
-       const char *phy_sel_compat = NULL;
        const void *fdt = gd->fdt_blob;
        int node = dev_of_offset(dev);
        int subnode;
@@ -1203,45 +1190,47 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
        int num_mode_gpios;
        int ret;
 
+       data = calloc(1, sizeof(struct cpsw_platform_data));
+       pdata->priv_pdata = data;
        pdata->iobase = devfdt_get_addr(dev);
-       priv->data.version = CPSW_CTRL_VERSION_2;
-       priv->data.bd_ram_ofs = CPSW_BD_OFFSET;
-       priv->data.ale_reg_ofs = CPSW_ALE_OFFSET;
-       priv->data.cpdma_reg_ofs = CPSW_CPDMA_OFFSET;
-       priv->data.mdio_div = CPSW_MDIO_DIV;
-       priv->data.host_port_reg_ofs = CPSW_HOST_PORT_OFFSET,
+       data->version = CPSW_CTRL_VERSION_2;
+       data->bd_ram_ofs = CPSW_BD_OFFSET;
+       data->ale_reg_ofs = CPSW_ALE_OFFSET;
+       data->cpdma_reg_ofs = CPSW_CPDMA_OFFSET;
+       data->mdio_div = CPSW_MDIO_DIV;
+       data->host_port_reg_ofs = CPSW_HOST_PORT_OFFSET,
 
        pdata->phy_interface = -1;
 
-       priv->data.cpsw_base = pdata->iobase;
-       priv->data.channels = fdtdec_get_int(fdt, node, "cpdma_channels", -1);
-       if (priv->data.channels <= 0) {
+       data->cpsw_base = pdata->iobase;
+       data->channels = fdtdec_get_int(fdt, node, "cpdma_channels", -1);
+       if (data->channels <= 0) {
                printf("error: cpdma_channels not found in dt\n");
                return -ENOENT;
        }
 
-       priv->data.slaves = fdtdec_get_int(fdt, node, "slaves", -1);
-       if (priv->data.slaves <= 0) {
+       data->slaves = fdtdec_get_int(fdt, node, "slaves", -1);
+       if (data->slaves <= 0) {
                printf("error: slaves not found in dt\n");
                return -ENOENT;
        }
-       priv->data.slave_data = malloc(sizeof(struct cpsw_slave_data) *
-                                      priv->data.slaves);
+       data->slave_data = malloc(sizeof(struct cpsw_slave_data) *
+                                      data->slaves);
 
-       priv->data.ale_entries = fdtdec_get_int(fdt, node, "ale_entries", -1);
-       if (priv->data.ale_entries <= 0) {
+       data->ale_entries = fdtdec_get_int(fdt, node, "ale_entries", -1);
+       if (data->ale_entries <= 0) {
                printf("error: ale_entries not found in dt\n");
                return -ENOENT;
        }
 
-       priv->data.bd_ram_ofs = fdtdec_get_int(fdt, node, "bd_ram_size", -1);
-       if (priv->data.bd_ram_ofs <= 0) {
+       data->bd_ram_ofs = fdtdec_get_int(fdt, node, "bd_ram_size", -1);
+       if (data->bd_ram_ofs <= 0) {
                printf("error: bd_ram_size not found in dt\n");
                return -ENOENT;
        }
 
-       priv->data.mac_control = fdtdec_get_int(fdt, node, "mac_control", -1);
-       if (priv->data.mac_control <= 0) {
+       data->mac_control = fdtdec_get_int(fdt, node, "mac_control", -1);
+       if (data->mac_control <= 0) {
                printf("error: ale_entries not found in dt\n");
                return -ENOENT;
        }
@@ -1256,7 +1245,7 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
        }
 
        active_slave = fdtdec_get_int(fdt, node, "active_slave", 0);
-       priv->data.active_slave = active_slave;
+       data->active_slave = active_slave;
 
        fdt_for_each_subnode(subnode, fdt, node) {
                int len;
@@ -1271,108 +1260,107 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
                                pr_err("Not able to get MDIO address space\n");
                                return -ENOENT;
                        }
-                       priv->data.mdio_base = mdio_base;
+                       data->mdio_base = mdio_base;
                }
 
                if (!strncmp(name, "slave", 5)) {
                        u32 phy_id[2];
 
-                       if (slave_index >= priv->data.slaves)
+                       if (slave_index >= data->slaves)
                                continue;
                        phy_mode = fdt_getprop(fdt, subnode, "phy-mode", NULL);
                        if (phy_mode)
-                               priv->data.slave_data[slave_index].phy_if =
+                               data->slave_data[slave_index].phy_if =
                                        phy_get_interface_by_name(phy_mode);
 
-                       priv->data.slave_data[slave_index].phy_of_handle =
+                       data->slave_data[slave_index].phy_of_handle =
                                fdtdec_lookup_phandle(fdt, subnode,
                                                      "phy-handle");
 
-                       if (priv->data.slave_data[slave_index].phy_of_handle >= 0) {
-                               priv->data.slave_data[slave_index].phy_addr =
+                       if (data->slave_data[slave_index].phy_of_handle >= 0) {
+                               data->slave_data[slave_index].phy_addr =
                                                fdtdec_get_int(gd->fdt_blob,
-                                                              priv->data.slave_data[slave_index].phy_of_handle,
+                                               data->slave_data[slave_index].phy_of_handle,
                                                               "reg", -1);
                        } else {
                                fdtdec_get_int_array(fdt, subnode, "phy_id",
                                                     phy_id, 2);
-                               priv->data.slave_data[slave_index].phy_addr =
+                               data->slave_data[slave_index].phy_addr =
                                                phy_id[1];
                        }
                        slave_index++;
                }
 
                if (!strncmp(name, "cpsw-phy-sel", 12)) {
-                       priv->data.gmii_sel = cpsw_get_addr_by_node(fdt,
-                                                                   subnode);
+                       data->gmii_sel = cpsw_get_addr_by_node(fdt, subnode);
 
-                       if (priv->data.gmii_sel == FDT_ADDR_T_NONE) {
+                       if (data->gmii_sel == FDT_ADDR_T_NONE) {
                                pr_err("Not able to get gmii_sel reg address\n");
                                return -ENOENT;
                        }
 
                        if (fdt_get_property(fdt, subnode, "rmii-clock-ext",
                                             NULL))
-                               priv->data.rmii_clock_external = true;
+                               data->rmii_clock_external = true;
 
-                       phy_sel_compat = fdt_getprop(fdt, subnode, "compatible",
-                                                    NULL);
-                       if (!phy_sel_compat) {
+                       data->phy_sel_compat = fdt_getprop(fdt, subnode,
+                                                          "compatible", NULL);
+                       if (!data->phy_sel_compat) {
                                pr_err("Not able to get gmii_sel compatible\n");
                                return -ENOENT;
                        }
                }
        }
 
-       priv->data.slave_data[0].slave_reg_ofs = CPSW_SLAVE0_OFFSET;
-       priv->data.slave_data[0].sliver_reg_ofs = CPSW_SLIVER0_OFFSET;
+       data->slave_data[0].slave_reg_ofs = CPSW_SLAVE0_OFFSET;
+       data->slave_data[0].sliver_reg_ofs = CPSW_SLIVER0_OFFSET;
 
-       if (priv->data.slaves == 2) {
-               priv->data.slave_data[1].slave_reg_ofs = CPSW_SLAVE1_OFFSET;
-               priv->data.slave_data[1].sliver_reg_ofs = CPSW_SLIVER1_OFFSET;
+       if (data->slaves == 2) {
+               data->slave_data[1].slave_reg_ofs = CPSW_SLAVE1_OFFSET;
+               data->slave_data[1].sliver_reg_ofs = CPSW_SLIVER1_OFFSET;
        }
 
-       ret = ti_cm_get_macid(dev, active_slave, pdata->enetaddr);
+       ret = ti_cm_get_macid_addr(dev, active_slave, data);
        if (ret < 0) {
                pr_err("cpsw read efuse mac failed\n");
                return ret;
        }
 
-       pdata->phy_interface = priv->data.slave_data[active_slave].phy_if;
+       pdata->phy_interface = data->slave_data[active_slave].phy_if;
        if (pdata->phy_interface == -1) {
                debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
                return -EINVAL;
        }
 
-       /* Select phy interface in control module */
-       cpsw_phy_sel(priv, phy_sel_compat, pdata->phy_interface);
-
        return 0;
 }
 
+static const struct udevice_id cpsw_eth_ids[] = {
+       { .compatible = "ti,cpsw" },
+       { .compatible = "ti,am335x-cpsw" },
+       { }
+};
+#endif
+
 int cpsw_get_slave_phy_addr(struct udevice *dev, int slave)
 {
        struct cpsw_priv *priv = dev_get_priv(dev);
-       struct cpsw_platform_data *data = &priv->data;
+       struct cpsw_platform_data *data = priv->data;
 
        return data->slave_data[slave].phy_addr;
 }
 
-static const struct udevice_id cpsw_eth_ids[] = {
-       { .compatible = "ti,cpsw" },
-       { .compatible = "ti,am335x-cpsw" },
-       { }
-};
-
 U_BOOT_DRIVER(eth_cpsw) = {
        .name   = "eth_cpsw",
        .id     = UCLASS_ETH,
+#if CONFIG_IS_ENABLED(OF_CONTROL)
        .of_match = cpsw_eth_ids,
        .ofdata_to_platdata = cpsw_eth_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+#endif
        .probe  = cpsw_eth_probe,
        .ops    = &cpsw_eth_ops,
        .priv_auto_alloc_size = sizeof(struct cpsw_priv),
-       .platdata_auto_alloc_size = sizeof(struct eth_pdata),
-       .flags = DM_FLAG_ALLOC_PRIV_DMA,
+       .flags = DM_FLAG_ALLOC_PRIV_DMA | DM_FLAG_PRE_RELOC,
 };
 #endif /* CONFIG_DM_ETH */
index a3ba91cc3f5600a8bc928908ffae4b4d33f62ac0..4baeeb83f109cb551cc748c520b2f05e6264010c 100644 (file)
@@ -88,6 +88,7 @@ struct ks2_eth_priv {
        struct mii_dev                  *mdio_bus;
        int                             phy_addr;
        phy_interface_t                 phy_if;
+       int                             phy_of_handle;
        int                             sgmii_link_type;
        void                            *mdio_base;
        struct rx_buff_desc             net_rx_buffs;
@@ -588,6 +589,10 @@ static int ks2_eth_probe(struct udevice *dev)
        if (priv->has_mdio) {
                priv->phydev = phy_connect(priv->mdio_bus, priv->phy_addr,
                                           dev, priv->phy_if);
+#ifdef CONFIG_DM_ETH
+       if (priv->phy_of_handle)
+               priv->phydev->node = offset_to_ofnode(priv->phy_of_handle);
+#endif
                phy_config(priv->phydev);
        }
 
@@ -679,6 +684,7 @@ static int ks2_eth_parse_slave_interface(int netcp, int slave,
        int phy;
        int dma_count;
        u32 dma_channel[8];
+       const char *phy_mode;
 
        priv->slave_port = fdtdec_get_int(fdt, slave, "slave-port", -1);
        priv->net_rx_buffs.rx_flow = priv->slave_port * 8;
@@ -700,7 +706,9 @@ static int ks2_eth_parse_slave_interface(int netcp, int slave,
        priv->link_type = fdtdec_get_int(fdt, slave, "link-interface", -1);
 
        phy = fdtdec_lookup_phandle(fdt, slave, "phy-handle");
+
        if (phy >= 0) {
+               priv->phy_of_handle = phy;
                priv->phy_addr = fdtdec_get_int(fdt, phy, "reg", -1);
 
                mdio = fdt_parent_offset(fdt, phy);
@@ -717,7 +725,19 @@ static int ks2_eth_parse_slave_interface(int netcp, int slave,
                priv->sgmii_link_type = SGMII_LINK_MAC_PHY;
                priv->has_mdio = true;
        } else if (priv->link_type == LINK_TYPE_RGMII_LINK_MAC_PHY) {
-               priv->phy_if = PHY_INTERFACE_MODE_RGMII;
+               phy_mode = fdt_getprop(fdt, slave, "phy-mode", NULL);
+               if (phy_mode) {
+                       priv->phy_if = phy_get_interface_by_name(phy_mode);
+                       if (priv->phy_if != PHY_INTERFACE_MODE_RGMII &&
+                           priv->phy_if != PHY_INTERFACE_MODE_RGMII_ID &&
+                           priv->phy_if != PHY_INTERFACE_MODE_RGMII_RXID &&
+                           priv->phy_if != PHY_INTERFACE_MODE_RGMII_TXID) {
+                               pr_err("invalid phy-mode\n");
+                               return -EINVAL;
+                       }
+               } else {
+                       priv->phy_if = PHY_INTERFACE_MODE_RGMII;
+               }
                pdata->phy_interface = priv->phy_if;
                priv->has_mdio = true;
        }
index 32bbf41dd1f5972e6aaa8c25d36d151e14f92f3a..102fb91fffd07cc0f65a8aef150247dae6459a15 100644 (file)
@@ -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
index 099551d693082596878f52bbc592962e70429fb3..b55917bce1ae62353fb4ace629c74e790fedf808 100644 (file)
@@ -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 (file)
index 0000000..268da8e
--- /dev/null
@@ -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),
+};
index be709f73d7dfe55d5f1d4e09e3a898fce16ca2e5..a0ac167d145a548bd738d2440e215889a3955bc5 100644 (file)
@@ -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
index e2c2b159d8c8894384d870a3c5f9ea6cc5b5a911..4b080b74dcd19f9689d1eeb3515214871f06541e 100644 (file)
@@ -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/
index 1daa2123a149e65084827ad41e7b6b243e889c8e..c7d1e44882e8438c6373c5a45ce61c43e3dc0bda 100644 (file)
@@ -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 (file)
index 0000000..5431df9
--- /dev/null
@@ -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,
+};
index 0e3260afd1ee72afa4fa349114334a534e4cedf8..0e6c559d5efb21ed66325338ca86aadda70daed3 100644 (file)
@@ -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;
 
index 8cf60ebcf3d71a253ec003301bf7e4aea544096e..b0cd26035432c7d9ef69d96d5efe182a2f21f9ef 100644 (file)
@@ -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.
index 637352ab2b7297dab91c9137d8ecfecdff031125..ce250cb1555afd724bf4377c10cc897ddc5aa1a7 100644 (file)
@@ -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 (file)
index 0000000..65296c5
--- /dev/null
@@ -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 (file)
index 47af012..0000000
+++ /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,
-};
index 3ed0dd2264a9b5372886746e5bda1d9f1de9ff51..72dfc48981a281e327582fc03a33715c76f8b91a 100644 (file)
@@ -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.
index f617ce723a96a16a40db35cb88185981ce57b206..8c1506c88edb8e8a5c66fefa8d4daffb47046200 100644 (file)
@@ -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
index 4ed3c94e03115e06286a1bb7f41186bdebfba605..88dc9f273aebed4db07729cc4a082d46c7d1bfe8 100644 (file)
@@ -238,7 +238,7 @@ static int pbias_regulator_set_value(struct udevice *dev, int uV)
        if (rc)
                return rc;
 
-       if (uV == 3000000)
+       if (uV == 3300000)
                reg |= p->vmode;
        else if (uV == 1800000)
                reg &= ~p->vmode;
diff --git a/drivers/power/regulator/stpmic1.c b/drivers/power/regulator/stpmic1.c
new file mode 100644 (file)
index 0000000..50ef2a2
--- /dev/null
@@ -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 (file)
index 6eb2420..0000000
+++ /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,
-};
index bd497a3021d825a85ac493164107a2e1c9486c91..e45a3b2658a31dce190c436fb659b7db278244fb 100644 (file)
@@ -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/soc/Kconfig b/drivers/soc/Kconfig
new file mode 100644 (file)
index 0000000..7b4e4d6
--- /dev/null
@@ -0,0 +1,5 @@
+menu "SOC (System On Chip) specific Drivers"
+
+source "drivers/soc/ti/Kconfig"
+
+endmenu
index 42037f99d587bbd99f293226e0b6f40d3fca9796..ce253b7aa88612f2425dd0fbe5d8c003693ac365 100644 (file)
@@ -2,4 +2,4 @@
 #
 # Makefile for the U-Boot SOC specific device drivers.
 
-obj-$(CONFIG_ARCH_KEYSTONE)    += keystone/
+obj-$(CONFIG_SOC_TI) += ti/
diff --git a/drivers/soc/keystone/Makefile b/drivers/soc/keystone/Makefile
deleted file mode 100644 (file)
index dfebb14..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-
-obj-$(CONFIG_TI_KEYSTONE_SERDES) += keystone_serdes.o
diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig
new file mode 100644 (file)
index 0000000..e4f8834
--- /dev/null
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+menuconfig SOC_TI
+       bool "TI SOC drivers support"
+
+if SOC_TI
+
+config TI_K3_NAVSS_RINGACC
+       bool "K3 Ring accelerator Sub System"
+       depends on ARCH_K3
+       select MISC
+       help
+         Say y here to support the K3 AM65x Ring accelerator module.
+         The Ring Accelerator (RINGACC or RA)  provides hardware acceleration
+         to enable straightforward passing of work between a producer
+         and a consumer. There is one RINGACC module per NAVSS on TI AM65x SoCs
+         If unsure, say N.
+
+config TI_KEYSTONE_SERDES
+       bool "Keystone SerDes driver for ethernet"
+       depends on ARCH_KEYSTONE
+       help
+        SerDes driver for Keystone SoC used for ethernet support on TI
+        K2 platforms.
+
+endif # SOC_TI
diff --git a/drivers/soc/ti/Makefile b/drivers/soc/ti/Makefile
new file mode 100644 (file)
index 0000000..4ec04ee
--- /dev/null
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-$(CONFIG_TI_K3_NAVSS_RINGACC)      += k3-navss-ringacc.o
+obj-$(CONFIG_TI_KEYSTONE_SERDES)       += keystone_serdes.o
diff --git a/drivers/soc/ti/k3-navss-ringacc.c b/drivers/soc/ti/k3-navss-ringacc.c
new file mode 100644 (file)
index 0000000..fcb84f7
--- /dev/null
@@ -0,0 +1,1057 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * TI K3 AM65x NAVSS Ring accelerator Manager (RA) subsystem driver
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <asm/dma-mapping.h>
+#include <asm/bitops.h>
+#include <dm.h>
+#include <dm/read.h>
+#include <dm/uclass.h>
+#include <linux/compat.h>
+#include <linux/soc/ti/k3-navss-ringacc.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+
+#define set_bit(bit, bitmap)   __set_bit(bit, bitmap)
+#define clear_bit(bit, bitmap) __clear_bit(bit, bitmap)
+#define dma_free_coherent(dev, size, cpu_addr, dma_handle) \
+       dma_free_coherent(cpu_addr)
+#define dma_zalloc_coherent(dev, size, dma_handle, flag) \
+({ \
+       void    *ring_mem_virt; \
+       ring_mem_virt = dma_alloc_coherent((size), \
+                                          (unsigned long *)(dma_handle)); \
+       if (ring_mem_virt) \
+               memset(ring_mem_virt, 0, (size)); \
+       ring_mem_virt; \
+})
+
+static LIST_HEAD(k3_nav_ringacc_list);
+
+static void ringacc_writel(u32 v, void __iomem *reg)
+{
+       pr_debug("WRITEL(32): v(%08X)-->reg(%p)\n", v, reg);
+       writel(v, reg);
+}
+
+static u32 ringacc_readl(void __iomem *reg)
+{
+       u32 v;
+
+       v = readl(reg);
+       pr_debug("READL(32): v(%08X)<--reg(%p)\n", v, reg);
+       return v;
+}
+
+#define KNAV_RINGACC_CFG_RING_SIZE_ELCNT_MASK          GENMASK(19, 0)
+
+/**
+ * struct k3_nav_ring_rt_regs -  The RA Control/Status Registers region
+ */
+struct k3_nav_ring_rt_regs {
+       u32     resv_16[4];
+       u32     db;             /* RT Ring N Doorbell Register */
+       u32     resv_4[1];
+       u32     occ;            /* RT Ring N Occupancy Register */
+       u32     indx;           /* RT Ring N Current Index Register */
+       u32     hwocc;          /* RT Ring N Hardware Occupancy Register */
+       u32     hwindx;         /* RT Ring N Current Index Register */
+};
+
+#define KNAV_RINGACC_RT_REGS_STEP      0x1000
+
+/**
+ * struct k3_nav_ring_fifo_regs -  The Ring Accelerator Queues Registers region
+ */
+struct k3_nav_ring_fifo_regs {
+       u32     head_data[128];         /* Ring Head Entry Data Registers */
+       u32     tail_data[128];         /* Ring Tail Entry Data Registers */
+       u32     peek_head_data[128];    /* Ring Peek Head Entry Data Regs */
+       u32     peek_tail_data[128];    /* Ring Peek Tail Entry Data Regs */
+};
+
+/**
+ * struct k3_ringacc_proxy_gcfg_regs - RA Proxy Global Config MMIO Region
+ */
+struct k3_ringacc_proxy_gcfg_regs {
+       u32     revision;       /* Revision Register */
+       u32     config;         /* Config Register */
+};
+
+#define K3_RINGACC_PROXY_CFG_THREADS_MASK              GENMASK(15, 0)
+
+/**
+ * struct k3_ringacc_proxy_target_regs -  RA Proxy Datapath MMIO Region
+ */
+struct k3_ringacc_proxy_target_regs {
+       u32     control;        /* Proxy Control Register */
+       u32     status;         /* Proxy Status Register */
+       u8      resv_512[504];
+       u32     data[128];      /* Proxy Data Register */
+};
+
+#define K3_RINGACC_PROXY_TARGET_STEP   0x1000
+#define K3_RINGACC_PROXY_NOT_USED      (-1)
+
+enum k3_ringacc_proxy_access_mode {
+       PROXY_ACCESS_MODE_HEAD = 0,
+       PROXY_ACCESS_MODE_TAIL = 1,
+       PROXY_ACCESS_MODE_PEEK_HEAD = 2,
+       PROXY_ACCESS_MODE_PEEK_TAIL = 3,
+};
+
+#define KNAV_RINGACC_FIFO_WINDOW_SIZE_BYTES  (512U)
+#define KNAV_RINGACC_FIFO_REGS_STEP    0x1000
+#define KNAV_RINGACC_MAX_DB_RING_CNT    (127U)
+
+/**
+ * struct k3_nav_ring_ops -  Ring operations
+ */
+struct k3_nav_ring_ops {
+       int (*push_tail)(struct k3_nav_ring *ring, void *elm);
+       int (*push_head)(struct k3_nav_ring *ring, void *elm);
+       int (*pop_tail)(struct k3_nav_ring *ring, void *elm);
+       int (*pop_head)(struct k3_nav_ring *ring, void *elm);
+};
+
+/**
+ * struct k3_nav_ring - RA Ring descriptor
+ *
+ * @rt - Ring control/status registers
+ * @fifos - Ring queues registers
+ * @proxy - Ring Proxy Datapath registers
+ * @ring_mem_dma - Ring buffer dma address
+ * @ring_mem_virt - Ring buffer virt address
+ * @ops - Ring operations
+ * @size - Ring size in elements
+ * @elm_size - Size of the ring element
+ * @mode - Ring mode
+ * @flags - flags
+ * @free - Number of free elements
+ * @occ - Ring occupancy
+ * @windex - Write index (only for @K3_NAV_RINGACC_RING_MODE_RING)
+ * @rindex - Read index (only for @K3_NAV_RINGACC_RING_MODE_RING)
+ * @ring_id - Ring Id
+ * @parent - Pointer on struct @k3_nav_ringacc
+ * @use_count - Use count for shared rings
+ * @proxy_id - RA Ring Proxy Id (only if @K3_NAV_RINGACC_RING_USE_PROXY)
+ */
+struct k3_nav_ring {
+       struct k3_nav_ring_rt_regs __iomem *rt;
+       struct k3_nav_ring_fifo_regs __iomem *fifos;
+       struct k3_ringacc_proxy_target_regs  __iomem *proxy;
+       dma_addr_t      ring_mem_dma;
+       void            *ring_mem_virt;
+       struct k3_nav_ring_ops *ops;
+       u32             size;
+       enum k3_nav_ring_size elm_size;
+       enum k3_nav_ring_mode mode;
+       u32             flags;
+#define KNAV_RING_FLAG_BUSY    BIT(1)
+#define K3_NAV_RING_FLAG_SHARED        BIT(2)
+       u32             free;
+       u32             occ;
+       u32             windex;
+       u32             rindex;
+       u32             ring_id;
+       struct k3_nav_ringacc   *parent;
+       u32             use_count;
+       int             proxy_id;
+};
+
+/**
+ * struct k3_nav_ringacc - Rings accelerator descriptor
+ *
+ * @dev - pointer on RA device
+ * @proxy_gcfg - RA proxy global config registers
+ * @proxy_target_base - RA proxy datapath region
+ * @num_rings - number of ring in RA
+ * @rm_gp_range - general purpose rings range from tisci
+ * @dma_ring_reset_quirk - DMA reset w/a enable
+ * @num_proxies - number of RA proxies
+ * @rings - array of rings descriptors (struct @k3_nav_ring)
+ * @list - list of RAs in the system
+ * @tisci - pointer ti-sci handle
+ * @tisci_ring_ops - ti-sci rings ops
+ * @tisci_dev_id - ti-sci device id
+ */
+struct k3_nav_ringacc {
+       struct udevice *dev;
+       struct k3_ringacc_proxy_gcfg_regs __iomem *proxy_gcfg;
+       void __iomem *proxy_target_base;
+       u32 num_rings; /* number of rings in Ringacc module */
+       unsigned long *rings_inuse;
+       struct ti_sci_resource *rm_gp_range;
+       bool dma_ring_reset_quirk;
+       u32 num_proxies;
+       unsigned long *proxy_inuse;
+
+       struct k3_nav_ring *rings;
+       struct list_head list;
+
+       const struct ti_sci_handle *tisci;
+       const struct ti_sci_rm_ringacc_ops *tisci_ring_ops;
+       u32  tisci_dev_id;
+};
+
+static long k3_nav_ringacc_ring_get_fifo_pos(struct k3_nav_ring *ring)
+{
+       return KNAV_RINGACC_FIFO_WINDOW_SIZE_BYTES -
+              (4 << ring->elm_size);
+}
+
+static void *k3_nav_ringacc_get_elm_addr(struct k3_nav_ring *ring, u32 idx)
+{
+       return (idx * (4 << ring->elm_size) + ring->ring_mem_virt);
+}
+
+static int k3_nav_ringacc_ring_push_mem(struct k3_nav_ring *ring, void *elem);
+static int k3_nav_ringacc_ring_pop_mem(struct k3_nav_ring *ring, void *elem);
+
+static struct k3_nav_ring_ops k3_nav_mode_ring_ops = {
+               .push_tail = k3_nav_ringacc_ring_push_mem,
+               .pop_head = k3_nav_ringacc_ring_pop_mem,
+};
+
+static int k3_nav_ringacc_ring_push_io(struct k3_nav_ring *ring, void *elem);
+static int k3_nav_ringacc_ring_pop_io(struct k3_nav_ring *ring, void *elem);
+static int k3_nav_ringacc_ring_push_head_io(struct k3_nav_ring *ring,
+                                           void *elem);
+static int k3_nav_ringacc_ring_pop_tail_io(struct k3_nav_ring *ring,
+                                          void *elem);
+
+static struct k3_nav_ring_ops k3_nav_mode_msg_ops = {
+               .push_tail = k3_nav_ringacc_ring_push_io,
+               .push_head = k3_nav_ringacc_ring_push_head_io,
+               .pop_tail = k3_nav_ringacc_ring_pop_tail_io,
+               .pop_head = k3_nav_ringacc_ring_pop_io,
+};
+
+static int k3_ringacc_ring_push_head_proxy(struct k3_nav_ring *ring,
+                                          void *elem);
+static int k3_ringacc_ring_push_tail_proxy(struct k3_nav_ring *ring,
+                                          void *elem);
+static int k3_ringacc_ring_pop_head_proxy(struct k3_nav_ring *ring, void *elem);
+static int k3_ringacc_ring_pop_tail_proxy(struct k3_nav_ring *ring, void *elem);
+
+static struct k3_nav_ring_ops k3_nav_mode_proxy_ops = {
+               .push_tail = k3_ringacc_ring_push_tail_proxy,
+               .push_head = k3_ringacc_ring_push_head_proxy,
+               .pop_tail = k3_ringacc_ring_pop_tail_proxy,
+               .pop_head = k3_ringacc_ring_pop_head_proxy,
+};
+
+struct udevice *k3_nav_ringacc_get_dev(struct k3_nav_ringacc *ringacc)
+{
+       return ringacc->dev;
+}
+
+struct k3_nav_ring *k3_nav_ringacc_request_ring(struct k3_nav_ringacc *ringacc,
+                                               int id, u32 flags)
+{
+       int proxy_id = K3_RINGACC_PROXY_NOT_USED;
+
+       if (id == K3_NAV_RINGACC_RING_ID_ANY) {
+               /* Request for any general purpose ring */
+               struct ti_sci_resource_desc *gp_rings =
+                                       &ringacc->rm_gp_range->desc[0];
+               unsigned long size;
+
+               size = gp_rings->start + gp_rings->num;
+               id = find_next_zero_bit(ringacc->rings_inuse,
+                                       size, gp_rings->start);
+               if (id == size)
+                       goto error;
+       } else if (id < 0) {
+               goto error;
+       }
+
+       if (test_bit(id, ringacc->rings_inuse) &&
+           !(ringacc->rings[id].flags & K3_NAV_RING_FLAG_SHARED))
+               goto error;
+       else if (ringacc->rings[id].flags & K3_NAV_RING_FLAG_SHARED)
+               goto out;
+
+       if (flags & K3_NAV_RINGACC_RING_USE_PROXY) {
+               proxy_id = find_next_zero_bit(ringacc->proxy_inuse,
+                                             ringacc->num_proxies, 0);
+               if (proxy_id == ringacc->num_proxies)
+                       goto error;
+       }
+
+       if (!try_module_get(ringacc->dev->driver->owner))
+               goto error;
+
+       if (proxy_id != K3_RINGACC_PROXY_NOT_USED) {
+               set_bit(proxy_id, ringacc->proxy_inuse);
+               ringacc->rings[id].proxy_id = proxy_id;
+               pr_debug("Giving ring#%d proxy#%d\n",
+                        id, proxy_id);
+       } else {
+               pr_debug("Giving ring#%d\n", id);
+       }
+
+       set_bit(id, ringacc->rings_inuse);
+out:
+       ringacc->rings[id].use_count++;
+       return &ringacc->rings[id];
+
+error:
+       return NULL;
+}
+
+static void k3_ringacc_ring_reset_sci(struct k3_nav_ring *ring)
+{
+       struct k3_nav_ringacc *ringacc = ring->parent;
+       int ret;
+
+       ret = ringacc->tisci_ring_ops->config(
+                       ringacc->tisci,
+                       TI_SCI_MSG_VALUE_RM_RING_COUNT_VALID,
+                       ringacc->tisci_dev_id,
+                       ring->ring_id,
+                       0,
+                       0,
+                       ring->size,
+                       0,
+                       0,
+                       0);
+       if (ret)
+               dev_err(ringacc->dev, "TISCI reset ring fail (%d) ring_idx %d\n",
+                       ret, ring->ring_id);
+}
+
+void k3_nav_ringacc_ring_reset(struct k3_nav_ring *ring)
+{
+       if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
+               return;
+
+       ring->occ = 0;
+       ring->free = 0;
+       ring->rindex = 0;
+       ring->windex = 0;
+
+       k3_ringacc_ring_reset_sci(ring);
+}
+
+static void k3_ringacc_ring_reconfig_qmode_sci(struct k3_nav_ring *ring,
+                                              enum k3_nav_ring_mode mode)
+{
+       struct k3_nav_ringacc *ringacc = ring->parent;
+       int ret;
+
+       ret = ringacc->tisci_ring_ops->config(
+                       ringacc->tisci,
+                       TI_SCI_MSG_VALUE_RM_RING_MODE_VALID,
+                       ringacc->tisci_dev_id,
+                       ring->ring_id,
+                       0,
+                       0,
+                       0,
+                       mode,
+                       0,
+                       0);
+       if (ret)
+               dev_err(ringacc->dev, "TISCI reconf qmode fail (%d) ring_idx %d\n",
+                       ret, ring->ring_id);
+}
+
+void k3_nav_ringacc_ring_reset_dma(struct k3_nav_ring *ring, u32 occ)
+{
+       if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
+               return;
+
+       if (!ring->parent->dma_ring_reset_quirk)
+               return;
+
+       if (!occ)
+               occ = ringacc_readl(&ring->rt->occ);
+
+       if (occ) {
+               u32 db_ring_cnt, db_ring_cnt_cur;
+
+               pr_debug("%s %u occ: %u\n", __func__,
+                        ring->ring_id, occ);
+               /* 2. Reset the ring */
+               k3_ringacc_ring_reset_sci(ring);
+
+               /*
+                * 3. Setup the ring in ring/doorbell mode
+                * (if not already in this mode)
+                */
+               if (ring->mode != K3_NAV_RINGACC_RING_MODE_RING)
+                       k3_ringacc_ring_reconfig_qmode_sci(
+                                       ring, K3_NAV_RINGACC_RING_MODE_RING);
+               /*
+                * 4. Ring the doorbell 2**22 â€“ ringOcc times.
+                * This will wrap the internal UDMAP ring state occupancy
+                * counter (which is 21-bits wide) to 0.
+                */
+               db_ring_cnt = (1U << 22) - occ;
+
+               while (db_ring_cnt != 0) {
+                       /*
+                        * Ring the doorbell with the maximum count each
+                        * iteration if possible to minimize the total
+                        * of writes
+                        */
+                       if (db_ring_cnt > KNAV_RINGACC_MAX_DB_RING_CNT)
+                               db_ring_cnt_cur = KNAV_RINGACC_MAX_DB_RING_CNT;
+                       else
+                               db_ring_cnt_cur = db_ring_cnt;
+
+                       writel(db_ring_cnt_cur, &ring->rt->db);
+                       db_ring_cnt -= db_ring_cnt_cur;
+               }
+
+               /* 5. Restore the original ring mode (if not ring mode) */
+               if (ring->mode != K3_NAV_RINGACC_RING_MODE_RING)
+                       k3_ringacc_ring_reconfig_qmode_sci(ring, ring->mode);
+       }
+
+       /* 2. Reset the ring */
+       k3_nav_ringacc_ring_reset(ring);
+}
+
+static void k3_ringacc_ring_free_sci(struct k3_nav_ring *ring)
+{
+       struct k3_nav_ringacc *ringacc = ring->parent;
+       int ret;
+
+       ret = ringacc->tisci_ring_ops->config(
+                       ringacc->tisci,
+                       TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER,
+                       ringacc->tisci_dev_id,
+                       ring->ring_id,
+                       0,
+                       0,
+                       0,
+                       0,
+                       0,
+                       0);
+       if (ret)
+               dev_err(ringacc->dev, "TISCI ring free fail (%d) ring_idx %d\n",
+                       ret, ring->ring_id);
+}
+
+int k3_nav_ringacc_ring_free(struct k3_nav_ring *ring)
+{
+       struct k3_nav_ringacc *ringacc;
+
+       if (!ring)
+               return -EINVAL;
+
+       ringacc = ring->parent;
+
+       pr_debug("%s flags: 0x%08x\n", __func__, ring->flags);
+
+       if (!test_bit(ring->ring_id, ringacc->rings_inuse))
+               return -EINVAL;
+
+       if (--ring->use_count)
+               goto out;
+
+       if (!(ring->flags & KNAV_RING_FLAG_BUSY))
+               goto no_init;
+
+       k3_ringacc_ring_free_sci(ring);
+
+       dma_free_coherent(ringacc->dev,
+                         ring->size * (4 << ring->elm_size),
+                         ring->ring_mem_virt, ring->ring_mem_dma);
+       ring->flags &= ~KNAV_RING_FLAG_BUSY;
+       ring->ops = NULL;
+       if (ring->proxy_id != K3_RINGACC_PROXY_NOT_USED) {
+               clear_bit(ring->proxy_id, ringacc->proxy_inuse);
+               ring->proxy = NULL;
+               ring->proxy_id = K3_RINGACC_PROXY_NOT_USED;
+       }
+
+no_init:
+       clear_bit(ring->ring_id, ringacc->rings_inuse);
+
+       module_put(ringacc->dev->driver->owner);
+
+out:
+       return 0;
+}
+
+u32 k3_nav_ringacc_get_ring_id(struct k3_nav_ring *ring)
+{
+       if (!ring)
+               return -EINVAL;
+
+       return ring->ring_id;
+}
+
+static int k3_nav_ringacc_ring_cfg_sci(struct k3_nav_ring *ring)
+{
+       struct k3_nav_ringacc *ringacc = ring->parent;
+       u32 ring_idx;
+       int ret;
+
+       if (!ringacc->tisci)
+               return -EINVAL;
+
+       ring_idx = ring->ring_id;
+       ret = ringacc->tisci_ring_ops->config(
+                       ringacc->tisci,
+                       TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER,
+                       ringacc->tisci_dev_id,
+                       ring_idx,
+                       lower_32_bits(ring->ring_mem_dma),
+                       upper_32_bits(ring->ring_mem_dma),
+                       ring->size,
+                       ring->mode,
+                       ring->elm_size,
+                       0);
+       if (ret)
+               dev_err(ringacc->dev, "TISCI config ring fail (%d) ring_idx %d\n",
+                       ret, ring_idx);
+
+       return ret;
+}
+
+int k3_nav_ringacc_ring_cfg(struct k3_nav_ring *ring,
+                           struct k3_nav_ring_cfg *cfg)
+{
+       struct k3_nav_ringacc *ringacc = ring->parent;
+       int ret = 0;
+
+       if (!ring || !cfg)
+               return -EINVAL;
+       if (cfg->elm_size > K3_NAV_RINGACC_RING_ELSIZE_256 ||
+           cfg->mode > K3_NAV_RINGACC_RING_MODE_QM ||
+           cfg->size & ~KNAV_RINGACC_CFG_RING_SIZE_ELCNT_MASK ||
+           !test_bit(ring->ring_id, ringacc->rings_inuse))
+               return -EINVAL;
+
+       if (ring->use_count != 1)
+               return 0;
+
+       ring->size = cfg->size;
+       ring->elm_size = cfg->elm_size;
+       ring->mode = cfg->mode;
+       ring->occ = 0;
+       ring->free = 0;
+       ring->rindex = 0;
+       ring->windex = 0;
+
+       if (ring->proxy_id != K3_RINGACC_PROXY_NOT_USED)
+               ring->proxy = ringacc->proxy_target_base +
+                             ring->proxy_id * K3_RINGACC_PROXY_TARGET_STEP;
+
+       switch (ring->mode) {
+       case K3_NAV_RINGACC_RING_MODE_RING:
+               ring->ops = &k3_nav_mode_ring_ops;
+               break;
+       case K3_NAV_RINGACC_RING_MODE_QM:
+               /*
+                * In Queue mode elm_size can be 8 only and each operation
+                * uses 2 element slots
+                */
+               if (cfg->elm_size != K3_NAV_RINGACC_RING_ELSIZE_8 ||
+                   cfg->size % 2)
+                       goto err_free_proxy;
+       case K3_NAV_RINGACC_RING_MODE_MESSAGE:
+               if (ring->proxy)
+                       ring->ops = &k3_nav_mode_proxy_ops;
+               else
+                       ring->ops = &k3_nav_mode_msg_ops;
+               break;
+       default:
+               ring->ops = NULL;
+               ret = -EINVAL;
+               goto err_free_proxy;
+       };
+
+       ring->ring_mem_virt =
+                       dma_zalloc_coherent(ringacc->dev,
+                                           ring->size * (4 << ring->elm_size),
+                                           &ring->ring_mem_dma, GFP_KERNEL);
+       if (!ring->ring_mem_virt) {
+               dev_err(ringacc->dev, "Failed to alloc ring mem\n");
+               ret = -ENOMEM;
+               goto err_free_ops;
+       }
+
+       ret = k3_nav_ringacc_ring_cfg_sci(ring);
+
+       if (ret)
+               goto err_free_mem;
+
+       ring->flags |= KNAV_RING_FLAG_BUSY;
+       ring->flags |= (cfg->flags & K3_NAV_RINGACC_RING_SHARED) ?
+                       K3_NAV_RING_FLAG_SHARED : 0;
+
+       return 0;
+
+err_free_mem:
+       dma_free_coherent(ringacc->dev,
+                         ring->size * (4 << ring->elm_size),
+                         ring->ring_mem_virt,
+                         ring->ring_mem_dma);
+err_free_ops:
+       ring->ops = NULL;
+err_free_proxy:
+       ring->proxy = NULL;
+       return ret;
+}
+
+u32 k3_nav_ringacc_ring_get_size(struct k3_nav_ring *ring)
+{
+       if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
+               return -EINVAL;
+
+       return ring->size;
+}
+
+u32 k3_nav_ringacc_ring_get_free(struct k3_nav_ring *ring)
+{
+       if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
+               return -EINVAL;
+
+       if (!ring->free)
+               ring->free = ring->size - ringacc_readl(&ring->rt->occ);
+
+       return ring->free;
+}
+
+u32 k3_nav_ringacc_ring_get_occ(struct k3_nav_ring *ring)
+{
+       if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
+               return -EINVAL;
+
+       return ringacc_readl(&ring->rt->occ);
+}
+
+u32 k3_nav_ringacc_ring_is_full(struct k3_nav_ring *ring)
+{
+       return !k3_nav_ringacc_ring_get_free(ring);
+}
+
+enum k3_ringacc_access_mode {
+       K3_RINGACC_ACCESS_MODE_PUSH_HEAD,
+       K3_RINGACC_ACCESS_MODE_POP_HEAD,
+       K3_RINGACC_ACCESS_MODE_PUSH_TAIL,
+       K3_RINGACC_ACCESS_MODE_POP_TAIL,
+       K3_RINGACC_ACCESS_MODE_PEEK_HEAD,
+       K3_RINGACC_ACCESS_MODE_PEEK_TAIL,
+};
+
+static int k3_ringacc_ring_cfg_proxy(struct k3_nav_ring *ring,
+                                    enum k3_ringacc_proxy_access_mode mode)
+{
+       u32 val;
+
+       val = ring->ring_id;
+       val |= mode << 16;
+       val |= ring->elm_size << 24;
+       ringacc_writel(val, &ring->proxy->control);
+       return 0;
+}
+
+static int k3_nav_ringacc_ring_access_proxy(
+                       struct k3_nav_ring *ring, void *elem,
+                       enum k3_ringacc_access_mode access_mode)
+{
+       void __iomem *ptr;
+
+       ptr = (void __iomem *)&ring->proxy->data;
+
+       switch (access_mode) {
+       case K3_RINGACC_ACCESS_MODE_PUSH_HEAD:
+       case K3_RINGACC_ACCESS_MODE_POP_HEAD:
+               k3_ringacc_ring_cfg_proxy(ring, PROXY_ACCESS_MODE_HEAD);
+               break;
+       case K3_RINGACC_ACCESS_MODE_PUSH_TAIL:
+       case K3_RINGACC_ACCESS_MODE_POP_TAIL:
+               k3_ringacc_ring_cfg_proxy(ring, PROXY_ACCESS_MODE_TAIL);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ptr += k3_nav_ringacc_ring_get_fifo_pos(ring);
+
+       switch (access_mode) {
+       case K3_RINGACC_ACCESS_MODE_POP_HEAD:
+       case K3_RINGACC_ACCESS_MODE_POP_TAIL:
+               pr_debug("proxy:memcpy_fromio(x): --> ptr(%p), mode:%d\n",
+                        ptr, access_mode);
+               memcpy_fromio(elem, ptr, (4 << ring->elm_size));
+               ring->occ--;
+               break;
+       case K3_RINGACC_ACCESS_MODE_PUSH_TAIL:
+       case K3_RINGACC_ACCESS_MODE_PUSH_HEAD:
+               pr_debug("proxy:memcpy_toio(x): --> ptr(%p), mode:%d\n",
+                        ptr, access_mode);
+               memcpy_toio(ptr, elem, (4 << ring->elm_size));
+               ring->free--;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       pr_debug("proxy: free%d occ%d\n",
+                ring->free, ring->occ);
+       return 0;
+}
+
+static int k3_ringacc_ring_push_head_proxy(struct k3_nav_ring *ring, void *elem)
+{
+       return k3_nav_ringacc_ring_access_proxy(
+                       ring, elem, K3_RINGACC_ACCESS_MODE_PUSH_HEAD);
+}
+
+static int k3_ringacc_ring_push_tail_proxy(struct k3_nav_ring *ring, void *elem)
+{
+       return k3_nav_ringacc_ring_access_proxy(
+                       ring, elem, K3_RINGACC_ACCESS_MODE_PUSH_TAIL);
+}
+
+static int k3_ringacc_ring_pop_head_proxy(struct k3_nav_ring *ring, void *elem)
+{
+       return k3_nav_ringacc_ring_access_proxy(
+                       ring, elem, K3_RINGACC_ACCESS_MODE_POP_HEAD);
+}
+
+static int k3_ringacc_ring_pop_tail_proxy(struct k3_nav_ring *ring, void *elem)
+{
+       return k3_nav_ringacc_ring_access_proxy(
+                       ring, elem, K3_RINGACC_ACCESS_MODE_POP_HEAD);
+}
+
+static int k3_nav_ringacc_ring_access_io(
+               struct k3_nav_ring *ring, void *elem,
+               enum k3_ringacc_access_mode access_mode)
+{
+       void __iomem *ptr;
+
+       switch (access_mode) {
+       case K3_RINGACC_ACCESS_MODE_PUSH_HEAD:
+       case K3_RINGACC_ACCESS_MODE_POP_HEAD:
+               ptr = (void __iomem *)&ring->fifos->head_data;
+               break;
+       case K3_RINGACC_ACCESS_MODE_PUSH_TAIL:
+       case K3_RINGACC_ACCESS_MODE_POP_TAIL:
+               ptr = (void __iomem *)&ring->fifos->tail_data;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ptr += k3_nav_ringacc_ring_get_fifo_pos(ring);
+
+       switch (access_mode) {
+       case K3_RINGACC_ACCESS_MODE_POP_HEAD:
+       case K3_RINGACC_ACCESS_MODE_POP_TAIL:
+               pr_debug("memcpy_fromio(x): --> ptr(%p), mode:%d\n",
+                        ptr, access_mode);
+               memcpy_fromio(elem, ptr, (4 << ring->elm_size));
+               ring->occ--;
+               break;
+       case K3_RINGACC_ACCESS_MODE_PUSH_TAIL:
+       case K3_RINGACC_ACCESS_MODE_PUSH_HEAD:
+               pr_debug("memcpy_toio(x): --> ptr(%p), mode:%d\n",
+                        ptr, access_mode);
+               memcpy_toio(ptr, elem, (4 << ring->elm_size));
+               ring->free--;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       pr_debug("free%d index%d occ%d index%d\n",
+                ring->free, ring->windex, ring->occ, ring->rindex);
+       return 0;
+}
+
+static int k3_nav_ringacc_ring_push_head_io(struct k3_nav_ring *ring,
+                                           void *elem)
+{
+       return k3_nav_ringacc_ring_access_io(
+                       ring, elem, K3_RINGACC_ACCESS_MODE_PUSH_HEAD);
+}
+
+static int k3_nav_ringacc_ring_push_io(struct k3_nav_ring *ring, void *elem)
+{
+       return k3_nav_ringacc_ring_access_io(
+                       ring, elem, K3_RINGACC_ACCESS_MODE_PUSH_TAIL);
+}
+
+static int k3_nav_ringacc_ring_pop_io(struct k3_nav_ring *ring, void *elem)
+{
+       return k3_nav_ringacc_ring_access_io(
+                       ring, elem, K3_RINGACC_ACCESS_MODE_POP_HEAD);
+}
+
+static int k3_nav_ringacc_ring_pop_tail_io(struct k3_nav_ring *ring, void *elem)
+{
+       return k3_nav_ringacc_ring_access_io(
+                       ring, elem, K3_RINGACC_ACCESS_MODE_POP_HEAD);
+}
+
+static int k3_nav_ringacc_ring_push_mem(struct k3_nav_ring *ring, void *elem)
+{
+       void *elem_ptr;
+
+       elem_ptr = k3_nav_ringacc_get_elm_addr(ring, ring->windex);
+
+       memcpy(elem_ptr, elem, (4 << ring->elm_size));
+
+       ring->windex = (ring->windex + 1) % ring->size;
+       ring->free--;
+       ringacc_writel(1, &ring->rt->db);
+
+       pr_debug("ring_push_mem: free%d index%d\n",
+                ring->free, ring->windex);
+
+       return 0;
+}
+
+static int k3_nav_ringacc_ring_pop_mem(struct k3_nav_ring *ring, void *elem)
+{
+       void *elem_ptr;
+
+       elem_ptr = k3_nav_ringacc_get_elm_addr(ring, ring->rindex);
+
+       memcpy(elem, elem_ptr, (4 << ring->elm_size));
+
+       ring->rindex = (ring->rindex + 1) % ring->size;
+       ring->occ--;
+       ringacc_writel(-1, &ring->rt->db);
+
+       pr_debug("ring_pop_mem: occ%d index%d pos_ptr%p\n",
+                ring->occ, ring->rindex, elem_ptr);
+       return 0;
+}
+
+int k3_nav_ringacc_ring_push(struct k3_nav_ring *ring, void *elem)
+{
+       int ret = -EOPNOTSUPP;
+
+       if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
+               return -EINVAL;
+
+       pr_debug("ring_push%d: free%d index%d\n",
+                ring->ring_id, ring->free, ring->windex);
+
+       if (k3_nav_ringacc_ring_is_full(ring))
+               return -ENOMEM;
+
+       if (ring->ops && ring->ops->push_tail)
+               ret = ring->ops->push_tail(ring, elem);
+
+       return ret;
+}
+
+int k3_nav_ringacc_ring_push_head(struct k3_nav_ring *ring, void *elem)
+{
+       int ret = -EOPNOTSUPP;
+
+       if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
+               return -EINVAL;
+
+       pr_debug("ring_push_head: free%d index%d\n",
+                ring->free, ring->windex);
+
+       if (k3_nav_ringacc_ring_is_full(ring))
+               return -ENOMEM;
+
+       if (ring->ops && ring->ops->push_head)
+               ret = ring->ops->push_head(ring, elem);
+
+       return ret;
+}
+
+int k3_nav_ringacc_ring_pop(struct k3_nav_ring *ring, void *elem)
+{
+       int ret = -EOPNOTSUPP;
+
+       if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
+               return -EINVAL;
+
+       if (!ring->occ)
+               ring->occ = k3_nav_ringacc_ring_get_occ(ring);
+
+       pr_debug("ring_pop%d: occ%d index%d\n",
+                ring->ring_id, ring->occ, ring->rindex);
+
+       if (!ring->occ)
+               return -ENODATA;
+
+       if (ring->ops && ring->ops->pop_head)
+               ret = ring->ops->pop_head(ring, elem);
+
+       return ret;
+}
+
+int k3_nav_ringacc_ring_pop_tail(struct k3_nav_ring *ring, void *elem)
+{
+       int ret = -EOPNOTSUPP;
+
+       if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
+               return -EINVAL;
+
+       if (!ring->occ)
+               ring->occ = k3_nav_ringacc_ring_get_occ(ring);
+
+       pr_debug("ring_pop_tail: occ%d index%d\n",
+                ring->occ, ring->rindex);
+
+       if (!ring->occ)
+               return -ENODATA;
+
+       if (ring->ops && ring->ops->pop_tail)
+               ret = ring->ops->pop_tail(ring, elem);
+
+       return ret;
+}
+
+static int k3_nav_ringacc_probe_dt(struct k3_nav_ringacc *ringacc)
+{
+       struct udevice *dev = ringacc->dev;
+       struct udevice *tisci_dev = NULL;
+       int ret;
+
+       ringacc->num_rings = dev_read_u32_default(dev, "ti,num-rings", 0);
+       if (!ringacc->num_rings) {
+               dev_err(dev, "ti,num-rings read failure %d\n", ret);
+               return -EINVAL;
+       }
+
+       ringacc->dma_ring_reset_quirk =
+                       dev_read_bool(dev, "ti,dma-ring-reset-quirk");
+
+       ret = uclass_get_device_by_name(UCLASS_FIRMWARE, "dmsc", &tisci_dev);
+       if (ret) {
+               pr_debug("TISCI RA RM get failed (%d)\n", ret);
+               ringacc->tisci = NULL;
+               return -ENODEV;
+       }
+       ringacc->tisci = (struct ti_sci_handle *)
+                        (ti_sci_get_handle_from_sysfw(tisci_dev));
+
+       ret = dev_read_u32_default(dev, "ti,sci", 0);
+       if (!ret) {
+               dev_err(dev, "TISCI RA RM disabled\n");
+               ringacc->tisci = NULL;
+               return ret;
+       }
+
+       ret = dev_read_u32(dev, "ti,sci-dev-id", &ringacc->tisci_dev_id);
+       if (ret) {
+               dev_err(dev, "ti,sci-dev-id read failure %d\n", ret);
+               ringacc->tisci = NULL;
+               return ret;
+       }
+
+       ringacc->rm_gp_range = devm_ti_sci_get_of_resource(
+                                       ringacc->tisci, dev,
+                                       ringacc->tisci_dev_id,
+                                       "ti,sci-rm-range-gp-rings");
+       if (IS_ERR(ringacc->rm_gp_range))
+               ret = PTR_ERR(ringacc->rm_gp_range);
+
+       return 0;
+}
+
+static int k3_nav_ringacc_probe(struct udevice *dev)
+{
+       struct k3_nav_ringacc *ringacc;
+       void __iomem *base_fifo, *base_rt;
+       int ret, i;
+
+       ringacc = dev_get_priv(dev);
+       if (!ringacc)
+               return -ENOMEM;
+
+       ringacc->dev = dev;
+
+       ret = k3_nav_ringacc_probe_dt(ringacc);
+       if (ret)
+               return ret;
+
+       base_rt = (uint32_t *)devfdt_get_addr_name(dev, "rt");
+       pr_debug("rt %p\n", base_rt);
+       if (IS_ERR(base_rt))
+               return PTR_ERR(base_rt);
+
+       base_fifo = (uint32_t *)devfdt_get_addr_name(dev, "fifos");
+       pr_debug("fifos %p\n", base_fifo);
+       if (IS_ERR(base_fifo))
+               return PTR_ERR(base_fifo);
+
+       ringacc->proxy_gcfg = (struct k3_ringacc_proxy_gcfg_regs __iomem *)
+               devfdt_get_addr_name(dev, "proxy_gcfg");
+       if (IS_ERR(ringacc->proxy_gcfg))
+               return PTR_ERR(ringacc->proxy_gcfg);
+       ringacc->proxy_target_base =
+               (struct k3_ringacc_proxy_gcfg_regs __iomem *)
+               devfdt_get_addr_name(dev, "proxy_target");
+       if (IS_ERR(ringacc->proxy_target_base))
+               return PTR_ERR(ringacc->proxy_target_base);
+
+       ringacc->num_proxies = ringacc_readl(&ringacc->proxy_gcfg->config) &
+                                        K3_RINGACC_PROXY_CFG_THREADS_MASK;
+
+       ringacc->rings = devm_kzalloc(dev,
+                                     sizeof(*ringacc->rings) *
+                                     ringacc->num_rings,
+                                     GFP_KERNEL);
+       ringacc->rings_inuse = devm_kcalloc(dev,
+                                           BITS_TO_LONGS(ringacc->num_rings),
+                                           sizeof(unsigned long), GFP_KERNEL);
+       ringacc->proxy_inuse = devm_kcalloc(dev,
+                                           BITS_TO_LONGS(ringacc->num_proxies),
+                                           sizeof(unsigned long), GFP_KERNEL);
+
+       if (!ringacc->rings || !ringacc->rings_inuse || !ringacc->proxy_inuse)
+               return -ENOMEM;
+
+       for (i = 0; i < ringacc->num_rings; i++) {
+               ringacc->rings[i].rt = base_rt +
+                                      KNAV_RINGACC_RT_REGS_STEP * i;
+               ringacc->rings[i].fifos = base_fifo +
+                                         KNAV_RINGACC_FIFO_REGS_STEP * i;
+               ringacc->rings[i].parent = ringacc;
+               ringacc->rings[i].ring_id = i;
+               ringacc->rings[i].proxy_id = K3_RINGACC_PROXY_NOT_USED;
+       }
+       dev_set_drvdata(dev, ringacc);
+
+       ringacc->tisci_ring_ops = &ringacc->tisci->ops.rm_ring_ops;
+
+       list_add_tail(&ringacc->list, &k3_nav_ringacc_list);
+
+       dev_info(dev, "Ring Accelerator probed rings:%u, gp-rings[%u,%u] sci-dev-id:%u\n",
+                ringacc->num_rings,
+                ringacc->rm_gp_range->desc[0].start,
+                ringacc->rm_gp_range->desc[0].num,
+                ringacc->tisci_dev_id);
+       dev_info(dev, "dma-ring-reset-quirk: %s\n",
+                ringacc->dma_ring_reset_quirk ? "enabled" : "disabled");
+       dev_info(dev, "RA Proxy rev. %08x, num_proxies:%u\n",
+                ringacc_readl(&ringacc->proxy_gcfg->revision),
+                ringacc->num_proxies);
+       return 0;
+}
+
+static const struct udevice_id knav_ringacc_ids[] = {
+       { .compatible = "ti,am654-navss-ringacc" },
+       {},
+};
+
+U_BOOT_DRIVER(k3_navss_ringacc) = {
+       .name   = "k3-navss-ringacc",
+       .id     = UCLASS_MISC,
+       .of_match = knav_ringacc_ids,
+       .probe = k3_nav_ringacc_probe,
+       .priv_auto_alloc_size = sizeof(struct k3_nav_ringacc),
+};
index 098372e0932408779194a10addb1553d2abe6545..a700f240adff4834c30c3070fb838b90bb25affc 100644 (file)
@@ -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
index 8b60d7c3b2245f79b8f95c868a952956804627cc..bb1067ff4a9fc2cce0d1f6a8191a9780f77c5b8e 100644 (file)
@@ -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,
 };
index 34506402ac3a1c59f9f94c2b0b210df7d83faa61..3fb39b9952e313c721340fd81eb4f639bad427a7 100644 (file)
@@ -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;
        }
index 34e78beb2a66f8f6d7afd54409e718f6902f08ba..9d7f503b698dc560eb67fd8958b16b1f8f21a0a7 100644 (file)
@@ -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.
index a0df02d10382bb369415ecbd1f3335dfce7ee4e6..885821d562ea1ae49eec315a33a6b22144648081 100644 (file)
@@ -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;
 }
 
index a5f30c8fd03b53559a55190e909b35f0c5cf0527..c9ab66cccc817910979f35699a8f8ffa6b5e1987 100644 (file)
@@ -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
index 29eda66fad846eadcd9a412b578f0800449fef19..d0b95f483d34cc4649c39f53355587f3a277fd0c 100644 (file)
@@ -26,7 +26,7 @@
 #if defined(CONFIG_CMD_SAVEENV) && defined(CONFIG_CMD_NAND) && \
                !defined(CONFIG_SPL_BUILD)
 #define CMD_SAVEENV
-#elif defined(CONFIG_ENV_OFFSET_REDUND)
+#elif defined(CONFIG_ENV_OFFSET_REDUND) && !defined(CONFIG_SPL_BUILD)
 #error CONFIG_ENV_OFFSET_REDUND must have CONFIG_CMD_SAVEENV & CONFIG_CMD_NAND
 #endif
 
diff --git a/include/configs/am335x_guardian.h b/include/configs/am335x_guardian.h
new file mode 100644 (file)
index 0000000..8bde198
--- /dev/null
@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * am335x_guardian_.h
+ *
+ * Copyright (C) 2018 Robert Bosch Power Tools GmbH
+ * Copyright (C) 2018 sjoerd Simons <sjoerd.simons@collabora.co.uk>
+ *
+ */
+
+#ifndef __CONFIG_AM335X_GUARDIAN_H
+#define __CONFIG_AM335X_GUARDIAN_H
+
+#include <configs/ti_am335x_common.h>
+
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_TIMESTAMP
+#endif
+
+/* Clock Defines */
+#define V_OSCK                         24000000  /* Clock output from T2 */
+#define V_SCLK                         (V_OSCK)
+
+#ifndef CONFIG_SPL_BUILD
+
+#define MEM_LAYOUT_ENV_SETTINGS \
+       "scriptaddr=0x80000000\0" \
+       "pxefile_addr_r=0x80100000\0" \
+       "kernel_addr_r=0x82000000\0" \
+       "fdt_addr_r=0x88000000\0" \
+       "ramdisk_addr_r=0x88080000\0" \
+
+#define BOOT_TARGET_DEVICES(func) \
+       func(MMC, mmc, 0) \
+       func(UBIFS, ubifs, 0) \
+       func(PXE, pxe, na) \
+       func(DHCP, dhcp, na)
+
+#define AM335XX_BOARD_FDTFILE "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0"
+
+#include <config_distro_bootcmd.h>
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+       AM335XX_BOARD_FDTFILE \
+       MEM_LAYOUT_ENV_SETTINGS \
+       BOOTENV \
+       "bootlimit=3\0" \
+       "altbootcmd=" \
+               "setenv boot_config \"extlinux-rollback.conf\"; " \
+               "run distro_bootcmd\0"
+
+#endif /* CONFIG_SPL_BUILD */
+
+/* NS16550 Configuration */
+#define CONFIG_SYS_NS16550_COM1                0x44e09000      /* UART0 */
+#define CONFIG_SYS_NS16550_COM2                0x48022000      /* UART1 */
+#define CONFIG_SYS_NS16550_COM3                0x48024000      /* UART2 */
+#define CONFIG_SYS_NS16550_COM4                0x481a6000      /* UART3 */
+#define CONFIG_SYS_NS16550_COM5                0x481a8000      /* UART4 */
+#define CONFIG_SYS_NS16550_COM6                0x481aa000      /* UART5 */
+
+/* PMIC support */
+#define CONFIG_POWER_TPS65217
+
+/* Bootcount using the RTC block */
+#define CONFIG_SYS_BOOTCOUNT_LE
+
+#ifdef CONFIG_NAND
+#define CONFIG_ENV_OFFSET              0x300000
+#define CONFIG_ENV_OFFSET_REDUND       0x340000
+#define CONFIG_ENV_SIZE                        0x040000
+
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#define CONFIG_SYS_NAND_PAGE_COUNT      (CONFIG_SYS_NAND_BLOCK_SIZE / \
+                                       CONFIG_SYS_NAND_PAGE_SIZE)
+#define CONFIG_SYS_NAND_PAGE_SIZE       4096
+#define CONFIG_SYS_NAND_OOBSIZE         256
+#define CONFIG_SYS_NAND_BLOCK_SIZE      (256 * 1024)
+
+#define CONFIG_SYS_NAND_ECCPOS  {   2,   3,   4,   5,   6,   7,   8,   9, \
+                        10,  11,  12,  13,  14,  15,  16,  17,  18,  19, \
+                        20,  21,  22,  23,  24,  25,  26,  27,  28,  29, \
+                        30,  31,  32,  33,  34,  35,  36,  37,  38,  39, \
+                        40,  41,  42,  43,  44,  45,  46,  47,  48,  49, \
+                        50,  51,  52,  53,  54,  55,  56,  57,  58,  59, \
+                        60,  61,  62,  63,  64,  65,  66,  67,  68,  69, \
+                        70,  71,  72,  73,  74,  75,  76,  77,  78,  79, \
+                        80,  81,  82,  83,  84,  85,  86,  87,  88,  89, \
+                        90,  91,  92,  93,  94,  95,  96,  97,  98,  99, \
+                       100, 101, 102, 103, 104, 105, 106, 107, 108, 109, \
+                       110, 111, 112, 113, 114, 115, 116, 117, 118, 119, \
+                       120, 121, 122, 123, 124, 125, 126, 127, 128, 129, \
+                       130, 131, 132, 133, 134, 135, 136, 137, 138, 139, \
+                       140, 141, 142, 143, 144, 145, 146, 147, 148, 149, \
+                       150, 151, 152, 153, 154, 155, 156, 157, 158, 159, \
+                       160, 161, 162, 163, 164, 165, 166, 167, 168, 169, \
+                       170, 171, 172, 173, 174, 175, 176, 177, 178, 179, \
+                       180, 181, 182, 183, 184, 185, 186, 187, 188, 189, \
+                       190, 191, 192, 193, 194, 195, 196, 197, 198, 199, \
+                       200, 201, 202, 203, 204, 205, 206, 207, 208, 209, \
+                       }
+#define CONFIG_SYS_NAND_ECCSIZE         512
+#define CONFIG_SYS_NAND_ECCBYTES        26
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+#define CONFIG_NAND_OMAP_ECCSCHEME      OMAP_ECC_BCH16_CODE_HW
+#define MTDIDS_DEFAULT                  "nand0=nand.0"
+
+#define CONFIG_SYS_NAND_BAD_BLOCK_POS   NAND_LARGE_BADBLOCK_POS
+
+#endif /* CONFIG_NAND */
+
+#endif /* ! __CONFIG_AM335X_GUARDIAN_H */
diff --git a/include/configs/ap152.h b/include/configs/ap152.h
new file mode 100644 (file)
index 0000000..c948a44
--- /dev/null
@@ -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 */
index c51cf284502b922961538ffd04554d1a60818c46..9f8d3cc9e5e8cd9f0b49fd2e7389d55c0f84c8d2 100644 (file)
@@ -21,8 +21,6 @@
  * Commands configuration
  */
 
-/* SPI NOR flash default params, used by sf commands */
-
 /*
  * SDIO/MMC Card Configuration
  */
index 583f9948072830b81e49d1ae6cb08362c4a8664e..94848f5128b05c6a58c48f45e4fef8ed564bc7e1 100644 (file)
@@ -48,7 +48,8 @@
 #define PHYS_SDRAM_1           DAVINCI_DDR_EMIF_DATA_BASE /* DDR Start */
 #define PHYS_SDRAM_1_SIZE      (64 << 20) /* SDRAM size 64MB */
 #define CONFIG_MAX_RAM_BANK_SIZE (512 << 20) /* max size from SPRS586*/
-
+#define CONFIG_SPL_BSS_START_ADDR DAVINCI_DDR_EMIF_DATA_BASE
+#define CONFIG_SPL_BSS_MAX_SIZE 0x1080000
 /* memtest start addr */
 #define CONFIG_SYS_MEMTEST_START       (PHYS_SDRAM_1 + 0x2000000)
 
index 55968c2749efeb86be72042d65392fc5a811df4a..63194d58a29bcf5d0968c031e3984d42d5c03436 100644 (file)
@@ -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 */
index f1bdc2d3e74ffb9a3cd783e4e39e7082f3ed6210..2fdc845029214dc3a2da0d6e606bc26efe07210f 100644 (file)
@@ -16,8 +16,6 @@
  * Commands configuration
  */
 
-/* SPI NOR flash default params, used by sf commands */
-
 /* USB/EHCI configuration */
 #define CONFIG_EHCI_IS_TDI
 
index d378052a8f7caf0925ead9aded12df677b2ff853..ec2405bbb456115d4b6f5c68433ab0f9ce700371 100644 (file)
 #define CONFIG_SYS_I2C_SLAVE           0x0
 #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
  */
index b78dbcb6b946610b172d2e76ee94429c9748af78..1f9d24b19b980a87118371d4269d6b58fd22920f 100644 (file)
@@ -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 (file)
index 0000000..0f75ad7
--- /dev/null
@@ -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 */
index 10eac20aa0c8fca754550a74c23f3853b2171451..7441f4a69dea100ace1f2f2cfaf3ae764cb7c33e 100644 (file)
                                         50, 51, 52, 53, 54, 55, 56, 57, }
 #define CONFIG_SYS_NAND_ECCSIZE                512
 #define CONFIG_SYS_NAND_ECCBYTES       14
-#define CONFIG_SYS_NAND_U_BOOT_OFFS    0x000c0000
+#define CONFIG_SYS_NAND_U_BOOT_OFFS    0x00140000
 /* NAND: SPL related configs */
 /* NAND: SPL falcon mode configs */
 #ifdef CONFIG_SPL_OS_BOOT
index 275a2b4788052f5808ad587430b2b6636e013cbe..192c055c5cc45c1801ada6973650e4f21c6358d5 100644 (file)
@@ -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 */
index df4d8bcb3bbf869c830a8b0138e6d1b446c144a9..b2badab15eab25f82ca14057125d23e4a6bd8960 100644 (file)
@@ -23,8 +23,6 @@
  * Commands configuration
  */
 
-/* SPI NOR flash default params, used by sf commands */
-
 /*
  * SDIO/MMC Card Configuration
  */
index 2c0e4cbe92fd2244ce759fd2fac0b8f09c613ce0..547127490c9258e3301f5d5986fbb7a1912ae7ad 100644 (file)
 
 #include <configs/ti_armv7_keystone2.h>
 
-/* SPL SPI Loader Configuration */
-#define CONFIG_SPL_TEXT_BASE           0x0c100000
-
-
 #define SPI_MTD_PARTS KEYSTONE_SPI0_MTD_PARTS
 
 /* NAND Configuration */
index b1aec98a37225345cc20059c41265bd76b2eaba7..3ec5a5acf5f9780c744e44c68c0ba2a2aa8b662e 100644 (file)
@@ -72,9 +72,6 @@
        "bootm ${fit_loadaddr}#${name_fdt}"
 #endif
 
-/* SPL SPI Loader Configuration */
-#define CONFIG_SPL_TEXT_BASE           0x0c0a0000
-
 /* NAND Configuration */
 #define CONFIG_SYS_NAND_PAGE_2K
 
index 0b909a1bf6fabbbe82c8c67eefbfcc4dc6160734..d4f2e96bab087bf6355cf1138ac963c88de1097b 100644 (file)
@@ -40,9 +40,6 @@
 
 #include <configs/ti_armv7_keystone2.h>
 
-/* SPL SPI Loader Configuration */
-#define CONFIG_SPL_TEXT_BASE           0x0c200000
-
 #define SPI_MTD_PARTS KEYSTONE_SPI0_MTD_PARTS
 
 /* NAND Configuration */
index 59e6b096733a47c37a713a9a45de4c53e6a18f39..cfdb36e2d7ff72100bc996ace2239db88306583e 100644 (file)
@@ -40,9 +40,6 @@
 
 #include <configs/ti_armv7_keystone2.h>
 
-/* SPL SPI Loader Configuration */
-#define CONFIG_SPL_TEXT_BASE           0x0c100000
-
 #define SPI_MTD_PARTS KEYSTONE_SPI0_MTD_PARTS
 
 /* NAND Configuration */
index 72e62658d0ccc7a201e134111706a148b3160b23..55c4e633254755d54f21998ac4e6eedbd9e2207e 100644 (file)
@@ -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 "               \
                "&& 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 "                                        \
 #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 */
index f4972b64dcb158cf6ff8463cb56197957c8a5801..b28f3b94085ab695413d98759c062de11696a74c 100644 (file)
 /* 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 */
index 1786e099ad4f7f7bff87b56ddd789f8ed85b3e5a..6680c3e5037507ace510cd9499a2762671d53987 100644 (file)
@@ -43,6 +43,9 @@
 #define PHYS_SDRAM_1_SIZE      (128 << 20) /* SDRAM size 128MB */
 #define CONFIG_MAX_RAM_BANK_SIZE (512 << 20) /* max size from SPRS586*/
 
+#define CONFIG_SPL_BSS_START_ADDR DAVINCI_DDR_EMIF_DATA_BASE
+#define CONFIG_SPL_BSS_MAX_SIZE 0x1080000
+
 /* memtest start addr */
 #define CONFIG_SYS_MEMTEST_START       (PHYS_SDRAM_1 + 0x2000000)
 
index 701298cab88b8f588f641ccf40a6cf0130b6f802..737dfd6a5c2ae2af6e26a477c02bf883d0e56236 100644 (file)
 #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 */
                                         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 */
index 59b2546f0b4caab351c6a59e40edc6687dd687cd..cd92835112dd56b44bef5f78e39862f75e2a9de5 100644 (file)
@@ -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 */
index fb8c082c1dcdaf706d07d5af791ec628ac75c748..eeca085f9fc2cb9f57e788ce695df95322ff3fec 100644 (file)
@@ -22,7 +22,7 @@
 /* Memory Configuration */
 #define CONFIG_SYS_LPAE_SDRAM_BASE     0x800000000
 #define CONFIG_MAX_RAM_BANK_SIZE       (2 << 30)       /* 2GB */
-#define CONFIG_SYS_INIT_SP_ADDR                (CONFIG_SPL_TEXT_BASE - \
+#define CONFIG_SYS_INIT_SP_ADDR                (CONFIG_ISW_ENTRY_ADDR - \
                                        GENERATED_GBL_DATA_SIZE)
 
 #ifdef CONFIG_SYS_MALLOC_F_LEN
 #endif
 
 /* SPL SPI Loader Configuration */
+#define CONFIG_SPL_TEXT_BASE           CONFIG_ISW_ENTRY_ADDR
 #define CONFIG_SPL_PAD_TO              65536
 #define CONFIG_SPL_MAX_SIZE            (CONFIG_SPL_PAD_TO - 8)
-#define CONFIG_SPL_BSS_START_ADDR      (CONFIG_SPL_TEXT_BASE + \
+#define CONFIG_SPL_BSS_START_ADDR      (CONFIG_ISW_ENTRY_ADDR + \
                                        CONFIG_SPL_MAX_SIZE)
 #define CONFIG_SPL_BSS_MAX_SIZE                (32 * 1024)
 #define CONFIG_SYS_SPL_MALLOC_START    (CONFIG_SPL_BSS_START_ADDR + \
 #define CONFIG_KSNET_SERDES_SGMII2_BASE                KS2_SGMII_SERDES2_BASE
 #define CONFIG_KSNET_SERDES_LANES_PER_SGMII    KS2_LANES_PER_SGMII_SERDES
 
-/* SerDes */
-#define CONFIG_TI_KEYSTONE_SERDES
-
 #define CONFIG_AEMIF_CNTRL_BASE                KS2_AEMIF_CNTRL_BASE
 
 /* I2C Configuration */
index ba57c40182cca7aa3739d1d84e9753dc9c3c565e..7c08e47d3d19ada432466d47908f08ff9b566451 100644 (file)
@@ -56,6 +56,7 @@
 
 #include <environment/ti/boot.h>
 #include <environment/ti/mmc.h>
+#include <environment/ti/nand.h>
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
        DEFAULT_LINUX_BOOT_ENV \
@@ -65,6 +66,7 @@
        DEFAULT_FDT_TI_ARGS \
        DFUARGS \
        NETARGS \
+       NANDARGS \
 
 /*
  * SPL related defines.  The Public RAM memory map the ROM defines the
 
 #define CONFIG_SYS_SPL_ARGS_ADDR       (CONFIG_SYS_SDRAM_BASE + \
                                         (128 << 20))
-
 #ifdef CONFIG_SPL_BUILD
 #undef CONFIG_TIMER
 #endif
index 5d5394e3e53b9fed10733a267ab05d1084b4a066..0de40eddcb5b1ec6545a06fff373c99874addd24 100644 (file)
 #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 */
index 038f6398eb6c690dd165a358f03882ec79ac8907..c7805cf36bf2c142cb974853dcd3cd1bd5b51ca1 100644 (file)
@@ -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
  */
index 2840c7b815b53275afeea6392fca53fda683e7e4..8c68372026e9f089df5062bb9430ab5fc1751105 100644 (file)
@@ -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
index 9f8ce8850f51d1958596a76edf5f2c1c06fb3def..96ff254f981254900123b9117471646da6931997 100644 (file)
 #ifndef _CPSW_H_
 #define _CPSW_H_
 
+/* reg offset */
+#define CPSW_HOST_PORT_OFFSET  0x108
+#define CPSW_SLAVE0_OFFSET     0x208
+#define CPSW_SLAVE1_OFFSET     0x308
+#define CPSW_SLAVE_SIZE                0x100
+#define CPSW_CPDMA_OFFSET      0x800
+#define CPSW_HW_STATS          0x900
+#define CPSW_STATERAM_OFFSET   0xa00
+#define CPSW_CPTS_OFFSET       0xc00
+#define CPSW_ALE_OFFSET                0xd00
+#define CPSW_SLIVER0_OFFSET    0xd80
+#define CPSW_SLIVER1_OFFSET    0xdc0
+#define CPSW_BD_OFFSET         0x2000
+#define CPSW_MDIO_DIV          0xff
+
+#define AM335X_GMII_SEL_OFFSET 0x630
+
 struct cpsw_slave_data {
        u32             slave_reg_ofs;
        u32             sliver_reg_ofs;
@@ -50,10 +67,16 @@ struct cpsw_platform_data {
        u32     active_slave;
        bool    rmii_clock_external;
        u8      version;
+       const char *phy_sel_compat;
+       u32     syscon_addr;
+       const char *macid_sel_compat;
 };
 
 int cpsw_register(struct cpsw_platform_data *data);
-int ti_cm_get_macid(struct udevice *dev, int slave, u8 *mac_addr);
+int ti_cm_get_macid_addr(struct udevice *dev, int slave,
+                        struct cpsw_platform_data *data);
+void ti_cm_get_macid(struct udevice *dev, struct cpsw_platform_data *data,
+                    u8 *mac_addr);
 int cpsw_get_slave_phy_addr(struct udevice *dev, int slave);
 
 #endif /* _CPSW_H_  */
index ff2b82e7c25d23896c9803bf82fc1d376bfdb85d..63a7d55b88808c428c71ff243f5850262af30121 100644 (file)
@@ -354,18 +354,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
  *
index 9ff6531d1b25f3380ed35bdb9c21ec620086f027..60d3b93decdb321e7bb2476cda4ef75918ca0418 100644 (file)
@@ -39,32 +39,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.
  *
diff --git a/include/dt-bindings/dma/k3-udma.h b/include/dt-bindings/dma/k3-udma.h
new file mode 100644 (file)
index 0000000..670e123
--- /dev/null
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
+ */
+
+#ifndef __DT_TI_UDMA_H
+#define __DT_TI_UDMA_H
+
+#define UDMA_TR_MODE           0
+#define UDMA_PKT_MODE          1
+
+#define UDMA_DIR_TX            0
+#define UDMA_DIR_RX            1
+
+#define PSIL_STATIC_TR_NONE    0
+#define PSIL_STATIC_TR_XY      1
+#define PSIL_STATIC_TR_MCAN    2
+
+#define UDMA_PDMA_TR_XY(id)                            \
+       ti,psil-config##id {                            \
+               linux,udma-mode = <UDMA_TR_MODE>;       \
+               statictr-type = <PSIL_STATIC_TR_XY>;    \
+       }
+
+#define UDMA_PDMA_PKT_XY(id)                           \
+       ti,psil-config##id {                            \
+               linux,udma-mode = <UDMA_PKT_MODE>;      \
+               statictr-type = <PSIL_STATIC_TR_XY>;    \
+       }
+
+#endif /* __DT_TI_UDMA_H */
diff --git a/include/dt-bindings/mfd/st,stpmic1.h b/include/dt-bindings/mfd/st,stpmic1.h
new file mode 100644 (file)
index 0000000..b2d6c83
--- /dev/null
@@ -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 (file)
index 81982eb..0000000
+++ /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 (file)
index 0000000..2f06fc5
--- /dev/null
@@ -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/environment/ti/nand.h b/include/environment/ti/nand.h
new file mode 100644 (file)
index 0000000..f838cb3
--- /dev/null
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Environment variable definitions for NAND on TI boards.
+ */
+
+#ifdef CONFIG_NAND
+#define NANDARGS \
+       "mtdids=" CONFIG_MTDIDS_DEFAULT "\0" \
+       "mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0" \
+       "nandargs=setenv bootargs console=${console} " \
+               "${optargs} " \
+               "root=${nandroot} " \
+               "rootfstype=${nandrootfstype}\0" \
+       "nandroot=ubi0:rootfs rw ubi.mtd=NAND.file-system,2048\0" \
+       "nandrootfstype=ubifs rootwait=1\0" \
+       "nandboot=echo Booting from nand ...; " \
+               "run nandargs; " \
+               "nand read ${fdtaddr} NAND.u-boot-spl-os; " \
+               "nand read ${loadaddr} NAND.kernel; " \
+               "bootz ${loadaddr} - ${fdtaddr}\0"
+#else
+#define NANDARGS ""
+#endif
+
index ad00f79f203a469fe1b92ade5fa2e07fe513d0bb..266c58271f0bb627b8c69b4de6dd8e3d6bd9c90c 100644 (file)
  */
 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
 
@@ -991,6 +1020,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
  */
index ccffc195527547c7d46ae8809b373212eb75f181..a5c760c711edcca9e278e478cd0c4babbef80b80 100644 (file)
@@ -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/soc/ti/cppi5.h b/include/linux/soc/ti/cppi5.h
new file mode 100644 (file)
index 0000000..34038b3
--- /dev/null
@@ -0,0 +1,995 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * CPPI5 descriptors interface
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
+ */
+
+#ifndef __TI_CPPI5_H__
+#define __TI_CPPI5_H__
+
+#include <hexdump.h>
+#include <linux/bitops.h>
+
+/**
+ * Descriptor header, present in all types of descriptors
+ */
+struct cppi5_desc_hdr_t {
+       u32 pkt_info0;  /* Packet info word 0 (n/a in Buffer desc) */
+       u32 pkt_info1;  /* Packet info word 1 (n/a in Buffer desc) */
+       u32 pkt_info2;  /* Packet info word 2 Buffer reclamation info */
+       u32 src_dst_tag; /* Packet info word 3 (n/a in Buffer desc) */
+} __packed;
+
+/**
+ * Host-mode packet and buffer descriptor definition
+ */
+struct cppi5_host_desc_t {
+       struct cppi5_desc_hdr_t hdr;
+       u64 next_desc;  /* w4/5: Linking word */
+       u64 buf_ptr;    /* w6/7: Buffer pointer */
+       u32 buf_info1;  /* w8: Buffer valid data length */
+       u32 org_buf_len; /* w9: Original buffer length */
+       u64 org_buf_ptr; /* w10/11: Original buffer pointer */
+       u32 epib[0];    /* Extended Packet Info Data (optional, 4 words) */
+       /*
+        * Protocol Specific Data (optional, 0-128 bytes in multiples of 4),
+        * and/or Other Software Data (0-N bytes, optional)
+        */
+} __packed;
+
+#define CPPI5_DESC_MIN_ALIGN                   (16U)
+
+#define CPPI5_INFO0_HDESC_EPIB_SIZE            (16U)
+#define CPPI5_INFO0_HDESC_PSDATA_MAX_SIZE      (128U)
+
+#define CPPI5_INFO0_HDESC_TYPE_SHIFT           (30U)
+#define CPPI5_INFO0_HDESC_TYPE_MASK            GENMASK(31, 30)
+#define   CPPI5_INFO0_DESC_TYPE_VAL_HOST       (1U)
+#define   CPPI5_INFO0_DESC_TYPE_VAL_MONO       (2U)
+#define   CPPI5_INFO0_DESC_TYPE_VAL_TR         (3U)
+#define CPPI5_INFO0_HDESC_EPIB_PRESENT         BIT(29)
+/*
+ * Protocol Specific Words location:
+ * 0 - located in the descriptor,
+ * 1 = located in the SOP Buffer immediately prior to the data.
+ */
+#define CPPI5_INFO0_HDESC_PSINFO_LOCATION      BIT(28)
+#define CPPI5_INFO0_HDESC_PSINFO_SIZE_SHIFT    (22U)
+#define CPPI5_INFO0_HDESC_PSINFO_SIZE_MASK     GENMASK(27, 22)
+#define CPPI5_INFO0_HDESC_PKTLEN_SHIFT         (0)
+#define CPPI5_INFO0_HDESC_PKTLEN_MASK          GENMASK(21, 0)
+
+#define CPPI5_INFO1_DESC_PKTERROR_SHIFT                (28U)
+#define CPPI5_INFO1_DESC_PKTERROR_MASK         GENMASK(31, 28)
+#define CPPI5_INFO1_HDESC_PSFLGS_SHIFT         (24U)
+#define CPPI5_INFO1_HDESC_PSFLGS_MASK          GENMASK(27, 24)
+#define CPPI5_INFO1_DESC_PKTID_SHIFT           (14U)
+#define CPPI5_INFO1_DESC_PKTID_MASK            GENMASK(23, 14)
+#define CPPI5_INFO1_DESC_FLOWID_SHIFT          (0)
+#define CPPI5_INFO1_DESC_FLOWID_MASK           GENMASK(13, 0)
+
+#define CPPI5_INFO2_HDESC_PKTTYPE_SHIFT                (27U)
+#define CPPI5_INFO2_HDESC_PKTTYPE_MASK         GENMASK(31, 27)
+/* Return Policy: 0 - Entire packet 1 - Each buffer */
+#define CPPI5_INFO2_HDESC_RETPOLICY            BIT(18)
+/*
+ * Early Return:
+ * 0 = desc pointers should be returned after all reads have been completed
+ * 1 = desc pointers should be returned immediately upon fetching
+ * the descriptor and beginning to transfer data.
+ */
+#define CPPI5_INFO2_HDESC_EARLYRET             BIT(17)
+/*
+ * Return Push Policy:
+ * 0 = Descriptor must be returned to tail of queue
+ * 1 = Descriptor must be returned to head of queue
+ */
+#define CPPI5_INFO2_DESC_RETPUSHPOLICY         BIT(16)
+#define CPPI5_INFO2_DESC_RETQ_SHIFT            (0)
+#define CPPI5_INFO2_DESC_RETQ_MASK             GENMASK(15, 0)
+
+#define CPPI5_INFO3_DESC_SRCTAG_SHIFT          (16U)
+#define CPPI5_INFO3_DESC_SRCTAG_MASK           GENMASK(31, 16)
+#define CPPI5_INFO3_DESC_DSTTAG_SHIFT          (0)
+#define CPPI5_INFO3_DESC_DSTTAG_MASK           GENMASK(15, 0)
+
+#define CPPI5_BUFINFO1_HDESC_DATA_LEN_SHIFT    (0)
+#define CPPI5_BUFINFO1_HDESC_DATA_LEN_MASK     GENMASK(27, 0)
+
+#define CPPI5_OBUFINFO0_HDESC_BUF_LEN_SHIFT    (0)
+#define CPPI5_OBUFINFO0_HDESC_BUF_LEN_MASK     GENMASK(27, 0)
+
+/*
+ * Host Packet Descriptor Extended Packet Info Block
+ */
+struct cppi5_desc_epib_t {
+       u32 timestamp;  /* w0: application specific timestamp */
+       u32 sw_info0;   /* w1: Software Info 0 */
+       u32 sw_info1;   /* w2: Software Info 1 */
+       u32 sw_info2;   /* w3: Software Info 2 */
+};
+
+/**
+ * Monolithic-mode packet descriptor
+ */
+struct cppi5_monolithic_desc_t {
+       struct cppi5_desc_hdr_t hdr;
+       u32 epib[0];    /* Extended Packet Info Data (optional, 4 words) */
+       /*
+        * Protocol Specific Data (optional, 0-128 bytes in multiples of 4),
+        *  and/or Other Software Data (0-N bytes, optional)
+        */
+};
+
+#define CPPI5_INFO2_MDESC_DATA_OFFSET_SHIFT    (18U)
+#define CPPI5_INFO2_MDESC_DATA_OFFSET_MASK     GENMASK(26, 18)
+
+/*
+ * Reload Enable:
+ * 0 = Finish the packet and place the descriptor back on the return queue
+ * 1 = Vector to the Reload Index and resume processing
+ */
+#define CPPI5_INFO0_TRDESC_RLDCNT_SHIFT                (20U)
+#define CPPI5_INFO0_TRDESC_RLDCNT_MASK         GENMASK(28, 20)
+#define CPPI5_INFO0_TRDESC_RLDCNT_MAX          (0x1ff)
+#define CPPI5_INFO0_TRDESC_RLDCNT_INFINITE     CPPI5_INFO0_TRDESC_RLDCNT_MAX
+#define CPPI5_INFO0_TRDESC_RLDIDX_SHIFT                (14U)
+#define CPPI5_INFO0_TRDESC_RLDIDX_MASK         GENMASK(19, 14)
+#define CPPI5_INFO0_TRDESC_RLDIDX_MAX          (0x3f)
+#define CPPI5_INFO0_TRDESC_LASTIDX_SHIFT       (0)
+#define CPPI5_INFO0_TRDESC_LASTIDX_MASK                GENMASK(13, 0)
+
+#define CPPI5_INFO1_TRDESC_RECSIZE_SHIFT       (24U)
+#define CPPI5_INFO1_TRDESC_RECSIZE_MASK                GENMASK(26, 24)
+#define   CPPI5_INFO1_TRDESC_RECSIZE_VAL_16B   (0)
+#define   CPPI5_INFO1_TRDESC_RECSIZE_VAL_32B   (1U)
+#define   CPPI5_INFO1_TRDESC_RECSIZE_VAL_64B   (2U)
+#define   CPPI5_INFO1_TRDESC_RECSIZE_VAL_128B  (3U)
+
+static inline void cppi5_desc_dump(void *desc, u32 size)
+{
+       print_hex_dump(KERN_ERR "dump udmap_desc: ", DUMP_PREFIX_NONE,
+                      32, 4, desc, size, false);
+}
+
+/**
+ * cppi5_desc_get_type - get descriptor type
+ * @desc_hdr: packet descriptor/TR header
+ *
+ * Returns descriptor type:
+ * CPPI5_INFO0_DESC_TYPE_VAL_HOST
+ * CPPI5_INFO0_DESC_TYPE_VAL_MONO
+ * CPPI5_INFO0_DESC_TYPE_VAL_TR
+ */
+static inline u32 cppi5_desc_get_type(struct cppi5_desc_hdr_t *desc_hdr)
+{
+       WARN_ON(!desc_hdr);
+
+       return (desc_hdr->pkt_info0 & CPPI5_INFO0_HDESC_TYPE_MASK) >>
+               CPPI5_INFO0_HDESC_TYPE_SHIFT;
+}
+
+/**
+ * cppi5_desc_get_errflags - get Error Flags from Desc
+ * @desc_hdr: packet/TR descriptor header
+ *
+ * Returns Error Flags from Packet/TR Descriptor
+ */
+static inline u32 cppi5_desc_get_errflags(struct cppi5_desc_hdr_t *desc_hdr)
+{
+       WARN_ON(!desc_hdr);
+
+       return (desc_hdr->pkt_info1 & CPPI5_INFO1_DESC_PKTERROR_MASK) >>
+               CPPI5_INFO1_DESC_PKTERROR_SHIFT;
+}
+
+/**
+ * cppi5_desc_get_pktids - get Packet and Flow ids from Desc
+ * @desc_hdr: packet/TR descriptor header
+ * @pkt_id: Packet ID
+ * @flow_id: Flow ID
+ *
+ * Returns Packet and Flow ids from packet/TR descriptor
+ */
+static inline void cppi5_desc_get_pktids(struct cppi5_desc_hdr_t *desc_hdr,
+                                        u32 *pkt_id, u32 *flow_id)
+{
+       WARN_ON(!desc_hdr);
+
+       *pkt_id = (desc_hdr->pkt_info1 & CPPI5_INFO1_DESC_PKTID_MASK) >>
+                  CPPI5_INFO1_DESC_PKTID_SHIFT;
+       *flow_id = (desc_hdr->pkt_info1 & CPPI5_INFO1_DESC_FLOWID_MASK) >>
+                   CPPI5_INFO1_DESC_FLOWID_SHIFT;
+}
+
+/**
+ * cppi5_desc_set_pktids - set Packet and Flow ids in Desc
+ * @desc_hdr: packet/TR descriptor header
+ * @pkt_id: Packet ID
+ * @flow_id: Flow ID
+ */
+static inline void cppi5_desc_set_pktids(struct cppi5_desc_hdr_t *desc_hdr,
+                                        u32 pkt_id, u32 flow_id)
+{
+       WARN_ON(!desc_hdr);
+
+       desc_hdr->pkt_info1 |= (pkt_id << CPPI5_INFO1_DESC_PKTID_SHIFT) &
+                               CPPI5_INFO1_DESC_PKTID_MASK;
+       desc_hdr->pkt_info1 |= (flow_id << CPPI5_INFO1_DESC_FLOWID_SHIFT) &
+                               CPPI5_INFO1_DESC_FLOWID_MASK;
+}
+
+/**
+ * cppi5_desc_set_retpolicy - set Packet Return Policy in Desc
+ * @desc_hdr: packet/TR descriptor header
+ * @flags: fags, supported values
+ *  CPPI5_INFO2_HDESC_RETPOLICY
+ *  CPPI5_INFO2_HDESC_EARLYRET
+ *  CPPI5_INFO2_DESC_RETPUSHPOLICY
+ * @return_ring_id: Packet Return Queue/Ring id, value 0xFFFF reserved
+ */
+static inline void cppi5_desc_set_retpolicy(struct cppi5_desc_hdr_t *desc_hdr,
+                                           u32 flags, u32 return_ring_id)
+{
+       WARN_ON(!desc_hdr);
+
+       desc_hdr->pkt_info2 |= flags;
+       desc_hdr->pkt_info2 |= return_ring_id & CPPI5_INFO2_DESC_RETQ_MASK;
+}
+
+/**
+ * cppi5_desc_get_tags_ids - get Packet Src/Dst Tags from Desc
+ * @desc_hdr: packet/TR descriptor header
+ * @src_tag_id: Source Tag
+ * @dst_tag_id: Dest Tag
+ *
+ * Returns Packet Src/Dst Tags from packet/TR descriptor
+ */
+static inline void cppi5_desc_get_tags_ids(struct cppi5_desc_hdr_t *desc_hdr,
+                                          u32 *src_tag_id, u32 *dst_tag_id)
+{
+       WARN_ON(!desc_hdr);
+
+       if (src_tag_id)
+               *src_tag_id = (desc_hdr->src_dst_tag &
+                             CPPI5_INFO3_DESC_SRCTAG_MASK) >>
+                             CPPI5_INFO3_DESC_SRCTAG_SHIFT;
+       if (dst_tag_id)
+               *dst_tag_id = desc_hdr->src_dst_tag &
+                             CPPI5_INFO3_DESC_DSTTAG_MASK;
+}
+
+/**
+ * cppi5_desc_set_tags_ids - set Packet Src/Dst Tags in HDesc
+ * @desc_hdr: packet/TR descriptor header
+ * @src_tag_id: Source Tag
+ * @dst_tag_id: Dest Tag
+ *
+ * Returns Packet Src/Dst Tags from packet/TR descriptor
+ */
+static inline void cppi5_desc_set_tags_ids(struct cppi5_desc_hdr_t *desc_hdr,
+                                          u32 src_tag_id, u32 dst_tag_id)
+{
+       WARN_ON(!desc_hdr);
+
+       desc_hdr->src_dst_tag = (src_tag_id << CPPI5_INFO3_DESC_SRCTAG_SHIFT) &
+                               CPPI5_INFO3_DESC_SRCTAG_MASK;
+       desc_hdr->src_dst_tag |= dst_tag_id & CPPI5_INFO3_DESC_DSTTAG_MASK;
+}
+
+/**
+ * cppi5_hdesc_calc_size - Calculate Host Packet Descriptor size
+ * @epib: is EPIB present
+ * @psdata_size: PSDATA size
+ * @sw_data_size: SWDATA size
+ *
+ * Returns required Host Packet Descriptor size
+ * 0 - if PSDATA > CPPI5_INFO0_HDESC_PSDATA_MAX_SIZE
+ */
+static inline u32 cppi5_hdesc_calc_size(bool epib, u32 psdata_size,
+                                       u32 sw_data_size)
+{
+       u32 desc_size;
+
+       if (psdata_size > CPPI5_INFO0_HDESC_PSDATA_MAX_SIZE)
+               return 0;
+       //TODO_GS: align
+       desc_size = sizeof(struct cppi5_host_desc_t) + psdata_size +
+                   sw_data_size;
+
+       if (epib)
+               desc_size += CPPI5_INFO0_HDESC_EPIB_SIZE;
+
+       return ALIGN(desc_size, CPPI5_DESC_MIN_ALIGN);
+}
+
+/**
+ * cppi5_hdesc_init - Init Host Packet Descriptor size
+ * @desc: Host packet descriptor
+ * @flags: supported values
+ *     CPPI5_INFO0_HDESC_EPIB_PRESENT
+ *     CPPI5_INFO0_HDESC_PSINFO_LOCATION
+ * @psdata_size: PSDATA size
+ *
+ * Returns required Host Packet Descriptor size
+ * 0 - if PSDATA > CPPI5_INFO0_HDESC_PSDATA_MAX_SIZE
+ */
+static inline void cppi5_hdesc_init(struct cppi5_host_desc_t *desc, u32 flags,
+                                   u32 psdata_size)
+{
+       WARN_ON(!desc);
+       WARN_ON(psdata_size > CPPI5_INFO0_HDESC_PSDATA_MAX_SIZE);
+       WARN_ON(flags & ~(CPPI5_INFO0_HDESC_EPIB_PRESENT |
+                         CPPI5_INFO0_HDESC_PSINFO_LOCATION));
+
+       desc->hdr.pkt_info0 = (CPPI5_INFO0_DESC_TYPE_VAL_HOST <<
+                              CPPI5_INFO0_HDESC_TYPE_SHIFT) | (flags);
+       desc->hdr.pkt_info0 |= ((psdata_size >> 2) <<
+                               CPPI5_INFO0_HDESC_PSINFO_SIZE_SHIFT) &
+                               CPPI5_INFO0_HDESC_PSINFO_SIZE_MASK;
+       desc->next_desc = 0;
+}
+
+/**
+ * cppi5_hdesc_update_flags - Replace descriptor flags
+ * @desc: Host packet descriptor
+ * @flags: supported values
+ *     CPPI5_INFO0_HDESC_EPIB_PRESENT
+ *     CPPI5_INFO0_HDESC_PSINFO_LOCATION
+ */
+static inline void cppi5_hdesc_update_flags(struct cppi5_host_desc_t *desc,
+                                           u32 flags)
+{
+       WARN_ON(!desc);
+       WARN_ON(flags & ~(CPPI5_INFO0_HDESC_EPIB_PRESENT |
+                         CPPI5_INFO0_HDESC_PSINFO_LOCATION));
+
+       desc->hdr.pkt_info0 &= ~(CPPI5_INFO0_HDESC_EPIB_PRESENT |
+                                CPPI5_INFO0_HDESC_PSINFO_LOCATION);
+       desc->hdr.pkt_info0 |= flags;
+}
+
+/**
+ * cppi5_hdesc_update_psdata_size - Replace PSdata size
+ * @desc: Host packet descriptor
+ * @psdata_size: PSDATA size
+ */
+static inline void cppi5_hdesc_update_psdata_size(
+                               struct cppi5_host_desc_t *desc, u32 psdata_size)
+{
+       WARN_ON(!desc);
+       WARN_ON(psdata_size > CPPI5_INFO0_HDESC_PSDATA_MAX_SIZE);
+
+       desc->hdr.pkt_info0 &= ~CPPI5_INFO0_HDESC_PSINFO_SIZE_MASK;
+       desc->hdr.pkt_info0 |= ((psdata_size >> 2) <<
+                               CPPI5_INFO0_HDESC_PSINFO_SIZE_SHIFT) &
+                               CPPI5_INFO0_HDESC_PSINFO_SIZE_MASK;
+}
+
+/**
+ * cppi5_hdesc_get_psdata_size - get PSdata size in bytes
+ * @desc: Host packet descriptor
+ */
+static inline u32 cppi5_hdesc_get_psdata_size(struct cppi5_host_desc_t *desc)
+{
+       u32 psdata_size = 0;
+
+       WARN_ON(!desc);
+
+       if (!(desc->hdr.pkt_info0 & CPPI5_INFO0_HDESC_PSINFO_LOCATION))
+               psdata_size = (desc->hdr.pkt_info0 &
+                              CPPI5_INFO0_HDESC_PSINFO_SIZE_MASK) >>
+                              CPPI5_INFO0_HDESC_PSINFO_SIZE_SHIFT;
+
+       return (psdata_size << 2);
+}
+
+/**
+ * cppi5_hdesc_get_pktlen - get Packet Length from HDesc
+ * @desc: Host packet descriptor
+ *
+ * Returns Packet Length from Host Packet Descriptor
+ */
+static inline u32 cppi5_hdesc_get_pktlen(struct cppi5_host_desc_t *desc)
+{
+       WARN_ON(!desc);
+
+       return (desc->hdr.pkt_info0 & CPPI5_INFO0_HDESC_PKTLEN_MASK);
+}
+
+/**
+ * cppi5_hdesc_set_pktlen - set Packet Length in HDesc
+ * @desc: Host packet descriptor
+ */
+static inline void cppi5_hdesc_set_pktlen(struct cppi5_host_desc_t *desc,
+                                         u32 pkt_len)
+{
+       WARN_ON(!desc);
+
+       desc->hdr.pkt_info0 |= (pkt_len & CPPI5_INFO0_HDESC_PKTLEN_MASK);
+}
+
+/**
+ * cppi5_hdesc_get_psflags - get Protocol Specific Flags from HDesc
+ * @desc: Host packet descriptor
+ *
+ * Returns Protocol Specific Flags from Host Packet Descriptor
+ */
+static inline u32 cppi5_hdesc_get_psflags(struct cppi5_host_desc_t *desc)
+{
+       WARN_ON(!desc);
+
+       return (desc->hdr.pkt_info1 & CPPI5_INFO1_HDESC_PSFLGS_MASK) >>
+               CPPI5_INFO1_HDESC_PSFLGS_SHIFT;
+}
+
+/**
+ * cppi5_hdesc_set_psflags - set Protocol Specific Flags in HDesc
+ * @desc: Host packet descriptor
+ */
+static inline void cppi5_hdesc_set_psflags(struct cppi5_host_desc_t *desc,
+                                          u32 ps_flags)
+{
+       WARN_ON(!desc);
+
+       desc->hdr.pkt_info1 |= (ps_flags <<
+                               CPPI5_INFO1_HDESC_PSFLGS_SHIFT) &
+                               CPPI5_INFO1_HDESC_PSFLGS_MASK;
+}
+
+/**
+ * cppi5_hdesc_get_errflags - get Packet Type from HDesc
+ * @desc: Host packet descriptor
+ */
+static inline u32 cppi5_hdesc_get_pkttype(struct cppi5_host_desc_t *desc)
+{
+       WARN_ON(!desc);
+
+       return (desc->hdr.pkt_info2 & CPPI5_INFO2_HDESC_PKTTYPE_MASK) >>
+               CPPI5_INFO2_HDESC_PKTTYPE_SHIFT;
+}
+
+/**
+ * cppi5_hdesc_get_errflags - set Packet Type in HDesc
+ * @desc: Host packet descriptor
+ * @pkt_type: Packet Type
+ */
+static inline void cppi5_hdesc_set_pkttype(struct cppi5_host_desc_t *desc,
+                                          u32 pkt_type)
+{
+       WARN_ON(!desc);
+       desc->hdr.pkt_info2 |=
+                       (pkt_type << CPPI5_INFO2_HDESC_PKTTYPE_SHIFT) &
+                        CPPI5_INFO2_HDESC_PKTTYPE_MASK;
+}
+
+/**
+ * cppi5_hdesc_attach_buf - attach buffer to HDesc
+ * @desc: Host packet descriptor
+ * @buf: Buffer physical address
+ * @buf_data_len: Buffer length
+ * @obuf: Original Buffer physical address
+ * @obuf_len: Original Buffer length
+ *
+ * Attaches buffer to Host Packet Descriptor
+ */
+static inline void cppi5_hdesc_attach_buf(struct cppi5_host_desc_t *desc,
+                                         dma_addr_t buf, u32 buf_data_len,
+                                         dma_addr_t obuf, u32 obuf_len)
+{
+       WARN_ON(!desc);
+       WARN_ON(!buf && !obuf);
+
+       desc->buf_ptr = buf;
+       desc->buf_info1 = buf_data_len & CPPI5_BUFINFO1_HDESC_DATA_LEN_MASK;
+       desc->org_buf_ptr = obuf;
+       desc->org_buf_len = obuf_len & CPPI5_OBUFINFO0_HDESC_BUF_LEN_MASK;
+}
+
+static inline void cppi5_hdesc_get_obuf(struct cppi5_host_desc_t *desc,
+                                       dma_addr_t *obuf, u32 *obuf_len)
+{
+       WARN_ON(!desc);
+       WARN_ON(!obuf);
+       WARN_ON(!obuf_len);
+
+       *obuf = desc->org_buf_ptr;
+       *obuf_len = desc->org_buf_len & CPPI5_OBUFINFO0_HDESC_BUF_LEN_MASK;
+}
+
+static inline void cppi5_hdesc_reset_to_original(struct cppi5_host_desc_t *desc)
+{
+       WARN_ON(!desc);
+
+       desc->buf_ptr = desc->org_buf_ptr;
+       desc->buf_info1 = desc->org_buf_len;
+}
+
+/**
+ * cppi5_hdesc_link_hbdesc - link Host Buffer Descriptor to HDesc
+ * @desc: Host Packet Descriptor
+ * @buf_desc: Host Buffer Descriptor physical address
+ *
+ * add and link Host Buffer Descriptor to HDesc
+ */
+static inline void cppi5_hdesc_link_hbdesc(struct cppi5_host_desc_t *desc,
+                                          dma_addr_t hbuf_desc)
+{
+       WARN_ON(!desc);
+       WARN_ON(!hbuf_desc);
+
+       desc->next_desc = hbuf_desc;
+}
+
+static inline dma_addr_t cppi5_hdesc_get_next_hbdesc(
+                               struct cppi5_host_desc_t *desc)
+{
+       WARN_ON(!desc);
+
+       return (dma_addr_t)desc->next_desc;
+}
+
+static inline void cppi5_hdesc_reset_hbdesc(struct cppi5_host_desc_t *desc)
+{
+       WARN_ON(!desc);
+
+       desc->hdr = (struct cppi5_desc_hdr_t) { 0 };
+       desc->next_desc = 0;
+}
+
+/**
+ * cppi5_hdesc_epib_present -  check if EPIB present
+ * @desc_hdr: packet descriptor/TR header
+ *
+ * Returns true if EPIB present in the packet
+ */
+static inline bool cppi5_hdesc_epib_present(struct cppi5_desc_hdr_t *desc_hdr)
+{
+       WARN_ON(!desc_hdr);
+       return !!(desc_hdr->pkt_info0 & CPPI5_INFO0_HDESC_EPIB_PRESENT);
+}
+
+/**
+ * cppi5_hdesc_get_psdata -  Get pointer on PSDATA
+ * @desc: Host packet descriptor
+ *
+ * Returns pointer on PSDATA in HDesc.
+ * NULL - if ps_data placed at the start of data buffer.
+ */
+static inline void *cppi5_hdesc_get_psdata(struct cppi5_host_desc_t *desc)
+{
+       u32 psdata_size;
+       void *psdata;
+
+       WARN_ON(!desc);
+
+       if (desc->hdr.pkt_info0 & CPPI5_INFO0_HDESC_PSINFO_LOCATION)
+               return NULL;
+
+       psdata_size = (desc->hdr.pkt_info0 &
+                      CPPI5_INFO0_HDESC_PSINFO_SIZE_MASK) >>
+                      CPPI5_INFO0_HDESC_PSINFO_SIZE_SHIFT;
+
+       if (!psdata_size)
+               return NULL;
+
+       psdata = &desc->epib;
+
+       if (cppi5_hdesc_epib_present(&desc->hdr))
+               psdata += CPPI5_INFO0_HDESC_EPIB_SIZE;
+
+       return psdata;
+}
+
+static inline u32 *cppi5_hdesc_get_psdata32(struct cppi5_host_desc_t *desc)
+{
+       return (u32 *)cppi5_hdesc_get_psdata(desc);
+}
+
+/**
+ * cppi5_hdesc_get_swdata -  Get pointer on swdata
+ * @desc: Host packet descriptor
+ *
+ * Returns pointer on SWDATA in HDesc.
+ * NOTE. It's caller responsibility to be sure hdesc actually has swdata.
+ */
+static inline void *cppi5_hdesc_get_swdata(struct cppi5_host_desc_t *desc)
+{
+       u32 psdata_size = 0;
+       void *swdata;
+
+       WARN_ON(!desc);
+
+       if (!(desc->hdr.pkt_info0 & CPPI5_INFO0_HDESC_PSINFO_LOCATION))
+               psdata_size = (desc->hdr.pkt_info0 &
+                              CPPI5_INFO0_HDESC_PSINFO_SIZE_MASK) >>
+                              CPPI5_INFO0_HDESC_PSINFO_SIZE_SHIFT;
+
+       swdata = &desc->epib;
+
+       if (cppi5_hdesc_epib_present(&desc->hdr))
+               swdata += CPPI5_INFO0_HDESC_EPIB_SIZE;
+
+       swdata += (psdata_size << 2);
+
+       return swdata;
+}
+
+/* ================================== TR ================================== */
+
+#define CPPI5_TR_TYPE_SHIFT                    (0U)
+#define CPPI5_TR_TYPE_MASK                     GENMASK(3, 0)
+#define CPPI5_TR_STATIC                                BIT(4)
+#define CPPI5_TR_WAIT                          BIT(5)
+#define CPPI5_TR_EVENT_SIZE_SHIFT              (6U)
+#define CPPI5_TR_EVENT_SIZE_MASK               GENMASK(7, 6)
+#define CPPI5_TR_TRIGGER0_SHIFT                        (8U)
+#define CPPI5_TR_TRIGGER0_MASK                 GENMASK(9, 8)
+#define CPPI5_TR_TRIGGER0_TYPE_SHIFT           (10U)
+#define CPPI5_TR_TRIGGER0_TYPE_MASK            GENMASK(11, 10)
+#define CPPI5_TR_TRIGGER1_SHIFT                        (12U)
+#define CPPI5_TR_TRIGGER1_MASK                 GENMASK(13, 12)
+#define CPPI5_TR_TRIGGER1_TYPE_SHIFT           (14U)
+#define CPPI5_TR_TRIGGER1_TYPE_MASK            GENMASK(15, 14)
+#define CPPI5_TR_CMD_ID_SHIFT                  (16U)
+#define CPPI5_TR_CMD_ID_MASK                   GENMASK(23, 16)
+#define CPPI5_TR_CSF_FLAGS_SHIFT               (24U)
+#define CPPI5_TR_CSF_FLAGS_MASK                        GENMASK(31, 24)
+#define   CPPI5_TR_CSF_SA_INDIRECT             BIT(0)
+#define   CPPI5_TR_CSF_DA_INDIRECT             BIT(1)
+#define   CPPI5_TR_CSF_SUPR_EVT                        BIT(2)
+#define   CPPI5_TR_CSF_EOL_ADV_SHIFT           (4U)
+#define   CPPI5_TR_CSF_EOL_ADV_MASK            GENMASK(6, 4)
+#define   CPPI5_TR_CSF_EOP                     BIT(7)
+
+/* Udmap TR flags Type field specifies the type of TR. */
+enum cppi5_tr_types {
+       /* type0: One dimensional data move */
+       CPPI5_TR_TYPE0 = 0,
+       /* type1: Two dimensional data move */
+       CPPI5_TR_TYPE1,
+       /* type2: Three dimensional data move */
+       CPPI5_TR_TYPE2,
+       /* type3: Four dimensional data move */
+       CPPI5_TR_TYPE3,
+       /* type4: Four dimensional data move with data formatting */
+       CPPI5_TR_TYPE4,
+       /* type5: Four dimensional Cache Warm */
+       CPPI5_TR_TYPE5,
+       /* type6-7: Reserved */
+       /* type8: Four Dimensional Block Move */
+       CPPI5_TR_TYPE8 = 8,
+       /* type9: Four Dimensional Block Move with Repacking */
+       CPPI5_TR_TYPE9,
+       /* type10: Two Dimensional Block Move */
+       CPPI5_TR_TYPE10,
+       /* type11: Two Dimensional Block Move with Repacking */
+       CPPI5_TR_TYPE11,
+       /* type12-14: Reserved */
+       /* type15 Four Dimensional Block Move with Repacking and Indirection */
+       CPPI5_TR_TYPE15 = 15,
+       CPPI5_TR_TYPE_MAX
+};
+
+/*
+ * Udmap TR Flags EVENT_SIZE field specifies when an event is generated
+ * for each TR.
+ */
+enum cppi5_tr_event_size {
+       /* When TR is complete and all status for the TR has been received */
+       CPPI5_TR_EVENT_SIZE_COMPLETION,
+       /*
+        * Type 0: when the last data transaction is sent for the TR;
+        * Type 1-11: when ICNT1 is decremented
+        */
+       CPPI5_TR_EVENT_SIZE_ICNT1_DEC,
+       /*
+        * Type 0-1,10-11: when the last data transaction is sent for the TR;
+        * All other types: when ICNT2 is decremented
+        */
+       CPPI5_TR_EVENT_SIZE_ICNT2_DEC,
+       /*
+        * Type 0-2,10-11: when the last data transaction is sent for the TR;
+        * All other types: when ICNT3 is decremented
+        */
+       CPPI5_TR_EVENT_SIZE_ICNT3_DEC,
+       CPPI5_TR_EVENT_SIZE_MAX
+};
+
+/*
+ * Udmap TR Flags TRIGGERx field specifies the type of trigger used to
+ * enable the TR to transfer data as specified by TRIGGERx_TYPE field.
+ */
+enum cppi5_tr_trigger {
+       CPPI5_TR_TRIGGER_NONE,          /* No Trigger */
+       CPPI5_TR_TRIGGER_GLOBAL0,               /* Global Trigger 0 */
+       CPPI5_TR_TRIGGER_GLOBAL1,               /* Global Trigger 1 */
+       CPPI5_TR_TRIGGER_LOCAL_EVENT,   /* Local Event */
+       CPPI5_TR_TRIGGER_MAX
+};
+
+/*
+ * Udmap TR Flags TRIGGERx_TYPE field specifies the type of data transfer
+ * that will be enabled by receiving a trigger as specified by TRIGGERx.
+ */
+enum cppi5_tr_trigger_type {
+       /* The second inner most loop (ICNT1) will be decremented by 1 */
+       CPPI5_TR_TRIGGER_TYPE_ICNT1_DEC,
+       /* The third inner most loop (ICNT2) will be decremented by 1 */
+       CPPI5_TR_TRIGGER_TYPE_ICNT2_DEC,
+       /* The outer most loop (ICNT3) will be decremented by 1 */
+       CPPI5_TR_TRIGGER_TYPE_ICNT3_DEC,
+       /* The entire TR will be allowed to complete */
+       CPPI5_TR_TRIGGER_TYPE_ALL,
+       CPPI5_TR_TRIGGER_TYPE_MAX
+};
+
+typedef u32 cppi5_tr_flags_t;
+
+/* Type 0 (One dimensional data move) TR (16 byte) */
+struct cppi5_tr_type0_t {
+       cppi5_tr_flags_t flags;
+       u16 icnt0;
+       u16 unused;
+       u64 addr;
+} __aligned(16) __packed;
+
+/* Type 1 (Two dimensional data move) TR (32 byte) */
+struct cppi5_tr_type1_t {
+       cppi5_tr_flags_t flags;
+       u16 icnt0;
+       u16 icnt1;
+       u64 addr;
+       s32 dim1;
+} __aligned(32) __packed;
+
+/* Type 2 (Three dimensional data move) TR (32 byte) */
+struct cppi5_tr_type2_t {
+       cppi5_tr_flags_t flags;
+       u16 icnt0;
+       u16 icnt1;
+       u64 addr;
+       s32 dim1;
+       u16 icnt2;
+       u16 unused;
+       s32 dim2;
+} __aligned(32) __packed;
+
+/* Type 3 (Four dimensional data move) TR (32 byte) */
+struct cppi5_tr_type3_t {
+       cppi5_tr_flags_t flags;
+       u16 icnt0;
+       u16 icnt1;
+       u64 addr;
+       s32 dim1;
+       u16 icnt2;
+       u16 icnt3;
+       s32 dim2;
+       s32 dim3;
+} __aligned(32) __packed;
+
+/*
+ * Type 15 (Four Dimensional Block Copy with Repacking and
+ * Indirection Support) TR (64 byte).
+ */
+struct cppi5_tr_type15_t {
+       cppi5_tr_flags_t flags;
+       u16 icnt0;
+       u16 icnt1;
+       u64 addr;
+       s32 dim1;
+       u16 icnt2;
+       u16 icnt3;
+       s32 dim2;
+       s32 dim3;
+       u32 _reserved;
+       s32 ddim1;
+       u64 daddr;
+       s32 ddim2;
+       s32 ddim3;
+       u16 dicnt0;
+       u16 dicnt1;
+       u16 dicnt2;
+       u16 dicnt3;
+} __aligned(64) __packed;
+
+struct cppi5_tr_resp_t {
+       u8 status;
+       u8 reserved;
+       u8 cmd_id;
+       u8 flags;
+} __packed;
+
+#define CPPI5_TR_RESPONSE_STATUS_TYPE_SHIFT    (0U)
+#define CPPI5_TR_RESPONSE_STATUS_TYPE_MASK     GENMASK(3, 0)
+#define CPPI5_TR_RESPONSE_STATUS_INFO_SHIFT    (4U)
+#define CPPI5_TR_RESPONSE_STATUS_INFO_MASK     GENMASK(7, 4)
+#define CPPI5_TR_RESPONSE_CMDID_SHIFT          (16U)
+#define CPPI5_TR_RESPONSE_CMDID_MASK           GENMASK(23, 16)
+#define CPPI5_TR_RESPONSE_CFG_SPECIFIC_SHIFT   (24U)
+#define CPPI5_TR_RESPONSE_CFG_SPECIFIC_MASK    GENMASK(31, 24)
+
+/*
+ * Udmap TR Response Status Type field is used to determine
+ * what type of status is being returned.
+ */
+enum cppi5_tr_resp_status_type {
+       CPPI5_TR_RESPONSE_STATUS_COMPLETE,              /* None */
+       CPPI5_TR_RESPONSE_STATUS_TRANSFER_ERR,          /* Transfer Error */
+       CPPI5_TR_RESPONSE_STATUS_ABORTED_ERR,           /* Aborted Error */
+       CPPI5_TR_RESPONSE_STATUS_SUBMISSION_ERR,        /* Submission Error */
+       CPPI5_TR_RESPONSE_STATUS_UNSUPPORTED_ERR,       /* Unsup. Feature */
+       CPPI5_TR_RESPONSE_STATUS_MAX
+};
+
+/*
+ * Udmap TR Response Status field values which corresponds
+ * CPPI5_TR_RESPONSE_STATUS_SUBMISSION_ERR
+ */
+enum cppi5_tr_resp_status_submission {
+       /* ICNT0 was 0 */
+       CPPI5_TR_RESPONSE_STATUS_SUBMISSION_ICNT0,
+       /* Channel FIFO was full when TR received */
+       CPPI5_TR_RESPONSE_STATUS_SUBMISSION_FIFO_FULL,
+       /* Channel is not owned by the submitter */
+       CPPI5_TR_RESPONSE_STATUS_SUBMISSION_OWN,
+       CPPI5_TR_RESPONSE_STATUS_SUBMISSION_MAX
+};
+
+/*
+ * Udmap TR Response Status field values which corresponds
+ * CPPI5_TR_RESPONSE_STATUS_UNSUPPORTED_ERR
+ */
+enum cppi5_tr_resp_status_unsupported {
+       /* TR Type not supported */
+       CPPI5_TR_RESPONSE_STATUS_UNSUPPORTED_TR_TYPE,
+       /* STATIC not supported */
+       CPPI5_TR_RESPONSE_STATUS_UNSUPPORTED_STATIC,
+       /* EOL not supported */
+       CPPI5_TR_RESPONSE_STATUS_UNSUPPORTED_EOL,
+       /* CONFIGURATION SPECIFIC not supported */
+       CPPI5_TR_RESPONSE_STATUS_UNSUPPORTED_CFG_SPECIFIC,
+       /* AMODE not supported */
+       CPPI5_TR_RESPONSE_STATUS_UNSUPPORTED_AMODE,
+       /* ELTYPE not supported */
+       CPPI5_TR_RESPONSE_STATUS_UNSUPPORTED_ELTYPE,
+       /* DFMT not supported */
+       CPPI5_TR_RESPONSE_STATUS_UNSUPPORTED_DFMT,
+       /* SECTR not supported */
+       CPPI5_TR_RESPONSE_STATUS_UNSUPPORTED_SECTR,
+       /* AMODE SPECIFIC field not supported */
+       CPPI5_TR_RESPONSE_STATUS_UNSUPPORTED_AMODE_SPECIFIC,
+       CPPI5_TR_RESPONSE_STATUS_UNSUPPORTED_MAX
+};
+
+/**
+ * cppi5_trdesc_calc_size - Calculate TR Descriptor size
+ * @tr_count: number of TR records
+ * @tr_size: Nominal size of TR record (max) [16, 32, 64, 128]
+ *
+ * Returns required TR Descriptor size
+ */
+static inline size_t cppi5_trdesc_calc_size(u32 tr_count, u32 tr_size)
+{
+       /*
+        * The Size of a TR descriptor is:
+        * 1 x tr_size : the first 16 bytes is used by the packet info block +
+        * tr_count x tr_size : Transfer Request Records +
+        * tr_count x sizeof(struct cppi5_tr_resp_t) : Transfer Response Records
+        */
+       return tr_size * (tr_count + 1) +
+               sizeof(struct cppi5_tr_resp_t) * tr_count;
+}
+
+/**
+ * cppi5_trdesc_init - Init TR Descriptor
+ * @desc: TR Descriptor
+ * @tr_count: number of TR records
+ * @tr_size: Nominal size of TR record (max) [16, 32, 64, 128]
+ * @reload_idx: Absolute index to jump to on the 2nd and following passes
+ *             through the TR packet.
+ * @reload_count: Number of times to jump from last entry to reload_idx. 0x1ff
+ *               indicates infinite looping.
+ *
+ * Init TR Descriptor
+ */
+static inline void cppi5_trdesc_init(struct cppi5_desc_hdr_t *desc_hdr,
+                                    u32 tr_count, u32 tr_size, u32 reload_idx,
+                                    u32 reload_count)
+{
+       WARN_ON(!desc_hdr);
+       WARN_ON(tr_count & ~CPPI5_INFO0_TRDESC_LASTIDX_MASK);
+       WARN_ON(reload_idx > CPPI5_INFO0_TRDESC_RLDIDX_MAX);
+       WARN_ON(reload_count > CPPI5_INFO0_TRDESC_RLDCNT_MAX);
+
+       desc_hdr->pkt_info0 = CPPI5_INFO0_DESC_TYPE_VAL_TR <<
+                             CPPI5_INFO0_HDESC_TYPE_SHIFT;
+       desc_hdr->pkt_info0 |= (reload_count << CPPI5_INFO0_TRDESC_RLDCNT_SHIFT) &
+                              CPPI5_INFO0_TRDESC_RLDCNT_MASK;
+       desc_hdr->pkt_info0 |= (reload_idx << CPPI5_INFO0_TRDESC_RLDIDX_SHIFT) &
+                              CPPI5_INFO0_TRDESC_RLDIDX_MASK;
+       desc_hdr->pkt_info0 |= (tr_count - 1) & CPPI5_INFO0_TRDESC_LASTIDX_MASK;
+
+       desc_hdr->pkt_info1 |= ((ffs(tr_size >> 4) - 1) <<
+                               CPPI5_INFO1_TRDESC_RECSIZE_SHIFT) &
+                               CPPI5_INFO1_TRDESC_RECSIZE_MASK;
+}
+
+/**
+ * cppi5_tr_init - Init TR record
+ * @flags: Pointer to the TR's flags
+ * @type: TR type
+ * @static_tr: TR is static
+ * @wait: Wait for TR completion before allow the next TR to start
+ * @event_size: output event generation cfg
+ * @cmd_id: TR identifier (application specifics)
+ *
+ * Init TR record
+ */
+static inline void cppi5_tr_init(cppi5_tr_flags_t *flags,
+                                enum cppi5_tr_types type, bool static_tr,
+                                bool wait, enum cppi5_tr_event_size event_size,
+                                u32 cmd_id)
+{
+       WARN_ON(!flags);
+
+       *flags = type;
+       *flags |= (event_size << CPPI5_TR_EVENT_SIZE_SHIFT) &
+                 CPPI5_TR_EVENT_SIZE_MASK;
+
+       *flags |= (cmd_id << CPPI5_TR_CMD_ID_SHIFT) &
+                 CPPI5_TR_CMD_ID_MASK;
+
+       if (static_tr && (type == CPPI5_TR_TYPE8 || type == CPPI5_TR_TYPE9))
+               *flags |= CPPI5_TR_STATIC;
+
+       if (wait)
+               *flags |= CPPI5_TR_WAIT;
+}
+
+/**
+ * cppi5_tr_set_trigger - Configure trigger0/1 and trigger0/1_type
+ * @flags: Pointer to the TR's flags
+ * @trigger0: trigger0 selection
+ * @trigger0_type: type of data transfer that will be enabled by trigger0
+ * @trigger1: trigger1 selection
+ * @trigger1_type: type of data transfer that will be enabled by trigger1
+ *
+ * Configure the triggers for the TR
+ */
+static inline void cppi5_tr_set_trigger(cppi5_tr_flags_t *flags,
+                               enum cppi5_tr_trigger trigger0,
+                               enum cppi5_tr_trigger_type trigger0_type,
+                               enum cppi5_tr_trigger trigger1,
+                               enum cppi5_tr_trigger_type trigger1_type)
+{
+       WARN_ON(!flags);
+
+       *flags |= (trigger0 << CPPI5_TR_TRIGGER0_SHIFT) &
+                 CPPI5_TR_TRIGGER0_MASK;
+       *flags |= (trigger0_type << CPPI5_TR_TRIGGER0_TYPE_SHIFT) &
+                 CPPI5_TR_TRIGGER0_TYPE_MASK;
+
+       *flags |= (trigger1 << CPPI5_TR_TRIGGER1_SHIFT) &
+                 CPPI5_TR_TRIGGER1_MASK;
+       *flags |= (trigger1_type << CPPI5_TR_TRIGGER1_TYPE_SHIFT) &
+                 CPPI5_TR_TRIGGER1_TYPE_MASK;
+}
+
+/**
+ * cppi5_tr_cflag_set - Update the Configuration specific flags
+ * @flags: Pointer to the TR's flags
+ * @csf: Configuration specific flags
+ *
+ * Set a bit in Configuration Specific Flags section of the TR flags.
+ */
+static inline void cppi5_tr_csf_set(cppi5_tr_flags_t *flags, u32 csf)
+{
+       WARN_ON(!flags);
+
+       *flags |= (csf << CPPI5_TR_CSF_FLAGS_SHIFT) &
+                 CPPI5_TR_CSF_FLAGS_MASK;
+}
+
+#endif /* __TI_CPPI5_H__ */
diff --git a/include/linux/soc/ti/k3-navss-ringacc.h b/include/linux/soc/ti/k3-navss-ringacc.h
new file mode 100644 (file)
index 0000000..487dfe9
--- /dev/null
@@ -0,0 +1,236 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * TI K3 AM65x NAVSS Ring accelerator Manager (RA) subsystem driver
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
+ */
+
+#ifndef __SOC_TI_K3_NAVSS_RINGACC_API_H_
+#define __SOC_TI_K3_NAVSS_RINGACC_API_H_
+
+#include <dm/ofnode.h>
+
+/**
+ * enum k3_nav_ring_mode - &struct k3_nav_ring_cfg mode
+ *
+ * RA ring operational modes
+ *
+ * @K3_NAV_RINGACC_RING_MODE_RING: Exposed Ring mode for SW direct access
+ * @K3_NAV_RINGACC_RING_MODE_MESSAGE: Messaging mode. Messaging mode requires
+ *     that all accesses to the queue must go through this IP so that all
+ *     accesses to the memory are controlled and ordered. This IP then
+ *     controls the entire state of the queue, and SW has no directly control,
+ *     such as through doorbells and cannot access the storage memory directly.
+ *     This is particularly useful when more than one SW or HW entity can be
+ *     the producer and/or consumer at the same time
+ * @K3_NAV_RINGACC_RING_MODE_CREDENTIALS: Credentials mode is message mode plus
+ *     stores credentials with each message, requiring the element size to be
+ *     doubled to fit the credentials. Any exposed memory should be protected
+ *     by a firewall from unwanted access
+ * @K3_NAV_RINGACC_RING_MODE_QM:  Queue manager mode. This takes the credentials
+ *     mode and adds packet length per element, along with additional read only
+ *     fields for element count and accumulated queue length. The QM mode only
+ *     operates with an 8 byte element size (any other element size is
+ *     illegal), and like in credentials mode each operation uses 2 element
+ *     slots to store the credentials and length fields
+ */
+enum k3_nav_ring_mode {
+       K3_NAV_RINGACC_RING_MODE_RING = 0,
+       K3_NAV_RINGACC_RING_MODE_MESSAGE,
+       K3_NAV_RINGACC_RING_MODE_CREDENTIALS,
+       K3_NAV_RINGACC_RING_MODE_QM,
+       k3_NAV_RINGACC_RING_MODE_INVALID
+};
+
+/**
+ * enum k3_nav_ring_size - &struct k3_nav_ring_cfg elm_size
+ *
+ * RA ring element's sizes in bytes.
+ */
+enum k3_nav_ring_size {
+       K3_NAV_RINGACC_RING_ELSIZE_4 = 0,
+       K3_NAV_RINGACC_RING_ELSIZE_8,
+       K3_NAV_RINGACC_RING_ELSIZE_16,
+       K3_NAV_RINGACC_RING_ELSIZE_32,
+       K3_NAV_RINGACC_RING_ELSIZE_64,
+       K3_NAV_RINGACC_RING_ELSIZE_128,
+       K3_NAV_RINGACC_RING_ELSIZE_256,
+       K3_NAV_RINGACC_RING_ELSIZE_INVALID
+};
+
+struct k3_nav_ringacc;
+struct k3_nav_ring;
+
+/**
+ * enum k3_nav_ring_cfg - RA ring configuration structure
+ *
+ * @size: Ring size, number of elements
+ * @elm_size: Ring element size
+ * @mode: Ring operational mode
+ * @flags: Ring configuration flags. Possible values:
+ *      @K3_NAV_RINGACC_RING_SHARED: when set allows to request the same ring
+ *      few times. It's usable when the same ring is used as Free Host PD ring
+ *      for different flows, for example.
+ *      Note: Locking should be done by consumer if required
+ */
+struct k3_nav_ring_cfg {
+       u32 size;
+       enum k3_nav_ring_size elm_size;
+       enum k3_nav_ring_mode mode;
+#define K3_NAV_RINGACC_RING_SHARED BIT(1)
+       u32 flags;
+};
+
+#define K3_NAV_RINGACC_RING_ID_ANY (-1)
+#define K3_NAV_RINGACC_RING_USE_PROXY BIT(1)
+
+/**
+ * k3_nav_ringacc_request_ring - request ring from ringacc
+ * @ringacc: pointer on ringacc
+ * @id: ring id or K3_NAV_RINGACC_RING_ID_ANY for any general purpose ring
+ * @flags:
+ *     @K3_NAV_RINGACC_RING_USE_PROXY: if set - proxy will be allocated and
+ *             used to access ring memory. Sopported only for rings in
+ *             Message/Credentials/Queue mode.
+ *
+ * Returns pointer on the Ring - struct k3_nav_ring
+ * or NULL in case of failure.
+ */
+struct k3_nav_ring *k3_nav_ringacc_request_ring(struct k3_nav_ringacc *ringacc,
+                                               int id, u32 flags);
+
+/**
+ * k3_nav_ringacc_get_dev - get pointer on RA device
+ * @ringacc: pointer on RA
+ *
+ * Returns device pointer
+ */
+struct udevice *k3_nav_ringacc_get_dev(struct k3_nav_ringacc *ringacc);
+
+/**
+ * k3_nav_ringacc_ring_reset - ring reset
+ * @ring: pointer on Ring
+ *
+ * Resets ring internal state ((hw)occ, (hw)idx).
+ * TODO_GS: ? Ring can be reused without reconfiguration
+ */
+void k3_nav_ringacc_ring_reset(struct k3_nav_ring *ring);
+/**
+ * k3_nav_ringacc_ring_reset - ring reset for DMA rings
+ * @ring: pointer on Ring
+ *
+ * Resets ring internal state ((hw)occ, (hw)idx). Should be used for rings
+ * which are read by K3 UDMA, like TX or Free Host PD rings.
+ */
+void k3_nav_ringacc_ring_reset_dma(struct k3_nav_ring *ring, u32 occ);
+
+/**
+ * k3_nav_ringacc_ring_free - ring free
+ * @ring: pointer on Ring
+ *
+ * Resets ring and free all alocated resources.
+ */
+int k3_nav_ringacc_ring_free(struct k3_nav_ring *ring);
+
+/**
+ * k3_nav_ringacc_get_ring_id - Get the Ring ID
+ * @ring: pointer on ring
+ *
+ * Returns the Ring ID
+ */
+u32 k3_nav_ringacc_get_ring_id(struct k3_nav_ring *ring);
+
+/**
+ * k3_nav_ringacc_ring_cfg - ring configure
+ * @ring: pointer on ring
+ * @cfg: Ring configuration parameters (see &struct k3_nav_ring_cfg)
+ *
+ * Configures ring, including ring memory allocation.
+ * Returns 0 on success, errno otherwise.
+ */
+int k3_nav_ringacc_ring_cfg(struct k3_nav_ring *ring,
+                           struct k3_nav_ring_cfg *cfg);
+
+/**
+ * k3_nav_ringacc_ring_get_size - get ring size
+ * @ring: pointer on ring
+ *
+ * Returns ring size in number of elements.
+ */
+u32 k3_nav_ringacc_ring_get_size(struct k3_nav_ring *ring);
+
+/**
+ * k3_nav_ringacc_ring_get_free - get free elements
+ * @ring: pointer on ring
+ *
+ * Returns number of free elements in the ring.
+ */
+u32 k3_nav_ringacc_ring_get_free(struct k3_nav_ring *ring);
+
+/**
+ * k3_nav_ringacc_ring_get_occ - get ring occupancy
+ * @ring: pointer on ring
+ *
+ * Returns total number of valid entries on the ring
+ */
+u32 k3_nav_ringacc_ring_get_occ(struct k3_nav_ring *ring);
+
+/**
+ * k3_nav_ringacc_ring_is_full - checks if ring is full
+ * @ring: pointer on ring
+ *
+ * Returns true if the ring is full
+ */
+u32 k3_nav_ringacc_ring_is_full(struct k3_nav_ring *ring);
+
+/**
+ * k3_nav_ringacc_ring_push - push element to the ring tail
+ * @ring: pointer on ring
+ * @elem: pointer on ring element buffer
+ *
+ * Push one ring element to the ring tail. Size of the ring element is
+ * determined by ring configuration &struct k3_nav_ring_cfg elm_size.
+ *
+ * Returns 0 on success, errno otherwise.
+ */
+int k3_nav_ringacc_ring_push(struct k3_nav_ring *ring, void *elem);
+
+/**
+ * k3_nav_ringacc_ring_pop - pop element from the ring head
+ * @ring: pointer on ring
+ * @elem: pointer on ring element buffer
+ *
+ * Push one ring element from the ring head. Size of the ring element is
+ * determined by ring configuration &struct k3_nav_ring_cfg elm_size..
+ *
+ * Returns 0 on success, errno otherwise.
+ */
+int k3_nav_ringacc_ring_pop(struct k3_nav_ring *ring, void *elem);
+
+/**
+ * k3_nav_ringacc_ring_push_head - push element to the ring head
+ * @ring: pointer on ring
+ * @elem: pointer on ring element buffer
+ *
+ * Push one ring element to the ring head. Size of the ring element is
+ * determined by ring configuration &struct k3_nav_ring_cfg elm_size.
+ *
+ * Returns 0 on success, errno otherwise.
+ * Not Supported by ring modes: K3_NAV_RINGACC_RING_MODE_RING
+ */
+int k3_nav_ringacc_ring_push_head(struct k3_nav_ring *ring, void *elem);
+
+/**
+ * k3_nav_ringacc_ring_pop_tail - pop element from the ring tail
+ * @ring: pointer on ring
+ * @elem: pointer on ring element buffer
+ *
+ * Push one ring element from the ring tail. Size of the ring element is
+ * determined by ring configuration &struct k3_nav_ring_cfg elm_size.
+ *
+ * Returns 0 on success, errno otherwise.
+ * Not Supported by ring modes: K3_NAV_RINGACC_RING_MODE_RING
+ */
+int k3_nav_ringacc_ring_pop_tail(struct k3_nav_ring *ring, void *elem);
+
+#endif /* __SOC_TI_K3_NAVSS_RINGACC_API_H_ */
diff --git a/include/linux/soc/ti/ti-udma.h b/include/linux/soc/ti/ti-udma.h
new file mode 100644 (file)
index 0000000..e9d4226
--- /dev/null
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *  Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
+ *  Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ */
+
+#ifndef __TI_UDMA_H
+#define __TI_UDMA_H
+
+/**
+ * struct ti_udma_drv_packet_data - TI UDMA transfer specific data
+ *
+ * @pkt_type: Packet Type - specific for each DMA client HW
+ * @dest_tag: Destination tag The source pointer.
+ *
+ * TI UDMA transfer specific data passed as part of DMA transfer to
+ * the DMA client HW in UDMA descriptors.
+ */
+struct ti_udma_drv_packet_data {
+       u32     pkt_type;
+       u32     dest_tag;
+};
+
+#endif /* __TI_UDMA_H */
index 90d5053636522d7d8340817ae22556e3e77d085d..222cf665460ff294b5344764f700fcc82818ad5f 100644 (file)
@@ -212,14 +212,43 @@ struct ti_sci_clk_ops {
                        u64 *current_freq);
 };
 
+/**
+ * struct ti_sci_rm_core_ops - Resource management core operations
+ * @get_range:         Get a range of resources belonging to ti sci host.
+ * @get_rage_from_shost:       Get a range of resources belonging to
+ *                             specified host id.
+ *                     - s_host: Host processing entity to which the
+ *                               resources are allocated
+ *
+ * NOTE: for these functions, all the parameters are consolidated and defined
+ * as below:
+ * - handle:   Pointer to TISCI handle as retrieved by *ti_sci_get_handle
+ * - dev_id:   TISCI device ID.
+ * - subtype:  Resource assignment subtype that is being requested
+ *             from the given device.
+ * - range_start:      Start index of the resource range
+ * - range_end:                Number of resources in the range
+ */
+struct ti_sci_rm_core_ops {
+       int (*get_range)(const struct ti_sci_handle *handle, u32 dev_id,
+                        u8 subtype, u16 *range_start, u16 *range_num);
+       int (*get_range_from_shost)(const struct ti_sci_handle *handle,
+                                   u32 dev_id, u8 subtype, u8 s_host,
+                                   u16 *range_start, u16 *range_num);
+};
+
 /**
  * struct ti_sci_core_ops - SoC Core Operations
  * @reboot_device: Reboot the SoC
  *             Returns 0 for successful request(ideally should never return),
  *             else returns corresponding error value.
+ * @query_msmc: Query the size of available msmc
+ *             Return 0 for successful query else appropriate error value.
  */
 struct ti_sci_core_ops {
        int (*reboot_device)(const struct ti_sci_handle *handle);
+       int (*query_msmc)(const struct ti_sci_handle *handle,
+                         u64 *msmc_start, u64 *msmc_end);
 };
 
 /**
@@ -257,6 +286,230 @@ struct ti_sci_proc_ops {
                                    u32 *sts_flags);
 };
 
+#define TI_SCI_RING_MODE_RING                  (0)
+#define TI_SCI_RING_MODE_MESSAGE               (1)
+#define TI_SCI_RING_MODE_CREDENTIALS           (2)
+#define TI_SCI_RING_MODE_QM                    (3)
+
+#define TI_SCI_MSG_UNUSED_SECONDARY_HOST TI_SCI_RM_NULL_U8
+
+/* RA config.addr_lo parameter is valid for RM ring configure TI_SCI message */
+#define TI_SCI_MSG_VALUE_RM_RING_ADDR_LO_VALID BIT(0)
+/* RA config.addr_hi parameter is valid for RM ring configure TI_SCI message */
+#define TI_SCI_MSG_VALUE_RM_RING_ADDR_HI_VALID BIT(1)
+ /* RA config.count parameter is valid for RM ring configure TI_SCI message */
+#define TI_SCI_MSG_VALUE_RM_RING_COUNT_VALID   BIT(2)
+/* RA config.mode parameter is valid for RM ring configure TI_SCI message */
+#define TI_SCI_MSG_VALUE_RM_RING_MODE_VALID    BIT(3)
+/* RA config.size parameter is valid for RM ring configure TI_SCI message */
+#define TI_SCI_MSG_VALUE_RM_RING_SIZE_VALID    BIT(4)
+/* RA config.order_id parameter is valid for RM ring configure TISCI message */
+#define TI_SCI_MSG_VALUE_RM_RING_ORDER_ID_VALID        BIT(5)
+
+#define TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER \
+       (TI_SCI_MSG_VALUE_RM_RING_ADDR_LO_VALID | \
+       TI_SCI_MSG_VALUE_RM_RING_ADDR_HI_VALID | \
+       TI_SCI_MSG_VALUE_RM_RING_COUNT_VALID | \
+       TI_SCI_MSG_VALUE_RM_RING_MODE_VALID | \
+       TI_SCI_MSG_VALUE_RM_RING_SIZE_VALID)
+
+/**
+ * struct ti_sci_rm_ringacc_ops - Ring Accelerator Management operations
+ * @config: configure the SoC Navigator Subsystem Ring Accelerator ring
+ * @get_config: get the SoC Navigator Subsystem Ring Accelerator ring
+ *             configuration
+ */
+struct ti_sci_rm_ringacc_ops {
+       int (*config)(const struct ti_sci_handle *handle,
+                     u32 valid_params, u16 nav_id, u16 index,
+                     u32 addr_lo, u32 addr_hi, u32 count, u8 mode,
+                     u8 size, u8 order_id
+       );
+       int (*get_config)(const struct ti_sci_handle *handle,
+                         u32 nav_id, u32 index, u8 *mode,
+                         u32 *addr_lo, u32 *addr_hi, u32 *count,
+                         u8 *size, u8 *order_id);
+};
+
+/**
+ * struct ti_sci_rm_psil_ops - PSI-L thread operations
+ * @pair: pair PSI-L source thread to a destination thread.
+ *     If the src_thread is mapped to UDMA tchan, the corresponding channel's
+ *     TCHAN_THRD_ID register is updated.
+ *     If the dst_thread is mapped to UDMA rchan, the corresponding channel's
+ *     RCHAN_THRD_ID register is updated.
+ * @unpair: unpair PSI-L source thread from a destination thread.
+ *     If the src_thread is mapped to UDMA tchan, the corresponding channel's
+ *     TCHAN_THRD_ID register is cleared.
+ *     If the dst_thread is mapped to UDMA rchan, the corresponding channel's
+ *     RCHAN_THRD_ID register is cleared.
+ */
+struct ti_sci_rm_psil_ops {
+       int (*pair)(const struct ti_sci_handle *handle, u32 nav_id,
+                   u32 src_thread, u32 dst_thread);
+       int (*unpair)(const struct ti_sci_handle *handle, u32 nav_id,
+                     u32 src_thread, u32 dst_thread);
+};
+
+/* UDMAP channel types */
+#define TI_SCI_RM_UDMAP_CHAN_TYPE_PKT_PBRR             2
+#define TI_SCI_RM_UDMAP_CHAN_TYPE_PKT_PBRR_SB          3       /* RX only */
+#define TI_SCI_RM_UDMAP_CHAN_TYPE_3RDP_PBRR            10
+#define TI_SCI_RM_UDMAP_CHAN_TYPE_3RDP_PBVR            11
+#define TI_SCI_RM_UDMAP_CHAN_TYPE_3RDP_BCOPY_PBRR      12
+#define TI_SCI_RM_UDMAP_CHAN_TYPE_3RDP_BCOPY_PBVR      13
+
+/* UDMAP channel atypes */
+#define TI_SCI_RM_UDMAP_ATYPE_PHYS                     0
+#define TI_SCI_RM_UDMAP_ATYPE_INTERMEDIATE             1
+#define TI_SCI_RM_UDMAP_ATYPE_VIRTUAL                  2
+
+/* UDMAP channel scheduling priorities */
+#define TI_SCI_RM_UDMAP_SCHED_PRIOR_HIGH               0
+#define TI_SCI_RM_UDMAP_SCHED_PRIOR_MEDHIGH            1
+#define TI_SCI_RM_UDMAP_SCHED_PRIOR_MEDLOW             2
+#define TI_SCI_RM_UDMAP_SCHED_PRIOR_LOW                        3
+
+#define TI_SCI_RM_UDMAP_RX_FLOW_DESC_HOST              0
+#define TI_SCI_RM_UDMAP_RX_FLOW_DESC_MONO              2
+
+/* UDMAP TX/RX channel valid_params common declarations */
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_PAUSE_ON_ERR_VALID                BIT(0)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_ATYPE_VALID                BIT(1)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_CHAN_TYPE_VALID            BIT(2)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_FETCH_SIZE_VALID           BIT(3)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_CQ_QNUM_VALID              BIT(4)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_PRIORITY_VALID             BIT(5)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_QOS_VALID                  BIT(6)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_ORDER_ID_VALID             BIT(7)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_SCHED_PRIORITY_VALID       BIT(8)
+
+/**
+ * Configures a Navigator Subsystem UDMAP transmit channel
+ *
+ * Configures a Navigator Subsystem UDMAP transmit channel registers.
+ * See @ti_sci_msg_rm_udmap_tx_ch_cfg_req
+ */
+struct ti_sci_msg_rm_udmap_tx_ch_cfg {
+       u32 valid_params;
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_FILT_EINFO_VALID        BIT(9)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_FILT_PSWORDS_VALID      BIT(10)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_SUPR_TDPKT_VALID        BIT(11)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_CREDIT_COUNT_VALID      BIT(12)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_TX_FDEPTH_VALID            BIT(13)
+       u16 nav_id;
+       u16 index;
+       u8 tx_pause_on_err;
+       u8 tx_filt_einfo;
+       u8 tx_filt_pswords;
+       u8 tx_atype;
+       u8 tx_chan_type;
+       u8 tx_supr_tdpkt;
+       u16 tx_fetch_size;
+       u8 tx_credit_count;
+       u16 txcq_qnum;
+       u8 tx_priority;
+       u8 tx_qos;
+       u8 tx_orderid;
+       u16 fdepth;
+       u8 tx_sched_priority;
+};
+
+/**
+ * Configures a Navigator Subsystem UDMAP receive channel
+ *
+ * Configures a Navigator Subsystem UDMAP receive channel registers.
+ * See @ti_sci_msg_rm_udmap_rx_ch_cfg_req
+ */
+struct ti_sci_msg_rm_udmap_rx_ch_cfg {
+       u32 valid_params;
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_START_VALID      BIT(9)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_CNT_VALID        BIT(10)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_IGNORE_SHORT_VALID      BIT(11)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_IGNORE_LONG_VALID       BIT(12)
+       u16 nav_id;
+       u16 index;
+       u16 rx_fetch_size;
+       u16 rxcq_qnum;
+       u8 rx_priority;
+       u8 rx_qos;
+       u8 rx_orderid;
+       u8 rx_sched_priority;
+       u16 flowid_start;
+       u16 flowid_cnt;
+       u8 rx_pause_on_err;
+       u8 rx_atype;
+       u8 rx_chan_type;
+       u8 rx_ignore_short;
+       u8 rx_ignore_long;
+};
+
+/**
+ * Configures a Navigator Subsystem UDMAP receive flow
+ *
+ * Configures a Navigator Subsystem UDMAP receive flow's registers.
+ * See @tis_ci_msg_rm_udmap_flow_cfg_req
+ */
+struct ti_sci_msg_rm_udmap_flow_cfg {
+       u32 valid_params;
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_EINFO_PRESENT_VALID     BIT(0)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_PSINFO_PRESENT_VALID     BIT(1)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_ERROR_HANDLING_VALID     BIT(2)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_DESC_TYPE_VALID          BIT(3)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_SOP_OFFSET_VALID         BIT(4)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_DEST_QNUM_VALID          BIT(5)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_SRC_TAG_HI_VALID         BIT(6)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_SRC_TAG_LO_VALID         BIT(7)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_DEST_TAG_HI_VALID        BIT(8)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_DEST_TAG_LO_VALID        BIT(9)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_SRC_TAG_HI_SEL_VALID     BIT(10)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_SRC_TAG_LO_SEL_VALID     BIT(11)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_DEST_TAG_HI_SEL_VALID    BIT(12)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_DEST_TAG_LO_SEL_VALID    BIT(13)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_FDQ0_SZ0_QNUM_VALID      BIT(14)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_FDQ1_QNUM_VALID          BIT(15)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_FDQ2_QNUM_VALID          BIT(16)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_FDQ3_QNUM_VALID          BIT(17)
+#define TI_SCI_MSG_VALUE_RM_UDMAP_FLOW_PS_LOCATION_VALID        BIT(18)
+       u16 nav_id;
+       u16 flow_index;
+       u8 rx_einfo_present;
+       u8 rx_psinfo_present;
+       u8 rx_error_handling;
+       u8 rx_desc_type;
+       u16 rx_sop_offset;
+       u16 rx_dest_qnum;
+       u8 rx_src_tag_hi;
+       u8 rx_src_tag_lo;
+       u8 rx_dest_tag_hi;
+       u8 rx_dest_tag_lo;
+       u8 rx_src_tag_hi_sel;
+       u8 rx_src_tag_lo_sel;
+       u8 rx_dest_tag_hi_sel;
+       u8 rx_dest_tag_lo_sel;
+       u16 rx_fdq0_sz0_qnum;
+       u16 rx_fdq1_qnum;
+       u16 rx_fdq2_qnum;
+       u16 rx_fdq3_qnum;
+       u8 rx_ps_location;
+};
+
+/**
+ * struct ti_sci_rm_udmap_ops - UDMA Management operations
+ * @tx_ch_cfg: configure SoC Navigator Subsystem UDMA transmit channel.
+ * @rx_ch_cfg: configure SoC Navigator Subsystem UDMA receive channel.
+ * @rx_flow_cfg: configure SoC Navigator Subsystem UDMA receive flow.
+ */
+struct ti_sci_rm_udmap_ops {
+       int (*tx_ch_cfg)(const struct ti_sci_handle *handle,
+                        const struct ti_sci_msg_rm_udmap_tx_ch_cfg *params);
+       int (*rx_ch_cfg)(const struct ti_sci_handle *handle,
+                        const struct ti_sci_msg_rm_udmap_rx_ch_cfg *params);
+       int (*rx_flow_cfg)(
+               const struct ti_sci_handle *handle,
+               const struct ti_sci_msg_rm_udmap_flow_cfg *params);
+};
+
 /**
  * struct ti_sci_ops - Function support for TI SCI
  * @board_ops: Miscellaneous operations
@@ -264,6 +517,7 @@ struct ti_sci_proc_ops {
  * @clk_ops:   Clock specific operations
  * @core_ops:  Core specific operations
  * @proc_ops:  Processor specific operations
+ * @ring_ops: Ring Accelerator Management operations
  */
 struct ti_sci_ops {
        struct ti_sci_board_ops board_ops;
@@ -271,6 +525,10 @@ struct ti_sci_ops {
        struct ti_sci_clk_ops clk_ops;
        struct ti_sci_core_ops core_ops;
        struct ti_sci_proc_ops proc_ops;
+       struct ti_sci_rm_core_ops rm_core_ops;
+       struct ti_sci_rm_ringacc_ops rm_ring_ops;
+       struct ti_sci_rm_psil_ops rm_psil_ops;
+       struct ti_sci_rm_udmap_ops rm_udmap_ops;
 };
 
 /**
@@ -283,12 +541,42 @@ struct ti_sci_handle {
        struct ti_sci_version_info version;
 };
 
+#define TI_SCI_RESOURCE_NULL   0xffff
+
+/**
+ * struct ti_sci_resource_desc - Description of TI SCI resource instance range.
+ * @start:     Start index of the resource.
+ * @num:       Number of resources.
+ * @res_map:   Bitmap to manage the allocation of these resources.
+ */
+struct ti_sci_resource_desc {
+       u16 start;
+       u16 num;
+       unsigned long *res_map;
+};
+
+/**
+ * struct ti_sci_resource - Structure representing a resource assigned
+ *                         to a device.
+ * @sets:      Number of sets available from this resource type
+ * @desc:      Array of resource descriptors.
+ */
+struct ti_sci_resource {
+       u16 sets;
+       struct ti_sci_resource_desc *desc;
+};
+
 #if IS_ENABLED(CONFIG_TI_SCI_PROTOCOL)
 
 const struct ti_sci_handle *ti_sci_get_handle_from_sysfw(struct udevice *dev);
 const struct ti_sci_handle *ti_sci_get_handle(struct udevice *dev);
 const struct ti_sci_handle *ti_sci_get_by_phandle(struct udevice *dev,
                                                  const char *property);
+u16 ti_sci_get_free_resource(struct ti_sci_resource *res);
+void ti_sci_release_resource(struct ti_sci_resource *res, u16 id);
+struct ti_sci_resource *
+devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
+                           struct udevice *dev, u32 dev_id, char *of_prop);
 
 #else  /* CONFIG_TI_SCI_PROTOCOL */
 
@@ -309,6 +597,22 @@ const struct ti_sci_handle *ti_sci_get_by_phandle(struct udevice *dev,
 {
        return ERR_PTR(-EINVAL);
 }
+
+static inline u16 ti_sci_get_free_resource(struct ti_sci_resource *res)
+{
+       return TI_SCI_RESOURCE_NULL;
+}
+
+static inline void ti_sci_release_resource(struct ti_sci_resource *res, u16 id)
+{
+}
+
+static inline struct ti_sci_resource *
+devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
+                           struct udevice *dev, u32 dev_id, char *of_prop)
+{
+       return ERR_PTR(-EINVAL);
+}
 #endif /* CONFIG_TI_SCI_PROTOCOL */
 
 #endif /* __TISCI_PROTOCOL_H */
index dd52ed3f476c156c0528a7cbc3ed1ea153ad1493..44b32385c402e5697fec20ad9a820d0435773c39 100644 (file)
@@ -92,12 +92,14 @@ enum eth_state_t {
  * @enetaddr: The Ethernet MAC address that is loaded from EEPROM or env
  * @phy_interface: PHY interface to use - see PHY_INTERFACE_MODE_...
  * @max_speed: Maximum speed of Ethernet connection supported by MAC
+ * @priv_pdata: device specific platdata
  */
 struct eth_pdata {
        phys_addr_t iobase;
        unsigned char enetaddr[ARP_HLEN];
        int phy_interface;
        int max_speed;
+       void *priv_pdata;
 };
 
 enum eth_recv_flags {
diff --git a/include/power/stpmic1.h b/include/power/stpmic1.h
new file mode 100644 (file)
index 0000000..0e6721d
--- /dev/null
@@ -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 (file)
index 5906fbf..0000000
+++ /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
index 8fe5d85a050643c512963402ac566d2ad9801848..2120216593eec74b3f462e3a83dbb7cbbc8b06ad 100644 (file)
@@ -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
index 21f1eee92d3035689d954f59c3ab59da6572a576..9c9c30234732f09b8162414e12145373a23b6cc6 100644 (file)
@@ -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)
index a82e27de942f2fb3ac2bfda8943b6bf63f7f1be1..f6defe16c5a694a9af4e5e476aa550edf4ab6225 100644 (file)
 /* 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;
 }
index b6ca4e0b0c308fb9f5ebb9dfe5639aaa90769f8c..693de9aa5ad8032375b22749a25bc236dc15d950 100644 (file)
@@ -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);
index 1b6c154d8d722215767a7cef1c850850dda6088a..2403825dc98d9c0430eb5b76e8d0bbc83ae09440 100644 (file)
@@ -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 */
index 70de9bb13a665c68de0c66193d04b0548cf0cfa2..de67677f61aef1223bdfd324f1d31ea6510c7de6 100644 (file)
@@ -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)))
index 8c7c1592a562435a758b19ed84d1e6274994c260..fa98efc24c0be17ea60047e74b9ebf85a8dd0421 100644 (file)
@@ -4399,7 +4399,6 @@ CONFIG_THOR_RESET_OFF
 CONFIG_THUNDERX
 CONFIG_TIMESTAMP
 CONFIG_TIZEN
-CONFIG_TI_KEYSTONE_SERDES
 CONFIG_TI_KSNAV
 CONFIG_TI_SPI_MMAP
 CONFIG_TMU_TIMER
index dfb3236da3882654f5e7c393019f93da36d40bff..dc499884e4d1a7f1858225024cc97799af4f57ce 100644 (file)
@@ -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);
index fd73688f9e9f3e03e7298eb74db50439d5b2ab3d..cf86ddba88113f22f989c3041b8025193b69d71d 100644 (file)
 
 #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)                */
 /**********************************************************************/
@@ -313,6 +317,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
index bd2474628775ff6d7439d37c09344ab4e9edc56e..3ff9e28630752c1f55052e8c47c300d1dfb13e67 100644 (file)
@@ -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>
index a294dda02e7dd6a5ce087d601ac67a7c919931db..0ff9da7ec630bbe70f633d6a9dddc3977c648433 100644 (file)
@@ -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;
index a88a3830c0c8d41c93765474622205f8b43c22d8..dffaf9043a040815efedac502338308e3228eb9d 100644 (file)
@@ -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) {
index 2899adff81079e4a92edfe454e88c92d159d2e7a..d1e1a6743d15f9f03c59138b11941afda37964d2 100644 (file)
@@ -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, &params);
+               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, &params);
+               } 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, &params);
+               }
 
                (void) munmap((void *)ptr, sbuf.st_size);
                (void) close (ifd);