mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-17 10:18:38 +00:00
Xilinx changes for v2023.01-rc1
cmd: - bdinfo - guard LMB code to run only when LMB is enabled timer: - convert arm twd timer to DM power-domain: - Skip loading config object for Versal xilinx: - Fix logic when dfu_alt_info is generated - Define only mmc devnum not partition - Add xlnx prefix to GEM compatible string - Add missing tca6416 to zynqmp SC - vck190 - Add env redund offset - Enable CMD_GREPENV/SETEXPR by default - Move board_get_usable_ram_top() to common location - Add support for SOC detection net/gem: - Check rate before setting it up microblaze: - drop CONFIG_SYS_INIT_RAM_ADDR and CONFIG_SYS_INIT_RAM_SIZE - Show cache size in bdinfo spi: - cadence_qspi: driver updates - zynqmp_gqspi: driver updates - zynqmp_gqspi: Add tap delays for Versal zynq: - Enable mkeficapsule compilation - Use CONFIG_SPL_FS_LOAD_PAYLOAD_NAME for dfu_alt_info - Align bss and end of u-boot image to 64bits - Align qspi node name with Linux kernel - DT: List OCM memory zynqmp: - Fix AES cache handling with a user provided key - SOM: Add mtd partition for secure OS storage area - Add ref_clk property for REFCLKPER calculation - Fix mdio bus description for vck190-sc xilinx-mini: - Remove unneeded configs - Disable LMB versal: - Enable i2c mux pca954x by default - Define CONFIG_CQSPI_REF_CLK - Enable power domain driver - Enable zynqmp_gqspi driver -----BEGIN PGP SIGNATURE----- iF0EABECAB0WIQQbPNTMvXmYlBPRwx7KSWXLKUoMIQUCYyBsQQAKCRDKSWXLKUoM IR2tAJ9GfXT90zd0eU7KeZzhekX9wrAxNACglOVqanFpEr2ITSa3Pv8+FknD4XE= =VuHq -----END PGP SIGNATURE----- Merge tag 'xilinx-for-v2023.01-rc1' of https://source.denx.de/u-boot/custodians/u-boot-microblaze into next Xilinx changes for v2023.01-rc1 cmd: - bdinfo - guard LMB code to run only when LMB is enabled timer: - convert arm twd timer to DM power-domain: - Skip loading config object for Versal xilinx: - Fix logic when dfu_alt_info is generated - Define only mmc devnum not partition - Add xlnx prefix to GEM compatible string - Add missing tca6416 to zynqmp SC - vck190 - Add env redund offset - Enable CMD_GREPENV/SETEXPR by default - Move board_get_usable_ram_top() to common location - Add support for SOC detection net/gem: - Check rate before setting it up microblaze: - drop CONFIG_SYS_INIT_RAM_ADDR and CONFIG_SYS_INIT_RAM_SIZE - Show cache size in bdinfo spi: - cadence_qspi: driver updates - zynqmp_gqspi: driver updates - zynqmp_gqspi: Add tap delays for Versal zynq: - Enable mkeficapsule compilation - Use CONFIG_SPL_FS_LOAD_PAYLOAD_NAME for dfu_alt_info - Align bss and end of u-boot image to 64bits - Align qspi node name with Linux kernel - DT: List OCM memory zynqmp: - Fix AES cache handling with a user provided key - SOM: Add mtd partition for secure OS storage area - Add ref_clk property for REFCLKPER calculation - Fix mdio bus description for vck190-sc xilinx-mini: - Remove unneeded configs - Disable LMB versal: - Enable i2c mux pca954x by default - Define CONFIG_CQSPI_REF_CLK - Enable power domain driver - Enable zynqmp_gqspi driver
This commit is contained in:
commit
b3d9c0b6d5
49 changed files with 757 additions and 520 deletions
|
@ -1259,6 +1259,7 @@ config ARCH_VF610
|
||||||
|
|
||||||
config ARCH_ZYNQ
|
config ARCH_ZYNQ
|
||||||
bool "Xilinx Zynq based platform"
|
bool "Xilinx Zynq based platform"
|
||||||
|
select ARM_TWD_TIMER
|
||||||
select CLK
|
select CLK
|
||||||
select CLK_ZYNQ
|
select CLK_ZYNQ
|
||||||
select CPU_V7A
|
select CPU_V7A
|
||||||
|
@ -1278,7 +1279,9 @@ config ARCH_ZYNQ
|
||||||
select SPL_DM_SPI_FLASH if SPL
|
select SPL_DM_SPI_FLASH if SPL
|
||||||
select SPL_OF_CONTROL if SPL
|
select SPL_OF_CONTROL if SPL
|
||||||
select SPL_SEPARATE_BSS if SPL
|
select SPL_SEPARATE_BSS if SPL
|
||||||
|
select SPL_TIMER if SPL
|
||||||
select SUPPORT_SPL
|
select SUPPORT_SPL
|
||||||
|
select TIMER
|
||||||
imply ARCH_EARLY_INIT_R
|
imply ARCH_EARLY_INIT_R
|
||||||
imply BOARD_LATE_INIT
|
imply BOARD_LATE_INIT
|
||||||
imply CMD_CLK
|
imply CMD_CLK
|
||||||
|
|
|
@ -192,6 +192,17 @@
|
||||||
reg = <0xf8006000 0x1000>;
|
reg = <0xf8006000 0x1000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ocm: sram@fffc0000 {
|
||||||
|
compatible = "mmio-sram";
|
||||||
|
reg = <0xfffc0000 0x10000>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
ranges = <0 0xfffc0000 0x10000>;
|
||||||
|
ocm-sram@0 {
|
||||||
|
reg = <0x0 0x10000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
uart0: serial@e0000000 {
|
uart0: serial@e0000000 {
|
||||||
compatible = "xlnx,xuartps", "cdns,uart-r1p8";
|
compatible = "xlnx,xuartps", "cdns,uart-r1p8";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
@ -235,19 +246,19 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
qspi: spi@e000d000 {
|
qspi: spi@e000d000 {
|
||||||
clock-names = "ref_clk", "pclk";
|
|
||||||
clocks = <&clkc 10>, <&clkc 43>;
|
|
||||||
compatible = "xlnx,zynq-qspi-1.0";
|
compatible = "xlnx,zynq-qspi-1.0";
|
||||||
status = "disabled";
|
reg = <0xe000d000 0x1000>;
|
||||||
interrupt-parent = <&intc>;
|
interrupt-parent = <&intc>;
|
||||||
interrupts = <0 19 4>;
|
interrupts = <0 19 4>;
|
||||||
reg = <0xe000d000 0x1000>;
|
clocks = <&clkc 10>, <&clkc 43>;
|
||||||
|
clock-names = "ref_clk", "pclk";
|
||||||
|
status = "disabled";
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
};
|
};
|
||||||
|
|
||||||
gem0: ethernet@e000b000 {
|
gem0: ethernet@e000b000 {
|
||||||
compatible = "cdns,zynq-gem", "cdns,gem";
|
compatible = "xlnx,zynq-gem", "cdns,zynq-gem", "cdns,gem";
|
||||||
reg = <0xe000b000 0x1000>;
|
reg = <0xe000b000 0x1000>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
interrupts = <0 22 4>;
|
interrupts = <0 22 4>;
|
||||||
|
@ -258,7 +269,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
gem1: ethernet@e000c000 {
|
gem1: ethernet@e000c000 {
|
||||||
compatible = "cdns,zynq-gem", "cdns,gem";
|
compatible = "xlnx,zynq-gem", "cdns,zynq-gem", "cdns,gem";
|
||||||
reg = <0xe000c000 0x1000>;
|
reg = <0xe000c000 0x1000>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
interrupts = <0 45 4>;
|
interrupts = <0 45 4>;
|
||||||
|
@ -378,9 +389,9 @@
|
||||||
|
|
||||||
devcfg: devcfg@f8007000 {
|
devcfg: devcfg@f8007000 {
|
||||||
compatible = "xlnx,zynq-devcfg-1.0";
|
compatible = "xlnx,zynq-devcfg-1.0";
|
||||||
|
reg = <0xf8007000 0x100>;
|
||||||
interrupt-parent = <&intc>;
|
interrupt-parent = <&intc>;
|
||||||
interrupts = <0 8 4>;
|
interrupts = <0 8 4>;
|
||||||
reg = <0xf8007000 0x100>;
|
|
||||||
clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
|
clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>;
|
||||||
clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
|
clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3";
|
||||||
syscon = <&slcr>;
|
syscon = <&slcr>;
|
||||||
|
@ -416,6 +427,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
scutimer: timer@f8f00600 {
|
scutimer: timer@f8f00600 {
|
||||||
|
u-boot,dm-pre-reloc;
|
||||||
interrupt-parent = <&intc>;
|
interrupt-parent = <&intc>;
|
||||||
interrupts = <1 13 0x301>;
|
interrupts = <1 13 0x301>;
|
||||||
compatible = "arm,cortex-a9-twd-timer";
|
compatible = "arm,cortex-a9-twd-timer";
|
||||||
|
|
|
@ -64,19 +64,6 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&amba {
|
|
||||||
ocm: sram@fffc0000 {
|
|
||||||
compatible = "mmio-sram";
|
|
||||||
reg = <0xfffc0000 0x10000>;
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
ranges = <0 0xfffc0000 0x10000>;
|
|
||||||
ocm-sram@0 {
|
|
||||||
reg = <0x0 0x10000>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
&can0 {
|
&can0 {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
|
|
|
@ -260,11 +260,19 @@
|
||||||
assigned-clocks = <&zynqmp_clk USB0_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
|
assigned-clocks = <&zynqmp_clk USB0_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&dwc3_0 {
|
||||||
|
clocks = <&zynqmp_clk USB3_DUAL_REF>;
|
||||||
|
};
|
||||||
|
|
||||||
&usb1 {
|
&usb1 {
|
||||||
clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
|
clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
|
||||||
assigned-clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
|
assigned-clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&dwc3_1 {
|
||||||
|
clocks = <&zynqmp_clk USB3_DUAL_REF>;
|
||||||
|
};
|
||||||
|
|
||||||
&watchdog0 {
|
&watchdog0 {
|
||||||
clocks = <&zynqmp_clk WDT>;
|
clocks = <&zynqmp_clk WDT>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -155,8 +155,12 @@
|
||||||
phy-handle = <&phy0>;
|
phy-handle = <&phy0>;
|
||||||
phy-mode = "sgmii";
|
phy-mode = "sgmii";
|
||||||
is-internal-pcspma;
|
is-internal-pcspma;
|
||||||
phy0: ethernet-phy@0 { /* u131 M88E1512 */
|
mdio: mdio {
|
||||||
reg = <0>;
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
phy0: ethernet-phy@0 { /* u131 M88E1512 */
|
||||||
|
reg = <0>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -203,6 +207,18 @@
|
||||||
&i2c0 { /* MIO 34-35 - can't stay here */
|
&i2c0 { /* MIO 34-35 - can't stay here */
|
||||||
status = "okay";
|
status = "okay";
|
||||||
clock-frequency = <400000>;
|
clock-frequency = <400000>;
|
||||||
|
|
||||||
|
tca6416_u233: gpio@20 { /* u233 */
|
||||||
|
compatible = "ti,tca6416";
|
||||||
|
reg = <0x20>;
|
||||||
|
gpio-controller; /* interrupt not connected */
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
gpio-line-names = "MAX6643_OT_B", "MAX6643_FANFAIL_B", "", "", /* 0 - 3 */
|
||||||
|
"PMBUS2_INA226_ALERT", "", "", "MAX6643_FULLSPD", /* 4 - 7 */
|
||||||
|
"FMCP1_FMC_PRSNT_M2C_B", "FMCP2_FMC_PRSNT_M2C_B", "FMCP1_FMCP_PRSNT_M2C_B", "FMCP2_FMCP_PRSNT_M2C_B", /* 10 - 13 */
|
||||||
|
"VCCINT_VRHOT_B", "8A34001_EXP_RST_B", "PMBUS_ALERT", "PMBUS1_INA226_ALERT"; /* 14 - 17 */
|
||||||
|
};
|
||||||
|
|
||||||
i2c-mux@74 { /* u33 */
|
i2c-mux@74 { /* u33 */
|
||||||
compatible = "nxp,pca9548";
|
compatible = "nxp,pca9548";
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
|
|
|
@ -214,13 +214,17 @@
|
||||||
};
|
};
|
||||||
partition@2240000 {
|
partition@2240000 {
|
||||||
label = "SHA256";
|
label = "SHA256";
|
||||||
reg = <0x2240000 0x10000>; /* 256B but 64KB sector */
|
reg = <0x2240000 0x40000>; /* 256B but 256KB sector */
|
||||||
read-only;
|
read-only;
|
||||||
lock;
|
lock;
|
||||||
};
|
};
|
||||||
partition@2250000 {
|
partition@2280000 {
|
||||||
|
label = "Secure OS Storage";
|
||||||
|
reg = <0x2280000 0x20000>; /* 128KB */
|
||||||
|
};
|
||||||
|
partition@22A0000 {
|
||||||
label = "User";
|
label = "User";
|
||||||
reg = <0x2250000 0x1db0000>; /* 29.5 MB */
|
reg = <0x22A0000 0x1db0000>; /* 29.5 MB */
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -529,7 +529,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
gem0: ethernet@ff0b0000 {
|
gem0: ethernet@ff0b0000 {
|
||||||
compatible = "cdns,zynqmp-gem", "cdns,gem";
|
compatible = "xlnx,zynqmp-gem", "cdns,zynqmp-gem", "cdns,gem";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
interrupt-parent = <&gic>;
|
interrupt-parent = <&gic>;
|
||||||
interrupts = <0 57 4>, <0 57 4>;
|
interrupts = <0 57 4>, <0 57 4>;
|
||||||
|
@ -543,7 +543,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
gem1: ethernet@ff0c0000 {
|
gem1: ethernet@ff0c0000 {
|
||||||
compatible = "cdns,zynqmp-gem", "cdns,gem";
|
compatible = "xlnx,zynqmp-gem", "cdns,zynqmp-gem", "cdns,gem";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
interrupt-parent = <&gic>;
|
interrupt-parent = <&gic>;
|
||||||
interrupts = <0 59 4>, <0 59 4>;
|
interrupts = <0 59 4>, <0 59 4>;
|
||||||
|
@ -557,7 +557,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
gem2: ethernet@ff0d0000 {
|
gem2: ethernet@ff0d0000 {
|
||||||
compatible = "cdns,zynqmp-gem", "cdns,gem";
|
compatible = "xlnx,zynqmp-gem", "cdns,zynqmp-gem", "cdns,gem";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
interrupt-parent = <&gic>;
|
interrupt-parent = <&gic>;
|
||||||
interrupts = <0 61 4>, <0 61 4>;
|
interrupts = <0 61 4>, <0 61 4>;
|
||||||
|
@ -571,7 +571,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
gem3: ethernet@ff0e0000 {
|
gem3: ethernet@ff0e0000 {
|
||||||
compatible = "cdns,zynqmp-gem", "cdns,gem";
|
compatible = "xlnx,zynqmp-gem", "cdns,zynqmp-gem", "cdns,gem";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
interrupt-parent = <&gic>;
|
interrupt-parent = <&gic>;
|
||||||
interrupts = <0 63 4>, <0 63 4>;
|
interrupts = <0 63 4>, <0 63 4>;
|
||||||
|
@ -869,6 +869,7 @@
|
||||||
iommus = <&smmu 0x860>;
|
iommus = <&smmu 0x860>;
|
||||||
snps,quirk-frame-length-adjustment = <0x20>;
|
snps,quirk-frame-length-adjustment = <0x20>;
|
||||||
snps,refclk_fladj;
|
snps,refclk_fladj;
|
||||||
|
clock-names = "ref";
|
||||||
snps,enable_guctl1_resume_quirk;
|
snps,enable_guctl1_resume_quirk;
|
||||||
snps,enable_guctl1_ipd_quirk;
|
snps,enable_guctl1_ipd_quirk;
|
||||||
snps,xhci-stream-quirk;
|
snps,xhci-stream-quirk;
|
||||||
|
@ -900,6 +901,7 @@
|
||||||
iommus = <&smmu 0x861>;
|
iommus = <&smmu 0x861>;
|
||||||
snps,quirk-frame-length-adjustment = <0x20>;
|
snps,quirk-frame-length-adjustment = <0x20>;
|
||||||
snps,refclk_fladj;
|
snps,refclk_fladj;
|
||||||
|
clock-names = "ref";
|
||||||
snps,enable_guctl1_resume_quirk;
|
snps,enable_guctl1_resume_quirk;
|
||||||
snps,enable_guctl1_ipd_quirk;
|
snps,enable_guctl1_ipd_quirk;
|
||||||
snps,xhci-stream-quirk;
|
snps,xhci-stream-quirk;
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
* Copyright 2016 - 2018 Xilinx, Inc.
|
* Copyright 2016 - 2018 Xilinx, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/build_bug.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TCM_LOCK,
|
TCM_LOCK,
|
||||||
TCM_SPLIT,
|
TCM_SPLIT,
|
||||||
|
@ -10,3 +12,9 @@ enum {
|
||||||
|
|
||||||
void tcm_init(u8 mode);
|
void tcm_init(u8 mode);
|
||||||
void mem_map_fill(void);
|
void mem_map_fill(void);
|
||||||
|
|
||||||
|
static inline int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value)
|
||||||
|
{
|
||||||
|
BUILD_BUG();
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
# (C) Copyright 2008
|
# (C) Copyright 2008
|
||||||
# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
|
# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
|
||||||
|
|
||||||
obj-y := timer.o
|
|
||||||
obj-y += cpu.o
|
obj-y += cpu.o
|
||||||
obj-y += ddrc.o
|
obj-y += ddrc.o
|
||||||
obj-y += slcr.o
|
obj-y += slcr.o
|
||||||
|
|
|
@ -52,10 +52,12 @@ int set_cpu_clk_info(void)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
rate = clk_get_rate(&clk) / 1000000;
|
rate = clk_get_rate(&clk) / 1000000;
|
||||||
if (i)
|
if (i) {
|
||||||
gd->bd->bi_ddr_freq = rate;
|
gd->bd->bi_ddr_freq = rate;
|
||||||
else
|
} else {
|
||||||
gd->bd->bi_arm_freq = rate;
|
gd->bd->bi_arm_freq = rate;
|
||||||
|
gd->cpu_clk = clk_get_rate(&clk);
|
||||||
|
}
|
||||||
|
|
||||||
clk_free(&clk);
|
clk_free(&clk);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,113 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0+
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2017 Weidmüller Interface GmbH & Co. KG
|
|
||||||
* Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
|
|
||||||
*
|
|
||||||
* Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
|
|
||||||
* Copyright (C) 2011-2017 Xilinx, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* (C) Copyright 2008
|
|
||||||
* Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
|
|
||||||
*
|
|
||||||
* (C) Copyright 2004
|
|
||||||
* Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
|
|
||||||
*
|
|
||||||
* (C) Copyright 2002-2004
|
|
||||||
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
|
|
||||||
*
|
|
||||||
* (C) Copyright 2003
|
|
||||||
* Texas Instruments <www.ti.com>
|
|
||||||
*
|
|
||||||
* (C) Copyright 2002
|
|
||||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
|
||||||
* Marius Groeger <mgroeger@sysgo.de>
|
|
||||||
*
|
|
||||||
* (C) Copyright 2002
|
|
||||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
|
||||||
* Alex Zuepke <azu@sysgo.de>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <clk.h>
|
|
||||||
#include <common.h>
|
|
||||||
#include <div64.h>
|
|
||||||
#include <dm.h>
|
|
||||||
#include <init.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <asm/global_data.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
#include <asm/arch/hardware.h>
|
|
||||||
#include <asm/arch/clk.h>
|
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
|
||||||
|
|
||||||
struct scu_timer {
|
|
||||||
u32 load; /* Timer Load Register */
|
|
||||||
u32 counter; /* Timer Counter Register */
|
|
||||||
u32 control; /* Timer Control Register */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct scu_timer *timer_base =
|
|
||||||
(struct scu_timer *)ZYNQ_SCUTIMER_BASEADDR;
|
|
||||||
|
|
||||||
#define SCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00 /* Prescaler */
|
|
||||||
#define SCUTIMER_CONTROL_PRESCALER_SHIFT 8
|
|
||||||
#define SCUTIMER_CONTROL_AUTO_RELOAD_MASK 0x00000002 /* Auto-reload */
|
|
||||||
#define SCUTIMER_CONTROL_ENABLE_MASK 0x00000001 /* Timer enable */
|
|
||||||
|
|
||||||
#define TIMER_LOAD_VAL 0xFFFFFFFF
|
|
||||||
#define TIMER_PRESCALE 255
|
|
||||||
|
|
||||||
int timer_init(void)
|
|
||||||
{
|
|
||||||
const u32 emask = SCUTIMER_CONTROL_AUTO_RELOAD_MASK |
|
|
||||||
(TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT) |
|
|
||||||
SCUTIMER_CONTROL_ENABLE_MASK;
|
|
||||||
|
|
||||||
struct udevice *dev;
|
|
||||||
struct clk clk;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = uclass_get_device_by_driver(UCLASS_CLK,
|
|
||||||
DM_DRIVER_GET(zynq_clk), &dev);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
clk.id = cpu_6or4x_clk;
|
|
||||||
ret = clk_request(dev, &clk);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
gd->cpu_clk = clk_get_rate(&clk);
|
|
||||||
|
|
||||||
clk_free(&clk);
|
|
||||||
|
|
||||||
gd->arch.timer_rate_hz = (gd->cpu_clk / 2) / (TIMER_PRESCALE + 1);
|
|
||||||
|
|
||||||
/* Load the timer counter register */
|
|
||||||
writel(0xFFFFFFFF, &timer_base->load);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start the A9Timer device
|
|
||||||
* Enable Auto reload mode, Clear prescaler control bits
|
|
||||||
* Set prescaler value, Enable the decrementer
|
|
||||||
*/
|
|
||||||
clrsetbits_le32(&timer_base->control, SCUTIMER_CONTROL_PRESCALER_MASK,
|
|
||||||
emask);
|
|
||||||
|
|
||||||
/* Reset time */
|
|
||||||
gd->arch.lastinc = readl(&timer_base->counter) /
|
|
||||||
(gd->arch.timer_rate_hz / CONFIG_SYS_HZ);
|
|
||||||
gd->arch.tbl = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function is derived from PowerPC code (timebase clock frequency).
|
|
||||||
* On ARM it returns the number of timer ticks per second.
|
|
||||||
*/
|
|
||||||
ulong get_tbclk(void)
|
|
||||||
{
|
|
||||||
return gd->arch.timer_rate_hz;
|
|
||||||
}
|
|
|
@ -75,7 +75,7 @@ SECTIONS
|
||||||
*(.__efi_runtime_rel_stop)
|
*(.__efi_runtime_rel_stop)
|
||||||
}
|
}
|
||||||
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(8);
|
||||||
.image_copy_end :
|
.image_copy_end :
|
||||||
{
|
{
|
||||||
*(.__image_copy_end)
|
*(.__image_copy_end)
|
||||||
|
@ -114,7 +114,7 @@ SECTIONS
|
||||||
|
|
||||||
.bss __bss_base (OVERLAY) : {
|
.bss __bss_base (OVERLAY) : {
|
||||||
*(.bss*)
|
*(.bss*)
|
||||||
. = ALIGN(4);
|
. = ALIGN(8);
|
||||||
__bss_limit = .;
|
__bss_limit = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,4 +4,5 @@
|
||||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||||
|
|
||||||
obj-$(CONFIG_CMD_BOOTM) += bootm.o
|
obj-$(CONFIG_CMD_BOOTM) += bootm.o
|
||||||
|
obj-$(CONFIG_CMD_BDI) += bdinfo.o
|
||||||
obj-y += muldi3.o
|
obj-y += muldi3.o
|
||||||
|
|
24
arch/microblaze/lib/bdinfo.c
Normal file
24
arch/microblaze/lib/bdinfo.c
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022, Ovidiu Panait <ovpanait@gmail.com>
|
||||||
|
*/
|
||||||
|
#include <init.h>
|
||||||
|
#include <asm/cpuinfo.h>
|
||||||
|
#include <asm/global_data.h>
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
void arch_print_bdinfo(void)
|
||||||
|
{
|
||||||
|
struct microblaze_cpuinfo *ci = gd_cpuinfo();
|
||||||
|
|
||||||
|
if (ci->icache_size) {
|
||||||
|
bdinfo_print_size("icache", ci->icache_size);
|
||||||
|
bdinfo_print_size("icache line", ci->icache_line_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ci->dcache_size) {
|
||||||
|
bdinfo_print_size("dcache", ci->dcache_size);
|
||||||
|
bdinfo_print_size("dcache line", ci->dcache_line_length);
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,8 @@
|
||||||
#include <efi.h>
|
#include <efi.h>
|
||||||
#include <efi_loader.h>
|
#include <efi_loader.h>
|
||||||
#include <env.h>
|
#include <env.h>
|
||||||
|
#include <image.h>
|
||||||
|
#include <lmb.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
#include <asm/global_data.h>
|
#include <asm/global_data.h>
|
||||||
#include <asm/sections.h>
|
#include <asm/sections.h>
|
||||||
|
@ -583,8 +585,33 @@ bool __maybe_unused __weak board_detection(void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool __maybe_unused __weak soc_detection(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * __maybe_unused __weak soc_name_decode(void)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int embedded_dtb_select(void)
|
int embedded_dtb_select(void)
|
||||||
{
|
{
|
||||||
|
if (soc_detection()) {
|
||||||
|
char *soc_local_name;
|
||||||
|
|
||||||
|
soc_local_name = soc_name_decode();
|
||||||
|
if (soc_local_name) {
|
||||||
|
board_name = soc_local_name;
|
||||||
|
printf("Detected SOC name: %s\n", board_name);
|
||||||
|
|
||||||
|
/* Time to change DTB on fly */
|
||||||
|
/* Both ways should work here */
|
||||||
|
/* fdtdec_resetup(&rescan); */
|
||||||
|
return fdtdec_setup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (board_detection()) {
|
if (board_detection()) {
|
||||||
char *board_local_name;
|
char *board_local_name;
|
||||||
|
|
||||||
|
@ -602,3 +629,30 @@ int embedded_dtb_select(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_LMB)
|
||||||
|
ulong board_get_usable_ram_top(ulong total_size)
|
||||||
|
{
|
||||||
|
phys_size_t size;
|
||||||
|
phys_addr_t reg;
|
||||||
|
struct lmb lmb;
|
||||||
|
|
||||||
|
if (!total_size)
|
||||||
|
return gd->ram_top;
|
||||||
|
|
||||||
|
if (!IS_ALIGNED((ulong)gd->fdt_blob, 0x8))
|
||||||
|
panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob);
|
||||||
|
|
||||||
|
/* found enough not-reserved memory to relocated U-Boot */
|
||||||
|
lmb_init(&lmb);
|
||||||
|
lmb_add(&lmb, gd->ram_base, gd->ram_size);
|
||||||
|
boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob);
|
||||||
|
size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE);
|
||||||
|
reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE);
|
||||||
|
|
||||||
|
if (!reg)
|
||||||
|
reg = gd->ram_top - size;
|
||||||
|
|
||||||
|
return reg + size;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <env.h>
|
#include <env.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <image.h>
|
|
||||||
#include <lmb.h>
|
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
#include <asm/global_data.h>
|
#include <asm/global_data.h>
|
||||||
#include <dm/lists.h>
|
#include <dm/lists.h>
|
||||||
|
@ -38,25 +36,6 @@ int dram_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
ulong board_get_usable_ram_top(ulong total_size)
|
|
||||||
{
|
|
||||||
phys_size_t size;
|
|
||||||
phys_addr_t reg;
|
|
||||||
struct lmb lmb;
|
|
||||||
|
|
||||||
/* found enough not-reserved memory to relocated U-Boot */
|
|
||||||
lmb_init(&lmb);
|
|
||||||
lmb_add(&lmb, gd->ram_base, gd->ram_size);
|
|
||||||
boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob);
|
|
||||||
size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE);
|
|
||||||
reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE);
|
|
||||||
|
|
||||||
if (!reg)
|
|
||||||
reg = gd->ram_top - size;
|
|
||||||
|
|
||||||
return reg + size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int board_late_init(void)
|
int board_late_init(void)
|
||||||
{
|
{
|
||||||
ulong max_size;
|
ulong max_size;
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include <env.h>
|
#include <env.h>
|
||||||
#include <fdtdec.h>
|
#include <fdtdec.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <image.h>
|
|
||||||
#include <env_internal.h>
|
#include <env_internal.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
@ -270,28 +269,6 @@ int dram_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong board_get_usable_ram_top(ulong total_size)
|
|
||||||
{
|
|
||||||
phys_size_t size;
|
|
||||||
phys_addr_t reg;
|
|
||||||
struct lmb lmb;
|
|
||||||
|
|
||||||
if (!total_size)
|
|
||||||
return gd->ram_top;
|
|
||||||
|
|
||||||
/* found enough not-reserved memory to relocated U-Boot */
|
|
||||||
lmb_init(&lmb);
|
|
||||||
lmb_add(&lmb, gd->ram_base, gd->ram_size);
|
|
||||||
boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob);
|
|
||||||
size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE);
|
|
||||||
reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE);
|
|
||||||
|
|
||||||
if (!reg)
|
|
||||||
reg = gd->ram_top - size;
|
|
||||||
|
|
||||||
return reg + size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset_cpu(void)
|
void reset_cpu(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,8 +168,7 @@ void set_dfu_alt_info(char *interface, char *devstr)
|
||||||
{
|
{
|
||||||
ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
|
ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
|
||||||
|
|
||||||
if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) &&
|
if (env_get("dfu_alt_info"))
|
||||||
env_get("dfu_alt_info"))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
|
@ -177,13 +176,14 @@ void set_dfu_alt_info(char *interface, char *devstr)
|
||||||
switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
|
switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
|
||||||
case ZYNQ_BM_SD:
|
case ZYNQ_BM_SD:
|
||||||
snprintf(buf, DFU_ALT_BUF_LEN,
|
snprintf(buf, DFU_ALT_BUF_LEN,
|
||||||
"mmc 0:1=boot.bin fat 0 1;"
|
"mmc 0=boot.bin fat 0 1;"
|
||||||
"u-boot.img fat 0 1");
|
"%s fat 0 1", CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
|
||||||
break;
|
break;
|
||||||
case ZYNQ_BM_QSPI:
|
case ZYNQ_BM_QSPI:
|
||||||
snprintf(buf, DFU_ALT_BUF_LEN,
|
snprintf(buf, DFU_ALT_BUF_LEN,
|
||||||
"sf 0:0=boot.bin raw 0 0x1500000;"
|
"sf 0:0=boot.bin raw 0 0x1500000;"
|
||||||
"u-boot.img raw 0x%x 0x500000",
|
"%s raw 0x%x 0x500000",
|
||||||
|
CONFIG_SPL_FS_LOAD_PAYLOAD_NAME,
|
||||||
CONFIG_SYS_SPI_U_BOOT_OFFS);
|
CONFIG_SYS_SPI_U_BOOT_OFFS);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -142,9 +142,6 @@ static int do_zynqmp_aes(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
aes->keysrc = hextoul(argv[6], NULL);
|
aes->keysrc = hextoul(argv[6], NULL);
|
||||||
aes->dstaddr = hextoul(argv[7], NULL);
|
aes->dstaddr = hextoul(argv[7], NULL);
|
||||||
|
|
||||||
flush_dcache_range((ulong)aes, (ulong)(aes) +
|
|
||||||
roundup(sizeof(struct aes), ARCH_DMA_MINALIGN));
|
|
||||||
|
|
||||||
if (aes->srcaddr && aes->ivaddr && aes->dstaddr) {
|
if (aes->srcaddr && aes->ivaddr && aes->dstaddr) {
|
||||||
flush_dcache_range(aes->srcaddr,
|
flush_dcache_range(aes->srcaddr,
|
||||||
(aes->srcaddr +
|
(aes->srcaddr +
|
||||||
|
@ -169,6 +166,9 @@ static int do_zynqmp_aes(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
ARCH_DMA_MINALIGN)));
|
ARCH_DMA_MINALIGN)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flush_dcache_range((ulong)aes, (ulong)(aes) +
|
||||||
|
roundup(sizeof(struct aes), ARCH_DMA_MINALIGN));
|
||||||
|
|
||||||
ret = xilinx_pm_request(PM_SECURE_AES, upper_32_bits((ulong)aes),
|
ret = xilinx_pm_request(PM_SECURE_AES, upper_32_bits((ulong)aes),
|
||||||
lower_32_bits((ulong)aes), 0, 0, ret_payload);
|
lower_32_bits((ulong)aes), 0, 0, ret_payload);
|
||||||
if (ret || ret_payload[1])
|
if (ret || ret_payload[1])
|
||||||
|
|
|
@ -12,8 +12,6 @@
|
||||||
#include <env.h>
|
#include <env.h>
|
||||||
#include <env_internal.h>
|
#include <env_internal.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <image.h>
|
|
||||||
#include <lmb.h>
|
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <sata.h>
|
#include <sata.h>
|
||||||
|
@ -256,33 +254,6 @@ int dram_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_LMB)
|
|
||||||
ulong board_get_usable_ram_top(ulong total_size)
|
|
||||||
{
|
|
||||||
phys_size_t size;
|
|
||||||
phys_addr_t reg;
|
|
||||||
struct lmb lmb;
|
|
||||||
|
|
||||||
if (!total_size)
|
|
||||||
return gd->ram_top;
|
|
||||||
|
|
||||||
if (!IS_ALIGNED((ulong)gd->fdt_blob, 0x8))
|
|
||||||
panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob);
|
|
||||||
|
|
||||||
/* found enough not-reserved memory to relocated U-Boot */
|
|
||||||
lmb_init(&lmb);
|
|
||||||
lmb_add(&lmb, gd->ram_base, gd->ram_size);
|
|
||||||
boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob);
|
|
||||||
size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE);
|
|
||||||
reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE);
|
|
||||||
|
|
||||||
if (!reg)
|
|
||||||
reg = gd->ram_top - size;
|
|
||||||
|
|
||||||
return reg + size;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
int dram_init_banksize(void)
|
int dram_init_banksize(void)
|
||||||
{
|
{
|
||||||
|
@ -641,8 +612,7 @@ void set_dfu_alt_info(char *interface, char *devstr)
|
||||||
|
|
||||||
ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
|
ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
|
||||||
|
|
||||||
if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) &&
|
if (env_get("dfu_alt_info"))
|
||||||
env_get("dfu_alt_info"))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
|
@ -662,13 +632,13 @@ void set_dfu_alt_info(char *interface, char *devstr)
|
||||||
bootseq = mmc_get_env_dev();
|
bootseq = mmc_get_env_dev();
|
||||||
if (!multiboot)
|
if (!multiboot)
|
||||||
snprintf(buf, DFU_ALT_BUF_LEN,
|
snprintf(buf, DFU_ALT_BUF_LEN,
|
||||||
"mmc %d:1=boot.bin fat %d 1;"
|
"mmc %d=boot.bin fat %d 1;"
|
||||||
"%s fat %d 1",
|
"%s fat %d 1",
|
||||||
bootseq, bootseq,
|
bootseq, bootseq,
|
||||||
CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, bootseq);
|
CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, bootseq);
|
||||||
else
|
else
|
||||||
snprintf(buf, DFU_ALT_BUF_LEN,
|
snprintf(buf, DFU_ALT_BUF_LEN,
|
||||||
"mmc %d:1=boot%04d.bin fat %d 1;"
|
"mmc %d=boot%04d.bin fat %d 1;"
|
||||||
"%s fat %d 1",
|
"%s fat %d 1",
|
||||||
bootseq, multiboot, bootseq,
|
bootseq, multiboot, bootseq,
|
||||||
CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, bootseq);
|
CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, bootseq);
|
||||||
|
|
|
@ -16,9 +16,16 @@
|
||||||
#include <vsprintf.h>
|
#include <vsprintf.h>
|
||||||
#include <asm/cache.h>
|
#include <asm/cache.h>
|
||||||
#include <asm/global_data.h>
|
#include <asm/global_data.h>
|
||||||
|
#include <display_options.h>
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
void bdinfo_print_size(const char *name, uint64_t size)
|
||||||
|
{
|
||||||
|
printf("%-12s= ", name);
|
||||||
|
print_size(size, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
void bdinfo_print_num_l(const char *name, ulong value)
|
void bdinfo_print_num_l(const char *name, ulong value)
|
||||||
{
|
{
|
||||||
printf("%-12s= 0x%0*lx\n", name, 2 * (int)sizeof(value), value);
|
printf("%-12s= 0x%0*lx\n", name, 2 * (int)sizeof(value), value);
|
||||||
|
@ -123,7 +130,7 @@ int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||||
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
|
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
|
||||||
bdinfo_print_num_l("multi_dtb_fit", (ulong)gd->multi_dtb_fit);
|
bdinfo_print_num_l("multi_dtb_fit", (ulong)gd->multi_dtb_fit);
|
||||||
#endif
|
#endif
|
||||||
if (gd->fdt_blob) {
|
if (IS_ENABLED(CONFIG_LMB) && gd->fdt_blob) {
|
||||||
struct lmb lmb;
|
struct lmb lmb;
|
||||||
|
|
||||||
lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
|
lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
|
||||||
|
|
|
@ -43,9 +43,9 @@ CONFIG_SYS_BOOTM_LEN=0x4000000
|
||||||
CONFIG_CMD_IMLS=y
|
CONFIG_CMD_IMLS=y
|
||||||
CONFIG_CMD_SPL=y
|
CONFIG_CMD_SPL=y
|
||||||
CONFIG_CMD_ASKENV=y
|
CONFIG_CMD_ASKENV=y
|
||||||
|
CONFIG_CMD_GREPENV=y
|
||||||
CONFIG_CMD_GPIO=y
|
CONFIG_CMD_GPIO=y
|
||||||
CONFIG_CMD_SAVES=y
|
CONFIG_CMD_SAVES=y
|
||||||
# CONFIG_CMD_SETEXPR is not set
|
|
||||||
CONFIG_BOOTP_BOOTFILESIZE=y
|
CONFIG_BOOTP_BOOTFILESIZE=y
|
||||||
CONFIG_CMD_TFTPPUT=y
|
CONFIG_CMD_TFTPPUT=y
|
||||||
CONFIG_CMD_CACHE=y
|
CONFIG_CMD_CACHE=y
|
||||||
|
|
|
@ -66,3 +66,4 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||||
# CONFIG_MMC is not set
|
# CONFIG_MMC is not set
|
||||||
CONFIG_ARM_DCC=y
|
CONFIG_ARM_DCC=y
|
||||||
# CONFIG_GZIP is not set
|
# CONFIG_GZIP is not set
|
||||||
|
# CONFIG_LMB is not set
|
||||||
|
|
|
@ -67,3 +67,4 @@ CONFIG_ARM_DCC=y
|
||||||
CONFIG_FAT_WRITE=y
|
CONFIG_FAT_WRITE=y
|
||||||
# CONFIG_GZIP is not set
|
# CONFIG_GZIP is not set
|
||||||
# CONFIG_EFI_LOADER is not set
|
# CONFIG_EFI_LOADER is not set
|
||||||
|
# CONFIG_LMB is not set
|
||||||
|
|
|
@ -67,3 +67,4 @@ CONFIG_ARM_DCC=y
|
||||||
CONFIG_FAT_WRITE=y
|
CONFIG_FAT_WRITE=y
|
||||||
# CONFIG_GZIP is not set
|
# CONFIG_GZIP is not set
|
||||||
# CONFIG_EFI_LOADER is not set
|
# CONFIG_EFI_LOADER is not set
|
||||||
|
# CONFIG_LMB is not set
|
||||||
|
|
|
@ -7,6 +7,7 @@ CONFIG_SYS_TEXT_BASE=0x8000000
|
||||||
CONFIG_SYS_MALLOC_F_LEN=0x100000
|
CONFIG_SYS_MALLOC_F_LEN=0x100000
|
||||||
CONFIG_DEFAULT_DEVICE_TREE="xilinx-versal-virt"
|
CONFIG_DEFAULT_DEVICE_TREE="xilinx-versal-virt"
|
||||||
CONFIG_SYS_PROMPT="Versal> "
|
CONFIG_SYS_PROMPT="Versal> "
|
||||||
|
CONFIG_ENV_OFFSET_REDUND=0x7F00000
|
||||||
CONFIG_CMD_FRU=y
|
CONFIG_CMD_FRU=y
|
||||||
CONFIG_DEFINE_TCM_OCM_MMAP=y
|
CONFIG_DEFINE_TCM_OCM_MMAP=y
|
||||||
CONFIG_SYS_LOAD_ADDR=0x8000000
|
CONFIG_SYS_LOAD_ADDR=0x8000000
|
||||||
|
@ -25,6 +26,7 @@ CONFIG_SYS_MAXARGS=64
|
||||||
CONFIG_SYS_PBSIZE=2073
|
CONFIG_SYS_PBSIZE=2073
|
||||||
CONFIG_SYS_BOOTM_LEN=0x6400000
|
CONFIG_SYS_BOOTM_LEN=0x6400000
|
||||||
CONFIG_CMD_BOOTMENU=y
|
CONFIG_CMD_BOOTMENU=y
|
||||||
|
CONFIG_CMD_GREPENV=y
|
||||||
CONFIG_CMD_NVEDIT_EFI=y
|
CONFIG_CMD_NVEDIT_EFI=y
|
||||||
CONFIG_CMD_MEMTEST=y
|
CONFIG_CMD_MEMTEST=y
|
||||||
CONFIG_SYS_ALT_MEMTEST=y
|
CONFIG_SYS_ALT_MEMTEST=y
|
||||||
|
@ -69,6 +71,8 @@ CONFIG_FPGA_XILINX=y
|
||||||
CONFIG_FPGA_VERSALPL=y
|
CONFIG_FPGA_VERSALPL=y
|
||||||
CONFIG_DM_I2C=y
|
CONFIG_DM_I2C=y
|
||||||
CONFIG_SYS_I2C_CADENCE=y
|
CONFIG_SYS_I2C_CADENCE=y
|
||||||
|
CONFIG_I2C_MUX=y
|
||||||
|
CONFIG_I2C_MUX_PCA954x=y
|
||||||
CONFIG_DM_MAILBOX=y
|
CONFIG_DM_MAILBOX=y
|
||||||
CONFIG_ZYNQMP_IPI=y
|
CONFIG_ZYNQMP_IPI=y
|
||||||
CONFIG_MISC=y
|
CONFIG_MISC=y
|
||||||
|
@ -102,6 +106,8 @@ CONFIG_PHY_GIGE=y
|
||||||
CONFIG_XILINX_AXIEMAC=y
|
CONFIG_XILINX_AXIEMAC=y
|
||||||
CONFIG_XILINX_AXIMRMAC=y
|
CONFIG_XILINX_AXIMRMAC=y
|
||||||
CONFIG_ZYNQ_GEM=y
|
CONFIG_ZYNQ_GEM=y
|
||||||
|
CONFIG_POWER_DOMAIN=y
|
||||||
|
CONFIG_ZYNQMP_POWER_DOMAIN=y
|
||||||
CONFIG_DM_RESET=y
|
CONFIG_DM_RESET=y
|
||||||
CONFIG_RESET_ZYNQMP=y
|
CONFIG_RESET_ZYNQMP=y
|
||||||
CONFIG_ARM_DCC=y
|
CONFIG_ARM_DCC=y
|
||||||
|
@ -111,8 +117,11 @@ CONFIG_SOC_XILINX_VERSAL=y
|
||||||
CONFIG_SPI=y
|
CONFIG_SPI=y
|
||||||
CONFIG_DM_SPI=y
|
CONFIG_DM_SPI=y
|
||||||
CONFIG_CADENCE_QSPI=y
|
CONFIG_CADENCE_QSPI=y
|
||||||
|
CONFIG_HAS_CQSPI_REF_CLK=y
|
||||||
|
CONFIG_CQSPI_REF_CLK=200000000
|
||||||
CONFIG_CADENCE_OSPI_VERSAL=y
|
CONFIG_CADENCE_OSPI_VERSAL=y
|
||||||
CONFIG_ZYNQ_SPI=y
|
CONFIG_ZYNQ_SPI=y
|
||||||
|
CONFIG_ZYNQMP_GQSPI=y
|
||||||
CONFIG_USB=y
|
CONFIG_USB=y
|
||||||
CONFIG_DM_USB_GADGET=y
|
CONFIG_DM_USB_GADGET=y
|
||||||
CONFIG_USB_XHCI_HCD=y
|
CONFIG_USB_XHCI_HCD=y
|
||||||
|
|
|
@ -8,6 +8,7 @@ CONFIG_DM_GPIO=y
|
||||||
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc706"
|
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc706"
|
||||||
CONFIG_SPL_STACK_R_ADDR=0x200000
|
CONFIG_SPL_STACK_R_ADDR=0x200000
|
||||||
CONFIG_SPL=y
|
CONFIG_SPL=y
|
||||||
|
CONFIG_ENV_OFFSET_REDUND=0xE40000
|
||||||
CONFIG_CMD_FRU=y
|
CONFIG_CMD_FRU=y
|
||||||
CONFIG_CMD_ZYNQ_AES=y
|
CONFIG_CMD_ZYNQ_AES=y
|
||||||
CONFIG_SYS_LOAD_ADDR=0x0
|
CONFIG_SYS_LOAD_ADDR=0x0
|
||||||
|
@ -50,6 +51,7 @@ CONFIG_SYS_PBSIZE=2071
|
||||||
CONFIG_SYS_BOOTM_LEN=0x3c00000
|
CONFIG_SYS_BOOTM_LEN=0x3c00000
|
||||||
CONFIG_CMD_IMLS=y
|
CONFIG_CMD_IMLS=y
|
||||||
CONFIG_CMD_THOR_DOWNLOAD=y
|
CONFIG_CMD_THOR_DOWNLOAD=y
|
||||||
|
CONFIG_CMD_GREPENV=y
|
||||||
CONFIG_CMD_MEMTEST=y
|
CONFIG_CMD_MEMTEST=y
|
||||||
CONFIG_SYS_ALT_MEMTEST=y
|
CONFIG_SYS_ALT_MEMTEST=y
|
||||||
CONFIG_CMD_DFU=y
|
CONFIG_CMD_DFU=y
|
||||||
|
@ -64,7 +66,6 @@ CONFIG_CMD_MTD=y
|
||||||
CONFIG_CMD_NAND_LOCK_UNLOCK=y
|
CONFIG_CMD_NAND_LOCK_UNLOCK=y
|
||||||
CONFIG_CMD_SF_TEST=y
|
CONFIG_CMD_SF_TEST=y
|
||||||
CONFIG_CMD_USB=y
|
CONFIG_CMD_USB=y
|
||||||
# CONFIG_CMD_SETEXPR is not set
|
|
||||||
CONFIG_BOOTP_MAY_FAIL=y
|
CONFIG_BOOTP_MAY_FAIL=y
|
||||||
CONFIG_CMD_TFTPPUT=y
|
CONFIG_CMD_TFTPPUT=y
|
||||||
CONFIG_CMD_CACHE=y
|
CONFIG_CMD_CACHE=y
|
||||||
|
@ -149,3 +150,4 @@ CONFIG_DISPLAY=y
|
||||||
CONFIG_SPL_GZIP=y
|
CONFIG_SPL_GZIP=y
|
||||||
CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
|
CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
|
||||||
CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
|
CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
|
||||||
|
CONFIG_TOOLS_MKEFICAPSULE=y
|
||||||
|
|
|
@ -65,3 +65,4 @@ CONFIG_SYS_NAND_MAX_CHIPS=2
|
||||||
CONFIG_ARM_DCC=y
|
CONFIG_ARM_DCC=y
|
||||||
CONFIG_PANIC_HANG=y
|
CONFIG_PANIC_HANG=y
|
||||||
# CONFIG_GZIP is not set
|
# CONFIG_GZIP is not set
|
||||||
|
# CONFIG_LMB is not set
|
||||||
|
|
|
@ -64,3 +64,4 @@ CONFIG_SYS_NAND_ONFI_DETECTION=y
|
||||||
CONFIG_ARM_DCC=y
|
CONFIG_ARM_DCC=y
|
||||||
CONFIG_PANIC_HANG=y
|
CONFIG_PANIC_HANG=y
|
||||||
# CONFIG_GZIP is not set
|
# CONFIG_GZIP is not set
|
||||||
|
# CONFIG_LMB is not set
|
||||||
|
|
|
@ -3,7 +3,7 @@ CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_mini_qspi"
|
||||||
CONFIG_SYS_ICACHE_OFF=y
|
CONFIG_SYS_ICACHE_OFF=y
|
||||||
CONFIG_ARCH_ZYNQMP=y
|
CONFIG_ARCH_ZYNQMP=y
|
||||||
CONFIG_SYS_TEXT_BASE=0xFFFC0000
|
CONFIG_SYS_TEXT_BASE=0xFFFC0000
|
||||||
CONFIG_SYS_MALLOC_LEN=0x1a00
|
CONFIG_SYS_MALLOC_LEN=0x1b00
|
||||||
CONFIG_NR_DRAM_BANKS=1
|
CONFIG_NR_DRAM_BANKS=1
|
||||||
CONFIG_ENV_SIZE=0x80
|
CONFIG_ENV_SIZE=0x80
|
||||||
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-qspi"
|
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-qspi"
|
||||||
|
@ -19,7 +19,9 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xfffe0000
|
||||||
# CONFIG_EXPERT is not set
|
# CONFIG_EXPERT is not set
|
||||||
CONFIG_REMAKE_ELF=y
|
CONFIG_REMAKE_ELF=y
|
||||||
# CONFIG_LEGACY_IMAGE_FORMAT is not set
|
# CONFIG_LEGACY_IMAGE_FORMAT is not set
|
||||||
|
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
|
||||||
# CONFIG_AUTOBOOT is not set
|
# CONFIG_AUTOBOOT is not set
|
||||||
|
CONFIG_LOGLEVEL=0
|
||||||
# CONFIG_DISPLAY_CPUINFO is not set
|
# CONFIG_DISPLAY_CPUINFO is not set
|
||||||
# CONFIG_BOARD_LATE_INIT is not set
|
# CONFIG_BOARD_LATE_INIT is not set
|
||||||
CONFIG_CLOCKS=y
|
CONFIG_CLOCKS=y
|
||||||
|
@ -62,6 +64,7 @@ CONFIG_SYS_PBSIZE=1049
|
||||||
# CONFIG_CMD_SOURCE is not set
|
# CONFIG_CMD_SOURCE is not set
|
||||||
# CONFIG_CMD_SETEXPR is not set
|
# CONFIG_CMD_SETEXPR is not set
|
||||||
# CONFIG_CMD_SLEEP is not set
|
# CONFIG_CMD_SLEEP is not set
|
||||||
|
# CONFIG_CMD_MP is not set
|
||||||
CONFIG_SPL_OF_CONTROL=y
|
CONFIG_SPL_OF_CONTROL=y
|
||||||
CONFIG_OF_EMBED=y
|
CONFIG_OF_EMBED=y
|
||||||
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||||
|
@ -69,17 +72,24 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||||
# CONFIG_DM_WARN is not set
|
# CONFIG_DM_WARN is not set
|
||||||
# CONFIG_DM_DEVICE_REMOVE is not set
|
# CONFIG_DM_DEVICE_REMOVE is not set
|
||||||
CONFIG_SPL_DM_SEQ_ALIAS=y
|
CONFIG_SPL_DM_SEQ_ALIAS=y
|
||||||
|
# CONFIG_FIRMWARE is not set
|
||||||
|
# CONFIG_GPIO is not set
|
||||||
|
# CONFIG_I2C is not set
|
||||||
|
# CONFIG_INPUT is not set
|
||||||
# CONFIG_MMC is not set
|
# CONFIG_MMC is not set
|
||||||
CONFIG_SPI_FLASH_BAR=y
|
# CONFIG_SPI_FLASH_SMART_HWCAPS is not set
|
||||||
|
# CONFIG_SPI_FLASH_UNLOCK_ALL is not set
|
||||||
CONFIG_SPI_FLASH_ISSI=y
|
CONFIG_SPI_FLASH_ISSI=y
|
||||||
CONFIG_SPI_FLASH_MACRONIX=y
|
CONFIG_SPI_FLASH_MACRONIX=y
|
||||||
CONFIG_SPI_FLASH_SPANSION=y
|
CONFIG_SPI_FLASH_SPANSION=y
|
||||||
CONFIG_SPI_FLASH_STMICRO=y
|
CONFIG_SPI_FLASH_STMICRO=y
|
||||||
CONFIG_SPI_FLASH_WINBOND=y
|
CONFIG_SPI_FLASH_WINBOND=y
|
||||||
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
|
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
|
||||||
|
# CONFIG_POWER is not set
|
||||||
CONFIG_ARM_DCC=y
|
CONFIG_ARM_DCC=y
|
||||||
CONFIG_SPI=y
|
CONFIG_SPI=y
|
||||||
CONFIG_ZYNQMP_GQSPI=y
|
CONFIG_ZYNQMP_GQSPI=y
|
||||||
|
# CONFIG_FAT_WRITE is not set
|
||||||
CONFIG_PANIC_HANG=y
|
CONFIG_PANIC_HANG=y
|
||||||
# CONFIG_GZIP is not set
|
# CONFIG_GZIP is not set
|
||||||
# CONFIG_LMB is not set
|
# CONFIG_LMB is not set
|
||||||
|
|
|
@ -10,6 +10,7 @@ CONFIG_SPL_STACK_R_ADDR=0x18000000
|
||||||
CONFIG_SPL_SIZE_LIMIT=0x2a000
|
CONFIG_SPL_SIZE_LIMIT=0x2a000
|
||||||
CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK=0x0
|
CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK=0x0
|
||||||
CONFIG_SPL=y
|
CONFIG_SPL=y
|
||||||
|
CONFIG_ENV_OFFSET_REDUND=0x1E80000
|
||||||
CONFIG_SPL_SPI_FLASH_SUPPORT=y
|
CONFIG_SPL_SPI_FLASH_SUPPORT=y
|
||||||
CONFIG_SPL_SPI=y
|
CONFIG_SPL_SPI=y
|
||||||
CONFIG_ZYNQ_MAC_IN_EEPROM=y
|
CONFIG_ZYNQ_MAC_IN_EEPROM=y
|
||||||
|
@ -56,6 +57,7 @@ CONFIG_SYS_PBSIZE=2073
|
||||||
CONFIG_SYS_BOOTM_LEN=0x6400000
|
CONFIG_SYS_BOOTM_LEN=0x6400000
|
||||||
CONFIG_CMD_BOOTMENU=y
|
CONFIG_CMD_BOOTMENU=y
|
||||||
CONFIG_CMD_THOR_DOWNLOAD=y
|
CONFIG_CMD_THOR_DOWNLOAD=y
|
||||||
|
CONFIG_CMD_GREPENV=y
|
||||||
CONFIG_CMD_NVEDIT_EFI=y
|
CONFIG_CMD_NVEDIT_EFI=y
|
||||||
CONFIG_CMD_MEMTEST=y
|
CONFIG_CMD_MEMTEST=y
|
||||||
CONFIG_SYS_ALT_MEMTEST=y
|
CONFIG_SYS_ALT_MEMTEST=y
|
||||||
|
|
|
@ -79,3 +79,4 @@ CONFIG_NAND_ZYNQ=y
|
||||||
CONFIG_SYS_NAND_ONFI_DETECTION=y
|
CONFIG_SYS_NAND_ONFI_DETECTION=y
|
||||||
CONFIG_ARM_DCC=y
|
CONFIG_ARM_DCC=y
|
||||||
# CONFIG_GZIP is not set
|
# CONFIG_GZIP is not set
|
||||||
|
# CONFIG_LMB is not set
|
||||||
|
|
|
@ -81,3 +81,4 @@ CONFIG_SYS_FLASH_CFI=y
|
||||||
CONFIG_SYS_FLASH_QUIET_TEST=y
|
CONFIG_SYS_FLASH_QUIET_TEST=y
|
||||||
CONFIG_ARM_DCC=y
|
CONFIG_ARM_DCC=y
|
||||||
# CONFIG_GZIP is not set
|
# CONFIG_GZIP is not set
|
||||||
|
# CONFIG_LMB is not set
|
||||||
|
|
|
@ -91,3 +91,4 @@ CONFIG_SPI_FLASH_WINBOND=y
|
||||||
CONFIG_ARM_DCC=y
|
CONFIG_ARM_DCC=y
|
||||||
CONFIG_ZYNQ_QSPI=y
|
CONFIG_ZYNQ_QSPI=y
|
||||||
# CONFIG_GZIP is not set
|
# CONFIG_GZIP is not set
|
||||||
|
# CONFIG_LMB is not set
|
||||||
|
|
|
@ -97,8 +97,10 @@ static int microblaze_cpu_get_desc(const struct udevice *dev, char *buf,
|
||||||
ret = snprintf(buf, size,
|
ret = snprintf(buf, size,
|
||||||
"MicroBlaze @ %uMHz, Rev: %s, FPGA family: %s",
|
"MicroBlaze @ %uMHz, Rev: %s, FPGA family: %s",
|
||||||
cpu_freq_mhz, cpu_ver, fpga_family);
|
cpu_freq_mhz, cpu_ver, fpga_family);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return 0;
|
return (ret >= size) ? -ENOSPC : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int microblaze_cpu_get_info(const struct udevice *dev,
|
static int microblaze_cpu_get_info(const struct udevice *dev,
|
||||||
|
|
|
@ -413,7 +413,8 @@ static int zynq_load(xilinx_desc *desc, const void *buf, size_t bsize,
|
||||||
if (bstype != BIT_PARTIAL)
|
if (bstype != BIT_PARTIAL)
|
||||||
zynq_slcr_devcfg_enable();
|
zynq_slcr_devcfg_enable();
|
||||||
|
|
||||||
puts("INFO:post config was not run, please run manually if needed\n");
|
if (!IS_ENABLED(CONFIG_SPL_BUILD))
|
||||||
|
puts("INFO:post config was not run, please run manually if needed\n");
|
||||||
|
|
||||||
return FPGA_SUCCESS;
|
return FPGA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -500,10 +500,13 @@ static int zynq_gem_init(struct udevice *dev)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = clk_set_rate(&priv->tx_clk, clk_rate);
|
ret = clk_get_rate(&priv->tx_clk);
|
||||||
if (IS_ERR_VALUE(ret)) {
|
if (ret != clk_rate) {
|
||||||
dev_err(dev, "failed to set tx clock rate\n");
|
ret = clk_set_rate(&priv->tx_clk, clk_rate);
|
||||||
return ret;
|
if (IS_ERR_VALUE(ret)) {
|
||||||
|
dev_err(dev, "failed to set tx clock rate %ld\n", clk_rate);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = clk_enable(&priv->tx_clk);
|
ret = clk_enable(&priv->tx_clk);
|
||||||
|
|
|
@ -25,7 +25,10 @@ static int zynqmp_power_domain_request(struct power_domain *power_domain)
|
||||||
{
|
{
|
||||||
dev_dbg(power_domain->dev, "Request for id: %ld\n", power_domain->id);
|
dev_dbg(power_domain->dev, "Request for id: %ld\n", power_domain->id);
|
||||||
|
|
||||||
return zynqmp_pmufw_node(power_domain->id);
|
if (IS_ENABLED(CONFIG_ARCH_ZYNQMP))
|
||||||
|
return zynqmp_pmufw_node(power_domain->id);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zynqmp_power_domain_free(struct power_domain *power_domain)
|
static int zynqmp_power_domain_free(struct power_domain *power_domain)
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#define CMD_4BYTE_READ 0x13
|
#define CMD_4BYTE_READ 0x13
|
||||||
#define CMD_4BYTE_FAST_READ 0x0C
|
#define CMD_4BYTE_FAST_READ 0x0C
|
||||||
|
|
||||||
int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op)
|
const struct spi_mem_op *op)
|
||||||
{
|
{
|
||||||
u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data;
|
u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data;
|
||||||
|
@ -34,86 +34,86 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat,
|
||||||
|
|
||||||
if (bytes_to_dma) {
|
if (bytes_to_dma) {
|
||||||
cadence_qspi_apb_enable_linear_mode(false);
|
cadence_qspi_apb_enable_linear_mode(false);
|
||||||
reg = readl(plat->regbase + CQSPI_REG_CONFIG);
|
reg = readl(priv->regbase + CQSPI_REG_CONFIG);
|
||||||
reg |= CQSPI_REG_CONFIG_ENBL_DMA;
|
reg |= CQSPI_REG_CONFIG_ENBL_DMA;
|
||||||
writel(reg, plat->regbase + CQSPI_REG_CONFIG);
|
writel(reg, priv->regbase + CQSPI_REG_CONFIG);
|
||||||
|
|
||||||
writel(bytes_to_dma, plat->regbase + CQSPI_REG_INDIRECTRDBYTES);
|
writel(bytes_to_dma, priv->regbase + CQSPI_REG_INDIRECTRDBYTES);
|
||||||
|
|
||||||
writel(CQSPI_DFLT_INDIR_TRIG_ADDR_RANGE,
|
writel(CQSPI_DFLT_INDIR_TRIG_ADDR_RANGE,
|
||||||
plat->regbase + CQSPI_REG_INDIR_TRIG_ADDR_RANGE);
|
priv->regbase + CQSPI_REG_INDIR_TRIG_ADDR_RANGE);
|
||||||
writel(CQSPI_DFLT_DMA_PERIPH_CFG,
|
writel(CQSPI_DFLT_DMA_PERIPH_CFG,
|
||||||
plat->regbase + CQSPI_REG_DMA_PERIPH_CFG);
|
priv->regbase + CQSPI_REG_DMA_PERIPH_CFG);
|
||||||
writel((unsigned long)rxbuf, plat->regbase +
|
writel((unsigned long)rxbuf, priv->regbase +
|
||||||
CQSPI_DMA_DST_ADDR_REG);
|
CQSPI_DMA_DST_ADDR_REG);
|
||||||
writel(plat->trigger_address, plat->regbase +
|
writel(priv->trigger_address, priv->regbase +
|
||||||
CQSPI_DMA_SRC_RD_ADDR_REG);
|
CQSPI_DMA_SRC_RD_ADDR_REG);
|
||||||
writel(bytes_to_dma, plat->regbase +
|
writel(bytes_to_dma, priv->regbase +
|
||||||
CQSPI_DMA_DST_SIZE_REG);
|
CQSPI_DMA_DST_SIZE_REG);
|
||||||
flush_dcache_range((unsigned long)rxbuf,
|
flush_dcache_range((unsigned long)rxbuf,
|
||||||
(unsigned long)rxbuf + bytes_to_dma);
|
(unsigned long)rxbuf + bytes_to_dma);
|
||||||
writel(CQSPI_DFLT_DST_CTRL_REG_VAL,
|
writel(CQSPI_DFLT_DST_CTRL_REG_VAL,
|
||||||
plat->regbase + CQSPI_DMA_DST_CTRL_REG);
|
priv->regbase + CQSPI_DMA_DST_CTRL_REG);
|
||||||
|
|
||||||
/* Start the indirect read transfer */
|
/* Start the indirect read transfer */
|
||||||
writel(CQSPI_REG_INDIRECTRD_START, plat->regbase +
|
writel(CQSPI_REG_INDIRECTRD_START, priv->regbase +
|
||||||
CQSPI_REG_INDIRECTRD);
|
CQSPI_REG_INDIRECTRD);
|
||||||
/* Wait for dma to complete transfer */
|
/* Wait for dma to complete transfer */
|
||||||
ret = cadence_qspi_apb_wait_for_dma_cmplt(plat);
|
ret = cadence_qspi_apb_wait_for_dma_cmplt(priv);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Clear indirect completion status */
|
/* Clear indirect completion status */
|
||||||
writel(CQSPI_REG_INDIRECTRD_DONE, plat->regbase +
|
writel(CQSPI_REG_INDIRECTRD_DONE, priv->regbase +
|
||||||
CQSPI_REG_INDIRECTRD);
|
CQSPI_REG_INDIRECTRD);
|
||||||
rxbuf += bytes_to_dma;
|
rxbuf += bytes_to_dma;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rx_rem) {
|
if (rx_rem) {
|
||||||
reg = readl(plat->regbase + CQSPI_REG_CONFIG);
|
reg = readl(priv->regbase + CQSPI_REG_CONFIG);
|
||||||
reg &= ~CQSPI_REG_CONFIG_ENBL_DMA;
|
reg &= ~CQSPI_REG_CONFIG_ENBL_DMA;
|
||||||
writel(reg, plat->regbase + CQSPI_REG_CONFIG);
|
writel(reg, priv->regbase + CQSPI_REG_CONFIG);
|
||||||
|
|
||||||
reg = readl(plat->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);
|
reg = readl(priv->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);
|
||||||
reg += bytes_to_dma;
|
reg += bytes_to_dma;
|
||||||
writel(reg, plat->regbase + CQSPI_REG_CMDADDRESS);
|
writel(reg, priv->regbase + CQSPI_REG_CMDADDRESS);
|
||||||
|
|
||||||
addr_bytes = readl(plat->regbase + CQSPI_REG_SIZE) &
|
addr_bytes = readl(priv->regbase + CQSPI_REG_SIZE) &
|
||||||
CQSPI_REG_SIZE_ADDRESS_MASK;
|
CQSPI_REG_SIZE_ADDRESS_MASK;
|
||||||
|
|
||||||
opcode = CMD_4BYTE_FAST_READ;
|
opcode = CMD_4BYTE_FAST_READ;
|
||||||
dummy_cycles = 8;
|
dummy_cycles = 8;
|
||||||
writel((dummy_cycles << CQSPI_REG_RD_INSTR_DUMMY_LSB) | opcode,
|
writel((dummy_cycles << CQSPI_REG_RD_INSTR_DUMMY_LSB) | opcode,
|
||||||
plat->regbase + CQSPI_REG_RD_INSTR);
|
priv->regbase + CQSPI_REG_RD_INSTR);
|
||||||
|
|
||||||
reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
|
reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
|
||||||
reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB);
|
reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB);
|
||||||
reg |= (addr_bytes & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) <<
|
reg |= (addr_bytes & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) <<
|
||||||
CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
|
CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
|
||||||
reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
|
reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
|
||||||
dummy_cycles = (readl(plat->regbase + CQSPI_REG_RD_INSTR) >>
|
dummy_cycles = (readl(priv->regbase + CQSPI_REG_RD_INSTR) >>
|
||||||
CQSPI_REG_RD_INSTR_DUMMY_LSB) &
|
CQSPI_REG_RD_INSTR_DUMMY_LSB) &
|
||||||
CQSPI_REG_RD_INSTR_DUMMY_MASK;
|
CQSPI_REG_RD_INSTR_DUMMY_MASK;
|
||||||
reg |= (dummy_cycles & CQSPI_REG_CMDCTRL_DUMMY_MASK) <<
|
reg |= (dummy_cycles & CQSPI_REG_CMDCTRL_DUMMY_MASK) <<
|
||||||
CQSPI_REG_CMDCTRL_DUMMY_LSB;
|
CQSPI_REG_CMDCTRL_DUMMY_LSB;
|
||||||
reg |= (((rx_rem - 1) & CQSPI_REG_CMDCTRL_RD_BYTES_MASK) <<
|
reg |= (((rx_rem - 1) & CQSPI_REG_CMDCTRL_RD_BYTES_MASK) <<
|
||||||
CQSPI_REG_CMDCTRL_RD_BYTES_LSB);
|
CQSPI_REG_CMDCTRL_RD_BYTES_LSB);
|
||||||
ret = cadence_qspi_apb_exec_flash_cmd(plat->regbase, reg);
|
ret = cadence_qspi_apb_exec_flash_cmd(priv->regbase, reg);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
data = readl(plat->regbase + CQSPI_REG_CMDREADDATALOWER);
|
data = readl(priv->regbase + CQSPI_REG_CMDREADDATALOWER);
|
||||||
memcpy(rxbuf, &data, rx_rem);
|
memcpy(rxbuf, &data, rx_rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_plat *plat)
|
int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_priv *priv)
|
||||||
{
|
{
|
||||||
u32 timeout = CQSPI_DMA_TIMEOUT;
|
u32 timeout = CQSPI_DMA_TIMEOUT;
|
||||||
|
|
||||||
while (!(readl(plat->regbase + CQSPI_DMA_DST_I_STS_REG) &
|
while (!(readl(priv->regbase + CQSPI_DMA_DST_I_STS_REG) &
|
||||||
CQSPI_DMA_DST_I_STS_DONE) && timeout--)
|
CQSPI_DMA_DST_I_STS_DONE) && timeout--)
|
||||||
udelay(1);
|
udelay(1);
|
||||||
|
|
||||||
|
@ -122,13 +122,13 @@ int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_plat *plat)
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
writel(readl(plat->regbase + CQSPI_DMA_DST_I_STS_REG),
|
writel(readl(priv->regbase + CQSPI_DMA_DST_I_STS_REG),
|
||||||
plat->regbase + CQSPI_DMA_DST_I_STS_REG);
|
priv->regbase + CQSPI_DMA_DST_I_STS_REG);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_DM_GPIO)
|
#if defined(CONFIG_DM_GPIO)
|
||||||
int cadence_spi_versal_flash_reset(struct udevice *dev)
|
int cadence_qspi_versal_flash_reset(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct gpio_desc gpio;
|
struct gpio_desc gpio;
|
||||||
u32 reset_gpio;
|
u32 reset_gpio;
|
||||||
|
@ -169,7 +169,7 @@ int cadence_spi_versal_flash_reset(struct udevice *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int cadence_spi_versal_flash_reset(struct udevice *dev)
|
int cadence_qspi_versal_flash_reset(struct udevice *dev)
|
||||||
{
|
{
|
||||||
/* CRP WPROT */
|
/* CRP WPROT */
|
||||||
writel(0, WPROT_CRP);
|
writel(0, WPROT_CRP);
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#define CQSPI_READ 2
|
#define CQSPI_READ 2
|
||||||
#define CQSPI_WRITE 3
|
#define CQSPI_WRITE 3
|
||||||
|
|
||||||
__weak int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat,
|
__weak int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op)
|
const struct spi_mem_op *op)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -42,36 +42,40 @@ __weak int cadence_qspi_versal_flash_reset(struct udevice *dev)
|
||||||
|
|
||||||
static int cadence_spi_write_speed(struct udevice *bus, uint hz)
|
static int cadence_spi_write_speed(struct udevice *bus, uint hz)
|
||||||
{
|
{
|
||||||
struct cadence_spi_plat *plat = dev_get_plat(bus);
|
|
||||||
struct cadence_spi_priv *priv = dev_get_priv(bus);
|
struct cadence_spi_priv *priv = dev_get_priv(bus);
|
||||||
|
|
||||||
cadence_qspi_apb_config_baudrate_div(priv->regbase,
|
cadence_qspi_apb_config_baudrate_div(priv->regbase,
|
||||||
plat->ref_clk_hz, hz);
|
priv->ref_clk_hz, hz);
|
||||||
|
|
||||||
/* Reconfigure delay timing if speed is changed. */
|
/* Reconfigure delay timing if speed is changed. */
|
||||||
cadence_qspi_apb_delay(priv->regbase, plat->ref_clk_hz, hz,
|
cadence_qspi_apb_delay(priv->regbase, priv->ref_clk_hz, hz,
|
||||||
plat->tshsl_ns, plat->tsd2d_ns,
|
priv->tshsl_ns, priv->tsd2d_ns,
|
||||||
plat->tchsh_ns, plat->tslch_ns);
|
priv->tchsh_ns, priv->tslch_ns);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cadence_spi_read_id(struct cadence_spi_plat *plat, u8 len,
|
static int cadence_spi_read_id(struct cadence_spi_priv *priv, u8 len,
|
||||||
u8 *idcode)
|
u8 *idcode)
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(0x9F, 1),
|
struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(0x9F, 1),
|
||||||
SPI_MEM_OP_NO_ADDR,
|
SPI_MEM_OP_NO_ADDR,
|
||||||
SPI_MEM_OP_NO_DUMMY,
|
SPI_MEM_OP_NO_DUMMY,
|
||||||
SPI_MEM_OP_DATA_IN(len, idcode, 1));
|
SPI_MEM_OP_DATA_IN(len, idcode, 1));
|
||||||
|
|
||||||
return cadence_qspi_apb_command_read(plat, &op);
|
err = cadence_qspi_apb_command_read_setup(priv, &op);
|
||||||
|
if (!err)
|
||||||
|
err = cadence_qspi_apb_command_read(priv, &op);
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calibration sequence to determine the read data capture delay register */
|
/* Calibration sequence to determine the read data capture delay register */
|
||||||
static int spi_calibration(struct udevice *bus, uint hz)
|
static int spi_calibration(struct udevice *bus, uint hz)
|
||||||
{
|
{
|
||||||
struct cadence_spi_priv *priv = dev_get_priv(bus);
|
struct cadence_spi_priv *priv = dev_get_priv(bus);
|
||||||
struct cadence_spi_plat *plat = dev_get_plat(bus);
|
|
||||||
void *base = priv->regbase;
|
void *base = priv->regbase;
|
||||||
unsigned int idcode = 0, temp = 0;
|
unsigned int idcode = 0, temp = 0;
|
||||||
int err = 0, i, range_lo = -1, range_hi = -1;
|
int err = 0, i, range_lo = -1, range_hi = -1;
|
||||||
|
@ -86,7 +90,7 @@ static int spi_calibration(struct udevice *bus, uint hz)
|
||||||
cadence_qspi_apb_controller_enable(base);
|
cadence_qspi_apb_controller_enable(base);
|
||||||
|
|
||||||
/* read the ID which will be our golden value */
|
/* read the ID which will be our golden value */
|
||||||
err = cadence_spi_read_id(plat, 3, (u8 *)&idcode);
|
err = cadence_spi_read_id(priv, 3, (u8 *)&idcode);
|
||||||
if (err) {
|
if (err) {
|
||||||
puts("SF: Calibration failed (read)\n");
|
puts("SF: Calibration failed (read)\n");
|
||||||
return err;
|
return err;
|
||||||
|
@ -105,7 +109,7 @@ static int spi_calibration(struct udevice *bus, uint hz)
|
||||||
cadence_qspi_apb_controller_enable(base);
|
cadence_qspi_apb_controller_enable(base);
|
||||||
|
|
||||||
/* issue a RDID to get the ID value */
|
/* issue a RDID to get the ID value */
|
||||||
err = cadence_spi_read_id(plat, 3, (u8 *)&temp);
|
err = cadence_spi_read_id(priv, 3, (u8 *)&temp);
|
||||||
if (err) {
|
if (err) {
|
||||||
puts("SF: Calibration failed (read)\n");
|
puts("SF: Calibration failed (read)\n");
|
||||||
return err;
|
return err;
|
||||||
|
@ -147,13 +151,11 @@ static int spi_calibration(struct udevice *bus, uint hz)
|
||||||
|
|
||||||
static int cadence_spi_set_speed(struct udevice *bus, uint hz)
|
static int cadence_spi_set_speed(struct udevice *bus, uint hz)
|
||||||
{
|
{
|
||||||
struct cadence_spi_plat *plat = dev_get_plat(bus);
|
|
||||||
struct cadence_spi_priv *priv = dev_get_priv(bus);
|
struct cadence_spi_priv *priv = dev_get_priv(bus);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!hz || hz > plat->max_hz)
|
if (!hz || hz > priv->max_hz)
|
||||||
hz = plat->max_hz;
|
hz = priv->max_hz;
|
||||||
|
|
||||||
/* Disable QSPI */
|
/* Disable QSPI */
|
||||||
cadence_qspi_apb_controller_disable(priv->regbase);
|
cadence_qspi_apb_controller_disable(priv->regbase);
|
||||||
|
|
||||||
|
@ -161,10 +163,10 @@ static int cadence_spi_set_speed(struct udevice *bus, uint hz)
|
||||||
* If the device tree already provides a read delay value, use that
|
* If the device tree already provides a read delay value, use that
|
||||||
* instead of calibrating.
|
* instead of calibrating.
|
||||||
*/
|
*/
|
||||||
if (plat->read_delay >= 0) {
|
if (priv->read_delay >= 0) {
|
||||||
cadence_spi_write_speed(bus, hz);
|
cadence_spi_write_speed(bus, hz);
|
||||||
cadence_qspi_apb_readdata_capture(priv->regbase, 1,
|
cadence_qspi_apb_readdata_capture(priv->regbase, 1,
|
||||||
plat->read_delay);
|
priv->read_delay);
|
||||||
} else if (priv->previous_hz != hz ||
|
} else if (priv->previous_hz != hz ||
|
||||||
priv->qspi_calibrated_hz != hz ||
|
priv->qspi_calibrated_hz != hz ||
|
||||||
priv->qspi_calibrated_cs != spi_chip_select(bus)) {
|
priv->qspi_calibrated_cs != spi_chip_select(bus)) {
|
||||||
|
@ -195,29 +197,44 @@ static int cadence_spi_probe(struct udevice *bus)
|
||||||
struct clk clk;
|
struct clk clk;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
priv->regbase = plat->regbase;
|
priv->regbase = plat->regbase;
|
||||||
priv->ahbbase = plat->ahbbase;
|
priv->ahbbase = plat->ahbbase;
|
||||||
|
priv->is_dma = plat->is_dma;
|
||||||
|
priv->is_decoded_cs = plat->is_decoded_cs;
|
||||||
|
priv->fifo_depth = plat->fifo_depth;
|
||||||
|
priv->fifo_width = plat->fifo_width;
|
||||||
|
priv->trigger_address = plat->trigger_address;
|
||||||
|
priv->read_delay = plat->read_delay;
|
||||||
|
priv->ahbsize = plat->ahbsize;
|
||||||
|
priv->max_hz = plat->max_hz;
|
||||||
|
|
||||||
|
priv->page_size = plat->page_size;
|
||||||
|
priv->block_size = plat->block_size;
|
||||||
|
priv->tshsl_ns = plat->tshsl_ns;
|
||||||
|
priv->tsd2d_ns = plat->tsd2d_ns;
|
||||||
|
priv->tchsh_ns = plat->tchsh_ns;
|
||||||
|
priv->tslch_ns = plat->tslch_ns;
|
||||||
|
|
||||||
if (CONFIG_IS_ENABLED(ZYNQMP_FIRMWARE))
|
if (CONFIG_IS_ENABLED(ZYNQMP_FIRMWARE))
|
||||||
xilinx_pm_request(PM_REQUEST_NODE, PM_DEV_OSPI,
|
xilinx_pm_request(PM_REQUEST_NODE, PM_DEV_OSPI,
|
||||||
ZYNQMP_PM_CAPABILITY_ACCESS, ZYNQMP_PM_MAX_QOS,
|
ZYNQMP_PM_CAPABILITY_ACCESS, ZYNQMP_PM_MAX_QOS,
|
||||||
ZYNQMP_PM_REQUEST_ACK_NO, NULL);
|
ZYNQMP_PM_REQUEST_ACK_NO, NULL);
|
||||||
|
|
||||||
if (plat->ref_clk_hz == 0) {
|
if (priv->ref_clk_hz == 0) {
|
||||||
ret = clk_get_by_index(bus, 0, &clk);
|
ret = clk_get_by_index(bus, 0, &clk);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
#ifdef CONFIG_HAS_CQSPI_REF_CLK
|
#ifdef CONFIG_HAS_CQSPI_REF_CLK
|
||||||
plat->ref_clk_hz = CONFIG_CQSPI_REF_CLK;
|
priv->ref_clk_hz = CONFIG_CQSPI_REF_CLK;
|
||||||
#elif defined(CONFIG_ARCH_SOCFPGA)
|
#elif defined(CONFIG_ARCH_SOCFPGA)
|
||||||
plat->ref_clk_hz = cm_get_qspi_controller_clk_hz();
|
priv->ref_clk_hz = cm_get_qspi_controller_clk_hz();
|
||||||
#else
|
#else
|
||||||
return ret;
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
plat->ref_clk_hz = clk_get_rate(&clk);
|
priv->ref_clk_hz = clk_get_rate(&clk);
|
||||||
clk_free(&clk);
|
clk_free(&clk);
|
||||||
if (IS_ERR_VALUE(plat->ref_clk_hz))
|
if (IS_ERR_VALUE(priv->ref_clk_hz))
|
||||||
return plat->ref_clk_hz;
|
return priv->ref_clk_hz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,16 +243,16 @@ static int cadence_spi_probe(struct udevice *bus)
|
||||||
reset_deassert_bulk(priv->resets);
|
reset_deassert_bulk(priv->resets);
|
||||||
|
|
||||||
if (!priv->qspi_is_init) {
|
if (!priv->qspi_is_init) {
|
||||||
cadence_qspi_apb_controller_init(plat);
|
cadence_qspi_apb_controller_init(priv);
|
||||||
priv->qspi_is_init = 1;
|
priv->qspi_is_init = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
plat->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC, plat->ref_clk_hz);
|
priv->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC, priv->ref_clk_hz);
|
||||||
|
|
||||||
if (CONFIG_IS_ENABLED(ARCH_VERSAL)) {
|
if (CONFIG_IS_ENABLED(ARCH_VERSAL)) {
|
||||||
/* Versal platform uses spi calibration to set read delay */
|
/* Versal platform uses spi calibration to set read delay */
|
||||||
if (plat->read_delay >= 0)
|
if (priv->read_delay >= 0)
|
||||||
plat->read_delay = -1;
|
priv->read_delay = -1;
|
||||||
/* Reset ospi flash device */
|
/* Reset ospi flash device */
|
||||||
ret = cadence_qspi_versal_flash_reset(bus);
|
ret = cadence_qspi_versal_flash_reset(bus);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -258,7 +275,6 @@ static int cadence_spi_remove(struct udevice *dev)
|
||||||
|
|
||||||
static int cadence_spi_set_mode(struct udevice *bus, uint mode)
|
static int cadence_spi_set_mode(struct udevice *bus, uint mode)
|
||||||
{
|
{
|
||||||
struct cadence_spi_plat *plat = dev_get_plat(bus);
|
|
||||||
struct cadence_spi_priv *priv = dev_get_priv(bus);
|
struct cadence_spi_priv *priv = dev_get_priv(bus);
|
||||||
|
|
||||||
/* Disable QSPI */
|
/* Disable QSPI */
|
||||||
|
@ -268,7 +284,7 @@ static int cadence_spi_set_mode(struct udevice *bus, uint mode)
|
||||||
cadence_qspi_apb_set_clk_mode(priv->regbase, mode);
|
cadence_qspi_apb_set_clk_mode(priv->regbase, mode);
|
||||||
|
|
||||||
/* Enable Direct Access Controller */
|
/* Enable Direct Access Controller */
|
||||||
if (plat->use_dac_mode)
|
if (priv->use_dac_mode)
|
||||||
cadence_qspi_apb_dac_mode_enable(priv->regbase);
|
cadence_qspi_apb_dac_mode_enable(priv->regbase);
|
||||||
|
|
||||||
/* Enable QSPI */
|
/* Enable QSPI */
|
||||||
|
@ -281,7 +297,6 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi,
|
||||||
const struct spi_mem_op *op)
|
const struct spi_mem_op *op)
|
||||||
{
|
{
|
||||||
struct udevice *bus = spi->dev->parent;
|
struct udevice *bus = spi->dev->parent;
|
||||||
struct cadence_spi_plat *plat = dev_get_plat(bus);
|
|
||||||
struct cadence_spi_priv *priv = dev_get_priv(bus);
|
struct cadence_spi_priv *priv = dev_get_priv(bus);
|
||||||
void *base = priv->regbase;
|
void *base = priv->regbase;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -289,7 +304,7 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi,
|
||||||
|
|
||||||
/* Set Chip select */
|
/* Set Chip select */
|
||||||
cadence_qspi_apb_chipselect(base, spi_chip_select(spi->dev),
|
cadence_qspi_apb_chipselect(base, spi_chip_select(spi->dev),
|
||||||
plat->is_decoded_cs);
|
priv->is_decoded_cs);
|
||||||
|
|
||||||
if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) {
|
if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) {
|
||||||
if (!op->addr.nbytes)
|
if (!op->addr.nbytes)
|
||||||
|
@ -305,28 +320,28 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi,
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case CQSPI_STIG_READ:
|
case CQSPI_STIG_READ:
|
||||||
err = cadence_qspi_apb_command_read_setup(plat, op);
|
err = cadence_qspi_apb_command_read_setup(priv, op);
|
||||||
if (!err)
|
if (!err)
|
||||||
err = cadence_qspi_apb_command_read(plat, op);
|
err = cadence_qspi_apb_command_read(priv, op);
|
||||||
break;
|
break;
|
||||||
case CQSPI_STIG_WRITE:
|
case CQSPI_STIG_WRITE:
|
||||||
err = cadence_qspi_apb_command_write_setup(plat, op);
|
err = cadence_qspi_apb_command_write_setup(priv, op);
|
||||||
if (!err)
|
if (!err)
|
||||||
err = cadence_qspi_apb_command_write(plat, op);
|
err = cadence_qspi_apb_command_write(priv, op);
|
||||||
break;
|
break;
|
||||||
case CQSPI_READ:
|
case CQSPI_READ:
|
||||||
err = cadence_qspi_apb_read_setup(plat, op);
|
err = cadence_qspi_apb_read_setup(priv, op);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
if (plat->is_dma)
|
if (priv->is_dma)
|
||||||
err = cadence_qspi_apb_dma_read(plat, op);
|
err = cadence_qspi_apb_dma_read(priv, op);
|
||||||
else
|
else
|
||||||
err = cadence_qspi_apb_read_execute(plat, op);
|
err = cadence_qspi_apb_read_execute(priv, op);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CQSPI_WRITE:
|
case CQSPI_WRITE:
|
||||||
err = cadence_qspi_apb_write_setup(plat, op);
|
err = cadence_qspi_apb_write_setup(priv, op);
|
||||||
if (!err)
|
if (!err)
|
||||||
err = cadence_qspi_apb_write_execute(plat, op);
|
err = cadence_qspi_apb_write_execute(priv, op);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
err = -1;
|
err = -1;
|
||||||
|
@ -359,6 +374,7 @@ static bool cadence_spi_mem_supports_op(struct spi_slave *slave,
|
||||||
static int cadence_spi_of_to_plat(struct udevice *bus)
|
static int cadence_spi_of_to_plat(struct udevice *bus)
|
||||||
{
|
{
|
||||||
struct cadence_spi_plat *plat = dev_get_plat(bus);
|
struct cadence_spi_plat *plat = dev_get_plat(bus);
|
||||||
|
struct cadence_spi_priv *priv = dev_get_priv(bus);
|
||||||
ofnode subnode;
|
ofnode subnode;
|
||||||
|
|
||||||
plat->regbase = (void *)devfdt_get_addr_index(bus, 0);
|
plat->regbase = (void *)devfdt_get_addr_index(bus, 0);
|
||||||
|
@ -372,7 +388,7 @@ static int cadence_spi_of_to_plat(struct udevice *bus)
|
||||||
0);
|
0);
|
||||||
/* Use DAC mode only when MMIO window is at least 8M wide */
|
/* Use DAC mode only when MMIO window is at least 8M wide */
|
||||||
if (plat->ahbsize >= SZ_8M)
|
if (plat->ahbsize >= SZ_8M)
|
||||||
plat->use_dac_mode = true;
|
priv->use_dac_mode = true;
|
||||||
|
|
||||||
plat->is_dma = dev_read_bool(bus, "cdns,is-dma");
|
plat->is_dma = dev_read_bool(bus, "cdns,is-dma");
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,6 @@
|
||||||
CQSPI_REG_SDRAMLEVEL_WR_LSB) & CQSPI_REG_SDRAMLEVEL_WR_MASK)
|
CQSPI_REG_SDRAMLEVEL_WR_LSB) & CQSPI_REG_SDRAMLEVEL_WR_MASK)
|
||||||
|
|
||||||
struct cadence_spi_plat {
|
struct cadence_spi_plat {
|
||||||
unsigned int ref_clk_hz;
|
|
||||||
unsigned int max_hz;
|
unsigned int max_hz;
|
||||||
void *regbase;
|
void *regbase;
|
||||||
void *ahbbase;
|
void *ahbbase;
|
||||||
|
@ -209,7 +208,6 @@ struct cadence_spi_plat {
|
||||||
fdt_addr_t ahbsize;
|
fdt_addr_t ahbsize;
|
||||||
bool use_dac_mode;
|
bool use_dac_mode;
|
||||||
int read_delay;
|
int read_delay;
|
||||||
u32 wr_delay;
|
|
||||||
|
|
||||||
/* Flash parameters */
|
/* Flash parameters */
|
||||||
u32 page_size;
|
u32 page_size;
|
||||||
|
@ -219,17 +217,18 @@ struct cadence_spi_plat {
|
||||||
u32 tchsh_ns;
|
u32 tchsh_ns;
|
||||||
u32 tslch_ns;
|
u32 tslch_ns;
|
||||||
|
|
||||||
/* Transaction protocol parameters. */
|
|
||||||
u8 inst_width;
|
|
||||||
u8 addr_width;
|
|
||||||
u8 data_width;
|
|
||||||
bool dtr;
|
|
||||||
bool is_dma;
|
bool is_dma;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cadence_spi_priv {
|
struct cadence_spi_priv {
|
||||||
|
unsigned int ref_clk_hz;
|
||||||
|
unsigned int max_hz;
|
||||||
void *regbase;
|
void *regbase;
|
||||||
void *ahbbase;
|
void *ahbbase;
|
||||||
|
unsigned int fifo_depth;
|
||||||
|
unsigned int fifo_width;
|
||||||
|
unsigned int trigger_address;
|
||||||
|
fdt_addr_t ahbsize;
|
||||||
size_t cmd_len;
|
size_t cmd_len;
|
||||||
u8 cmd_buf[32];
|
u8 cmd_buf[32];
|
||||||
size_t data_len;
|
size_t data_len;
|
||||||
|
@ -238,32 +237,53 @@ struct cadence_spi_priv {
|
||||||
unsigned int qspi_calibrated_hz;
|
unsigned int qspi_calibrated_hz;
|
||||||
unsigned int qspi_calibrated_cs;
|
unsigned int qspi_calibrated_cs;
|
||||||
unsigned int previous_hz;
|
unsigned int previous_hz;
|
||||||
|
u32 wr_delay;
|
||||||
|
int read_delay;
|
||||||
|
|
||||||
struct reset_ctl_bulk *resets;
|
struct reset_ctl_bulk *resets;
|
||||||
|
u32 page_size;
|
||||||
|
u32 block_size;
|
||||||
|
u32 tshsl_ns;
|
||||||
|
u32 tsd2d_ns;
|
||||||
|
u32 tchsh_ns;
|
||||||
|
u32 tslch_ns;
|
||||||
|
u8 edge_mode;
|
||||||
|
u8 dll_mode;
|
||||||
|
bool extra_dummy;
|
||||||
|
bool ddr_init;
|
||||||
|
bool is_decoded_cs;
|
||||||
|
bool use_dac_mode;
|
||||||
|
bool is_dma;
|
||||||
|
|
||||||
|
/* Transaction protocol parameters. */
|
||||||
|
u8 inst_width;
|
||||||
|
u8 addr_width;
|
||||||
|
u8 data_width;
|
||||||
|
bool dtr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Functions call declaration */
|
/* Functions call declaration */
|
||||||
void cadence_qspi_apb_controller_init(struct cadence_spi_plat *plat);
|
void cadence_qspi_apb_controller_init(struct cadence_spi_priv *priv);
|
||||||
void cadence_qspi_apb_controller_enable(void *reg_base_addr);
|
void cadence_qspi_apb_controller_enable(void *reg_base_addr);
|
||||||
void cadence_qspi_apb_controller_disable(void *reg_base_addr);
|
void cadence_qspi_apb_controller_disable(void *reg_base_addr);
|
||||||
void cadence_qspi_apb_dac_mode_enable(void *reg_base);
|
void cadence_qspi_apb_dac_mode_enable(void *reg_base);
|
||||||
|
|
||||||
int cadence_qspi_apb_command_read_setup(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_command_read_setup(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op);
|
const struct spi_mem_op *op);
|
||||||
int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_command_read(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op);
|
const struct spi_mem_op *op);
|
||||||
int cadence_qspi_apb_command_write_setup(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_command_write_setup(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op);
|
const struct spi_mem_op *op);
|
||||||
int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_command_write(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op);
|
const struct spi_mem_op *op);
|
||||||
|
|
||||||
int cadence_qspi_apb_read_setup(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_read_setup(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op);
|
const struct spi_mem_op *op);
|
||||||
int cadence_qspi_apb_read_execute(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_read_execute(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op);
|
const struct spi_mem_op *op);
|
||||||
int cadence_qspi_apb_write_setup(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_write_setup(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op);
|
const struct spi_mem_op *op);
|
||||||
int cadence_qspi_apb_write_execute(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_write_execute(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op);
|
const struct spi_mem_op *op);
|
||||||
|
|
||||||
void cadence_qspi_apb_chipselect(void *reg_base,
|
void cadence_qspi_apb_chipselect(void *reg_base,
|
||||||
|
@ -279,9 +299,9 @@ void cadence_qspi_apb_enter_xip(void *reg_base, char xip_dummy);
|
||||||
void cadence_qspi_apb_readdata_capture(void *reg_base,
|
void cadence_qspi_apb_readdata_capture(void *reg_base,
|
||||||
unsigned int bypass, unsigned int delay);
|
unsigned int bypass, unsigned int delay);
|
||||||
unsigned int cm_get_qspi_controller_clk_hz(void);
|
unsigned int cm_get_qspi_controller_clk_hz(void);
|
||||||
int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op);
|
const struct spi_mem_op *op);
|
||||||
int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_plat *plat);
|
int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_priv *priv);
|
||||||
int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg);
|
int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg);
|
||||||
int cadence_qspi_versal_flash_reset(struct udevice *dev);
|
int cadence_qspi_versal_flash_reset(struct udevice *dev);
|
||||||
void cadence_qspi_apb_enable_linear_mode(bool enable);
|
void cadence_qspi_apb_enable_linear_mode(bool enable);
|
||||||
|
|
|
@ -83,13 +83,13 @@ static unsigned int cadence_qspi_calc_dummy(const struct spi_mem_op *op,
|
||||||
return dummy_clk;
|
return dummy_clk;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 cadence_qspi_calc_rdreg(struct cadence_spi_plat *plat)
|
static u32 cadence_qspi_calc_rdreg(struct cadence_spi_priv *priv)
|
||||||
{
|
{
|
||||||
u32 rdreg = 0;
|
u32 rdreg = 0;
|
||||||
|
|
||||||
rdreg |= plat->inst_width << CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB;
|
rdreg |= priv->inst_width << CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB;
|
||||||
rdreg |= plat->addr_width << CQSPI_REG_RD_INSTR_TYPE_ADDR_LSB;
|
rdreg |= priv->addr_width << CQSPI_REG_RD_INSTR_TYPE_ADDR_LSB;
|
||||||
rdreg |= plat->data_width << CQSPI_REG_RD_INSTR_TYPE_DATA_LSB;
|
rdreg |= priv->data_width << CQSPI_REG_RD_INSTR_TYPE_DATA_LSB;
|
||||||
|
|
||||||
return rdreg;
|
return rdreg;
|
||||||
}
|
}
|
||||||
|
@ -115,27 +115,27 @@ static int cadence_qspi_buswidth_to_inst_type(u8 buswidth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cadence_qspi_set_protocol(struct cadence_spi_plat *plat,
|
static int cadence_qspi_set_protocol(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op)
|
const struct spi_mem_op *op)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
plat->dtr = op->data.dtr && op->cmd.dtr && op->addr.dtr;
|
priv->dtr = op->data.dtr && op->cmd.dtr && op->addr.dtr;
|
||||||
|
|
||||||
ret = cadence_qspi_buswidth_to_inst_type(op->cmd.buswidth);
|
ret = cadence_qspi_buswidth_to_inst_type(op->cmd.buswidth);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
plat->inst_width = ret;
|
priv->inst_width = ret;
|
||||||
|
|
||||||
ret = cadence_qspi_buswidth_to_inst_type(op->addr.buswidth);
|
ret = cadence_qspi_buswidth_to_inst_type(op->addr.buswidth);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
plat->addr_width = ret;
|
priv->addr_width = ret;
|
||||||
|
|
||||||
ret = cadence_qspi_buswidth_to_inst_type(op->data.buswidth);
|
ret = cadence_qspi_buswidth_to_inst_type(op->data.buswidth);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
plat->data_width = ret;
|
priv->data_width = ret;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -314,31 +314,31 @@ void cadence_qspi_apb_delay(void *reg_base,
|
||||||
cadence_qspi_apb_controller_enable(reg_base);
|
cadence_qspi_apb_controller_enable(reg_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cadence_qspi_apb_controller_init(struct cadence_spi_plat *plat)
|
void cadence_qspi_apb_controller_init(struct cadence_spi_priv *priv)
|
||||||
{
|
{
|
||||||
unsigned reg;
|
unsigned reg;
|
||||||
|
|
||||||
cadence_qspi_apb_controller_disable(plat->regbase);
|
cadence_qspi_apb_controller_disable(priv->regbase);
|
||||||
|
|
||||||
/* Configure the device size and address bytes */
|
/* Configure the device size and address bytes */
|
||||||
reg = readl(plat->regbase + CQSPI_REG_SIZE);
|
reg = readl(priv->regbase + CQSPI_REG_SIZE);
|
||||||
/* Clear the previous value */
|
/* Clear the previous value */
|
||||||
reg &= ~(CQSPI_REG_SIZE_PAGE_MASK << CQSPI_REG_SIZE_PAGE_LSB);
|
reg &= ~(CQSPI_REG_SIZE_PAGE_MASK << CQSPI_REG_SIZE_PAGE_LSB);
|
||||||
reg &= ~(CQSPI_REG_SIZE_BLOCK_MASK << CQSPI_REG_SIZE_BLOCK_LSB);
|
reg &= ~(CQSPI_REG_SIZE_BLOCK_MASK << CQSPI_REG_SIZE_BLOCK_LSB);
|
||||||
reg |= (plat->page_size << CQSPI_REG_SIZE_PAGE_LSB);
|
reg |= (priv->page_size << CQSPI_REG_SIZE_PAGE_LSB);
|
||||||
reg |= (plat->block_size << CQSPI_REG_SIZE_BLOCK_LSB);
|
reg |= (priv->block_size << CQSPI_REG_SIZE_BLOCK_LSB);
|
||||||
writel(reg, plat->regbase + CQSPI_REG_SIZE);
|
writel(reg, priv->regbase + CQSPI_REG_SIZE);
|
||||||
|
|
||||||
/* Configure the remap address register, no remap */
|
/* Configure the remap address register, no remap */
|
||||||
writel(0, plat->regbase + CQSPI_REG_REMAP);
|
writel(0, priv->regbase + CQSPI_REG_REMAP);
|
||||||
|
|
||||||
/* Indirect mode configurations */
|
/* Indirect mode configurations */
|
||||||
writel(plat->fifo_depth / 2, plat->regbase + CQSPI_REG_SRAMPARTITION);
|
writel(priv->fifo_depth / 2, priv->regbase + CQSPI_REG_SRAMPARTITION);
|
||||||
|
|
||||||
/* Disable all interrupts */
|
/* Disable all interrupts */
|
||||||
writel(0, plat->regbase + CQSPI_REG_IRQMASK);
|
writel(0, priv->regbase + CQSPI_REG_IRQMASK);
|
||||||
|
|
||||||
cadence_qspi_apb_controller_enable(plat->regbase);
|
cadence_qspi_apb_controller_enable(priv->regbase);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg)
|
int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg)
|
||||||
|
@ -370,7 +370,7 @@ int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cadence_qspi_setup_opcode_ext(struct cadence_spi_plat *plat,
|
static int cadence_qspi_setup_opcode_ext(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op,
|
const struct spi_mem_op *op,
|
||||||
unsigned int shift)
|
unsigned int shift)
|
||||||
{
|
{
|
||||||
|
@ -383,15 +383,15 @@ static int cadence_qspi_setup_opcode_ext(struct cadence_spi_plat *plat,
|
||||||
/* Opcode extension is the LSB. */
|
/* Opcode extension is the LSB. */
|
||||||
ext = op->cmd.opcode & 0xff;
|
ext = op->cmd.opcode & 0xff;
|
||||||
|
|
||||||
reg = readl(plat->regbase + CQSPI_REG_OP_EXT_LOWER);
|
reg = readl(priv->regbase + CQSPI_REG_OP_EXT_LOWER);
|
||||||
reg &= ~(0xff << shift);
|
reg &= ~(0xff << shift);
|
||||||
reg |= ext << shift;
|
reg |= ext << shift;
|
||||||
writel(reg, plat->regbase + CQSPI_REG_OP_EXT_LOWER);
|
writel(reg, priv->regbase + CQSPI_REG_OP_EXT_LOWER);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cadence_qspi_enable_dtr(struct cadence_spi_plat *plat,
|
static int cadence_qspi_enable_dtr(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op,
|
const struct spi_mem_op *op,
|
||||||
unsigned int shift,
|
unsigned int shift,
|
||||||
bool enable)
|
bool enable)
|
||||||
|
@ -399,14 +399,14 @@ static int cadence_qspi_enable_dtr(struct cadence_spi_plat *plat,
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
reg = readl(plat->regbase + CQSPI_REG_CONFIG);
|
reg = readl(priv->regbase + CQSPI_REG_CONFIG);
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
reg |= CQSPI_REG_CONFIG_DTR_PROTO;
|
reg |= CQSPI_REG_CONFIG_DTR_PROTO;
|
||||||
reg |= CQSPI_REG_CONFIG_DUAL_OPCODE;
|
reg |= CQSPI_REG_CONFIG_DUAL_OPCODE;
|
||||||
|
|
||||||
/* Set up command opcode extension. */
|
/* Set up command opcode extension. */
|
||||||
ret = cadence_qspi_setup_opcode_ext(plat, op, shift);
|
ret = cadence_qspi_setup_opcode_ext(priv, op, shift);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
|
@ -414,37 +414,37 @@ static int cadence_qspi_enable_dtr(struct cadence_spi_plat *plat,
|
||||||
reg &= ~CQSPI_REG_CONFIG_DUAL_OPCODE;
|
reg &= ~CQSPI_REG_CONFIG_DUAL_OPCODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
writel(reg, plat->regbase + CQSPI_REG_CONFIG);
|
writel(reg, priv->regbase + CQSPI_REG_CONFIG);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cadence_qspi_apb_command_read_setup(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_command_read_setup(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op)
|
const struct spi_mem_op *op)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
|
|
||||||
ret = cadence_qspi_set_protocol(plat, op);
|
ret = cadence_qspi_set_protocol(priv, op);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_STIG_LSB,
|
ret = cadence_qspi_enable_dtr(priv, op, CQSPI_REG_OP_EXT_STIG_LSB,
|
||||||
plat->dtr);
|
priv->dtr);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
reg = cadence_qspi_calc_rdreg(plat);
|
reg = cadence_qspi_calc_rdreg(priv);
|
||||||
writel(reg, plat->regbase + CQSPI_REG_RD_INSTR);
|
writel(reg, priv->regbase + CQSPI_REG_RD_INSTR);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For command RDID, RDSR. */
|
/* For command RDID, RDSR. */
|
||||||
int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_command_read(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op)
|
const struct spi_mem_op *op)
|
||||||
{
|
{
|
||||||
void *reg_base = plat->regbase;
|
void *reg_base = priv->regbase;
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
unsigned int read_len;
|
unsigned int read_len;
|
||||||
int status;
|
int status;
|
||||||
|
@ -458,7 +458,7 @@ int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plat->dtr)
|
if (priv->dtr)
|
||||||
opcode = op->cmd.opcode >> 8;
|
opcode = op->cmd.opcode >> 8;
|
||||||
else
|
else
|
||||||
opcode = op->cmd.opcode;
|
opcode = op->cmd.opcode;
|
||||||
|
@ -466,7 +466,7 @@ int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat,
|
||||||
reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
|
reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
|
||||||
|
|
||||||
/* Set up dummy cycles. */
|
/* Set up dummy cycles. */
|
||||||
dummy_clk = cadence_qspi_calc_dummy(op, plat->dtr);
|
dummy_clk = cadence_qspi_calc_dummy(op, priv->dtr);
|
||||||
if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
|
if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
|
|
||||||
|
@ -499,29 +499,29 @@ int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cadence_qspi_apb_command_write_setup(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_command_write_setup(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op)
|
const struct spi_mem_op *op)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
|
|
||||||
ret = cadence_qspi_set_protocol(plat, op);
|
ret = cadence_qspi_set_protocol(priv, op);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_STIG_LSB,
|
ret = cadence_qspi_enable_dtr(priv, op, CQSPI_REG_OP_EXT_STIG_LSB,
|
||||||
plat->dtr);
|
priv->dtr);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
reg = cadence_qspi_calc_rdreg(plat);
|
reg = cadence_qspi_calc_rdreg(priv);
|
||||||
writel(reg, plat->regbase + CQSPI_REG_RD_INSTR);
|
writel(reg, priv->regbase + CQSPI_REG_RD_INSTR);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For commands: WRSR, WREN, WRDI, CHIP_ERASE, BE, etc. */
|
/* For commands: WRSR, WREN, WRDI, CHIP_ERASE, BE, etc. */
|
||||||
int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_command_write(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op)
|
const struct spi_mem_op *op)
|
||||||
{
|
{
|
||||||
unsigned int reg = 0;
|
unsigned int reg = 0;
|
||||||
|
@ -529,7 +529,7 @@ int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat,
|
||||||
unsigned int wr_len;
|
unsigned int wr_len;
|
||||||
unsigned int txlen = op->data.nbytes;
|
unsigned int txlen = op->data.nbytes;
|
||||||
const void *txbuf = op->data.buf.out;
|
const void *txbuf = op->data.buf.out;
|
||||||
void *reg_base = plat->regbase;
|
void *reg_base = priv->regbase;
|
||||||
u32 addr;
|
u32 addr;
|
||||||
u8 opcode;
|
u8 opcode;
|
||||||
|
|
||||||
|
@ -547,7 +547,7 @@ int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plat->dtr)
|
if (priv->dtr)
|
||||||
opcode = op->cmd.opcode >> 8;
|
opcode = op->cmd.opcode >> 8;
|
||||||
else
|
else
|
||||||
opcode = op->cmd.opcode;
|
opcode = op->cmd.opcode;
|
||||||
|
@ -579,7 +579,7 @@ int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode + Address (3/4 bytes) + dummy bytes (0-4 bytes) */
|
/* Opcode + Address (3/4 bytes) + dummy bytes (0-4 bytes) */
|
||||||
int cadence_qspi_apb_read_setup(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_read_setup(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op)
|
const struct spi_mem_op *op)
|
||||||
{
|
{
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
|
@ -589,33 +589,33 @@ int cadence_qspi_apb_read_setup(struct cadence_spi_plat *plat,
|
||||||
int ret;
|
int ret;
|
||||||
u8 opcode;
|
u8 opcode;
|
||||||
|
|
||||||
ret = cadence_qspi_set_protocol(plat, op);
|
ret = cadence_qspi_set_protocol(priv, op);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_READ_LSB,
|
ret = cadence_qspi_enable_dtr(priv, op, CQSPI_REG_OP_EXT_READ_LSB,
|
||||||
plat->dtr);
|
priv->dtr);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Setup the indirect trigger address */
|
/* Setup the indirect trigger address */
|
||||||
writel(plat->trigger_address,
|
writel(priv->trigger_address,
|
||||||
plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
|
priv->regbase + CQSPI_REG_INDIRECTTRIGGER);
|
||||||
|
|
||||||
/* Configure the opcode */
|
/* Configure the opcode */
|
||||||
if (plat->dtr)
|
if (priv->dtr)
|
||||||
opcode = op->cmd.opcode >> 8;
|
opcode = op->cmd.opcode >> 8;
|
||||||
else
|
else
|
||||||
opcode = op->cmd.opcode;
|
opcode = op->cmd.opcode;
|
||||||
|
|
||||||
rd_reg = opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
|
rd_reg = opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
|
||||||
rd_reg |= cadence_qspi_calc_rdreg(plat);
|
rd_reg |= cadence_qspi_calc_rdreg(priv);
|
||||||
|
|
||||||
writel(op->addr.val, plat->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);
|
writel(op->addr.val, priv->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);
|
||||||
|
|
||||||
if (dummy_bytes) {
|
if (dummy_bytes) {
|
||||||
/* Convert to clock cycles. */
|
/* Convert to clock cycles. */
|
||||||
dummy_clk = cadence_qspi_calc_dummy(op, plat->dtr);
|
dummy_clk = cadence_qspi_calc_dummy(op, priv->dtr);
|
||||||
|
|
||||||
if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
|
if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
|
@ -625,30 +625,30 @@ int cadence_qspi_apb_read_setup(struct cadence_spi_plat *plat,
|
||||||
<< CQSPI_REG_RD_INSTR_DUMMY_LSB;
|
<< CQSPI_REG_RD_INSTR_DUMMY_LSB;
|
||||||
}
|
}
|
||||||
|
|
||||||
writel(rd_reg, plat->regbase + CQSPI_REG_RD_INSTR);
|
writel(rd_reg, priv->regbase + CQSPI_REG_RD_INSTR);
|
||||||
|
|
||||||
/* set device size */
|
/* set device size */
|
||||||
reg = readl(plat->regbase + CQSPI_REG_SIZE);
|
reg = readl(priv->regbase + CQSPI_REG_SIZE);
|
||||||
reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
|
reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
|
||||||
reg |= (op->addr.nbytes - 1);
|
reg |= (op->addr.nbytes - 1);
|
||||||
writel(reg, plat->regbase + CQSPI_REG_SIZE);
|
writel(reg, priv->regbase + CQSPI_REG_SIZE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 cadence_qspi_get_rd_sram_level(struct cadence_spi_plat *plat)
|
static u32 cadence_qspi_get_rd_sram_level(struct cadence_spi_priv *priv)
|
||||||
{
|
{
|
||||||
u32 reg = readl(plat->regbase + CQSPI_REG_SDRAMLEVEL);
|
u32 reg = readl(priv->regbase + CQSPI_REG_SDRAMLEVEL);
|
||||||
reg >>= CQSPI_REG_SDRAMLEVEL_RD_LSB;
|
reg >>= CQSPI_REG_SDRAMLEVEL_RD_LSB;
|
||||||
return reg & CQSPI_REG_SDRAMLEVEL_RD_MASK;
|
return reg & CQSPI_REG_SDRAMLEVEL_RD_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cadence_qspi_wait_for_data(struct cadence_spi_plat *plat)
|
static int cadence_qspi_wait_for_data(struct cadence_spi_priv *priv)
|
||||||
{
|
{
|
||||||
unsigned int timeout = 10000;
|
unsigned int timeout = 10000;
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
while (timeout--) {
|
while (timeout--) {
|
||||||
reg = cadence_qspi_get_rd_sram_level(plat);
|
reg = cadence_qspi_get_rd_sram_level(priv);
|
||||||
if (reg)
|
if (reg)
|
||||||
return reg;
|
return reg;
|
||||||
udelay(1);
|
udelay(1);
|
||||||
|
@ -658,21 +658,21 @@ static int cadence_qspi_wait_for_data(struct cadence_spi_plat *plat)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cadence_qspi_apb_indirect_read_execute(struct cadence_spi_plat *plat,
|
cadence_qspi_apb_indirect_read_execute(struct cadence_spi_priv *priv,
|
||||||
unsigned int n_rx, u8 *rxbuf)
|
unsigned int n_rx, u8 *rxbuf)
|
||||||
{
|
{
|
||||||
unsigned int remaining = n_rx;
|
unsigned int remaining = n_rx;
|
||||||
unsigned int bytes_to_read = 0;
|
unsigned int bytes_to_read = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
writel(n_rx, plat->regbase + CQSPI_REG_INDIRECTRDBYTES);
|
writel(n_rx, priv->regbase + CQSPI_REG_INDIRECTRDBYTES);
|
||||||
|
|
||||||
/* Start the indirect read transfer */
|
/* Start the indirect read transfer */
|
||||||
writel(CQSPI_REG_INDIRECTRD_START,
|
writel(CQSPI_REG_INDIRECTRD_START,
|
||||||
plat->regbase + CQSPI_REG_INDIRECTRD);
|
priv->regbase + CQSPI_REG_INDIRECTRD);
|
||||||
|
|
||||||
while (remaining > 0) {
|
while (remaining > 0) {
|
||||||
ret = cadence_qspi_wait_for_data(plat);
|
ret = cadence_qspi_wait_for_data(priv);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printf("Indirect write timed out (%i)\n", ret);
|
printf("Indirect write timed out (%i)\n", ret);
|
||||||
goto failrd;
|
goto failrd;
|
||||||
|
@ -681,7 +681,7 @@ cadence_qspi_apb_indirect_read_execute(struct cadence_spi_plat *plat,
|
||||||
bytes_to_read = ret;
|
bytes_to_read = ret;
|
||||||
|
|
||||||
while (bytes_to_read != 0) {
|
while (bytes_to_read != 0) {
|
||||||
bytes_to_read *= plat->fifo_width;
|
bytes_to_read *= priv->fifo_width;
|
||||||
bytes_to_read = bytes_to_read > remaining ?
|
bytes_to_read = bytes_to_read > remaining ?
|
||||||
remaining : bytes_to_read;
|
remaining : bytes_to_read;
|
||||||
/*
|
/*
|
||||||
|
@ -689,18 +689,18 @@ cadence_qspi_apb_indirect_read_execute(struct cadence_spi_plat *plat,
|
||||||
* data abort.
|
* data abort.
|
||||||
*/
|
*/
|
||||||
if (((uintptr_t)rxbuf % 4) || (bytes_to_read % 4))
|
if (((uintptr_t)rxbuf % 4) || (bytes_to_read % 4))
|
||||||
readsb(plat->ahbbase, rxbuf, bytes_to_read);
|
readsb(priv->ahbbase, rxbuf, bytes_to_read);
|
||||||
else
|
else
|
||||||
readsl(plat->ahbbase, rxbuf,
|
readsl(priv->ahbbase, rxbuf,
|
||||||
bytes_to_read >> 2);
|
bytes_to_read >> 2);
|
||||||
rxbuf += bytes_to_read;
|
rxbuf += bytes_to_read;
|
||||||
remaining -= bytes_to_read;
|
remaining -= bytes_to_read;
|
||||||
bytes_to_read = cadence_qspi_get_rd_sram_level(plat);
|
bytes_to_read = cadence_qspi_get_rd_sram_level(priv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check indirect done status */
|
/* Check indirect done status */
|
||||||
ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTRD,
|
ret = wait_for_bit_le32(priv->regbase + CQSPI_REG_INDIRECTRD,
|
||||||
CQSPI_REG_INDIRECTRD_DONE, 1, 10, 0);
|
CQSPI_REG_INDIRECTRD_DONE, 1, 10, 0);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("Indirect read completion error (%i)\n", ret);
|
printf("Indirect read completion error (%i)\n", ret);
|
||||||
|
@ -709,10 +709,10 @@ cadence_qspi_apb_indirect_read_execute(struct cadence_spi_plat *plat,
|
||||||
|
|
||||||
/* Clear indirect completion status */
|
/* Clear indirect completion status */
|
||||||
writel(CQSPI_REG_INDIRECTRD_DONE,
|
writel(CQSPI_REG_INDIRECTRD_DONE,
|
||||||
plat->regbase + CQSPI_REG_INDIRECTRD);
|
priv->regbase + CQSPI_REG_INDIRECTRD);
|
||||||
|
|
||||||
/* Check indirect done status */
|
/* Check indirect done status */
|
||||||
ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTRD,
|
ret = wait_for_bit_le32(priv->regbase + CQSPI_REG_INDIRECTRD,
|
||||||
CQSPI_REG_INDIRECTRD_DONE, 0, 10, 0);
|
CQSPI_REG_INDIRECTRD_DONE, 0, 10, 0);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("Indirect read clear completion error (%i)\n", ret);
|
printf("Indirect read clear completion error (%i)\n", ret);
|
||||||
|
@ -724,11 +724,11 @@ cadence_qspi_apb_indirect_read_execute(struct cadence_spi_plat *plat,
|
||||||
failrd:
|
failrd:
|
||||||
/* Cancel the indirect read */
|
/* Cancel the indirect read */
|
||||||
writel(CQSPI_REG_INDIRECTRD_CANCEL,
|
writel(CQSPI_REG_INDIRECTRD_CANCEL,
|
||||||
plat->regbase + CQSPI_REG_INDIRECTRD);
|
priv->regbase + CQSPI_REG_INDIRECTRD);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cadence_qspi_apb_read_execute(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_read_execute(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op)
|
const struct spi_mem_op *op)
|
||||||
{
|
{
|
||||||
u64 from = op->addr.val;
|
u64 from = op->addr.val;
|
||||||
|
@ -738,57 +738,57 @@ int cadence_qspi_apb_read_execute(struct cadence_spi_plat *plat,
|
||||||
if (CONFIG_IS_ENABLED(ARCH_VERSAL))
|
if (CONFIG_IS_ENABLED(ARCH_VERSAL))
|
||||||
cadence_qspi_apb_enable_linear_mode(true);
|
cadence_qspi_apb_enable_linear_mode(true);
|
||||||
|
|
||||||
if (plat->use_dac_mode && (from + len < plat->ahbsize)) {
|
if (priv->use_dac_mode && (from + len < priv->ahbsize)) {
|
||||||
if (len < 256 ||
|
if (len < 256 ||
|
||||||
dma_memcpy(buf, plat->ahbbase + from, len) < 0) {
|
dma_memcpy(buf, priv->ahbbase + from, len) < 0) {
|
||||||
memcpy_fromio(buf, plat->ahbbase + from, len);
|
memcpy_fromio(buf, priv->ahbbase + from, len);
|
||||||
}
|
}
|
||||||
if (!cadence_qspi_wait_idle(plat->regbase))
|
if (!cadence_qspi_wait_idle(priv->regbase))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cadence_qspi_apb_indirect_read_execute(plat, len, buf);
|
return cadence_qspi_apb_indirect_read_execute(priv, len, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode + Address (3/4 bytes) */
|
/* Opcode + Address (3/4 bytes) */
|
||||||
int cadence_qspi_apb_write_setup(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_write_setup(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op)
|
const struct spi_mem_op *op)
|
||||||
{
|
{
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
int ret;
|
int ret;
|
||||||
u8 opcode;
|
u8 opcode;
|
||||||
|
|
||||||
ret = cadence_qspi_set_protocol(plat, op);
|
ret = cadence_qspi_set_protocol(priv, op);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_WRITE_LSB,
|
ret = cadence_qspi_enable_dtr(priv, op, CQSPI_REG_OP_EXT_WRITE_LSB,
|
||||||
plat->dtr);
|
priv->dtr);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Setup the indirect trigger address */
|
/* Setup the indirect trigger address */
|
||||||
writel(plat->trigger_address,
|
writel(priv->trigger_address,
|
||||||
plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
|
priv->regbase + CQSPI_REG_INDIRECTTRIGGER);
|
||||||
|
|
||||||
/* Configure the opcode */
|
/* Configure the opcode */
|
||||||
if (plat->dtr)
|
if (priv->dtr)
|
||||||
opcode = op->cmd.opcode >> 8;
|
opcode = op->cmd.opcode >> 8;
|
||||||
else
|
else
|
||||||
opcode = op->cmd.opcode;
|
opcode = op->cmd.opcode;
|
||||||
|
|
||||||
reg = opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
|
reg = opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
|
||||||
reg |= plat->data_width << CQSPI_REG_WR_INSTR_TYPE_DATA_LSB;
|
reg |= priv->data_width << CQSPI_REG_WR_INSTR_TYPE_DATA_LSB;
|
||||||
reg |= plat->addr_width << CQSPI_REG_WR_INSTR_TYPE_ADDR_LSB;
|
reg |= priv->addr_width << CQSPI_REG_WR_INSTR_TYPE_ADDR_LSB;
|
||||||
writel(reg, plat->regbase + CQSPI_REG_WR_INSTR);
|
writel(reg, priv->regbase + CQSPI_REG_WR_INSTR);
|
||||||
|
|
||||||
reg = cadence_qspi_calc_rdreg(plat);
|
reg = cadence_qspi_calc_rdreg(priv);
|
||||||
writel(reg, plat->regbase + CQSPI_REG_RD_INSTR);
|
writel(reg, priv->regbase + CQSPI_REG_RD_INSTR);
|
||||||
|
|
||||||
writel(op->addr.val, plat->regbase + CQSPI_REG_INDIRECTWRSTARTADDR);
|
writel(op->addr.val, priv->regbase + CQSPI_REG_INDIRECTWRSTARTADDR);
|
||||||
|
|
||||||
if (plat->dtr) {
|
if (priv->dtr) {
|
||||||
/*
|
/*
|
||||||
* Some flashes like the cypress Semper flash expect a 4-byte
|
* Some flashes like the cypress Semper flash expect a 4-byte
|
||||||
* dummy address with the Read SR command in DTR mode, but this
|
* dummy address with the Read SR command in DTR mode, but this
|
||||||
|
@ -797,23 +797,23 @@ int cadence_qspi_apb_write_setup(struct cadence_spi_plat *plat,
|
||||||
* controller's side. spi-nor will take care of polling the
|
* controller's side. spi-nor will take care of polling the
|
||||||
* status register.
|
* status register.
|
||||||
*/
|
*/
|
||||||
reg = readl(plat->regbase + CQSPI_REG_WR_COMPLETION_CTRL);
|
reg = readl(priv->regbase + CQSPI_REG_WR_COMPLETION_CTRL);
|
||||||
reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL;
|
reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL;
|
||||||
writel(reg, plat->regbase + CQSPI_REG_WR_COMPLETION_CTRL);
|
writel(reg, priv->regbase + CQSPI_REG_WR_COMPLETION_CTRL);
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = readl(plat->regbase + CQSPI_REG_SIZE);
|
reg = readl(priv->regbase + CQSPI_REG_SIZE);
|
||||||
reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
|
reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
|
||||||
reg |= (op->addr.nbytes - 1);
|
reg |= (op->addr.nbytes - 1);
|
||||||
writel(reg, plat->regbase + CQSPI_REG_SIZE);
|
writel(reg, priv->regbase + CQSPI_REG_SIZE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat,
|
cadence_qspi_apb_indirect_write_execute(struct cadence_spi_priv *priv,
|
||||||
unsigned int n_tx, const u8 *txbuf)
|
unsigned int n_tx, const u8 *txbuf)
|
||||||
{
|
{
|
||||||
unsigned int page_size = plat->page_size;
|
unsigned int page_size = priv->page_size;
|
||||||
unsigned int remaining = n_tx;
|
unsigned int remaining = n_tx;
|
||||||
const u8 *bb_txbuf = txbuf;
|
const u8 *bb_txbuf = txbuf;
|
||||||
void *bounce_buf = NULL;
|
void *bounce_buf = NULL;
|
||||||
|
@ -833,27 +833,27 @@ cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configure the indirect read transfer bytes */
|
/* Configure the indirect read transfer bytes */
|
||||||
writel(n_tx, plat->regbase + CQSPI_REG_INDIRECTWRBYTES);
|
writel(n_tx, priv->regbase + CQSPI_REG_INDIRECTWRBYTES);
|
||||||
|
|
||||||
/* Start the indirect write transfer */
|
/* Start the indirect write transfer */
|
||||||
writel(CQSPI_REG_INDIRECTWR_START,
|
writel(CQSPI_REG_INDIRECTWR_START,
|
||||||
plat->regbase + CQSPI_REG_INDIRECTWR);
|
priv->regbase + CQSPI_REG_INDIRECTWR);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some delay is required for the above bit to be internally
|
* Some delay is required for the above bit to be internally
|
||||||
* synchronized by the QSPI module.
|
* synchronized by the QSPI module.
|
||||||
*/
|
*/
|
||||||
ndelay(plat->wr_delay);
|
ndelay(priv->wr_delay);
|
||||||
|
|
||||||
while (remaining > 0) {
|
while (remaining > 0) {
|
||||||
write_bytes = remaining > page_size ? page_size : remaining;
|
write_bytes = remaining > page_size ? page_size : remaining;
|
||||||
writesl(plat->ahbbase, bb_txbuf, write_bytes >> 2);
|
writesl(priv->ahbbase, bb_txbuf, write_bytes >> 2);
|
||||||
if (write_bytes % 4)
|
if (write_bytes % 4)
|
||||||
writesb(plat->ahbbase,
|
writesb(priv->ahbbase,
|
||||||
bb_txbuf + rounddown(write_bytes, 4),
|
bb_txbuf + rounddown(write_bytes, 4),
|
||||||
write_bytes % 4);
|
write_bytes % 4);
|
||||||
|
|
||||||
ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_SDRAMLEVEL,
|
ret = wait_for_bit_le32(priv->regbase + CQSPI_REG_SDRAMLEVEL,
|
||||||
CQSPI_REG_SDRAMLEVEL_WR_MASK <<
|
CQSPI_REG_SDRAMLEVEL_WR_MASK <<
|
||||||
CQSPI_REG_SDRAMLEVEL_WR_LSB, 0, 10, 0);
|
CQSPI_REG_SDRAMLEVEL_WR_LSB, 0, 10, 0);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -866,7 +866,7 @@ cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check indirect done status */
|
/* Check indirect done status */
|
||||||
ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTWR,
|
ret = wait_for_bit_le32(priv->regbase + CQSPI_REG_INDIRECTWR,
|
||||||
CQSPI_REG_INDIRECTWR_DONE, 1, 10, 0);
|
CQSPI_REG_INDIRECTWR_DONE, 1, 10, 0);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("Indirect write completion error (%i)\n", ret);
|
printf("Indirect write completion error (%i)\n", ret);
|
||||||
|
@ -875,10 +875,10 @@ cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat,
|
||||||
|
|
||||||
/* Clear indirect completion status */
|
/* Clear indirect completion status */
|
||||||
writel(CQSPI_REG_INDIRECTWR_DONE,
|
writel(CQSPI_REG_INDIRECTWR_DONE,
|
||||||
plat->regbase + CQSPI_REG_INDIRECTWR);
|
priv->regbase + CQSPI_REG_INDIRECTWR);
|
||||||
|
|
||||||
/* Check indirect done status */
|
/* Check indirect done status */
|
||||||
ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTWR,
|
ret = wait_for_bit_le32(priv->regbase + CQSPI_REG_INDIRECTWR,
|
||||||
CQSPI_REG_INDIRECTWR_DONE, 0, 10, 0);
|
CQSPI_REG_INDIRECTWR_DONE, 0, 10, 0);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("Indirect write clear completion error (%i)\n", ret);
|
printf("Indirect write clear completion error (%i)\n", ret);
|
||||||
|
@ -892,13 +892,13 @@ cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat,
|
||||||
failwr:
|
failwr:
|
||||||
/* Cancel the indirect write */
|
/* Cancel the indirect write */
|
||||||
writel(CQSPI_REG_INDIRECTWR_CANCEL,
|
writel(CQSPI_REG_INDIRECTWR_CANCEL,
|
||||||
plat->regbase + CQSPI_REG_INDIRECTWR);
|
priv->regbase + CQSPI_REG_INDIRECTWR);
|
||||||
if (bounce_buf)
|
if (bounce_buf)
|
||||||
free(bounce_buf);
|
free(bounce_buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cadence_qspi_apb_write_execute(struct cadence_spi_plat *plat,
|
int cadence_qspi_apb_write_execute(struct cadence_spi_priv *priv,
|
||||||
const struct spi_mem_op *op)
|
const struct spi_mem_op *op)
|
||||||
{
|
{
|
||||||
u32 to = op->addr.val;
|
u32 to = op->addr.val;
|
||||||
|
@ -916,14 +916,15 @@ int cadence_qspi_apb_write_execute(struct cadence_spi_plat *plat,
|
||||||
* mode. So, we can not use direct mode when in DTR mode for writing
|
* mode. So, we can not use direct mode when in DTR mode for writing
|
||||||
* data.
|
* data.
|
||||||
*/
|
*/
|
||||||
if (!plat->dtr && plat->use_dac_mode && (to + len < plat->ahbsize)) {
|
cadence_qspi_apb_enable_linear_mode(true);
|
||||||
memcpy_toio(plat->ahbbase + to, buf, len);
|
if (!priv->dtr && priv->use_dac_mode && (to + len < priv->ahbsize)) {
|
||||||
if (!cadence_qspi_wait_idle(plat->regbase))
|
memcpy_toio(priv->ahbbase + to, buf, len);
|
||||||
|
if (!cadence_qspi_wait_idle(priv->regbase))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cadence_qspi_apb_indirect_write_execute(plat, len, buf);
|
return cadence_qspi_apb_indirect_write_execute(priv, len, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cadence_qspi_apb_enter_xip(void *reg_base, char xip_dummy)
|
void cadence_qspi_apb_enter_xip(void *reg_base, char xip_dummy)
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include <dm/device_compat.h>
|
#include <dm/device_compat.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
|
#include <linux/sizes.h>
|
||||||
|
#include <zynqmp_firmware.h>
|
||||||
|
|
||||||
#define GQSPI_GFIFO_STRT_MODE_MASK BIT(29)
|
#define GQSPI_GFIFO_STRT_MODE_MASK BIT(29)
|
||||||
#define GQSPI_CONFIG_MODE_EN_MASK (3 << 30)
|
#define GQSPI_CONFIG_MODE_EN_MASK (3 << 30)
|
||||||
|
@ -102,8 +104,10 @@
|
||||||
#define TAP_DLY_BYPASS_LQSPI_RX_VALUE 0x1
|
#define TAP_DLY_BYPASS_LQSPI_RX_VALUE 0x1
|
||||||
#define TAP_DLY_BYPASS_LQSPI_RX_SHIFT 2
|
#define TAP_DLY_BYPASS_LQSPI_RX_SHIFT 2
|
||||||
#define GQSPI_DATA_DLY_ADJ_OFST 0x000001F8
|
#define GQSPI_DATA_DLY_ADJ_OFST 0x000001F8
|
||||||
#define IOU_TAPDLY_BYPASS_OFST 0xFF180390
|
#define IOU_TAPDLY_BYPASS_OFST !IS_ENABLED(CONFIG_ARCH_VERSAL) ? \
|
||||||
|
0xFF180390 : 0xF103003C
|
||||||
#define GQSPI_LPBK_DLY_ADJ_LPBK_MASK 0x00000020
|
#define GQSPI_LPBK_DLY_ADJ_LPBK_MASK 0x00000020
|
||||||
|
#define GQSPI_FREQ_37_5MHZ 37500000
|
||||||
#define GQSPI_FREQ_40MHZ 40000000
|
#define GQSPI_FREQ_40MHZ 40000000
|
||||||
#define GQSPI_FREQ_100MHZ 100000000
|
#define GQSPI_FREQ_100MHZ 100000000
|
||||||
#define GQSPI_FREQ_150MHZ 150000000
|
#define GQSPI_FREQ_150MHZ 150000000
|
||||||
|
@ -163,6 +167,7 @@ struct zynqmp_qspi_plat {
|
||||||
struct zynqmp_qspi_dma_regs *dma_regs;
|
struct zynqmp_qspi_dma_regs *dma_regs;
|
||||||
u32 frequency;
|
u32 frequency;
|
||||||
u32 speed_hz;
|
u32 speed_hz;
|
||||||
|
unsigned int io_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zynqmp_qspi_priv {
|
struct zynqmp_qspi_priv {
|
||||||
|
@ -171,6 +176,7 @@ struct zynqmp_qspi_priv {
|
||||||
const void *tx_buf;
|
const void *tx_buf;
|
||||||
void *rx_buf;
|
void *rx_buf;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
unsigned int io_mode;
|
||||||
int bytes_to_transfer;
|
int bytes_to_transfer;
|
||||||
int bytes_to_receive;
|
int bytes_to_receive;
|
||||||
const struct spi_mem_op *op;
|
const struct spi_mem_op *op;
|
||||||
|
@ -187,6 +193,8 @@ static int zynqmp_qspi_of_to_plat(struct udevice *bus)
|
||||||
plat->dma_regs = (struct zynqmp_qspi_dma_regs *)
|
plat->dma_regs = (struct zynqmp_qspi_dma_regs *)
|
||||||
(dev_read_addr(bus) + GQSPI_DMA_REG_OFFSET);
|
(dev_read_addr(bus) + GQSPI_DMA_REG_OFFSET);
|
||||||
|
|
||||||
|
plat->io_mode = dev_read_bool(bus, "has-io-mode");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,8 +214,11 @@ static void zynqmp_qspi_init_hw(struct zynqmp_qspi_priv *priv)
|
||||||
config_reg = readl(®s->confr);
|
config_reg = readl(®s->confr);
|
||||||
config_reg &= ~(GQSPI_GFIFO_STRT_MODE_MASK |
|
config_reg &= ~(GQSPI_GFIFO_STRT_MODE_MASK |
|
||||||
GQSPI_CONFIG_MODE_EN_MASK);
|
GQSPI_CONFIG_MODE_EN_MASK);
|
||||||
config_reg |= GQSPI_CONFIG_DMA_MODE | GQSPI_GFIFO_WP_HOLD |
|
config_reg |= GQSPI_GFIFO_WP_HOLD | GQSPI_DFLT_BAUD_RATE_DIV;
|
||||||
GQSPI_DFLT_BAUD_RATE_DIV | GQSPI_GFIFO_STRT_MODE_MASK;
|
config_reg |= GQSPI_GFIFO_STRT_MODE_MASK;
|
||||||
|
if (!priv->io_mode)
|
||||||
|
config_reg |= GQSPI_CONFIG_DMA_MODE;
|
||||||
|
|
||||||
writel(config_reg, ®s->confr);
|
writel(config_reg, ®s->confr);
|
||||||
|
|
||||||
writel(GQSPI_ENABLE_ENABLE_MASK, ®s->enbr);
|
writel(GQSPI_ENABLE_ENABLE_MASK, ®s->enbr);
|
||||||
|
@ -297,28 +308,41 @@ void zynqmp_qspi_set_tapdelay(struct udevice *bus, u32 baudrateval)
|
||||||
debug("%s, req_hz:%d, clk_rate:%d, baudrateval:%d\n",
|
debug("%s, req_hz:%d, clk_rate:%d, baudrateval:%d\n",
|
||||||
__func__, reqhz, clk_rate, baudrateval);
|
__func__, reqhz, clk_rate, baudrateval);
|
||||||
|
|
||||||
if (reqhz < GQSPI_FREQ_40MHZ) {
|
if (!IS_ENABLED(CONFIG_ARCH_VERSAL)) {
|
||||||
zynqmp_mmio_read(IOU_TAPDLY_BYPASS_OFST, &tapdlybypass);
|
if (reqhz <= GQSPI_FREQ_40MHZ) {
|
||||||
tapdlybypass |= (TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
|
tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
|
||||||
TAP_DLY_BYPASS_LQSPI_RX_SHIFT);
|
TAP_DLY_BYPASS_LQSPI_RX_SHIFT;
|
||||||
} else if (reqhz <= GQSPI_FREQ_100MHZ) {
|
} else if (reqhz <= GQSPI_FREQ_100MHZ) {
|
||||||
zynqmp_mmio_read(IOU_TAPDLY_BYPASS_OFST, &tapdlybypass);
|
tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
|
||||||
tapdlybypass |= (TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
|
TAP_DLY_BYPASS_LQSPI_RX_SHIFT;
|
||||||
TAP_DLY_BYPASS_LQSPI_RX_SHIFT);
|
lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK;
|
||||||
lpbkdlyadj = readl(®s->lpbkdly);
|
datadlyadj = (GQSPI_USE_DATA_DLY <<
|
||||||
lpbkdlyadj |= (GQSPI_LPBK_DLY_ADJ_LPBK_MASK);
|
GQSPI_USE_DATA_DLY_SHIFT) |
|
||||||
datadlyadj = readl(®s->gqspidlyadj);
|
(GQSPI_DATA_DLY_ADJ_VALUE <<
|
||||||
datadlyadj |= ((GQSPI_USE_DATA_DLY << GQSPI_USE_DATA_DLY_SHIFT)
|
GQSPI_DATA_DLY_ADJ_SHIFT);
|
||||||
| (GQSPI_DATA_DLY_ADJ_VALUE <<
|
} else if (reqhz <= GQSPI_FREQ_150MHZ) {
|
||||||
GQSPI_DATA_DLY_ADJ_SHIFT));
|
lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK |
|
||||||
} else if (reqhz <= GQSPI_FREQ_150MHZ) {
|
GQSPI_LPBK_DLY_ADJ_DLY_0;
|
||||||
lpbkdlyadj = readl(®s->lpbkdly);
|
}
|
||||||
lpbkdlyadj |= ((GQSPI_LPBK_DLY_ADJ_LPBK_MASK) |
|
zynqmp_mmio_write(IOU_TAPDLY_BYPASS_OFST,
|
||||||
GQSPI_LPBK_DLY_ADJ_DLY_0);
|
IOU_TAPDLY_BYPASS_MASK, tapdlybypass);
|
||||||
|
} else {
|
||||||
|
if (reqhz <= GQSPI_FREQ_37_5MHZ) {
|
||||||
|
tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
|
||||||
|
TAP_DLY_BYPASS_LQSPI_RX_SHIFT;
|
||||||
|
} else if (reqhz <= GQSPI_FREQ_100MHZ) {
|
||||||
|
tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE <<
|
||||||
|
TAP_DLY_BYPASS_LQSPI_RX_SHIFT;
|
||||||
|
lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK;
|
||||||
|
datadlyadj = GQSPI_USE_DATA_DLY <<
|
||||||
|
GQSPI_USE_DATA_DLY_SHIFT;
|
||||||
|
} else if (reqhz <= GQSPI_FREQ_150MHZ) {
|
||||||
|
lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK |
|
||||||
|
(GQSPI_LPBK_DLY_ADJ_DLY_1 <<
|
||||||
|
GQSPI_LPBK_DLY_ADJ_DLY_1_SHIFT);
|
||||||
|
}
|
||||||
|
writel(tapdlybypass, IOU_TAPDLY_BYPASS_OFST);
|
||||||
}
|
}
|
||||||
|
|
||||||
zynqmp_mmio_write(IOU_TAPDLY_BYPASS_OFST, IOU_TAPDLY_BYPASS_MASK,
|
|
||||||
tapdlybypass);
|
|
||||||
writel(lpbkdlyadj, ®s->lpbkdly);
|
writel(lpbkdlyadj, ®s->lpbkdly);
|
||||||
writel(datadlyadj, ®s->gqspidlyadj);
|
writel(datadlyadj, ®s->gqspidlyadj);
|
||||||
}
|
}
|
||||||
|
@ -372,6 +396,7 @@ static int zynqmp_qspi_probe(struct udevice *bus)
|
||||||
|
|
||||||
priv->regs = plat->regs;
|
priv->regs = plat->regs;
|
||||||
priv->dma_regs = plat->dma_regs;
|
priv->dma_regs = plat->dma_regs;
|
||||||
|
priv->io_mode = plat->io_mode;
|
||||||
|
|
||||||
ret = clk_get_by_index(bus, 0, &clk);
|
ret = clk_get_by_index(bus, 0, &clk);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -409,8 +434,7 @@ static int zynqmp_qspi_set_mode(struct udevice *bus, uint mode)
|
||||||
debug("%s\n", __func__);
|
debug("%s\n", __func__);
|
||||||
/* Set the SPI Clock phase and polarities */
|
/* Set the SPI Clock phase and polarities */
|
||||||
confr = readl(®s->confr);
|
confr = readl(®s->confr);
|
||||||
confr &= ~(GQSPI_CONFIG_CPHA_MASK |
|
confr &= ~(GQSPI_CONFIG_CPHA_MASK | GQSPI_CONFIG_CPOL_MASK);
|
||||||
GQSPI_CONFIG_CPOL_MASK);
|
|
||||||
|
|
||||||
if (mode & SPI_CPHA)
|
if (mode & SPI_CPHA)
|
||||||
confr |= GQSPI_CONFIG_CPHA_MASK;
|
confr |= GQSPI_CONFIG_CPHA_MASK;
|
||||||
|
@ -554,8 +578,7 @@ static int zynqmp_qspi_genfifo_fill_tx(struct zynqmp_qspi_priv *priv)
|
||||||
|
|
||||||
gen_fifo_cmd = zynqmp_qspi_bus_select(priv);
|
gen_fifo_cmd = zynqmp_qspi_bus_select(priv);
|
||||||
gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(priv->op->data.buswidth);
|
gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(priv->op->data.buswidth);
|
||||||
gen_fifo_cmd |= GQSPI_GFIFO_TX |
|
gen_fifo_cmd |= GQSPI_GFIFO_TX | GQSPI_GFIFO_DATA_XFR_MASK;
|
||||||
GQSPI_GFIFO_DATA_XFR_MASK;
|
|
||||||
|
|
||||||
while (priv->len) {
|
while (priv->len) {
|
||||||
len = zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd);
|
len = zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd);
|
||||||
|
@ -564,11 +587,9 @@ static int zynqmp_qspi_genfifo_fill_tx(struct zynqmp_qspi_priv *priv)
|
||||||
debug("GFIFO_CMD_TX:0x%x\n", gen_fifo_cmd);
|
debug("GFIFO_CMD_TX:0x%x\n", gen_fifo_cmd);
|
||||||
|
|
||||||
if (gen_fifo_cmd & GQSPI_GFIFO_EXP_MASK)
|
if (gen_fifo_cmd & GQSPI_GFIFO_EXP_MASK)
|
||||||
ret = zynqmp_qspi_fill_tx_fifo(priv,
|
ret = zynqmp_qspi_fill_tx_fifo(priv, 1 << len);
|
||||||
1 << len);
|
|
||||||
else
|
else
|
||||||
ret = zynqmp_qspi_fill_tx_fifo(priv,
|
ret = zynqmp_qspi_fill_tx_fifo(priv, len);
|
||||||
len);
|
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -576,45 +597,120 @@ static int zynqmp_qspi_genfifo_fill_tx(struct zynqmp_qspi_priv *priv)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int zynqmp_qspi_start_io(struct zynqmp_qspi_priv *priv,
|
||||||
|
u32 gen_fifo_cmd, u32 *buf)
|
||||||
|
{
|
||||||
|
u32 len;
|
||||||
|
u32 actuallen = priv->len;
|
||||||
|
u32 config_reg, ier, isr;
|
||||||
|
u32 timeout = GQSPI_TIMEOUT;
|
||||||
|
struct zynqmp_qspi_regs *regs = priv->regs;
|
||||||
|
u32 last_bits;
|
||||||
|
u32 *traverse = buf;
|
||||||
|
|
||||||
|
while (priv->len) {
|
||||||
|
len = zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd);
|
||||||
|
/* If exponent bit is set, reset immediate to be 2^len */
|
||||||
|
if (gen_fifo_cmd & GQSPI_GFIFO_EXP_MASK)
|
||||||
|
priv->bytes_to_receive = (1 << len);
|
||||||
|
else
|
||||||
|
priv->bytes_to_receive = len;
|
||||||
|
zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd);
|
||||||
|
debug("GFIFO_CMD_RX:0x%x\n", gen_fifo_cmd);
|
||||||
|
/* Manual start */
|
||||||
|
config_reg = readl(®s->confr);
|
||||||
|
config_reg |= GQSPI_STRT_GEN_FIFO;
|
||||||
|
writel(config_reg, ®s->confr);
|
||||||
|
/* Enable RX interrupts for IO mode */
|
||||||
|
ier = readl(®s->ier);
|
||||||
|
ier |= GQSPI_IXR_ALL_MASK;
|
||||||
|
writel(ier, ®s->ier);
|
||||||
|
while (priv->bytes_to_receive && timeout) {
|
||||||
|
isr = readl(®s->isr);
|
||||||
|
if (isr & GQSPI_IXR_RXNEMTY_MASK) {
|
||||||
|
if (priv->bytes_to_receive >= 4) {
|
||||||
|
*traverse = readl(®s->drxr);
|
||||||
|
traverse++;
|
||||||
|
priv->bytes_to_receive -= 4;
|
||||||
|
} else {
|
||||||
|
last_bits = readl(®s->drxr);
|
||||||
|
memcpy(traverse, &last_bits,
|
||||||
|
priv->bytes_to_receive);
|
||||||
|
priv->bytes_to_receive = 0;
|
||||||
|
}
|
||||||
|
timeout = GQSPI_TIMEOUT;
|
||||||
|
} else {
|
||||||
|
udelay(1);
|
||||||
|
timeout--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("buf:0x%lx, rxbuf:0x%lx, *buf:0x%x len: 0x%x\n",
|
||||||
|
(unsigned long)buf, (unsigned long)priv->rx_buf,
|
||||||
|
*buf, actuallen);
|
||||||
|
if (!timeout) {
|
||||||
|
printf("IO timeout: %d\n", readl(®s->isr));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int zynqmp_qspi_start_dma(struct zynqmp_qspi_priv *priv,
|
static int zynqmp_qspi_start_dma(struct zynqmp_qspi_priv *priv,
|
||||||
u32 gen_fifo_cmd, u32 *buf)
|
u32 gen_fifo_cmd, u32 *buf)
|
||||||
{
|
{
|
||||||
u32 addr;
|
u32 addr;
|
||||||
u32 size;
|
u32 size;
|
||||||
u32 actuallen = priv->len;
|
u32 actuallen = priv->len;
|
||||||
|
u32 totallen = priv->len;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct zynqmp_qspi_dma_regs *dma_regs = priv->dma_regs;
|
struct zynqmp_qspi_dma_regs *dma_regs = priv->dma_regs;
|
||||||
|
|
||||||
writel((unsigned long)buf, &dma_regs->dmadst);
|
while (totallen) {
|
||||||
writel(roundup(priv->len, GQSPI_DMA_ALIGN), &dma_regs->dmasize);
|
if (totallen >= SZ_512M)
|
||||||
writel(GQSPI_DMA_DST_I_STS_MASK, &dma_regs->dmaier);
|
priv->len = SZ_256M;
|
||||||
addr = (unsigned long)buf;
|
else
|
||||||
size = roundup(priv->len, GQSPI_DMA_ALIGN);
|
priv->len = totallen;
|
||||||
flush_dcache_range(addr, addr + size);
|
|
||||||
|
|
||||||
while (priv->len) {
|
totallen -= priv->len; /* Save remaining bytes length to read */
|
||||||
zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd);
|
actuallen = priv->len; /* Actual number of bytes reading */
|
||||||
zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd);
|
|
||||||
|
|
||||||
debug("GFIFO_CMD_RX:0x%x\n", gen_fifo_cmd);
|
writel((unsigned long)buf, &dma_regs->dmadst);
|
||||||
|
writel(roundup(priv->len, GQSPI_DMA_ALIGN), &dma_regs->dmasize);
|
||||||
|
writel(GQSPI_DMA_DST_I_STS_MASK, &dma_regs->dmaier);
|
||||||
|
addr = (unsigned long)buf;
|
||||||
|
size = roundup(priv->len, GQSPI_DMA_ALIGN);
|
||||||
|
flush_dcache_range(addr, addr + size);
|
||||||
|
|
||||||
|
while (priv->len) {
|
||||||
|
zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd);
|
||||||
|
zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd);
|
||||||
|
|
||||||
|
debug("GFIFO_CMD_RX:0x%x\n", gen_fifo_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = wait_for_bit_le32(&dma_regs->dmaisr,
|
||||||
|
GQSPI_DMA_DST_I_STS_DONE, 1,
|
||||||
|
GQSPI_TIMEOUT, 1);
|
||||||
|
if (ret) {
|
||||||
|
printf("DMA Timeout:0x%x\n", readl(&dma_regs->dmaisr));
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
writel(GQSPI_DMA_DST_I_STS_DONE, &dma_regs->dmaisr);
|
||||||
|
|
||||||
|
debug("buf:0x%lx, rxbuf:0x%lx, *buf:0x%x len: 0x%x\n",
|
||||||
|
(unsigned long)buf, (unsigned long)priv->rx_buf, *buf,
|
||||||
|
actuallen);
|
||||||
|
|
||||||
|
if (buf != priv->rx_buf)
|
||||||
|
memcpy(priv->rx_buf, buf, actuallen);
|
||||||
|
|
||||||
|
buf = (u32 *)((u8 *)buf + actuallen);
|
||||||
|
priv->rx_buf = (u8 *)priv->rx_buf + actuallen;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = wait_for_bit_le32(&dma_regs->dmaisr, GQSPI_DMA_DST_I_STS_DONE,
|
|
||||||
1, GQSPI_TIMEOUT, 1);
|
|
||||||
if (ret) {
|
|
||||||
printf("DMA Timeout:0x%x\n", readl(&dma_regs->dmaisr));
|
|
||||||
return -ETIMEDOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
writel(GQSPI_DMA_DST_I_STS_DONE, &dma_regs->dmaisr);
|
|
||||||
|
|
||||||
debug("buf:0x%lx, rxbuf:0x%lx, *buf:0x%x len: 0x%x\n",
|
|
||||||
(unsigned long)buf, (unsigned long)priv->rx_buf, *buf,
|
|
||||||
actuallen);
|
|
||||||
|
|
||||||
if (buf != priv->rx_buf)
|
|
||||||
memcpy(priv->rx_buf, buf, actuallen);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,21 +722,22 @@ static int zynqmp_qspi_genfifo_fill_rx(struct zynqmp_qspi_priv *priv)
|
||||||
|
|
||||||
gen_fifo_cmd = zynqmp_qspi_bus_select(priv);
|
gen_fifo_cmd = zynqmp_qspi_bus_select(priv);
|
||||||
gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(priv->op->data.buswidth);
|
gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(priv->op->data.buswidth);
|
||||||
gen_fifo_cmd |= GQSPI_GFIFO_RX |
|
gen_fifo_cmd |= GQSPI_GFIFO_RX | GQSPI_GFIFO_DATA_XFR_MASK;
|
||||||
GQSPI_GFIFO_DATA_XFR_MASK;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if receive buffer is aligned to 4 byte and length
|
* Check if receive buffer is aligned to 4 byte and length
|
||||||
* is multiples of four byte as we are using dma to receive.
|
* is multiples of four byte as we are using dma to receive.
|
||||||
*/
|
*/
|
||||||
if (!((unsigned long)priv->rx_buf & (GQSPI_DMA_ALIGN - 1)) &&
|
if ((!((unsigned long)priv->rx_buf & (GQSPI_DMA_ALIGN - 1)) &&
|
||||||
!(actuallen % GQSPI_DMA_ALIGN)) {
|
!(actuallen % GQSPI_DMA_ALIGN)) || priv->io_mode) {
|
||||||
buf = (u32 *)priv->rx_buf;
|
buf = (u32 *)priv->rx_buf;
|
||||||
return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf);
|
if (priv->io_mode)
|
||||||
|
return zynqmp_qspi_start_io(priv, gen_fifo_cmd, buf);
|
||||||
|
else
|
||||||
|
return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALLOC_CACHE_ALIGN_BUFFER(u8, tmp, roundup(priv->len,
|
ALLOC_CACHE_ALIGN_BUFFER(u8, tmp, roundup(priv->len, GQSPI_DMA_ALIGN));
|
||||||
GQSPI_DMA_ALIGN));
|
|
||||||
buf = (u32 *)tmp;
|
buf = (u32 *)tmp;
|
||||||
return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf);
|
return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,12 @@ config ARC_TIMER
|
||||||
usually at least one of them exists. Either of them is supported
|
usually at least one of them exists. Either of them is supported
|
||||||
in U-Boot.
|
in U-Boot.
|
||||||
|
|
||||||
|
config ARM_TWD_TIMER
|
||||||
|
bool "ARM timer watchdog (TWD) timer support"
|
||||||
|
depends on TIMER && CLK
|
||||||
|
help
|
||||||
|
Select this to enable support for the ARM global timer watchdog timer.
|
||||||
|
|
||||||
config AST_TIMER
|
config AST_TIMER
|
||||||
bool "Aspeed ast2400/ast2500 timer support"
|
bool "Aspeed ast2400/ast2500 timer support"
|
||||||
depends on TIMER
|
depends on TIMER
|
||||||
|
|
|
@ -6,6 +6,7 @@ obj-y += timer-uclass.o
|
||||||
obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
|
obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
|
||||||
obj-$(CONFIG_ANDES_PLMT_TIMER) += andes_plmt_timer.o
|
obj-$(CONFIG_ANDES_PLMT_TIMER) += andes_plmt_timer.o
|
||||||
obj-$(CONFIG_ARC_TIMER) += arc_timer.o
|
obj-$(CONFIG_ARC_TIMER) += arc_timer.o
|
||||||
|
obj-$(CONFIG_ARM_TWD_TIMER) += arm_twd_timer.o
|
||||||
obj-$(CONFIG_AST_TIMER) += ast_timer.o
|
obj-$(CONFIG_AST_TIMER) += ast_timer.o
|
||||||
obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o
|
obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o
|
||||||
obj-$(CONFIG_$(SPL_)ATMEL_PIT_TIMER) += atmel_pit_timer.o
|
obj-$(CONFIG_$(SPL_)ATMEL_PIT_TIMER) += atmel_pit_timer.o
|
||||||
|
|
108
drivers/timer/arm_twd_timer.c
Normal file
108
drivers/timer/arm_twd_timer.c
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017-2022 Weidmüller Interface GmbH & Co. KG
|
||||||
|
* Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
|
||||||
|
* Copyright (C) 2011-2017 Xilinx, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* (C) Copyright 2008
|
||||||
|
* Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
|
||||||
|
*
|
||||||
|
* (C) Copyright 2004
|
||||||
|
* Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
|
||||||
|
*
|
||||||
|
* (C) Copyright 2002-2004
|
||||||
|
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
|
||||||
|
*
|
||||||
|
* (C) Copyright 2003
|
||||||
|
* Texas Instruments <www.ti.com>
|
||||||
|
*
|
||||||
|
* (C) Copyright 2002
|
||||||
|
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||||
|
* Marius Groeger <mgroeger@sysgo.de>
|
||||||
|
*
|
||||||
|
* (C) Copyright 2002
|
||||||
|
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||||
|
* Alex Zuepke <azu@sysgo.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <fdtdec.h>
|
||||||
|
#include <timer.h>
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
|
||||||
|
#include <asm/io.h>
|
||||||
|
|
||||||
|
#define SCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00 /* Prescaler */
|
||||||
|
#define SCUTIMER_CONTROL_AUTO_RELOAD_MASK 0x00000002 /* Auto-reload */
|
||||||
|
#define SCUTIMER_CONTROL_ENABLE_MASK 0x00000001 /* Timer enable */
|
||||||
|
|
||||||
|
#define TIMER_LOAD_VAL 0xFFFFFFFF
|
||||||
|
|
||||||
|
struct arm_twd_timer_regs {
|
||||||
|
u32 load; /* Timer Load Register */
|
||||||
|
u32 counter; /* Timer Counter Register */
|
||||||
|
u32 control; /* Timer Control Register */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct arm_twd_timer_priv {
|
||||||
|
struct arm_twd_timer_regs *base;
|
||||||
|
};
|
||||||
|
|
||||||
|
static u64 arm_twd_timer_get_count(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct arm_twd_timer_priv *priv = dev_get_priv(dev);
|
||||||
|
struct arm_twd_timer_regs *regs = priv->base;
|
||||||
|
u32 count = TIMER_LOAD_VAL - readl(®s->counter);
|
||||||
|
|
||||||
|
return timer_conv_64(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int arm_twd_timer_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct arm_twd_timer_priv *priv = dev_get_priv(dev);
|
||||||
|
struct arm_twd_timer_regs *regs;
|
||||||
|
fdt_addr_t addr;
|
||||||
|
|
||||||
|
addr = dev_read_addr(dev);
|
||||||
|
if (addr == FDT_ADDR_T_NONE)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
priv->base = (struct arm_twd_timer_regs *)addr;
|
||||||
|
|
||||||
|
regs = priv->base;
|
||||||
|
|
||||||
|
/* Load the timer counter register */
|
||||||
|
writel(0xFFFFFFFF, ®s->load);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start the A9Timer device
|
||||||
|
* Enable Auto reload mode, Clear prescaler control bits
|
||||||
|
* Set prescaler value, Enable the decrementer
|
||||||
|
*/
|
||||||
|
clrsetbits_le32(®s->control, SCUTIMER_CONTROL_PRESCALER_MASK,
|
||||||
|
SCUTIMER_CONTROL_AUTO_RELOAD_MASK |
|
||||||
|
SCUTIMER_CONTROL_ENABLE_MASK);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct timer_ops arm_twd_timer_ops = {
|
||||||
|
.get_count = arm_twd_timer_get_count,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct udevice_id arm_twd_timer_ids[] = {
|
||||||
|
{ .compatible = "arm,cortex-a9-twd-timer" },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(arm_twd_timer) = {
|
||||||
|
.name = "arm_twd_timer",
|
||||||
|
.id = UCLASS_TIMER,
|
||||||
|
.of_match = arm_twd_timer_ids,
|
||||||
|
.priv_auto = sizeof(struct arm_twd_timer_priv),
|
||||||
|
.probe = arm_twd_timer_probe,
|
||||||
|
.ops = &arm_twd_timer_ops,
|
||||||
|
};
|
1
env/Kconfig
vendored
1
env/Kconfig
vendored
|
@ -570,6 +570,7 @@ config ENV_OFFSET_REDUND
|
||||||
hex "Redundant environment offset"
|
hex "Redundant environment offset"
|
||||||
depends on (ENV_IS_IN_EEPROM || ENV_IS_IN_MMC || ENV_IS_IN_NAND || \
|
depends on (ENV_IS_IN_EEPROM || ENV_IS_IN_MMC || ENV_IS_IN_NAND || \
|
||||||
ENV_IS_IN_SPI_FLASH) && SYS_REDUNDAND_ENVIRONMENT
|
ENV_IS_IN_SPI_FLASH) && SYS_REDUNDAND_ENVIRONMENT
|
||||||
|
default 0x10C0000 if MICROBLAZE
|
||||||
default 0
|
default 0
|
||||||
help
|
help
|
||||||
Offset from the start of the device (or partition) of the redundant
|
Offset from the start of the device (or partition) of the redundant
|
||||||
|
|
|
@ -97,10 +97,4 @@
|
||||||
|
|
||||||
#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE
|
#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE
|
||||||
|
|
||||||
/* SP location before relocation, must use scratch RAM */
|
|
||||||
/* BRAM start */
|
|
||||||
#define CONFIG_SYS_INIT_RAM_ADDR 0x0
|
|
||||||
/* BRAM size - will be generated */
|
|
||||||
#define CONFIG_SYS_INIT_RAM_SIZE 0x100000
|
|
||||||
|
|
||||||
#endif /* __CONFIG_H */
|
#endif /* __CONFIG_H */
|
||||||
|
|
|
@ -343,6 +343,19 @@ void bdinfo_print_num_ll(const char *name, unsigned long long value);
|
||||||
/* Print a clock speed in MHz */
|
/* Print a clock speed in MHz */
|
||||||
void bdinfo_print_mhz(const char *name, unsigned long hz);
|
void bdinfo_print_mhz(const char *name, unsigned long hz);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bdinfo_print_size - print size variables in bdinfo format
|
||||||
|
* @name: string to print before the size
|
||||||
|
* @size: size to print
|
||||||
|
*
|
||||||
|
* Helper function for displaying size variables as properly formatted bdinfo
|
||||||
|
* entries. The size is printed as "xxx Bytes", "xxx KiB", "xxx MiB",
|
||||||
|
* "xxx GiB", etc. as needed;
|
||||||
|
*
|
||||||
|
* For use in arch_print_bdinfo().
|
||||||
|
*/
|
||||||
|
void bdinfo_print_size(const char *name, uint64_t size);
|
||||||
|
|
||||||
/* Show arch-specific information for the 'bd' command */
|
/* Show arch-specific information for the 'bd' command */
|
||||||
void arch_print_bdinfo(void);
|
void arch_print_bdinfo(void);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue