Merge https://gitlab.denx.de/u-boot/custodians/u-boot-riscv
authorTom Rini <trini@konsulko.com>
Mon, 18 Jan 2021 13:04:28 +0000 (08:04 -0500)
committerTom Rini <trini@konsulko.com>
Mon, 18 Jan 2021 13:04:28 +0000 (08:04 -0500)
- Update qemu-riscv.rst build instructions.
- Add support for SPI on Kendryte K210.
- Add Microchip PolarFire SoC Icicle Kit support.
- Add support for an early timer.
  - Select TIMER_EARLY to avoid infinite recursion for Trace.

35 files changed:
arch/riscv/Kconfig
arch/riscv/dts/Makefile
arch/riscv/dts/microchip-mpfs-icicle-kit-u-boot.dtsi [new file with mode: 0644]
arch/riscv/dts/microchip-mpfs-icicle-kit.dts [new file with mode: 0644]
arch/riscv/include/asm/types.h
board/microchip/mpfs_icicle/Kconfig
board/microchip/mpfs_icicle/mpfs_icicle.c
board/sipeed/maix/Kconfig
configs/microchip_mpfs_icicle_defconfig
configs/sipeed_maix_bitm_defconfig
doc/board/emulation/qemu-riscv.rst
doc/board/index.rst
doc/board/microchip/index.rst [new file with mode: 0644]
doc/board/microchip/mpfs_icicle.rst [new file with mode: 0644]
doc/board/sipeed/maix.rst
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/microchip/Kconfig [new file with mode: 0644]
drivers/clk/microchip/Makefile [new file with mode: 0644]
drivers/clk/microchip/mpfs_clk.c [new file with mode: 0644]
drivers/clk/microchip/mpfs_clk.h [new file with mode: 0644]
drivers/clk/microchip/mpfs_clk_cfg.c [new file with mode: 0644]
drivers/clk/microchip/mpfs_clk_periph.c [new file with mode: 0644]
drivers/net/macb.c
drivers/net/macb.h
drivers/timer/andes_plmt_timer.c
drivers/timer/riscv_timer.c
drivers/timer/sifive_clint_timer.c
include/configs/ax25-ae350.h
include/configs/microchip_mpfs_icicle.h
include/configs/qemu-riscv.h
include/configs/sifive-fu540.h
include/configs/sipeed-maix.h
include/dt-bindings/clock/microchip-mpfs-clock.h [new file with mode: 0644]
lib/Kconfig

index 30b0540..55eaee2 100644 (file)
@@ -152,6 +152,10 @@ config 32BIT
 config 64BIT
        bool
 
+config DMA_ADDR_T_64BIT
+       bool
+       default y if 64BIT
+
 config SIFIVE_CLINT
        bool
        depends on RISCV_MMODE || SPL_RISCV_MMODE
index 3a6f96c..01331b0 100644 (file)
@@ -3,6 +3,7 @@
 dtb-$(CONFIG_TARGET_AX25_AE350) += ae350_32.dtb ae350_64.dtb
 dtb-$(CONFIG_TARGET_SIFIVE_FU540) += hifive-unleashed-a00.dtb
 dtb-$(CONFIG_TARGET_SIPEED_MAIX) += k210-maix-bit.dtb
+dtb-$(CONFIG_TARGET_MICROCHIP_ICICLE) += microchip-mpfs-icicle-kit.dtb
 
 targets += $(dtb-y)
 
