Merge tag 'rpi-next-2022.01' of https://source.denx.de/u-boot/custodians/u-boot-raspb...
authorTom Rini <trini@konsulko.com>
Wed, 15 Dec 2021 16:49:30 +0000 (11:49 -0500)
committerTom Rini <trini@konsulko.com>
Wed, 15 Dec 2021 16:49:30 +0000 (11:49 -0500)
- enable RPi Zero 2 W
- fix MMC numbering issue
- Update link to documentation

79 files changed:
MAINTAINERS
arch/arm/dts/beacon-renesom-baseboard.dtsi
arch/arm/dts/beacon-renesom-som.dtsi
arch/arm/dts/r8a774a1-beacon-rzg2m-kit-u-boot.dtsi
arch/arm/dts/r8a774a1-beacon-rzg2m-kit.dts
arch/arm/dts/r8a774b1-beacon-rzg2n-kit-u-boot.dtsi
arch/arm/dts/r8a774b1-beacon-rzg2n-kit.dts
arch/arm/dts/r8a774e1-beacon-rzg2h-kit-u-boot.dtsi
arch/arm/dts/r8a774e1-beacon-rzg2h-kit.dts
arch/arm/dts/rz-g2-beacon-u-boot.dtsi [new file with mode: 0644]
arch/arm/dts/stm32mp15xx-dhcor-avenger96-u-boot.dtsi
arch/arm/dts/sunxi-u-boot.dtsi
arch/riscv/cpu/fu740/Kconfig
arch/riscv/dts/hifive-unmatched-a00-u-boot.dtsi
arch/riscv/dts/microchip-mpfs-icicle-kit.dts
arch/riscv/dts/microchip-mpfs.dtsi [new file with mode: 0644]
arch/sandbox/dts/test.dts
board/CZ.NIC/turris_omnia/turris_omnia.c
board/beacon/beacon-rzg2m/MAINTAINERS
board/dhelectronics/dh_stm32mp1/board.c
board/microchip/mpfs_icicle/Kconfig
board/microchip/mpfs_icicle/mpfs_icicle.c
board/sifive/unmatched/Kconfig
board/sifive/unmatched/spl.c
board/sunxi/board.c
cmd/tpm-v2.c
configs/microchip_mpfs_icicle_defconfig
configs/qemu_arm64_defconfig
configs/qemu_arm_defconfig
configs/rzg2_beacon_defconfig
configs/sifive_unmatched_defconfig
configs/stm32mp15_dhcor_basic_defconfig
disk/part.c
doc/board/emulation/qemu-arm.rst
doc/board/microchip/mpfs_icicle.rst
doc/board/sifive/unmatched.rst
doc/develop/uefi/uefi.rst
doc/usage/fdt_overlays.rst
drivers/block/Kconfig
drivers/block/Makefile
drivers/block/blk-uclass.c
drivers/block/efi-media-uclass.c [new file with mode: 0644]
drivers/block/efi_blk.c [new file with mode: 0644]
drivers/block/sb_efi_media.c [new file with mode: 0644]
drivers/i2c/Kconfig
drivers/i2c/Makefile
drivers/i2c/i2c-microchip.c [new file with mode: 0644]
drivers/net/dwc_eth_qos.c
drivers/net/eth-phy-uclass.c
drivers/net/macb.c
drivers/net/ravb.c
drivers/pci/pci-aardvark.c
drivers/pci/pci_mvebu.c
drivers/serial/serial_mvebu_a3700.c
drivers/tpm/tpm2_tis_core.c
drivers/tpm/tpm2_tis_mmio.c
include/blk.h
include/configs/ax25-ae350.h
include/configs/beacon-rzg2m.h
include/configs/stm32mp15_common.h
include/configs/stm32mp15_dh_dhsom.h
include/dm/uclass-id.h
include/dt-bindings/interrupt-controller/microchip-mpfs-plic.h [new file with mode: 0644]
include/dt-bindings/interrupt-controller/riscv-hart.h [new file with mode: 0644]
include/efi.h
include/efi_loader.h
include/tpm-v2.h
lib/efi_driver/efi_block_device.c
lib/efi_driver/efi_uclass.c
lib/efi_loader/Kconfig
lib/efi_loader/efi_boottime.c
lib/efi_loader/efi_image_loader.c
lib/efi_loader/efi_setup.c
lib/efi_loader/efi_tcg2.c
lib/tpm-v2.c
test/dm/Makefile
test/dm/efi_media.c [new file with mode: 0644]
test/py/tests/test_efi_selftest.py
test/py/tests/test_tpm2.py

index e718ad2..90666ce 100644 (file)
@@ -713,8 +713,11 @@ W: https://u-boot.readthedocs.io/en/latest/develop/uefi/u-boot_on_efi.html
 F:     board/efi/efi-x86_app
 F:     configs/efi-x86_app*
 F:     doc/develop/uefi/u-boot_on_efi.rst
+F:     drivers/block/efi-media-uclass.c
+F:     drivers/block/sb_efi_media.c
 F:     lib/efi/efi_app.c
 F:     scripts/build-efi.sh
+F:     test/dm/efi_media.c
 
 EFI PAYLOAD
 M:     Heinrich Schuchardt <xypron.glpk@gmx.de>
index 5f998d4..2692cc6 100644 (file)
                compatible = "audio-graph-card";
                label = "rcar-sound";
                dais = <&rsnd_port0>, <&rsnd_port1>;
+               widgets = "Microphone", "Mic Jack",
+                         "Line", "Line In Jack",
+                         "Headphone", "Headphone Jack";
+               mic-det-gpio = <&gpio0 2 GPIO_ACTIVE_LOW>;
+               routing = "Headphone Jack", "HPOUTL",
+                        "Headphone Jack", "HPOUTR",
+                        "IN3R", "MICBIAS",
+                        "Mic Jack", "IN3R";
        };
 
        vccq_sdhi0: regulator-vccq-sdhi0 {
 &ehci0 {
        dr_mode = "otg";
        status = "okay";
-       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&versaclock5 3>;
+       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&usb2_clksel>, <&versaclock5 3>;
 };
 
 &ehci1 {
        status = "okay";
-       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
+       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&usb2_clksel>, <&versaclock5 3>;
 };
 
 &hdmi0 {
 };
 
 &rcar_sound {
-       pinctrl-0 = <&sound_pins &sound_clk_pins>;
+       pinctrl-0 = <&sound_pins>, <&sound_clk_pins>;
        pinctrl-names = "default";
 
        /* Single DAI */
                                bitclock-master = <&rsnd_endpoint0>;
                                frame-master = <&rsnd_endpoint0>;
 
-                               playback = <&ssi1 &dvc1 &src1>;
+                               playback = <&ssi1>, <&dvc1>, <&src1>;
                                capture = <&ssi0>;
                        };
                };
index d30bab3..0d13680 100644 (file)
@@ -7,19 +7,10 @@
 #include <dt-bindings/clk/versaclock.h>
 
 / {
-       aliases {
-               spi0 = &rpc;
-       };
-
        memory@48000000 {
                device_type = "memory";
                /* first 128MB is reserved for secure area. */
-               reg = <0x0 0x48000000 0x0 0xc000000>;
-       };
-
-       memory@57000000 {
-               device_type = "memory";
-               reg = <0x0 0x57000000 0x0 0x29000000>;
+               reg = <0x0 0x48000000 0x0 0x78000000>;
        };
 
        osc_32k: osc_32k {
 &avb {
        pinctrl-0 = <&avb_pins>;
        pinctrl-names = "default";
+       phy-mode = "rgmii-rxid";
        phy-handle = <&phy0>;
        rx-internal-delay-ps = <1800>;
        tx-internal-delay-ps = <2000>;
+       clocks = <&cpg CPG_MOD 812>, <&versaclock5 4>;
+       clock-names = "fck", "refclk";
        status = "okay";
 
        phy0: ethernet-phy@0 {
+               compatible = "ethernet-phy-id004d.d074",
+                            "ethernet-phy-ieee802.3-c22";
                reg = <0>;
                interrupt-parent = <&gpio2>;
                interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
        };
 
        eeprom@50 {
-               compatible = "microchip,at24c64", "atmel,24c64";
+               compatible = "microchip,24c64", "atmel,24c64";
                pagesize = <32>;
                read-only;      /* Manufacturing EEPROM programmed at factory */
                reg = <0x50>;
        };
 };
 
-&rpc {
-       compatible = "renesas,rcar-gen3-rpc";
-       num-cs = <1>;
-       spi-max-frequency = <40000000>;
-       #address-cells = <1>;
-       #size-cells = <0>;
-       status = "okay";
-
-       flash0: spi-flash@0 {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               reg = <0>;
-               compatible = "spi-flash", "jedec,spi-nor";
-               spi-max-frequency = <40000000>;
-               spi-tx-bus-width = <1>;
-               spi-rx-bus-width = <1>;
-       };
-};
-
 &scif_clk {
        clock-frequency = <14745600>;
 };
        vqmmc-supply = <&reg_1p8v>;
        bus-width = <8>;
        mmc-hs200-1_8v;
+       no-sd;
+       no-sdio;
        non-removable;
        fixed-emmc-driver-type = <1>;
        status = "okay";
 };
 
 &usb2_clksel {
-       status = "okay";
        clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>,
-                <&versaclock5 3>, <&usb3s0_clk>;
-       clock-names = "ehci_ohci", "hs-usb-if",
-                     "usb_extal", "usb_xtal";
+                 <&versaclock5 3>, <&usb3s0_clk>;
+       status = "okay";
 };
 
 &usb3s0_clk {
index a0c0a7f..85336d5 100644 (file)
@@ -1,34 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright 2020 Compass Electronics Group, LLC
+ * Copyright 2021 LogicPD dba Beacon EmbeddedWorks
  */
 
-/ {
-       soc {
-               u-boot,dm-pre-reloc;
-       };
-};
-
-&cpg {
-       u-boot,dm-pre-reloc;
-};
-
-&extal_clk {
-       u-boot,dm-pre-reloc;
-};
-
-&prr {
-       u-boot,dm-pre-reloc;
-};
-
-&extalr_clk {
-       u-boot,dm-pre-reloc;
-};
-
-&sdhi0 {
-       /delete-property/ cd-gpios;
-};
-
-&sdhi2 {
-       status = "disabled";
-};
+#include "rz-g2-beacon-u-boot.dtsi"
index 501cb05..3cf2e07 100644 (file)
@@ -21,6 +21,9 @@
                serial4 = &hscif2;
                serial5 = &scif5;
                ethernet0 = &avb;
+               mmc0 = &sdhi3;
+               mmc1 = &sdhi0;
+               mmc2 = &sdhi2;
        };
 
        chosen {
index a0c0a7f..85336d5 100644 (file)
@@ -1,34 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright 2020 Compass Electronics Group, LLC
+ * Copyright 2021 LogicPD dba Beacon EmbeddedWorks
  */
 
-/ {
-       soc {
-               u-boot,dm-pre-reloc;
-       };
-};
-
-&cpg {
-       u-boot,dm-pre-reloc;
-};
-
-&extal_clk {
-       u-boot,dm-pre-reloc;
-};
-
-&prr {
-       u-boot,dm-pre-reloc;
-};
-
-&extalr_clk {
-       u-boot,dm-pre-reloc;
-};
-
-&sdhi0 {
-       /delete-property/ cd-gpios;
-};
-
-&sdhi2 {
-       status = "disabled";
-};
+#include "rz-g2-beacon-u-boot.dtsi"
index 71763f4..3c0d59d 100644 (file)
@@ -22,6 +22,9 @@
                serial5 = &scif5;
                serial6 = &scif4;
                ethernet0 = &avb;
+               mmc0 = &sdhi3;
+               mmc1 = &sdhi0;
+               mmc2 = &sdhi2;
        };
 
        chosen {
index eef200a..85336d5 100644 (file)
@@ -1,44 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright 2020 Compass Electronics Group, LLC
+ * Copyright 2021 LogicPD dba Beacon EmbeddedWorks
  */
 
-/ {
-       soc {
-               u-boot,dm-pre-reloc;
-       };
-};
-
-&cpg {
-       u-boot,dm-pre-reloc;
-};
-
-&extal_clk {
-       u-boot,dm-pre-reloc;
-};
-
-&prr {
-       u-boot,dm-pre-reloc;
-};
-
-&extalr_clk {
-       u-boot,dm-pre-reloc;
-};
-
-&sdhi0 {
-       /delete-property/ cd-gpios;
-       sd-uhs-sdr12;
-       sd-uhs-sdr25;
-       sd-uhs-sdr104;
-       max-frequency = <208000000>;
-};
-
-&sdhi2 {
-       status = "disabled";
-};
-
-&sdhi3 {
-       mmc-ddr-1_8v;
-       mmc-hs200-1_8v;
-       mmc-hs400-1_8v;
-};
+#include "rz-g2-beacon-u-boot.dtsi"
index 273f062..7b6649a 100644 (file)
@@ -22,6 +22,9 @@
                serial5 = &scif5;
                serial6 = &scif4;
                ethernet0 = &avb;
+               mmc0 = &sdhi3;
+               mmc1 = &sdhi0;
+               mmc2 = &sdhi2;
        };
 
        chosen {
diff --git a/arch/arm/dts/rz-g2-beacon-u-boot.dtsi b/arch/arm/dts/rz-g2-beacon-u-boot.dtsi
new file mode 100644 (file)
index 0000000..ef0b96a
--- /dev/null
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2021 LogicPD dba Beacon EmbeddedWorks
+ */
+
+/ {
+       aliases {
+               spi0 = &rpc;
+       };
+
+       soc {
+               u-boot,dm-pre-reloc;
+       };
+};
+
+&cpg {
+       u-boot,dm-pre-reloc;
+};
+
+&ehci0 {
+       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&versaclock5 3>;
+};
+
+&ehci1 {
+       clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&versaclock5 3>;
+};
+
+&extal_clk {
+       u-boot,dm-pre-reloc;
+};
+
+&extalr_clk {
+       u-boot,dm-pre-reloc;
+};
+
+&prr {
+       u-boot,dm-pre-reloc;
+};
+
+&rpc {
+       compatible = "renesas,rcar-gen3-rpc";
+       num-cs = <1>;
+       spi-max-frequency = <40000000>;
+       #address-cells = <1>;
+       #size-cells = <0>;
+       status = "okay";
+
+       flash0: spi-flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0>;
+               compatible = "spi-flash", "jedec,spi-nor";
+               spi-max-frequency = <40000000>;
+               spi-tx-bus-width = <1>;
+               spi-rx-bus-width = <1>;
+       };
+};
+
+&sdhi0 {
+       /delete-property/ cd-gpios;
+       sd-uhs-sdr12;
+       sd-uhs-sdr25;
+       sd-uhs-sdr104;
+       max-frequency = <208000000>;
+};
+
+&sdhi2 {
+       status = "disabled";
+};
+
+&sdhi3 {
+       mmc-ddr-1_8v;
+       mmc-hs200-1_8v;
+       mmc-hs400-1_8v;
+};
index 8b275e4..4b1dbf0 100644 (file)
        };
 };
 
+
+&ethernet0 {
+       mdio0 {
+               ethernet-phy@7 {
+                       reset-gpios = <&gpioz 2 GPIO_ACTIVE_LOW>;
+                       reset-assert-us = <11000>;
+                       reset-deassert-us = <1000>;
+               };
+       };
+};
+
 &sdmmc1 {
        u-boot,dm-spl;
 };
index b7244c1..f2d7361 100644 (file)
@@ -13,7 +13,7 @@
 / {
        aliases {
                mmc0 = &mmc0;
-#if CONFIG_MMC_SUNXI_EXTRA_SLOT == 2
+#if CONFIG_MMC_SUNXI_SLOT_EXTRA == 2
                mmc1 = &mmc2;
 #endif
        };
index 049a0a0..3e0c1fd 100644 (file)
@@ -40,3 +40,16 @@ config SIFIVE_FU740
        imply DM_I2C
        imply SYS_I2C_OCORES
        imply SPL_I2C
+
+if ENV_IS_IN_SPI_FLASH
+
+config ENV_OFFSET
+       default 0x505000
+
+config ENV_SIZE
+       default 0x20000
+
+config ENV_SECT_SIZE
+       default 0x10000
+
+endif # ENV_IS_IN_SPI_FLASH
index c5475aa..1ee8ab1 100644 (file)
                u-boot,dm-spl;
        };
 
+       config {
+               u-boot,spl-payload-offset = <0x105000>; /* loader2 @1044KB */
+       };
+
        hfclk {
                u-boot,dm-spl;
        };
        clocks = <&rtcclk>;
 };
 
