aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-08-27 08:33:02 -0400
committerTom Rini <trini@konsulko.com>2021-08-27 08:33:02 -0400
commitb9cb74a5aa256fc34a1b2b9dd847a985b91f34f6 (patch)
treea618344b253ec3164848e797a2636bbd8f060223
parent7bfa565453ec5f63668a3464da21629055c3053f (diff)
parent229cb5c6ba3469cbc4a0bcc69389fe61c51fd3b4 (diff)
downloadu-boot-WIP/27Aug2021.zip
u-boot-WIP/27Aug2021.tar.gz
u-boot-WIP/27Aug2021.tar.bz2
Merge tag 'xilinx-for-v2021.10-rc3' of https://gitlab.denx.de/u-boot/custodians/u-boot-microblazeWIP/27Aug2021
Xilinx changes for v2021.10-rc3 xilinx: - Disable CONFIG_ARCH_FIXUP_FDT_MEMORY - Print information about cpu via soc drivers and enable DISPLAY_CPUINFO - Wire infrastructure for DTB_RESELECT and MULTI_DTB_FIT zynq: - Wire single QSPI - Use power-source instead of io-standard properties - Enable nor on zc770-xm012 zynqmp: - Change handling around multi_boot() - Setup offset for u-boot.itb in spi - Generate run time dfu_alt_info for capsule update - Use explicit values for enums (zynqmp_firmware.h) - Enable RTC/SHA1/BUTTON/BUTTON_GPIO command - Disable WDT driver by default - Bind usb/scsi via preboot because of EFI - DT updates/fixes - Add soc driver - Fix SPL SPI boot mode versal: - Add soc driver sdhci: - Update tap delay programming for zynq_sdhci driver cmd: - Fix RTC uclass handling in date command - Update pwm help message - Update reset help message watchdog: - Fix wwdt compilation rtc: - Deal with seq alias in rtc uclass - Add zynqmp RTC driver fdt: - Add kernel-doc for fdt_fixup_memory_banks()
-rw-r--r--MAINTAINERS4
-rw-r--r--Makefile3
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/dts/Makefile2
-rw-r--r--arch/arm/dts/zynq-cc108.dts2
-rw-r--r--arch/arm/dts/zynq-cse-qspi.dtsi2
-rw-r--r--arch/arm/dts/zynq-topic-miami.dts2
-rw-r--r--arch/arm/dts/zynq-zc702.dts30
-rw-r--r--arch/arm/dts/zynq-zc706.dts26
-rw-r--r--arch/arm/dts/zynq-zc770-xm010.dts8
-rw-r--r--arch/arm/dts/zynq-zc770-xm012.dts9
-rw-r--r--arch/arm/dts/zynq-zc770-xm013.dts8
-rw-r--r--arch/arm/dts/zynqmp-sck-kv-g-revA.dts8
-rw-r--r--arch/arm/dts/zynqmp-sck-kv-g-revB.dts8
-rw-r--r--arch/arm/dts/zynqmp-sm-k26-revA.dts9
-rw-r--r--arch/arm/dts/zynqmp-topic-miamimp-xilinx-xdp-v1r1.dts2
-rw-r--r--arch/arm/mach-versal/cpu.c5
-rw-r--r--arch/arm/mach-versal/include/mach/hardware.h4
-rw-r--r--arch/arm/mach-zynqmp/cpu.c5
-rw-r--r--arch/arm/mach-zynqmp/include/mach/hardware.h3
-rwxr-xr-xarch/arm/mach-zynqmp/mkimage_fit_atf.sh51
-rw-r--r--board/xilinx/common/board.c184
-rw-r--r--board/xilinx/zynqmp/Makefile2
-rw-r--r--board/xilinx/zynqmp/tap_delays.c101
-rw-r--r--board/xilinx/zynqmp/zynqmp.c74
-rw-r--r--cmd/boot.c3
-rw-r--r--cmd/date.c9
-rw-r--r--cmd/pwm.c7
-rw-r--r--common/fdt_support.c18
-rw-r--r--configs/xilinx_versal_virt_defconfig3
-rw-r--r--configs/xilinx_zynq_virt_defconfig1
-rw-r--r--configs/xilinx_zynqmp_virt_defconfig16
-rw-r--r--drivers/mmc/sdhci.c10
-rw-r--r--drivers/mmc/zynq_sdhci.c244
-rw-r--r--drivers/reset/Kconfig9
-rw-r--r--drivers/reset/Makefile1
-rw-r--r--drivers/reset/reset-zynqmp.c100
-rw-r--r--drivers/rtc/Kconfig7
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-uclass.c1
-rw-r--r--drivers/rtc/zynqmp_rtc.c158
-rw-r--r--drivers/soc/Kconfig16
-rw-r--r--drivers/soc/Makefile2
-rw-r--r--drivers/soc/soc_xilinx_versal.c76
-rw-r--r--drivers/soc/soc_xilinx_zynqmp.c78
-rw-r--r--drivers/watchdog/xilinx_wwdt.c1
-rw-r--r--include/sdhci.h2
-rw-r--r--include/zynqmp_firmware.h351
-rw-r--r--include/zynqmp_tap_delay.h21
49 files changed, 1395 insertions, 294 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 776ff70..4cf0c33 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -546,6 +546,7 @@ S: Maintained
T: git https://source.denx.de/u-boot/custodians/u-boot-microblaze.git
F: arch/arm/mach-versal/
F: drivers/net/xilinx_axi_mrmac.*
+F: drivers/soc/soc_xilinx_versal.c
F: drivers/watchdog/xilinx_wwdt.c
N: (?<!uni)versal
@@ -600,6 +601,9 @@ F: drivers/mtd/nand/raw/zynq_nand.c
F: drivers/net/phy/xilinx_phy.c
F: drivers/net/zynq_gem.c
F: drivers/serial/serial_zynq.c
+F: drivers/reset/reset-zynqmp.c
+F: drivers/rtc/zynqmp_rtc.c
+F: drivers/soc/soc_xilinx_zynqmp.c
F: drivers/spi/zynq_qspi.c
F: drivers/spi/zynq_spi.c
F: drivers/timer/cadence-ttc.c
diff --git a/Makefile b/Makefile
index 3c8437d..9335a3a 100644
--- a/Makefile
+++ b/Makefile
@@ -1169,6 +1169,8 @@ MKIMAGEFLAGS_fit-dtb.blob = -f auto -A $(ARCH) -T firmware -C none -O u-boot \
-a 0 -e 0 -E \
$(patsubst %,-b arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST))) -d /dev/null
+MKIMAGEFLAGS_fit-dtb.blob += -B 0x8
+
ifneq ($(EXT_DTB),)
u-boot-fit-dtb.bin: u-boot-nodtb.bin $(EXT_DTB)
$(call if_changed,cat)
@@ -1431,6 +1433,7 @@ MKIMAGEFLAGS_u-boot.itb =
else
MKIMAGEFLAGS_u-boot.itb = -E
endif
+MKIMAGEFLAGS_u-boot.itb += -B 0x8
ifdef U_BOOT_ITS
u-boot.itb: u-boot-nodtb.bin \
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d692139..2d59562 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1064,6 +1064,7 @@ config ARCH_VERSAL
select DM_SERIAL
select GPIO_EXTRA_HEADER
select OF_CONTROL
+ select SOC_DEVICE
imply BOARD_LATE_INIT
imply ENV_VARS_UBOOT_RUNTIME_CONFIG
@@ -1142,6 +1143,7 @@ config ARCH_ZYNQMP
select SPL_SEPARATE_BSS if SPL
select SUPPORT_SPL
select ZYNQMP_IPI
+ select SOC_DEVICE
imply BOARD_LATE_INIT
imply CMD_DM
imply ENV_VARS_UBOOT_RUNTIME_CONFIG
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 82a0790..fc16a57 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1133,7 +1133,7 @@ dtb-$(CONFIG_TARGET_EA_LPC3250DEVKITV2) += lpc3250-ea3250.dtb
targets += $(dtb-y)
# Add any required device tree compiler flags here
-DTC_FLAGS +=
+DTC_FLAGS += -a 0x8
PHONY += dtbs
dtbs: $(addprefix $(obj)/, $(dtb-y))
diff --git a/arch/arm/dts/zynq-cc108.dts b/arch/arm/dts/zynq-cc108.dts
index 64d73ec..036106e 100644
--- a/arch/arm/dts/zynq-cc108.dts
+++ b/arch/arm/dts/zynq-cc108.dts
@@ -58,7 +58,7 @@
is-dual = <0>;
num-cs = <1>;
flash@0 { /* 16 MB */
- compatible = "n25q128a11";
+ compatible = "n25q128a11", "jedec,spi-nor";
reg = <0x0>;
spi-max-frequency = <50000000>;
spi-tx-bus-width = <1>;
diff --git a/arch/arm/dts/zynq-cse-qspi.dtsi b/arch/arm/dts/zynq-cse-qspi.dtsi
index eb0e29e..38410ee 100644
--- a/arch/arm/dts/zynq-cse-qspi.dtsi
+++ b/arch/arm/dts/zynq-cse-qspi.dtsi
@@ -60,7 +60,7 @@
#size-cells = <0>;
num-cs = <1>;
flash0: flash@0 {
- compatible = "n25q128a11";
+ compatible = "n25q128a11", "jedec,spi-nor";
reg = <0x0>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
diff --git a/arch/arm/dts/zynq-topic-miami.dts b/arch/arm/dts/zynq-topic-miami.dts
index ab6bde9..c4ec561 100644
--- a/arch/arm/dts/zynq-topic-miami.dts
+++ b/arch/arm/dts/zynq-topic-miami.dts
@@ -36,7 +36,7 @@
is-dual = <0>;
num-cs = <1>;
flash@0 {
- compatible = "st,m25p80", "n25q256a";
+ compatible = "st,m25p80", "n25q256a", "jedec,spi-nor";
m25p,fast-read;
reg = <0x0>;
spi-tx-bus-width = <1>;
diff --git a/arch/arm/dts/zynq-zc702.dts b/arch/arm/dts/zynq-zc702.dts
index 4474f4b..f2e05a5 100644
--- a/arch/arm/dts/zynq-zc702.dts
+++ b/arch/arm/dts/zynq-zc702.dts
@@ -213,7 +213,7 @@
conf {
groups = "can0_9_grp";
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
};
conf-rx {
@@ -236,7 +236,7 @@
conf {
groups = "ethernet0_0_grp";
slew-rate = <0>;
- io-standard = <4>;
+ power-source = <4>;
};
conf-rx {
@@ -259,7 +259,7 @@
conf-mdio {
groups = "mdio0_0_grp";
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
bias-disable;
};
};
@@ -277,7 +277,7 @@
"gpio0_10_grp", "gpio0_11_grp", "gpio0_12_grp",
"gpio0_13_grp", "gpio0_14_grp";
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
};
conf-pull-up {
@@ -301,7 +301,7 @@
groups = "i2c0_10_grp";
bias-pull-up;
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
};
};
@@ -314,7 +314,7 @@
conf {
groups = "gpio0_50_grp", "gpio0_51_grp";
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
};
};
@@ -327,7 +327,7 @@
conf {
groups = "sdio0_2_grp";
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
bias-disable;
};
@@ -341,7 +341,7 @@
bias-high-impedance;
bias-pull-up;
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
};
mux-wp {
@@ -354,7 +354,7 @@
bias-high-impedance;
bias-pull-up;
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
};
};
@@ -367,7 +367,7 @@
conf {
groups = "uart1_10_grp";
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
};
conf-rx {
@@ -390,7 +390,7 @@
conf {
groups = "usb0_0_grp";
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
};
conf-rx {
@@ -409,6 +409,14 @@
&qspi {
u-boot,dm-pre-reloc;
status = "okay";
+ num-cs = <1>;
+ flash@0 {
+ compatible = "n25q128a11", "jedec,spi-nor";
+ reg = <0x0>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <50000000>;
+ };
};
&sdhci0 {
diff --git a/arch/arm/dts/zynq-zc706.dts b/arch/arm/dts/zynq-zc706.dts
index 84729e9..cb919e4 100644
--- a/arch/arm/dts/zynq-zc706.dts
+++ b/arch/arm/dts/zynq-zc706.dts
@@ -151,7 +151,7 @@
conf {
groups = "ethernet0_0_grp";
slew-rate = <0>;
- io-standard = <4>;
+ power-source = <4>;
};
conf-rx {
@@ -174,7 +174,7 @@
conf-mdio {
groups = "mdio0_0_grp";
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
bias-disable;
};
};
@@ -188,7 +188,7 @@
conf {
groups = "gpio0_7_grp", "gpio0_46_grp", "gpio0_47_grp";
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
};
conf-pull-up {
@@ -212,7 +212,7 @@
groups = "i2c0_10_grp";
bias-pull-up;
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
};
};
@@ -225,7 +225,7 @@
conf {
groups = "sdio0_2_grp";
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
bias-disable;
};
@@ -239,7 +239,7 @@
bias-high-impedance;
bias-pull-up;
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
};
mux-wp {
@@ -252,7 +252,7 @@
bias-high-impedance;
bias-pull-up;
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
};
};
@@ -265,7 +265,7 @@
conf {
groups = "uart1_10_grp";
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
};
conf-rx {
@@ -288,7 +288,7 @@
conf {
groups = "usb0_0_grp";
slew-rate = <0>;
- io-standard = <1>;
+ power-source = <1>;
};
conf-rx {
@@ -307,6 +307,14 @@
&qspi {
u-boot,dm-pre-reloc;
status = "okay";
+ num-cs = <1>;
+ flash@0 {
+ compatible = "n25q128a11", "jedec,spi-nor";
+ reg = <0x0>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <50000000>;
+ };
};
&sdhci0 {
diff --git a/arch/arm/dts/zynq-zc770-xm010.dts b/arch/arm/dts/zynq-zc770-xm010.dts
index c547d79..002ff9f 100644
--- a/arch/arm/dts/zynq-zc770-xm010.dts
+++ b/arch/arm/dts/zynq-zc770-xm010.dts
@@ -62,6 +62,14 @@
&qspi {
status = "okay";
+ num-cs = <1>;
+ flash@0 {
+ compatible = "n25q128a11", "jedec,spi-nor";
+ reg = <0x0>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <50000000>;
+ };
};
&sdhci0 {
diff --git a/arch/arm/dts/zynq-zc770-xm012.dts b/arch/arm/dts/zynq-zc770-xm012.dts
index 0d001c9..ccf76e7 100644
--- a/arch/arm/dts/zynq-zc770-xm012.dts
+++ b/arch/arm/dts/zynq-zc770-xm012.dts
@@ -53,6 +53,15 @@
};
};
+&nor0 {
+ status = "okay";
+ bank-width = <1>;
+};
+
+&smcc {
+ status = "okay";
+};
+
&spi1 {
status = "okay";
num-cs = <4>;
diff --git a/arch/arm/dts/zynq-zc770-xm013.dts b/arch/arm/dts/zynq-zc770-xm013.dts
index 7218ee3..455c8a9 100644
--- a/arch/arm/dts/zynq-zc770-xm013.dts
+++ b/arch/arm/dts/zynq-zc770-xm013.dts
@@ -61,6 +61,14 @@
&qspi {
status = "okay";
+ num-cs = <1>;
+ flash@0 {
+ compatible = "n25q128a11", "jedec,spi-nor";
+ reg = <0x0>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <50000000>;
+ };
};
&spi0 {
diff --git a/arch/arm/dts/zynqmp-sck-kv-g-revA.dts b/arch/arm/dts/zynqmp-sck-kv-g-revA.dts
index 4e8086c..22602d8 100644
--- a/arch/arm/dts/zynqmp-sck-kv-g-revA.dts
+++ b/arch/arm/dts/zynqmp-sck-kv-g-revA.dts
@@ -12,10 +12,10 @@
* Michal Simek <michal.simek@xilinx.com>
*/
- #include <dt-bindings/gpio/gpio.h>
- #include <dt-bindings/net/ti-dp83867.h>
- #include <dt-bindings/phy/phy.h>
- #include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
/dts-v1/;
/plugin/;
diff --git a/arch/arm/dts/zynqmp-sck-kv-g-revB.dts b/arch/arm/dts/zynqmp-sck-kv-g-revB.dts
index 048d566..df054e1 100644
--- a/arch/arm/dts/zynqmp-sck-kv-g-revB.dts
+++ b/arch/arm/dts/zynqmp-sck-kv-g-revB.dts
@@ -7,10 +7,10 @@
* Michal Simek <michal.simek@xilinx.com>
*/
- #include <dt-bindings/gpio/gpio.h>
- #include <dt-bindings/net/ti-dp83867.h>
- #include <dt-bindings/phy/phy.h>
- #include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
/dts-v1/;
/plugin/;
diff --git a/arch/arm/dts/zynqmp-sm-k26-revA.dts b/arch/arm/dts/zynqmp-sm-k26-revA.dts
index b613ab2..5f55df2 100644
--- a/arch/arm/dts/zynqmp-sm-k26-revA.dts
+++ b/arch/arm/dts/zynqmp-sm-k26-revA.dts
@@ -60,13 +60,13 @@
leds {
compatible = "gpio-leds";
- ds35 {
+ ds35-led {
label = "heartbeat";
gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
};
- ds36 {
+ ds36-led {
label = "vbus_det";
gpios = <&gpio 8 GPIO_ACTIVE_HIGH>;
default-state = "on";
@@ -183,7 +183,7 @@
};
};
-&sdhci0 { /* MIO13-23 - 16GB emmc MTFC16GAPALBH-IT - U133A*/
+&sdhci0 { /* MIO13-23 - 16GB emmc MTFC16GAPALBH-IT - U133A */
status = "okay";
non-removable;
disable-wp;
@@ -204,17 +204,20 @@
&i2c1 {
status = "okay";
+ u-boot,dm-pre-reloc;
clock-frequency = <400000>;
scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
eeprom: eeprom@50 { /* u46 - also at address 0x58 */
+ u-boot,dm-pre-reloc;
compatible = "st,24c64", "atmel,24c64"; /* st m24c64 */
reg = <0x50>;
/* WP pin EE_WP_EN connected to slg7x644092@68 */
};
eeprom_cc: eeprom@51 { /* required by spec - also at address 0x59 */
+ u-boot,dm-pre-reloc;
compatible = "st,24c64", "atmel,24c64"; /* st m24c64 */
reg = <0x51>;
};
diff --git a/arch/arm/dts/zynqmp-topic-miamimp-xilinx-xdp-v1r1.dts b/arch/arm/dts/zynqmp-topic-miamimp-xilinx-xdp-v1r1.dts
index 6ec96e0..300e2eb 100644
--- a/arch/arm/dts/zynqmp-topic-miamimp-xilinx-xdp-v1r1.dts
+++ b/arch/arm/dts/zynqmp-topic-miamimp-xilinx-xdp-v1r1.dts
@@ -58,7 +58,7 @@
status = "okay";
is-dual = <1>;
flash@0 {
- compatible = "st,m25p80", "n25q256a";
+ compatible = "st,m25p80", "n25q256a", "jedec,spi-nor";
m25p,fast-read;
reg = <0x0>;
spi-tx-bus-width = <1>;
diff --git a/arch/arm/mach-versal/cpu.c b/arch/arm/mach-versal/cpu.c
index a35aac2..9dc308b 100644
--- a/arch/arm/mach-versal/cpu.c
+++ b/arch/arm/mach-versal/cpu.c
@@ -13,6 +13,7 @@
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
#include <asm/cache.h>
+#include <dm/platdata.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -120,3 +121,7 @@ int arm_reserve_mmu(void)
return 0;
}
#endif
+
+U_BOOT_DRVINFO(soc_xilinx_versal) = {
+ .name = "soc_xilinx_versal",
+};
diff --git a/arch/arm/mach-versal/include/mach/hardware.h b/arch/arm/mach-versal/include/mach/hardware.h
index 9af5afd..7b728ac 100644
--- a/arch/arm/mach-versal/include/mach/hardware.h
+++ b/arch/arm/mach-versal/include/mach/hardware.h
@@ -65,6 +65,10 @@ struct crp_regs {
#define crp_base ((struct crp_regs *)VERSAL_CRP_BASEADDR)
+#define VERSAL_PS_PMC_VERSION 0xF11A0004
+#define VERSAL_PS_VER_MASK GENMASK(7, 0)
+#define VERSAL_PS_VER_SHIFT 12
+
/* Bootmode setting values */
#define BOOT_MODES_MASK 0x0000000F
#define QSPI_MODE_24BIT 0x00000001
diff --git a/arch/arm/mach-zynqmp/cpu.c b/arch/arm/mach-zynqmp/cpu.c
index 29743ca..26e285c 100644
--- a/arch/arm/mach-zynqmp/cpu.c
+++ b/arch/arm/mach-zynqmp/cpu.c
@@ -15,6 +15,7 @@
#include <asm/io.h>
#include <zynqmp_firmware.h>
#include <asm/cache.h>
+#include <dm/platdata.h>
#define ZYNQ_SILICON_VER_MASK 0xF000
#define ZYNQ_SILICON_VER_SHIFT 12
@@ -218,3 +219,7 @@ int zynqmp_mmio_read(const u32 address, u32 *value)
return ret;
}
+
+U_BOOT_DRVINFO(soc_xilinx_zynqmp) = {
+ .name = "soc_xilinx_zynqmp",
+};
diff --git a/arch/arm/mach-zynqmp/include/mach/hardware.h b/arch/arm/mach-zynqmp/include/mach/hardware.h
index 3776499..eebf3855 100644
--- a/arch/arm/mach-zynqmp/include/mach/hardware.h
+++ b/arch/arm/mach-zynqmp/include/mach/hardware.h
@@ -69,6 +69,9 @@ struct iou_scntr_secure {
#define iou_scntr_secure ((struct iou_scntr_secure *)ZYNQMP_IOU_SCNTR_SECURE)
+#define ZYNQMP_PS_VERSION 0xFFCA0044
+#define ZYNQMP_PS_VER_MASK GENMASK(1, 0)
+
/* Bootmode setting values */
#define BOOT_MODES_MASK 0x0000000F
#define QSPI_MODE_24BIT 0x00000001
diff --git a/arch/arm/mach-zynqmp/mkimage_fit_atf.sh b/arch/arm/mach-zynqmp/mkimage_fit_atf.sh
index 592be7f..72a8a3e 100755
--- a/arch/arm/mach-zynqmp/mkimage_fit_atf.sh
+++ b/arch/arm/mach-zynqmp/mkimage_fit_atf.sh
@@ -57,7 +57,7 @@ cat << __HEADER_EOF
/dts-v1/;
/ {
- description = "Configuration to load ATF before U-Boot";
+ description = "Configuration for Xilinx ZynqMP SoC";
images {
uboot {
@@ -78,7 +78,7 @@ __HEADER_EOF
if [ -f $BL31 ]; then
cat << __ATF
atf {
- description = "ARM Trusted Firmware";
+ description = "Trusted Firmware-A";
data = /incbin/("$BL31");
type = "firmware";
os = "arm-trusted-firmware";
@@ -111,6 +111,51 @@ cat << __TEE
__TEE
fi
+MULTI_DTB=`awk '/CONFIG_MULTI_DTB_FIT / { print $3 }' include/generated/autoconf.h`
+
+if [ 1"$MULTI_DTB" -eq 11 ]; then
+ cat << __FDT_IMAGE_EOF
+ fdt_1 {
+ description = "Multi DTB fit image";
+ data = /incbin/("fit-dtb.blob");
+ type = "flat_dt";
+ arch = "arm64";
+ compression = "none";
+ $DTB_LOAD
+ hash {
+ algo = "md5";
+ };
+ };
+ };
+ configurations {
+ default = "config_1";
+__FDT_IMAGE_EOF
+
+if [ ! -f $BL31 ]; then
+cat << __CONF_SECTION1_EOF
+ config_1 {
+ description = "Multi DTB without TF-A";
+ firmware = "uboot";
+ loadables = "fdt_1";
+ };
+__CONF_SECTION1_EOF
+else
+cat << __CONF_SECTION1_EOF
+ config_1 {
+ description = "Multi DTB with TF-A";
+ firmware = "atf";
+ loadables = "uboot", "fdt_1";
+ };
+__CONF_SECTION1_EOF
+fi
+
+cat << __ITS_EOF
+ };
+};
+__ITS_EOF
+
+else
+
DEFAULT=1
cnt=1
for dtname in $DT
@@ -181,3 +226,5 @@ cat << __ITS_EOF
};
};
__ITS_EOF
+
+fi
diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index 92b61d8..9006bd3 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -18,6 +18,8 @@
#include <i2c_eeprom.h>
#include <net.h>
#include <generated/dt.h>
+#include <soc.h>
+#include <linux/ctype.h>
#include "fru.h"
@@ -67,7 +69,7 @@ struct xilinx_board_description {
};
static int highest_id = -1;
-static struct xilinx_board_description **board_info;
+static struct xilinx_board_description *board_info;
#define XILINX_I2C_DETECTION_BITS sizeof(struct fru_common_hdr)
@@ -167,7 +169,7 @@ static bool xilinx_detect_legacy(u8 *buffer)
static int xilinx_read_eeprom_fru(struct udevice *dev, char *name,
struct xilinx_board_description *desc)
{
- int ret, eeprom_size;
+ int i, ret, eeprom_size;
u8 *fru_content;
/* FIXME this is shortcut - if eeprom type is wrong it will fail */
@@ -184,21 +186,23 @@ static int xilinx_read_eeprom_fru(struct udevice *dev, char *name,
eeprom_size);
if (ret) {
debug("%s: I2C EEPROM read failed\n", __func__);
- free(fru_content);
- return ret;
+ goto end;
}
- printf("Xilinx I2C FRU format at %s:\n", name);
fru_capture((unsigned long)fru_content);
- ret = fru_display(0);
- if (ret) {
- printf("FRU format decoding failed.\n");
- return ret;
+ if (gd->flags & GD_FLG_RELOC || (_DEBUG && CONFIG_IS_ENABLED(DTB_RESELECT))) {
+ printf("Xilinx I2C FRU format at %s:\n", name);
+ ret = fru_display(0);
+ if (ret) {
+ printf("FRU format decoding failed.\n");
+ goto end;
+ }
}
if (desc->header == EEPROM_HEADER_MAGIC) {
debug("Information already filled\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto end;
}
/* It is clear that FRU was captured and structures were filled */
@@ -206,13 +210,19 @@ static int xilinx_read_eeprom_fru(struct udevice *dev, char *name,
sizeof(desc->manufacturer));
strncpy(desc->name, (char *)fru_data.brd.product_name,
sizeof(desc->name));
+ for (i = 0; i < sizeof(desc->name); i++) {
+ if (desc->name[i] == ' ')
+ desc->name[i] = '\0';
+ }
strncpy(desc->revision, (char *)fru_data.brd.rev,
sizeof(desc->revision));
strncpy(desc->serial, (char *)fru_data.brd.serial_number,
sizeof(desc->serial));
desc->header = EEPROM_HEADER_MAGIC;
- return 0;
+end:
+ free(fru_content);
+ return ret;
}
static bool xilinx_detect_fru(u8 *buffer)
@@ -275,7 +285,7 @@ static int xilinx_read_eeprom_single(char *name,
__maybe_unused int xilinx_read_eeprom(void)
{
- int id, ret;
+ int id;
char name_buf[8]; /* 8 bytes should be enough for nvmem+number */
struct xilinx_board_description *desc;
@@ -284,7 +294,7 @@ __maybe_unused int xilinx_read_eeprom(void)
if (highest_id < 0)
return -EINVAL;
- board_info = calloc(1, sizeof(desc) * highest_id);
+ board_info = calloc(1, sizeof(*desc) * (highest_id + 1));
if (!board_info)
return -ENOMEM;
@@ -295,21 +305,10 @@ __maybe_unused int xilinx_read_eeprom(void)
snprintf(name_buf, sizeof(name_buf), "nvmem%d", id);
/* Alloc structure */
- desc = board_info[id];
- if (!desc) {
- desc = calloc(1, sizeof(*desc));
- if (!desc)
- return -ENOMEM;
-
- board_info[id] = desc;
- }
+ desc = &board_info[id];
/* Ignoring return value for supporting multiple chips */
- ret = xilinx_read_eeprom_single(name_buf, desc);
- if (ret) {
- free(desc);
- board_info[id] = NULL;
- }
+ xilinx_read_eeprom_single(name_buf, desc);
}
/*
@@ -395,7 +394,7 @@ int board_late_init_xilinx(void)
ret |= env_set_addr("bootm_size", (void *)bootm_size);
for (id = 0; id <= highest_id; id++) {
- desc = board_info[id];
+ desc = &board_info[id];
if (desc && desc->header == EEPROM_HEADER_MAGIC) {
if (desc->manufacturer[0])
ret |= env_set_by_index("manufacturer", id,
@@ -431,12 +430,139 @@ int board_late_init_xilinx(void)
}
#endif
+static char *board_name = DEVICE_TREE;
+
int __maybe_unused board_fit_config_name_match(const char *name)
{
- debug("%s: Check %s, default %s\n", __func__, name, DEVICE_TREE);
+ debug("%s: Check %s, default %s\n", __func__, name, board_name);
- if (!strcmp(name, DEVICE_TREE))
+ if (!strcmp(name, board_name))
return 0;
return -1;
}
+
+#if defined(CONFIG_DISPLAY_CPUINFO) && !defined(CONFIG_ARCH_ZYNQ)
+int print_cpuinfo(void)
+{
+ struct udevice *soc;
+ char name[SOC_MAX_STR_SIZE];
+ int ret;
+
+ ret = soc_get(&soc);
+ if (ret) {
+ printf("CPU: UNKNOWN\n");
+ return 0;
+ }
+
+ ret = soc_get_family(soc, name, SOC_MAX_STR_SIZE);
+ if (ret)
+ printf("CPU: %s\n", name);
+
+ ret = soc_get_revision(soc, name, SOC_MAX_STR_SIZE);
+ if (ret)
+ printf("Silicon: %s\n", name);
+
+ return 0;
+}
+#endif
+
+#if CONFIG_IS_ENABLED(DTB_RESELECT)
+#define MAX_NAME_LENGTH 50
+
+char * __maybe_unused __weak board_name_decode(void)
+{
+ char *board_local_name;
+ struct xilinx_board_description *desc;
+ int i, id;
+
+ board_local_name = calloc(1, MAX_NAME_LENGTH);
+ if (!board_info)
+ return NULL;
+
+ for (id = 0; id <= highest_id; id++) {
+ desc = &board_info[id];
+
+ /* No board description */
+ if (!desc)
+ goto error;
+
+ /* Board is not detected */
+ if (desc->header != EEPROM_HEADER_MAGIC)
+ continue;
+
+ /* The first string should be soc name */
+ if (!id)
+ strcat(board_local_name, CONFIG_SYS_BOARD);
+
+ /*
+ * For two purpose here:
+ * soc_name- eg: zynqmp-
+ * and between base board and CC eg: ..revA-sck...
+ */
+ strcat(board_local_name, "-");
+
+ if (desc->name[0]) {
+ /* For DT composition name needs to be lowercase */
+ for (i = 0; i < sizeof(desc->name); i++)
+ desc->name[i] = tolower(desc->name[i]);
+
+ strcat(board_local_name, desc->name);
+ }
+ if (desc->revision[0]) {
+ strcat(board_local_name, "-rev");
+
+ /* And revision needs to be uppercase */
+ for (i = 0; i < sizeof(desc->revision); i++)
+ desc->revision[i] = toupper(desc->revision[i]);
+
+ strcat(board_local_name, desc->revision);
+ }
+ }
+
+ /*
+ * Longer strings will end up with buffer overflow and potential
+ * attacks that's why check it
+ */
+ if (strlen(board_local_name) >= MAX_NAME_LENGTH)
+ panic("Board name can't be determined\n");
+
+ if (strlen(board_local_name))
+ return board_local_name;
+
+error:
+ free(board_local_name);
+ return NULL;
+}
+
+bool __maybe_unused __weak board_detection(void)
+{
+ if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM)) {
+ int ret;
+
+ ret = xilinx_read_eeprom();
+ return !ret ? true : false;
+ }
+
+ return false;
+}
+
+int embedded_dtb_select(void)
+{
+ if (board_detection()) {
+ char *board_local_name;
+
+ board_local_name = board_name_decode();
+ if (board_local_name) {
+ board_name = board_local_name;
+ printf("Detected name: %s\n", board_name);
+
+ /* Time to change DTB on fly */
+ /* Both ways should work here */
+ /* fdtdec_resetup(&rescan); */
+ fdtdec_setup();
+ }
+ }
+ return 0;
+}
+#endif
diff --git a/board/xilinx/zynqmp/Makefile b/board/xilinx/zynqmp/Makefile
index 7d8277c..a914028 100644
--- a/board/xilinx/zynqmp/Makefile
+++ b/board/xilinx/zynqmp/Makefile
@@ -44,8 +44,6 @@ $(obj)/pm_cfg_obj.o: $(shell cd $(srctree); readlink -f $(CONFIG_ZYNQMP_SPL_PM_C
endif
endif
-obj-$(CONFIG_MMC_SDHCI_ZYNQ) += tap_delays.o
-
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_CMD_ZYNQMP) += cmds.o
endif
diff --git a/board/xilinx/zynqmp/tap_delays.c b/board/xilinx/zynqmp/tap_delays.c
deleted file mode 100644
index d16bbb8..0000000
--- a/board/xilinx/zynqmp/tap_delays.c
+++ /dev/null
@@ -1,101 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Xilinx ZynqMP SoC Tap Delay Programming
- *
- * Copyright (C) 2018 Xilinx, Inc.
- */
-
-#include <common.h>
-#include <zynqmp_tap_delay.h>
-#include <asm/arch/sys_proto.h>
-#include <linux/delay.h>
-#include <mmc.h>
-
-#define SD_DLL_CTRL 0xFF180358
-#define SD_ITAP_DLY 0xFF180314
-#define SD_OTAP_DLY 0xFF180318
-#define SD0_DLL_RST_MASK 0x00000004
-#define SD0_DLL_RST 0x00000004
-#define SD1_DLL_RST_MASK 0x00040000
-#define SD1_DLL_RST 0x00040000
-#define SD0_ITAPCHGWIN_MASK 0x00000200
-#define SD0_ITAPCHGWIN 0x00000200
-#define SD1_ITAPCHGWIN_MASK 0x02000000
-#define SD1_ITAPCHGWIN 0x02000000
-#define SD0_ITAPDLYENA_MASK 0x00000100
-#define SD0_ITAPDLYENA 0x00000100
-#define SD1_ITAPDLYENA_MASK 0x01000000
-#define SD1_ITAPDLYENA 0x01000000
-#define SD0_ITAPDLYSEL_MASK 0x000000FF
-#define SD1_ITAPDLYSEL_MASK 0x00FF0000
-#define SD0_OTAPDLYSEL_MASK 0x0000003F
-#define SD1_OTAPDLYSEL_MASK 0x003F0000
-
-void zynqmp_dll_reset(u8 deviceid)
-{
- /* Issue DLL Reset */
- if (deviceid == 0)
- zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK,
- SD0_DLL_RST);
- else
- zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK,
- SD1_DLL_RST);
-
- mdelay(1);
-
- /* Release DLL Reset */
- if (deviceid == 0)
- zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
- else
- zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
-}
-
-void arasan_zynqmp_set_in_tapdelay(u8 deviceid, u32 itap_delay)
-{
- if (deviceid == 0) {
- zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, SD0_DLL_RST);
-
- /* Program ITAP delay */
- zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK,
- SD0_ITAPCHGWIN);
- zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK,
- SD0_ITAPDLYENA);
- zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK, itap_delay);
- zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, 0x0);
-
- zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
- } else {
- zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, SD1_DLL_RST);
-
- /* Program ITAP delay */
- zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK,
- SD1_ITAPCHGWIN);
- zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK,
- SD1_ITAPDLYENA);
- zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
- (itap_delay << 16));
- zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, 0x0);
-
- zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
- }
-}
-
-void arasan_zynqmp_set_out_tapdelay(u8 deviceid, u32 otap_delay)
-{
- if (deviceid == 0) {
- zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, SD0_DLL_RST);
-
- /* Program OTAP delay */
- zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK, otap_delay);
-
- zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
- } else {
- zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, SD1_DLL_RST);
-
- /* Program OTAP delay */
- zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
- (otap_delay << 16));
-
- zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
- }
-}
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index 38c910f..ea15e62 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -8,6 +8,7 @@
#include <command.h>
#include <cpu_func.h>
#include <debug_uart.h>
+#include <dfu.h>
#include <env.h>
#include <env_internal.h>
#include <init.h>
@@ -19,6 +20,7 @@
#include <ahci.h>
#include <scsi.h>
#include <malloc.h>
+#include <memalign.h>
#include <wdt.h>
#include <asm/arch/clk.h>
#include <asm/arch/hardware.h>
@@ -346,13 +348,14 @@ int board_early_init_f(void)
static int multi_boot(void)
{
- u32 multiboot;
-
- multiboot = readl(&csu_base->multi_boot);
+ u32 multiboot = 0;
+ int ret;
- printf("Multiboot:\t%d\n", multiboot);
+ ret = zynqmp_mmio_read((ulong)&csu_base->multi_boot, &multiboot);
+ if (ret)
+ return -EINVAL;
- return 0;
+ return multiboot;
}
#define PS_SYSMON_ANALOG_BUS_VAL 0x3210
@@ -392,7 +395,7 @@ int board_init(void)
#endif
if (current_el() == 3)
- multi_boot();
+ printf("Multiboot:\t%d\n", multi_boot());
return 0;
}
@@ -467,6 +470,9 @@ ulong board_get_usable_ram_top(ulong total_size)
phys_addr_t reg;
struct lmb lmb;
+ if (!IS_ALIGNED((ulong)gd->fdt_blob, 0x8))
+ panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob);
+
/* found enough not-reserved memory to relocated U-Boot */
lmb_init(&lmb);
lmb_add(&lmb, gd->ram_base, gd->ram_size);
@@ -515,6 +521,9 @@ static u8 __maybe_unused zynqmp_get_bootmode(void)
if (ret)
return -EINVAL;
+ debug("HW boot mode: %x\n", reg & BOOT_MODES_MASK);
+ debug("ALT boot mode: %x\n", reg >> BOOT_MODE_ALT_SHIFT);
+
if (reg >> BOOT_MODE_ALT_SHIFT)
reg >>= BOOT_MODE_ALT_SHIFT;
@@ -735,6 +744,7 @@ int board_late_init(void)
env_targets ? env_targets : "");
env_set("boot_targets", new_targets);
+ free(new_targets);
reset_reason();
@@ -816,3 +826,55 @@ enum env_location env_get_location(enum env_operation op, int prio)
return ENVL_NOWHERE;
}
}
+
+#if defined(CONFIG_SET_DFU_ALT_INFO)
+
+#define DFU_ALT_BUF_LEN SZ_1K
+
+void set_dfu_alt_info(char *interface, char *devstr)
+{
+ u8 multiboot;
+ int bootseq = 0;
+
+ ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
+
+ if (env_get("dfu_alt_info"))
+ return;
+
+ memset(buf, 0, sizeof(buf));
+
+ multiboot = multi_boot();
+ debug("Multiboot: %d\n", multiboot);
+
+ switch (zynqmp_get_bootmode()) {
+ case EMMC_MODE:
+ case SD_MODE:
+ case SD1_LSHFT_MODE:
+ case SD_MODE1:
+ bootseq = mmc_get_env_dev();
+ if (!multiboot)
+ snprintf(buf, DFU_ALT_BUF_LEN,
+ "mmc %d:1=boot.bin fat %d 1;"
+ "u-boot.itb fat %d 1",
+ bootseq, bootseq, bootseq);
+ else
+ snprintf(buf, DFU_ALT_BUF_LEN,
+ "mmc %d:1=boot%04d.bin fat %d 1;"
+ "u-boot.itb fat %d 1",
+ bootseq, multiboot, bootseq, bootseq);
+ break;
+ case QSPI_MODE_24BIT:
+ case QSPI_MODE_32BIT:
+ snprintf(buf, DFU_ALT_BUF_LEN,
+ "sf 0:0=boot.bin raw %x 0x1500000;"
+ "u-boot.itb raw 0x%x 0x500000",
+ multiboot * SZ_32K, CONFIG_SYS_SPI_U_BOOT_OFFS);
+ break;
+ default:
+ return;
+ }
+
+ env_set("dfu_alt_info", buf);
+ puts("DFU alt info setting: done\n");
+}
+#endif
diff --git a/cmd/boot.c b/cmd/boot.c
index fab294e..be67a59 100644
--- a/cmd/boot.c
+++ b/cmd/boot.c
@@ -58,7 +58,8 @@ U_BOOT_CMD(
U_BOOT_CMD(
reset, 2, 0, do_reset,
"Perform RESET of the CPU",
- ""
+ "- cold boot without level specifier\n"
+ "reset -w - warm reset if implemented"
);
#ifdef CONFIG_CMD_POWEROFF
diff --git a/cmd/date.c b/cmd/date.c
index e377cfe..149ca42 100644
--- a/cmd/date.c
+++ b/cmd/date.c
@@ -41,10 +41,13 @@ static int do_date(struct cmd_tbl *cmdtp, int flag, int argc,
#ifdef CONFIG_DM_RTC
struct udevice *dev;
- rcode = uclass_get_device(UCLASS_RTC, 0, &dev);
+ rcode = uclass_get_device_by_seq(UCLASS_RTC, 0, &dev);
if (rcode) {
- printf("Cannot find RTC: err=%d\n", rcode);
- return CMD_RET_FAILURE;
+ rcode = uclass_get_device(UCLASS_RTC, 0, &dev);
+ if (rcode) {
+ printf("Cannot find RTC: err=%d\n", rcode);
+ return CMD_RET_FAILURE;
+ }
}
#elif defined(CONFIG_SYS_I2C_LEGACY)
old_bus = i2c_get_bus_num();
diff --git a/cmd/pwm.c b/cmd/pwm.c
index 87d840a..7947e61 100644
--- a/cmd/pwm.c
+++ b/cmd/pwm.c
@@ -108,7 +108,8 @@ static int do_pwm(struct cmd_tbl *cmdtp, int flag, int argc,
U_BOOT_CMD(pwm, 6, 0, do_pwm,
"control pwm channels",
- "pwm <invert> <pwm_dev_num> <channel> <polarity>\n"
- "pwm <config> <pwm_dev_num> <channel> <period_ns> <duty_ns>\n"
- "pwm <enable/disable> <pwm_dev_num> <channel>\n"
+ "invert <pwm_dev_num> <channel> <polarity> - invert polarity\n"
+ "pwm config <pwm_dev_num> <channel> <period_ns> <duty_ns> - config PWM\n"
+ "pwm enable <pwm_dev_num> <channel> - enable PWM output\n"
+ "pwm disable <pwm_dev_num> <channel> - eisable PWM output\n"
"Note: All input values are in decimal");
diff --git a/common/fdt_support.c b/common/fdt_support.c
index 4341d84..8992ac5 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -420,6 +420,24 @@ static int fdt_pack_reg(const void *fdt, void *buf, u64 *address, u64 *size,
#else
#define MEMORY_BANKS_MAX 4
#endif
+
+/**
+ * fdt_fixup_memory_banks - Update DT memory node
+ * @blob: Pointer to DT blob
+ * @start: Pointer to memory start addresses array
+ * @size: Pointer to memory sizes array
+ * @banks: Number of memory banks
+ *
+ * Return: 0 on success, negative value on failure
+ *
+ * Based on the passed number of banks and arrays, the function is able to
+ * update existing DT memory nodes to match run time detected/changed memory
+ * configuration. Implementation is handling one specific case with only one
+ * memory node where multiple tuples could be added/updated.
+ * The case where multiple memory nodes with a single tuple (base, size) are
+ * used, this function is only updating the first memory node without removing
+ * others.
+ */
int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks)
{
int err, nodeoffset;
diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig
index e679051..590a217 100644
--- a/configs/xilinx_versal_virt_defconfig
+++ b/configs/xilinx_versal_virt_defconfig
@@ -13,9 +13,9 @@ CONFIG_COUNTER_FREQUENCY=100000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
CONFIG_BOOTDELAY=5
CONFIG_USE_PREBOOT=y
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SYS_PROMPT="Versal> "
CONFIG_CMD_BOOTMENU=y
@@ -95,6 +95,7 @@ CONFIG_ZYNQ_GEM=y
CONFIG_ARM_DCC=y
CONFIG_PL01X_SERIAL=y
CONFIG_XILINX_UARTLITE=y
+CONFIG_SOC_XILINX_VERSAL=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_ZYNQ_SPI=y
diff --git a/configs/xilinx_zynq_virt_defconfig b/configs/xilinx_zynq_virt_defconfig
index ae67a50..66af37a 100644
--- a/configs/xilinx_zynq_virt_defconfig
+++ b/configs/xilinx_zynq_virt_defconfig
@@ -22,6 +22,7 @@ CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000
# CONFIG_USE_SPL_FIT_GENERATOR is not set
CONFIG_LEGACY_IMAGE_FORMAT=y
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
CONFIG_USE_PREBOOT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_FPGA=y
diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig
index e6af7c8..44fc6a7 100644
--- a/configs/xilinx_zynqmp_virt_defconfig
+++ b/configs/xilinx_zynqmp_virt_defconfig
@@ -5,8 +5,12 @@ CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SYS_MEMTEST_START=0x00000000
CONFIG_SYS_MEMTEST_END=0x00001000
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x100000
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu100-revC"
+CONFIG_SPL_STACK_R_ADDR=0x18000000
+CONFIG_SPL_SIZE_LIMIT=0x2a000
+CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK=0x0
CONFIG_SPL=y
CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI_SUPPORT=y
@@ -20,10 +24,12 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
CONFIG_USE_PREBOOT=y
-# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_PREBOOT="run scsi_init;usb start"
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_BOARD_EARLY_INIT_R=y
+CONFIG_SPL_STACK_R=y
CONFIG_SPL_FPGA=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
@@ -36,6 +42,7 @@ CONFIG_CMD_THOR_DOWNLOAD=y
CONFIG_CMD_NVEDIT_EFI=y
CONFIG_CMD_MEMTEST=y
CONFIG_SYS_ALT_MEMTEST=y
+CONFIG_CMD_SHA1SUM=y
CONFIG_CMD_BIND=y
CONFIG_CMD_CLK=y
CONFIG_CMD_DFU=y
@@ -59,6 +66,7 @@ CONFIG_CMD_TFTPPUT=y
CONFIG_CMD_BMP=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_EFIDEBUG=y
+CONFIG_CMD_RTC=y
CONFIG_CMD_TIME=y
CONFIG_CMD_GETTIME=y
CONFIG_CMD_TIMER=y
@@ -85,6 +93,8 @@ CONFIG_NETCONSOLE=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_SCSI_AHCI=y
CONFIG_SATA_CEVA=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
CONFIG_CLK_ZYNQMP=y
CONFIG_DFU_TFTP=y
CONFIG_DFU_TIMEOUT=y
@@ -93,6 +103,7 @@ CONFIG_DFU_NAND=y
CONFIG_DFU_RAM=y
CONFIG_DFU_SF=y
CONFIG_DFU_MTD=y
+CONFIG_SET_DFU_ALT_INFO=y
CONFIG_SYS_DFU_DATA_BUF_SIZE=0x1800000
CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_FLASH=y
@@ -149,11 +160,13 @@ CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_RTC=y
CONFIG_RTC_EMULATION=y
+CONFIG_RTC_ZYNQMP=y
CONFIG_SCSI=y
CONFIG_DM_SCSI=y
CONFIG_ARM_DCC=y
CONFIG_XILINX_UARTLITE=y
CONFIG_ZYNQ_SERIAL=y
+CONFIG_SOC_XILINX_ZYNQMP=y
CONFIG_SPI=y
CONFIG_ZYNQ_SPI=y
CONFIG_ZYNQMP_GQSPI=y
@@ -187,7 +200,6 @@ CONFIG_BMP_16BPP=y
CONFIG_BMP_24BPP=y
CONFIG_BMP_32BPP=y
CONFIG_WDT=y
-CONFIG_WDT_CDNS=y
CONFIG_PANIC_HANG=y
CONFIG_TPM=y
CONFIG_SPL_GZIP=y
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index eea4701..2f78da6 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -366,6 +366,7 @@ int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
{
struct sdhci_host *host = mmc->priv;
unsigned int div, clk = 0, timeout;
+ int ret;
/* Wait max 20 ms */
timeout = 200;
@@ -386,8 +387,13 @@ int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
if (clock == 0)
return 0;
- if (host->ops && host->ops->set_delay)
- host->ops->set_delay(host);
+ if (host->ops && host->ops->set_delay) {
+ ret = host->ops->set_delay(host);
+ if (ret) {
+ printf("%s: Error while setting tap delay\n", __func__);
+ return ret;
+ }
+ }
if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
/*
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index ba87ee8..c94825d 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -15,9 +15,10 @@
#include <dm/device_compat.h>
#include <linux/err.h>
#include <linux/libfdt.h>
+#include <asm/cache.h>
#include <malloc.h>
#include <sdhci.h>
-#include <zynqmp_tap_delay.h>
+#include <zynqmp_firmware.h>
#define SDHCI_ARASAN_ITAPDLY_REGISTER 0xF0F8
#define SDHCI_ARASAN_ITAPDLY_SEL_MASK GENMASK(7, 0)
@@ -30,6 +31,20 @@
#define SDHCI_TUNING_LOOP_COUNT 40
#define MMC_BANK2 0x2
+#define SD_DLL_CTRL 0xFF180358
+#define SD_ITAP_DLY 0xFF180314
+#define SD_OTAP_DLY 0xFF180318
+#define SD0_DLL_RST BIT(2)
+#define SD1_DLL_RST BIT(18)
+#define SD0_ITAPCHGWIN BIT(9)
+#define SD1_ITAPCHGWIN BIT(25)
+#define SD0_ITAPDLYENA BIT(8)
+#define SD1_ITAPDLYENA BIT(24)
+#define SD0_ITAPDLYSEL_MASK GENMASK(7, 0)
+#define SD1_ITAPDLYSEL_MASK GENMASK(23, 16)
+#define SD0_OTAPDLYSEL_MASK GENMASK(5, 0)
+#define SD1_OTAPDLYSEL_MASK GENMASK(21, 16)
+
struct arasan_sdhci_clk_data {
int clk_phase_in[MMC_TIMING_MMC_HS400 + 1];
int clk_phase_out[MMC_TIMING_MMC_HS400 + 1];
@@ -48,6 +63,12 @@ struct arasan_sdhci_priv {
u8 no_1p8;
};
+/* For Versal platforms zynqmp_mmio_write() won't be available */
+__weak int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value)
+{
+ return 0;
+}
+
#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL)
/* Default settings for ZynqMP Clock Phases */
static const u32 zynqmp_iclk_phases[] = {0, 63, 63, 0, 63, 0,
@@ -75,26 +96,126 @@ static const u8 mode2timing[] = {
[MMC_HS_200] = MMC_TIMING_MMC_HS200,
};
-static void arasan_zynqmp_dll_reset(struct sdhci_host *host, u8 deviceid)
+static inline int arasan_zynqmp_set_in_tapdelay(u8 node_id, u32 itap_delay)
{
- u16 clk;
+ int ret;
+
+ if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
+ if (node_id == NODE_SD_0) {
+ ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN,
+ SD0_ITAPCHGWIN);
+ if (ret)
+ return ret;
+
+ ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA,
+ SD0_ITAPDLYENA);
+ if (ret)
+ return ret;
+
+ ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK,
+ itap_delay);
+ if (ret)
+ return ret;
+
+ ret = zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN, 0);
+ if (ret)
+ return ret;
+ }
+ ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN,
+ SD1_ITAPCHGWIN);
+ if (ret)
+ return ret;
+
+ ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA,
+ SD1_ITAPDLYENA);
+ if (ret)
+ return ret;
+
+ ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
+ (itap_delay << 16));
+ if (ret)
+ return ret;
+
+ ret = zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN, 0);
+ if (ret)
+ return ret;
+ } else {
+ return xilinx_pm_request(PM_IOCTL, (u32)node_id,
+ IOCTL_SET_SD_TAPDELAY,
+ PM_TAPDELAY_INPUT, itap_delay, NULL);
+ }
+
+ return 0;
+}
+
+static inline int arasan_zynqmp_set_out_tapdelay(u8 node_id, u32 otap_delay)
+{
+ if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
+ if (node_id == NODE_SD_0)
+ return zynqmp_mmio_write(SD_OTAP_DLY,
+ SD0_OTAPDLYSEL_MASK,
+ otap_delay);
+
+ return zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
+ (otap_delay << 16));
+ } else {
+ return xilinx_pm_request(PM_IOCTL, (u32)node_id,
+ IOCTL_SET_SD_TAPDELAY,
+ PM_TAPDELAY_OUTPUT, otap_delay, NULL);
+ }
+}
+
+static inline int zynqmp_dll_reset(u8 node_id, u32 type)
+{
+ if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
+ if (node_id == NODE_SD_0)
+ return zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST,
+ type == PM_DLL_RESET_ASSERT ?
+ SD0_DLL_RST : 0);
+
+ return zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST,
+ type == PM_DLL_RESET_ASSERT ?
+ SD1_DLL_RST : 0);
+ } else {
+ return xilinx_pm_request(PM_IOCTL, (u32)node_id,
+ IOCTL_SD_DLL_RESET, type, 0, NULL);
+ }
+}
+
+static int arasan_zynqmp_dll_reset(struct sdhci_host *host, u8 node_id)
+{
+ struct mmc *mmc = (struct mmc *)host->mmc;
+ struct udevice *dev = mmc->dev;
unsigned long timeout;
+ int ret;
+ u16 clk;
clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
clk &= ~(SDHCI_CLOCK_CARD_EN);
sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
/* Issue DLL Reset */
- zynqmp_dll_reset(deviceid);
+ ret = zynqmp_dll_reset(node_id, PM_DLL_RESET_ASSERT);
+ if (ret) {
+ dev_err(dev, "dll_reset assert failed with err: %d\n", ret);
+ return ret;
+ }
+
+ /* Allow atleast 1ms delay for proper DLL reset */
+ mdelay(1);
+ ret = zynqmp_dll_reset(node_id, PM_DLL_RESET_RELEASE);
+ if (ret) {
+ dev_err(dev, "dll_reset release failed with err: %d\n", ret);
+ return ret;
+ }
/* Wait max 20 ms */
timeout = 100;
while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
& SDHCI_CLOCK_INT_STABLE)) {
if (timeout == 0) {
- dev_err(mmc_dev(host->mmc),
- ": Internal clock never stabilised.\n");
- return;
+ dev_err(dev, ": Internal clock never stabilised.\n");
+ return -EBUSY;
}
timeout--;
udelay(1000);
@@ -102,6 +223,8 @@ static void arasan_zynqmp_dll_reset(struct sdhci_host *host, u8 deviceid)
clk |= SDHCI_CLOCK_CARD_EN;
sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+ return 0;
}
static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
@@ -112,12 +235,11 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
struct sdhci_host *host;
struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
char tuning_loop_counter = SDHCI_TUNING_LOOP_COUNT;
- u8 deviceid;
+ u8 node_id = priv->deviceid ? NODE_SD_1 : NODE_SD_0;
debug("%s\n", __func__);
host = priv->host;
- deviceid = priv->deviceid;
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
ctrl |= SDHCI_CTRL_EXEC_TUNING;
@@ -125,7 +247,7 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
mdelay(1);
- arasan_zynqmp_dll_reset(host, deviceid);
+ arasan_zynqmp_dll_reset(host, node_id);
sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
@@ -171,7 +293,7 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
}
udelay(1);
- arasan_zynqmp_dll_reset(host, deviceid);
+ arasan_zynqmp_dll_reset(host, node_id);
/* Enable only interrupts served by the SD controller */
sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK,
@@ -194,10 +316,13 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host,
int degrees)
{
- struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev);
struct mmc *mmc = (struct mmc *)host->mmc;
+ struct udevice *dev = mmc->dev;
+ struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
+ u8 node_id = priv->deviceid ? NODE_SD_1 : NODE_SD_0;
u8 tap_delay, tap_max = 0;
int timing = mode2timing[mmc->selected_mode];
+ int ret;
/*
* This is applicable for SDHCI_SPEC_300 and above
@@ -233,7 +358,19 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host,
/* Limit output tap_delay value to 6 bits */
tap_delay &= SDHCI_ARASAN_OTAPDLY_SEL_MASK;
- arasan_zynqmp_set_out_tapdelay(priv->deviceid, tap_delay);
+ /* Set the Clock Phase */
+ ret = arasan_zynqmp_set_out_tapdelay(node_id, tap_delay);
+ if (ret) {
+ dev_err(dev, "Error setting output Tap Delay\n");
+ return ret;
+ }
+
+ /* Release DLL Reset */
+ ret = zynqmp_dll_reset(node_id, PM_DLL_RESET_RELEASE);
+ if (ret) {
+ dev_err(dev, "dll_reset release failed with err: %d\n", ret);
+ return ret;
+ }
return 0;
}
@@ -250,10 +387,13 @@ static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host,
static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host,
int degrees)
{
- struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev);
struct mmc *mmc = (struct mmc *)host->mmc;
+ struct udevice *dev = mmc->dev;
+ struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
+ u8 node_id = priv->deviceid ? NODE_SD_1 : NODE_SD_0;
u8 tap_delay, tap_max = 0;
int timing = mode2timing[mmc->selected_mode];
+ int ret;
/*
* This is applicable for SDHCI_SPEC_300 and above
@@ -263,6 +403,13 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host,
if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300)
return 0;
+ /* Assert DLL Reset */
+ ret = zynqmp_dll_reset(node_id, PM_DLL_RESET_ASSERT);
+ if (ret) {
+ dev_err(dev, "dll_reset assert failed with err: %d\n", ret);
+ return ret;
+ }
+
switch (timing) {
case MMC_TIMING_MMC_HS:
case MMC_TIMING_SD_HS:
@@ -289,7 +436,11 @@ static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host,
/* Limit input tap_delay value to 8 bits */
tap_delay &= SDHCI_ARASAN_ITAPDLY_SEL_MASK;
- arasan_zynqmp_set_in_tapdelay(priv->deviceid, tap_delay);
+ ret = arasan_zynqmp_set_in_tapdelay(node_id, tap_delay);
+ if (ret) {
+ dev_err(dev, "Error setting Input Tap Delay\n");
+ return ret;
+ }
return 0;
}
@@ -422,7 +573,7 @@ static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host,
return 0;
}
-static void arasan_sdhci_set_tapdelay(struct sdhci_host *host)
+static int arasan_sdhci_set_tapdelay(struct sdhci_host *host)
{
struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev);
struct arasan_sdhci_clk_data *clk_data = &priv->clk_data;
@@ -431,18 +582,31 @@ static void arasan_sdhci_set_tapdelay(struct sdhci_host *host)
u8 timing = mode2timing[mmc->selected_mode];
u32 iclk_phase = clk_data->clk_phase_in[timing];
u32 oclk_phase = clk_data->clk_phase_out[timing];
+ int ret;
dev_dbg(dev, "%s, host:%s, mode:%d\n", __func__, host->name, timing);
if (IS_ENABLED(CONFIG_ARCH_ZYNQMP) &&
device_is_compatible(dev, "xlnx,zynqmp-8.9a")) {
- sdhci_zynqmp_sampleclk_set_phase(host, iclk_phase);
- sdhci_zynqmp_sdcardclk_set_phase(host, oclk_phase);
+ ret = sdhci_zynqmp_sampleclk_set_phase(host, iclk_phase);
+ if (ret)
+ return ret;
+
+ ret = sdhci_zynqmp_sdcardclk_set_phase(host, oclk_phase);
+ if (ret)
+ return ret;
} else if (IS_ENABLED(CONFIG_ARCH_VERSAL) &&
device_is_compatible(dev, "xlnx,versal-8.9a")) {
- sdhci_versal_sampleclk_set_phase(host, iclk_phase);
- sdhci_versal_sdcardclk_set_phase(host, oclk_phase);
+ ret = sdhci_versal_sampleclk_set_phase(host, iclk_phase);
+ if (ret)
+ return ret;
+
+ ret = sdhci_versal_sdcardclk_set_phase(host, oclk_phase);
+ if (ret)
+ return ret;
}
+
+ return 0;
}
static void arasan_dt_read_clk_phase(struct udevice *dev, unsigned char timing,
@@ -526,29 +690,10 @@ static void arasan_dt_parse_clk_phases(struct udevice *dev)
"clk-phase-mmc-hs400");
}
-static void arasan_sdhci_set_control_reg(struct sdhci_host *host)
-{
- struct mmc *mmc = (struct mmc *)host->mmc;
- u32 reg;
-
- if (!IS_SD(mmc))
- return;
-
- if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
- reg = sdhci_readw(host, SDHCI_HOST_CONTROL2);
- reg |= SDHCI_CTRL_VDD_180;
- sdhci_writew(host, reg, SDHCI_HOST_CONTROL2);
- }
-
- if (mmc->selected_mode > SD_HS &&
- mmc->selected_mode <= MMC_HS_200)
- sdhci_set_uhs_timing(host);
-}
-
static const struct sdhci_ops arasan_ops = {
.platform_execute_tuning = &arasan_sdhci_execute_tuning,
.set_delay = &arasan_sdhci_set_tapdelay,
- .set_control_reg = &arasan_sdhci_set_control_reg,
+ .set_control_reg = &sdhci_set_control_reg,
};
#endif
@@ -612,6 +757,25 @@ static int arasan_sdhci_probe(struct udevice *dev)
return ret;
upriv->mmc = host->mmc;
+ /*
+ * WORKAROUND: Versal platforms have an issue with card detect state.
+ * Due to this, host controller is switching off voltage to sd card
+ * causing sd card timeout error. Workaround this by adding a wait for
+ * 1000msec till the card detect state gets stable.
+ */
+ if (IS_ENABLED(CONFIG_ARCH_VERSAL)) {
+ u32 timeout = 1000;
+
+ while (((sdhci_readl(host, SDHCI_PRESENT_STATE) &
+ SDHCI_CARD_STATE_STABLE) == 0) && timeout--) {
+ mdelay(1);
+ }
+ if (!timeout) {
+ dev_err(dev, "Sdhci card detect state not stable\n");
+ return -ETIMEDOUT;
+ }
+ }
+
return sdhci_probe(dev);
}
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index a42b3f0..d73daf5 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -197,4 +197,13 @@ config RESET_SCMI
Enable this option if you want to support reset controller
devices exposed by a SCMI agent based on SCMI reset domain
protocol communication with a SCMI server.
+
+config RESET_ZYNQMP
+ bool "Reset Driver for Xilinx ZynqMP SoC's"
+ depends on DM_RESET && ZYNQMP_FIRMWARE
+ help
+ Support for reset controller on Xilinx ZynqMP SoC. Driver is only
+ passing request via Xilinx firmware interface to TF-A and PMU
+ firmware.
+
endmenu
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 8a0f528..d69486b 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_RESET_SIFIVE) += reset-sifive.o
obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o
obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
+obj-$(CONFIG_RESET_ZYNQMP) += reset-zynqmp.o
diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c
new file mode 100644
index 0000000..5765234
--- /dev/null
+++ b/drivers/reset/reset-zynqmp.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Xilinx, Inc. - Michal Simek
+ */
+
+#define LOG_CATEGORY UCLASS_RESET
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <reset-uclass.h>
+#include <zynqmp_firmware.h>
+
+#define ZYNQMP_NR_RESETS (ZYNQMP_PM_RESET_END - ZYNQMP_PM_RESET_START)
+#define ZYNQMP_RESET_ID ZYNQMP_PM_RESET_START
+
+struct zynqmp_reset_priv {
+ u32 reset_id;
+ u32 nr_reset;
+};
+
+static int zynqmp_pm_reset_assert(const u32 reset,
+ const enum zynqmp_pm_reset_action assert_flag)
+{
+ return xilinx_pm_request(PM_RESET_ASSERT, reset, assert_flag, 0, 0,
+ NULL);
+}
+
+static int zynqmp_reset_assert(struct reset_ctl *rst)
+{
+ struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev);
+
+ dev_dbg(rst->dev, "%s(rst=%p) (id=%lu)\n", __func__, rst, rst->id);
+
+ return zynqmp_pm_reset_assert(priv->reset_id + rst->id,
+ PM_RESET_ACTION_ASSERT);
+}
+
+static int zynqmp_reset_deassert(struct reset_ctl *rst)
+{
+ struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev);
+
+ dev_dbg(rst->dev, "%s(rst=%p) (id=%lu)\n", __func__, rst, rst->id);
+
+ return zynqmp_pm_reset_assert(priv->reset_id + rst->id,
+ PM_RESET_ACTION_RELEASE);
+}
+
+static int zynqmp_reset_request(struct reset_ctl *rst)
+{
+ struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev);
+
+ dev_dbg(rst->dev, "%s(rst=%p) (id=%lu) (nr_reset=%d)\n", __func__,
+ rst, rst->id, priv->nr_reset);
+
+ if (rst->id > priv->nr_reset)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int zynqmp_reset_free(struct reset_ctl *rst)
+{
+ struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev);
+
+ dev_dbg(rst->dev, "%s(rst=%p) (id=%lu) (nr_reset=%d)\n", __func__,
+ rst, rst->id, priv->nr_reset);
+
+ return 0;
+}
+
+static int zynqmp_reset_probe(struct udevice *dev)
+{
+ struct zynqmp_reset_priv *priv = dev_get_priv(dev);
+
+ priv->reset_id = ZYNQMP_RESET_ID;
+ priv->nr_reset = ZYNQMP_NR_RESETS;
+ return 0;
+}
+
+const struct reset_ops zynqmp_reset_ops = {
+ .request = zynqmp_reset_request,
+ .rfree = zynqmp_reset_free,
+ .rst_assert = zynqmp_reset_assert,
+ .rst_deassert = zynqmp_reset_deassert,
+};
+
+static const struct udevice_id zynqmp_reset_ids[] = {
+ { .compatible = "xlnx,zynqmp-reset" },
+ { }
+};
+
+U_BOOT_DRIVER(zynqmp_reset) = {
+ .name = "zynqmp_reset",
+ .id = UCLASS_RESET,
+ .of_match = zynqmp_reset_ids,
+ .ops = &zynqmp_reset_ops,
+ .probe = zynqmp_reset_probe,
+ .priv_auto = sizeof(struct zynqmp_reset_priv),
+};
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index cbdfddb..b6692e6 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -195,4 +195,11 @@ config RTC_DAVINCI
Say "yes" here to support the on chip real time clock
present on TI OMAP1, AM33xx, DA8xx/OMAP-L13x, AM43xx and DRA7xx.
+config RTC_ZYNQMP
+ bool "Enable ZynqMP RTC driver"
+ depends on ARCH_ZYNQMP
+ help
+ Say "yes" here to support the on chip real time clock
+ present on Xilinx ZynqMP SoC.
+
endmenu
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 331a49a..d621be6 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -57,3 +57,4 @@ obj-$(CONFIG_RTC_STM32) += stm32_rtc.o
obj-$(CONFIG_SANDBOX) += sandbox_rtc.o
obj-$(CONFIG_RTC_X1205) += x1205.o
obj-$(CONFIG_RTC_ABX80X) += abx80x.o
+obj-$(CONFIG_RTC_ZYNQMP) += zynqmp_rtc.o
diff --git a/drivers/rtc/rtc-uclass.c b/drivers/rtc/rtc-uclass.c
index be6a2dd..321b873 100644
--- a/drivers/rtc/rtc-uclass.c
+++ b/drivers/rtc/rtc-uclass.c
@@ -176,6 +176,7 @@ int rtc_write32(struct udevice *dev, unsigned int reg, u32 value)
UCLASS_DRIVER(rtc) = {
.name = "rtc",
.id = UCLASS_RTC,
+ .flags = DM_UC_FLAG_SEQ_ALIAS,
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
.post_bind = dm_scan_fdt_dev,
#endif
diff --git a/drivers/rtc/zynqmp_rtc.c b/drivers/rtc/zynqmp_rtc.c
new file mode 100644
index 0000000..ab9b93c
--- /dev/null
+++ b/drivers/rtc/zynqmp_rtc.c
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021, Xilinx, Inc.
+ */
+
+#define LOG_CATEGORY UCLASS_RTC
+
+#include <common.h>
+#include <dm.h>
+#include <rtc.h>
+#include <asm/io.h>
+
+/* RTC Registers */
+#define RTC_SET_TM_WR 0x00
+#define RTC_SET_TM_RD 0x04
+#define RTC_CALIB_WR 0x08
+#define RTC_CUR_TM 0x10
+#define RTC_INT_STS 0x20
+#define RTC_CTRL 0x40
+
+#define RTC_INT_SEC BIT(0)
+#define RTC_BATT_EN BIT(31)
+#define RTC_CALIB_DEF 0x198233
+#define RTC_CALIB_MASK 0x1FFFFF
+
+struct zynqmp_rtc_priv {
+ fdt_addr_t base;
+ unsigned int calibval;
+};
+
+static int zynqmp_rtc_get(struct udevice *dev, struct rtc_time *tm)
+{
+ struct zynqmp_rtc_priv *priv = dev_get_priv(dev);
+ u32 status;
+ unsigned long read_time;
+
+ status = readl(priv->base + RTC_INT_STS);
+
+ if (status & RTC_INT_SEC) {
+ /*
+ * RTC has updated the CURRENT_TIME with the time written into
+ * SET_TIME_WRITE register.
+ */
+ read_time = readl(priv->base + RTC_CUR_TM);
+ } else {
+ /*
+ * Time written in SET_TIME_WRITE has not yet updated into
+ * the seconds read register, so read the time from the
+ * SET_TIME_WRITE instead of CURRENT_TIME register.
+ * Since we add +1 sec while writing, we need to -1 sec while
+ * reading.
+ */
+ read_time = readl(priv->base + RTC_SET_TM_RD) - 1;
+ }
+
+ rtc_to_tm(read_time, tm);
+
+ return 0;
+}
+
+static int zynqmp_rtc_set(struct udevice *dev, const struct rtc_time *tm)
+{
+ struct zynqmp_rtc_priv *priv = dev_get_priv(dev);
+ unsigned long new_time = 0;
+
+ if (tm)
+ /*
+ * The value written will be updated after 1 sec into the
+ * seconds read register, so we need to program time +1 sec
+ * to get the correct time on read.
+ */
+ new_time = rtc_mktime(tm) + 1;
+
+ /*
+ * Writing into calibration register will clear the Tick Counter and
+ * force the next second to be signaled exactly in 1 second period
+ */
+ priv->calibval &= RTC_CALIB_MASK;
+ writel(priv->calibval, (priv->base + RTC_CALIB_WR));
+
+ writel(new_time, priv->base + RTC_SET_TM_WR);
+
+ /*
+ * Clear the rtc interrupt status register after setting the
+ * time. During a read_time function, the code should read the
+ * RTC_INT_STATUS register and if bit 0 is still 0, it means
+ * that one second has not elapsed yet since RTC was set and
+ * the current time should be read from SET_TIME_READ register;
+ * otherwise, CURRENT_TIME register is read to report the time
+ */
+ writel(RTC_INT_SEC, priv->base + RTC_INT_STS);
+
+ return 0;
+}
+
+static int zynqmp_rtc_reset(struct udevice *dev)
+{
+ return zynqmp_rtc_set(dev, NULL);
+}
+
+static int zynqmp_rtc_init(struct udevice *dev)
+{
+ struct zynqmp_rtc_priv *priv = dev_get_priv(dev);
+ u32 rtc_ctrl;
+
+ /* Enable RTC switch to battery when VCC_PSAUX is not available */
+ rtc_ctrl = readl(priv->base + RTC_CTRL);
+ rtc_ctrl |= RTC_BATT_EN;
+ writel(rtc_ctrl, priv->base + RTC_CTRL);
+
+ /*
+ * Based on crystal freq of 33.330 KHz
+ * set the seconds counter and enable, set fractions counter
+ * to default value suggested as per design spec
+ * to correct RTC delay in frequency over period of time.
+ */
+ priv->calibval &= RTC_CALIB_MASK;
+ writel(priv->calibval, (priv->base + RTC_CALIB_WR));
+
+ return 0;
+}
+
+static int zynqmp_rtc_probe(struct udevice *dev)
+{
+ struct zynqmp_rtc_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ priv->base = dev_read_addr(dev);
+ if (priv->base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ priv->calibval = dev_read_u32_default(dev, "calibration",
+ RTC_CALIB_DEF);
+
+ ret = zynqmp_rtc_init(dev);
+
+ return ret;
+}
+
+static const struct rtc_ops zynqmp_rtc_ops = {
+ .get = zynqmp_rtc_get,
+ .set = zynqmp_rtc_set,
+ .reset = zynqmp_rtc_reset,
+};
+
+static const struct udevice_id zynqmp_rtc_ids[] = {
+ { .compatible = "xlnx,zynqmp-rtc" },
+ { }
+};
+
+U_BOOT_DRIVER(rtc_zynqmp) = {
+ .name = "rtc-zynqmp",
+ .id = UCLASS_RTC,
+ .probe = zynqmp_rtc_probe,
+ .of_match = zynqmp_rtc_ids,
+ .ops = &zynqmp_rtc_ops,
+ .priv_auto = sizeof(struct zynqmp_rtc_priv),
+};
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 864d00a..292dc41 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -16,6 +16,22 @@ config SOC_DEVICE_TI_K3
This allows Texas Instruments Keystone 3 SoCs to identify
specifics about the SoC in use.
+config SOC_XILINX_ZYNQMP
+ bool "Enable SoC Device ID driver for Xilinx ZynqMP"
+ depends on SOC_DEVICE && ARCH_ZYNQMP
+ help
+ Enable this option to select SoC device id driver for Xilinx ZynqMP.
+ This allows other drivers to verify the SoC familiy & revision
+ using matching SoC attributes.
+
+config SOC_XILINX_VERSAL
+ bool "Enable SoC Device ID driver for Xilinx Versal"
+ depends on SOC_DEVICE && ARCH_VERSAL
+ help
+ Enable this option to select SoC device id driver for Xilinx Versal.
+ This allows other drivers to verify the SoC familiy & revision using
+ matching SoC attributes.
+
source "drivers/soc/ti/Kconfig"
endmenu
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 9ef20ca..031fa76 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -6,3 +6,5 @@ obj-$(CONFIG_SOC_TI) += ti/
obj-$(CONFIG_SOC_DEVICE) += soc-uclass.o
obj-$(CONFIG_SOC_DEVICE_TI_K3) += soc_ti_k3.o
obj-$(CONFIG_SANDBOX) += soc_sandbox.o
+obj-$(CONFIG_SOC_XILINX_ZYNQMP) += soc_xilinx_zynqmp.o
+obj-$(CONFIG_SOC_XILINX_VERSAL) += soc_xilinx_versal.o
diff --git a/drivers/soc/soc_xilinx_versal.c b/drivers/soc/soc_xilinx_versal.c
new file mode 100644
index 0000000..f8bcd9a
--- /dev/null
+++ b/drivers/soc/soc_xilinx_versal.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Versal SOC driver
+ *
+ * Copyright (C) 2021 Xilinx, Inc.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <soc.h>
+#include <zynqmp_firmware.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+/*
+ * v1 -> 0x10 - ES1
+ * v2 -> 0x20 - Production
+ */
+static const char versal_family[] = "Versal";
+
+struct soc_xilinx_versal_priv {
+ const char *family;
+ char revision;
+};
+
+static int soc_xilinx_versal_get_family(struct udevice *dev, char *buf, int size)
+{
+ struct soc_xilinx_versal_priv *priv = dev_get_priv(dev);
+
+ return snprintf(buf, size, "%s", priv->family);
+}
+
+static int soc_xilinx_versal_get_revision(struct udevice *dev, char *buf, int size)
+{
+ struct soc_xilinx_versal_priv *priv = dev_get_priv(dev);
+
+ return snprintf(buf, size, "v%d", priv->revision);
+}
+
+static const struct soc_ops soc_xilinx_versal_ops = {
+ .get_family = soc_xilinx_versal_get_family,
+ .get_revision = soc_xilinx_versal_get_revision,
+};
+
+static int soc_xilinx_versal_probe(struct udevice *dev)
+{
+ struct soc_xilinx_versal_priv *priv = dev_get_priv(dev);
+ u32 ret_payload[4];
+ int ret;
+
+ priv->family = versal_family;
+
+ if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE)) {
+ ret = xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0,
+ ret_payload);
+ if (ret)
+ return ret;
+ } else {
+ ret_payload[2] = readl(VERSAL_PS_PMC_VERSION);
+ if (!ret_payload[2])
+ return -EINVAL;
+ }
+
+ priv->revision = ret_payload[2] >> VERSAL_PS_VER_SHIFT;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(soc_xilinx_versal) = {
+ .name = "soc_xilinx_versal",
+ .id = UCLASS_SOC,
+ .ops = &soc_xilinx_versal_ops,
+ .probe = soc_xilinx_versal_probe,
+ .priv_auto = sizeof(struct soc_xilinx_versal_priv),
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/soc/soc_xilinx_zynqmp.c b/drivers/soc/soc_xilinx_zynqmp.c
new file mode 100644
index 0000000..7d33ce2
--- /dev/null
+++ b/drivers/soc/soc_xilinx_zynqmp.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx ZynqMP SOC driver
+ *
+ * Copyright (C) 2021 Xilinx, Inc.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/cache.h>
+#include <soc.h>
+#include <zynqmp_firmware.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
+
+/*
+ * Zynqmp has 4 silicon revisions
+ * v0 -> 0(XCZU9EG-ES1)
+ * v1 -> 1(XCZU3EG-ES1, XCZU15EG-ES1)
+ * v2 -> 2(XCZU7EV-ES1, XCZU9EG-ES2, XCZU19EG-ES1)
+ * v3 -> 3(Production Level)
+ */
+static const char zynqmp_family[] = "ZynqMP";
+
+struct soc_xilinx_zynqmp_priv {
+ const char *family;
+ char revision;
+};
+
+static int soc_xilinx_zynqmp_get_family(struct udevice *dev, char *buf, int size)
+{
+ struct soc_xilinx_zynqmp_priv *priv = dev_get_priv(dev);
+
+ return snprintf(buf, size, "%s", priv->family);
+}
+
+static int soc_xilinx_zynqmp_get_revision(struct udevice *dev, char *buf, int size)
+{
+ struct soc_xilinx_zynqmp_priv *priv = dev_get_priv(dev);
+
+ return snprintf(buf, size, "v%d", priv->revision);
+}
+
+static const struct soc_ops soc_xilinx_zynqmp_ops = {
+ .get_family = soc_xilinx_zynqmp_get_family,
+ .get_revision = soc_xilinx_zynqmp_get_revision,
+};
+
+static int soc_xilinx_zynqmp_probe(struct udevice *dev)
+{
+ struct soc_xilinx_zynqmp_priv *priv = dev_get_priv(dev);
+ u32 ret_payload[4];
+ int ret;
+
+ priv->family = zynqmp_family;
+
+ if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3 ||
+ !IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE))
+ ret = zynqmp_mmio_read(ZYNQMP_PS_VERSION, &ret_payload[2]);
+ else
+ ret = xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0,
+ ret_payload);
+ if (ret < 0)
+ return ret;
+
+ priv->revision = ret_payload[2] & ZYNQMP_PS_VER_MASK;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(soc_xilinx_zynqmp) = {
+ .name = "soc_xilinx_zynqmp",
+ .id = UCLASS_SOC,
+ .ops = &soc_xilinx_zynqmp_ops,
+ .probe = soc_xilinx_zynqmp_probe,
+ .priv_auto = sizeof(struct soc_xilinx_zynqmp_priv),
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/watchdog/xilinx_wwdt.c b/drivers/watchdog/xilinx_wwdt.c
index 11b30ae..c8e6c60 100644
--- a/drivers/watchdog/xilinx_wwdt.c
+++ b/drivers/watchdog/xilinx_wwdt.c
@@ -14,6 +14,7 @@
#include <regmap.h>
#include <wdt.h>
#include <linux/compat.h>
+#include <dm/device_compat.h>
#include <linux/io.h>
/* Refresh Register Masks */
diff --git a/include/sdhci.h b/include/sdhci.h
index 0ae9471..44a0d84 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -268,7 +268,7 @@ struct sdhci_ops {
int (*set_ios_post)(struct sdhci_host *host);
void (*set_clock)(struct sdhci_host *host, u32 div);
int (*platform_execute_tuning)(struct mmc *host, u8 opcode);
- void (*set_delay)(struct sdhci_host *host);
+ int (*set_delay)(struct sdhci_host *host);
int (*deferred_probe)(struct sdhci_host *host);
};
diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h
index f6f82bf..0b068d7 100644
--- a/include/zynqmp_firmware.h
+++ b/include/zynqmp_firmware.h
@@ -10,58 +10,156 @@
enum pm_api_id {
PM_GET_API_VERSION = 1,
- PM_SET_CONFIGURATION,
- PM_GET_NODE_STATUS,
- PM_GET_OPERATING_CHARACTERISTIC,
- PM_REGISTER_NOTIFIER,
- PM_REQUEST_SUSPEND,
- PM_SELF_SUSPEND,
- PM_FORCE_POWERDOWN,
- PM_ABORT_SUSPEND,
- PM_REQUEST_WAKEUP,
- PM_SET_WAKEUP_SOURCE,
- PM_SYSTEM_SHUTDOWN,
- PM_REQUEST_NODE,
- PM_RELEASE_NODE,
- PM_SET_REQUIREMENT,
- PM_SET_MAX_LATENCY,
- PM_RESET_ASSERT,
- PM_RESET_GET_STATUS,
- PM_MMIO_WRITE,
- PM_MMIO_READ,
- PM_PM_INIT_FINALIZE,
- PM_FPGA_LOAD,
- PM_FPGA_GET_STATUS,
- PM_GET_CHIPID,
+ PM_SET_CONFIGURATION = 2,
+ PM_GET_NODE_STATUS = 3,
+ PM_GET_OPERATING_CHARACTERISTIC = 4,
+ PM_REGISTER_NOTIFIER = 5,
+ /* API for suspending */
+ PM_REQUEST_SUSPEND = 6,
+ PM_SELF_SUSPEND = 7,
+ PM_FORCE_POWERDOWN = 8,
+ PM_ABORT_SUSPEND = 9,
+ PM_REQUEST_WAKEUP = 10,
+ PM_SET_WAKEUP_SOURCE = 11,
+ PM_SYSTEM_SHUTDOWN = 12,
+ PM_REQUEST_NODE = 13,
+ PM_RELEASE_NODE = 14,
+ PM_SET_REQUIREMENT = 15,
+ PM_SET_MAX_LATENCY = 16,
+ /* Direct control API functions: */
+ PM_RESET_ASSERT = 17,
+ PM_RESET_GET_STATUS = 18,
+ PM_MMIO_WRITE = 19,
+ PM_MMIO_READ = 20,
+ PM_PM_INIT_FINALIZE = 21,
+ PM_FPGA_LOAD = 22,
+ PM_FPGA_GET_STATUS = 23,
+ PM_GET_CHIPID = 24,
+ /* ID 25 is been used by U-boot to process secure boot images */
+ /* Secure library generic API functions */
PM_SECURE_SHA = 26,
- PM_SECURE_RSA,
- PM_PINCTRL_REQUEST,
- PM_PINCTRL_RELEASE,
- PM_PINCTRL_GET_FUNCTION,
- PM_PINCTRL_SET_FUNCTION,
- PM_PINCTRL_CONFIG_PARAM_GET,
- PM_PINCTRL_CONFIG_PARAM_SET,
- PM_IOCTL,
- PM_QUERY_DATA,
- PM_CLOCK_ENABLE,
- PM_CLOCK_DISABLE,
- PM_CLOCK_GETSTATE,
- PM_CLOCK_SETDIVIDER,
- PM_CLOCK_GETDIVIDER,
- PM_CLOCK_SETRATE,
- PM_CLOCK_GETRATE,
- PM_CLOCK_SETPARENT,
- PM_CLOCK_GETPARENT,
- PM_SECURE_IMAGE,
+ PM_SECURE_RSA = 27,
+ PM_PINCTRL_REQUEST = 28,
+ PM_PINCTRL_RELEASE = 29,
+ PM_PINCTRL_GET_FUNCTION = 30,
+ PM_PINCTRL_SET_FUNCTION = 31,
+ PM_PINCTRL_CONFIG_PARAM_GET = 32,
+ PM_PINCTRL_CONFIG_PARAM_SET = 33,
+ PM_IOCTL = 34,
+ PM_QUERY_DATA = 35,
+ PM_CLOCK_ENABLE = 36,
+ PM_CLOCK_DISABLE = 37,
+ PM_CLOCK_GETSTATE = 38,
+ PM_CLOCK_SETDIVIDER = 39,
+ PM_CLOCK_GETDIVIDER = 40,
+ PM_CLOCK_SETRATE = 41,
+ PM_CLOCK_GETRATE = 42,
+ PM_CLOCK_SETPARENT = 43,
+ PM_CLOCK_GETPARENT = 44,
+ PM_SECURE_IMAGE = 45,
PM_FPGA_READ = 46,
- PM_SECURE_AES,
+ PM_SECURE_AES = 47,
PM_CLOCK_PLL_GETPARAM = 49,
+ /* PM_REGISTER_ACCESS API */
PM_REGISTER_ACCESS = 52,
- PM_EFUSE_ACCESS,
+ PM_EFUSE_ACCESS = 53,
PM_FEATURE_CHECK = 63,
PM_API_MAX,
};
+enum pm_node_id {
+ NODE_UNKNOWN = 0,
+ NODE_APU = 1,
+ NODE_APU_0 = 2,
+ NODE_APU_1 = 3,
+ NODE_APU_2 = 4,
+ NODE_APU_3 = 5,
+ NODE_RPU = 6,
+ NODE_RPU_0 = 7,
+ NODE_RPU_1 = 8,
+ NODE_PLD = 9,
+ NODE_FPD = 10,
+ NODE_OCM_BANK_0 = 11,
+ NODE_OCM_BANK_1 = 12,
+ NODE_OCM_BANK_2 = 13,
+ NODE_OCM_BANK_3 = 14,
+ NODE_TCM_0_A = 15,
+ NODE_TCM_0_B = 16,
+ NODE_TCM_1_A = 17,
+ NODE_TCM_1_B = 18,
+ NODE_L2 = 19,
+ NODE_GPU_PP_0 = 20,
+ NODE_GPU_PP_1 = 21,
+ NODE_USB_0 = 22,
+ NODE_USB_1 = 23,
+ NODE_TTC_0 = 24,
+ NODE_TTC_1 = 25,
+ NODE_TTC_2 = 26,
+ NODE_TTC_3 = 27,
+ NODE_SATA = 28,
+ NODE_ETH_0 = 29,
+ NODE_ETH_1 = 30,
+ NODE_ETH_2 = 31,
+ NODE_ETH_3 = 32,
+ NODE_UART_0 = 33,
+ NODE_UART_1 = 34,
+ NODE_SPI_0 = 35,
+ NODE_SPI_1 = 36,
+ NODE_I2C_0 = 37,
+ NODE_I2C_1 = 38,
+ NODE_SD_0 = 39,
+ NODE_SD_1 = 40,
+ NODE_DP = 41,
+ NODE_GDMA = 42,
+ NODE_ADMA = 43,
+ NODE_NAND = 44,
+ NODE_QSPI = 45,
+ NODE_GPIO = 46,
+ NODE_CAN_0 = 47,
+ NODE_CAN_1 = 48,
+ NODE_EXTERN = 49,
+ NODE_APLL = 50,
+ NODE_VPLL = 51,
+ NODE_DPLL = 52,
+ NODE_RPLL = 53,
+ NODE_IOPLL = 54,
+ NODE_DDR = 55,
+ NODE_IPI_APU = 56,
+ NODE_IPI_RPU_0 = 57,
+ NODE_GPU = 58,
+ NODE_PCIE = 59,
+ NODE_PCAP = 60,
+ NODE_RTC = 61,
+ NODE_LPD = 62,
+ NODE_VCU = 63,
+ NODE_IPI_RPU_1 = 64,
+ NODE_IPI_PL_0 = 65,
+ NODE_IPI_PL_1 = 66,
+ NODE_IPI_PL_2 = 67,
+ NODE_IPI_PL_3 = 68,
+ NODE_PL = 69,
+ NODE_GEM_TSU = 70,
+ NODE_SWDT_0 = 71,
+ NODE_SWDT_1 = 72,
+ NODE_CSU = 73,
+ NODE_PJTAG = 74,
+ NODE_TRACE = 75,
+ NODE_TESTSCAN = 76,
+ NODE_PMU = 77,
+ NODE_MAX = 78,
+};
+
+enum tap_delay_type {
+ PM_TAPDELAY_INPUT = 0,
+ PM_TAPDELAY_OUTPUT = 1,
+};
+
+enum dll_reset_type {
+ PM_DLL_RESET_ASSERT = 0,
+ PM_DLL_RESET_RELEASE = 1,
+ PM_DLL_RESET_PULSE = 2,
+};
+
enum pm_query_id {
PM_QID_INVALID = 0,
PM_QID_CLOCK_GET_NAME = 1,
@@ -79,6 +177,171 @@ enum pm_query_id {
PM_QID_CLOCK_GET_MAX_DIVISOR = 13,
};
+enum zynqmp_pm_reset_action {
+ PM_RESET_ACTION_RELEASE = 0,
+ PM_RESET_ACTION_ASSERT = 1,
+ PM_RESET_ACTION_PULSE = 2,
+};
+
+enum zynqmp_pm_reset {
+ ZYNQMP_PM_RESET_START = 1000,
+ ZYNQMP_PM_RESET_PCIE_CFG = ZYNQMP_PM_RESET_START,
+ ZYNQMP_PM_RESET_PCIE_BRIDGE = 1001,
+ ZYNQMP_PM_RESET_PCIE_CTRL = 1002,
+ ZYNQMP_PM_RESET_DP = 1003,
+ ZYNQMP_PM_RESET_SWDT_CRF = 1004,
+ ZYNQMP_PM_RESET_AFI_FM5 = 1005,
+ ZYNQMP_PM_RESET_AFI_FM4 = 1006,
+ ZYNQMP_PM_RESET_AFI_FM3 = 1007,
+ ZYNQMP_PM_RESET_AFI_FM2 = 1008,
+ ZYNQMP_PM_RESET_AFI_FM1 = 1009,
+ ZYNQMP_PM_RESET_AFI_FM0 = 1010,
+ ZYNQMP_PM_RESET_GDMA = 1011,
+ ZYNQMP_PM_RESET_GPU_PP1 = 1012,
+ ZYNQMP_PM_RESET_GPU_PP0 = 1013,
+ ZYNQMP_PM_RESET_GPU = 1014,
+ ZYNQMP_PM_RESET_GT = 1015,
+ ZYNQMP_PM_RESET_SATA = 1016,
+ ZYNQMP_PM_RESET_ACPU3_PWRON = 1017,
+ ZYNQMP_PM_RESET_ACPU2_PWRON = 1018,
+ ZYNQMP_PM_RESET_ACPU1_PWRON = 1019,
+ ZYNQMP_PM_RESET_ACPU0_PWRON = 1020,
+ ZYNQMP_PM_RESET_APU_L2 = 1021,
+ ZYNQMP_PM_RESET_ACPU3 = 1022,
+ ZYNQMP_PM_RESET_ACPU2 = 1023,
+ ZYNQMP_PM_RESET_ACPU1 = 1024,
+ ZYNQMP_PM_RESET_ACPU0 = 1025,
+ ZYNQMP_PM_RESET_DDR = 1026,
+ ZYNQMP_PM_RESET_APM_FPD = 1027,
+ ZYNQMP_PM_RESET_SOFT = 1028,
+ ZYNQMP_PM_RESET_GEM0 = 1029,
+ ZYNQMP_PM_RESET_GEM1 = 1030,
+ ZYNQMP_PM_RESET_GEM2 = 1031,
+ ZYNQMP_PM_RESET_GEM3 = 1032,
+ ZYNQMP_PM_RESET_QSPI = 1033,
+ ZYNQMP_PM_RESET_UART0 = 1034,
+ ZYNQMP_PM_RESET_UART1 = 1035,
+ ZYNQMP_PM_RESET_SPI0 = 1036,
+ ZYNQMP_PM_RESET_SPI1 = 1037,
+ ZYNQMP_PM_RESET_SDIO0 = 1038,
+ ZYNQMP_PM_RESET_SDIO1 = 1039,
+ ZYNQMP_PM_RESET_CAN0 = 1040,
+ ZYNQMP_PM_RESET_CAN1 = 1041,
+ ZYNQMP_PM_RESET_I2C0 = 1042,
+ ZYNQMP_PM_RESET_I2C1 = 1043,
+ ZYNQMP_PM_RESET_TTC0 = 1044,
+ ZYNQMP_PM_RESET_TTC1 = 1045,
+ ZYNQMP_PM_RESET_TTC2 = 1046,
+ ZYNQMP_PM_RESET_TTC3 = 1047,
+ ZYNQMP_PM_RESET_SWDT_CRL = 1048,
+ ZYNQMP_PM_RESET_NAND = 1049,
+ ZYNQMP_PM_RESET_ADMA = 1050,
+ ZYNQMP_PM_RESET_GPIO = 1051,
+ ZYNQMP_PM_RESET_IOU_CC = 1052,
+ ZYNQMP_PM_RESET_TIMESTAMP = 1053,
+ ZYNQMP_PM_RESET_RPU_R50 = 1054,
+ ZYNQMP_PM_RESET_RPU_R51 = 1055,
+ ZYNQMP_PM_RESET_RPU_AMBA = 1056,
+ ZYNQMP_PM_RESET_OCM = 1057,
+ ZYNQMP_PM_RESET_RPU_PGE = 1058,
+ ZYNQMP_PM_RESET_USB0_CORERESET = 1059,
+ ZYNQMP_PM_RESET_USB1_CORERESET = 1060,
+ ZYNQMP_PM_RESET_USB0_HIBERRESET = 1061,
+ ZYNQMP_PM_RESET_USB1_HIBERRESET = 1062,
+ ZYNQMP_PM_RESET_USB0_APB = 1063,
+ ZYNQMP_PM_RESET_USB1_APB = 1064,
+ ZYNQMP_PM_RESET_IPI = 1065,
+ ZYNQMP_PM_RESET_APM_LPD = 1066,
+ ZYNQMP_PM_RESET_RTC = 1067,
+ ZYNQMP_PM_RESET_SYSMON = 1068,
+ ZYNQMP_PM_RESET_AFI_FM6 = 1069,
+ ZYNQMP_PM_RESET_LPD_SWDT = 1070,
+ ZYNQMP_PM_RESET_FPD = 1071,
+ ZYNQMP_PM_RESET_RPU_DBG1 = 1072,
+ ZYNQMP_PM_RESET_RPU_DBG0 = 1073,
+ ZYNQMP_PM_RESET_DBG_LPD = 1074,
+ ZYNQMP_PM_RESET_DBG_FPD = 1075,
+ ZYNQMP_PM_RESET_APLL = 1076,
+ ZYNQMP_PM_RESET_DPLL = 1077,
+ ZYNQMP_PM_RESET_VPLL = 1078,
+ ZYNQMP_PM_RESET_IOPLL = 1079,
+ ZYNQMP_PM_RESET_RPLL = 1080,
+ ZYNQMP_PM_RESET_GPO3_PL_0 = 1081,
+ ZYNQMP_PM_RESET_GPO3_PL_1 = 1082,
+ ZYNQMP_PM_RESET_GPO3_PL_2 = 1083,
+ ZYNQMP_PM_RESET_GPO3_PL_3 = 1084,
+ ZYNQMP_PM_RESET_GPO3_PL_4 = 1085,
+ ZYNQMP_PM_RESET_GPO3_PL_5 = 1086,
+ ZYNQMP_PM_RESET_GPO3_PL_6 = 1087,
+ ZYNQMP_PM_RESET_GPO3_PL_7 = 1088,
+ ZYNQMP_PM_RESET_GPO3_PL_8 = 1089,
+ ZYNQMP_PM_RESET_GPO3_PL_9 = 1090,
+ ZYNQMP_PM_RESET_GPO3_PL_10 = 1091,
+ ZYNQMP_PM_RESET_GPO3_PL_11 = 1092,
+ ZYNQMP_PM_RESET_GPO3_PL_12 = 1093,
+ ZYNQMP_PM_RESET_GPO3_PL_13 = 1094,
+ ZYNQMP_PM_RESET_GPO3_PL_14 = 1095,
+ ZYNQMP_PM_RESET_GPO3_PL_15 = 1096,
+ ZYNQMP_PM_RESET_GPO3_PL_16 = 1097,
+ ZYNQMP_PM_RESET_GPO3_PL_17 = 1098,
+ ZYNQMP_PM_RESET_GPO3_PL_18 = 1099,
+ ZYNQMP_PM_RESET_GPO3_PL_19 = 1100,
+ ZYNQMP_PM_RESET_GPO3_PL_20 = 1101,
+ ZYNQMP_PM_RESET_GPO3_PL_21 = 1102,
+ ZYNQMP_PM_RESET_GPO3_PL_22 = 1103,
+ ZYNQMP_PM_RESET_GPO3_PL_23 = 1104,
+ ZYNQMP_PM_RESET_GPO3_PL_24 = 1105,
+ ZYNQMP_PM_RESET_GPO3_PL_25 = 1106,
+ ZYNQMP_PM_RESET_GPO3_PL_26 = 1107,
+ ZYNQMP_PM_RESET_GPO3_PL_27 = 1108,
+ ZYNQMP_PM_RESET_GPO3_PL_28 = 1109,
+ ZYNQMP_PM_RESET_GPO3_PL_29 = 1110,
+ ZYNQMP_PM_RESET_GPO3_PL_30 = 1111,
+ ZYNQMP_PM_RESET_GPO3_PL_31 = 1112,
+ ZYNQMP_PM_RESET_RPU_LS = 1113,
+ ZYNQMP_PM_RESET_PS_ONLY = 1114,
+ ZYNQMP_PM_RESET_PL = 1115,
+ ZYNQMP_PM_RESET_PS_PL0 = 1116,
+ ZYNQMP_PM_RESET_PS_PL1 = 1117,
+ ZYNQMP_PM_RESET_PS_PL2 = 1118,
+ ZYNQMP_PM_RESET_PS_PL3 = 1119,
+ ZYNQMP_PM_RESET_END = ZYNQMP_PM_RESET_PS_PL3
+};
+
+enum pm_ioctl_id {
+ IOCTL_GET_RPU_OPER_MODE = 0,
+ IOCTL_SET_RPU_OPER_MODE = 1,
+ IOCTL_RPU_BOOT_ADDR_CONFIG = 2,
+ IOCTL_TCM_COMB_CONFIG = 3,
+ IOCTL_SET_TAPDELAY_BYPASS = 4,
+ IOCTL_SET_SGMII_MODE = 5,
+ IOCTL_SD_DLL_RESET = 6,
+ IOCTL_SET_SD_TAPDELAY = 7,
+ IOCTL_SET_PLL_FRAC_MODE = 8,
+ IOCTL_GET_PLL_FRAC_MODE = 9,
+ IOCTL_SET_PLL_FRAC_DATA = 10,
+ IOCTL_GET_PLL_FRAC_DATA = 11,
+ IOCTL_WRITE_GGS = 12,
+ IOCTL_READ_GGS = 13,
+ IOCTL_WRITE_PGGS = 14,
+ IOCTL_READ_PGGS = 15,
+ /* IOCTL for ULPI reset */
+ IOCTL_ULPI_RESET = 16,
+ /* Set healthy bit value*/
+ IOCTL_SET_BOOT_HEALTH_STATUS = 17,
+ IOCTL_AFI = 18,
+ /* Probe counter read/write */
+ IOCTL_PROBE_COUNTER_READ = 19,
+ IOCTL_PROBE_COUNTER_WRITE = 20,
+ IOCTL_OSPI_MUX_SELECT = 21,
+ /* IOCTL for USB power request */
+ IOCTL_USB_SET_STATE = 22,
+ /* IOCTL to get last reset reason */
+ IOCTL_GET_LAST_RESET_REASON = 23,
+ /* AIE ISR Clear */
+ IOCTL_AIE_ISR_CLEAR = 24,
+};
+
#define PM_SIP_SVC 0xc2000000
#define ZYNQMP_PM_VERSION_MAJOR 1
diff --git a/include/zynqmp_tap_delay.h b/include/zynqmp_tap_delay.h
deleted file mode 100644
index 1c1e3e7..0000000
--- a/include/zynqmp_tap_delay.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Xilinx ZynqMP SoC Tap Delay Programming
- *
- * Copyright (C) 2018 Xilinx, Inc.
- */
-
-#ifndef __ZYNQMP_TAP_DELAY_H__
-#define __ZYNQMP_TAP_DELAY_H__
-
-#ifdef CONFIG_ARCH_ZYNQMP
-void zynqmp_dll_reset(u8 deviceid);
-void arasan_zynqmp_set_in_tapdelay(u8 device_id, u32 itap_delay);
-void arasan_zynqmp_set_out_tapdelay(u8 device_id, u32 otap_delay);
-#else
-inline void zynqmp_dll_reset(u8 deviceid) {}
-inline void arasan_zynqmp_set_in_tapdelay(u8 device_id, u32 itap_delay) {}
-inline void arasan_zynqmp_set_out_tapdelay(u8 device_id, u32 otap_delay) {}
-#endif
-
-#endif