diff options
author | Tom Rini <trini@konsulko.com> | 2021-08-27 08:33:02 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-08-27 08:33:02 -0400 |
commit | b9cb74a5aa256fc34a1b2b9dd847a985b91f34f6 (patch) | |
tree | a618344b253ec3164848e797a2636bbd8f060223 | |
parent | 7bfa565453ec5f63668a3464da21629055c3053f (diff) | |
parent | 229cb5c6ba3469cbc4a0bcc69389fe61c51fd3b4 (diff) | |
download | u-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()
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 @@ -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 @@ -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 @@ -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(); @@ -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 |