mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-24 12:44:23 +08:00
Xilinx changes for v2021.01-v2
common: - Add support for 64bit loadables from SPL xilinx: - Update documentation and record ownership - Enable eeprom board detection based legacy and fru formats - Add support for FRU format microblaze: - Optimize low level ASM code - Enable SPI/I2C - Enable distro boot zynq: - Add support for Zturn V5 zynqmp: - Improve silicon detection code - Enable several kconfig options - Align DT with the latest state - Enabling security commands - Enable and support FPGA loading from SPL - Optimize xilinx_pm_request() calling versal: - Some DTs/Kconfig/defconfig alignments - Add binding header for clock and power zynq-sdhci: - Add support for tap delay programming zynq-spi/zynq-qspi: - Use clock framework for getting clocks xilinx-spi: - Fix some code issues (unused variables) serial: - Check return value from clock functions in pl01x -----BEGIN PGP SIGNATURE----- iF0EABECAB0WIQQbPNTMvXmYlBPRwx7KSWXLKUoMIQUCX5rH/QAKCRDKSWXLKUoM IRPAAJ9SvHR3w1qTc5W+Q5CWBUH5wJbNYQCaA4PpqZCdvyu1+nF5luL6JHhbDgw= =hOd7 -----END PGP SIGNATURE----- Merge tag 'xilinx-for-v2021.01-v2' of https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze Xilinx changes for v2021.01-v2 common: - Add support for 64bit loadables from SPL xilinx: - Update documentation and record ownership - Enable eeprom board detection based legacy and fru formats - Add support for FRU format microblaze: - Optimize low level ASM code - Enable SPI/I2C - Enable distro boot zynq: - Add support for Zturn V5 zynqmp: - Improve silicon detection code - Enable several kconfig options - Align DT with the latest state - Enabling security commands - Enable and support FPGA loading from SPL - Optimize xilinx_pm_request() calling versal: - Some DTs/Kconfig/defconfig alignments - Add binding header for clock and power zynq-sdhci: - Add support for tap delay programming zynq-spi/zynq-qspi: - Use clock framework for getting clocks xilinx-spi: - Fix some code issues (unused variables) serial: - Check return value from clock functions in pl01x
This commit is contained in:
commit
47754334b1
@ -546,6 +546,7 @@ M: Michal Simek <monstr@monstr.eu>
|
||||
S: Maintained
|
||||
T: git https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze.git
|
||||
F: arch/arm/mach-zynq/
|
||||
F: doc/board/xilinx/
|
||||
F: drivers/clk/clk_zynq.c
|
||||
F: drivers/fpga/zynqpl.c
|
||||
F: drivers/gpio/zynq_gpio.c
|
||||
|
@ -279,6 +279,7 @@ dtb-$(CONFIG_ARCH_ZYNQ) += \
|
||||
zynq-zc770-xm013.dtb \
|
||||
zynq-zed.dtb \
|
||||
zynq-zturn.dtb \
|
||||
zynq-zturn-v5.dtb \
|
||||
zynq-zybo.dtb \
|
||||
zynq-zybo-z7.dtb
|
||||
dtb-$(CONFIG_ARCH_ZYNQMP) += \
|
||||
|
@ -16,10 +16,10 @@
|
||||
#size-cells = <2>;
|
||||
model = "Xilinx Versal MINI eMMC0";
|
||||
|
||||
clk25: clk25 {
|
||||
clk200: clk200 {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0x0>;
|
||||
clock-frequency = <25000000>;
|
||||
clock-frequency = <200000000>;
|
||||
};
|
||||
|
||||
dcc: dcc {
|
||||
@ -38,9 +38,12 @@
|
||||
sdhci0: sdhci@f1040000 {
|
||||
compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a";
|
||||
status = "okay";
|
||||
non-removable;
|
||||
disable-wp;
|
||||
bus-width = <8>;
|
||||
reg = <0x0 0xf1040000 0x0 0x10000>;
|
||||
clock-names = "clk_xin", "clk_ahb";
|
||||
clocks = <&clk25 &clk25>;
|
||||
clocks = <&clk200 &clk200>;
|
||||
xlnx,device_id = <0>;
|
||||
no-1-8-v;
|
||||
xlnx,mio-bank = <0>;
|
||||
|
@ -16,10 +16,10 @@
|
||||
#size-cells = <2>;
|
||||
model = "Xilinx Versal MINI eMMC1";
|
||||
|
||||
clk25: clk25 {
|
||||
clk200: clk200 {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0x0>;
|
||||
clock-frequency = <25000000>;
|
||||
clock-frequency = <200000000>;
|
||||
};
|
||||
|
||||
dcc: dcc {
|
||||
@ -38,9 +38,12 @@
|
||||
sdhci1: sdhci@f1050000 {
|
||||
compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a";
|
||||
status = "okay";
|
||||
non-removable;
|
||||
disable-wp;
|
||||
bus-width = <8>;
|
||||
reg = <0x0 0xf1050000 0x0 0x10000>;
|
||||
clock-names = "clk_xin", "clk_ahb";
|
||||
clocks = <&clk25 &clk25>;
|
||||
clocks = <&clk200 &clk200>;
|
||||
xlnx,device_id = <1>;
|
||||
no-1-8-v;
|
||||
xlnx,mio-bank = <0>;
|
||||
|
120
arch/arm/dts/zynq-zturn-common.dtsi
Normal file
120
arch/arm/dts/zynq-zturn-common.dtsi
Normal file
@ -0,0 +1,120 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2015 Andrea Merello <adnrea.merello@gmail.com>
|
||||
* Copyright (C) 2017 Alexander Graf <agraf@suse.de>
|
||||
*
|
||||
* Based on zynq-zed.dts which is:
|
||||
* Copyright (C) 2011 - 2014 Xilinx
|
||||
* Copyright (C) 2012 National Instruments Corp.
|
||||
*
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/include/ "zynq-7000.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "xlnx,zynq-7000";
|
||||
|
||||
aliases {
|
||||
ethernet0 = &gem0;
|
||||
serial0 = &uart1;
|
||||
serial1 = &uart0;
|
||||
mmc0 = &sdhci0;
|
||||
};
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x40000000>;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
usr-led1 {
|
||||
label = "usr-led1";
|
||||
gpios = <&gpio0 0x0 0x1>;
|
||||
default-state = "off";
|
||||
};
|
||||
|
||||
usr-led2 {
|
||||
label = "usr-led2";
|
||||
gpios = <&gpio0 0x9 0x1>;
|
||||
default-state = "off";
|
||||
};
|
||||
};
|
||||
|
||||
gpio-keys {
|
||||
compatible = "gpio-keys";
|
||||
autorepeat;
|
||||
K1 {
|
||||
label = "K1";
|
||||
gpios = <&gpio0 0x32 0x1>;
|
||||
linux,code = <0x66>;
|
||||
wakeup-source;
|
||||
autorepeat;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&clkc {
|
||||
ps-clk-frequency = <33333333>;
|
||||
};
|
||||
|
||||
&qspi {
|
||||
u-boot,dm-pre-reloc;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gem0 {
|
||||
status = "okay";
|
||||
phy-mode = "rgmii-id";
|
||||
phy-handle = <ðernet_phy>;
|
||||
|
||||
ethernet_phy: ethernet-phy@0 {
|
||||
};
|
||||
};
|
||||
|
||||
&sdhci0 {
|
||||
u-boot,dm-pre-reloc;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
u-boot,dm-pre-reloc;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&uart1 {
|
||||
u-boot,dm-pre-reloc;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb0 {
|
||||
status = "okay";
|
||||
dr_mode = "host";
|
||||
};
|
||||
|
||||
&can0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
status = "okay";
|
||||
clock-frequency = <400000>;
|
||||
|
||||
stlm75@49 {
|
||||
status = "okay";
|
||||
compatible = "lm75";
|
||||
reg = <0x49>;
|
||||
};
|
||||
|
||||
accelerometer@53 {
|
||||
compatible = "adi,adxl345", "adxl345", "adi,adxl34x", "adxl34x";
|
||||
reg = <0x53>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <0x0 0x1e 0x4>;
|
||||
};
|
||||
};
|
15
arch/arm/dts/zynq-zturn-v5.dts
Normal file
15
arch/arm/dts/zynq-zturn-v5.dts
Normal file
@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
/dts-v1/;
|
||||
/include/ "zynq-zturn-common.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Zynq Z-Turn MYIR Board V5";
|
||||
compatible = "myir,zynq-zturn-v5", "xlnx,zynq-7000";
|
||||
};
|
||||
|
||||
&gem0 {
|
||||
ethernet_phy: ethernet-phy@0 {
|
||||
reg = <0x3>;
|
||||
};
|
||||
};
|
@ -1,122 +1,15 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2015 Andrea Merello <adnrea.merello@gmail.com>
|
||||
* Copyright (C) 2017 Alexander Graf <agraf@suse.de>
|
||||
*
|
||||
* Based on zynq-zed.dts which is:
|
||||
* Copyright (C) 2011 - 2014 Xilinx
|
||||
* Copyright (C) 2012 National Instruments Corp.
|
||||
*
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/include/ "zynq-7000.dtsi"
|
||||
/include/ "zynq-zturn-common.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Zynq Z-Turn MYIR Board";
|
||||
compatible = "myir,zynq-zturn", "xlnx,zynq-7000";
|
||||
|
||||
aliases {
|
||||
ethernet0 = &gem0;
|
||||
serial0 = &uart1;
|
||||
serial1 = &uart0;
|
||||
mmc0 = &sdhci0;
|
||||
};
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x40000000>;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
usr-led1 {
|
||||
label = "usr-led1";
|
||||
gpios = <&gpio0 0x0 0x1>;
|
||||
default-state = "off";
|
||||
};
|
||||
|
||||
usr-led2 {
|
||||
label = "usr-led2";
|
||||
gpios = <&gpio0 0x9 0x1>;
|
||||
default-state = "off";
|
||||
};
|
||||
};
|
||||
|
||||
gpio-keys {
|
||||
compatible = "gpio-keys";
|
||||
autorepeat;
|
||||
K1 {
|
||||
label = "K1";
|
||||
gpios = <&gpio0 0x32 0x1>;
|
||||
linux,code = <0x66>;
|
||||
wakeup-source;
|
||||
autorepeat;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&clkc {
|
||||
ps-clk-frequency = <33333333>;
|
||||
};
|
||||
|
||||
&qspi {
|
||||
u-boot,dm-pre-reloc;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gem0 {
|
||||
status = "okay";
|
||||
phy-mode = "rgmii-id";
|
||||
phy-handle = <ðernet_phy>;
|
||||
|
||||
ethernet_phy: ethernet-phy@0 {
|
||||
reg = <0x0>;
|
||||
};
|
||||
};
|
||||
|
||||
&sdhci0 {
|
||||
u-boot,dm-pre-reloc;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
u-boot,dm-pre-reloc;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&uart1 {
|
||||
u-boot,dm-pre-reloc;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb0 {
|
||||
status = "okay";
|
||||
dr_mode = "host";
|
||||
};
|
||||
|
||||
&can0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
status = "okay";
|
||||
clock-frequency = <400000>;
|
||||
|
||||
stlm75@49 {
|
||||
status = "okay";
|
||||
compatible = "lm75";
|
||||
reg = <0x49>;
|
||||
};
|
||||
|
||||
accelerometer@53 {
|
||||
compatible = "adi,adxl345", "adxl345", "adi,adxl34x", "adxl34x";
|
||||
reg = <0x53>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <0x0 0x1e 0x4>;
|
||||
};
|
||||
};
|
||||
|
@ -70,7 +70,7 @@
|
||||
reg = <0x0>;
|
||||
spi-tx-bus-width = <1>;
|
||||
spi-rx-bus-width = <4>;
|
||||
spi-max-frequency = <108000000>;
|
||||
spi-max-frequency = <40000000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <init.h>
|
||||
#include <log.h>
|
||||
#include <spl.h>
|
||||
#include <generated/dt.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/spl.h>
|
||||
@ -86,16 +85,3 @@ void spl_board_prepare_for_boot(void)
|
||||
ps7_post_config();
|
||||
debug("SPL bye\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_LOAD_FIT
|
||||
int board_fit_config_name_match(const char *name)
|
||||
{
|
||||
/* Just empty function now - can't decide what to choose */
|
||||
debug("%s: Check %s, default %s\n", __func__, name, DEVICE_TREE);
|
||||
|
||||
if (!strcmp(name, DEVICE_TREE))
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
@ -9,6 +9,16 @@
|
||||
|
||||
#define ZYNQMP_CSU_SILICON_VER_MASK 0xF
|
||||
#define KEY_PTR_LEN 32
|
||||
#define IV_SIZE 12
|
||||
#define RSA_KEY_SIZE 512
|
||||
#define MODULUS_LEN 512
|
||||
#define PRIV_EXPO_LEN 512
|
||||
#define PUB_EXPO_LEN 4
|
||||
|
||||
#define ZYNQMP_SHA3_INIT 1
|
||||
#define ZYNQMP_SHA3_UPDATE 2
|
||||
#define ZYNQMP_SHA3_FINAL 4
|
||||
#define ZYNQMP_SHA3_SIZE 48
|
||||
|
||||
#define ZYNQMP_FPGA_BIT_AUTH_DDR 1
|
||||
#define ZYNQMP_FPGA_BIT_AUTH_OCM 2
|
||||
|
@ -119,13 +119,3 @@ int spl_start_uboot(void)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPL_LOAD_FIT
|
||||
int board_fit_config_name_match(const char *name)
|
||||
{
|
||||
/* Just empty function now - can't decide what to choose */
|
||||
debug("%s: %s\n", __func__, name);
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
@ -16,10 +16,14 @@ config TARGET_MICROBLAZE_GENERIC
|
||||
select OF_CONTROL
|
||||
select SUPPORT_SPL
|
||||
select SYSRESET
|
||||
select DM_SPI
|
||||
select DM_SPI_FLASH
|
||||
select SPI
|
||||
imply CMD_DM
|
||||
|
||||
endchoice
|
||||
|
||||
source "board/xilinx/Kconfig"
|
||||
source "board/xilinx/microblaze-generic/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
@ -13,31 +13,108 @@
|
||||
.text
|
||||
.global _start
|
||||
_start:
|
||||
/*
|
||||
* reserve registers:
|
||||
* r10: Stores little/big endian offset for vectors
|
||||
* r2: Stores imm opcode
|
||||
* r3: Stores brai opcode
|
||||
*/
|
||||
|
||||
mts rmsr, r0 /* disable cache */
|
||||
|
||||
addi r8, r0, __end
|
||||
mts rslr, r8
|
||||
/* TODO: Redo this code to call board_init_f_*() */
|
||||
|
||||
#if defined(CONFIG_SPL_BUILD)
|
||||
addi r1, r0, CONFIG_SPL_STACK_ADDR
|
||||
mts rshr, r1
|
||||
addi r1, r1, -4 /* Decrement SP to top of memory */
|
||||
#else
|
||||
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
|
||||
addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET - CONFIG_VAL(SYS_MALLOC_F_LEN)
|
||||
#else
|
||||
addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET
|
||||
#endif
|
||||
mts rshr, r1
|
||||
|
||||
addi r1, r1, -4 /* Decrement SP to top of memory */
|
||||
|
||||
/* Call board_init_f_alloc_reserve with the current stack pointer as
|
||||
* parameter. */
|
||||
add r5, r0, r1
|
||||
bralid r15, board_init_f_alloc_reserve
|
||||
nop
|
||||
|
||||
/* board_init_f_alloc_reserve returns a pointer to the allocated area
|
||||
* in r3. Set the new stack pointer below this area. */
|
||||
add r1, r0, r3
|
||||
mts rshr, r1
|
||||
addi r1, r1, -4
|
||||
|
||||
/* Call board_init_f_init_reserve with the address returned by
|
||||
* board_init_f_alloc_reserve as parameter. */
|
||||
add r5, r0, r3
|
||||
bralid r15, board_init_f_init_reserve
|
||||
nop
|
||||
|
||||
#if !defined(CONFIG_SPL_BUILD)
|
||||
/* Setup vectors with pre-relocation symbols */
|
||||
or r5, r0, r0
|
||||
bralid r15, __setup_exceptions
|
||||
nop
|
||||
#endif
|
||||
|
||||
/* Flush cache before enable cache */
|
||||
addik r5, r0, 0
|
||||
addik r6, r0, XILINX_DCACHE_BYTE_SIZE
|
||||
bralid r15, flush_cache
|
||||
nop
|
||||
|
||||
/* enable instruction and data cache */
|
||||
mfs r12, rmsr
|
||||
ori r12, r12, 0x1a0
|
||||
mts rmsr, r12
|
||||
|
||||
clear_bss:
|
||||
/* clear BSS segments */
|
||||
addi r5, r0, __bss_start
|
||||
addi r4, r0, __bss_end
|
||||
cmp r6, r5, r4
|
||||
beqi r6, 3f
|
||||
2:
|
||||
swi r0, r5, 0 /* write zero to loc */
|
||||
addi r5, r5, 4 /* increment to next loc */
|
||||
cmp r6, r5, r4 /* check if we have reach the end */
|
||||
bnei r6, 2b
|
||||
3: /* jumping to board_init */
|
||||
#ifdef CONFIG_DEBUG_UART
|
||||
bralid r15, debug_uart_init
|
||||
nop
|
||||
#endif
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
or r5, r0, r0 /* flags - empty */
|
||||
brai board_init_f
|
||||
#else
|
||||
brai board_init_r
|
||||
#endif
|
||||
1: bri 1b
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
.text
|
||||
.ent __setup_exceptions
|
||||
.align 2
|
||||
/*
|
||||
* Set up reset, interrupt, user exception and hardware exception vectors.
|
||||
*
|
||||
* Parameters:
|
||||
* r5 - relocation offset (zero when setting up vectors before
|
||||
* relocation, and gd->reloc_off when setting up vectors after
|
||||
* relocation)
|
||||
* - the relocation offset is added to the _exception_handler,
|
||||
* _interrupt_handler and _hw_exception_handler symbols to reflect the
|
||||
* post-relocation memory addresses
|
||||
*
|
||||
* Reserve registers:
|
||||
* r10: Stores little/big endian offset for vectors
|
||||
* r2: Stores imm opcode
|
||||
* r3: Stores brai opcode
|
||||
*/
|
||||
__setup_exceptions:
|
||||
addik r1, r1, -28
|
||||
swi r2, r1, 4
|
||||
swi r3, r1, 8
|
||||
swi r6, r1, 12
|
||||
swi r7, r1, 16
|
||||
swi r8, r1, 20
|
||||
swi r10, r1, 24
|
||||
|
||||
/* Find-out if u-boot is running on BIG/LITTLE endian platform
|
||||
* There are some steps which is necessary to keep in mind:
|
||||
* 1. Setup offset value to r6
|
||||
@ -76,7 +153,7 @@ _start:
|
||||
swi r2, r0, 0x8 /* user vector exception - imm opcode */
|
||||
swi r3, r0, 0xC /* user vector exception - brai opcode */
|
||||
|
||||
addik r6, r0, _exception_handler
|
||||
addik r6, r5, _exception_handler
|
||||
sw r6, r1, r0
|
||||
/*
|
||||
* BIG ENDIAN memory map for user exception
|
||||
@ -109,7 +186,7 @@ _start:
|
||||
swi r2, r0, 0x10 /* interrupt - imm opcode */
|
||||
swi r3, r0, 0x14 /* interrupt - brai opcode */
|
||||
|
||||
addik r6, r0, _interrupt_handler
|
||||
addik r6, r5, _interrupt_handler
|
||||
sw r6, r1, r0
|
||||
lhu r7, r1, r10
|
||||
rsubi r8, r10, 0x12
|
||||
@ -121,67 +198,26 @@ _start:
|
||||
swi r2, r0, 0x20 /* hardware exception - imm opcode */
|
||||
swi r3, r0, 0x24 /* hardware exception - brai opcode */
|
||||
|
||||
addik r6, r0, _hw_exception_handler
|
||||
addik r6, r5, _hw_exception_handler
|
||||
sw r6, r1, r0
|
||||
lhu r7, r1, r10
|
||||
rsubi r8, r10, 0x22
|
||||
sh r7, r0, r8
|
||||
rsubi r8, r10, 0x26
|
||||
sh r6, r0, r8
|
||||
#endif /* CONFIG_SPL_BUILD */
|
||||
|
||||
/* Flush cache before enable cache */
|
||||
addik r5, r0, 0
|
||||
addik r6, r0, XILINX_DCACHE_BYTE_SIZE
|
||||
bralid r15, flush_cache
|
||||
nop
|
||||
lwi r10, r1, 24
|
||||
lwi r8, r1, 20
|
||||
lwi r7, r1, 16
|
||||
lwi r6, r1, 12
|
||||
lwi r3, r1, 8
|
||||
lwi r2, r1, 4
|
||||
addik r1, r1, 28
|
||||
|
||||
/* enable instruction and data cache */
|
||||
mfs r12, rmsr
|
||||
ori r12, r12, 0x1a0
|
||||
mts rmsr, r12
|
||||
rtsd r15, 8
|
||||
or r0, r0, r0
|
||||
.end __setup_exceptions
|
||||
|
||||
/* TODO: Redo this code to call board_init_f_*() */
|
||||
clear_bss:
|
||||
/* clear BSS segments */
|
||||
addi r5, r0, __bss_start
|
||||
addi r4, r0, __bss_end
|
||||
cmp r6, r5, r4
|
||||
beqi r6, 3f
|
||||
2:
|
||||
swi r0, r5, 0 /* write zero to loc */
|
||||
addi r5, r5, 4 /* increment to next loc */
|
||||
cmp r6, r5, r4 /* check if we have reach the end */
|
||||
bnei r6, 2b
|
||||
3: /* jumping to board_init */
|
||||
#ifdef CONFIG_DEBUG_UART
|
||||
bralid r15, debug_uart_init
|
||||
nop
|
||||
#endif
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
or r5, r0, r0 /* flags - empty */
|
||||
addi r31, r0, _gd
|
||||
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
|
||||
addi r6, r0, CONFIG_SYS_INIT_SP_OFFSET
|
||||
swi r6, r31, GD_MALLOC_BASE
|
||||
#endif
|
||||
brai board_init_f
|
||||
#else
|
||||
addi r31, r0, _gd
|
||||
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
|
||||
addi r6, r0, CONFIG_SPL_STACK_ADDR
|
||||
swi r6, r31, GD_MALLOC_BASE
|
||||
#endif
|
||||
brai board_init_r
|
||||
#endif
|
||||
1: bri 1b
|
||||
|
||||
.section .bss
|
||||
.align 4
|
||||
_gd:
|
||||
.space GENERATED_GBL_DATA_SIZE
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
/*
|
||||
* Read 16bit little endian
|
||||
*/
|
||||
@ -249,39 +285,10 @@ relocate_code:
|
||||
addi r24, r0, CONFIG_SYS_TEXT_BASE /* Get reloc offset */
|
||||
rsub r23, r24, r23 /* keep - this is already here gd->reloc_off */
|
||||
|
||||
addik r6, r0, 0x2 /* BIG/LITTLE endian offset */
|
||||
lwi r7, r0, 0x28
|
||||
swi r6, r0, 0x28 /* used first unused MB vector */
|
||||
lbui r10, r0, 0x28 /* used first unused MB vector */
|
||||
swi r7, r0, 0x28
|
||||
|
||||
#ifdef CONFIG_SYS_USR_EXCEP
|
||||
addik r6, r0, _exception_handler
|
||||
addk r6, r6, r23 /* add offset */
|
||||
sw r6, r1, r0
|
||||
lhu r7, r1, r10
|
||||
rsubi r8, r10, 0xa
|
||||
sh r7, r0, r8
|
||||
rsubi r8, r10, 0xe
|
||||
sh r6, r0, r8
|
||||
#endif
|
||||
addik r6, r0, _hw_exception_handler
|
||||
addk r6, r6, r23 /* add offset */
|
||||
sw r6, r1, r0
|
||||
lhu r7, r1, r10
|
||||
rsubi r8, r10, 0x22
|
||||
sh r7, r0, r8
|
||||
rsubi r8, r10, 0x26
|
||||
sh r6, r0, r8
|
||||
|
||||
addik r6, r0, _interrupt_handler
|
||||
addk r6, r6, r23 /* add offset */
|
||||
sw r6, r1, r0
|
||||
lhu r7, r1, r10
|
||||
rsubi r8, r10, 0x12
|
||||
sh r7, r0, r8
|
||||
rsubi r8, r10, 0x16
|
||||
sh r6, r0, r8
|
||||
/* Setup vectors with post-relocation symbols */
|
||||
add r5, r0, r23 /* load gd->reloc_off to r5 */
|
||||
bralid r15, __setup_exceptions
|
||||
nop
|
||||
|
||||
/* Check if GOT exist */
|
||||
addik r21, r23, _got_start
|
||||
|
@ -50,9 +50,34 @@ config XILINX_OF_BOARD_DTB_ADDR
|
||||
|
||||
config BOOT_SCRIPT_OFFSET
|
||||
hex "Boot script offset"
|
||||
depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL
|
||||
default 0xFC0000 if ARCH_ZYNQ
|
||||
depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL || MICROBLAZE
|
||||
default 0xFC0000 if ARCH_ZYNQ || MICROBLAZE
|
||||
default 0x3E80000 if ARCH_ZYNQMP
|
||||
default 0x7F80000 if ARCH_VERSAL
|
||||
help
|
||||
Specifies distro boot script offset in NAND/NOR flash.
|
||||
Specifies distro boot script offset in NAND/QSPI/NOR flash.
|
||||
|
||||
config ZYNQ_MAC_IN_EEPROM
|
||||
bool "Reading MAC address from EEPROM"
|
||||
help
|
||||
Enable this option if your MAC address is saved in eeprom and
|
||||
xlnx,eeprom DT property in chosen node points to it.
|
||||
|
||||
if ZYNQ_MAC_IN_EEPROM
|
||||
|
||||
config ZYNQ_GEM_I2C_MAC_OFFSET
|
||||
hex "Set the I2C MAC offset"
|
||||
default 0x0
|
||||
depends on DM_I2C
|
||||
help
|
||||
Set the MAC offset for i2C.
|
||||
|
||||
endif
|
||||
|
||||
config CMD_FRU
|
||||
bool "FRU information for product"
|
||||
help
|
||||
This option enables FRU commands to capture and display FRU
|
||||
information present in the device. The FRU Information is used
|
||||
to primarily to provide "inventory" information about the boards
|
||||
that the FRU Information Device is located on.
|
||||
|
10
board/xilinx/common/Makefile
Normal file
10
board/xilinx/common/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# (C) Copyright 2020 Xilinx, Inc.
|
||||
# Michal Simek <michal.simek@xilinx.com>
|
||||
#
|
||||
|
||||
obj-y += board.o
|
||||
ifndef CONFIG_SPL_BUILD
|
||||
obj-$(CONFIG_CMD_FRU) += fru.o fru_ops.o
|
||||
endif
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2014 - 2019 Xilinx, Inc.
|
||||
* (C) Copyright 2014 - 2020 Xilinx, Inc.
|
||||
* Michal Simek <michal.simek@xilinx.com>
|
||||
*/
|
||||
|
||||
@ -11,7 +11,14 @@
|
||||
#include <dm/uclass.h>
|
||||
#include <i2c.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <malloc.h>
|
||||
#include "board.h"
|
||||
#include <dm.h>
|
||||
#include <i2c_eeprom.h>
|
||||
#include <net.h>
|
||||
#include <generated/dt.h>
|
||||
|
||||
#include "fru.h"
|
||||
|
||||
#if defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET)
|
||||
int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
|
||||
@ -41,6 +48,277 @@ int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
|
||||
}
|
||||
#endif
|
||||
|
||||
#define EEPROM_HEADER_MAGIC 0xdaaddeed
|
||||
#define EEPROM_HDR_MANUFACTURER_LEN 16
|
||||
#define EEPROM_HDR_NAME_LEN 16
|
||||
#define EEPROM_HDR_REV_LEN 8
|
||||
#define EEPROM_HDR_SERIAL_LEN 20
|
||||
#define EEPROM_HDR_NO_OF_MAC_ADDR 4
|
||||
#define EEPROM_HDR_ETH_ALEN ETH_ALEN
|
||||
|
||||
struct xilinx_board_description {
|
||||
u32 header;
|
||||
char manufacturer[EEPROM_HDR_MANUFACTURER_LEN + 1];
|
||||
char name[EEPROM_HDR_NAME_LEN + 1];
|
||||
char revision[EEPROM_HDR_REV_LEN + 1];
|
||||
char serial[EEPROM_HDR_SERIAL_LEN + 1];
|
||||
u8 mac_addr[EEPROM_HDR_NO_OF_MAC_ADDR][EEPROM_HDR_ETH_ALEN + 1];
|
||||
};
|
||||
|
||||
static int highest_id = -1;
|
||||
static struct xilinx_board_description **board_info;
|
||||
|
||||
#define XILINX_I2C_DETECTION_BITS sizeof(struct fru_common_hdr)
|
||||
|
||||
/* Variable which stores pointer to array which stores eeprom content */
|
||||
struct xilinx_legacy_format {
|
||||
char board_sn[18]; /* 0x0 */
|
||||
char unused0[14]; /* 0x12 */
|
||||
char eth_mac[6]; /* 0x20 */
|
||||
char unused1[170]; /* 0x26 */
|
||||
char board_name[11]; /* 0xd0 */
|
||||
char unused2[5]; /* 0xdc */
|
||||
char board_revision[3]; /* 0xe0 */
|
||||
char unused3[29]; /* 0xe3 */
|
||||
};
|
||||
|
||||
static void xilinx_eeprom_legacy_cleanup(char *eeprom, int size)
|
||||
{
|
||||
int i;
|
||||
char byte;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
byte = eeprom[i];
|
||||
|
||||
/* Remove all ffs and spaces */
|
||||
if (byte == 0xff || byte == ' ')
|
||||
eeprom[i] = 0;
|
||||
|
||||
/* Convert strings to lower case */
|
||||
if (byte >= 'A' && byte <= 'Z')
|
||||
eeprom[i] = byte + 'a' - 'A';
|
||||
}
|
||||
}
|
||||
|
||||
static int xilinx_read_eeprom_legacy(struct udevice *dev, char *name,
|
||||
struct xilinx_board_description *desc)
|
||||
{
|
||||
int ret, size;
|
||||
struct xilinx_legacy_format *eeprom_content;
|
||||
bool eth_valid = false;
|
||||
|
||||
size = sizeof(*eeprom_content);
|
||||
|
||||
eeprom_content = calloc(1, size);
|
||||
if (!eeprom_content)
|
||||
return -ENOMEM;
|
||||
|
||||
debug("%s: I2C EEPROM read pass data at %p\n", __func__,
|
||||
eeprom_content);
|
||||
|
||||
ret = dm_i2c_read(dev, 0, (uchar *)eeprom_content, size);
|
||||
if (ret) {
|
||||
debug("%s: I2C EEPROM read failed\n", __func__);
|
||||
free(eeprom_content);
|
||||
return ret;
|
||||
}
|
||||
|
||||
xilinx_eeprom_legacy_cleanup((char *)eeprom_content, size);
|
||||
|
||||
printf("Xilinx I2C Legacy format at %s:\n", name);
|
||||
printf(" Board name:\t%s\n", eeprom_content->board_name);
|
||||
printf(" Board rev:\t%s\n", eeprom_content->board_revision);
|
||||
printf(" Board SN:\t%s\n", eeprom_content->board_sn);
|
||||
|
||||
eth_valid = is_valid_ethaddr((const u8 *)eeprom_content->eth_mac);
|
||||
if (eth_valid)
|
||||
printf(" Ethernet mac:\t%pM\n", eeprom_content->eth_mac);
|
||||
|
||||
/* Terminating \0 chars ensure end of string */
|
||||
strcpy(desc->name, eeprom_content->board_name);
|
||||
strcpy(desc->revision, eeprom_content->board_revision);
|
||||
strcpy(desc->serial, eeprom_content->board_sn);
|
||||
if (eth_valid)
|
||||
memcpy(desc->mac_addr[0], eeprom_content->eth_mac, ETH_ALEN);
|
||||
|
||||
desc->header = EEPROM_HEADER_MAGIC;
|
||||
|
||||
free(eeprom_content);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool xilinx_detect_legacy(u8 *buffer)
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
|
||||
for (i = 0; i < XILINX_I2C_DETECTION_BITS; i++) {
|
||||
c = buffer[i];
|
||||
|
||||
if (c < '0' || c > '9')
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int xilinx_read_eeprom_fru(struct udevice *dev, char *name,
|
||||
struct xilinx_board_description *desc)
|
||||
{
|
||||
int ret, eeprom_size;
|
||||
u8 *fru_content;
|
||||
|
||||
/* FIXME this is shortcut - if eeprom type is wrong it will fail */
|
||||
eeprom_size = i2c_eeprom_size(dev);
|
||||
|
||||
fru_content = calloc(1, eeprom_size);
|
||||
if (!fru_content)
|
||||
return -ENOMEM;
|
||||
|
||||
debug("%s: I2C EEPROM read pass data at %p\n", __func__,
|
||||
fru_content);
|
||||
|
||||
ret = dm_i2c_read(dev, 0, (uchar *)fru_content,
|
||||
eeprom_size);
|
||||
if (ret) {
|
||||
debug("%s: I2C EEPROM read failed\n", __func__);
|
||||
free(fru_content);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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 (desc->header == EEPROM_HEADER_MAGIC) {
|
||||
debug("Information already filled\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* It is clear that FRU was captured and structures were filled */
|
||||
strncpy(desc->manufacturer, (char *)fru_data.brd.manufacturer_name,
|
||||
sizeof(desc->manufacturer));
|
||||
strncpy(desc->name, (char *)fru_data.brd.product_name,
|
||||
sizeof(desc->name));
|
||||
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;
|
||||
}
|
||||
|
||||
static bool xilinx_detect_fru(u8 *buffer)
|
||||
{
|
||||
u8 checksum = 0;
|
||||
int i;
|
||||
|
||||
checksum = fru_checksum((u8 *)buffer, sizeof(struct fru_common_hdr));
|
||||
if (checksum) {
|
||||
debug("%s Common header CRC FAIL\n", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool all_zeros = true;
|
||||
/* Checksum over all zeros is also zero that's why detect this case */
|
||||
for (i = 0; i < sizeof(struct fru_common_hdr); i++) {
|
||||
if (buffer[i] != 0)
|
||||
all_zeros = false;
|
||||
}
|
||||
|
||||
if (all_zeros)
|
||||
return false;
|
||||
|
||||
debug("%s Common header CRC PASS\n", __func__);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int xilinx_read_eeprom_single(char *name,
|
||||
struct xilinx_board_description *desc)
|
||||
{
|
||||
int ret;
|
||||
struct udevice *dev;
|
||||
ofnode eeprom;
|
||||
u8 buffer[XILINX_I2C_DETECTION_BITS];
|
||||
|
||||
eeprom = ofnode_get_aliases_node(name);
|
||||
if (!ofnode_valid(eeprom))
|
||||
return -ENODEV;
|
||||
|
||||
ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, eeprom, &dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = dm_i2c_read(dev, 0, buffer, sizeof(buffer));
|
||||
if (ret) {
|
||||
debug("%s: I2C EEPROM read failed\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
debug("%s: i2c memory detected: %s\n", __func__, name);
|
||||
|
||||
if (CONFIG_IS_ENABLED(CMD_FRU) && xilinx_detect_fru(buffer))
|
||||
return xilinx_read_eeprom_fru(dev, name, desc);
|
||||
|
||||
if (xilinx_detect_legacy(buffer))
|
||||
return xilinx_read_eeprom_legacy(dev, name, desc);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
__maybe_unused int xilinx_read_eeprom(void)
|
||||
{
|
||||
int id, ret;
|
||||
char name_buf[8]; /* 8 bytes should be enough for nvmem+number */
|
||||
struct xilinx_board_description *desc;
|
||||
|
||||
highest_id = dev_read_alias_highest_id("nvmem");
|
||||
/* No nvmem aliases present */
|
||||
if (highest_id < 0)
|
||||
return -EINVAL;
|
||||
|
||||
board_info = calloc(1, sizeof(desc) * highest_id);
|
||||
if (!board_info)
|
||||
return -ENOMEM;
|
||||
|
||||
debug("%s: Highest ID %d, board_info %p\n", __func__,
|
||||
highest_id, board_info);
|
||||
|
||||
for (id = 0; id <= highest_id; id++) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* Ignoring return value for supporting multiple chips */
|
||||
ret = xilinx_read_eeprom_single(name_buf, desc);
|
||||
if (ret) {
|
||||
free(desc);
|
||||
board_info[id] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Consider to clean board_info structure when board/cards are not
|
||||
* detected.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE)
|
||||
void *board_fdt_blob_setup(void)
|
||||
{
|
||||
@ -75,12 +353,36 @@ void *board_fdt_blob_setup(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BOARD_LATE_INIT)
|
||||
static int env_set_by_index(const char *name, int index, char *data)
|
||||
{
|
||||
char var[32];
|
||||
|
||||
if (!index)
|
||||
sprintf(var, "board_%s", name);
|
||||
else
|
||||
sprintf(var, "card%d_%s", index, name);
|
||||
|
||||
return env_set(var, data);
|
||||
}
|
||||
|
||||
int board_late_init_xilinx(void)
|
||||
{
|
||||
u32 ret = 0;
|
||||
int i, id, macid = 0;
|
||||
struct xilinx_board_description *desc;
|
||||
phys_size_t bootm_size = gd->ram_size;
|
||||
struct bd_info *bd = gd->bd;
|
||||
|
||||
if (CONFIG_IS_ENABLED(ARCH_ZYNQ))
|
||||
if (!CONFIG_IS_ENABLED(MICROBLAZE) && bd->bi_dram[0].start) {
|
||||
ulong scriptaddr;
|
||||
|
||||
scriptaddr = env_get_hex("scriptaddr", 0);
|
||||
ret |= env_set_hex("scriptaddr",
|
||||
bd->bi_dram[0].start + scriptaddr);
|
||||
}
|
||||
|
||||
if (CONFIG_IS_ENABLED(ARCH_ZYNQ) || CONFIG_IS_ENABLED(MICROBLAZE))
|
||||
bootm_size = min(bootm_size, (phys_size_t)(SZ_512M + SZ_256M));
|
||||
|
||||
ret |= env_set_hex("script_offset_f", CONFIG_BOOT_SCRIPT_OFFSET);
|
||||
@ -88,8 +390,49 @@ int board_late_init_xilinx(void)
|
||||
ret |= env_set_addr("bootm_low", (void *)gd->ram_base);
|
||||
ret |= env_set_addr("bootm_size", (void *)bootm_size);
|
||||
|
||||
for (id = 0; id <= highest_id; id++) {
|
||||
desc = board_info[id];
|
||||
if (desc && desc->header == EEPROM_HEADER_MAGIC) {
|
||||
if (desc->manufacturer[0])
|
||||
ret |= env_set_by_index("manufacturer", id,
|
||||
desc->manufacturer);
|
||||
if (desc->name[0])
|
||||
ret |= env_set_by_index("name", id,
|
||||
desc->name);
|
||||
if (desc->revision[0])
|
||||
ret |= env_set_by_index("rev", id,
|
||||
desc->revision);
|
||||
if (desc->serial[0])
|
||||
ret |= env_set_by_index("serial", id,
|
||||
desc->serial);
|
||||
|
||||
if (!CONFIG_IS_ENABLED(NET))
|
||||
continue;
|
||||
|
||||
for (i = 0; i < EEPROM_HDR_NO_OF_MAC_ADDR; i++) {
|
||||
if (!desc->mac_addr[i])
|
||||
continue;
|
||||
|
||||
if (is_valid_ethaddr((const u8 *)desc->mac_addr[i]))
|
||||
ret |= eth_env_set_enetaddr_by_index("eth",
|
||||
macid++, desc->mac_addr[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
printf("%s: Saving run time variables FAILED\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int __maybe_unused board_fit_config_name_match(const char *name)
|
||||
{
|
||||
debug("%s: Check %s, default %s\n", __func__, name, DEVICE_TREE);
|
||||
|
||||
if (!strcmp(name, DEVICE_TREE))
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -9,4 +9,6 @@
|
||||
|
||||
int board_late_init_xilinx(void);
|
||||
|
||||
int xilinx_read_eeprom(void);
|
||||
|
||||
#endif /* BOARD_XILINX_COMMON_BOARD_H */
|
||||
|
91
board/xilinx/common/fru.c
Normal file
91
board/xilinx/common/fru.c
Normal file
@ -0,0 +1,91 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* (C) Copyright 2019 - 2020 Xilinx, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <fdtdec.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "fru.h"
|
||||
|
||||
static int do_fru_capture(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
unsigned long addr;
|
||||
char *endp;
|
||||
|
||||
if (argc < cmdtp->maxargs)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
addr = simple_strtoul(argv[2], &endp, 16);
|
||||
if (*argv[1] == 0 || *endp != 0)
|
||||
return -1;
|
||||
|
||||
return fru_capture(addr);
|
||||
}
|
||||
|
||||
static int do_fru_display(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
fru_display(1);
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static int do_fru_generate(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
unsigned long addr;
|
||||
|
||||
if (argc < cmdtp->maxargs)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
addr = simple_strtoul(argv[2], NULL, 16);
|
||||
|
||||
return fru_generate(addr, argv[3], argv[4], argv[5], argv[6], argv[7]);
|
||||
}
|
||||
|
||||
static struct cmd_tbl cmd_fru_sub[] = {
|
||||
U_BOOT_CMD_MKENT(capture, 3, 0, do_fru_capture, "", ""),
|
||||
U_BOOT_CMD_MKENT(display, 2, 0, do_fru_display, "", ""),
|
||||
U_BOOT_CMD_MKENT(board_gen, 8, 0, do_fru_generate, "", ""),
|
||||
};
|
||||
|
||||
static int do_fru(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
struct cmd_tbl *c;
|
||||
int ret;
|
||||
|
||||
if (argc < 2)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
c = find_cmd_tbl(argv[1], &cmd_fru_sub[0],
|
||||
ARRAY_SIZE(cmd_fru_sub));
|
||||
if (!c)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
ret = c->cmd(c, flag, argc, argv);
|
||||
|
||||
return cmd_process_error(c, ret);
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
#ifdef CONFIG_SYS_LONGHELP
|
||||
static char fru_help_text[] =
|
||||
"capture <addr> - Parse and capture FRU table present at address.\n"
|
||||
"fru display - Displays content of FRU table that was captured using\n"
|
||||
" fru capture command\n"
|
||||
"fru board_gen <addr> <manufacturer> <board name> <serial number>\n"
|
||||
" <part number> <revision> - Generate FRU format with\n"
|
||||
" board info area filled based on parameters. <addr> is\n"
|
||||
" pointing to place where FRU is generated.\n"
|
||||
;
|
||||
#endif
|
||||
|
||||
U_BOOT_CMD(
|
||||
fru, 8, 1, do_fru,
|
||||
"FRU table info",
|
||||
fru_help_text
|
||||
)
|
83
board/xilinx/common/fru.h
Normal file
83
board/xilinx/common/fru.h
Normal file
@ -0,0 +1,83 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* (C) Copyright 2019 Xilinx, Inc.
|
||||
* Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
|
||||
*/
|
||||
|
||||
#ifndef __FRU_H
|
||||
#define __FRU_H
|
||||
|
||||
struct fru_common_hdr {
|
||||
u8 version;
|
||||
u8 off_internal;
|
||||
u8 off_chassis;
|
||||
u8 off_board;
|
||||
u8 off_product;
|
||||
u8 off_multirec;
|
||||
u8 pad;
|
||||
u8 crc;
|
||||
};
|
||||
|
||||
#define FRU_BOARD_MAX_LEN 32
|
||||
|
||||
struct __packed fru_board_info_header {
|
||||
u8 ver;
|
||||
u8 len;
|
||||
u8 lang_code;
|
||||
u8 time[3];
|
||||
};
|
||||
|
||||
struct __packed fru_board_info_member {
|
||||
u8 type_len;
|
||||
u8 *name;
|
||||
};
|
||||
|
||||
struct fru_board_data {
|
||||
u8 ver;
|
||||
u8 len;
|
||||
u8 lang_code;
|
||||
u8 time[3];
|
||||
u8 manufacturer_type_len;
|
||||
u8 manufacturer_name[FRU_BOARD_MAX_LEN];
|
||||
u8 product_name_type_len;
|
||||
u8 product_name[FRU_BOARD_MAX_LEN];
|
||||
u8 serial_number_type_len;
|
||||
u8 serial_number[FRU_BOARD_MAX_LEN];
|
||||
u8 part_number_type_len;
|
||||
u8 part_number[FRU_BOARD_MAX_LEN];
|
||||
u8 file_id_type_len;
|
||||
u8 file_id[FRU_BOARD_MAX_LEN];
|
||||
/* Xilinx custom fields */
|
||||
u8 rev_type_len;
|
||||
u8 rev[FRU_BOARD_MAX_LEN];
|
||||
};
|
||||
|
||||
struct fru_table {
|
||||
bool captured;
|
||||
struct fru_common_hdr hdr;
|
||||
struct fru_board_data brd;
|
||||
};
|
||||
|
||||
#define FRU_TYPELEN_CODE_MASK 0xC0
|
||||
#define FRU_TYPELEN_LEN_MASK 0x3F
|
||||
#define FRU_COMMON_HDR_VER_MASK 0xF
|
||||
#define FRU_COMMON_HDR_LEN_MULTIPLIER 8
|
||||
#define FRU_LANG_CODE_ENGLISH 0
|
||||
#define FRU_LANG_CODE_ENGLISH_1 25
|
||||
#define FRU_TYPELEN_EOF 0xC1
|
||||
|
||||
/* This should be minimum of fields */
|
||||
#define FRU_BOARD_AREA_TOTAL_FIELDS 5
|
||||
#define FRU_TYPELEN_TYPE_SHIFT 6
|
||||
#define FRU_TYPELEN_TYPE_BINARY 0
|
||||
#define FRU_TYPELEN_TYPE_ASCII8 3
|
||||
|
||||
int fru_display(int verbose);
|
||||
int fru_capture(unsigned long addr);
|
||||
int fru_generate(unsigned long addr, char *manufacturer, char *board_name,
|
||||
char *serial_no, char *part_no, char *revision);
|
||||
u8 fru_checksum(u8 *addr, u8 len);
|
||||
|
||||
extern struct fru_table fru_data;
|
||||
|
||||
#endif /* FRU_H */
|
362
board/xilinx/common/fru_ops.c
Normal file
362
board/xilinx/common/fru_ops.c
Normal file
@ -0,0 +1,362 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* (C) Copyright 2019 - 2020 Xilinx, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <cpu_func.h>
|
||||
#include <env.h>
|
||||
#include <fdtdec.h>
|
||||
#include <log.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
|
||||
#include "fru.h"
|
||||
|
||||
struct fru_table fru_data __section(.data);
|
||||
|
||||
static u16 fru_cal_area_len(u8 len)
|
||||
{
|
||||
return len * FRU_COMMON_HDR_LEN_MULTIPLIER;
|
||||
}
|
||||
|
||||
static u8 fru_version(u8 ver)
|
||||
{
|
||||
return ver & FRU_COMMON_HDR_VER_MASK;
|
||||
}
|
||||
|
||||
static int fru_check_language(u8 code)
|
||||
{
|
||||
if (code != FRU_LANG_CODE_ENGLISH && code != FRU_LANG_CODE_ENGLISH_1) {
|
||||
printf("FRU_ERROR: Only English Language is supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 fru_checksum(u8 *addr, u8 len)
|
||||
{
|
||||
u8 checksum = 0;
|
||||
|
||||
while (len--) {
|
||||
checksum += *addr;
|
||||
addr++;
|
||||
}
|
||||
|
||||
return checksum;
|
||||
}
|
||||
|
||||
static int fru_check_type_len(u8 type_len, u8 language, u8 *type)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (type_len == FRU_TYPELEN_EOF)
|
||||
return -EINVAL;
|
||||
|
||||
*type = (type_len & FRU_TYPELEN_CODE_MASK) >> FRU_TYPELEN_TYPE_SHIFT;
|
||||
|
||||
len = type_len & FRU_TYPELEN_LEN_MASK;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Return len */
|
||||
static u8 fru_gen_type_len(u8 *addr, char *name)
|
||||
{
|
||||
int len = strlen(name);
|
||||
struct fru_board_info_member *member;
|
||||
|
||||
member = (struct fru_board_info_member *)addr;
|
||||
member->type_len = FRU_TYPELEN_TYPE_ASCII8 << FRU_TYPELEN_TYPE_SHIFT;
|
||||
member->type_len |= len;
|
||||
|
||||
debug("%lx/%lx: Add %s to 0x%lx (len 0x%x)\n", (ulong)addr,
|
||||
(ulong)&member->type_len, name, (ulong)&member->name, len);
|
||||
memcpy(&member->name, name, len);
|
||||
|
||||
/* Add +1 for type_len parameter */
|
||||
return 1 + len;
|
||||
}
|
||||
|
||||
int fru_generate(unsigned long addr, char *manufacturer, char *board_name,
|
||||
char *serial_no, char *part_no, char *revision)
|
||||
{
|
||||
struct fru_common_hdr *header = (struct fru_common_hdr *)addr;
|
||||
struct fru_board_info_header *board_info;
|
||||
u8 *member;
|
||||
u8 len, pad, modulo;
|
||||
|
||||
header->version = 1; /* Only version 1.0 is supported now */
|
||||
header->off_internal = 0; /* not present */
|
||||
header->off_chassis = 0; /* not present */
|
||||
header->off_board = (sizeof(*header)) / 8; /* Starting offset 8 */
|
||||
header->off_product = 0; /* not present */
|
||||
header->off_multirec = 0; /* not present */
|
||||
header->pad = 0;
|
||||
/*
|
||||
* This unsigned byte can be used to calculate a zero checksum
|
||||
* for the data area following the header. I.e. the modulo 256 sum of
|
||||
* the record data bytes plus the checksum byte equals zero.
|
||||
*/
|
||||
header->crc = 0; /* Clear before calculation */
|
||||
header->crc = 0 - fru_checksum((u8 *)header, sizeof(*header));
|
||||
|
||||
/* board info is just right after header */
|
||||
board_info = (void *)((u8 *)header + sizeof(*header));
|
||||
|
||||
debug("header %lx, board_info %lx\n", (ulong)header, (ulong)board_info);
|
||||
|
||||
board_info->ver = 1; /* 1.0 spec */
|
||||
board_info->lang_code = 0; /* English */
|
||||
board_info->time[0] = 0; /* unspecified */
|
||||
board_info->time[1] = 0; /* unspecified */
|
||||
board_info->time[2] = 0; /* unspecified */
|
||||
|
||||
/* Member fields are just after board_info header */
|
||||
member = (u8 *)board_info + sizeof(*board_info);
|
||||
|
||||
len = fru_gen_type_len(member, manufacturer); /* Board Manufacturer */
|
||||
member += len;
|
||||
len = fru_gen_type_len(member, board_name); /* Board Product name */
|
||||
member += len;
|
||||
len = fru_gen_type_len(member, serial_no); /* Board Serial number */
|
||||
member += len;
|
||||
len = fru_gen_type_len(member, part_no); /* Board part number */
|
||||
member += len;
|
||||
len = fru_gen_type_len(member, "U-Boot generator"); /* File ID */
|
||||
member += len;
|
||||
len = fru_gen_type_len(member, revision); /* Revision */
|
||||
member += len;
|
||||
|
||||
*member++ = 0xc1; /* Indication of no more fields */
|
||||
|
||||
len = member - (u8 *)board_info; /* Find current length */
|
||||
len += 1; /* Add checksum there too for calculation */
|
||||
|
||||
modulo = len % 8;
|
||||
|
||||
if (modulo) {
|
||||
/* Do not fill last item which is checksum */
|
||||
for (pad = 0; pad < 8 - modulo; pad++)
|
||||
*member++ = 0;
|
||||
|
||||
/* Increase structure size */
|
||||
len += 8 - modulo;
|
||||
}
|
||||
|
||||
board_info->len = len / 8; /* Size in multiples of 8 bytes */
|
||||
|
||||
*member = 0; /* Clear before calculation */
|
||||
*member = 0 - fru_checksum((u8 *)board_info, len);
|
||||
|
||||
debug("checksum %x(addr %x)\n", *member, len);
|
||||
|
||||
env_set_hex("fru_addr", addr);
|
||||
env_set_hex("filesize", (unsigned long)member - addr + 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fru_parse_board(unsigned long addr)
|
||||
{
|
||||
u8 i, type;
|
||||
int len;
|
||||
u8 *data, *term;
|
||||
|
||||
memcpy(&fru_data.brd.ver, (void *)addr, 6);
|
||||
addr += 6;
|
||||
data = (u8 *)&fru_data.brd.manufacturer_type_len;
|
||||
|
||||
for (i = 0; ; i++, data += FRU_BOARD_MAX_LEN) {
|
||||
len = fru_check_type_len(*(u8 *)addr, fru_data.brd.lang_code,
|
||||
&type);
|
||||
/*
|
||||
* Stop cature if it end of fields
|
||||
*/
|
||||
if (len == -EINVAL)
|
||||
break;
|
||||
|
||||
/* This record type/len field */
|
||||
*data++ = *(u8 *)addr;
|
||||
|
||||
/* Add offset to match data */
|
||||
addr += 1;
|
||||
|
||||
/* If len is 0 it means empty field that's why skip writing */
|
||||
if (!len)
|
||||
continue;
|
||||
|
||||
/* Record data field */
|
||||
memcpy(data, (u8 *)addr, len);
|
||||
term = data + (u8)len;
|
||||
*term = 0;
|
||||
addr += len;
|
||||
}
|
||||
|
||||
if (i < FRU_BOARD_AREA_TOTAL_FIELDS) {
|
||||
printf("Board area require minimum %d fields\n",
|
||||
FRU_BOARD_AREA_TOTAL_FIELDS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fru_capture(unsigned long addr)
|
||||
{
|
||||
struct fru_common_hdr *hdr;
|
||||
u8 checksum = 0;
|
||||
|
||||
checksum = fru_checksum((u8 *)addr, sizeof(struct fru_common_hdr));
|
||||
if (checksum) {
|
||||
printf("%s Common header CRC error\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdr = (struct fru_common_hdr *)addr;
|
||||
|
||||
memcpy((void *)&fru_data.hdr, (void *)hdr,
|
||||
sizeof(struct fru_common_hdr));
|
||||
|
||||
fru_data.captured = true;
|
||||
|
||||
if (hdr->off_board) {
|
||||
addr += fru_cal_area_len(hdr->off_board);
|
||||
fru_parse_board(addr);
|
||||
}
|
||||
|
||||
env_set_hex("fru_addr", addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fru_display_board(struct fru_board_data *brd, int verbose)
|
||||
{
|
||||
u32 time = 0;
|
||||
u8 type;
|
||||
int len;
|
||||
u8 *data;
|
||||
static const char * const typecode[] = {
|
||||
"Binary/Unspecified",
|
||||
"BCD plus",
|
||||
"6-bit ASCII",
|
||||
"8-bit ASCII",
|
||||
"2-byte UNICODE"
|
||||
};
|
||||
static const char * const boardinfo[] = {
|
||||
"Manufacturer Name",
|
||||
"Product Name",
|
||||
"Serial No",
|
||||
"Part Number",
|
||||
"File ID",
|
||||
/* Xilinx spec */
|
||||
"Revision Number",
|
||||
};
|
||||
|
||||
if (verbose) {
|
||||
printf("*****BOARD INFO*****\n");
|
||||
printf("Version:%d\n", fru_version(brd->ver));
|
||||
printf("Board Area Length:%d\n", fru_cal_area_len(brd->len));
|
||||
}
|
||||
|
||||
if (fru_check_language(brd->lang_code))
|
||||
return -EINVAL;
|
||||
|
||||
time = brd->time[2] << 16 | brd->time[1] << 8 |
|
||||
brd->time[0];
|
||||
|
||||
if (verbose)
|
||||
printf("Time in Minutes from 0:00hrs 1/1/96: %d\n", time);
|
||||
|
||||
data = (u8 *)&brd->manufacturer_type_len;
|
||||
|
||||
for (u8 i = 0; i < (sizeof(boardinfo) / sizeof(*boardinfo)); i++) {
|
||||
len = fru_check_type_len(*data++, brd->lang_code,
|
||||
&type);
|
||||
if (len == -EINVAL) {
|
||||
printf("**** EOF for Board Area ****\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (type <= FRU_TYPELEN_TYPE_ASCII8 &&
|
||||
(brd->lang_code == FRU_LANG_CODE_ENGLISH ||
|
||||
brd->lang_code == FRU_LANG_CODE_ENGLISH_1))
|
||||
debug("Type code: %s\n", typecode[type]);
|
||||
else
|
||||
debug("Type code: %s\n", typecode[type + 1]);
|
||||
|
||||
if (!len) {
|
||||
debug("%s not found\n", boardinfo[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case FRU_TYPELEN_TYPE_BINARY:
|
||||
debug("Length: %d\n", len);
|
||||
printf(" %s: 0x%x\n", boardinfo[i], *data);
|
||||
break;
|
||||
case FRU_TYPELEN_TYPE_ASCII8:
|
||||
debug("Length: %d\n", len);
|
||||
printf(" %s: %s\n", boardinfo[i], data);
|
||||
break;
|
||||
default:
|
||||
debug("Unsupported type %x\n", type);
|
||||
}
|
||||
|
||||
data += FRU_BOARD_MAX_LEN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fru_display_common_hdr(struct fru_common_hdr *hdr, int verbose)
|
||||
{
|
||||
if (!verbose)
|
||||
return;
|
||||
|
||||
printf("*****COMMON HEADER*****\n");
|
||||
printf("Version:%d\n", fru_version(hdr->version));
|
||||
if (hdr->off_internal)
|
||||
printf("Internal Use Area Offset:%d\n",
|
||||
fru_cal_area_len(hdr->off_internal));
|
||||
else
|
||||
printf("*** No Internal Area ***\n");
|
||||
|
||||
if (hdr->off_chassis)
|
||||
printf("Chassis Info Area Offset:%d\n",
|
||||
fru_cal_area_len(hdr->off_chassis));
|
||||
else
|
||||
printf("*** No Chassis Info Area ***\n");
|
||||
|
||||
if (hdr->off_board)
|
||||
printf("Board Area Offset:%d\n",
|
||||
fru_cal_area_len(hdr->off_board));
|
||||
else
|
||||
printf("*** No Board Area ***\n");
|
||||
|
||||
if (hdr->off_product)
|
||||
printf("Product Info Area Offset:%d\n",
|
||||
fru_cal_area_len(hdr->off_product));
|
||||
else
|
||||
printf("*** No Product Info Area ***\n");
|
||||
|
||||
if (hdr->off_multirec)
|
||||
printf("MultiRecord Area Offset:%d\n",
|
||||
fru_cal_area_len(hdr->off_multirec));
|
||||
else
|
||||
printf("*** No MultiRecord Area ***\n");
|
||||
}
|
||||
|
||||
int fru_display(int verbose)
|
||||
{
|
||||
if (!fru_data.captured) {
|
||||
printf("FRU data not available please run fru parse\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fru_display_common_hdr(&fru_data.hdr, verbose);
|
||||
|
||||
return fru_display_board(&fru_data.brd, verbose);
|
||||
}
|
@ -18,6 +18,7 @@
|
||||
#include <dm/lists.h>
|
||||
#include <fdtdec.h>
|
||||
#include <linux/sizes.h>
|
||||
#include "../common/board.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@ -36,7 +37,8 @@ int dram_init(void)
|
||||
|
||||
int board_late_init(void)
|
||||
{
|
||||
ulong max_size, lowmem_size;
|
||||
ulong max_size;
|
||||
u32 status = 0;
|
||||
|
||||
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SYSRESET_MICROBLAZE)
|
||||
int ret;
|
||||
@ -55,12 +57,19 @@ int board_late_init(void)
|
||||
max_size = gd->start_addr_sp - CONFIG_STACK_SIZE;
|
||||
max_size = round_down(max_size, SZ_16M);
|
||||
|
||||
/* Linux default LOWMEM_SIZE is 0x30000000 = 768MB */
|
||||
lowmem_size = gd->ram_base + 768 * 1024 * 1024;
|
||||
status |= env_set_hex("scriptaddr", max_size + SZ_2M);
|
||||
|
||||
env_set_addr("initrd_high", (void *)min_t(ulong, max_size,
|
||||
lowmem_size));
|
||||
env_set_addr("fdt_high", (void *)min_t(ulong, max_size, lowmem_size));
|
||||
status |= env_set_hex("pxefile_addr_r", max_size + SZ_1M);
|
||||
|
||||
return 0;
|
||||
status |= env_set_hex("kernel_addr_r", gd->ram_base + SZ_32M);
|
||||
|
||||
status |= env_set_hex("fdt_addr_r", gd->ram_base + SZ_32M - SZ_1M);
|
||||
|
||||
status |= env_set_hex("ramdisk_addr_r",
|
||||
gd->ram_base + SZ_32M + SZ_4M + SZ_2M);
|
||||
|
||||
if (status)
|
||||
printf("%s: Saving run time variables FAILED\n", __func__);
|
||||
|
||||
return board_late_init_xilinx();
|
||||
}
|
||||
|
@ -6,4 +6,3 @@
|
||||
|
||||
obj-y := board.o
|
||||
obj-$(CONFIG_CMD_VERSAL) += cmds.o
|
||||
obj-y += ../common/board.o
|
||||
|
@ -36,6 +36,9 @@ int board_init(void)
|
||||
fpga_add(fpga_xilinx, &versalpl);
|
||||
#endif
|
||||
|
||||
if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM))
|
||||
xilinx_read_eeprom();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
|
||||
obj-y := board.o
|
||||
obj-y += ../common/board.o
|
||||
|
||||
ifneq ($(CONFIG_XILINX_PS_INIT_FILE),"")
|
||||
PS_INIT_FILE := $(shell cd $(srctree); readlink -f $(CONFIG_XILINX_PS_INIT_FILE))
|
||||
|
273
board/xilinx/zynq/zynq-zturn-v5/ps7_init_gpl.c
Normal file
273
board/xilinx/zynq/zynq-zturn-v5/ps7_init_gpl.c
Normal file
@ -0,0 +1,273 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) Xilinx, Inc.
|
||||
*/
|
||||
|
||||
#include <asm/arch/ps7_init_gpl.h>
|
||||
|
||||
static unsigned long ps7_pll_init_data[] = {
|
||||
EMIT_WRITE(0xF8000008, 0x0000DF0DU),
|
||||
EMIT_MASKWRITE(0xF8000110, 0x003FFFF0U, 0x000FA220U),
|
||||
EMIT_MASKWRITE(0xF8000100, 0x0007F000U, 0x00028000U),
|
||||
EMIT_MASKWRITE(0xF8000100, 0x00000010U, 0x00000010U),
|
||||
EMIT_MASKWRITE(0xF8000100, 0x00000001U, 0x00000001U),
|
||||
EMIT_MASKWRITE(0xF8000100, 0x00000001U, 0x00000000U),
|
||||
EMIT_MASKPOLL(0xF800010C, 0x00000001U),
|
||||
EMIT_MASKWRITE(0xF8000100, 0x00000010U, 0x00000000U),
|
||||
EMIT_MASKWRITE(0xF8000120, 0x1F003F30U, 0x1F000200U),
|
||||
EMIT_MASKWRITE(0xF8000114, 0x003FFFF0U, 0x0012C220U),
|
||||
EMIT_MASKWRITE(0xF8000104, 0x0007F000U, 0x00020000U),
|
||||
EMIT_MASKWRITE(0xF8000104, 0x00000010U, 0x00000010U),
|
||||
EMIT_MASKWRITE(0xF8000104, 0x00000001U, 0x00000001U),
|
||||
EMIT_MASKWRITE(0xF8000104, 0x00000001U, 0x00000000U),
|
||||
EMIT_MASKPOLL(0xF800010C, 0x00000002U),
|
||||
EMIT_MASKWRITE(0xF8000104, 0x00000010U, 0x00000000U),
|
||||
EMIT_MASKWRITE(0xF8000124, 0xFFF00003U, 0x0C200003U),
|
||||
EMIT_MASKWRITE(0xF8000118, 0x003FFFF0U, 0x001452C0U),
|
||||
EMIT_MASKWRITE(0xF8000108, 0x0007F000U, 0x0001E000U),
|
||||
EMIT_MASKWRITE(0xF8000108, 0x00000010U, 0x00000010U),
|
||||
EMIT_MASKWRITE(0xF8000108, 0x00000001U, 0x00000001U),
|
||||
EMIT_MASKWRITE(0xF8000108, 0x00000001U, 0x00000000U),
|
||||
EMIT_MASKPOLL(0xF800010C, 0x00000004U),
|
||||
EMIT_MASKWRITE(0xF8000108, 0x00000010U, 0x00000000U),
|
||||
EMIT_WRITE(0xF8000004, 0x0000767BU),
|
||||
EMIT_EXIT(),
|
||||
};
|
||||
|
||||
static unsigned long ps7_clock_init_data[] = {
|
||||
EMIT_WRITE(0xF8000008, 0x0000DF0DU),
|
||||
EMIT_MASKWRITE(0xF8000128, 0x03F03F01U, 0x00700F01U),
|
||||
EMIT_MASKWRITE(0xF8000138, 0x00000011U, 0x00000001U),
|
||||
EMIT_MASKWRITE(0xF8000140, 0x03F03F71U, 0x00100801U),
|
||||
EMIT_MASKWRITE(0xF800014C, 0x00003F31U, 0x00000501U),
|
||||
EMIT_MASKWRITE(0xF8000150, 0x00003F33U, 0x00001401U),
|
||||
EMIT_MASKWRITE(0xF8000154, 0x00003F33U, 0x00000A03U),
|
||||
EMIT_MASKWRITE(0xF800015C, 0x03F03F33U, 0x00200501U),
|
||||
EMIT_MASKWRITE(0xF8000160, 0x007F007FU, 0x00000000U),
|
||||
EMIT_MASKWRITE(0xF8000168, 0x00003F31U, 0x00000501U),
|
||||
EMIT_MASKWRITE(0xF8000170, 0x03F03F30U, 0x00200500U),
|
||||
EMIT_MASKWRITE(0xF8000180, 0x03F03F30U, 0x00400500U),
|
||||
EMIT_MASKWRITE(0xF80001C4, 0x00000001U, 0x00000001U),
|
||||
EMIT_MASKWRITE(0xF800012C, 0x01FFCCCDU, 0x01FD044DU),
|
||||
EMIT_WRITE(0xF8000004, 0x0000767BU),
|
||||
EMIT_EXIT(),
|
||||
};
|
||||
|
||||
static unsigned long ps7_ddr_init_data[] = {
|
||||
EMIT_MASKWRITE(0xF8006000, 0x0001FFFFU, 0x00000080U),
|
||||
EMIT_MASKWRITE(0xF8006004, 0x0007FFFFU, 0x00001082U),
|
||||
EMIT_MASKWRITE(0xF8006008, 0x03FFFFFFU, 0x03C0780FU),
|
||||
EMIT_MASKWRITE(0xF800600C, 0x03FFFFFFU, 0x02001001U),
|
||||
EMIT_MASKWRITE(0xF8006010, 0x03FFFFFFU, 0x00014001U),
|
||||
EMIT_MASKWRITE(0xF8006014, 0x001FFFFFU, 0x0004285BU),
|
||||
EMIT_MASKWRITE(0xF8006018, 0xF7FFFFFFU, 0x44E458D3U),
|
||||
EMIT_MASKWRITE(0xF800601C, 0xFFFFFFFFU, 0x7282BCE5U),
|
||||
EMIT_MASKWRITE(0xF8006020, 0x7FDFFFFCU, 0x270872D0U),
|
||||
EMIT_MASKWRITE(0xF8006024, 0x0FFFFFC3U, 0x00000000U),
|
||||
EMIT_MASKWRITE(0xF8006028, 0x00003FFFU, 0x00002007U),
|
||||
EMIT_MASKWRITE(0xF800602C, 0xFFFFFFFFU, 0x00000008U),
|
||||
EMIT_MASKWRITE(0xF8006030, 0xFFFFFFFFU, 0x00040B30U),
|
||||
EMIT_MASKWRITE(0xF8006034, 0x13FF3FFFU, 0x000116D4U),
|
||||
EMIT_MASKWRITE(0xF8006038, 0x00000003U, 0x00000000U),
|
||||
EMIT_MASKWRITE(0xF800603C, 0x000FFFFFU, 0x00000777U),
|
||||
EMIT_MASKWRITE(0xF8006040, 0xFFFFFFFFU, 0xFFF00000U),
|
||||
EMIT_MASKWRITE(0xF8006044, 0x0FFFFFFFU, 0x0F666666U),
|
||||
EMIT_MASKWRITE(0xF8006048, 0x0003F03FU, 0x0003C008U),
|
||||
EMIT_MASKWRITE(0xF8006050, 0xFF0F8FFFU, 0x77010800U),
|
||||
EMIT_MASKWRITE(0xF8006058, 0x00010000U, 0x00000000U),
|
||||
EMIT_MASKWRITE(0xF800605C, 0x0000FFFFU, 0x00005003U),
|
||||
EMIT_MASKWRITE(0xF8006060, 0x000017FFU, 0x0000003EU),
|
||||
EMIT_MASKWRITE(0xF8006064, 0x00021FE0U, 0x00020000U),
|
||||
EMIT_MASKWRITE(0xF8006068, 0x03FFFFFFU, 0x00284141U),
|
||||
EMIT_MASKWRITE(0xF800606C, 0x0000FFFFU, 0x00001610U),
|
||||
EMIT_MASKWRITE(0xF8006078, 0x03FFFFFFU, 0x00466111U),
|
||||
EMIT_MASKWRITE(0xF800607C, 0x000FFFFFU, 0x00032222U),
|
||||
EMIT_MASKWRITE(0xF80060A4, 0xFFFFFFFFU, 0x10200802U),
|
||||
EMIT_MASKWRITE(0xF80060A8, 0x0FFFFFFFU, 0x0690CB73U),
|
||||
EMIT_MASKWRITE(0xF80060AC, 0x000001FFU, 0x000001FEU),
|
||||
EMIT_MASKWRITE(0xF80060B0, 0x1FFFFFFFU, 0x1CFFFFFFU),
|
||||
EMIT_MASKWRITE(0xF80060B4, 0x00000200U, 0x00000200U),
|
||||
EMIT_MASKWRITE(0xF80060B8, 0x01FFFFFFU, 0x00200066U),
|
||||
EMIT_MASKWRITE(0xF80060C4, 0x00000003U, 0x00000000U),
|
||||
EMIT_MASKWRITE(0xF80060C8, 0x000000FFU, 0x00000000U),
|
||||
EMIT_MASKWRITE(0xF80060DC, 0x00000001U, 0x00000000U),
|
||||
EMIT_MASKWRITE(0xF80060F0, 0x0000FFFFU, 0x00000000U),
|
||||
EMIT_MASKWRITE(0xF80060F4, 0x0000000FU, 0x00000008U),
|
||||
EMIT_MASKWRITE(0xF8006114, 0x000000FFU, 0x00000000U),
|
||||
EMIT_MASKWRITE(0xF8006118, 0x7FFFFFCFU, 0x40000001U),
|
||||
EMIT_MASKWRITE(0xF800611C, 0x7FFFFFCFU, 0x40000001U),
|
||||
EMIT_MASKWRITE(0xF8006120, 0x7FFFFFCFU, 0x40000001U),
|
||||
EMIT_MASKWRITE(0xF8006124, 0x7FFFFFCFU, 0x40000001U),
|
||||
EMIT_MASKWRITE(0xF800612C, 0x000FFFFFU, 0x0002A81FU),
|
||||
EMIT_MASKWRITE(0xF8006130, 0x000FFFFFU, 0x00029822U),
|
||||
EMIT_MASKWRITE(0xF8006134, 0x000FFFFFU, 0x00026C10U),
|
||||
EMIT_MASKWRITE(0xF8006138, 0x000FFFFFU, 0x00026013U),
|
||||
EMIT_MASKWRITE(0xF8006140, 0x000FFFFFU, 0x00000035U),
|
||||
EMIT_MASKWRITE(0xF8006144, 0x000FFFFFU, 0x00000035U),
|
||||
EMIT_MASKWRITE(0xF8006148, 0x000FFFFFU, 0x00000035U),
|
||||
EMIT_MASKWRITE(0xF800614C, 0x000FFFFFU, 0x00000035U),
|
||||
EMIT_MASKWRITE(0xF8006154, 0x000FFFFFU, 0x0000009FU),
|
||||
EMIT_MASKWRITE(0xF8006158, 0x000FFFFFU, 0x000000A2U),
|
||||
EMIT_MASKWRITE(0xF800615C, 0x000FFFFFU, 0x00000090U),
|
||||
EMIT_MASKWRITE(0xF8006160, 0x000FFFFFU, 0x00000093U),
|
||||
EMIT_MASKWRITE(0xF8006168, 0x001FFFFFU, 0x000000FFU),
|
||||
EMIT_MASKWRITE(0xF800616C, 0x001FFFFFU, 0x000000FBU),
|
||||
EMIT_MASKWRITE(0xF8006170, 0x001FFFFFU, 0x000000F0U),
|
||||
EMIT_MASKWRITE(0xF8006174, 0x001FFFFFU, 0x000000EDU),
|
||||
EMIT_MASKWRITE(0xF800617C, 0x000FFFFFU, 0x000000DFU),
|
||||
EMIT_MASKWRITE(0xF8006180, 0x000FFFFFU, 0x000000E2U),
|
||||
EMIT_MASKWRITE(0xF8006184, 0x000FFFFFU, 0x000000D0U),
|
||||
EMIT_MASKWRITE(0xF8006188, 0x000FFFFFU, 0x000000D3U),
|
||||
EMIT_MASKWRITE(0xF8006190, 0x6FFFFEFEU, 0x00040080U),
|
||||
EMIT_MASKWRITE(0xF8006194, 0x000FFFFFU, 0x0001FC82U),
|
||||
EMIT_MASKWRITE(0xF8006204, 0xFFFFFFFFU, 0x00000000U),
|
||||
EMIT_MASKWRITE(0xF8006208, 0x000703FFU, 0x000003FFU),
|
||||
EMIT_MASKWRITE(0xF800620C, 0x000703FFU, 0x000003FFU),
|
||||
EMIT_MASKWRITE(0xF8006210, 0x000703FFU, 0x000003FFU),
|
||||
EMIT_MASKWRITE(0xF8006214, 0x000703FFU, 0x000003FFU),
|
||||
EMIT_MASKWRITE(0xF8006218, 0x000F03FFU, 0x000003FFU),
|
||||
EMIT_MASKWRITE(0xF800621C, 0x000F03FFU, 0x000003FFU),
|
||||
EMIT_MASKWRITE(0xF8006220, 0x000F03FFU, 0x000003FFU),
|
||||
EMIT_MASKWRITE(0xF8006224, 0x000F03FFU, 0x000003FFU),
|
||||
EMIT_MASKWRITE(0xF80062A8, 0x00000FF5U, 0x00000000U),
|
||||
EMIT_MASKWRITE(0xF80062AC, 0xFFFFFFFFU, 0x00000000U),
|
||||
EMIT_MASKWRITE(0xF80062B0, 0x003FFFFFU, 0x00005125U),
|
||||
EMIT_MASKWRITE(0xF80062B4, 0x0003FFFFU, 0x000012A8U),
|
||||
EMIT_MASKPOLL(0xF8000B74, 0x00002000U),
|
||||
EMIT_MASKWRITE(0xF8006000, 0x0001FFFFU, 0x00000081U),
|
||||
EMIT_MASKPOLL(0xF8006054, 0x00000007U),
|
||||
EMIT_EXIT(),
|
||||
};
|
||||
|
||||
static unsigned long ps7_mio_init_data[] = {
|
||||
EMIT_WRITE(0xF8000008, 0x0000DF0DU),
|
||||
EMIT_MASKWRITE(0xF8000B40, 0x00000FFFU, 0x00000600U),
|
||||
EMIT_MASKWRITE(0xF8000B44, 0x00000FFFU, 0x00000600U),
|
||||
EMIT_MASKWRITE(0xF8000B48, 0x00000FFFU, 0x00000672U),
|
||||
EMIT_MASKWRITE(0xF8000B4C, 0x00000FFFU, 0x00000672U),
|
||||
EMIT_MASKWRITE(0xF8000B50, 0x00000FFFU, 0x00000674U),
|
||||
EMIT_MASKWRITE(0xF8000B54, 0x00000FFFU, 0x00000674U),
|
||||
EMIT_MASKWRITE(0xF8000B58, 0x00000FFFU, 0x00000600U),
|
||||
EMIT_MASKWRITE(0xF8000B5C, 0xFFFFFFFFU, 0x0018C61CU),
|
||||
EMIT_MASKWRITE(0xF8000B60, 0xFFFFFFFFU, 0x00F9861CU),
|
||||
EMIT_MASKWRITE(0xF8000B64, 0xFFFFFFFFU, 0x00F9861CU),
|
||||
EMIT_MASKWRITE(0xF8000B68, 0xFFFFFFFFU, 0x00F9861CU),
|
||||
EMIT_MASKWRITE(0xF8000B6C, 0x00007FFFU, 0x00000260U),
|
||||
EMIT_MASKWRITE(0xF8000B70, 0x00000001U, 0x00000001U),
|
||||
EMIT_MASKWRITE(0xF8000B70, 0x00000021U, 0x00000020U),
|
||||
EMIT_MASKWRITE(0xF8000B70, 0x07FEFFFFU, 0x00000823U),
|
||||
EMIT_MASKWRITE(0xF8000700, 0x00003FFFU, 0x00001600U),
|
||||
EMIT_MASKWRITE(0xF8000704, 0x00003FFFU, 0x00000602U),
|
||||
EMIT_MASKWRITE(0xF8000708, 0x00003FFFU, 0x00000602U),
|
||||
EMIT_MASKWRITE(0xF800070C, 0x00003FFFU, 0x00000602U),
|
||||
EMIT_MASKWRITE(0xF8000710, 0x00003FFFU, 0x00000602U),
|
||||
EMIT_MASKWRITE(0xF8000714, 0x00003FFFU, 0x00000602U),
|
||||
EMIT_MASKWRITE(0xF8000718, 0x00003FFFU, 0x00000602U),
|
||||
EMIT_MASKWRITE(0xF800071C, 0x00003FFFU, 0x00000600U),
|
||||
EMIT_MASKWRITE(0xF8000720, 0x00003FFFU, 0x00000602U),
|
||||
EMIT_MASKWRITE(0xF8000724, 0x00003FFFU, 0x00000600U),
|
||||
EMIT_MASKWRITE(0xF8000728, 0x00003FFFU, 0x000016E1U),
|
||||
EMIT_MASKWRITE(0xF800072C, 0x00003FFFU, 0x000016E0U),
|
||||
EMIT_MASKWRITE(0xF8000730, 0x00003FFFU, 0x00001640U),
|
||||
EMIT_MASKWRITE(0xF8000734, 0x00003FFFU, 0x00001640U),
|
||||
EMIT_MASKWRITE(0xF8000738, 0x00003FFFU, 0x00001621U),
|
||||
EMIT_MASKWRITE(0xF800073C, 0x00003FFFU, 0x00001620U),
|
||||
EMIT_MASKWRITE(0xF8000740, 0x00003FFFU, 0x00001202U),
|
||||
EMIT_MASKWRITE(0xF8000744, 0x00003FFFU, 0x00001202U),
|
||||
EMIT_MASKWRITE(0xF8000748, 0x00003FFFU, 0x00001202U),
|
||||
EMIT_MASKWRITE(0xF800074C, 0x00003FFFU, 0x00001202U),
|
||||
EMIT_MASKWRITE(0xF8000750, 0x00003FFFU, 0x00001202U),
|
||||
EMIT_MASKWRITE(0xF8000754, 0x00003FFFU, 0x00001202U),
|
||||
EMIT_MASKWRITE(0xF8000758, 0x00003FFFU, 0x00001203U),
|
||||
EMIT_MASKWRITE(0xF800075C, 0x00003FFFU, 0x00001203U),
|
||||
EMIT_MASKWRITE(0xF8000760, 0x00003FFFU, 0x00001203U),
|
||||
EMIT_MASKWRITE(0xF8000764, 0x00003FFFU, 0x00001203U),
|
||||
EMIT_MASKWRITE(0xF8000768, 0x00003FFFU, 0x00001203U),
|
||||
EMIT_MASKWRITE(0xF800076C, 0x00003FFFU, 0x00001203U),
|
||||
EMIT_MASKWRITE(0xF8000770, 0x00003FFFU, 0x00001204U),
|
||||
EMIT_MASKWRITE(0xF8000774, 0x00003FFFU, 0x00001205U),
|
||||
EMIT_MASKWRITE(0xF8000778, 0x00003FFFU, 0x00001204U),
|
||||
EMIT_MASKWRITE(0xF800077C, 0x00003FFFU, 0x00001205U),
|
||||
EMIT_MASKWRITE(0xF8000780, 0x00003FFFU, 0x00001204U),
|
||||
EMIT_MASKWRITE(0xF8000784, 0x00003FFFU, 0x00001204U),
|
||||
EMIT_MASKWRITE(0xF8000788, 0x00003FFFU, 0x00001204U),
|
||||
EMIT_MASKWRITE(0xF800078C, 0x00003FFFU, 0x00001204U),
|
||||
EMIT_MASKWRITE(0xF8000790, 0x00003FFFU, 0x00001205U),
|
||||
EMIT_MASKWRITE(0xF8000794, 0x00003FFFU, 0x00001204U),
|
||||
EMIT_MASKWRITE(0xF8000798, 0x00003FFFU, 0x00001204U),
|
||||
EMIT_MASKWRITE(0xF800079C, 0x00003FFFU, 0x00001204U),
|
||||
EMIT_MASKWRITE(0xF80007A0, 0x00003FFFU, 0x00001280U),
|
||||
EMIT_MASKWRITE(0xF80007A4, 0x00003FFFU, 0x00001280U),
|
||||
EMIT_MASKWRITE(0xF80007A8, 0x00003FFFU, 0x00001280U),
|
||||
EMIT_MASKWRITE(0xF80007AC, 0x00003FFFU, 0x00001280U),
|
||||
EMIT_MASKWRITE(0xF80007B0, 0x00003FFFU, 0x00001280U),
|
||||
EMIT_MASKWRITE(0xF80007B4, 0x00003FFFU, 0x00001280U),
|
||||
EMIT_MASKWRITE(0xF80007B8, 0x00003F01U, 0x00000201U),
|
||||
EMIT_MASKWRITE(0xF80007BC, 0x00003F01U, 0x00000201U),
|
||||
EMIT_MASKWRITE(0xF80007C0, 0x00003FFFU, 0x000012E0U),
|
||||
EMIT_MASKWRITE(0xF80007C4, 0x00003FFFU, 0x000012E1U),
|
||||
EMIT_MASKWRITE(0xF80007C8, 0x00003FFFU, 0x00000200U),
|
||||
EMIT_MASKWRITE(0xF80007CC, 0x00003FFFU, 0x00000200U),
|
||||
EMIT_MASKWRITE(0xF80007D0, 0x00003FFFU, 0x00001280U),
|
||||
EMIT_MASKWRITE(0xF80007D4, 0x00003FFFU, 0x00001280U),
|
||||
EMIT_MASKWRITE(0xF8000830, 0x003F003FU, 0x002E002FU),
|
||||
EMIT_WRITE(0xF8000004, 0x0000767BU),
|
||||
EMIT_EXIT(),
|
||||
};
|
||||
|
||||
static unsigned long ps7_peripherals_init_data[] = {
|
||||
EMIT_WRITE(0xF8000008, 0x0000DF0DU),
|
||||
EMIT_MASKWRITE(0xF8000B48, 0x00000180U, 0x00000180U),
|
||||
EMIT_MASKWRITE(0xF8000B4C, 0x00000180U, 0x00000180U),
|
||||
EMIT_MASKWRITE(0xF8000B50, 0x00000180U, 0x00000180U),
|
||||
EMIT_MASKWRITE(0xF8000B54, 0x00000180U, 0x00000180U),
|
||||
EMIT_WRITE(0xF8000004, 0x0000767BU),
|
||||
EMIT_MASKWRITE(0xE000D000, 0x00080000U, 0x00080000U),
|
||||
EMIT_MASKWRITE(0xF8007000, 0x20000000U, 0x00000000U),
|
||||
EMIT_MASKWRITE(0xE000A244, 0x003FFFFFU, 0x00080000U),
|
||||
EMIT_MASKWRITE(0xE000A00C, 0x003F003FU, 0x00370008U),
|
||||
EMIT_MASKWRITE(0xE000A248, 0x003FFFFFU, 0x00080000U),
|
||||
EMIT_MASKWRITE(0xE000A00C, 0x003F003FU, 0x00370000U),
|
||||
EMIT_MASKDELAY(0xF8F00200, 1),
|
||||
EMIT_MASKWRITE(0xE000A00C, 0x003F003FU, 0x00370008U),
|
||||
EMIT_EXIT(),
|
||||
};
|
||||
|
||||
static unsigned long ps7_post_config_0[] = {
|
||||
EMIT_WRITE(0xF8000008, 0x0000DF0DU),
|
||||
EMIT_MASKWRITE(0xF8000900, 0x0000000FU, 0x0000000FU),
|
||||
EMIT_MASKWRITE(0xF8000240, 0xFFFFFFFFU, 0x00000000U),
|
||||
EMIT_WRITE(0xF8000004, 0x0000767BU),
|
||||
EMIT_EXIT(),
|
||||
};
|
||||
|
||||
int ps7_post_config(void)
|
||||
{
|
||||
return ps7_config(ps7_post_config_0);
|
||||
}
|
||||
|
||||
int ps7_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ps7_config(ps7_mio_init_data);
|
||||
if (ret != PS7_INIT_SUCCESS)
|
||||
return ret;
|
||||
|
||||
ret = ps7_config(ps7_pll_init_data);
|
||||
if (ret != PS7_INIT_SUCCESS)
|
||||
return ret;
|
||||
|
||||
ret = ps7_config(ps7_clock_init_data);
|
||||
if (ret != PS7_INIT_SUCCESS)
|
||||
return ret;
|
||||
|
||||
ret = ps7_config(ps7_ddr_init_data);
|
||||
if (ret != PS7_INIT_SUCCESS)
|
||||
return ret;
|
||||
|
||||
ret = ps7_config(ps7_peripherals_init_data);
|
||||
if (ret != PS7_INIT_SUCCESS)
|
||||
return ret;
|
||||
return PS7_INIT_SUCCESS;
|
||||
}
|
@ -3,6 +3,7 @@ M: Michal Simek <michal.simek@xilinx.com>
|
||||
S: Maintained
|
||||
F: arch/arm/dts/zynqmp-*
|
||||
F: arch/arm/dts/avnet-ultra96*
|
||||
F: board/xilinx/common/
|
||||
F: board/xilinx/zynqmp/
|
||||
F: include/configs/xilinx_zynqmp*
|
||||
F: configs/xilinx_zynqmp*
|
||||
|
@ -4,7 +4,6 @@
|
||||
# Michal Simek <michal.simek@xilinx.com>
|
||||
|
||||
obj-y := zynqmp.o
|
||||
obj-y += ../common/board.o
|
||||
|
||||
ifneq ($(CONFIG_XILINX_PS_INIT_FILE),"")
|
||||
PS_INIT_FILE := $(shell cd $(srctree); readlink -f $(CONFIG_XILINX_PS_INIT_FILE))
|
||||
|
@ -9,11 +9,22 @@
|
||||
#include <cpu_func.h>
|
||||
#include <env.h>
|
||||
#include <malloc.h>
|
||||
#include <memalign.h>
|
||||
#include <zynqmp_firmware.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
struct aes {
|
||||
u64 srcaddr;
|
||||
u64 ivaddr;
|
||||
u64 keyaddr;
|
||||
u64 dstaddr;
|
||||
u64 len;
|
||||
u64 op;
|
||||
u64 keysrc;
|
||||
};
|
||||
|
||||
static int do_zynqmp_verify_secure(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
@ -107,6 +118,66 @@ static int do_zynqmp_mmio_write(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int do_zynqmp_aes(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
ALLOC_CACHE_ALIGN_BUFFER(struct aes, aes, 1);
|
||||
int ret;
|
||||
u32 ret_payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
if (zynqmp_firmware_version() <= PMUFW_V1_0) {
|
||||
puts("ERR: PMUFW v1.0 or less is detected\n");
|
||||
puts("ERR: Encrypt/Decrypt feature is not supported\n");
|
||||
puts("ERR: Please upgrade PMUFW\n");
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
if (argc < cmdtp->maxargs - 1)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
aes->srcaddr = simple_strtoul(argv[2], NULL, 16);
|
||||
aes->ivaddr = simple_strtoul(argv[3], NULL, 16);
|
||||
aes->len = simple_strtoul(argv[4], NULL, 16);
|
||||
aes->op = simple_strtoul(argv[5], NULL, 16);
|
||||
aes->keysrc = simple_strtoul(argv[6], NULL, 16);
|
||||
aes->dstaddr = simple_strtoul(argv[7], NULL, 16);
|
||||
|
||||
flush_dcache_range((ulong)aes, (ulong)(aes) +
|
||||
roundup(sizeof(struct aes), ARCH_DMA_MINALIGN));
|
||||
|
||||
if (aes->srcaddr && aes->ivaddr && aes->dstaddr) {
|
||||
flush_dcache_range(aes->srcaddr,
|
||||
(aes->srcaddr +
|
||||
roundup(aes->len, ARCH_DMA_MINALIGN)));
|
||||
flush_dcache_range(aes->ivaddr,
|
||||
(aes->ivaddr +
|
||||
roundup(IV_SIZE, ARCH_DMA_MINALIGN)));
|
||||
flush_dcache_range(aes->dstaddr,
|
||||
(aes->dstaddr +
|
||||
roundup(aes->len, ARCH_DMA_MINALIGN)));
|
||||
}
|
||||
|
||||
if (aes->keysrc == 0) {
|
||||
if (argc < cmdtp->maxargs)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
aes->keyaddr = simple_strtoul(argv[8], NULL, 16);
|
||||
if (aes->keyaddr)
|
||||
flush_dcache_range(aes->keyaddr,
|
||||
(aes->keyaddr +
|
||||
roundup(KEY_PTR_LEN,
|
||||
ARCH_DMA_MINALIGN)));
|
||||
}
|
||||
|
||||
ret = xilinx_pm_request(PM_SECURE_AES, upper_32_bits((ulong)aes),
|
||||
lower_32_bits((ulong)aes), 0, 0, ret_payload);
|
||||
if (ret || ret_payload[1])
|
||||
printf("Failed: AES op status:0x%x, errcode:0x%x\n",
|
||||
ret, ret_payload[1]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEFINE_TCM_OCM_MMAP
|
||||
static int do_zynqmp_tcm_init(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
@ -148,11 +219,145 @@ static int do_zynqmp_pmufw(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_zynqmp_rsa(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
u64 srcaddr, mod, exp;
|
||||
u32 srclen, rsaop, size, ret_payload[PAYLOAD_ARG_CNT];
|
||||
int ret;
|
||||
|
||||
if (argc != cmdtp->maxargs)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
if (zynqmp_firmware_version() <= PMUFW_V1_0) {
|
||||
puts("ERR: PMUFW v1.0 or less is detected\n");
|
||||
puts("ERR: Encrypt/Decrypt feature is not supported\n");
|
||||
puts("ERR: Please upgrade PMUFW\n");
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
srcaddr = simple_strtoul(argv[2], NULL, 16);
|
||||
srclen = simple_strtoul(argv[3], NULL, 16);
|
||||
if (srclen != RSA_KEY_SIZE) {
|
||||
puts("ERR: srclen should be equal to 0x200(512 bytes)\n");
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
|
||||
mod = simple_strtoul(argv[4], NULL, 16);
|
||||
exp = simple_strtoul(argv[5], NULL, 16);
|
||||
rsaop = simple_strtoul(argv[6], NULL, 16);
|
||||
if (!(rsaop == 0 || rsaop == 1)) {
|
||||
puts("ERR: rsaop should be either 0 or 1\n");
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
|
||||
memcpy((void *)srcaddr + srclen, (void *)mod, MODULUS_LEN);
|
||||
|
||||
/*
|
||||
* For encryption we load public exponent (key size 4096-bits),
|
||||
* for decryption we load private exponent (32-bits)
|
||||
*/
|
||||
if (rsaop) {
|
||||
memcpy((void *)srcaddr + srclen + MODULUS_LEN,
|
||||
(void *)exp, PUB_EXPO_LEN);
|
||||
size = srclen + MODULUS_LEN + PUB_EXPO_LEN;
|
||||
} else {
|
||||
memcpy((void *)srcaddr + srclen + MODULUS_LEN,
|
||||
(void *)exp, PRIV_EXPO_LEN);
|
||||
size = srclen + MODULUS_LEN + PRIV_EXPO_LEN;
|
||||
}
|
||||
|
||||
flush_dcache_range((ulong)srcaddr,
|
||||
(ulong)(srcaddr) + roundup(size, ARCH_DMA_MINALIGN));
|
||||
|
||||
ret = xilinx_pm_request(PM_SECURE_RSA, upper_32_bits((ulong)srcaddr),
|
||||
lower_32_bits((ulong)srcaddr), srclen, rsaop,
|
||||
ret_payload);
|
||||
if (ret || ret_payload[1]) {
|
||||
printf("Failed: RSA status:0x%x, errcode:0x%x\n",
|
||||
ret, ret_payload[1]);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static int do_zynqmp_sha3(struct cmd_tbl *cmdtp, int flag,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
u64 srcaddr, hashaddr;
|
||||
u32 srclen, ret_payload[PAYLOAD_ARG_CNT];
|
||||
int ret;
|
||||
|
||||
if (argc > cmdtp->maxargs || argc < (cmdtp->maxargs - 1))
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
if (zynqmp_firmware_version() <= PMUFW_V1_0) {
|
||||
puts("ERR: PMUFW v1.0 or less is detected\n");
|
||||
puts("ERR: Encrypt/Decrypt feature is not supported\n");
|
||||
puts("ERR: Please upgrade PMUFW\n");
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
srcaddr = simple_strtoul(argv[2], NULL, 16);
|
||||
srclen = simple_strtoul(argv[3], NULL, 16);
|
||||
|
||||
if (argc == 5) {
|
||||
hashaddr = simple_strtoul(argv[4], NULL, 16);
|
||||
flush_dcache_range(hashaddr,
|
||||
hashaddr + roundup(ZYNQMP_SHA3_SIZE,
|
||||
ARCH_DMA_MINALIGN));
|
||||
} else {
|
||||
hashaddr = srcaddr;
|
||||
}
|
||||
|
||||
/* Check srcaddr or srclen != 0 */
|
||||
if (!srcaddr || !srclen) {
|
||||
puts("ERR: srcaddr & srclen should not be 0\n");
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
|
||||
flush_dcache_range(srcaddr,
|
||||
srcaddr + roundup(srclen, ARCH_DMA_MINALIGN));
|
||||
|
||||
ret = xilinx_pm_request(PM_SECURE_SHA, 0, 0, 0,
|
||||
ZYNQMP_SHA3_INIT, ret_payload);
|
||||
if (ret || ret_payload[1]) {
|
||||
printf("Failed: SHA INIT status:0x%x, errcode:0x%x\n",
|
||||
ret, ret_payload[1]);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
ret = xilinx_pm_request(PM_SECURE_SHA, upper_32_bits((ulong)srcaddr),
|
||||
lower_32_bits((ulong)srcaddr),
|
||||
srclen, ZYNQMP_SHA3_UPDATE, ret_payload);
|
||||
if (ret || ret_payload[1]) {
|
||||
printf("Failed: SHA UPDATE status:0x%x, errcode:0x%x\n",
|
||||
ret, ret_payload[1]);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
ret = xilinx_pm_request(PM_SECURE_SHA, upper_32_bits((ulong)hashaddr),
|
||||
lower_32_bits((ulong)hashaddr),
|
||||
ZYNQMP_SHA3_SIZE, ZYNQMP_SHA3_FINAL,
|
||||
ret_payload);
|
||||
if (ret || ret_payload[1]) {
|
||||
printf("Failed: SHA FINAL status:0x%x, errcode:0x%x\n",
|
||||
ret, ret_payload[1]);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static struct cmd_tbl cmd_zynqmp_sub[] = {
|
||||
U_BOOT_CMD_MKENT(secure, 5, 0, do_zynqmp_verify_secure, "", ""),
|
||||
U_BOOT_CMD_MKENT(pmufw, 4, 0, do_zynqmp_pmufw, "", ""),
|
||||
U_BOOT_CMD_MKENT(mmio_read, 3, 0, do_zynqmp_mmio_read, "", ""),
|
||||
U_BOOT_CMD_MKENT(mmio_write, 5, 0, do_zynqmp_mmio_write, "", ""),
|
||||
U_BOOT_CMD_MKENT(aes, 9, 0, do_zynqmp_aes, "", ""),
|
||||
U_BOOT_CMD_MKENT(rsa, 7, 0, do_zynqmp_rsa, "", ""),
|
||||
U_BOOT_CMD_MKENT(sha3, 5, 0, do_zynqmp_sha3, "", ""),
|
||||
#ifdef CONFIG_DEFINE_TCM_OCM_MMAP
|
||||
U_BOOT_CMD_MKENT(tcminit, 3, 0, do_zynqmp_tcm_init, "", ""),
|
||||
#endif
|
||||
@ -196,6 +401,14 @@ static char zynqmp_help_text[] =
|
||||
"zynqmp mmio_read address - read from address\n"
|
||||
"zynqmp mmio_write address mask value - write value after masking to\n"
|
||||
" address\n"
|
||||
"zynqmp aes srcaddr ivaddr len aesop keysrc dstaddr [keyaddr] -\n"
|
||||
" Encrypts or decrypts blob of data at src address and puts it\n"
|
||||
" back to dstaddr using key and iv at keyaddr and ivaddr\n"
|
||||
" respectively. keysrc value specifies from which source key\n"
|
||||
" has to be used, it can be User/Device/PUF key. A value of 0\n"
|
||||
" for KUP(user key),1 for DeviceKey and 2 for PUF key. The\n"
|
||||
" aesop value specifies the operation which can be 0 for\n"
|
||||
" decrypt and 1 for encrypt operation\n"
|
||||
#ifdef CONFIG_DEFINE_TCM_OCM_MMAP
|
||||
"zynqmp tcminit mode - Initialize the TCM with zeros. TCM needs to be\n"
|
||||
" initialized before accessing to avoid ECC\n"
|
||||
@ -204,11 +417,24 @@ static char zynqmp_help_text[] =
|
||||
" lock(0)/split(1)\n"
|
||||
#endif
|
||||
"zynqmp pmufw address size - load PMU FW configuration object\n"
|
||||
"zynqmp rsa srcaddr srclen mod exp rsaop -\n"
|
||||
" Performs RSA encryption and RSA decryption on blob of data\n"
|
||||
" at srcaddr and puts it back in srcaddr using modulus and\n"
|
||||
" public or private exponent\n"
|
||||
" srclen : must be key size(4096 bits)\n"
|
||||
" exp : private key exponent for RSA decryption(4096 bits)\n"
|
||||
" public key exponent for RSA encryption(32 bits)\n"
|
||||
" rsaop : 0 for RSA Decryption, 1 for RSA Encryption\n"
|
||||
"zynqmp sha3 srcaddr srclen [key_addr] -\n"
|
||||
" Generates sha3 hash value for data blob at srcaddr and puts\n"
|
||||
" 48 bytes hash value into srcaddr\n"
|
||||
" Optional key_addr can be specified for saving sha3 hash value\n"
|
||||
" Note: srcaddr/srclen should not be 0\n"
|
||||
;
|
||||
#endif
|
||||
|
||||
U_BOOT_CMD(
|
||||
zynqmp, 5, 1, do_zynqmp,
|
||||
zynqmp, 9, 1, do_zynqmp,
|
||||
"ZynqMP sub-system",
|
||||
zynqmp_help_text
|
||||
)
|
||||
|
@ -6,8 +6,10 @@
|
||||
*/
|
||||
|
||||
#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
|
||||
@ -25,43 +27,9 @@
|
||||
#define SD1_ITAPDLYENA_MASK 0x01000000
|
||||
#define SD1_ITAPDLYENA 0x01000000
|
||||
#define SD0_ITAPDLYSEL_MASK 0x000000FF
|
||||
#define SD0_ITAPDLYSEL_HSD 0x00000015
|
||||
#define SD0_ITAPDLYSEL_SD_DDR50 0x0000003D
|
||||
#define SD0_ITAPDLYSEL_MMC_DDR50 0x00000012
|
||||
|
||||
#define SD1_ITAPDLYSEL_MASK 0x00FF0000
|
||||
#define SD1_ITAPDLYSEL_HSD 0x00150000
|
||||
#define SD1_ITAPDLYSEL_SD_DDR50 0x003D0000
|
||||
#define SD1_ITAPDLYSEL_MMC_DDR50 0x00120000
|
||||
|
||||
#define SD0_OTAPDLYSEL_MASK 0x0000003F
|
||||
#define SD0_OTAPDLYSEL_MMC_HSD 0x00000006
|
||||
#define SD0_OTAPDLYSEL_SD_HSD 0x00000005
|
||||
#define SD0_OTAPDLYSEL_SDR50 0x00000003
|
||||
#define SD0_OTAPDLYSEL_SDR104_B0 0x00000003
|
||||
#define SD0_OTAPDLYSEL_SDR104_B2 0x00000002
|
||||
#define SD0_OTAPDLYSEL_SD_DDR50 0x00000004
|
||||
#define SD0_OTAPDLYSEL_MMC_DDR50 0x00000006
|
||||
|
||||
#define SD1_OTAPDLYSEL_MASK 0x003F0000
|
||||
#define SD1_OTAPDLYSEL_MMC_HSD 0x00060000
|
||||
#define SD1_OTAPDLYSEL_SD_HSD 0x00050000
|
||||
#define SD1_OTAPDLYSEL_SDR50 0x00030000
|
||||
#define SD1_OTAPDLYSEL_SDR104_B0 0x00030000
|
||||
#define SD1_OTAPDLYSEL_SDR104_B2 0x00020000
|
||||
#define SD1_OTAPDLYSEL_SD_DDR50 0x00040000
|
||||
#define SD1_OTAPDLYSEL_MMC_DDR50 0x00060000
|
||||
|
||||
#define MMC_BANK2 0x2
|
||||
|
||||
#define MMC_TIMING_UHS_SDR25 1
|
||||
#define MMC_TIMING_UHS_SDR50 2
|
||||
#define MMC_TIMING_UHS_SDR104 3
|
||||
#define MMC_TIMING_UHS_DDR50 4
|
||||
#define MMC_TIMING_MMC_HS200 5
|
||||
#define MMC_TIMING_SD_HS 6
|
||||
#define MMC_TIMING_MMC_DDR52 7
|
||||
#define MMC_TIMING_MMC_HS 8
|
||||
|
||||
void zynqmp_dll_reset(u8 deviceid)
|
||||
{
|
||||
@ -82,149 +50,49 @@ void zynqmp_dll_reset(u8 deviceid)
|
||||
zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
|
||||
}
|
||||
|
||||
static void arasan_zynqmp_tap_sdr104(u8 deviceid, u8 timing, u8 bank)
|
||||
void arasan_zynqmp_set_tapdelay(u8 deviceid, u32 itap_delay, u32 otap_delay)
|
||||
{
|
||||
if (deviceid == 0) {
|
||||
/* Program OTAP */
|
||||
if (bank == MMC_BANK2)
|
||||
zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
|
||||
SD0_OTAPDLYSEL_SDR104_B2);
|
||||
else
|
||||
zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
|
||||
SD0_OTAPDLYSEL_SDR104_B0);
|
||||
} else {
|
||||
/* Program OTAP */
|
||||
if (bank == MMC_BANK2)
|
||||
zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
|
||||
SD1_OTAPDLYSEL_SDR104_B2);
|
||||
else
|
||||
zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
|
||||
SD1_OTAPDLYSEL_SDR104_B0);
|
||||
}
|
||||
}
|
||||
|
||||
static void arasan_zynqmp_tap_hs(u8 deviceid, u8 timing, u8 bank)
|
||||
{
|
||||
if (deviceid == 0) {
|
||||
/* Program ITAP */
|
||||
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,
|
||||
SD0_ITAPDLYSEL_HSD);
|
||||
zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, 0x0);
|
||||
/* Program OTAP */
|
||||
if (timing == MMC_TIMING_MMC_HS)
|
||||
zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
|
||||
SD0_OTAPDLYSEL_MMC_HSD);
|
||||
else
|
||||
zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
|
||||
SD0_OTAPDLYSEL_SD_HSD);
|
||||
} else {
|
||||
/* Program ITAP */
|
||||
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,
|
||||
SD1_ITAPDLYSEL_HSD);
|
||||
zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, 0x0);
|
||||
/* Program OTAP */
|
||||
if (timing == MMC_TIMING_MMC_HS)
|
||||
zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
|
||||
SD1_OTAPDLYSEL_MMC_HSD);
|
||||
else
|
||||
zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
|
||||
SD1_OTAPDLYSEL_SD_HSD);
|
||||
}
|
||||
}
|
||||
|
||||
static void arasan_zynqmp_tap_ddr50(u8 deviceid, u8 timing, u8 bank)
|
||||
{
|
||||
if (deviceid == 0) {
|
||||
/* Program ITAP */
|
||||
zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK,
|
||||
SD0_ITAPCHGWIN);
|
||||
zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK,
|
||||
SD0_ITAPDLYENA);
|
||||
if (timing == MMC_TIMING_UHS_DDR50)
|
||||
zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK,
|
||||
SD0_ITAPDLYSEL_SD_DDR50);
|
||||
else
|
||||
zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK,
|
||||
SD0_ITAPDLYSEL_MMC_DDR50);
|
||||
zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, 0x0);
|
||||
/* Program OTAP */
|
||||
if (timing == MMC_TIMING_UHS_DDR50)
|
||||
zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
|
||||
SD0_OTAPDLYSEL_SD_DDR50);
|
||||
else
|
||||
zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
|
||||
SD0_OTAPDLYSEL_MMC_DDR50);
|
||||
} else {
|
||||
/* Program ITAP */
|
||||
zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK,
|
||||
SD1_ITAPCHGWIN);
|
||||
zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK,
|
||||
SD1_ITAPDLYENA);
|
||||
if (timing == MMC_TIMING_UHS_DDR50)
|
||||
zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
|
||||
SD1_ITAPDLYSEL_SD_DDR50);
|
||||
else
|
||||
zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
|
||||
SD1_ITAPDLYSEL_MMC_DDR50);
|
||||
zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, 0x0);
|
||||
/* Program OTAP */
|
||||
if (timing == MMC_TIMING_UHS_DDR50)
|
||||
zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
|
||||
SD1_OTAPDLYSEL_SD_DDR50);
|
||||
else
|
||||
zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
|
||||
SD1_OTAPDLYSEL_MMC_DDR50);
|
||||
}
|
||||
}
|
||||
|
||||
static void arasan_zynqmp_tap_sdr50(u8 deviceid, u8 timing, u8 bank)
|
||||
{
|
||||
if (deviceid == 0) {
|
||||
/* Program OTAP */
|
||||
zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
|
||||
SD0_OTAPDLYSEL_SDR50);
|
||||
} else {
|
||||
/* Program OTAP */
|
||||
zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
|
||||
SD1_OTAPDLYSEL_SDR50);
|
||||
}
|
||||
}
|
||||
|
||||
void arasan_zynqmp_set_tapdelay(u8 deviceid, u8 timing, u8 bank)
|
||||
{
|
||||
if (deviceid == 0)
|
||||
zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK,
|
||||
SD0_DLL_RST);
|
||||
else
|
||||
/* Program ITAP */
|
||||
if (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);
|
||||
}
|
||||
|
||||
/* Program OTAP */
|
||||
if (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 ITAP */
|
||||
if (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);
|
||||
}
|
||||
|
||||
switch (timing) {
|
||||
case MMC_TIMING_UHS_SDR25:
|
||||
arasan_zynqmp_tap_hs(deviceid, timing, bank);
|
||||
break;
|
||||
case MMC_TIMING_UHS_SDR50:
|
||||
arasan_zynqmp_tap_sdr50(deviceid, timing, bank);
|
||||
break;
|
||||
case MMC_TIMING_UHS_SDR104:
|
||||
case MMC_TIMING_MMC_HS200:
|
||||
arasan_zynqmp_tap_sdr104(deviceid, timing, bank);
|
||||
break;
|
||||
case MMC_TIMING_UHS_DDR50:
|
||||
arasan_zynqmp_tap_ddr50(deviceid, timing, bank);
|
||||
break;
|
||||
}
|
||||
/* Program OTAP */
|
||||
if (otap_delay)
|
||||
zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
|
||||
(otap_delay << 16));
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -40,12 +40,12 @@
|
||||
#include "pm_cfg_obj.h"
|
||||
|
||||
#define ZYNQMP_VERSION_SIZE 7
|
||||
#define EFUSE_VCU_DIS_MASK 0x100
|
||||
#define EFUSE_VCU_DIS_SHIFT 8
|
||||
#define EFUSE_GPU_DIS_MASK 0x20
|
||||
#define EFUSE_GPU_DIS_SHIFT 5
|
||||
#define IDCODE2_PL_INIT_MASK 0x200
|
||||
#define IDCODE2_PL_INIT_SHIFT 9
|
||||
#define EFUSE_VCU_DIS_MASK 0x100
|
||||
#define EFUSE_VCU_DIS_SHIFT 8
|
||||
#define EFUSE_GPU_DIS_MASK 0x20
|
||||
#define EFUSE_GPU_DIS_SHIFT 5
|
||||
#define IDCODE2_PL_INIT_MASK 0x200
|
||||
#define IDCODE2_PL_INIT_SHIFT 9
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@ -100,7 +100,7 @@ static const struct {
|
||||
{
|
||||
.id = 0x04738093,
|
||||
.device = 9,
|
||||
.variants = ZYNQMP_VARIANT_EG,
|
||||
.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
|
||||
},
|
||||
{
|
||||
.id = 0x04740093,
|
||||
@ -190,8 +190,13 @@ static char *zynqmp_get_silicon_idcode_name(void)
|
||||
u32 idcode, idcode2;
|
||||
char name[ZYNQMP_VERSION_SIZE];
|
||||
u32 ret_payload[PAYLOAD_ARG_CNT];
|
||||
int ret;
|
||||
|
||||
xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
|
||||
ret = xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
|
||||
if (ret) {
|
||||
debug("%s: Getting chipid failed\n", __func__);
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
/*
|
||||
* Firmware returns:
|
||||
@ -204,7 +209,7 @@ static char *zynqmp_get_silicon_idcode_name(void)
|
||||
|
||||
idcode = ret_payload[1];
|
||||
idcode2 = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
|
||||
debug("%s, IDCODE: 0x%0X, IDCODE2: 0x%0X\r\n", __func__, idcode,
|
||||
debug("%s, IDCODE: 0x%0x, IDCODE2: 0x%0x\r\n", __func__, idcode,
|
||||
idcode2);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
|
||||
@ -216,8 +221,10 @@ static char *zynqmp_get_silicon_idcode_name(void)
|
||||
return "unknown";
|
||||
|
||||
/* Add device prefix to the name */
|
||||
strncpy(name, "zu", ZYNQMP_VERSION_SIZE);
|
||||
strncat(&name[2], simple_itoa(zynqmp_devices[i].device), 2);
|
||||
ret = snprintf(name, ZYNQMP_VERSION_SIZE, "zu%d",
|
||||
zynqmp_devices[i].device);
|
||||
if (ret < 0)
|
||||
return "unknown";
|
||||
|
||||
if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EV) {
|
||||
/* Devices with EV variant might be EG/CG/EV family */
|
||||
@ -321,6 +328,9 @@ int board_init(void)
|
||||
if (sizeof(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE) > 1)
|
||||
zynqmp_pmufw_load_config_object(zynqmp_pm_cfg_obj,
|
||||
zynqmp_pm_cfg_obj_size);
|
||||
#else
|
||||
if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM))
|
||||
xilinx_read_eeprom();
|
||||
#endif
|
||||
|
||||
printf("EL Level:\tEL%d\n", current_el());
|
||||
|
@ -611,14 +611,9 @@ int fdt_record_loadable(void *blob, u32 index, const char *name,
|
||||
if (node < 0)
|
||||
return node;
|
||||
|
||||
/*
|
||||
* We record these as 32bit entities, possibly truncating addresses.
|
||||
* However, spl_fit.c is not 64bit safe either: i.e. we should not
|
||||
* have an issue here.
|
||||
*/
|
||||
fdt_setprop_u32(blob, node, "load-addr", load_addr);
|
||||
fdt_setprop_u64(blob, node, "load", load_addr);
|
||||
if (entry_point != -1)
|
||||
fdt_setprop_u32(blob, node, "entry-point", entry_point);
|
||||
fdt_setprop_u64(blob, node, "entry", entry_point);
|
||||
fdt_setprop_u32(blob, node, "size", size);
|
||||
if (type)
|
||||
fdt_setprop_string(blob, node, "type", type);
|
||||
|
@ -791,17 +791,18 @@ static int fit_image_get_address(const void *fit, int noffset, char *name,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len > sizeof(ulong)) {
|
||||
printf("Unsupported %s address size\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cell_len = len >> 2;
|
||||
/* Use load64 to avoid compiling warning for 32-bit target */
|
||||
while (cell_len--) {
|
||||
load64 = (load64 << 32) | uimage_to_cpu(*cell);
|
||||
cell++;
|
||||
}
|
||||
|
||||
if (len > sizeof(ulong) && (uint32_t)(load64 >> 32)) {
|
||||
printf("Unsupported %s address size\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*load = (ulong)load64;
|
||||
|
||||
return 0;
|
||||
|
@ -132,10 +132,11 @@ static int spl_fit_images_find(void *blob, int os)
|
||||
uintptr_t spl_fit_images_get_entry(void *blob, int node)
|
||||
{
|
||||
ulong val;
|
||||
int ret;
|
||||
|
||||
val = fdt_getprop_u32(blob, node, "entry-point");
|
||||
if (val == FDT_ERROR)
|
||||
val = fdt_getprop_u32(blob, node, "load-addr");
|
||||
ret = fit_image_get_entry(blob, node, &val);
|
||||
if (ret)
|
||||
ret = fit_image_get_load(blob, node, &val);
|
||||
|
||||
debug("%s: entry point 0x%lx\n", __func__, val);
|
||||
return val;
|
||||
|
@ -332,9 +332,15 @@ static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
|
||||
}
|
||||
|
||||
if (image_info) {
|
||||
ulong entry_point;
|
||||
|
||||
image_info->load_addr = load_addr;
|
||||
image_info->size = length;
|
||||
image_info->entry_point = fdt_getprop_u32(fit, node, "entry");
|
||||
|
||||
if (!fit_image_get_entry(fit, node, &entry_point))
|
||||
image_info->entry_point = entry_point;
|
||||
else
|
||||
image_info->entry_point = FDT_ERROR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -61,11 +61,9 @@ void spl_invoke_opensbi(struct spl_image_info *spl_image)
|
||||
}
|
||||
|
||||
/* Get U-Boot entry point */
|
||||
uboot_entry = fdt_getprop_u32(spl_image->fdt_addr, uboot_node,
|
||||
"entry-point");
|
||||
if (uboot_entry == FDT_ERROR)
|
||||
uboot_entry = fdt_getprop_u32(spl_image->fdt_addr, uboot_node,
|
||||
"load-addr");
|
||||
ret = fit_image_get_entry(spl_image->fdt_addr, uboot_node, &uboot_entry);
|
||||
if (ret)
|
||||
ret = fit_image_get_load(spl_image->fdt_addr, uboot_node, &uboot_entry);
|
||||
|
||||
/* Prepare obensbi_info object */
|
||||
opensbi_info.magic = FW_DYNAMIC_INFO_MAGIC_VALUE;
|
||||
|
@ -8,6 +8,8 @@ CONFIG_DEBUG_UART_BASE=0xff000000
|
||||
CONFIG_DEBUG_UART_CLOCK=100000000
|
||||
CONFIG_SPL_SPI_FLASH_SUPPORT=y
|
||||
CONFIG_SPL_SPI_SUPPORT=y
|
||||
CONFIG_ZYNQ_MAC_IN_EEPROM=y
|
||||
CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0xfa
|
||||
CONFIG_DEFAULT_DEVICE_TREE="avnet-ultrazedev-cc-v1.0-ultrazedev-som-v1.0"
|
||||
CONFIG_DEBUG_UART=y
|
||||
CONFIG_DISTRO_DEFAULTS=y
|
||||
@ -42,7 +44,6 @@ CONFIG_I2C_MUX=y
|
||||
CONFIG_I2C_MUX_PCA954x=y
|
||||
CONFIG_MISC=y
|
||||
CONFIG_I2C_EEPROM=y
|
||||
CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0xfa
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_ZYNQ=y
|
||||
CONFIG_SPI_FLASH_BAR=y
|
||||
|
@ -12,6 +12,7 @@ CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1
|
||||
CONFIG_XILINX_MICROBLAZE0_USE_DIV=1
|
||||
CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL=1
|
||||
CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic"
|
||||
CONFIG_DISTRO_DEFAULTS=y
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_VERBOSE=y
|
||||
CONFIG_BOOTDELAY=-1
|
||||
@ -21,13 +22,12 @@ CONFIG_USE_PREBOOT=y
|
||||
CONFIG_PREBOOT="echo U-BOOT for ${hostname};setenv preboot;echo"
|
||||
CONFIG_SYS_CONSOLE_IS_IN_ENV=y
|
||||
CONFIG_DISPLAY_BOARDINFO=y
|
||||
CONFIG_DISPLAY_BOARDINFO_LATE=y
|
||||
CONFIG_SPL_BOARD_INIT=y
|
||||
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
|
||||
CONFIG_SPL_NOR_SUPPORT=y
|
||||
CONFIG_SPL_OS_BOOT=y
|
||||
CONFIG_SYS_OS_BASE=0x2c060000
|
||||
CONFIG_HUSH_PARSER=y
|
||||
# CONFIG_AUTO_COMPLETE is not set
|
||||
CONFIG_SYS_PROMPT="U-Boot-mONStR> "
|
||||
CONFIG_CMD_IMLS=y
|
||||
CONFIG_CMD_SPL=y
|
||||
@ -35,10 +35,7 @@ CONFIG_CMD_ASKENV=y
|
||||
CONFIG_CMD_GPIO=y
|
||||
CONFIG_CMD_SAVES=y
|
||||
# CONFIG_CMD_SETEXPR is not set
|
||||
CONFIG_CMD_DHCP=y
|
||||
CONFIG_CMD_TFTPPUT=y
|
||||
CONFIG_CMD_MII=y
|
||||
CONFIG_CMD_PING=y
|
||||
CONFIG_CMD_CACHE=y
|
||||
CONFIG_CMD_JFFS2=y
|
||||
CONFIG_SPL_OF_CONTROL=y
|
||||
@ -47,6 +44,7 @@ CONFIG_NET_RANDOM_ETHADDR=y
|
||||
CONFIG_NETCONSOLE=y
|
||||
CONFIG_SPL_DM=y
|
||||
CONFIG_XILINX_GPIO=y
|
||||
CONFIG_DM_I2C=y
|
||||
CONFIG_LED=y
|
||||
CONFIG_LED_GPIO=y
|
||||
CONFIG_MTD=y
|
||||
@ -56,6 +54,12 @@ CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
|
||||
CONFIG_FLASH_CFI_MTD=y
|
||||
CONFIG_SYS_FLASH_PROTECTION=y
|
||||
CONFIG_SYS_FLASH_CFI=y
|
||||
CONFIG_SPI_FLASH_ISSI=y
|
||||
CONFIG_SPI_FLASH_MACRONIX=y
|
||||
CONFIG_SPI_FLASH_SPANSION=y
|
||||
CONFIG_SPI_FLASH_STMICRO=y
|
||||
CONFIG_SPI_FLASH_SST=y
|
||||
CONFIG_SPI_FLASH_WINBOND=y
|
||||
CONFIG_PHY_ATHEROS=y
|
||||
CONFIG_PHY_BROADCOM=y
|
||||
CONFIG_PHY_DAVICOM=y
|
||||
@ -71,6 +75,7 @@ CONFIG_XILINX_AXIEMAC=y
|
||||
CONFIG_XILINX_EMACLITE=y
|
||||
CONFIG_SYS_NS16550=y
|
||||
CONFIG_XILINX_UARTLITE=y
|
||||
CONFIG_XILINX_SPI=y
|
||||
CONFIG_SYSRESET_GPIO=y
|
||||
CONFIG_SYSRESET_MICROBLAZE=y
|
||||
CONFIG_WDT=y
|
||||
|
@ -9,6 +9,8 @@ CONFIG_SPL_STACK_R_ADDR=0x200000
|
||||
CONFIG_SPL=y
|
||||
CONFIG_DEBUG_UART_BASE=0xe0000000
|
||||
CONFIG_DEBUG_UART_CLOCK=50000000
|
||||
CONFIG_ZYNQ_MAC_IN_EEPROM=y
|
||||
CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0xFA
|
||||
CONFIG_DEFAULT_DEVICE_TREE="zynq-syzygy-hub"
|
||||
CONFIG_DEBUG_UART=y
|
||||
CONFIG_DISTRO_DEFAULTS=y
|
||||
@ -40,7 +42,6 @@ CONFIG_FPGA_XILINX=y
|
||||
CONFIG_FPGA_ZYNQPL=y
|
||||
CONFIG_DM_I2C=y
|
||||
CONFIG_SYS_I2C_CADENCE=y
|
||||
CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0xFA
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_ZYNQ=y
|
||||
CONFIG_PHY_MARVELL=y
|
||||
|
@ -7,7 +7,7 @@ CONFIG_NR_DRAM_BANKS=3
|
||||
CONFIG_ENV_SIZE=0x80
|
||||
CONFIG_SYS_MALLOC_LEN=0x2000
|
||||
CONFIG_SYS_MEM_RSVD_FOR_MMU=y
|
||||
CONFIG_COUNTER_FREQUENCY=2720000
|
||||
CONFIG_COUNTER_FREQUENCY=100000000
|
||||
# CONFIG_PSCI_RESET is not set
|
||||
CONFIG_DEFAULT_DEVICE_TREE="versal-mini"
|
||||
# CONFIG_EXPERT is not set
|
||||
|
@ -6,7 +6,7 @@ CONFIG_SYS_TEXT_BASE=0x10000
|
||||
CONFIG_NR_DRAM_BANKS=1
|
||||
CONFIG_ENV_SIZE=0x80
|
||||
CONFIG_SYS_MALLOC_LEN=0x80000
|
||||
CONFIG_COUNTER_FREQUENCY=2720000
|
||||
CONFIG_COUNTER_FREQUENCY=100000000
|
||||
# CONFIG_PSCI_RESET is not set
|
||||
CONFIG_DEFAULT_DEVICE_TREE="versal-mini-emmc0"
|
||||
# CONFIG_EXPERT is not set
|
||||
|
@ -6,7 +6,7 @@ CONFIG_SYS_TEXT_BASE=0x10000
|
||||
CONFIG_NR_DRAM_BANKS=1
|
||||
CONFIG_ENV_SIZE=0x80
|
||||
CONFIG_SYS_MALLOC_LEN=0x80000
|
||||
CONFIG_COUNTER_FREQUENCY=2720000
|
||||
CONFIG_COUNTER_FREQUENCY=100000000
|
||||
# CONFIG_PSCI_RESET is not set
|
||||
CONFIG_DEFAULT_DEVICE_TREE="versal-mini-emmc1"
|
||||
# CONFIG_EXPERT is not set
|
||||
|
@ -4,8 +4,9 @@ CONFIG_ARCH_VERSAL=y
|
||||
CONFIG_SYS_TEXT_BASE=0x8000000
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x100000
|
||||
CONFIG_DM_GPIO=y
|
||||
CONFIG_CMD_FRU=y
|
||||
CONFIG_DEFINE_TCM_OCM_MMAP=y
|
||||
CONFIG_COUNTER_FREQUENCY=62500000
|
||||
CONFIG_COUNTER_FREQUENCY=100000000
|
||||
CONFIG_DISTRO_DEFAULTS=y
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_VERBOSE=y
|
||||
@ -27,6 +28,7 @@ CONFIG_CMD_GPIO=y
|
||||
CONFIG_CMD_I2C=y
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_CMD_MTD=y
|
||||
CONFIG_CMD_SF_TEST=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_CMD_TFTPPUT=y
|
||||
CONFIG_CMD_CACHE=y
|
||||
@ -51,6 +53,7 @@ CONFIG_MISC=y
|
||||
CONFIG_I2C_EEPROM=y
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR=0x0
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW=0x0
|
||||
CONFIG_SUPPORT_EMMC_BOOT=y
|
||||
CONFIG_MMC_IO_VOLTAGE=y
|
||||
CONFIG_MMC_UHS_SUPPORT=y
|
||||
CONFIG_MMC_HS400_SUPPORT=y
|
||||
@ -83,6 +86,7 @@ CONFIG_PL01X_SERIAL=y
|
||||
CONFIG_XILINX_UARTLITE=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_ZYNQ_SPI=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_DM_USB=y
|
||||
CONFIG_DM_USB_GADGET=y
|
||||
|
@ -6,6 +6,8 @@ CONFIG_SYS_SPI_U_BOOT_OFFS=0x100000
|
||||
CONFIG_DM_GPIO=y
|
||||
CONFIG_SPL_STACK_R_ADDR=0x200000
|
||||
CONFIG_SPL=y
|
||||
CONFIG_CMD_FRU=y
|
||||
CONFIG_CMD_ZYNQ_AES=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc706"
|
||||
CONFIG_DISTRO_DEFAULTS=y
|
||||
CONFIG_SYS_CUSTOM_LDSCRIPT=y
|
||||
@ -40,6 +42,7 @@ CONFIG_CMD_I2C=y
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_CMD_MTD=y
|
||||
CONFIG_CMD_NAND_LOCK_UNLOCK=y
|
||||
CONFIG_CMD_SF_TEST=y
|
||||
CONFIG_CMD_USB=y
|
||||
# CONFIG_CMD_SETEXPR is not set
|
||||
CONFIG_CMD_TFTPPUT=y
|
||||
@ -49,7 +52,7 @@ CONFIG_CMD_MTDPARTS=y
|
||||
CONFIG_CMD_MTDPARTS_SPREAD=y
|
||||
CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES=y
|
||||
CONFIG_CMD_UBI=y
|
||||
CONFIG_OF_LIST="zynq-zc702 zynq-zc706 zynq-zc770-xm010 zynq-zc770-xm011 zynq-zc770-xm011-x16 zynq-zc770-xm012 zynq-zc770-xm013 zynq-cc108 zynq-microzed zynq-minized zynq-picozed zynq-zed zynq-zturn zynq-zybo zynq-zybo-z7 zynq-dlc20-rev1.0"
|
||||
CONFIG_OF_LIST="zynq-zc702 zynq-zc706 zynq-zc770-xm010 zynq-zc770-xm011 zynq-zc770-xm011-x16 zynq-zc770-xm012 zynq-zc770-xm013 zynq-cc108 zynq-microzed zynq-minized zynq-picozed zynq-zed zynq-zturn zynq-zturn-v5 zynq-zybo zynq-zybo-z7 zynq-dlc20-rev1.0"
|
||||
CONFIG_ENV_OVERWRITE=y
|
||||
CONFIG_ENV_IS_IN_SPI_FLASH=y
|
||||
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||
@ -88,6 +91,8 @@ CONFIG_SPI_FLASH_STMICRO=y
|
||||
CONFIG_SPI_FLASH_SST=y
|
||||
CONFIG_SPI_FLASH_WINBOND=y
|
||||
CONFIG_PHY_MARVELL=y
|
||||
CONFIG_PHY_MICREL=y
|
||||
CONFIG_PHY_MICREL_KSZ90X1=y
|
||||
CONFIG_PHY_REALTEK=y
|
||||
CONFIG_PHY_XILINX=y
|
||||
CONFIG_MII=y
|
||||
|
@ -7,6 +7,9 @@ CONFIG_DM_GPIO=y
|
||||
CONFIG_SPL=y
|
||||
CONFIG_SPL_SPI_FLASH_SUPPORT=y
|
||||
CONFIG_SPL_SPI_SUPPORT=y
|
||||
CONFIG_ZYNQ_MAC_IN_EEPROM=y
|
||||
CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20
|
||||
CONFIG_CMD_FRU=y
|
||||
CONFIG_ZYNQMP_USB=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu100-revC"
|
||||
CONFIG_AHCI=y
|
||||
@ -19,6 +22,7 @@ CONFIG_USE_PREBOOT=y
|
||||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
CONFIG_BOARD_EARLY_INIT_F=y
|
||||
CONFIG_BOARD_EARLY_INIT_R=y
|
||||
CONFIG_SPL_FPGA=y
|
||||
CONFIG_SPL_OS_BOOT=y
|
||||
CONFIG_SPL_RAM_SUPPORT=y
|
||||
CONFIG_SPL_RAM_DEVICE=y
|
||||
@ -45,10 +49,12 @@ CONFIG_CMD_MTD=y
|
||||
CONFIG_CMD_NAND_LOCK_UNLOCK=y
|
||||
CONFIG_CMD_POWEROFF=y
|
||||
CONFIG_CMD_SDRAM=y
|
||||
CONFIG_CMD_SF_TEST=y
|
||||
CONFIG_CMD_SPI=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_CMD_USB_MASS_STORAGE=y
|
||||
CONFIG_CMD_TFTPPUT=y
|
||||
CONFIG_CMD_CACHE=y
|
||||
CONFIG_CMD_TIME=y
|
||||
CONFIG_CMD_TIMER=y
|
||||
CONFIG_CMD_EXT4_WRITE=y
|
||||
@ -58,6 +64,7 @@ CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES=y
|
||||
CONFIG_CMD_UBI=y
|
||||
CONFIG_SPL_OF_CONTROL=y
|
||||
CONFIG_OF_LIST="avnet-ultra96-rev1 zynqmp-a2197-revA zynqmp-e-a2197-00-revA zynqmp-g-a2197-00-revA zynqmp-m-a2197-01-revA zynqmp-m-a2197-02-revA zynqmp-m-a2197-03-revA zynqmp-p-a2197-00-revA zynqmp-zc1232-revA zynqmp-zc1254-revA zynqmp-zc1751-xm015-dc1 zynqmp-zc1751-xm016-dc2 zynqmp-zc1751-xm017-dc3 zynqmp-zc1751-xm018-dc4 zynqmp-zc1751-xm019-dc5 zynqmp-zcu100-revC zynqmp-zcu102-rev1.1 zynqmp-zcu102-rev1.0 zynqmp-zcu102-revA zynqmp-zcu102-revB zynqmp-zcu104-revA zynqmp-zcu104-revC zynqmp-zcu106-revA zynqmp-zcu111-revA zynqmp-zcu1275-revA zynqmp-zcu1275-revB zynqmp-zcu1285-revA zynqmp-zcu208-revA zynqmp-zcu216-revA zynqmp-topic-miamimp-xilinx-xdp-v1r1"
|
||||
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent interrupts iommus power-domains"
|
||||
CONFIG_ENV_IS_NOWHERE=y
|
||||
CONFIG_ENV_IS_IN_FAT=y
|
||||
CONFIG_ENV_IS_IN_NAND=y
|
||||
@ -88,7 +95,6 @@ CONFIG_LED=y
|
||||
CONFIG_LED_GPIO=y
|
||||
CONFIG_MISC=y
|
||||
CONFIG_I2C_EEPROM=y
|
||||
CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR=0x0
|
||||
CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW=0x0
|
||||
CONFIG_SUPPORT_EMMC_BOOT=y
|
||||
|
@ -8,3 +8,5 @@ Xilinx
|
||||
|
||||
xilinx
|
||||
zynq
|
||||
zynqmp
|
||||
zynqmp-r5
|
||||
|
@ -10,18 +10,28 @@ kernel.
|
||||
|
||||
* ata
|
||||
- Documentation/devicetree/bindings/ata/ahci-ceva.txt
|
||||
* clock
|
||||
- Documentation/devicetree/bindings/clock/xlnx,zynqmp-clk.txt
|
||||
* firmware
|
||||
- Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt
|
||||
* fpga
|
||||
- Documentation/devicetree/bindings/fpga/xlnx,zynqmp-pcap-fpga.txt
|
||||
* gpio
|
||||
- Documentation/devicetree/bindings/gpio/gpio-xilinx.txt
|
||||
- Documentation/devicetree/bindings/gpio/gpio-zynq.txt
|
||||
* i2c
|
||||
- Documentation/devicetree/bindings/i2c/i2c-xiic.txt
|
||||
- Documentation/devicetree/bindings/i2c/i2c-cadence.txt
|
||||
- Documentation/devicetree/bindings/i2c/xlnx,xps-iic-2.00.a.yaml
|
||||
- Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml
|
||||
* mmc
|
||||
- Documentation/devicetree/bindings/mmc/arasan,sdhci.txt
|
||||
- Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml
|
||||
* net
|
||||
- Documentation/devicetree/bindings/net/macb.txt
|
||||
- Documentation/devicetree/bindings/net/xilinx_axienet.txt
|
||||
- Documentation/devicetree/bindings/net/xilinx_emaclite.txt
|
||||
* nvmem
|
||||
- Documentation/devicetree/bindings/nvmem/xlnx,zynqmp-nvmem.txt
|
||||
* power
|
||||
- Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt
|
||||
* serial
|
||||
- Documentation/devicetree/bindings/serial/cdns,uart.txt
|
||||
- Documentation/devicetree/bindings/serial/xlnx,opb-uartlite.txt
|
||||
|
@ -83,7 +83,7 @@ Mainline status
|
||||
---------------
|
||||
|
||||
- Added basic board configurations support.
|
||||
- Added zynq u-boot bsp code - arch/arm/cpu/armv7/zynq
|
||||
- Added zynq u-boot bsp code - arch/arm/mach-zynq
|
||||
- Added zynq boards named - zc70x, zed, microzed, zc770_xm010/xm011/xm012/xm013
|
||||
- Added zynq drivers:
|
||||
|
||||
@ -99,11 +99,6 @@ Mainline status
|
||||
- Added basic FDT support for zynq boards
|
||||
- d-cache support for zynq_gem.c
|
||||
|
||||
TODO
|
||||
----
|
||||
|
||||
Add FDT support on individual drivers
|
||||
|
||||
* [1] http://www.xilinx.com/products/boards-and-kits/EK-Z7-ZC702-G.htm
|
||||
* [2] http://www.xilinx.com/products/boards-and-kits/EK-Z7-ZC706-G.htm
|
||||
* [3] http://zedboard.org/product/zedboard
|
||||
|
137
doc/board/xilinx/zynqmp-r5.rst
Normal file
137
doc/board/xilinx/zynqmp-r5.rst
Normal file
@ -0,0 +1,137 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
.. (C) Copyright 2020 Xilinx, Inc.
|
||||
|
||||
ZYNQMP-R5
|
||||
=========
|
||||
|
||||
About this
|
||||
----------
|
||||
|
||||
This document describes the information about Xilinx Zynq UltraScale+ MPSOC
|
||||
U-Boot Cortex R5 support.
|
||||
|
||||
ZynqMP R5 boards
|
||||
----------------
|
||||
|
||||
* zynqmp-r5 - U-Boot running on RPU Cortex-R5
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
configure and build armv7 toolchain::
|
||||
|
||||
$ make xilinx_zynqmp_r5_defconfig
|
||||
$ make
|
||||
|
||||
Notes
|
||||
^^^^^
|
||||
|
||||
Output fragment is u-boot.
|
||||
|
||||
Loading
|
||||
-------
|
||||
|
||||
ZynqMP R5 U-Boot was created for supporting loading OS on RPU. There are two
|
||||
ways how to start U-Boot on R5.
|
||||
|
||||
Bootgen
|
||||
^^^^^^^
|
||||
|
||||
The first way is to use Xilinx FSBL (First stage
|
||||
bootloader) to load u-boot and start it. The following bif can be used for boot
|
||||
image generation via Xilinx bootgen utility::
|
||||
|
||||
|
||||
the_ROM_image:
|
||||
{
|
||||
[bootloader,destination_cpu=r5-0] fsbl_rpu.elf
|
||||
[destination_cpu=r5-0]u-boot.elf
|
||||
}
|
||||
|
||||
Bootgen command for building boot.bin::
|
||||
|
||||
bootgen -image <bif>.bif -r -w -o i boot.bin
|
||||
|
||||
|
||||
U-Boot cpu command
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The second way to load U-Boot to Cortex R5 is from U-Boot running on A53 as is
|
||||
visible from the following log::
|
||||
|
||||
U-Boot SPL 2020.10-rc4-00090-g801b3d5c5757 (Sep 15 2020 - 14:07:24 +0200)
|
||||
PMUFW: v1.1
|
||||
Loading new PMUFW cfg obj (2024 bytes)
|
||||
EL Level: EL3
|
||||
Multiboot: 0
|
||||
Trying to boot from MMC2
|
||||
spl: could not initialize mmc. error: -19
|
||||
Trying to boot from MMC1
|
||||
spl_load_image_fat_os: error reading image u-boot.bin, err - -2
|
||||
NOTICE: ATF running on XCZU7EG/EV/silicon v4/RTL5.1 at 0xfffea000
|
||||
NOTICE: BL31: v2.2(release):v2.2-614-ged9dc512fb9c
|
||||
NOTICE: BL31: Built : 09:32:09, Mar 13 2020
|
||||
|
||||
|
||||
U-Boot 2020.10-rc4-00090-g801b3d5c5757 (Sep 15 2020 - 14:07:24 +0200)
|
||||
|
||||
Model: ZynqMP ZCU104 RevC
|
||||
Board: Xilinx ZynqMP
|
||||
DRAM: 2 GiB
|
||||
PMUFW: v1.1
|
||||
EL Level: EL2
|
||||
Chip ID: zu7e
|
||||
WDT: Started with servicing (60s timeout)
|
||||
NAND: 0 MiB
|
||||
MMC: mmc@ff170000: 0
|
||||
Loading Environment from FAT... *** Warning - bad CRC, using default environment
|
||||
|
||||
In: serial
|
||||
Out: serial
|
||||
Err: serial
|
||||
Bootmode: LVL_SHFT_SD_MODE1
|
||||
Reset reason: SOFT
|
||||
Net:
|
||||
ZYNQ GEM: ff0e0000, mdio bus ff0e0000, phyaddr 12, interface rgmii-id
|
||||
eth0: ethernet@ff0e0000
|
||||
Hit any key to stop autoboot: 0
|
||||
ZynqMP> setenv autoload no
|
||||
ZynqMP> dhcp
|
||||
BOOTP broadcast 1
|
||||
DHCP client bound to address 192.168.0.167 (8 ms)
|
||||
ZynqMP> tftpboot 20000000 192.168.0.105:u-boot-r5-2.elf
|
||||
Using ethernet@ff0e0000 device
|
||||
TFTP from server 192.168.0.105; our IP address is 192.168.0.167
|
||||
Filename 'u-boot-r5-2.elf'.
|
||||
Load address: 0x20000000
|
||||
Loading: #################################################################
|
||||
#################################################################
|
||||
#################################################################
|
||||
#################################################################
|
||||
#################################################################
|
||||
#################################################################
|
||||
################
|
||||
376 KiB/s
|
||||
done
|
||||
Bytes transferred = 2075464 (1fab48 hex)
|
||||
ZynqMP> setenv autostart no
|
||||
ZynqMP> bootelf -p 20000000
|
||||
ZynqMP> cpu 4 release 10000000 lockstep
|
||||
Using TCM jump trampoline for address 0x10000000
|
||||
R5 lockstep mode
|
||||
ZynqMP>
|
||||
|
||||
Then on second uart you can see U-Boot up and running on R5::
|
||||
|
||||
U-Boot 2020.10-rc4-00071-g7045622cc9ba (Sep 16 2020 - 13:38:53 +0200)
|
||||
|
||||
Model: Xilinx ZynqMP R5
|
||||
DRAM: 512 MiB
|
||||
MMC:
|
||||
In: serial@ff010000
|
||||
Out: serial@ff010000
|
||||
Err: serial@ff010000
|
||||
Net: No ethernet found.
|
||||
ZynqMP r5>
|
||||
|
||||
Please make sure MIO pins for uart are properly configured to see output.
|
115
doc/board/xilinx/zynqmp.rst
Normal file
115
doc/board/xilinx/zynqmp.rst
Normal file
@ -0,0 +1,115 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
.. (C) Copyright 2020 Xilinx, Inc.
|
||||
|
||||
ZYNQMP
|
||||
======
|
||||
|
||||
About this
|
||||
----------
|
||||
|
||||
This document describes the information about Xilinx Zynq UltraScale+ MPSOC
|
||||
U-Boot support. Core support is available in arch/arm/mach-zynqmp folder.
|
||||
|
||||
ZynqMP boards
|
||||
-------------
|
||||
|
||||
* zcu100 (ultra96 v1), zcu102, zcu104, zcu106 - Evaluation boards
|
||||
* zc1232 - Characterization boards
|
||||
* zcu111, zcu208, zcu216 - RFSOC evaluation boards
|
||||
* zcu1254, zcu1275, zcu1285 - RFSOC characterization boards
|
||||
* a2197 - System Controller on Versal boards
|
||||
* mini - Mini U-Boot running out of OCM
|
||||
* zc1751 - Characterization Processor boards
|
||||
- zc1751-xm015-dc1
|
||||
- zc1751-xm016-dc2
|
||||
- zc1751-xm017-dc3
|
||||
- zc1751-xm018-dc4
|
||||
- zc1751-xm019-dc5
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
Configure and build for zcu102 board::
|
||||
|
||||
$ source arm64 toolchain
|
||||
$ export DEVICE_TREE=zynqmp-zcu102-revA
|
||||
$ make xilinx_zynqmp_virt_defconfig
|
||||
$ make
|
||||
|
||||
U-Boot SPL flow
|
||||
---------------
|
||||
|
||||
For getting U-Boot SPL flow up and running it is necessary to do some additional
|
||||
steps because booting device requires external images which are not the part of
|
||||
U-Boot repository.
|
||||
|
||||
PMU firmware
|
||||
^^^^^^^^^^^^
|
||||
The Platform Management Unit (PMU) RAM can be loaded with a firmware (PMU
|
||||
Firmware) at run-time and can be used to extend or customize the functionality
|
||||
of PMU. The PMU firmware is the part of boot image (boot.bin) and it is
|
||||
automatically loaded by BootROM. boot.bin can be directly generated by mkimage
|
||||
tool as the part of make. If you want to create boot.bin with PMU Firmware
|
||||
include please point CONFIG_PMUFW_INIT_FILE to PMU firmware binary. For example:::
|
||||
|
||||
CONFIG_PMUFW_INIT_FILE="<path>/pmu.bin"
|
||||
|
||||
If you see below message you need to load PMU Firmware::
|
||||
|
||||
PMUFW is not found - Please load it!
|
||||
|
||||
The second external blob is PMU Configuration object which is object which is
|
||||
passed from U-Boot SPL to PMU Firmware for initial system configuration. PMU
|
||||
configuration object is the part of U-Boot SPL image. For pointing to this
|
||||
object please use CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE symbol. For example:::
|
||||
|
||||
CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE="<path>/pmu_obj.bin"
|
||||
|
||||
|
||||
PMU configuration object
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Object can be obtain in several ways. The easiest way is to take pm_cfg_obj.c
|
||||
from SDK/Vitis design and build it:::
|
||||
|
||||
$ git clone https://github.com/Xilinx/embeddedsw.git
|
||||
$ export EMBEDDED_SW=$PWD/embeddedsw
|
||||
$ gcc -c pm_cfg_obj.c -I ${EMBEDDED_SW}/lib/bsp/standalone/src/common/ -I ${EMBEDDED_SW}/lib/sw_services/xilpm/src/zynqmp/client/common/
|
||||
$ objcopy -O binary pm_cfg_obj.o pmu_obj.bin
|
||||
|
||||
The second way is to use tools/zynqmp_pm_cfg_obj_convert.py. For more
|
||||
information about this tool please run it with -h parameter.
|
||||
|
||||
The third way is to extract it from Xilinx FSBL elf file. Object is starting at
|
||||
XPm_ConfigObject symbol.
|
||||
|
||||
|
||||
Arm Trusted Firmware (ATF)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
U-Boot itself can run from EL3 to EL1. Without ATF U-Boot runs in EL3. Boot flow
|
||||
is U-Boot SPL->U-Boot in EL3. When ATF is used U-Boot normally runs in EL2. Boot
|
||||
flow is U-Boot SPL->ATF->U-Boot in EL2. As the part of build process u-boot.itb
|
||||
is generated. When BL31 shell variable is present u-boot.itb is generated with
|
||||
ATF included. You can point to it by:::
|
||||
|
||||
$ export BL31=<path>/bl31.bin
|
||||
|
||||
Flashing
|
||||
--------
|
||||
|
||||
SD Card
|
||||
^^^^^^^
|
||||
|
||||
To write an image that boots from a SD card first create a FAT32 partition
|
||||
and a FAT32 filesystem on the SD card::
|
||||
|
||||
sudo fdisk /dev/sdx
|
||||
sudo mkfs.vfat -F 32 /dev/sdx1
|
||||
|
||||
Mount the SD card and copy the SPL and U-Boot to the root directory of the
|
||||
SD card::
|
||||
|
||||
sudo mount -t vfat /dev/sdx1 /mnt
|
||||
sudo cp spl/boot.bin /mnt
|
||||
sudo cp u-boot.itb /mnt
|
@ -66,6 +66,90 @@ can point to a script which generates this image source file during
|
||||
the build process. It gets passed a list of device tree files (taken from the
|
||||
CONFIG_OF_LIST symbol).
|
||||
|
||||
The SPL also records to a DT all additional images (called loadables) which are
|
||||
loaded. The information about loadables locations is passed via the DT node with
|
||||
fit-images name.
|
||||
|
||||
Loadables Example
|
||||
-----------------
|
||||
Consider the following case for an ARM64 platform where U-Boot runs in EL2
|
||||
started by ATF where SPL is loading U-Boot (as loadables) and ATF (as firmware).
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
description = "Configuration to load ATF before U-Boot";
|
||||
|
||||
images {
|
||||
uboot {
|
||||
description = "U-Boot (64-bit)";
|
||||
data = /incbin/("u-boot-nodtb.bin");
|
||||
type = "firmware";
|
||||
os = "u-boot";
|
||||
arch = "arm64";
|
||||
compression = "none";
|
||||
load = <0x8 0x8000000>;
|
||||
entry = <0x8 0x8000000>;
|
||||
hash {
|
||||
algo = "md5";
|
||||
};
|
||||
};
|
||||
atf {
|
||||
description = "ARM Trusted Firmware";
|
||||
data = /incbin/("bl31.bin");
|
||||
type = "firmware";
|
||||
os = "arm-trusted-firmware";
|
||||
arch = "arm64";
|
||||
compression = "none";
|
||||
load = <0xfffea000>;
|
||||
entry = <0xfffea000>;
|
||||
hash {
|
||||
algo = "md5";
|
||||
};
|
||||
};
|
||||
fdt_1 {
|
||||
description = "zynqmp-zcu102-revA";
|
||||
data = /incbin/("arch/arm/dts/zynqmp-zcu102-revA.dtb");
|
||||
type = "flat_dt";
|
||||
arch = "arm64";
|
||||
compression = "none";
|
||||
load = <0x100000>;
|
||||
hash {
|
||||
algo = "md5";
|
||||
};
|
||||
};
|
||||
};
|
||||
configurations {
|
||||
default = "config_1";
|
||||
|
||||
config_1 {
|
||||
description = "zynqmp-zcu102-revA";
|
||||
firmware = "atf";
|
||||
loadables = "uboot";
|
||||
fdt = "fdt_1";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
In this case the SPL records via fit-images DT node the information about
|
||||
loadables U-Boot image.
|
||||
|
||||
ZynqMP> fdt addr $fdtcontroladdr
|
||||
ZynqMP> fdt print /fit-images
|
||||
fit-images {
|
||||
uboot {
|
||||
os = "u-boot";
|
||||
type = "firmware";
|
||||
size = <0x001017c8>;
|
||||
entry = <0x00000008 0x08000000>;
|
||||
load = <0x00000008 0x08000000>;
|
||||
};
|
||||
};
|
||||
|
||||
As you can see entry and load properties are 64bit wide to support loading
|
||||
images above 4GB (in past entry and load properties where just 32bit).
|
||||
|
||||
|
||||
Example 1 -- old-style (non-FDT) kernel booting
|
||||
-----------------------------------------------
|
||||
|
||||
|
@ -476,6 +476,28 @@ ofnode ofnode_get_chosen_node(const char *name)
|
||||
return ofnode_path(prop);
|
||||
}
|
||||
|
||||
const void *ofnode_read_aliases_prop(const char *propname, int *sizep)
|
||||
{
|
||||
ofnode node;
|
||||
|
||||
node = ofnode_path("/aliases");
|
||||
|
||||
return ofnode_read_prop(node, propname, sizep);
|
||||
}
|
||||
|
||||
ofnode ofnode_get_aliases_node(const char *name)
|
||||
{
|
||||
const char *prop;
|
||||
|
||||
prop = ofnode_read_aliases_prop(name, NULL);
|
||||
if (!prop)
|
||||
return ofnode_null();
|
||||
|
||||
debug("%s: node_path: %s\n", __func__, prop);
|
||||
|
||||
return ofnode_path(prop);
|
||||
}
|
||||
|
||||
int ofnode_get_child_count(ofnode parent)
|
||||
{
|
||||
ofnode child;
|
||||
|
@ -165,6 +165,14 @@ int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
|
||||
*/
|
||||
u32 regs[] = {api_id, arg0, arg1, arg2, arg3};
|
||||
|
||||
if (api_id == PM_FPGA_LOAD) {
|
||||
/* Swap addr_hi/low because of incompatibility */
|
||||
u32 temp = regs[1];
|
||||
|
||||
regs[1] = regs[2];
|
||||
regs[2] = temp;
|
||||
}
|
||||
|
||||
ipi_req(regs, PAYLOAD_ARG_CNT, ret_payload, PAYLOAD_ARG_CNT);
|
||||
#else
|
||||
return -EPERM;
|
||||
|
@ -56,7 +56,7 @@ static int zynqmp_ipi_send(struct mbox_chan *chan, const void *data)
|
||||
|
||||
/* Wait until observation bit is cleared */
|
||||
ret = wait_for_bit_le32(&ipi_int_apu->obs, IPI_BIT_MASK_PMU0, false,
|
||||
100, false);
|
||||
1000, false);
|
||||
|
||||
debug("%s, send %ld bytes\n", __func__, msg->len);
|
||||
return ret;
|
||||
|
@ -376,13 +376,6 @@ config SPL_I2C_EEPROM
|
||||
This option is an SPL-variant of the I2C_EEPROM option.
|
||||
See the help of I2C_EEPROM for details.
|
||||
|
||||
config ZYNQ_GEM_I2C_MAC_OFFSET
|
||||
hex "Set the I2C MAC offset"
|
||||
default 0x0
|
||||
depends on DM_I2C
|
||||
help
|
||||
Set the MAC offset for i2C.
|
||||
|
||||
if I2C_EEPROM
|
||||
|
||||
config SYS_I2C_EEPROM_ADDR
|
||||
|
@ -812,7 +812,8 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
|
||||
cfg->host_caps &= ~MMC_MODE_HS_52MHz;
|
||||
}
|
||||
|
||||
if (!(cfg->voltages & MMC_VDD_165_195))
|
||||
if (!(cfg->voltages & MMC_VDD_165_195) ||
|
||||
(host->quirks & SDHCI_QUIRK_NO_1_8_V))
|
||||
caps_1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
|
||||
SDHCI_SUPPORT_DDR50);
|
||||
|
||||
|
@ -19,6 +19,20 @@
|
||||
#include <sdhci.h>
|
||||
#include <zynqmp_tap_delay.h>
|
||||
|
||||
#define SDHCI_ARASAN_ITAPDLY_REGISTER 0xF0F8
|
||||
#define SDHCI_ARASAN_OTAPDLY_REGISTER 0xF0FC
|
||||
#define SDHCI_ITAPDLY_CHGWIN 0x200
|
||||
#define SDHCI_ITAPDLY_ENABLE 0x100
|
||||
#define SDHCI_OTAPDLY_ENABLE 0x40
|
||||
|
||||
#define SDHCI_TUNING_LOOP_COUNT 40
|
||||
#define MMC_BANK2 0x2
|
||||
|
||||
struct arasan_sdhci_clk_data {
|
||||
int clk_phase_in[MMC_TIMING_MMC_HS400 + 1];
|
||||
int clk_phase_out[MMC_TIMING_MMC_HS400 + 1];
|
||||
};
|
||||
|
||||
struct arasan_sdhci_plat {
|
||||
struct mmc_config cfg;
|
||||
struct mmc mmc;
|
||||
@ -26,29 +40,35 @@ struct arasan_sdhci_plat {
|
||||
|
||||
struct arasan_sdhci_priv {
|
||||
struct sdhci_host *host;
|
||||
struct arasan_sdhci_clk_data clk_data;
|
||||
u8 deviceid;
|
||||
u8 bank;
|
||||
u8 no_1p8;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_ARCH_ZYNQMP)
|
||||
#define MMC_HS200_BUS_SPEED 5
|
||||
#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL)
|
||||
/* Default settings for ZynqMP Clock Phases */
|
||||
const u32 zynqmp_iclk_phases[] = {0, 63, 63, 0, 63, 0, 0, 183, 54, 0, 0};
|
||||
const u32 zynqmp_oclk_phases[] = {0, 72, 60, 0, 60, 72, 135, 48, 72, 135, 0};
|
||||
|
||||
/* Default settings for Versal Clock Phases */
|
||||
const u32 versal_iclk_phases[] = {0, 132, 132, 0, 132, 0, 0, 162, 90, 0, 0};
|
||||
const u32 versal_oclk_phases[] = {0, 60, 48, 0, 48, 72, 90, 36, 60, 90, 0};
|
||||
|
||||
static const u8 mode2timing[] = {
|
||||
[MMC_LEGACY] = UHS_SDR12_BUS_SPEED,
|
||||
[MMC_HS] = HIGH_SPEED_BUS_SPEED,
|
||||
[SD_HS] = HIGH_SPEED_BUS_SPEED,
|
||||
[MMC_HS_52] = HIGH_SPEED_BUS_SPEED,
|
||||
[MMC_DDR_52] = HIGH_SPEED_BUS_SPEED,
|
||||
[UHS_SDR12] = UHS_SDR12_BUS_SPEED,
|
||||
[UHS_SDR25] = UHS_SDR25_BUS_SPEED,
|
||||
[UHS_SDR50] = UHS_SDR50_BUS_SPEED,
|
||||
[UHS_DDR50] = UHS_DDR50_BUS_SPEED,
|
||||
[UHS_SDR104] = UHS_SDR104_BUS_SPEED,
|
||||
[MMC_HS_200] = MMC_HS200_BUS_SPEED,
|
||||
[MMC_LEGACY] = MMC_TIMING_LEGACY,
|
||||
[MMC_HS] = MMC_TIMING_MMC_HS,
|
||||
[SD_HS] = MMC_TIMING_SD_HS,
|
||||
[MMC_HS_52] = MMC_TIMING_UHS_SDR50,
|
||||
[MMC_DDR_52] = MMC_TIMING_UHS_DDR50,
|
||||
[UHS_SDR12] = MMC_TIMING_UHS_SDR12,
|
||||
[UHS_SDR25] = MMC_TIMING_UHS_SDR25,
|
||||
[UHS_SDR50] = MMC_TIMING_UHS_SDR50,
|
||||
[UHS_DDR50] = MMC_TIMING_UHS_DDR50,
|
||||
[UHS_SDR104] = MMC_TIMING_UHS_SDR104,
|
||||
[MMC_HS_200] = MMC_TIMING_MMC_HS200,
|
||||
};
|
||||
|
||||
#define SDHCI_TUNING_LOOP_COUNT 40
|
||||
|
||||
static void arasan_zynqmp_dll_reset(struct sdhci_host *host, u8 deviceid)
|
||||
{
|
||||
u16 clk;
|
||||
@ -156,17 +176,352 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void arasan_sdhci_set_tapdelay(struct sdhci_host *host)
|
||||
/**
|
||||
* sdhci_zynqmp_sdcardclk_set_phase - Set the SD Output Clock Tap Delays
|
||||
*
|
||||
* Set the SD Output Clock Tap Delays for Output path
|
||||
*
|
||||
* @host: Pointer to the sdhci_host structure.
|
||||
* @degrees: The clock phase shift between 0 - 359.
|
||||
* Return: 0 on success and error value on error
|
||||
*/
|
||||
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;
|
||||
u8 uhsmode;
|
||||
u8 tap_delay, tap_max = 0;
|
||||
int ret;
|
||||
int timing = mode2timing[mmc->selected_mode];
|
||||
|
||||
uhsmode = mode2timing[mmc->selected_mode];
|
||||
/*
|
||||
* This is applicable for SDHCI_SPEC_300 and above
|
||||
* ZynqMP does not set phase for <=25MHz clock.
|
||||
* If degrees is zero, no need to do anything.
|
||||
*/
|
||||
if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300 ||
|
||||
timing == MMC_TIMING_LEGACY ||
|
||||
timing == MMC_TIMING_UHS_SDR12 || !degrees)
|
||||
return 0;
|
||||
|
||||
if (uhsmode >= UHS_SDR25_BUS_SPEED)
|
||||
arasan_zynqmp_set_tapdelay(priv->deviceid, uhsmode,
|
||||
priv->bank);
|
||||
switch (timing) {
|
||||
case MMC_TIMING_MMC_HS:
|
||||
case MMC_TIMING_SD_HS:
|
||||
case MMC_TIMING_UHS_SDR25:
|
||||
case MMC_TIMING_UHS_DDR50:
|
||||
case MMC_TIMING_MMC_DDR52:
|
||||
/* For 50MHz clock, 30 Taps are available */
|
||||
tap_max = 30;
|
||||
break;
|
||||
case MMC_TIMING_UHS_SDR50:
|
||||
/* For 100MHz clock, 15 Taps are available */
|
||||
tap_max = 15;
|
||||
break;
|
||||
case MMC_TIMING_UHS_SDR104:
|
||||
case MMC_TIMING_MMC_HS200:
|
||||
/* For 200MHz clock, 8 Taps are available */
|
||||
tap_max = 8;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
tap_delay = (degrees * tap_max) / 360;
|
||||
|
||||
arasan_zynqmp_set_tapdelay(priv->deviceid, 0, tap_delay);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* sdhci_zynqmp_sampleclk_set_phase - Set the SD Input Clock Tap Delays
|
||||
*
|
||||
* Set the SD Input Clock Tap Delays for Input path
|
||||
*
|
||||
* @host: Pointer to the sdhci_host structure.
|
||||
* @degrees: The clock phase shift between 0 - 359.
|
||||
* Return: 0 on success and error value on error
|
||||
*/
|
||||
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;
|
||||
u8 tap_delay, tap_max = 0;
|
||||
int ret;
|
||||
int timing = mode2timing[mmc->selected_mode];
|
||||
|
||||
/*
|
||||
* This is applicable for SDHCI_SPEC_300 and above
|
||||
* ZynqMP does not set phase for <=25MHz clock.
|
||||
* If degrees is zero, no need to do anything.
|
||||
*/
|
||||
if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300 ||
|
||||
timing == MMC_TIMING_LEGACY ||
|
||||
timing == MMC_TIMING_UHS_SDR12 || !degrees)
|
||||
return 0;
|
||||
|
||||
switch (timing) {
|
||||
case MMC_TIMING_MMC_HS:
|
||||
case MMC_TIMING_SD_HS:
|
||||
case MMC_TIMING_UHS_SDR25:
|
||||
case MMC_TIMING_UHS_DDR50:
|
||||
case MMC_TIMING_MMC_DDR52:
|
||||
/* For 50MHz clock, 120 Taps are available */
|
||||
tap_max = 120;
|
||||
break;
|
||||
case MMC_TIMING_UHS_SDR50:
|
||||
/* For 100MHz clock, 60 Taps are available */
|
||||
tap_max = 60;
|
||||
break;
|
||||
case MMC_TIMING_UHS_SDR104:
|
||||
case MMC_TIMING_MMC_HS200:
|
||||
/* For 200MHz clock, 30 Taps are available */
|
||||
tap_max = 30;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
tap_delay = (degrees * tap_max) / 360;
|
||||
|
||||
arasan_zynqmp_set_tapdelay(priv->deviceid, tap_delay, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* sdhci_versal_sdcardclk_set_phase - Set the SD Output Clock Tap Delays
|
||||
*
|
||||
* Set the SD Output Clock Tap Delays for Output path
|
||||
*
|
||||
* @host: Pointer to the sdhci_host structure.
|
||||
* @degrees The clock phase shift between 0 - 359.
|
||||
* Return: 0 on success and error value on error
|
||||
*/
|
||||
static int sdhci_versal_sdcardclk_set_phase(struct sdhci_host *host,
|
||||
int degrees)
|
||||
{
|
||||
struct mmc *mmc = (struct mmc *)host->mmc;
|
||||
u8 tap_delay, tap_max = 0;
|
||||
int ret;
|
||||
int timing = mode2timing[mmc->selected_mode];
|
||||
|
||||
/*
|
||||
* This is applicable for SDHCI_SPEC_300 and above
|
||||
* Versal does not set phase for <=25MHz clock.
|
||||
* If degrees is zero, no need to do anything.
|
||||
*/
|
||||
if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300 ||
|
||||
timing == MMC_TIMING_LEGACY ||
|
||||
timing == MMC_TIMING_UHS_SDR12 || !degrees)
|
||||
return 0;
|
||||
|
||||
switch (timing) {
|
||||
case MMC_TIMING_MMC_HS:
|
||||
case MMC_TIMING_SD_HS:
|
||||
case MMC_TIMING_UHS_SDR25:
|
||||
case MMC_TIMING_UHS_DDR50:
|
||||
case MMC_TIMING_MMC_DDR52:
|
||||
/* For 50MHz clock, 30 Taps are available */
|
||||
tap_max = 30;
|
||||
break;
|
||||
case MMC_TIMING_UHS_SDR50:
|
||||
/* For 100MHz clock, 15 Taps are available */
|
||||
tap_max = 15;
|
||||
break;
|
||||
case MMC_TIMING_UHS_SDR104:
|
||||
case MMC_TIMING_MMC_HS200:
|
||||
/* For 200MHz clock, 8 Taps are available */
|
||||
tap_max = 8;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
tap_delay = (degrees * tap_max) / 360;
|
||||
|
||||
/* Set the Clock Phase */
|
||||
if (tap_delay) {
|
||||
u32 regval;
|
||||
|
||||
regval = sdhci_readl(host, SDHCI_ARASAN_OTAPDLY_REGISTER);
|
||||
regval |= SDHCI_OTAPDLY_ENABLE;
|
||||
sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER);
|
||||
regval |= tap_delay;
|
||||
sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* sdhci_versal_sampleclk_set_phase - Set the SD Input Clock Tap Delays
|
||||
*
|
||||
* Set the SD Input Clock Tap Delays for Input path
|
||||
*
|
||||
* @host: Pointer to the sdhci_host structure.
|
||||
* @degrees The clock phase shift between 0 - 359.
|
||||
* Return: 0 on success and error value on error
|
||||
*/
|
||||
static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host,
|
||||
int degrees)
|
||||
{
|
||||
struct mmc *mmc = (struct mmc *)host->mmc;
|
||||
u8 tap_delay, tap_max = 0;
|
||||
int ret;
|
||||
int timing = mode2timing[mmc->selected_mode];
|
||||
|
||||
/*
|
||||
* This is applicable for SDHCI_SPEC_300 and above
|
||||
* Versal does not set phase for <=25MHz clock.
|
||||
* If degrees is zero, no need to do anything.
|
||||
*/
|
||||
if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300 ||
|
||||
timing == MMC_TIMING_LEGACY ||
|
||||
timing == MMC_TIMING_UHS_SDR12 || !degrees)
|
||||
return 0;
|
||||
|
||||
switch (timing) {
|
||||
case MMC_TIMING_MMC_HS:
|
||||
case MMC_TIMING_SD_HS:
|
||||
case MMC_TIMING_UHS_SDR25:
|
||||
case MMC_TIMING_UHS_DDR50:
|
||||
case MMC_TIMING_MMC_DDR52:
|
||||
/* For 50MHz clock, 120 Taps are available */
|
||||
tap_max = 120;
|
||||
break;
|
||||
case MMC_TIMING_UHS_SDR50:
|
||||
/* For 100MHz clock, 60 Taps are available */
|
||||
tap_max = 60;
|
||||
break;
|
||||
case MMC_TIMING_UHS_SDR104:
|
||||
case MMC_TIMING_MMC_HS200:
|
||||
/* For 200MHz clock, 30 Taps are available */
|
||||
tap_max = 30;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
tap_delay = (degrees * tap_max) / 360;
|
||||
|
||||
/* Set the Clock Phase */
|
||||
if (tap_delay) {
|
||||
u32 regval;
|
||||
|
||||
regval = sdhci_readl(host, SDHCI_ARASAN_ITAPDLY_REGISTER);
|
||||
regval |= SDHCI_ITAPDLY_CHGWIN;
|
||||
sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
|
||||
regval |= SDHCI_ITAPDLY_ENABLE;
|
||||
sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
|
||||
regval |= tap_delay;
|
||||
sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
|
||||
regval &= ~SDHCI_ITAPDLY_CHGWIN;
|
||||
sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void 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;
|
||||
struct mmc *mmc = (struct mmc *)host->mmc;
|
||||
struct udevice *dev = mmc->dev;
|
||||
u8 timing = mode2timing[mmc->selected_mode];
|
||||
u32 iclk_phase = clk_data->clk_phase_in[timing];
|
||||
u32 oclk_phase = clk_data->clk_phase_out[timing];
|
||||
|
||||
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);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
static void arasan_dt_read_clk_phase(struct udevice *dev, unsigned char timing,
|
||||
const char *prop)
|
||||
{
|
||||
struct arasan_sdhci_priv *priv = dev_get_priv(dev);
|
||||
struct arasan_sdhci_clk_data *clk_data = &priv->clk_data;
|
||||
u32 clk_phase[2] = {0};
|
||||
|
||||
/*
|
||||
* Read Tap Delay values from DT, if the DT does not contain the
|
||||
* Tap Values then use the pre-defined values
|
||||
*/
|
||||
if (dev_read_u32_array(dev, prop, &clk_phase[0], 2)) {
|
||||
dev_dbg(dev, "Using predefined clock phase for %s = %d %d\n",
|
||||
prop, clk_data->clk_phase_in[timing],
|
||||
clk_data->clk_phase_out[timing]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* The values read are Input and Output Clock Delays in order */
|
||||
clk_data->clk_phase_in[timing] = clk_phase[0];
|
||||
clk_data->clk_phase_out[timing] = clk_phase[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* arasan_dt_parse_clk_phases - Read Tap Delay values from DT
|
||||
*
|
||||
* Called at initialization to parse the values of Tap Delays.
|
||||
*
|
||||
* @dev: Pointer to our struct udevice.
|
||||
*/
|
||||
static void arasan_dt_parse_clk_phases(struct udevice *dev)
|
||||
{
|
||||
struct arasan_sdhci_priv *priv = dev_get_priv(dev);
|
||||
struct arasan_sdhci_clk_data *clk_data = &priv->clk_data;
|
||||
int i;
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARCH_ZYNQMP) &&
|
||||
device_is_compatible(dev, "xlnx,zynqmp-8.9a")) {
|
||||
for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) {
|
||||
clk_data->clk_phase_in[i] = zynqmp_iclk_phases[i];
|
||||
clk_data->clk_phase_out[i] = zynqmp_oclk_phases[i];
|
||||
}
|
||||
|
||||
if (priv->bank == MMC_BANK2) {
|
||||
clk_data->clk_phase_out[MMC_TIMING_UHS_SDR104] = 90;
|
||||
clk_data->clk_phase_out[MMC_TIMING_MMC_HS200] = 90;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARCH_VERSAL) &&
|
||||
device_is_compatible(dev, "xlnx,versal-8.9a")) {
|
||||
for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) {
|
||||
clk_data->clk_phase_in[i] = versal_iclk_phases[i];
|
||||
clk_data->clk_phase_out[i] = versal_oclk_phases[i];
|
||||
}
|
||||
}
|
||||
|
||||
arasan_dt_read_clk_phase(dev, MMC_TIMING_LEGACY,
|
||||
"clk-phase-legacy");
|
||||
arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_HS,
|
||||
"clk-phase-mmc-hs");
|
||||
arasan_dt_read_clk_phase(dev, MMC_TIMING_SD_HS,
|
||||
"clk-phase-sd-hs");
|
||||
arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR12,
|
||||
"clk-phase-uhs-sdr12");
|
||||
arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR25,
|
||||
"clk-phase-uhs-sdr25");
|
||||
arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR50,
|
||||
"clk-phase-uhs-sdr50");
|
||||
arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR104,
|
||||
"clk-phase-uhs-sdr104");
|
||||
arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_DDR50,
|
||||
"clk-phase-uhs-ddr50");
|
||||
arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_DDR52,
|
||||
"clk-phase-mmc-ddr52");
|
||||
arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_HS200,
|
||||
"clk-phase-mmc-hs200");
|
||||
arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_HS400,
|
||||
"clk-phase-mmc-hs400");
|
||||
}
|
||||
|
||||
static void arasan_sdhci_set_control_reg(struct sdhci_host *host)
|
||||
@ -184,12 +539,10 @@ static void arasan_sdhci_set_control_reg(struct sdhci_host *host)
|
||||
}
|
||||
|
||||
if (mmc->selected_mode > SD_HS &&
|
||||
mmc->selected_mode <= UHS_DDR50)
|
||||
mmc->selected_mode <= MMC_HS_200)
|
||||
sdhci_set_uhs_timing(host);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_ZYNQMP)
|
||||
const struct sdhci_ops arasan_ops = {
|
||||
.platform_execute_tuning = &arasan_sdhci_execute_tuning,
|
||||
.set_delay = &arasan_sdhci_set_tapdelay,
|
||||
@ -236,6 +589,9 @@ static int arasan_sdhci_probe(struct udevice *dev)
|
||||
host->quirks |= SDHCI_QUIRK_BROKEN_HISPD_MODE;
|
||||
#endif
|
||||
|
||||
if (priv->no_1p8)
|
||||
host->quirks |= SDHCI_QUIRK_NO_1_8_V;
|
||||
|
||||
plat->cfg.f_max = CONFIG_ZYNQ_SDHCI_MAX_FREQ;
|
||||
|
||||
ret = mmc_of_parse(dev, &plat->cfg);
|
||||
@ -267,8 +623,9 @@ static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
|
||||
|
||||
priv->host->name = dev->name;
|
||||
|
||||
#if defined(CONFIG_ARCH_ZYNQMP)
|
||||
#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL)
|
||||
priv->host->ops = &arasan_ops;
|
||||
arasan_dt_parse_clk_phases(dev);
|
||||
#endif
|
||||
|
||||
priv->host->ioaddr = (void *)dev_read_addr(dev);
|
||||
@ -277,6 +634,7 @@ static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
|
||||
|
||||
priv->deviceid = dev_read_u32_default(dev, "xlnx,device_id", -1);
|
||||
priv->bank = dev_read_u32_default(dev, "xlnx,mio-bank", 0);
|
||||
priv->no_1p8 = dev_read_bool(dev, "no-1-8-v");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ struct flash_info {
|
||||
#define SPI_NOR_SKIP_SFDP BIT(13) /* Skip parsing of SFDP tables */
|
||||
#define USE_CLSR BIT(14) /* use CLSR command */
|
||||
#define SPI_NOR_HAS_SST26LOCK BIT(15) /* Flash supports lock/unlock via BPR */
|
||||
#define SPI_NOR_OCTAL_READ BIT(16) /* Flash supports Octal Read */
|
||||
#define SPI_NOR_OCTAL_READ BIT(16) /* Flash supports Octal Read */
|
||||
};
|
||||
|
||||
extern const struct flash_info spi_nor_ids[];
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <watchdog.h>
|
||||
#include <asm/io.h>
|
||||
#include <serial.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <dm/platform_data/serial_pl01x.h>
|
||||
#include <linux/compiler.h>
|
||||
#include "serial_pl01x_internal.h"
|
||||
@ -362,8 +363,18 @@ int pl01x_serial_ofdata_to_platdata(struct udevice *dev)
|
||||
plat->clock = dev_read_u32_default(dev, "clock", CONFIG_PL011_CLOCK);
|
||||
ret = clk_get_by_index(dev, 0, &clk);
|
||||
if (!ret) {
|
||||
clk_enable(&clk);
|
||||
ret = clk_enable(&clk);
|
||||
if (ret && ret != -ENOSYS) {
|
||||
dev_err(dev, "failed to enable clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
plat->clock = clk_get_rate(&clk);
|
||||
if (IS_ERR_VALUE(plat->clock)) {
|
||||
dev_err(dev, "failed to get rate\n");
|
||||
return plat->clock;
|
||||
}
|
||||
debug("%s: CLK %d\n", __func__, plat->clock);
|
||||
}
|
||||
plat->type = dev_get_driver_data(dev);
|
||||
plat->skip_init = dev_read_bool(dev, "skip-init");
|
||||
|
@ -214,7 +214,7 @@ static void xilinx_spi_startup_block(struct udevice *dev, unsigned int bytes,
|
||||
struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
|
||||
const unsigned char *txp = dout;
|
||||
unsigned char *rxp = din;
|
||||
u32 reg, count;
|
||||
u32 reg;
|
||||
u32 txbytes = bytes;
|
||||
u32 rxbytes = bytes;
|
||||
|
||||
@ -224,10 +224,10 @@ static void xilinx_spi_startup_block(struct udevice *dev, unsigned int bytes,
|
||||
* it sets txp to the initial value for the normal operation.
|
||||
*/
|
||||
for ( ; priv->startup < 2; priv->startup++) {
|
||||
count = xilinx_spi_fill_txfifo(bus, txp, txbytes);
|
||||
xilinx_spi_fill_txfifo(bus, txp, txbytes);
|
||||
reg = readl(®s->spicr) & ~SPICR_MASTER_INHIBIT;
|
||||
writel(reg, ®s->spicr);
|
||||
count = xilinx_spi_read_rxfifo(bus, rxp, rxbytes);
|
||||
xilinx_spi_read_rxfifo(bus, rxp, rxbytes);
|
||||
txp = din;
|
||||
|
||||
if (priv->startup) {
|
||||
@ -251,7 +251,7 @@ static int xilinx_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||
unsigned char *rxp = din;
|
||||
u32 txbytes = bytes;
|
||||
u32 rxbytes = bytes;
|
||||
u32 reg, count, timeout;
|
||||
u32 reg, count;
|
||||
int ret;
|
||||
|
||||
debug("spi_xfer: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n",
|
||||
|
@ -6,8 +6,10 @@
|
||||
* Xilinx Zynq Quad-SPI(QSPI) controller driver (master mode only)
|
||||
*/
|
||||
|
||||
#include <clk.h>
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <log.h>
|
||||
#include <malloc.h>
|
||||
#include <spi.h>
|
||||
@ -105,17 +107,29 @@ static int zynq_qspi_ofdata_to_platdata(struct udevice *bus)
|
||||
plat->regs = (struct zynq_qspi_regs *)fdtdec_get_addr(blob,
|
||||
node, "reg");
|
||||
|
||||
/* FIXME: Use 166MHz as a suitable default */
|
||||
plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
|
||||
166666666);
|
||||
plat->speed_hz = plat->frequency / 2;
|
||||
|
||||
debug("%s: regs=%p max-frequency=%d\n", __func__,
|
||||
plat->regs, plat->frequency);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* zynq_qspi_init_hw - Initialize the hardware
|
||||
* @priv: Pointer to the zynq_qspi_priv structure
|
||||
*
|
||||
* The default settings of the QSPI controller's configurable parameters on
|
||||
* reset are
|
||||
* - Master mode
|
||||
* - Baud rate divisor is set to 2
|
||||
* - Threshold value for TX FIFO not full interrupt is set to 1
|
||||
* - Flash memory interface mode enabled
|
||||
* - Size of the word to be transferred as 8 bit
|
||||
* This function performs the following actions
|
||||
* - Disable and clear all the interrupts
|
||||
* - Enable manual slave select
|
||||
* - Enable auto start
|
||||
* - Deselect all the chip select lines
|
||||
* - Set the size of the word to be transferred as 32 bit
|
||||
* - Set the little endian mode of TX FIFO and
|
||||
* - Enable the QSPI controller
|
||||
*/
|
||||
static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
|
||||
{
|
||||
struct zynq_qspi_regs *regs = priv->regs;
|
||||
@ -159,19 +173,45 @@ static int zynq_qspi_probe(struct udevice *bus)
|
||||
{
|
||||
struct zynq_qspi_platdata *plat = dev_get_platdata(bus);
|
||||
struct zynq_qspi_priv *priv = dev_get_priv(bus);
|
||||
struct clk clk;
|
||||
unsigned long clock;
|
||||
int ret;
|
||||
|
||||
priv->regs = plat->regs;
|
||||
priv->fifo_depth = ZYNQ_QSPI_FIFO_DEPTH;
|
||||
|
||||
ret = clk_get_by_name(bus, "ref_clk", &clk);
|
||||
if (ret < 0) {
|
||||
dev_err(bus, "failed to get clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
clock = clk_get_rate(&clk);
|
||||
if (IS_ERR_VALUE(clock)) {
|
||||
dev_err(bus, "failed to get rate\n");
|
||||
return clock;
|
||||
}
|
||||
|
||||
ret = clk_enable(&clk);
|
||||
if (ret && ret != -ENOSYS) {
|
||||
dev_err(bus, "failed to enable clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* init the zynq spi hw */
|
||||
zynq_qspi_init_hw(priv);
|
||||
|
||||
plat->frequency = clock;
|
||||
plat->speed_hz = plat->frequency / 2;
|
||||
|
||||
debug("%s: max-frequency=%d\n", __func__, plat->speed_hz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* zynq_qspi_read_data - Copy data to RX buffer
|
||||
* @zqspi: Pointer to the zynq_qspi structure
|
||||
* @priv: Pointer to the zynq_qspi_priv structure
|
||||
* @data: The 32 bit variable where data is stored
|
||||
* @size: Number of bytes to be copied from data to RX buffer
|
||||
*/
|
||||
@ -214,9 +254,9 @@ static void zynq_qspi_read_data(struct zynq_qspi_priv *priv, u32 data, u8 size)
|
||||
priv->bytes_to_receive = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* zynq_qspi_write_data - Copy data from TX buffer
|
||||
* @zqspi: Pointer to the zynq_qspi structure
|
||||
* @priv: Pointer to the zynq_qspi_priv structure
|
||||
* @data: Pointer to the 32 bit variable where data is to be copied
|
||||
* @size: Number of bytes to be copied from TX buffer to data
|
||||
*/
|
||||
@ -263,6 +303,11 @@ static void zynq_qspi_write_data(struct zynq_qspi_priv *priv,
|
||||
priv->bytes_to_transfer = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* zynq_qspi_chipselect - Select or deselect the chip select line
|
||||
* @priv: Pointer to the zynq_qspi_priv structure
|
||||
* @is_on: Select(1) or deselect (0) the chip select line
|
||||
*/
|
||||
static void zynq_qspi_chipselect(struct zynq_qspi_priv *priv, int is_on)
|
||||
{
|
||||
u32 confr;
|
||||
@ -282,9 +327,10 @@ static void zynq_qspi_chipselect(struct zynq_qspi_priv *priv, int is_on)
|
||||
writel(confr, ®s->cr);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* zynq_qspi_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible
|
||||
* @zqspi: Pointer to the zynq_qspi structure
|
||||
* @priv: Pointer to the zynq_qspi_priv structure
|
||||
* @size: Number of bytes to be copied to fifo
|
||||
*/
|
||||
static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv *priv, u32 size)
|
||||
{
|
||||
@ -322,9 +368,9 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv *priv, u32 size)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* zynq_qspi_irq_poll - Interrupt service routine of the QSPI controller
|
||||
* @zqspi: Pointer to the zynq_qspi structure
|
||||
* @priv: Pointer to the zynq_qspi structure
|
||||
*
|
||||
* This function handles TX empty and Mode Fault interrupts only.
|
||||
* On TX empty interrupt this function reads the received data from RX FIFO and
|
||||
@ -410,11 +456,9 @@ static int zynq_qspi_irq_poll(struct zynq_qspi_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* zynq_qspi_start_transfer - Initiates the QSPI transfer
|
||||
* @qspi: Pointer to the spi_device structure
|
||||
* @transfer: Pointer to the spi_transfer structure which provide information
|
||||
* about next transfer parameters
|
||||
* @priv: Pointer to the zynq_qspi_priv structure
|
||||
*
|
||||
* This function fills the TX FIFO, starts the QSPI transfer, and waits for the
|
||||
* transfer to be completed.
|
||||
|
@ -8,10 +8,12 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <log.h>
|
||||
#include <malloc.h>
|
||||
#include <spi.h>
|
||||
#include <time.h>
|
||||
#include <clk.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/delay.h>
|
||||
@ -79,17 +81,10 @@ static int zynq_spi_ofdata_to_platdata(struct udevice *bus)
|
||||
|
||||
plat->regs = dev_read_addr_ptr(bus);
|
||||
|
||||
/* FIXME: Use 250MHz as a suitable default */
|
||||
plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
|
||||
250000000);
|
||||
plat->deactivate_delay_us = fdtdec_get_int(blob, node,
|
||||
"spi-deactivate-delay", 0);
|
||||
plat->activate_delay_us = fdtdec_get_int(blob, node,
|
||||
"spi-activate-delay", 0);
|
||||
plat->speed_hz = plat->frequency / 2;
|
||||
|
||||
debug("%s: regs=%p max-frequency=%d\n", __func__,
|
||||
plat->regs, plat->frequency);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -128,13 +123,39 @@ static int zynq_spi_probe(struct udevice *bus)
|
||||
{
|
||||
struct zynq_spi_platdata *plat = dev_get_platdata(bus);
|
||||
struct zynq_spi_priv *priv = dev_get_priv(bus);
|
||||
struct clk clk;
|
||||
unsigned long clock;
|
||||
int ret;
|
||||
|
||||
priv->regs = plat->regs;
|
||||
priv->fifo_depth = ZYNQ_SPI_FIFO_DEPTH;
|
||||
|
||||
ret = clk_get_by_name(bus, "ref_clk", &clk);
|
||||
if (ret < 0) {
|
||||
dev_err(bus, "failed to get clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
clock = clk_get_rate(&clk);
|
||||
if (IS_ERR_VALUE(clock)) {
|
||||
dev_err(bus, "failed to get rate\n");
|
||||
return clock;
|
||||
}
|
||||
|
||||
ret = clk_enable(&clk);
|
||||
if (ret && ret != -ENOSYS) {
|
||||
dev_err(bus, "failed to enable clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* init the zynq spi hw */
|
||||
zynq_spi_init_hw(priv);
|
||||
|
||||
plat->frequency = clock;
|
||||
plat->speed_hz = plat->frequency / 2;
|
||||
|
||||
debug("%s: max-frequency=%d\n", __func__, plat->speed_hz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -125,21 +125,67 @@
|
||||
#define CONFIG_SYS_LOAD_ADDR 0
|
||||
|
||||
#define CONFIG_HOSTNAME "microblaze-generic"
|
||||
#define CONFIG_BOOTCOMMAND "base 0;tftp 11000000 image.img;bootm"
|
||||
|
||||
/* architecture dependent code */
|
||||
#define CONFIG_SYS_USR_EXCEP /* user exception */
|
||||
|
||||
#if defined(CONFIG_CMD_PXE) && defined(CONFIG_CMD_DHCP)
|
||||
#define BOOT_TARGET_DEVICES_PXE(func) func(PXE, pxe, na)
|
||||
#else
|
||||
#define BOOT_TARGET_DEVICES_PXE(func)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CMD_DHCP)
|
||||
#define BOOT_TARGET_DEVICES_DHCP(func) func(DHCP, dhcp, na)
|
||||
#else
|
||||
#define BOOT_TARGET_DEVICES_DHCP(func)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPI_FLASH)
|
||||
# define BOOT_TARGET_DEVICES_QSPI(func) func(QSPI, qspi, na)
|
||||
#else
|
||||
# define BOOT_TARGET_DEVICES_QSPI(func)
|
||||
#endif
|
||||
|
||||
#define BOOTENV_DEV_QSPI(devtypeu, devtypel, instance) \
|
||||
"bootcmd_qspi=sf probe 0 0 0 && " \
|
||||
"sf read ${scriptaddr} ${script_offset_f} ${script_size_f} && " \
|
||||
"echo QSPI: Trying to boot script at ${scriptaddr} && " \
|
||||
"source ${scriptaddr}; echo QSPI: SCRIPT FAILED: continuing...;\0"
|
||||
|
||||
#define BOOTENV_DEV_NAME_QSPI(devtypeu, devtypel, instance) \
|
||||
"qspi "
|
||||
|
||||
#define BOOT_TARGET_DEVICES_JTAG(func) func(JTAG, jtag, na)
|
||||
|
||||
#define BOOTENV_DEV_JTAG(devtypeu, devtypel, instance) \
|
||||
"bootcmd_jtag=echo JTAG: Trying to boot script at ${scriptaddr} && " \
|
||||
"source ${scriptaddr}; echo JTAG: SCRIPT FAILED: continuing...;\0"
|
||||
|
||||
#define BOOTENV_DEV_NAME_JTAG(devtypeu, devtypel, instance) \
|
||||
"jtag "
|
||||
|
||||
#define BOOT_TARGET_DEVICES(func) \
|
||||
BOOT_TARGET_DEVICES_JTAG(func) \
|
||||
BOOT_TARGET_DEVICES_QSPI(func) \
|
||||
BOOT_TARGET_DEVICES_DHCP(func) \
|
||||
BOOT_TARGET_DEVICES_PXE(func)
|
||||
|
||||
#include <config_distro_bootcmd.h>
|
||||
|
||||
#ifndef CONFIG_EXTRA_ENV_SETTINGS
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS "unlock=yes\0" \
|
||||
"nor0=flash-0\0"\
|
||||
"mtdparts=mtdparts=flash-0:"\
|
||||
"256k(u-boot),256k(env),3m(kernel),"\
|
||||
"1m(romfs),1m(cramfs),-(jffs2)\0"\
|
||||
"nc=setenv stdout nc;"\
|
||||
"setenv stdin nc\0" \
|
||||
"serial=setenv stdout serial;"\
|
||||
"setenv stdin serial\0"
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
"unlock=yes\0"\
|
||||
"nor0=flash-0\0"\
|
||||
"mtdparts=mtdparts=flash-0:"\
|
||||
"256k(u-boot),256k(env),3m(kernel),"\
|
||||
"1m(romfs),1m(cramfs),-(jffs2)\0"\
|
||||
"nc=setenv stdout nc;"\
|
||||
"setenv stdin nc\0" \
|
||||
"serial=setenv stdout serial;"\
|
||||
"setenv stdin serial\0"\
|
||||
"script_size_f=0x40000\0"\
|
||||
BOOTENV
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_XILINX_AXIEMAC)
|
||||
@ -167,8 +213,7 @@
|
||||
#define CONFIG_SYS_INIT_RAM_SIZE 0x100000
|
||||
|
||||
# define CONFIG_SPL_STACK_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \
|
||||
CONFIG_SYS_INIT_RAM_SIZE - \
|
||||
CONFIG_SYS_MALLOC_F_LEN)
|
||||
CONFIG_SYS_INIT_RAM_SIZE)
|
||||
|
||||
/* Just for sure that there is a space for stack */
|
||||
#define CONFIG_SPL_STACK_SIZE 0x100
|
||||
|
@ -18,7 +18,6 @@
|
||||
#define GICD_BASE 0xF9000000
|
||||
#define GICR_BASE 0xF9080000
|
||||
|
||||
|
||||
#define CONFIG_SYS_INIT_SP_ADDR CONFIG_SYS_TEXT_BASE
|
||||
|
||||
/* Generic Timer Definitions - setup in EL3. Setup by ATF for other cases */
|
||||
|
@ -10,7 +10,6 @@
|
||||
#ifndef __CONFIG_VERSAL_MINI_H
|
||||
#define __CONFIG_VERSAL_MINI_H
|
||||
|
||||
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS
|
||||
|
||||
#include <configs/xilinx_versal.h>
|
||||
|
@ -10,7 +10,6 @@
|
||||
#ifndef __CONFIG_ZYNQMP_MINI_H
|
||||
#define __CONFIG_ZYNQMP_MINI_H
|
||||
|
||||
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS
|
||||
|
||||
#include <configs/xilinx_zynqmp.h>
|
||||
|
@ -605,6 +605,28 @@ const char *ofnode_read_chosen_string(const char *propname);
|
||||
*/
|
||||
ofnode ofnode_get_chosen_node(const char *propname);
|
||||
|
||||
/**
|
||||
* ofnode_read_aliases_prop() - get the value of a aliases property
|
||||
*
|
||||
* This looks for a property within the /aliases node and returns its value
|
||||
*
|
||||
* @propname: Property name to look for
|
||||
* @sizep: Returns size of property, or FDT_ERR_... error code if function
|
||||
* returns NULL
|
||||
* @return property value if found, else NULL
|
||||
*/
|
||||
const void *ofnode_read_aliases_prop(const char *propname, int *sizep);
|
||||
|
||||
/**
|
||||
* ofnode_get_aliases_node() - get a referenced node from the aliases node
|
||||
*
|
||||
* This looks up a named property in the aliases node and uses that as a path to
|
||||
* look up a code.
|
||||
*
|
||||
* @return the referenced node if present, else ofnode_null()
|
||||
*/
|
||||
ofnode ofnode_get_aliases_node(const char *propname);
|
||||
|
||||
struct display_timing;
|
||||
/**
|
||||
* ofnode_decode_display_timing() - decode display timings
|
||||
|
123
include/dt-bindings/clock/xlnx-versal-clk.h
Normal file
123
include/dt-bindings/clock/xlnx-versal-clk.h
Normal file
@ -0,0 +1,123 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2019 Xilinx Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_VERSAL_H
|
||||
#define _DT_BINDINGS_CLK_VERSAL_H
|
||||
|
||||
#define PMC_PLL 1
|
||||
#define APU_PLL 2
|
||||
#define RPU_PLL 3
|
||||
#define CPM_PLL 4
|
||||
#define NOC_PLL 5
|
||||
#define PLL_MAX 6
|
||||
#define PMC_PRESRC 7
|
||||
#define PMC_POSTCLK 8
|
||||
#define PMC_PLL_OUT 9
|
||||
#define PPLL 10
|
||||
#define NOC_PRESRC 11
|
||||
#define NOC_POSTCLK 12
|
||||
#define NOC_PLL_OUT 13
|
||||
#define NPLL 14
|
||||
#define APU_PRESRC 15
|
||||
#define APU_POSTCLK 16
|
||||
#define APU_PLL_OUT 17
|
||||
#define APLL 18
|
||||
#define RPU_PRESRC 19
|
||||
#define RPU_POSTCLK 20
|
||||
#define RPU_PLL_OUT 21
|
||||
#define RPLL 22
|
||||
#define CPM_PRESRC 23
|
||||
#define CPM_POSTCLK 24
|
||||
#define CPM_PLL_OUT 25
|
||||
#define CPLL 26
|
||||
#define PPLL_TO_XPD 27
|
||||
#define NPLL_TO_XPD 28
|
||||
#define APLL_TO_XPD 29
|
||||
#define RPLL_TO_XPD 30
|
||||
#define EFUSE_REF 31
|
||||
#define SYSMON_REF 32
|
||||
#define IRO_SUSPEND_REF 33
|
||||
#define USB_SUSPEND 34
|
||||
#define SWITCH_TIMEOUT 35
|
||||
#define RCLK_PMC 36
|
||||
#define RCLK_LPD 37
|
||||
#define WDT 38
|
||||
#define TTC0 39
|
||||
#define TTC1 40
|
||||
#define TTC2 41
|
||||
#define TTC3 42
|
||||
#define GEM_TSU 43
|
||||
#define GEM_TSU_LB 44
|
||||
#define MUXED_IRO_DIV2 45
|
||||
#define MUXED_IRO_DIV4 46
|
||||
#define PSM_REF 47
|
||||
#define GEM0_RX 48
|
||||
#define GEM0_TX 49
|
||||
#define GEM1_RX 50
|
||||
#define GEM1_TX 51
|
||||
#define CPM_CORE_REF 52
|
||||
#define CPM_LSBUS_REF 53
|
||||
#define CPM_DBG_REF 54
|
||||
#define CPM_AUX0_REF 55
|
||||
#define CPM_AUX1_REF 56
|
||||
#define QSPI_REF 57
|
||||
#define OSPI_REF 58
|
||||
#define SDIO0_REF 59
|
||||
#define SDIO1_REF 60
|
||||
#define PMC_LSBUS_REF 61
|
||||
#define I2C_REF 62
|
||||
#define TEST_PATTERN_REF 63
|
||||
#define DFT_OSC_REF 64
|
||||
#define PMC_PL0_REF 65
|
||||
#define PMC_PL1_REF 66
|
||||
#define PMC_PL2_REF 67
|
||||
#define PMC_PL3_REF 68
|
||||
#define CFU_REF 69
|
||||
#define SPARE_REF 70
|
||||
#define NPI_REF 71
|
||||
#define HSM0_REF 72
|
||||
#define HSM1_REF 73
|
||||
#define SD_DLL_REF 74
|
||||
#define FPD_TOP_SWITCH 75
|
||||
#define FPD_LSBUS 76
|
||||
#define ACPU 77
|
||||
#define DBG_TRACE 78
|
||||
#define DBG_FPD 79
|
||||
#define LPD_TOP_SWITCH 80
|
||||
#define ADMA 81
|
||||
#define LPD_LSBUS 82
|
||||
#define CPU_R5 83
|
||||
#define CPU_R5_CORE 84
|
||||
#define CPU_R5_OCM 85
|
||||
#define CPU_R5_OCM2 86
|
||||
#define IOU_SWITCH 87
|
||||
#define GEM0_REF 88
|
||||
#define GEM1_REF 89
|
||||
#define GEM_TSU_REF 90
|
||||
#define USB0_BUS_REF 91
|
||||
#define UART0_REF 92
|
||||
#define UART1_REF 93
|
||||
#define SPI0_REF 94
|
||||
#define SPI1_REF 95
|
||||
#define CAN0_REF 96
|
||||
#define CAN1_REF 97
|
||||
#define I2C0_REF 98
|
||||
#define I2C1_REF 99
|
||||
#define DBG_LPD 100
|
||||
#define TIMESTAMP_REF 101
|
||||
#define DBG_TSTMP 102
|
||||
#define CPM_TOPSW_REF 103
|
||||
#define USB3_DUAL_REF 104
|
||||
#define OUTCLK_MAX 105
|
||||
#define REF_CLK 106
|
||||
#define PL_ALT_REF_CLK 107
|
||||
#define MUXED_IRO 108
|
||||
#define PL_EXT 109
|
||||
#define PL_LB 110
|
||||
#define MIO_50_OR_51 111
|
||||
#define MIO_24_OR_25 112
|
||||
|
||||
#endif
|
42
include/dt-bindings/power/xlnx-versal-power.h
Normal file
42
include/dt-bindings/power/xlnx-versal-power.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2019 - 2020 Xilinx, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_VERSAL_POWER_H
|
||||
#define _DT_BINDINGS_VERSAL_POWER_H
|
||||
|
||||
#define PM_DEV_USB_0 (0x18224018U)
|
||||
#define PM_DEV_GEM_0 (0x18224019U)
|
||||
#define PM_DEV_GEM_1 (0x1822401aU)
|
||||
#define PM_DEV_SPI_0 (0x1822401bU)
|
||||
#define PM_DEV_SPI_1 (0x1822401cU)
|
||||
#define PM_DEV_I2C_0 (0x1822401dU)
|
||||
#define PM_DEV_I2C_1 (0x1822401eU)
|
||||
#define PM_DEV_CAN_FD_0 (0x1822401fU)
|
||||
#define PM_DEV_CAN_FD_1 (0x18224020U)
|
||||
#define PM_DEV_UART_0 (0x18224021U)
|
||||
#define PM_DEV_UART_1 (0x18224022U)
|
||||
#define PM_DEV_GPIO (0x18224023U)
|
||||
#define PM_DEV_TTC_0 (0x18224024U)
|
||||
#define PM_DEV_TTC_1 (0x18224025U)
|
||||
#define PM_DEV_TTC_2 (0x18224026U)
|
||||
#define PM_DEV_TTC_3 (0x18224027U)
|
||||
#define PM_DEV_SWDT_FPD (0x18224029U)
|
||||
#define PM_DEV_OSPI (0x1822402aU)
|
||||
#define PM_DEV_QSPI (0x1822402bU)
|
||||
#define PM_DEV_GPIO_PMC (0x1822402cU)
|
||||
#define PM_DEV_SDIO_0 (0x1822402eU)
|
||||
#define PM_DEV_SDIO_1 (0x1822402fU)
|
||||
#define PM_DEV_RTC (0x18224034U)
|
||||
#define PM_DEV_ADMA_0 (0x18224035U)
|
||||
#define PM_DEV_ADMA_1 (0x18224036U)
|
||||
#define PM_DEV_ADMA_2 (0x18224037U)
|
||||
#define PM_DEV_ADMA_3 (0x18224038U)
|
||||
#define PM_DEV_ADMA_4 (0x18224039U)
|
||||
#define PM_DEV_ADMA_5 (0x1822403aU)
|
||||
#define PM_DEV_ADMA_6 (0x1822403bU)
|
||||
#define PM_DEV_ADMA_7 (0x1822403cU)
|
||||
#define PM_DEV_AI (0x18224072U)
|
||||
|
||||
#endif
|
@ -360,6 +360,19 @@ enum mmc_voltage {
|
||||
#define MMC_NUM_BOOT_PARTITION 2
|
||||
#define MMC_PART_RPMB 3 /* RPMB partition number */
|
||||
|
||||
/* timing specification used */
|
||||
#define MMC_TIMING_LEGACY 0
|
||||
#define MMC_TIMING_MMC_HS 1
|
||||
#define MMC_TIMING_SD_HS 2
|
||||
#define MMC_TIMING_UHS_SDR12 3
|
||||
#define MMC_TIMING_UHS_SDR25 4
|
||||
#define MMC_TIMING_UHS_SDR50 5
|
||||
#define MMC_TIMING_UHS_SDR104 6
|
||||
#define MMC_TIMING_UHS_DDR50 7
|
||||
#define MMC_TIMING_MMC_DDR52 8
|
||||
#define MMC_TIMING_MMC_HS200 9
|
||||
#define MMC_TIMING_MMC_HS400 10
|
||||
|
||||
/* Driver model support */
|
||||
|
||||
/**
|
||||
|
@ -244,6 +244,7 @@
|
||||
#define SDHCI_QUIRK_BROKEN_HISPD_MODE BIT(5)
|
||||
#define SDHCI_QUIRK_WAIT_SEND_CMD (1 << 6)
|
||||
#define SDHCI_QUIRK_USE_WIDE8 (1 << 8)
|
||||
#define SDHCI_QUIRK_NO_1_8_V (1 << 9)
|
||||
|
||||
/* to make gcc happy */
|
||||
struct sdhci_host;
|
||||
|
@ -66,7 +66,7 @@ int rsa_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
|
||||
struct key_prop *node, uint8_t *out);
|
||||
|
||||
#if defined(CONFIG_CMD_ZYNQ_RSA)
|
||||
int zynq_pow_mod(u32 *keyptr, u32 *inout);
|
||||
int zynq_pow_mod(uint32_t *keyptr, uint32_t *inout);
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -10,10 +10,11 @@
|
||||
|
||||
#ifdef CONFIG_ARCH_ZYNQMP
|
||||
void zynqmp_dll_reset(u8 deviceid);
|
||||
void arasan_zynqmp_set_tapdelay(u8 device_id, u8 uhsmode, u8 bank);
|
||||
void arasan_zynqmp_set_tapdelay(u8 device_id, u32 itap_delay, u32 otap_delay);
|
||||
#else
|
||||
inline void zynqmp_dll_reset(u8 deviceid) {}
|
||||
inline void arasan_zynqmp_set_tapdelay(u8 device_id, u8 uhsmode, u8 bank) {}
|
||||
inline void arasan_zynqmp_set_tapdelay(u8 device_id, u32 itap_delay,
|
||||
u32 otap_delay) {}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -321,7 +321,7 @@ int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len,
|
||||
* pow_mod calculation required for zynq is bit different from
|
||||
* pw_mod above here, hence defined zynq specific routine.
|
||||
*/
|
||||
int zynq_pow_mod(u32 *keyptr, u32 *inout)
|
||||
int zynq_pow_mod(uint32_t *keyptr, uint32_t *inout)
|
||||
{
|
||||
u32 *result, *ptr;
|
||||
uint i;
|
||||
|
@ -207,6 +207,28 @@ static int dm_test_ofnode_read_chosen(struct unit_test_state *uts)
|
||||
}
|
||||
DM_TEST(dm_test_ofnode_read_chosen, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
|
||||
|
||||
static int dm_test_ofnode_read_aliases(struct unit_test_state *uts)
|
||||
{
|
||||
const void *val;
|
||||
ofnode node;
|
||||
int size;
|
||||
|
||||
node = ofnode_get_aliases_node("eth3");
|
||||
ut_assert(ofnode_valid(node));
|
||||
ut_asserteq_str("sbe5", ofnode_get_name(node));
|
||||
|
||||
node = ofnode_get_aliases_node("unknown");
|
||||
ut_assert(!ofnode_valid(node));
|
||||
|
||||
val = ofnode_read_aliases_prop("spi0", &size);
|
||||
ut_assertnonnull(val);
|
||||
ut_asserteq(7, size);
|
||||
ut_asserteq_str("/spi@0", (const char *)val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_ofnode_read_aliases, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
|
||||
|
||||
static int dm_test_ofnode_get_child_count(struct unit_test_state *uts)
|
||||
{
|
||||
ofnode node, child_node;
|
||||
|
Loading…
Reference in New Issue
Block a user