diff --git a/arch/riscv/dts/microchip-mpfs-icicle-kit-u-boot.dtsi b/arch/riscv/dts/microchip-mpfs-icicle-kit-u-boot.dtsi
new file mode 100644 (file)
index 0000000..f60283f
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+
+/ {
+       aliases {
+               cpu1 = &cpu1;
+               cpu2 = &cpu2;
+               cpu3 = &cpu3;
+               cpu4 = &cpu4;
+       };
+};
diff --git a/arch/riscv/dts/microchip-mpfs-icicle-kit.dts b/arch/riscv/dts/microchip-mpfs-icicle-kit.dts
new file mode 100644 (file)
index 0000000..e2b9dec
--- /dev/null
@@ -0,0 +1,421 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/* Copyright (c) 2020 Microchip Technology Inc */
+
+/dts-v1/;
+#include "dt-bindings/clock/microchip-mpfs-clock.h"
+
+/* 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";
+
+       aliases {
+               serial0 = &uart0;
+               ethernet0 = &emac1;
+       };
+
+       chosen {
+               stdout-path = "serial0";
+       };
+
+       cpucomplex: cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               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;
+                       };
+               };
+               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;
+                       };
+               };
+               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;
+                       };
+               };
+       };
+       refclk: refclk {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <600000000>;
+               clock-output-names = "msspllclk";
+       };
+       ddr: memory@80000000 {
+               device_type = "memory";
+               reg = <0x0 0x80000000 0x0 0x40000000>;
+               clocks = <&clkcfg CLK_DDRC>;
+       };
+       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>;
+                       clock-frequency = <150000000>;
+                       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>;
+                       clock-frequency = <150000000>;
+                       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>;
+                       clock-frequency = <150000000>;
+                       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>;
+                       clock-frequency = <150000000>;
+                       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";
+
+                       #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";
+               };
+       };
+};
index 403cf9a..b800b2d 100644 (file)
@@ -29,7 +29,11 @@ typedef unsigned short umode_t;
 
 #include <stddef.h>
 
+#ifdef CONFIG_DMA_ADDR_T_64BIT
+typedef u64 dma_addr_t;
+#else
 typedef u32 dma_addr_t;
+#endif
 
 typedef unsigned long phys_addr_t;
 typedef unsigned long phys_size_t;
index bf8e1a1..4678462 100644 (file)
@@ -20,7 +20,30 @@ config BOARD_SPECIFIC_OPTIONS # dummy
        def_bool y
        select GENERIC_RISCV
        select BOARD_EARLY_INIT_F
+       select BOARD_LATE_INIT
        imply SMP
+       imply CLK_CCF
+       imply CLK_MPFS
        imply SYS_NS16550
+       imply CMD_DHCP
+       imply CMD_EXT2
+       imply CMD_EXT4
+       imply CMD_FAT
+       imply CMD_FS_GENERIC
+       imply CMD_NET
+       imply CMD_PING
+       imply CMD_MMC
+       imply DOS_PARTITION
+       imply EFI_PARTITION
+       imply IP_DYN
+       imply ISO_PARTITION
+       imply MACB
+       imply MII
+       imply PHY_LIB
+       imply PHY_VITESSE
+       imply MMC
+       imply MMC_WRITE
+       imply MMC_SDHCI
+       imply MMC_SDHCI_CADENCE
 
 endif
index 8381361..0e34409 100644 (file)
@@ -6,10 +6,49 @@
 
 #include <common.h>
 #include <dm.h>
+#include <env.h>
 #include <init.h>
 #include <asm/io.h>
 
-#define MPFS_SYSREG_SOFT_RESET ((unsigned int *)0x20002088)
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MPFS_SYSREG_SOFT_RESET         ((unsigned int *)0x20002088)
+#define MPFS_SYS_SERVICE_CR            ((unsigned int *)0x37020050)
+#define MPFS_SYS_SERVICE_SR            ((unsigned int *)0x37020054)
+#define MPFS_SYS_SERVICE_MAILBOX       ((unsigned char *)0x37020800)
+
+#define PERIPH_RESET_VALUE             0x1e8u
+#define SERVICE_CR_REQ                 0x1u
+#define SERVICE_SR_BUSY                        0x2u
+
+static void read_device_serial_number(u8 *response, u8 response_size)
+{
+       u8 idx;
+       u8 *response_buf;
+       unsigned int val;
+
+       response_buf = (u8 *)response;
+
+       writel(SERVICE_CR_REQ, MPFS_SYS_SERVICE_CR);
+       /*
+        * REQ bit will remain set till the system controller starts
+        * processing.
+        */
+       do {
+               val = readl(MPFS_SYS_SERVICE_CR);
+       } while (SERVICE_CR_REQ == (val & SERVICE_CR_REQ));
+
+       /*
+        * Once system controller starts processing the busy bit will
+        * go high and service is completed when busy bit is gone low
+        */
+       do {
+               val = readl(MPFS_SYS_SERVICE_SR);
+       } while (SERVICE_SR_BUSY == (val & SERVICE_SR_BUSY));
+
+       for (idx = 0; idx < response_size; idx++)
+               response_buf[idx] = readb(MPFS_SYS_SERVICE_MAILBOX + idx);
+}
 
 int board_init(void)
 {
@@ -22,10 +61,64 @@ int board_early_init_f(void)
 {
        unsigned int val;
 
-       /* Reset uart peripheral */
+       /* Reset uart, mmc peripheral */
        val = readl(MPFS_SYSREG_SOFT_RESET);
-       val = (val & ~(1u << 5u));
+       val = (val & ~(PERIPH_RESET_VALUE));
        writel(val, MPFS_SYSREG_SOFT_RESET);
 
        return 0;
 }
+
+int board_late_init(void)
+{
+       u32 ret;
+       u32 node;
+       u8 idx;
+       u8 device_serial_number[16] = { 0 };
+       unsigned char mac_addr[6];
+       char icicle_mac_addr[20];
+       void *blob = (void *)gd->fdt_blob;
+
+       node = fdt_path_offset(blob, "ethernet0");
+       if (node < 0) {
+               printf("No ethernet0 path offset\n");
+               return -ENODEV;
+       }
+
+       ret = fdtdec_get_byte_array(blob, node, "local-mac-address", mac_addr, 6);
+       if (ret) {
+               printf("No local-mac-address property\n");
+               return -EINVAL;
+       }
+
+       read_device_serial_number(device_serial_number, 16);
+
+       /* Update MAC address with device serial number */
+       mac_addr[0] = 0x00;
+       mac_addr[1] = 0x04;
+       mac_addr[2] = 0xA3;
+       mac_addr[3] = device_serial_number[2];
+       mac_addr[4] = device_serial_number[1];
+       mac_addr[5] = device_serial_number[0];
+
+       ret = fdt_setprop(blob, node, "local-mac-address", mac_addr, 6);
+       if (ret) {
+               printf("Error setting local-mac-address property\n");
+               return -ENODEV;
+       }
+
+       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_addr", icicle_mac_addr);
+
+       return 0;
+}
index 4c42dd2..2cdea8e 100644 (file)
@@ -53,4 +53,20 @@ config BOARD_SPECIFIC_OPTIONS
        imply CMD_GPIO
        imply LED
        imply LED_GPIO
+       imply SPI
+       imply DESIGNWARE_SPI
+       imply SPI_FLASH_GIGADEVICE
+       imply SPI_FLASH_WINBOND
+       imply DM_MTD
+       imply SPI_FLASH_MTD
+       imply CMD_MTD
+       imply ENV_IS_IN_SPI_FLASH
+       imply MMC
+       imply MMC_BROKEN_CD
+       imply MMC_SPI
+       imply CMD_MMC
+       imply DOS_PARTITION
+       imply EFI_PARTITION
+       imply CMD_PART
+       imply CMD_FS_GENERIC
 endif
index 2977966..9abbc18 100644 (file)
@@ -1,12 +1,15 @@
 CONFIG_RISCV=y
 CONFIG_ENV_SIZE=0x2000
 CONFIG_TARGET_MICROCHIP_ICICLE=y
-CONFIG_NR_CPUS=5
 CONFIG_ARCH_RV64I=y
+CONFIG_RISCV_SMODE=y
+CONFIG_SBI_V01=y
+CONFIG_DEFAULT_DEVICE_TREE="microchip-mpfs-icicle-kit"
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DISPLAY_BOARDINFO=y
 CONFIG_FIT=y
-CONFIG_BOOTDELAY=3
 CONFIG_SYS_PROMPT="RISC-V # "
-CONFIG_OF_PRIOR_STAGE=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_BOOTP_SEND_HOSTNAME=y
 CONFIG_DM_MTD=y
index 459bf0d..210848c 100644 (file)
@@ -1,8 +1,19 @@
 CONFIG_RISCV=y
+CONFIG_ENV_SIZE=0x1000
+CONFIG_ENV_OFFSET=0xfff000
+CONFIG_ENV_SECT_SIZE=0x1000
 CONFIG_TARGET_SIPEED_MAIX=y
 CONFIG_ARCH_RV64I=y
 CONFIG_STACK_SIZE=0x100000
+CONFIG_USE_BOOTCOMMAND=y
+CONFIG_BOOTCOMMAND="run k210_bootcmd"
+CONFIG_HUSH_PARSER=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi3:0"
+CONFIG_MTDPARTS_DEFAULT="nor0:1M(u-boot),0x1000@0xfff000(env)"
 # CONFIG_NET is not set
 # CONFIG_INPUT is not set
+CONFIG_SF_DEFAULT_BUS=3
 # CONFIG_DM_ETH is not set
+CONFIG_FS_EXT4=y
+CONFIG_FS_FAT=y
 # CONFIG_EFI_LOADER is not set
index 3acd406..4b8e104 100644 (file)
@@ -73,7 +73,7 @@ supported by U-Boot. Clone the OpenSBI repository and run the following command.
 
     git clone https://github.com/riscv/opensbi.git
     cd opensbi
-    make PLATFORM=qemu/virt
+    make PLATFORM=generic
 
 See the OpenSBI documentation for full details:
 https://github.com/riscv/opensbi/blob/master/docs/platform/qemu_virt.md
index 915f1be..08c167b 100644 (file)
@@ -17,6 +17,7 @@ Board-specific doc
    google/index
    intel/index
    kontron/index
+   microchip/index
    renesas/index
    rockchip/index
    sifive/index
diff --git a/doc/board/microchip/index.rst b/doc/board/microchip/index.rst
new file mode 100644 (file)
index 0000000..affc5a9
--- /dev/null
@@ -0,0 +1,9 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Microchip
+=========
+
+.. toctree::
+   :maxdepth: 2
+
+   mpfs_icicle
diff --git a/doc/board/microchip/mpfs_icicle.rst b/doc/board/microchip/mpfs_icicle.rst
new file mode 100644 (file)
index 0000000..7489761
--- /dev/null
@@ -0,0 +1,810 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Microchip PolarFire SoC Icicle Kit
+==================================
+
+RISC-V PolarFire SoC
+--------------------
+The PolarFire SoC is the 4+1 64-bit RISC-V SoC from Microchip.
+
+The Icicle Kit development platform is based on PolarFire SoC and capable
+of running Linux.
+
+Mainline support
+----------------
+The support for following drivers are already enabled:
+
+1. NS16550 UART Driver.
+2. Microchip Clock Driver.
+3. Cadence MACB ethernet driver for networking support.
+4. Cadence MMC Driver for eMMC/SD support.
+
+Booting from eMMC using HSS
+---------------------------
+
+Building U-Boot
+---------------
+
+1. Add the RISC-V toolchain to your PATH.
+2. Setup ARCH & cross compilation environment variable:
+
+.. code-block:: none
+
+   export CROSS_COMPILE=<riscv64 toolchain prefix>
+
+3. make microchip_mpfs_icicle_defconfig
+4. make
+
+Flashing
+--------
+
+The current U-Boot port is supported in S-mode only and loaded from DRAM.
+
+A prior stage M-mode firmware/bootloader (e.g HSS with OpenSBI) is required to
+boot the u-boot.bin in S-mode.
+
+Currently, the u-boot.bin is used as a payload of the HSS firmware (Microchip
+boot-flow) and OpenSBI generic platform fw_payload.bin (with u-boot.bin embedded)
+as HSS payload (Custom boot-flow)
+
+Microchip boot-flow
+-------------------
+HSS with OpenSBI (M-Mode) -> U-Boot (S-Mode) -> Linux (S-Mode)
+
+Build the HSS (Hart Software Services) - Microchip boot-flow
+------------------------------------------------------------
+(Note: HSS git repo is at https://github.com/polarfire-soc/hart-software-services)
+
+1. Configure
+
+.. code-block:: none
+
+   make BOARD=icicle-kit-es config
+
+Alternatively, copy the default config for Microchip boot-flow.
+
+.. code-block:: none
+
+   cp boards/icicle-kit-es/def_config .config
+
+2. make BOARD=icicle-kit-es
+3. In the Default subdirectory, the standard build will create hss.elf and
+   various binary formats (hss.hex and hss.bin).
+
+The FPGA design will use the hss.hex or hss.bin.
+
+FPGA design with HSS programming file
+-------------------------------------
+https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/boards/mpfs-icicle-kit-es/updating-icicle-kit/updating-icicle-kit-design-and-linux.md
+
+The HSS firmware runs from the PolarFire SoC eNVM on reset.
+
+Creating the HSS payload - Microchip boot-flow
+----------------------------------------------
+1. You will be creating a payload from `u-boot-dtb.bin`.
+   Copy this file to the HSS/tools/hss-payload-generator/test directory.
+2. Go to hss-payload-generator source directory.
+
+.. code-block:: none
+
+   cd hart-software-services/tools/hss-payload-generator
+
+3. Edit test/uboot.yaml file for hart entry points and correct name of the binary file.
+
+       hart-entry-points: {u54_1: '0x80200000', u54_2: '0x80200000', u54_3: '0x80200000', u54_4: '0x80200000'}
+
+       payloads:
+       test/u-boot-dtb.bin: {exec-addr: '0x80200000', owner-hart: u54_1, secondary-hart: u54_2, secondary-hart: u54_3, secondary-hart: u54_4, priv-mode: prv_s}
+
+4. Generate payload
+
+.. code-block:: none
+
+   ./hss-payload-generator -c test/uboot.yaml payload.bin
+
+Once the payload binary is generated, it should be copied to the eMMC.
+
+Please refer to HSS documenation to build the HSS firmware for payload.
+(Note: HSS git repo is at https://github.com/polarfire-soc/hart-software-services/blob/master/tools/hss-payload-generator/README.md)
+
+Custom boot-flow
+----------------
+HSS without OpenSBI (M-Mode) -> OpenSBI (M-Mode) -> U-Boot (S-Mode) -> Linux (S-Mode)
+
+Build OpenSBI
+-------------
+
+1. Get the OpenSBI source
+
+.. code-block:: none
+
+   git clone https://github.com/riscv/opensbi.git
+   cd opensbi
+
+2. Build
+
+.. code-block:: none
+
+   make PLATFORM=generic FW_PAYLOAD_PATH=<u-boot-directory>/u-boot.bin
+   FW_FDT_PATH=<u-boot-directory>/arch/riscv/dts/microchip-mpfs-icicle-kit-.dtb
+
+3. Output "fw_payload.bin" file available at
+   "<opensbi-directory>/build/platform/generic/firmware/fw_payload.bin"
+
+Build the HSS (Hart Software Services)- Custom boot-flow
+--------------------------------------------------------
+(Note: HSS git repo is at https://github.com/polarfire-soc/hart-software-services)
+
+1. Configure
+
+.. code-block:: none
+
+   make BOARD=icicle-kit-es config
+
+Alternatively, copy the default custom config for Custom boot-flow.
+
+.. code-block:: none
+
+   cp boards/icicle-kit-es/def_config_custom .config
+
+2. make BOARD=icicle-kit-es
+3. In the Default subdirectory, the standard build will create hss.elf and
+   various binary formats (hss.hex and hss.bin).
+
+The FPGA design will use the hss.hex or hss.bin.
+
+Creating the HSS payload - Custom boot-flow
+-------------------------------------------
+1. You will be creating a payload from `fw_payload.bin`.
+   Copy this file to the HSS/tools/hss-payload-generator/test directory.
+2. Go to hss-payload-generator source directory.
+
+.. code-block:: none
+
+   cd hart-software-services/tools/hss-payload-generator
+
+3. Edit test/uboot.yaml file for hart entry points and correct name of the binary file.
+
+       hart-entry-points: {u54_1: '0x80000000', u54_2: '0x80000000', u54_3: '0x80000000', u54_4: '0x80000000'}
+
+       payloads:
+       test/fw_payload.bin: {exec-addr: '0x80000000', owner-hart: u54_1, secondary-hart: u54_2, secondary-hart: u54_3, secondary-hart: u54_4, priv-mode: prv_m}
+
+4. Generate payload
+
+.. code-block:: none
+
+   ./hss-payload-generator -c test/uboot.yaml payload.bin
+
+Once the payload binary is generated, it should be copied to the eMMC.
+
+Please refer to HSS documenation to build the HSS firmware for payload.
+(Note: HSS git repo is at https://github.com/polarfire-soc/hart-software-services/blob/master/tools/hss-payload-generator/README.md
+and also refer the HSS payload generator at https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/software-development/hss-payloads.md)
+
+eMMC
+----
+Program eMMC with payload binary is explained in the PolarFire SoC documentation.
+(Note: PolarFire SoC Documentation git repo is at https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/boards/mpfs-icicle-kit-es/updating-icicle-kit/updating-icicle-kit-design-and-linux.md#eMMC)
+
+Once the payload image is copied to the eMMC, press CTRL+C in the HSS command
+line interface, then type 'boot' and enter to boot the newly copied image.
+
+.. code-block:: none
+
+    sudo dd if=<payload_binary> of=/dev/sdX bs=512
+
+GUID type
+---------
+The HSS always picks up HSS payload from a GPT partition with
+GIUD type "21686148-6449-6E6F-744E-656564454649" or sector '0' of the eMMC if no
+GPT partition.
+
+Booting
+-------
+You should see the U-Boot prompt on UART0.
+
+Sample boot log from MPFS Icicle Kit
+------------------------------------
+
+.. code-block:: none
+
+   U-Boot 2021.01-00314-g7303332537-dirty (Jan 14 2021 - 10:09:43 +0530)
+
+   CPU:   rv64imafdc
+   Model: Microchip MPFS Icicle Kit
+   DRAM:  1 GiB
+   MMC:   sdhc@20008000: 0
+   In:    serial@20100000
+   Out:   serial@20100000
+   Err:   serial@20100000
+   Net:   eth0: ethernet@20112000
+   Hit any key to stop autoboot:  0
+
+Now you can configure your networking, tftp server and use tftp boot method to
+load uImage (with initramfs).
+
+.. code-block:: none
+
+   RISC-V # setenv kernel_addr_r 0x80200000
+   RISC-V # setenv fdt_addr_r 0x82200000
+
+   RISC-V # setenv ipaddr 192.168.1.5
+   RISC-V # setenv netmask 255.255.255.0
+   RISC-V # setenv serverip 192.168.1.3
+   RISC-V # setenv gateway 192.168.1.1
+
+   RISC-V # tftpboot ${kernel_addr_r} uImage
+   ethernet@20112000: PHY present at 9
+   ethernet@20112000: Starting autonegotiation...
+   ethernet@20112000: Autonegotiation complete
+   ethernet@20112000: link up, 1000Mbps full-duplex (lpa: 0x7800)
+   Using ethernet@20112000 device
+   TFTP from server 192.168.1.3; our IP address is 192.168.1.5
+   Filename 'uImage'.
+   Load address: 0x80200000
+   Loading: #################################################################
+           #################################################################
+           #################################################################
+           #################################################################
+           #################################################################
+           #################################################################
+           #################################################################
+           #################################################################
+           #################################################################
+           #################################################################
+           #################################################################
+           #################################################################
+           #################################################################
+           #################################################################
+           #################################################################
+           ############
+           6.4 MiB/s
+   done
+   Bytes transferred = 14482480 (dcfc30 hex)
+
+   RISC-V # tftpboot ${fdt_addr_r} microchip-mpfs-icicle-kit.dtb
+   ethernet@20112000: PHY present at 9
+   ethernet@20112000: Starting autonegotiation...
+   ethernet@20112000: Autonegotiation complete
+   ethernet@20112000: link up, 1000Mbps full-duplex (lpa: 0x7800)
+   Using ethernet@20112000 device
+   TFTP from server 192.168.1.3; our IP address is 192.168.1.5
+   Filename 'microchip-mpfs-icicle-kit.dtb'.
+   Load address: 0x82200000
+   Loading: #
+                       2.5 MiB/s
+   done
+   Bytes transferred = 10282 (282a hex)
+
+   RISC-V # bootm ${kernel_addr_r} - ${fdt_addr_r}
+   ## Booting kernel from Legacy Image at 80200000 ...
+               Image Name:   Linux
+               Image Type:   RISC-V Linux Kernel Image (uncompressed)
+               Data Size:    14482416 Bytes = 13.8 MiB
+               Load Address: 80200000
+               Entry Point:  80200000
+               Verifying Checksum ... OK
+   ## Flattened Device Tree blob at 82200000
+               Booting using the fdt blob at 0x82200000
+               Loading Kernel Image
+               Using Device Tree in place at 000000008fffa000, end 000000008ffff829 ... OK
+
+   Starting kernel ...
+
+   [    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
+   [    0.000000] Linux version 5.6.17 (padmarao@padmarao-VirtualBox) (gcc version 7.2.0 (GCC)) #2 SMP Tue Jun 16 21:27:50 IST 2020
+   [    0.000000] initrd not found or empty - disabling initrd
+   [    0.000000] Zone ranges:
+   [    0.000000]   DMA32    [mem 0x0000000080200000-0x00000000bfffffff]
+   [    0.000000]   Normal   empty
+   [    0.000000] Movable zone start for each node
+   [    0.000000] Early memory node ranges
+   [    0.000000]   node   0: [mem 0x0000000080200000-0x00000000bfffffff]
+   [    0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x00000000bfffffff]
+   [    0.000000] software IO TLB: mapped [mem 0xbb1f5000-0xbf1f5000] (64MB)
+   [    0.000000] elf_hwcap is 0x112d
+   [    0.000000] percpu: Embedded 14 pages/cpu s24856 r0 d32488 u57344
+   [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 258055
+   [    0.000000] Kernel command line: console=ttyS0,115200n8
+   [    0.000000] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
+   [    0.000000] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
+   [    0.000000] Sorting __ex_table...
+   [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
+   [    0.000000] Memory: 950308K/1046528K available (3289K kernel code, 212K rwdata, 900K rodata, 9476K init, 250K bss, 96220K reserved, 0K cma-reserved)
+   [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
+   [    0.000000] rcu: Hierarchical RCU implementation.
+   [    0.000000] rcu:         RCU event tracing is enabled.
+   [    0.000000] rcu:         RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
+   [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
+   [    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
+   [    0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0
+   [    0.000000] plic: mapped 186 interrupts with 4 handlers for 9 contexts.
+   [    0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [1]
+   [    0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x1d854df40, max_idle_ns: 3526361616960 ns
+   [    0.000015] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps every 2199023255500ns
+   [    0.000311] Calibrating delay loop (skipped), value calculated using timer frequency.. 2.00 BogoMIPS (lpj=10000)
+   [    0.000349] pid_max: default: 32768 minimum: 301
+   [    0.000846] Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
+   [    0.000964] Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
+   [    0.005630] rcu: Hierarchical SRCU implementation.
+   [    0.006901] smp: Bringing up secondary CPUs ...
+   [    0.012545] smp: Brought up 1 node, 4 CPUs
+   [    0.014431] devtmpfs: initialized
+   [    0.020526] random: get_random_bytes called from setup_net+0x36/0x192 with crng_init=0
+   [    0.020928] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
+   [    0.020999] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
+   [    0.022768] NET: Registered protocol family 16
+   [    0.035478] microchip-pfsoc-clkcfg 20002000.clkcfg: Registered PFSOC core clocks
+   [    0.048429] SCSI subsystem initialized
+   [    0.049694] pps_core: LinuxPPS API ver. 1 registered
+   [    0.049719] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
+   [    0.049780] PTP clock support registered
+   [    0.051781] clocksource: Switched to clocksource riscv_clocksource
+   [    0.055326] NET: Registered protocol family 2
+   [    0.056922] tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes, linear)
+   [    0.057053] TCP established hash table entries: 8192 (order: 4, 65536 bytes, linear)
+   [    0.057648] TCP bind hash table entries: 8192 (order: 5, 131072 bytes, linear)
+   [    0.058579] TCP: Hash tables configured (established 8192 bind 8192)
+   [    0.059648] UDP hash table entries: 512 (order: 2, 16384 bytes, linear)
+   [    0.059837] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear)
+   [    0.060707] NET: Registered protocol family 1
+   [    0.266229] workingset: timestamp_bits=62 max_order=18 bucket_order=0
+   [    0.287107] io scheduler mq-deadline registered
+   [    0.287140] io scheduler kyber registered
+   [    0.429601] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
+   [    0.433979] printk: console [ttyS0] disabled
+   [    0.434154] 20000000.serial: ttyS0 at MMIO 0x20000000 (irq = 18, base_baud = 9375000) is a 16550A
+   [    0.928039] printk: console [ttyS0] enabled
+   [    0.939804] libphy: Fixed MDIO Bus: probed
+   [    0.948702] libphy: MACB_mii_bus: probed
+   [    0.993698] macb 20112000.ethernet eth0: Cadence GEM rev 0x0107010c at 0x20112000 irq 21 (56:34:12:00:fc:00)
+   [    1.006751] mousedev: PS/2 mouse device common for all mice
+   [    1.013803] i2c /dev entries driver
+   [    1.019451] sdhci: Secure Digital Host Controller Interface driver
+   [    1.027242] sdhci: Copyright(c) Pierre Ossman
+   [    1.032731] sdhci-pltfm: SDHCI platform and OF driver helper
+   [    1.091826] mmc0: SDHCI controller on 20008000.sdhc [20008000.sdhc] using ADMA 64-bit
+   [    1.102738] NET: Registered protocol family 17
+   [    1.170326] Freeing unused kernel memory: 9476K
+   [    1.176067] This architecture does not have kernel memory protection.
+   [    1.184157] Run /init as init process
+   Starting logging: OK
+   Starting mdev...
+   /etc/init.d/S10mdev: line 21: can't create /proc/sys/kernel/hotplug: nonexiste[    1.331981] mmc0: mmc_select_hs200 failed, error -74
+   nt directory
+   [    1.355011] mmc0: new MMC card at address 0001
+   [    1.363981] mmcblk0: mmc0:0001 DG4008 7.28 GiB
+   [    1.372248] mmcblk0boot0: mmc0:0001 DG4008 partition 1 4.00 MiB
+   [    1.382292] mmcblk0boot1: mmc0:0001 DG4008 partition 2 4.00 MiB
+   [    1.390265] mmcblk0rpmb: mmc0:0001 DG4008 partition 3 4.00 MiB, chardev (251:0)
+   [    1.425234] GPT:Primary header thinks Alt. header is not at the end of the disk.
+   [    1.434656] GPT:2255809 != 15273599
+   [    1.439038] GPT:Alternate GPT header not at the end of the disk.
+   [    1.446671] GPT:2255809 != 15273599
+   [    1.451048] GPT: Use GNU Parted to correct GPT errors.
+   [    1.457755]  mmcblk0: p1 p2 p3
+   sort: /sys/devices/platform/Fixed: No such file or directory
+   modprobe: can't change directory to '/lib/modules': No such file or directory
+   Initializing random number generator... [    2.830198] random: dd: uninitialized urandom read (512 bytes read)
+   done.
+   Starting network...
+   [    3.061867] macb 20112000.ethernet eth0: PHY [20112000.ethernet-ffffffff:09] driver [Vitesse VSC8662] (irq=POLL)
+   [    3.074674] macb 20112000.ethernet eth0: configuring for phy/sgmii link mode
+   [    3.084263] pps pps0: new PPS source ptp0
+   [    3.089710] macb 20112000.ethernet: gem-ptp-timer ptp clock registered.
+   udhcpc (v1.24.2) started
+   Sending discover...
+   Sending discover...
+   [    6.380169] macb 20112000.ethernet eth0: Link is Up - 1Gbps/Full - flow control tx
+   Sending discover...
+   Sending select for 192.168.1.2...
+   Lease of 192.168.1.2 obtained, lease time 86400
+   deleting routers
+   adding dns 192.168.1.1
+   Starting dropbear sshd: [   11.385619] random: dropbear: uninitialized urandom read (32 bytes read)
+   OK
+
+   Welcome to Buildroot
+   buildroot login: root
+   Password:
+   #
+
+Booting U-Boot and Linux from eMMC
+----------------------------------
+
+FPGA design with HSS programming file and Linux Image
+-----------------------------------------------------
+https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/boards/mpfs-icicle-kit-es/updating-icicle-kit/updating-icicle-kit-design-and-linux.md
+
+The HSS firmware runs from the PolarFire SoC eNVM on reset.
+
+eMMC
+----
+Program eMMC with payload binary and Linux image is explained in the
+PolarFire SoC documentation.
+The payload binary should be copied to partition 2 of the eMMC.
+
+(Note: PolarFire SoC Documentation git repo is at https://github.com/polarfire-soc/polarfire-soc-documentation/blob/master/boards/mpfs-icicle-kit-es/updating-icicle-kit/updating-icicle-kit-design-and-linux.md#eMMC)
+
+Once the Linux image and payload binary is copied to the eMMC, press CTRL+C
+in the HSS command line interface, then type 'boot' and enter to boot the newly
+copied payload and Linux image.
+
+.. code-block:: none
+
+    zcat <linux-image>.wic.gz | sudo dd of=/dev/sdX bs=4096 iflag=fullblock oflag=direct conv=fsync status=progress
+
+    sudo dd if=<payload_binary> of=/dev/sdX2 bs=512
+
+You should see the U-Boot prompt on UART0.
+
+GUID type
+---------
+The HSS always picks up the HSS payload from a GPT partition with
+GIUD type "21686148-6449-6E6F-744E-656564454649" or sector '0' of the eMMC if no
+GPT partition.
+
+Sample boot log from MPFS Icicle Kit
+------------------------------------
+
+.. code-block:: none
+
+   U-Boot 2021.01-00314-g7303332537-dirty (Jan 14 2021 - 10:09:43 +0530)
+
+   CPU:   rv64imafdc
+   Model: Microchip MPFS Icicle Kit
+   DRAM:  1 GiB
+   MMC:   sdhc@20008000: 0
+   In:    serial@20100000
+   Out:   serial@20100000
+   Err:   serial@20100000
+   Net:   eth0: ethernet@20112000
+   Hit any key to stop autoboot:  0
+
+   RISC-V # mmc info
+   Device: sdhc@20008000
+   Manufacturer ID: 45
+   OEM: 100
+   Name: DG400
+   Bus Speed: 52000000
+   Mode: MMC High Speed (52MHz)
+   Rd Block Len: 512
+   MMC version 5.1
+   High Capacity: Yes
+   Capacity: 7.3 GiB
+   Bus Width: 4-bit
+   Erase Group Size: 512 KiB
+   HC WP Group Size: 8 MiB
+   User Capacity: 7.3 GiB WRREL
+   Boot Capacity: 4 MiB ENH
+   RPMB Capacity: 4 MiB ENH
+
+   RISC-V # mmc part
+   Partition Map for MMC device 0  --   Partition Type: EFI
+
+   Part        Start LBA       End LBA         Name
+               Attributes
+               Type GUID
+               Partition GUID
+       1       0x00002000      0x0000b031      "boot"
+               attrs:  0x0000000000000004
+               type:   ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
+               guid:   99ff6a94-f2e7-44dd-a7df-f3a2da106ef9
+       2       0x0000b032      0x0000f031      "primary"
+               attrs:  0x0000000000000000
+               type:   21686148-6449-6e6f-744e-656564454649
+               guid:   12006052-e64b-4423-beb0-b956ea00f1ba
+       3       0x00010000      0x00226b9f      "root"
+               attrs:  0x0000000000000000
+               type:   0fc63daf-8483-4772-8e79-3d69d8477de4
+               guid:   dd2c5619-2272-4c3c-8dc2-e21942e17ce6
+
+   RISC-V # load mmc 0 ${ramdisk_addr_r} fitimage
+   RISC-V # bootm ${ramdisk_addr_r}
+   ## Loading kernel from FIT Image at 88300000 ...
+   Using 'conf@microchip_icicle-kit-es-a000-microchip.dtb' configuration
+   Trying 'kernel@1' kernel subimage
+     Description:  Linux kernel
+     Type:         Kernel Image
+     Compression:  gzip compressed
+     Data Start:   0x883000fc
+     Data Size:    3574555 Bytes = 3.4 MiB
+     Architecture: RISC-V
+     OS:           Linux
+     Load Address: 0x80200000
+     Entry Point:  0x80200000
+     Hash algo:    sha256
+     Hash value:   21f18d72cf2f0a7192220abb577ad25c77c26960052d779aa02bf55dbf0a6403
+   Verifying Hash Integrity ... sha256+ OK
+   ## Loading fdt from FIT Image at 88300000 ...
+   Using 'conf@microchip_icicle-kit-es-a000-microchip.dtb' configuration
+   Trying 'fdt@microchip_icicle-kit-es-a000-microchip.dtb' fdt subimage
+     Description:  Flattened Device Tree blob
+     Type:         Flat Device Tree
+     Compression:  uncompressed
+     Data Start:   0x88668d44
+     Data Size:    9760 Bytes = 9.5 KiB
+     Architecture: RISC-V
+     Load Address: 0x82200000
+     Hash algo:    sha256
+     Hash value:   5c3a9f30d41b6b8e53b47916e1f339b3a4d454006554d1f7e1f552ed62409f4b
+   Verifying Hash Integrity ... sha256+ OK
+   Loading fdt from 0x88668d48 to 0x82200000
+   Booting using the fdt blob at 0x82200000
+   Uncompressing Kernel Image
+   Loading Device Tree to 000000008fffa000, end 000000008ffff61f ... OK
+
+   Starting kernel ...
+
+   [    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
+   [    0.000000] Linux version 5.6.16 (oe-user@oe-host) (gcc version 9.3.0 (GCC)) #1 SMP Fri Oct 9 11:49:47 UTC 2020
+   [    0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
+   [    0.000000] printk: bootconsole [sbi0] enabled
+   [    0.000000] Zone ranges:
+   [    0.000000]   DMA32    [mem 0x0000000080200000-0x00000000bfffffff]
+   [    0.000000]   Normal   empty
+   [    0.000000] Movable zone start for each node
+   [    0.000000] Early memory node ranges
+   [    0.000000]   node   0: [mem 0x0000000080200000-0x00000000bfffffff]
+   [    0.000000] Zeroed struct page in unavailable ranges: 512 pages
+   [    0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x00000000bfffffff]
+   [    0.000000] software IO TLB: mapped [mem 0xb9e00000-0xbde00000] (64MB)
+   [    0.000000] CPU with hartid=0 is not available
+   [    0.000000] CPU with hartid=0 is not available
+   [    0.000000] elf_hwcap is 0x112d
+   [    0.000000] percpu: Embedded 17 pages/cpu s29784 r8192 d31656 u69632
+   [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 258055
+   [    0.000000] Kernel command line: earlycon=sbi root=/dev/mmcblk0p3 rootwait console=ttyS0,115200n8 uio_pdrv_genirq.of_id=generic-uio
+   [    0.000000] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
+   [    0.000000] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
+   [    0.000000] Sorting __ex_table...
+   [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
+   [    0.000000] Memory: 941440K/1046528K available (4118K kernel code, 280K rwdata, 1687K rodata, 169K init, 273K bss, 105088K reserved, 0K cma-reserved)
+   [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
+   [    0.000000] rcu: Hierarchical RCU implementation.
+   [    0.000000] rcu:         RCU event tracing is enabled.
+   [    0.000000] rcu:         RCU restricting CPUs from NR_CPUS=5 to nr_cpu_ids=4.
+   [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
+   [    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
+   [    0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0
+   [    0.000000] plic: mapped 53 interrupts with 4 handlers for 9 contexts.
+   [    0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [1]
+   [    0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x1d854df40, max_idle_ns: 3526361616960 ns
+   [    0.000015] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps every 2199023255500ns
+   [    0.008679] Console: colour dummy device 80x25
+   [    0.013112] Calibrating delay loop (skipped), value calculated using timer frequency.. 2.00 BogoMIPS (lpj=10000)
+   [    0.023368] pid_max: default: 32768 minimum: 301
+   [    0.028314] Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
+   [    0.035766] Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
+   [    0.047099] rcu: Hierarchical SRCU implementation.
+   [    0.052813] smp: Bringing up secondary CPUs ...
+   [    0.061581] smp: Brought up 1 node, 4 CPUs
+   [    0.067069] devtmpfs: initialized
+   [    0.073621] random: get_random_u32 called from bucket_table_alloc.isra.0+0x4e/0x150 with crng_init=0
+   [    0.074409] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
+   [    0.093399] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
+   [    0.101879] NET: Registered protocol family 16
+   [    0.110336] microchip-pfsoc-clkcfg 20002000.clkcfg: Registered PFSOC core clocks
+   [    0.132717] usbcore: registered new interface driver usbfs
+   [    0.138225] usbcore: registered new interface driver hub
+   [    0.143813] usbcore: registered new device driver usb
+   [    0.148939] pps_core: LinuxPPS API ver. 1 registered
+   [    0.153929] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
+   [    0.163071] PTP clock support registered
+   [    0.168521] clocksource: Switched to clocksource riscv_clocksource
+   [    0.174927] VFS: Disk quotas dquot_6.6.0
+   [    0.179016] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
+   [    0.205536] NET: Registered protocol family 2
+   [    0.210944] tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes, linear)
+   [    0.219393] TCP established hash table entries: 8192 (order: 4, 65536 bytes, linear)
+   [    0.227497] TCP bind hash table entries: 8192 (order: 5, 131072 bytes, linear)
+   [    0.235440] TCP: Hash tables configured (established 8192 bind 8192)
+   [    0.242537] UDP hash table entries: 512 (order: 2, 16384 bytes, linear)
+   [    0.249285] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear)
+   [    0.256690] NET: Registered protocol family 1
+   [    0.262585] workingset: timestamp_bits=62 max_order=18 bucket_order=0
+   [    0.281036] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 249)
+   [    0.288481] io scheduler mq-deadline registered
+   [    0.292983] io scheduler kyber registered
+   [    0.298895] microsemi,mss-gpio 20122000.gpio: Microsemi MSS GPIO registered 32 GPIOs
+   [    0.453723] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
+   [    0.462911] printk: console [ttyS0] disabled
+   [    0.467216] 20100000.serial: ttyS0 at MMIO 0x20100000 (irq = 12, base_baud = 9375000) is a 16550A
+   [    0.476201] printk: console [ttyS0] enabled
+   [    0.476201] printk: console [ttyS0] enabled
+   [    0.484576] printk: bootconsole [sbi0] disabled
+   [    0.484576] printk: bootconsole [sbi0] disabled
+   [    0.494920] 20102000.serial: ttyS1 at MMIO 0x20102000 (irq = 13, base_baud = 9375000) is a 16550A
+   [    0.505068] 20104000.serial: ttyS2 at MMIO 0x20104000 (irq = 14, base_baud = 9375000) is a 16550A
+   [    0.533336] loop: module loaded
+   [    0.572284] Rounding down aligned max_sectors from 4294967295 to 4294967288
+   [    0.580000] db_root: cannot open: /etc/target
+   [    0.585413] libphy: Fixed MDIO Bus: probed
+   [    0.591526] libphy: MACB_mii_bus: probed
+   [    0.598060] macb 20112000.ethernet eth0: Cadence GEM rev 0x0107010c at 0x20112000 irq 17 (56:34:12:00:fc:00)
+   [    0.608352] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
+   [    0.615001] ehci-platform: EHCI generic platform driver
+   [    0.620446] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
+   [    0.626632] ohci-platform: OHCI generic platform driver
+   [    0.632326] usbcore: registered new interface driver cdc_acm
+   [    0.637996] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
+   [    0.646459] i2c /dev entries driver
+   [    0.650852] microsemi-mss-i2c 2010b000.i2c: Microsemi I2C Probe Complete
+   [    0.658010] sdhci: Secure Digital Host Controller Interface driver
+   [    0.664326] sdhci: Copyright(c) Pierre Ossman
+   [    0.668754] sdhci-pltfm: SDHCI platform and OF driver helper
+   [    0.706845] mmc0: SDHCI controller on 20008000.sdhc [20008000.sdhc] using ADMA 64-bit
+   [    0.715052] usbcore: registered new interface driver usbhid
+   [    0.720722] usbhid: USB HID core driver
+   [    0.725174] pac193x 0-0010: Chip revision: 0x03
+   [    0.733339] pac193x 0-0010: :pac193x_prep_iio_channels: Channel 0 active
+   [    0.740127] pac193x 0-0010: :pac193x_prep_iio_channels: Channel 1 active
+   [    0.746881] pac193x 0-0010: :pac193x_prep_iio_channels: Channel 2 active
+   [    0.753686] pac193x 0-0010: :pac193x_prep_iio_channels: Channel 3 active
+   [    0.760495] pac193x 0-0010: :pac193x_prep_iio_channels: Active chip channels: 25
+   [    0.778006] NET: Registered protocol family 10
+   [    0.784929] Segment Routing with IPv6
+   [    0.788875] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
+   [    0.795743] NET: Registered protocol family 17
+   [    0.801191] hctosys: unable to open rtc device (rtc0)
+   [    0.807774] Waiting for root device /dev/mmcblk0p3...
+   [    0.858506] mmc0: mmc_select_hs200 failed, error -74
+   [    0.865764] mmc0: new MMC card at address 0001
+   [    0.872564] mmcblk0: mmc0:0001 DG4008 7.28 GiB
+   [    0.878777] mmcblk0boot0: mmc0:0001 DG4008 partition 1 4.00 MiB
+   [    0.886182] mmcblk0boot1: mmc0:0001 DG4008 partition 2 4.00 MiB
+   [    0.892633] mmcblk0rpmb: mmc0:0001 DG4008 partition 3 4.00 MiB, chardev (247:0)
+   [    0.919029] GPT:Primary header thinks Alt. header is not at the end of the disk.
+   [    0.926448] GPT:2255841 != 15273599
+   [    0.930019] GPT:Alternate GPT header not at the end of the disk.
+   [    0.936029] GPT:2255841 != 15273599
+   [    0.939583] GPT: Use GNU Parted to correct GPT errors.
+   [    0.944800]  mmcblk0: p1 p2 p3
+   [    0.966696] EXT4-fs (mmcblk0p3): INFO: recovery required on readonly filesystem
+   [    0.974105] EXT4-fs (mmcblk0p3): write access will be enabled during recovery
+   [    1.052362] random: fast init done
+   [    1.057961] EXT4-fs (mmcblk0p3): recovery complete
+   [    1.065734] EXT4-fs (mmcblk0p3): mounted filesystem with ordered data mode. Opts: (null)
+   [    1.074002] VFS: Mounted root (ext4 filesystem) readonly on device 179:3.
+   [    1.081654] Freeing unused kernel memory: 168K
+   [    1.086108] This architecture does not have kernel memory protection.
+   [    1.092629] Run /sbin/init as init process
+   [    1.702217] systemd[1]: System time before build time, advancing clock.
+   [    1.754192] systemd[1]: systemd 244.3+ running in system mode. (+PAM -AUDIT -SELINUX +IMA -APPARMOR -SMACK +SYSVINIT +UTMP -LIBCRYPTSETUP -GCRYPT -GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID -ELFUTILS +KMOD -IDN2 -IDN -PCRE2 default-hierarchy=hybrid)
+   [    1.776361] systemd[1]: Detected architecture riscv64.
+
+   Welcome to OpenEmbedded nodistro.0!
+
+   [    1.829651] systemd[1]: Set hostname to <icicle-kit-es>.
+   [    2.648597] random: systemd: uninitialized urandom read (16 bytes read)
+   [    2.657485] systemd[1]: Created slice system-getty.slice.
+   [  OK  ] Created slice system-getty.slice.
+   [    2.698779] random: systemd: uninitialized urandom read (16 bytes read)
+   [    2.706317] systemd[1]: Created slice system-serial\x2dgetty.slice.
+   [  OK  ] Created slice system-serial\x2dgetty.slice.
+   [    2.748716] random: systemd: uninitialized urandom read (16 bytes read)
+   [    2.756098] systemd[1]: Created slice User and Session Slice.
+   [  OK  ] Created slice User and Session Slice.
+   [    2.789065] systemd[1]: Started Dispatch Password Requests to Console Directory Watch.
+   [  OK  ] Started Dispatch Password â€¦ts to Console Directory Watch.
+   [    2.828974] systemd[1]: Started Forward Password Requests to Wall Directory Watch.
+   [  OK  ] Started Forward Password R…uests to Wall Directory Watch.
+   [    2.869009] systemd[1]: Reached target Paths.
+   [  OK  ] Reached target Paths.
+   [    2.898808] systemd[1]: Reached target Remote File Systems.
+   [  OK  ] Reached target Remote File Systems.
+   [    2.938771] systemd[1]: Reached target Slices.
+   [  OK  ] Reached target Slices.
+   [    2.968754] systemd[1]: Reached target Swap.
+   [  OK  ] Reached target Swap.
+   [    2.999283] systemd[1]: Listening on initctl Compatibility Named Pipe.
+   [  OK  ] Listening on initctl Compatibility Named Pipe.
+   [    3.060458] systemd[1]: Condition check resulted in Journal Audit Socket being skipped.
+   [    3.069826] systemd[1]: Listening on Journal Socket (/dev/log).
+   [  OK  ] Listening on Journal Socket (/dev/log).
+   [    3.109601] systemd[1]: Listening on Journal Socket.
+   [  OK  ] Listening on Journal Socket.
+   [    3.149868] systemd[1]: Listening on Network Service Netlink Socket.
+   [  OK  ] Listening on Network Service Netlink Socket.
+   [    3.189419] systemd[1]: Listening on udev Control Socket.
+   [  OK  ] Listening on udev Control Socket.
+   [    3.229179] systemd[1]: Listening on udev Kernel Socket.
+   [  OK  ] Listening on udev Kernel Socket.
+   [    3.269520] systemd[1]: Condition check resulted in Huge Pages File System being skipped.
+   [    3.278477] systemd[1]: Condition check resulted in POSIX Message Queue File System being skipped.
+   [    3.288200] systemd[1]: Condition check resulted in Kernel Debug File System being skipped.
+   [    3.302570] systemd[1]: Mounting Temporary Directory (/tmp)...
+            Mounting Temporary Directory (/tmp)...
+   [    3.339226] systemd[1]: Condition check resulted in Create list of static device nodes for the current kernel being skipped.
+   [    3.355883] systemd[1]: Starting File System Check on Root Device...
+            Starting File System Check on Root Device...
+   [    3.407220] systemd[1]: Starting Journal Service...
+            Starting Journal Service...
+   [    3.422441] systemd[1]: Condition check resulted in Load Kernel Modules being skipped.
+   [    3.431770] systemd[1]: Condition check resulted in FUSE Control File System being skipped.
+   [    3.446415] systemd[1]: Mounting Kernel Configuration File System...
+            Mounting Kernel Configuration File System...
+   [    3.458983] systemd[1]: Starting Apply Kernel Variables...
+            Starting Apply Kernel Variables...
+   [    3.471368] systemd[1]: Starting udev Coldplug all Devices...
+            Starting udev Coldplug all Devices...
+   [    3.491071] systemd[1]: Mounted Temporary Directory (/tmp).
+   [  OK      3.498114] systemd[1]: Mounted Kernel Configuration File System.
+   0m] Mounted Temporary Directory (/tmp).
+   [  OK  ] Mounted Kernel Configuration File System.
+   [    3.550853] systemd[1]: Started Apply Kernel Variables.
+   [  OK      3.557535] systemd[1]: Started Journal Service.
+   0m] Started Apply Kernel Variables.
+   [  OK  ] Started Journal Service.
+   [  OK  ] Started udev Coldplug all Devices.
+   [  OK  ] Started File System Check on Root Device.
+            Starting Remount Root and Kernel File Systems...
+   [    8.133469] EXT4-fs (mmcblk0p3): re-mounted. Opts: (null)
+   [  OK  ] Started Remount Root and Kernel File Systems.
+            Starting Flush Journal to Persistent Storage...
+   [    8.215327] systemd-journald[77]: Received client request to flush runtime journal.
+            Starting Create Static Device Nodes in /dev...
+   [  OK  ] Started Flush Journal to Persistent Storage.
+   [  OK  ] Started Create Static Device Nodes in /dev.
+   [  OK  ] Reached target Local File Systems (Pre).
+            Mounting /var/volatile...
+            Starting udev Kernel Device Manager...
+   [  OK  ] Mounted /var/volatile.
+            Starting Load/Save Random Seed...
+   [  OK  ] Reached target Local File Systems.
+            Starting Create Volatile Files and Directories...
+   [  OK  ] Started udev Kernel Device Manager.
+   [  OK  ] Started Create Volatile Files and Directories.
+            Starting Network Time Synchronization...
+            Starting Update UTMP about System Boot/Shutdown...
+   [  OK  ] Started Update UTMP about System Boot/Shutdown.
+   [  OK  ] Started Network Time Synchronization.
+   [   11.618575] random: crng init done
+   [   11.622007] random: 7 urandom warning(s) missed due to ratelimiting
+   [  OK  ] Started Load/Save Random Seed.
+   [  OK  ] Reached target System Initialization.
+   [  OK  ] Started Daily Cleanup of Temporary Directories.
+   [  OK  ] Reached target System Time Set.
+   [  OK  ] Reached target System Time Synchronized.
+   [  OK  ] Reached target Timers.
+   [  OK  ] Listening on D-Bus System Message Bus Socket.
+   [  OK  ] Listening on dropbear.socket.
+   [  OK  ] Reached target Sockets.
+   [  OK  ] Reached target Basic System.
+   [  OK  ] Started D-Bus System Message Bus.
+            Starting IPv6 Packet Filtering Framework...
+            Starting IPv4 Packet Filtering Framework...
+            Starting Login Service...
+   [  OK  ] Started IPv6 Packet Filtering Framework.
+   [  OK  ] Started IPv4 Packet Filtering Framework.
+   [  OK  ] Reached target Network (Pre).
+            Starting Network Service...
+   [  OK  ] Started Login Service.
+   [   12.602455] macb 20112000.ethernet eth0: PHY [20112000.ethernet-ffffffff:09] driver [Vitesse VSC8662] (irq=POLL)
+   [   12.612795] macb 20112000.ethernet eth0: configuring for phy/sgmii link mode
+   [   12.622153] pps pps0: new PPS source ptp0
+   [  OK     12.626725] macb 20112000.ethernet: gem-ptp-timer ptp clock registered.
+   0m] Started Network Service.
+            Starting Network Name Resolution...
+   [  OK  ] Started Network Name Resolution.
+   [  OK  ] Reached target Network.
+   [  OK  ] Reached target Host and Network Name Lookups.
+   [  OK  ] Started Collectd.
+   [  OK  ] Started Collectd.
+            Starting Permit User Sessions...
+   [  OK  ] Started Permit User Sessions.
+   [  OK  ] Started Getty on tty1.
+   [  OK  ] Started Serial Getty on ttyS0.
+   [  OK  ] Reached target Login Prompts.
+   [  OK  ] Reached target Multi-User System.
+            Starting Update UTMP about System Runlevel Changes...
+   [  OK  ] Started Update UTMP about System Runlevel Changes.
+
+   OpenEmbedded nodistro.0 icicle-kit-es ttyS0
+
+   icicle-kit-es login: [   15.795564] macb 20112000.ethernet eth0: Link is Up - 1Gbps/Full - flow control tx
+   [   15.803306] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
+
+   icicle-kit-es login: root
+   root@icicle-kit-es:~#
index 92f2d11..bf945b3 100644 (file)
@@ -70,6 +70,7 @@ console shall be opened immediately. Boot output should look like the following:
     U-Boot 2020.04-rc2-00087-g2221cc09c1-dirty (Feb 28 2020 - 13:53:09 -0500)
 
     DRAM:  8 MiB
+    MMC:   spi@53000000:slot@0: 0
     In:    serial@38000000
     Out:   serial@38000000
     Err:   serial@38000000
@@ -118,14 +119,115 @@ The value of FW_PAYLOAD_OFFSET must match CONFIG_SYS_TEXT_BASE - 0x80000000.
 
 The file to flash is build/platform/kendryte/k210/firmware/fw_payload.bin.
 
+Booting
+^^^^^^^
+
+The default boot process is to load and boot the files ``/uImage`` and
+``/k210.dtb`` off of the first partition of the MMC. For Linux, this will result
+in an output like
+
+.. code-block:: none
+
+    U-Boot 2020.10-00691-gd1d651d988-dirty (Oct 16 2020 - 17:05:24 -0400)
+
+    DRAM:  8 MiB
+    MMC:   spi@53000000:slot@0: 0
+    Loading Environment from SPIFlash... SF: Detected w25q128fw with page size 256 Bytes, erase size 4 KiB, total 16 MiB
+    OK
+    In:    serial@38000000
+    Out:   serial@38000000
+    Err:   serial@38000000
+    Hit any key to stop autoboot:  0
+    1827380 bytes read in 1044 ms (1.7 MiB/s)
+    13428 bytes read in 10 ms (1.3 MiB/s)
+    ## Booting kernel from Legacy Image at 80060000 ...
+       Image Name:   linux
+       Image Type:   RISC-V Linux Kernel Image (uncompressed)
+       Data Size:    1827316 Bytes = 1.7 MiB
+       Load Address: 80000000
+       Entry Point:  80000000
+       Verifying Checksum ... OK
+    ## Flattened Device Tree blob at 80400000
+       Booting using the fdt blob at 0x80400000
+       Loading Kernel Image
+       Loading Device Tree to 00000000803f9000, end 00000000803ff473 ... OK
+
+    Starting kernel ...
+
+    [    0.000000] Linux version 5.9.0-00021-g6dcc2f0814c6-dirty (sean@godwin) (riscv64-linux-gnu-gcc (GCC) 10.2.0, GNU ld (GNU Binutils) 2.35) #34 SMP Fri Oct 16 14:40:57 EDT 2020
+    [    0.000000] earlycon: sifive0 at MMIO 0x0000000038000000 (options '115200n8')
+    [    0.000000] printk: bootconsole [sifive0] enabled
+    [    0.000000] Zone ranges:
+    [    0.000000]   DMA32    [mem 0x0000000080000000-0x00000000807fffff]
+    [    0.000000]   Normal   empty
+    [    0.000000] Movable zone start for each node
+    [    0.000000] Early memory node ranges
+    [    0.000000]   node   0: [mem 0x0000000080000000-0x00000000807fffff]
+    [    0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x00000000807fffff]
+    [    0.000000] riscv: ISA extensions acdfgim
+    [    0.000000] riscv: ELF capabilities acdfim
+    [    0.000000] percpu: max_distance=0x18000 too large for vmalloc space 0x0
+    [    0.000000] percpu: Embedded 12 pages/cpu s18848 r0 d30304 u49152
+    [    0.000000] Built 1 zonelists, mobility grouping off.  Total pages: 2020
+    [    0.000000] Kernel command line: earlycon console=ttySIF0
+    [    0.000000] Dentry cache hash table entries: 1024 (order: 1, 8192 bytes, linear)
+    [    0.000000] Inode-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
+    [    0.000000] Sorting __ex_table...
+    [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
+    [    0.000000] Memory: 6004K/8192K available (1139K kernel code, 126K rwdata, 198K rodata, 90K init, 81K bss, 2188K reserved, 0K cma-reserved)
+    [    0.000000] rcu: Hierarchical RCU implementation.
+    [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
+    [    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
+    [    0.000000] riscv-intc: 64 local interrupts mapped
+    [    0.000000] plic: interrupt-controller@C000000: mapped 65 interrupts with 2 handlers for 2 contexts.
+    [    0.000000] random: get_random_bytes called from 0x00000000800019a8 with crng_init=0
+    [    0.000000] k210-clk: clock-controller
+    [    0.000000] k210-clk: clock-controller: fixed-rate 26 MHz osc base clock
+    [    0.000000] clint: clint@2000000: timer running at 7800000 Hz
+    [    0.000000] clocksource: clint_clocksource: mask: 0xffffffffffffffff max_cycles: 0x3990be68b, max_idle_ns: 881590404272 ns
+    [    0.000014] sched_clock: 64 bits at 7MHz, resolution 128ns, wraps every 4398046511054ns
+    [    0.008450] Console: colour dummy device 80x25
+    [    0.012494] Calibrating delay loop (skipped), value calculated using timer frequency.. 15.60 BogoMIPS (lpj=31200)
+    [    0.022693] pid_max: default: 4096 minimum: 301
+    [    0.027352] Mount-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
+    [    0.034428] Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
+    [    0.045099] rcu: Hierarchical SRCU implementation.
+    [    0.050048] smp: Bringing up secondary CPUs ...
+    [    0.055417] smp: Brought up 1 node, 2 CPUs
+    [    0.059602] devtmpfs: initialized
+    [    0.082796] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
+    [    0.091820] futex hash table entries: 16 (order: -2, 1024 bytes, linear)
+    [    0.098507] pinctrl core: initialized pinctrl subsystem
+    [    0.140938] clocksource: Switched to clocksource clint_clocksource
+    [    0.247216] workingset: timestamp_bits=62 max_order=11 bucket_order=0
+    [    0.277392] k210-fpioa 502b0000.pinmux: K210 FPIOA pin controller
+    [    0.291724] k210-sysctl 50440000.syscon: K210 system controller
+    [    0.305317] k210-rst 50440000.syscon:reset-controller: K210 reset controller
+    [    0.313808] 38000000.serial: ttySIF0 at MMIO 0x38000000 (irq = 1, base_baud = 115200) is a SiFive UART v0
+    [    0.322712] printk: console [ttySIF0] enabled
+    [    0.322712] printk: console [ttySIF0] enabled
+    [    0.331328] printk: bootconsole [sifive0] disabled
+    [    0.331328] printk: bootconsole [sifive0] disabled
+    [    0.353347] Freeing unused kernel memory: 88K
+    [    0.357004] This architecture does not have kernel memory protection.
+    [    0.363397] Run /init as init process
+
+Loading, Booting, and Storing Images
+------------------------------------
+
+.. _loading:
+
 Loading Images
 ^^^^^^^^^^^^^^
 
-To load a kernel, transfer it over serial.
+Serial
+""""""
+
+Use the ``loady`` command to load images over serial.
 
 .. code-block:: none
 
-    => loady 80000000 1500000
+    => loady $loadaddr 1500000
     ## Switch baudrate to 1500000 bps and press ENTER ...
 
     *** baud: 1500000
@@ -150,6 +252,61 @@ To load a kernel, transfer it over serial.
     *** baud: 115200 ***
     =>
 
+This command does not set ``$filesize``, so it may need to be set manually.
+
+SPI Flash
+"""""""""
+
+To load an image off of SPI flash, first set up a partition as described in
+:ref:`partitions`. Then, use ``mtd`` to load that partition
+
+.. code-block:: none
+
+    => sf probe
+    SF: Detected w25q128fw with page size 256 Bytes, erase size 4 KiB, total 16 MiB
+    => mtd read linux $loadaddr
+    Reading 2097152 byte(s) at offset 0x00000000
+
+This command does not set ``$filesize``, so it may need to be set manually.
+
+MMC
+"""
+
+The MMC device number is 0. To list partitions on the device, use ``part``:
+
+.. code-block:: none
+
+    => part list mmc 0
+
+    Partition Map for MMC device 0  --   Partition Type: EFI
+
+    Part    Start LBA       End LBA          Name
+            Attributes
+            Type GUID
+            Partition GUID
+      1     0x00000800      0x039effde      "boot"
+            attrs:  0x0000000000000000
+            type:   c12a7328-f81f-11d2-ba4b-00a0c93ec93b
+            guid:   96161f7d-7113-4cc7-9a24-08ab7fc5cb72
+
+To list files, use ``ls``:
+
+.. code-block:: none
+
+    => ls mmc 0:1
+    <DIR>       4096 .
+    <DIR>       4096 ..
+    <DIR>      16384 lost+found
+               13428 k210.dtb
+             1827380 uImage
+
+To load a file, use ``load``:
+
+.. code-block:: none
+
+    => load mmc 0:1 $loadaddr uImage
+    1827380 bytes read in 1049 ms (1.7 MiB/s)
+
 Running Programs
 ^^^^^^^^^^^^^^^^
 
@@ -160,20 +317,6 @@ To run a bare binary, use the ``go`` command:
 
 .. code-block:: none
 
-    => loady
-    ## Ready for binary (ymodem) download to 0x80000000 at 115200 bps...
-    C
-    *** file: ./examples/standalone/hello_world.bin
-    $ sz -vv ./examples/standalone/hello_world.bin
-    Sending: hello_world.bin
-    Bytes Sent:   4864   BPS:649
-    Sending:
-    Ymodem sectors/kbytes sent:   0/ 0k
-    Transfer complete
-
-    *** exit status: 0 ***
-    (CAN) packets, 5 retries
-    ## Total Size      = 0x000012f8 = 4856 Bytes
     => go 80000000
     ## Starting application at 0x80000000 ...
     Example expects ABI version 9
@@ -184,51 +327,127 @@ To run a bare binary, use the ``go`` command:
     argv[1] = "<NULL>"
     Hit any key to exit ...
 
+Note that this will only start a program on one hart. As-of this writing it is
+only possible to start a program on multiple harts using the ``bootm`` command.
+
 Legacy Images
 """""""""""""
 
-To run legacy images, use the ``bootm`` command:
+To create a legacy image, use ``tools/mkimage``:
 
 .. code-block:: none
 
-    $ tools/mkimage -A riscv -O u-boot -T standalone -C none -a 80000000 -e 80000000 -d examples/standalone/hello_world.bin hello_world.img
-    Image Name:
-    Created:      Thu Mar  5 12:04:10 2020
-    Image Type:   RISC-V U-Boot Standalone Program (uncompressed)
-    Data Size:    4856 Bytes = 4.74 KiB = 0.00 MiB
+    $ tools/mkimage -A riscv -O linux -T kernel -C none -a 0x80000000 -e 0x80000000 -n linux -d ../linux-git/arch/riscv/boot/Image uImage
+    Image Name:   linux
+    Created:      Fri Oct 16 17:36:32 2020
+    Image Type:   RISC-V Linux Kernel Image (uncompressed)
+    Data Size:    1827316 Bytes = 1784.49 KiB = 1.74 MiB
     Load Address: 80000000
     Entry Point:  80000000
 
-    $ picocom -b 115200 /dev/ttyUSB0
-    => loady
-    ## Ready for binary (ymodem) download to 0x80000000 at 115200 bps...
-    C
-    *** file: hello_world.img
-    $ sz -vv hello_world.img
-    Sending: hello_world.img
-    Bytes Sent:   4992   BPS:665
-    Sending:
-    Ymodem sectors/kbytes sent:   0/ 0k
-    Transfer complete
+The ``bootm`` command also requires an FDT, even if the image doesn't require
+one. After loading the image to ``$loadaddr`` and the FDT to ``$fdt_addr_r``,
+boot with:
 
-    *** exit status: 0 ***
-    CAN) packets, 3 retries
-    ## Total Size      = 0x00001338 = 4920 Bytes
-    => bootm
-    ## Booting kernel from Legacy Image at 80000000 ...
-       Image Name:
-       Image Type:   RISC-V U-Boot Standalone Program (uncompressed)
-       Data Size:    4856 Bytes = 4.7 KiB
+.. code-block:: none
+
+    => bootm $loadaddr - $fdt_addr_r
+    ## Booting kernel from Legacy Image at 80060000 ...
+       Image Name:   linux
+       Image Type:   RISC-V Linux Kernel Image (uncompressed)
+       Data Size:    1827316 Bytes = 1.7 MiB
        Load Address: 80000000
        Entry Point:  80000000
        Verifying Checksum ... OK
-       Loading Standalone Program
-    Example expects ABI version 9
-    Actual U-Boot ABI version 9
-    Hello World
-    argc = 0
-    argv[0] = "<NULL>"
-    Hit any key to exit ...
+    ## Flattened Device Tree blob at 80400000
+       Booting using the fdt blob at 0x80400000
+       Loading Kernel Image
+       Loading Device Tree to 00000000803f9000, end 00000000803ff473 ... OK
+
+    Starting kernel ...
+
+The FDT is verified after the kernel is relocated, so it must be loaded high
+enough so that it won't be overwritten. The default values for ``$loadaddr``
+and ``$fdt_addr_r`` should provide ample headroom for most use-cases.
+
+Flashing Images
+^^^^^^^^^^^^^^^
+
+SPI Flash
+"""""""""
+
+To flash data to SPI flash, first load it using one of the methods in
+:ref:`loading`. Addiotionally, create some partitions as described in
+:ref:`partitions`. Then use the ``mtd`` command:
+
+.. code-block:: none
+
+    => sf probe
+    SF: Detected w25q128fw with page size 256 Bytes, erase size 4 KiB, total 16 MiB
+    => mtd write linux $loadaddr 0 $filesize
+    Writing 2478162 byte(s) at offset 0x00000000
+
+Note that in order to write a bootable image, a header and tailer must be added.
+
+MMC
+"""
+
+MMC writes are unsupported for now.
+
+SPI Flash
+^^^^^^^^^
+
+Sipeed MAIX boards typically provide around 16 MiB of SPI NOR flash. U-Boot is
+stored in the first 1 MiB or so of this flash. U-Boot's environment is stored at
+the end of flash.
+
+.. _partitions:
+
+Partitions
+""""""""""
+
+There is no set data layout. The default partition layout only allocates
+partitions for U-Boot and its default environment
+
+.. code-block:: none
+
+    => mtd list
+    List of MTD devices:
+    * nor0
+      - type: NOR flash
+      - block size: 0x1000 bytes
+      - min I/O: 0x1 bytes
+      - 0x000000000000-0x000001000000 : "nor0"
+          - 0x000000000000-0x000000100000 : "u-boot"
+          - 0x000000fff000-0x000001000000 : "env"
+
+As an example, to allocate 2MiB for Linux and (almost) 13 MiB for other data,
+set the ``mtdparts`` like:
+
+.. code-block:: none
+
+    => env set mtdparts nor0:1M(u-boot),2M(linux),0xcff000(data),0x1000@0xfff000(env)
+    => mtd list
+    List of MTD devices:
+    * nor0
+      - type: NOR flash
+      - block size: 0x1000 bytes
+      - min I/O: 0x1 bytes
+      - 0x000000000000-0x000001000000 : "nor0"
+          - 0x000000000000-0x000000100000 : "u-boot"
+          - 0x000000100000-0x000000300000 : "linux"
+          - 0x000000300000-0x000000fff000 : "data"
+          - 0x000000fff000-0x000001000000 : "env"
+
+To make these changes permanent, save the environment:
+
+.. code-block:: none
+
+    => env save
+    Saving Environment to SPIFlash... Erasing SPI flash...Writing to SPI flash...done
+    OK
+
+U-Boot will always load the environment from the last 4 KiB of flash.
 
 Pin Assignment
 --------------
index db06f27..4aeaa0c 100644 (file)
@@ -165,6 +165,7 @@ source "drivers/clk/exynos/Kconfig"
 source "drivers/clk/imx/Kconfig"
 source "drivers/clk/kendryte/Kconfig"
 source "drivers/clk/meson/Kconfig"
+source "drivers/clk/microchip/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/owl/Kconfig"
 source "drivers/clk/renesas/Kconfig"
index f8383e5..645709b 100644 (file)
@@ -30,6 +30,7 @@ obj-$(CONFIG_$(SPL_TPL_)CLK_INTEL) += intel/
 obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o
 obj-$(CONFIG_CLK_K210) += kendryte/
 obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o
+obj-$(CONFIG_CLK_MPFS) += microchip/
 obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o
 obj-$(CONFIG_CLK_OWL) += owl/
 obj-$(CONFIG_CLK_RENESAS) += renesas/
diff --git a/drivers/clk/microchip/Kconfig b/drivers/clk/microchip/Kconfig
new file mode 100644 (file)
index 0000000..b702415
--- /dev/null
@@ -0,0 +1,5 @@
+config CLK_MPFS
+       bool "Clock support for Microchip PolarFire SoC"
+       depends on CLK && CLK_CCF
+       help
+         This enables support clock driver for Microchip PolarFire SoC platform.
diff --git a/drivers/clk/microchip/Makefile b/drivers/clk/microchip/Makefile
new file mode 100644 (file)
index 0000000..904b345
--- /dev/null
@@ -0,0 +1 @@
+obj-y += mpfs_clk.o mpfs_clk_cfg.o mpfs_clk_periph.o
diff --git a/drivers/clk/microchip/mpfs_clk.c b/drivers/clk/microchip/mpfs_clk.c
new file mode 100644 (file)
index 0000000..722c79b
--- /dev/null
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+#include <common.h>
+#include <clk.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <log.h>
+#include <dm/device.h>
+#include <dm/devres.h>
+#include <dm/uclass.h>
+#include <linux/err.h>
+
+#include "mpfs_clk.h"
+
+/* All methods are delegated to CCF clocks */
+
+static ulong mpfs_clk_get_rate(struct clk *clk)
+{
+       struct clk *c;
+       int err = clk_get_by_id(clk->id, &c);
+
+       if (err)
+               return err;
+       return clk_get_rate(c);
+}
+
+static ulong mpfs_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       struct clk *c;
+       int err = clk_get_by_id(clk->id, &c);
+
+       if (err)
+               return err;
+       return clk_set_rate(c, rate);
+}
+
+static int mpfs_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+       struct clk *c, *p;
+       int err = clk_get_by_id(clk->id, &c);
+
+       if (err)
+               return err;
+
+       err = clk_get_by_id(parent->id, &p);
+       if (err)
+               return err;
+
+       return clk_set_parent(c, p);
+}
+
+static int mpfs_clk_endisable(struct clk *clk, bool enable)
+{
+       struct clk *c;
+       int err = clk_get_by_id(clk->id, &c);
+
+       if (err)
+               return err;
+       return enable ? clk_enable(c) : clk_disable(c);
+}
+
+static int mpfs_clk_enable(struct clk *clk)
+{
+       return mpfs_clk_endisable(clk, true);
+}
+
+static int mpfs_clk_disable(struct clk *clk)
+{
+       return mpfs_clk_endisable(clk, false);
+}
+
+static int mpfs_clk_probe(struct udevice *dev)
+{
+       int ret;
+       void __iomem *base;
+       u32 clk_rate;
+       const char *parent_clk_name;
+       struct clk *clk = dev_get_priv(dev);
+
+       base = dev_read_addr_ptr(dev);
+       if (!base)
+               return -EINVAL;
+
+       ret = clk_get_by_index(dev, 0, clk);
+       if (ret)
+               return ret;
+
+       dev_read_u32(clk->dev, "clock-frequency", &clk_rate);
+       parent_clk_name = clk->dev->name;
+
+       ret = mpfs_clk_register_cfgs(base, clk_rate, parent_clk_name);
+       if (ret)
+               return ret;
+
+       ret = mpfs_clk_register_periphs(base, clk_rate, "clk_ahb");
+
+       return ret;
+}
+
+static const struct clk_ops mpfs_clk_ops = {
+       .set_rate = mpfs_clk_set_rate,
+       .get_rate = mpfs_clk_get_rate,
+       .set_parent = mpfs_clk_set_parent,
+       .enable = mpfs_clk_enable,
+       .disable = mpfs_clk_disable,
+};
+
+static const struct udevice_id mpfs_of_match[] = {
+       { .compatible = "microchip,mpfs-clkcfg" },
+       { }
+};
+
+U_BOOT_DRIVER(mpfs_clk) = {
+       .name = "mpfs_clk",
+       .id = UCLASS_CLK,
+       .of_match = mpfs_of_match,
+       .ops = &mpfs_clk_ops,
+       .probe = mpfs_clk_probe,
+       .priv_auto = sizeof(struct clk),
+};
diff --git a/drivers/clk/microchip/mpfs_clk.h b/drivers/clk/microchip/mpfs_clk.h
new file mode 100644 (file)
index 0000000..8e3fc55
--- /dev/null
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+#ifndef __MICROCHIP_MPFS_CLK_H
+#define __MICROCHIP_MPFS_CLK_H
+
+#include <linux/clk-provider.h>
+/**
+ * mpfs_clk_register_cfgs() - register configuration clocks
+ *
+ * @base: base address of the mpfs system register.
+ * @clk_rate: the mpfs pll clock rate.
+ * @parent_name: a pointer to parent clock name.
+ * @return zero on success, or a negative error code.
+ */
+int mpfs_clk_register_cfgs(void __iomem *base, u32 clk_rate,
+                          const char *parent_name);
+/**
+ * mpfs_clk_register_periphs() - register peripheral clocks
+ *
+ * @base: base address of the mpfs system register.
+ * @clk_rate: the mpfs pll clock rate.
+ * @parent_name: a pointer to parent clock name.
+ * @return zero on success, or a negative error code.
+ */
+int mpfs_clk_register_periphs(void __iomem *base, u32 clk_rate,
+                             const char *parent_name);
+/**
+ * divider_get_val() - get the clock divider value
+ *
+ * @rate: requested clock rate.
+ * @parent_rate: parent clock rate.
+ * @table: a pointer to clock divider table.
+ * @width: width of the divider bit field.
+ * @flags: common clock framework flags.
+ * @return divider value on success, or a negative error code.
+ */
+int divider_get_val(unsigned long rate, unsigned long parent_rate,
+                   const struct clk_div_table *table,
+                   u8 width, unsigned long flags);
+
+#endif /* __MICROCHIP_MPFS_CLK_H */
diff --git a/drivers/clk/microchip/mpfs_clk_cfg.c b/drivers/clk/microchip/mpfs_clk_cfg.c
new file mode 100644 (file)
index 0000000..fefddd1
--- /dev/null
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+#include <common.h>
+#include <clk.h>
+#include <clk-uclass.h>
+#include <asm/io.h>
+#include <dm/device.h>
+#include <dm/devres.h>
+#include <dm/uclass.h>
+#include <dt-bindings/clock/microchip-mpfs-clock.h>
+#include <linux/err.h>
+
+#include "mpfs_clk.h"
+
+#define MPFS_CFG_CLOCK "mpfs_cfg_clock"
+
+#define REG_CLOCK_CONFIG_CR 0x08
+
+/* CPU and AXI clock divisors */
+static const struct clk_div_table mpfs_div_cpu_axi_table[] = {
+       { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
+       { 0, 0 }
+};
+
+/* AHB clock divisors */
+static const struct clk_div_table mpfs_div_ahb_table[] = {
+       { 1, 2 }, { 2, 4}, { 3, 8 },
+       { 0, 0 }
+};
+
+/**
+ * struct mpfs_cfg_clock - per instance of configuration clock
+ * @id: index of a configuration clock
+ * @name: name of a configuration clock
+ * @shift: shift to the divider bit field of a configuration clock
+ * @width: width of the divider bit field of a configation clock
+ * @table: clock divider table instance
+ * @flags: common clock framework flags
+ */
+struct mpfs_cfg_clock {
+       unsigned int id;
+       const char *name;
+       u8 shift;
+       u8 width;
+       const struct clk_div_table *table;
+       unsigned long flags;
+};
+
+/**
+ * struct mpfs_cfg_hw_clock - hardware configuration clock (cpu, axi, ahb)
+ * @cfg: configuration clock instance
+ * @sys_base: base address of the mpfs system register
+ * @prate: the pll clock rate
+ * @hw: clock instance
+ */
+struct mpfs_cfg_hw_clock {
+       struct mpfs_cfg_clock cfg;
+       void __iomem *sys_base;
+       u32 prate;
+       struct clk hw;
+};
+
+#define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw)
+
+static ulong mpfs_cfg_clk_recalc_rate(struct clk *hw)
+{
+       struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
+       struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
+       void __iomem *base_addr = cfg_hw->sys_base;
+       unsigned long rate;
+       u32 val;
+
+       val = readl(base_addr + REG_CLOCK_CONFIG_CR) >> cfg->shift;
+       val &= clk_div_mask(cfg->width);
+       rate = cfg_hw->prate / (1u << val);
+       hw->rate = rate;
+
+       return rate;
+}
+
+static ulong mpfs_cfg_clk_set_rate(struct clk *hw, ulong rate)
+{
+       struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
+       struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
+       void __iomem *base_addr = cfg_hw->sys_base;
+       u32  val;
+       int divider_setting;
+
+       divider_setting = divider_get_val(rate, cfg_hw->prate, cfg->table, cfg->width, cfg->flags);
+
+       if (divider_setting < 0)
+               return divider_setting;
+
+       val = readl(base_addr + REG_CLOCK_CONFIG_CR);
+       val &= ~(clk_div_mask(cfg->width) << cfg_hw->cfg.shift);
+       val |= divider_setting << cfg->shift;
+       writel(val, base_addr + REG_CLOCK_CONFIG_CR);
+
+       return clk_get_rate(hw);
+}
+
+#define CLK_CFG(_id, _name, _shift, _width, _table, _flags) {  \
+               .cfg.id = _id,                                  \
+               .cfg.name = _name,                              \
+               .cfg.shift = _shift,                            \
+               .cfg.width = _width,                            \
+               .cfg.table = _table,                            \
+               .cfg.flags = _flags,                            \
+       }
+
+static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
+       CLK_CFG(CLK_CPU, "clk_cpu", 0, 2, mpfs_div_cpu_axi_table, 0),
+       CLK_CFG(CLK_AXI, "clk_axi", 2, 2, mpfs_div_cpu_axi_table, 0),
+       CLK_CFG(CLK_AHB, "clk_ahb", 4, 2, mpfs_div_ahb_table, 0),
+};
+
+int mpfs_clk_register_cfgs(void __iomem *base, u32 clk_rate,
+                          const char *parent_name)
+{
+       int ret;
+       int i, id, num_clks;
+       const char *name;
+       struct clk *hw;
+
+       num_clks = ARRAY_SIZE(mpfs_cfg_clks);
+       for (i = 0; i < num_clks; i++) {
+               hw = &mpfs_cfg_clks[i].hw;
+               mpfs_cfg_clks[i].sys_base = base;
+               mpfs_cfg_clks[i].prate = clk_rate;
+               name = mpfs_cfg_clks[i].cfg.name;
+               ret = clk_register(hw, MPFS_CFG_CLOCK, name, parent_name);
+               if (ret)
+                       ERR_PTR(ret);
+               id = mpfs_cfg_clks[i].cfg.id;
+               clk_dm(id, hw);
+       }
+       return 0;
+}
+
+const struct clk_ops mpfs_cfg_clk_ops = {
+       .set_rate = mpfs_cfg_clk_set_rate,
+       .get_rate = mpfs_cfg_clk_recalc_rate,
+};
+
+U_BOOT_DRIVER(mpfs_cfg_clock) = {
+       .name   = MPFS_CFG_CLOCK,
+       .id     = UCLASS_CLK,
+       .ops    = &mpfs_cfg_clk_ops,
+};
diff --git a/drivers/clk/microchip/mpfs_clk_periph.c b/drivers/clk/microchip/mpfs_clk_periph.c
new file mode 100644 (file)
index 0000000..61d90eb
--- /dev/null
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+#include <common.h>
+#include <clk.h>
+#include <clk-uclass.h>
+#include <asm/io.h>
+#include <dm/device.h>
+#include <dm/devres.h>
+#include <dm/uclass.h>
+#include <dt-bindings/clock/microchip-mpfs-clock.h>
+#include <linux/err.h>
+
+#include "mpfs_clk.h"
+
+#define MPFS_PERIPH_CLOCK "mpfs_periph_clock"
+
+#define REG_CLOCK_CONFIG_CR 0x08
+#define REG_SUBBLK_CLOCK_CR 0x84
+#define REG_SUBBLK_RESET_CR 0x88
+
+#define CFG_CPU_SHIFT   0x0
+#define CFG_AXI_SHIFT   0x2
+#define CFG_AHB_SHIFT   0x4
+#define CFG_WIDTH       0x2
+
+/**
+ * struct mpfs_periph_clock - per instance of peripheral clock
+ * @id: index of a peripheral clock
+ * @name: name of a peripheral clock
+ * @shift: shift to a peripheral clock bit field
+ * @flags: common clock framework flags
+ */
+struct mpfs_periph_clock {
+       unsigned int id;
+       const char *name;
+       u8 shift;
+       unsigned long flags;
+};
+
+/**
+ * struct mpfs_periph_hw_clock - hardware peripheral clock
+ * @periph: peripheral clock instance
+ * @sys_base: base address of the mpfs system register
+ * @prate: the pll clock rate
+ * @hw: clock instance
+ */
+struct mpfs_periph_hw_clock {
+       struct mpfs_periph_clock periph;
+       void __iomem *sys_base;
+       u32 prate;
+       struct clk hw;
+};
+
+#define to_mpfs_periph_clk(_hw) container_of(_hw, struct mpfs_periph_hw_clock, hw)
+
+static int mpfs_periph_clk_enable(struct clk *hw)
+{
+       struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
+       struct mpfs_periph_clock *periph = &periph_hw->periph;
+       void __iomem *base_addr = periph_hw->sys_base;
+       u32 reg, val;
+
+       if (periph->flags != CLK_IS_CRITICAL) {
+               reg = readl(base_addr + REG_SUBBLK_RESET_CR);
+               val = reg & ~(1u << periph->shift);
+               writel(val, base_addr + REG_SUBBLK_RESET_CR);
+
+               reg = readl(base_addr + REG_SUBBLK_CLOCK_CR);
+               val = reg | (1u << periph->shift);
+               writel(val, base_addr + REG_SUBBLK_CLOCK_CR);
+       }
+
+       return 0;
+}
+
+static int mpfs_periph_clk_disable(struct clk *hw)
+{
+       struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
+       struct mpfs_periph_clock *periph = &periph_hw->periph;
+       void __iomem *base_addr = periph_hw->sys_base;
+       u32 reg, val;
+
+       if (periph->flags != CLK_IS_CRITICAL) {
+               reg = readl(base_addr + REG_SUBBLK_RESET_CR);
+               val = reg | (1u << periph->shift);
+               writel(val, base_addr + REG_SUBBLK_RESET_CR);
+
+               reg = readl(base_addr + REG_SUBBLK_CLOCK_CR);
+               val = reg & ~(1u << periph->shift);
+               writel(val, base_addr + REG_SUBBLK_CLOCK_CR);
+       }
+
+       return 0;
+}
+
+static ulong mpfs_periph_clk_recalc_rate(struct clk *hw)
+{
+       struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
+       void __iomem *base_addr = periph_hw->sys_base;
+       unsigned long rate;
+       u32 val;
+
+       val = readl(base_addr + REG_CLOCK_CONFIG_CR) >> CFG_AHB_SHIFT;
+       val &= clk_div_mask(CFG_WIDTH);
+       rate = periph_hw->prate / (1u << val);
+       hw->rate = rate;
+
+       return rate;
+}
+
+#define CLK_PERIPH(_id, _name, _shift, _flags) {       \
+               .periph.id = _id,                       \
+               .periph.name = _name,                   \
+               .periph.shift = _shift,                 \
+               .periph.flags = _flags,                 \
+       }
+
+static struct mpfs_periph_hw_clock mpfs_periph_clks[] = {
+       CLK_PERIPH(CLK_ENVM, "clk_periph_envm", 0, CLK_IS_CRITICAL),
+       CLK_PERIPH(CLK_MAC0, "clk_periph_mac0", 1, 0),
+       CLK_PERIPH(CLK_MAC1, "clk_periph_mac1", 2, 0),
+       CLK_PERIPH(CLK_MMC, "clk_periph_mmc", 3, 0),
+       CLK_PERIPH(CLK_TIMER, "clk_periph_timer", 4, 0),
+       CLK_PERIPH(CLK_MMUART0, "clk_periph_mmuart0", 5, 0),
+       CLK_PERIPH(CLK_MMUART1, "clk_periph_mmuart1", 6, 0),
+       CLK_PERIPH(CLK_MMUART2, "clk_periph_mmuart2", 7, 0),
+       CLK_PERIPH(CLK_MMUART3, "clk_periph_mmuart3", 8, 0),
+       CLK_PERIPH(CLK_MMUART4, "clk_periph_mmuart4", 9, 0),
+       CLK_PERIPH(CLK_SPI0, "clk_periph_spi0", 10, 0),
+       CLK_PERIPH(CLK_SPI1, "clk_periph_spi1", 11, 0),
+       CLK_PERIPH(CLK_I2C0, "clk_periph_i2c0", 12, 0),
+       CLK_PERIPH(CLK_I2C1, "clk_periph_i2c1", 13, 0),
+       CLK_PERIPH(CLK_CAN0, "clk_periph_can0", 14, 0),
+       CLK_PERIPH(CLK_CAN1, "clk_periph_can1", 15, 0),
+       CLK_PERIPH(CLK_USB, "clk_periph_usb", 16, 0),
+       CLK_PERIPH(CLK_RTC, "clk_periph_rtc", 18, 0),
+       CLK_PERIPH(CLK_QSPI, "clk_periph_qspi", 19, 0),
+       CLK_PERIPH(CLK_GPIO0, "clk_periph_gpio0", 20, 0),
+       CLK_PERIPH(CLK_GPIO1, "clk_periph_gpio1", 21, 0),
+       CLK_PERIPH(CLK_GPIO2, "clk_periph_gpio2", 22, 0),
+       CLK_PERIPH(CLK_DDRC, "clk_periph_ddrc", 23, CLK_IS_CRITICAL),
+       CLK_PERIPH(CLK_FIC0, "clk_periph_fic0", 24, 0),
+       CLK_PERIPH(CLK_FIC1, "clk_periph_fic1", 25, 0),
+       CLK_PERIPH(CLK_FIC2, "clk_periph_fic2", 26, 0),
+       CLK_PERIPH(CLK_FIC3, "clk_periph_fic3", 27, 0),
+       CLK_PERIPH(CLK_ATHENA, "clk_periph_athena", 28, 0),
+       CLK_PERIPH(CLK_CFM, "clk_periph_cfm", 29, 0),
+};
+
+int mpfs_clk_register_periphs(void __iomem *base, u32 clk_rate,
+                             const char *parent_name)
+{
+       int ret;
+       int i, id, num_clks;
+       const char *name;
+       struct clk *hw;
+
+       num_clks = ARRAY_SIZE(mpfs_periph_clks);
+       for (i = 0; i < num_clks; i++)  {
+               hw = &mpfs_periph_clks[i].hw;
+               mpfs_periph_clks[i].sys_base = base;
+               mpfs_periph_clks[i].prate = clk_rate;
+               name = mpfs_periph_clks[i].periph.name;
+               ret = clk_register(hw, MPFS_PERIPH_CLOCK, name, parent_name);
+               if (ret)
+                       ERR_PTR(ret);
+               id = mpfs_periph_clks[i].periph.id;
+               clk_dm(id, hw);
+       }
+
+       return 0;
+}
+
+const struct clk_ops mpfs_periph_clk_ops = {
+       .enable = mpfs_periph_clk_enable,
+       .disable = mpfs_periph_clk_disable,
+       .get_rate = mpfs_periph_clk_recalc_rate,
+};
+
+U_BOOT_DRIVER(mpfs_periph_clock) = {
+       .name   = MPFS_PERIPH_CLOCK,
+       .id     = UCLASS_CLK,
+       .ops    = &mpfs_periph_clk_ops,
+};
index e287c29..2225b33 100644 (file)
@@ -83,7 +83,16 @@ struct macb_dma_desc {
        u32     ctrl;
 };
 
-#define DMA_DESC_BYTES(n)      (n * sizeof(struct macb_dma_desc))
+struct macb_dma_desc_64 {
+       u32 addrh;
+       u32 unused;
+};
+
+#define HW_DMA_CAP_32B         0
+#define HW_DMA_CAP_64B         1
+
+#define DMA_DESC_SIZE          16
+#define DMA_DESC_BYTES(n)      ((n) * DMA_DESC_SIZE)
 #define MACB_TX_DMA_DESC_SIZE  (DMA_DESC_BYTES(MACB_TX_RING_SIZE))
 #define MACB_RX_DMA_DESC_SIZE  (DMA_DESC_BYTES(MACB_RX_RING_SIZE))
 #define MACB_TX_DUMMY_DMA_DESC_SIZE    (DMA_DESC_BYTES(1))
@@ -137,6 +146,7 @@ struct macb_device {
 
 struct macb_config {
        unsigned int            dma_burst_length;
+       unsigned int            hw_dma_cap;
 
        int                     (*clk_init)(struct udevice *dev, ulong rate);
 };
@@ -307,6 +317,24 @@ static inline void macb_invalidate_rx_buffer(struct macb_device *macb)
 
 #if defined(CONFIG_CMD_NET)
 
+static struct macb_dma_desc_64 *macb_64b_desc(struct macb_dma_desc *desc)
+{
+       return (struct macb_dma_desc_64 *)((void *)desc
+               + sizeof(struct macb_dma_desc));
+}
+
+static void macb_set_addr(struct macb_device *macb, struct macb_dma_desc *desc,
+                         ulong addr)
+{
+       struct macb_dma_desc_64 *desc_64;
+
+       if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
+               desc_64 = macb_64b_desc(desc);
+               desc_64->addrh = upper_32_bits(addr);
+       }
+       desc->addr = lower_32_bits(addr);
+}
+
 static int _macb_send(struct macb_device *macb, const char *name, void *packet,
                      int length)
 {
@@ -325,8 +353,12 @@ static int _macb_send(struct macb_device *macb, const char *name, void *packet,
                macb->tx_head++;
        }
 
+       if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
+               tx_head = tx_head * 2;
+
        macb->tx_ring[tx_head].ctrl = ctrl;
-       macb->tx_ring[tx_head].addr = paddr;
+       macb_set_addr(macb, &macb->tx_ring[tx_head], paddr);
+
        barrier();
        macb_flush_ring_desc(macb, TX);
        macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
@@ -363,19 +395,28 @@ static void reclaim_rx_buffers(struct macb_device *macb,
                               unsigned int new_tail)
 {
        unsigned int i;
+       unsigned int count;
 
        i = macb->rx_tail;
 
        macb_invalidate_ring_desc(macb, RX);
        while (i > new_tail) {
-               macb->rx_ring[i].addr &= ~MACB_BIT(RX_USED);
+               if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
+                       count = i * 2;
+               else
+                       count = i;
+               macb->rx_ring[count].addr &= ~MACB_BIT(RX_USED);
                i++;
                if (i > MACB_RX_RING_SIZE)
                        i = 0;
        }
 
        while (i < new_tail) {
-               macb->rx_ring[i].addr &= ~MACB_BIT(RX_USED);
+               if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
+                       count = i * 2;
+               else
+                       count = i;
+               macb->rx_ring[count].addr &= ~MACB_BIT(RX_USED);
                i++;
        }
 
@@ -390,16 +431,25 @@ static int _macb_recv(struct macb_device *macb, uchar **packetp)
        void *buffer;
        int length;
        u32 status;
+       u8 flag = false;
 
        macb->wrapped = false;
        for (;;) {
                macb_invalidate_ring_desc(macb, RX);
 
+               if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
+                       next_rx_tail = next_rx_tail * 2;
+
                if (!(macb->rx_ring[next_rx_tail].addr & MACB_BIT(RX_USED)))
                        return -EAGAIN;
 
                status = macb->rx_ring[next_rx_tail].ctrl;
                if (status & MACB_BIT(RX_SOF)) {
+                       if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
+                               next_rx_tail = next_rx_tail / 2;
+                               flag = true;
+                       }
+
                        if (next_rx_tail != macb->rx_tail)
                                reclaim_rx_buffers(macb, next_rx_tail);
                        macb->wrapped = false;
@@ -426,11 +476,22 @@ static int _macb_recv(struct macb_device *macb, uchar **packetp)
                                *packetp = buffer;
                        }
 
+                       if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
+                               if (!flag)
+                                       next_rx_tail = next_rx_tail / 2;
+                       }
+
                        if (++next_rx_tail >= MACB_RX_RING_SIZE)
                                next_rx_tail = 0;
                        macb->next_rx_tail = next_rx_tail;
                        return length;
                } else {
+                       if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
+                               if (!flag)
+                                       next_rx_tail = next_rx_tail / 2;
+                               flag = false;
+                       }
+
                        if (++next_rx_tail >= MACB_RX_RING_SIZE) {
                                macb->wrapped = true;
                                next_rx_tail = 0;
@@ -470,6 +531,12 @@ static int macb_phy_find(struct macb_device *macb, const char *name)
        int i;
        u16 phy_id;
 
+       phy_id = macb_mdio_read(macb, macb->phy_addr, MII_PHYSID1);
+       if (phy_id != 0xffff) {
+               printf("%s: PHY present at %d\n", name, macb->phy_addr);
+               return 0;
+       }
+
        /* Search for PHY... */
        for (i = 0; i < 32; i++) {
                macb->phy_addr = i;
@@ -718,6 +785,7 @@ static int gmac_init_multi_queues(struct macb_device *macb)
 {
        int i, num_queues = 1;
        u32 queue_mask;
+       unsigned long paddr;
 
        /* bit 0 is never set but queue 0 always exists */
        queue_mask = gem_readl(macb, DCFG6) & 0xff;
@@ -731,10 +799,18 @@ static int gmac_init_multi_queues(struct macb_device *macb)
        macb->dummy_desc->addr = 0;
        flush_dcache_range(macb->dummy_desc_dma, macb->dummy_desc_dma +
                        ALIGN(MACB_TX_DUMMY_DMA_DESC_SIZE, PKTALIGN));
-
-       for (i = 1; i < num_queues; i++)
-               gem_writel_queue_TBQP(macb, macb->dummy_desc_dma, i - 1);
-
+       paddr = macb->dummy_desc_dma;
+
+       for (i = 1; i < num_queues; i++) {
+               gem_writel_queue_TBQP(macb, lower_32_bits(paddr), i - 1);
+               gem_writel_queue_RBQP(macb, lower_32_bits(paddr), i - 1);
+               if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
+                       gem_writel_queue_TBQPH(macb, upper_32_bits(paddr),
+                                              i - 1);
+                       gem_writel_queue_RBQPH(macb, upper_32_bits(paddr),
+                                              i - 1);
+               }
+       }
        return 0;
 }
 
@@ -760,6 +836,9 @@ static void gmac_configure_dma(struct macb_device *macb)
                dmacfg &= ~GEM_BIT(ENDIA_DESC);
 
        dmacfg &= ~GEM_BIT(ADDR64);
+       if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
+               dmacfg |= GEM_BIT(ADDR64);
+
        gem_writel(macb, DMACFG, dmacfg);
 }
 
@@ -775,6 +854,7 @@ static int _macb_init(struct macb_device *macb, const char *name)
        unsigned long paddr;
        int ret;
        int i;
+       int count;
 
        /*
         * macb_halt should have been called at some point before now,
@@ -786,20 +866,28 @@ static int _macb_init(struct macb_device *macb, const char *name)
        for (i = 0; i < MACB_RX_RING_SIZE; i++) {
                if (i == (MACB_RX_RING_SIZE - 1))
                        paddr |= MACB_BIT(RX_WRAP);
-               macb->rx_ring[i].addr = paddr;
-               macb->rx_ring[i].ctrl = 0;
+               if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
+                       count = i * 2;
+               else
+                       count = i;
+               macb->rx_ring[count].ctrl = 0;
+               macb_set_addr(macb, &macb->rx_ring[count], paddr);
                paddr += macb->rx_buffer_size;
        }
        macb_flush_ring_desc(macb, RX);
        macb_flush_rx_buffer(macb);
 
        for (i = 0; i < MACB_TX_RING_SIZE; i++) {
-               macb->tx_ring[i].addr = 0;
+               if (macb->config->hw_dma_cap & HW_DMA_CAP_64B)
+                       count = i * 2;
+               else
+                       count = i;
+               macb_set_addr(macb, &macb->tx_ring[count], 0);
                if (i == (MACB_TX_RING_SIZE - 1))
-                       macb->tx_ring[i].ctrl = MACB_BIT(TX_USED) |
+                       macb->tx_ring[count].ctrl = MACB_BIT(TX_USED) |
                                MACB_BIT(TX_WRAP);
                else
-                       macb->tx_ring[i].ctrl = MACB_BIT(TX_USED);
+                       macb->tx_ring[count].ctrl = MACB_BIT(TX_USED);
        }
        macb_flush_ring_desc(macb, TX);
 
@@ -812,8 +900,12 @@ static int _macb_init(struct macb_device *macb, const char *name)
        gem_writel(macb, DMACFG, MACB_ZYNQ_GEM_DMACR_INIT);
 #endif
 
-       macb_writel(macb, RBQP, macb->rx_ring_dma);
-       macb_writel(macb, TBQP, macb->tx_ring_dma);
+       macb_writel(macb, RBQP, lower_32_bits(macb->rx_ring_dma));
+       macb_writel(macb, TBQP, lower_32_bits(macb->tx_ring_dma));
+       if (macb->config->hw_dma_cap & HW_DMA_CAP_64B) {
+               macb_writel(macb, RBQPH, upper_32_bits(macb->rx_ring_dma));
+               macb_writel(macb, TBQPH, upper_32_bits(macb->tx_ring_dma));
+       }
 
        if (macb_is_gem(macb)) {
                /* Initialize DMA properties */
@@ -1217,6 +1309,7 @@ static int macb_enable_clk(struct udevice *dev)
 
 static const struct macb_config default_gem_config = {
        .dma_burst_length = 16,
+       .hw_dma_cap = HW_DMA_CAP_32B,
        .clk_init = NULL,
 };
 
@@ -1224,11 +1317,12 @@ static int macb_eth_probe(struct udevice *dev)
 {
        struct eth_pdata *pdata = dev_get_plat(dev);
        struct macb_device *macb = dev_get_priv(dev);
+       struct ofnode_phandle_args phandle_args;
        const char *phy_mode;
        int ret;
 
-       phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
-                              NULL);
+       phy_mode = dev_read_prop(dev, "phy-mode", NULL);
+
        if (phy_mode)
                macb->phy_interface = phy_get_interface_by_name(phy_mode);
        if (macb->phy_interface == -1) {
@@ -1236,6 +1330,12 @@ static int macb_eth_probe(struct udevice *dev)
                return -EINVAL;
        }
 
+       /* Read phyaddr from DT */
+       if (!dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
+                                       &phandle_args))
+               macb->phy_addr = ofnode_read_u32_default(phandle_args.node,
+                                                        "reg", -1);
+
        macb->regs = (void *)pdata->iobase;
 
        macb->is_big_endian = (cpu_to_be32(0x12345678) == 0x12345678);
@@ -1304,13 +1404,21 @@ static int macb_eth_of_to_plat(struct udevice *dev)
        return macb_late_eth_of_to_plat(dev);
 }
 
+static const struct macb_config microchip_config = {
+       .dma_burst_length = 16,
+       .hw_dma_cap = HW_DMA_CAP_64B,
+       .clk_init = NULL,
+};
+
 static const struct macb_config sama5d4_config = {
        .dma_burst_length = 4,
+       .hw_dma_cap = HW_DMA_CAP_32B,
        .clk_init = NULL,
 };
 
 static const struct macb_config sifive_config = {
        .dma_burst_length = 16,
+       .hw_dma_cap = HW_DMA_CAP_32B,
        .clk_init = macb_sifive_clk_init,
 };
 
@@ -1324,6 +1432,8 @@ 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 9b16383..72b84ae 100644 (file)
 #define GEM_RX_CSUM_CHECKED_MASK               2
 #define gem_writel_queue_TBQP(port, value, queue_num)  \
        writel((value), (port)->regs + GEM_TBQP(queue_num))
+#define gem_writel_queue_TBQPH(port, value, queue_num) \
+       writel((value), (port)->regs + GEM_TBQPH(queue_num))
+#define gem_writel_queue_RBQP(port, value, queue_num)  \
+       writel((value), (port)->regs + GEM_RBQP(queue_num))
+#define gem_writel_queue_RBQPH(port, value, queue_num) \
+       writel((value), (port)->regs + GEM_RBQPH(queue_num))
 
 #endif /* __DRIVERS_MACB_H__ */
index db2cf86..a3797b2 100644 (file)
 /* mtime register */
 #define MTIME_REG(base)                        ((ulong)(base))
 
-static u64 andes_plmt_get_count(struct udevice *dev)
+static u64 notrace andes_plmt_get_count(struct udevice *dev)
 {
        return readq((void __iomem *)MTIME_REG(dev_get_priv(dev)));
 }
 
+#if CONFIG_IS_ENABLED(RISCV_MMODE) && IS_ENABLED(CONFIG_TIMER_EARLY)
+/**
+ * timer_early_get_rate() - Get the timer rate before driver model
+ */
+unsigned long notrace timer_early_get_rate(void)
+{
+       return RISCV_MMODE_TIMER_FREQ;
+}
+
+/**
+ * timer_early_get_count() - Get the timer count before driver model
+ *
+ */
+u64 notrace timer_early_get_count(void)
+{
+       return readq((void __iomem *)MTIME_REG(RISCV_MMODE_TIMERBASE));
+}
+#endif
+
 static const struct timer_ops andes_plmt_ops = {
        .get_count = andes_plmt_get_count,
 };
index 21ae184..3627ed7 100644 (file)
@@ -16,7 +16,7 @@
 #include <timer.h>
 #include <asm/csr.h>
 
-static u64 riscv_timer_get_count(struct udevice *dev)
+static u64 notrace riscv_timer_get_count(struct udevice *dev)
 {
        __maybe_unused u32 hi, lo;
 
@@ -31,6 +31,25 @@ static u64 riscv_timer_get_count(struct udevice *dev)
        return ((u64)hi << 32) | lo;
 }
 
+#if CONFIG_IS_ENABLED(RISCV_SMODE) && IS_ENABLED(CONFIG_TIMER_EARLY)
+/**
+ * timer_early_get_rate() - Get the timer rate before driver model
+ */
+unsigned long notrace timer_early_get_rate(void)
+{
+       return RISCV_SMODE_TIMER_FREQ;
+}
+
+/**
+ * timer_early_get_count() - Get the timer count before driver model
+ *
+ */
+u64 notrace timer_early_get_count(void)
+{
+       return riscv_timer_get_count(NULL);
+}
+#endif
+
 static int riscv_timer_probe(struct udevice *dev)
 {
        struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
index de23b85..de7b4b9 100644 (file)
 /* mtime register */
 #define MTIME_REG(base)                        ((ulong)(base) + 0xbff8)
 
-static u64 sifive_clint_get_count(struct udevice *dev)
+static u64 notrace sifive_clint_get_count(struct udevice *dev)
 {
        return readq((void __iomem *)MTIME_REG(dev_get_priv(dev)));
 }
 
+#if CONFIG_IS_ENABLED(RISCV_MMODE) && IS_ENABLED(CONFIG_TIMER_EARLY)
+/**
+ * timer_early_get_rate() - Get the timer rate before driver model
+ */
+unsigned long notrace timer_early_get_rate(void)
+{
+       return RISCV_MMODE_TIMER_FREQ;
+}
+
+/**
+ * timer_early_get_count() - Get the timer count before driver model
+ *
+ */
+u64 notrace timer_early_get_count(void)
+{
+       return readq((void __iomem *)MTIME_REG(RISCV_MMODE_TIMERBASE));
+}
+#endif
+
 static const struct timer_ops sifive_clint_ops = {
        .get_count = sifive_clint_get_count,
 };
index b2606e7..bd9c371 100644 (file)
 #endif
 #endif
 
+#define RISCV_MMODE_TIMERBASE           0xe6000000
+#define RISCV_MMODE_TIMER_FREQ          60000000
+
+#define RISCV_SMODE_TIMER_FREQ          60000000
+
 /*
  * CPU and Board Configuration Options
  */
index 8a74705..2499037 100644 (file)
@@ -7,53 +7,34 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
-/*
- * CPU and Board Configuration Options
- */
+#include <linux/sizes.h>
 
-/*
- * Miscellaneous configurable options
- */
-#define CONFIG_SYS_CBSIZE      1024 /* Console I/O Buffer Size */
+#define CONFIG_SYS_SDRAM_BASE       0x80000000
+#define CONFIG_SYS_INIT_SP_ADDR     (CONFIG_SYS_SDRAM_BASE + SZ_2M)
 
-/*
- * Print Buffer Size
- */
-#define CONFIG_SYS_PBSIZE      \
-       (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_LOAD_ADDR        (CONFIG_SYS_SDRAM_BASE + SZ_2M)
 
-/*
- * max number of command args
- */
-#define CONFIG_SYS_MAXARGS     16
+#define CONFIG_SYS_MALLOC_LEN       SZ_8M
 
-/*
- * Boot Argument Buffer Size
- */
-#define CONFIG_SYS_BARGSIZE    CONFIG_SYS_CBSIZE
-
-/*
- * Size of malloc() pool
- * 512kB is suggested, (CONFIG_ENV_SIZE + 128 * 1024) was not enough
- */
-#define CONFIG_SYS_MALLOC_LEN  (512 << 10)
+#define CONFIG_SYS_BOOTM_LEN        SZ_64M
 
-/*
- * Physical Memory Map
- */
-#define PHYS_SDRAM_0           0x80000000 /* SDRAM Bank #1 */
-#define PHYS_SDRAM_0_SIZE      0x40000000 /* 1 GB */
-#define CONFIG_SYS_SDRAM_BASE  PHYS_SDRAM_0
+#define CONFIG_STANDALONE_LOAD_ADDR 0x80200000
 
-/* Init Stack Pointer */
-#define CONFIG_SYS_INIT_SP_ADDR        (CONFIG_SYS_SDRAM_BASE + 0x200000)
+/* Environment options */
 
-#define CONFIG_SYS_LOAD_ADDR   0x80000000 /* SDRAM */
+#define BOOT_TARGET_DEVICES(func) \
+       func(MMC, mmc, 0) \
+       func(DHCP, dhcp, na)
 
-/*
- * memtest works on DRAM
- */
+#include <config_distro_bootcmd.h>
 
-/* When we use RAM as ENV */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+       "bootm_size=0x10000000\0" \
+       "kernel_addr_r=0x84000000\0" \
+       "fdt_addr_r=0x88000000\0" \
+       "scriptaddr=0x88100000\0" \
+       "pxefile_addr_r=0x88200000\0" \
+       "ramdisk_addr_r=0x88300000\0" \
+       BOOTENV
 
 #endif /* __CONFIG_H */
index a2f3358..5291de8 100644 (file)
 
 #define CONFIG_STANDALONE_LOAD_ADDR    0x80200000
 
+#define RISCV_MMODE_TIMERBASE          0x2000000
+#define RISCV_MMODE_TIMER_FREQ         1000000
+
+#define RISCV_SMODE_TIMER_FREQ         1000000
+
 /* Environment options */
 
 #ifndef CONFIG_SPL_BUILD
index c1c79db..0d69d1c 100644 (file)
 
 #define CONFIG_STANDALONE_LOAD_ADDR    0x80200000
 
+#define RISCV_MMODE_TIMERBASE          0x2000000
+#define RISCV_MMODE_TIMER_FREQ         1000000
+
+#define RISCV_SMODE_TIMER_FREQ         1000000
+
 /* Environment options */
 
 #ifndef CONFIG_SPL_BUILD
index 36ff522..08acb25 100644 (file)
 #ifndef CONFIG_EXTRA_ENV_SETTINGS
 #define CONFIG_EXTRA_ENV_SETTINGS \
        "loadaddr=0x80060000\0" \
-       "fdt_addr_r=0x80028000\0" \
+       "fdt_addr_r=0x80400000\0" \
        "scriptaddr=0x80020000\0" \
        "kernel_addr_r=0x80060000\0" \
-       "fdtfile=kendryte/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0"
+       "fdtfile=kendryte/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
+       "k210_bootcmd=load mmc 0:1 $loadaddr /uImage && " \
+               "load mmc 0:1 $fdt_addr_r /k210.dtb && " \
+               "bootm $loadaddr - $fdt_addr_r\0"
 #endif
 
 #endif /* CONFIGS_SIPEED_MAIX_H */
diff --git a/include/dt-bindings/clock/microchip-mpfs-clock.h b/include/dt-bindings/clock/microchip-mpfs-clock.h
new file mode 100644 (file)
index 0000000..55fe646
--- /dev/null
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Copyright (C) 2020 Microchip Technology Inc.
+ * Padmarao Begari <padmarao.begari@microchip.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MICROCHIP_MPFS_H_
+#define _DT_BINDINGS_CLK_MICROCHIP_MPFS_H_
+
+#define CLK_CPU                0
+#define CLK_AXI                1
+#define CLK_AHB                2
+
+#define CLK_ENVM       3
+#define CLK_MAC0       4
+#define CLK_MAC1       5
+#define CLK_MMC                6
+#define CLK_TIMER      7
+#define CLK_MMUART0    8
+#define CLK_MMUART1    9
+#define CLK_MMUART2    10
+#define CLK_MMUART3    11
+#define CLK_MMUART4    12
+#define CLK_SPI0       13
+#define CLK_SPI1       14
+#define CLK_I2C0       15
+#define CLK_I2C1       16
+#define CLK_CAN0       17
+#define CLK_CAN1       18
+#define CLK_USB                19
+#define CLK_RESERVED   20
+#define CLK_RTC                21
+#define CLK_QSPI       22
+#define CLK_GPIO0      23
+#define CLK_GPIO1      24
+#define CLK_GPIO2      25
+#define CLK_DDRC       26
+#define CLK_FIC0       27
+#define CLK_FIC1       28
+#define CLK_FIC2       29
+#define CLK_FIC3       30
+#define CLK_ATHENA     31
+#define CLK_CFM                32
+
+#endif /* _DT_BINDINGS_CLK_MICROCHIP_MPFS_H_ */
index 88c43a3..b35a71a 100644 (file)
@@ -210,6 +210,7 @@ config BITREVERSE
 config TRACE
        bool "Support for tracing of function calls and timing"
        imply CMD_TRACE
+       select TIMER_EARLY
        help
          Enables function tracing within U-Boot. This allows recording of call
          traces including timing information. The command can write data to