+&qspi0 {
+       u-boot,dm-spl;
+       flash@0 {
+               u-boot,dm-spl;
+       };
+};
+
 &spi0 {
        mmc@0 {
                u-boot,dm-spl;
index 89c4cf5..287ef3d 100644 (file)
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/* Copyright (c) 2020 Microchip Technology Inc */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2021 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
 
 /dts-v1/;
-#include "dt-bindings/clock/microchip-mpfs-clock.h"
+
+#include "microchip-mpfs.dtsi"
 
 /* Clock frequency (in Hz) of the rtcclk */
 #define RTCCLK_FREQ            1000000
 
 / {
-       #address-cells = <2>;
-       #size-cells = <2>;
-       model = "Microchip MPFS Icicle Kit";
-       compatible = "microchip,mpfs-icicle-kit";
+       model = "Microchip PolarFire-SoC Icicle Kit";
+       compatible = "microchip,mpfs-icicle-kit", "microchip,mpfs";
 
        aliases {
-               serial0 = &uart0;
-               ethernet0 = &emac1;
+               serial1 = &uart1;
+               ethernet0 = &mac1;
        };
 
        chosen {
-               stdout-path = "serial0";
+               stdout-path = "serial1";
        };
 
-       cpucomplex: cpus {
-               #address-cells = <1>;
-               #size-cells = <0>;
+       cpus {
                timebase-frequency = <RTCCLK_FREQ>;
-               cpu0: cpu@0 {
-                       clocks = <&clkcfg CLK_CPU>;
-                       compatible = "sifive,e51", "sifive,rocket0", "riscv";
-                       device_type = "cpu";
-                       i-cache-block-size = <64>;
-                       i-cache-sets = <128>;
-                       i-cache-size = <16384>;
-                       reg = <0>;
-                       riscv,isa = "rv64imac";
-                       status = "disabled";
-                       operating-points = <
-                               /* kHz  uV */
-                               600000  1100000
-                               300000   950000
-                               150000   750000
-                       >;
-                       cpu0intc: interrupt-controller {
-                               #interrupt-cells = <1>;
-                               compatible = "riscv,cpu-intc";
-                               interrupt-controller;
-                       };
-               };
-               cpu1: cpu@1 {
-                       clocks = <&clkcfg CLK_CPU>;
-                       compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
-                       d-cache-block-size = <64>;
-                       d-cache-sets = <64>;
-                       d-cache-size = <32768>;
-                       d-tlb-sets = <1>;
-                       d-tlb-size = <32>;
-                       device_type = "cpu";
-                       i-cache-block-size = <64>;
-                       i-cache-sets = <64>;
-                       i-cache-size = <32768>;
-                       i-tlb-sets = <1>;
-                       i-tlb-size = <32>;
-                       mmu-type = "riscv,sv39";
-                       reg = <1>;
-                       riscv,isa = "rv64imafdc";
-                       tlb-split;
-                       status = "okay";
-                       operating-points = <
-                               /* kHz  uV */
-                               600000  1100000
-                               300000   950000
-                               150000   750000
-                       >;
-                       cpu1intc: interrupt-controller {
-                               #interrupt-cells = <1>;
-                               compatible = "riscv,cpu-intc";
-                               interrupt-controller;
-                       };
-               };
-               cpu2: cpu@2 {
-                       clocks = <&clkcfg CLK_CPU>;
-                       compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
-                       d-cache-block-size = <64>;
-                       d-cache-sets = <64>;
-                       d-cache-size = <32768>;
-                       d-tlb-sets = <1>;
-                       d-tlb-size = <32>;
-                       device_type = "cpu";
-                       i-cache-block-size = <64>;
-                       i-cache-sets = <64>;
-                       i-cache-size = <32768>;
-                       i-tlb-sets = <1>;
-                       i-tlb-size = <32>;
-                       mmu-type = "riscv,sv39";
-                       reg = <2>;
-                       riscv,isa = "rv64imafdc";
-                       tlb-split;
-                       status = "okay";
-                       operating-points = <
-                               /* kHz  uV */
-                               600000  1100000
-                               300000   950000
-                               150000   750000
-                       >;
-                       cpu2intc: interrupt-controller {
-                               #interrupt-cells = <1>;
-                               compatible = "riscv,cpu-intc";
-                               interrupt-controller;
-                       };
+       };
+
+       reserved-memory {
+               ranges;
+               #size-cells = <2>;
+               #address-cells = <2>;
+
+               fabricbuf0: fabricbuf@0 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x0 0xae000000 0x0 0x2000000>;
+                       label = "fabricbuf0-ddr-c";
                };
-               cpu3: cpu@3 {
-                       clocks = <&clkcfg CLK_CPU>;
-                       compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
-                       d-cache-block-size = <64>;
-                       d-cache-sets = <64>;
-                       d-cache-size = <32768>;
-                       d-tlb-sets = <1>;
-                       d-tlb-size = <32>;
-                       device_type = "cpu";
-                       i-cache-block-size = <64>;
-                       i-cache-sets = <64>;
-                       i-cache-size = <32768>;
-                       i-tlb-sets = <1>;
-                       i-tlb-size = <32>;
-                       mmu-type = "riscv,sv39";
-                       reg = <3>;
-                       riscv,isa = "rv64imafdc";
-                       tlb-split;
-                       status = "okay";
-                       operating-points = <
-                               /* kHz  uV */
-                               600000  1100000
-                               300000   950000
-                               150000   750000
-                       >;
-                       cpu3intc: interrupt-controller {
-                               #interrupt-cells = <1>;
-                               compatible = "riscv,cpu-intc";
-                               interrupt-controller;
-                       };
+
+               fabricbuf1: fabricbuf@1 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x0 0xc0000000 0x0 0x8000000>;
+                       label = "fabricbuf1-ddr-nc";
                };
-               cpu4: cpu@4 {
-                       clocks = <&clkcfg CLK_CPU>;
-                       compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
-                       d-cache-block-size = <64>;
-                       d-cache-sets = <64>;
-                       d-cache-size = <32768>;
-                       d-tlb-sets = <1>;
-                       d-tlb-size = <32>;
-                       device_type = "cpu";
-                       i-cache-block-size = <64>;
-                       i-cache-sets = <64>;
-                       i-cache-size = <32768>;
-                       i-tlb-sets = <1>;
-                       i-tlb-size = <32>;
-                       mmu-type = "riscv,sv39";
-                       reg = <4>;
-                       riscv,isa = "rv64imafdc";
-                       tlb-split;
-                       status = "okay";
-                       operating-points = <
-                               /* kHz  uV */
-                               600000  1100000
-                               300000   950000
-                               150000   750000
-                       >;
-                       cpu4intc: interrupt-controller {
-                               #interrupt-cells = <1>;
-                               compatible = "riscv,cpu-intc";
-                               interrupt-controller;
-                       };
+
+               fabricbuf2: fabricbuf@2 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x0 0xd8000000 0x0 0x8000000>;
+                       label = "fabricbuf2-ddr-nc-wcb";
                };
        };
-       refclk: refclk {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <600000000>;
-               clock-output-names = "msspllclk";
+
+       udmabuf0 {
+               compatible = "ikwzm,u-dma-buf";
+               device-name = "udmabuf-ddr-c0";
+               minor-number = <0>;
+               size = <0x0 0x2000000>;
+               memory-region = <&fabricbuf0>;
+               sync-mode = <3>;
+       };
+
+       udmabuf1 {
+               compatible = "ikwzm,u-dma-buf";
+               device-name = "udmabuf-ddr-nc0";
+               minor-number = <1>;
+               size = <0x0 0x8000000>;
+               memory-region = <&fabricbuf1>;
+               sync-mode = <3>;
+       };
+
+       udmabuf2 {
+               compatible = "ikwzm,u-dma-buf";
+               device-name = "udmabuf-ddr-nc-wcb0";
+               minor-number = <2>;
+               size = <0x0 0x8000000>;
+               memory-region = <&fabricbuf2>;
+               sync-mode = <3>;
        };
-       ddr: memory@80000000 {
+
+       ddrc_cache_lo: memory@80000000 {
                device_type = "memory";
-               reg = <0x0 0x80000000 0x0 0x40000000>;
+               reg = <0x0 0x80000000 0x0 0x2e000000>;
                clocks = <&clkcfg CLK_DDRC>;
+               status = "okay";
        };
-       soc: soc {
-               #address-cells = <2>;
-               #size-cells = <2>;
-               compatible = "microchip,mpfs-icicle-kit", "simple-bus";
-               ranges;
-               clint0: clint@2000000 {
-                       compatible = "riscv,clint0";
-                       interrupts-extended = <&cpu0intc 3 &cpu0intc 7
-                                               &cpu1intc 3 &cpu1intc 7
-                                               &cpu2intc 3 &cpu2intc 7
-                                               &cpu3intc 3 &cpu3intc 7
-                                               &cpu4intc 3 &cpu4intc 7>;
-                       reg = <0x0 0x2000000 0x0 0x10000>;
-                       reg-names = "control";
-                       clock-frequency = <RTCCLK_FREQ>;
-               };
-               cachecontroller: cache-controller@2010000 {
-                       compatible = "sifive,fu540-c000-ccache", "cache";
-                       cache-block-size = <64>;
-                       cache-level = <2>;
-                       cache-sets = <1024>;
-                       cache-size = <2097152>;
-                       cache-unified;
-                       interrupt-parent = <&plic>;
-                       interrupts = <1 2 3>;
-                       reg = <0x0 0x2010000 0x0 0x1000>;
-               };
-               plic: interrupt-controller@c000000 {
-                       #interrupt-cells = <1>;
-                       compatible = "sifive,plic-1.0.0";
-                       reg = <0x0 0xc000000 0x0 0x4000000>;
-                       riscv,max-priority = <7>;
-                       riscv,ndev = <186>;
-                       interrupt-controller;
-                       interrupts-extended = <
-                               &cpu0intc 11
-                               &cpu1intc 11 &cpu1intc 9
-                               &cpu2intc 11 &cpu2intc 9
-                               &cpu3intc 11 &cpu3intc 9
-                               &cpu4intc 11 &cpu4intc 9>;
-               };
-               uart0: serial@20000000 {
-                       compatible = "ns16550a";
-                       reg = <0x0 0x20000000 0x0 0x400>;
-                       reg-io-width = <4>;
-                       reg-shift = <2>;
-                       interrupt-parent = <&plic>;
-                       interrupts = <90>;
-                       clocks = <&clkcfg CLK_MMUART0>;
-                       status = "okay";
-               };
-               clkcfg: clkcfg@20002000 {
-                       compatible = "microchip,mpfs-clkcfg";
-                       reg = <0x0 0x20002000 0x0 0x1000>;
-                       reg-names = "mss_sysreg";
-                       clocks = <&refclk>;
-                       #clock-cells = <1>;
-                       clock-output-names = "cpu", "axi", "ahb", "envm",
-                                       "mac0", "mac1", "mmc", "timer",
-                                       "mmuart0", "mmuart1", "mmuart2",
-                                       "mmuart3", "mmuart4", "spi0", "spi1",
-                                       "i2c0", "i2c1", "can0", "can1", "usb",
-                                       "reserved", "rtc", "qspi", "gpio0",
-                                       "gpio1", "gpio2", "ddrc", "fic0",
-                                       "fic1", "fic2", "fic3", "athena",
-                                       "cfm";
-               };
-               emmc: mmc@20008000 {
-                       compatible = "cdns,sd4hc";
-                       reg = <0x0 0x20008000 0x0 0x1000>;
-                       interrupt-parent = <&plic>;
-                       interrupts = <88 89>;
-                       pinctrl-names = "default";
-                       clocks = <&clkcfg CLK_MMC>;
-                       bus-width = <4>;
-                       cap-mmc-highspeed;
-                       mmc-ddr-3_3v;
-                       max-frequency = <200000000>;
-                       non-removable;
-                       no-sd;
-                       no-sdio;
-                       voltage-ranges = <3300 3300>;
-                       status = "okay";
-               };
-               sdcard: sd@20008000 {
-                       compatible = "cdns,sd4hc";
-                       reg = <0x0 0x20008000 0x0 0x1000>;
-                       interrupt-parent = <&plic>;
-                       interrupts = <88>;
-                       pinctrl-names = "default";
-                       clocks = <&clkcfg CLK_MMC>;
-                       bus-width = <4>;
-                       disable-wp;
-                       cap-sd-highspeed;
-                       card-detect-delay = <200>;
-                       sd-uhs-sdr12;
-                       sd-uhs-sdr25;
-                       sd-uhs-sdr50;
-                       sd-uhs-sdr104;
-                       max-frequency = <200000000>;
-                       status = "disabled";
-               };
-               uart1: serial@20100000 {
-                       compatible = "ns16550a";
-                       reg = <0x0 0x20100000 0x0 0x400>;
-                       reg-io-width = <4>;
-                       reg-shift = <2>;
-                       interrupt-parent = <&plic>;
-                       interrupts = <91>;
-                       clocks = <&clkcfg CLK_MMUART1>;
-                       status = "okay";
-               };
-               uart2: serial@20102000 {
-                       compatible = "ns16550a";
-                       reg = <0x0 0x20102000 0x0 0x400>;
-                       reg-io-width = <4>;
-                       reg-shift = <2>;
-                       interrupt-parent = <&plic>;
-                       interrupts = <92>;
-                       clocks = <&clkcfg CLK_MMUART2>;
-                       status = "okay";
-               };
-               uart3: serial@20104000 {
-                       compatible = "ns16550a";
-                       reg = <0x0 0x20104000 0x0 0x400>;
-                       reg-io-width = <4>;
-                       reg-shift = <2>;
-                       interrupt-parent = <&plic>;
-                       interrupts = <93>;
-                       clocks = <&clkcfg CLK_MMUART3>;
-                       status = "okay";
-               };
-               i2c0: i2c@2010a000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "microchip,mpfs-mss-i2c";
-                       reg = <0x0 0x2010a000 0x0 0x1000>;
-                       interrupt-parent = <&plic>;
-                       interrupts = <58>;
-                       clocks = <&clkcfg CLK_I2C0>;
-                       status = "disabled";
-               };
-               i2c1: i2c@2010b000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "microchip,mpfs-mss-i2c";
-                       reg = <0x0 0x2010b000 0x0 0x1000>;
-                       interrupt-parent = <&plic>;
-                       interrupts = <61>;
-                       clocks = <&clkcfg CLK_I2C1>;
-                       status = "disabled";
-                       pac193x@10 {
-                               compatible = "microchip,pac1934";
-                               reg = <0x10>;
-                               samp-rate = <64>;
-                               status = "disabled";
-                               ch1: channel0 {
-                                       uohms-shunt-res = <10000>;
-                                       rail-name = "VDD";
-                                       channel_enabled;
-                               };
-                               ch2: channel1 {
-                                       uohms-shunt-res = <10000>;
-                                       rail-name = "VDDA25";
-                                       channel_enabled;
-                               };
-                               ch3: channel2 {
-                                       uohms-shunt-res = <10000>;
-                                       rail-name = "VDD25";
-                                       channel_enabled;
-                               };
-                               ch4: channel3 {
-                                       uohms-shunt-res = <10000>;
-                                       rail-name = "VDDA";
-                                       channel_enabled;
-                               };
-                       };
-               };
-               emac0: ethernet@20110000 {
-                       compatible = "microchip,mpfs-mss-gem";
-                       reg = <0x0 0x20110000 0x0 0x2000>;
-                       interrupt-parent = <&plic>;
-                       interrupts = <64 65 66 67>;
-                       local-mac-address = [56 34 00 FC 00 02];
-                       phy-mode = "sgmii";
-                       clocks = <&clkcfg CLK_MAC0>, <&clkcfg CLK_AXI>;
-                       clock-names = "pclk", "hclk";
-                       status = "disabled";
 
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       phy-handle = <&phy0>;
-                       phy0: ethernet-phy@8 {
-                               reg = <8>;
-                               ti,fifo-depth = <0x01>;
-                       };
-               };
-               emac1: ethernet@20112000 {
-                       compatible = "microchip,mpfs-mss-gem";
-                       reg = <0x0 0x20112000 0x0 0x2000>;
-                       interrupt-parent = <&plic>;
-                       interrupts = <70 71 72 73>;
-                       local-mac-address = [00 00 00 00 00 00];
-                       phy-mode = "sgmii";
-                       clocks = <&clkcfg CLK_MAC1>, <&clkcfg CLK_AHB>;
-                       clock-names = "pclk", "hclk";
-                       status = "okay";
+       ddrc_cache_hi: memory@1000000000 {
+               device_type = "memory";
+               reg = <0x10 0x0 0x0 0x40000000>;
+               clocks = <&clkcfg CLK_DDRC>;
+               status = "okay";
+       };
+};
 
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       phy-handle = <&phy1>;
-                       phy1: ethernet-phy@9 {
-                               reg = <9>;
-                               ti,fifo-depth = <0x01>;
-                       };
-               };
-               gpio: gpio@20122000 {
-                       compatible = "microchip,mpfs-mss-gpio";
-                       interrupt-parent = <&plic>;
-                       interrupts = <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>;
-                       gpio-controller;
-                       clocks = <&clkcfg CLK_GPIO2>;
-                       reg = <0x00 0x20122000 0x0 0x1000>;
-                       reg-names = "control";
-                       #gpio-cells = <2>;
-                       status = "disabled";
+&uart1 {
+       status = "okay";
+};
+
+&mmc {
+       status = "okay";
+
+       bus-width = <4>;
+       disable-wp;
+       cap-mmc-highspeed;
+       cap-sd-highspeed;
+       card-detect-delay = <200>;
+       mmc-ddr-1_8v;
+       mmc-hs200-1_8v;
+       sd-uhs-sdr12;
+       sd-uhs-sdr25;
+       sd-uhs-sdr50;
+       sd-uhs-sdr104;
+};
+
+&i2c1 {
+       status = "okay";
+       clock-frequency = <100000>;
+
+       pac193x: pac193x@10 {
+               compatible = "microchip,pac1934";
+               reg = <0x10>;
+               samp-rate = <64>;
+               status = "okay";
+               ch1: channel0 {
+                       uohms-shunt-res = <10000>;
+                       rail-name = "VDDREG";
+                       channel_enabled;
+               };
+               ch2: channel1 {
+                       uohms-shunt-res = <10000>;
+                       rail-name = "VDDA25";
+                       channel_enabled;
+               };
+               ch3: channel2 {
+                       uohms-shunt-res = <10000>;
+                       rail-name = "VDD25";
+                       channel_enabled;
+               };
+               ch4: channel3 {
+                       uohms-shunt-res = <10000>;
+                       rail-name = "VDDA_REG";
+                       channel_enabled;
                };
        };
 };
+
+&mac1 {
+       status = "okay";
+       phy-mode = "sgmii";
+       phy-handle = <&phy1>;
+       phy1: ethernet-phy@9 {
+               reg = <9>;
+               ti,fifo-depth = <0x1>;
+       };
+};
diff --git a/arch/riscv/dts/microchip-mpfs.dtsi b/arch/riscv/dts/microchip-mpfs.dtsi
new file mode 100644 (file)
index 0000000..4f449a3
--- /dev/null
@@ -0,0 +1,571 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/* Copyright (c) 2020-2021 Microchip Technology Inc */
+
+#include "dt-bindings/clock/microchip-mpfs-clock.h"
+#include "dt-bindings/interrupt-controller/microchip-mpfs-plic.h"
+#include "dt-bindings/interrupt-controller/riscv-hart.h"
+
+/ {
+       #address-cells = <2>;
+       #size-cells = <2>;
+       model = "Microchip PolarFire SoC";
+       compatible = "microchip,mpfs";
+
+       chosen {
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       compatible = "sifive,e51", "sifive,rocket0", "riscv";
+                       device_type = "cpu";
+                       i-cache-block-size = <64>;
+                       i-cache-sets = <128>;
+                       i-cache-size = <16384>;
+                       reg = <0>;
+                       riscv,isa = "rv64imac";
+                       clocks = <&clkcfg CLK_CPU>;
+                       status = "disabled";
+                       operating-points = <
+                               /* kHz  uV */
+                               600000  1100000
+                               300000   950000
+                               150000   750000
+                       >;
+                       cpu0_intc: interrupt-controller {
+                               #interrupt-cells = <1>;
+                               compatible = "riscv,cpu-intc";
+                               interrupt-controller;
+                       };
+               };
+
+               cpu1: cpu@1 {
+                       compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
+                       d-cache-block-size = <64>;
+                       d-cache-sets = <64>;
+                       d-cache-size = <32768>;
+                       d-tlb-sets = <1>;
+                       d-tlb-size = <32>;
+                       device_type = "cpu";
+                       i-cache-block-size = <64>;
+                       i-cache-sets = <64>;
+                       i-cache-size = <32768>;
+                       i-tlb-sets = <1>;
+                       i-tlb-size = <32>;
+                       mmu-type = "riscv,sv39";
+                       reg = <1>;
+                       riscv,isa = "rv64imafdc";
+                       clocks = <&clkcfg CLK_CPU>;
+                       tlb-split;
+                       status = "okay";
+                       operating-points = <
+                               /* kHz  uV */
+                               600000  1100000
+                               300000   950000
+                               150000   750000
+                       >;
+                       cpu1_intc: interrupt-controller {
+                               #interrupt-cells = <1>;
+                               compatible = "riscv,cpu-intc";
+                               interrupt-controller;
+                       };
+               };
+
+               cpu2: cpu@2 {
+                       compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
+                       d-cache-block-size = <64>;
+                       d-cache-sets = <64>;
+                       d-cache-size = <32768>;
+                       d-tlb-sets = <1>;
+                       d-tlb-size = <32>;
+                       device_type = "cpu";
+                       i-cache-block-size = <64>;
+                       i-cache-sets = <64>;
+                       i-cache-size = <32768>;
+                       i-tlb-sets = <1>;
+                       i-tlb-size = <32>;
+                       mmu-type = "riscv,sv39";
+                       reg = <2>;
+                       riscv,isa = "rv64imafdc";
+                       clocks = <&clkcfg CLK_CPU>;
+                       tlb-split;
+                       status = "okay";
+                       operating-points = <
+                               /* kHz  uV */
+                               600000  1100000
+                               300000   950000
+                               150000   750000
+                       >;
+                       cpu2_intc: interrupt-controller {
+                               #interrupt-cells = <1>;
+                               compatible = "riscv,cpu-intc";
+                               interrupt-controller;
+                       };
+               };
+
+               cpu3: cpu@3 {
+                       compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
+                       d-cache-block-size = <64>;
+                       d-cache-sets = <64>;
+                       d-cache-size = <32768>;
+                       d-tlb-sets = <1>;
+                       d-tlb-size = <32>;
+                       device_type = "cpu";
+                       i-cache-block-size = <64>;
+                       i-cache-sets = <64>;
+                       i-cache-size = <32768>;
+                       i-tlb-sets = <1>;
+                       i-tlb-size = <32>;
+                       mmu-type = "riscv,sv39";
+                       reg = <3>;
+                       riscv,isa = "rv64imafdc";
+                       clocks = <&clkcfg CLK_CPU>;
+                       tlb-split;
+                       status = "okay";
+                       operating-points = <
+                               /* kHz  uV */
+                               600000  1100000
+                               300000   950000
+                               150000   750000
+                       >;
+                       cpu3_intc: interrupt-controller {
+                               #interrupt-cells = <1>;
+                               compatible = "riscv,cpu-intc";
+                               interrupt-controller;
+                       };
+               };
+
+               cpu4: cpu@4 {
+                       compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
+                       d-cache-block-size = <64>;
+                       d-cache-sets = <64>;
+                       d-cache-size = <32768>;
+                       d-tlb-sets = <1>;
+                       d-tlb-size = <32>;
+                       device_type = "cpu";
+                       i-cache-block-size = <64>;
+                       i-cache-sets = <64>;
+                       i-cache-size = <32768>;
+                       i-tlb-sets = <1>;
+                       i-tlb-size = <32>;
+                       mmu-type = "riscv,sv39";
+                       reg = <4>;
+                       riscv,isa = "rv64imafdc";
+                       clocks = <&clkcfg CLK_CPU>;
+                       tlb-split;
+                       status = "okay";
+                       operating-points = <
+                               /* kHz  uV */
+                               600000  1100000
+                               300000   950000
+                               150000   750000
+                       >;
+                       cpu4_intc: interrupt-controller {
+                               #interrupt-cells = <1>;
+                               compatible = "riscv,cpu-intc";
+                               interrupt-controller;
+                       };
+               };
+       };
+
+       soc {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               compatible = "microchip,mpfs-soc", "simple-bus";
+               ranges;
+
+               clint: clint@2000000 {
+                       compatible = "sifive,clint0";
+                       reg = <0x0 0x2000000 0x0 0xC000>;
+                       interrupts-extended =
+                                       <&cpu0_intc HART_INT_M_SOFT &cpu0_intc HART_INT_M_TIMER
+                                        &cpu1_intc HART_INT_M_SOFT &cpu1_intc HART_INT_M_TIMER
+                                        &cpu2_intc HART_INT_M_SOFT &cpu2_intc HART_INT_M_TIMER
+                                        &cpu3_intc HART_INT_M_SOFT &cpu3_intc HART_INT_M_TIMER
+                                        &cpu4_intc HART_INT_M_SOFT &cpu4_intc HART_INT_M_TIMER>;
+               };
+
+               cachecontroller: cache-controller@2010000 {
+                       compatible = "sifive,fu540-c000-ccache", "cache";
+                       reg = <0x0 0x2010000 0x0 0x1000>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_L2_METADATA_CORR
+                               PLIC_INT_L2_METADATA_UNCORR
+                               PLIC_INT_L2_DATA_CORR>;
+                       cache-block-size = <64>;
+                       cache-level = <2>;
+                       cache-sets = <1024>;
+                       cache-size = <2097152>;
+                       cache-unified;
+               };
+
+               pdma: pdma@3000000 {
+                       compatible = "microchip,mpfs-pdma-uio","sifive,fu540-c000-pdma";
+                       reg = <0x0 0x3000000 0x0 0x8000>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_DMA_CH0_DONE PLIC_INT_DMA_CH0_ERR
+                               PLIC_INT_DMA_CH1_DONE PLIC_INT_DMA_CH1_ERR
+                               PLIC_INT_DMA_CH2_DONE PLIC_INT_DMA_CH2_ERR
+                               PLIC_INT_DMA_CH3_DONE PLIC_INT_DMA_CH3_ERR>;
+                       #dma-cells = <1>;
+               };
+
+               plic: interrupt-controller@c000000 {
+                       compatible = "sifive,plic-1.0.0";
+                       reg = <0x0 0xc000000 0x0 0x4000000>;
+                       #interrupt-cells = <1>;
+                       riscv,ndev = <186>;
+                       interrupt-controller;
+                       interrupts-extended = <&cpu0_intc HART_INT_M_EXT
+                                       &cpu1_intc HART_INT_M_EXT &cpu1_intc HART_INT_S_EXT
+                                       &cpu2_intc HART_INT_M_EXT &cpu2_intc HART_INT_S_EXT
+                                       &cpu3_intc HART_INT_M_EXT &cpu3_intc HART_INT_S_EXT
+                                       &cpu4_intc HART_INT_M_EXT &cpu4_intc HART_INT_S_EXT>;
+               };
+
+               refclk: refclk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <600000000>;
+                       clock-output-names = "msspllclk";
+               };
+
+               clkcfg: clkcfg@20002000 {
+                       compatible = "microchip,mpfs-clkcfg";
+                       reg = <0x0 0x20002000 0x0 0x1000>;
+                       reg-names = "mss_sysreg";
+                       clocks = <&refclk>;
+                       #clock-cells = <1>;
+                       clock-output-names = "cpu", "axi", "ahb", "envm",       /* 0-3   */
+                               "mac0", "mac1", "mmc", "timer",                         /* 4-7   */
+                               "mmuart0", "mmuart1", "mmuart2", "mmuart3",     /* 8-11  */
+                               "mmuart4", "spi0", "spi1", "i2c0",                      /* 12-15 */
+                               "i2c1", "can0", "can1", "usb",                          /* 16-19 */
+                               "rsvd", "rtc", "qspi", "gpio0",                         /* 20-23 */
+                               "gpio1", "gpio2", "ddrc", "fic0",                       /* 24-27 */
+                               "fic1", "fic2", "fic3", "athena", "cfm";        /* 28-32 */
+               };
+
+               /* Common node entry for eMMC/SD */
+               mmc: mmc@20008000 {
+                       compatible = "microchip,mpfs-sd4hc","cdns,sd4hc";
+                       reg = <0x0 0x20008000 0x0 0x1000>;
+                       clocks = <&clkcfg CLK_MMC>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_MMC_MAIN PLIC_INT_MMC_WAKEUP>;
+                       max-frequency = <200000000>;
+                       status = "disabled";
+               };
+
+               uart0: serial@20000000 {
+                       compatible = "ns16550a";
+                       reg = <0x0 0x20000000 0x0 0x400>;
+                       reg-io-width = <4>;
+                       reg-shift = <2>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_MMUART0>;
+                       clocks = <&clkcfg CLK_MMUART0>;
+                       status = "disabled"; /* Reserved for the HSS */
+               };
+
+               uart1: serial@20100000 {
+                       compatible = "ns16550a";
+                       reg = <0x0 0x20100000 0x0 0x400>;
+                       reg-io-width = <4>;
+                       reg-shift = <2>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_MMUART1>;
+                       clocks = <&clkcfg CLK_MMUART1>;
+                       status = "disabled";
+               };
+
+               uart2: serial@20102000 {
+                       compatible = "ns16550a";
+                       reg = <0x0 0x20102000 0x0 0x400>;
+                       reg-io-width = <4>;
+                       reg-shift = <2>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_MMUART2>;
+                       clocks = <&clkcfg CLK_MMUART2>;
+                       status = "disabled";
+               };
+
+               uart3: serial@20104000 {
+                       compatible = "ns16550a";
+                       reg = <0x0 0x20104000 0x0 0x400>;
+                       reg-io-width = <4>;
+                       reg-shift = <2>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_MMUART3>;
+                       clocks = <&clkcfg CLK_MMUART3>;
+                       status = "disabled";
+               };
+
+               uart4: serial@20106000 {
+                       compatible = "ns16550a";
+                       reg = <0x0 0x20106000 0x0 0x400>;
+                       reg-io-width = <4>;
+                       reg-shift = <2>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_MMUART4>;
+                       clocks = <&clkcfg CLK_MMUART4>;
+                       status = "disabled";
+               };
+
+               spi0: spi@20108000 {
+                       compatible = "microchip,mpfs-spi";
+                       reg = <0x0 0x20108000 0x0 0x1000>;
+                       clocks = <&clkcfg CLK_SPI0>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_SPI0>;
+                       num-cs = <8>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               spi1: spi@20109000 {
+                       compatible = "microchip,mpfs-spi";
+                       reg = <0x0 0x20109000 0x0 0x1000>;
+                       clocks = <&clkcfg CLK_SPI1>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_SPI1>;
+                       num-cs = <8>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c0: i2c@2010a000 {
+                       compatible = "microchip,mpfs-i2c";
+                       reg = <0x0 0x2010a000 0x0 0x1000>;
+                       clocks = <&clkcfg CLK_I2C0>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_I2C0_MAIN>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c1: i2c@2010b000 {
+                       compatible = "microchip,mpfs-i2c";
+                       reg = <0x0 0x2010b000 0x0 0x1000>;
+                       clocks = <&clkcfg CLK_I2C1>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_I2C1_MAIN>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               can0: can@2010c000 {
+                       compatible = "microchip,mpfs-can-uio";
+                       reg = <0x0 0x2010c000 0x0 0x1000>;
+                       clocks = <&clkcfg CLK_CAN0>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_CAN0>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               can1: can@2010d000 {
+                       compatible = "microchip,mpfs-can-uio";
+                       reg = <0x0 0x2010d000 0x0 0x1000>;
+                       clocks = <&clkcfg CLK_CAN1>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_CAN1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               mac0: ethernet@20110000 {
+                       compatible = "cdns,macb";
+                       reg = <0x0 0x20110000 0x0 0x2000>;
+                       clocks = <&clkcfg CLK_MAC0>, <&clkcfg CLK_AHB>;
+                       clock-names = "pclk", "hclk";
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_MAC0_INT
+                               PLIC_INT_MAC0_QUEUE1
+                               PLIC_INT_MAC0_QUEUE2
+                               PLIC_INT_MAC0_QUEUE3
+                               PLIC_INT_MAC0_EMAC
+                               PLIC_INT_MAC0_MMSL>;
+                       local-mac-address = [00 00 00 00 00 00];
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               mac1: ethernet@20112000 {
+                       compatible = "cdns,macb";
+                       reg = <0x0 0x20112000 0x0 0x2000>;
+                       clocks = <&clkcfg CLK_MAC1>, <&clkcfg CLK_AHB>;
+                       clock-names = "pclk", "hclk";
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_MAC1_INT
+                               PLIC_INT_MAC1_QUEUE1
+                               PLIC_INT_MAC1_QUEUE2
+                               PLIC_INT_MAC1_QUEUE3
+                               PLIC_INT_MAC1_EMAC
+                               PLIC_INT_MAC1_MMSL>;
+                       local-mac-address = [00 00 00 00 00 00];
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               gpio0: gpio@20120000 {
+                       compatible = "microchip,mpfs-gpio";
+                       reg = <0x0 0x20120000 0x0 0x1000>;
+                       reg-names = "control";
+                       clocks = <&clkcfg CLK_GPIO0>;
+                       interrupt-parent = <&plic>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       status = "disabled";
+               };
+
+               gpio1: gpio@20121000 {
+                       compatible = "microchip,mpfs-gpio";
+                       reg = <000 0x20121000 0x0 0x1000>;
+                       reg-names = "control";
+                       clocks = <&clkcfg CLK_GPIO1>;
+                       interrupt-parent = <&plic>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       status = "disabled";
+               };
+
+               gpio2: gpio@20122000 {
+                       compatible = "microchip,mpfs-gpio";
+                       reg = <0x0 0x20122000 0x0 0x1000>;
+                       reg-names = "control";
+                       clocks = <&clkcfg CLK_GPIO2>;
+                       interrupt-parent = <&plic>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       status = "disabled";
+               };
+
+               rtc: rtc@20124000 {
+                       compatible = "microchip,mpfs-rtc";
+                       reg = <0x0 0x20124000 0x0 0x1000>;
+                       clocks = <&clkcfg CLK_RTC>;
+                       clock-names = "rtc";
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_RTC_WAKEUP PLIC_INT_RTC_MATCH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               usb: usb@20201000 {
+                       compatible = "microchip,mpfs-usb-host";
+                       reg = <0x0 0x20201000 0x0 0x1000>;
+                       reg-names = "mc","control";
+                       clocks = <&clkcfg CLK_USB>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_USB_DMA PLIC_INT_USB_MC>;
+                       interrupt-names = "dma","mc";
+                       dr_mode = "host";
+                       status = "disabled";
+               };
+
+               qspi: qspi@21000000 {
+                       compatible = "microchip,mpfs-qspi";
+                       reg = <0x0 0x21000000 0x0 0x1000>;
+                       clocks = <&clkcfg CLK_QSPI>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_QSPI>;
+                       num-cs = <8>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               mbox: mailbox@37020000 {
+                       compatible = "microchip,mpfs-mailbox";
+                       reg = <0x0 0x37020000 0x0 0x1000>, <0x0 0x2000318C 0x0 0x40>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_G5C_MESSAGE>;
+                       #mbox-cells = <1>;
+                       status = "disabled";
+               };
+
+               pcie: pcie@2000000000 {
+                       compatible = "microchip,pcie-host-1.0";
+                       #address-cells = <0x3>;
+                       #interrupt-cells = <0x1>;
+                       #size-cells = <0x2>;
+                       device_type = "pci";
+                       reg = <0x20 0x0 0x0 0x8000000 0x0 0x43000000 0x0 0x10000>;
+                       reg-names = "cfg", "apb";
+                       clocks = <&clkcfg CLK_FIC0>, <&clkcfg CLK_FIC1>, <&clkcfg CLK_FIC3>;
+                       clock-names = "fic0", "fic1", "fic3";
+                       bus-range = <0x0 0x7f>;
+                       interrupt-parent = <&plic>;
+                       interrupts = <PLIC_INT_FABRIC_F2H_2>;
+                       interrupt-map = <0 0 0 1 &pcie_intc 0>,
+                                       <0 0 0 2 &pcie_intc 1>,
+                                       <0 0 0 3 &pcie_intc 2>,
+                                       <0 0 0 4 &pcie_intc 3>;
+                       interrupt-map-mask = <0 0 0 7>;
+                       ranges = <0x3000000 0x0 0x8000000 0x20 0x8000000 0x0 0x80000000>;
+                       msi-parent = <&pcie>;
+                       msi-controller;
+                       mchp,axi-m-atr0 = <0x10 0x0>;
+                       status = "disabled";
+                       pcie_intc: legacy-interrupt-controller {
+                               #address-cells = <0>;
+                               #interrupt-cells = <1>;
+                               interrupt-controller;
+                       };
+               };
+
+               syscontroller: syscontroller {
+                       compatible = "microchip,mpfs-sys-controller";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       mboxes = <&mbox 0>;
+               };
+
+               hwrandom: hwrandom {
+                       compatible = "microchip,mpfs-rng";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       syscontroller = <&syscontroller>;
+               };
+
+               serialnum: serialnum {
+                       compatible = "microchip,mpfs-serial-number";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       syscontroller = <&syscontroller>;
+               };
+
+               fpgadigest: fpgadigest {
+                       compatible = "microchip,mpfs-digest";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       syscontroller = <&syscontroller>;
+               };
+
+               devicecert: cert {
+                       compatible = "microchip,mpfs-device-cert";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       syscontroller = <&syscontroller>;
+               };
+
+               signature: signature {
+                       compatible = "microchip,mpfs-signature";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       syscontroller = <&syscontroller>;
+               };
+       };
+};
index 8cd688e..2cea4a4 100644 (file)
                compatible = "sandbox,clk-ccf";
        };
 
+       efi-media {
+               compatible = "sandbox,efi-media";
+       };
+
        eth@10002000 {
                compatible = "sandbox,eth";
                reg = <0x10002000 0x1000>;
index 36c596e..ae24d14 100644 (file)
@@ -43,6 +43,23 @@ DECLARE_GLOBAL_DATA_PTR;
 #define OMNIA_I2C_EEPROM_CHIP_LEN      2
 #define OMNIA_I2C_EEPROM_MAGIC         0x0341a034
 
+#define SYS_RSTOUT_MASK                        MVEBU_REGISTER(0x18260)
+#define   SYS_RSTOUT_MASK_WD           BIT(10)
+
+#define A385_WDT_GLOBAL_CTRL           MVEBU_REGISTER(0x20300)
+#define   A385_WDT_GLOBAL_RATIO_MASK   GENMASK(18, 16)
+#define   A385_WDT_GLOBAL_RATIO_SHIFT  16
+#define   A385_WDT_GLOBAL_25MHZ                BIT(10)
+#define   A385_WDT_GLOBAL_ENABLE       BIT(8)
+
+#define A385_WDT_GLOBAL_STATUS         MVEBU_REGISTER(0x20304)
+#define   A385_WDT_GLOBAL_EXPIRED      BIT(31)
+
+#define A385_WDT_DURATION              MVEBU_REGISTER(0x20334)
+
+#define A385_WD_RSTOUT_UNMASK          MVEBU_REGISTER(0x20704)
+#define   A385_WD_RSTOUT_UNMASK_GLOBAL BIT(8)
+
 enum mcu_commands {
        CMD_GET_STATUS_WORD     = 0x01,
        CMD_GET_RESET           = 0x09,
@@ -141,6 +158,47 @@ static int omnia_mcu_write(u8 cmd, const void *buf, int len)
        return dm_i2c_write(chip, cmd, buf, len);
 }
 
+static void enable_a385_watchdog(unsigned int timeout_minutes)
+{
+       struct sar_freq_modes sar_freq;
+       u32 watchdog_freq;
+
+       printf("Enabling A385 watchdog with %u minutes timeout...\n",
+              timeout_minutes);
+
+       /*
+        * Use NBCLK clock (a.k.a. L2 clock) as watchdog input clock with
+        * its maximal ratio 7 instead of default fixed 25 MHz clock.
+        * It allows to set watchdog duration up to the 22 minutes.
+        */
+       clrsetbits_32(A385_WDT_GLOBAL_CTRL,
+                     A385_WDT_GLOBAL_25MHZ | A385_WDT_GLOBAL_RATIO_MASK,
+                     7 << A385_WDT_GLOBAL_RATIO_SHIFT);
+
+       /*
+        * Calculate watchdog clock frequency. It is defined by formula:
+        *   freq = NBCLK / 2 / (2 ^ ratio)
+        * We set ratio to the maximal possible value 7.
+        */
+       get_sar_freq(&sar_freq);
+       watchdog_freq = sar_freq.nb_clk * 1000000 / 2 / (1 << 7);
+
+       /* Set watchdog duration */
+       writel(timeout_minutes * 60 * watchdog_freq, A385_WDT_DURATION);
+
+       /* Clear the watchdog expiration bit */
+       clrbits_32(A385_WDT_GLOBAL_STATUS, A385_WDT_GLOBAL_EXPIRED);
+
+       /* Enable watchdog timer */
+       setbits_32(A385_WDT_GLOBAL_CTRL, A385_WDT_GLOBAL_ENABLE);
+
+       /* Enable reset on watchdog */
+       setbits_32(A385_WD_RSTOUT_UNMASK, A385_WD_RSTOUT_UNMASK_GLOBAL);
+
+       /* Unmask reset for watchdog */
+       clrbits_32(SYS_RSTOUT_MASK, SYS_RSTOUT_MASK_WD);
+}
+
 static bool disable_mcu_watchdog(void)
 {
        int ret;
@@ -423,10 +481,13 @@ void spl_board_init(void)
 {
        /*
         * If booting from UART, disable MCU watchdog in SPL, since uploading
-        * U-Boot proper can take too much time and trigger it.
+        * U-Boot proper can take too much time and trigger it. Instead enable
+        * A385 watchdog with very high timeout (10 minutes) to prevent hangup.
         */
-       if (get_boot_device() == BOOT_DEVICE_UART)
+       if (get_boot_device() == BOOT_DEVICE_UART) {
+               enable_a385_watchdog(10);
                disable_mcu_watchdog();
+       }
 }
 
 int board_init(void)
index 77c4057..f8042bb 100644 (file)
@@ -4,3 +4,13 @@ S:     Maintained
 F:     board/beacon/beacon-rzg2m/
 F:     include/configs/beacon-rzg2m.h
 F:     configs/rzg2_beacon_defconfig
+F:     arch/arm/dts/beacon-renesom-baseboard.dtsi
+F:     arch/arm/dts/beacon-renesom-som.dtsi
+F:     arch/arm/dts/r8a774a1-beacon-rzg2m-kit.dts
+F:     arch/arm/dts/r8a774b1-beacon-rzg2n-kit.dts
+F:     arch/arm/dts/r8a774e1-beacon-rzg2h-kit.dts
+F:     arch/arm/dts/r8a774a1-beacon-rzg2m-kit-u-boot.dtsi
+F:     arch/arm/dts/r8a774b1-beacon-rzg2n-kit-u-boot.dtsi
+F:     arch/arm/dts/r8a774e1-beacon-rzg2h-kit-u-boot.dtsi
+F:     arch/arm/dts/rz-g2-beacon-u-boot.dtsi
+
index a8402e2..f44afb0 100644 (file)
@@ -212,34 +212,40 @@ static void board_get_coding_straps(void)
        ofnode node;
        int i, ret;
 
+       brdcode = 0;
+       ddr3code = 0;
+       somcode = 0;
+
        node = ofnode_path("/config");
        if (!ofnode_valid(node)) {
                printf("%s: no /config node?\n", __func__);
                return;
        }
 
-       brdcode = 0;
-       ddr3code = 0;
-       somcode = 0;
-
        ret = gpio_request_list_by_name_nodev(node, "dh,som-coding-gpios",
                                              gpio, ARRAY_SIZE(gpio),
                                              GPIOD_IS_IN);
        for (i = 0; i < ret; i++)
                somcode |= !!dm_gpio_get_value(&(gpio[i])) << i;
 
+       gpio_free_list_nodev(gpio, ret);
+
        ret = gpio_request_list_by_name_nodev(node, "dh,ddr3-coding-gpios",
                                              gpio, ARRAY_SIZE(gpio),
                                              GPIOD_IS_IN);
        for (i = 0; i < ret; i++)
                ddr3code |= !!dm_gpio_get_value(&(gpio[i])) << i;
 
+       gpio_free_list_nodev(gpio, ret);
+
        ret = gpio_request_list_by_name_nodev(node, "dh,board-coding-gpios",
                                              gpio, ARRAY_SIZE(gpio),
                                              GPIOD_IS_IN);
        for (i = 0; i < ret; i++)
                brdcode |= !!dm_gpio_get_value(&(gpio[i])) << i;
 
+       gpio_free_list_nodev(gpio, ret);
+
        printf("Code:  SoM:rev=%d,ddr3=%d Board:rev=%d\n",
                somcode, ddr3code, brdcode);
 }
index 4678462..092e411 100644 (file)
@@ -45,5 +45,10 @@ config BOARD_SPECIFIC_OPTIONS # dummy
        imply MMC_WRITE
        imply MMC_SDHCI
        imply MMC_SDHCI_CADENCE
+       imply MMC_SDHCI_ADMA
+       imply MMC_HS200_SUPPORT
+       imply CMD_I2C
+       imply DM_I2C
+       imply SYS_I2C_MICROCHIP
 
 endif
index afef719..e74c9fb 100644 (file)
@@ -119,7 +119,22 @@ int board_late_init(void)
                if (icicle_mac_addr[idx] == ':')
                        icicle_mac_addr[idx] = ' ';
        }
-       env_set("icicle_mac_addr", icicle_mac_addr);
+       env_set("icicle_mac_addr0", icicle_mac_addr);
+
+       mac_addr[5] = device_serial_number[0] + 1;
+
+       icicle_mac_addr[0] = '[';
+
+       sprintf(&icicle_mac_addr[1], "%pM", mac_addr);
+
+       icicle_mac_addr[18] = ']';
+       icicle_mac_addr[19] = '\0';
+
+       for (idx = 0; idx < 20; idx++) {
+               if (icicle_mac_addr[idx] == ':')
+                       icicle_mac_addr[idx] = ' ';
+       }
+       env_set("icicle_mac_addr1", icicle_mac_addr);
 
        return 0;
 }
index fb2c1fb..fe213fd 100644 (file)
@@ -26,6 +26,7 @@ config SPL_OPENSBI_LOAD_ADDR
 config BOARD_SPECIFIC_OPTIONS # dummy
        def_bool y
        select SIFIVE_FU740
+       select ENV_IS_IN_SPI_FLASH
        select SUPPORT_SPL
        select RESET_SIFIVE
        select BINMAN
index d566327..7c0beed 100644 (file)
@@ -22,6 +22,7 @@
 #define GEM_PHY_RESET  SIFIVE_GENERIC_GPIO_NR(0, 12)
 
 #define MODE_SELECT_REG                0x1000
+#define MODE_SELECT_SPI                0x6
 #define MODE_SELECT_SD         0xb
 #define MODE_SELECT_MASK       GENMASK(3, 0)
 
@@ -123,6 +124,8 @@ u32 spl_boot_device(void)
        u32 boot_device = mode_select & MODE_SELECT_MASK;
 
        switch (boot_device) {
+       case MODE_SELECT_SPI:
+               return BOOT_DEVICE_SPI;
        case MODE_SELECT_SD:
                return BOOT_DEVICE_MMC1;
        default:
index 4f5747c..fdbcd40 100644 (file)
@@ -698,13 +698,7 @@ int g_dnl_board_usb_cable_connected(void)
                return ret;
        }
 
-       ret = sun4i_usb_phy_vbus_detect(&phy);
-       if (ret == 1) {
-               pr_err("A charger is plugged into the OTG\n");
-               return -ENODEV;
-       }
-
-       return ret;
+       return sun4i_usb_phy_vbus_detect(&phy);
 }
 #endif
 
index daae911..4ea5f9f 100644 (file)
@@ -151,7 +151,8 @@ static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc,
 
        data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0);
 
-       rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, data, &updates);
+       rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, TPM2_ALG_SHA256,
+                          data, TPM2_DIGEST_LEN, &updates);
        if (!rc) {
                printf("PCR #%u content (%u known updates):\n", index, updates);
                print_byte_string(data, TPM2_DIGEST_LEN);
index 54458b7..e51afc1 100644 (file)
@@ -6,7 +6,6 @@ CONFIG_DEFAULT_DEVICE_TREE="microchip-mpfs-icicle-kit"
 CONFIG_TARGET_MICROCHIP_ICICLE=y
 CONFIG_ARCH_RV64I=y
 CONFIG_RISCV_SMODE=y
-CONFIG_SBI_V01=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_SYS_LOAD_ADDR=0x80200000
 CONFIG_FIT=y
index 83d7ae5..e8a6f75 100644 (file)
@@ -23,6 +23,7 @@ CONFIG_CMD_DFU=y
 CONFIG_CMD_MTD=y
 CONFIG_CMD_PCI=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_TPM=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_OF_BOARD=y
 CONFIG_ENV_IS_IN_FLASH=y
index ab55748..b459305 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_CMD_DFU=y
 CONFIG_CMD_MTD=y
 CONFIG_CMD_PCI=y
 CONFIG_CMD_USB=y
+CONFIG_CMD_TPM=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_OF_BOARD=y
 CONFIG_ENV_IS_IN_FLASH=y
index b9bbc20..6c48c3b 100644 (file)
@@ -39,7 +39,6 @@ CONFIG_MULTI_DTB_FIT_LZO=y
 CONFIG_MULTI_DTB_FIT_USER_DEFINED_AREA=y
 CONFIG_ENV_OVERWRITE=y
 CONFIG_ENV_IS_IN_MMC=y
-CONFIG_SYS_MMC_ENV_DEV=1
 CONFIG_SYS_MMC_ENV_PART=2
 CONFIG_VERSION_VARIABLE=y
 CONFIG_REGMAP=y
index 9cc18b0..d400ed0 100644 (file)
@@ -8,6 +8,7 @@ CONFIG_SPL_DM_SPI=y
 CONFIG_DEFAULT_DEVICE_TREE="hifive-unmatched-a00"
 CONFIG_SPL_MMC=y
 CONFIG_SPL=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
 CONFIG_SPL_SPI=y
 CONFIG_AHCI=y
 CONFIG_TARGET_SIFIVE_UNMATCHED=y
@@ -23,17 +24,22 @@ CONFIG_DISPLAY_BOARDINFO=y
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_ID_EEPROM=y
 CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_SPL_DM_RESET=y
+CONFIG_SPL_SPI_LOAD=y
 CONFIG_CMD_EEPROM=y
 CONFIG_CMD_MEMINFO=y
 CONFIG_CMD_PWM=y
 CONFIG_CMD_GPT_RENAME=y
 CONFIG_CMD_PCI=y
 CONFIG_CMD_USB=y
+CONFIG_USE_ENV_SPI_BUS=y
+CONFIG_ENV_SPI_BUS=1
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_SCSI_AHCI=y
 CONFIG_AHCI_PCI=y
 CONFIG_SPL_CLK=y
+CONFIG_SPI_FLASH_ISSI=y
 CONFIG_SYS_I2C_EEPROM_ADDR=0x54
 CONFIG_E1000=y
 CONFIG_NVME=y
index aa000ef..2356de7 100644 (file)
@@ -108,6 +108,8 @@ CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY_MICREL=y
+CONFIG_PHY_MICREL_KSZ90X1=y
 CONFIG_DM_ETH=y
 CONFIG_DWC_ETH_QOS=y
 CONFIG_PHY=y
index fe1ebd4..e857a9f 100644 (file)
@@ -296,8 +296,11 @@ static void print_part_header(const char *type, struct blk_desc *dev_desc)
        case IF_TYPE_VIRTIO:
                puts("VirtIO");
                break;
+       case IF_TYPE_EFI_MEDIA:
+               puts("EFI");
+               break;
        default:
-               puts ("UNKNOWN");
+               puts("UNKNOWN");
                break;
        }
        printf (" device %d  --   Partition Type: %s\n\n",
index 584ef0a..7c24e29 100644 (file)
@@ -65,7 +65,8 @@ can be enabled with the following command line parameters:
 
 - To add a Serial ATA disk via an Intel ICH9 AHCI controller, pass e.g.::
 
-    -drive if=none,file=disk.img,id=mydisk -device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0
+    -drive if=none,file=disk.img,format=raw,id=mydisk \
+    -device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0
 
 - To add an Intel E1000 network adapter, pass e.g.::
 
@@ -75,10 +76,14 @@ can be enabled with the following command line parameters:
 
     -device usb-ehci,id=ehci
 
-- To add a NVMe disk, pass e.g.::
+- To add an NVMe disk, pass e.g.::
 
     -drive if=none,file=disk.img,id=mydisk -device nvme,drive=mydisk,serial=foo
 
+- To add a random number generator, pass e.g.::
+
+    -device virtio-rng-pci
+
 These have been tested in QEMU 2.9.0 but should work in at least 2.5.0 as well.
 
 Enabling TPMv2 support
index c71c2f3..a4b10c6 100644 (file)
@@ -20,6 +20,7 @@ The support for following drivers are already enabled:
 2. Microchip Clock Driver.
 3. Cadence MACB ethernet driver for networking support.
 4. Cadence MMC Driver for eMMC/SD support.
+5. Microchip I2C Driver.
 
 Booting from eMMC using HSS
 ---------------------------
@@ -214,7 +215,8 @@ GPT partition.
 Booting
 ~~~~~~~
 
-You should see the U-Boot prompt on UART0.
+You should see the U-Boot prompt on UART1.
+(Note: UART0 is reserved for HSS)
 
 Sample boot log from MPFS Icicle Kit
 ''''''''''''''''''''''''''''''''''''
@@ -451,7 +453,8 @@ copied payload and Linux image.
 
     sudo dd if=<payload_binary> of=/dev/sdX2 bs=512
 
-You should see the U-Boot prompt on UART0.
+You should see the U-Boot prompt on UART1.
+(Note: UART0 is reserved for HSS)
 
 GUID type
 ~~~~~~~~~
index 6b024f0..b52a1f6 100644 (file)
@@ -534,3 +534,34 @@ Sample boot log from HiFive Unmatched board
        OpenEmbedded nodistro.0 unmatched ttySIF0
 
        unmatched login:
+
+
+Booting from SPI
+----------------
+
+Use Building steps from "Booting from uSD using U-Boot SPL" section.
+
+Partition the SPI in Linux via mtdblock.  The partition types here are
+"HiFive Unleashed FSBL", "HiFive Unleashed BBL", and "U-Boot environment"
+for partitions one through three respectively.
+
+.. code-block:: none
+
+       sgdisk --clear -a 1 \
+           --new=1:40:2087     --change-name=1:spl   --typecode=1:5B193300-FC78-40CD-8002-E86C45580B47 \
+           --new=2:2088:10279  --change-name=2:uboot --typecode=2:2E54B353-1271-4842-806F-E436D6AF6985 \
+           --new=3:10280:10535 --change-name=3:env   --typecode=3:3DE21764-95BD-54BD-A5C3-4ABE786F38A8 \
+           /dev/mtdblock0
+
+Write U-boot SPL and U-boot to their partitions.
+
+.. code-block:: none
+
+       dd if=u-boot-spl.bin of=/dev/mtdblock0 bs=4096 seek=5 conv=sync
+       dd if=u-boot.itb  of=/dev/mtdblock0 bs=4096 seek=261 conv=sync
+
+Power off the board.
+
+Change DIP switches MSEL[3:0] to 0110.
+
+Power up the board.
index f17138f..a3e2656 100644 (file)
@@ -620,12 +620,12 @@ EFI_DRIVER_BINDING_PROTOCOL implementation for the UEFI drivers.
 
 A linker created list is used to keep track of the UEFI drivers. To create an
 entry in the list the UEFI driver uses the U_BOOT_DRIVER macro specifying
-UCLASS_EFI as the ID of its uclass, e.g::
+UCLASS_EFI_LOADER as the ID of its uclass, e.g::
 
     /* Identify as UEFI driver */
     U_BOOT_DRIVER(efi_block) = {
         .name  = "EFI block driver",
-        .id    = UCLASS_EFI,
+        .id    = UCLASS_EFI_LOADER,
         .ops   = &driver_ops,
     };
 
@@ -651,8 +651,8 @@ UEFI block IO driver
 The UEFI block IO driver supports devices exposing the EFI_BLOCK_IO_PROTOCOL.
 
 When connected it creates a new U-Boot block IO device with interface type
-IF_TYPE_EFI, adds child controllers mapping the partitions, and installs the
-EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on these. This can be used together with the
+IF_TYPE_EFI_LOADER, adds child controllers mapping the partitions, and installs
+the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on these. This can be used together with the
 software iPXE to boot from iSCSI network drives [4].
 
 This driver is only available if U-Boot is configured with::
index ea39713..7f113ed 100644 (file)
@@ -102,7 +102,7 @@ Manually Loading and Applying Overlays
 
 ::
 
-    => fdtaddr $fdtaddr
+    => fdt addr $fdtaddr
 
 4. Grow it enough so it can encompass all applied overlays
 
index 56a4eec..8235430 100644 (file)
@@ -61,6 +61,39 @@ config TPL_BLOCK_CACHE
        help
          This option enables the disk-block cache in TPL
 
+config EFI_MEDIA
+       bool "Support EFI media drivers"
+       default y if EFI || SANDBOX
+       help
+         Enable this to support media devices on top of UEFI. This enables
+         just the uclass so you also need a specific driver to make this do
+         anything.
+
+         For sandbox there is a test driver.
+
+if EFI_MEDIA
+
+config EFI_MEDIA_SANDBOX
+       bool "Sandbox EFI media driver"
+       depends on SANDBOX
+       default y
+       help
+         Enables a simple sandbox media driver, used for testing just the
+         EFI_MEDIA uclass. It does not do anything useful, since sandbox does
+         not actually support running on top of UEFI.
+
+config EFI_MEDIA_BLK
+       bool "EFI media block driver"
+       depends on EFI_APP
+       default y
+       help
+         Enables a block driver for providing access to UEFI devices. This
+         allows use of block devices detected by the underlying UEFI
+         implementation. With this it is possible to use filesystems on these
+         devices, for example.
+
+endif  # EFI_MEDIA
+
 config IDE
        bool "Support IDE controllers"
        select HAVE_BLOCK_DEVICE
index 94ab5c6..b221a7c 100644 (file)
@@ -14,3 +14,7 @@ obj-$(CONFIG_IDE) += ide.o
 endif
 obj-$(CONFIG_SANDBOX) += sandbox.o
 obj-$(CONFIG_$(SPL_TPL_)BLOCK_CACHE) += blkcache.o
+
+obj-$(CONFIG_EFI_MEDIA) += efi-media-uclass.o
+obj-$(CONFIG_EFI_MEDIA_SANDBOX) += sb_efi_media.o
+obj-$(CONFIG_EFI_MEDIA_BLK) += efi_blk.o
index 83682dc..4ae8af6 100644 (file)
@@ -28,7 +28,8 @@ static const char *if_typename_str[IF_TYPE_COUNT] = {
        [IF_TYPE_SATA]          = "sata",
        [IF_TYPE_HOST]          = "host",
        [IF_TYPE_NVME]          = "nvme",
-       [IF_TYPE_EFI]           = "efi",
+       [IF_TYPE_EFI_MEDIA]     = "efi",
+       [IF_TYPE_EFI_LOADER]    = "efiloader",
        [IF_TYPE_VIRTIO]        = "virtio",
        [IF_TYPE_PVBLOCK]       = "pvblock",
 };
@@ -44,7 +45,8 @@ static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
        [IF_TYPE_SATA]          = UCLASS_AHCI,
        [IF_TYPE_HOST]          = UCLASS_ROOT,
        [IF_TYPE_NVME]          = UCLASS_NVME,
-       [IF_TYPE_EFI]           = UCLASS_EFI,
+       [IF_TYPE_EFI_MEDIA]     = UCLASS_EFI_MEDIA,
+       [IF_TYPE_EFI_LOADER]    = UCLASS_EFI_LOADER,
        [IF_TYPE_VIRTIO]        = UCLASS_VIRTIO,
        [IF_TYPE_PVBLOCK]       = UCLASS_PVBLOCK,
 };
diff --git a/drivers/block/efi-media-uclass.c b/drivers/block/efi-media-uclass.c
new file mode 100644 (file)
index 0000000..e012f6f
--- /dev/null
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Uclass for EFI media devices
+ *
+ * Copyright 2021 Google LLC
+ */
+
+#include <common.h>
+#include <dm.h>
+
+UCLASS_DRIVER(efi_media) = {
+       .id             = UCLASS_EFI_MEDIA,
+       .name           = "efi_media",
+       .flags          = DM_UC_FLAG_SEQ_ALIAS,
+};
diff --git a/drivers/block/efi_blk.c b/drivers/block/efi_blk.c
new file mode 100644 (file)
index 0000000..9d25ecb
--- /dev/null
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Block driver for EFI devices
+ * This supports a media driver of UCLASS_EFI with a child UCLASS_BLK
+ * It allows block-level access to EFI devices made available via EFI boot
+ * services
+ *
+ * Copyright 2021 Google LLC
+ */
+
+#include <common.h>
+#include <blk.h>
+#include <dm.h>
+#include <efi.h>
+#include <efi_api.h>
+
+struct efi_block_plat {
+       struct efi_block_io *blkio;
+};
+
+/**
+ * Read from block device
+ *
+ * @dev:       device
+ * @blknr:     first block to be read
+ * @blkcnt:    number of blocks to read
+ * @buffer:    output buffer
+ * Return:     number of blocks transferred
+ */
+static ulong efi_bl_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+                        void *buffer)
+{
+       struct efi_block_plat *plat = dev_get_plat(dev);
+       struct efi_block_io *io = plat->blkio;
+       efi_status_t ret;
+
+       log_debug("read buf=%p, block=%lx, count=%lx: ", buffer, (ulong)blknr,
+                 (ulong)blkcnt);
+       ret = io->read_blocks(io, io->media->media_id, blknr,
+                             blkcnt * io->media->block_size, buffer);
+       log_debug("ret=%lx (dec %ld)\n", ret & ~EFI_ERROR_MASK,
+                 ret & ~EFI_ERROR_MASK);
+       if (ret)
+               return 0;
+
+       return blkcnt;
+}
+
+/**
+ * Write to block device
+ *
+ * @dev:       device
+ * @blknr:     first block to be write
+ * @blkcnt:    number of blocks to write
+ * @buffer:    input buffer
+ * Return:     number of blocks transferred
+ */
+static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+                         const void *buffer)
+{
+       struct efi_block_plat *plat = dev_get_plat(dev);
+       struct efi_block_io *io = plat->blkio;
+       efi_status_t ret;
+
+       log_debug("write buf=%p, block=%lx, count=%lx: ", buffer, (ulong)blknr,
+                 (ulong)blkcnt);
+       ret = io->write_blocks(io, io->media->media_id, blknr,
+                              blkcnt * io->media->block_size, (void *)buffer);
+       log_debug("ret=%lx (dec %ld)\n", ret & ~EFI_ERROR_MASK,
+                 ret & ~EFI_ERROR_MASK);
+       if (ret)
+               return 0;
+
+       return blkcnt;
+}
+
+/* Block device driver operators */
+static const struct blk_ops efi_blk_ops = {
+       .read   = efi_bl_read,
+       .write  = efi_bl_write,
+};
+
+U_BOOT_DRIVER(efi_block) = {
+       .name           = "efi_block",
+       .id             = UCLASS_BLK,
+       .ops            = &efi_blk_ops,
+       .plat_auto      = sizeof(struct efi_block_plat),
+};
+
+static int efi_media_bind(struct udevice *dev)
+{
+       struct efi_media_plat *plat = dev_get_plat(dev);
+       struct efi_block_plat *blk_plat;
+       struct udevice *blk;
+       int ret;
+
+       ret = blk_create_devicef(dev, "efi_block", "blk", IF_TYPE_EFI_MEDIA,
+                                dev_seq(dev), plat->blkio->media->block_size,
+                                plat->blkio->media->last_block, &blk);
+       if (ret) {
+               debug("Cannot create block device\n");
+               return ret;
+       }
+       blk_plat = dev_get_plat(blk);
+       blk_plat->blkio = plat->blkio;
+
+       return 0;
+}
+
+U_BOOT_DRIVER(efi_media) = {
+       .name           = "efi_media",
+       .id             = UCLASS_EFI_MEDIA,
+       .bind           = efi_media_bind,
+       .plat_auto      = sizeof(struct efi_media_plat),
+};
diff --git a/drivers/block/sb_efi_media.c b/drivers/block/sb_efi_media.c
new file mode 100644 (file)
index 0000000..52af155
--- /dev/null
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * EFI_MEDIA driver for sandbox
+ *
+ * Copyright 2021 Google LLC
+ */
+
+#include <common.h>
+#include <dm.h>
+
+static const struct udevice_id sandbox_efi_media_ids[] = {
+       { .compatible = "sandbox,efi-media" },
+       { }
+};
+
+U_BOOT_DRIVER(sandbox_efi_media) = {
+       .name           = "sandbox_efi_media",
+       .id             = UCLASS_EFI_MEDIA,
+       .of_match       = sandbox_efi_media_ids,
+};
index 7c447a8..5482a4a 100644 (file)
@@ -250,6 +250,12 @@ config SYS_I2C_MESON
          internal buffer holding up to 8 bytes for transfers and supports
          both 7-bit and 10-bit addresses.
 
+config SYS_I2C_MICROCHIP
+       bool "Microchip I2C driver"
+       help
+         Add support for the Microchip I2C driver. This is operating on
+         standard mode up to 100 kbits/s and fast mode up to 400 kbits/s.
+
 config SYS_I2C_MXC
        bool "NXP MXC I2C driver"
        help
index fca6b15..9d41f37 100644 (file)
@@ -28,6 +28,7 @@ obj-$(CONFIG_SYS_I2C_IPROC) += iproc_i2c.o
 obj-$(CONFIG_SYS_I2C_KONA) += kona_i2c.o
 obj-$(CONFIG_SYS_I2C_LPC32XX) += lpc32xx_i2c.o
 obj-$(CONFIG_SYS_I2C_MESON) += meson_i2c.o
+obj-$(CONFIG_SYS_I2C_MICROCHIP) += i2c-microchip.o
 obj-$(CONFIG_SYS_I2C_MV) += mv_i2c.o
 obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o
 obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o
diff --git a/drivers/i2c/i2c-microchip.c b/drivers/i2c/i2c-microchip.c
new file mode 100644 (file)
index 0000000..12f65d0
--- /dev/null
@@ -0,0 +1,482 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Microchip I2C controller driver
+ *
+ * Copyright (C) 2021 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <i2c.h>
+#include <asm/io.h>
+#include <dm/device_compat.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+
+#define        MICROCHIP_I2C_TIMEOUT   (1000 * 60)
+
+#define MPFS_I2C_CTRL  (0x00)
+#define        CTRL_CR0                (0x00)
+#define        CTRL_CR1                (0x01)
+#define        CTRL_AA                 BIT(2)
+#define        CTRL_SI                 BIT(3)
+#define        CTRL_STO                BIT(4)
+#define        CTRL_STA                BIT(5)
+#define        CTRL_ENS1               BIT(6)
+#define        CTRL_CR2                (0x07)
+#define MPFS_I2C_STATUS                                                        (0x04)
+#define        STATUS_BUS_ERROR                                                (0x00)
+#define        STATUS_M_START_SENT                                             (0x08)
+#define        STATUS_M_REPEATED_START_SENT                    (0x10)
+#define        STATUS_M_SLAW_ACK                                               (0x18)
+#define        STATUS_M_SLAW_NACK                                              (0x20)
+#define        STATUS_M_TX_DATA_ACK                                    (0x28)
+#define        STATUS_M_TX_DATA_NACK                                   (0x30)
+#define        STATUS_M_ARB_LOST                                               (0x38)
+#define        STATUS_M_SLAR_ACK                                               (0x40)
+#define        STATUS_M_SLAR_NACK                                              (0x48)
+#define        STATUS_M_RX_DATA_ACKED                                  (0x50)
+#define        STATUS_M_RX_DATA_NACKED                                 (0x58)
+#define        STATUS_S_SLAW_ACKED                                             (0x60)
+#define        STATUS_S_ARB_LOST_SLAW_ACKED                    (0x68)
+#define        STATUS_S_GENERAL_CALL_ACKED                             (0x70)
+#define        STATUS_S_ARB_LOST_GENERAL_CALL_ACKED    (0x78)
+#define        STATUS_S_RX_DATA_ACKED                                  (0x80)
+#define        STATUS_S_RX_DATA_NACKED                                 (0x88)
+#define        STATUS_S_GENERAL_CALL_RX_DATA_ACKED             (0x90)
+#define        STATUS_S_GENERAL_CALL_RX_DATA_NACKED    (0x98)
+#define        STATUS_S_RX_STOP                                                (0xA0)
+#define        STATUS_S_SLAR_ACKED                                             (0xA8)
+#define        STATUS_S_ARB_LOST_SLAR_ACKED                    (0xB0)
+#define        STATUS_S_TX_DATA_ACK                                    (0xb8)
+#define        STATUS_S_TX_DATA_NACK                                   (0xC0)
+#define        STATUS_LAST_DATA_ACK                                    (0xC8)
+#define        STATUS_M_SMB_MASTER_RESET                               (0xD0)
+#define        STATUS_S_SCL_LOW_TIMEOUT                                (0xD8)
+#define        STATUS_NO_STATE_INFO                                    (0xF8)
+#define MPFS_I2C_DATA                  (0x08)
+#define MPFS_I2C_SLAVE0_ADDR   (0x0c)
+#define MPFS_I2C_SMBUS                 (0x10)
+#define MPFS_I2C_FREQ                  (0x14)
+#define MPFS_I2C_GLITCHREG             (0x18)
+#define MPFS_I2C_SLAVE1_ADDR   (0x1c)
+
+#define PCLK_DIV_256   ((0 << CTRL_CR0) | (0 << CTRL_CR1) | (0 << CTRL_CR2))
+#define PCLK_DIV_224   ((1 << CTRL_CR0) | (0 << CTRL_CR1) | (0 << CTRL_CR2))
+#define PCLK_DIV_192   ((0 << CTRL_CR0) | (1 << CTRL_CR1) | (0 << CTRL_CR2))
+#define PCLK_DIV_160   ((1 << CTRL_CR0) | (1 << CTRL_CR1) | (0 << CTRL_CR2))
+#define PCLK_DIV_960   ((0 << CTRL_CR0) | (0 << CTRL_CR1) | (1 << CTRL_CR2))
+#define PCLK_DIV_120   ((1 << CTRL_CR0) | (0 << CTRL_CR1) | (1 << CTRL_CR2))
+#define PCLK_DIV_60            ((0 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2))
+#define BCLK_DIV_8             ((1 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2))
+#define CLK_MASK               ((1 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2))
+
+/*
+ * mpfs_i2c_bus - I2C bus context
+ * @base: pointer to register struct
+ * @msg_len: number of bytes transferred in msg
+ * @msg_err: error code for completed message
+ * @i2c_clk: clock reference for i2c input clock
+ * @clk_rate: current i2c bus clock rate
+ * @buf: ptr to msg buffer for easier use.
+ * @addr: i2c address.
+ * @isr_status: cached copy of local ISR status.
+ */
+struct mpfs_i2c_bus {
+       void __iomem *base;
+       size_t msg_len;
+       int msg_err;
+       struct clk i2c_clk;
+       u32 clk_rate;
+       u8 *buf;
+       u8 addr;
+       u32 isr_status;
+};
+
+static inline u8 i2c_8bit_addr_from_msg(const struct i2c_msg *msg)
+{
+       return (msg->addr << 1) | (msg->flags & I2C_M_RD ? 1 : 0);
+}
+
+static void mpfs_i2c_int_clear(struct mpfs_i2c_bus *bus)
+{
+       u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
+
+       ctrl &= ~CTRL_SI;
+       writel(ctrl, bus->base + MPFS_I2C_CTRL);
+}
+
+static void mpfs_i2c_core_disable(struct mpfs_i2c_bus *bus)
+{
+       u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
+
+       ctrl &= ~CTRL_ENS1;
+       writel(ctrl, bus->base + MPFS_I2C_CTRL);
+}
+
+static void mpfs_i2c_core_enable(struct mpfs_i2c_bus *bus)
+{
+       u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
+
+       ctrl |= CTRL_ENS1;
+       writel(ctrl, bus->base + MPFS_I2C_CTRL);
+}
+
+static void mpfs_i2c_reset(struct mpfs_i2c_bus *bus)
+{
+       mpfs_i2c_core_disable(bus);
+       mpfs_i2c_core_enable(bus);
+}
+
+static inline void mpfs_i2c_stop(struct mpfs_i2c_bus *bus)
+{
+       u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
+
+       ctrl |= CTRL_STO;
+       writel(ctrl, bus->base + MPFS_I2C_CTRL);
+}
+
+static inline int mpfs_generate_divisor(u32 rate, u8 *code)
+{
+       int ret = 0;
+
+       if (rate >= 960)
+               *code = PCLK_DIV_960;
+       else if (rate >= 256)
+               *code = PCLK_DIV_256;
+       else if (rate >= 224)
+               *code = PCLK_DIV_224;
+       else if (rate >= 192)
+               *code = PCLK_DIV_192;
+       else if (rate >= 160)
+               *code = PCLK_DIV_160;
+       else if (rate >= 120)
+               *code = PCLK_DIV_120;
+       else if (rate >= 60)
+               *code = PCLK_DIV_60;
+       else if (rate >= 8)
+               *code = BCLK_DIV_8;
+       else
+               ret = -EINVAL;
+
+       return ret;
+}
+
+static int mpfs_i2c_init(struct mpfs_i2c_bus *bus, struct udevice *dev)
+{
+       u32 clk_rate, divisor;
+       u8 clkval, ctrl;
+       int ret;
+
+       ret = clk_get_by_index(dev, 0, &bus->i2c_clk);
+       if (ret)
+               return -EINVAL;
+
+       ret = clk_enable(&bus->i2c_clk);
+       if (ret)
+               return ret;
+
+       clk_rate = clk_get_rate(&bus->i2c_clk);
+       if (!clk_rate)
+               return -EINVAL;
+
+       clk_free(&bus->i2c_clk);
+
+       divisor = clk_rate / bus->clk_rate;
+
+       ctrl = readl(bus->base + MPFS_I2C_CTRL);
+
+       ctrl &= ~CLK_MASK;
+
+       ret = mpfs_generate_divisor(divisor, &clkval);
+       if (ret)
+               return -EINVAL;
+
+       ctrl |= clkval;
+
+       writel(ctrl, bus->base + MPFS_I2C_CTRL);
+
+       ctrl = readl(bus->base + MPFS_I2C_CTRL);
+
+       /* Reset I2C core */
+       mpfs_i2c_reset(bus);
+
+       return 0;
+}
+
+static void mpfs_i2c_transfer(struct mpfs_i2c_bus *bus, u32 data)
+{
+       if (bus->msg_len > 0)
+               writel(data, bus->base + MPFS_I2C_DATA);
+}
+
+static void mpfs_i2c_empty_rx(struct mpfs_i2c_bus *bus)
+{
+       u8 ctrl;
+       u8 data_read;
+
+       if (bus->msg_len > 0) {
+               data_read = readl(bus->base + MPFS_I2C_DATA);
+               *bus->buf++ = data_read;
+               bus->msg_len--;
+       }
+
+       if (bus->msg_len == 0) {
+               ctrl = readl(bus->base + MPFS_I2C_CTRL);
+               ctrl &= ~CTRL_AA;
+               writel(ctrl, bus->base + MPFS_I2C_CTRL);
+       }
+}
+
+static int mpfs_i2c_fill_tx(struct mpfs_i2c_bus *bus)
+{
+       mpfs_i2c_transfer(bus, *bus->buf++);
+       bus->msg_len--;
+
+       return 0;
+}
+
+static int mpfs_i2c_service_handler(struct mpfs_i2c_bus *bus)
+{
+       bool finish = false;
+       u32 status;
+       u8 ctrl;
+
+       status = bus->isr_status;
+
+       switch (status) {
+       case STATUS_M_START_SENT:
+       case STATUS_M_REPEATED_START_SENT:
+               ctrl = readl(bus->base + MPFS_I2C_CTRL);
+               ctrl &= ~CTRL_STA;
+               writel(bus->addr, bus->base + MPFS_I2C_DATA);
+               writel(ctrl, bus->base + MPFS_I2C_CTRL);
+               break;
+       case STATUS_M_SLAW_ACK:
+       case STATUS_M_TX_DATA_ACK:
+               if (bus->msg_len > 0) {
+                       mpfs_i2c_fill_tx(bus);
+               } else {
+                       /* On the last byte to be transmitted, send STOP */
+                       mpfs_i2c_stop(bus);
+                       finish = true;
+               }
+               break;
+       case STATUS_M_SLAR_ACK:
+               ctrl = readl(bus->base + MPFS_I2C_CTRL);
+               ctrl |= CTRL_AA;
+               writel(ctrl, bus->base + MPFS_I2C_CTRL);
+               if (bus->msg_len == 0) {
+                       /* On the last byte to be transmitted, send STOP */
+                       mpfs_i2c_stop(bus);
+                       finish = true;
+               }
+               break;
+       case STATUS_M_RX_DATA_ACKED:
+               mpfs_i2c_empty_rx(bus);
+               if (bus->msg_len == 0) {
+                       /* On the last byte to be transmitted, send STOP */
+                       mpfs_i2c_stop(bus);
+                       finish = true;
+               }
+               break;
+       case STATUS_M_TX_DATA_NACK:
+       case STATUS_M_RX_DATA_NACKED:
+       case STATUS_M_SLAR_NACK:
+       case STATUS_M_SLAW_NACK:
+               bus->msg_err = -ENXIO;
+               mpfs_i2c_stop(bus);
+               finish = true;
+               break;
+
+       case STATUS_M_ARB_LOST:
+               /* Handle Lost Arbitration */
+               bus->msg_err = -EAGAIN;
+               finish = true;
+               break;
+       default:
+               break;
+       }
+
+       if (finish) {
+               ctrl = readl(bus->base + MPFS_I2C_CTRL);
+               ctrl &= ~CTRL_AA;
+               writel(ctrl, bus->base + MPFS_I2C_CTRL);
+               return 0;
+       }
+
+       return 1;
+}
+
+static int mpfs_i2c_service(struct mpfs_i2c_bus *bus)
+{
+       int ret = 0;
+       int si_bit;
+
+       si_bit = readl(bus->base + MPFS_I2C_CTRL);
+       if (si_bit & CTRL_SI) {
+               bus->isr_status = readl(bus->base + MPFS_I2C_STATUS);
+               ret = mpfs_i2c_service_handler(bus);
+       }
+       /* Clear the si flag */
+       mpfs_i2c_int_clear(bus);
+       si_bit = readl(bus->base + MPFS_I2C_CTRL);
+
+       return ret;
+}
+
+static int mpfs_i2c_check_service_change(struct mpfs_i2c_bus *bus)
+{
+       u8 ctrl;
+       u32 count = 0;
+
+       while (1) {
+               ctrl = readl(bus->base + MPFS_I2C_CTRL);
+               if (ctrl & CTRL_SI)
+                       break;
+               udelay(1);
+               count += 1;
+               if (count == MICROCHIP_I2C_TIMEOUT)
+                       return -ETIMEDOUT;
+       }
+       return 0;
+}
+
+static int mpfs_i2c_poll_device(struct mpfs_i2c_bus *bus)
+{
+       int ret;
+
+       while (1) {
+               ret = mpfs_i2c_check_service_change(bus);
+               if (ret)
+                       return ret;
+
+               ret = mpfs_i2c_service(bus);
+               if (!ret)
+                       /* all messages have been transferred */
+                       return ret;
+       }
+}
+
+static int mpfs_i2c_xfer_msg(struct mpfs_i2c_bus *bus, struct i2c_msg *msg)
+{
+       u8 ctrl;
+       int ret;
+
+       if (!msg->len || !msg->buf)
+               return -EINVAL;
+
+       bus->addr = i2c_8bit_addr_from_msg(msg);
+       bus->msg_len = msg->len;
+       bus->buf = msg->buf;
+       bus->msg_err = 0;
+
+       mpfs_i2c_core_enable(bus);
+
+       ctrl = readl(bus->base + MPFS_I2C_CTRL);
+
+       ctrl |= CTRL_STA;
+
+       writel(ctrl, bus->base + MPFS_I2C_CTRL);
+
+       ret = mpfs_i2c_poll_device(bus);
+       if (ret)
+               return ret;
+
+       return bus->msg_err;
+}
+
+static int mpfs_i2c_xfer(struct udevice *dev, struct i2c_msg *msgs, int num_msgs)
+{
+       struct mpfs_i2c_bus *bus = dev_get_priv(dev);
+       int idx, ret;
+
+       if (!msgs || !num_msgs)
+               return -EINVAL;
+
+       for (idx = 0; idx < num_msgs; idx++) {
+               ret = mpfs_i2c_xfer_msg(bus, msgs++);
+               if (ret)
+                       return ret;
+       }
+
+       return ret;
+}
+
+static int mpfs_i2c_probe_chip(struct udevice *dev, uint addr, uint flags)
+{
+       struct mpfs_i2c_bus *bus = dev_get_priv(dev);
+       int ret;
+       u8 ctrl, reg = 0;
+
+       /*
+        * Send the chip address and verify that the
+        * address was <ACK>ed.
+        */
+       bus->addr = addr << 1 | I2C_M_RD;
+       bus->buf = &reg;
+       bus->msg_len = 0;
+       bus->msg_err = 0;
+
+       mpfs_i2c_core_enable(bus);
+
+       ctrl = readl(bus->base + MPFS_I2C_CTRL);
+
+       ctrl |= CTRL_STA;
+
+       writel(ctrl, bus->base + MPFS_I2C_CTRL);
+
+       ret = mpfs_i2c_poll_device(bus);
+       if (ret)
+               return ret;
+
+       return bus->msg_err;
+}
+
+static int mpfs_i2c_probe(struct udevice *dev)
+{
+       int ret;
+       u32 val;
+       struct mpfs_i2c_bus *bus = dev_get_priv(dev);
+
+       bus->base = dev_read_addr_ptr(dev);
+       if (!bus->base)
+               return -EINVAL;
+
+       val = dev_read_u32(dev, "clock-frequency", &bus->clk_rate);
+       if (val) {
+               printf("Default to 100kHz\n");
+               /* default clock rate */
+               bus->clk_rate = 100000;
+       }
+
+       if (bus->clk_rate > 400000 || bus->clk_rate <= 0) {
+               printf("Invalid clock-frequency %d\n", bus->clk_rate);
+               return -EINVAL;
+       }
+
+       ret = mpfs_i2c_init(bus, dev);
+
+       return ret;
+}
+
+static const struct dm_i2c_ops mpfs_i2c_ops = {
+       .xfer = mpfs_i2c_xfer,
+       .probe_chip = mpfs_i2c_probe_chip,
+};
+
+static const struct udevice_id mpfs_i2c_ids[] = {
+       {.compatible = "microchip,mpfs-i2c"},
+       {}
+};
+
+U_BOOT_DRIVER(mpfs_i2c) = {
+       .name = "mpfs_i2c",
+       .id = UCLASS_I2C,
+       .of_match = mpfs_i2c_ids,
+       .ops = &mpfs_i2c_ops,
+       .probe = mpfs_i2c_probe,
+       .priv_auto = sizeof(struct mpfs_i2c_bus),
+};
index 5851018..22dad5b 100644 (file)
@@ -1045,16 +1045,10 @@ static int eqos_start(struct udevice *dev)
        eqos->tx_desc_idx = 0;
        eqos->rx_desc_idx = 0;
 
-       ret = eqos->config->ops->eqos_start_clks(dev);
-       if (ret < 0) {
-               pr_err("eqos_start_clks() failed: %d", ret);
-               goto err;
-       }
-
        ret = eqos->config->ops->eqos_start_resets(dev);
        if (ret < 0) {
                pr_err("eqos_start_resets() failed: %d", ret);
-               goto err_stop_clks;
+               goto err;
        }
 
        udelay(10);
@@ -1360,8 +1354,6 @@ err_shutdown_phy:
        phy_shutdown(eqos->phy);
 err_stop_resets:
        eqos->config->ops->eqos_stop_resets(dev);
-err_stop_clks:
-       eqos->config->ops->eqos_stop_clks(dev);
 err:
        pr_err("FAILED: %d", ret);
        return ret;
@@ -1416,7 +1408,6 @@ static void eqos_stop(struct udevice *dev)
                phy_shutdown(eqos->phy);
        }
        eqos->config->ops->eqos_stop_resets(dev);
-       eqos->config->ops->eqos_stop_clks(dev);
 
        debug("%s: OK\n", __func__);
 }
@@ -1862,6 +1853,12 @@ static int eqos_probe(struct udevice *dev)
                goto err_remove_resources_core;
        }
 
+       ret = eqos->config->ops->eqos_start_clks(dev);
+       if (ret < 0) {
+               pr_err("eqos_start_clks() failed: %d", ret);
+               goto err_remove_resources_tegra;
+       }
+
 #ifdef CONFIG_DM_ETH_PHY
        eqos->mii = eth_phy_get_mdio_bus(dev);
 #endif
@@ -1870,7 +1867,7 @@ static int eqos_probe(struct udevice *dev)
                if (!eqos->mii) {
                        pr_err("mdio_alloc() failed");
                        ret = -ENOMEM;
-                       goto err_remove_resources_tegra;
+                       goto err_stop_clks;
                }
                eqos->mii->read = eqos_mdio_read;
                eqos->mii->write = eqos_mdio_write;
@@ -1893,6 +1890,8 @@ static int eqos_probe(struct udevice *dev)
 
 err_free_mdio:
        mdio_free(eqos->mii);
+err_stop_clks:
+       eqos->config->ops->eqos_stop_clks(dev);
 err_remove_resources_tegra:
        eqos->config->ops->eqos_remove_resources(dev);
 err_remove_resources_core:
@@ -1910,6 +1909,7 @@ static int eqos_remove(struct udevice *dev)
 
        mdio_unregister(eqos->mii);
        mdio_free(eqos->mii);
+       eqos->config->ops->eqos_stop_clks(dev);
        eqos->config->ops->eqos_remove_resources(dev);
 
        eqos_probe_resources_core(dev);
index c04bab9..a9b358e 100644 (file)
@@ -138,7 +138,7 @@ static int eth_phy_of_to_plat(struct udevice *dev)
        ret = gpio_request_by_name(dev, "reset-gpios", 0,
                                   &uc_priv->reset_gpio,
                                   GPIOD_IS_OUT);
-       if (ret != -ENOENT)
+       if (ret && ret != -ENOENT)
                return ret;
 
        uc_priv->reset_assert_delay = dev_read_u32_default(dev, "reset-assert-us", 0);
index 8c6461e..37eed59 100644 (file)
@@ -1348,7 +1348,7 @@ static const struct macb_usrio_cfg macb_default_usrio = {
        .clken = MACB_BIT(CLKEN),
 };
 
-static const struct macb_config default_gem_config = {
+static struct macb_config default_gem_config = {
        .dma_burst_length = 16,
        .hw_dma_cap = HW_DMA_CAP_32B,
        .clk_init = NULL,
@@ -1383,8 +1383,13 @@ static int macb_eth_probe(struct udevice *dev)
        macb->is_big_endian = (cpu_to_be32(0x12345678) == 0x12345678);
 
        macb->config = (struct macb_config *)dev_get_driver_data(dev);
-       if (!macb->config)
+       if (!macb->config) {
+               if (IS_ENABLED(CONFIG_DMA_ADDR_T_64BIT)) {
+                       if (GEM_BFEXT(DAW64, gem_readl(macb, DCFG6)))
+                               default_gem_config.hw_dma_cap = HW_DMA_CAP_64B;
+               }
                macb->config = &default_gem_config;
+       }
 
 #ifdef CONFIG_CLK
        ret = macb_enable_clk(dev);
@@ -1453,13 +1458,6 @@ static const struct macb_usrio_cfg sama7g5_usrio = {
        .clken = BIT(2),
 };
 
-static const struct macb_config microchip_config = {
-       .dma_burst_length = 16,
-       .hw_dma_cap = HW_DMA_CAP_64B,
-       .clk_init = NULL,
-       .usrio = &macb_default_usrio,
-};
-
 static const struct macb_config sama5d4_config = {
        .dma_burst_length = 4,
        .hw_dma_cap = HW_DMA_CAP_32B,
@@ -1502,8 +1500,6 @@ static const struct udevice_id macb_eth_ids[] = {
        { .compatible = "cdns,zynq-gem" },
        { .compatible = "sifive,fu540-c000-gem",
          .data = (ulong)&sifive_config },
-       { .compatible = "microchip,mpfs-mss-gem",
-         .data = (ulong)&microchip_config },
        { }
 };
 
index 6953b72..1d1118c 100644 (file)
@@ -129,7 +129,7 @@ struct ravb_priv {
        struct phy_device       *phydev;
        struct mii_dev          *bus;
        void __iomem            *iobase;
-       struct clk              clk;
+       struct clk_bulk         clks;
        struct gpio_desc        reset_gpio;
 };
 
@@ -485,7 +485,7 @@ static int ravb_probe(struct udevice *dev)
        iobase = map_physmem(pdata->iobase, 0x1000, MAP_NOCACHE);
        eth->iobase = iobase;
 
-       ret = clk_get_by_index(dev, 0, &eth->clk);
+       ret = clk_get_bulk(dev, &eth->clks);
        if (ret < 0)
                goto err_mdio_alloc;
 
@@ -518,7 +518,7 @@ static int ravb_probe(struct udevice *dev)
        eth->bus = miiphy_get_dev_by_name(dev->name);
 
        /* Bring up PHY */
-       ret = clk_enable(&eth->clk);
+       ret = clk_enable_bulk(&eth->clks);
        if (ret)
                goto err_mdio_register;
 
@@ -533,7 +533,7 @@ static int ravb_probe(struct udevice *dev)
        return 0;
 
 err_mdio_reset:
-       clk_disable(&eth->clk);
+       clk_release_bulk(&eth->clks);
 err_mdio_register:
        mdio_free(mdiodev);
 err_mdio_alloc:
@@ -545,7 +545,7 @@ static int ravb_remove(struct udevice *dev)
 {
        struct ravb_priv *eth = dev_get_priv(dev);
 
-       clk_disable(&eth->clk);
+       clk_release_bulk(&eth->clks);
 
        free(eth->phydev);
        mdio_unregister(eth->bus);
index 4e94b77..a92f00d 100644 (file)
@@ -202,7 +202,7 @@ struct pcie_advk {
        int                     sec_busno;
        struct udevice          *dev;
        struct gpio_desc        reset_gpio;
-       u32                     cfgcache[0x34 - 0x10];
+       u32                     cfgcache[(0x3c - 0x10) / 4];
        bool                    cfgcrssve;
 };
 
@@ -389,20 +389,19 @@ static int pcie_advk_read_config(const struct udevice *bus, pci_dev_t bdf,
        }
 
        /*
-        * The configuration space of the PCI Bridge on primary (local) bus is
+        * The configuration space of the PCI Bridge on primary (first) bus is
         * not accessible via PIO transfers like all other PCIe devices. PCI
         * Bridge config registers are available directly in Aardvark memory
-        * space starting at offset zero. Moreover PCI Bridge registers in the
-        * range 0x10 - 0x34 are not available and register 0x38 (Expansion ROM
-        * Base Address) is at offset 0x30.
-        * We therefore read configuration space content of the primary PCI
-        * Bridge from our virtual cache.
+        * space starting at offset zero. The PCI Bridge config space is of
+        * Type 0, but the BAR registers (including ROM BAR) don't have the same
+        * meaning as in the PCIe specification. Therefore do not access BAR
+        * registers and non-common registers (those which have different
+        * meaning for Type 0 and Type 1 config space) of the primary PCI Bridge
+        * and instead read their content from driver virtual cfgcache[].
         */
        if (busno == pcie->first_busno) {
-               if (offset >= 0x10 && offset < 0x34)
+               if ((offset >= 0x10 && offset < 0x34) || (offset >= 0x38 && offset < 0x3c))
                        data = pcie->cfgcache[(offset - 0x10) / 4];
-               else if ((offset & ~3) == PCI_ROM_ADDRESS1)
-                       data = advk_readl(pcie, PCIE_CORE_EXP_ROM_BAR_REG);
                else
                        data = advk_readl(pcie, offset & ~3);
 
@@ -576,23 +575,22 @@ static int pcie_advk_write_config(struct udevice *bus, pci_dev_t bdf,
        }
 
        /*
-        * As explained in pcie_advk_read_config(), for the configuration
-        * space of the primary PCI Bridge, we write the content into virtual
-        * cache.
+        * As explained in pcie_advk_read_config(), PCI Bridge config registers
+        * are available directly in Aardvark memory space starting at offset
+        * zero. Type 1 specific registers are not available, so we write their
+        * content only into driver virtual cfgcache[].
         */
        if (busno == pcie->first_busno) {
-               if (offset >= 0x10 && offset < 0x34) {
+               if ((offset >= 0x10 && offset < 0x34) ||
+                   (offset >= 0x38 && offset < 0x3c)) {
                        data = pcie->cfgcache[(offset - 0x10) / 4];
                        data = pci_conv_size_to_32(data, value, offset, size);
                        /* This PCI bridge does not have configurable bars */
                        if ((offset & ~3) == PCI_BASE_ADDRESS_0 ||
-                           (offset & ~3) == PCI_BASE_ADDRESS_1)
+                           (offset & ~3) == PCI_BASE_ADDRESS_1 ||
+                           (offset & ~3) == PCI_ROM_ADDRESS1)
                                data = 0x0;
                        pcie->cfgcache[(offset - 0x10) / 4] = data;
-               } else if ((offset & ~3) == PCI_ROM_ADDRESS1) {
-                       data = advk_readl(pcie, PCIE_CORE_EXP_ROM_BAR_REG);
-                       data = pci_conv_size_to_32(data, value, offset, size);
-                       advk_writel(pcie, data, PCIE_CORE_EXP_ROM_BAR_REG);
                } else {
                        data = advk_readl(pcie, offset & ~3);
                        data = pci_conv_size_to_32(data, value, offset, size);
@@ -830,12 +828,20 @@ static int pcie_advk_setup_hw(struct pcie_advk *pcie)
         *
         * Note that this Aardvark PCI Bridge does not have a compliant Type 1
         * Configuration Space and it even cannot be accessed via Aardvark's
-        * PCI config space access method. Something like config space is
+        * PCI config space access method. Aardvark PCI Bridge Config space is
         * available in internal Aardvark registers starting at offset 0x0
-        * and is reported as Type 0. In range 0x10 - 0x34 it has totally
-        * different registers. So our driver reports Header Type as Type 1 and
-        * for the above mentioned range redirects access to the virtual
-        * cfgcache[] buffer, which avoids changing internal Aardvark registers.
+        * and has format of Type 0 config space.
+        *
+        * Moreover Type 0 BAR registers (ranges 0x10 - 0x28 and 0x30 - 0x34)
+        * have the same format in Marvell's specification as in PCIe
+        * specification, but their meaning is totally different (and not even
+        * the same meaning as explained in the corresponding comment in the
+        * pci_mvebu driver; aardvark is still different).
+        *
+        * So our driver converts Type 0 config space to Type 1 and reports
+        * Header Type as Type 1. Access to BAR registers and to non-existent
+        * Type 1 registers is redirected to the virtual cfgcache[] buffer,
+        * which avoids changing unrelated registers.
         */
        reg = advk_readl(pcie, PCIE_CORE_DEV_REV_REG);
        reg &= ~0xffffff00;
index 14cd82d..62a4df3 100644 (file)
@@ -88,7 +88,7 @@ struct mvebu_pcie {
        unsigned int mem_attr;
        unsigned int io_target;
        unsigned int io_attr;
-       u32 cfgcache[0x34 - 0x10];
+       u32 cfgcache[(0x3c - 0x10) / 4];
 };
 
 /*
@@ -167,20 +167,20 @@ static int mvebu_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
        }
 
        /*
-        * mvebu has different internal registers mapped into PCI config space
-        * in range 0x10-0x34 for PCI bridge, so do not access PCI config space
-        * for this range and instead read content from driver virtual cfgcache
+        * The configuration space of the PCI Bridge on primary (first) bus is
+        * of Type 0 but the BAR registers (including ROM BAR) don't have the
+        * same meaning as in the PCIe specification. Therefore do not access
+        * BAR registers and non-common registers (those which have different
+        * meaning for Type 0 and Type 1 config space) of the PCI Bridge and
+        * instead read their content from driver virtual cfgcache[].
         */
-       if (busno == pcie->first_busno && offset >= 0x10 && offset < 0x34) {
+       if (busno == pcie->first_busno && ((offset >= 0x10 && offset < 0x34) ||
+                                          (offset >= 0x38 && offset < 0x3c))) {
                data = pcie->cfgcache[(offset - 0x10) / 4];
                debug("(addr,size,val)=(0x%04x, %d, 0x%08x) from cfgcache\n",
                      offset, size, data);
                *valuep = pci_conv_32_to_size(data, offset, size);
                return 0;
-       } else if (busno == pcie->first_busno &&
-                  (offset & ~3) == PCI_ROM_ADDRESS1) {
-               /* mvebu has Expansion ROM Base Address (0x38) at offset 0x30 */
-               offset -= PCI_ROM_ADDRESS1 - PCIE_EXP_ROM_BAR_OFF;
        }
 
        /*
@@ -247,17 +247,21 @@ static int mvebu_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
        }
 
        /*
-        * mvebu has different internal registers mapped into PCI config space
-        * in range 0x10-0x34 for PCI bridge, so do not access PCI config space
-        * for this range and instead write content to driver virtual cfgcache
+        * As explained in mvebu_pcie_read_config(), PCI Bridge Type 1 specific
+        * config registers are not available, so we write their content only
+        * into driver virtual cfgcache[].
+        * And as explained in mvebu_pcie_probe(), mvebu has its own specific
+        * way for configuring primary and secondary bus numbers.
         */
-       if (busno == pcie->first_busno && offset >= 0x10 && offset < 0x34) {
+       if (busno == pcie->first_busno && ((offset >= 0x10 && offset < 0x34) ||
+                                          (offset >= 0x38 && offset < 0x3c))) {
                debug("Writing to cfgcache only\n");
                data = pcie->cfgcache[(offset - 0x10) / 4];
                data = pci_conv_size_to_32(data, value, offset, size);
                /* mvebu PCI bridge does not have configurable bars */
                if ((offset & ~3) == PCI_BASE_ADDRESS_0 ||
-                   (offset & ~3) == PCI_BASE_ADDRESS_1)
+                   (offset & ~3) == PCI_BASE_ADDRESS_1 ||
+                   (offset & ~3) == PCI_ROM_ADDRESS1)
                        data = 0x0;
                pcie->cfgcache[(offset - 0x10) / 4] = data;
                /* mvebu has its own way how to set PCI primary bus number */
@@ -275,10 +279,6 @@ static int mvebu_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
                              pcie->sec_busno);
                }
                return 0;
-       } else if (busno == pcie->first_busno &&
-                  (offset & ~3) == PCI_ROM_ADDRESS1) {
-               /* mvebu has Expansion ROM Base Address (0x38) at offset 0x30 */
-               offset -= PCI_ROM_ADDRESS1 - PCIE_EXP_ROM_BAR_OFF;
        }
 
        /*
@@ -384,13 +384,20 @@ static int mvebu_pcie_probe(struct udevice *dev)
         * U-Boot cannot recognize as P2P Bridge.
         *
         * Note that this mvebu PCI Bridge does not have compliant Type 1
-        * Configuration Space. Header Type is reported as Type 0 and in
-        * range 0x10-0x34 it has aliased internal mvebu registers 0x10-0x34
-        * (e.g. PCIE_BAR_LO_OFF) and register 0x38 is reserved.
+        * Configuration Space. Header Type is reported as Type 0 and it
+        * has format of Type 0 config space.
         *
-        * Driver for this range redirects access to virtual cfgcache[] buffer
-        * which avoids changing internal mvebu registers. And changes Header
-        * Type response value to Type 1.
+        * Moreover Type 0 BAR registers (ranges 0x10 - 0x28 and 0x30 - 0x34)
+        * have the same format in Marvell's specification as in PCIe
+        * specification, but their meaning is totally different and they do
+        * different things: they are aliased into internal mvebu registers
+        * (e.g. PCIE_BAR_LO_OFF) and these should not be changed or
+        * reconfigured by pci device drivers.
+        *
+        * So our driver converts Type 0 config space to Type 1 and reports
+        * Header Type as Type 1. Access to BAR registers and to non-existent
+        * Type 1 registers is redirected to the virtual cfgcache[] buffer,
+        * which avoids changing unrelated registers.
         */
        reg = readl(pcie->base + PCIE_DEV_REV_OFF);
        reg &= ~0xffffff00;
index 6bca8e4..93e4d38 100644 (file)
@@ -9,6 +9,7 @@
 #include <serial.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
+#include <mach/soc.h>
 
 struct mvebu_plat {
        void __iomem *base;
@@ -213,6 +214,7 @@ static int mvebu_serial_remove(struct udevice *dev)
        u32 new_oversampling;
        u32 oversampling;
        u32 d1, d2;
+       u32 nb_rst;
 
        /*
         * Switch UART base clock back to XTAL because older Linux kernel
@@ -260,12 +262,22 @@ static int mvebu_serial_remove(struct udevice *dev)
                        return 0;
        }
 
+       /* wait until TX empty */
        while (!(readl(base + UART_STATUS_REG) & UART_STATUS_TX_EMPTY))
                ;
 
+       /* external reset of UART via North Bridge Peripheral */
+       nb_rst = readl(MVEBU_REGISTER(0x12400));
+       writel(nb_rst & ~BIT(3), MVEBU_REGISTER(0x12400));
+       writel(nb_rst | BIT(3), MVEBU_REGISTER(0x12400));
+
+       /* set baudrate and oversampling */
        writel(new_divider, base + UART_BAUD_REG);
        writel(new_oversampling, base + UART_POSSR_REG);
 
+       /* No Parity, 1 Stop */
+       writel(0, base + UART_CTRL_REG);
+
        return 0;
 }
 
@@ -305,7 +317,6 @@ U_BOOT_DRIVER(serial_mvebu) = {
 #ifdef CONFIG_DEBUG_MVEBU_A3700_UART
 
 #include <debug_uart.h>
-#include <mach/soc.h>
 
 static inline void _debug_uart_init(void)
 {
index ec8c730..51392c4 100644 (file)
@@ -378,8 +378,14 @@ out:
 int tpm_tis_cleanup(struct udevice *dev)
 {
        struct tpm_chip *chip = dev_get_priv(dev);
+       int ret;
+
+       ret = tpm_tis_request_locality(dev, 0);
+       if (ret)
+               return ret;
 
        tpm_tis_ready(dev);
+
        tpm_tis_release_locality(dev, chip->locality);
 
        return 0;
index 9cedff2..a646ce4 100644 (file)
@@ -118,10 +118,13 @@ iounmap:
 static int tpm_tis_remove(struct udevice *dev)
 {
        struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev);
+       int ret;
+
+       ret = tpm_tis_cleanup(dev);
 
        iounmap(drv_data->iobase);
 
-       return tpm_tis_cleanup(dev);
+       return ret;
 }
 
 static const struct tpm_ops tpm_tis_ops = {
index f0cc7ca..dde2173 100644 (file)
@@ -34,9 +34,10 @@ enum if_type {
        IF_TYPE_SATA,
        IF_TYPE_HOST,
        IF_TYPE_NVME,
-       IF_TYPE_EFI,
+       IF_TYPE_EFI_LOADER,
        IF_TYPE_PVBLOCK,
        IF_TYPE_VIRTIO,
+       IF_TYPE_EFI_MEDIA,
 
        IF_TYPE_COUNT,                  /* Number of interface types */
 };
index bf3f34e..1c3f957 100644 (file)
 /* Increase max gunzip size */
 #define CONFIG_SYS_BOOTM_LEN   (64 << 20)
 
+/* Support autoboot from RAM (kernel image is loaded via debug port) */
+#define KERNEL_IMAGE_ADDR      "0x2000000 "
+#define BOOTENV_DEV_NAME_RAM(devtypeu, devtypel, instance) \
+       "ram "
+#define BOOTENV_DEV_RAM(devtypeu, devtypel, instance) \
+       "bootcmd_ram=" \
+       "booti " \
+       KERNEL_IMAGE_ADDR \
+       "- $fdtcontroladdr\0"
+
 /* When we use RAM as ENV */
 
 /* Enable distro boot */
 #define BOOT_TARGET_DEVICES(func) \
        func(MMC, mmc, 0) \
-       func(DHCP, dhcp, na)
+       func(DHCP, dhcp, na) \
+       func(RAM, ram, na)
 #include <config_distro_bootcmd.h>
 
 #define CONFIG_EXTRA_ENV_SETTINGS      \
index 18d442e..14d6df3 100644 (file)
@@ -23,7 +23,7 @@
        "boot_fdt=try\0" \
        "fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" \
        "initrd_addr=0x43800000\0"              \
-       "mmcdev=0\0" \
+       "mmcdev=1\0" \
        "mmcpart=1\0" \
        "mmcrootpart=2\0" \
        "finduuid=part uuid mmc ${mmcdev}:${mmcrootpart} uuid\0" \
index 4e2cabf..dab679f 100644 (file)
        "env_check=if env info -p -d -q; then env save; fi\0" \
        "boot_net_usb_start=true\0"
 
+#ifndef STM32MP_BOARD_EXTRA_ENV
+#define STM32MP_BOARD_EXTRA_ENV
+#endif
+
 #include <config_distro_bootcmd.h>
 
 /*
        STM32MP_BOOTCMD \
        STM32MP_PARTS_DEFAULT \
        BOOTENV \
-       STM32MP_EXTRA
+       STM32MP_EXTRA \
+       STM32MP_BOARD_EXTRA_ENV
 
 #endif /* ifndef CONFIG_SPL_BUILD */
 #endif /* ifdef CONFIG_DISTRO_DEFAULTS*/
index c559cd7..c79f027 100644 (file)
@@ -8,6 +8,22 @@
 #ifndef __CONFIG_STM32MP15_DH_DHSOM_H__
 #define __CONFIG_STM32MP15_DH_DHSOM_H__
 
+/* PHY needs a longer autoneg timeout */
+#define PHY_ANEG_TIMEOUT               20000
+
+#define STM32MP_BOARD_EXTRA_ENV \
+       "usb_pgood_delay=1000\0" \
+       "update_sf=" /* Erase SPI NOR and install U-Boot from SD */     \
+               "setexpr loadaddr1 ${loadaddr} + 0x1000000 && "         \
+               "load mmc 0:4 ${loadaddr1} /boot/u-boot-spl.stm32 && "  \
+               "env set filesize1 ${filesize} && "                     \
+               "load mmc 0:4 ${loadaddr} /boot/u-boot.itb && "         \
+               "sf probe && sf erase 0 0x200000 && "                   \
+               "sf update ${loadaddr1} 0 ${filesize1} && "             \
+               "sf update ${loadaddr1} 0x40000 ${filesize1} && "       \
+               "sf update ${loadaddr} 0x80000 ${filesize} && "         \
+               "env set filesize1 && env set loadaddr1\0"
+
 #include <configs/stm32mp15_common.h>
 
 #define CONFIG_SPL_TARGET              "u-boot.itb"
index fd139b9..0e26e1d 100644 (file)
@@ -48,7 +48,8 @@ enum uclass_id {
        UCLASS_DMA,             /* Direct Memory Access */
        UCLASS_DSA,             /* Distributed (Ethernet) Switch Architecture */
        UCLASS_ECDSA,           /* Elliptic curve cryptographic device */
-       UCLASS_EFI,             /* EFI managed devices */
+       UCLASS_EFI_LOADER,      /* Devices created by UEFI applications */
+       UCLASS_EFI_MEDIA,       /* Devices provided by UEFI firmware */
        UCLASS_ETH,             /* Ethernet device */
        UCLASS_ETH_PHY,         /* Ethernet PHY device */
        UCLASS_FIRMWARE,        /* Firmware */
diff --git a/include/dt-bindings/interrupt-controller/microchip-mpfs-plic.h b/include/dt-bindings/interrupt-controller/microchip-mpfs-plic.h
new file mode 100644 (file)
index 0000000..eba1bac
--- /dev/null
@@ -0,0 +1,196 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/* Copyright (c) 2020-2021 Microchip Technology Inc */
+
+#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_MICROCHIP_MPFS_PLIC_H
+#define _DT_BINDINGS_INTERRUPT_CONTROLLER_MICROCHIP_MPFS_PLIC_H
+
+#define PLIC_INT_INVALID                                               0
+#define PLIC_INT_L2_METADATA_CORR                              1
+#define PLIC_INT_L2_METADATA_UNCORR                            2
+#define PLIC_INT_L2_DATA_CORR                                  3
+#define PLIC_INT_L2_DATA_UNCORR                                        4
+#define PLIC_INT_DMA_CH0_DONE                                  5
+#define PLIC_INT_DMA_CH0_ERR                                   6
+#define PLIC_INT_DMA_CH1_DONE                                  7
+#define PLIC_INT_DMA_CH1_ERR                                   8
+#define PLIC_INT_DMA_CH2_DONE                                  9
+#define PLIC_INT_DMA_CH2_ERR                                   10
+#define PLIC_INT_DMA_CH3_DONE                                  11
+#define PLIC_INT_DMA_CH3_ERR                                   12
+
+#define PLIC_INT_GPIO0_BIT0_OR_GPIO2_BIT0              13
+#define PLIC_INT_GPIO0_BIT1_OR_GPIO2_BIT1              14
+#define PLIC_INT_GPIO0_BIT2_OR_GPIO2_BIT2              15
+#define PLIC_INT_GPIO0_BIT3_OR_GPIO2_BIT3              16
+#define PLIC_INT_GPIO0_BIT4_OR_GPIO2_BIT4              17
+#define PLIC_INT_GPIO0_BIT5_OR_GPIO2_BIT5              18
+#define PLIC_INT_GPIO0_BIT6_OR_GPIO2_BIT6              19
+#define PLIC_INT_GPIO0_BIT7_OR_GPIO2_BIT7              20
+#define PLIC_INT_GPIO0_BIT8_OR_GPIO2_BIT8              21
+#define PLIC_INT_GPIO0_BIT9_OR_GPIO2_BIT9              22
+#define PLIC_INT_GPIO0_BIT10_OR_GPIO2_BIT10            23
+#define PLIC_INT_GPIO0_BIT11_OR_GPIO2_BIT11            24
+#define PLIC_INT_GPIO0_BIT12_OR_GPIO2_BIT12            25
+#define PLIC_INT_GPIO0_BIT13_OR_GPIO2_BIT13            26
+#define PLIC_INT_GPIO1_BIT0_OR_GPIO2_BIT14             27
+#define PLIC_INT_GPIO1_BIT1_OR_GPIO2_BIT15             28
+#define PLIC_INT_GPIO1_BIT2_OR_GPIO2_BIT16             29
+#define PLIC_INT_GPIO1_BIT3_OR_GPIO2_BIT17             30
+#define PLIC_INT_GPIO1_BIT4_OR_GPIO2_BIT18             31
+#define PLIC_INT_GPIO1_BIT5_OR_GPIO2_BIT19             32
+#define PLIC_INT_GPIO1_BIT6_OR_GPIO2_BIT20             33
+#define PLIC_INT_GPIO1_BIT7_OR_GPIO2_BIT21             34
+#define PLIC_INT_GPIO1_BIT8_OR_GPIO2_BIT22             35
+#define PLIC_INT_GPIO1_BIT9_OR_GPIO2_BIT23             36
+#define PLIC_INT_GPIO1_BIT10_OR_GPIO2_BIT24            37
+#define PLIC_INT_GPIO1_BIT11_OR_GPIO2_BIT25            38
+#define PLIC_INT_GPIO1_BIT12_OR_GPIO2_BIT26            39
+#define PLIC_INT_GPIO1_BIT13_OR_GPIO2_BIT27            40
+#define PLIC_INT_GPIO1_BIT14_OR_GPIO2_BIT28            41
+#define PLIC_INT_GPIO1_BIT15_OR_GPIO2_BIT29            42
+#define PLIC_INT_GPIO1_BIT16_OR_GPIO2_BIT30            43
+#define PLIC_INT_GPIO1_BIT17_OR_GPIO2_BIT31            44
+#define PLIC_INT_GPIO1_BIT18                                   45
+#define PLIC_INT_GPIO1_BIT19                                   46
+#define PLIC_INT_GPIO1_BIT20                                   47
+#define PLIC_INT_GPIO1_BIT21                                   48
+#define PLIC_INT_GPIO1_BIT22                                   49
+#define PLIC_INT_GPIO1_BIT23                                   50
+#define PLIC_INT_GPIO0_NON_DIRECT                              51
+#define PLIC_INT_GPIO1_NON_DIRECT                              52
+#define PLIC_INT_GPIO2_NON_DIRECT                              53
+#define PLIC_INT_SPI0                                                  54
+#define PLIC_INT_SPI1                                                  55
+#define PLIC_INT_CAN0                                                  56
+#define PLIC_INT_CAN1                                                  57
+#define PLIC_INT_I2C0_MAIN                                             58
+#define PLIC_INT_I2C0_ALERT                                            59
+#define PLIC_INT_I2C0_SUS                                              60
+#define PLIC_INT_I2C1_MAIN                                             61
+#define PLIC_INT_I2C1_ALERT                                            62
+#define PLIC_INT_I2C1_SUS                                              63
+#define PLIC_INT_MAC0_INT                                              64
+#define PLIC_INT_MAC0_QUEUE1                                   65
+#define PLIC_INT_MAC0_QUEUE2                                   66
+#define PLIC_INT_MAC0_QUEUE3                                   67
+#define PLIC_INT_MAC0_EMAC                                             68
+#define PLIC_INT_MAC0_MMSL                                             69
+#define PLIC_INT_MAC1_INT                                              70
+#define PLIC_INT_MAC1_QUEUE1                                   71
+#define PLIC_INT_MAC1_QUEUE2                                   72
+#define PLIC_INT_MAC1_QUEUE3                                   73
+#define PLIC_INT_MAC1_EMAC                                             74
+#define PLIC_INT_MAC1_MMSL                                             75
+#define PLIC_INT_DDRC_TRAIN                                            76
+#define PLIC_INT_SCB_INTERRUPT                                 77
+#define PLIC_INT_ECC_ERROR                                             78
+#define PLIC_INT_ECC_CORRECT                                   79
+#define PLIC_INT_RTC_WAKEUP                                            80
+#define PLIC_INT_RTC_MATCH                                             81
+#define PLIC_INT_TIMER1                                                        82
+#define PLIC_INT_TIMER2                                                        83
+#define PLIC_INT_ENVM                                                  84
+#define PLIC_INT_QSPI                                                  85
+#define PLIC_INT_USB_DMA                                               86
+#define PLIC_INT_USB_MC                                                        87
+#define PLIC_INT_MMC_MAIN                                              88
+#define PLIC_INT_MMC_WAKEUP                                            89
+#define PLIC_INT_MMUART0                                               90
+#define PLIC_INT_MMUART1                                               91
+#define PLIC_INT_MMUART2                                               92
+#define PLIC_INT_MMUART3                                               93
+#define PLIC_INT_MMUART4                                               94
+#define PLIC_INT_G5C_DEVRST                                            95
+#define PLIC_INT_G5C_MESSAGE                                   96
+#define PLIC_INT_USOC_VC_INTERRUPT                             97
+#define PLIC_INT_USOC_SMB_INTERRUPT                            98
+#define PLIC_INT_E51_0_MAINTENACE                              99
+#define PLIC_INT_WDOG0_MRVP                                            100
+#define PLIC_INT_WDOG1_MRVP                                            101
+#define PLIC_INT_WDOG2_MRVP                                            102
+#define PLIC_INT_WDOG3_MRVP                                            103
+#define PLIC_INT_WDOG4_MRVP                                            104
+#define PLIC_INT_WDOG0_TOUT                                            105
+#define PLIC_INT_WDOG1_TOUT                                            106
+#define PLIC_INT_WDOG2_TOUT                                            107
+#define PLIC_INT_WDOG3_TOUT                                            108
+#define PLIC_INT_WDOG4_TOUT                                            109
+#define PLIC_INT_G5C_MSS_SPI                                   110
+#define PLIC_INT_VOLT_TEMP_ALARM                               111
+#define PLIC_INT_ATHENA_COMPLETE                               112
+#define PLIC_INT_ATHENA_ALARM                                  113
+#define PLIC_INT_ATHENA_BUS_ERROR                              114
+#define PLIC_INT_USOC_AXIC_US                                  115
+#define PLIC_INT_USOC_AXIC_DS                                  116
+#define PLIC_INT_SPARE                                                 117
+#define PLIC_INT_FABRIC_F2H_0                                  118
+#define PLIC_INT_FABRIC_F2H_1                                  119
+#define PLIC_INT_FABRIC_F2H_2                                  120
+#define PLIC_INT_FABRIC_F2H_3                                  121
+#define PLIC_INT_FABRIC_F2H_4                                  122
+#define PLIC_INT_FABRIC_F2H_5                                  123
+#define PLIC_INT_FABRIC_F2H_6                                  124
+#define PLIC_INT_FABRIC_F2H_7                                  125
+#define PLIC_INT_FABRIC_F2H_8                                  126
+#define PLIC_INT_FABRIC_F2H_9                                  127
+#define PLIC_INT_FABRIC_F2H_10                                 128
+#define PLIC_INT_FABRIC_F2H_11                                 129
+#define PLIC_INT_FABRIC_F2H_12                                 130
+#define PLIC_INT_FABRIC_F2H_13                                 131
+#define PLIC_INT_FABRIC_F2H_14                                 132
+#define PLIC_INT_FABRIC_F2H_15                                 133
+#define PLIC_INT_FABRIC_F2H_16                                 134
+#define PLIC_INT_FABRIC_F2H_17                                 135
+#define PLIC_INT_FABRIC_F2H_18                                 136
+#define PLIC_INT_FABRIC_F2H_19                                 137
+#define PLIC_INT_FABRIC_F2H_20                                 138
+#define PLIC_INT_FABRIC_F2H_21                                 139
+#define PLIC_INT_FABRIC_F2H_22                                 140
+#define PLIC_INT_FABRIC_F2H_23                                 141
+#define PLIC_INT_FABRIC_F2H_24                                 142
+#define PLIC_INT_FABRIC_F2H_25                                 143
+#define PLIC_INT_FABRIC_F2H_26                                 144
+#define PLIC_INT_FABRIC_F2H_27                                 145
+#define PLIC_INT_FABRIC_F2H_28                                 146
+#define PLIC_INT_FABRIC_F2H_29                                 147
+#define PLIC_INT_FABRIC_F2H_30                                 148
+#define PLIC_INT_FABRIC_F2H_31                                 149
+#define PLIC_INT_FABRIC_F2H_32                                 150
+#define PLIC_INT_FABRIC_F2H_33                                 151
+#define PLIC_INT_FABRIC_F2H_34                                 152
+#define PLIC_INT_FABRIC_F2H_35                                 153
+#define PLIC_INT_FABRIC_F2H_36                                 154
+#define PLIC_INT_FABRIC_F2H_37                                 155
+#define PLIC_INT_FABRIC_F2H_38                                 156
+#define PLIC_INT_FABRIC_F2H_39                                 157
+#define PLIC_INT_FABRIC_F2H_40                                 158
+#define PLIC_INT_FABRIC_F2H_41                                 159
+#define PLIC_INT_FABRIC_F2H_42                                 160
+#define PLIC_INT_FABRIC_F2H_43                                 161
+#define PLIC_INT_FABRIC_F2H_44                                 162
+#define PLIC_INT_FABRIC_F2H_45                                 163
+#define PLIC_INT_FABRIC_F2H_46                                 164
+#define PLIC_INT_FABRIC_F2H_47                                 165
+#define PLIC_INT_FABRIC_F2H_48                                 166
+#define PLIC_INT_FABRIC_F2H_49                                 167
+#define PLIC_INT_FABRIC_F2H_50                                 168
+#define PLIC_INT_FABRIC_F2H_51                                 169
+#define PLIC_INT_FABRIC_F2H_52                                 170
+#define PLIC_INT_FABRIC_F2H_53                                 171
+#define PLIC_INT_FABRIC_F2H_54                                 172
+#define PLIC_INT_FABRIC_F2H_55                                 173
+#define PLIC_INT_FABRIC_F2H_56                                 174
+#define PLIC_INT_FABRIC_F2H_57                                 175
+#define PLIC_INT_FABRIC_F2H_58                                 176
+#define PLIC_INT_FABRIC_F2H_59                                 177
+#define PLIC_INT_FABRIC_F2H_60                                 178
+#define PLIC_INT_FABRIC_F2H_61                                 179
+#define PLIC_INT_FABRIC_F2H_62                                 180
+#define PLIC_INT_FABRIC_F2H_63                                 181
+#define PLIC_INT_BUS_ERROR_UNIT_HART_0                 182
+#define PLIC_INT_BUS_ERROR_UNIT_HART_1                 183
+#define PLIC_INT_BUS_ERROR_UNIT_HART_2                 184
+#define PLIC_INT_BUS_ERROR_UNIT_HART_3                 185
+#define PLIC_INT_BUS_ERROR_UNIT_HART_4                 186
+
+#endif /* _DT_BINDINGS_INTERRUPT_CONTROLLER_MICROCHIP_MPFS_PLIC_H */
diff --git a/include/dt-bindings/interrupt-controller/riscv-hart.h b/include/dt-bindings/interrupt-controller/riscv-hart.h
new file mode 100644 (file)
index 0000000..c4331b8
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/* Copyright (c) 2020-2021 Microchip Technology Inc */
+
+#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_RISCV_HART_H
+#define _DT_BINDINGS_INTERRUPT_CONTROLLER_RISCV_HART_H
+
+#define HART_INT_U_SOFT   0
+#define HART_INT_S_SOFT   1
+#define HART_INT_M_SOFT   3
+#define HART_INT_U_TIMER  4
+#define HART_INT_S_TIMER  5
+#define HART_INT_M_TIMER  7
+#define HART_INT_U_EXT    8
+#define HART_INT_S_EXT    9
+#define HART_INT_M_EXT    11
+
+#endif /* _DT_BINDINGS_INTERRUPT_CONTROLLER_RISCV_HART_H */
index b583542..0ec5913 100644 (file)
@@ -414,6 +414,17 @@ struct efi_priv {
        void *next_hdr;
 };
 
+/*
+ * EFI attributes of the udevice handled by efi_media driver
+ *
+ * @handle: handle of the controller on which this driver is installed
+ * @blkio: block io protocol proxied by this driver
+ */
+struct efi_media_plat {
+       efi_handle_t            handle;
+       struct efi_block_io     *blkio;
+};
+
 /* Base address of the EFI image */
 extern char image_base[];
 
index d52e399..f4860e8 100644 (file)
@@ -525,6 +525,8 @@ efi_status_t efi_disk_register(void);
 efi_status_t efi_rng_register(void);
 /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */
 efi_status_t efi_tcg2_register(void);
+/* Called by efi_init_obj_list() to do initial measurement */
+efi_status_t efi_tcg2_do_initial_measurement(void);
 /* measure the pe-coff image, extend PCR and add Event Log */
 efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
                                   struct efi_loaded_image_obj *handle,
@@ -988,4 +990,6 @@ efi_status_t efi_esrt_register(void);
  */
 efi_status_t efi_esrt_populate(void);
 efi_status_t efi_load_capsule_drivers(void);
+
+efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr, u32 *sz);
 #endif /* _EFI_LOADER_H */
index ceff7d2..4e9dd52 100644 (file)
@@ -512,13 +512,16 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data,
  * @dev                TPM device
  * @idx                Index of the PCR
  * @idx_min_sz Minimum size in bytes of the pcrSelect array
+ * @algorithm  Algorithm used, defined in 'enum tpm2_algorithms'
  * @data       Output buffer for contents of the named PCR
+ * @digest_len  len of the data
  * @updates    Optional out parameter: number of updates for this PCR
  *
  * @return code of the operation
  */
 u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz,
-                 void *data, unsigned int *updates);
+                 u16 algorithm, void *data, u32 digest_len,
+                 unsigned int *updates);
 
 /**
  * Issue a TPM2_GetCapability command.  This implementation is limited
index 0937e35..04cb3ef 100644 (file)
@@ -147,7 +147,7 @@ static int efi_bl_bind(efi_handle_t handle, void *interface)
        if (!obj)
                return -ENOENT;
 
-       devnum = blk_find_max_devnum(IF_TYPE_EFI);
+       devnum = blk_find_max_devnum(IF_TYPE_EFI_LOADER);
        if (devnum == -ENODEV)
                devnum = 0;
        else if (devnum < 0)
@@ -159,8 +159,8 @@ static int efi_bl_bind(efi_handle_t handle, void *interface)
        sprintf(name, "efiblk#%d", devnum);
 
        /* Create driver model udevice for the EFI block io device */
-       ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI, devnum,
-                               io->media->block_size,
+       ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI_LOADER,
+                               devnum, io->media->block_size,
                                (lbaint_t)io->media->last_block, &bdev);
        if (ret)
                return ret;
@@ -209,6 +209,6 @@ static const struct efi_driver_ops driver_ops = {
 /* Identify as EFI driver */
 U_BOOT_DRIVER(efi_block) = {
        .name           = "EFI block driver",
-       .id             = UCLASS_EFI,
+       .id             = UCLASS_EFI_LOADER,
        .ops            = &driver_ops,
 };
index 382c2b4..b01ce89 100644 (file)
@@ -308,7 +308,7 @@ efi_status_t efi_driver_init(void)
        log_debug("Initializing EFI driver framework\n");
        for (drv = ll_entry_start(struct driver, driver);
             drv < ll_entry_end(struct driver, driver); ++drv) {
-               if (drv->id == UCLASS_EFI) {
+               if (drv->id == UCLASS_EFI_LOADER) {
                        ret = efi_add_driver(drv);
                        if (ret != EFI_SUCCESS) {
                                log_err("Failed to add EFI driver %s\n",
@@ -328,7 +328,7 @@ efi_status_t efi_driver_init(void)
  */
 static int efi_uc_init(struct uclass *class)
 {
-       log_debug("Initializing UCLASS_EFI\n");
+       log_debug("Initializing UCLASS_EFI_LOADER\n");
        return 0;
 }
 
@@ -340,13 +340,13 @@ static int efi_uc_init(struct uclass *class)
  */
 static int efi_uc_destroy(struct uclass *class)
 {
-       log_debug("Destroying UCLASS_EFI\n");
+       log_debug("Destroying UCLASS_EFI_LOADER\n");
        return 0;
 }
 
 UCLASS_DRIVER(efi) = {
        .name           = "efi",
-       .id             = UCLASS_EFI,
+       .id             = UCLASS_EFI_LOADER,
        .init           = efi_uc_init,
        .destroy        = efi_uc_destroy,
 };
index 700dc83..24f9a2b 100644 (file)
@@ -308,6 +308,8 @@ config EFI_TCG2_PROTOCOL
        bool "EFI_TCG2_PROTOCOL support"
        default y
        depends on TPM_V2
+       # Sandbox TPM currently fails on GetCapabilities needed for TCG2
+       depends on !SANDBOX
        select SHA1
        select SHA256
        select SHA384
index 8492b73..20b6969 100644 (file)
@@ -3016,9 +3016,12 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
        if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
                if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION) {
                        ret = efi_tcg2_measure_efi_app_invocation(image_obj);
-                       if (ret != EFI_SUCCESS) {
-                               log_warning("tcg2 measurement fails(0x%lx)\n",
-                                           ret);
+                       if (ret == EFI_SECURITY_VIOLATION) {
+                               /*
+                                * TCG2 Protocol is installed but no TPM device found,
+                                * this is not expected.
+                                */
+                               return EFI_EXIT(EFI_SECURITY_VIOLATION);
                        }
                }
        }
index eb95580..773bd06 100644 (file)
@@ -934,9 +934,16 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle,
 
 #if CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL)
        /* Measure an PE/COFF image */
-       if (tcg2_measure_pe_image(efi, efi_size, handle,
-                                 loaded_image_info))
-               log_err("PE image measurement failed\n");
+       ret = tcg2_measure_pe_image(efi, efi_size, handle, loaded_image_info);
+       if (ret == EFI_SECURITY_VIOLATION) {
+               /*
+                * TCG2 Protocol is installed but no TPM device found,
+                * this is not expected.
+                */
+               log_err("PE image measurement failed, no tpm device found\n");
+               goto err;
+       }
+
 #endif
 
        /* Copy PE headers */
index 1aba71c..49172e3 100644 (file)
@@ -241,6 +241,10 @@ efi_status_t efi_init_obj_list(void)
                ret = efi_tcg2_register();
                if (ret != EFI_SUCCESS)
                        goto out;
+
+               ret = efi_tcg2_do_initial_measurement();
+               if (ret == EFI_SECURITY_VIOLATION)
+                       goto out;
        }
 
        /* Secure boot */
index 8c1f22e..0ae07ef 100644 (file)
@@ -153,6 +153,15 @@ static u16 alg_to_len(u16 hash_alg)
        return 0;
 }
 
+static bool is_tcg2_protocol_installed(void)
+{
+       struct efi_handler *handler;
+       efi_status_t ret;
+
+       ret = efi_search_protocol(efi_root, &efi_guid_tcg2_protocol, &handler);
+       return ret == EFI_SUCCESS;
+}
+
 static u32 tcg_event_final_size(struct tpml_digest_values *digest_list)
 {
        u32 len;
@@ -199,6 +208,44 @@ static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index,
        return EFI_SUCCESS;
 }
 
+/* tcg2_pcr_read - Read PCRs for a TPM2 device for a given tpml_digest_values
+ *
+ * @dev:               device
+ * @pcr_index:         PCR index
+ * @digest_list:       list of digest algorithms to extend
+ *
+ * @Return: status code
+ */
+static efi_status_t tcg2_pcr_read(struct udevice *dev, u32 pcr_index,
+                                 struct tpml_digest_values *digest_list)
+{
+       struct tpm_chip_priv *priv;
+       unsigned int updates, pcr_select_min;
+       u32 rc;
+       size_t i;
+
+       priv = dev_get_uclass_priv(dev);
+       if (!priv)
+               return EFI_DEVICE_ERROR;
+
+       pcr_select_min = priv->pcr_select_min;
+
+       for (i = 0; i < digest_list->count; i++) {
+               u16 hash_alg = digest_list->digests[i].hash_alg;
+               u8 *digest = (u8 *)&digest_list->digests[i].digest;
+
+               rc = tpm2_pcr_read(dev, pcr_index, pcr_select_min,
+                                  hash_alg, digest, alg_to_len(hash_alg),
+                                  &updates);
+               if (rc) {
+                       EFI_PRINT("Failed to read PCR\n");
+                       return EFI_DEVICE_ERROR;
+               }
+       }
+
+       return EFI_SUCCESS;
+}
+
 /* put_event - Append an agile event to an eventlog
  *
  * @pcr_index:         PCR index
@@ -325,6 +372,45 @@ __weak efi_status_t platform_get_tpm2_device(struct udevice **dev)
 }
 
 /**
+ * platform_get_eventlog() - retrieve the eventlog address and size
+ *
+ * This function retrieves the eventlog address and size if the underlying
+ * firmware has done some measurements and passed them.
+ *
+ * This function may be overridden based on platform specific method of
+ * passing the eventlog address and size.
+ *
+ * @dev:       udevice
+ * @addr:      eventlog address
+ * @sz:                eventlog size
+ * Return:     status code
+ */
+__weak efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr,
+                                         u32 *sz)
+{
+       const u64 *basep;
+       const u32 *sizep;
+
+       basep = dev_read_prop(dev, "tpm_event_log_addr", NULL);
+       if (!basep)
+               return EFI_NOT_FOUND;
+
+       *addr = be64_to_cpup((__force __be64 *)basep);
+
+       sizep = dev_read_prop(dev, "tpm_event_log_size", NULL);
+       if (!sizep)
+               return EFI_NOT_FOUND;
+
+       *sz = be32_to_cpup((__force __be32 *)sizep);
+       if (*sz == 0) {
+               log_debug("event log empty\n");
+               return EFI_NOT_FOUND;
+       }
+
+       return EFI_SUCCESS;
+}
+
+/**
  * tpm2_get_max_command_size() - get the supported max command size
  *
  * @dev:               TPM device
@@ -886,9 +972,12 @@ efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
        IMAGE_NT_HEADERS32 *nt;
        struct efi_handler *handler;
 
+       if (!is_tcg2_protocol_installed())
+               return EFI_SUCCESS;
+
        ret = platform_get_tpm2_device(&dev);
        if (ret != EFI_SUCCESS)
-               return ret;
+               return EFI_SECURITY_VIOLATION;
 
        switch (handle->image_type) {
        case IMAGE_SUBSYSTEM_EFI_APPLICATION:
@@ -1182,6 +1271,318 @@ static const struct efi_tcg2_protocol efi_tcg2_protocol = {
 };
 
 /**
+ * parse_event_log_header() -  Parse and verify the event log header fields
+ *
+ * @buffer:                    Pointer to the start of the eventlog
+ * @size:                      Size of the eventlog
+ * @pos:                       Return offset of the next event in buffer right
+ *                             after the event header i.e specID
+ *
+ * Return:     status code
+ */
+static efi_status_t parse_event_log_header(void *buffer, u32 size, u32 *pos)
+{
+       struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer;
+       int i = 0;
+
+       if (size < sizeof(*event_header))
+               return EFI_COMPROMISED_DATA;
+
+       if (get_unaligned_le32(&event_header->pcr_index) != 0 ||
+           get_unaligned_le32(&event_header->event_type) != EV_NO_ACTION)
+               return EFI_COMPROMISED_DATA;
+
+       for (i = 0; i < sizeof(event_header->digest); i++) {
+               if (event_header->digest[i])
+                       return EFI_COMPROMISED_DATA;
+       }
+
+       *pos += sizeof(*event_header);
+
+       return EFI_SUCCESS;
+}
+
+/**
+ * parse_specid_event() -  Parse and verify the specID Event in the eventlog
+ *
+ * @dev:               udevice
+ * @buffer:            Pointer to the start of the eventlog
+ * @log_size:          Size of the eventlog
+ * @pos:               [in] Offset of specID event in the eventlog buffer
+ *                     [out] Return offset of the next event in the buffer
+ *                     after the specID
+ * @digest_list:       list of digests in the event
+ *
+ * Return:             status code
+ * @pos                        Offset in the eventlog where the specID event ends
+ * @digest_list:       list of digests in the event
+ */
+static efi_status_t parse_specid_event(struct udevice *dev, void *buffer,
+                                      u32 log_size, u32 *pos,
+                                      struct tpml_digest_values *digest_list)
+{
+       struct tcg_efi_spec_id_event *spec_event;
+       struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer;
+       size_t spec_event_size;
+       u32 active = 0, supported = 0, pcr_count = 0, alg_count = 0;
+       u32 spec_active = 0;
+       u16 hash_alg;
+       u8 vendor_sz;
+       int err, i;
+
+       if (*pos >= log_size || (*pos + sizeof(*spec_event)) > log_size)
+               return EFI_COMPROMISED_DATA;
+
+       /* Check specID event data */
+       spec_event = (struct tcg_efi_spec_id_event *)((uintptr_t)buffer + *pos);
+       /* Check for signature */
+       if (memcmp(spec_event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03,
+                  sizeof(TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03))) {
+               log_err("specID Event: Signature mismatch\n");
+               return EFI_COMPROMISED_DATA;
+       }
+
+       if (spec_event->spec_version_minor !=
+                       TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 ||
+           spec_event->spec_version_major !=
+                       TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2)
+               return EFI_COMPROMISED_DATA;
+
+       if (spec_event->number_of_algorithms > MAX_HASH_COUNT ||
+           spec_event->number_of_algorithms < 1) {
+               log_err("specID Event: Number of algorithms incorrect\n");
+               return EFI_COMPROMISED_DATA;
+       }
+
+       alg_count = spec_event->number_of_algorithms;
+
+       err = tpm2_get_pcr_info(dev, &supported, &active, &pcr_count);
+       if (err)
+               return EFI_DEVICE_ERROR;
+
+       digest_list->count = 0;
+       /*
+        * We have to take care that the sequence of algorithms that we record
+        * in digest_list matches the sequence in eventlog.
+        */
+       for (i = 0; i < alg_count; i++) {
+               hash_alg =
+                 get_unaligned_le16(&spec_event->digest_sizes[i].algorithm_id);
+
+               if (!(supported & alg_to_mask(hash_alg))) {
+                       log_err("specID Event: Unsupported algorithm\n");
+                       return EFI_COMPROMISED_DATA;
+               }
+               digest_list->digests[digest_list->count++].hash_alg = hash_alg;
+
+               spec_active |= alg_to_mask(hash_alg);
+       }
+
+       /*
+        * TCG specification expects the event log to have hashes for all
+        * active PCR's
+        */
+       if (spec_active != active) {
+               /*
+                * Previous stage bootloader should know all the active PCR's
+                * and use them in the Eventlog.
+                */
+               log_err("specID Event: All active hash alg not present\n");
+               return EFI_COMPROMISED_DATA;
+       }
+
+       /*
+        * the size of the spec event and placement of vendor_info_size
+        * depends on supported algoriths
+        */
+       spec_event_size =
+               offsetof(struct tcg_efi_spec_id_event, digest_sizes) +
+               alg_count * sizeof(spec_event->digest_sizes[0]);
+
+       if (*pos + spec_event_size >= log_size)
+               return EFI_COMPROMISED_DATA;
+
+       vendor_sz = *(uint8_t *)((uintptr_t)buffer + *pos + spec_event_size);
+
+       spec_event_size += sizeof(vendor_sz) + vendor_sz;
+       *pos += spec_event_size;
+
+       if (get_unaligned_le32(&event_header->event_size) != spec_event_size) {
+               log_err("specID event: header event size mismatch\n");
+               /* Right way to handle this can be to call SetActive PCR's */
+               return EFI_COMPROMISED_DATA;
+       }
+
+       return EFI_SUCCESS;
+}
+
+/**
+ * tcg2_parse_event() -  Parse the event in the eventlog
+ *
+ * @dev:               udevice
+ * @buffer:            Pointer to the start of the eventlog
+ * @log_size:          Size of the eventlog
+ * @offset:            [in] Offset of the event in the eventlog buffer
+ *                     [out] Return offset of the next event in the buffer
+ * @digest_list:       list of digests in the event
+ * @pcr                        Index of the PCR in the event
+ *
+ * Return:             status code
+ */
+static efi_status_t tcg2_parse_event(struct udevice *dev, void *buffer,
+                                    u32 log_size, u32 *offset,
+                                    struct tpml_digest_values *digest_list,
+                                    u32 *pcr)
+{
+       struct tcg_pcr_event2 *event = NULL;
+       u32 count, size, event_size;
+       size_t pos;
+
+       event_size = tcg_event_final_size(digest_list);
+       if (*offset >= log_size || *offset + event_size > log_size) {
+               log_err("Event exceeds log size\n");
+               return EFI_COMPROMISED_DATA;
+       }
+
+       event = (struct tcg_pcr_event2 *)((uintptr_t)buffer + *offset);
+       *pcr = get_unaligned_le32(&event->pcr_index);
+
+       /* get the count */
+       count = get_unaligned_le32(&event->digests.count);
+       if (count != digest_list->count)
+               return EFI_COMPROMISED_DATA;
+
+       pos = offsetof(struct tcg_pcr_event2, digests);
+       pos += offsetof(struct tpml_digest_values, digests);
+
+       for (int i = 0; i < digest_list->count; i++) {
+               u16 alg;
+               u16 hash_alg = digest_list->digests[i].hash_alg;
+               u8 *digest = (u8 *)&digest_list->digests[i].digest;
+
+               alg = get_unaligned_le16((void *)((uintptr_t)event + pos));
+
+               if (alg != hash_alg)
+                       return EFI_COMPROMISED_DATA;
+
+               pos += offsetof(struct tpmt_ha, digest);
+               memcpy(digest, (void *)((uintptr_t)event + pos), alg_to_len(hash_alg));
+               pos += alg_to_len(hash_alg);
+       }
+
+       size = get_unaligned_le32((void *)((uintptr_t)event + pos));
+       event_size += size;
+       pos += sizeof(u32); /* tcg_pcr_event2 event_size*/
+       pos += size;
+
+       /* make sure the calculated buffer is what we checked against */
+       if (pos != event_size)
+               return EFI_COMPROMISED_DATA;
+
+       if (pos > log_size)
+               return EFI_COMPROMISED_DATA;
+
+       *offset += pos;
+
+       return EFI_SUCCESS;
+}
+
+/**
+ * tcg2_get_fw_eventlog() -  Get the eventlog address and size
+ *
+ * If the previous firmware has passed some eventlog, this function get it's
+ * location and check for it's validity.
+ *
+ * @dev:               udevice
+ * @log_buffer:                eventlog address
+ * @log_sz:            eventlog size
+ *
+ * Return:     status code
+ */
+static efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer,
+                                        size_t *log_sz)
+{
+       struct tpml_digest_values digest_list;
+       void *buffer;
+       efi_status_t ret;
+       u32 pcr, pos;
+       u64 base;
+       u32 sz;
+       bool extend_pcr = false;
+       int i;
+
+       ret = platform_get_eventlog(dev, &base, &sz);
+       if (ret != EFI_SUCCESS)
+               return ret;
+
+       if (sz > TPM2_EVENT_LOG_SIZE)
+               return EFI_VOLUME_FULL;
+
+       buffer = (void *)(uintptr_t)base;
+       pos = 0;
+       /* Parse the eventlog to check for its validity */
+       ret = parse_event_log_header(buffer, sz, &pos);
+       if (ret)
+               return ret;
+
+       ret = parse_specid_event(dev, buffer, sz, &pos, &digest_list);
+       if (ret) {
+               log_err("Error parsing SPEC ID Event\n");
+               return ret;
+       }
+
+       ret = tcg2_pcr_read(dev, 0, &digest_list);
+       if (ret) {
+               log_err("Error reading PCR 0\n");
+               return ret;
+       }
+
+       /*
+        * If PCR0 is 0, previous firmware didn't have the capability
+        * to extend the PCR. In this scenario, extend the PCR as
+        * the eventlog is parsed.
+        */
+       for (i = 0; i < digest_list.count; i++) {
+               u8 hash_buf[TPM2_SHA512_DIGEST_SIZE] = { 0 };
+               u16 hash_alg = digest_list.digests[i].hash_alg;
+
+               if (!memcmp((u8 *)&digest_list.digests[i].digest, hash_buf,
+                           alg_to_len(hash_alg)))
+                       extend_pcr = true;
+       }
+
+       while (pos < sz) {
+               ret = tcg2_parse_event(dev, buffer, sz, &pos, &digest_list,
+                                      &pcr);
+               if (ret) {
+                       log_err("Error parsing event\n");
+                       return ret;
+               }
+               if (extend_pcr) {
+                       ret = tcg2_pcr_extend(dev, pcr, &digest_list);
+                       if (ret != EFI_SUCCESS) {
+                               log_err("Error in extending PCR\n");
+                               return ret;
+                       }
+
+                       /* Clear the digest for next event */
+                       for (i = 0; i < digest_list.count; i++) {
+                               u16 hash_alg = digest_list.digests[i].hash_alg;
+                               u8 *digest =
+                                  (u8 *)&digest_list.digests[i].digest;
+
+                               memset(digest, 0, alg_to_len(hash_alg));
+                       }
+               }
+       }
+
+       memcpy(log_buffer, buffer, sz);
+       *log_sz = sz;
+
+       return ret;
+}
+
+/**
  * create_specid_event() - Create the first event in the eventlog
  *
  * @dev:                       tpm device
@@ -1275,6 +1676,14 @@ void tcg2_uninit(void)
        event_log.buffer = NULL;
        efi_free_pool(event_log.final_buffer);
        event_log.final_buffer = NULL;
+
+       if (!is_tcg2_protocol_installed())
+               return;
+
+       ret = efi_remove_protocol(efi_root, &efi_guid_tcg2_protocol,
+                                 (void *)&efi_tcg2_protocol);
+       if (ret != EFI_SUCCESS)
+               log_err("Failed to remove EFI TCG2 protocol\n");
 }
 
 /**
@@ -1313,69 +1722,6 @@ out:
 }
 
 /**
- * efi_init_event_log() - initialize an eventlog
- */
-static efi_status_t efi_init_event_log(void)
-{
-       /*
-        * vendor_info_size is currently set to 0, we need to change the length
-        * and allocate the flexible array member if this changes
-        */
-       struct tcg_pcr_event *event_header = NULL;
-       struct udevice *dev;
-       size_t spec_event_size;
-       efi_status_t ret;
-
-       ret = platform_get_tpm2_device(&dev);
-       if (ret != EFI_SUCCESS)
-               goto out;
-
-       ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, TPM2_EVENT_LOG_SIZE,
-                               (void **)&event_log.buffer);
-       if (ret != EFI_SUCCESS)
-               goto out;
-
-       /*
-        * initialize log area as 0xff so the OS can easily figure out the
-        * last log entry
-        */
-       memset(event_log.buffer, 0xff, TPM2_EVENT_LOG_SIZE);
-       event_log.pos = 0;
-       event_log.last_event_size = 0;
-       event_log.get_event_called = false;
-       event_log.ebs_called = false;
-       event_log.truncated = false;
-
-       /*
-        * The log header is defined to be in SHA1 event log entry format.
-        * Setup event header
-        */
-       event_header =  (struct tcg_pcr_event *)event_log.buffer;
-       put_unaligned_le32(0, &event_header->pcr_index);
-       put_unaligned_le32(EV_NO_ACTION, &event_header->event_type);
-       memset(&event_header->digest, 0, sizeof(event_header->digest));
-       ret = create_specid_event(dev, (void *)((uintptr_t)event_log.buffer + sizeof(*event_header)),
-                                 &spec_event_size);
-       if (ret != EFI_SUCCESS)
-               goto free_pool;
-       put_unaligned_le32(spec_event_size, &event_header->event_size);
-       event_log.pos = spec_event_size + sizeof(*event_header);
-       event_log.last_event_size = event_log.pos;
-
-       ret = create_final_event();
-       if (ret != EFI_SUCCESS)
-               goto free_pool;
-
-out:
-       return ret;
-
-free_pool:
-       efi_free_pool(event_log.buffer);
-       event_log.buffer = NULL;
-       return ret;
-}
-
-/**
  * tcg2_measure_event() - common function to add event log and extend PCR
  *
  * @dev:               TPM device
@@ -1428,6 +1774,93 @@ static efi_status_t efi_append_scrtm_version(struct udevice *dev)
 }
 
 /**
+ * efi_init_event_log() - initialize an eventlog
+ *
+ * Return:             status code
+ */
+static efi_status_t efi_init_event_log(void)
+{
+       /*
+        * vendor_info_size is currently set to 0, we need to change the length
+        * and allocate the flexible array member if this changes
+        */
+       struct tcg_pcr_event *event_header = NULL;
+       struct udevice *dev;
+       size_t spec_event_size;
+       efi_status_t ret;
+
+       ret = platform_get_tpm2_device(&dev);
+       if (ret != EFI_SUCCESS)
+               return ret;
+
+       ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, TPM2_EVENT_LOG_SIZE,
+                               (void **)&event_log.buffer);
+       if (ret != EFI_SUCCESS)
+               return ret;
+
+       /*
+        * initialize log area as 0xff so the OS can easily figure out the
+        * last log entry
+        */
+       memset(event_log.buffer, 0xff, TPM2_EVENT_LOG_SIZE);
+
+       /*
+        * The log header is defined to be in SHA1 event log entry format.
+        * Setup event header
+        */
+       event_header =  (struct tcg_pcr_event *)event_log.buffer;
+       event_log.pos = 0;
+       event_log.last_event_size = 0;
+       event_log.get_event_called = false;
+       event_log.ebs_called = false;
+       event_log.truncated = false;
+
+       /*
+        * Check if earlier firmware have passed any eventlog. Different
+        * platforms can use different ways to do so.
+        */
+       ret = tcg2_get_fw_eventlog(dev, event_log.buffer, &event_log.pos);
+       /*
+        * If earlier firmware hasn't passed any eventlog, go ahead and
+        * create the eventlog header.
+        */
+       if (ret == EFI_NOT_FOUND) {
+               put_unaligned_le32(0, &event_header->pcr_index);
+               put_unaligned_le32(EV_NO_ACTION, &event_header->event_type);
+               memset(&event_header->digest, 0, sizeof(event_header->digest));
+               ret = create_specid_event(dev,
+                                         (void *)((uintptr_t)event_log.buffer +
+                                                  sizeof(*event_header)),
+                                         &spec_event_size);
+               if (ret != EFI_SUCCESS)
+                       goto free_pool;
+               put_unaligned_le32(spec_event_size, &event_header->event_size);
+               event_log.pos = spec_event_size + sizeof(*event_header);
+               event_log.last_event_size = event_log.pos;
+
+               /*
+                * Add SCRTM version to the log if previous firmmware
+                * doesn't pass an eventlog.
+                */
+               ret = efi_append_scrtm_version(dev);
+       }
+
+       if (ret != EFI_SUCCESS)
+               goto free_pool;
+
+       ret = create_final_event();
+       if (ret != EFI_SUCCESS)
+               goto free_pool;
+
+       return ret;
+
+free_pool:
+       efi_free_pool(event_log.buffer);
+       event_log.buffer = NULL;
+       return ret;
+}
+
+/**
  * tcg2_measure_variable() - add variable event log and extend PCR
  *
  * @dev:               TPM device
@@ -1759,12 +2192,15 @@ efi_status_t efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *ha
        u32 event = 0;
        struct smbios_entry *entry;
 
+       if (!is_tcg2_protocol_installed())
+               return EFI_SUCCESS;
+
        if (tcg2_efi_app_invoked)
                return EFI_SUCCESS;
 
        ret = platform_get_tpm2_device(&dev);
        if (ret != EFI_SUCCESS)
-               return ret;
+               return EFI_SECURITY_VIOLATION;
 
        ret = tcg2_measure_boot_variable(dev);
        if (ret != EFI_SUCCESS)
@@ -1809,6 +2245,9 @@ efi_status_t efi_tcg2_measure_efi_app_exit(void)
        efi_status_t ret;
        struct udevice *dev;
 
+       if (!is_tcg2_protocol_installed())
+               return EFI_SUCCESS;
+
        ret = platform_get_tpm2_device(&dev);
        if (ret != EFI_SUCCESS)
                return ret;
@@ -1834,6 +2273,12 @@ efi_tcg2_notify_exit_boot_services(struct efi_event *event, void *context)
        EFI_ENTRY("%p, %p", event, context);
 
        event_log.ebs_called = true;
+
+       if (!is_tcg2_protocol_installed()) {
+               ret = EFI_SUCCESS;
+               goto out;
+       }
+
        ret = platform_get_tpm2_device(&dev);
        if (ret != EFI_SUCCESS)
                goto out;
@@ -1863,6 +2308,9 @@ efi_status_t efi_tcg2_notify_exit_boot_services_failed(void)
        struct udevice *dev;
        efi_status_t ret;
 
+       if (!is_tcg2_protocol_installed())
+               return EFI_SUCCESS;
+
        ret = platform_get_tpm2_device(&dev);
        if (ret != EFI_SUCCESS)
                goto out;
@@ -1933,11 +2381,36 @@ error:
 }
 
 /**
+ * efi_tcg2_do_initial_measurement() - do initial measurement
+ *
+ * Return:     status code
+ */
+efi_status_t efi_tcg2_do_initial_measurement(void)
+{
+       efi_status_t ret;
+       struct udevice *dev;
+
+       if (!is_tcg2_protocol_installed())
+               return EFI_SUCCESS;
+
+       ret = platform_get_tpm2_device(&dev);
+       if (ret != EFI_SUCCESS)
+               return EFI_SECURITY_VIOLATION;
+
+       ret = tcg2_measure_secure_boot_variable(dev);
+       if (ret != EFI_SUCCESS)
+               goto out;
+
+out:
+       return ret;
+}
+
+/**
  * efi_tcg2_register() - register EFI_TCG2_PROTOCOL
  *
  * If a TPM2 device is available, the TPM TCG2 Protocol is registered
  *
- * Return:     An error status is only returned if adding the protocol fails.
+ * Return:     status code
  */
 efi_status_t efi_tcg2_register(void)
 {
@@ -1960,10 +2433,6 @@ efi_status_t efi_tcg2_register(void)
        }
 
        ret = efi_init_event_log();
-       if (ret != EFI_SUCCESS)
-               goto fail;
-
-       ret = efi_append_scrtm_version(dev);
        if (ret != EFI_SUCCESS) {
                tcg2_uninit();
                goto fail;
@@ -1984,24 +2453,9 @@ efi_status_t efi_tcg2_register(void)
                goto fail;
        }
 
-       ret = tcg2_measure_secure_boot_variable(dev);
-       if (ret != EFI_SUCCESS) {
-               tcg2_uninit();
-               goto fail;
-       }
-
        return ret;
 
 fail:
        log_err("Cannot install EFI_TCG2_PROTOCOL\n");
-       /*
-        * Return EFI_SUCCESS and don't stop the EFI subsystem.
-        * That's done for 2 reasons
-        * - If the protocol is not installed the PCRs won't be extended.  So
-        *   someone later in the boot flow will notice that and take the
-        *   necessary actions.
-        * - The TPM sandbox is limited and we won't be able to run any efi
-        *   related tests with TCG2 enabled
-        */
-       return EFI_SUCCESS;
+       return ret;
 }
index 2e7b27b..1bf6278 100644 (file)
@@ -254,7 +254,8 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data,
 }
 
 u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz,
-                 void *data, unsigned int *updates)
+                 u16 algorithm, void *data, u32 digest_len,
+                 unsigned int *updates)
 {
        u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8));
        u8 command_v2[COMMAND_BUFFER_SIZE] = {
@@ -264,7 +265,7 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz,
 
                /* TPML_PCR_SELECTION */
                tpm_u32(1),                     /* Number of selections */
-               tpm_u16(TPM2_ALG_SHA256),       /* Algorithm of the hash */
+               tpm_u16(algorithm),             /* Algorithm of the hash */
                idx_array_sz,                   /* Array size for selection */
                /* bitmap(idx)                     Selected PCR bitmap */
        };
@@ -283,10 +284,13 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz,
        if (ret)
                return ret;
 
+       if (digest_len > response_len)
+               return TPM_LIB_ERROR;
+
        if (unpack_byte_string(response, response_len, "ds",
                               10, &counter,
-                              response_len - TPM2_DIGEST_LEN, data,
-                              TPM2_DIGEST_LEN))
+                              response_len - digest_len, data,
+                              digest_len))
                return TPM_LIB_ERROR;
 
        if (updates)
