mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-24 04:34:22 +08:00
Prepare v2022.01-rc4
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEEGjx/cOCPqxcHgJu/FHw5/5Y0tywFAmHArDwACgkQFHw5/5Y0 tyzxyAv/SjZjoEwG8nu7ptVZqTsZfm+tVwwWmQEBAA40MXy/KSccDtbUwB5GCO6f Uvk+qFFDbCkbGZh5VKbQusMmUoB02Xu9zUoSxKxcXL4WfC6Bg5GV/UWN9s8G3Tm6 4wcP0l8WFcQjjr89UfXugiZH58psvFu6PBbWVY4rMH9gZ5ds0AkNOF0L+HbdVmMR a5HBfrcySRY2kiTQuKF+RVlMW6BtaOqJp/XIyy8w6bH09ykMomj/u7z3JP3y9ZzL w3FXqCLlIEnvdDcqfWvfjoJ/gm0WcLulgSVpTFGS0jgJpnbeAURtZcuVgj6aPRUW FRon+u0tj3wpFjibs2cpyXWd+gw/bLLFpDXx78AUAPjxG31tEKbnR1j8R8wBZJ0B TqWZ3pCne/LPOT90y2KW2z6ty2n/yEn6qEFFT9MN9R4L0N+U0er//sYJC/nn/e6u fjvQ9OPLbnAfHVrad3ZeIkePrLOIF6XYwNQpsjt9aE2kU9IvV5sTa8TxZuQgasBU A46FgXtC =MEG2 -----END PGP SIGNATURE----- Merge tag 'v2022.01-rc4' into next Prepare v2022.01-rc4
This commit is contained in:
commit
4afab30cae
@ -728,8 +728,11 @@ W: https://u-boot.readthedocs.io/en/latest/develop/uefi/u-boot_on_efi.html
|
||||
F: board/efi/efi-x86_app
|
||||
F: configs/efi-x86_app*
|
||||
F: doc/develop/uefi/u-boot_on_efi.rst
|
||||
F: drivers/block/efi-media-uclass.c
|
||||
F: drivers/block/sb_efi_media.c
|
||||
F: lib/efi/efi_app.c
|
||||
F: scripts/build-efi.sh
|
||||
F: test/dm/efi_media.c
|
||||
|
||||
EFI PAYLOAD
|
||||
M: Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||
|
2
Makefile
2
Makefile
@ -3,7 +3,7 @@
|
||||
VERSION = 2022
|
||||
PATCHLEVEL = 01
|
||||
SUBLEVEL =
|
||||
EXTRAVERSION = -rc3
|
||||
EXTRAVERSION = -rc4
|
||||
NAME =
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -197,6 +197,14 @@
|
||||
compatible = "audio-graph-card";
|
||||
label = "rcar-sound";
|
||||
dais = <&rsnd_port0>, <&rsnd_port1>;
|
||||
widgets = "Microphone", "Mic Jack",
|
||||
"Line", "Line In Jack",
|
||||
"Headphone", "Headphone Jack";
|
||||
mic-det-gpio = <&gpio0 2 GPIO_ACTIVE_LOW>;
|
||||
routing = "Headphone Jack", "HPOUTL",
|
||||
"Headphone Jack", "HPOUTR",
|
||||
"IN3R", "MICBIAS",
|
||||
"Mic Jack", "IN3R";
|
||||
};
|
||||
|
||||
vccq_sdhi0: regulator-vccq-sdhi0 {
|
||||
@ -271,12 +279,12 @@
|
||||
&ehci0 {
|
||||
dr_mode = "otg";
|
||||
status = "okay";
|
||||
clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&versaclock5 3>;
|
||||
clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&usb2_clksel>, <&versaclock5 3>;
|
||||
};
|
||||
|
||||
&ehci1 {
|
||||
status = "okay";
|
||||
clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>;
|
||||
clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&usb2_clksel>, <&versaclock5 3>;
|
||||
};
|
||||
|
||||
&hdmi0 {
|
||||
@ -615,7 +623,7 @@
|
||||
};
|
||||
|
||||
&rcar_sound {
|
||||
pinctrl-0 = <&sound_pins &sound_clk_pins>;
|
||||
pinctrl-0 = <&sound_pins>, <&sound_clk_pins>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
/* Single DAI */
|
||||
@ -639,7 +647,7 @@
|
||||
bitclock-master = <&rsnd_endpoint0>;
|
||||
frame-master = <&rsnd_endpoint0>;
|
||||
|
||||
playback = <&ssi1 &dvc1 &src1>;
|
||||
playback = <&ssi1>, <&dvc1>, <&src1>;
|
||||
capture = <&ssi0>;
|
||||
};
|
||||
};
|
||||
|
@ -7,19 +7,10 @@
|
||||
#include <dt-bindings/clk/versaclock.h>
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
spi0 = &rpc;
|
||||
};
|
||||
|
||||
memory@48000000 {
|
||||
device_type = "memory";
|
||||
/* first 128MB is reserved for secure area. */
|
||||
reg = <0x0 0x48000000 0x0 0xc000000>;
|
||||
};
|
||||
|
||||
memory@57000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x57000000 0x0 0x29000000>;
|
||||
reg = <0x0 0x48000000 0x0 0x78000000>;
|
||||
};
|
||||
|
||||
osc_32k: osc_32k {
|
||||
@ -59,12 +50,17 @@
|
||||
&avb {
|
||||
pinctrl-0 = <&avb_pins>;
|
||||
pinctrl-names = "default";
|
||||
phy-mode = "rgmii-rxid";
|
||||
phy-handle = <&phy0>;
|
||||
rx-internal-delay-ps = <1800>;
|
||||
tx-internal-delay-ps = <2000>;
|
||||
clocks = <&cpg CPG_MOD 812>, <&versaclock5 4>;
|
||||
clock-names = "fck", "refclk";
|
||||
status = "okay";
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
compatible = "ethernet-phy-id004d.d074",
|
||||
"ethernet-phy-ieee802.3-c22";
|
||||
reg = <0>;
|
||||
interrupt-parent = <&gpio2>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
@ -153,7 +149,7 @@
|
||||
};
|
||||
|
||||
eeprom@50 {
|
||||
compatible = "microchip,at24c64", "atmel,24c64";
|
||||
compatible = "microchip,24c64", "atmel,24c64";
|
||||
pagesize = <32>;
|
||||
read-only; /* Manufacturing EEPROM programmed at factory */
|
||||
reg = <0x50>;
|
||||
@ -279,25 +275,6 @@
|
||||
};
|
||||
};
|
||||
|
||||
&rpc {
|
||||
compatible = "renesas,rcar-gen3-rpc";
|
||||
num-cs = <1>;
|
||||
spi-max-frequency = <40000000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "okay";
|
||||
|
||||
flash0: spi-flash@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
reg = <0>;
|
||||
compatible = "spi-flash", "jedec,spi-nor";
|
||||
spi-max-frequency = <40000000>;
|
||||
spi-tx-bus-width = <1>;
|
||||
spi-rx-bus-width = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
&scif_clk {
|
||||
clock-frequency = <14745600>;
|
||||
};
|
||||
@ -340,17 +317,17 @@
|
||||
vqmmc-supply = <®_1p8v>;
|
||||
bus-width = <8>;
|
||||
mmc-hs200-1_8v;
|
||||
no-sd;
|
||||
no-sdio;
|
||||
non-removable;
|
||||
fixed-emmc-driver-type = <1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb2_clksel {
|
||||
status = "okay";
|
||||
clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>,
|
||||
<&versaclock5 3>, <&usb3s0_clk>;
|
||||
clock-names = "ehci_ohci", "hs-usb-if",
|
||||
"usb_extal", "usb_xtal";
|
||||
<&versaclock5 3>, <&usb3s0_clk>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb3s0_clk {
|
||||
|
@ -1,34 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2020 Compass Electronics Group, LLC
|
||||
* Copyright 2021 LogicPD dba Beacon EmbeddedWorks
|
||||
*/
|
||||
|
||||
/ {
|
||||
soc {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
};
|
||||
|
||||
&cpg {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&extal_clk {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&prr {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&extalr_clk {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&sdhi0 {
|
||||
/delete-property/ cd-gpios;
|
||||
};
|
||||
|
||||
&sdhi2 {
|
||||
status = "disabled";
|
||||
};
|
||||
#include "rz-g2-beacon-u-boot.dtsi"
|
||||
|
@ -21,6 +21,9 @@
|
||||
serial4 = &hscif2;
|
||||
serial5 = &scif5;
|
||||
ethernet0 = &avb;
|
||||
mmc0 = &sdhi3;
|
||||
mmc1 = &sdhi0;
|
||||
mmc2 = &sdhi2;
|
||||
};
|
||||
|
||||
chosen {
|
||||
|
@ -1,34 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2020 Compass Electronics Group, LLC
|
||||
* Copyright 2021 LogicPD dba Beacon EmbeddedWorks
|
||||
*/
|
||||
|
||||
/ {
|
||||
soc {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
};
|
||||
|
||||
&cpg {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&extal_clk {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&prr {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&extalr_clk {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&sdhi0 {
|
||||
/delete-property/ cd-gpios;
|
||||
};
|
||||
|
||||
&sdhi2 {
|
||||
status = "disabled";
|
||||
};
|
||||
#include "rz-g2-beacon-u-boot.dtsi"
|
||||
|
@ -22,6 +22,9 @@
|
||||
serial5 = &scif5;
|
||||
serial6 = &scif4;
|
||||
ethernet0 = &avb;
|
||||
mmc0 = &sdhi3;
|
||||
mmc1 = &sdhi0;
|
||||
mmc2 = &sdhi2;
|
||||
};
|
||||
|
||||
chosen {
|
||||
|
@ -1,44 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2020 Compass Electronics Group, LLC
|
||||
* Copyright 2021 LogicPD dba Beacon EmbeddedWorks
|
||||
*/
|
||||
|
||||
/ {
|
||||
soc {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
};
|
||||
|
||||
&cpg {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&extal_clk {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&prr {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&extalr_clk {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&sdhi0 {
|
||||
/delete-property/ cd-gpios;
|
||||
sd-uhs-sdr12;
|
||||
sd-uhs-sdr25;
|
||||
sd-uhs-sdr104;
|
||||
max-frequency = <208000000>;
|
||||
};
|
||||
|
||||
&sdhi2 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&sdhi3 {
|
||||
mmc-ddr-1_8v;
|
||||
mmc-hs200-1_8v;
|
||||
mmc-hs400-1_8v;
|
||||
};
|
||||
#include "rz-g2-beacon-u-boot.dtsi"
|
||||
|
@ -22,6 +22,9 @@
|
||||
serial5 = &scif5;
|
||||
serial6 = &scif4;
|
||||
ethernet0 = &avb;
|
||||
mmc0 = &sdhi3;
|
||||
mmc1 = &sdhi0;
|
||||
mmc2 = &sdhi2;
|
||||
};
|
||||
|
||||
chosen {
|
||||
|
75
arch/arm/dts/rz-g2-beacon-u-boot.dtsi
Normal file
75
arch/arm/dts/rz-g2-beacon-u-boot.dtsi
Normal file
@ -0,0 +1,75 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2021 LogicPD dba Beacon EmbeddedWorks
|
||||
*/
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
spi0 = &rpc;
|
||||
};
|
||||
|
||||
soc {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
};
|
||||
|
||||
&cpg {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&ehci0 {
|
||||
clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&versaclock5 3>;
|
||||
};
|
||||
|
||||
&ehci1 {
|
||||
clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&versaclock5 3>;
|
||||
};
|
||||
|
||||
&extal_clk {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&extalr_clk {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&prr {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&rpc {
|
||||
compatible = "renesas,rcar-gen3-rpc";
|
||||
num-cs = <1>;
|
||||
spi-max-frequency = <40000000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "okay";
|
||||
|
||||
flash0: spi-flash@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
reg = <0>;
|
||||
compatible = "spi-flash", "jedec,spi-nor";
|
||||
spi-max-frequency = <40000000>;
|
||||
spi-tx-bus-width = <1>;
|
||||
spi-rx-bus-width = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
&sdhi0 {
|
||||
/delete-property/ cd-gpios;
|
||||
sd-uhs-sdr12;
|
||||
sd-uhs-sdr25;
|
||||
sd-uhs-sdr104;
|
||||
max-frequency = <208000000>;
|
||||
};
|
||||
|
||||
&sdhi2 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&sdhi3 {
|
||||
mmc-ddr-1_8v;
|
||||
mmc-hs200-1_8v;
|
||||
mmc-hs400-1_8v;
|
||||
};
|
@ -13,7 +13,7 @@
|
||||
/ {
|
||||
aliases {
|
||||
mmc0 = &mmc0;
|
||||
#if CONFIG_MMC_SUNXI_EXTRA_SLOT == 2
|
||||
#if CONFIG_MMC_SUNXI_SLOT_EXTRA == 2
|
||||
mmc1 = &mmc2;
|
||||
#endif
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2016-2017 Intel Corporation
|
||||
* Copyright (C) 2016-2021 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef _SOCFPGA_MISC_H_
|
||||
@ -45,7 +45,12 @@ int is_fpga_config_ready(void);
|
||||
#endif
|
||||
|
||||
void do_bridge_reset(int enable, unsigned int mask);
|
||||
void force_periph_program(unsigned int status);
|
||||
bool is_regular_boot_valid(void);
|
||||
bool is_periph_program_force(void);
|
||||
void set_regular_boot(unsigned int status);
|
||||
void socfpga_pl310_clear(void);
|
||||
void socfpga_get_managers_addr(void);
|
||||
int qspi_flash_software_reset(void);
|
||||
|
||||
#endif /* _SOCFPGA_MISC_H_ */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2016-2017 Intel Corporation
|
||||
* Copyright (C) 2016-2021 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef _RESET_MANAGER_ARRIA10_H_
|
||||
@ -22,6 +22,7 @@ int socfpga_bridges_reset(void);
|
||||
#define RSTMGR_A10_PER1MODRST 0x28
|
||||
#define RSTMGR_A10_BRGMODRST 0x2c
|
||||
#define RSTMGR_A10_SYSMODRST 0x30
|
||||
#define RSTMGR_A10_SYSWARMMASK 0x50
|
||||
|
||||
#define RSTMGR_CTRL RSTMGR_A10_CTRL
|
||||
|
||||
@ -115,4 +116,7 @@ int socfpga_bridges_reset(void);
|
||||
#define ALT_RSTMGR_HDSKEN_FPGAHSEN_SET_MSK BIT(2)
|
||||
#define ALT_RSTMGR_HDSKEN_ETRSTALLEN_SET_MSK BIT(3)
|
||||
|
||||
#define ALT_RSTMGR_FPGAMGRWARMMASK_S2F_SET_MSK BIT(3)
|
||||
#define ALT_RSTMGR_SYSWARMMASK_S2F_SET_MSK BIT(4)
|
||||
|
||||
#endif /* _RESET_MANAGER_ARRIA10_H_ */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2016-2017 Intel Corporation <www.intel.com>
|
||||
* Copyright (C) 2016-2021 Intel Corporation <www.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef _SYSTEM_MANAGER_ARRIA10_H_
|
||||
@ -31,6 +31,11 @@
|
||||
#define SYSMGR_A10_NOC_IDLEACK 0xd0
|
||||
#define SYSMGR_A10_NOC_IDLESTATUS 0xd4
|
||||
#define SYSMGR_A10_FPGA2SOC_CTRL 0xd8
|
||||
#define SYSMGR_A10_ROMCODE_CTRL 0x204
|
||||
#define SYSMGR_A10_ROMCODE_INITSWSTATE 0x20C
|
||||
#define SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND 0x208
|
||||
#define SYSMGR_A10_ISW_HANDOFF_BASE 0x230
|
||||
#define SYSMGR_A10_ISW_HANDOFF_7 0x1c
|
||||
|
||||
#define SYSMGR_SDMMC SYSMGR_A10_SDMMC
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2016-2017 Intel Corporation
|
||||
* Copyright (C) 2016-2021 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <altera.h>
|
||||
@ -11,6 +11,7 @@
|
||||
#include <miiphy.h>
|
||||
#include <netdev.h>
|
||||
#include <ns16550.h>
|
||||
#include <spi_flash.h>
|
||||
#include <watchdog.h>
|
||||
#include <asm/arch/misc.h>
|
||||
#include <asm/arch/pinmux.h>
|
||||
@ -21,6 +22,7 @@
|
||||
#include <asm/arch/nic301.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/pl310.h>
|
||||
#include <linux/sizes.h>
|
||||
|
||||
#define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q1_3 0x08
|
||||
#define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q2_11 0x58
|
||||
@ -29,6 +31,13 @@
|
||||
#define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q3_7 0x78
|
||||
#define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q4_3 0x98
|
||||
|
||||
#define REGULAR_BOOT_MAGIC 0xd15ea5e
|
||||
#define PERIPH_RBF_PROG_FORCE 0x50455249
|
||||
|
||||
#define QSPI_S25FL_SOFT_RESET_COMMAND 0x00f0ff82
|
||||
#define QSPI_N25_SOFT_RESET_COMMAND 0x00000001
|
||||
#define QSPI_NO_SOFT_RESET 0x00000000
|
||||
|
||||
/*
|
||||
* FPGA programming support for SoC FPGA Arria 10
|
||||
*/
|
||||
@ -122,3 +131,118 @@ void do_bridge_reset(int enable, unsigned int mask)
|
||||
else
|
||||
socfpga_bridges_reset();
|
||||
}
|
||||
|
||||
/*
|
||||
* This function set/unset flag with number "0x50455249" to
|
||||
* handoff register isw_handoff[7] - 0xffd0624c
|
||||
* This flag is used to force periph RBF program regardless FPGA status
|
||||
* and double periph RBF config are needed on some devices or boards to
|
||||
* stabilize the IO config system.
|
||||
*/
|
||||
void force_periph_program(unsigned int status)
|
||||
{
|
||||
if (status)
|
||||
writel(PERIPH_RBF_PROG_FORCE, socfpga_get_sysmgr_addr() +
|
||||
SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7);
|
||||
else
|
||||
writel(0, socfpga_get_sysmgr_addr() +
|
||||
SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is used to check whether
|
||||
* handoff register isw_handoff[7] contains
|
||||
* flag for forcing the periph RBF program "0x50455249".
|
||||
*/
|
||||
bool is_periph_program_force(void)
|
||||
{
|
||||
unsigned int status;
|
||||
|
||||
status = readl(socfpga_get_sysmgr_addr() +
|
||||
SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7);
|
||||
|
||||
if (status == PERIPH_RBF_PROG_FORCE)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function set/unset magic number "0xd15ea5e" to
|
||||
* handoff register isw_handoff[7] - 0xffd0624c
|
||||
* This magic number is part of boot progress tracking
|
||||
* and it's required for warm reset workaround on MPFE hang issue.
|
||||
*/
|
||||
void set_regular_boot(unsigned int status)
|
||||
{
|
||||
if (status)
|
||||
writel(REGULAR_BOOT_MAGIC, socfpga_get_sysmgr_addr() +
|
||||
SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7);
|
||||
else
|
||||
writel(0, socfpga_get_sysmgr_addr() +
|
||||
SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is used to check whether
|
||||
* handoff register isw_handoff[7] contains
|
||||
* magic number "0xd15ea5e".
|
||||
*/
|
||||
bool is_regular_boot_valid(void)
|
||||
{
|
||||
unsigned int status;
|
||||
|
||||
status = readl(socfpga_get_sysmgr_addr() +
|
||||
SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7);
|
||||
|
||||
if (status == REGULAR_BOOT_MAGIC)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_CADENCE_QSPI)
|
||||
/* This function is used to trigger software reset
|
||||
* to the QSPI flash. On some boards, the QSPI flash reset may
|
||||
* not be connected to the HPS warm reset.
|
||||
*/
|
||||
int qspi_flash_software_reset(void)
|
||||
{
|
||||
struct udevice *flash;
|
||||
int ret;
|
||||
|
||||
/* Get the flash info */
|
||||
ret = spi_flash_probe_bus_cs(CONFIG_SF_DEFAULT_BUS,
|
||||
CONFIG_SF_DEFAULT_CS,
|
||||
CONFIG_SF_DEFAULT_SPEED,
|
||||
CONFIG_SF_DEFAULT_MODE,
|
||||
&flash);
|
||||
|
||||
if (ret) {
|
||||
debug("Failed to initialize SPI flash at ");
|
||||
debug("%u:%u (error %d)\n", CONFIG_SF_DEFAULT_BUS,
|
||||
CONFIG_SF_DEFAULT_CS, ret);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!flash)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* QSPI flash software reset command, for the case where
|
||||
* no HPS reset connected to QSPI flash reset
|
||||
*/
|
||||
if (!memcmp(flash->name, "N25", SZ_1 + SZ_2))
|
||||
writel(QSPI_N25_SOFT_RESET_COMMAND, socfpga_get_sysmgr_addr() +
|
||||
SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND);
|
||||
else if (!memcmp(flash->name, "S25FL", SZ_1 + SZ_4))
|
||||
writel(QSPI_S25FL_SOFT_RESET_COMMAND,
|
||||
socfpga_get_sysmgr_addr() +
|
||||
SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND);
|
||||
else /* No software reset */
|
||||
writel(QSPI_NO_SOFT_RESET, socfpga_get_sysmgr_addr() +
|
||||
SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2012-2019 Altera Corporation <www.altera.com>
|
||||
* Copyright (C) 2012-2021 Altera Corporation <www.altera.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
@ -30,8 +30,13 @@
|
||||
#include <asm/arch/fpga_manager.h>
|
||||
#include <mmc.h>
|
||||
#include <memalign.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#define FPGA_BUFSIZ 16 * 1024
|
||||
#define FSBL_IMAGE_IS_VALID 0x49535756
|
||||
|
||||
#define FSBL_IMAGE_IS_INVALID 0x0
|
||||
#define BOOTROM_CONFIGURES_IO_PINMUX 0x3
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@ -106,6 +111,8 @@ u32 spl_mmc_boot_mode(const u32 boot_device)
|
||||
|
||||
void spl_board_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ALLOC_CACHE_ALIGN_BUFFER(char, buf, FPGA_BUFSIZ);
|
||||
|
||||
/* enable console uart printing */
|
||||
@ -116,8 +123,7 @@ void spl_board_init(void)
|
||||
|
||||
/* If the full FPGA is already loaded, ie.from EPCQ, config fpga pins */
|
||||
if (is_fpgamgr_user_mode()) {
|
||||
int ret = config_pins(gd->fdt_blob, "shared");
|
||||
|
||||
ret = config_pins(gd->fdt_blob, "shared");
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
@ -127,11 +133,110 @@ void spl_board_init(void)
|
||||
} else if (!is_fpgamgr_early_user_mode()) {
|
||||
/* Program IOSSM(early IO release) or full FPGA */
|
||||
fpgamgr_program(buf, FPGA_BUFSIZ, 0);
|
||||
|
||||
/* Skipping double program for combined RBF */
|
||||
if (!is_fpgamgr_user_mode()) {
|
||||
/*
|
||||
* Expect FPGA entered early user mode, so
|
||||
* the flag is set to re-program IOSSM
|
||||
*/
|
||||
force_periph_program(true);
|
||||
|
||||
/* Re-program IOSSM to stabilize IO system */
|
||||
fpgamgr_program(buf, FPGA_BUFSIZ, 0);
|
||||
|
||||
force_periph_program(false);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the IOSSM/full FPGA is already loaded, start DDR */
|
||||
if (is_fpgamgr_early_user_mode() || is_fpgamgr_user_mode())
|
||||
if (is_fpgamgr_early_user_mode() || is_fpgamgr_user_mode()) {
|
||||
if (!is_regular_boot_valid()) {
|
||||
/*
|
||||
* Ensure all signals in stable state before triggering
|
||||
* warm reset. This value is recommended from stress
|
||||
* test.
|
||||
*/
|
||||
mdelay(10);
|
||||
|
||||
#if IS_ENABLED(CONFIG_CADENCE_QSPI)
|
||||
/*
|
||||
* Trigger software reset to QSPI flash.
|
||||
* On some boards, the QSPI flash reset may not be
|
||||
* connected to the HPS warm reset.
|
||||
*/
|
||||
qspi_flash_software_reset();
|
||||
#endif
|
||||
|
||||
ret = readl(socfpga_get_rstmgr_addr() +
|
||||
RSTMGR_A10_SYSWARMMASK);
|
||||
/*
|
||||
* Masking s2f & FPGA manager module reset from warm
|
||||
* reset
|
||||
*/
|
||||
writel(ret & (~(ALT_RSTMGR_SYSWARMMASK_S2F_SET_MSK |
|
||||
ALT_RSTMGR_FPGAMGRWARMMASK_S2F_SET_MSK)),
|
||||
socfpga_get_rstmgr_addr() +
|
||||
RSTMGR_A10_SYSWARMMASK);
|
||||
|
||||
/*
|
||||
* BootROM will configure both IO and pin mux after a
|
||||
* warm reset
|
||||
*/
|
||||
ret = readl(socfpga_get_sysmgr_addr() +
|
||||
SYSMGR_A10_ROMCODE_CTRL);
|
||||
writel(ret | BOOTROM_CONFIGURES_IO_PINMUX,
|
||||
socfpga_get_sysmgr_addr() +
|
||||
SYSMGR_A10_ROMCODE_CTRL);
|
||||
|
||||
/*
|
||||
* Up to here, image is considered valid and should be
|
||||
* set as valid before warm reset is triggered
|
||||
*/
|
||||
writel(FSBL_IMAGE_IS_VALID, socfpga_get_sysmgr_addr() +
|
||||
SYSMGR_A10_ROMCODE_INITSWSTATE);
|
||||
|
||||
/*
|
||||
* Set this flag to scratch register, so that a proper
|
||||
* boot progress before / after warm reset can be
|
||||
* tracked by FSBL
|
||||
*/
|
||||
set_regular_boot(true);
|
||||
|
||||
WATCHDOG_RESET();
|
||||
|
||||
reset_cpu();
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset this flag to scratch register, so that a proper
|
||||
* boot progress before / after warm reset can be
|
||||
* tracked by FSBL
|
||||
*/
|
||||
set_regular_boot(false);
|
||||
|
||||
ret = readl(socfpga_get_rstmgr_addr() +
|
||||
RSTMGR_A10_SYSWARMMASK);
|
||||
|
||||
/*
|
||||
* Unmasking s2f & FPGA manager module reset from warm
|
||||
* reset
|
||||
*/
|
||||
writel(ret | ALT_RSTMGR_SYSWARMMASK_S2F_SET_MSK |
|
||||
ALT_RSTMGR_FPGAMGRWARMMASK_S2F_SET_MSK,
|
||||
socfpga_get_rstmgr_addr() + RSTMGR_A10_SYSWARMMASK);
|
||||
|
||||
/*
|
||||
* Up to here, MPFE hang workaround is considered done and
|
||||
* should be reset as invalid until FSBL successfully loading
|
||||
* SSBL, and prepare jumping to SSBL, then only setting as
|
||||
* valid
|
||||
*/
|
||||
writel(FSBL_IMAGE_IS_INVALID, socfpga_get_sysmgr_addr() +
|
||||
SYSMGR_A10_ROMCODE_INITSWSTATE);
|
||||
|
||||
ddr_calibration_sequence();
|
||||
}
|
||||
|
||||
if (!is_fpgamgr_user_mode())
|
||||
fpgamgr_program(buf, FPGA_BUFSIZ, 0);
|
||||
@ -169,3 +274,10 @@ void board_init_f(ulong dummy)
|
||||
config_dedicated_pins(gd->fdt_blob);
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
/* board specific function prior loading SSBL / U-Boot proper */
|
||||
void spl_board_prepare_for_boot(void)
|
||||
{
|
||||
writel(FSBL_IMAGE_IS_VALID, socfpga_get_sysmgr_addr() +
|
||||
SYSMGR_A10_ROMCODE_INITSWSTATE);
|
||||
}
|
||||
|
@ -40,3 +40,16 @@ config SIFIVE_FU740
|
||||
imply DM_I2C
|
||||
imply SYS_I2C_OCORES
|
||||
imply SPL_I2C
|
||||
|
||||
if ENV_IS_IN_SPI_FLASH
|
||||
|
||||
config ENV_OFFSET
|
||||
default 0x505000
|
||||
|
||||
config ENV_SIZE
|
||||
default 0x20000
|
||||
|
||||
config ENV_SECT_SIZE
|
||||
default 0x10000
|
||||
|
||||
endif # ENV_IS_IN_SPI_FLASH
|
||||
|
@ -16,6 +16,10 @@
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
config {
|
||||
u-boot,spl-payload-offset = <0x105000>; /* loader2 @1044KB */
|
||||
};
|
||||
|
||||
hfclk {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
@ -30,6 +34,13 @@
|
||||
clocks = <&rtcclk>;
|
||||
};
|
||||
|
||||
&qspi0 {
|
||||
u-boot,dm-spl;
|
||||
flash@0 {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
mmc@0 {
|
||||
u-boot,dm-spl;
|
||||
|
@ -1,417 +1,157 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/* Copyright (c) 2020 Microchip Technology Inc */
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (C) 2021 Microchip Technology Inc.
|
||||
* Padmarao Begari <padmarao.begari@microchip.com>
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include "dt-bindings/clock/microchip-mpfs-clock.h"
|
||||
|
||||
#include "microchip-mpfs.dtsi"
|
||||
|
||||
/* Clock frequency (in Hz) of the rtcclk */
|
||||
#define RTCCLK_FREQ 1000000
|
||||
|
||||
/ {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
model = "Microchip MPFS Icicle Kit";
|
||||
compatible = "microchip,mpfs-icicle-kit";
|
||||
model = "Microchip PolarFire-SoC Icicle Kit";
|
||||
compatible = "microchip,mpfs-icicle-kit", "microchip,mpfs";
|
||||
|
||||
aliases {
|
||||
serial0 = &uart0;
|
||||
ethernet0 = &emac1;
|
||||
serial1 = &uart1;
|
||||
ethernet0 = &mac1;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0";
|
||||
stdout-path = "serial1";
|
||||
};
|
||||
|
||||
cpucomplex: cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
cpus {
|
||||
timebase-frequency = <RTCCLK_FREQ>;
|
||||
cpu0: cpu@0 {
|
||||
clocks = <&clkcfg CLK_CPU>;
|
||||
compatible = "sifive,e51", "sifive,rocket0", "riscv";
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-sets = <128>;
|
||||
i-cache-size = <16384>;
|
||||
reg = <0>;
|
||||
riscv,isa = "rv64imac";
|
||||
status = "disabled";
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
600000 1100000
|
||||
300000 950000
|
||||
150000 750000
|
||||
>;
|
||||
cpu0intc: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
cpu1: cpu@1 {
|
||||
clocks = <&clkcfg CLK_CPU>;
|
||||
compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
|
||||
d-cache-block-size = <64>;
|
||||
d-cache-sets = <64>;
|
||||
d-cache-size = <32768>;
|
||||
d-tlb-sets = <1>;
|
||||
d-tlb-size = <32>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-sets = <64>;
|
||||
i-cache-size = <32768>;
|
||||
i-tlb-sets = <1>;
|
||||
i-tlb-size = <32>;
|
||||
mmu-type = "riscv,sv39";
|
||||
reg = <1>;
|
||||
riscv,isa = "rv64imafdc";
|
||||
tlb-split;
|
||||
status = "okay";
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
600000 1100000
|
||||
300000 950000
|
||||
150000 750000
|
||||
>;
|
||||
cpu1intc: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
cpu2: cpu@2 {
|
||||
clocks = <&clkcfg CLK_CPU>;
|
||||
compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
|
||||
d-cache-block-size = <64>;
|
||||
d-cache-sets = <64>;
|
||||
d-cache-size = <32768>;
|
||||
d-tlb-sets = <1>;
|
||||
d-tlb-size = <32>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-sets = <64>;
|
||||
i-cache-size = <32768>;
|
||||
i-tlb-sets = <1>;
|
||||
i-tlb-size = <32>;
|
||||
mmu-type = "riscv,sv39";
|
||||
reg = <2>;
|
||||
riscv,isa = "rv64imafdc";
|
||||
tlb-split;
|
||||
status = "okay";
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
600000 1100000
|
||||
300000 950000
|
||||
150000 750000
|
||||
>;
|
||||
cpu2intc: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
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";
|
||||
|
||||
reserved-memory {
|
||||
ranges;
|
||||
clint0: clint@2000000 {
|
||||
compatible = "riscv,clint0";
|
||||
interrupts-extended = <&cpu0intc 3 &cpu0intc 7
|
||||
&cpu1intc 3 &cpu1intc 7
|
||||
&cpu2intc 3 &cpu2intc 7
|
||||
&cpu3intc 3 &cpu3intc 7
|
||||
&cpu4intc 3 &cpu4intc 7>;
|
||||
reg = <0x0 0x2000000 0x0 0x10000>;
|
||||
reg-names = "control";
|
||||
clock-frequency = <RTCCLK_FREQ>;
|
||||
};
|
||||
cachecontroller: cache-controller@2010000 {
|
||||
compatible = "sifive,fu540-c000-ccache", "cache";
|
||||
cache-block-size = <64>;
|
||||
cache-level = <2>;
|
||||
cache-sets = <1024>;
|
||||
cache-size = <2097152>;
|
||||
cache-unified;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <1 2 3>;
|
||||
reg = <0x0 0x2010000 0x0 0x1000>;
|
||||
};
|
||||
plic: interrupt-controller@c000000 {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "sifive,plic-1.0.0";
|
||||
reg = <0x0 0xc000000 0x0 0x4000000>;
|
||||
riscv,max-priority = <7>;
|
||||
riscv,ndev = <186>;
|
||||
interrupt-controller;
|
||||
interrupts-extended = <
|
||||
&cpu0intc 11
|
||||
&cpu1intc 11 &cpu1intc 9
|
||||
&cpu2intc 11 &cpu2intc 9
|
||||
&cpu3intc 11 &cpu3intc 9
|
||||
&cpu4intc 11 &cpu4intc 9>;
|
||||
};
|
||||
uart0: serial@20000000 {
|
||||
compatible = "ns16550a";
|
||||
reg = <0x0 0x20000000 0x0 0x400>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <90>;
|
||||
clocks = <&clkcfg CLK_MMUART0>;
|
||||
status = "okay";
|
||||
};
|
||||
clkcfg: clkcfg@20002000 {
|
||||
compatible = "microchip,mpfs-clkcfg";
|
||||
reg = <0x0 0x20002000 0x0 0x1000>;
|
||||
reg-names = "mss_sysreg";
|
||||
clocks = <&refclk>;
|
||||
#clock-cells = <1>;
|
||||
clock-output-names = "cpu", "axi", "ahb", "envm",
|
||||
"mac0", "mac1", "mmc", "timer",
|
||||
"mmuart0", "mmuart1", "mmuart2",
|
||||
"mmuart3", "mmuart4", "spi0", "spi1",
|
||||
"i2c0", "i2c1", "can0", "can1", "usb",
|
||||
"reserved", "rtc", "qspi", "gpio0",
|
||||
"gpio1", "gpio2", "ddrc", "fic0",
|
||||
"fic1", "fic2", "fic3", "athena",
|
||||
"cfm";
|
||||
};
|
||||
emmc: mmc@20008000 {
|
||||
compatible = "cdns,sd4hc";
|
||||
reg = <0x0 0x20008000 0x0 0x1000>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <88 89>;
|
||||
pinctrl-names = "default";
|
||||
clocks = <&clkcfg CLK_MMC>;
|
||||
bus-width = <4>;
|
||||
cap-mmc-highspeed;
|
||||
mmc-ddr-3_3v;
|
||||
max-frequency = <200000000>;
|
||||
non-removable;
|
||||
no-sd;
|
||||
no-sdio;
|
||||
voltage-ranges = <3300 3300>;
|
||||
status = "okay";
|
||||
};
|
||||
sdcard: sd@20008000 {
|
||||
compatible = "cdns,sd4hc";
|
||||
reg = <0x0 0x20008000 0x0 0x1000>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <88>;
|
||||
pinctrl-names = "default";
|
||||
clocks = <&clkcfg CLK_MMC>;
|
||||
bus-width = <4>;
|
||||
disable-wp;
|
||||
cap-sd-highspeed;
|
||||
card-detect-delay = <200>;
|
||||
sd-uhs-sdr12;
|
||||
sd-uhs-sdr25;
|
||||
sd-uhs-sdr50;
|
||||
sd-uhs-sdr104;
|
||||
max-frequency = <200000000>;
|
||||
status = "disabled";
|
||||
};
|
||||
uart1: serial@20100000 {
|
||||
compatible = "ns16550a";
|
||||
reg = <0x0 0x20100000 0x0 0x400>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <91>;
|
||||
clocks = <&clkcfg CLK_MMUART1>;
|
||||
status = "okay";
|
||||
};
|
||||
uart2: serial@20102000 {
|
||||
compatible = "ns16550a";
|
||||
reg = <0x0 0x20102000 0x0 0x400>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <92>;
|
||||
clocks = <&clkcfg CLK_MMUART2>;
|
||||
status = "okay";
|
||||
};
|
||||
uart3: serial@20104000 {
|
||||
compatible = "ns16550a";
|
||||
reg = <0x0 0x20104000 0x0 0x400>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <93>;
|
||||
clocks = <&clkcfg CLK_MMUART3>;
|
||||
status = "okay";
|
||||
};
|
||||
i2c0: i2c@2010a000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "microchip,mpfs-mss-i2c";
|
||||
reg = <0x0 0x2010a000 0x0 0x1000>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <58>;
|
||||
clocks = <&clkcfg CLK_I2C0>;
|
||||
status = "disabled";
|
||||
};
|
||||
i2c1: i2c@2010b000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "microchip,mpfs-mss-i2c";
|
||||
reg = <0x0 0x2010b000 0x0 0x1000>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <61>;
|
||||
clocks = <&clkcfg CLK_I2C1>;
|
||||
status = "disabled";
|
||||
pac193x@10 {
|
||||
compatible = "microchip,pac1934";
|
||||
reg = <0x10>;
|
||||
samp-rate = <64>;
|
||||
status = "disabled";
|
||||
ch1: channel0 {
|
||||
uohms-shunt-res = <10000>;
|
||||
rail-name = "VDD";
|
||||
channel_enabled;
|
||||
};
|
||||
ch2: channel1 {
|
||||
uohms-shunt-res = <10000>;
|
||||
rail-name = "VDDA25";
|
||||
channel_enabled;
|
||||
};
|
||||
ch3: channel2 {
|
||||
uohms-shunt-res = <10000>;
|
||||
rail-name = "VDD25";
|
||||
channel_enabled;
|
||||
};
|
||||
ch4: channel3 {
|
||||
uohms-shunt-res = <10000>;
|
||||
rail-name = "VDDA";
|
||||
channel_enabled;
|
||||
};
|
||||
};
|
||||
};
|
||||
emac0: ethernet@20110000 {
|
||||
compatible = "microchip,mpfs-mss-gem";
|
||||
reg = <0x0 0x20110000 0x0 0x2000>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <64 65 66 67>;
|
||||
local-mac-address = [56 34 00 FC 00 02];
|
||||
phy-mode = "sgmii";
|
||||
clocks = <&clkcfg CLK_MAC0>, <&clkcfg CLK_AXI>;
|
||||
clock-names = "pclk", "hclk";
|
||||
status = "disabled";
|
||||
#size-cells = <2>;
|
||||
#address-cells = <2>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
phy-handle = <&phy0>;
|
||||
phy0: ethernet-phy@8 {
|
||||
reg = <8>;
|
||||
ti,fifo-depth = <0x01>;
|
||||
};
|
||||
fabricbuf0: fabricbuf@0 {
|
||||
compatible = "shared-dma-pool";
|
||||
reg = <0x0 0xae000000 0x0 0x2000000>;
|
||||
label = "fabricbuf0-ddr-c";
|
||||
};
|
||||
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>;
|
||||
};
|
||||
fabricbuf1: fabricbuf@1 {
|
||||
compatible = "shared-dma-pool";
|
||||
reg = <0x0 0xc0000000 0x0 0x8000000>;
|
||||
label = "fabricbuf1-ddr-nc";
|
||||
};
|
||||
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";
|
||||
|
||||
fabricbuf2: fabricbuf@2 {
|
||||
compatible = "shared-dma-pool";
|
||||
reg = <0x0 0xd8000000 0x0 0x8000000>;
|
||||
label = "fabricbuf2-ddr-nc-wcb";
|
||||
};
|
||||
};
|
||||
|
||||
udmabuf0 {
|
||||
compatible = "ikwzm,u-dma-buf";
|
||||
device-name = "udmabuf-ddr-c0";
|
||||
minor-number = <0>;
|
||||
size = <0x0 0x2000000>;
|
||||
memory-region = <&fabricbuf0>;
|
||||
sync-mode = <3>;
|
||||
};
|
||||
|
||||
udmabuf1 {
|
||||
compatible = "ikwzm,u-dma-buf";
|
||||
device-name = "udmabuf-ddr-nc0";
|
||||
minor-number = <1>;
|
||||
size = <0x0 0x8000000>;
|
||||
memory-region = <&fabricbuf1>;
|
||||
sync-mode = <3>;
|
||||
};
|
||||
|
||||
udmabuf2 {
|
||||
compatible = "ikwzm,u-dma-buf";
|
||||
device-name = "udmabuf-ddr-nc-wcb0";
|
||||
minor-number = <2>;
|
||||
size = <0x0 0x8000000>;
|
||||
memory-region = <&fabricbuf2>;
|
||||
sync-mode = <3>;
|
||||
};
|
||||
|
||||
ddrc_cache_lo: memory@80000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x80000000 0x0 0x2e000000>;
|
||||
clocks = <&clkcfg CLK_DDRC>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ddrc_cache_hi: memory@1000000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x10 0x0 0x0 0x40000000>;
|
||||
clocks = <&clkcfg CLK_DDRC>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&uart1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mmc {
|
||||
status = "okay";
|
||||
|
||||
bus-width = <4>;
|
||||
disable-wp;
|
||||
cap-mmc-highspeed;
|
||||
cap-sd-highspeed;
|
||||
card-detect-delay = <200>;
|
||||
mmc-ddr-1_8v;
|
||||
mmc-hs200-1_8v;
|
||||
sd-uhs-sdr12;
|
||||
sd-uhs-sdr25;
|
||||
sd-uhs-sdr50;
|
||||
sd-uhs-sdr104;
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
status = "okay";
|
||||
clock-frequency = <100000>;
|
||||
|
||||
pac193x: pac193x@10 {
|
||||
compatible = "microchip,pac1934";
|
||||
reg = <0x10>;
|
||||
samp-rate = <64>;
|
||||
status = "okay";
|
||||
ch1: channel0 {
|
||||
uohms-shunt-res = <10000>;
|
||||
rail-name = "VDDREG";
|
||||
channel_enabled;
|
||||
};
|
||||
ch2: channel1 {
|
||||
uohms-shunt-res = <10000>;
|
||||
rail-name = "VDDA25";
|
||||
channel_enabled;
|
||||
};
|
||||
ch3: channel2 {
|
||||
uohms-shunt-res = <10000>;
|
||||
rail-name = "VDD25";
|
||||
channel_enabled;
|
||||
};
|
||||
ch4: channel3 {
|
||||
uohms-shunt-res = <10000>;
|
||||
rail-name = "VDDA_REG";
|
||||
channel_enabled;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&mac1 {
|
||||
status = "okay";
|
||||
phy-mode = "sgmii";
|
||||
phy-handle = <&phy1>;
|
||||
phy1: ethernet-phy@9 {
|
||||
reg = <9>;
|
||||
ti,fifo-depth = <0x1>;
|
||||
};
|
||||
};
|
||||
|
571
arch/riscv/dts/microchip-mpfs.dtsi
Normal file
571
arch/riscv/dts/microchip-mpfs.dtsi
Normal file
@ -0,0 +1,571 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/* Copyright (c) 2020-2021 Microchip Technology Inc */
|
||||
|
||||
#include "dt-bindings/clock/microchip-mpfs-clock.h"
|
||||
#include "dt-bindings/interrupt-controller/microchip-mpfs-plic.h"
|
||||
#include "dt-bindings/interrupt-controller/riscv-hart.h"
|
||||
|
||||
/ {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
model = "Microchip PolarFire SoC";
|
||||
compatible = "microchip,mpfs";
|
||||
|
||||
chosen {
|
||||
};
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu0: cpu@0 {
|
||||
compatible = "sifive,e51", "sifive,rocket0", "riscv";
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-sets = <128>;
|
||||
i-cache-size = <16384>;
|
||||
reg = <0>;
|
||||
riscv,isa = "rv64imac";
|
||||
clocks = <&clkcfg CLK_CPU>;
|
||||
status = "disabled";
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
600000 1100000
|
||||
300000 950000
|
||||
150000 750000
|
||||
>;
|
||||
cpu0_intc: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
|
||||
cpu1: cpu@1 {
|
||||
compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
|
||||
d-cache-block-size = <64>;
|
||||
d-cache-sets = <64>;
|
||||
d-cache-size = <32768>;
|
||||
d-tlb-sets = <1>;
|
||||
d-tlb-size = <32>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-sets = <64>;
|
||||
i-cache-size = <32768>;
|
||||
i-tlb-sets = <1>;
|
||||
i-tlb-size = <32>;
|
||||
mmu-type = "riscv,sv39";
|
||||
reg = <1>;
|
||||
riscv,isa = "rv64imafdc";
|
||||
clocks = <&clkcfg CLK_CPU>;
|
||||
tlb-split;
|
||||
status = "okay";
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
600000 1100000
|
||||
300000 950000
|
||||
150000 750000
|
||||
>;
|
||||
cpu1_intc: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
|
||||
cpu2: cpu@2 {
|
||||
compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
|
||||
d-cache-block-size = <64>;
|
||||
d-cache-sets = <64>;
|
||||
d-cache-size = <32768>;
|
||||
d-tlb-sets = <1>;
|
||||
d-tlb-size = <32>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-sets = <64>;
|
||||
i-cache-size = <32768>;
|
||||
i-tlb-sets = <1>;
|
||||
i-tlb-size = <32>;
|
||||
mmu-type = "riscv,sv39";
|
||||
reg = <2>;
|
||||
riscv,isa = "rv64imafdc";
|
||||
clocks = <&clkcfg CLK_CPU>;
|
||||
tlb-split;
|
||||
status = "okay";
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
600000 1100000
|
||||
300000 950000
|
||||
150000 750000
|
||||
>;
|
||||
cpu2_intc: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
|
||||
cpu3: cpu@3 {
|
||||
compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
|
||||
d-cache-block-size = <64>;
|
||||
d-cache-sets = <64>;
|
||||
d-cache-size = <32768>;
|
||||
d-tlb-sets = <1>;
|
||||
d-tlb-size = <32>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-sets = <64>;
|
||||
i-cache-size = <32768>;
|
||||
i-tlb-sets = <1>;
|
||||
i-tlb-size = <32>;
|
||||
mmu-type = "riscv,sv39";
|
||||
reg = <3>;
|
||||
riscv,isa = "rv64imafdc";
|
||||
clocks = <&clkcfg CLK_CPU>;
|
||||
tlb-split;
|
||||
status = "okay";
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
600000 1100000
|
||||
300000 950000
|
||||
150000 750000
|
||||
>;
|
||||
cpu3_intc: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
|
||||
cpu4: cpu@4 {
|
||||
compatible = "sifive,u54-mc", "sifive,rocket0", "riscv";
|
||||
d-cache-block-size = <64>;
|
||||
d-cache-sets = <64>;
|
||||
d-cache-size = <32768>;
|
||||
d-tlb-sets = <1>;
|
||||
d-tlb-size = <32>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-sets = <64>;
|
||||
i-cache-size = <32768>;
|
||||
i-tlb-sets = <1>;
|
||||
i-tlb-size = <32>;
|
||||
mmu-type = "riscv,sv39";
|
||||
reg = <4>;
|
||||
riscv,isa = "rv64imafdc";
|
||||
clocks = <&clkcfg CLK_CPU>;
|
||||
tlb-split;
|
||||
status = "okay";
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
600000 1100000
|
||||
300000 950000
|
||||
150000 750000
|
||||
>;
|
||||
cpu4_intc: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
compatible = "microchip,mpfs-soc", "simple-bus";
|
||||
ranges;
|
||||
|
||||
clint: clint@2000000 {
|
||||
compatible = "sifive,clint0";
|
||||
reg = <0x0 0x2000000 0x0 0xC000>;
|
||||
interrupts-extended =
|
||||
<&cpu0_intc HART_INT_M_SOFT &cpu0_intc HART_INT_M_TIMER
|
||||
&cpu1_intc HART_INT_M_SOFT &cpu1_intc HART_INT_M_TIMER
|
||||
&cpu2_intc HART_INT_M_SOFT &cpu2_intc HART_INT_M_TIMER
|
||||
&cpu3_intc HART_INT_M_SOFT &cpu3_intc HART_INT_M_TIMER
|
||||
&cpu4_intc HART_INT_M_SOFT &cpu4_intc HART_INT_M_TIMER>;
|
||||
};
|
||||
|
||||
cachecontroller: cache-controller@2010000 {
|
||||
compatible = "sifive,fu540-c000-ccache", "cache";
|
||||
reg = <0x0 0x2010000 0x0 0x1000>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_L2_METADATA_CORR
|
||||
PLIC_INT_L2_METADATA_UNCORR
|
||||
PLIC_INT_L2_DATA_CORR>;
|
||||
cache-block-size = <64>;
|
||||
cache-level = <2>;
|
||||
cache-sets = <1024>;
|
||||
cache-size = <2097152>;
|
||||
cache-unified;
|
||||
};
|
||||
|
||||
pdma: pdma@3000000 {
|
||||
compatible = "microchip,mpfs-pdma-uio","sifive,fu540-c000-pdma";
|
||||
reg = <0x0 0x3000000 0x0 0x8000>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_DMA_CH0_DONE PLIC_INT_DMA_CH0_ERR
|
||||
PLIC_INT_DMA_CH1_DONE PLIC_INT_DMA_CH1_ERR
|
||||
PLIC_INT_DMA_CH2_DONE PLIC_INT_DMA_CH2_ERR
|
||||
PLIC_INT_DMA_CH3_DONE PLIC_INT_DMA_CH3_ERR>;
|
||||
#dma-cells = <1>;
|
||||
};
|
||||
|
||||
plic: interrupt-controller@c000000 {
|
||||
compatible = "sifive,plic-1.0.0";
|
||||
reg = <0x0 0xc000000 0x0 0x4000000>;
|
||||
#interrupt-cells = <1>;
|
||||
riscv,ndev = <186>;
|
||||
interrupt-controller;
|
||||
interrupts-extended = <&cpu0_intc HART_INT_M_EXT
|
||||
&cpu1_intc HART_INT_M_EXT &cpu1_intc HART_INT_S_EXT
|
||||
&cpu2_intc HART_INT_M_EXT &cpu2_intc HART_INT_S_EXT
|
||||
&cpu3_intc HART_INT_M_EXT &cpu3_intc HART_INT_S_EXT
|
||||
&cpu4_intc HART_INT_M_EXT &cpu4_intc HART_INT_S_EXT>;
|
||||
};
|
||||
|
||||
refclk: refclk {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <600000000>;
|
||||
clock-output-names = "msspllclk";
|
||||
};
|
||||
|
||||
clkcfg: clkcfg@20002000 {
|
||||
compatible = "microchip,mpfs-clkcfg";
|
||||
reg = <0x0 0x20002000 0x0 0x1000>;
|
||||
reg-names = "mss_sysreg";
|
||||
clocks = <&refclk>;
|
||||
#clock-cells = <1>;
|
||||
clock-output-names = "cpu", "axi", "ahb", "envm", /* 0-3 */
|
||||
"mac0", "mac1", "mmc", "timer", /* 4-7 */
|
||||
"mmuart0", "mmuart1", "mmuart2", "mmuart3", /* 8-11 */
|
||||
"mmuart4", "spi0", "spi1", "i2c0", /* 12-15 */
|
||||
"i2c1", "can0", "can1", "usb", /* 16-19 */
|
||||
"rsvd", "rtc", "qspi", "gpio0", /* 20-23 */
|
||||
"gpio1", "gpio2", "ddrc", "fic0", /* 24-27 */
|
||||
"fic1", "fic2", "fic3", "athena", "cfm"; /* 28-32 */
|
||||
};
|
||||
|
||||
/* Common node entry for eMMC/SD */
|
||||
mmc: mmc@20008000 {
|
||||
compatible = "microchip,mpfs-sd4hc","cdns,sd4hc";
|
||||
reg = <0x0 0x20008000 0x0 0x1000>;
|
||||
clocks = <&clkcfg CLK_MMC>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_MMC_MAIN PLIC_INT_MMC_WAKEUP>;
|
||||
max-frequency = <200000000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart0: serial@20000000 {
|
||||
compatible = "ns16550a";
|
||||
reg = <0x0 0x20000000 0x0 0x400>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_MMUART0>;
|
||||
clocks = <&clkcfg CLK_MMUART0>;
|
||||
status = "disabled"; /* Reserved for the HSS */
|
||||
};
|
||||
|
||||
uart1: serial@20100000 {
|
||||
compatible = "ns16550a";
|
||||
reg = <0x0 0x20100000 0x0 0x400>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_MMUART1>;
|
||||
clocks = <&clkcfg CLK_MMUART1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart2: serial@20102000 {
|
||||
compatible = "ns16550a";
|
||||
reg = <0x0 0x20102000 0x0 0x400>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_MMUART2>;
|
||||
clocks = <&clkcfg CLK_MMUART2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart3: serial@20104000 {
|
||||
compatible = "ns16550a";
|
||||
reg = <0x0 0x20104000 0x0 0x400>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_MMUART3>;
|
||||
clocks = <&clkcfg CLK_MMUART3>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart4: serial@20106000 {
|
||||
compatible = "ns16550a";
|
||||
reg = <0x0 0x20106000 0x0 0x400>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_MMUART4>;
|
||||
clocks = <&clkcfg CLK_MMUART4>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spi0: spi@20108000 {
|
||||
compatible = "microchip,mpfs-spi";
|
||||
reg = <0x0 0x20108000 0x0 0x1000>;
|
||||
clocks = <&clkcfg CLK_SPI0>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_SPI0>;
|
||||
num-cs = <8>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spi1: spi@20109000 {
|
||||
compatible = "microchip,mpfs-spi";
|
||||
reg = <0x0 0x20109000 0x0 0x1000>;
|
||||
clocks = <&clkcfg CLK_SPI1>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_SPI1>;
|
||||
num-cs = <8>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c0: i2c@2010a000 {
|
||||
compatible = "microchip,mpfs-i2c";
|
||||
reg = <0x0 0x2010a000 0x0 0x1000>;
|
||||
clocks = <&clkcfg CLK_I2C0>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_I2C0_MAIN>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c1: i2c@2010b000 {
|
||||
compatible = "microchip,mpfs-i2c";
|
||||
reg = <0x0 0x2010b000 0x0 0x1000>;
|
||||
clocks = <&clkcfg CLK_I2C1>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_I2C1_MAIN>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
can0: can@2010c000 {
|
||||
compatible = "microchip,mpfs-can-uio";
|
||||
reg = <0x0 0x2010c000 0x0 0x1000>;
|
||||
clocks = <&clkcfg CLK_CAN0>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_CAN0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
can1: can@2010d000 {
|
||||
compatible = "microchip,mpfs-can-uio";
|
||||
reg = <0x0 0x2010d000 0x0 0x1000>;
|
||||
clocks = <&clkcfg CLK_CAN1>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_CAN1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mac0: ethernet@20110000 {
|
||||
compatible = "cdns,macb";
|
||||
reg = <0x0 0x20110000 0x0 0x2000>;
|
||||
clocks = <&clkcfg CLK_MAC0>, <&clkcfg CLK_AHB>;
|
||||
clock-names = "pclk", "hclk";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_MAC0_INT
|
||||
PLIC_INT_MAC0_QUEUE1
|
||||
PLIC_INT_MAC0_QUEUE2
|
||||
PLIC_INT_MAC0_QUEUE3
|
||||
PLIC_INT_MAC0_EMAC
|
||||
PLIC_INT_MAC0_MMSL>;
|
||||
local-mac-address = [00 00 00 00 00 00];
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
mac1: ethernet@20112000 {
|
||||
compatible = "cdns,macb";
|
||||
reg = <0x0 0x20112000 0x0 0x2000>;
|
||||
clocks = <&clkcfg CLK_MAC1>, <&clkcfg CLK_AHB>;
|
||||
clock-names = "pclk", "hclk";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_MAC1_INT
|
||||
PLIC_INT_MAC1_QUEUE1
|
||||
PLIC_INT_MAC1_QUEUE2
|
||||
PLIC_INT_MAC1_QUEUE3
|
||||
PLIC_INT_MAC1_EMAC
|
||||
PLIC_INT_MAC1_MMSL>;
|
||||
local-mac-address = [00 00 00 00 00 00];
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
gpio0: gpio@20120000 {
|
||||
compatible = "microchip,mpfs-gpio";
|
||||
reg = <0x0 0x20120000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
clocks = <&clkcfg CLK_GPIO0>;
|
||||
interrupt-parent = <&plic>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gpio1: gpio@20121000 {
|
||||
compatible = "microchip,mpfs-gpio";
|
||||
reg = <000 0x20121000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
clocks = <&clkcfg CLK_GPIO1>;
|
||||
interrupt-parent = <&plic>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gpio2: gpio@20122000 {
|
||||
compatible = "microchip,mpfs-gpio";
|
||||
reg = <0x0 0x20122000 0x0 0x1000>;
|
||||
reg-names = "control";
|
||||
clocks = <&clkcfg CLK_GPIO2>;
|
||||
interrupt-parent = <&plic>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
rtc: rtc@20124000 {
|
||||
compatible = "microchip,mpfs-rtc";
|
||||
reg = <0x0 0x20124000 0x0 0x1000>;
|
||||
clocks = <&clkcfg CLK_RTC>;
|
||||
clock-names = "rtc";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_RTC_WAKEUP PLIC_INT_RTC_MATCH>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb: usb@20201000 {
|
||||
compatible = "microchip,mpfs-usb-host";
|
||||
reg = <0x0 0x20201000 0x0 0x1000>;
|
||||
reg-names = "mc","control";
|
||||
clocks = <&clkcfg CLK_USB>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_USB_DMA PLIC_INT_USB_MC>;
|
||||
interrupt-names = "dma","mc";
|
||||
dr_mode = "host";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
qspi: qspi@21000000 {
|
||||
compatible = "microchip,mpfs-qspi";
|
||||
reg = <0x0 0x21000000 0x0 0x1000>;
|
||||
clocks = <&clkcfg CLK_QSPI>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_QSPI>;
|
||||
num-cs = <8>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mbox: mailbox@37020000 {
|
||||
compatible = "microchip,mpfs-mailbox";
|
||||
reg = <0x0 0x37020000 0x0 0x1000>, <0x0 0x2000318C 0x0 0x40>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_G5C_MESSAGE>;
|
||||
#mbox-cells = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pcie: pcie@2000000000 {
|
||||
compatible = "microchip,pcie-host-1.0";
|
||||
#address-cells = <0x3>;
|
||||
#interrupt-cells = <0x1>;
|
||||
#size-cells = <0x2>;
|
||||
device_type = "pci";
|
||||
reg = <0x20 0x0 0x0 0x8000000 0x0 0x43000000 0x0 0x10000>;
|
||||
reg-names = "cfg", "apb";
|
||||
clocks = <&clkcfg CLK_FIC0>, <&clkcfg CLK_FIC1>, <&clkcfg CLK_FIC3>;
|
||||
clock-names = "fic0", "fic1", "fic3";
|
||||
bus-range = <0x0 0x7f>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <PLIC_INT_FABRIC_F2H_2>;
|
||||
interrupt-map = <0 0 0 1 &pcie_intc 0>,
|
||||
<0 0 0 2 &pcie_intc 1>,
|
||||
<0 0 0 3 &pcie_intc 2>,
|
||||
<0 0 0 4 &pcie_intc 3>;
|
||||
interrupt-map-mask = <0 0 0 7>;
|
||||
ranges = <0x3000000 0x0 0x8000000 0x20 0x8000000 0x0 0x80000000>;
|
||||
msi-parent = <&pcie>;
|
||||
msi-controller;
|
||||
mchp,axi-m-atr0 = <0x10 0x0>;
|
||||
status = "disabled";
|
||||
pcie_intc: legacy-interrupt-controller {
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
|
||||
syscontroller: syscontroller {
|
||||
compatible = "microchip,mpfs-sys-controller";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
mboxes = <&mbox 0>;
|
||||
};
|
||||
|
||||
hwrandom: hwrandom {
|
||||
compatible = "microchip,mpfs-rng";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
syscontroller = <&syscontroller>;
|
||||
};
|
||||
|
||||
serialnum: serialnum {
|
||||
compatible = "microchip,mpfs-serial-number";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
syscontroller = <&syscontroller>;
|
||||
};
|
||||
|
||||
fpgadigest: fpgadigest {
|
||||
compatible = "microchip,mpfs-digest";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
syscontroller = <&syscontroller>;
|
||||
};
|
||||
|
||||
devicecert: cert {
|
||||
compatible = "microchip,mpfs-device-cert";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
syscontroller = <&syscontroller>;
|
||||
};
|
||||
|
||||
signature: signature {
|
||||
compatible = "microchip,mpfs-signature";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
syscontroller = <&syscontroller>;
|
||||
};
|
||||
};
|
||||
};
|
@ -499,6 +499,10 @@
|
||||
compatible = "sandbox,clk-ccf";
|
||||
};
|
||||
|
||||
efi-media {
|
||||
compatible = "sandbox,efi-media";
|
||||
};
|
||||
|
||||
eth@10002000 {
|
||||
compatible = "sandbox,eth";
|
||||
reg = <0x10002000 0x1000>;
|
||||
|
@ -43,6 +43,23 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
#define OMNIA_I2C_EEPROM_CHIP_LEN 2
|
||||
#define OMNIA_I2C_EEPROM_MAGIC 0x0341a034
|
||||
|
||||
#define SYS_RSTOUT_MASK MVEBU_REGISTER(0x18260)
|
||||
#define SYS_RSTOUT_MASK_WD BIT(10)
|
||||
|
||||
#define A385_WDT_GLOBAL_CTRL MVEBU_REGISTER(0x20300)
|
||||
#define A385_WDT_GLOBAL_RATIO_MASK GENMASK(18, 16)
|
||||
#define A385_WDT_GLOBAL_RATIO_SHIFT 16
|
||||
#define A385_WDT_GLOBAL_25MHZ BIT(10)
|
||||
#define A385_WDT_GLOBAL_ENABLE BIT(8)
|
||||
|
||||
#define A385_WDT_GLOBAL_STATUS MVEBU_REGISTER(0x20304)
|
||||
#define A385_WDT_GLOBAL_EXPIRED BIT(31)
|
||||
|
||||
#define A385_WDT_DURATION MVEBU_REGISTER(0x20334)
|
||||
|
||||
#define A385_WD_RSTOUT_UNMASK MVEBU_REGISTER(0x20704)
|
||||
#define A385_WD_RSTOUT_UNMASK_GLOBAL BIT(8)
|
||||
|
||||
enum mcu_commands {
|
||||
CMD_GET_STATUS_WORD = 0x01,
|
||||
CMD_GET_RESET = 0x09,
|
||||
@ -141,6 +158,47 @@ static int omnia_mcu_write(u8 cmd, const void *buf, int len)
|
||||
return dm_i2c_write(chip, cmd, buf, len);
|
||||
}
|
||||
|
||||
static void enable_a385_watchdog(unsigned int timeout_minutes)
|
||||
{
|
||||
struct sar_freq_modes sar_freq;
|
||||
u32 watchdog_freq;
|
||||
|
||||
printf("Enabling A385 watchdog with %u minutes timeout...\n",
|
||||
timeout_minutes);
|
||||
|
||||
/*
|
||||
* Use NBCLK clock (a.k.a. L2 clock) as watchdog input clock with
|
||||
* its maximal ratio 7 instead of default fixed 25 MHz clock.
|
||||
* It allows to set watchdog duration up to the 22 minutes.
|
||||
*/
|
||||
clrsetbits_32(A385_WDT_GLOBAL_CTRL,
|
||||
A385_WDT_GLOBAL_25MHZ | A385_WDT_GLOBAL_RATIO_MASK,
|
||||
7 << A385_WDT_GLOBAL_RATIO_SHIFT);
|
||||
|
||||
/*
|
||||
* Calculate watchdog clock frequency. It is defined by formula:
|
||||
* freq = NBCLK / 2 / (2 ^ ratio)
|
||||
* We set ratio to the maximal possible value 7.
|
||||
*/
|
||||
get_sar_freq(&sar_freq);
|
||||
watchdog_freq = sar_freq.nb_clk * 1000000 / 2 / (1 << 7);
|
||||
|
||||
/* Set watchdog duration */
|
||||
writel(timeout_minutes * 60 * watchdog_freq, A385_WDT_DURATION);
|
||||
|
||||
/* Clear the watchdog expiration bit */
|
||||
clrbits_32(A385_WDT_GLOBAL_STATUS, A385_WDT_GLOBAL_EXPIRED);
|
||||
|
||||
/* Enable watchdog timer */
|
||||
setbits_32(A385_WDT_GLOBAL_CTRL, A385_WDT_GLOBAL_ENABLE);
|
||||
|
||||
/* Enable reset on watchdog */
|
||||
setbits_32(A385_WD_RSTOUT_UNMASK, A385_WD_RSTOUT_UNMASK_GLOBAL);
|
||||
|
||||
/* Unmask reset for watchdog */
|
||||
clrbits_32(SYS_RSTOUT_MASK, SYS_RSTOUT_MASK_WD);
|
||||
}
|
||||
|
||||
static bool disable_mcu_watchdog(void)
|
||||
{
|
||||
int ret;
|
||||
@ -423,10 +481,13 @@ void spl_board_init(void)
|
||||
{
|
||||
/*
|
||||
* If booting from UART, disable MCU watchdog in SPL, since uploading
|
||||
* U-Boot proper can take too much time and trigger it.
|
||||
* U-Boot proper can take too much time and trigger it. Instead enable
|
||||
* A385 watchdog with very high timeout (10 minutes) to prevent hangup.
|
||||
*/
|
||||
if (get_boot_device() == BOOT_DEVICE_UART)
|
||||
if (get_boot_device() == BOOT_DEVICE_UART) {
|
||||
enable_a385_watchdog(10);
|
||||
disable_mcu_watchdog();
|
||||
}
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
|
@ -4,3 +4,13 @@ S: Maintained
|
||||
F: board/beacon/beacon-rzg2m/
|
||||
F: include/configs/beacon-rzg2m.h
|
||||
F: configs/rzg2_beacon_defconfig
|
||||
F: arch/arm/dts/beacon-renesom-baseboard.dtsi
|
||||
F: arch/arm/dts/beacon-renesom-som.dtsi
|
||||
F: arch/arm/dts/r8a774a1-beacon-rzg2m-kit.dts
|
||||
F: arch/arm/dts/r8a774b1-beacon-rzg2n-kit.dts
|
||||
F: arch/arm/dts/r8a774e1-beacon-rzg2h-kit.dts
|
||||
F: arch/arm/dts/r8a774a1-beacon-rzg2m-kit-u-boot.dtsi
|
||||
F: arch/arm/dts/r8a774b1-beacon-rzg2n-kit-u-boot.dtsi
|
||||
F: arch/arm/dts/r8a774e1-beacon-rzg2h-kit-u-boot.dtsi
|
||||
F: arch/arm/dts/rz-g2-beacon-u-boot.dtsi
|
||||
|
||||
|
@ -45,5 +45,10 @@ config BOARD_SPECIFIC_OPTIONS # dummy
|
||||
imply MMC_WRITE
|
||||
imply MMC_SDHCI
|
||||
imply MMC_SDHCI_CADENCE
|
||||
imply MMC_SDHCI_ADMA
|
||||
imply MMC_HS200_SUPPORT
|
||||
imply CMD_I2C
|
||||
imply DM_I2C
|
||||
imply SYS_I2C_MICROCHIP
|
||||
|
||||
endif
|
||||
|
@ -119,7 +119,22 @@ int board_late_init(void)
|
||||
if (icicle_mac_addr[idx] == ':')
|
||||
icicle_mac_addr[idx] = ' ';
|
||||
}
|
||||
env_set("icicle_mac_addr", icicle_mac_addr);
|
||||
env_set("icicle_mac_addr0", icicle_mac_addr);
|
||||
|
||||
mac_addr[5] = device_serial_number[0] + 1;
|
||||
|
||||
icicle_mac_addr[0] = '[';
|
||||
|
||||
sprintf(&icicle_mac_addr[1], "%pM", mac_addr);
|
||||
|
||||
icicle_mac_addr[18] = ']';
|
||||
icicle_mac_addr[19] = '\0';
|
||||
|
||||
for (idx = 0; idx < 20; idx++) {
|
||||
if (icicle_mac_addr[idx] == ':')
|
||||
icicle_mac_addr[idx] = ' ';
|
||||
}
|
||||
env_set("icicle_mac_addr1", icicle_mac_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ struct msg_get_clock_rate {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
|
||||
* https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#raspberry-pi-revision-codes
|
||||
*/
|
||||
struct rpi_model {
|
||||
const char *name;
|
||||
@ -157,6 +157,11 @@ static const struct rpi_model rpi_models_new_scheme[] = {
|
||||
DTB_DIR "bcm2711-rpi-4-b.dtb",
|
||||
true,
|
||||
},
|
||||
[0x12] = {
|
||||
"Zero 2 W",
|
||||
DTB_DIR "bcm2837-rpi-zero-2.dtb",
|
||||
false,
|
||||
},
|
||||
[0x13] = {
|
||||
"400",
|
||||
DTB_DIR "bcm2711-rpi-400.dtb",
|
||||
|
@ -26,6 +26,7 @@ config SPL_OPENSBI_LOAD_ADDR
|
||||
config BOARD_SPECIFIC_OPTIONS # dummy
|
||||
def_bool y
|
||||
select SIFIVE_FU740
|
||||
select ENV_IS_IN_SPI_FLASH
|
||||
select SUPPORT_SPL
|
||||
select RESET_SIFIVE
|
||||
select BINMAN
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define GEM_PHY_RESET SIFIVE_GENERIC_GPIO_NR(0, 12)
|
||||
|
||||
#define MODE_SELECT_REG 0x1000
|
||||
#define MODE_SELECT_SPI 0x6
|
||||
#define MODE_SELECT_SD 0xb
|
||||
#define MODE_SELECT_MASK GENMASK(3, 0)
|
||||
|
||||
@ -123,6 +124,8 @@ u32 spl_boot_device(void)
|
||||
u32 boot_device = mode_select & MODE_SELECT_MASK;
|
||||
|
||||
switch (boot_device) {
|
||||
case MODE_SELECT_SPI:
|
||||
return BOOT_DEVICE_SPI;
|
||||
case MODE_SELECT_SD:
|
||||
return BOOT_DEVICE_MMC1;
|
||||
default:
|
||||
|
@ -698,13 +698,7 @@ int g_dnl_board_usb_cable_connected(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sun4i_usb_phy_vbus_detect(&phy);
|
||||
if (ret == 1) {
|
||||
pr_err("A charger is plugged into the OTG\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return sun4i_usb_phy_vbus_detect(&phy);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
|
||||
/**
|
||||
* image_get_ramdisk - get and verify ramdisk image
|
||||
* @rd_addr: ramdisk image start address
|
||||
@ -85,6 +86,7 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, u8 arch,
|
||||
|
||||
return rd_hdr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Shared dual-format routines */
|
||||
@ -325,18 +327,16 @@ int genimg_has_config(bootm_headers_t *images)
|
||||
static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch,
|
||||
ulong *rd_datap, ulong *rd_lenp)
|
||||
{
|
||||
ulong rd_addr = 0;
|
||||
ulong rd_addr;
|
||||
char *buf;
|
||||
const char *fit_uname_config = images->fit_uname_cfg;
|
||||
const char *fit_uname_ramdisk = NULL;
|
||||
bool processed;
|
||||
int rd_noffset;
|
||||
|
||||
if (select) {
|
||||
ulong default_addr;
|
||||
bool done = true;
|
||||
#if CONFIG_IS_ENABLED(FIT)
|
||||
const char *fit_uname_config = images->fit_uname_cfg;
|
||||
const char *fit_uname_ramdisk = NULL;
|
||||
int rd_noffset;
|
||||
|
||||
if (CONFIG_IS_ENABLED(FIT)) {
|
||||
if (select) {
|
||||
ulong default_addr;
|
||||
/*
|
||||
* If the init ramdisk comes from the FIT image and
|
||||
* the FIT image address is omitted in the command
|
||||
@ -348,8 +348,8 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch,
|
||||
else
|
||||
default_addr = image_load_addr;
|
||||
|
||||
if (fit_parse_conf(select, default_addr, &rd_addr,
|
||||
&fit_uname_config)) {
|
||||
if (fit_parse_conf(select, default_addr,
|
||||
&rd_addr, &fit_uname_config)) {
|
||||
debug("* ramdisk: config '%s' from image at 0x%08lx\n",
|
||||
fit_uname_config, rd_addr);
|
||||
} else if (fit_parse_subimage(select, default_addr,
|
||||
@ -357,58 +357,60 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch,
|
||||
&fit_uname_ramdisk)) {
|
||||
debug("* ramdisk: subimage '%s' from image at 0x%08lx\n",
|
||||
fit_uname_ramdisk, rd_addr);
|
||||
} else {
|
||||
done = false;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
rd_addr = hextoul(select, NULL);
|
||||
debug("* ramdisk: cmdline image address = 0x%08lx\n",
|
||||
rd_addr);
|
||||
}
|
||||
#if CONFIG_IS_ENABLED(FIT)
|
||||
} else {
|
||||
/* use FIT configuration provided in first bootm
|
||||
* command argument. If the property is not defined,
|
||||
* quit silently (with -ENOPKG)
|
||||
*/
|
||||
rd_addr = map_to_sysmem(images->fit_hdr_os);
|
||||
rd_noffset = fit_get_node_from_config(images,
|
||||
FIT_RAMDISK_PROP,
|
||||
rd_addr);
|
||||
if (rd_noffset == -ENOENT)
|
||||
return -ENOPKG;
|
||||
else if (rd_noffset < 0)
|
||||
return rd_noffset;
|
||||
}
|
||||
if (!done) {
|
||||
rd_addr = hextoul(select, NULL);
|
||||
debug("* ramdisk: cmdline image address = 0x%08lx\n",
|
||||
rd_addr);
|
||||
}
|
||||
} else if (CONFIG_IS_ENABLED(FIT)) {
|
||||
/* use FIT configuration provided in first bootm
|
||||
* command argument. If the property is not defined,
|
||||
* quit silently (with -ENOPKG )
|
||||
*/
|
||||
rd_addr = map_to_sysmem(images->fit_hdr_os);
|
||||
rd_noffset = fit_get_node_from_config(images, FIT_RAMDISK_PROP,
|
||||
rd_addr);
|
||||
if (rd_noffset == -ENOENT)
|
||||
return -ENOPKG;
|
||||
else if (rd_noffset < 0)
|
||||
return rd_noffset;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check if there is an initrd image at the
|
||||
* address provided in the second bootm argument
|
||||
* check image type, for FIT images get FIT node.
|
||||
*/
|
||||
buf = map_sysmem(rd_addr, 0);
|
||||
processed = false;
|
||||
switch (genimg_get_format(buf)) {
|
||||
case IMAGE_FORMAT_LEGACY:
|
||||
if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) {
|
||||
/*
|
||||
* Check if there is an initrd image at the
|
||||
* address provided in the second bootm argument
|
||||
* check image type, for FIT images get FIT node.
|
||||
*/
|
||||
buf = map_sysmem(rd_addr, 0);
|
||||
switch (genimg_get_format(buf)) {
|
||||
#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
|
||||
case IMAGE_FORMAT_LEGACY: {
|
||||
const image_header_t *rd_hdr;
|
||||
|
||||
printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n",
|
||||
rd_addr);
|
||||
|
||||
bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK);
|
||||
rd_hdr = image_get_ramdisk(rd_addr, arch, images->verify);
|
||||
rd_hdr = image_get_ramdisk(rd_addr, arch,
|
||||
images->verify);
|
||||
|
||||
if (!rd_hdr)
|
||||
return -ENOENT;
|
||||
|
||||
*rd_datap = image_get_data(rd_hdr);
|
||||
*rd_lenp = image_get_data_size(rd_hdr);
|
||||
processed = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IMAGE_FORMAT_FIT:
|
||||
if (CONFIG_IS_ENABLED(FIT)) {
|
||||
rd_noffset = fit_image_load(images, rd_addr,
|
||||
&fit_uname_ramdisk,
|
||||
#endif
|
||||
#if CONFIG_IS_ENABLED(FIT)
|
||||
case IMAGE_FORMAT_FIT:
|
||||
rd_noffset = fit_image_load(images,
|
||||
rd_addr, &fit_uname_ramdisk,
|
||||
&fit_uname_config, arch,
|
||||
IH_TYPE_RAMDISK,
|
||||
BOOTSTAGE_ID_FIT_RD_START,
|
||||
@ -420,36 +422,29 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch,
|
||||
images->fit_hdr_rd = map_sysmem(rd_addr, 0);
|
||||
images->fit_uname_rd = fit_uname_ramdisk;
|
||||
images->fit_noffset_rd = rd_noffset;
|
||||
processed = true;
|
||||
}
|
||||
break;
|
||||
case IMAGE_FORMAT_ANDROID:
|
||||
if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) {
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_ANDROID_BOOT_IMAGE
|
||||
case IMAGE_FORMAT_ANDROID:
|
||||
android_image_get_ramdisk((void *)images->os.start,
|
||||
rd_datap, rd_lenp);
|
||||
processed = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) {
|
||||
char *end = NULL;
|
||||
|
||||
if (!processed) {
|
||||
if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) {
|
||||
char *end = NULL;
|
||||
|
||||
if (select)
|
||||
end = strchr(select, ':');
|
||||
if (end) {
|
||||
*rd_lenp = hextoul(++end, NULL);
|
||||
*rd_datap = rd_addr;
|
||||
processed = true;
|
||||
if (select)
|
||||
end = strchr(select, ':');
|
||||
if (end) {
|
||||
*rd_lenp = hextoul(++end, NULL);
|
||||
*rd_datap = rd_addr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!processed) {
|
||||
puts("Wrong Ramdisk Image Format\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -151,7 +151,8 @@ static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
|
||||
data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0);
|
||||
|
||||
rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, data, &updates);
|
||||
rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, TPM2_ALG_SHA256,
|
||||
data, TPM2_DIGEST_LEN, &updates);
|
||||
if (!rc) {
|
||||
printf("PCR #%u content (%u known updates):\n", index, updates);
|
||||
print_byte_string(data, TPM2_DIGEST_LEN);
|
||||
|
@ -6,7 +6,6 @@ CONFIG_DEFAULT_DEVICE_TREE="microchip-mpfs-icicle-kit"
|
||||
CONFIG_TARGET_MICROCHIP_ICICLE=y
|
||||
CONFIG_ARCH_RV64I=y
|
||||
CONFIG_RISCV_SMODE=y
|
||||
CONFIG_SBI_V01=y
|
||||
CONFIG_DISTRO_DEFAULTS=y
|
||||
CONFIG_SYS_LOAD_ADDR=0x80200000
|
||||
CONFIG_FIT=y
|
||||
|
@ -26,6 +26,7 @@ CONFIG_CMD_DFU=y
|
||||
CONFIG_CMD_MTD=y
|
||||
CONFIG_CMD_PCI=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_CMD_TPM=y
|
||||
CONFIG_CMD_MTDPARTS=y
|
||||
CONFIG_OF_BOARD=y
|
||||
CONFIG_ENV_IS_IN_FLASH=y
|
||||
|
@ -28,6 +28,7 @@ CONFIG_CMD_DFU=y
|
||||
CONFIG_CMD_MTD=y
|
||||
CONFIG_CMD_PCI=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_CMD_TPM=y
|
||||
CONFIG_CMD_MTDPARTS=y
|
||||
CONFIG_OF_BOARD=y
|
||||
CONFIG_ENV_IS_IN_FLASH=y
|
||||
|
@ -41,7 +41,6 @@ CONFIG_MULTI_DTB_FIT_LZO=y
|
||||
CONFIG_MULTI_DTB_FIT_USER_DEFINED_AREA=y
|
||||
CONFIG_ENV_OVERWRITE=y
|
||||
CONFIG_ENV_IS_IN_MMC=y
|
||||
CONFIG_SYS_MMC_ENV_DEV=1
|
||||
CONFIG_SYS_MMC_ENV_PART=2
|
||||
CONFIG_VERSION_VARIABLE=y
|
||||
CONFIG_REGMAP=y
|
||||
|
@ -8,6 +8,7 @@ CONFIG_SPL_DM_SPI=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="hifive-unmatched-a00"
|
||||
CONFIG_SPL_MMC=y
|
||||
CONFIG_SPL=y
|
||||
CONFIG_SPL_SPI_FLASH_SUPPORT=y
|
||||
CONFIG_SPL_SPI=y
|
||||
CONFIG_AHCI=y
|
||||
CONFIG_TARGET_SIFIVE_UNMATCHED=y
|
||||
@ -23,17 +24,22 @@ CONFIG_DISPLAY_BOARDINFO=y
|
||||
CONFIG_DISPLAY_BOARDINFO_LATE=y
|
||||
CONFIG_ID_EEPROM=y
|
||||
CONFIG_SPL_SEPARATE_BSS=y
|
||||
CONFIG_SPL_DM_SPI_FLASH=y
|
||||
CONFIG_SPL_DM_RESET=y
|
||||
CONFIG_SPL_SPI_LOAD=y
|
||||
CONFIG_CMD_EEPROM=y
|
||||
CONFIG_CMD_MEMINFO=y
|
||||
CONFIG_CMD_PWM=y
|
||||
CONFIG_CMD_GPT_RENAME=y
|
||||
CONFIG_CMD_PCI=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_USE_ENV_SPI_BUS=y
|
||||
CONFIG_ENV_SPI_BUS=1
|
||||
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||
CONFIG_SCSI_AHCI=y
|
||||
CONFIG_AHCI_PCI=y
|
||||
CONFIG_SPL_CLK=y
|
||||
CONFIG_SPI_FLASH_ISSI=y
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR=0x54
|
||||
CONFIG_E1000=y
|
||||
CONFIG_NVME=y
|
||||
|
@ -296,8 +296,11 @@ static void print_part_header(const char *type, struct blk_desc *dev_desc)
|
||||
case IF_TYPE_VIRTIO:
|
||||
puts("VirtIO");
|
||||
break;
|
||||
case IF_TYPE_EFI_MEDIA:
|
||||
puts("EFI");
|
||||
break;
|
||||
default:
|
||||
puts ("UNKNOWN");
|
||||
puts("UNKNOWN");
|
||||
break;
|
||||
}
|
||||
printf (" device %d -- Partition Type: %s\n\n",
|
||||
@ -427,7 +430,8 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
|
||||
* Always should be done, otherwise hw partition 0 will return stale
|
||||
* data after displaying a non-zero hw partition.
|
||||
*/
|
||||
part_init(*dev_desc);
|
||||
if ((*dev_desc)->if_type == IF_TYPE_MMC)
|
||||
part_init(*dev_desc);
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
|
@ -65,7 +65,8 @@ can be enabled with the following command line parameters:
|
||||
|
||||
- To add a Serial ATA disk via an Intel ICH9 AHCI controller, pass e.g.::
|
||||
|
||||
-drive if=none,file=disk.img,id=mydisk -device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0
|
||||
-drive if=none,file=disk.img,format=raw,id=mydisk \
|
||||
-device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0
|
||||
|
||||
- To add an Intel E1000 network adapter, pass e.g.::
|
||||
|
||||
@ -75,10 +76,14 @@ can be enabled with the following command line parameters:
|
||||
|
||||
-device usb-ehci,id=ehci
|
||||
|
||||
- To add a NVMe disk, pass e.g.::
|
||||
- To add an NVMe disk, pass e.g.::
|
||||
|
||||
-drive if=none,file=disk.img,id=mydisk -device nvme,drive=mydisk,serial=foo
|
||||
|
||||
- To add a random number generator, pass e.g.::
|
||||
|
||||
-device virtio-rng-pci
|
||||
|
||||
These have been tested in QEMU 2.9.0 but should work in at least 2.5.0 as well.
|
||||
|
||||
Enabling TPMv2 support
|
||||
|
78
doc/board/highbank/highbank.rst
Normal file
78
doc/board/highbank/highbank.rst
Normal file
@ -0,0 +1,78 @@
|
||||
Calxeda Highbank/Midway board support
|
||||
=====================================
|
||||
|
||||
The Calxeda ECX-1000 ("Highbank") and ECX-2000 ("Midway") were ARM based
|
||||
servers, providing high-density cluster systems. A single motherboard could
|
||||
host between 12 and 48 nodes, each with their own quad-core ARMv7
|
||||
processor, private DRAM and peripherals, connected through a high-bandwith
|
||||
and low-latency "fabric" network. Multiple motherboards could be connected
|
||||
together, to extend this fabric.
|
||||
|
||||
For the purpose of U-Boot we just care about a single node, this can be
|
||||
used as a single system, just using the fabric to connect to some Ethernet
|
||||
network. Each node boots on its own, either from a local hard disk, or
|
||||
via the network.
|
||||
|
||||
The earlier ECX-1000 nodes ("Highbank") contain four ARM Cortex-A9 cores,
|
||||
a Cortex-M3 system controller, three 10GBit/s MACs and five SATA
|
||||
controllers. The DRAM is limited to 4GB.
|
||||
|
||||
The later ECX-2000 nodes ("Midway") use four Cortex-A15 cores, alongside
|
||||
two Cortex-A7 management cores, and support up to 32GB of DRAM, while
|
||||
keeping the other peripherals.
|
||||
|
||||
For the purpose of U-Boot those two SoCs are very similar, so we offer
|
||||
one build target. The subtle differences are handled at runtime.
|
||||
Calxeda as a company is long defunct, and the remaining systems are
|
||||
considered legacy at this point.
|
||||
|
||||
Bgilding U-Boot
|
||||
---------------
|
||||
There is only one defconfig to cover both systems::
|
||||
|
||||
$ make highbank_defconfig
|
||||
$ make
|
||||
|
||||
This will create ``u-boot.bin``, which could become part of the firmware update
|
||||
package, or could be chainloaded by the existing U-Boot, see below for more
|
||||
details.
|
||||
|
||||
Boot process
|
||||
------------
|
||||
Upon powering up a node (which would be controlled by some BMC style
|
||||
management controller on the motherboard), the system controller ("ECME")
|
||||
would start and do some system initialisation (fabric registration,
|
||||
DRAM init, clock setup). It would load the device tree binary, some secure
|
||||
monitor code (``a9boot``/``a15boot``) and a U-Boot binary from SPI flash
|
||||
into DRAM, then power up the actual application cores (ARM Cortex-A9/A15).
|
||||
They would start executing ``a9boot``/``a15boot``, registering the PSCI SMC
|
||||
handlers, then dropping into U-Boot, but in non-secure state (HYP mode on
|
||||
the A15s).
|
||||
|
||||
U-Boot would act as a mere loader, trying to find some ``boot.scr`` file on
|
||||
the local hard disks, or reverting to PXE boot.
|
||||
|
||||
Updating U-Boot
|
||||
---------------
|
||||
The U-Boot binary is loaded from SPI flash, which is controlled exclusively
|
||||
by the ECME. This can be reached via IPMI using the LANplus transport protocol.
|
||||
Updating the SPI flash content requires vendor specific additions to the
|
||||
IPMI protocol, support for which was never upstreamed to ipmitool or
|
||||
FreeIPMI. Some older repositories for `ipmitool`_, the `pyipmi`_ library and
|
||||
a Python `management script`_ to update the SPI flash can be found on Github.
|
||||
|
||||
A simpler and safer way to get an up-to-date U-Boot running, is chainloading
|
||||
it via the legacy U-Boot::
|
||||
|
||||
$ mkimage -A arm -O u-boot -T standalone -C none -a 0x8000 -e 0x8000 \
|
||||
-n U-Boot -d u-boot.bin u-boot-highbank.img
|
||||
|
||||
Then load this image file, either from hard disk, or via TFTP, from the
|
||||
existing U-Boot, and execute it with bootm::
|
||||
|
||||
=> tftpboot 0x8000 u-boot-highbank.img
|
||||
=> bootm
|
||||
|
||||
.. _`ipmitool`: https://github.com/Cynerva/ipmitool
|
||||
.. _`pyipmi`: https://pypi.org/project/pyipmi/
|
||||
.. _`management script`: https://github.com/Cynerva/cxmanage
|
9
doc/board/highbank/index.rst
Normal file
9
doc/board/highbank/index.rst
Normal file
@ -0,0 +1,9 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
Highbank
|
||||
========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
highbank
|
@ -16,6 +16,7 @@ Board-specific doc
|
||||
coreboot/index
|
||||
emulation/index
|
||||
google/index
|
||||
highbank/index
|
||||
intel/index
|
||||
kontron/index
|
||||
microchip/index
|
||||
|
@ -20,6 +20,7 @@ The support for following drivers are already enabled:
|
||||
2. Microchip Clock Driver.
|
||||
3. Cadence MACB ethernet driver for networking support.
|
||||
4. Cadence MMC Driver for eMMC/SD support.
|
||||
5. Microchip I2C Driver.
|
||||
|
||||
Booting from eMMC using HSS
|
||||
---------------------------
|
||||
@ -214,7 +215,8 @@ GPT partition.
|
||||
Booting
|
||||
~~~~~~~
|
||||
|
||||
You should see the U-Boot prompt on UART0.
|
||||
You should see the U-Boot prompt on UART1.
|
||||
(Note: UART0 is reserved for HSS)
|
||||
|
||||
Sample boot log from MPFS Icicle Kit
|
||||
''''''''''''''''''''''''''''''''''''
|
||||
@ -451,7 +453,8 @@ copied payload and Linux image.
|
||||
|
||||
sudo dd if=<payload_binary> of=/dev/sdX2 bs=512
|
||||
|
||||
You should see the U-Boot prompt on UART0.
|
||||
You should see the U-Boot prompt on UART1.
|
||||
(Note: UART0 is reserved for HSS)
|
||||
|
||||
GUID type
|
||||
~~~~~~~~~
|
||||
|
@ -534,3 +534,34 @@ Sample boot log from HiFive Unmatched board
|
||||
OpenEmbedded nodistro.0 unmatched ttySIF0
|
||||
|
||||
unmatched login:
|
||||
|
||||
|
||||
Booting from SPI
|
||||
----------------
|
||||
|
||||
Use Building steps from "Booting from uSD using U-Boot SPL" section.
|
||||
|
||||
Partition the SPI in Linux via mtdblock. The partition types here are
|
||||
"HiFive Unleashed FSBL", "HiFive Unleashed BBL", and "U-Boot environment"
|
||||
for partitions one through three respectively.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
sgdisk --clear -a 1 \
|
||||
--new=1:40:2087 --change-name=1:spl --typecode=1:5B193300-FC78-40CD-8002-E86C45580B47 \
|
||||
--new=2:2088:10279 --change-name=2:uboot --typecode=2:2E54B353-1271-4842-806F-E436D6AF6985 \
|
||||
--new=3:10280:10535 --change-name=3:env --typecode=3:3DE21764-95BD-54BD-A5C3-4ABE786F38A8 \
|
||||
/dev/mtdblock0
|
||||
|
||||
Write U-boot SPL and U-boot to their partitions.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
dd if=u-boot-spl.bin of=/dev/mtdblock0 bs=4096 seek=5 conv=sync
|
||||
dd if=u-boot.itb of=/dev/mtdblock0 bs=4096 seek=261 conv=sync
|
||||
|
||||
Power off the board.
|
||||
|
||||
Change DIP switches MSEL[3:0] to 0110.
|
||||
|
||||
Power up the board.
|
||||
|
@ -620,12 +620,12 @@ EFI_DRIVER_BINDING_PROTOCOL implementation for the UEFI drivers.
|
||||
|
||||
A linker created list is used to keep track of the UEFI drivers. To create an
|
||||
entry in the list the UEFI driver uses the U_BOOT_DRIVER macro specifying
|
||||
UCLASS_EFI as the ID of its uclass, e.g::
|
||||
UCLASS_EFI_LOADER as the ID of its uclass, e.g::
|
||||
|
||||
/* Identify as UEFI driver */
|
||||
U_BOOT_DRIVER(efi_block) = {
|
||||
.name = "EFI block driver",
|
||||
.id = UCLASS_EFI,
|
||||
.id = UCLASS_EFI_LOADER,
|
||||
.ops = &driver_ops,
|
||||
};
|
||||
|
||||
@ -651,8 +651,8 @@ UEFI block IO driver
|
||||
The UEFI block IO driver supports devices exposing the EFI_BLOCK_IO_PROTOCOL.
|
||||
|
||||
When connected it creates a new U-Boot block IO device with interface type
|
||||
IF_TYPE_EFI, adds child controllers mapping the partitions, and installs the
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on these. This can be used together with the
|
||||
IF_TYPE_EFI_LOADER, adds child controllers mapping the partitions, and installs
|
||||
the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on these. This can be used together with the
|
||||
software iPXE to boot from iSCSI network drives [4].
|
||||
|
||||
This driver is only available if U-Boot is configured with::
|
||||
|
@ -102,7 +102,7 @@ Manually Loading and Applying Overlays
|
||||
|
||||
::
|
||||
|
||||
=> fdtaddr $fdtaddr
|
||||
=> fdt addr $fdtaddr
|
||||
|
||||
4. Grow it enough so it can encompass all applied overlays
|
||||
|
||||
|
@ -61,6 +61,39 @@ config TPL_BLOCK_CACHE
|
||||
help
|
||||
This option enables the disk-block cache in TPL
|
||||
|
||||
config EFI_MEDIA
|
||||
bool "Support EFI media drivers"
|
||||
default y if EFI || SANDBOX
|
||||
help
|
||||
Enable this to support media devices on top of UEFI. This enables
|
||||
just the uclass so you also need a specific driver to make this do
|
||||
anything.
|
||||
|
||||
For sandbox there is a test driver.
|
||||
|
||||
if EFI_MEDIA
|
||||
|
||||
config EFI_MEDIA_SANDBOX
|
||||
bool "Sandbox EFI media driver"
|
||||
depends on SANDBOX
|
||||
default y
|
||||
help
|
||||
Enables a simple sandbox media driver, used for testing just the
|
||||
EFI_MEDIA uclass. It does not do anything useful, since sandbox does
|
||||
not actually support running on top of UEFI.
|
||||
|
||||
config EFI_MEDIA_BLK
|
||||
bool "EFI media block driver"
|
||||
depends on EFI_APP
|
||||
default y
|
||||
help
|
||||
Enables a block driver for providing access to UEFI devices. This
|
||||
allows use of block devices detected by the underlying UEFI
|
||||
implementation. With this it is possible to use filesystems on these
|
||||
devices, for example.
|
||||
|
||||
endif # EFI_MEDIA
|
||||
|
||||
config IDE
|
||||
bool "Support IDE controllers"
|
||||
select HAVE_BLOCK_DEVICE
|
||||
|
@ -14,3 +14,7 @@ obj-$(CONFIG_IDE) += ide.o
|
||||
endif
|
||||
obj-$(CONFIG_SANDBOX) += sandbox.o
|
||||
obj-$(CONFIG_$(SPL_TPL_)BLOCK_CACHE) += blkcache.o
|
||||
|
||||
obj-$(CONFIG_EFI_MEDIA) += efi-media-uclass.o
|
||||
obj-$(CONFIG_EFI_MEDIA_SANDBOX) += sb_efi_media.o
|
||||
obj-$(CONFIG_EFI_MEDIA_BLK) += efi_blk.o
|
||||
|
@ -28,7 +28,8 @@ static const char *if_typename_str[IF_TYPE_COUNT] = {
|
||||
[IF_TYPE_SATA] = "sata",
|
||||
[IF_TYPE_HOST] = "host",
|
||||
[IF_TYPE_NVME] = "nvme",
|
||||
[IF_TYPE_EFI] = "efi",
|
||||
[IF_TYPE_EFI_MEDIA] = "efi",
|
||||
[IF_TYPE_EFI_LOADER] = "efiloader",
|
||||
[IF_TYPE_VIRTIO] = "virtio",
|
||||
[IF_TYPE_PVBLOCK] = "pvblock",
|
||||
};
|
||||
@ -44,7 +45,8 @@ static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
|
||||
[IF_TYPE_SATA] = UCLASS_AHCI,
|
||||
[IF_TYPE_HOST] = UCLASS_ROOT,
|
||||
[IF_TYPE_NVME] = UCLASS_NVME,
|
||||
[IF_TYPE_EFI] = UCLASS_EFI,
|
||||
[IF_TYPE_EFI_MEDIA] = UCLASS_EFI_MEDIA,
|
||||
[IF_TYPE_EFI_LOADER] = UCLASS_EFI_LOADER,
|
||||
[IF_TYPE_VIRTIO] = UCLASS_VIRTIO,
|
||||
[IF_TYPE_PVBLOCK] = UCLASS_PVBLOCK,
|
||||
};
|
||||
@ -670,6 +672,19 @@ int blk_create_devicef(struct udevice *parent, const char *drv_name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blk_probe_or_unbind(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = device_probe(dev);
|
||||
if (ret) {
|
||||
log_debug("probing %s failed\n", dev->name);
|
||||
device_unbind(dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int blk_unbind_all(int if_type)
|
||||
{
|
||||
struct uclass *uc;
|
||||
|
15
drivers/block/efi-media-uclass.c
Normal file
15
drivers/block/efi-media-uclass.c
Normal file
@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Uclass for EFI media devices
|
||||
*
|
||||
* Copyright 2021 Google LLC
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
|
||||
UCLASS_DRIVER(efi_media) = {
|
||||
.id = UCLASS_EFI_MEDIA,
|
||||
.name = "efi_media",
|
||||
.flags = DM_UC_FLAG_SEQ_ALIAS,
|
||||
};
|
115
drivers/block/efi_blk.c
Normal file
115
drivers/block/efi_blk.c
Normal file
@ -0,0 +1,115 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Block driver for EFI devices
|
||||
* This supports a media driver of UCLASS_EFI with a child UCLASS_BLK
|
||||
* It allows block-level access to EFI devices made available via EFI boot
|
||||
* services
|
||||
*
|
||||
* Copyright 2021 Google LLC
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <blk.h>
|
||||
#include <dm.h>
|
||||
#include <efi.h>
|
||||
#include <efi_api.h>
|
||||
|
||||
struct efi_block_plat {
|
||||
struct efi_block_io *blkio;
|
||||
};
|
||||
|
||||
/**
|
||||
* Read from block device
|
||||
*
|
||||
* @dev: device
|
||||
* @blknr: first block to be read
|
||||
* @blkcnt: number of blocks to read
|
||||
* @buffer: output buffer
|
||||
* Return: number of blocks transferred
|
||||
*/
|
||||
static ulong efi_bl_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
|
||||
void *buffer)
|
||||
{
|
||||
struct efi_block_plat *plat = dev_get_plat(dev);
|
||||
struct efi_block_io *io = plat->blkio;
|
||||
efi_status_t ret;
|
||||
|
||||
log_debug("read buf=%p, block=%lx, count=%lx: ", buffer, (ulong)blknr,
|
||||
(ulong)blkcnt);
|
||||
ret = io->read_blocks(io, io->media->media_id, blknr,
|
||||
blkcnt * io->media->block_size, buffer);
|
||||
log_debug("ret=%lx (dec %ld)\n", ret & ~EFI_ERROR_MASK,
|
||||
ret & ~EFI_ERROR_MASK);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
return blkcnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to block device
|
||||
*
|
||||
* @dev: device
|
||||
* @blknr: first block to be write
|
||||
* @blkcnt: number of blocks to write
|
||||
* @buffer: input buffer
|
||||
* Return: number of blocks transferred
|
||||
*/
|
||||
static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
|
||||
const void *buffer)
|
||||
{
|
||||
struct efi_block_plat *plat = dev_get_plat(dev);
|
||||
struct efi_block_io *io = plat->blkio;
|
||||
efi_status_t ret;
|
||||
|
||||
log_debug("write buf=%p, block=%lx, count=%lx: ", buffer, (ulong)blknr,
|
||||
(ulong)blkcnt);
|
||||
ret = io->write_blocks(io, io->media->media_id, blknr,
|
||||
blkcnt * io->media->block_size, (void *)buffer);
|
||||
log_debug("ret=%lx (dec %ld)\n", ret & ~EFI_ERROR_MASK,
|
||||
ret & ~EFI_ERROR_MASK);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
return blkcnt;
|
||||
}
|
||||
|
||||
/* Block device driver operators */
|
||||
static const struct blk_ops efi_blk_ops = {
|
||||
.read = efi_bl_read,
|
||||
.write = efi_bl_write,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(efi_block) = {
|
||||
.name = "efi_block",
|
||||
.id = UCLASS_BLK,
|
||||
.ops = &efi_blk_ops,
|
||||
.plat_auto = sizeof(struct efi_block_plat),
|
||||
};
|
||||
|
||||
static int efi_media_bind(struct udevice *dev)
|
||||
{
|
||||
struct efi_media_plat *plat = dev_get_plat(dev);
|
||||
struct efi_block_plat *blk_plat;
|
||||
struct udevice *blk;
|
||||
int ret;
|
||||
|
||||
ret = blk_create_devicef(dev, "efi_block", "blk", IF_TYPE_EFI_MEDIA,
|
||||
dev_seq(dev), plat->blkio->media->block_size,
|
||||
plat->blkio->media->last_block, &blk);
|
||||
if (ret) {
|
||||
debug("Cannot create block device\n");
|
||||
return ret;
|
||||
}
|
||||
blk_plat = dev_get_plat(blk);
|
||||
blk_plat->blkio = plat->blkio;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(efi_media) = {
|
||||
.name = "efi_media",
|
||||
.id = UCLASS_EFI_MEDIA,
|
||||
.bind = efi_media_bind,
|
||||
.plat_auto = sizeof(struct efi_media_plat),
|
||||
};
|
20
drivers/block/sb_efi_media.c
Normal file
20
drivers/block/sb_efi_media.c
Normal file
@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* EFI_MEDIA driver for sandbox
|
||||
*
|
||||
* Copyright 2021 Google LLC
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
|
||||
static const struct udevice_id sandbox_efi_media_ids[] = {
|
||||
{ .compatible = "sandbox,efi-media" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sandbox_efi_media) = {
|
||||
.name = "sandbox_efi_media",
|
||||
.id = UCLASS_EFI_MEDIA,
|
||||
.of_match = sandbox_efi_media_ids,
|
||||
};
|
@ -4,14 +4,17 @@
|
||||
* Copyright 2019 NXP
|
||||
*/
|
||||
|
||||
#define LOG_CATEGORY UCLASS_CLK
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <malloc.h>
|
||||
#include <clk.h>
|
||||
#include <clk-uclass.h>
|
||||
#include <log.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/io.h>
|
||||
#include <dm/device.h>
|
||||
#include <dm/devres.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <clk.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
@ -9,14 +9,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define LOG_CATEGORY UCLASS_CLK
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <malloc.h>
|
||||
#include <clk-uclass.h>
|
||||
#include <log.h>
|
||||
#include <dm/device.h>
|
||||
#include <dm/devres.h>
|
||||
#include <dm/uclass.h>
|
||||
#include <dm/lists.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/clk-provider.h>
|
||||
@ -190,7 +194,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,
|
||||
|
||||
if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
|
||||
if (width + shift > 16) {
|
||||
pr_warn("divider value exceeds LOWORD field\n");
|
||||
dev_warn(dev, "divider value exceeds LOWORD field\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
}
|
||||
|
@ -5,17 +5,22 @@
|
||||
*
|
||||
* Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
|
||||
*/
|
||||
|
||||
#define LOG_CATEGORY UCLASS_CLK
|
||||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <clk.h>
|
||||
#include <clk-uclass.h>
|
||||
#include <div64.h>
|
||||
#include <log.h>
|
||||
#include <malloc.h>
|
||||
#include <dm/device.h>
|
||||
#include <dm/devres.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <div64.h>
|
||||
#include <clk.h>
|
||||
#include "clk.h"
|
||||
#include <linux/err.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
||||
#define UBOOT_DM_CLK_IMX_FIXED_FACTOR "ccf_clk_fixed_factor"
|
||||
|
||||
static ulong clk_factor_recalc_rate(struct clk *clk)
|
||||
|
@ -7,18 +7,23 @@
|
||||
* Gated clock implementation
|
||||
*/
|
||||
|
||||
#define LOG_CATEGORY UCLASS_CLK
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <malloc.h>
|
||||
#include <clk.h>
|
||||
#include <log.h>
|
||||
#include <clk-uclass.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/io.h>
|
||||
#include <dm/device.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <dm/devres.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <clk.h>
|
||||
#include "clk.h"
|
||||
#include <linux/err.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
||||
#define UBOOT_DM_CLK_GATE "clk_gate"
|
||||
|
||||
/**
|
||||
@ -123,7 +128,7 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
|
||||
|
||||
if (clk_gate_flags & CLK_GATE_HIWORD_MASK) {
|
||||
if (bit_idx > 15) {
|
||||
pr_err("gate bit exceeds LOWORD field\n");
|
||||
dev_err(dev, "gate bit exceeds LOWORD field\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
}
|
||||
|
@ -21,17 +21,22 @@
|
||||
* clock.
|
||||
*/
|
||||
|
||||
#define LOG_CATEGORY UCLASS_CLK
|
||||
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <clk-uclass.h>
|
||||
#include <log.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/io.h>
|
||||
#include <dm/device.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <dm/devres.h>
|
||||
#include <dm/uclass.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
||||
#define UBOOT_DM_CLK_CCF_MUX "ccf_clk_mux"
|
||||
@ -123,7 +128,7 @@ static int clk_mux_set_parent(struct clk *clk, struct clk *parent)
|
||||
|
||||
index = clk_fetch_parent_index(clk, parent);
|
||||
if (index < 0) {
|
||||
printf("Could not fetch index\n");
|
||||
log_err("Could not fetch index\n");
|
||||
return index;
|
||||
}
|
||||
|
||||
@ -169,7 +174,7 @@ struct clk *clk_hw_register_mux_table(struct device *dev, const char *name,
|
||||
if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
|
||||
width = fls(mask) - ffs(mask) + 1;
|
||||
if (width + shift > 16) {
|
||||
pr_err("mux value exceeds LOWORD field\n");
|
||||
dev_err(dev, "mux value exceeds LOWORD field\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <errno.h>
|
||||
#include <log.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/devres.h>
|
||||
@ -23,7 +24,6 @@
|
||||
#include <linux/bug.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <asm/global_data.h>
|
||||
|
||||
static inline const struct clk_ops *clk_dev_ops(struct udevice *dev)
|
||||
{
|
||||
|
@ -4,14 +4,16 @@
|
||||
* Lukasz Majewski, DENX Software Engineering, lukma@denx.de
|
||||
*/
|
||||
|
||||
#define LOG_CATEGORY UCLASS_CLK
|
||||
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <clk-uclass.h>
|
||||
#include <log.h>
|
||||
#include <dm/device.h>
|
||||
#include <dm/uclass.h>
|
||||
#include <dm/lists.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <clk.h>
|
||||
|
||||
int clk_register(struct clk *clk, const char *drv_name,
|
||||
const char *name, const char *parent_name)
|
||||
@ -22,24 +24,24 @@ int clk_register(struct clk *clk, const char *drv_name,
|
||||
|
||||
ret = uclass_get_device_by_name(UCLASS_CLK, parent_name, &parent);
|
||||
if (ret) {
|
||||
printf("%s: failed to get %s device (parent of %s)\n",
|
||||
__func__, parent_name, name);
|
||||
log_err("%s: failed to get %s device (parent of %s)\n",
|
||||
__func__, parent_name, name);
|
||||
} else {
|
||||
debug("%s: name: %s parent: %s [0x%p]\n", __func__, name,
|
||||
parent->name, parent);
|
||||
log_debug("%s: name: %s parent: %s [0x%p]\n", __func__, name,
|
||||
parent->name, parent);
|
||||
}
|
||||
|
||||
drv = lists_driver_lookup_name(drv_name);
|
||||
if (!drv) {
|
||||
printf("%s: %s is not a valid driver name\n",
|
||||
__func__, drv_name);
|
||||
log_err("%s: %s is not a valid driver name\n",
|
||||
__func__, drv_name);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
ret = device_bind(parent, drv, name, NULL, ofnode_null(), &clk->dev);
|
||||
if (ret) {
|
||||
printf("%s: CLK: %s driver bind error [%d]!\n", __func__, name,
|
||||
ret);
|
||||
log_err("%s: CLK: %s driver bind error [%d]!\n", __func__, name,
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -5,10 +5,13 @@
|
||||
* Author: Anup Patel <anup.patel@wdc.com>
|
||||
*/
|
||||
|
||||
#define LOG_CATEGORY UCLASS_CLK
|
||||
|
||||
#include <common.h>
|
||||
#include <clk-uclass.h>
|
||||
#include <div64.h>
|
||||
#include <dm.h>
|
||||
#include <log.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
struct clk_fixed_factor {
|
||||
|
@ -3,9 +3,12 @@
|
||||
* Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com>
|
||||
*/
|
||||
|
||||
#define LOG_CATEGORY UCLASS_CLK
|
||||
|
||||
#include <common.h>
|
||||
#include <clk-uclass.h>
|
||||
#include <dm.h>
|
||||
#include <log.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
|
@ -604,7 +604,8 @@ static int first_loading_rbf_to_buffer(struct udevice *dev,
|
||||
|
||||
if (strstr(uname, "fpga-periph") &&
|
||||
(!is_fpgamgr_early_user_mode() ||
|
||||
is_fpgamgr_user_mode())) {
|
||||
is_fpgamgr_user_mode() ||
|
||||
is_periph_program_force())) {
|
||||
fpga_node_name = uname;
|
||||
printf("FPGA: Start to program ");
|
||||
printf("peripheral/full bitstream ...\n");
|
||||
|
@ -250,6 +250,12 @@ config SYS_I2C_MESON
|
||||
internal buffer holding up to 8 bytes for transfers and supports
|
||||
both 7-bit and 10-bit addresses.
|
||||
|
||||
config SYS_I2C_MICROCHIP
|
||||
bool "Microchip I2C driver"
|
||||
help
|
||||
Add support for the Microchip I2C driver. This is operating on
|
||||
standard mode up to 100 kbits/s and fast mode up to 400 kbits/s.
|
||||
|
||||
config SYS_I2C_MXC
|
||||
bool "NXP MXC I2C driver"
|
||||
help
|
||||
|
@ -28,6 +28,7 @@ obj-$(CONFIG_SYS_I2C_IPROC) += iproc_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C_KONA) += kona_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C_LPC32XX) += lpc32xx_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C_MESON) += meson_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C_MICROCHIP) += i2c-microchip.o
|
||||
obj-$(CONFIG_SYS_I2C_MV) += mv_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o
|
||||
obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o
|
||||
|
482
drivers/i2c/i2c-microchip.c
Normal file
482
drivers/i2c/i2c-microchip.c
Normal file
@ -0,0 +1,482 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Microchip I2C controller driver
|
||||
*
|
||||
* Copyright (C) 2021 Microchip Technology Inc.
|
||||
* Padmarao Begari <padmarao.begari@microchip.com>
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <i2c.h>
|
||||
#include <asm/io.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#define MICROCHIP_I2C_TIMEOUT (1000 * 60)
|
||||
|
||||
#define MPFS_I2C_CTRL (0x00)
|
||||
#define CTRL_CR0 (0x00)
|
||||
#define CTRL_CR1 (0x01)
|
||||
#define CTRL_AA BIT(2)
|
||||
#define CTRL_SI BIT(3)
|
||||
#define CTRL_STO BIT(4)
|
||||
#define CTRL_STA BIT(5)
|
||||
#define CTRL_ENS1 BIT(6)
|
||||
#define CTRL_CR2 (0x07)
|
||||
#define MPFS_I2C_STATUS (0x04)
|
||||
#define STATUS_BUS_ERROR (0x00)
|
||||
#define STATUS_M_START_SENT (0x08)
|
||||
#define STATUS_M_REPEATED_START_SENT (0x10)
|
||||
#define STATUS_M_SLAW_ACK (0x18)
|
||||
#define STATUS_M_SLAW_NACK (0x20)
|
||||
#define STATUS_M_TX_DATA_ACK (0x28)
|
||||
#define STATUS_M_TX_DATA_NACK (0x30)
|
||||
#define STATUS_M_ARB_LOST (0x38)
|
||||
#define STATUS_M_SLAR_ACK (0x40)
|
||||
#define STATUS_M_SLAR_NACK (0x48)
|
||||
#define STATUS_M_RX_DATA_ACKED (0x50)
|
||||
#define STATUS_M_RX_DATA_NACKED (0x58)
|
||||
#define STATUS_S_SLAW_ACKED (0x60)
|
||||
#define STATUS_S_ARB_LOST_SLAW_ACKED (0x68)
|
||||
#define STATUS_S_GENERAL_CALL_ACKED (0x70)
|
||||
#define STATUS_S_ARB_LOST_GENERAL_CALL_ACKED (0x78)
|
||||
#define STATUS_S_RX_DATA_ACKED (0x80)
|
||||
#define STATUS_S_RX_DATA_NACKED (0x88)
|
||||
#define STATUS_S_GENERAL_CALL_RX_DATA_ACKED (0x90)
|
||||
#define STATUS_S_GENERAL_CALL_RX_DATA_NACKED (0x98)
|
||||
#define STATUS_S_RX_STOP (0xA0)
|
||||
#define STATUS_S_SLAR_ACKED (0xA8)
|
||||
#define STATUS_S_ARB_LOST_SLAR_ACKED (0xB0)
|
||||
#define STATUS_S_TX_DATA_ACK (0xb8)
|
||||
#define STATUS_S_TX_DATA_NACK (0xC0)
|
||||
#define STATUS_LAST_DATA_ACK (0xC8)
|
||||
#define STATUS_M_SMB_MASTER_RESET (0xD0)
|
||||
#define STATUS_S_SCL_LOW_TIMEOUT (0xD8)
|
||||
#define STATUS_NO_STATE_INFO (0xF8)
|
||||
#define MPFS_I2C_DATA (0x08)
|
||||
#define MPFS_I2C_SLAVE0_ADDR (0x0c)
|
||||
#define MPFS_I2C_SMBUS (0x10)
|
||||
#define MPFS_I2C_FREQ (0x14)
|
||||
#define MPFS_I2C_GLITCHREG (0x18)
|
||||
#define MPFS_I2C_SLAVE1_ADDR (0x1c)
|
||||
|
||||
#define PCLK_DIV_256 ((0 << CTRL_CR0) | (0 << CTRL_CR1) | (0 << CTRL_CR2))
|
||||
#define PCLK_DIV_224 ((1 << CTRL_CR0) | (0 << CTRL_CR1) | (0 << CTRL_CR2))
|
||||
#define PCLK_DIV_192 ((0 << CTRL_CR0) | (1 << CTRL_CR1) | (0 << CTRL_CR2))
|
||||
#define PCLK_DIV_160 ((1 << CTRL_CR0) | (1 << CTRL_CR1) | (0 << CTRL_CR2))
|
||||
#define PCLK_DIV_960 ((0 << CTRL_CR0) | (0 << CTRL_CR1) | (1 << CTRL_CR2))
|
||||
#define PCLK_DIV_120 ((1 << CTRL_CR0) | (0 << CTRL_CR1) | (1 << CTRL_CR2))
|
||||
#define PCLK_DIV_60 ((0 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2))
|
||||
#define BCLK_DIV_8 ((1 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2))
|
||||
#define CLK_MASK ((1 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2))
|
||||
|
||||
/*
|
||||
* mpfs_i2c_bus - I2C bus context
|
||||
* @base: pointer to register struct
|
||||
* @msg_len: number of bytes transferred in msg
|
||||
* @msg_err: error code for completed message
|
||||
* @i2c_clk: clock reference for i2c input clock
|
||||
* @clk_rate: current i2c bus clock rate
|
||||
* @buf: ptr to msg buffer for easier use.
|
||||
* @addr: i2c address.
|
||||
* @isr_status: cached copy of local ISR status.
|
||||
*/
|
||||
struct mpfs_i2c_bus {
|
||||
void __iomem *base;
|
||||
size_t msg_len;
|
||||
int msg_err;
|
||||
struct clk i2c_clk;
|
||||
u32 clk_rate;
|
||||
u8 *buf;
|
||||
u8 addr;
|
||||
u32 isr_status;
|
||||
};
|
||||
|
||||
static inline u8 i2c_8bit_addr_from_msg(const struct i2c_msg *msg)
|
||||
{
|
||||
return (msg->addr << 1) | (msg->flags & I2C_M_RD ? 1 : 0);
|
||||
}
|
||||
|
||||
static void mpfs_i2c_int_clear(struct mpfs_i2c_bus *bus)
|
||||
{
|
||||
u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
|
||||
|
||||
ctrl &= ~CTRL_SI;
|
||||
writel(ctrl, bus->base + MPFS_I2C_CTRL);
|
||||
}
|
||||
|
||||
static void mpfs_i2c_core_disable(struct mpfs_i2c_bus *bus)
|
||||
{
|
||||
u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
|
||||
|
||||
ctrl &= ~CTRL_ENS1;
|
||||
writel(ctrl, bus->base + MPFS_I2C_CTRL);
|
||||
}
|
||||
|
||||
static void mpfs_i2c_core_enable(struct mpfs_i2c_bus *bus)
|
||||
{
|
||||
u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
|
||||
|
||||
ctrl |= CTRL_ENS1;
|
||||
writel(ctrl, bus->base + MPFS_I2C_CTRL);
|
||||
}
|
||||
|
||||
static void mpfs_i2c_reset(struct mpfs_i2c_bus *bus)
|
||||
{
|
||||
mpfs_i2c_core_disable(bus);
|
||||
mpfs_i2c_core_enable(bus);
|
||||
}
|
||||
|
||||
static inline void mpfs_i2c_stop(struct mpfs_i2c_bus *bus)
|
||||
{
|
||||
u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
|
||||
|
||||
ctrl |= CTRL_STO;
|
||||
writel(ctrl, bus->base + MPFS_I2C_CTRL);
|
||||
}
|
||||
|
||||
static inline int mpfs_generate_divisor(u32 rate, u8 *code)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (rate >= 960)
|
||||
*code = PCLK_DIV_960;
|
||||
else if (rate >= 256)
|
||||
*code = PCLK_DIV_256;
|
||||
else if (rate >= 224)
|
||||
*code = PCLK_DIV_224;
|
||||
else if (rate >= 192)
|
||||
*code = PCLK_DIV_192;
|
||||
else if (rate >= 160)
|
||||
*code = PCLK_DIV_160;
|
||||
else if (rate >= 120)
|
||||
*code = PCLK_DIV_120;
|
||||
else if (rate >= 60)
|
||||
*code = PCLK_DIV_60;
|
||||
else if (rate >= 8)
|
||||
*code = BCLK_DIV_8;
|
||||
else
|
||||
ret = -EINVAL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mpfs_i2c_init(struct mpfs_i2c_bus *bus, struct udevice *dev)
|
||||
{
|
||||
u32 clk_rate, divisor;
|
||||
u8 clkval, ctrl;
|
||||
int ret;
|
||||
|
||||
ret = clk_get_by_index(dev, 0, &bus->i2c_clk);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
ret = clk_enable(&bus->i2c_clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk_rate = clk_get_rate(&bus->i2c_clk);
|
||||
if (!clk_rate)
|
||||
return -EINVAL;
|
||||
|
||||
clk_free(&bus->i2c_clk);
|
||||
|
||||
divisor = clk_rate / bus->clk_rate;
|
||||
|
||||
ctrl = readl(bus->base + MPFS_I2C_CTRL);
|
||||
|
||||
ctrl &= ~CLK_MASK;
|
||||
|
||||
ret = mpfs_generate_divisor(divisor, &clkval);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
ctrl |= clkval;
|
||||
|
||||
writel(ctrl, bus->base + MPFS_I2C_CTRL);
|
||||
|
||||
ctrl = readl(bus->base + MPFS_I2C_CTRL);
|
||||
|
||||
/* Reset I2C core */
|
||||
mpfs_i2c_reset(bus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mpfs_i2c_transfer(struct mpfs_i2c_bus *bus, u32 data)
|
||||
{
|
||||
if (bus->msg_len > 0)
|
||||
writel(data, bus->base + MPFS_I2C_DATA);
|
||||
}
|
||||
|
||||
static void mpfs_i2c_empty_rx(struct mpfs_i2c_bus *bus)
|
||||
{
|
||||
u8 ctrl;
|
||||
u8 data_read;
|
||||
|
||||
if (bus->msg_len > 0) {
|
||||
data_read = readl(bus->base + MPFS_I2C_DATA);
|
||||
*bus->buf++ = data_read;
|
||||
bus->msg_len--;
|
||||
}
|
||||
|
||||
if (bus->msg_len == 0) {
|
||||
ctrl = readl(bus->base + MPFS_I2C_CTRL);
|
||||
ctrl &= ~CTRL_AA;
|
||||
writel(ctrl, bus->base + MPFS_I2C_CTRL);
|
||||
}
|
||||
}
|
||||
|
||||
static int mpfs_i2c_fill_tx(struct mpfs_i2c_bus *bus)
|
||||
{
|
||||
mpfs_i2c_transfer(bus, *bus->buf++);
|
||||
bus->msg_len--;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpfs_i2c_service_handler(struct mpfs_i2c_bus *bus)
|
||||
{
|
||||
bool finish = false;
|
||||
u32 status;
|
||||
u8 ctrl;
|
||||
|
||||
status = bus->isr_status;
|
||||
|
||||
switch (status) {
|
||||
case STATUS_M_START_SENT:
|
||||
case STATUS_M_REPEATED_START_SENT:
|
||||
ctrl = readl(bus->base + MPFS_I2C_CTRL);
|
||||
ctrl &= ~CTRL_STA;
|
||||
writel(bus->addr, bus->base + MPFS_I2C_DATA);
|
||||
writel(ctrl, bus->base + MPFS_I2C_CTRL);
|
||||
break;
|
||||
case STATUS_M_SLAW_ACK:
|
||||
case STATUS_M_TX_DATA_ACK:
|
||||
if (bus->msg_len > 0) {
|
||||
mpfs_i2c_fill_tx(bus);
|
||||
} else {
|
||||
/* On the last byte to be transmitted, send STOP */
|
||||
mpfs_i2c_stop(bus);
|
||||
finish = true;
|
||||
}
|
||||
break;
|
||||
case STATUS_M_SLAR_ACK:
|
||||
ctrl = readl(bus->base + MPFS_I2C_CTRL);
|
||||
ctrl |= CTRL_AA;
|
||||
writel(ctrl, bus->base + MPFS_I2C_CTRL);
|
||||
if (bus->msg_len == 0) {
|
||||
/* On the last byte to be transmitted, send STOP */
|
||||
mpfs_i2c_stop(bus);
|
||||
finish = true;
|
||||
}
|
||||
break;
|
||||
case STATUS_M_RX_DATA_ACKED:
|
||||
mpfs_i2c_empty_rx(bus);
|
||||
if (bus->msg_len == 0) {
|
||||
/* On the last byte to be transmitted, send STOP */
|
||||
mpfs_i2c_stop(bus);
|
||||
finish = true;
|
||||
}
|
||||
break;
|
||||
case STATUS_M_TX_DATA_NACK:
|
||||
case STATUS_M_RX_DATA_NACKED:
|
||||
case STATUS_M_SLAR_NACK:
|
||||
case STATUS_M_SLAW_NACK:
|
||||
bus->msg_err = -ENXIO;
|
||||
mpfs_i2c_stop(bus);
|
||||
finish = true;
|
||||
break;
|
||||
|
||||
case STATUS_M_ARB_LOST:
|
||||
/* Handle Lost Arbitration */
|
||||
bus->msg_err = -EAGAIN;
|
||||
finish = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (finish) {
|
||||
ctrl = readl(bus->base + MPFS_I2C_CTRL);
|
||||
ctrl &= ~CTRL_AA;
|
||||
writel(ctrl, bus->base + MPFS_I2C_CTRL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int mpfs_i2c_service(struct mpfs_i2c_bus *bus)
|
||||
{
|
||||
int ret = 0;
|
||||
int si_bit;
|
||||
|
||||
si_bit = readl(bus->base + MPFS_I2C_CTRL);
|
||||
if (si_bit & CTRL_SI) {
|
||||
bus->isr_status = readl(bus->base + MPFS_I2C_STATUS);
|
||||
ret = mpfs_i2c_service_handler(bus);
|
||||
}
|
||||
/* Clear the si flag */
|
||||
mpfs_i2c_int_clear(bus);
|
||||
si_bit = readl(bus->base + MPFS_I2C_CTRL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mpfs_i2c_check_service_change(struct mpfs_i2c_bus *bus)
|
||||
{
|
||||
u8 ctrl;
|
||||
u32 count = 0;
|
||||
|
||||
while (1) {
|
||||
ctrl = readl(bus->base + MPFS_I2C_CTRL);
|
||||
if (ctrl & CTRL_SI)
|
||||
break;
|
||||
udelay(1);
|
||||
count += 1;
|
||||
if (count == MICROCHIP_I2C_TIMEOUT)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpfs_i2c_poll_device(struct mpfs_i2c_bus *bus)
|
||||
{
|
||||
int ret;
|
||||
|
||||
while (1) {
|
||||
ret = mpfs_i2c_check_service_change(bus);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mpfs_i2c_service(bus);
|
||||
if (!ret)
|
||||
/* all messages have been transferred */
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
static int mpfs_i2c_xfer_msg(struct mpfs_i2c_bus *bus, struct i2c_msg *msg)
|
||||
{
|
||||
u8 ctrl;
|
||||
int ret;
|
||||
|
||||
if (!msg->len || !msg->buf)
|
||||
return -EINVAL;
|
||||
|
||||
bus->addr = i2c_8bit_addr_from_msg(msg);
|
||||
bus->msg_len = msg->len;
|
||||
bus->buf = msg->buf;
|
||||
bus->msg_err = 0;
|
||||
|
||||
mpfs_i2c_core_enable(bus);
|
||||
|
||||
ctrl = readl(bus->base + MPFS_I2C_CTRL);
|
||||
|
||||
ctrl |= CTRL_STA;
|
||||
|
||||
writel(ctrl, bus->base + MPFS_I2C_CTRL);
|
||||
|
||||
ret = mpfs_i2c_poll_device(bus);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return bus->msg_err;
|
||||
}
|
||||
|
||||
static int mpfs_i2c_xfer(struct udevice *dev, struct i2c_msg *msgs, int num_msgs)
|
||||
{
|
||||
struct mpfs_i2c_bus *bus = dev_get_priv(dev);
|
||||
int idx, ret;
|
||||
|
||||
if (!msgs || !num_msgs)
|
||||
return -EINVAL;
|
||||
|
||||
for (idx = 0; idx < num_msgs; idx++) {
|
||||
ret = mpfs_i2c_xfer_msg(bus, msgs++);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mpfs_i2c_probe_chip(struct udevice *dev, uint addr, uint flags)
|
||||
{
|
||||
struct mpfs_i2c_bus *bus = dev_get_priv(dev);
|
||||
int ret;
|
||||
u8 ctrl, reg = 0;
|
||||
|
||||
/*
|
||||
* Send the chip address and verify that the
|
||||
* address was <ACK>ed.
|
||||
*/
|
||||
bus->addr = addr << 1 | I2C_M_RD;
|
||||
bus->buf = ®
|
||||
bus->msg_len = 0;
|
||||
bus->msg_err = 0;
|
||||
|
||||
mpfs_i2c_core_enable(bus);
|
||||
|
||||
ctrl = readl(bus->base + MPFS_I2C_CTRL);
|
||||
|
||||
ctrl |= CTRL_STA;
|
||||
|
||||
writel(ctrl, bus->base + MPFS_I2C_CTRL);
|
||||
|
||||
ret = mpfs_i2c_poll_device(bus);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return bus->msg_err;
|
||||
}
|
||||
|
||||
static int mpfs_i2c_probe(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
u32 val;
|
||||
struct mpfs_i2c_bus *bus = dev_get_priv(dev);
|
||||
|
||||
bus->base = dev_read_addr_ptr(dev);
|
||||
if (!bus->base)
|
||||
return -EINVAL;
|
||||
|
||||
val = dev_read_u32(dev, "clock-frequency", &bus->clk_rate);
|
||||
if (val) {
|
||||
printf("Default to 100kHz\n");
|
||||
/* default clock rate */
|
||||
bus->clk_rate = 100000;
|
||||
}
|
||||
|
||||
if (bus->clk_rate > 400000 || bus->clk_rate <= 0) {
|
||||
printf("Invalid clock-frequency %d\n", bus->clk_rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = mpfs_i2c_init(bus, dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct dm_i2c_ops mpfs_i2c_ops = {
|
||||
.xfer = mpfs_i2c_xfer,
|
||||
.probe_chip = mpfs_i2c_probe_chip,
|
||||
};
|
||||
|
||||
static const struct udevice_id mpfs_i2c_ids[] = {
|
||||
{.compatible = "microchip,mpfs-i2c"},
|
||||
{}
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mpfs_i2c) = {
|
||||
.name = "mpfs_i2c",
|
||||
.id = UCLASS_I2C,
|
||||
.of_match = mpfs_i2c_ids,
|
||||
.ops = &mpfs_i2c_ops,
|
||||
.probe = mpfs_i2c_probe,
|
||||
.priv_auto = sizeof(struct mpfs_i2c_bus),
|
||||
};
|
@ -860,6 +860,9 @@ static int mvtwsi_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
|
||||
{
|
||||
struct mvtwsi_i2c_dev *dev = dev_get_priv(bus);
|
||||
struct i2c_msg *dmsg, *omsg, dummy;
|
||||
u8 *addr_buf_ptr;
|
||||
u8 addr_buf[4];
|
||||
int i;
|
||||
|
||||
memset(&dummy, 0, sizeof(struct i2c_msg));
|
||||
|
||||
@ -873,12 +876,17 @@ static int mvtwsi_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
|
||||
omsg = nmsgs == 1 ? &dummy : msg;
|
||||
dmsg = nmsgs == 1 ? msg : msg + 1;
|
||||
|
||||
/* We need to swap the register address if its size is > 1 */
|
||||
addr_buf_ptr = &addr_buf[0];
|
||||
for (i = omsg->len; i > 0; i--)
|
||||
*addr_buf_ptr++ = omsg->buf[i - 1];
|
||||
|
||||
if (dmsg->flags & I2C_M_RD)
|
||||
return __twsi_i2c_read(dev->base, dmsg->addr, omsg->buf,
|
||||
return __twsi_i2c_read(dev->base, dmsg->addr, addr_buf,
|
||||
omsg->len, dmsg->buf, dmsg->len,
|
||||
dev->tick);
|
||||
else
|
||||
return __twsi_i2c_write(dev->base, dmsg->addr, omsg->buf,
|
||||
return __twsi_i2c_write(dev->base, dmsg->addr, addr_buf,
|
||||
omsg->len, dmsg->buf, dmsg->len,
|
||||
dev->tick);
|
||||
}
|
||||
|
@ -1045,16 +1045,10 @@ static int eqos_start(struct udevice *dev)
|
||||
eqos->tx_desc_idx = 0;
|
||||
eqos->rx_desc_idx = 0;
|
||||
|
||||
ret = eqos->config->ops->eqos_start_clks(dev);
|
||||
if (ret < 0) {
|
||||
pr_err("eqos_start_clks() failed: %d", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = eqos->config->ops->eqos_start_resets(dev);
|
||||
if (ret < 0) {
|
||||
pr_err("eqos_start_resets() failed: %d", ret);
|
||||
goto err_stop_clks;
|
||||
goto err;
|
||||
}
|
||||
|
||||
udelay(10);
|
||||
@ -1360,8 +1354,6 @@ err_shutdown_phy:
|
||||
phy_shutdown(eqos->phy);
|
||||
err_stop_resets:
|
||||
eqos->config->ops->eqos_stop_resets(dev);
|
||||
err_stop_clks:
|
||||
eqos->config->ops->eqos_stop_clks(dev);
|
||||
err:
|
||||
pr_err("FAILED: %d", ret);
|
||||
return ret;
|
||||
@ -1416,7 +1408,6 @@ static void eqos_stop(struct udevice *dev)
|
||||
phy_shutdown(eqos->phy);
|
||||
}
|
||||
eqos->config->ops->eqos_stop_resets(dev);
|
||||
eqos->config->ops->eqos_stop_clks(dev);
|
||||
|
||||
debug("%s: OK\n", __func__);
|
||||
}
|
||||
@ -1862,6 +1853,12 @@ static int eqos_probe(struct udevice *dev)
|
||||
goto err_remove_resources_core;
|
||||
}
|
||||
|
||||
ret = eqos->config->ops->eqos_start_clks(dev);
|
||||
if (ret < 0) {
|
||||
pr_err("eqos_start_clks() failed: %d", ret);
|
||||
goto err_remove_resources_tegra;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_ETH_PHY
|
||||
eqos->mii = eth_phy_get_mdio_bus(dev);
|
||||
#endif
|
||||
@ -1870,7 +1867,7 @@ static int eqos_probe(struct udevice *dev)
|
||||
if (!eqos->mii) {
|
||||
pr_err("mdio_alloc() failed");
|
||||
ret = -ENOMEM;
|
||||
goto err_remove_resources_tegra;
|
||||
goto err_stop_clks;
|
||||
}
|
||||
eqos->mii->read = eqos_mdio_read;
|
||||
eqos->mii->write = eqos_mdio_write;
|
||||
@ -1893,6 +1890,8 @@ static int eqos_probe(struct udevice *dev)
|
||||
|
||||
err_free_mdio:
|
||||
mdio_free(eqos->mii);
|
||||
err_stop_clks:
|
||||
eqos->config->ops->eqos_stop_clks(dev);
|
||||
err_remove_resources_tegra:
|
||||
eqos->config->ops->eqos_remove_resources(dev);
|
||||
err_remove_resources_core:
|
||||
@ -1910,6 +1909,7 @@ static int eqos_remove(struct udevice *dev)
|
||||
|
||||
mdio_unregister(eqos->mii);
|
||||
mdio_free(eqos->mii);
|
||||
eqos->config->ops->eqos_stop_clks(dev);
|
||||
eqos->config->ops->eqos_remove_resources(dev);
|
||||
|
||||
eqos_probe_resources_core(dev);
|
||||
|
@ -138,7 +138,7 @@ static int eth_phy_of_to_plat(struct udevice *dev)
|
||||
ret = gpio_request_by_name(dev, "reset-gpios", 0,
|
||||
&uc_priv->reset_gpio,
|
||||
GPIOD_IS_OUT);
|
||||
if (ret != -ENOENT)
|
||||
if (ret && ret != -ENOENT)
|
||||
return ret;
|
||||
|
||||
uc_priv->reset_assert_delay = dev_read_u32_default(dev, "reset-assert-us", 0);
|
||||
|
@ -1348,7 +1348,7 @@ static const struct macb_usrio_cfg macb_default_usrio = {
|
||||
.clken = MACB_BIT(CLKEN),
|
||||
};
|
||||
|
||||
static const struct macb_config default_gem_config = {
|
||||
static struct macb_config default_gem_config = {
|
||||
.dma_burst_length = 16,
|
||||
.hw_dma_cap = HW_DMA_CAP_32B,
|
||||
.clk_init = NULL,
|
||||
@ -1383,8 +1383,13 @@ static int macb_eth_probe(struct udevice *dev)
|
||||
macb->is_big_endian = (cpu_to_be32(0x12345678) == 0x12345678);
|
||||
|
||||
macb->config = (struct macb_config *)dev_get_driver_data(dev);
|
||||
if (!macb->config)
|
||||
if (!macb->config) {
|
||||
if (IS_ENABLED(CONFIG_DMA_ADDR_T_64BIT)) {
|
||||
if (GEM_BFEXT(DAW64, gem_readl(macb, DCFG6)))
|
||||
default_gem_config.hw_dma_cap = HW_DMA_CAP_64B;
|
||||
}
|
||||
macb->config = &default_gem_config;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CLK
|
||||
ret = macb_enable_clk(dev);
|
||||
@ -1453,13 +1458,6 @@ static const struct macb_usrio_cfg sama7g5_usrio = {
|
||||
.clken = BIT(2),
|
||||
};
|
||||
|
||||
static const struct macb_config microchip_config = {
|
||||
.dma_burst_length = 16,
|
||||
.hw_dma_cap = HW_DMA_CAP_64B,
|
||||
.clk_init = NULL,
|
||||
.usrio = &macb_default_usrio,
|
||||
};
|
||||
|
||||
static const struct macb_config sama5d4_config = {
|
||||
.dma_burst_length = 4,
|
||||
.hw_dma_cap = HW_DMA_CAP_32B,
|
||||
@ -1502,8 +1500,6 @@ static const struct udevice_id macb_eth_ids[] = {
|
||||
{ .compatible = "cdns,zynq-gem" },
|
||||
{ .compatible = "sifive,fu540-c000-gem",
|
||||
.data = (ulong)&sifive_config },
|
||||
{ .compatible = "microchip,mpfs-mss-gem",
|
||||
.data = (ulong)µchip_config },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -129,7 +129,7 @@ struct ravb_priv {
|
||||
struct phy_device *phydev;
|
||||
struct mii_dev *bus;
|
||||
void __iomem *iobase;
|
||||
struct clk clk;
|
||||
struct clk_bulk clks;
|
||||
struct gpio_desc reset_gpio;
|
||||
};
|
||||
|
||||
@ -485,7 +485,7 @@ static int ravb_probe(struct udevice *dev)
|
||||
iobase = map_physmem(pdata->iobase, 0x1000, MAP_NOCACHE);
|
||||
eth->iobase = iobase;
|
||||
|
||||
ret = clk_get_by_index(dev, 0, ð->clk);
|
||||
ret = clk_get_bulk(dev, ð->clks);
|
||||
if (ret < 0)
|
||||
goto err_mdio_alloc;
|
||||
|
||||
@ -518,7 +518,7 @@ static int ravb_probe(struct udevice *dev)
|
||||
eth->bus = miiphy_get_dev_by_name(dev->name);
|
||||
|
||||
/* Bring up PHY */
|
||||
ret = clk_enable(ð->clk);
|
||||
ret = clk_enable_bulk(ð->clks);
|
||||
if (ret)
|
||||
goto err_mdio_register;
|
||||
|
||||
@ -533,7 +533,7 @@ static int ravb_probe(struct udevice *dev)
|
||||
return 0;
|
||||
|
||||
err_mdio_reset:
|
||||
clk_disable(ð->clk);
|
||||
clk_release_bulk(ð->clks);
|
||||
err_mdio_register:
|
||||
mdio_free(mdiodev);
|
||||
err_mdio_alloc:
|
||||
@ -545,7 +545,7 @@ static int ravb_remove(struct udevice *dev)
|
||||
{
|
||||
struct ravb_priv *eth = dev_get_priv(dev);
|
||||
|
||||
clk_disable(ð->clk);
|
||||
clk_release_bulk(ð->clks);
|
||||
|
||||
free(eth->phydev);
|
||||
mdio_unregister(eth->bus);
|
||||
|
@ -193,7 +193,7 @@ struct pcie_advk {
|
||||
int sec_busno;
|
||||
struct udevice *dev;
|
||||
struct gpio_desc reset_gpio;
|
||||
u32 cfgcache[0x34 - 0x10];
|
||||
u32 cfgcache[(0x3c - 0x10) / 4];
|
||||
bool cfgcrssve;
|
||||
};
|
||||
|
||||
@ -380,20 +380,19 @@ static int pcie_advk_read_config(const struct udevice *bus, pci_dev_t bdf,
|
||||
}
|
||||
|
||||
/*
|
||||
* The configuration space of the PCI Bridge on primary (local) bus is
|
||||
* The configuration space of the PCI Bridge on primary (first) bus is
|
||||
* not accessible via PIO transfers like all other PCIe devices. PCI
|
||||
* Bridge config registers are available directly in Aardvark memory
|
||||
* space starting at offset zero. Moreover PCI Bridge registers in the
|
||||
* range 0x10 - 0x34 are not available and register 0x38 (Expansion ROM
|
||||
* Base Address) is at offset 0x30.
|
||||
* We therefore read configuration space content of the primary PCI
|
||||
* Bridge from our virtual cache.
|
||||
* space starting at offset zero. The PCI Bridge config space is of
|
||||
* Type 0, but the BAR registers (including ROM BAR) don't have the same
|
||||
* meaning as in the PCIe specification. Therefore do not access BAR
|
||||
* registers and non-common registers (those which have different
|
||||
* meaning for Type 0 and Type 1 config space) of the primary PCI Bridge
|
||||
* and instead read their content from driver virtual cfgcache[].
|
||||
*/
|
||||
if (busno == pcie->first_busno) {
|
||||
if (offset >= 0x10 && offset < 0x34)
|
||||
if ((offset >= 0x10 && offset < 0x34) || (offset >= 0x38 && offset < 0x3c))
|
||||
data = pcie->cfgcache[(offset - 0x10) / 4];
|
||||
else if ((offset & ~3) == PCI_ROM_ADDRESS1)
|
||||
data = advk_readl(pcie, PCIE_CORE_EXP_ROM_BAR_REG);
|
||||
else
|
||||
data = advk_readl(pcie, offset & ~3);
|
||||
|
||||
@ -567,23 +566,22 @@ static int pcie_advk_write_config(struct udevice *bus, pci_dev_t bdf,
|
||||
}
|
||||
|
||||
/*
|
||||
* As explained in pcie_advk_read_config(), for the configuration
|
||||
* space of the primary PCI Bridge, we write the content into virtual
|
||||
* cache.
|
||||
* As explained in pcie_advk_read_config(), PCI Bridge config registers
|
||||
* are available directly in Aardvark memory space starting at offset
|
||||
* zero. Type 1 specific registers are not available, so we write their
|
||||
* content only into driver virtual cfgcache[].
|
||||
*/
|
||||
if (busno == pcie->first_busno) {
|
||||
if (offset >= 0x10 && offset < 0x34) {
|
||||
if ((offset >= 0x10 && offset < 0x34) ||
|
||||
(offset >= 0x38 && offset < 0x3c)) {
|
||||
data = pcie->cfgcache[(offset - 0x10) / 4];
|
||||
data = pci_conv_size_to_32(data, value, offset, size);
|
||||
/* This PCI bridge does not have configurable bars */
|
||||
if ((offset & ~3) == PCI_BASE_ADDRESS_0 ||
|
||||
(offset & ~3) == PCI_BASE_ADDRESS_1)
|
||||
(offset & ~3) == PCI_BASE_ADDRESS_1 ||
|
||||
(offset & ~3) == PCI_ROM_ADDRESS1)
|
||||
data = 0x0;
|
||||
pcie->cfgcache[(offset - 0x10) / 4] = data;
|
||||
} else if ((offset & ~3) == PCI_ROM_ADDRESS1) {
|
||||
data = advk_readl(pcie, PCIE_CORE_EXP_ROM_BAR_REG);
|
||||
data = pci_conv_size_to_32(data, value, offset, size);
|
||||
advk_writel(pcie, data, PCIE_CORE_EXP_ROM_BAR_REG);
|
||||
} else {
|
||||
data = advk_readl(pcie, offset & ~3);
|
||||
data = pci_conv_size_to_32(data, value, offset, size);
|
||||
@ -821,12 +819,20 @@ static int pcie_advk_setup_hw(struct pcie_advk *pcie)
|
||||
*
|
||||
* Note that this Aardvark PCI Bridge does not have a compliant Type 1
|
||||
* Configuration Space and it even cannot be accessed via Aardvark's
|
||||
* PCI config space access method. Something like config space is
|
||||
* PCI config space access method. Aardvark PCI Bridge Config space is
|
||||
* available in internal Aardvark registers starting at offset 0x0
|
||||
* and is reported as Type 0. In range 0x10 - 0x34 it has totally
|
||||
* different registers. So our driver reports Header Type as Type 1 and
|
||||
* for the above mentioned range redirects access to the virtual
|
||||
* cfgcache[] buffer, which avoids changing internal Aardvark registers.
|
||||
* and has format of Type 0 config space.
|
||||
*
|
||||
* Moreover Type 0 BAR registers (ranges 0x10 - 0x28 and 0x30 - 0x34)
|
||||
* have the same format in Marvell's specification as in PCIe
|
||||
* specification, but their meaning is totally different (and not even
|
||||
* the same meaning as explained in the corresponding comment in the
|
||||
* pci_mvebu driver; aardvark is still different).
|
||||
*
|
||||
* So our driver converts Type 0 config space to Type 1 and reports
|
||||
* Header Type as Type 1. Access to BAR registers and to non-existent
|
||||
* Type 1 registers is redirected to the virtual cfgcache[] buffer,
|
||||
* which avoids changing unrelated registers.
|
||||
*/
|
||||
reg = advk_readl(pcie, PCIE_CORE_DEV_REV_REG);
|
||||
reg &= ~0xffffff00;
|
||||
|
@ -89,7 +89,7 @@ struct mvebu_pcie {
|
||||
unsigned int mem_attr;
|
||||
unsigned int io_target;
|
||||
unsigned int io_attr;
|
||||
u32 cfgcache[0x34 - 0x10];
|
||||
u32 cfgcache[(0x3c - 0x10) / 4];
|
||||
};
|
||||
|
||||
/*
|
||||
@ -168,20 +168,20 @@ static int mvebu_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
|
||||
}
|
||||
|
||||
/*
|
||||
* mvebu has different internal registers mapped into PCI config space
|
||||
* in range 0x10-0x34 for PCI bridge, so do not access PCI config space
|
||||
* for this range and instead read content from driver virtual cfgcache
|
||||
* The configuration space of the PCI Bridge on primary (first) bus is
|
||||
* of Type 0 but the BAR registers (including ROM BAR) don't have the
|
||||
* same meaning as in the PCIe specification. Therefore do not access
|
||||
* BAR registers and non-common registers (those which have different
|
||||
* meaning for Type 0 and Type 1 config space) of the PCI Bridge and
|
||||
* instead read their content from driver virtual cfgcache[].
|
||||
*/
|
||||
if (busno == pcie->first_busno && offset >= 0x10 && offset < 0x34) {
|
||||
if (busno == pcie->first_busno && ((offset >= 0x10 && offset < 0x34) ||
|
||||
(offset >= 0x38 && offset < 0x3c))) {
|
||||
data = pcie->cfgcache[(offset - 0x10) / 4];
|
||||
debug("(addr,size,val)=(0x%04x, %d, 0x%08x) from cfgcache\n",
|
||||
offset, size, data);
|
||||
*valuep = pci_conv_32_to_size(data, offset, size);
|
||||
return 0;
|
||||
} else if (busno == pcie->first_busno &&
|
||||
(offset & ~3) == PCI_ROM_ADDRESS1) {
|
||||
/* mvebu has Expansion ROM Base Address (0x38) at offset 0x30 */
|
||||
offset -= PCI_ROM_ADDRESS1 - PCIE_EXP_ROM_BAR_OFF;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -248,17 +248,21 @@ static int mvebu_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
|
||||
}
|
||||
|
||||
/*
|
||||
* mvebu has different internal registers mapped into PCI config space
|
||||
* in range 0x10-0x34 for PCI bridge, so do not access PCI config space
|
||||
* for this range and instead write content to driver virtual cfgcache
|
||||
* As explained in mvebu_pcie_read_config(), PCI Bridge Type 1 specific
|
||||
* config registers are not available, so we write their content only
|
||||
* into driver virtual cfgcache[].
|
||||
* And as explained in mvebu_pcie_probe(), mvebu has its own specific
|
||||
* way for configuring primary and secondary bus numbers.
|
||||
*/
|
||||
if (busno == pcie->first_busno && offset >= 0x10 && offset < 0x34) {
|
||||
if (busno == pcie->first_busno && ((offset >= 0x10 && offset < 0x34) ||
|
||||
(offset >= 0x38 && offset < 0x3c))) {
|
||||
debug("Writing to cfgcache only\n");
|
||||
data = pcie->cfgcache[(offset - 0x10) / 4];
|
||||
data = pci_conv_size_to_32(data, value, offset, size);
|
||||
/* mvebu PCI bridge does not have configurable bars */
|
||||
if ((offset & ~3) == PCI_BASE_ADDRESS_0 ||
|
||||
(offset & ~3) == PCI_BASE_ADDRESS_1)
|
||||
(offset & ~3) == PCI_BASE_ADDRESS_1 ||
|
||||
(offset & ~3) == PCI_ROM_ADDRESS1)
|
||||
data = 0x0;
|
||||
pcie->cfgcache[(offset - 0x10) / 4] = data;
|
||||
/* mvebu has its own way how to set PCI primary bus number */
|
||||
@ -276,10 +280,6 @@ static int mvebu_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
|
||||
pcie->sec_busno);
|
||||
}
|
||||
return 0;
|
||||
} else if (busno == pcie->first_busno &&
|
||||
(offset & ~3) == PCI_ROM_ADDRESS1) {
|
||||
/* mvebu has Expansion ROM Base Address (0x38) at offset 0x30 */
|
||||
offset -= PCI_ROM_ADDRESS1 - PCIE_EXP_ROM_BAR_OFF;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -385,13 +385,20 @@ static int mvebu_pcie_probe(struct udevice *dev)
|
||||
* U-Boot cannot recognize as P2P Bridge.
|
||||
*
|
||||
* Note that this mvebu PCI Bridge does not have compliant Type 1
|
||||
* Configuration Space. Header Type is reported as Type 0 and in
|
||||
* range 0x10-0x34 it has aliased internal mvebu registers 0x10-0x34
|
||||
* (e.g. PCIE_BAR_LO_OFF) and register 0x38 is reserved.
|
||||
* Configuration Space. Header Type is reported as Type 0 and it
|
||||
* has format of Type 0 config space.
|
||||
*
|
||||
* Driver for this range redirects access to virtual cfgcache[] buffer
|
||||
* which avoids changing internal mvebu registers. And changes Header
|
||||
* Type response value to Type 1.
|
||||
* Moreover Type 0 BAR registers (ranges 0x10 - 0x28 and 0x30 - 0x34)
|
||||
* have the same format in Marvell's specification as in PCIe
|
||||
* specification, but their meaning is totally different and they do
|
||||
* different things: they are aliased into internal mvebu registers
|
||||
* (e.g. PCIE_BAR_LO_OFF) and these should not be changed or
|
||||
* reconfigured by pci device drivers.
|
||||
*
|
||||
* So our driver converts Type 0 config space to Type 1 and reports
|
||||
* Header Type as Type 1. Access to BAR registers and to non-existent
|
||||
* Type 1 registers is redirected to the virtual cfgcache[] buffer,
|
||||
* which avoids changing unrelated registers.
|
||||
*/
|
||||
reg = readl(pcie->base + PCIE_DEV_REV_OFF);
|
||||
reg &= ~0xffffff00;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <serial.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <mach/soc.h>
|
||||
|
||||
struct mvebu_plat {
|
||||
void __iomem *base;
|
||||
@ -214,6 +215,7 @@ static int mvebu_serial_remove(struct udevice *dev)
|
||||
u32 new_oversampling;
|
||||
u32 oversampling;
|
||||
u32 d1, d2;
|
||||
u32 nb_rst;
|
||||
|
||||
/*
|
||||
* Switch UART base clock back to XTAL because older Linux kernel
|
||||
@ -261,12 +263,22 @@ static int mvebu_serial_remove(struct udevice *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* wait until TX empty */
|
||||
while (!(readl(base + UART_STATUS_REG) & UART_STATUS_TX_EMPTY))
|
||||
;
|
||||
|
||||
/* external reset of UART via North Bridge Peripheral */
|
||||
nb_rst = readl(MVEBU_REGISTER(0x12400));
|
||||
writel(nb_rst & ~BIT(3), MVEBU_REGISTER(0x12400));
|
||||
writel(nb_rst | BIT(3), MVEBU_REGISTER(0x12400));
|
||||
|
||||
/* set baudrate and oversampling */
|
||||
writel(new_divider, base + UART_BAUD_REG);
|
||||
writel(new_oversampling, base + UART_POSSR_REG);
|
||||
|
||||
/* No Parity, 1 Stop */
|
||||
writel(0, base + UART_CTRL_REG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -306,7 +318,6 @@ U_BOOT_DRIVER(serial_mvebu) = {
|
||||
#ifdef CONFIG_DEBUG_MVEBU_A3700_UART
|
||||
|
||||
#include <debug_uart.h>
|
||||
#include <mach/soc.h>
|
||||
|
||||
static inline void _debug_uart_init(void)
|
||||
{
|
||||
|
@ -378,8 +378,14 @@ out:
|
||||
int tpm_tis_cleanup(struct udevice *dev)
|
||||
{
|
||||
struct tpm_chip *chip = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
ret = tpm_tis_request_locality(dev, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
tpm_tis_ready(dev);
|
||||
|
||||
tpm_tis_release_locality(dev, chip->locality);
|
||||
|
||||
return 0;
|
||||
|
@ -118,10 +118,13 @@ iounmap:
|
||||
static int tpm_tis_remove(struct udevice *dev)
|
||||
{
|
||||
struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev);
|
||||
int ret;
|
||||
|
||||
ret = tpm_tis_cleanup(dev);
|
||||
|
||||
iounmap(drv_data->iobase);
|
||||
|
||||
return tpm_tis_cleanup(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct tpm_ops tpm_tis_ops = {
|
||||
|
@ -34,9 +34,10 @@ enum if_type {
|
||||
IF_TYPE_SATA,
|
||||
IF_TYPE_HOST,
|
||||
IF_TYPE_NVME,
|
||||
IF_TYPE_EFI,
|
||||
IF_TYPE_EFI_LOADER,
|
||||
IF_TYPE_PVBLOCK,
|
||||
IF_TYPE_VIRTIO,
|
||||
IF_TYPE_EFI_MEDIA,
|
||||
|
||||
IF_TYPE_COUNT, /* Number of interface types */
|
||||
};
|
||||
@ -369,6 +370,18 @@ int blk_create_devicef(struct udevice *parent, const char *drv_name,
|
||||
const char *name, int if_type, int devnum, int blksz,
|
||||
lbaint_t lba, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* blk_probe_or_unbind() - Try to probe
|
||||
*
|
||||
* Try to probe the device, primarily for enumerating partitions.
|
||||
* If it fails, the device itself is unbound since it means that it won't
|
||||
* work any more.
|
||||
*
|
||||
* @dev: The device to probe
|
||||
* Return: 0 if OK, -ve on error
|
||||
*/
|
||||
int blk_probe_or_unbind(struct udevice *dev);
|
||||
|
||||
/**
|
||||
* blk_unbind_all() - Unbind all device of the given interface type
|
||||
*
|
||||
|
@ -389,7 +389,8 @@ int clk_free(struct clk *clk);
|
||||
*
|
||||
* @clk: A clock struct that was previously successfully requested by
|
||||
* clk_request/get_by_*().
|
||||
* @return clock rate in Hz, or -ve error code.
|
||||
* @return clock rate in Hz on success, 0 for invalid clock, or -ve error code
|
||||
* for other errors.
|
||||
*/
|
||||
ulong clk_get_rate(struct clk *clk);
|
||||
|
||||
|
@ -119,12 +119,23 @@
|
||||
/* Increase max gunzip size */
|
||||
#define CONFIG_SYS_BOOTM_LEN (64 << 20)
|
||||
|
||||
/* Support autoboot from RAM (kernel image is loaded via debug port) */
|
||||
#define KERNEL_IMAGE_ADDR "0x2000000 "
|
||||
#define BOOTENV_DEV_NAME_RAM(devtypeu, devtypel, instance) \
|
||||
"ram "
|
||||
#define BOOTENV_DEV_RAM(devtypeu, devtypel, instance) \
|
||||
"bootcmd_ram=" \
|
||||
"booti " \
|
||||
KERNEL_IMAGE_ADDR \
|
||||
"- $fdtcontroladdr\0"
|
||||
|
||||
/* When we use RAM as ENV */
|
||||
|
||||
/* Enable distro boot */
|
||||
#define BOOT_TARGET_DEVICES(func) \
|
||||
func(MMC, mmc, 0) \
|
||||
func(DHCP, dhcp, na)
|
||||
func(DHCP, dhcp, na) \
|
||||
func(RAM, ram, na)
|
||||
#include <config_distro_bootcmd.h>
|
||||
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
|
@ -23,7 +23,7 @@
|
||||
"boot_fdt=try\0" \
|
||||
"fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" \
|
||||
"initrd_addr=0x43800000\0" \
|
||||
"mmcdev=0\0" \
|
||||
"mmcdev=1\0" \
|
||||
"mmcpart=1\0" \
|
||||
"mmcrootpart=2\0" \
|
||||
"finduuid=part uuid mmc ${mmcdev}:${mmcrootpart} uuid\0" \
|
||||
|
@ -136,7 +136,8 @@
|
||||
#if CONFIG_IS_ENABLED(CMD_MMC)
|
||||
#define BOOT_TARGET_MMC(func) \
|
||||
func(MMC, mmc, 0) \
|
||||
func(MMC, mmc, 1)
|
||||
func(MMC, mmc, 1) \
|
||||
func(MMC, mmc, 2)
|
||||
#else
|
||||
#define BOOT_TARGET_MMC(func)
|
||||
#endif
|
||||
|
@ -971,8 +971,8 @@ static inline bool device_is_on_pci_bus(const struct udevice *dev)
|
||||
* @parent: parent device to scan
|
||||
*/
|
||||
#define device_foreach_child_of_to_plat(pos, parent) \
|
||||
for (int _ret = device_first_child_ofdata_err(parent, &dev); !_ret; \
|
||||
_ret = device_next_child_ofdata_err(&dev))
|
||||
for (int _ret = device_first_child_ofdata_err(parent, &pos); !_ret; \
|
||||
_ret = device_next_child_ofdata_err(&pos))
|
||||
|
||||
/**
|
||||
* device_foreach_child_probe() - iterate through children, probing them
|
||||
@ -988,8 +988,8 @@ static inline bool device_is_on_pci_bus(const struct udevice *dev)
|
||||
* @parent: parent device to scan
|
||||
*/
|
||||
#define device_foreach_child_probe(pos, parent) \
|
||||
for (int _ret = device_first_child_err(parent, &dev); !_ret; \
|
||||
_ret = device_next_child_err(&dev))
|
||||
for (int _ret = device_first_child_err(parent, &pos); !_ret; \
|
||||
_ret = device_next_child_err(&pos))
|
||||
|
||||
/**
|
||||
* dm_scan_fdt_dev() - Bind child device in the device tree
|
||||
|
@ -48,7 +48,8 @@ enum uclass_id {
|
||||
UCLASS_DMA, /* Direct Memory Access */
|
||||
UCLASS_DSA, /* Distributed (Ethernet) Switch Architecture */
|
||||
UCLASS_ECDSA, /* Elliptic curve cryptographic device */
|
||||
UCLASS_EFI, /* EFI managed devices */
|
||||
UCLASS_EFI_LOADER, /* Devices created by UEFI applications */
|
||||
UCLASS_EFI_MEDIA, /* Devices provided by UEFI firmware */
|
||||
UCLASS_ETH, /* Ethernet device */
|
||||
UCLASS_ETH_PHY, /* Ethernet PHY device */
|
||||
UCLASS_FIRMWARE, /* Firmware */
|
||||
|
196
include/dt-bindings/interrupt-controller/microchip-mpfs-plic.h
Normal file
196
include/dt-bindings/interrupt-controller/microchip-mpfs-plic.h
Normal file
@ -0,0 +1,196 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
|
||||
/* Copyright (c) 2020-2021 Microchip Technology Inc */
|
||||
|
||||
#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_MICROCHIP_MPFS_PLIC_H
|
||||
#define _DT_BINDINGS_INTERRUPT_CONTROLLER_MICROCHIP_MPFS_PLIC_H
|
||||
|
||||
#define PLIC_INT_INVALID 0
|
||||
#define PLIC_INT_L2_METADATA_CORR 1
|
||||
#define PLIC_INT_L2_METADATA_UNCORR 2
|
||||
#define PLIC_INT_L2_DATA_CORR 3
|
||||
#define PLIC_INT_L2_DATA_UNCORR 4
|
||||
#define PLIC_INT_DMA_CH0_DONE 5
|
||||
#define PLIC_INT_DMA_CH0_ERR 6
|
||||
#define PLIC_INT_DMA_CH1_DONE 7
|
||||
#define PLIC_INT_DMA_CH1_ERR 8
|
||||
#define PLIC_INT_DMA_CH2_DONE 9
|
||||
#define PLIC_INT_DMA_CH2_ERR 10
|
||||
#define PLIC_INT_DMA_CH3_DONE 11
|
||||
#define PLIC_INT_DMA_CH3_ERR 12
|
||||
|
||||
#define PLIC_INT_GPIO0_BIT0_OR_GPIO2_BIT0 13
|
||||
#define PLIC_INT_GPIO0_BIT1_OR_GPIO2_BIT1 14
|
||||
#define PLIC_INT_GPIO0_BIT2_OR_GPIO2_BIT2 15
|
||||
#define PLIC_INT_GPIO0_BIT3_OR_GPIO2_BIT3 16
|
||||
#define PLIC_INT_GPIO0_BIT4_OR_GPIO2_BIT4 17
|
||||
#define PLIC_INT_GPIO0_BIT5_OR_GPIO2_BIT5 18
|
||||
#define PLIC_INT_GPIO0_BIT6_OR_GPIO2_BIT6 19
|
||||
#define PLIC_INT_GPIO0_BIT7_OR_GPIO2_BIT7 20
|
||||
#define PLIC_INT_GPIO0_BIT8_OR_GPIO2_BIT8 21
|
||||
#define PLIC_INT_GPIO0_BIT9_OR_GPIO2_BIT9 22
|
||||
#define PLIC_INT_GPIO0_BIT10_OR_GPIO2_BIT10 23
|
||||
#define PLIC_INT_GPIO0_BIT11_OR_GPIO2_BIT11 24
|
||||
#define PLIC_INT_GPIO0_BIT12_OR_GPIO2_BIT12 25
|
||||
#define PLIC_INT_GPIO0_BIT13_OR_GPIO2_BIT13 26
|
||||
#define PLIC_INT_GPIO1_BIT0_OR_GPIO2_BIT14 27
|
||||
#define PLIC_INT_GPIO1_BIT1_OR_GPIO2_BIT15 28
|
||||
#define PLIC_INT_GPIO1_BIT2_OR_GPIO2_BIT16 29
|
||||
#define PLIC_INT_GPIO1_BIT3_OR_GPIO2_BIT17 30
|
||||
#define PLIC_INT_GPIO1_BIT4_OR_GPIO2_BIT18 31
|
||||
#define PLIC_INT_GPIO1_BIT5_OR_GPIO2_BIT19 32
|
||||
#define PLIC_INT_GPIO1_BIT6_OR_GPIO2_BIT20 33
|
||||
#define PLIC_INT_GPIO1_BIT7_OR_GPIO2_BIT21 34
|
||||
#define PLIC_INT_GPIO1_BIT8_OR_GPIO2_BIT22 35
|
||||
#define PLIC_INT_GPIO1_BIT9_OR_GPIO2_BIT23 36
|
||||
#define PLIC_INT_GPIO1_BIT10_OR_GPIO2_BIT24 37
|
||||
#define PLIC_INT_GPIO1_BIT11_OR_GPIO2_BIT25 38
|
||||
#define PLIC_INT_GPIO1_BIT12_OR_GPIO2_BIT26 39
|
||||
#define PLIC_INT_GPIO1_BIT13_OR_GPIO2_BIT27 40
|
||||
#define PLIC_INT_GPIO1_BIT14_OR_GPIO2_BIT28 41
|
||||
#define PLIC_INT_GPIO1_BIT15_OR_GPIO2_BIT29 42
|
||||
#define PLIC_INT_GPIO1_BIT16_OR_GPIO2_BIT30 43
|
||||
#define PLIC_INT_GPIO1_BIT17_OR_GPIO2_BIT31 44
|
||||
#define PLIC_INT_GPIO1_BIT18 45
|
||||
#define PLIC_INT_GPIO1_BIT19 46
|
||||
#define PLIC_INT_GPIO1_BIT20 47
|
||||
#define PLIC_INT_GPIO1_BIT21 48
|
||||
#define PLIC_INT_GPIO1_BIT22 49
|
||||
#define PLIC_INT_GPIO1_BIT23 50
|
||||
#define PLIC_INT_GPIO0_NON_DIRECT 51
|
||||
#define PLIC_INT_GPIO1_NON_DIRECT 52
|
||||
#define PLIC_INT_GPIO2_NON_DIRECT 53
|
||||
#define PLIC_INT_SPI0 54
|
||||
#define PLIC_INT_SPI1 55
|
||||
#define PLIC_INT_CAN0 56
|
||||
#define PLIC_INT_CAN1 57
|
||||
#define PLIC_INT_I2C0_MAIN 58
|
||||
#define PLIC_INT_I2C0_ALERT 59
|
||||
#define PLIC_INT_I2C0_SUS 60
|
||||
#define PLIC_INT_I2C1_MAIN 61
|
||||
#define PLIC_INT_I2C1_ALERT 62
|
||||
#define PLIC_INT_I2C1_SUS 63
|
||||
#define PLIC_INT_MAC0_INT 64
|
||||
#define PLIC_INT_MAC0_QUEUE1 65
|
||||
#define PLIC_INT_MAC0_QUEUE2 66
|
||||
#define PLIC_INT_MAC0_QUEUE3 67
|
||||
#define PLIC_INT_MAC0_EMAC 68
|
||||
#define PLIC_INT_MAC0_MMSL 69
|
||||
#define PLIC_INT_MAC1_INT 70
|
||||
#define PLIC_INT_MAC1_QUEUE1 71
|
||||
#define PLIC_INT_MAC1_QUEUE2 72
|
||||
#define PLIC_INT_MAC1_QUEUE3 73
|
||||
#define PLIC_INT_MAC1_EMAC 74
|
||||
#define PLIC_INT_MAC1_MMSL 75
|
||||
#define PLIC_INT_DDRC_TRAIN 76
|
||||
#define PLIC_INT_SCB_INTERRUPT 77
|
||||
#define PLIC_INT_ECC_ERROR 78
|
||||
#define PLIC_INT_ECC_CORRECT 79
|
||||
#define PLIC_INT_RTC_WAKEUP 80
|
||||
#define PLIC_INT_RTC_MATCH 81
|
||||
#define PLIC_INT_TIMER1 82
|
||||
#define PLIC_INT_TIMER2 83
|
||||
#define PLIC_INT_ENVM 84
|
||||
#define PLIC_INT_QSPI 85
|
||||
#define PLIC_INT_USB_DMA 86
|
||||
#define PLIC_INT_USB_MC 87
|
||||
#define PLIC_INT_MMC_MAIN 88
|
||||
#define PLIC_INT_MMC_WAKEUP 89
|
||||
#define PLIC_INT_MMUART0 90
|
||||
#define PLIC_INT_MMUART1 91
|
||||
#define PLIC_INT_MMUART2 92
|
||||
#define PLIC_INT_MMUART3 93
|
||||
#define PLIC_INT_MMUART4 94
|
||||
#define PLIC_INT_G5C_DEVRST 95
|
||||
#define PLIC_INT_G5C_MESSAGE 96
|
||||
#define PLIC_INT_USOC_VC_INTERRUPT 97
|
||||
#define PLIC_INT_USOC_SMB_INTERRUPT 98
|
||||
#define PLIC_INT_E51_0_MAINTENACE 99
|
||||
#define PLIC_INT_WDOG0_MRVP 100
|
||||
#define PLIC_INT_WDOG1_MRVP 101
|
||||
#define PLIC_INT_WDOG2_MRVP 102
|
||||
#define PLIC_INT_WDOG3_MRVP 103
|
||||
#define PLIC_INT_WDOG4_MRVP 104
|
||||
#define PLIC_INT_WDOG0_TOUT 105
|
||||
#define PLIC_INT_WDOG1_TOUT 106
|
||||
#define PLIC_INT_WDOG2_TOUT 107
|
||||
#define PLIC_INT_WDOG3_TOUT 108
|
||||
#define PLIC_INT_WDOG4_TOUT 109
|
||||
#define PLIC_INT_G5C_MSS_SPI 110
|
||||
#define PLIC_INT_VOLT_TEMP_ALARM 111
|
||||
#define PLIC_INT_ATHENA_COMPLETE 112
|
||||
#define PLIC_INT_ATHENA_ALARM 113
|
||||
#define PLIC_INT_ATHENA_BUS_ERROR 114
|
||||
#define PLIC_INT_USOC_AXIC_US 115
|
||||
#define PLIC_INT_USOC_AXIC_DS 116
|
||||
#define PLIC_INT_SPARE 117
|
||||
#define PLIC_INT_FABRIC_F2H_0 118
|
||||
#define PLIC_INT_FABRIC_F2H_1 119
|
||||
#define PLIC_INT_FABRIC_F2H_2 120
|
||||
#define PLIC_INT_FABRIC_F2H_3 121
|
||||
#define PLIC_INT_FABRIC_F2H_4 122
|
||||
#define PLIC_INT_FABRIC_F2H_5 123
|
||||
#define PLIC_INT_FABRIC_F2H_6 124
|
||||
#define PLIC_INT_FABRIC_F2H_7 125
|
||||
#define PLIC_INT_FABRIC_F2H_8 126
|
||||
#define PLIC_INT_FABRIC_F2H_9 127
|
||||
#define PLIC_INT_FABRIC_F2H_10 128
|
||||
#define PLIC_INT_FABRIC_F2H_11 129
|
||||
#define PLIC_INT_FABRIC_F2H_12 130
|
||||
#define PLIC_INT_FABRIC_F2H_13 131
|
||||
#define PLIC_INT_FABRIC_F2H_14 132
|
||||
#define PLIC_INT_FABRIC_F2H_15 133
|
||||
#define PLIC_INT_FABRIC_F2H_16 134
|
||||
#define PLIC_INT_FABRIC_F2H_17 135
|
||||
#define PLIC_INT_FABRIC_F2H_18 136
|
||||
#define PLIC_INT_FABRIC_F2H_19 137
|
||||
#define PLIC_INT_FABRIC_F2H_20 138
|
||||
#define PLIC_INT_FABRIC_F2H_21 139
|
||||
#define PLIC_INT_FABRIC_F2H_22 140
|
||||
#define PLIC_INT_FABRIC_F2H_23 141
|
||||
#define PLIC_INT_FABRIC_F2H_24 142
|
||||
#define PLIC_INT_FABRIC_F2H_25 143
|
||||
#define PLIC_INT_FABRIC_F2H_26 144
|
||||
#define PLIC_INT_FABRIC_F2H_27 145
|
||||
#define PLIC_INT_FABRIC_F2H_28 146
|
||||
#define PLIC_INT_FABRIC_F2H_29 147
|
||||
#define PLIC_INT_FABRIC_F2H_30 148
|
||||
#define PLIC_INT_FABRIC_F2H_31 149
|
||||
#define PLIC_INT_FABRIC_F2H_32 150
|
||||
#define PLIC_INT_FABRIC_F2H_33 151
|
||||
#define PLIC_INT_FABRIC_F2H_34 152
|
||||
#define PLIC_INT_FABRIC_F2H_35 153
|
||||
#define PLIC_INT_FABRIC_F2H_36 154
|
||||
#define PLIC_INT_FABRIC_F2H_37 155
|
||||
#define PLIC_INT_FABRIC_F2H_38 156
|
||||
#define PLIC_INT_FABRIC_F2H_39 157
|
||||
#define PLIC_INT_FABRIC_F2H_40 158
|
||||
#define PLIC_INT_FABRIC_F2H_41 159
|
||||
#define PLIC_INT_FABRIC_F2H_42 160
|
||||
#define PLIC_INT_FABRIC_F2H_43 161
|
||||
#define PLIC_INT_FABRIC_F2H_44 162
|
||||
#define PLIC_INT_FABRIC_F2H_45 163
|
||||
#define PLIC_INT_FABRIC_F2H_46 164
|
||||
#define PLIC_INT_FABRIC_F2H_47 165
|
||||
#define PLIC_INT_FABRIC_F2H_48 166
|
||||
#define PLIC_INT_FABRIC_F2H_49 167
|
||||
#define PLIC_INT_FABRIC_F2H_50 168
|
||||
#define PLIC_INT_FABRIC_F2H_51 169
|
||||
#define PLIC_INT_FABRIC_F2H_52 170
|
||||
#define PLIC_INT_FABRIC_F2H_53 171
|
||||
#define PLIC_INT_FABRIC_F2H_54 172
|
||||
#define PLIC_INT_FABRIC_F2H_55 173
|
||||
#define PLIC_INT_FABRIC_F2H_56 174
|
||||
#define PLIC_INT_FABRIC_F2H_57 175
|
||||
#define PLIC_INT_FABRIC_F2H_58 176
|
||||
#define PLIC_INT_FABRIC_F2H_59 177
|
||||
#define PLIC_INT_FABRIC_F2H_60 178
|
||||
#define PLIC_INT_FABRIC_F2H_61 179
|
||||
#define PLIC_INT_FABRIC_F2H_62 180
|
||||
#define PLIC_INT_FABRIC_F2H_63 181
|
||||
#define PLIC_INT_BUS_ERROR_UNIT_HART_0 182
|
||||
#define PLIC_INT_BUS_ERROR_UNIT_HART_1 183
|
||||
#define PLIC_INT_BUS_ERROR_UNIT_HART_2 184
|
||||
#define PLIC_INT_BUS_ERROR_UNIT_HART_3 185
|
||||
#define PLIC_INT_BUS_ERROR_UNIT_HART_4 186
|
||||
|
||||
#endif /* _DT_BINDINGS_INTERRUPT_CONTROLLER_MICROCHIP_MPFS_PLIC_H */
|
17
include/dt-bindings/interrupt-controller/riscv-hart.h
Normal file
17
include/dt-bindings/interrupt-controller/riscv-hart.h
Normal file
@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
|
||||
/* Copyright (c) 2020-2021 Microchip Technology Inc */
|
||||
|
||||
#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_RISCV_HART_H
|
||||
#define _DT_BINDINGS_INTERRUPT_CONTROLLER_RISCV_HART_H
|
||||
|
||||
#define HART_INT_U_SOFT 0
|
||||
#define HART_INT_S_SOFT 1
|
||||
#define HART_INT_M_SOFT 3
|
||||
#define HART_INT_U_TIMER 4
|
||||
#define HART_INT_S_TIMER 5
|
||||
#define HART_INT_M_TIMER 7
|
||||
#define HART_INT_U_EXT 8
|
||||
#define HART_INT_S_EXT 9
|
||||
#define HART_INT_M_EXT 11
|
||||
|
||||
#endif /* _DT_BINDINGS_INTERRUPT_CONTROLLER_RISCV_HART_H */
|
@ -414,6 +414,17 @@ struct efi_priv {
|
||||
void *next_hdr;
|
||||
};
|
||||
|
||||
/*
|
||||
* EFI attributes of the udevice handled by efi_media driver
|
||||
*
|
||||
* @handle: handle of the controller on which this driver is installed
|
||||
* @blkio: block io protocol proxied by this driver
|
||||
*/
|
||||
struct efi_media_plat {
|
||||
efi_handle_t handle;
|
||||
struct efi_block_io *blkio;
|
||||
};
|
||||
|
||||
/* Base address of the EFI image */
|
||||
extern char image_base[];
|
||||
|
||||
|
@ -525,6 +525,8 @@ efi_status_t efi_disk_register(void);
|
||||
efi_status_t efi_rng_register(void);
|
||||
/* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */
|
||||
efi_status_t efi_tcg2_register(void);
|
||||
/* Called by efi_init_obj_list() to do initial measurement */
|
||||
efi_status_t efi_tcg2_do_initial_measurement(void);
|
||||
/* measure the pe-coff image, extend PCR and add Event Log */
|
||||
efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
|
||||
struct efi_loaded_image_obj *handle,
|
||||
@ -988,4 +990,6 @@ efi_status_t efi_esrt_register(void);
|
||||
*/
|
||||
efi_status_t efi_esrt_populate(void);
|
||||
efi_status_t efi_load_capsule_drivers(void);
|
||||
|
||||
efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr, u32 *sz);
|
||||
#endif /* _EFI_LOADER_H */
|
||||
|
@ -512,13 +512,16 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data,
|
||||
* @dev TPM device
|
||||
* @idx Index of the PCR
|
||||
* @idx_min_sz Minimum size in bytes of the pcrSelect array
|
||||
* @algorithm Algorithm used, defined in 'enum tpm2_algorithms'
|
||||
* @data Output buffer for contents of the named PCR
|
||||
* @digest_len len of the data
|
||||
* @updates Optional out parameter: number of updates for this PCR
|
||||
*
|
||||
* @return code of the operation
|
||||
*/
|
||||
u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz,
|
||||
void *data, unsigned int *updates);
|
||||
u16 algorithm, void *data, u32 digest_len,
|
||||
unsigned int *updates);
|
||||
|
||||
/**
|
||||
* Issue a TPM2_GetCapability command. This implementation is limited
|
||||
|
@ -147,7 +147,7 @@ static int efi_bl_bind(efi_handle_t handle, void *interface)
|
||||
if (!obj)
|
||||
return -ENOENT;
|
||||
|
||||
devnum = blk_find_max_devnum(IF_TYPE_EFI);
|
||||
devnum = blk_find_max_devnum(IF_TYPE_EFI_LOADER);
|
||||
if (devnum == -ENODEV)
|
||||
devnum = 0;
|
||||
else if (devnum < 0)
|
||||
@ -159,8 +159,8 @@ static int efi_bl_bind(efi_handle_t handle, void *interface)
|
||||
sprintf(name, "efiblk#%d", devnum);
|
||||
|
||||
/* Create driver model udevice for the EFI block io device */
|
||||
ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI, devnum,
|
||||
io->media->block_size,
|
||||
ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI_LOADER,
|
||||
devnum, io->media->block_size,
|
||||
(lbaint_t)io->media->last_block, &bdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -209,6 +209,6 @@ static const struct efi_driver_ops driver_ops = {
|
||||
/* Identify as EFI driver */
|
||||
U_BOOT_DRIVER(efi_block) = {
|
||||
.name = "EFI block driver",
|
||||
.id = UCLASS_EFI,
|
||||
.id = UCLASS_EFI_LOADER,
|
||||
.ops = &driver_ops,
|
||||
};
|
||||
|
@ -308,7 +308,7 @@ efi_status_t efi_driver_init(void)
|
||||
log_debug("Initializing EFI driver framework\n");
|
||||
for (drv = ll_entry_start(struct driver, driver);
|
||||
drv < ll_entry_end(struct driver, driver); ++drv) {
|
||||
if (drv->id == UCLASS_EFI) {
|
||||
if (drv->id == UCLASS_EFI_LOADER) {
|
||||
ret = efi_add_driver(drv);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
log_err("Failed to add EFI driver %s\n",
|
||||
@ -328,7 +328,7 @@ efi_status_t efi_driver_init(void)
|
||||
*/
|
||||
static int efi_uc_init(struct uclass *class)
|
||||
{
|
||||
log_debug("Initializing UCLASS_EFI\n");
|
||||
log_debug("Initializing UCLASS_EFI_LOADER\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -340,13 +340,13 @@ static int efi_uc_init(struct uclass *class)
|
||||
*/
|
||||
static int efi_uc_destroy(struct uclass *class)
|
||||
{
|
||||
log_debug("Destroying UCLASS_EFI\n");
|
||||
log_debug("Destroying UCLASS_EFI_LOADER\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(efi) = {
|
||||
.name = "efi",
|
||||
.id = UCLASS_EFI,
|
||||
.id = UCLASS_EFI_LOADER,
|
||||
.init = efi_uc_init,
|
||||
.destroy = efi_uc_destroy,
|
||||
};
|
||||
|
@ -308,6 +308,8 @@ config EFI_TCG2_PROTOCOL
|
||||
bool "EFI_TCG2_PROTOCOL support"
|
||||
default y
|
||||
depends on TPM_V2
|
||||
# Sandbox TPM currently fails on GetCapabilities needed for TCG2
|
||||
depends on !SANDBOX
|
||||
select SHA1
|
||||
select SHA256
|
||||
select SHA384
|
||||
|
@ -3016,9 +3016,12 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
|
||||
if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
|
||||
if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION) {
|
||||
ret = efi_tcg2_measure_efi_app_invocation(image_obj);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
log_warning("tcg2 measurement fails(0x%lx)\n",
|
||||
ret);
|
||||
if (ret == EFI_SECURITY_VIOLATION) {
|
||||
/*
|
||||
* TCG2 Protocol is installed but no TPM device found,
|
||||
* this is not expected.
|
||||
*/
|
||||
return EFI_EXIT(EFI_SECURITY_VIOLATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -934,9 +934,16 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle,
|
||||
|
||||
#if CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL)
|
||||
/* Measure an PE/COFF image */
|
||||
if (tcg2_measure_pe_image(efi, efi_size, handle,
|
||||
loaded_image_info))
|
||||
log_err("PE image measurement failed\n");
|
||||
ret = tcg2_measure_pe_image(efi, efi_size, handle, loaded_image_info);
|
||||
if (ret == EFI_SECURITY_VIOLATION) {
|
||||
/*
|
||||
* TCG2 Protocol is installed but no TPM device found,
|
||||
* this is not expected.
|
||||
*/
|
||||
log_err("PE image measurement failed, no tpm device found\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Copy PE headers */
|
||||
|
@ -241,6 +241,10 @@ efi_status_t efi_init_obj_list(void)
|
||||
ret = efi_tcg2_register();
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
ret = efi_tcg2_do_initial_measurement();
|
||||
if (ret == EFI_SECURITY_VIOLATION)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Secure boot */
|
||||
|
@ -153,6 +153,15 @@ static u16 alg_to_len(u16 hash_alg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_tcg2_protocol_installed(void)
|
||||
{
|
||||
struct efi_handler *handler;
|
||||
efi_status_t ret;
|
||||
|
||||
ret = efi_search_protocol(efi_root, &efi_guid_tcg2_protocol, &handler);
|
||||
return ret == EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static u32 tcg_event_final_size(struct tpml_digest_values *digest_list)
|
||||
{
|
||||
u32 len;
|
||||
@ -199,6 +208,44 @@ static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index,
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* tcg2_pcr_read - Read PCRs for a TPM2 device for a given tpml_digest_values
|
||||
*
|
||||
* @dev: device
|
||||
* @pcr_index: PCR index
|
||||
* @digest_list: list of digest algorithms to extend
|
||||
*
|
||||
* @Return: status code
|
||||
*/
|
||||
static efi_status_t tcg2_pcr_read(struct udevice *dev, u32 pcr_index,
|
||||
struct tpml_digest_values *digest_list)
|
||||
{
|
||||
struct tpm_chip_priv *priv;
|
||||
unsigned int updates, pcr_select_min;
|
||||
u32 rc;
|
||||
size_t i;
|
||||
|
||||
priv = dev_get_uclass_priv(dev);
|
||||
if (!priv)
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
pcr_select_min = priv->pcr_select_min;
|
||||
|
||||
for (i = 0; i < digest_list->count; i++) {
|
||||
u16 hash_alg = digest_list->digests[i].hash_alg;
|
||||
u8 *digest = (u8 *)&digest_list->digests[i].digest;
|
||||
|
||||
rc = tpm2_pcr_read(dev, pcr_index, pcr_select_min,
|
||||
hash_alg, digest, alg_to_len(hash_alg),
|
||||
&updates);
|
||||
if (rc) {
|
||||
EFI_PRINT("Failed to read PCR\n");
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* put_event - Append an agile event to an eventlog
|
||||
*
|
||||
* @pcr_index: PCR index
|
||||
@ -324,6 +371,45 @@ __weak efi_status_t platform_get_tpm2_device(struct udevice **dev)
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* platform_get_eventlog() - retrieve the eventlog address and size
|
||||
*
|
||||
* This function retrieves the eventlog address and size if the underlying
|
||||
* firmware has done some measurements and passed them.
|
||||
*
|
||||
* This function may be overridden based on platform specific method of
|
||||
* passing the eventlog address and size.
|
||||
*
|
||||
* @dev: udevice
|
||||
* @addr: eventlog address
|
||||
* @sz: eventlog size
|
||||
* Return: status code
|
||||
*/
|
||||
__weak efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr,
|
||||
u32 *sz)
|
||||
{
|
||||
const u64 *basep;
|
||||
const u32 *sizep;
|
||||
|
||||
basep = dev_read_prop(dev, "tpm_event_log_addr", NULL);
|
||||
if (!basep)
|
||||
return EFI_NOT_FOUND;
|
||||
|
||||
*addr = be64_to_cpup((__force __be64 *)basep);
|
||||
|
||||
sizep = dev_read_prop(dev, "tpm_event_log_size", NULL);
|
||||
if (!sizep)
|
||||
return EFI_NOT_FOUND;
|
||||
|
||||
*sz = be32_to_cpup((__force __be32 *)sizep);
|
||||
if (*sz == 0) {
|
||||
log_debug("event log empty\n");
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* tpm2_get_max_command_size() - get the supported max command size
|
||||
*
|
||||
@ -886,9 +972,12 @@ efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
|
||||
IMAGE_NT_HEADERS32 *nt;
|
||||
struct efi_handler *handler;
|
||||
|
||||
if (!is_tcg2_protocol_installed())
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
return ret;
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
|
||||
switch (handle->image_type) {
|
||||
case IMAGE_SUBSYSTEM_EFI_APPLICATION:
|
||||
@ -1181,6 +1270,318 @@ static const struct efi_tcg2_protocol efi_tcg2_protocol = {
|
||||
.get_result_of_set_active_pcr_banks = efi_tcg2_get_result_of_set_active_pcr_banks,
|
||||
};
|
||||
|
||||
/**
|
||||
* parse_event_log_header() - Parse and verify the event log header fields
|
||||
*
|
||||
* @buffer: Pointer to the start of the eventlog
|
||||
* @size: Size of the eventlog
|
||||
* @pos: Return offset of the next event in buffer right
|
||||
* after the event header i.e specID
|
||||
*
|
||||
* Return: status code
|
||||
*/
|
||||
static efi_status_t parse_event_log_header(void *buffer, u32 size, u32 *pos)
|
||||
{
|
||||
struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer;
|
||||
int i = 0;
|
||||
|
||||
if (size < sizeof(*event_header))
|
||||
return EFI_COMPROMISED_DATA;
|
||||
|
||||
if (get_unaligned_le32(&event_header->pcr_index) != 0 ||
|
||||
get_unaligned_le32(&event_header->event_type) != EV_NO_ACTION)
|
||||
return EFI_COMPROMISED_DATA;
|
||||
|
||||
for (i = 0; i < sizeof(event_header->digest); i++) {
|
||||
if (event_header->digest[i])
|
||||
return EFI_COMPROMISED_DATA;
|
||||
}
|
||||
|
||||
*pos += sizeof(*event_header);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* parse_specid_event() - Parse and verify the specID Event in the eventlog
|
||||
*
|
||||
* @dev: udevice
|
||||
* @buffer: Pointer to the start of the eventlog
|
||||
* @log_size: Size of the eventlog
|
||||
* @pos: [in] Offset of specID event in the eventlog buffer
|
||||
* [out] Return offset of the next event in the buffer
|
||||
* after the specID
|
||||
* @digest_list: list of digests in the event
|
||||
*
|
||||
* Return: status code
|
||||
* @pos Offset in the eventlog where the specID event ends
|
||||
* @digest_list: list of digests in the event
|
||||
*/
|
||||
static efi_status_t parse_specid_event(struct udevice *dev, void *buffer,
|
||||
u32 log_size, u32 *pos,
|
||||
struct tpml_digest_values *digest_list)
|
||||
{
|
||||
struct tcg_efi_spec_id_event *spec_event;
|
||||
struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer;
|
||||
size_t spec_event_size;
|
||||
u32 active = 0, supported = 0, pcr_count = 0, alg_count = 0;
|
||||
u32 spec_active = 0;
|
||||
u16 hash_alg;
|
||||
u8 vendor_sz;
|
||||
int err, i;
|
||||
|
||||
if (*pos >= log_size || (*pos + sizeof(*spec_event)) > log_size)
|
||||
return EFI_COMPROMISED_DATA;
|
||||
|
||||
/* Check specID event data */
|
||||
spec_event = (struct tcg_efi_spec_id_event *)((uintptr_t)buffer + *pos);
|
||||
/* Check for signature */
|
||||
if (memcmp(spec_event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03,
|
||||
sizeof(TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03))) {
|
||||
log_err("specID Event: Signature mismatch\n");
|
||||
return EFI_COMPROMISED_DATA;
|
||||
}
|
||||
|
||||
if (spec_event->spec_version_minor !=
|
||||
TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 ||
|
||||
spec_event->spec_version_major !=
|
||||
TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2)
|
||||
return EFI_COMPROMISED_DATA;
|
||||
|
||||
if (spec_event->number_of_algorithms > MAX_HASH_COUNT ||
|
||||
spec_event->number_of_algorithms < 1) {
|
||||
log_err("specID Event: Number of algorithms incorrect\n");
|
||||
return EFI_COMPROMISED_DATA;
|
||||
}
|
||||
|
||||
alg_count = spec_event->number_of_algorithms;
|
||||
|
||||
err = tpm2_get_pcr_info(dev, &supported, &active, &pcr_count);
|
||||
if (err)
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
digest_list->count = 0;
|
||||
/*
|
||||
* We have to take care that the sequence of algorithms that we record
|
||||
* in digest_list matches the sequence in eventlog.
|
||||
*/
|
||||
for (i = 0; i < alg_count; i++) {
|
||||
hash_alg =
|
||||
get_unaligned_le16(&spec_event->digest_sizes[i].algorithm_id);
|
||||
|
||||
if (!(supported & alg_to_mask(hash_alg))) {
|
||||
log_err("specID Event: Unsupported algorithm\n");
|
||||
return EFI_COMPROMISED_DATA;
|
||||
}
|
||||
digest_list->digests[digest_list->count++].hash_alg = hash_alg;
|
||||
|
||||
spec_active |= alg_to_mask(hash_alg);
|
||||
}
|
||||
|
||||
/*
|
||||
* TCG specification expects the event log to have hashes for all
|
||||
* active PCR's
|
||||
*/
|
||||
if (spec_active != active) {
|
||||
/*
|
||||
* Previous stage bootloader should know all the active PCR's
|
||||
* and use them in the Eventlog.
|
||||
*/
|
||||
log_err("specID Event: All active hash alg not present\n");
|
||||
return EFI_COMPROMISED_DATA;
|
||||
}
|
||||
|
||||
/*
|
||||
* the size of the spec event and placement of vendor_info_size
|
||||
* depends on supported algoriths
|
||||
*/
|
||||
spec_event_size =
|
||||
offsetof(struct tcg_efi_spec_id_event, digest_sizes) +
|
||||
alg_count * sizeof(spec_event->digest_sizes[0]);
|
||||
|
||||
if (*pos + spec_event_size >= log_size)
|
||||
return EFI_COMPROMISED_DATA;
|
||||
|
||||
vendor_sz = *(uint8_t *)((uintptr_t)buffer + *pos + spec_event_size);
|
||||
|
||||
spec_event_size += sizeof(vendor_sz) + vendor_sz;
|
||||
*pos += spec_event_size;
|
||||
|
||||
if (get_unaligned_le32(&event_header->event_size) != spec_event_size) {
|
||||
log_err("specID event: header event size mismatch\n");
|
||||
/* Right way to handle this can be to call SetActive PCR's */
|
||||
return EFI_COMPROMISED_DATA;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* tcg2_parse_event() - Parse the event in the eventlog
|
||||
*
|
||||
* @dev: udevice
|
||||
* @buffer: Pointer to the start of the eventlog
|
||||
* @log_size: Size of the eventlog
|
||||
* @offset: [in] Offset of the event in the eventlog buffer
|
||||
* [out] Return offset of the next event in the buffer
|
||||
* @digest_list: list of digests in the event
|
||||
* @pcr Index of the PCR in the event
|
||||
*
|
||||
* Return: status code
|
||||
*/
|
||||
static efi_status_t tcg2_parse_event(struct udevice *dev, void *buffer,
|
||||
u32 log_size, u32 *offset,
|
||||
struct tpml_digest_values *digest_list,
|
||||
u32 *pcr)
|
||||
{
|
||||
struct tcg_pcr_event2 *event = NULL;
|
||||
u32 count, size, event_size;
|
||||
size_t pos;
|
||||
|
||||
event_size = tcg_event_final_size(digest_list);
|
||||
if (*offset >= log_size || *offset + event_size > log_size) {
|
||||
log_err("Event exceeds log size\n");
|
||||
return EFI_COMPROMISED_DATA;
|
||||
}
|
||||
|
||||
event = (struct tcg_pcr_event2 *)((uintptr_t)buffer + *offset);
|
||||
*pcr = get_unaligned_le32(&event->pcr_index);
|
||||
|
||||
/* get the count */
|
||||
count = get_unaligned_le32(&event->digests.count);
|
||||
if (count != digest_list->count)
|
||||
return EFI_COMPROMISED_DATA;
|
||||
|
||||
pos = offsetof(struct tcg_pcr_event2, digests);
|
||||
pos += offsetof(struct tpml_digest_values, digests);
|
||||
|
||||
for (int i = 0; i < digest_list->count; i++) {
|
||||
u16 alg;
|
||||
u16 hash_alg = digest_list->digests[i].hash_alg;
|
||||
u8 *digest = (u8 *)&digest_list->digests[i].digest;
|
||||
|
||||
alg = get_unaligned_le16((void *)((uintptr_t)event + pos));
|
||||
|
||||
if (alg != hash_alg)
|
||||
return EFI_COMPROMISED_DATA;
|
||||
|
||||
pos += offsetof(struct tpmt_ha, digest);
|
||||
memcpy(digest, (void *)((uintptr_t)event + pos), alg_to_len(hash_alg));
|
||||
pos += alg_to_len(hash_alg);
|
||||
}
|
||||
|
||||
size = get_unaligned_le32((void *)((uintptr_t)event + pos));
|
||||
event_size += size;
|
||||
pos += sizeof(u32); /* tcg_pcr_event2 event_size*/
|
||||
pos += size;
|
||||
|
||||
/* make sure the calculated buffer is what we checked against */
|
||||
if (pos != event_size)
|
||||
return EFI_COMPROMISED_DATA;
|
||||
|
||||
if (pos > log_size)
|
||||
return EFI_COMPROMISED_DATA;
|
||||
|
||||
*offset += pos;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* tcg2_get_fw_eventlog() - Get the eventlog address and size
|
||||
*
|
||||
* If the previous firmware has passed some eventlog, this function get it's
|
||||
* location and check for it's validity.
|
||||
*
|
||||
* @dev: udevice
|
||||
* @log_buffer: eventlog address
|
||||
* @log_sz: eventlog size
|
||||
*
|
||||
* Return: status code
|
||||
*/
|
||||
static efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer,
|
||||
size_t *log_sz)
|
||||
{
|
||||
struct tpml_digest_values digest_list;
|
||||
void *buffer;
|
||||
efi_status_t ret;
|
||||
u32 pcr, pos;
|
||||
u64 base;
|
||||
u32 sz;
|
||||
bool extend_pcr = false;
|
||||
int i;
|
||||
|
||||
ret = platform_get_eventlog(dev, &base, &sz);
|
||||
if (ret != EFI_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if (sz > TPM2_EVENT_LOG_SIZE)
|
||||
return EFI_VOLUME_FULL;
|
||||
|
||||
buffer = (void *)(uintptr_t)base;
|
||||
pos = 0;
|
||||
/* Parse the eventlog to check for its validity */
|
||||
ret = parse_event_log_header(buffer, sz, &pos);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = parse_specid_event(dev, buffer, sz, &pos, &digest_list);
|
||||
if (ret) {
|
||||
log_err("Error parsing SPEC ID Event\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = tcg2_pcr_read(dev, 0, &digest_list);
|
||||
if (ret) {
|
||||
log_err("Error reading PCR 0\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* If PCR0 is 0, previous firmware didn't have the capability
|
||||
* to extend the PCR. In this scenario, extend the PCR as
|
||||
* the eventlog is parsed.
|
||||
*/
|
||||
for (i = 0; i < digest_list.count; i++) {
|
||||
u8 hash_buf[TPM2_SHA512_DIGEST_SIZE] = { 0 };
|
||||
u16 hash_alg = digest_list.digests[i].hash_alg;
|
||||
|
||||
if (!memcmp((u8 *)&digest_list.digests[i].digest, hash_buf,
|
||||
alg_to_len(hash_alg)))
|
||||
extend_pcr = true;
|
||||
}
|
||||
|
||||
while (pos < sz) {
|
||||
ret = tcg2_parse_event(dev, buffer, sz, &pos, &digest_list,
|
||||
&pcr);
|
||||
if (ret) {
|
||||
log_err("Error parsing event\n");
|
||||
return ret;
|
||||
}
|
||||
if (extend_pcr) {
|
||||
ret = tcg2_pcr_extend(dev, pcr, &digest_list);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
log_err("Error in extending PCR\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Clear the digest for next event */
|
||||
for (i = 0; i < digest_list.count; i++) {
|
||||
u16 hash_alg = digest_list.digests[i].hash_alg;
|
||||
u8 *digest =
|
||||
(u8 *)&digest_list.digests[i].digest;
|
||||
|
||||
memset(digest, 0, alg_to_len(hash_alg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(log_buffer, buffer, sz);
|
||||
*log_sz = sz;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* create_specid_event() - Create the first event in the eventlog
|
||||
*
|
||||
@ -1275,6 +1676,14 @@ void tcg2_uninit(void)
|
||||
event_log.buffer = NULL;
|
||||
efi_free_pool(event_log.final_buffer);
|
||||
event_log.final_buffer = NULL;
|
||||
|
||||
if (!is_tcg2_protocol_installed())
|
||||
return;
|
||||
|
||||
ret = efi_remove_protocol(efi_root, &efi_guid_tcg2_protocol,
|
||||
(void *)&efi_tcg2_protocol);
|
||||
if (ret != EFI_SUCCESS)
|
||||
log_err("Failed to remove EFI TCG2 protocol\n");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1312,69 +1721,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_init_event_log() - initialize an eventlog
|
||||
*/
|
||||
static efi_status_t efi_init_event_log(void)
|
||||
{
|
||||
/*
|
||||
* vendor_info_size is currently set to 0, we need to change the length
|
||||
* and allocate the flexible array member if this changes
|
||||
*/
|
||||
struct tcg_pcr_event *event_header = NULL;
|
||||
struct udevice *dev;
|
||||
size_t spec_event_size;
|
||||
efi_status_t ret;
|
||||
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, TPM2_EVENT_LOG_SIZE,
|
||||
(void **)&event_log.buffer);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* initialize log area as 0xff so the OS can easily figure out the
|
||||
* last log entry
|
||||
*/
|
||||
memset(event_log.buffer, 0xff, TPM2_EVENT_LOG_SIZE);
|
||||
event_log.pos = 0;
|
||||
event_log.last_event_size = 0;
|
||||
event_log.get_event_called = false;
|
||||
event_log.ebs_called = false;
|
||||
event_log.truncated = false;
|
||||
|
||||
/*
|
||||
* The log header is defined to be in SHA1 event log entry format.
|
||||
* Setup event header
|
||||
*/
|
||||
event_header = (struct tcg_pcr_event *)event_log.buffer;
|
||||
put_unaligned_le32(0, &event_header->pcr_index);
|
||||
put_unaligned_le32(EV_NO_ACTION, &event_header->event_type);
|
||||
memset(&event_header->digest, 0, sizeof(event_header->digest));
|
||||
ret = create_specid_event(dev, (void *)((uintptr_t)event_log.buffer + sizeof(*event_header)),
|
||||
&spec_event_size);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto free_pool;
|
||||
put_unaligned_le32(spec_event_size, &event_header->event_size);
|
||||
event_log.pos = spec_event_size + sizeof(*event_header);
|
||||
event_log.last_event_size = event_log.pos;
|
||||
|
||||
ret = create_final_event();
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto free_pool;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
|
||||
free_pool:
|
||||
efi_free_pool(event_log.buffer);
|
||||
event_log.buffer = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* tcg2_measure_event() - common function to add event log and extend PCR
|
||||
*
|
||||
@ -1427,6 +1773,93 @@ static efi_status_t efi_append_scrtm_version(struct udevice *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_init_event_log() - initialize an eventlog
|
||||
*
|
||||
* Return: status code
|
||||
*/
|
||||
static efi_status_t efi_init_event_log(void)
|
||||
{
|
||||
/*
|
||||
* vendor_info_size is currently set to 0, we need to change the length
|
||||
* and allocate the flexible array member if this changes
|
||||
*/
|
||||
struct tcg_pcr_event *event_header = NULL;
|
||||
struct udevice *dev;
|
||||
size_t spec_event_size;
|
||||
efi_status_t ret;
|
||||
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
return ret;
|
||||
|
||||
ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, TPM2_EVENT_LOG_SIZE,
|
||||
(void **)&event_log.buffer);
|
||||
if (ret != EFI_SUCCESS)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* initialize log area as 0xff so the OS can easily figure out the
|
||||
* last log entry
|
||||
*/
|
||||
memset(event_log.buffer, 0xff, TPM2_EVENT_LOG_SIZE);
|
||||
|
||||
/*
|
||||
* The log header is defined to be in SHA1 event log entry format.
|
||||
* Setup event header
|
||||
*/
|
||||
event_header = (struct tcg_pcr_event *)event_log.buffer;
|
||||
event_log.pos = 0;
|
||||
event_log.last_event_size = 0;
|
||||
event_log.get_event_called = false;
|
||||
event_log.ebs_called = false;
|
||||
event_log.truncated = false;
|
||||
|
||||
/*
|
||||
* Check if earlier firmware have passed any eventlog. Different
|
||||
* platforms can use different ways to do so.
|
||||
*/
|
||||
ret = tcg2_get_fw_eventlog(dev, event_log.buffer, &event_log.pos);
|
||||
/*
|
||||
* If earlier firmware hasn't passed any eventlog, go ahead and
|
||||
* create the eventlog header.
|
||||
*/
|
||||
if (ret == EFI_NOT_FOUND) {
|
||||
put_unaligned_le32(0, &event_header->pcr_index);
|
||||
put_unaligned_le32(EV_NO_ACTION, &event_header->event_type);
|
||||
memset(&event_header->digest, 0, sizeof(event_header->digest));
|
||||
ret = create_specid_event(dev,
|
||||
(void *)((uintptr_t)event_log.buffer +
|
||||
sizeof(*event_header)),
|
||||
&spec_event_size);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto free_pool;
|
||||
put_unaligned_le32(spec_event_size, &event_header->event_size);
|
||||
event_log.pos = spec_event_size + sizeof(*event_header);
|
||||
event_log.last_event_size = event_log.pos;
|
||||
|
||||
/*
|
||||
* Add SCRTM version to the log if previous firmmware
|
||||
* doesn't pass an eventlog.
|
||||
*/
|
||||
ret = efi_append_scrtm_version(dev);
|
||||
}
|
||||
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto free_pool;
|
||||
|
||||
ret = create_final_event();
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto free_pool;
|
||||
|
||||
return ret;
|
||||
|
||||
free_pool:
|
||||
efi_free_pool(event_log.buffer);
|
||||
event_log.buffer = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* tcg2_measure_variable() - add variable event log and extend PCR
|
||||
*
|
||||
@ -1759,12 +2192,15 @@ efi_status_t efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *ha
|
||||
u32 event = 0;
|
||||
struct smbios_entry *entry;
|
||||
|
||||
if (!is_tcg2_protocol_installed())
|
||||
return EFI_SUCCESS;
|
||||
|
||||
if (tcg2_efi_app_invoked)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
return ret;
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
|
||||
ret = tcg2_measure_boot_variable(dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
@ -1809,6 +2245,9 @@ efi_status_t efi_tcg2_measure_efi_app_exit(void)
|
||||
efi_status_t ret;
|
||||
struct udevice *dev;
|
||||
|
||||
if (!is_tcg2_protocol_installed())
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
return ret;
|
||||
@ -1834,6 +2273,12 @@ efi_tcg2_notify_exit_boot_services(struct efi_event *event, void *context)
|
||||
EFI_ENTRY("%p, %p", event, context);
|
||||
|
||||
event_log.ebs_called = true;
|
||||
|
||||
if (!is_tcg2_protocol_installed()) {
|
||||
ret = EFI_SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
@ -1863,6 +2308,9 @@ efi_status_t efi_tcg2_notify_exit_boot_services_failed(void)
|
||||
struct udevice *dev;
|
||||
efi_status_t ret;
|
||||
|
||||
if (!is_tcg2_protocol_installed())
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
@ -1932,12 +2380,37 @@ error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_tcg2_do_initial_measurement() - do initial measurement
|
||||
*
|
||||
* Return: status code
|
||||
*/
|
||||
efi_status_t efi_tcg2_do_initial_measurement(void)
|
||||
{
|
||||
efi_status_t ret;
|
||||
struct udevice *dev;
|
||||
|
||||
if (!is_tcg2_protocol_installed())
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
|
||||
ret = tcg2_measure_secure_boot_variable(dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_tcg2_register() - register EFI_TCG2_PROTOCOL
|
||||
*
|
||||
* If a TPM2 device is available, the TPM TCG2 Protocol is registered
|
||||
*
|
||||
* Return: An error status is only returned if adding the protocol fails.
|
||||
* Return: status code
|
||||
*/
|
||||
efi_status_t efi_tcg2_register(void)
|
||||
{
|
||||
@ -1960,10 +2433,6 @@ efi_status_t efi_tcg2_register(void)
|
||||
}
|
||||
|
||||
ret = efi_init_event_log();
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
ret = efi_append_scrtm_version(dev);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
tcg2_uninit();
|
||||
goto fail;
|
||||
@ -1984,24 +2453,9 @@ efi_status_t efi_tcg2_register(void)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = tcg2_measure_secure_boot_variable(dev);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
tcg2_uninit();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
fail:
|
||||
log_err("Cannot install EFI_TCG2_PROTOCOL\n");
|
||||
/*
|
||||
* Return EFI_SUCCESS and don't stop the EFI subsystem.
|
||||
* That's done for 2 reasons
|
||||
* - If the protocol is not installed the PCRs won't be extended. So
|
||||
* someone later in the boot flow will notice that and take the
|
||||
* necessary actions.
|
||||
* - The TPM sandbox is limited and we won't be able to run any efi
|
||||
* related tests with TCG2 enabled
|
||||
*/
|
||||
return EFI_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
12
lib/tpm-v2.c
12
lib/tpm-v2.c
@ -254,7 +254,8 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data,
|
||||
}
|
||||
|
||||
u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz,
|
||||
void *data, unsigned int *updates)
|
||||
u16 algorithm, void *data, u32 digest_len,
|
||||
unsigned int *updates)
|
||||
{
|
||||
u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8));
|
||||
u8 command_v2[COMMAND_BUFFER_SIZE] = {
|
||||
@ -264,7 +265,7 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz,
|
||||
|
||||
/* TPML_PCR_SELECTION */
|
||||
tpm_u32(1), /* Number of selections */
|
||||
tpm_u16(TPM2_ALG_SHA256), /* Algorithm of the hash */
|
||||
tpm_u16(algorithm), /* Algorithm of the hash */
|
||||
idx_array_sz, /* Array size for selection */
|
||||
/* bitmap(idx) Selected PCR bitmap */
|
||||
};
|
||||
@ -283,10 +284,13 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (digest_len > response_len)
|
||||
return TPM_LIB_ERROR;
|
||||
|
||||
if (unpack_byte_string(response, response_len, "ds",
|
||||
10, &counter,
|
||||
response_len - TPM2_DIGEST_LEN, data,
|
||||
TPM2_DIGEST_LEN))
|
||||
response_len - digest_len, data,
|
||||
digest_len))
|
||||
return TPM_LIB_ERROR;
|
||||
|
||||
if (updates)
|
||||
|
@ -37,6 +37,7 @@ obj-$(CONFIG_DMA) += dma.o
|
||||
obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o
|
||||
obj-$(CONFIG_DM_DSA) += dsa.o
|
||||
obj-$(CONFIG_ECDSA_VERIFY) += ecdsa.o
|
||||
obj-$(CONFIG_EFI_MEDIA_SANDBOX) += efi_media.o
|
||||
obj-$(CONFIG_DM_ETH) += eth.o
|
||||
ifneq ($(CONFIG_EFI_PARTITION),)
|
||||
obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fastboot.o
|
||||
|
24
test/dm/efi_media.c
Normal file
24
test/dm/efi_media.c
Normal file
@ -0,0 +1,24 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Test for EFI_MEDIA uclass
|
||||
*
|
||||
* Copyright 2021 Google LLC
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <asm/test.h>
|
||||
#include <dm/test.h>
|
||||
#include <test/test.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
/* Test that we can use the EFI_MEDIA uclass */
|
||||
static int dm_test_efi_media(struct unit_test_state *uts)
|
||||
{
|
||||
struct udevice *dev;
|
||||
|
||||
ut_assertok(uclass_first_device_err(UCLASS_EFI_MEDIA, &dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_efi_media, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
|
@ -210,3 +210,23 @@ def test_efi_selftest_text_input_ex(u_boot_console):
|
||||
if m != 0:
|
||||
raise Exception('Failures occurred during the EFI selftest')
|
||||
u_boot_console.restart_uboot()
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_bootefi_selftest')
|
||||
@pytest.mark.buildconfigspec('efi_tcg2_protocol')
|
||||
def test_efi_selftest_tcg2(u_boot_console):
|
||||
"""Test the EFI_TCG2 PROTOCOL
|
||||
|
||||
:param u_boot_console: U-Boot console
|
||||
|
||||
This function executes the 'tcg2' unit test.
|
||||
"""
|
||||
u_boot_console.restart_uboot()
|
||||
u_boot_console.run_command(cmd='setenv efi_selftest list')
|
||||
output = u_boot_console.run_command('bootefi selftest')
|
||||
assert '\'tcg2\'' in output
|
||||
u_boot_console.run_command(cmd='setenv efi_selftest tcg2')
|
||||
u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False)
|
||||
m = u_boot_console.p.expect(['Summary: 0 failures', 'Press any key'])
|
||||
if m != 0:
|
||||
raise Exception('Failures occurred during the EFI selftest')
|
||||
u_boot_console.restart_uboot()
|
||||
|
@ -186,6 +186,7 @@ def test_tpm2_change_auth(u_boot_console):
|
||||
u_boot_console.run_command('tpm2 clear TPM2_RH_PLATFORM')
|
||||
assert output.endswith('0')
|
||||
|
||||
@pytest.mark.buildconfigspec('sandbox')
|
||||
@pytest.mark.buildconfigspec('cmd_tpm_v2')
|
||||
def test_tpm2_get_capability(u_boot_console):
|
||||
"""Execute a TPM_GetCapability command.
|
||||
|
15
tools/env/fw_env.c
vendored
15
tools/env/fw_env.c
vendored
@ -1083,12 +1083,6 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count)
|
||||
}
|
||||
|
||||
erase.length = erasesize;
|
||||
if (DEVTYPE(dev) != MTD_ABSENT) {
|
||||
was_locked = ioctl(fd, MEMISLOCKED, &erase);
|
||||
/* treat any errors as unlocked flash */
|
||||
if (was_locked < 0)
|
||||
was_locked = 0;
|
||||
}
|
||||
|
||||
/* This only runs once on NOR flash and SPI-dataflash */
|
||||
while (processed < write_total) {
|
||||
@ -1108,6 +1102,10 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count)
|
||||
|
||||
if (DEVTYPE(dev) != MTD_ABSENT) {
|
||||
erase.start = blockstart;
|
||||
was_locked = ioctl(fd, MEMISLOCKED, &erase);
|
||||
/* treat any errors as unlocked flash */
|
||||
if (was_locked < 0)
|
||||
was_locked = 0;
|
||||
if (was_locked)
|
||||
ioctl(fd, MEMUNLOCK, &erase);
|
||||
/* These do not need an explicit erase cycle */
|
||||
@ -1163,7 +1161,6 @@ static int flash_flag_obsolete(int dev, int fd, off_t offset)
|
||||
char tmp = ENV_REDUND_OBSOLETE;
|
||||
int was_locked; /* flash lock flag */
|
||||
|
||||
was_locked = ioctl(fd, MEMISLOCKED, &erase);
|
||||
erase.start = DEVOFFSET(dev);
|
||||
erase.length = DEVESIZE(dev);
|
||||
/* This relies on the fact, that ENV_REDUND_OBSOLETE == 0 */
|
||||
@ -1173,6 +1170,10 @@ static int flash_flag_obsolete(int dev, int fd, off_t offset)
|
||||
DEVNAME(dev));
|
||||
return rc;
|
||||
}
|
||||
was_locked = ioctl(fd, MEMISLOCKED, &erase);
|
||||
/* treat any errors as unlocked flash */
|
||||
if (was_locked < 0)
|
||||
was_locked = 0;
|
||||
if (was_locked)
|
||||
ioctl(fd, MEMUNLOCK, &erase);
|
||||
rc = write(fd, &tmp, sizeof(tmp));
|
||||
|
Loading…
Reference in New Issue
Block a user