index 548649f..d46552f 100644 (file)
@@ -37,6 +37,7 @@ obj-$(CONFIG_DMA) += dma.o
 obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o
 obj-$(CONFIG_DM_DSA) += dsa.o
 obj-$(CONFIG_ECDSA_VERIFY) += ecdsa.o
+obj-$(CONFIG_EFI_MEDIA_SANDBOX) += efi_media.o
 obj-$(CONFIG_DM_ETH) += eth.o
 ifneq ($(CONFIG_EFI_PARTITION),)
 obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fastboot.o
diff --git a/test/dm/efi_media.c b/test/dm/efi_media.c
new file mode 100644 (file)
index 0000000..e343a0e
--- /dev/null
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for EFI_MEDIA uclass
+ *
+ * Copyright 2021 Google LLC
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+/* Test that we can use the EFI_MEDIA uclass */
+static int dm_test_efi_media(struct unit_test_state *uts)
+{
+       struct udevice *dev;
+
+       ut_assertok(uclass_first_device_err(UCLASS_EFI_MEDIA, &dev));
+
+       return 0;
+}
+DM_TEST(dm_test_efi_media, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
index 0161a6e..a48cd32 100644 (file)
@@ -210,3 +210,23 @@ def test_efi_selftest_text_input_ex(u_boot_console):
     if m != 0:
         raise Exception('Failures occurred during the EFI selftest')
     u_boot_console.restart_uboot()
+
+@pytest.mark.buildconfigspec('cmd_bootefi_selftest')
+@pytest.mark.buildconfigspec('efi_tcg2_protocol')
+def test_efi_selftest_tcg2(u_boot_console):
+    """Test the EFI_TCG2 PROTOCOL
+
+    :param u_boot_console: U-Boot console
+
+    This function executes the 'tcg2' unit test.
+    """
+    u_boot_console.restart_uboot()
+    u_boot_console.run_command(cmd='setenv efi_selftest list')
+    output = u_boot_console.run_command('bootefi selftest')
+    assert '\'tcg2\'' in output
+    u_boot_console.run_command(cmd='setenv efi_selftest tcg2')
+    u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False)
+    m = u_boot_console.p.expect(['Summary: 0 failures', 'Press any key'])
+    if m != 0:
+        raise Exception('Failures occurred during the EFI selftest')
+    u_boot_console.restart_uboot()
index 7c89f5f..d2ad6f9 100644 (file)
@@ -186,6 +186,7 @@ def test_tpm2_change_auth(u_boot_console):
     u_boot_console.run_command('tpm2 clear TPM2_RH_PLATFORM')
     assert output.endswith('0')
 
+@pytest.mark.buildconfigspec('sandbox')
 @pytest.mark.buildconfigspec('cmd_tpm_v2')
 def test_tpm2_get_capability(u_boot_console):
     """Execute a TPM_GetCapability command.