[PATCH] clk: zynqmp: Add set_rate support for display clocks

2024-07-11 Thread Venkatesh Yadav Abbarapu
If "assigned-clock-rates" property is included in the
device tree, display driver probe is getting failed, as dp_video_ref
till dp_stc_ref clocks are missing from set rate function, adding
them to fix the probe failure.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/clk/clk_zynqmp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c
index 526614..5635451821 100644
--- a/drivers/clk/clk_zynqmp.c
+++ b/drivers/clk/clk_zynqmp.c
@@ -727,6 +727,7 @@ static ulong zynqmp_clk_set_rate(struct clk *clk, ulong 
rate)
case gem_tsu:
case qspi_ref ... can1_ref:
case usb0_bus_ref ... usb3_dual_ref:
+   case dp_video_ref ... dp_stc_ref:
return zynqmp_clk_set_peripheral_rate(priv, id,
  rate, two_divs);
default:
-- 
2.17.1



[PATCH] config: Enable the config CONFIG_MMC_SPEED_MODE_SET

2024-07-08 Thread Venkatesh Yadav Abbarapu
Enable setting speed mode using mmc dev commands.
The speed mode is provided as the last argument in these commands
(ex: mmc dev 0 0 10) and is indicated using the index from enum
bus_mode in include/mmc.h. A speed mode can be set if it is enabled
from device tree or from capabilities register

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 configs/amd_versal2_virt_defconfig   | 1 +
 configs/xilinx_versal_net_virt_defconfig | 1 +
 configs/xilinx_versal_virt_defconfig | 1 +
 configs/xilinx_zynq_virt_defconfig   | 2 +-
 configs/xilinx_zynqmp_virt_defconfig | 1 +
 5 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/configs/amd_versal2_virt_defconfig 
b/configs/amd_versal2_virt_defconfig
index 2d611f84cd..f8df0b53e5 100644
--- a/configs/amd_versal2_virt_defconfig
+++ b/configs/amd_versal2_virt_defconfig
@@ -59,6 +59,7 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_SQUASHFS=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_CMD_UBI=y
+CONFIG_MMC_SPEED_MODE_SET=y
 CONFIG_PARTITION_TYPE_GUID=y
 CONFIG_OF_BOARD=y
 CONFIG_DTB_RESELECT=y
diff --git a/configs/xilinx_versal_net_virt_defconfig 
b/configs/xilinx_versal_net_virt_defconfig
index 53ef81e64d..40a9b16b9c 100644
--- a/configs/xilinx_versal_net_virt_defconfig
+++ b/configs/xilinx_versal_net_virt_defconfig
@@ -58,6 +58,7 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_SQUASHFS=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_CMD_UBI=y
+CONFIG_MMC_SPEED_MODE_SET=y
 CONFIG_PARTITION_TYPE_GUID=y
 CONFIG_OF_BOARD=y
 CONFIG_DTB_RESELECT=y
diff --git a/configs/xilinx_versal_virt_defconfig 
b/configs/xilinx_versal_virt_defconfig
index 915f0b993c..dc1754f6d1 100644
--- a/configs/xilinx_versal_virt_defconfig
+++ b/configs/xilinx_versal_virt_defconfig
@@ -59,6 +59,7 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_SQUASHFS=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_CMD_UBI=y
+CONFIG_MMC_SPEED_MODE_SET=y
 CONFIG_PARTITION_TYPE_GUID=y
 CONFIG_OF_BOARD=y
 CONFIG_ENV_IS_NOWHERE=y
diff --git a/configs/xilinx_zynq_virt_defconfig 
b/configs/xilinx_zynq_virt_defconfig
index 9be904fd30..f8b6a3f1aa 100644
--- a/configs/xilinx_zynq_virt_defconfig
+++ b/configs/xilinx_zynq_virt_defconfig
@@ -81,6 +81,7 @@ CONFIG_CMD_MTDPARTS=y
 CONFIG_CMD_MTDPARTS_SPREAD=y
 CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES=y
 CONFIG_CMD_UBI=y
+CONFIG_MMC_SPEED_MODE_SET=y
 CONFIG_OF_BOARD=y
 CONFIG_OF_LIST="zynq-zc702 zynq-zc706 zynq-zc770-xm010 zynq-zc770-xm011 
zynq-zc770-xm011-x16 zynq-zc770-xm012 zynq-zc770-xm013 zynq-cc108 zynq-microzed 
zynq-minized zynq-picozed zynq-zed zynq-zturn zynq-zturn-v5 zynq-zybo 
zynq-zybo-z7 zynq-dlc20-rev1.0"
 CONFIG_ENV_IS_NOWHERE=y
@@ -155,4 +156,3 @@ CONFIG_SYS_TIMER_COUNTS_DOWN=y
 CONFIG_SPL_GZIP=y
 CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
 CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
-CONFIG_TOOLS_MKEFICAPSULE=y
diff --git a/configs/xilinx_zynqmp_virt_defconfig 
b/configs/xilinx_zynqmp_virt_defconfig
index fa912ae3bb..1133134e3f 100644
--- a/configs/xilinx_zynqmp_virt_defconfig
+++ b/configs/xilinx_zynqmp_virt_defconfig
@@ -101,6 +101,7 @@ CONFIG_CMD_MTDPARTS=y
 CONFIG_CMD_MTDPARTS_SPREAD=y
 CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES=y
 CONFIG_CMD_UBI=y
+CONFIG_MMC_SPEED_MODE_SET=y
 CONFIG_PARTITION_TYPE_GUID=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_BOARD=y
-- 
2.17.1



[PATCH 3/4] arm64: Add versal2 mini ospi support

2024-06-19 Thread Venkatesh Yadav Abbarapu
Add versal2 mini ospi configuration.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 configs/amd_versal2_mini_ospi_defconfig | 84 +
 1 file changed, 84 insertions(+)
 create mode 100644 configs/amd_versal2_mini_ospi_defconfig

diff --git a/configs/amd_versal2_mini_ospi_defconfig 
b/configs/amd_versal2_mini_ospi_defconfig
new file mode 100644
index 00..2242960392
--- /dev/null
+++ b/configs/amd_versal2_mini_ospi_defconfig
@@ -0,0 +1,84 @@
+CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="amd_versal2_mini"
+# CONFIG_ARM64_CRC32 is not set
+CONFIG_COUNTER_FREQUENCY=1
+# CONFIG_ARM64_SUPPORT_AARCH32 is not set
+CONFIG_ARCH_VERSAL2=y
+CONFIG_TEXT_BASE=0xBBF0
+CONFIG_SYS_MALLOC_LEN=0x2
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=3
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xBBF2
+CONFIG_ENV_SIZE=0x80
+CONFIG_DEFAULT_DEVICE_TREE="amd-versal2-mini"
+CONFIG_DEBUG_UART_BASE=0xf192
+CONFIG_DEBUG_UART_CLOCK=1
+CONFIG_SYS_MEM_RSVD_FOR_MMU=y
+# CONFIG_PSCI_RESET is not set
+CONFIG_SYS_LOAD_ADDR=0xBBF8
+CONFIG_DEBUG_UART=y
+# CONFIG_EXPERT is not set
+CONFIG_REMAKE_ELF=y
+# CONFIG_LEGACY_IMAGE_FORMAT is not set
+# CONFIG_AUTOBOOT is not set
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_BOARD_EARLY_INIT_R=y
+# CONFIG_BOARD_LATE_INIT is not set
+# CONFIG_CMDLINE_EDITING is not set
+# CONFIG_AUTO_COMPLETE is not set
+# CONFIG_SYS_LONGHELP is not set
+CONFIG_SYS_PROMPT="versal2> "
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTI is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_FDT is not set
+# CONFIG_CMD_GO is not set
+# CONFIG_CMD_RUN is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+# CONFIG_CMD_CRC32 is not set
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_ECHO is not set
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SOURCE is not set
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_CACHE=y
+# CONFIG_CMD_SLEEP is not set
+CONFIG_OF_EMBED=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
+# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_GPIO is not set
+# CONFIG_I2C is not set
+# CONFIG_INPUT is not set
+# CONFIG_MMC is not set
+CONFIG_MTD=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SOFT_RESET=y
+CONFIG_SPI_FLASH_SOFT_RESET_ON_BOOT=y
+# CONFIG_SPI_FLASH_LOCK is not set
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_MT35XU=y
+# CONFIG_POWER is not set
+CONFIG_DEBUG_UART_PL011=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_ARM_DCC=y
+CONFIG_PL01X_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CADENCE_QSPI=y
+CONFIG_HAS_CQSPI_REF_CLK=y
+CONFIG_CQSPI_REF_CLK=2
+CONFIG_CADENCE_OSPI_VERSAL=y
+# CONFIG_GZIP is not set
-- 
2.17.1



[PATCH 4/4] arm64: config: Add versal2 mini emmc defconfig

2024-06-19 Thread Venkatesh Yadav Abbarapu
Add versal2 mini emmc configuration.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 configs/amd_versal2_mini_emmc_defconfig | 69 +
 1 file changed, 69 insertions(+)
 create mode 100644 configs/amd_versal2_mini_emmc_defconfig

diff --git a/configs/amd_versal2_mini_emmc_defconfig 
b/configs/amd_versal2_mini_emmc_defconfig
new file mode 100644
index 00..7ad44386a6
--- /dev/null
+++ b/configs/amd_versal2_mini_emmc_defconfig
@@ -0,0 +1,69 @@
+CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="amd_versal2_mini"
+CONFIG_COUNTER_FREQUENCY=1
+CONFIG_ARCH_VERSAL2=y
+CONFIG_TEXT_BASE=0x1
+CONFIG_SYS_MALLOC_LEN=0x8
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x1
+CONFIG_ENV_SIZE=0x80
+CONFIG_DEFAULT_DEVICE_TREE="amd-versal2-mini"
+CONFIG_DEBUG_UART_BASE=0xf192
+CONFIG_DEBUG_UART_CLOCK=1
+# CONFIG_PSCI_RESET is not set
+CONFIG_SYS_LOAD_ADDR=0x800
+CONFIG_DEBUG_UART=y
+# CONFIG_EXPERT is not set
+CONFIG_REMAKE_ELF=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_BOARD_EARLY_INIT_R=y
+# CONFIG_BOARD_LATE_INIT is not set
+# CONFIG_CMDLINE_EDITING is not set
+# CONFIG_AUTO_COMPLETE is not set
+# CONFIG_SYS_LONGHELP is not set
+CONFIG_SYS_PROMPT="versal2> "
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTM is not set
+# CONFIG_CMD_BOOTI is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_FDT is not set
+# CONFIG_CMD_GO is not set
+# CONFIG_CMD_RUN is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+# CONFIG_CMD_CRC32 is not set
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_ECHO is not set
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SOURCE is not set
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_EMBED=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ZYNQ=y
+CONFIG_DEBUG_UART_PL011=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_ARM_DCC=y
+CONFIG_PL01X_SERIAL=y
+CONFIG_FAT_WRITE=y
+# CONFIG_GZIP is not set
+# CONFIG_EFI_LOADER is not set
+# CONFIG_LMB is not set
-- 
2.17.1



[PATCH 2/4] arm64: Add versal2 mini qspi support

2024-06-19 Thread Venkatesh Yadav Abbarapu
Add versal2 mini qspi configuration.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 configs/amd_versal2_mini_qspi_defconfig | 79 +
 1 file changed, 79 insertions(+)
 create mode 100644 configs/amd_versal2_mini_qspi_defconfig

diff --git a/configs/amd_versal2_mini_qspi_defconfig 
b/configs/amd_versal2_mini_qspi_defconfig
new file mode 100644
index 00..3360c1546a
--- /dev/null
+++ b/configs/amd_versal2_mini_qspi_defconfig
@@ -0,0 +1,79 @@
+CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="amd_versal2_mini"
+# CONFIG_ARM64_CRC32 is not set
+CONFIG_COUNTER_FREQUENCY=1
+# CONFIG_ARM64_SUPPORT_AARCH32 is not set
+CONFIG_ARCH_VERSAL2=y
+CONFIG_TEXT_BASE=0xBBF0
+CONFIG_SYS_MALLOC_LEN=0x2
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=3
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xBBF2
+CONFIG_ENV_SIZE=0x80
+CONFIG_DEFAULT_DEVICE_TREE="amd-versal2-mini"
+CONFIG_DEBUG_UART_BASE=0xf192
+CONFIG_DEBUG_UART_CLOCK=1
+CONFIG_SYS_MEM_RSVD_FOR_MMU=y
+# CONFIG_PSCI_RESET is not set
+CONFIG_SYS_LOAD_ADDR=0xBBF8
+CONFIG_DEBUG_UART=y
+# CONFIG_EXPERT is not set
+CONFIG_REMAKE_ELF=y
+# CONFIG_LEGACY_IMAGE_FORMAT is not set
+# CONFIG_AUTOBOOT is not set
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_BOARD_EARLY_INIT_R=y
+# CONFIG_BOARD_LATE_INIT is not set
+# CONFIG_CMDLINE_EDITING is not set
+# CONFIG_AUTO_COMPLETE is not set
+# CONFIG_SYS_LONGHELP is not set
+CONFIG_SYS_PROMPT="versal2> "
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTI is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_FDT is not set
+# CONFIG_CMD_GO is not set
+# CONFIG_CMD_RUN is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+# CONFIG_CMD_CRC32 is not set
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_ECHO is not set
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SOURCE is not set
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_CACHE=y
+# CONFIG_CMD_SLEEP is not set
+CONFIG_OF_EMBED=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
+# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_GPIO is not set
+# CONFIG_I2C is not set
+# CONFIG_INPUT is not set
+# CONFIG_MMC is not set
+CONFIG_MTD=y
+CONFIG_DM_SPI_FLASH=y
+# CONFIG_SPI_FLASH_LOCK is not set
+CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+# CONFIG_POWER is not set
+CONFIG_DEBUG_UART_PL011=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_ARM_DCC=y
+CONFIG_PL01X_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_ZYNQMP_GQSPI=y
+# CONFIG_GZIP is not set
-- 
2.17.1



[PATCH 1/4] arm64: versal2: Add support for mini configuration

2024-06-19 Thread Venkatesh Yadav Abbarapu
Versal2 mini configuration is designed for running memory test.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 arch/arm/dts/amd-versal2-mini.dts  | 11 +
 configs/amd_versal2_mini_defconfig | 77 ++
 include/configs/amd_versal2_mini.h | 20 
 3 files changed, 108 insertions(+)
 create mode 100644 arch/arm/dts/amd-versal2-mini.dts
 create mode 100644 configs/amd_versal2_mini_defconfig
 create mode 100644 include/configs/amd_versal2_mini.h

diff --git a/arch/arm/dts/amd-versal2-mini.dts 
b/arch/arm/dts/amd-versal2-mini.dts
new file mode 100644
index 00..ac685772da
--- /dev/null
+++ b/arch/arm/dts/amd-versal2-mini.dts
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Empty device tree for amd-versal2-mini
+ *
+ * Copyright (C) 2024, Advanced Micro Devices, Inc.
+ */
+
+/dts-v1/;
+
+/ {
+};
diff --git a/configs/amd_versal2_mini_defconfig 
b/configs/amd_versal2_mini_defconfig
new file mode 100644
index 00..0dd2305bfb
--- /dev/null
+++ b/configs/amd_versal2_mini_defconfig
@@ -0,0 +1,77 @@
+CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="amd_versal2_mini"
+# CONFIG_ARM64_CRC32 is not set
+CONFIG_COUNTER_FREQUENCY=1
+# CONFIG_ARM64_SUPPORT_AARCH32 is not set
+CONFIG_ARCH_VERSAL2=y
+CONFIG_TEXT_BASE=0xBBF0
+CONFIG_SYS_MALLOC_LEN=0x2
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=3
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xBBF2
+CONFIG_ENV_SIZE=0x80
+CONFIG_DEFAULT_DEVICE_TREE="amd-versal2-mini"
+CONFIG_DEBUG_UART_BASE=0xf192
+CONFIG_DEBUG_UART_CLOCK=1
+CONFIG_SYS_MEM_RSVD_FOR_MMU=y
+# CONFIG_PSCI_RESET is not set
+CONFIG_SYS_LOAD_ADDR=0xBBF8
+CONFIG_DEBUG_UART=y
+CONFIG_SYS_MEMTEST_START=0x
+CONFIG_SYS_MEMTEST_END=0x1000
+# CONFIG_EXPERT is not set
+CONFIG_REMAKE_ELF=y
+# CONFIG_LEGACY_IMAGE_FORMAT is not set
+# CONFIG_AUTOBOOT is not set
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_BOARD_EARLY_INIT_R=y
+# CONFIG_BOARD_LATE_INIT is not set
+# CONFIG_CMDLINE_EDITING is not set
+# CONFIG_AUTO_COMPLETE is not set
+# CONFIG_SYS_LONGHELP is not set
+CONFIG_SYS_PROMPT="versal2> "
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_BOOTI is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_FDT is not set
+# CONFIG_CMD_GO is not set
+# CONFIG_CMD_RUN is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_EXPORTENV is not set
+# CONFIG_CMD_IMPORTENV is not set
+# CONFIG_CMD_EDITENV is not set
+# CONFIG_CMD_SAVEENV is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MX_CYCLIC=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_SYS_ALT_MEMTEST=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+# CONFIG_CMD_ECHO is not set
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SOURCE is not set
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_CACHE=y
+# CONFIG_CMD_SLEEP is not set
+CONFIG_OF_EMBED=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
+# CONFIG_DM_DEVICE_REMOVE is not set
+# CONFIG_GPIO is not set
+# CONFIG_I2C is not set
+# CONFIG_INPUT is not set
+# CONFIG_MMC is not set
+# CONFIG_POWER is not set
+CONFIG_DEBUG_UART_PL011=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_ARM_DCC=y
+CONFIG_PL01X_SERIAL=y
+# CONFIG_GZIP is not set
diff --git a/include/configs/amd_versal2_mini.h 
b/include/configs/amd_versal2_mini.h
new file mode 100644
index 00..97e8f673a8
--- /dev/null
+++ b/include/configs/amd_versal2_mini.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Configuration for AMD Versal Gen2 MINI configuration
+ *
+ * Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc.
+ *
+ * Michal Simek 
+ */
+
+#ifndef __CONFIG_VERSAL2_MINI_H
+#define __CONFIG_VERSAL2_MINI_H
+
+#define CFG_EXTRA_ENV_SETTINGS
+
+#include 
+
+/* Undef unneeded configs */
+#undef CFG_EXTRA_ENV_SETTINGS
+
+#endif /* __CONFIG_VERSAL2_MINI_H */
-- 
2.17.1



[PATCH 0/4] Add mini configuration support for versal2

2024-06-19 Thread Venkatesh Yadav Abbarapu
Adding the basic mini u-boot configuration changes for qspi, 
ospi and emmc.

Branch:next

Venkatesh Yadav Abbarapu (4):
  arm64: versal2: Add support for mini configuration
  arm64: Add versal2 mini qspi support
  arm64: Add versal2 mini ospi support
  arm64: config: Add versal2 mini emmc defconfig

 arch/arm/dts/amd-versal2-mini.dts   | 11 
 configs/amd_versal2_mini_defconfig  | 77 +++
 configs/amd_versal2_mini_emmc_defconfig | 69 
 configs/amd_versal2_mini_ospi_defconfig | 84 +
 configs/amd_versal2_mini_qspi_defconfig | 79 +++
 include/configs/amd_versal2_mini.h  | 20 ++
 6 files changed, 340 insertions(+)
 create mode 100644 arch/arm/dts/amd-versal2-mini.dts
 create mode 100644 configs/amd_versal2_mini_defconfig
 create mode 100644 configs/amd_versal2_mini_emmc_defconfig
 create mode 100644 configs/amd_versal2_mini_ospi_defconfig
 create mode 100644 configs/amd_versal2_mini_qspi_defconfig
 create mode 100644 include/configs/amd_versal2_mini.h

-- 
2.17.1



[PATCH] xilinx: versal-net: Add env redund offset

2024-06-14 Thread Venkatesh Yadav Abbarapu
ENV_OFFSET_REDUND config is by default set to 0 for flashes.
Saving the env variables is overwriting data at 0 offset,
which is wrong. So add default redund env offset
ENV_OFFSET_REDUND at 0x7F0 for Versal NET platform.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 configs/xilinx_versal_net_virt_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/xilinx_versal_net_virt_defconfig 
b/configs/xilinx_versal_net_virt_defconfig
index 40c6a29a16..289f27cdea 100644
--- a/configs/xilinx_versal_net_virt_defconfig
+++ b/configs/xilinx_versal_net_virt_defconfig
@@ -8,6 +8,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x10
 CONFIG_DEFAULT_DEVICE_TREE="xilinx-versal-net-virt"
 CONFIG_OF_LIBFDT_OVERLAY=y
 CONFIG_DM_RESET=y
+CONFIG_ENV_OFFSET_REDUND=0x7F0
 CONFIG_CMD_FRU=y
 CONFIG_SYS_LOAD_ADDR=0x800
 CONFIG_SYS_MEMTEST_START=0x
-- 
2.17.1



[PATCH 2/2] xilinx: versal-net: Handle spi seq number based on boot device

2024-06-14 Thread Venkatesh Yadav Abbarapu
Versal NET boards has QSPI and OSPI and default bus set to 0
is not working when system is booting out of OSPI which is
controller 1, as fixed aliases are set for all the boards
i.e., QSPI to 0 and OSPI to 1. Add controller autodetection
via spi_get_env_dev().

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 board/xilinx/versal-net/board.c | 45 +
 1 file changed, 45 insertions(+)

diff --git a/board/xilinx/versal-net/board.c b/board/xilinx/versal-net/board.c
index da03024e16..5a93cb29c0 100644
--- a/board/xilinx/versal-net/board.c
+++ b/board/xilinx/versal-net/board.c
@@ -194,6 +194,51 @@ static u8 versal_net_get_bootmode(void)
return bootmode;
 }
 
+int spi_get_env_dev(void)
+{
+   struct udevice *dev;
+   const char *mode = NULL;
+   int bootseq = -1;
+
+   switch (versal_net_get_bootmode()) {
+   case QSPI_MODE_24BIT:
+   puts("QSPI_MODE_24\n");
+   if (uclass_get_device_by_name(UCLASS_SPI,
+ "spi@f103", )) {
+   debug("QSPI driver for QSPI device is not present\n");
+   break;
+   }
+   mode = "xspi";
+   bootseq = dev_seq(dev);
+   break;
+   case QSPI_MODE_32BIT:
+   puts("QSPI_MODE_32\n");
+   if (uclass_get_device_by_name(UCLASS_SPI,
+ "spi@f103", )) {
+   debug("QSPI driver for QSPI device is not present\n");
+   break;
+   }
+   mode = "xspi";
+   bootseq = dev_seq(dev);
+   break;
+   case OSPI_MODE:
+   puts("OSPI_MODE\n");
+   if (uclass_get_device_by_name(UCLASS_SPI,
+ "spi@f101", )) {
+   debug("OSPI driver for OSPI device is not present\n");
+   break;
+   }
+   mode = "xspi";
+   bootseq = dev_seq(dev);
+   break;
+   default:
+   break;
+   }
+
+   debug("bootseq %d\n", bootseq);
+   return bootseq;
+}
+
 static int boot_targets_setup(void)
 {
u8 bootmode;
-- 
2.17.1



[PATCH 1/2] env_spi: support overriding spi dev from board code

2024-06-14 Thread Venkatesh Yadav Abbarapu
This enables boards to choose where to/from the environment
should be saved/loaded. They can then for example support using
the same device (dynamically) from which the bootloader was
launched to load and save env data and do not have to
define CONFIG_ENV_SPI_BUS statically.

In my use case, the environment needs to be on the same device I
booted from. It can be the QSPI or OSPI device.
I therefore would override spi_get_env_dev in the board code,
read the bootmode registers to determine where we booted from
and return the corresponding device index.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 9 +
 env/sf.c   | 3 ++-
 include/spi.h  | 2 ++
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index f86003ca8c..2fb49a96f3 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -4206,3 +4206,12 @@ int spi_flash_cmd_get_sw_write_prot(struct spi_nor *nor)
 
return (sr >> 2) & 7;
 }
+
+__weak int spi_get_env_dev(void)
+{
+#ifdef CONFIG_ENV_SPI_BUS
+   return CONFIG_ENV_SPI_BUS;
+#else
+   return 0;
+#endif
+}
diff --git a/env/sf.c b/env/sf.c
index 8f5c03b00d..4d40fd613e 100644
--- a/env/sf.c
+++ b/env/sf.c
@@ -44,9 +44,10 @@ static int setup_flash_device(struct spi_flash **env_flash)
 #if CONFIG_IS_ENABLED(DM_SPI_FLASH)
struct udevice *new;
int ret;
+   int dev = spi_get_env_dev();
 
/* speed and mode will be read from DT */
-   ret = spi_flash_probe_bus_cs(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
+   ret = spi_flash_probe_bus_cs(dev, CONFIG_ENV_SPI_CS,
 );
if (ret) {
env_set_default("spi_flash_probe_bus_cs() failed", 0);
diff --git a/include/spi.h b/include/spi.h
index 7e38cc2a2a..9e9851284c 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -743,4 +743,6 @@ int dm_spi_get_mmap(struct udevice *dev, ulong *map_basep, 
uint *map_sizep,
 #define spi_get_ops(dev)   ((struct dm_spi_ops *)(dev)->driver->ops)
 #define spi_emul_get_ops(dev)  ((struct dm_spi_emul_ops *)(dev)->driver->ops)
 
+int spi_get_env_dev(void);
+
 #endif /* _SPI_H_ */
-- 
2.17.1



[PATCH 0/2] env_spi: support overriding spi dev from board code

2024-06-14 Thread Venkatesh Yadav Abbarapu
This enables boards to choose where to/from the environment
should be saved/loaded either QSPI or OSPI based on the bootmode.

Venkatesh Yadav Abbarapu (2):
  env_spi: support overriding spi dev from board code
  xilinx: versal-net: Handle spi seq number based on boot device

 board/xilinx/versal-net/board.c | 45 +
 drivers/mtd/spi/spi-nor-core.c  |  9 +++
 env/sf.c|  3 ++-
 include/spi.h   |  2 ++
 4 files changed, 58 insertions(+), 1 deletion(-)

-- 
2.17.1



[PATCH 7/7] arm64: zynqmp: Update the usb5744 hub node as per binding

2024-06-05 Thread Venkatesh Yadav Abbarapu
Updating the usb5744 hub node as per the latest upstream DT binding
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
tree/Documentation/devicetree/bindings/usb/microchip,usb5744.yaml?h=v6.8.8

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 arch/arm/dts/zynqmp-sck-kr-g-revA.dtso | 48 ++
 arch/arm/dts/zynqmp-sck-kr-g-revB.dtso | 48 ++
 arch/arm/dts/zynqmp-sck-kv-g-revA.dtso | 18 ++
 arch/arm/dts/zynqmp-sck-kv-g-revB.dtso | 25 +-
 4 files changed, 138 insertions(+), 1 deletion(-)

diff --git a/arch/arm/dts/zynqmp-sck-kr-g-revA.dtso 
b/arch/arm/dts/zynqmp-sck-kr-g-revA.dtso
index ce7c5eb6d34..18e9d308de3 100644
--- a/arch/arm/dts/zynqmp-sck-kr-g-revA.dtso
+++ b/arch/arm/dts/zynqmp-sck-kr-g-revA.dtso
@@ -105,11 +105,19 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
+   hub_1: usb-hub@2d {
+   compatible = "microchip,usb5744";
+   reg = <0x2d>;
+   };
};
usbhub_i2c1: i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
+   hub_2: usb-hub@2d {
+   compatible = "microchip,usb5744";
+   reg = <0x2d>;
+   };
};
/* Bus 2/3 are not connected */
};
@@ -164,6 +172,26 @@
dr_mode = "host";
snps,usb3_lpm_capable;
maximum-speed = "super-speed";
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   /* 2.0 hub on port 1 */
+   hub_2_0: hub@1 {
+   compatible = "usb424,2744";
+   reg = <1>;
+   peer-hub = <_3_0>;
+   i2c-bus = <_1>;
+   reset-gpios = < 3 GPIO_ACTIVE_LOW>;
+   };
+
+   /* 3.0 hub on port 2 */
+   hub_3_0: hub@2 {
+   compatible = "usb424,5744";
+   reg = <2>;
+   peer-hub = <_2_0>;
+   i2c-bus = <_1>;
+   reset-gpios = < 3 GPIO_ACTIVE_LOW>;
+   };
 };
 
  { /* mio64 - mio75 */
@@ -188,6 +216,26 @@
dr_mode = "host";
snps,usb3_lpm_capable;
maximum-speed = "super-speed";
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   /* 2.0 hub on port 1 */
+   hub1_2_0: hub@1 {
+   compatible = "usb424,2744";
+   reg = <1>;
+   peer-hub = <_3_0>;
+   i2c-bus = <_2>;
+   reset-gpios = < 4 GPIO_ACTIVE_LOW>;
+   };
+
+   /* 3.0 hub on port 2 */
+   hub1_3_0: hub@2 {
+   compatible = "usb424,5744";
+   reg = <2>;
+   peer-hub = <_2_0>;
+   i2c-bus = <_2>;
+   reset-gpios = < 4 GPIO_ACTIVE_LOW>;
+   };
 };
 
  { /* mdio mio50/51 */
diff --git a/arch/arm/dts/zynqmp-sck-kr-g-revB.dtso 
b/arch/arm/dts/zynqmp-sck-kr-g-revB.dtso
index 0a0cbd2b69a..5261e793c14 100644
--- a/arch/arm/dts/zynqmp-sck-kr-g-revB.dtso
+++ b/arch/arm/dts/zynqmp-sck-kr-g-revB.dtso
@@ -117,11 +117,19 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
+   hub_1: usb-hub@2d {
+   compatible = "microchip,usb5744";
+   reg = <0x2d>;
+   };
};
usbhub_i2c1: i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
+   hub_2: usb-hub@2d {
+   compatible = "microchip,usb5744";
+   reg = <0x2d>;
+   };
};
/* Bus 2/3 are not connected */
};
@@ -184,6 +192,26 @@
dr_mode = "host";
snps,usb3_lpm_capable;
maximum-speed = "super-speed";
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   /* 2.0 hub on port 1 */
+   hub_2_0: hub@1 {
+   compatible = "usb424,2744";
+   reg = <1>;
+   peer-hub = <_3_0>;
+   i2c-bus = <_1>;
+   reset-gpios = < 3 GPIO_ACTIVE_LOW>;
+   };
+
+   /* 3.0 hub on port 2 */
+   hub_3_0: hub@2 {
+   compatible = "usb424,5744";
+   reg = <2>;
+ 

[PATCH 5/7] usb: onboard-hub: Bail out if peer hub is already probed

2024-06-05 Thread Venkatesh Yadav Abbarapu
Many physical hub chips include multiple logical hubs to handle both
USB and 2 and 3. Both logical hubs will then match the onboard hub
driver, which means it will end up with two driver instances trying to
control the reset GPIO that is only present once on the physical chip.

The reference for this change is taken from
https://lore.barebox.org/barebox/20240327165554.894805-1-l.st...@pengutronix.de/

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 common/usb_onboard_hub.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/common/usb_onboard_hub.c b/common/usb_onboard_hub.c
index 09ce452af1b..519bad337e1 100644
--- a/common/usb_onboard_hub.c
+++ b/common/usb_onboard_hub.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -21,7 +22,7 @@
 #define USB5744_CONFIG_REG_ACCESS_LSB 0x99
 
 struct onboard_hub {
-   struct udevice *vdd;
+   struct udevice *vdd, *dev;
struct gpio_desc *reset_gpio;
 };
 
@@ -106,8 +107,18 @@ static int usb_onboard_hub_probe(struct udevice *dev)
struct onboard_hub_data *data =
(struct onboard_hub_data *)dev_get_driver_data(dev);
struct onboard_hub *hub = dev_get_priv(dev);
+   struct ofnode_phandle_args phandle;
+   struct udevice *hub_dev;
int ret;
 
+   if (!dev_read_phandle_with_args(dev, "peer-hub", NULL, 0, 0, )) 
{
+   if (ofnode_valid(phandle.node)) {
+   ret = uclass_find_device_by_ofnode(UCLASS_USB_HUB, 
phandle.node, _dev);
+   if (hub_dev && hub_dev->priv_)
+   return 0;
+   }
+   }
+
if (CONFIG_IS_ENABLED(DM_REGULATOR)) {
ret = device_get_supply_regulator(dev, "vdd-supply",
  >vdd);
@@ -148,6 +159,9 @@ static int usb_onboard_hub_probe(struct udevice *dev)
return ret;
}
}
+   hub->dev = dev;
+   dev->priv_ = hub;
+
return 0;
 }
 
-- 
2.17.1



[PATCH 6/7] configs: zynqmp_kria: Enable the USB onboard hub

2024-06-05 Thread Venkatesh Yadav Abbarapu
USB host support on ZYNQMP KRIA SOM needs onboard USB
hub driver for handling reset GPIO and for i2c initialization
sequence.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 configs/xilinx_zynqmp_kria_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/xilinx_zynqmp_kria_defconfig 
b/configs/xilinx_zynqmp_kria_defconfig
index ba42f0c7848..8ca80b67ee0 100644
--- a/configs/xilinx_zynqmp_kria_defconfig
+++ b/configs/xilinx_zynqmp_kria_defconfig
@@ -199,6 +199,7 @@ CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3_GENERIC=y
 CONFIG_USB_ULPI_VIEWPORT=y
 CONFIG_USB_ULPI=y
+CONFIG_USB_ONBOARD_HUB=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
 CONFIG_USB_GADGET=y
-- 
2.17.1



[PATCH 4/7] usb: onboard-hub: Add i2c initialization for usb5744 hub

2024-06-05 Thread Venkatesh Yadav Abbarapu
Add i2c initialization hook and set usb5744 platform
data with function having required i2c initialization sequence.

Apart from the USB command attach, prevent the hub from suspend.
when the “USB Attach with SMBUS (0xAA56)” command is issued to the hub,
the hub is getting enumerated and then it puts in a suspend mode.
This causes the hub to NAK any SMBUS access made by the SMBUS Master
during this period and not able to see the hub's slave address while
running the "i2c probe" command.

Prevent the MCU from the putting the HUB in suspend mode through register
write. The BYPASS_UDC_SUSPEND bit (Bit 3) of the RuntimeFlags2 register at
address 0x411D controls this aspect of the hub. The BYPASS_UDC_SUSPEND
bit in register 0x411Dh must be set to ensure that the MCU is always
enabled and ready to respond to SMBus runtime commands. This register
needs to be written before the USB attach command is issued.
The byte sequence is as follows:
Slave addr: 0x2d   00 00 05 00 01 41 1D 08
Slave addr: 0x2d   99 37 00
Slave addr: 0x2d   AA 56 00

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 common/usb_onboard_hub.c | 86 
 1 file changed, 86 insertions(+)

diff --git a/common/usb_onboard_hub.c b/common/usb_onboard_hub.c
index 50870285995..09ce452af1b 100644
--- a/common/usb_onboard_hub.c
+++ b/common/usb_onboard_hub.c
@@ -11,9 +11,15 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
+#define USB5744_COMMAND_ATTACH0x0056
+#define USB5744_COMMAND_ATTACH_LSB0xAA
+#define USB5744_CONFIG_REG_ACCESS 0x0037
+#define USB5744_CONFIG_REG_ACCESS_LSB 0x99
+
 struct onboard_hub {
struct udevice *vdd;
struct gpio_desc *reset_gpio;
@@ -21,8 +27,80 @@ struct onboard_hub {
 
 struct onboard_hub_data {
unsigned long reset_us;
+   int (*onboard_dev_i2c_init)(struct udevice *dev);
 };
 
+static int usb5744_i2c_init(struct udevice *dev)
+{
+   /*
+*  Prevent the MCU from the putting the HUB in suspend mode through 
register write.
+*  The BYPASS_UDC_SUSPEND bit (Bit 3) of the RuntimeFlags2 register at 
address
+*  0x411D controls this aspect of the hub.
+*  Format to write to hub registers via SMBus- 2D 00 00 05 00 01 41 1D 
08
+*  Byte 0: Address of slave 2D
+*  Byte 1: Memory address 00
+*  Byte 2: Memory address 00
+*  Byte 3: Number of bytes to write to memory
+*  Byte 4: Write configuration register (00)
+*  Byte 5: Write the number of data bytes (01- 1 data byte)
+*  Byte 6: LSB of register address 0x41
+*  Byte 7: MSB of register address 0x1D
+*  Byte 8: value to be written to the register
+*/
+   char data_buf[8] = {0x0, 0x5, 0x0, 0x1, 0x41, 0x1D, 0x08};
+   int ret, slave_addr;
+   u32 buf = USB5744_COMMAND_ATTACH;
+   u32 config_reg_access_buf = USB5744_CONFIG_REG_ACCESS;
+   struct dm_i2c_chip *i2c_chip;
+   struct ofnode_phandle_args phandle;
+   struct udevice *i2c_bus = NULL, *i2c_dev;
+
+   if (!dev_read_phandle_with_args(dev, "i2c-bus", NULL, 0, 0, )) {
+   ret = 
device_get_global_by_ofnode(ofnode_get_parent(phandle.node), _bus);
+   if (ret) {
+   dev_err(dev, "Failed to get i2c node, err: %d\n", ret);
+   return ret;
+   }
+   ret = ofnode_read_u32(phandle.node, "reg", _addr);
+   if (ret)
+   return ret;
+
+   ret = i2c_get_chip(i2c_bus, slave_addr, 1, _dev);
+   if (ret) {
+   debug("%s: can't find i2c chip device for addr %x\n", 
__func__,
+ slave_addr);
+   return ret;
+   }
+
+   i2c_chip = dev_get_parent_plat(i2c_dev);
+   if (i2c_chip) {
+   i2c_chip->flags &= ~DM_I2C_CHIP_WR_ADDRESS;
+   /* SMBus write command */
+   ret = dm_i2c_write(i2c_dev, 0, (uint8_t *)_buf, 8);
+   if (ret) {
+   dev_err(dev, "data_buf i2c_write failed, 
err:%d\n", ret);
+   return ret;
+   }
+
+   /* Configuration register access command */
+   ret = dm_i2c_write(i2c_dev, 
USB5744_CONFIG_REG_ACCESS_LSB,
+  (uint8_t *)_reg_access_buf, 
2);
+   if (ret) {
+   dev_err(dev, "config_reg_access i2c_write 
failed, err: %d\n", ret);
+   return ret;
+   }
+
+   /* USB Attach with SMBus */
+   ret = dm_i2c_write(i2c_dev, USB5744_COMMAND_ATTACH_LSB, 
(uint8_t *), 2);
+   

[PATCH 3/7] usb: onboard-hub: add support for Microchip USB5744

2024-06-05 Thread Venkatesh Yadav Abbarapu
Add support for the Microchip USB5744 USB3.0 and USB2.0 Hub.
The usb5744 driver trigger hub reset signal after soft reset.
The usb5744 hub need to reset after the phy initialization,
which toggles the gpio.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 common/usb_onboard_hub.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/common/usb_onboard_hub.c b/common/usb_onboard_hub.c
index 0cfaa90fce3..50870285995 100644
--- a/common/usb_onboard_hub.c
+++ b/common/usb_onboard_hub.c
@@ -88,11 +88,21 @@ static const struct onboard_hub_data usb2514_data = {
/* TBD */
 };
 
+static const struct onboard_hub_data usb5744_data = {
+   .reset_us = 1,
+};
+
 static const struct udevice_id usb_onboard_hub_ids[] = {
/* Use generic usbVID,PID dt-bindings (usb-device.yaml) */
{
.compatible = "usb424,2514", /* USB2514B USB 2.0 */
.data = (ulong)_data,
+   }, {
+   .compatible = "usb424,5744", /* USB5744 USB 3.0 */
+   .data = (ulong)_data,
+   }, {
+   .compatible = "usb424,2744", /* USB2744 USB 2.0 */
+   .data = (ulong)_data,
}
 };
 
-- 
2.17.1



[PATCH 2/7] usb: onboard-hub: Fix the return values of regulator APIs

2024-06-05 Thread Venkatesh Yadav Abbarapu
Use the regulator API's only if the config DM_REGULATOR is enabled.
Don't error out if there is no vdd regulator supply, as these are
optional properties.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 common/usb_onboard_hub.c | 22 ++
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/common/usb_onboard_hub.c b/common/usb_onboard_hub.c
index 2f6fb71935d..0cfaa90fce3 100644
--- a/common/usb_onboard_hub.c
+++ b/common/usb_onboard_hub.c
@@ -30,16 +30,22 @@ static int usb_onboard_hub_probe(struct udevice *dev)
struct onboard_hub *hub = dev_get_priv(dev);
int ret;
 
-   ret = device_get_supply_regulator(dev, "vdd-supply", >vdd);
-   if (ret) {
-   dev_err(dev, "can't get vdd-supply: %d\n", ret);
-   return ret;
+   if (CONFIG_IS_ENABLED(DM_REGULATOR)) {
+   ret = device_get_supply_regulator(dev, "vdd-supply",
+ >vdd);
+   if (ret && ret != -ENOENT) {
+   dev_err(dev, "Failed to get VDD regulator: %d\n", ret);
+   return ret;
+   }
+   if (hub->vdd) {
+   ret = regulator_set_enable_if_allowed(hub->vdd, true);
+   if (ret && ret != -ENOSYS) {
+   dev_err(dev, "Failed to enable VDD regulator: 
%d\n", ret);
+   return ret;
+   }
+   }
}
 
-   ret = regulator_set_enable_if_allowed(hub->vdd, true);
-   if (ret)
-   dev_err(dev, "can't enable vdd-supply: %d\n", ret);
-
hub->reset_gpio = devm_gpiod_get_optional(dev, "reset",
  GPIOD_IS_OUT | 
GPIOD_ACTIVE_LOW);
/* property is optional, don't return error! */
-- 
2.17.1



[PATCH 1/7] usb: onboard-hub: Add reset-gpio support

2024-06-05 Thread Venkatesh Yadav Abbarapu
As part of the reset, sets the direction of the pin to output before
toggling the pin. Delay of millisecond is added in between low and
high to meet the setup and hold time requirement of the reset.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 common/usb_onboard_hub.c | 44 +---
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/common/usb_onboard_hub.c b/common/usb_onboard_hub.c
index 89e18a2ddad..2f6fb71935d 100644
--- a/common/usb_onboard_hub.c
+++ b/common/usb_onboard_hub.c
@@ -7,17 +7,26 @@
  * Mostly inspired by Linux kernel v6.1 onboard_usb_hub driver
  */
 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 
 struct onboard_hub {
struct udevice *vdd;
+   struct gpio_desc *reset_gpio;
+};
+
+struct onboard_hub_data {
+   unsigned long reset_us;
 };
 
 static int usb_onboard_hub_probe(struct udevice *dev)
 {
+   struct onboard_hub_data *data =
+   (struct onboard_hub_data *)dev_get_driver_data(dev);
struct onboard_hub *hub = dev_get_priv(dev);
int ret;
 
@@ -31,7 +40,24 @@ static int usb_onboard_hub_probe(struct udevice *dev)
if (ret)
dev_err(dev, "can't enable vdd-supply: %d\n", ret);
 
-   return ret;
+   hub->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+ GPIOD_IS_OUT | 
GPIOD_ACTIVE_LOW);
+   /* property is optional, don't return error! */
+   if (hub->reset_gpio) {
+   ret = dm_gpio_set_value(hub->reset_gpio, 1);
+   if (ret)
+   return ret;
+
+   udelay(data->reset_us);
+
+   ret = dm_gpio_set_value(hub->reset_gpio, 0);
+   if (ret)
+   return ret;
+
+   udelay(data->reset_us);
+   }
+
+   return 0;
 }
 
 static int usb_onboard_hub_remove(struct udevice *dev)
@@ -39,6 +65,12 @@ static int usb_onboard_hub_remove(struct udevice *dev)
struct onboard_hub *hub = dev_get_priv(dev);
int ret;
 
+   if (hub->reset_gpio) {
+   struct gpio_desc *hub_reset_gpio = hub->reset_gpio;
+
+   dm_gpio_free(hub_reset_gpio->dev, hub_reset_gpio);
+   }
+
ret = regulator_set_enable_if_allowed(hub->vdd, false);
if (ret)
dev_err(dev, "can't disable vdd-supply: %d\n", ret);
@@ -46,10 +78,16 @@ static int usb_onboard_hub_remove(struct udevice *dev)
return ret;
 }
 
+static const struct onboard_hub_data usb2514_data = {
+   /* TBD */
+};
+
 static const struct udevice_id usb_onboard_hub_ids[] = {
/* Use generic usbVID,PID dt-bindings (usb-device.yaml) */
-   { .compatible = "usb424,2514" }, /* USB2514B USB 2.0 */
-   { }
+   {
+   .compatible = "usb424,2514", /* USB2514B USB 2.0 */
+   .data = (ulong)_data,
+   }
 };
 
 U_BOOT_DRIVER(usb_onboard_hub) = {
-- 
2.17.1



[PATCH 0/7] Add the USB5744 hub driver as per new DT binding

2024-06-05 Thread Venkatesh Yadav Abbarapu
Add the usb5744/usb2744 hub driver which does the reset gpio toggling
and the i2c initialization sequence.

Tested the USB5744/USB2744 usb hub for usb0, usb1 with the
DT nodes on KR260 board.

Venkatesh Yadav Abbarapu (7):
  usb: onboard-hub: Add reset-gpio support
  usb: onboard-hub: Fix the return values of regulator APIs
  usb: onboard-hub: add support for Microchip USB5744
  usb: onboard-hub: Add i2c initialization for usb5744 hub
  usb: onboard-hub: Bail out if peer hub is already probed
  configs: zynqmp_kria: Enable the USB onboard hub
  arm64: zynqmp: Update the usb5744 hub node as per binding

 arch/arm/dts/zynqmp-sck-kr-g-revA.dtso |  48 +++
 arch/arm/dts/zynqmp-sck-kr-g-revB.dtso |  48 +++
 arch/arm/dts/zynqmp-sck-kv-g-revA.dtso |  18 +++
 arch/arm/dts/zynqmp-sck-kv-g-revB.dtso |  25 +++-
 common/usb_onboard_hub.c   | 176 +++--
 configs/xilinx_zynqmp_kria_defconfig   |   1 +
 6 files changed, 304 insertions(+), 12 deletions(-)

-- 
2.17.1



[PATCH] mmc: Change the frequency to MMC_HS_52 when selecting hs400

2024-04-22 Thread Venkatesh Yadav Abbarapu
Per JESD84-B51 P47, host need to change frequency to <=52MHz
after setting HS_TIMING to 0x1, and host need to set the
8-bit DDR buswidth. Currently setting the frequency to 26MHz
and trying to switch 8-bit DDR buswidth resulting timeouts.

mmc dev 1 0
Select HS400 failed -110
switch to partitions #0, OK
mmc1(part 0) is current device

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mmc/mmc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 7b068c71ff..a2ed99aefe 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -962,8 +962,8 @@ static int mmc_set_card_speed(struct mmc *mmc, enum 
bus_mode mode,
 * Extended CSD. Reconfigure the controller to run at HS mode.
 */
if (hsdowngrade) {
-   mmc_select_mode(mmc, MMC_HS);
-   mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
+   mmc_select_mode(mmc, MMC_HS_52);
+   mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS_52), false);
}
 #endif
 
@@ -2043,7 +2043,7 @@ static int mmc_select_hs400(struct mmc *mmc)
}
 
/* Set back to HS */
-   mmc_set_card_speed(mmc, MMC_HS, true);
+   mmc_set_card_speed(mmc, MMC_HS_52, true);
 
err = mmc_hs400_prepare_ddr(mmc);
if (err)
-- 
2.17.1



[PATCH] soc: zynqmp: Add the IDcode for TEG variant

2024-04-02 Thread Venkatesh Yadav Abbarapu
ID code is added for zu3teg variant.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/soc/soc_xilinx_zynqmp.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/soc/soc_xilinx_zynqmp.c b/drivers/soc/soc_xilinx_zynqmp.c
index 786825d920..d8b4f172a3 100644
--- a/drivers/soc/soc_xilinx_zynqmp.c
+++ b/drivers/soc/soc_xilinx_zynqmp.c
@@ -44,6 +44,7 @@ enum {
ZYNQMP_VARIANT_DR = BIT(3),
ZYNQMP_VARIANT_DR_SE = BIT(4),
ZYNQMP_VARIANT_EG_SE = BIT(5),
+   ZYNQMP_VARIANT_TEG = BIT(6),
 };
 
 struct zynqmp_device {
@@ -74,6 +75,11 @@ static const struct zynqmp_device zynqmp_devices[] = {
.device = 3,
.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
},
+   {
+   .id = 0x04718093,
+   .device = 3,
+   .variants = ZYNQMP_VARIANT_TEG,
+   },
{
.id = 0x04721093,
.device = 4,
@@ -299,6 +305,8 @@ static int soc_xilinx_zynqmp_detect_machine(struct udevice 
*dev, u32 idcode,
strlcat(priv->machine, "dr", sizeof(priv->machine));
} else if (device->variants & ZYNQMP_VARIANT_DR_SE) {
strlcat(priv->machine, "dr_SE", sizeof(priv->machine));
+   } else if (device->variants & ZYNQMP_VARIANT_TEG) {
+   strlcat(priv->machine, "teg", sizeof(priv->machine));
}
 
return 0;
-- 
2.17.1



[PATCH] arm64: dts: zynqmp: make hw-ecc as the default ecc mode

2024-03-25 Thread Venkatesh Yadav Abbarapu
Except for Linux no other component (i.e., u-boot, fsbl
or BootRom) of the software stack supports software ecc
engine. So, make hw-ecc as the default ecc mode.
Update the same for mini u-boot nand configuration as well.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 arch/arm/dts/zynqmp-mini-nand.dts| 6 ++
 arch/arm/dts/zynqmp-zc1751-xm017-dc3.dts | 6 ++
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/arm/dts/zynqmp-mini-nand.dts 
b/arch/arm/dts/zynqmp-mini-nand.dts
index e0517cf460..5889d436ed 100644
--- a/arch/arm/dts/zynqmp-mini-nand.dts
+++ b/arch/arm/dts/zynqmp-mini-nand.dts
@@ -50,6 +50,12 @@
#size-cells = <1>;
arasan,has-mdma;
num-cs = <2>;
+   nand@0 {
+   reg = <0>;
+   #address-cells = <2>;
+   #size-cells = <1>;
+   nand-ecc-mode = "hw";
+   };
};
};
 };
diff --git a/arch/arm/dts/zynqmp-zc1751-xm017-dc3.dts 
b/arch/arm/dts/zynqmp-zc1751-xm017-dc3.dts
index b97f7ee8d4..48ab619472 100644
--- a/arch/arm/dts/zynqmp-zc1751-xm017-dc3.dts
+++ b/arch/arm/dts/zynqmp-zc1751-xm017-dc3.dts
@@ -136,8 +136,7 @@
reg = <0x0>;
#address-cells = <0x2>;
#size-cells = <0x1>;
-   nand-ecc-mode = "soft";
-   nand-ecc-algo = "bch";
+   nand-ecc-mode = "hw";
nand-rb = <0>;
label = "main-storage-0";
nand-ecc-step-size = <1024>;
@@ -173,8 +172,7 @@
reg = <0x1>;
#address-cells = <0x2>;
#size-cells = <0x1>;
-   nand-ecc-mode = "soft";
-   nand-ecc-algo = "bch";
+   nand-ecc-mode = "hw";
nand-rb = <0>;
label = "main-storage-1";
nand-ecc-step-size = <1024>;
-- 
2.17.1



[PATCH] xilinx: versal-net: Add support for saving env based on bootmode

2024-03-12 Thread Venkatesh Yadav Abbarapu
Enable saving variables to MMC(FAT) and SPI based on primary
bootmode. If bootmode is JTAG, dont save env anywhere(NOWHERE).

Enable ENV_FAT_DEVICE_AND_PART="0:auto" for versal-net platform as well.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 board/xilinx/versal-net/board.c  | 30 
 configs/xilinx_versal_net_virt_defconfig |  3 +++
 env/Kconfig  |  2 +-
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/board/xilinx/versal-net/board.c b/board/xilinx/versal-net/board.c
index 990ca1650a..aecaeb6574 100644
--- a/board/xilinx/versal-net/board.c
+++ b/board/xilinx/versal-net/board.c
@@ -371,3 +371,33 @@ int dram_init(void)
 void reset_cpu(void)
 {
 }
+
+enum env_location env_get_location(enum env_operation op, int prio)
+{
+   u8 bootmode = versal_net_get_bootmode();
+
+   if (prio)
+   return ENVL_UNKNOWN;
+
+   switch (bootmode) {
+   case EMMC_MODE:
+   case SD_MODE:
+   case SD1_LSHFT_MODE:
+   case SD_MODE1:
+   if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT))
+   return ENVL_FAT;
+   if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4))
+   return ENVL_EXT4;
+   return ENVL_NOWHERE;
+   case OSPI_MODE:
+   case QSPI_MODE_24BIT:
+   case QSPI_MODE_32BIT:
+   if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
+   return ENVL_SPI_FLASH;
+   return ENVL_NOWHERE;
+   case JTAG_MODE:
+   case SELECTMAP_MODE:
+   default:
+   return ENVL_NOWHERE;
+   }
+}
diff --git a/configs/xilinx_versal_net_virt_defconfig 
b/configs/xilinx_versal_net_virt_defconfig
index 29cebe2713..40c6a29a16 100644
--- a/configs/xilinx_versal_net_virt_defconfig
+++ b/configs/xilinx_versal_net_virt_defconfig
@@ -60,6 +60,9 @@ CONFIG_PARTITION_TYPE_GUID=y
 CONFIG_OF_BOARD=y
 CONFIG_DTB_RESELECT=y
 CONFIG_MULTI_DTB_FIT=y
+CONFIG_ENV_IS_NOWHERE=y
+CONFIG_ENV_IS_IN_FAT=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
 CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
diff --git a/env/Kconfig b/env/Kconfig
index 7885c8bf83..1f8e90af55 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -472,7 +472,7 @@ config ENV_FAT_DEVICE_AND_PART
string "Device and partition for where to store the environemt in FAT"
depends on ENV_IS_IN_FAT
default "0:1" if TI_COMMON_CMD_OPTIONS
-   default "0:auto" if ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL
+   default "0:auto" if ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL || 
ARCH_VERSAL_NET
default ":auto" if ARCH_SUNXI
default "0" if ARCH_AT91
help
-- 
2.17.1



[PATCH] arm64: gic: Add power up sequence for GIC-600

2024-03-06 Thread Venkatesh Yadav Abbarapu
Arm's GIC-600 features a Power Register (GICR_PWRR),
which needs to be programmed to enable redistributor
operation. Power on the redistributor and  wait until
the power on state is reflected by checking the bit
GICR_PWRR.RDPD == 0. While running U-Boot in EL3
without enabling this register, GICR_WAKER.ChildrenAsleep
bit is not getting cleared and loops infinitely.
This register(GICR_PWRR) must be programmed to mark the frame
as powered on, before accessing other registers in the frame.
Rest of initialization sequence remains the same.

ARM GIC-600 IP complies with ARM GICv3 architecture.
Enable this config if GIC-600 IP present.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 arch/arm/Kconfig |  9 +
 arch/arm/include/asm/gic.h   |  1 +
 arch/arm/lib/gic_64.S| 10 +-
 arch/arm/mach-versal-net/Kconfig |  3 +++
 4 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 01d6556c42..8374cb7acc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -122,6 +122,15 @@ config GIC_V3_ITS
  ARM GICV3 has limitation, once the LPI table is enabled, LPI
  configuration table can not be re-programmed, unless GICV3 reset.
 
+config GICV3_SUPPORT_GIC600
+   bool "ARM GICV3 GIC600 SUPPORT"
+   help
+ ARM GIC-600 IP complies with ARM GICv3 architecture, but among others,
+ implements a power control register in the Redistributor frame.This
+ register must be programmed to mark the frame as powered on, before
+ accessing other registers in the frame. Rest of initialization 
sequence
+ remains the same.
+
 config STATIC_RELA
bool
default y if ARM64
diff --git a/arch/arm/include/asm/gic.h b/arch/arm/include/asm/gic.h
index bd3a80cdf7..fb64ba076d 100644
--- a/arch/arm/include/asm/gic.h
+++ b/arch/arm/include/asm/gic.h
@@ -57,6 +57,7 @@
 #define GICR_TYPER 0x0008
 #define GICR_STATUSR   0x0010
 #define GICR_WAKER 0x0014
+#define GICR_PWRR  0x0024
 #define GICR_SETLPIR   0x0040
 #define GICR_CLRLPIR   0x0048
 #define GICR_SEIR  0x0068
diff --git a/arch/arm/lib/gic_64.S b/arch/arm/lib/gic_64.S
index 86cd882fc7..7fa48648d9 100644
--- a/arch/arm/lib/gic_64.S
+++ b/arch/arm/lib/gic_64.S
@@ -92,8 +92,16 @@ ENTRY(gic_init_secure_percpu)
add x9, x9, #(2 << 16)
b   1b
 
+2:
+#if defined(CONFIG_GICV3_SUPPORT_GIC600)
+mov w10, #0x0   /* Power on redistributor */
+str w10, [x9, GICR_PWRR]
+5:  ldr w10, [x9, GICR_PWRR]/* Wait until the power on state is 
reflected */
+tbnzw10, #1, 5b /* If RDPD == 0 then powered on */
+#endif
+
/* x9: ReDistributor Base Address of Current CPU */
-2: mov w10, #~0x2
+   mov w10, #~0x2
ldr w11, [x9, GICR_WAKER]
and w11, w11, w10   /* Clear ProcessorSleep */
str w11, [x9, GICR_WAKER]
diff --git a/arch/arm/mach-versal-net/Kconfig b/arch/arm/mach-versal-net/Kconfig
index edff5b039e..31d6443e9f 100644
--- a/arch/arm/mach-versal-net/Kconfig
+++ b/arch/arm/mach-versal-net/Kconfig
@@ -43,6 +43,9 @@ config SYS_MEM_RSVD_FOR_MMU
 config GICV3
def_bool y
 
+config GICV3_SUPPORT_GIC600
+   def_bool y
+
 config SYS_MALLOC_LEN
default 0x200
 
-- 
2.25.1



[PATCH v2] mtd: nand: arasan: Fix the crash caused by use after free

2024-03-05 Thread Venkatesh Yadav Abbarapu
The below exception observed on QEMU, as it doesn't support
NAND controller.

"Synchronous Abort" handler, esr 0x9605, far 0x17acfc878
elr: 0803ad40 lr : 0805f438 (reloc)
elr: 7fcb4d40 lr : 7fcd9438
x0 : 7bbfc880 x1 : ff10
x2 : 7fcf059c x3 : 7bbfc870
x4 : 7fd9a388 x5 : 00017acfc870
x6 :  x7 : 7bbfd0e0
x8 : 3dd4 x9 : 7bbeec0c
x10: 0001 x11: 3f8c
x12: 7bbeecfc x13: 7bbeeeb0
x14: 7bbeeeb0 x15: 7bbee474
x16: 7fcef18c x17: 
x18: 7bbf9d70 x19: 7bbfc888
x20: 7bbfc870 x21: 7fd68ddb
x22: ffed x23: 7bbfc878
x24:  x25: 
x26:  x27: 
x28:  x29: 7bbeed10

Code: 927ff8c1 924000c6 8b010065 f9400887 (f94004a2)
Resetting CPU ...

The crash is caused by the use after free.
Updating the correct return codes rather than hardcoding.
Fixes: 3dd0f8cccd6d ("mtd: nand: Remove hardcoded base address of nand")

Signed-off-by: Venkatesh Yadav Abbarapu 
---
Changes in v2:
- Updated the commit description.
---
 drivers/mtd/nand/raw/arasan_nfc.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/nand/raw/arasan_nfc.c 
b/drivers/mtd/nand/raw/arasan_nfc.c
index 0b1b91f771..ffcd963b3d 100644
--- a/drivers/mtd/nand/raw/arasan_nfc.c
+++ b/drivers/mtd/nand/raw/arasan_nfc.c
@@ -1232,7 +1232,7 @@ static int arasan_probe(struct udevice *dev)
struct nand_config *nand = >config;
struct mtd_info *mtd;
ofnode child;
-   int err = -1;
+   int ret;
const char *str;
 
info->reg = dev_read_addr_ptr(dev);
@@ -1259,9 +1259,10 @@ static int arasan_probe(struct udevice *dev)
writel(0x0, >reg->pgm_reg);
 
/* first scan to find the device and get the page size */
-   if (nand_scan_ident(mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL)) {
+   ret = nand_scan_ident(mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL);
+   if (ret) {
printf("%s: nand_scan_ident failed\n", __func__);
-   goto fail;
+   return ret;
}
 
str = ofnode_read_string(nand_chip->flash_node, "nand-ecc-mode");
@@ -1289,26 +1290,26 @@ static int arasan_probe(struct udevice *dev)
nand_chip->ecc.bytes = 0;
nand_chip->ecc.layout = _nand_oob_64;
} else {
-   if (arasan_nand_ecc_init(mtd)) {
+   ret = arasan_nand_ecc_init(mtd);
+   if (ret) {
printf("%s: nand_ecc_init failed\n", __func__);
-   goto fail;
+   return ret;
}
}
 
-   if (nand_scan_tail(mtd)) {
+   ret = nand_scan_tail(mtd);
+   if (ret) {
printf("%s: nand_scan_tail failed\n", __func__);
-   goto fail;
+   return ret;
}
 
-   if (nand_register(0, mtd)) {
+   ret = nand_register(0, mtd);
+   if (ret) {
printf("Nand Register Fail\n");
-   goto fail;
+   return ret;
}
 
-   return 0;
-fail:
-   free(nand);
-   return err;
+   return ret;
 }
 
 static const struct udevice_id arasan_nand_dt_ids[] = {
-- 
2.17.1



[PATCH v4] mtd: nand: arasan: Print warning for unsupported ecc modes

2024-03-05 Thread Venkatesh Yadav Abbarapu
Currently only hw ecc is supported in U-Boot. If any other ecc mode is
given in DT, it simply through an error. So better print
what is being done.

Revert this patch once soft ecc support is fixed in future.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
Changes in v2:
- Added the ecc mode check in the arasan driver itself.
Changes in v3:
- Skip the driver probe when sw-ecc mode is present in the device tree.
Changes in v4:
- Updated the commit description to through an error if other
than hw ecc mentioned in the DT.
- Added the NULL check.
---
 drivers/mtd/nand/raw/arasan_nfc.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mtd/nand/raw/arasan_nfc.c 
b/drivers/mtd/nand/raw/arasan_nfc.c
index 14766401bf..0b1b91f771 100644
--- a/drivers/mtd/nand/raw/arasan_nfc.c
+++ b/drivers/mtd/nand/raw/arasan_nfc.c
@@ -1233,6 +1233,7 @@ static int arasan_probe(struct udevice *dev)
struct mtd_info *mtd;
ofnode child;
int err = -1;
+   const char *str;
 
info->reg = dev_read_addr_ptr(dev);
mtd = nand_to_mtd(nand_chip);
@@ -1263,6 +1264,12 @@ static int arasan_probe(struct udevice *dev)
goto fail;
}
 
+   str = ofnode_read_string(nand_chip->flash_node, "nand-ecc-mode");
+   if (!str || strcmp(str, "hw") != 0) {
+   printf("%s ecc mode is not supported\n", str);
+   return -EINVAL;
+   }
+
nand_chip->ecc.mode = NAND_ECC_HW;
nand_chip->ecc.hwctl = NULL;
nand_chip->ecc.read_page = arasan_nand_read_page_hwecc;
-- 
2.17.1



[PATCH] arm64: zynqmp: Add usb4 to the boot targets

2024-03-05 Thread Venkatesh Yadav Abbarapu
USB4 has been added to the boot targets and
also add support to enable JTAG.

Signed-off-by: Shubhangi Shrikrushna Mahalle 

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 board/xilinx/zynqmp/zynqmp_kria.env | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/board/xilinx/zynqmp/zynqmp_kria.env 
b/board/xilinx/zynqmp/zynqmp_kria.env
index 0f940bd68f..7d3ad31226 100644
--- a/board/xilinx/zynqmp/zynqmp_kria.env
+++ b/board/xilinx/zynqmp/zynqmp_kria.env
@@ -44,7 +44,8 @@ usb_boot=usb start; if usb dev ${devnum}; then devtype=usb; 
run scan_dev_for_boo
 preboot=setenv boot_targets; setenv modeboot; run board_setup
 
 # SOM specific boot methods
-som_cc_boot=if test ${card1_name} = SCK-KV-G; then setenv boot_targets mmc1 
usb0 usb1 usb2 usb3 pxe dhcp && run distro_bootcmd; elif test ${card1_name} = 
SCK-KR-G; then setenv boot_targets usb0 usb1 usb2 usb3 pxe dhcp && run 
distro_bootcmd; else test ${card1_name} = SCK-KD-G; setenv boot_targets usb0 
usb1 usb2 usb3 pxe dhcp && run distro_bootcmd; fi;"
+usb_boot_devices='usb0 usb1 usb2 usb3 usb4'
+som_cc_boot=if test ${card1_name} = SCK-KV-G; then setenv boot_targets mmc1 
${usb_boot_devices} pxe dhcp jtag && run distro_bootcmd; elif test 
${card1_name} = SCK-KR-G; then setenv boot_targets ${usb_boot_devices} pxe dhcp 
jtag && run distro_bootcmd; else test ${card1_name} = SCK-KD-G; setenv 
boot_targets ${usb_boot_devices} pxe dhcp jtag && run distro_bootcmd; fi;"
 som_mmc_boot=setenv boot_targets mmc0 && run distro_bootcmd
 
 k26_starter=SMK-K26-XCL2G
-- 
2.25.1



[PATCH v11 7/8] spi: Add the spi advance options for non SPL

2024-03-03 Thread Venkatesh Yadav Abbarapu
Adding the config option SPI_ADVANCE for non SPL code.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/Kconfig  | 7 +++
 drivers/spi/spi-uclass.c | 3 ++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 69b184b0d9..e5640bcbe4 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -50,6 +50,13 @@ config SPI_DIRMAP
  improvements as it automates the whole process of sending SPI memory
  operations every time a new region is accessed.
 
+config SPI_ADVANCE
+   bool "Enable the advance feature"
+   default y
+   help
+ Enable the SPI advance feature support. By default this is set to y.
+ If you intend not to use the advance feature support you should say n 
here.
+
 if DM_SPI
 
 config ALTERA_SPI
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 992394c295..736159aa47 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -447,11 +447,12 @@ int _spi_get_bus_and_cs(int busnum, int cs, int speed, 
int mode,
slave = dev_get_parent_priv(dev);
bus_data = dev_get_uclass_priv(bus);
 
+#if CONFIG_IS_ENABLED(SPI_ADVANCE)
if ((dev_read_bool(dev, "parallel-memories")) && !slave->multi_cs_cap) {
dev_err(dev, "controller doesn't support multi CS\n");
return -EINVAL;
}
-
+#endif
/*
 * In case the operation speed is not yet established by
 * dm_spi_claim_bus() ensure the bus is configured properly.
-- 
2.17.1



[PATCH v11 8/8] config: xea: Enable the SPI_ADVANCE config option

2024-03-03 Thread Venkatesh Yadav Abbarapu
Disable the config SPI_ADVANCE, as getting the below error
../arm-xilinx-linux-gnueabi-ld.bfd.real: drivers/core/ofnode.o: in function
`ofnode_get_property':
/u-boot/drivers/core/ofnode.c:1185: undefined reference to `fdt_getprop'
make[1]: *** [scripts/Makefile.spl:527: spl/u-boot-spl] Error 1

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 configs/imx28_xea_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/imx28_xea_defconfig b/configs/imx28_xea_defconfig
index 64a0561a34..36d3e73d0a 100644
--- a/configs/imx28_xea_defconfig
+++ b/configs/imx28_xea_defconfig
@@ -122,6 +122,7 @@ CONFIG_SPECIFY_CONSOLE_INDEX=y
 CONFIG_DM_SERIAL=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
+# CONFIG_SPI_ADVANCE is not set
 CONFIG_MXS_SPI=y
 CONFIG_SPL_CRC8=y
 # CONFIG_SPL_OF_LIBFDT is not set
-- 
2.17.1



[PATCH v11 6/8] spi: zynq_qspi: Add parallel memories support in QSPI driver

2024-03-03 Thread Venkatesh Yadav Abbarapu
Add support for parallel memories in zynq_qspi.c driver. In case of
parallel memories STRIPE bit is set and sent to the qspi ip, which will
send data bits to both the flashes in parallel. However for few commands
we should not use stripe, instead send same data to both the flashes.
Those commands are exclueded by using zynqmp_qspi_update_stripe().

Also update copyright info for this file.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/zynq_qspi.c | 113 
 1 file changed, 102 insertions(+), 11 deletions(-)

diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c
index bc82acd0b6..41f7ae2ab2 100644
--- a/drivers/spi/zynq_qspi.c
+++ b/drivers/spi/zynq_qspi.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2013 Xilinx, Inc.
+ * (C) Copyright 2013 - 2022, Xilinx, Inc.
  * (C) Copyright 2015 Jagan Teki 
+ * (C) Copyright 2023, Advanced Micro Devices, Inc.
  *
  * Xilinx Zynq Quad-SPI(QSPI) controller driver (master mode only)
  */
@@ -13,10 +14,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include "../mtd/spi/sf_internal.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -42,6 +45,21 @@ DECLARE_GLOBAL_DATA_PTR;
 #define ZYNQ_QSPI_TXD_00_01_OFFSET 0x80/* Transmit 1-byte inst */
 #define ZYNQ_QSPI_TXD_00_10_OFFSET 0x84/* Transmit 2-byte inst */
 #define ZYNQ_QSPI_TXD_00_11_OFFSET 0x88/* Transmit 3-byte inst */
+#define ZYNQ_QSPI_FR_QOUT_CODE 0x6B/* read instruction code */
+
+#define QSPI_SELECT_LOWER_CSBIT(0)
+#define QSPI_SELECT_UPPER_CSBIT(1)
+
+/*
+ * QSPI Linear Configuration Register
+ *
+ * It is named Linear Configuration but it controls other modes when not in
+ * linear mode also.
+ */
+#define ZYNQ_QSPI_LCFG_TWO_MEM_MASK 0x4000 /* QSPI Enable Bit Mask */
+#define ZYNQ_QSPI_LCFG_SEP_BUS_MASK 0x2000 /* QSPI Enable Bit Mask */
+#define ZYNQ_QSPI_LCFG_U_PAGE   0x1000 /* QSPI Upper memory set */
+#define ZYNQ_QSPI_LCFG_DUMMY_SHIFT  8
 
 #define ZYNQ_QSPI_TXFIFO_THRESHOLD 1   /* Tx FIFO threshold level*/
 #define ZYNQ_QSPI_RXFIFO_THRESHOLD 32  /* Rx FIFO threshold level */
@@ -101,7 +119,11 @@ struct zynq_qspi_priv {
int bytes_to_transfer;
int bytes_to_receive;
unsigned int is_inst;
+   unsigned int is_parallel;
+   unsigned int is_stacked;
+   unsigned int u_page;
unsigned cs_change:1;
+   unsigned is_strip:1;
 };
 
 static int zynq_qspi_of_to_plat(struct udevice *bus)
@@ -112,7 +134,6 @@ static int zynq_qspi_of_to_plat(struct udevice *bus)
 
plat->regs = (struct zynq_qspi_regs *)fdtdec_get_addr(blob,
  node, "reg");
-
return 0;
 }
 
@@ -147,6 +168,9 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
/* Disable Interrupts */
writel(ZYNQ_QSPI_IXR_ALL_MASK, >idr);
 
+   /* Disable linear mode as the boot loader may have used it */
+   writel(0x0, >lqspicfg);
+
/* Clear the TX and RX threshold reg */
writel(ZYNQ_QSPI_TXFIFO_THRESHOLD, >txftr);
writel(ZYNQ_QSPI_RXFIFO_THRESHOLD, >rxftr);
@@ -164,12 +188,11 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
confr |= ZYNQ_QSPI_CR_IFMODE_MASK | ZYNQ_QSPI_CR_MCS_MASK |
ZYNQ_QSPI_CR_PCS_MASK | ZYNQ_QSPI_CR_FW_MASK |
ZYNQ_QSPI_CR_MSTREN_MASK;
-   writel(confr, >cr);
 
-   /* Disable the LQSPI feature */
-   confr = readl(>lqspicfg);
-   confr &= ~ZYNQ_QSPI_LQSPICFG_LQMODE_MASK;
-   writel(confr, >lqspicfg);
+   if (priv->is_stacked)
+   confr |= 0x10;
+
+   writel(confr, >cr);
 
/* Enable SPI */
writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, >enr);
@@ -181,6 +204,7 @@ static int zynq_qspi_child_pre_probe(struct udevice *bus)
struct zynq_qspi_priv *priv = dev_get_priv(bus->parent);
 
priv->max_hz = slave->max_hz;
+   slave->multi_cs_cap = true;
 
return 0;
 }
@@ -363,8 +387,8 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv 
*priv, u32 size)
unsigned len, offset;
struct zynq_qspi_regs *regs = priv->regs;
static const unsigned offsets[4] = {
-   ZYNQ_QSPI_TXD_00_00_OFFSET, ZYNQ_QSPI_TXD_00_01_OFFSET,
-   ZYNQ_QSPI_TXD_00_10_OFFSET, ZYNQ_QSPI_TXD_00_11_OFFSET };
+   ZYNQ_QSPI_TXD_00_01_OFFSET, ZYNQ_QSPI_TXD_00_10_OFFSET,
+   ZYNQ_QSPI_TXD_00_11_OFFSET, ZYNQ_QSPI_TXD_00_00_OFFSET };
 
while ((fifocount < size) &&
(priv->bytes_to_transfer > 0)) {
@@ -386,7 +410,11 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv 
*priv, u32 size)
return;
  

[PATCH v11 3/8] mtd: spi-nor: Add parallel and stacked memories support in read_bar and write_bar

2024-03-03 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Add support for parallel memories and stacked memories configuration
in read_bar and write_bar functions.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 55 +-
 1 file changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 9c55b424e1..faf02c7778 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -909,12 +909,32 @@ static int clean_bar(struct spi_nor *nor)
 
 static int write_bar(struct spi_nor *nor, u32 offset)
 {
-   u8 cmd, bank_sel;
+   u8 cmd, bank_sel, upage_curr;
int ret;
+   struct mtd_info *mtd = >mtd;
+
+   /* Wait until previous write command is finished */
+   if (spi_nor_wait_till_ready(nor))
+   return 1;
+
+   if (nor->flags & (SNOR_F_HAS_PARALLEL | SNOR_F_HAS_STACKED) &&
+   mtd->size <= SZ_32M)
+   return 0;
+
+   if (mtd->size <= SZ_16M)
+   return 0;
+
+   offset = offset % (u32)mtd->size;
+   bank_sel = offset >> 24;
 
-   bank_sel = offset / SZ_16M;
-   if (bank_sel == nor->bank_curr)
-   goto bar_end;
+   upage_curr = nor->spi->flags & SPI_XFER_U_PAGE;
+
+   if (!(nor->flags & SNOR_F_HAS_STACKED) && bank_sel == nor->bank_curr)
+   return 0;
+   else if (upage_curr == nor->upage_prev && bank_sel == nor->bank_curr)
+   return 0;
+
+   nor->upage_prev = upage_curr;
 
cmd = nor->bank_write_cmd;
write_enable(nor);
@@ -924,15 +944,19 @@ static int write_bar(struct spi_nor *nor, u32 offset)
return ret;
}
 
-bar_end:
nor->bank_curr = bank_sel;
-   return nor->bank_curr;
+
+   return write_disable(nor);
 }
 
 static int read_bar(struct spi_nor *nor, const struct flash_info *info)
 {
u8 curr_bank = 0;
int ret;
+   struct mtd_info *mtd = >mtd;
+
+   if (mtd->size <= SZ_16M)
+   return 0;
 
switch (JEDEC_MFR(info)) {
case SNOR_MFR_SPANSION:
@@ -944,15 +968,30 @@ static int read_bar(struct spi_nor *nor, const struct 
flash_info *info)
nor->bank_write_cmd = SPINOR_OP_WREAR;
}
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   nor->spi->flags |= SPI_XFER_LOWER;
+
ret = nor->read_reg(nor, nor->bank_read_cmd,
-   _bank, 1);
+   _bank, 1);
if (ret) {
debug("SF: fail to read bank addr register\n");
return ret;
}
nor->bank_curr = curr_bank;
 
-   return 0;
+   // Make sure both chips use the same BAR
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   write_enable(nor);
+   ret = nor->write_reg(nor, nor->bank_write_cmd, _bank, 1);
+   if (ret)
+   return ret;
+
+   ret = write_disable(nor);
+   if (ret)
+   return ret;
+   }
+
+   return ret;
 }
 #endif
 
-- 
2.17.1



[PATCH v11 5/8] spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver

2024-03-03 Thread Venkatesh Yadav Abbarapu
Add support for parallel memories in zynqmp_gqspi.c driver. In case of
parallel memories STRIPE bit is set and sent to the qspi ip, which will
send data bits to both the flashes in parallel. However for few commands
we should not use stripe, instead send same data to both the flashes.
Those commands are exclueded by using zynqmp_qspi_update_stripe().

Also update copyright info for this file.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/zynqmp_gqspi.c | 141 -
 include/spi.h  |   4 ++
 2 files changed, 129 insertions(+), 16 deletions(-)

diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index a323994fb2..dedf8270a8 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2018 Xilinx
- *
+ * (C) Copyright 2013 - 2022, Xilinx, Inc.
+ * (C) Copyright 2023, Advanced Micro Devices, Inc.
  * Xilinx ZynqMP Generic Quad-SPI(QSPI) controller driver(master mode only)
  */
 
@@ -25,6 +25,8 @@
 #include 
 #include 
 #include 
+#include 
+#include "../mtd/spi/sf_internal.h"
 #include 
 
 #define GQSPI_GFIFO_STRT_MODE_MASK BIT(29)
@@ -88,6 +90,9 @@
 #define SPI_XFER_ON_LOWER  1
 #define SPI_XFER_ON_UPPER  2
 
+#define GQSPI_SELECT_LOWER_CS  BIT(0)
+#define GQSPI_SELECT_UPPER_CS  BIT(1)
+
 #define GQSPI_DMA_ALIGN0x4
 #define GQSPI_MAX_BAUD_RATE_VAL7
 #define GQSPI_DFLT_BAUD_RATE_VAL   2
@@ -183,13 +188,14 @@ struct zynqmp_qspi_priv {
int bytes_to_transfer;
int bytes_to_receive;
const struct spi_mem_op *op;
+   unsigned int is_parallel;
+   unsigned int u_page;
+   unsigned int bus;
+   unsigned int stripe;
+   unsigned int flags;
+   u32 max_hz;
 };
 
-__weak int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 
value)
-{
-   return 0;
-}
-
 static int zynqmp_qspi_of_to_plat(struct udevice *bus)
 {
struct zynqmp_qspi_plat *plat = dev_get_plat(bus);
@@ -234,8 +240,30 @@ static u32 zynqmp_qspi_bus_select(struct zynqmp_qspi_priv 
*priv)
 {
u32 gqspi_fifo_reg = 0;
 
-   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
-GQSPI_GFIFO_CS_LOWER;
+   if (priv->is_parallel) {
+   if (priv->bus == SPI_XFER_ON_BOTH)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_CS_UPPER |
+GQSPI_GFIFO_CS_LOWER;
+   else if (priv->bus == SPI_XFER_ON_LOWER)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_UPPER |
+GQSPI_GFIFO_CS_LOWER;
+   else if (priv->bus == SPI_XFER_ON_UPPER)
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_CS_LOWER |
+GQSPI_GFIFO_CS_UPPER;
+   else
+   debug("Wrong Bus selection:0x%x\n", priv->bus);
+   } else {
+   if (priv->u_page)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_UPPER;
+   else
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_LOWER;
+   }
 
return gqspi_fifo_reg;
 }
@@ -295,8 +323,15 @@ static void zynqmp_qspi_chipselect(struct zynqmp_qspi_priv 
*priv, int is_on)
gqspi_fifo_reg |= GQSPI_SPI_MODE_SPI |
  GQSPI_IMD_DATA_CS_ASSERT;
} else {
-   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS;
-   gqspi_fifo_reg |= GQSPI_IMD_DATA_CS_DEASSERT;
+   if (priv->is_parallel) {
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_LOW_BUS;
+   } else if (priv->u_page) {
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS;
+   } else {
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS;
+   gqspi_fifo_reg |= GQSPI_IMD_DATA_CS_DEASSERT;
+   }
}
 
zynqmp_qspi_fill_gen_fifo(priv, gqspi_fifo_reg);
@@ -366,12 +401,13 @@ static int zynqmp_qspi_set_speed(struct udevice *bus, 
uint speed)
 
log_debug("%s, Speed: %d, Max: %d\n", __func__, speed, plat->frequency);
 
-   if (speed > plat->frequency)
-   speed = plat->frequency;
+   /*
+* If speed == 0 or speed > max freq, then set speed to highest
+*/
+   if (!speed || speed > priv->max_hz)
+   speed = pr

[PATCH v11 4/8] spi: spi-uclass: Read chipselect and restrict capabilities

2024-03-03 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Read chipselect properties from DT which are populated using 'reg'
property and save it in plat->cs[] array for later use.

Also read multi chipselect capability which is used for
parallel-memories and return errors if they are passed on using DT but
driver is not capable of handling it.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/sandbox.c|  2 +-
 drivers/spi/altera_spi.c |  4 ++--
 drivers/spi/atcspi200_spi.c  |  2 +-
 drivers/spi/ath79_spi.c  |  2 +-
 drivers/spi/atmel_spi.c  |  6 +++---
 drivers/spi/bcm63xx_hsspi.c  | 42 ++--
 drivers/spi/bcm63xx_spi.c|  6 +++---
 drivers/spi/bcmbca_hsspi.c   | 34 ++---
 drivers/spi/cf_spi.c |  6 +++---
 drivers/spi/davinci_spi.c|  8 +++
 drivers/spi/fsl_dspi.c   | 18 
 drivers/spi/fsl_espi.c   |  4 ++--
 drivers/spi/fsl_qspi.c   |  4 ++--
 drivers/spi/gxp_spi.c|  2 +-
 drivers/spi/mpc8xx_spi.c |  4 ++--
 drivers/spi/mpc8xxx_spi.c| 10 -
 drivers/spi/mscc_bb_spi.c|  4 ++--
 drivers/spi/mxc_spi.c|  6 +++---
 drivers/spi/npcm_fiu_spi.c   | 14 ++--
 drivers/spi/nxp_fspi.c   |  2 +-
 drivers/spi/octeon_spi.c |  2 +-
 drivers/spi/omap3_spi.c  |  4 ++--
 drivers/spi/pic32_spi.c  |  2 +-
 drivers/spi/rk_spi.c |  4 ++--
 drivers/spi/rockchip_sfc.c   |  2 +-
 drivers/spi/spi-aspeed-smc.c | 28 
 drivers/spi/spi-mxic.c   |  6 +++---
 drivers/spi/spi-qup.c|  4 ++--
 drivers/spi/spi-sifive.c |  6 +++---
 drivers/spi/spi-sn-f-ospi.c  |  2 +-
 drivers/spi/spi-sunxi.c  |  6 +++---
 drivers/spi/spi-synquacer.c  |  4 ++--
 drivers/spi/spi-uclass.c | 33 +++-
 drivers/spi/stm32_qspi.c |  2 +-
 drivers/spi/stm32_spi.c  |  4 ++--
 drivers/spi/ti_qspi.c| 14 ++--
 drivers/spi/xilinx_spi.c |  6 +++---
 drivers/spi/zynq_qspi.c  |  6 +++---
 drivers/spi/zynq_spi.c   |  6 +++---
 include/spi.h|  8 ++-
 lib/acpi/acpi_device.c   |  2 +-
 41 files changed, 180 insertions(+), 151 deletions(-)

diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 4fe547171a..72036d5a88 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -139,7 +139,7 @@ static int sandbox_sf_probe(struct udevice *dev)
return ret;
}
slave_plat = dev_get_parent_plat(dev);
-   cs = slave_plat->cs;
+   cs = slave_plat->cs[0];
debug("found at cs %d\n", cs);
 
if (!pdata->filename) {
diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c
index 989679e881..48782f81c1 100644
--- a/drivers/spi/altera_spi.c
+++ b/drivers/spi/altera_spi.c
@@ -96,7 +96,7 @@ static int altera_spi_xfer(struct udevice *dev, unsigned int 
bitlen,
uint32_t reg, data, start;
 
debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
- dev_seq(bus), slave_plat->cs, bitlen, bytes, flags);
+ dev_seq(bus), slave_plat->cs[0], bitlen, bytes, flags);
 
if (bitlen == 0)
goto done;
@@ -111,7 +111,7 @@ static int altera_spi_xfer(struct udevice *dev, unsigned 
int bitlen,
readl(>rxdata);
 
if (flags & SPI_XFER_BEGIN)
-   spi_cs_activate(dev, slave_plat->cs);
+   spi_cs_activate(dev, slave_plat->cs[0]);
 
while (bytes--) {
if (txp)
diff --git a/drivers/spi/atcspi200_spi.c b/drivers/spi/atcspi200_spi.c
index 70cb242cd3..3d8494acfd 100644
--- a/drivers/spi/atcspi200_spi.c
+++ b/drivers/spi/atcspi200_spi.c
@@ -321,7 +321,7 @@ static int atcspi200_spi_claim_bus(struct udevice *dev)
struct udevice *bus = dev->parent;
struct nds_spi_slave *ns = dev_get_priv(bus);
 
-   if (slave_plat->cs >= ns->num_cs) {
+   if (slave_plat->cs[0] >= ns->num_cs) {
printf("Invalid SPI chipselect\n");
return -EINVAL;
}
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
index 205567ef54..ad10cec2a6 100644
--- a/drivers/spi/ath79_spi.c
+++ b/drivers/spi/ath79_spi.c
@@ -74,7 +74,7 @@ static int ath79_spi_xfer(struct udevice *dev, unsigned int 
bitlen,
if (restbits)
bytes++;
 
-   out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs));
+   out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs[0]));
while (bytes > 0) {
bytes--;
curbyte = 0;
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index d4f0c4c448..5702d6c138 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -126,7 +126,7 @@ static int atmel_spi_claim_bus(struct udevice *dev)
struct atmel_spi_priv *priv = dev_get

[PATCH v11 2/8] mtd: spi-nor: Add parallel memories support for read_sr and read_fsr

2024-03-03 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Add support for parallel memories flash configuration in read status
register and read flag status register functions.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 50 --
 1 file changed, 36 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index cbcc1d1a31..9c55b424e1 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -462,8 +462,9 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, 
loff_t to, size_t len,
 }
 
 /*
- * Read the status register, returning its value in the location
- * Return the status register value.
+ * Return the status register value. If the chip is parallel, then the
+ * read will be striped, so we should read 2 bytes to get the sr
+ * register value from both of the parallel chips.
  * Returns negative if error occurred.
  */
 static int read_sr(struct spi_nor *nor)
@@ -495,18 +496,29 @@ static int read_sr(struct spi_nor *nor)
if (spi_nor_protocol_is_dtr(nor->reg_proto))
op.data.nbytes = 2;
 
-   ret = spi_nor_read_write_reg(nor, , val);
-   if (ret < 0) {
-   pr_debug("error %d reading SR\n", (int)ret);
-   return ret;
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   op.data.nbytes = 2;
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
+   val[0] |= val[1];
+   } else {
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
}
 
-   return *val;
+   return val[0];
 }
 
 /*
- * Read the flag status register, returning its value in the location
- * Return the status register value.
+ * Return the flag status register value. If the chip is parallel, then
+ * the read will be striped, so we should read 2 bytes to get the fsr
+ * register value from both of the parallel chips.
  * Returns negative if error occurred.
  */
 static int read_fsr(struct spi_nor *nor)
@@ -538,13 +550,23 @@ static int read_fsr(struct spi_nor *nor)
if (spi_nor_protocol_is_dtr(nor->reg_proto))
op.data.nbytes = 2;
 
-   ret = spi_nor_read_write_reg(nor, , val);
-   if (ret < 0) {
-   pr_debug("error %d reading FSR\n", ret);
-   return ret;
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   op.data.nbytes = 2;
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
+   val[0] &= val[1];
+   } else {
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading FSR\n", ret);
+   return ret;
+   }
}
 
-   return *val;
+   return val[0];
 }
 
 /*
-- 
2.17.1



[PATCH v11 1/8] mtd: spi-nor: Add parallel and stacked memories support

2024-03-03 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

In parallel mode, the current implementation assumes that a maximum of
two flashes are connected. The QSPI controller splits the data evenly
between both the flashes so, both the flashes that are connected in
parallel mode should be identical.
During each operation SPI-NOR sets 0th bit for CS0 & 1st bit for CS1 in
nor->flags.

In stacked mode the current implementation assumes that a maximum of two
flashes are connected and both the flashes are of same make but can
differ in sizes. So, except the sizes all other flash parameters of both
the flashes are identical

Spi-nor will pass on the appropriate flash select flag to low level
driver, and it will select pass all the data to that particular flash.

Write operation in parallel mode are performed in page size * 2 chunks as
each write operation results in writing both the flashes. For doubling
the address space each operation is performed at addr/2 flash offset,
where addr is the address specified by the user.

Similarly for read and erase operations it will read from both flashes,
so size and offset are divided by 2 and send to flash.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 294 +
 include/linux/mtd/spi-nor.h|  12 ++
 include/spi.h  |  11 ++
 3 files changed, 289 insertions(+), 28 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index f86003ca8c..cbcc1d1a31 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -663,12 +663,17 @@ static u8 spi_nor_convert_3to4_erase(u8 opcode)
 static void spi_nor_set_4byte_opcodes(struct spi_nor *nor,
  const struct flash_info *info)
 {
+   bool shift = 0;
+
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   shift = 1;
+
/* Do some manufacturer fixups first */
switch (JEDEC_MFR(info)) {
case SNOR_MFR_SPANSION:
/* No small sector erase for 4-byte command set */
nor->erase_opcode = SPINOR_OP_SE;
-   nor->mtd.erasesize = info->sector_size;
+   nor->mtd.erasesize = info->sector_size << shift;
break;
 
default:
@@ -989,8 +994,8 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 
addr)
 static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
+   u32 addr, len, rem, offset;
bool addr_known = false;
-   u32 addr, len, rem;
int ret, err;
 
dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
@@ -1015,6 +1020,19 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
ret = -EINTR;
goto erase_err;
}
+
+   offset = addr;
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   offset /= 2;
+
+   if (nor->flags & SNOR_F_HAS_STACKED) {
+   if (offset >= (mtd->size / 2)) {
+   offset = offset - (mtd->size / 2);
+   nor->spi->flags |= SPI_XFER_U_PAGE;
+   } else {
+   nor->spi->flags &= ~SPI_XFER_U_PAGE;
+   }
+   }
 #ifdef CONFIG_SPI_FLASH_BAR
ret = write_bar(nor, addr);
if (ret < 0)
@@ -1420,6 +1438,9 @@ static const struct flash_info *spi_nor_read_id(struct 
spi_nor *nor)
u8  id[SPI_NOR_MAX_ID_LEN];
const struct flash_info *info;
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   nor->spi->flags |= SPI_XFER_LOWER;
+
tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
if (tmp < 0) {
dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp);
@@ -1444,28 +1465,67 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t 
from, size_t len,
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
int ret;
+   loff_t offset = from;
+   u32 read_len = 0;
+   u32 rem_bank_len = 0;
+   u8 bank;
+   bool is_ofst_odd = false;
 
dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
 
+   if ((nor->flags & SNOR_F_HAS_PARALLEL) && (offset & 1)) {
+   /* We can hit this case when we use file system like ubifs */
+   from--;
+   len++;
+   is_ofst_odd = true;
+   }
+
while (len) {
-   loff_t addr = from;
-   size_t read_len = len;
+   if (nor->addr_width == 3) {
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+  

[PATCH v11 0/8] spi-nor: Add parallel and stacked memories support

2024-03-03 Thread Venkatesh Yadav Abbarapu
This series adds support for Xilinx qspi parallel and stacked memeories.

In parallel mode, the current implementation assumes that a maximum of
two flashes are connected. The QSPI controller splits the data evenly
between both the flashes so, both the flashes that are connected in
parallel mode should be identical.
During each operation SPI-NOR sets 0th bit for CS0 & 1st bit for CS1 in
nor->flags.

In stacked mode the current implementation assumes that a maximum of two
flashes are connected and both the flashes are of same make but can
differ in sizes. So, except the sizes all other flash parameters of both
the flashes are identical.

Spi-nor will pass on the appropriate flash select flag to low level driver,
and it will select pass all the data to that particular flash.

Write operation in parallel mode are performed in page size * 2 chunks as
each write operation results in writing both the flashes. For doubling the
address space each operation is performed at addr/2 flash offset, where addr
is the address specified by the user.

Similarly for read and erase operations it will read from both flashes, so
size and offset are divided by 2 and send to flash.

Changes in v2:
- Fixed the compilation issues.
Changes in v3:
- Fixed the CI issues.
Changes in v4:
- Removed the dio,dummy_bytes variables from zynq_qspi driver.
- Fix the compilation issue by including the DM_SPI config.
Changes in v5:
- Fixed the issue reported by buildman.
Changes in v6:
- Fixed the issues reported while running the sandbox test cases.
Changes in v7:
- Fixed the issues reported while running these da850evm_defconfig,
  imx28_xea_defconfig configs.
- Fixed the issue when DM_SPI config is disabled.
- Fixed the issue while running the sandbox_noinst_defconfig with spl
  ./spl/u-boot-spl -d arch/sandbox/dts/test.dtb
   jedec_spi_nor spi.bin@0: has no valid 'reg' property (-12)
   jedec_spi_nor spi.bin@1: has no valid 'reg' property (-12)
   ### ERROR ### Please RESET the board ###
Changes in v8:
- Fixed the compilation issue with imx28_xea_defconfig.
- Fixed the SPL size issue with the axm and taurus defconfigs.
- Rebased the patches on top of next branch.
Changes in v9:
- Updated the commit log why SPL_FIT is being enabled.
Changes in v10:
- Added the new config SPI_ADVANCE to fix the issue while enabling
imx28_xea_defconfig.
Changes in v11:
- Removed the unused variable, corrected the type of variable and 
replaced memcpy with memmove.

Ashok Reddy Soma (4):
  mtd: spi-nor: Add parallel and stacked memories support
  mtd: spi-nor: Add parallel memories support for read_sr and read_fsr
  mtd: spi-nor: Add parallel and stacked memories support in read_bar
and write_bar
  spi: spi-uclass: Read chipselect and restrict capabilities

Venkatesh Yadav Abbarapu (4):
  spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver
  spi: zynq_qspi: Add parallel memories support in QSPI driver
  spi: Add the spi advance options for non SPL
  config: xea: Enable the SPI_ADVANCE config option

 configs/imx28_xea_defconfig|   1 +
 drivers/mtd/spi/sandbox.c  |   2 +-
 drivers/mtd/spi/spi-nor-core.c | 399 -
 drivers/spi/Kconfig|   7 +
 drivers/spi/altera_spi.c   |   4 +-
 drivers/spi/atcspi200_spi.c|   2 +-
 drivers/spi/ath79_spi.c|   2 +-
 drivers/spi/atmel_spi.c|   6 +-
 drivers/spi/bcm63xx_hsspi.c|  42 ++--
 drivers/spi/bcm63xx_spi.c  |   6 +-
 drivers/spi/bcmbca_hsspi.c |  34 +--
 drivers/spi/cf_spi.c   |   6 +-
 drivers/spi/davinci_spi.c  |   8 +-
 drivers/spi/fsl_dspi.c |  18 +-
 drivers/spi/fsl_espi.c |   4 +-
 drivers/spi/fsl_qspi.c |   4 +-
 drivers/spi/gxp_spi.c  |   2 +-
 drivers/spi/mpc8xx_spi.c   |   4 +-
 drivers/spi/mpc8xxx_spi.c  |  10 +-
 drivers/spi/mscc_bb_spi.c  |   4 +-
 drivers/spi/mxc_spi.c  |   6 +-
 drivers/spi/npcm_fiu_spi.c |  14 +-
 drivers/spi/nxp_fspi.c |   2 +-
 drivers/spi/octeon_spi.c   |   2 +-
 drivers/spi/omap3_spi.c|   4 +-
 drivers/spi/pic32_spi.c|   2 +-
 drivers/spi/rk_spi.c   |   4 +-
 drivers/spi/rockchip_sfc.c |   2 +-
 drivers/spi/spi-aspeed-smc.c   |  28 +--
 drivers/spi/spi-mxic.c |   6 +-
 drivers/spi/spi-qup.c  |   4 +-
 drivers/spi/spi-sifive.c   |   6 +-
 drivers/spi/spi-sn-f-ospi.c|   2 +-
 drivers/spi/spi-sunxi.c|   6 +-
 drivers/spi/spi-synquacer.c|   4 +-
 drivers/spi/spi-uclass.c   |  34 ++-
 drivers/spi/stm32_qspi.c   |   2 +-
 drivers/spi/stm32_spi.c|   4 +-
 drivers/spi/ti_qspi.c  |  14 +-
 drivers/spi/xilinx_spi.c   |   6 +-
 drivers/spi/zynq_qspi.c| 119 --
 drivers/spi/zynq_spi.c |   6 +-
 drivers/spi/zynqmp_gqspi.c | 141 ++--
 include/linux/mtd/spi-nor.h|  12 +
 include/spi.h  |  23 +-
 lib/acpi/acpi_device.c |   2 +-
 46 files changed, 792 insertions(

[PATCH] mtd: nand: arasan: Update the correct return codes

2024-03-01 Thread Venkatesh Yadav Abbarapu
The below exception observed on QEMU, as it doesn't support
NAND controller.

"Synchronous Abort" handler, esr 0x9605, far 0x17acfc878
elr: 0803ad40 lr : 0805f438 (reloc)
elr: 7fcb4d40 lr : 7fcd9438
x0 : 7bbfc880 x1 : ff10
x2 : 7fcf059c x3 : 7bbfc870
x4 : 7fd9a388 x5 : 00017acfc870
x6 :  x7 : 7bbfd0e0
x8 : 3dd4 x9 : 7bbeec0c
x10: 0001 x11: 3f8c
x12: 7bbeecfc x13: 7bbeeeb0
x14: 7bbeeeb0 x15: 7bbee474
x16: 7fcef18c x17: 
x18: 7bbf9d70 x19: 7bbfc888
x20: 7bbfc870 x21: 7fd68ddb
x22: ffed x23: 7bbfc878
x24:  x25: 
x26:  x27: 
x28:  x29: 7bbeed10

Code: 927ff8c1 924000c6 8b010065 f9400887 (f94004a2)
Resetting CPU ...

Updating the correct return codes rather than hardcoding, remove the
free as there is no memory allocated using malloc.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/nand/raw/arasan_nfc.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/nand/raw/arasan_nfc.c 
b/drivers/mtd/nand/raw/arasan_nfc.c
index 426160c384..d78e9ada82 100644
--- a/drivers/mtd/nand/raw/arasan_nfc.c
+++ b/drivers/mtd/nand/raw/arasan_nfc.c
@@ -1232,7 +1232,7 @@ static int arasan_probe(struct udevice *dev)
struct nand_config *nand = >config;
struct mtd_info *mtd;
ofnode child;
-   int err = -1;
+   int ret;
const char *str;
 
info->reg = dev_read_addr_ptr(dev);
@@ -1259,9 +1259,10 @@ static int arasan_probe(struct udevice *dev)
writel(0x0, >reg->pgm_reg);
 
/* first scan to find the device and get the page size */
-   if (nand_scan_ident(mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL)) {
+   ret = nand_scan_ident(mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL);
+   if (ret) {
printf("%s: nand_scan_ident failed\n", __func__);
-   goto fail;
+   return ret;
}
 
str = ofnode_read_string(nand_chip->flash_node, "nand-ecc-mode");
@@ -1289,26 +1290,26 @@ static int arasan_probe(struct udevice *dev)
nand_chip->ecc.bytes = 0;
nand_chip->ecc.layout = _nand_oob_64;
} else {
-   if (arasan_nand_ecc_init(mtd)) {
+   ret = arasan_nand_ecc_init(mtd);
+   if (ret) {
printf("%s: nand_ecc_init failed\n", __func__);
-   goto fail;
+   return ret;
}
}
 
-   if (nand_scan_tail(mtd)) {
+   ret = nand_scan_tail(mtd);
+   if (ret) {
printf("%s: nand_scan_tail failed\n", __func__);
-   goto fail;
+   return ret;
}
 
-   if (nand_register(0, mtd)) {
+   ret = nand_register(0, mtd);
+   if (ret) {
printf("Nand Register Fail\n");
-   goto fail;
+   return ret;
}
 
-   return 0;
-fail:
-   free(nand);
-   return err;
+   return ret;
 }
 
 static const struct udevice_id arasan_nand_dt_ids[] = {
-- 
2.25.1



[UBOOT PATCH v3] mtd: nand: arasan: Print warning for unsupported ecc modes

2024-03-01 Thread Venkatesh Yadav Abbarapu
Currently only hw ecc is supported in U-Boot. If any other ecc mode is
given in DT, it simply ignores and switches to hw ecc. So better print
what is being done.

Revert this patch once soft ecc support is fixed in future.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
Changes in v2:
- Added the ecc mode check in the arasan driver itself.
Changes in v3:
- Skip the driver probe when sw-ecc mode is present in the device tree.
---
 drivers/mtd/nand/raw/arasan_nfc.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mtd/nand/raw/arasan_nfc.c 
b/drivers/mtd/nand/raw/arasan_nfc.c
index 14766401bf..426160c384 100644
--- a/drivers/mtd/nand/raw/arasan_nfc.c
+++ b/drivers/mtd/nand/raw/arasan_nfc.c
@@ -1233,6 +1233,7 @@ static int arasan_probe(struct udevice *dev)
struct mtd_info *mtd;
ofnode child;
int err = -1;
+   const char *str;
 
info->reg = dev_read_addr_ptr(dev);
mtd = nand_to_mtd(nand_chip);
@@ -1263,6 +1264,12 @@ static int arasan_probe(struct udevice *dev)
goto fail;
}
 
+   str = ofnode_read_string(nand_chip->flash_node, "nand-ecc-mode");
+   if (strcmp(str, "hw")) {
+   printf("%s ecc is not supported, switch to hw ecc\n", str);
+   return -EINVAL;
+   }
+
nand_chip->ecc.mode = NAND_ECC_HW;
nand_chip->ecc.hwctl = NULL;
nand_chip->ecc.read_page = arasan_nand_read_page_hwecc;
-- 
2.25.1



[PATCH] xilinx: zynqmp: Add the missing function prototype

2024-02-07 Thread Venkatesh Yadav Abbarapu
Add missing prototype to fix the below sparse warning
warning: no previous prototype for 'spl_spi_get_uboot_offs'
 [-Wmissing-prototypes]

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 board/xilinx/zynqmp/zynqmp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index 9f50090720..ba49eb7be2 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-- 
2.25.1



[PATCH v10 8/8] config: xea: Enable the SPI_ADVANCE config option

2024-01-29 Thread Venkatesh Yadav Abbarapu
Disable the config SPI_ADVANCE, as getting the below error
../arm-xilinx-linux-gnueabi-ld.bfd.real: drivers/core/ofnode.o: in function
`ofnode_get_property':
/u-boot/drivers/core/ofnode.c:1185: undefined reference to `fdt_getprop'
make[1]: *** [scripts/Makefile.spl:527: spl/u-boot-spl] Error 1

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 configs/imx28_xea_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/imx28_xea_defconfig b/configs/imx28_xea_defconfig
index 64a0561a34..36d3e73d0a 100644
--- a/configs/imx28_xea_defconfig
+++ b/configs/imx28_xea_defconfig
@@ -122,6 +122,7 @@ CONFIG_SPECIFY_CONSOLE_INDEX=y
 CONFIG_DM_SERIAL=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
+# CONFIG_SPI_ADVANCE is not set
 CONFIG_MXS_SPI=y
 CONFIG_SPL_CRC8=y
 # CONFIG_SPL_OF_LIBFDT is not set
-- 
2.25.1



[PATCH v10 6/8] spi: zynq_qspi: Add parallel memories support in QSPI driver

2024-01-29 Thread Venkatesh Yadav Abbarapu
Add support for parallel memories in zynq_qspi.c driver. In case of
parallel memories STRIPE bit is set and sent to the qspi ip, which will
send data bits to both the flashes in parallel. However for few commands
we should not use stripe, instead send same data to both the flashes.
Those commands are exclueded by using zynqmp_qspi_update_stripe().

Also update copyright info for this file.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/zynq_qspi.c | 113 
 1 file changed, 102 insertions(+), 11 deletions(-)

diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c
index bc82acd0b6..41f7ae2ab2 100644
--- a/drivers/spi/zynq_qspi.c
+++ b/drivers/spi/zynq_qspi.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2013 Xilinx, Inc.
+ * (C) Copyright 2013 - 2022, Xilinx, Inc.
  * (C) Copyright 2015 Jagan Teki 
+ * (C) Copyright 2023, Advanced Micro Devices, Inc.
  *
  * Xilinx Zynq Quad-SPI(QSPI) controller driver (master mode only)
  */
@@ -13,10 +14,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include "../mtd/spi/sf_internal.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -42,6 +45,21 @@ DECLARE_GLOBAL_DATA_PTR;
 #define ZYNQ_QSPI_TXD_00_01_OFFSET 0x80/* Transmit 1-byte inst */
 #define ZYNQ_QSPI_TXD_00_10_OFFSET 0x84/* Transmit 2-byte inst */
 #define ZYNQ_QSPI_TXD_00_11_OFFSET 0x88/* Transmit 3-byte inst */
+#define ZYNQ_QSPI_FR_QOUT_CODE 0x6B/* read instruction code */
+
+#define QSPI_SELECT_LOWER_CSBIT(0)
+#define QSPI_SELECT_UPPER_CSBIT(1)
+
+/*
+ * QSPI Linear Configuration Register
+ *
+ * It is named Linear Configuration but it controls other modes when not in
+ * linear mode also.
+ */
+#define ZYNQ_QSPI_LCFG_TWO_MEM_MASK 0x4000 /* QSPI Enable Bit Mask */
+#define ZYNQ_QSPI_LCFG_SEP_BUS_MASK 0x2000 /* QSPI Enable Bit Mask */
+#define ZYNQ_QSPI_LCFG_U_PAGE   0x1000 /* QSPI Upper memory set */
+#define ZYNQ_QSPI_LCFG_DUMMY_SHIFT  8
 
 #define ZYNQ_QSPI_TXFIFO_THRESHOLD 1   /* Tx FIFO threshold level*/
 #define ZYNQ_QSPI_RXFIFO_THRESHOLD 32  /* Rx FIFO threshold level */
@@ -101,7 +119,11 @@ struct zynq_qspi_priv {
int bytes_to_transfer;
int bytes_to_receive;
unsigned int is_inst;
+   unsigned int is_parallel;
+   unsigned int is_stacked;
+   unsigned int u_page;
unsigned cs_change:1;
+   unsigned is_strip:1;
 };
 
 static int zynq_qspi_of_to_plat(struct udevice *bus)
@@ -112,7 +134,6 @@ static int zynq_qspi_of_to_plat(struct udevice *bus)
 
plat->regs = (struct zynq_qspi_regs *)fdtdec_get_addr(blob,
  node, "reg");
-
return 0;
 }
 
@@ -147,6 +168,9 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
/* Disable Interrupts */
writel(ZYNQ_QSPI_IXR_ALL_MASK, >idr);
 
+   /* Disable linear mode as the boot loader may have used it */
+   writel(0x0, >lqspicfg);
+
/* Clear the TX and RX threshold reg */
writel(ZYNQ_QSPI_TXFIFO_THRESHOLD, >txftr);
writel(ZYNQ_QSPI_RXFIFO_THRESHOLD, >rxftr);
@@ -164,12 +188,11 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
confr |= ZYNQ_QSPI_CR_IFMODE_MASK | ZYNQ_QSPI_CR_MCS_MASK |
ZYNQ_QSPI_CR_PCS_MASK | ZYNQ_QSPI_CR_FW_MASK |
ZYNQ_QSPI_CR_MSTREN_MASK;
-   writel(confr, >cr);
 
-   /* Disable the LQSPI feature */
-   confr = readl(>lqspicfg);
-   confr &= ~ZYNQ_QSPI_LQSPICFG_LQMODE_MASK;
-   writel(confr, >lqspicfg);
+   if (priv->is_stacked)
+   confr |= 0x10;
+
+   writel(confr, >cr);
 
/* Enable SPI */
writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, >enr);
@@ -181,6 +204,7 @@ static int zynq_qspi_child_pre_probe(struct udevice *bus)
struct zynq_qspi_priv *priv = dev_get_priv(bus->parent);
 
priv->max_hz = slave->max_hz;
+   slave->multi_cs_cap = true;
 
return 0;
 }
@@ -363,8 +387,8 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv 
*priv, u32 size)
unsigned len, offset;
struct zynq_qspi_regs *regs = priv->regs;
static const unsigned offsets[4] = {
-   ZYNQ_QSPI_TXD_00_00_OFFSET, ZYNQ_QSPI_TXD_00_01_OFFSET,
-   ZYNQ_QSPI_TXD_00_10_OFFSET, ZYNQ_QSPI_TXD_00_11_OFFSET };
+   ZYNQ_QSPI_TXD_00_01_OFFSET, ZYNQ_QSPI_TXD_00_10_OFFSET,
+   ZYNQ_QSPI_TXD_00_11_OFFSET, ZYNQ_QSPI_TXD_00_00_OFFSET };
 
while ((fifocount < size) &&
(priv->bytes_to_transfer > 0)) {
@@ -386,7 +410,11 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv 
*priv, u32 size)
return;
  

[PATCH v10 7/8] spi: Add the spi advance options for non SPL

2024-01-29 Thread Venkatesh Yadav Abbarapu
Adding the config option SPI_ADVANCE for non SPL code.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/Kconfig  | 7 +++
 drivers/spi/spi-uclass.c | 3 ++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 69b184b0d9..e5640bcbe4 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -50,6 +50,13 @@ config SPI_DIRMAP
  improvements as it automates the whole process of sending SPI memory
  operations every time a new region is accessed.
 
+config SPI_ADVANCE
+   bool "Enable the advance feature"
+   default y
+   help
+ Enable the SPI advance feature support. By default this is set to y.
+ If you intend not to use the advance feature support you should say n 
here.
+
 if DM_SPI
 
 config ALTERA_SPI
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 992394c295..736159aa47 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -447,11 +447,12 @@ int _spi_get_bus_and_cs(int busnum, int cs, int speed, 
int mode,
slave = dev_get_parent_priv(dev);
bus_data = dev_get_uclass_priv(bus);
 
+#if CONFIG_IS_ENABLED(SPI_ADVANCE)
if ((dev_read_bool(dev, "parallel-memories")) && !slave->multi_cs_cap) {
dev_err(dev, "controller doesn't support multi CS\n");
return -EINVAL;
}
-
+#endif
/*
 * In case the operation speed is not yet established by
 * dm_spi_claim_bus() ensure the bus is configured properly.
-- 
2.25.1



[PATCH v10 4/8] spi: spi-uclass: Read chipselect and restrict capabilities

2024-01-29 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Read chipselect properties from DT which are populated using 'reg'
property and save it in plat->cs[] array for later use.

Also read multi chipselect capability which is used for
parallel-memories and return errors if they are passed on using DT but
driver is not capable of handling it.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/sandbox.c|  2 +-
 drivers/spi/altera_spi.c |  4 ++--
 drivers/spi/atcspi200_spi.c  |  2 +-
 drivers/spi/ath79_spi.c  |  2 +-
 drivers/spi/atmel_spi.c  |  6 +++---
 drivers/spi/bcm63xx_hsspi.c  | 42 ++--
 drivers/spi/bcm63xx_spi.c|  6 +++---
 drivers/spi/bcmbca_hsspi.c   | 34 ++---
 drivers/spi/cf_spi.c |  6 +++---
 drivers/spi/davinci_spi.c|  8 +++
 drivers/spi/fsl_dspi.c   | 18 
 drivers/spi/fsl_espi.c   |  4 ++--
 drivers/spi/fsl_qspi.c   |  4 ++--
 drivers/spi/gxp_spi.c|  2 +-
 drivers/spi/mpc8xx_spi.c |  4 ++--
 drivers/spi/mpc8xxx_spi.c| 10 -
 drivers/spi/mscc_bb_spi.c|  4 ++--
 drivers/spi/mxc_spi.c|  6 +++---
 drivers/spi/npcm_fiu_spi.c   | 14 ++--
 drivers/spi/nxp_fspi.c   |  2 +-
 drivers/spi/octeon_spi.c |  2 +-
 drivers/spi/omap3_spi.c  |  4 ++--
 drivers/spi/pic32_spi.c  |  2 +-
 drivers/spi/rk_spi.c |  4 ++--
 drivers/spi/rockchip_sfc.c   |  2 +-
 drivers/spi/spi-aspeed-smc.c | 28 
 drivers/spi/spi-mxic.c   |  6 +++---
 drivers/spi/spi-qup.c|  4 ++--
 drivers/spi/spi-sifive.c |  6 +++---
 drivers/spi/spi-sn-f-ospi.c  |  2 +-
 drivers/spi/spi-sunxi.c  |  6 +++---
 drivers/spi/spi-synquacer.c  |  4 ++--
 drivers/spi/spi-uclass.c | 33 +++-
 drivers/spi/stm32_qspi.c |  2 +-
 drivers/spi/stm32_spi.c  |  4 ++--
 drivers/spi/ti_qspi.c| 14 ++--
 drivers/spi/xilinx_spi.c |  6 +++---
 drivers/spi/zynq_qspi.c  |  6 +++---
 drivers/spi/zynq_spi.c   |  6 +++---
 include/spi.h|  8 ++-
 lib/acpi/acpi_device.c   |  2 +-
 41 files changed, 180 insertions(+), 151 deletions(-)

diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 4fe547171a..72036d5a88 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -139,7 +139,7 @@ static int sandbox_sf_probe(struct udevice *dev)
return ret;
}
slave_plat = dev_get_parent_plat(dev);
-   cs = slave_plat->cs;
+   cs = slave_plat->cs[0];
debug("found at cs %d\n", cs);
 
if (!pdata->filename) {
diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c
index 989679e881..48782f81c1 100644
--- a/drivers/spi/altera_spi.c
+++ b/drivers/spi/altera_spi.c
@@ -96,7 +96,7 @@ static int altera_spi_xfer(struct udevice *dev, unsigned int 
bitlen,
uint32_t reg, data, start;
 
debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
- dev_seq(bus), slave_plat->cs, bitlen, bytes, flags);
+ dev_seq(bus), slave_plat->cs[0], bitlen, bytes, flags);
 
if (bitlen == 0)
goto done;
@@ -111,7 +111,7 @@ static int altera_spi_xfer(struct udevice *dev, unsigned 
int bitlen,
readl(>rxdata);
 
if (flags & SPI_XFER_BEGIN)
-   spi_cs_activate(dev, slave_plat->cs);
+   spi_cs_activate(dev, slave_plat->cs[0]);
 
while (bytes--) {
if (txp)
diff --git a/drivers/spi/atcspi200_spi.c b/drivers/spi/atcspi200_spi.c
index de9c14837c..acee743653 100644
--- a/drivers/spi/atcspi200_spi.c
+++ b/drivers/spi/atcspi200_spi.c
@@ -321,7 +321,7 @@ static int atcspi200_spi_claim_bus(struct udevice *dev)
struct udevice *bus = dev->parent;
struct nds_spi_slave *ns = dev_get_priv(bus);
 
-   if (slave_plat->cs >= ns->num_cs) {
+   if (slave_plat->cs[0] >= ns->num_cs) {
printf("Invalid SPI chipselect\n");
return -EINVAL;
}
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
index 205567ef54..ad10cec2a6 100644
--- a/drivers/spi/ath79_spi.c
+++ b/drivers/spi/ath79_spi.c
@@ -74,7 +74,7 @@ static int ath79_spi_xfer(struct udevice *dev, unsigned int 
bitlen,
if (restbits)
bytes++;
 
-   out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs));
+   out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs[0]));
while (bytes > 0) {
bytes--;
curbyte = 0;
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index aec6f4eca9..e2de39d1ef 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -126,7 +126,7 @@ static int atmel_spi_claim_bus(struct udevice *dev)
struct atmel_spi_priv *priv = dev_get

[PATCH v10 5/8] spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver

2024-01-29 Thread Venkatesh Yadav Abbarapu
Add support for parallel memories in zynqmp_gqspi.c driver. In case of
parallel memories STRIPE bit is set and sent to the qspi ip, which will
send data bits to both the flashes in parallel. However for few commands
we should not use stripe, instead send same data to both the flashes.
Those commands are exclueded by using zynqmp_qspi_update_stripe().

Also update copyright info for this file.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/zynqmp_gqspi.c | 141 -
 include/spi.h  |   4 ++
 2 files changed, 129 insertions(+), 16 deletions(-)

diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index a323994fb2..dedf8270a8 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2018 Xilinx
- *
+ * (C) Copyright 2013 - 2022, Xilinx, Inc.
+ * (C) Copyright 2023, Advanced Micro Devices, Inc.
  * Xilinx ZynqMP Generic Quad-SPI(QSPI) controller driver(master mode only)
  */
 
@@ -25,6 +25,8 @@
 #include 
 #include 
 #include 
+#include 
+#include "../mtd/spi/sf_internal.h"
 #include 
 
 #define GQSPI_GFIFO_STRT_MODE_MASK BIT(29)
@@ -88,6 +90,9 @@
 #define SPI_XFER_ON_LOWER  1
 #define SPI_XFER_ON_UPPER  2
 
+#define GQSPI_SELECT_LOWER_CS  BIT(0)
+#define GQSPI_SELECT_UPPER_CS  BIT(1)
+
 #define GQSPI_DMA_ALIGN0x4
 #define GQSPI_MAX_BAUD_RATE_VAL7
 #define GQSPI_DFLT_BAUD_RATE_VAL   2
@@ -183,13 +188,14 @@ struct zynqmp_qspi_priv {
int bytes_to_transfer;
int bytes_to_receive;
const struct spi_mem_op *op;
+   unsigned int is_parallel;
+   unsigned int u_page;
+   unsigned int bus;
+   unsigned int stripe;
+   unsigned int flags;
+   u32 max_hz;
 };
 
-__weak int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 
value)
-{
-   return 0;
-}
-
 static int zynqmp_qspi_of_to_plat(struct udevice *bus)
 {
struct zynqmp_qspi_plat *plat = dev_get_plat(bus);
@@ -234,8 +240,30 @@ static u32 zynqmp_qspi_bus_select(struct zynqmp_qspi_priv 
*priv)
 {
u32 gqspi_fifo_reg = 0;
 
-   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
-GQSPI_GFIFO_CS_LOWER;
+   if (priv->is_parallel) {
+   if (priv->bus == SPI_XFER_ON_BOTH)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_CS_UPPER |
+GQSPI_GFIFO_CS_LOWER;
+   else if (priv->bus == SPI_XFER_ON_LOWER)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_UPPER |
+GQSPI_GFIFO_CS_LOWER;
+   else if (priv->bus == SPI_XFER_ON_UPPER)
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_CS_LOWER |
+GQSPI_GFIFO_CS_UPPER;
+   else
+   debug("Wrong Bus selection:0x%x\n", priv->bus);
+   } else {
+   if (priv->u_page)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_UPPER;
+   else
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_LOWER;
+   }
 
return gqspi_fifo_reg;
 }
@@ -295,8 +323,15 @@ static void zynqmp_qspi_chipselect(struct zynqmp_qspi_priv 
*priv, int is_on)
gqspi_fifo_reg |= GQSPI_SPI_MODE_SPI |
  GQSPI_IMD_DATA_CS_ASSERT;
} else {
-   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS;
-   gqspi_fifo_reg |= GQSPI_IMD_DATA_CS_DEASSERT;
+   if (priv->is_parallel) {
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_LOW_BUS;
+   } else if (priv->u_page) {
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS;
+   } else {
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS;
+   gqspi_fifo_reg |= GQSPI_IMD_DATA_CS_DEASSERT;
+   }
}
 
zynqmp_qspi_fill_gen_fifo(priv, gqspi_fifo_reg);
@@ -366,12 +401,13 @@ static int zynqmp_qspi_set_speed(struct udevice *bus, 
uint speed)
 
log_debug("%s, Speed: %d, Max: %d\n", __func__, speed, plat->frequency);
 
-   if (speed > plat->frequency)
-   speed = plat->frequency;
+   /*
+* If speed == 0 or speed > max freq, then set speed to highest
+*/
+   if (!speed || speed > priv->max_hz)
+   speed = pr

[PATCH v10 2/8] mtd: spi-nor: Add parallel memories support for read_sr and read_fsr

2024-01-29 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Add support for parallel memories flash configuration in read status
register and read flag status register functions.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 50 --
 1 file changed, 36 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index ef42964ace..b7e5f253a3 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -462,8 +462,9 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, 
loff_t to, size_t len,
 }
 
 /*
- * Read the status register, returning its value in the location
- * Return the status register value.
+ * Return the status register value. If the chip is parallel, then the
+ * read will be striped, so we should read 2 bytes to get the sr
+ * register value from both of the parallel chips.
  * Returns negative if error occurred.
  */
 static int read_sr(struct spi_nor *nor)
@@ -495,18 +496,29 @@ static int read_sr(struct spi_nor *nor)
if (spi_nor_protocol_is_dtr(nor->reg_proto))
op.data.nbytes = 2;
 
-   ret = spi_nor_read_write_reg(nor, , val);
-   if (ret < 0) {
-   pr_debug("error %d reading SR\n", (int)ret);
-   return ret;
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   op.data.nbytes = 2;
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
+   val[0] |= val[1];
+   } else {
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
}
 
-   return *val;
+   return val[0];
 }
 
 /*
- * Read the flag status register, returning its value in the location
- * Return the status register value.
+ * Return the flag status register value. If the chip is parallel, then
+ * the read will be striped, so we should read 2 bytes to get the fsr
+ * register value from both of the parallel chips.
  * Returns negative if error occurred.
  */
 static int read_fsr(struct spi_nor *nor)
@@ -538,13 +550,23 @@ static int read_fsr(struct spi_nor *nor)
if (spi_nor_protocol_is_dtr(nor->reg_proto))
op.data.nbytes = 2;
 
-   ret = spi_nor_read_write_reg(nor, , val);
-   if (ret < 0) {
-   pr_debug("error %d reading FSR\n", ret);
-   return ret;
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   op.data.nbytes = 2;
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
+   val[0] &= val[1];
+   } else {
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading FSR\n", ret);
+   return ret;
+   }
}
 
-   return *val;
+   return val[0];
 }
 
 /*
-- 
2.25.1



[PATCH v10 3/8] mtd: spi-nor: Add parallel and stacked memories support in read_bar and write_bar

2024-01-29 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Add support for parallel memories and stacked memories configuration
in read_bar and write_bar functions.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 55 +-
 1 file changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index b7e5f253a3..21fc9b52c6 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -909,12 +909,32 @@ static int clean_bar(struct spi_nor *nor)
 
 static int write_bar(struct spi_nor *nor, u32 offset)
 {
-   u8 cmd, bank_sel;
+   u8 cmd, bank_sel, upage_curr;
int ret;
+   struct mtd_info *mtd = >mtd;
+
+   /* Wait until previous write command is finished */
+   if (spi_nor_wait_till_ready(nor))
+   return 1;
+
+   if (nor->flags & (SNOR_F_HAS_PARALLEL | SNOR_F_HAS_STACKED) &&
+   mtd->size <= SZ_32M)
+   return 0;
+
+   if (mtd->size <= SZ_16M)
+   return 0;
+
+   offset = offset % (u32)mtd->size;
+   bank_sel = offset >> 24;
 
-   bank_sel = offset / SZ_16M;
-   if (bank_sel == nor->bank_curr)
-   goto bar_end;
+   upage_curr = nor->spi->flags & SPI_XFER_U_PAGE;
+
+   if (!(nor->flags & SNOR_F_HAS_STACKED) && bank_sel == nor->bank_curr)
+   return 0;
+   else if (upage_curr == nor->upage_prev && bank_sel == nor->bank_curr)
+   return 0;
+
+   nor->upage_prev = upage_curr;
 
cmd = nor->bank_write_cmd;
write_enable(nor);
@@ -924,15 +944,19 @@ static int write_bar(struct spi_nor *nor, u32 offset)
return ret;
}
 
-bar_end:
nor->bank_curr = bank_sel;
-   return nor->bank_curr;
+
+   return write_disable(nor);
 }
 
 static int read_bar(struct spi_nor *nor, const struct flash_info *info)
 {
u8 curr_bank = 0;
int ret;
+   struct mtd_info *mtd = >mtd;
+
+   if (mtd->size <= SZ_16M)
+   return 0;
 
switch (JEDEC_MFR(info)) {
case SNOR_MFR_SPANSION:
@@ -944,15 +968,30 @@ static int read_bar(struct spi_nor *nor, const struct 
flash_info *info)
nor->bank_write_cmd = SPINOR_OP_WREAR;
}
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   nor->spi->flags |= SPI_XFER_LOWER;
+
ret = nor->read_reg(nor, nor->bank_read_cmd,
-   _bank, 1);
+   _bank, 1);
if (ret) {
debug("SF: fail to read bank addr register\n");
return ret;
}
nor->bank_curr = curr_bank;
 
-   return 0;
+   // Make sure both chips use the same BAR
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   write_enable(nor);
+   ret = nor->write_reg(nor, nor->bank_write_cmd, _bank, 1);
+   if (ret)
+   return ret;
+
+   ret = write_disable(nor);
+   if (ret)
+   return ret;
+   }
+
+   return ret;
 }
 #endif
 
-- 
2.25.1



[PATCH v10 1/8] mtd: spi-nor: Add parallel and stacked memories support

2024-01-29 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

In parallel mode, the current implementation assumes that a maximum of
two flashes are connected. The QSPI controller splits the data evenly
between both the flashes so, both the flashes that are connected in
parallel mode should be identical.
During each operation SPI-NOR sets 0th bit for CS0 & 1st bit for CS1 in
nor->flags.

In stacked mode the current implementation assumes that a maximum of two
flashes are connected and both the flashes are of same make but can
differ in sizes. So, except the sizes all other flash parameters of both
the flashes are identical

Spi-nor will pass on the appropriate flash select flag to low level
driver, and it will select pass all the data to that particular flash.

Write operation in parallel mode are performed in page size * 2 chunks as
each write operation results in writing both the flashes. For doubling
the address space each operation is performed at addr/2 flash offset,
where addr is the address specified by the user.

Similarly for read and erase operations it will read from both flashes,
so size and offset are divided by 2 and send to flash.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 293 +
 include/linux/mtd/spi-nor.h|  12 ++
 include/spi.h  |  11 ++
 3 files changed, 288 insertions(+), 28 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index f86003ca8c..ef42964ace 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -663,12 +663,17 @@ static u8 spi_nor_convert_3to4_erase(u8 opcode)
 static void spi_nor_set_4byte_opcodes(struct spi_nor *nor,
  const struct flash_info *info)
 {
+   bool shift = 0;
+
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   shift = 1;
+
/* Do some manufacturer fixups first */
switch (JEDEC_MFR(info)) {
case SNOR_MFR_SPANSION:
/* No small sector erase for 4-byte command set */
nor->erase_opcode = SPINOR_OP_SE;
-   nor->mtd.erasesize = info->sector_size;
+   nor->mtd.erasesize = info->sector_size << shift;
break;
 
default:
@@ -989,8 +994,8 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 
addr)
 static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
+   u32 addr, len, rem, offset;
bool addr_known = false;
-   u32 addr, len, rem;
int ret, err;
 
dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
@@ -1015,6 +1020,19 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
ret = -EINTR;
goto erase_err;
}
+
+   offset = addr;
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   offset /= 2;
+
+   if (nor->flags & SNOR_F_HAS_STACKED) {
+   if (offset >= (mtd->size / 2)) {
+   offset = offset - (mtd->size / 2);
+   nor->spi->flags |= SPI_XFER_U_PAGE;
+   } else {
+   nor->spi->flags &= ~SPI_XFER_U_PAGE;
+   }
+   }
 #ifdef CONFIG_SPI_FLASH_BAR
ret = write_bar(nor, addr);
if (ret < 0)
@@ -1420,6 +1438,9 @@ static const struct flash_info *spi_nor_read_id(struct 
spi_nor *nor)
u8  id[SPI_NOR_MAX_ID_LEN];
const struct flash_info *info;
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   nor->spi->flags |= SPI_XFER_LOWER;
+
tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
if (tmp < 0) {
dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp);
@@ -1444,28 +1465,66 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t 
from, size_t len,
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
int ret;
+   u32 offset = from;
+   u32 stack_shift = 0;
+   u32 read_len = 0;
+   u32 rem_bank_len = 0;
+   u8 bank;
+   u8 is_ofst_odd = 0;
 
dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
 
+   if ((nor->flags & SNOR_F_HAS_PARALLEL) && (offset & 1)) {
+   /* We can hit this case when we use file system like ubifs */
+   from = (loff_t)(from - 1);
+   len = (size_t)(len + 1);
+   is_ofst_odd = 1;
+   }
+
while (len) {
-   loff_t addr = from;
-   size_t read_len = len;
+   if (nor->addr_width == 3) {
+   if (nor->

[PATCH v10 0/8] spi-nor: Add parallel and stacked memories support

2024-01-29 Thread Venkatesh Yadav Abbarapu
This series adds support for Xilinx qspi parallel and stacked memeories.

In parallel mode, the current implementation assumes that a maximum of
two flashes are connected. The QSPI controller splits the data evenly
between both the flashes so, both the flashes that are connected in
parallel mode should be identical.
During each operation SPI-NOR sets 0th bit for CS0 & 1st bit for CS1 in
nor->flags.

In stacked mode the current implementation assumes that a maximum of two
flashes are connected and both the flashes are of same make but can
differ in sizes. So, except the sizes all other flash parameters of both
the flashes are identical.

Spi-nor will pass on the appropriate flash select flag to low level driver,
and it will select pass all the data to that particular flash.

Write operation in parallel mode are performed in page size * 2 chunks as
each write operation results in writing both the flashes. For doubling the
address space each operation is performed at addr/2 flash offset, where addr
is the address specified by the user.

Similarly for read and erase operations it will read from both flashes, so
size and offset are divided by 2 and send to flash. 

Changes in v2:
- Fixed the compilation issues.
Changes in v3:
- Fixed the CI issues.
Changes in v4:
- Removed the dio,dummy_bytes variables from zynq_qspi driver.
- Fix the compilation issue by including the DM_SPI config.
Changes in v5:
- Fixed the issue reported by buildman.
Changes in v6:
- Fixed the issues reported while running the sandbox test cases.
Changes in v7:
- Fixed the issues reported while running these da850evm_defconfig,
  imx28_xea_defconfig configs.
- Fixed the issue when DM_SPI config is disabled.
- Fixed the issue while running the sandbox_noinst_defconfig with spl
  ./spl/u-boot-spl -d arch/sandbox/dts/test.dtb
   jedec_spi_nor spi.bin@0: has no valid 'reg' property (-12)
   jedec_spi_nor spi.bin@1: has no valid 'reg' property (-12)
   ### ERROR ### Please RESET the board ###
Changes in v8:
- Fixed the compilation issue with imx28_xea_defconfig.
- Fixed the SPL size issue with the axm and taurus defconfigs.
- Rebased the patches on top of next branch.
Changes in v9:
- Updated the commit log why SPL_FIT is being enabled.
Changes in v10:
- Added the new config SPI_ADVANCE to fix the issue while enabling
imx28_xea_defconfig.

Ashok Reddy Soma (4):
  mtd: spi-nor: Add parallel and stacked memories support
  mtd: spi-nor: Add parallel memories support for read_sr and read_fsr
  mtd: spi-nor: Add parallel and stacked memories support in read_bar
and write_bar
  spi: spi-uclass: Read chipselect and restrict capabilities

Venkatesh Yadav Abbarapu (4):
  spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver
  spi: zynq_qspi: Add parallel memories support in QSPI driver
  spi: Add the spi advance options for non SPL
  config: xea: Enable the SPI_ADVANCE config option

 configs/imx28_xea_defconfig|   1 +
 drivers/mtd/spi/sandbox.c  |   2 +-
 drivers/mtd/spi/spi-nor-core.c | 398 -
 drivers/spi/Kconfig|   7 +
 drivers/spi/altera_spi.c   |   4 +-
 drivers/spi/atcspi200_spi.c|   2 +-
 drivers/spi/ath79_spi.c|   2 +-
 drivers/spi/atmel_spi.c|   6 +-
 drivers/spi/bcm63xx_hsspi.c|  42 ++--
 drivers/spi/bcm63xx_spi.c  |   6 +-
 drivers/spi/bcmbca_hsspi.c |  34 +--
 drivers/spi/cf_spi.c   |   6 +-
 drivers/spi/davinci_spi.c  |   8 +-
 drivers/spi/fsl_dspi.c |  18 +-
 drivers/spi/fsl_espi.c |   4 +-
 drivers/spi/fsl_qspi.c |   4 +-
 drivers/spi/gxp_spi.c  |   2 +-
 drivers/spi/mpc8xx_spi.c   |   4 +-
 drivers/spi/mpc8xxx_spi.c  |  10 +-
 drivers/spi/mscc_bb_spi.c  |   4 +-
 drivers/spi/mxc_spi.c  |   6 +-
 drivers/spi/npcm_fiu_spi.c |  14 +-
 drivers/spi/nxp_fspi.c |   2 +-
 drivers/spi/octeon_spi.c   |   2 +-
 drivers/spi/omap3_spi.c|   4 +-
 drivers/spi/pic32_spi.c|   2 +-
 drivers/spi/rk_spi.c   |   4 +-
 drivers/spi/rockchip_sfc.c |   2 +-
 drivers/spi/spi-aspeed-smc.c   |  28 +--
 drivers/spi/spi-mxic.c |   6 +-
 drivers/spi/spi-qup.c  |   4 +-
 drivers/spi/spi-sifive.c   |   6 +-
 drivers/spi/spi-sn-f-ospi.c|   2 +-
 drivers/spi/spi-sunxi.c|   6 +-
 drivers/spi/spi-synquacer.c|   4 +-
 drivers/spi/spi-uclass.c   |  34 ++-
 drivers/spi/stm32_qspi.c   |   2 +-
 drivers/spi/stm32_spi.c|   4 +-
 drivers/spi/ti_qspi.c  |  14 +-
 drivers/spi/xilinx_spi.c   |   6 +-
 drivers/spi/zynq_qspi.c| 119 --
 drivers/spi/zynq_spi.c |   6 +-
 drivers/spi/zynqmp_gqspi.c | 141 ++--
 include/linux/mtd/spi-nor.h|  12 +
 include/spi.h  |  23 +-
 lib/acpi/acpi_device.c |   2 +-
 46 files changed, 791 insertions(+), 228 deletions(-)

-- 
2.25.1



[PATCH] configs: versal_net: Enable CONFIG_LTO for mini qspi/ospi

2024-01-26 Thread Venkatesh Yadav Abbarapu
Adding a tiny bit more code for mini u-boot leads to a OCM
image overflow. Fix this by enabling LTO for this board, so that such
changes still can be made to the common U-Boot code.

Enable building mini u-boot image with LTO, which results in about 8KB
reduction in size.

Signed-off-by: Michal Simek 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 configs/xilinx_versal_net_mini_ospi_defconfig | 1 +
 configs/xilinx_versal_net_mini_qspi_defconfig | 1 +
 2 files changed, 2 insertions(+)

diff --git a/configs/xilinx_versal_net_mini_ospi_defconfig 
b/configs/xilinx_versal_net_mini_ospi_defconfig
index 5f42243d22..d78c9f8059 100644
--- a/configs/xilinx_versal_net_mini_ospi_defconfig
+++ b/configs/xilinx_versal_net_mini_ospi_defconfig
@@ -15,6 +15,7 @@ CONFIG_DEFAULT_DEVICE_TREE="versal-net-mini-ospi-single"
 CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 # CONFIG_PSCI_RESET is not set
 CONFIG_SYS_LOAD_ADDR=0xBBF8
+CONFIG_LTO=y
 # CONFIG_EXPERT is not set
 CONFIG_REMAKE_ELF=y
 # CONFIG_AUTOBOOT is not set
diff --git a/configs/xilinx_versal_net_mini_qspi_defconfig 
b/configs/xilinx_versal_net_mini_qspi_defconfig
index 4fa83faa40..b0567f857a 100644
--- a/configs/xilinx_versal_net_mini_qspi_defconfig
+++ b/configs/xilinx_versal_net_mini_qspi_defconfig
@@ -13,6 +13,7 @@ CONFIG_DEFAULT_DEVICE_TREE="versal-net-mini-qspi-single"
 CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 # CONFIG_PSCI_RESET is not set
 CONFIG_SYS_LOAD_ADDR=0xBBF8
+CONFIG_LTO=y
 # CONFIG_EXPERT is not set
 CONFIG_REMAKE_ELF=y
 # CONFIG_AUTOBOOT is not set
-- 
2.25.1



[PATCH] configs: versal: Enable CONFIG_LTO for mini qspi/ospi

2024-01-26 Thread Venkatesh Yadav Abbarapu
Adding a tiny bit more code for mini u-boot leads to a OCM
image overflow. Fix this by enabling LTO for this board, so that such
changes still can be made to the common U-Boot code.

Enable building mini u-boot image with LTO, which results in about 8KB
reduction in size.

Signed-off-by: Michal Simek 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 configs/xilinx_versal_mini_ospi_defconfig | 1 +
 configs/xilinx_versal_mini_qspi_defconfig | 1 +
 2 files changed, 2 insertions(+)

diff --git a/configs/xilinx_versal_mini_ospi_defconfig 
b/configs/xilinx_versal_mini_ospi_defconfig
index 72a123d965..7a110350c2 100644
--- a/configs/xilinx_versal_mini_ospi_defconfig
+++ b/configs/xilinx_versal_mini_ospi_defconfig
@@ -16,6 +16,7 @@ CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 CONFIG_VERSAL_NO_DDR=y
 # CONFIG_PSCI_RESET is not set
 CONFIG_SYS_LOAD_ADDR=0x800
+CONFIG_LTO=y
 # CONFIG_EXPERT is not set
 CONFIG_REMAKE_ELF=y
 # CONFIG_AUTOBOOT is not set
diff --git a/configs/xilinx_versal_mini_qspi_defconfig 
b/configs/xilinx_versal_mini_qspi_defconfig
index d9fbac986c..58945a1cac 100644
--- a/configs/xilinx_versal_mini_qspi_defconfig
+++ b/configs/xilinx_versal_mini_qspi_defconfig
@@ -14,6 +14,7 @@ CONFIG_SYS_MEM_RSVD_FOR_MMU=y
 CONFIG_VERSAL_NO_DDR=y
 # CONFIG_PSCI_RESET is not set
 CONFIG_SYS_LOAD_ADDR=0x800
+CONFIG_LTO=y
 # CONFIG_EXPERT is not set
 CONFIG_REMAKE_ELF=y
 # CONFIG_AUTOBOOT is not set
-- 
2.25.1



[PATCH] soc: zynqmp: Add the IDcode for dr_SE and eg_SE variants

2024-01-22 Thread Venkatesh Yadav Abbarapu
ID code is added for zu67dr_SE, zu11eg_SE, zu19eg_SE and zu47dr_SE
variants. SE is the select edition of restricted devices with the
capabilities.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/soc/soc_xilinx_zynqmp.c | 28 +++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/soc_xilinx_zynqmp.c b/drivers/soc/soc_xilinx_zynqmp.c
index d9a5944965..786825d920 100644
--- a/drivers/soc/soc_xilinx_zynqmp.c
+++ b/drivers/soc/soc_xilinx_zynqmp.c
@@ -35,13 +35,15 @@ static const char zynqmp_family[] = "ZynqMP";
 #define IDCODE2_PL_INIT_SHIFT  9
 #define IDCODE2_PL_INIT_MASK   BIT(IDCODE2_PL_INIT_SHIFT)
 
-#define ZYNQMP_VERSION_SIZE7
+#define ZYNQMP_VERSION_SIZE10
 
 enum {
ZYNQMP_VARIANT_EG = BIT(0),
ZYNQMP_VARIANT_EV = BIT(1),
ZYNQMP_VARIANT_CG = BIT(2),
ZYNQMP_VARIANT_DR = BIT(3),
+   ZYNQMP_VARIANT_DR_SE = BIT(4),
+   ZYNQMP_VARIANT_EG_SE = BIT(5),
 };
 
 struct zynqmp_device {
@@ -105,6 +107,11 @@ static const struct zynqmp_device zynqmp_devices[] = {
.device = 11,
.variants = ZYNQMP_VARIANT_EG,
},
+   {
+   .id = 0x04741093,
+   .device = 11,
+   .variants = ZYNQMP_VARIANT_EG_SE,
+   },
{
.id = 0x04750093,
.device = 15,
@@ -120,6 +127,11 @@ static const struct zynqmp_device zynqmp_devices[] = {
.device = 19,
.variants = ZYNQMP_VARIANT_EG,
},
+   {
+   .id = 0x0475C093,
+   .device = 19,
+   .variants = ZYNQMP_VARIANT_EG_SE,
+   },
{
.id = 0x047E1093,
.device = 21,
@@ -170,6 +182,11 @@ static const struct zynqmp_device zynqmp_devices[] = {
.device = 47,
.variants = ZYNQMP_VARIANT_DR,
},
+   {
+   .id = 0x047FA093,
+   .device = 47,
+   .variants = ZYNQMP_VARIANT_DR_SE,
+   },
{
.id = 0x047FB093,
.device = 48,
@@ -185,6 +202,11 @@ static const struct zynqmp_device zynqmp_devices[] = {
.device = 67,
.variants = ZYNQMP_VARIANT_DR,
},
+   {
+   .id = 0x046d7093,
+   .device = 67,
+   .variants = ZYNQMP_VARIANT_DR_SE,
+   },
{
.id = 0x04712093,
.device = 24,
@@ -271,8 +293,12 @@ static int soc_xilinx_zynqmp_detect_machine(struct udevice 
*dev, u32 idcode,
"cg" : "eg", sizeof(priv->machine));
} else if (device->variants & ZYNQMP_VARIANT_EG) {
strlcat(priv->machine, "eg", sizeof(priv->machine));
+   } else if (device->variants & ZYNQMP_VARIANT_EG_SE) {
+   strlcat(priv->machine, "eg_SE", sizeof(priv->machine));
} else if (device->variants & ZYNQMP_VARIANT_DR) {
strlcat(priv->machine, "dr", sizeof(priv->machine));
+   } else if (device->variants & ZYNQMP_VARIANT_DR_SE) {
+   strlcat(priv->machine, "dr_SE", sizeof(priv->machine));
}
 
return 0;
-- 
2.25.1



[PATCH v2] mtd: nand: arasan: Print warning for unsupported ecc modes

2024-01-18 Thread Venkatesh Yadav Abbarapu
Currently only hw ecc is supported in U-Boot. If any other ecc mode is
given in DT, it simply ignores and switches to hw ecc. So better print
what is being done.

Revert this patch once soft ecc support is fixed in future.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
Changes in v2:
- Added the ecc mode check in the arasan driver itself.
---
 drivers/mtd/nand/raw/arasan_nfc.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/mtd/nand/raw/arasan_nfc.c 
b/drivers/mtd/nand/raw/arasan_nfc.c
index 14766401bf..8e5eef0881 100644
--- a/drivers/mtd/nand/raw/arasan_nfc.c
+++ b/drivers/mtd/nand/raw/arasan_nfc.c
@@ -1233,6 +1233,7 @@ static int arasan_probe(struct udevice *dev)
struct mtd_info *mtd;
ofnode child;
int err = -1;
+   const char *str;
 
info->reg = dev_read_addr_ptr(dev);
mtd = nand_to_mtd(nand_chip);
@@ -1263,6 +1264,10 @@ static int arasan_probe(struct udevice *dev)
goto fail;
}
 
+   str = ofnode_read_string(nand_chip->flash_node, "nand-ecc-mode");
+   if (strcmp(str, "hw"))
+   printf("%s ecc is not supported, switch to hw ecc\n", str);
+
nand_chip->ecc.mode = NAND_ECC_HW;
nand_chip->ecc.hwctl = NULL;
nand_chip->ecc.read_page = arasan_nand_read_page_hwecc;
-- 
2.25.1



[PATCH] mtd: nand: Print warning for unsupported ecc modes

2024-01-16 Thread Venkatesh Yadav Abbarapu
Currently only hw ecc is supported in U-Boot. If any other ecc mode is
given in DT, it simply ignores and switches to hw ecc. So better print
what is being done.

Revert this patch once soft ecc support is fixed in future.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/nand/raw/nand_base.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index c40a0f23d7..200f7f8ba0 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -4463,6 +4463,9 @@ static int nand_dt_init(struct mtd_info *mtd, struct 
nand_chip *chip, ofnode nod
 
str = ofnode_read_string(node, "nand-ecc-mode");
if (str) {
+   if (strcmp(str, "hw"))
+   printf("%s ecc is not supported, switching to hw 
ecc\n", str);
+
if (!strcmp(str, "none"))
ecc_mode = NAND_ECC_NONE;
else if (!strcmp(str, "soft"))
-- 
2.25.1



[PATCH v3 2/2] configs: zynqmp_kria: Enable CONFIG_OF_BOARD_SETUP

2024-01-16 Thread Venkatesh Yadav Abbarapu
Enable CONFIG_OF_BOARD_SETUP, so we could use ft_board_setup()
to enable the kaslr-seed and pass to kernel.

Signed-off-by: Michal Simek 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 configs/xilinx_zynqmp_kria_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/xilinx_zynqmp_kria_defconfig 
b/configs/xilinx_zynqmp_kria_defconfig
index a65a59c1ae..86741f1773 100644
--- a/configs/xilinx_zynqmp_kria_defconfig
+++ b/configs/xilinx_zynqmp_kria_defconfig
@@ -33,6 +33,7 @@ CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT_ADDRESS=0x1000
 CONFIG_SYS_BOOTM_LEN=0x640
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_OF_BOARD_SETUP=y
 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
 CONFIG_USE_PREBOOT=y
 CONFIG_SYS_PBSIZE=2073
-- 
2.25.1



[PATCH v3 0/2] xilinx: Update the kaslr-seed property

2024-01-16 Thread Venkatesh Yadav Abbarapu
Update the kaslr-seed property and enable the config CONFIG_OF_BOARD_SETUP.

Changes in v2:
- Created macro for size variable.
- Removed malloc and created array for rng buffer.
- Added debug logs for all the apis.
Changes in v3:
- Fixed the return values.

Venkatesh Yadav Abbarapu (2):
  xilinx: board: Update the kaslr-seed property
  configs: zynqmp_kria: Enable CONFIG_OF_BOARD_SETUP

 board/xilinx/common/board.c  | 49 
 configs/xilinx_zynqmp_kria_defconfig |  1 +
 2 files changed, 50 insertions(+)

-- 
2.25.1



[PATCH v3 1/2] xilinx: board: Update the kaslr-seed property

2024-01-16 Thread Venkatesh Yadav Abbarapu
Create a ft_board_setup() api that gets called as part
of bootm/booti before jumping to kernel. In this
ft_board_setup() callback that will inspect the DTB
and insert the device tree blob with the "kaslr-seed" property.

Signed-off-by: Michal Simek 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 board/xilinx/common/board.c | 49 +
 1 file changed, 49 insertions(+)

diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index 12a877c715..9641ed307b 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -682,3 +683,51 @@ phys_addr_t board_get_usable_ram_top(phys_size_t 
total_size)
return reg + size;
 }
 #endif
+
+#ifdef CONFIG_OF_BOARD_SETUP
+#define MAX_RAND_SIZE 8
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+   size_t n = MAX_RAND_SIZE;
+   struct udevice *dev;
+   u8 buf[MAX_RAND_SIZE];
+   int nodeoffset, ret;
+
+   if (uclass_get_device(UCLASS_RNG, 0, ) || !dev) {
+   debug("No RNG device\n");
+   return 0;
+   }
+
+   if (dm_rng_read(dev, buf, n)) {
+   debug("Reading RNG failed\n");
+   return 0;
+   }
+
+   if (!blob) {
+   debug("No FDT memory address configured. Please configure\n"
+ "the FDT address via \"fdt addr \" command.\n"
+ "Aborting!\n");
+   return 0;
+   }
+
+   ret = fdt_check_header(blob);
+   if (ret < 0) {
+   debug("fdt_chosen: %s\n", fdt_strerror(ret));
+   return ret;
+   }
+
+   nodeoffset = fdt_find_or_add_subnode(blob, 0, "chosen");
+   if (nodeoffset < 0) {
+   debug("Reading chosen node failed\n");
+   return nodeoffset;
+   }
+
+   ret = fdt_setprop(blob, nodeoffset, "kaslr-seed", buf, sizeof(buf));
+   if (ret < 0) {
+   debug("Unable to set kaslr-seed on chosen node: %s\n", 
fdt_strerror(ret));
+   return ret;
+   }
+
+   return 0;
+}
+#endif
-- 
2.25.1



[PATCH v2 2/2] configs: zynqmp_kria: Enable CONFIG_OF_BOARD_SETUP

2024-01-15 Thread Venkatesh Yadav Abbarapu
Enable CONFIG_OF_BOARD_SETUP, so we could use ft_board_setup()
to enable the kaslr-seed and pass to kernel.

Signed-off-by: Michal Simek 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 configs/xilinx_zynqmp_kria_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/xilinx_zynqmp_kria_defconfig 
b/configs/xilinx_zynqmp_kria_defconfig
index a65a59c1ae..86741f1773 100644
--- a/configs/xilinx_zynqmp_kria_defconfig
+++ b/configs/xilinx_zynqmp_kria_defconfig
@@ -33,6 +33,7 @@ CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT_ADDRESS=0x1000
 CONFIG_SYS_BOOTM_LEN=0x640
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_OF_BOARD_SETUP=y
 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
 CONFIG_USE_PREBOOT=y
 CONFIG_SYS_PBSIZE=2073
-- 
2.25.1



[PATCH v2 1/2] xilinx: board: Update the kaslr-seed property

2024-01-15 Thread Venkatesh Yadav Abbarapu
Create a ft_board_setup() api that gets called as part
of bootm/booti before jumping to kernel. In this
ft_board_setup() callback that will inspect the DTB
and insert the device tree blob with the "kaslr-seed" property.

Signed-off-by: Michal Simek 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 board/xilinx/common/board.c | 50 +
 1 file changed, 50 insertions(+)

diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index 12a877c715..2796d45351 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -682,3 +683,52 @@ phys_addr_t board_get_usable_ram_top(phys_size_t 
total_size)
return reg + size;
 }
 #endif
+
+#ifdef CONFIG_OF_BOARD_SETUP
+#define MAX_RAND_SIZE 8
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+   size_t n = MAX_RAND_SIZE;
+   struct udevice *dev;
+   u8 buf[MAX_RAND_SIZE];
+   int nodeoffset;
+   int ret;
+
+   if (uclass_get_device(UCLASS_RNG, 0, ) || !dev) {
+   debug("No RNG device\n");
+   return -EINVAL;
+   }
+
+   if (dm_rng_read(dev, buf, n)) {
+   debug("Reading RNG failed\n");
+   return -EINVAL;
+   }
+
+   if (!blob) {
+   debug("No FDT memory address configured. Please configure\n"
+ "the FDT address via \"fdt addr \" command.\n"
+ "Aborting!\n");
+   return -EINVAL;
+   }
+
+   ret = fdt_check_header(blob);
+   if (ret < 0) {
+   debug("fdt_chosen: %s\n", fdt_strerror(ret));
+   return -EINVAL;
+   }
+
+   nodeoffset = fdt_find_or_add_subnode(blob, 0, "chosen");
+   if (nodeoffset < 0) {
+   debug("Reading chosen node failed\n");
+   return -EINVAL;
+   }
+
+   ret = fdt_setprop(blob, nodeoffset, "kaslr-seed", buf, sizeof(buf));
+   if (ret < 0) {
+   debug("Unable to set kaslr-seed on chosen node: %s\n", 
fdt_strerror(ret));
+   return -EINVAL;
+   }
+
+   return ret;
+}
+#endif
-- 
2.25.1



[PATCH v2 0/2] xilinx: Update the kaslr-seed property

2024-01-15 Thread Venkatesh Yadav Abbarapu
Update the kaslr-seed property and enable the config CONFIG_OF_BOARD_SETUP.

Changes in v2:
- Created macro for size variable.
- Removed malloc and created array for rng buffer.
- Added debug logs for all the apis.

Venkatesh Yadav Abbarapu (2):
  xilinx: board: Update the kaslr-seed property
  configs: zynqmp_kria: Enable CONFIG_OF_BOARD_SETUP

 board/xilinx/common/board.c  | 50 
 configs/xilinx_zynqmp_kria_defconfig |  1 +
 2 files changed, 51 insertions(+)

-- 
2.25.1



[PATCH 1/2] xilinx: board: Update the kaslr-seed property

2024-01-11 Thread Venkatesh Yadav Abbarapu
Create a ft_board_setup() api that gets called as part
of bootm/booti before jumping to kernel. In this
ft_board_setup() callback that will inspect the DTB
and insert the device tree blob with the "kaslr-seed" property.

Signed-off-by: Michal Simek 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 board/xilinx/common/board.c | 59 +
 1 file changed, 59 insertions(+)

diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index 12a877c715..985a3825e6 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -682,3 +682,62 @@ phys_addr_t board_get_usable_ram_top(phys_size_t 
total_size)
return reg + size;
 }
 #endif
+
+#ifdef CONFIG_OF_BOARD_SETUP
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+   size_t n = 0x8;
+   struct udevice *dev;
+   u64 *buf;
+   int nodeoffset;
+   int ret;
+
+   if (uclass_get_device(UCLASS_RNG, 0, ) || !dev) {
+   debug("No RNG device\n");
+   return 0;
+   }
+
+   buf = malloc(n);
+   if (!buf) {
+   debug("Out of memory\n");
+   return 0;
+   }
+
+   if (dm_rng_read(dev, buf, n)) {
+   debug("Reading RNG failed\n");
+   ret = 0;
+   goto end;
+   }
+
+   if (!blob) {
+   debug("No FDT memory address configured. Please configure\n"
+ "the FDT address via \"fdt addr \" command.\n"
+ "Aborting!\n");
+   ret = 0;
+   goto end;
+   }
+
+   ret = fdt_check_header(blob);
+   if (ret < 0) {
+   printf("fdt_chosen: %s\n", fdt_strerror(ret));
+   goto end;
+   }
+
+   nodeoffset = fdt_find_or_add_subnode(blob, 0, "chosen");
+   if (nodeoffset < 0) {
+   printf("Reading chosen node failed\n");
+   ret = -EINVAL;
+   goto end;
+   }
+
+   ret = fdt_setprop(blob, nodeoffset, "kaslr-seed", buf, sizeof(buf));
+   if (ret < 0) {
+   printf("Unable to set kaslr-seed on chosen node: %s\n", 
fdt_strerror(ret));
+   goto end;
+   }
+end:
+   free(buf);
+
+   return ret;
+}
+#endif
-- 
2.25.1



[PATCH 0/2] xilinx: Update the kaslr-seed property

2024-01-11 Thread Venkatesh Yadav Abbarapu
Update the kaslr-seed property and enable the config
CONFIG_OF_BOARD_SETUP.

Venkatesh Yadav Abbarapu (2):
  xilinx: board: Update the kaslr-seed property
  configs: zynqmp_kria: Enable CONFIG_OF_BOARD_SETUP

 board/xilinx/common/board.c  | 59 
 configs/xilinx_zynqmp_kria_defconfig |  1 +
 2 files changed, 60 insertions(+)

-- 
2.25.1



[PATCH 2/2] configs: zynqmp_kria: Enable CONFIG_OF_BOARD_SETUP

2024-01-11 Thread Venkatesh Yadav Abbarapu
Enable CONFIG_OF_BOARD_SETUP, so we could use ft_board_setup()
to enable the kaslr-seed and pass to kernel.

Signed-off-by: Michal Simek 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 configs/xilinx_zynqmp_kria_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/xilinx_zynqmp_kria_defconfig 
b/configs/xilinx_zynqmp_kria_defconfig
index a65a59c1ae..86741f1773 100644
--- a/configs/xilinx_zynqmp_kria_defconfig
+++ b/configs/xilinx_zynqmp_kria_defconfig
@@ -33,6 +33,7 @@ CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT_ADDRESS=0x1000
 CONFIG_SYS_BOOTM_LEN=0x640
 CONFIG_DISTRO_DEFAULTS=y
+CONFIG_OF_BOARD_SETUP=y
 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
 CONFIG_USE_PREBOOT=y
 CONFIG_SYS_PBSIZE=2073
-- 
2.25.1



[PATCH] misc: usb2244: Add support to reset usb2244 usb2.0 SD controller

2024-01-11 Thread Venkatesh Yadav Abbarapu
Usb2244 driver needs to be reset to bring usb2244 out of reset. This
driver will reset the controller using gpio.

Signed-off-by: T Karthik Reddy 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 MAINTAINERS|  1 +
 drivers/misc/Kconfig   |  8 +
 drivers/misc/Makefile  |  1 +
 drivers/misc/usb2244.c | 69 ++
 4 files changed, 79 insertions(+)
 create mode 100644 drivers/misc/usb2244.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 1e950c3b45..be50fddc38 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -815,6 +815,7 @@ F:  drivers/i2c/i2c-cdns.c
 F: drivers/i2c/muxes/pca954x.c
 F: drivers/i2c/zynq_i2c.c
 F: drivers/mailbox/zynqmp-ipi.c
+F: drivers/misc/usb2244.c
 F: drivers/misc/usb5744.c
 F: drivers/mmc/zynq_sdhci.c
 F: drivers/mtd/nand/raw/zynq_nand.c
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index b7022c31ee..3b6ca7d4bc 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -696,4 +696,12 @@ config USB5744
  This enables support for Microchip USB5744 Hub. This driver reset
  the hub using gpio pin and configure hub via i2c.
 
+config USB2244
+   bool "Microchip USB2244 Ultra Fast USB 2.0 SD driver"
+   depends on DM_USB && DM_GPIO
+   help
+ This option enables support for Microchip USB2244 Ultra Fast USB 2.0
+ SD controller. This driver will reset the usb2244 controller using a
+ gpio pin.
+
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 19f5afa885..82b7b92c0a 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -91,3 +91,4 @@ obj-$(CONFIG_ESM_K3) += k3_esm.o
 obj-$(CONFIG_ESM_PMIC) += esm_pmic.o
 obj-$(CONFIG_SL28CPLD) += sl28cpld.o
 obj-$(CONFIG_USB5744)  += usb5744.o
+obj-$(CONFIG_USB2244)  += usb2244.o
diff --git a/drivers/misc/usb2244.c b/drivers/misc/usb2244.c
new file mode 100644
index 00..19dcd1eef6
--- /dev/null
+++ b/drivers/misc/usb2244.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for the Microchip USB2244 Ultra Fast USB 2.0 SD controller.
+ *
+ * Copyright (C) 2024,Advanced Micro Devices, Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct usb2244_priv {
+   struct gpio_desc reset_gpio;
+};
+
+static int usb2244_probe(struct udevice *dev)
+{
+   struct usb2244_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   ret = dm_gpio_set_value(>reset_gpio, 1);
+   if (ret)
+   return ret;
+
+   mdelay(5);
+
+   ret = dm_gpio_set_value(>reset_gpio, 0);
+   if (ret)
+   return ret;
+
+   mdelay(5);
+
+   return 0;
+}
+
+static int usb2244_plat(struct udevice *dev)
+{
+   struct usb2244_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   ret = gpio_request_by_name(dev, "reset-gpios", 0, >reset_gpio,
+  GPIOD_IS_OUT | GPIOD_ACTIVE_LOW);
+   if (ret) {
+   printf("%s, gpio request failed err: %d\n", __func__, ret);
+   return ret;
+   }
+
+   return 0;
+}
+
+U_BOOT_DRIVER(usb2244) = {
+   .name = "usb2244",
+   .id = UCLASS_MISC,
+   .probe = usb2244_probe,
+   .of_to_plat = usb2244_plat,
+   .priv_auto = sizeof(struct usb2244_priv),
+};
+
+static const struct usb_device_id usb2244_id_table[] = {
+   {
+   .idVendor = 0x0424,
+   .idProduct = 0x2240
+   },
+   { }
+};
+
+U_BOOT_USB_DEVICE(usb2244, usb2244_id_table);
-- 
2.25.1



[PATCH] misc: usb5744: Add support for usb5744 usb hub driver

2024-01-11 Thread Venkatesh Yadav Abbarapu
Microchip usb5744 driver resets the usbhub by toggling gpio to bring the
hub from reset. Also configures the usbhub by sending command using i2c
after hub reset.

Signed-off-by: T Karthik Reddy 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 MAINTAINERS|   1 +
 drivers/misc/Kconfig   |   7 +++
 drivers/misc/Makefile  |   1 +
 drivers/misc/usb5744.c | 138 +
 4 files changed, 147 insertions(+)
 create mode 100644 drivers/misc/usb5744.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4fec063a24..1e950c3b45 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -815,6 +815,7 @@ F:  drivers/i2c/i2c-cdns.c
 F: drivers/i2c/muxes/pca954x.c
 F: drivers/i2c/zynq_i2c.c
 F: drivers/mailbox/zynqmp-ipi.c
+F: drivers/misc/usb5744.c
 F: drivers/mmc/zynq_sdhci.c
 F: drivers/mtd/nand/raw/zynq_nand.c
 F: drivers/net/phy/xilinx_phy.c
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index e8e4400516..b7022c31ee 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -689,4 +689,11 @@ config SL28CPLD
  the base driver which provides common access methods for the
  sub-drivers.
 
+config USB5744
+   bool "Microchip USB5744 usb hub"
+   depends on DM_USB && DM_I2C && DM_GPIO
+   help
+ This enables support for Microchip USB5744 Hub. This driver reset
+ the hub using gpio pin and configure hub via i2c.
+
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index cda701d38e..19f5afa885 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -90,3 +90,4 @@ obj-$(CONFIG_K3_AVS0) += k3_avs.o
 obj-$(CONFIG_ESM_K3) += k3_esm.o
 obj-$(CONFIG_ESM_PMIC) += esm_pmic.o
 obj-$(CONFIG_SL28CPLD) += sl28cpld.o
+obj-$(CONFIG_USB5744)  += usb5744.o
diff --git a/drivers/misc/usb5744.c b/drivers/misc/usb5744.c
new file mode 100644
index 00..7dbc4fba90
--- /dev/null
+++ b/drivers/misc/usb5744.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for the Microchip USB5744 4-port hub.
+ *
+ * Copyright (C) 2024,Advanced Micro Devices, Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define I2C_ADDR   0x2D
+#define USB_COMMAND_ATTACH 0x0056
+#define USB_CONFIG_REG_ACCESS  0x0037
+
+struct usb5744_priv {
+   struct gpio_desc reset_gpio;
+   struct udevice *i2c_dev;
+};
+
+static int usb5744_probe(struct udevice *dev)
+{
+   struct usb5744_priv *priv = dev_get_priv(dev);
+   struct dm_i2c_chip *i2c_chip;
+   int ret;
+   u32 buf = USB_COMMAND_ATTACH;
+   u32 config_reg_access_buf = USB_CONFIG_REG_ACCESS;
+   /*
+*  Prevent the MCU from the putting the HUB in suspend mode through 
register write.
+*  The BYPASS_UDC_SUSPEND bit (Bit 3) of the RuntimeFlags2 register at 
address
+*  0x411D controls this aspect of the hub.
+*  Format to write to hub registers via SMBus- 2D 00 00 05 00 01 41 1D 
08
+*  Byte 0: Address of slave 2D
+*  Byte 1: Memory address 00
+*  Byte 2: Memory address 00
+*  Byte 3: Number of bytes to write to memory
+*  Byte 4: Write configuration register (00)
+*  Byte 5: Write the number of data bytes (01- 1 data byte)
+*  Byte 6: LSB of register address 0x41
+*  Byte 7: MSB of register address 0x1D
+*  Byte 8: value to be written to the register
+*/
+   char data_buf[8] = {0x0, 0x5, 0x0, 0x1, 0x41, 0x1D, 0x08};
+
+   ret = dm_gpio_set_value(>reset_gpio, 1);
+   if (ret)
+   return ret;
+
+   mdelay(5);
+
+   ret = dm_gpio_set_value(>reset_gpio, 0);
+   if (ret)
+   return ret;
+
+   mdelay(10);
+
+   i2c_chip = dev_get_parent_plat(priv->i2c_dev);
+   if (i2c_chip) {
+   i2c_chip->flags &= ~DM_I2C_CHIP_WR_ADDRESS;
+   /* SMBus write command */
+   ret = dm_i2c_write(priv->i2c_dev, 0x0, (uint8_t *)_buf, 8);
+   if (ret) {
+   dev_err(dev, "data_buf i2c_write failed, err:%d\n", 
ret);
+   return ret;
+   }
+
+   /* Configuration register access command */
+   ret = dm_i2c_write(priv->i2c_dev, 0x99, (uint8_t 
*)_reg_access_buf, 2);
+   if (ret) {
+   dev_err(dev, "config_reg_access i2c_write failed, err: 
%d\n", ret);
+   return ret;
+   }
+
+   /* USB Attach with SMBus */
+   ret = dm_i2c_write(priv->i2c_dev, 0xAA, (uint8_t *), 2);
+   if (ret) {
+   dev_err(dev, "usb_attach i2c_write failed, err: %d\n", 
ret);
+   return ret;
+   }
+   }
+
+   return 0;
+}
+
+static int usb5744_plat(struct udevice *dev)
+{
+   struct usb5744_priv *priv = d

[PATCH] usb: dwc3: Integrate usb5744 & usb2244 driver support

2024-01-10 Thread Venkatesh Yadav Abbarapu
Usb5744 & usb2244 are Microchip based usbhub and usb-2.0 based SD
controller devices. Integrate these devices into dwc3 driver to bind and
probe the respective drivers to get detected by usb controller.

Signed-off-by: T Karthik Reddy 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/usb/dwc3/dwc3-generic.c | 67 -
 1 file changed, 49 insertions(+), 18 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 6fb2de8a5a..a2eb2c8e24 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -430,29 +430,49 @@ static int dwc3_glue_bind_common(struct udevice *parent, 
ofnode node)
 
debug("%s: subnode name: %s\n", __func__, name);
 
+   if (!ofnode_device_is_compatible(node, "snps,dwc3")) {
+   if (ofnode_device_is_compatible(node,
+   "microchip,usb5744"))
+   driver = "usb5744";
+   else if (ofnode_device_is_compatible
+   (node, "microchip,usb2244"))
+   driver = "usb2244";
+
+   ret = device_bind_driver_to_node(parent, driver, name,
+node, );
+   if (ret) {
+   printf("Failed to bind: %s, err: %d\n",
+  driver, ret);
+   return ret;
+   }
+   }
+
/* if the parent node doesn't have a mode check the leaf */
dr_mode = usb_get_dr_mode(dev_ofnode(parent));
if (!dr_mode)
dr_mode = usb_get_dr_mode(node);
 
-   if (CONFIG_IS_ENABLED(DM_USB_GADGET) &&
-   (dr_mode == USB_DR_MODE_PERIPHERAL || dr_mode == USB_DR_MODE_OTG)) {
-   debug("%s: dr_mode: OTG or Peripheral\n", __func__);
-   driver = "dwc3-generic-peripheral";
-   } else if (CONFIG_IS_ENABLED(USB_HOST) && dr_mode == USB_DR_MODE_HOST) {
-   debug("%s: dr_mode: HOST\n", __func__);
-   driver = "dwc3-generic-host";
-   } else {
-   debug("%s: unsupported dr_mode %d\n", __func__, dr_mode);
-   return -ENODEV;
-   }
+   if (ofnode_device_is_compatible(node, "snps,dwc3")) {
+   if (CONFIG_IS_ENABLED(DM_USB_GADGET) &&
+   (dr_mode == USB_DR_MODE_PERIPHERAL || dr_mode == 
USB_DR_MODE_OTG)) {
+   debug("%s: dr_mode: OTG or Peripheral\n", __func__);
+   driver = "dwc3-generic-peripheral";
+   } else if (CONFIG_IS_ENABLED(USB_HOST) && dr_mode == 
USB_DR_MODE_HOST) {
+   debug("%s: dr_mode: HOST\n", __func__);
+   driver = "dwc3-generic-host";
+   } else {
+   debug("%s: unsupported dr_mode %d\n", __func__, 
dr_mode);
+   return -ENODEV;
+   }
 
-   ret = device_bind_driver_to_node(parent, driver, name,
-node, );
-   if (ret) {
-   debug("%s: not able to bind usb device mode\n",
- __func__);
-   return ret;
+   ret = device_bind_driver_to_node(parent, driver, name,
+node, );
+
+   if (ret) {
+   debug("%s: not able to bind usb device mode\n",
+ __func__);
+   return ret;
+   }
}
 
return 0;
@@ -479,7 +499,6 @@ int dwc3_glue_bind(struct udevice *parent)
if (ret)
return ret;
}
-
return 0;
 }
 
@@ -530,6 +549,7 @@ int dwc3_glue_probe(struct udevice *dev)
struct dwc3_glue_ops *ops = (struct dwc3_glue_ops 
*)dev_get_driver_data(dev);
struct dwc3_glue_data *glue = dev_get_plat(dev);
struct udevice *child = NULL;
+   ofnode node;
int index = 0;
int ret;
struct phy phy;
@@ -560,6 +580,17 @@ int dwc3_glue_probe(struct udevice *dev)
return ret;
}
 
+   ofnode_for_each_subnode(node, dev_ofnode(dev)) {
+   if (!ofnode_device_is_compatible(node, "snps,dwc3")) {
+   ret = uclass_get_device_by_ofnode(UCLASS_MISC, node, 
);
+   if (ret) {
+   printf("could not get device %s, err = %d\n",
+  node.np->name, ret);
+   return ret;
+   }
+   }
+   }
+
device_find_first_child(dev, );
if (!child)
return 0;
-- 
2.25.1



[PATCH v2] xilinx: r5: Include the sys_r5_proto.h header for future use

2024-01-10 Thread Venkatesh Yadav Abbarapu
Currently when using "W=1" with xilinx_zynqmp_r5_defconfig, getting
below warnings.
cc1.real: warning: ./arch/arm/mach-zynqmp-r5/include:
No such file or directory [-Wmissing-include-dirs]
Fix W=1 missing-include-dirs warnings by including the headers and
sys_r5_proto.h file which can be used.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
Changes in v2:
- Fixed the copyright and other minor syntax issues.
---
 arch/arm/mach-zynqmp-r5/include/mach/sys_r5_proto.h | 5 +
 1 file changed, 5 insertions(+)
 create mode 100644 arch/arm/mach-zynqmp-r5/include/mach/sys_r5_proto.h

diff --git a/arch/arm/mach-zynqmp-r5/include/mach/sys_r5_proto.h 
b/arch/arm/mach-zynqmp-r5/include/mach/sys_r5_proto.h
new file mode 100644
index 00..0f7a47bf24
--- /dev/null
+++ b/arch/arm/mach-zynqmp-r5/include/mach/sys_r5_proto.h
@@ -0,0 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2024, Advanced Micro Devices, Inc.
+ *  Michal Simek 
+ */
-- 
2.25.1



[PATCH] xilinx: r5: Include the sys_r5_proto.h header for future use

2024-01-08 Thread Venkatesh Yadav Abbarapu
Currently when using "W=1" with xilinx_zynqmp_r5_defconfig, getting
below warnings.
cc1.real: warning: ./arch/arm/mach-zynqmp-r5/include:
No such file or directory [-Wmissing-include-dirs]
Fix W=1 missing-include-dirs warnings by including the headers and
sys_r5_proto.h file which can be used.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 arch/arm/mach-zynqmp-r5/include/mach/sys_r5_proto.h | 10 ++
 1 file changed, 10 insertions(+)
 create mode 100644 arch/arm/mach-zynqmp-r5/include/mach/sys_r5_proto.h

diff --git a/arch/arm/mach-zynqmp-r5/include/mach/sys_r5_proto.h 
b/arch/arm/mach-zynqmp-r5/include/mach/sys_r5_proto.h
new file mode 100644
index 00..3f75658c15
--- /dev/null
+++ b/arch/arm/mach-zynqmp-r5/include/mach/sys_r5_proto.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ *(C) Copyright 2024, Advanced Micro Devices, Inc.
+ * Michal Simek 
+ */
+
+#ifndef _ASM_ARCH_SYS_R5_PROTO_H
+#define _ASM_ARCH_SYS_R5_PROTO_H
+
+#endif /* _ASM_ARCH_SYS_R5_PROTO_H */
-- 
2.25.1



[PATCH] mtd: spi-nor: scale up timeout for full-chip erase

2024-01-02 Thread Venkatesh Yadav Abbarapu
This patch fixes timeout issues seen on large NOR flash.
For full-chip erase, where we use the SPINOR_OP_CHIP_ERASE (0xc7)
opcode. Use a different timeout for full-chip erase than for other
commands.

 [Ported from Linux kernel commit
09b6a377687b ("mtd: spi-nor: scale up timeout for
   full-chip erase") ]

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 31 +--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 9a1801ba93..171c68787c 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -45,6 +45,12 @@
 
 #define DEFAULT_READY_WAIT_JIFFIES (40UL * HZ)
 
+/*
+ * For full-chip erase, calibrated to a 2MB flash (M25P16); should be scaled up
+ * for larger flash
+ */
+#define CHIP_ERASE_2MB_READY_WAIT_JIFFIES  (40UL * HZ)
+
 #define ROUND_UP_TO(x, y)  (((x) + (y) - 1) / (y) * (y))
 
 struct sfdp_parameter_header {
@@ -832,6 +838,20 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor)
DEFAULT_READY_WAIT_JIFFIES);
 }
 
+static int spi_nor_erase_chip_wait_till_ready(struct spi_nor *nor, unsigned 
long size)
+{
+   /*
+* Scale the timeout linearly with the size of the flash, with
+* a minimum calibrated to an old 2MB flash. We could try to
+* pull these from CFI/SFDP, but these values should be good
+* enough for now.
+*/
+   unsigned long timeout = max(CHIP_ERASE_2MB_READY_WAIT_JIFFIES,
+   CHIP_ERASE_2MB_READY_WAIT_JIFFIES *
+   (unsigned long)(size / SZ_2M));
+   return spi_nor_wait_till_ready_with_timeout(nor, timeout);
+}
+
 #ifdef CONFIG_SPI_FLASH_BAR
 /*
  * This "clean_bar" is necessary in a situation when one was accessing
@@ -966,7 +986,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
bool addr_known = false;
-   u32 addr, len, rem;
+   u32 addr, len, rem, max_size;
int ret, err;
 
dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
@@ -980,6 +1000,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
 
addr = instr->addr;
len = instr->len;
+   max_size = instr->len;
 
instr->state = MTD_ERASING;
addr_known = true;
@@ -1012,7 +1033,13 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
addr += ret;
len -= ret;
 
-   ret = spi_nor_wait_till_ready(nor);
+   if (max_size == mtd->size &&
+   !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
+   ret = spi_nor_erase_chip_wait_till_ready(nor, 
mtd->size);
+   } else {
+   ret = spi_nor_wait_till_ready(nor);
+   }
+
if (ret)
goto erase_err;
}
-- 
2.25.1



[PATCH v9 8/8] axm/taurus: Disable the SPL_SPI config

2023-12-26 Thread Venkatesh Yadav Abbarapu
Disabling the CONFIG_SPL_SPI for the axm and taurus defconfigs,
as facing the SPL size issue "SPL image too big".

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 board/siemens/taurus/taurus.c | 4 +++-
 configs/axm_defconfig | 7 ++-
 configs/taurus_defconfig  | 7 ++-
 3 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/board/siemens/taurus/taurus.c b/board/siemens/taurus/taurus.c
index ad44a7c0d2..ac1ce8acf4 100644
--- a/board/siemens/taurus/taurus.c
+++ b/board/siemens/taurus/taurus.c
@@ -135,11 +135,12 @@ void spl_board_init(void)
 
/* check for recovery mode */
if (at91_is_recovery() == 1) {
-   struct spi_flash *flash;
 
puts("Recovery button pressed\n");
nand_init();
spl_nand_erase_one(0, 0);
+#if defined(CONFIG_SPL_SPI)
+   struct spi_flash *flash;
flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
0,
CONFIG_SF_DEFAULT_SPEED,
@@ -151,6 +152,7 @@ void spl_board_init(void)
spi_flash_erase(flash, 0,
CFG_SYS_NAND_U_BOOT_SIZE);
}
+#endif
}
 }
 
diff --git a/configs/axm_defconfig b/configs/axm_defconfig
index e1a01b24b8..4d439832d7 100644
--- a/configs/axm_defconfig
+++ b/configs/axm_defconfig
@@ -3,7 +3,6 @@ CONFIG_SKIP_LOWLEVEL_INIT_ONLY=y
 CONFIG_SPL_SKIP_LOWLEVEL_INIT_ONLY=y
 CONFIG_SPL_SYS_DCACHE_OFF=y
 CONFIG_ARCH_CPU_INIT=y
-CONFIG_SYS_THUMB_BUILD=y
 # CONFIG_SPL_USE_ARCH_MEMCPY is not set
 # CONFIG_SPL_USE_ARCH_MEMSET is not set
 CONFIG_ARCH_AT91=y
@@ -26,14 +25,14 @@ CONFIG_SPL=y
 CONFIG_DEBUG_UART_BASE=0xf200
 CONFIG_DEBUG_UART_CLOCK=18432000
 CONFIG_ENV_OFFSET_REDUND=0x18
-CONFIG_SPL_SPI_FLASH_SUPPORT=y
-CONFIG_SPL_SPI=y
 CONFIG_SYS_LOAD_ADDR=0x2200
 CONFIG_DEBUG_UART=y
 CONFIG_NAND_BOOT=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTCOMMAND=y
 CONFIG_BOOTCOMMAND="run flash_self"
+CONFIG_SYS_CBSIZE=256
+CONFIG_SYS_PBSIZE=281
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_SPL_MAX_SIZE=0x3e00
@@ -57,8 +56,6 @@ CONFIG_SPL_NAND_BASE=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="U-Boot> "
-CONFIG_SYS_CBSIZE=256
-CONFIG_SYS_PBSIZE=281
 # CONFIG_CMD_BDI is not set
 CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMI is not set
diff --git a/configs/taurus_defconfig b/configs/taurus_defconfig
index 9be30c8d8a..7d71262d1a 100644
--- a/configs/taurus_defconfig
+++ b/configs/taurus_defconfig
@@ -4,7 +4,6 @@ CONFIG_SPL_SKIP_LOWLEVEL_INIT_ONLY=y
 CONFIG_SPL_SYS_ICACHE_OFF=y
 CONFIG_SPL_SYS_DCACHE_OFF=y
 CONFIG_ARCH_CPU_INIT=y
-CONFIG_SYS_THUMB_BUILD=y
 # CONFIG_SPL_USE_ARCH_MEMCPY is not set
 # CONFIG_SPL_USE_ARCH_MEMSET is not set
 CONFIG_ARCH_AT91=y
@@ -28,8 +27,6 @@ CONFIG_SPL=y
 CONFIG_DEBUG_UART_BASE=0xf200
 CONFIG_DEBUG_UART_CLOCK=18432000
 CONFIG_ENV_OFFSET_REDUND=0x18
-CONFIG_SPL_SPI_FLASH_SUPPORT=y
-CONFIG_SPL_SPI=y
 CONFIG_SYS_LOAD_ADDR=0x2200
 CONFIG_DEBUG_UART=y
 CONFIG_NAND_BOOT=y
@@ -38,6 +35,8 @@ CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk 
mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256k(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs)
 root=/dev/mtdblock7 rw rootfstype=jffs2"
 CONFIG_USE_BOOTCOMMAND=y
 CONFIG_BOOTCOMMAND="nand read 0x2200 0x20 0x30; bootm"
+CONFIG_SYS_CBSIZE=256
+CONFIG_SYS_PBSIZE=281
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_SPL_MAX_SIZE=0x3e00
@@ -61,8 +60,6 @@ CONFIG_SPL_NAND_BASE=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="U-Boot> "
-CONFIG_SYS_CBSIZE=256
-CONFIG_SYS_PBSIZE=281
 # CONFIG_SYS_XTRACE is not set
 # CONFIG_CMD_BDI is not set
 CONFIG_CMD_BOOTZ=y
-- 
2.25.1



[PATCH v9 7/8] config: xea: Enable the SPL_FIT config option

2023-12-26 Thread Venkatesh Yadav Abbarapu
Enable the config SPL_FIT, as getting the below error
../arm-xilinx-linux-gnueabi-ld.bfd.real: drivers/core/ofnode.o: in function
`ofnode_get_property':
/u-boot/drivers/core/ofnode.c:1185: undefined reference to `fdt_getprop'
make[1]: *** [scripts/Makefile.spl:527: spl/u-boot-spl] Error 1

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 configs/imx28_xea_defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configs/imx28_xea_defconfig b/configs/imx28_xea_defconfig
index c1b0487f7e..882b6093c9 100644
--- a/configs/imx28_xea_defconfig
+++ b/configs/imx28_xea_defconfig
@@ -29,6 +29,7 @@ CONFIG_SYS_LOAD_ADDR=0x4200
 CONFIG_SPL_PAYLOAD="u-boot.img"
 CONFIG_TIMESTAMP=y
 CONFIG_FIT=y
+CONFIG_SPL_FIT=y
 # CONFIG_BOOTMETH_EXTLINUX is not set
 # CONFIG_BOOTMETH_VBE is not set
 CONFIG_OF_BOARD_SETUP=y
@@ -123,4 +124,3 @@ CONFIG_DM_SERIAL=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
 CONFIG_MXS_SPI=y
-# CONFIG_SPL_OF_LIBFDT is not set
-- 
2.25.1



[PATCH v9 4/8] spi: spi-uclass: Read chipselect and restrict capabilities

2023-12-26 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Read chipselect properties from DT which are populated using 'reg'
property and save it in plat->cs[] array for later use.

Also read multi chipselect capability which is used for
parallel-memories and return errors if they are passed on using DT but
driver is not capable of handling it.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/sandbox.c|  2 +-
 drivers/spi/altera_spi.c |  4 ++--
 drivers/spi/atcspi200_spi.c  |  2 +-
 drivers/spi/ath79_spi.c  |  2 +-
 drivers/spi/atmel_spi.c  |  6 +++---
 drivers/spi/bcm63xx_hsspi.c  | 42 ++--
 drivers/spi/bcm63xx_spi.c|  6 +++---
 drivers/spi/bcmbca_hsspi.c   | 34 ++---
 drivers/spi/cf_spi.c |  6 +++---
 drivers/spi/davinci_spi.c|  8 +++
 drivers/spi/fsl_dspi.c   | 18 
 drivers/spi/fsl_espi.c   |  4 ++--
 drivers/spi/fsl_qspi.c   |  4 ++--
 drivers/spi/gxp_spi.c|  2 +-
 drivers/spi/mpc8xx_spi.c |  4 ++--
 drivers/spi/mpc8xxx_spi.c| 10 -
 drivers/spi/mscc_bb_spi.c|  4 ++--
 drivers/spi/mxc_spi.c|  6 +++---
 drivers/spi/npcm_fiu_spi.c   | 14 ++--
 drivers/spi/nxp_fspi.c   |  2 +-
 drivers/spi/octeon_spi.c |  2 +-
 drivers/spi/omap3_spi.c  |  4 ++--
 drivers/spi/pic32_spi.c  |  2 +-
 drivers/spi/rk_spi.c |  4 ++--
 drivers/spi/rockchip_sfc.c   |  2 +-
 drivers/spi/spi-aspeed-smc.c | 28 
 drivers/spi/spi-mxic.c   |  6 +++---
 drivers/spi/spi-qup.c|  4 ++--
 drivers/spi/spi-sifive.c |  6 +++---
 drivers/spi/spi-sn-f-ospi.c  |  2 +-
 drivers/spi/spi-sunxi.c  |  6 +++---
 drivers/spi/spi-synquacer.c  |  4 ++--
 drivers/spi/spi-uclass.c | 33 +++-
 drivers/spi/stm32_qspi.c |  2 +-
 drivers/spi/stm32_spi.c  |  4 ++--
 drivers/spi/ti_qspi.c| 14 ++--
 drivers/spi/xilinx_spi.c |  6 +++---
 drivers/spi/zynq_qspi.c  |  6 +++---
 drivers/spi/zynq_spi.c   |  6 +++---
 include/spi.h|  8 ++-
 lib/acpi/acpi_device.c   |  2 +-
 41 files changed, 180 insertions(+), 151 deletions(-)

diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 4fe547171a..72036d5a88 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -139,7 +139,7 @@ static int sandbox_sf_probe(struct udevice *dev)
return ret;
}
slave_plat = dev_get_parent_plat(dev);
-   cs = slave_plat->cs;
+   cs = slave_plat->cs[0];
debug("found at cs %d\n", cs);
 
if (!pdata->filename) {
diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c
index 989679e881..48782f81c1 100644
--- a/drivers/spi/altera_spi.c
+++ b/drivers/spi/altera_spi.c
@@ -96,7 +96,7 @@ static int altera_spi_xfer(struct udevice *dev, unsigned int 
bitlen,
uint32_t reg, data, start;
 
debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
- dev_seq(bus), slave_plat->cs, bitlen, bytes, flags);
+ dev_seq(bus), slave_plat->cs[0], bitlen, bytes, flags);
 
if (bitlen == 0)
goto done;
@@ -111,7 +111,7 @@ static int altera_spi_xfer(struct udevice *dev, unsigned 
int bitlen,
readl(>rxdata);
 
if (flags & SPI_XFER_BEGIN)
-   spi_cs_activate(dev, slave_plat->cs);
+   spi_cs_activate(dev, slave_plat->cs[0]);
 
while (bytes--) {
if (txp)
diff --git a/drivers/spi/atcspi200_spi.c b/drivers/spi/atcspi200_spi.c
index de9c14837c..acee743653 100644
--- a/drivers/spi/atcspi200_spi.c
+++ b/drivers/spi/atcspi200_spi.c
@@ -321,7 +321,7 @@ static int atcspi200_spi_claim_bus(struct udevice *dev)
struct udevice *bus = dev->parent;
struct nds_spi_slave *ns = dev_get_priv(bus);
 
-   if (slave_plat->cs >= ns->num_cs) {
+   if (slave_plat->cs[0] >= ns->num_cs) {
printf("Invalid SPI chipselect\n");
return -EINVAL;
}
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
index 205567ef54..ad10cec2a6 100644
--- a/drivers/spi/ath79_spi.c
+++ b/drivers/spi/ath79_spi.c
@@ -74,7 +74,7 @@ static int ath79_spi_xfer(struct udevice *dev, unsigned int 
bitlen,
if (restbits)
bytes++;
 
-   out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs));
+   out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs[0]));
while (bytes > 0) {
bytes--;
curbyte = 0;
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index aec6f4eca9..e2de39d1ef 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -126,7 +126,7 @@ static int atmel_spi_claim_bus(struct udevice *dev)
struct atmel_spi_priv *priv = dev_get

[PATCH v9 5/8] spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver

2023-12-26 Thread Venkatesh Yadav Abbarapu
Add support for parallel memories in zynqmp_gqspi.c driver. In case of
parallel memories STRIPE bit is set and sent to the qspi ip, which will
send data bits to both the flashes in parallel. However for few commands
we should not use stripe, instead send same data to both the flashes.
Those commands are exclueded by using zynqmp_qspi_update_stripe().

Also update copyright info for this file.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/zynqmp_gqspi.c | 141 -
 include/spi.h  |   4 ++
 2 files changed, 129 insertions(+), 16 deletions(-)

diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index a323994fb2..dedf8270a8 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2018 Xilinx
- *
+ * (C) Copyright 2013 - 2022, Xilinx, Inc.
+ * (C) Copyright 2023, Advanced Micro Devices, Inc.
  * Xilinx ZynqMP Generic Quad-SPI(QSPI) controller driver(master mode only)
  */
 
@@ -25,6 +25,8 @@
 #include 
 #include 
 #include 
+#include 
+#include "../mtd/spi/sf_internal.h"
 #include 
 
 #define GQSPI_GFIFO_STRT_MODE_MASK BIT(29)
@@ -88,6 +90,9 @@
 #define SPI_XFER_ON_LOWER  1
 #define SPI_XFER_ON_UPPER  2
 
+#define GQSPI_SELECT_LOWER_CS  BIT(0)
+#define GQSPI_SELECT_UPPER_CS  BIT(1)
+
 #define GQSPI_DMA_ALIGN0x4
 #define GQSPI_MAX_BAUD_RATE_VAL7
 #define GQSPI_DFLT_BAUD_RATE_VAL   2
@@ -183,13 +188,14 @@ struct zynqmp_qspi_priv {
int bytes_to_transfer;
int bytes_to_receive;
const struct spi_mem_op *op;
+   unsigned int is_parallel;
+   unsigned int u_page;
+   unsigned int bus;
+   unsigned int stripe;
+   unsigned int flags;
+   u32 max_hz;
 };
 
-__weak int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 
value)
-{
-   return 0;
-}
-
 static int zynqmp_qspi_of_to_plat(struct udevice *bus)
 {
struct zynqmp_qspi_plat *plat = dev_get_plat(bus);
@@ -234,8 +240,30 @@ static u32 zynqmp_qspi_bus_select(struct zynqmp_qspi_priv 
*priv)
 {
u32 gqspi_fifo_reg = 0;
 
-   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
-GQSPI_GFIFO_CS_LOWER;
+   if (priv->is_parallel) {
+   if (priv->bus == SPI_XFER_ON_BOTH)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_CS_UPPER |
+GQSPI_GFIFO_CS_LOWER;
+   else if (priv->bus == SPI_XFER_ON_LOWER)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_UPPER |
+GQSPI_GFIFO_CS_LOWER;
+   else if (priv->bus == SPI_XFER_ON_UPPER)
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_CS_LOWER |
+GQSPI_GFIFO_CS_UPPER;
+   else
+   debug("Wrong Bus selection:0x%x\n", priv->bus);
+   } else {
+   if (priv->u_page)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_UPPER;
+   else
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_LOWER;
+   }
 
return gqspi_fifo_reg;
 }
@@ -295,8 +323,15 @@ static void zynqmp_qspi_chipselect(struct zynqmp_qspi_priv 
*priv, int is_on)
gqspi_fifo_reg |= GQSPI_SPI_MODE_SPI |
  GQSPI_IMD_DATA_CS_ASSERT;
} else {
-   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS;
-   gqspi_fifo_reg |= GQSPI_IMD_DATA_CS_DEASSERT;
+   if (priv->is_parallel) {
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_LOW_BUS;
+   } else if (priv->u_page) {
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS;
+   } else {
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS;
+   gqspi_fifo_reg |= GQSPI_IMD_DATA_CS_DEASSERT;
+   }
}
 
zynqmp_qspi_fill_gen_fifo(priv, gqspi_fifo_reg);
@@ -366,12 +401,13 @@ static int zynqmp_qspi_set_speed(struct udevice *bus, 
uint speed)
 
log_debug("%s, Speed: %d, Max: %d\n", __func__, speed, plat->frequency);
 
-   if (speed > plat->frequency)
-   speed = plat->frequency;
+   /*
+* If speed == 0 or speed > max freq, then set speed to highest
+*/
+   if (!speed || speed > priv->max_hz)
+   speed = pr

[PATCH v9 3/8] mtd: spi-nor: Add parallel and stacked memories support in read_bar and write_bar

2023-12-26 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Add support for parallel memories and stacked memories configuration
in read_bar and write_bar functions.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 55 +-
 1 file changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 6d1bd4d54a..6ca43aa6e8 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -885,12 +885,32 @@ static int clean_bar(struct spi_nor *nor)
 
 static int write_bar(struct spi_nor *nor, u32 offset)
 {
-   u8 cmd, bank_sel;
+   u8 cmd, bank_sel, upage_curr;
int ret;
+   struct mtd_info *mtd = >mtd;
+
+   /* Wait until previous write command is finished */
+   if (spi_nor_wait_till_ready(nor))
+   return 1;
+
+   if (nor->flags & (SNOR_F_HAS_PARALLEL | SNOR_F_HAS_STACKED) &&
+   mtd->size <= SZ_32M)
+   return 0;
+
+   if (mtd->size <= SZ_16M)
+   return 0;
+
+   offset = offset % (u32)mtd->size;
+   bank_sel = offset >> 24;
 
-   bank_sel = offset / SZ_16M;
-   if (bank_sel == nor->bank_curr)
-   goto bar_end;
+   upage_curr = nor->spi->flags & SPI_XFER_U_PAGE;
+
+   if (!(nor->flags & SNOR_F_HAS_STACKED) && bank_sel == nor->bank_curr)
+   return 0;
+   else if (upage_curr == nor->upage_prev && bank_sel == nor->bank_curr)
+   return 0;
+
+   nor->upage_prev = upage_curr;
 
cmd = nor->bank_write_cmd;
write_enable(nor);
@@ -900,15 +920,19 @@ static int write_bar(struct spi_nor *nor, u32 offset)
return ret;
}
 
-bar_end:
nor->bank_curr = bank_sel;
-   return nor->bank_curr;
+
+   return write_disable(nor);
 }
 
 static int read_bar(struct spi_nor *nor, const struct flash_info *info)
 {
u8 curr_bank = 0;
int ret;
+   struct mtd_info *mtd = >mtd;
+
+   if (mtd->size <= SZ_16M)
+   return 0;
 
switch (JEDEC_MFR(info)) {
case SNOR_MFR_SPANSION:
@@ -920,15 +944,30 @@ static int read_bar(struct spi_nor *nor, const struct 
flash_info *info)
nor->bank_write_cmd = SPINOR_OP_WREAR;
}
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   nor->spi->flags |= SPI_XFER_LOWER;
+
ret = nor->read_reg(nor, nor->bank_read_cmd,
-   _bank, 1);
+   _bank, 1);
if (ret) {
debug("SF: fail to read bank addr register\n");
return ret;
}
nor->bank_curr = curr_bank;
 
-   return 0;
+   // Make sure both chips use the same BAR
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   write_enable(nor);
+   ret = nor->write_reg(nor, nor->bank_write_cmd, _bank, 1);
+   if (ret)
+   return ret;
+
+   ret = write_disable(nor);
+   if (ret)
+   return ret;
+   }
+
+   return ret;
 }
 #endif
 
-- 
2.25.1



[PATCH v9 2/8] mtd: spi-nor: Add parallel memories support for read_sr and read_fsr

2023-12-26 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Add support for parallel memories flash configuration in read status
register and read flag status register functions.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 50 --
 1 file changed, 36 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 9d72dff85e..6d1bd4d54a 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -438,8 +438,9 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, 
loff_t to, size_t len,
 }
 
 /*
- * Read the status register, returning its value in the location
- * Return the status register value.
+ * Return the status register value. If the chip is parallel, then the
+ * read will be striped, so we should read 2 bytes to get the sr
+ * register value from both of the parallel chips.
  * Returns negative if error occurred.
  */
 static int read_sr(struct spi_nor *nor)
@@ -471,18 +472,29 @@ static int read_sr(struct spi_nor *nor)
if (spi_nor_protocol_is_dtr(nor->reg_proto))
op.data.nbytes = 2;
 
-   ret = spi_nor_read_write_reg(nor, , val);
-   if (ret < 0) {
-   pr_debug("error %d reading SR\n", (int)ret);
-   return ret;
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   op.data.nbytes = 2;
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
+   val[0] |= val[1];
+   } else {
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
}
 
-   return *val;
+   return val[0];
 }
 
 /*
- * Read the flag status register, returning its value in the location
- * Return the status register value.
+ * Return the flag status register value. If the chip is parallel, then
+ * the read will be striped, so we should read 2 bytes to get the fsr
+ * register value from both of the parallel chips.
  * Returns negative if error occurred.
  */
 static int read_fsr(struct spi_nor *nor)
@@ -514,13 +526,23 @@ static int read_fsr(struct spi_nor *nor)
if (spi_nor_protocol_is_dtr(nor->reg_proto))
op.data.nbytes = 2;
 
-   ret = spi_nor_read_write_reg(nor, , val);
-   if (ret < 0) {
-   pr_debug("error %d reading FSR\n", ret);
-   return ret;
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   op.data.nbytes = 2;
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
+   val[0] &= val[1];
+   } else {
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading FSR\n", ret);
+   return ret;
+   }
}
 
-   return *val;
+   return val[0];
 }
 
 /*
-- 
2.25.1



[PATCH v9 1/8] mtd: spi-nor: Add parallel and stacked memories support

2023-12-26 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

In parallel mode, the current implementation assumes that a maximum of
two flashes are connected. The QSPI controller splits the data evenly
between both the flashes so, both the flashes that are connected in
parallel mode should be identical.
During each operation SPI-NOR sets 0th bit for CS0 & 1st bit for CS1 in
nor->flags.

In stacked mode the current implementation assumes that a maximum of two
flashes are connected and both the flashes are of same make but can
differ in sizes. So, except the sizes all other flash parameters of both
the flashes are identical

Spi-nor will pass on the appropriate flash select flag to low level
driver, and it will select pass all the data to that particular flash.

Write operation in parallel mode are performed in page size * 2 chunks as
each write operation results in writing both the flashes. For doubling
the address space each operation is performed at addr/2 flash offset,
where addr is the address specified by the user.

Similarly for read and erase operations it will read from both flashes,
so size and offset are divided by 2 and send to flash.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 293 +
 include/linux/mtd/spi-nor.h|  12 ++
 include/spi.h  |  11 ++
 3 files changed, 288 insertions(+), 28 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 3f5f3c89ac..9d72dff85e 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -639,12 +639,17 @@ static u8 spi_nor_convert_3to4_erase(u8 opcode)
 static void spi_nor_set_4byte_opcodes(struct spi_nor *nor,
  const struct flash_info *info)
 {
+   bool shift = 0;
+
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   shift = 1;
+
/* Do some manufacturer fixups first */
switch (JEDEC_MFR(info)) {
case SNOR_MFR_SPANSION:
/* No small sector erase for 4-byte command set */
nor->erase_opcode = SPINOR_OP_SE;
-   nor->mtd.erasesize = info->sector_size;
+   nor->mtd.erasesize = info->sector_size << shift;
break;
 
default:
@@ -965,8 +970,8 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 
addr)
 static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
+   u32 addr, len, rem, offset;
bool addr_known = false;
-   u32 addr, len, rem;
int ret, err;
 
dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
@@ -991,6 +996,19 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
ret = -EINTR;
goto erase_err;
}
+
+   offset = addr;
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   offset /= 2;
+
+   if (nor->flags & SNOR_F_HAS_STACKED) {
+   if (offset >= (mtd->size / 2)) {
+   offset = offset - (mtd->size / 2);
+   nor->spi->flags |= SPI_XFER_U_PAGE;
+   } else {
+   nor->spi->flags &= ~SPI_XFER_U_PAGE;
+   }
+   }
 #ifdef CONFIG_SPI_FLASH_BAR
ret = write_bar(nor, addr);
if (ret < 0)
@@ -1396,6 +1414,9 @@ static const struct flash_info *spi_nor_read_id(struct 
spi_nor *nor)
u8  id[SPI_NOR_MAX_ID_LEN];
const struct flash_info *info;
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   nor->spi->flags |= SPI_XFER_LOWER;
+
tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
if (tmp < 0) {
dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp);
@@ -1420,28 +1441,66 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t 
from, size_t len,
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
int ret;
+   u32 offset = from;
+   u32 stack_shift = 0;
+   u32 read_len = 0;
+   u32 rem_bank_len = 0;
+   u8 bank;
+   u8 is_ofst_odd = 0;
 
dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
 
+   if ((nor->flags & SNOR_F_HAS_PARALLEL) && (offset & 1)) {
+   /* We can hit this case when we use file system like ubifs */
+   from = (loff_t)(from - 1);
+   len = (size_t)(len + 1);
+   is_ofst_odd = 1;
+   }
+
while (len) {
-   loff_t addr = from;
-   size_t read_len = len;
+   if (nor->addr_width == 3) {
+   if (nor->

[PATCH v9 6/8] spi: zynq_qspi: Add parallel memories support in QSPI driver

2023-12-26 Thread Venkatesh Yadav Abbarapu
Add support for parallel memories in zynq_qspi.c driver. In case of
parallel memories STRIPE bit is set and sent to the qspi ip, which will
send data bits to both the flashes in parallel. However for few commands
we should not use stripe, instead send same data to both the flashes.
Those commands are exclueded by using zynqmp_qspi_update_stripe().

Also update copyright info for this file.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/zynq_qspi.c | 113 
 1 file changed, 102 insertions(+), 11 deletions(-)

diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c
index bc82acd0b6..41f7ae2ab2 100644
--- a/drivers/spi/zynq_qspi.c
+++ b/drivers/spi/zynq_qspi.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2013 Xilinx, Inc.
+ * (C) Copyright 2013 - 2022, Xilinx, Inc.
  * (C) Copyright 2015 Jagan Teki 
+ * (C) Copyright 2023, Advanced Micro Devices, Inc.
  *
  * Xilinx Zynq Quad-SPI(QSPI) controller driver (master mode only)
  */
@@ -13,10 +14,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include "../mtd/spi/sf_internal.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -42,6 +45,21 @@ DECLARE_GLOBAL_DATA_PTR;
 #define ZYNQ_QSPI_TXD_00_01_OFFSET 0x80/* Transmit 1-byte inst */
 #define ZYNQ_QSPI_TXD_00_10_OFFSET 0x84/* Transmit 2-byte inst */
 #define ZYNQ_QSPI_TXD_00_11_OFFSET 0x88/* Transmit 3-byte inst */
+#define ZYNQ_QSPI_FR_QOUT_CODE 0x6B/* read instruction code */
+
+#define QSPI_SELECT_LOWER_CSBIT(0)
+#define QSPI_SELECT_UPPER_CSBIT(1)
+
+/*
+ * QSPI Linear Configuration Register
+ *
+ * It is named Linear Configuration but it controls other modes when not in
+ * linear mode also.
+ */
+#define ZYNQ_QSPI_LCFG_TWO_MEM_MASK 0x4000 /* QSPI Enable Bit Mask */
+#define ZYNQ_QSPI_LCFG_SEP_BUS_MASK 0x2000 /* QSPI Enable Bit Mask */
+#define ZYNQ_QSPI_LCFG_U_PAGE   0x1000 /* QSPI Upper memory set */
+#define ZYNQ_QSPI_LCFG_DUMMY_SHIFT  8
 
 #define ZYNQ_QSPI_TXFIFO_THRESHOLD 1   /* Tx FIFO threshold level*/
 #define ZYNQ_QSPI_RXFIFO_THRESHOLD 32  /* Rx FIFO threshold level */
@@ -101,7 +119,11 @@ struct zynq_qspi_priv {
int bytes_to_transfer;
int bytes_to_receive;
unsigned int is_inst;
+   unsigned int is_parallel;
+   unsigned int is_stacked;
+   unsigned int u_page;
unsigned cs_change:1;
+   unsigned is_strip:1;
 };
 
 static int zynq_qspi_of_to_plat(struct udevice *bus)
@@ -112,7 +134,6 @@ static int zynq_qspi_of_to_plat(struct udevice *bus)
 
plat->regs = (struct zynq_qspi_regs *)fdtdec_get_addr(blob,
  node, "reg");
-
return 0;
 }
 
@@ -147,6 +168,9 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
/* Disable Interrupts */
writel(ZYNQ_QSPI_IXR_ALL_MASK, >idr);
 
+   /* Disable linear mode as the boot loader may have used it */
+   writel(0x0, >lqspicfg);
+
/* Clear the TX and RX threshold reg */
writel(ZYNQ_QSPI_TXFIFO_THRESHOLD, >txftr);
writel(ZYNQ_QSPI_RXFIFO_THRESHOLD, >rxftr);
@@ -164,12 +188,11 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
confr |= ZYNQ_QSPI_CR_IFMODE_MASK | ZYNQ_QSPI_CR_MCS_MASK |
ZYNQ_QSPI_CR_PCS_MASK | ZYNQ_QSPI_CR_FW_MASK |
ZYNQ_QSPI_CR_MSTREN_MASK;
-   writel(confr, >cr);
 
-   /* Disable the LQSPI feature */
-   confr = readl(>lqspicfg);
-   confr &= ~ZYNQ_QSPI_LQSPICFG_LQMODE_MASK;
-   writel(confr, >lqspicfg);
+   if (priv->is_stacked)
+   confr |= 0x10;
+
+   writel(confr, >cr);
 
/* Enable SPI */
writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, >enr);
@@ -181,6 +204,7 @@ static int zynq_qspi_child_pre_probe(struct udevice *bus)
struct zynq_qspi_priv *priv = dev_get_priv(bus->parent);
 
priv->max_hz = slave->max_hz;
+   slave->multi_cs_cap = true;
 
return 0;
 }
@@ -363,8 +387,8 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv 
*priv, u32 size)
unsigned len, offset;
struct zynq_qspi_regs *regs = priv->regs;
static const unsigned offsets[4] = {
-   ZYNQ_QSPI_TXD_00_00_OFFSET, ZYNQ_QSPI_TXD_00_01_OFFSET,
-   ZYNQ_QSPI_TXD_00_10_OFFSET, ZYNQ_QSPI_TXD_00_11_OFFSET };
+   ZYNQ_QSPI_TXD_00_01_OFFSET, ZYNQ_QSPI_TXD_00_10_OFFSET,
+   ZYNQ_QSPI_TXD_00_11_OFFSET, ZYNQ_QSPI_TXD_00_00_OFFSET };
 
while ((fifocount < size) &&
(priv->bytes_to_transfer > 0)) {
@@ -386,7 +410,11 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv 
*priv, u32 size)
return;
  

[PATCH v9 0/8] spi-nor: Add parallel and stacked memories support

2023-12-26 Thread Venkatesh Yadav Abbarapu
This series adds support for Xilinx qspi parallel and stacked memeories.

In parallel mode, the current implementation assumes that a maximum of
two flashes are connected. The QSPI controller splits the data evenly
between both the flashes so, both the flashes that are connected in
parallel mode should be identical.
During each operation SPI-NOR sets 0th bit for CS0 & 1st bit for CS1 in
nor->flags.

In stacked mode the current implementation assumes that a maximum of two
flashes are connected and both the flashes are of same make but can
differ in sizes. So, except the sizes all other flash parameters of both
the flashes are identical.

Spi-nor will pass on the appropriate flash select flag to low level driver,
and it will select pass all the data to that particular flash.

Write operation in parallel mode are performed in page size * 2 chunks as
each write operation results in writing both the flashes. For doubling the
address space each operation is performed at addr/2 flash offset, where addr
is the address specified by the user.

Similarly for read and erase operations it will read from both flashes, so
size and offset are divided by 2 and send to flash.

Changes in v2:
- Fixed the compilation issues.
Changes in v3:
- Fixed the CI issues.
Changes in v4:
- Removed the dio,dummy_bytes variables from zynq_qspi driver.
- Fix the compilation issue by including the DM_SPI config.
Changes in v5:
- Fixed the issue reported by buildman.
Changes in v6:
- Fixed the issues reported while running the sandbox test cases.
Changes in v7:
- Fixed the issues reported while running these da850evm_defconfig,
  imx28_xea_defconfig configs.
- Fixed the issue when DM_SPI config is disabled.
- Fixed the issue while running the sandbox_noinst_defconfig with spl
  ./spl/u-boot-spl -d arch/sandbox/dts/test.dtb
   jedec_spi_nor spi.bin@0: has no valid 'reg' property (-12)
   jedec_spi_nor spi.bin@1: has no valid 'reg' property (-12)
   ### ERROR ### Please RESET the board ###
Changes in v8:
- Fixed the compilation issue with imx28_xea_defconfig.
- Fixed the SPL size issue with the axm and taurus defconfigs.
- Rebased the patches on top of next branch.
Changes in v9:
- Updated the commit log why SPL_FIT is being enabled.

Ashok Reddy Soma (4):
  mtd: spi-nor: Add parallel and stacked memories support
  mtd: spi-nor: Add parallel memories support for read_sr and read_fsr
  mtd: spi-nor: Add parallel and stacked memories support in read_bar
and write_bar
  spi: spi-uclass: Read chipselect and restrict capabilities

Venkatesh Yadav Abbarapu (4):
  spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver
  spi: zynq_qspi: Add parallel memories support in QSPI driver
  config: xea: Enable the SPL_FIT config option
  axm/taurus: Disable the SPL_SPI config

 board/siemens/taurus/taurus.c  |   4 +-
 configs/axm_defconfig  |   7 +-
 configs/imx28_xea_defconfig|   2 +-
 configs/taurus_defconfig   |   7 +-
 drivers/mtd/spi/sandbox.c  |   2 +-
 drivers/mtd/spi/spi-nor-core.c | 398 -
 drivers/spi/altera_spi.c   |   4 +-
 drivers/spi/atcspi200_spi.c|   2 +-
 drivers/spi/ath79_spi.c|   2 +-
 drivers/spi/atmel_spi.c|   6 +-
 drivers/spi/bcm63xx_hsspi.c|  42 ++--
 drivers/spi/bcm63xx_spi.c  |   6 +-
 drivers/spi/bcmbca_hsspi.c |  34 +--
 drivers/spi/cf_spi.c   |   6 +-
 drivers/spi/davinci_spi.c  |   8 +-
 drivers/spi/fsl_dspi.c |  18 +-
 drivers/spi/fsl_espi.c |   4 +-
 drivers/spi/fsl_qspi.c |   4 +-
 drivers/spi/gxp_spi.c  |   2 +-
 drivers/spi/mpc8xx_spi.c   |   4 +-
 drivers/spi/mpc8xxx_spi.c  |  10 +-
 drivers/spi/mscc_bb_spi.c  |   4 +-
 drivers/spi/mxc_spi.c  |   6 +-
 drivers/spi/npcm_fiu_spi.c |  14 +-
 drivers/spi/nxp_fspi.c |   2 +-
 drivers/spi/octeon_spi.c   |   2 +-
 drivers/spi/omap3_spi.c|   4 +-
 drivers/spi/pic32_spi.c|   2 +-
 drivers/spi/rk_spi.c   |   4 +-
 drivers/spi/rockchip_sfc.c |   2 +-
 drivers/spi/spi-aspeed-smc.c   |  28 +--
 drivers/spi/spi-mxic.c |   6 +-
 drivers/spi/spi-qup.c  |   4 +-
 drivers/spi/spi-sifive.c   |   6 +-
 drivers/spi/spi-sn-f-ospi.c|   2 +-
 drivers/spi/spi-sunxi.c|   6 +-
 drivers/spi/spi-synquacer.c|   4 +-
 drivers/spi/spi-uclass.c   |  33 ++-
 drivers/spi/stm32_qspi.c   |   2 +-
 drivers/spi/stm32_spi.c|   4 +-
 drivers/spi/ti_qspi.c  |  14 +-
 drivers/spi/xilinx_spi.c   |   6 +-
 drivers/spi/zynq_qspi.c| 119 --
 drivers/spi/zynq_spi.c |   6 +-
 drivers/spi/zynqmp_gqspi.c | 141 ++--
 include/linux/mtd/spi-nor.h|  12 +
 include/spi.h  |  23 +-
 lib/acpi/acpi_device.c |   2 +-
 48 files changed, 790 insertions(+), 240 deletions(-)

-- 
2.25.1



[PATCH v8 8/8] axm/taurus: Disable the SPL_SPI config

2023-12-26 Thread Venkatesh Yadav Abbarapu
Disabling the CONFIG_SPL_SPI for the axm and taurus defconfigs,
as facing the SPL size issue "SPL image too big".

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 board/siemens/taurus/taurus.c | 4 +++-
 configs/axm_defconfig | 7 ++-
 configs/taurus_defconfig  | 7 ++-
 3 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/board/siemens/taurus/taurus.c b/board/siemens/taurus/taurus.c
index ad44a7c0d2..ac1ce8acf4 100644
--- a/board/siemens/taurus/taurus.c
+++ b/board/siemens/taurus/taurus.c
@@ -135,11 +135,12 @@ void spl_board_init(void)
 
/* check for recovery mode */
if (at91_is_recovery() == 1) {
-   struct spi_flash *flash;
 
puts("Recovery button pressed\n");
nand_init();
spl_nand_erase_one(0, 0);
+#if defined(CONFIG_SPL_SPI)
+   struct spi_flash *flash;
flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
0,
CONFIG_SF_DEFAULT_SPEED,
@@ -151,6 +152,7 @@ void spl_board_init(void)
spi_flash_erase(flash, 0,
CFG_SYS_NAND_U_BOOT_SIZE);
}
+#endif
}
 }
 
diff --git a/configs/axm_defconfig b/configs/axm_defconfig
index e1a01b24b8..4d439832d7 100644
--- a/configs/axm_defconfig
+++ b/configs/axm_defconfig
@@ -3,7 +3,6 @@ CONFIG_SKIP_LOWLEVEL_INIT_ONLY=y
 CONFIG_SPL_SKIP_LOWLEVEL_INIT_ONLY=y
 CONFIG_SPL_SYS_DCACHE_OFF=y
 CONFIG_ARCH_CPU_INIT=y
-CONFIG_SYS_THUMB_BUILD=y
 # CONFIG_SPL_USE_ARCH_MEMCPY is not set
 # CONFIG_SPL_USE_ARCH_MEMSET is not set
 CONFIG_ARCH_AT91=y
@@ -26,14 +25,14 @@ CONFIG_SPL=y
 CONFIG_DEBUG_UART_BASE=0xf200
 CONFIG_DEBUG_UART_CLOCK=18432000
 CONFIG_ENV_OFFSET_REDUND=0x18
-CONFIG_SPL_SPI_FLASH_SUPPORT=y
-CONFIG_SPL_SPI=y
 CONFIG_SYS_LOAD_ADDR=0x2200
 CONFIG_DEBUG_UART=y
 CONFIG_NAND_BOOT=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTCOMMAND=y
 CONFIG_BOOTCOMMAND="run flash_self"
+CONFIG_SYS_CBSIZE=256
+CONFIG_SYS_PBSIZE=281
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_SPL_MAX_SIZE=0x3e00
@@ -57,8 +56,6 @@ CONFIG_SPL_NAND_BASE=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="U-Boot> "
-CONFIG_SYS_CBSIZE=256
-CONFIG_SYS_PBSIZE=281
 # CONFIG_CMD_BDI is not set
 CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMI is not set
diff --git a/configs/taurus_defconfig b/configs/taurus_defconfig
index 9be30c8d8a..7d71262d1a 100644
--- a/configs/taurus_defconfig
+++ b/configs/taurus_defconfig
@@ -4,7 +4,6 @@ CONFIG_SPL_SKIP_LOWLEVEL_INIT_ONLY=y
 CONFIG_SPL_SYS_ICACHE_OFF=y
 CONFIG_SPL_SYS_DCACHE_OFF=y
 CONFIG_ARCH_CPU_INIT=y
-CONFIG_SYS_THUMB_BUILD=y
 # CONFIG_SPL_USE_ARCH_MEMCPY is not set
 # CONFIG_SPL_USE_ARCH_MEMSET is not set
 CONFIG_ARCH_AT91=y
@@ -28,8 +27,6 @@ CONFIG_SPL=y
 CONFIG_DEBUG_UART_BASE=0xf200
 CONFIG_DEBUG_UART_CLOCK=18432000
 CONFIG_ENV_OFFSET_REDUND=0x18
-CONFIG_SPL_SPI_FLASH_SUPPORT=y
-CONFIG_SPL_SPI=y
 CONFIG_SYS_LOAD_ADDR=0x2200
 CONFIG_DEBUG_UART=y
 CONFIG_NAND_BOOT=y
@@ -38,6 +35,8 @@ CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk 
mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256k(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs)
 root=/dev/mtdblock7 rw rootfstype=jffs2"
 CONFIG_USE_BOOTCOMMAND=y
 CONFIG_BOOTCOMMAND="nand read 0x2200 0x20 0x30; bootm"
+CONFIG_SYS_CBSIZE=256
+CONFIG_SYS_PBSIZE=281
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_SPL_MAX_SIZE=0x3e00
@@ -61,8 +60,6 @@ CONFIG_SPL_NAND_BASE=y
 CONFIG_SPL_DM_SPI_FLASH=y
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="U-Boot> "
-CONFIG_SYS_CBSIZE=256
-CONFIG_SYS_PBSIZE=281
 # CONFIG_SYS_XTRACE is not set
 # CONFIG_CMD_BDI is not set
 CONFIG_CMD_BOOTZ=y
-- 
2.25.1



[PATCH v8 7/8] config: xea: Enable the SPL_FIT config option

2023-12-26 Thread Venkatesh Yadav Abbarapu
Enable the config SPL_FIT.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
 configs/imx28_xea_defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configs/imx28_xea_defconfig b/configs/imx28_xea_defconfig
index c1b0487f7e..882b6093c9 100644
--- a/configs/imx28_xea_defconfig
+++ b/configs/imx28_xea_defconfig
@@ -29,6 +29,7 @@ CONFIG_SYS_LOAD_ADDR=0x4200
 CONFIG_SPL_PAYLOAD="u-boot.img"
 CONFIG_TIMESTAMP=y
 CONFIG_FIT=y
+CONFIG_SPL_FIT=y
 # CONFIG_BOOTMETH_EXTLINUX is not set
 # CONFIG_BOOTMETH_VBE is not set
 CONFIG_OF_BOARD_SETUP=y
@@ -123,4 +124,3 @@ CONFIG_DM_SERIAL=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
 CONFIG_MXS_SPI=y
-# CONFIG_SPL_OF_LIBFDT is not set
-- 
2.25.1



[PATCH v8 6/8] spi: zynq_qspi: Add parallel memories support in QSPI driver

2023-12-26 Thread Venkatesh Yadav Abbarapu
Add support for parallel memories in zynq_qspi.c driver. In case of
parallel memories STRIPE bit is set and sent to the qspi ip, which will
send data bits to both the flashes in parallel. However for few commands
we should not use stripe, instead send same data to both the flashes.
Those commands are exclueded by using zynqmp_qspi_update_stripe().

Also update copyright info for this file.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/zynq_qspi.c | 113 
 1 file changed, 102 insertions(+), 11 deletions(-)

diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c
index bc82acd0b6..41f7ae2ab2 100644
--- a/drivers/spi/zynq_qspi.c
+++ b/drivers/spi/zynq_qspi.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2013 Xilinx, Inc.
+ * (C) Copyright 2013 - 2022, Xilinx, Inc.
  * (C) Copyright 2015 Jagan Teki 
+ * (C) Copyright 2023, Advanced Micro Devices, Inc.
  *
  * Xilinx Zynq Quad-SPI(QSPI) controller driver (master mode only)
  */
@@ -13,10 +14,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include "../mtd/spi/sf_internal.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -42,6 +45,21 @@ DECLARE_GLOBAL_DATA_PTR;
 #define ZYNQ_QSPI_TXD_00_01_OFFSET 0x80/* Transmit 1-byte inst */
 #define ZYNQ_QSPI_TXD_00_10_OFFSET 0x84/* Transmit 2-byte inst */
 #define ZYNQ_QSPI_TXD_00_11_OFFSET 0x88/* Transmit 3-byte inst */
+#define ZYNQ_QSPI_FR_QOUT_CODE 0x6B/* read instruction code */
+
+#define QSPI_SELECT_LOWER_CSBIT(0)
+#define QSPI_SELECT_UPPER_CSBIT(1)
+
+/*
+ * QSPI Linear Configuration Register
+ *
+ * It is named Linear Configuration but it controls other modes when not in
+ * linear mode also.
+ */
+#define ZYNQ_QSPI_LCFG_TWO_MEM_MASK 0x4000 /* QSPI Enable Bit Mask */
+#define ZYNQ_QSPI_LCFG_SEP_BUS_MASK 0x2000 /* QSPI Enable Bit Mask */
+#define ZYNQ_QSPI_LCFG_U_PAGE   0x1000 /* QSPI Upper memory set */
+#define ZYNQ_QSPI_LCFG_DUMMY_SHIFT  8
 
 #define ZYNQ_QSPI_TXFIFO_THRESHOLD 1   /* Tx FIFO threshold level*/
 #define ZYNQ_QSPI_RXFIFO_THRESHOLD 32  /* Rx FIFO threshold level */
@@ -101,7 +119,11 @@ struct zynq_qspi_priv {
int bytes_to_transfer;
int bytes_to_receive;
unsigned int is_inst;
+   unsigned int is_parallel;
+   unsigned int is_stacked;
+   unsigned int u_page;
unsigned cs_change:1;
+   unsigned is_strip:1;
 };
 
 static int zynq_qspi_of_to_plat(struct udevice *bus)
@@ -112,7 +134,6 @@ static int zynq_qspi_of_to_plat(struct udevice *bus)
 
plat->regs = (struct zynq_qspi_regs *)fdtdec_get_addr(blob,
  node, "reg");
-
return 0;
 }
 
@@ -147,6 +168,9 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
/* Disable Interrupts */
writel(ZYNQ_QSPI_IXR_ALL_MASK, >idr);
 
+   /* Disable linear mode as the boot loader may have used it */
+   writel(0x0, >lqspicfg);
+
/* Clear the TX and RX threshold reg */
writel(ZYNQ_QSPI_TXFIFO_THRESHOLD, >txftr);
writel(ZYNQ_QSPI_RXFIFO_THRESHOLD, >rxftr);
@@ -164,12 +188,11 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
confr |= ZYNQ_QSPI_CR_IFMODE_MASK | ZYNQ_QSPI_CR_MCS_MASK |
ZYNQ_QSPI_CR_PCS_MASK | ZYNQ_QSPI_CR_FW_MASK |
ZYNQ_QSPI_CR_MSTREN_MASK;
-   writel(confr, >cr);
 
-   /* Disable the LQSPI feature */
-   confr = readl(>lqspicfg);
-   confr &= ~ZYNQ_QSPI_LQSPICFG_LQMODE_MASK;
-   writel(confr, >lqspicfg);
+   if (priv->is_stacked)
+   confr |= 0x10;
+
+   writel(confr, >cr);
 
/* Enable SPI */
writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, >enr);
@@ -181,6 +204,7 @@ static int zynq_qspi_child_pre_probe(struct udevice *bus)
struct zynq_qspi_priv *priv = dev_get_priv(bus->parent);
 
priv->max_hz = slave->max_hz;
+   slave->multi_cs_cap = true;
 
return 0;
 }
@@ -363,8 +387,8 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv 
*priv, u32 size)
unsigned len, offset;
struct zynq_qspi_regs *regs = priv->regs;
static const unsigned offsets[4] = {
-   ZYNQ_QSPI_TXD_00_00_OFFSET, ZYNQ_QSPI_TXD_00_01_OFFSET,
-   ZYNQ_QSPI_TXD_00_10_OFFSET, ZYNQ_QSPI_TXD_00_11_OFFSET };
+   ZYNQ_QSPI_TXD_00_01_OFFSET, ZYNQ_QSPI_TXD_00_10_OFFSET,
+   ZYNQ_QSPI_TXD_00_11_OFFSET, ZYNQ_QSPI_TXD_00_00_OFFSET };
 
while ((fifocount < size) &&
(priv->bytes_to_transfer > 0)) {
@@ -386,7 +410,11 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv 
*priv, u32 size)
return;
  

[PATCH v8 5/8] spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver

2023-12-26 Thread Venkatesh Yadav Abbarapu
Add support for parallel memories in zynqmp_gqspi.c driver. In case of
parallel memories STRIPE bit is set and sent to the qspi ip, which will
send data bits to both the flashes in parallel. However for few commands
we should not use stripe, instead send same data to both the flashes.
Those commands are exclueded by using zynqmp_qspi_update_stripe().

Also update copyright info for this file.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/zynqmp_gqspi.c | 141 -
 include/spi.h  |   4 ++
 2 files changed, 129 insertions(+), 16 deletions(-)

diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index a323994fb2..dedf8270a8 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2018 Xilinx
- *
+ * (C) Copyright 2013 - 2022, Xilinx, Inc.
+ * (C) Copyright 2023, Advanced Micro Devices, Inc.
  * Xilinx ZynqMP Generic Quad-SPI(QSPI) controller driver(master mode only)
  */
 
@@ -25,6 +25,8 @@
 #include 
 #include 
 #include 
+#include 
+#include "../mtd/spi/sf_internal.h"
 #include 
 
 #define GQSPI_GFIFO_STRT_MODE_MASK BIT(29)
@@ -88,6 +90,9 @@
 #define SPI_XFER_ON_LOWER  1
 #define SPI_XFER_ON_UPPER  2
 
+#define GQSPI_SELECT_LOWER_CS  BIT(0)
+#define GQSPI_SELECT_UPPER_CS  BIT(1)
+
 #define GQSPI_DMA_ALIGN0x4
 #define GQSPI_MAX_BAUD_RATE_VAL7
 #define GQSPI_DFLT_BAUD_RATE_VAL   2
@@ -183,13 +188,14 @@ struct zynqmp_qspi_priv {
int bytes_to_transfer;
int bytes_to_receive;
const struct spi_mem_op *op;
+   unsigned int is_parallel;
+   unsigned int u_page;
+   unsigned int bus;
+   unsigned int stripe;
+   unsigned int flags;
+   u32 max_hz;
 };
 
-__weak int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 
value)
-{
-   return 0;
-}
-
 static int zynqmp_qspi_of_to_plat(struct udevice *bus)
 {
struct zynqmp_qspi_plat *plat = dev_get_plat(bus);
@@ -234,8 +240,30 @@ static u32 zynqmp_qspi_bus_select(struct zynqmp_qspi_priv 
*priv)
 {
u32 gqspi_fifo_reg = 0;
 
-   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
-GQSPI_GFIFO_CS_LOWER;
+   if (priv->is_parallel) {
+   if (priv->bus == SPI_XFER_ON_BOTH)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_CS_UPPER |
+GQSPI_GFIFO_CS_LOWER;
+   else if (priv->bus == SPI_XFER_ON_LOWER)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_UPPER |
+GQSPI_GFIFO_CS_LOWER;
+   else if (priv->bus == SPI_XFER_ON_UPPER)
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_CS_LOWER |
+GQSPI_GFIFO_CS_UPPER;
+   else
+   debug("Wrong Bus selection:0x%x\n", priv->bus);
+   } else {
+   if (priv->u_page)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_UPPER;
+   else
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_LOWER;
+   }
 
return gqspi_fifo_reg;
 }
@@ -295,8 +323,15 @@ static void zynqmp_qspi_chipselect(struct zynqmp_qspi_priv 
*priv, int is_on)
gqspi_fifo_reg |= GQSPI_SPI_MODE_SPI |
  GQSPI_IMD_DATA_CS_ASSERT;
} else {
-   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS;
-   gqspi_fifo_reg |= GQSPI_IMD_DATA_CS_DEASSERT;
+   if (priv->is_parallel) {
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_LOW_BUS;
+   } else if (priv->u_page) {
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS;
+   } else {
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS;
+   gqspi_fifo_reg |= GQSPI_IMD_DATA_CS_DEASSERT;
+   }
}
 
zynqmp_qspi_fill_gen_fifo(priv, gqspi_fifo_reg);
@@ -366,12 +401,13 @@ static int zynqmp_qspi_set_speed(struct udevice *bus, 
uint speed)
 
log_debug("%s, Speed: %d, Max: %d\n", __func__, speed, plat->frequency);
 
-   if (speed > plat->frequency)
-   speed = plat->frequency;
+   /*
+* If speed == 0 or speed > max freq, then set speed to highest
+*/
+   if (!speed || speed > priv->max_hz)
+   speed = pr

[PATCH v8 4/8] spi: spi-uclass: Read chipselect and restrict capabilities

2023-12-26 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Read chipselect properties from DT which are populated using 'reg'
property and save it in plat->cs[] array for later use.

Also read multi chipselect capability which is used for
parallel-memories and return errors if they are passed on using DT but
driver is not capable of handling it.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/sandbox.c|  2 +-
 drivers/spi/altera_spi.c |  4 ++--
 drivers/spi/atcspi200_spi.c  |  2 +-
 drivers/spi/ath79_spi.c  |  2 +-
 drivers/spi/atmel_spi.c  |  6 +++---
 drivers/spi/bcm63xx_hsspi.c  | 42 ++--
 drivers/spi/bcm63xx_spi.c|  6 +++---
 drivers/spi/bcmbca_hsspi.c   | 34 ++---
 drivers/spi/cf_spi.c |  6 +++---
 drivers/spi/davinci_spi.c|  8 +++
 drivers/spi/fsl_dspi.c   | 18 
 drivers/spi/fsl_espi.c   |  4 ++--
 drivers/spi/fsl_qspi.c   |  4 ++--
 drivers/spi/gxp_spi.c|  2 +-
 drivers/spi/mpc8xx_spi.c |  4 ++--
 drivers/spi/mpc8xxx_spi.c| 10 -
 drivers/spi/mscc_bb_spi.c|  4 ++--
 drivers/spi/mxc_spi.c|  6 +++---
 drivers/spi/npcm_fiu_spi.c   | 14 ++--
 drivers/spi/nxp_fspi.c   |  2 +-
 drivers/spi/octeon_spi.c |  2 +-
 drivers/spi/omap3_spi.c  |  4 ++--
 drivers/spi/pic32_spi.c  |  2 +-
 drivers/spi/rk_spi.c |  4 ++--
 drivers/spi/rockchip_sfc.c   |  2 +-
 drivers/spi/spi-aspeed-smc.c | 28 
 drivers/spi/spi-mxic.c   |  6 +++---
 drivers/spi/spi-qup.c|  4 ++--
 drivers/spi/spi-sifive.c |  6 +++---
 drivers/spi/spi-sn-f-ospi.c  |  2 +-
 drivers/spi/spi-sunxi.c  |  6 +++---
 drivers/spi/spi-synquacer.c  |  4 ++--
 drivers/spi/spi-uclass.c | 33 +++-
 drivers/spi/stm32_qspi.c |  2 +-
 drivers/spi/stm32_spi.c  |  4 ++--
 drivers/spi/ti_qspi.c| 14 ++--
 drivers/spi/xilinx_spi.c |  6 +++---
 drivers/spi/zynq_qspi.c  |  6 +++---
 drivers/spi/zynq_spi.c   |  6 +++---
 include/spi.h|  8 ++-
 lib/acpi/acpi_device.c   |  2 +-
 41 files changed, 180 insertions(+), 151 deletions(-)

diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 4fe547171a..72036d5a88 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -139,7 +139,7 @@ static int sandbox_sf_probe(struct udevice *dev)
return ret;
}
slave_plat = dev_get_parent_plat(dev);
-   cs = slave_plat->cs;
+   cs = slave_plat->cs[0];
debug("found at cs %d\n", cs);
 
if (!pdata->filename) {
diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c
index 989679e881..48782f81c1 100644
--- a/drivers/spi/altera_spi.c
+++ b/drivers/spi/altera_spi.c
@@ -96,7 +96,7 @@ static int altera_spi_xfer(struct udevice *dev, unsigned int 
bitlen,
uint32_t reg, data, start;
 
debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
- dev_seq(bus), slave_plat->cs, bitlen, bytes, flags);
+ dev_seq(bus), slave_plat->cs[0], bitlen, bytes, flags);
 
if (bitlen == 0)
goto done;
@@ -111,7 +111,7 @@ static int altera_spi_xfer(struct udevice *dev, unsigned 
int bitlen,
readl(>rxdata);
 
if (flags & SPI_XFER_BEGIN)
-   spi_cs_activate(dev, slave_plat->cs);
+   spi_cs_activate(dev, slave_plat->cs[0]);
 
while (bytes--) {
if (txp)
diff --git a/drivers/spi/atcspi200_spi.c b/drivers/spi/atcspi200_spi.c
index de9c14837c..acee743653 100644
--- a/drivers/spi/atcspi200_spi.c
+++ b/drivers/spi/atcspi200_spi.c
@@ -321,7 +321,7 @@ static int atcspi200_spi_claim_bus(struct udevice *dev)
struct udevice *bus = dev->parent;
struct nds_spi_slave *ns = dev_get_priv(bus);
 
-   if (slave_plat->cs >= ns->num_cs) {
+   if (slave_plat->cs[0] >= ns->num_cs) {
printf("Invalid SPI chipselect\n");
return -EINVAL;
}
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
index 205567ef54..ad10cec2a6 100644
--- a/drivers/spi/ath79_spi.c
+++ b/drivers/spi/ath79_spi.c
@@ -74,7 +74,7 @@ static int ath79_spi_xfer(struct udevice *dev, unsigned int 
bitlen,
if (restbits)
bytes++;
 
-   out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs));
+   out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs[0]));
while (bytes > 0) {
bytes--;
curbyte = 0;
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index aec6f4eca9..e2de39d1ef 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -126,7 +126,7 @@ static int atmel_spi_claim_bus(struct udevice *dev)
struct atmel_spi_priv *priv = dev_get

[PATCH v8 3/8] mtd: spi-nor: Add parallel and stacked memories support in read_bar and write_bar

2023-12-26 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Add support for parallel memories and stacked memories configuration
in read_bar and write_bar functions.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 55 +-
 1 file changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 6d1bd4d54a..6ca43aa6e8 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -885,12 +885,32 @@ static int clean_bar(struct spi_nor *nor)
 
 static int write_bar(struct spi_nor *nor, u32 offset)
 {
-   u8 cmd, bank_sel;
+   u8 cmd, bank_sel, upage_curr;
int ret;
+   struct mtd_info *mtd = >mtd;
+
+   /* Wait until previous write command is finished */
+   if (spi_nor_wait_till_ready(nor))
+   return 1;
+
+   if (nor->flags & (SNOR_F_HAS_PARALLEL | SNOR_F_HAS_STACKED) &&
+   mtd->size <= SZ_32M)
+   return 0;
+
+   if (mtd->size <= SZ_16M)
+   return 0;
+
+   offset = offset % (u32)mtd->size;
+   bank_sel = offset >> 24;
 
-   bank_sel = offset / SZ_16M;
-   if (bank_sel == nor->bank_curr)
-   goto bar_end;
+   upage_curr = nor->spi->flags & SPI_XFER_U_PAGE;
+
+   if (!(nor->flags & SNOR_F_HAS_STACKED) && bank_sel == nor->bank_curr)
+   return 0;
+   else if (upage_curr == nor->upage_prev && bank_sel == nor->bank_curr)
+   return 0;
+
+   nor->upage_prev = upage_curr;
 
cmd = nor->bank_write_cmd;
write_enable(nor);
@@ -900,15 +920,19 @@ static int write_bar(struct spi_nor *nor, u32 offset)
return ret;
}
 
-bar_end:
nor->bank_curr = bank_sel;
-   return nor->bank_curr;
+
+   return write_disable(nor);
 }
 
 static int read_bar(struct spi_nor *nor, const struct flash_info *info)
 {
u8 curr_bank = 0;
int ret;
+   struct mtd_info *mtd = >mtd;
+
+   if (mtd->size <= SZ_16M)
+   return 0;
 
switch (JEDEC_MFR(info)) {
case SNOR_MFR_SPANSION:
@@ -920,15 +944,30 @@ static int read_bar(struct spi_nor *nor, const struct 
flash_info *info)
nor->bank_write_cmd = SPINOR_OP_WREAR;
}
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   nor->spi->flags |= SPI_XFER_LOWER;
+
ret = nor->read_reg(nor, nor->bank_read_cmd,
-   _bank, 1);
+   _bank, 1);
if (ret) {
debug("SF: fail to read bank addr register\n");
return ret;
}
nor->bank_curr = curr_bank;
 
-   return 0;
+   // Make sure both chips use the same BAR
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   write_enable(nor);
+   ret = nor->write_reg(nor, nor->bank_write_cmd, _bank, 1);
+   if (ret)
+   return ret;
+
+   ret = write_disable(nor);
+   if (ret)
+   return ret;
+   }
+
+   return ret;
 }
 #endif
 
-- 
2.25.1



[PATCH v8 2/8] mtd: spi-nor: Add parallel memories support for read_sr and read_fsr

2023-12-26 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Add support for parallel memories flash configuration in read status
register and read flag status register functions.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 50 --
 1 file changed, 36 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 9d72dff85e..6d1bd4d54a 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -438,8 +438,9 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, 
loff_t to, size_t len,
 }
 
 /*
- * Read the status register, returning its value in the location
- * Return the status register value.
+ * Return the status register value. If the chip is parallel, then the
+ * read will be striped, so we should read 2 bytes to get the sr
+ * register value from both of the parallel chips.
  * Returns negative if error occurred.
  */
 static int read_sr(struct spi_nor *nor)
@@ -471,18 +472,29 @@ static int read_sr(struct spi_nor *nor)
if (spi_nor_protocol_is_dtr(nor->reg_proto))
op.data.nbytes = 2;
 
-   ret = spi_nor_read_write_reg(nor, , val);
-   if (ret < 0) {
-   pr_debug("error %d reading SR\n", (int)ret);
-   return ret;
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   op.data.nbytes = 2;
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
+   val[0] |= val[1];
+   } else {
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
}
 
-   return *val;
+   return val[0];
 }
 
 /*
- * Read the flag status register, returning its value in the location
- * Return the status register value.
+ * Return the flag status register value. If the chip is parallel, then
+ * the read will be striped, so we should read 2 bytes to get the fsr
+ * register value from both of the parallel chips.
  * Returns negative if error occurred.
  */
 static int read_fsr(struct spi_nor *nor)
@@ -514,13 +526,23 @@ static int read_fsr(struct spi_nor *nor)
if (spi_nor_protocol_is_dtr(nor->reg_proto))
op.data.nbytes = 2;
 
-   ret = spi_nor_read_write_reg(nor, , val);
-   if (ret < 0) {
-   pr_debug("error %d reading FSR\n", ret);
-   return ret;
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   op.data.nbytes = 2;
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
+   val[0] &= val[1];
+   } else {
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading FSR\n", ret);
+   return ret;
+   }
}
 
-   return *val;
+   return val[0];
 }
 
 /*
-- 
2.25.1



[PATCH v8 1/8] mtd: spi-nor: Add parallel and stacked memories support

2023-12-26 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

In parallel mode, the current implementation assumes that a maximum of
two flashes are connected. The QSPI controller splits the data evenly
between both the flashes so, both the flashes that are connected in
parallel mode should be identical.
During each operation SPI-NOR sets 0th bit for CS0 & 1st bit for CS1 in
nor->flags.

In stacked mode the current implementation assumes that a maximum of two
flashes are connected and both the flashes are of same make but can
differ in sizes. So, except the sizes all other flash parameters of both
the flashes are identical

Spi-nor will pass on the appropriate flash select flag to low level
driver, and it will select pass all the data to that particular flash.

Write operation in parallel mode are performed in page size * 2 chunks as
each write operation results in writing both the flashes. For doubling
the address space each operation is performed at addr/2 flash offset,
where addr is the address specified by the user.

Similarly for read and erase operations it will read from both flashes,
so size and offset are divided by 2 and send to flash.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 293 +
 include/linux/mtd/spi-nor.h|  12 ++
 include/spi.h  |  11 ++
 3 files changed, 288 insertions(+), 28 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 3f5f3c89ac..9d72dff85e 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -639,12 +639,17 @@ static u8 spi_nor_convert_3to4_erase(u8 opcode)
 static void spi_nor_set_4byte_opcodes(struct spi_nor *nor,
  const struct flash_info *info)
 {
+   bool shift = 0;
+
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   shift = 1;
+
/* Do some manufacturer fixups first */
switch (JEDEC_MFR(info)) {
case SNOR_MFR_SPANSION:
/* No small sector erase for 4-byte command set */
nor->erase_opcode = SPINOR_OP_SE;
-   nor->mtd.erasesize = info->sector_size;
+   nor->mtd.erasesize = info->sector_size << shift;
break;
 
default:
@@ -965,8 +970,8 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 
addr)
 static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
+   u32 addr, len, rem, offset;
bool addr_known = false;
-   u32 addr, len, rem;
int ret, err;
 
dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
@@ -991,6 +996,19 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
ret = -EINTR;
goto erase_err;
}
+
+   offset = addr;
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   offset /= 2;
+
+   if (nor->flags & SNOR_F_HAS_STACKED) {
+   if (offset >= (mtd->size / 2)) {
+   offset = offset - (mtd->size / 2);
+   nor->spi->flags |= SPI_XFER_U_PAGE;
+   } else {
+   nor->spi->flags &= ~SPI_XFER_U_PAGE;
+   }
+   }
 #ifdef CONFIG_SPI_FLASH_BAR
ret = write_bar(nor, addr);
if (ret < 0)
@@ -1396,6 +1414,9 @@ static const struct flash_info *spi_nor_read_id(struct 
spi_nor *nor)
u8  id[SPI_NOR_MAX_ID_LEN];
const struct flash_info *info;
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   nor->spi->flags |= SPI_XFER_LOWER;
+
tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
if (tmp < 0) {
dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp);
@@ -1420,28 +1441,66 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t 
from, size_t len,
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
int ret;
+   u32 offset = from;
+   u32 stack_shift = 0;
+   u32 read_len = 0;
+   u32 rem_bank_len = 0;
+   u8 bank;
+   u8 is_ofst_odd = 0;
 
dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
 
+   if ((nor->flags & SNOR_F_HAS_PARALLEL) && (offset & 1)) {
+   /* We can hit this case when we use file system like ubifs */
+   from = (loff_t)(from - 1);
+   len = (size_t)(len + 1);
+   is_ofst_odd = 1;
+   }
+
while (len) {
-   loff_t addr = from;
-   size_t read_len = len;
+   if (nor->addr_width == 3) {
+   if (nor->

[PATCH v8 0/8] spi-nor: Add parallel and stacked memories support

2023-12-26 Thread Venkatesh Yadav Abbarapu
This series adds support for Xilinx qspi parallel and stacked memeories.

In parallel mode, the current implementation assumes that a maximum of 
two flashes are connected. The QSPI controller splits the data evenly
between both the flashes so, both the flashes that are connected in 
parallel mode should be identical.
During each operation SPI-NOR sets 0th bit for CS0 & 1st bit for CS1 in
nor->flags.

In stacked mode the current implementation assumes that a maximum of two
flashes are connected and both the flashes are of same make but can
differ in sizes. So, except the sizes all other flash parameters of both
the flashes are identical.

Spi-nor will pass on the appropriate flash select flag to low level driver,
and it will select pass all the data to that particular flash.

Write operation in parallel mode are performed in page size * 2 chunks as
each write operation results in writing both the flashes. For doubling the
address space each operation is performed at addr/2 flash offset, where addr
is the address specified by the user.

Similarly for read and erase operations it will read from both flashes, so
size and offset are divided by 2 and send to flash.

Changes in v2:
- Fixed the compilation issues.
Changes in v3:
- Fixed the CI issues.
Changes in v4:
- Removed the dio,dummy_bytes variables from zynq_qspi driver.
- Fix the compilation issue by including the DM_SPI config.
Changes in v5:
- Fixed the issue reported by buildman.
Changes in v6:
- Fixed the issues reported while running the sandbox test cases.
Changes in v7:
- Fixed the issues reported while running these da850evm_defconfig,
  imx28_xea_defconfig configs.
- Fixed the issue when DM_SPI config is disabled.
- Fixed the issue while running the sandbox_noinst_defconfig with spl
  ./spl/u-boot-spl -d arch/sandbox/dts/test.dtb
   jedec_spi_nor spi.bin@0: has no valid 'reg' property (-12)
   jedec_spi_nor spi.bin@1: has no valid 'reg' property (-12)
   ### ERROR ### Please RESET the board ###
Changes in v8:
- Fixed the compilation issue with imx28_xea_defconfig.
- Fixed the SPL size issue with the axm and taurus defconfigs.
- Rebased the patches on top of next branch.

Ashok Reddy Soma (4):
  mtd: spi-nor: Add parallel and stacked memories support
  mtd: spi-nor: Add parallel memories support for read_sr and read_fsr
  mtd: spi-nor: Add parallel and stacked memories support in read_bar
and write_bar
  spi: spi-uclass: Read chipselect and restrict capabilities

Venkatesh Yadav Abbarapu (4):
  spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver
  spi: zynq_qspi: Add parallel memories support in QSPI driver
  config: xea: Enable the SPL_FIT config option
  axm/taurus: Disable the SPL_SPI config

 board/siemens/taurus/taurus.c  |   4 +-
 configs/axm_defconfig  |   7 +-
 configs/imx28_xea_defconfig|   2 +-
 configs/taurus_defconfig   |   7 +-
 drivers/mtd/spi/sandbox.c  |   2 +-
 drivers/mtd/spi/spi-nor-core.c | 398 -
 drivers/spi/altera_spi.c   |   4 +-
 drivers/spi/atcspi200_spi.c|   2 +-
 drivers/spi/ath79_spi.c|   2 +-
 drivers/spi/atmel_spi.c|   6 +-
 drivers/spi/bcm63xx_hsspi.c|  42 ++--
 drivers/spi/bcm63xx_spi.c  |   6 +-
 drivers/spi/bcmbca_hsspi.c |  34 +--
 drivers/spi/cf_spi.c   |   6 +-
 drivers/spi/davinci_spi.c  |   8 +-
 drivers/spi/fsl_dspi.c |  18 +-
 drivers/spi/fsl_espi.c |   4 +-
 drivers/spi/fsl_qspi.c |   4 +-
 drivers/spi/gxp_spi.c  |   2 +-
 drivers/spi/mpc8xx_spi.c   |   4 +-
 drivers/spi/mpc8xxx_spi.c  |  10 +-
 drivers/spi/mscc_bb_spi.c  |   4 +-
 drivers/spi/mxc_spi.c  |   6 +-
 drivers/spi/npcm_fiu_spi.c |  14 +-
 drivers/spi/nxp_fspi.c |   2 +-
 drivers/spi/octeon_spi.c   |   2 +-
 drivers/spi/omap3_spi.c|   4 +-
 drivers/spi/pic32_spi.c|   2 +-
 drivers/spi/rk_spi.c   |   4 +-
 drivers/spi/rockchip_sfc.c |   2 +-
 drivers/spi/spi-aspeed-smc.c   |  28 +--
 drivers/spi/spi-mxic.c |   6 +-
 drivers/spi/spi-qup.c  |   4 +-
 drivers/spi/spi-sifive.c   |   6 +-
 drivers/spi/spi-sn-f-ospi.c|   2 +-
 drivers/spi/spi-sunxi.c|   6 +-
 drivers/spi/spi-synquacer.c|   4 +-
 drivers/spi/spi-uclass.c   |  33 ++-
 drivers/spi/stm32_qspi.c   |   2 +-
 drivers/spi/stm32_spi.c|   4 +-
 drivers/spi/ti_qspi.c  |  14 +-
 drivers/spi/xilinx_spi.c   |   6 +-
 drivers/spi/zynq_qspi.c| 119 --
 drivers/spi/zynq_spi.c |   6 +-
 drivers/spi/zynqmp_gqspi.c | 141 ++--
 include/linux/mtd/spi-nor.h|  12 +
 include/spi.h  |  23 +-
 lib/acpi/acpi_device.c |   2 +-
 48 files changed, 790 insertions(+), 240 deletions(-)

-- 
2.25.1



[PATCH v7 6/6] spi: zynq_qspi: Add parallel memories support in QSPI driver

2023-12-18 Thread Venkatesh Yadav Abbarapu
Add support for parallel memories in zynq_qspi.c driver. In case of
parallel memories STRIPE bit is set and sent to the qspi ip, which will
send data bits to both the flashes in parallel. However for few commands
we should not use stripe, instead send same data to both the flashes.
Those commands are exclueded by using zynqmp_qspi_update_stripe().

Also update copyright info for this file.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/zynq_qspi.c | 113 
 1 file changed, 102 insertions(+), 11 deletions(-)

diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c
index bc82acd0b6..41f7ae2ab2 100644
--- a/drivers/spi/zynq_qspi.c
+++ b/drivers/spi/zynq_qspi.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2013 Xilinx, Inc.
+ * (C) Copyright 2013 - 2022, Xilinx, Inc.
  * (C) Copyright 2015 Jagan Teki 
+ * (C) Copyright 2023, Advanced Micro Devices, Inc.
  *
  * Xilinx Zynq Quad-SPI(QSPI) controller driver (master mode only)
  */
@@ -13,10 +14,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include "../mtd/spi/sf_internal.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -42,6 +45,21 @@ DECLARE_GLOBAL_DATA_PTR;
 #define ZYNQ_QSPI_TXD_00_01_OFFSET 0x80/* Transmit 1-byte inst */
 #define ZYNQ_QSPI_TXD_00_10_OFFSET 0x84/* Transmit 2-byte inst */
 #define ZYNQ_QSPI_TXD_00_11_OFFSET 0x88/* Transmit 3-byte inst */
+#define ZYNQ_QSPI_FR_QOUT_CODE 0x6B/* read instruction code */
+
+#define QSPI_SELECT_LOWER_CSBIT(0)
+#define QSPI_SELECT_UPPER_CSBIT(1)
+
+/*
+ * QSPI Linear Configuration Register
+ *
+ * It is named Linear Configuration but it controls other modes when not in
+ * linear mode also.
+ */
+#define ZYNQ_QSPI_LCFG_TWO_MEM_MASK 0x4000 /* QSPI Enable Bit Mask */
+#define ZYNQ_QSPI_LCFG_SEP_BUS_MASK 0x2000 /* QSPI Enable Bit Mask */
+#define ZYNQ_QSPI_LCFG_U_PAGE   0x1000 /* QSPI Upper memory set */
+#define ZYNQ_QSPI_LCFG_DUMMY_SHIFT  8
 
 #define ZYNQ_QSPI_TXFIFO_THRESHOLD 1   /* Tx FIFO threshold level*/
 #define ZYNQ_QSPI_RXFIFO_THRESHOLD 32  /* Rx FIFO threshold level */
@@ -101,7 +119,11 @@ struct zynq_qspi_priv {
int bytes_to_transfer;
int bytes_to_receive;
unsigned int is_inst;
+   unsigned int is_parallel;
+   unsigned int is_stacked;
+   unsigned int u_page;
unsigned cs_change:1;
+   unsigned is_strip:1;
 };
 
 static int zynq_qspi_of_to_plat(struct udevice *bus)
@@ -112,7 +134,6 @@ static int zynq_qspi_of_to_plat(struct udevice *bus)
 
plat->regs = (struct zynq_qspi_regs *)fdtdec_get_addr(blob,
  node, "reg");
-
return 0;
 }
 
@@ -147,6 +168,9 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
/* Disable Interrupts */
writel(ZYNQ_QSPI_IXR_ALL_MASK, >idr);
 
+   /* Disable linear mode as the boot loader may have used it */
+   writel(0x0, >lqspicfg);
+
/* Clear the TX and RX threshold reg */
writel(ZYNQ_QSPI_TXFIFO_THRESHOLD, >txftr);
writel(ZYNQ_QSPI_RXFIFO_THRESHOLD, >rxftr);
@@ -164,12 +188,11 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
confr |= ZYNQ_QSPI_CR_IFMODE_MASK | ZYNQ_QSPI_CR_MCS_MASK |
ZYNQ_QSPI_CR_PCS_MASK | ZYNQ_QSPI_CR_FW_MASK |
ZYNQ_QSPI_CR_MSTREN_MASK;
-   writel(confr, >cr);
 
-   /* Disable the LQSPI feature */
-   confr = readl(>lqspicfg);
-   confr &= ~ZYNQ_QSPI_LQSPICFG_LQMODE_MASK;
-   writel(confr, >lqspicfg);
+   if (priv->is_stacked)
+   confr |= 0x10;
+
+   writel(confr, >cr);
 
/* Enable SPI */
writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, >enr);
@@ -181,6 +204,7 @@ static int zynq_qspi_child_pre_probe(struct udevice *bus)
struct zynq_qspi_priv *priv = dev_get_priv(bus->parent);
 
priv->max_hz = slave->max_hz;
+   slave->multi_cs_cap = true;
 
return 0;
 }
@@ -363,8 +387,8 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv 
*priv, u32 size)
unsigned len, offset;
struct zynq_qspi_regs *regs = priv->regs;
static const unsigned offsets[4] = {
-   ZYNQ_QSPI_TXD_00_00_OFFSET, ZYNQ_QSPI_TXD_00_01_OFFSET,
-   ZYNQ_QSPI_TXD_00_10_OFFSET, ZYNQ_QSPI_TXD_00_11_OFFSET };
+   ZYNQ_QSPI_TXD_00_01_OFFSET, ZYNQ_QSPI_TXD_00_10_OFFSET,
+   ZYNQ_QSPI_TXD_00_11_OFFSET, ZYNQ_QSPI_TXD_00_00_OFFSET };
 
while ((fifocount < size) &&
(priv->bytes_to_transfer > 0)) {
@@ -386,7 +410,11 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv 
*priv, u32 size)
return;
  

[PATCH v7 4/6] spi: spi-uclass: Read chipselect and restrict capabilities

2023-12-18 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Read chipselect properties from DT which are populated using 'reg'
property and save it in plat->cs[] array for later use.

Also read multi chipselect capability which is used for
parallel-memories and return errors if they are passed on using DT but
driver is not capable of handling it.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/sandbox.c|  2 +-
 drivers/spi/altera_spi.c |  4 ++--
 drivers/spi/atcspi200_spi.c  |  2 +-
 drivers/spi/ath79_spi.c  |  2 +-
 drivers/spi/atmel_spi.c  |  6 +++---
 drivers/spi/bcm63xx_hsspi.c  | 42 ++--
 drivers/spi/bcm63xx_spi.c|  6 +++---
 drivers/spi/bcmbca_hsspi.c   | 34 ++---
 drivers/spi/cf_spi.c |  6 +++---
 drivers/spi/davinci_spi.c|  8 +++
 drivers/spi/fsl_dspi.c   | 18 
 drivers/spi/fsl_espi.c   |  4 ++--
 drivers/spi/fsl_qspi.c   |  4 ++--
 drivers/spi/gxp_spi.c|  2 +-
 drivers/spi/mpc8xx_spi.c |  4 ++--
 drivers/spi/mpc8xxx_spi.c| 10 -
 drivers/spi/mscc_bb_spi.c|  4 ++--
 drivers/spi/mxc_spi.c|  6 +++---
 drivers/spi/npcm_fiu_spi.c   | 14 ++--
 drivers/spi/nxp_fspi.c   |  2 +-
 drivers/spi/octeon_spi.c |  2 +-
 drivers/spi/omap3_spi.c  |  4 ++--
 drivers/spi/pic32_spi.c  |  2 +-
 drivers/spi/rk_spi.c |  4 ++--
 drivers/spi/rockchip_sfc.c   |  2 +-
 drivers/spi/spi-aspeed-smc.c | 28 
 drivers/spi/spi-mxic.c   |  6 +++---
 drivers/spi/spi-qup.c|  4 ++--
 drivers/spi/spi-sifive.c |  6 +++---
 drivers/spi/spi-sn-f-ospi.c  |  2 +-
 drivers/spi/spi-sunxi.c  |  6 +++---
 drivers/spi/spi-synquacer.c  |  4 ++--
 drivers/spi/spi-uclass.c | 33 +++-
 drivers/spi/stm32_qspi.c |  2 +-
 drivers/spi/stm32_spi.c  |  4 ++--
 drivers/spi/ti_qspi.c| 14 ++--
 drivers/spi/xilinx_spi.c |  4 ++--
 drivers/spi/zynq_qspi.c  |  6 +++---
 drivers/spi/zynq_spi.c   |  6 +++---
 include/spi.h|  8 ++-
 lib/acpi/acpi_device.c   |  2 +-
 41 files changed, 179 insertions(+), 150 deletions(-)

diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 4fe547171a..72036d5a88 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -139,7 +139,7 @@ static int sandbox_sf_probe(struct udevice *dev)
return ret;
}
slave_plat = dev_get_parent_plat(dev);
-   cs = slave_plat->cs;
+   cs = slave_plat->cs[0];
debug("found at cs %d\n", cs);
 
if (!pdata->filename) {
diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c
index 989679e881..48782f81c1 100644
--- a/drivers/spi/altera_spi.c
+++ b/drivers/spi/altera_spi.c
@@ -96,7 +96,7 @@ static int altera_spi_xfer(struct udevice *dev, unsigned int 
bitlen,
uint32_t reg, data, start;
 
debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
- dev_seq(bus), slave_plat->cs, bitlen, bytes, flags);
+ dev_seq(bus), slave_plat->cs[0], bitlen, bytes, flags);
 
if (bitlen == 0)
goto done;
@@ -111,7 +111,7 @@ static int altera_spi_xfer(struct udevice *dev, unsigned 
int bitlen,
readl(>rxdata);
 
if (flags & SPI_XFER_BEGIN)
-   spi_cs_activate(dev, slave_plat->cs);
+   spi_cs_activate(dev, slave_plat->cs[0]);
 
while (bytes--) {
if (txp)
diff --git a/drivers/spi/atcspi200_spi.c b/drivers/spi/atcspi200_spi.c
index de9c14837c..acee743653 100644
--- a/drivers/spi/atcspi200_spi.c
+++ b/drivers/spi/atcspi200_spi.c
@@ -321,7 +321,7 @@ static int atcspi200_spi_claim_bus(struct udevice *dev)
struct udevice *bus = dev->parent;
struct nds_spi_slave *ns = dev_get_priv(bus);
 
-   if (slave_plat->cs >= ns->num_cs) {
+   if (slave_plat->cs[0] >= ns->num_cs) {
printf("Invalid SPI chipselect\n");
return -EINVAL;
}
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
index 205567ef54..ad10cec2a6 100644
--- a/drivers/spi/ath79_spi.c
+++ b/drivers/spi/ath79_spi.c
@@ -74,7 +74,7 @@ static int ath79_spi_xfer(struct udevice *dev, unsigned int 
bitlen,
if (restbits)
bytes++;
 
-   out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs));
+   out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs[0]));
while (bytes > 0) {
bytes--;
curbyte = 0;
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index aec6f4eca9..e2de39d1ef 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -126,7 +126,7 @@ static int atmel_spi_claim_bus(struct udevice *dev)
struct atmel_spi_priv *priv = dev_get

[PATCH v7 5/6] spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver

2023-12-18 Thread Venkatesh Yadav Abbarapu
Add support for parallel memories in zynqmp_gqspi.c driver. In case of
parallel memories STRIPE bit is set and sent to the qspi ip, which will
send data bits to both the flashes in parallel. However for few commands
we should not use stripe, instead send same data to both the flashes.
Those commands are exclueded by using zynqmp_qspi_update_stripe().

Also update copyright info for this file.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/zynqmp_gqspi.c | 141 -
 include/spi.h  |   4 ++
 2 files changed, 129 insertions(+), 16 deletions(-)

diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index a323994fb2..dedf8270a8 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2018 Xilinx
- *
+ * (C) Copyright 2013 - 2022, Xilinx, Inc.
+ * (C) Copyright 2023, Advanced Micro Devices, Inc.
  * Xilinx ZynqMP Generic Quad-SPI(QSPI) controller driver(master mode only)
  */
 
@@ -25,6 +25,8 @@
 #include 
 #include 
 #include 
+#include 
+#include "../mtd/spi/sf_internal.h"
 #include 
 
 #define GQSPI_GFIFO_STRT_MODE_MASK BIT(29)
@@ -88,6 +90,9 @@
 #define SPI_XFER_ON_LOWER  1
 #define SPI_XFER_ON_UPPER  2
 
+#define GQSPI_SELECT_LOWER_CS  BIT(0)
+#define GQSPI_SELECT_UPPER_CS  BIT(1)
+
 #define GQSPI_DMA_ALIGN0x4
 #define GQSPI_MAX_BAUD_RATE_VAL7
 #define GQSPI_DFLT_BAUD_RATE_VAL   2
@@ -183,13 +188,14 @@ struct zynqmp_qspi_priv {
int bytes_to_transfer;
int bytes_to_receive;
const struct spi_mem_op *op;
+   unsigned int is_parallel;
+   unsigned int u_page;
+   unsigned int bus;
+   unsigned int stripe;
+   unsigned int flags;
+   u32 max_hz;
 };
 
-__weak int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 
value)
-{
-   return 0;
-}
-
 static int zynqmp_qspi_of_to_plat(struct udevice *bus)
 {
struct zynqmp_qspi_plat *plat = dev_get_plat(bus);
@@ -234,8 +240,30 @@ static u32 zynqmp_qspi_bus_select(struct zynqmp_qspi_priv 
*priv)
 {
u32 gqspi_fifo_reg = 0;
 
-   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
-GQSPI_GFIFO_CS_LOWER;
+   if (priv->is_parallel) {
+   if (priv->bus == SPI_XFER_ON_BOTH)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_CS_UPPER |
+GQSPI_GFIFO_CS_LOWER;
+   else if (priv->bus == SPI_XFER_ON_LOWER)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_UPPER |
+GQSPI_GFIFO_CS_LOWER;
+   else if (priv->bus == SPI_XFER_ON_UPPER)
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_CS_LOWER |
+GQSPI_GFIFO_CS_UPPER;
+   else
+   debug("Wrong Bus selection:0x%x\n", priv->bus);
+   } else {
+   if (priv->u_page)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_UPPER;
+   else
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_LOWER;
+   }
 
return gqspi_fifo_reg;
 }
@@ -295,8 +323,15 @@ static void zynqmp_qspi_chipselect(struct zynqmp_qspi_priv 
*priv, int is_on)
gqspi_fifo_reg |= GQSPI_SPI_MODE_SPI |
  GQSPI_IMD_DATA_CS_ASSERT;
} else {
-   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS;
-   gqspi_fifo_reg |= GQSPI_IMD_DATA_CS_DEASSERT;
+   if (priv->is_parallel) {
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_LOW_BUS;
+   } else if (priv->u_page) {
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS;
+   } else {
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS;
+   gqspi_fifo_reg |= GQSPI_IMD_DATA_CS_DEASSERT;
+   }
}
 
zynqmp_qspi_fill_gen_fifo(priv, gqspi_fifo_reg);
@@ -366,12 +401,13 @@ static int zynqmp_qspi_set_speed(struct udevice *bus, 
uint speed)
 
log_debug("%s, Speed: %d, Max: %d\n", __func__, speed, plat->frequency);
 
-   if (speed > plat->frequency)
-   speed = plat->frequency;
+   /*
+* If speed == 0 or speed > max freq, then set speed to highest
+*/
+   if (!speed || speed > priv->max_hz)
+   speed = pr

[PATCH v7 3/6] mtd: spi-nor: Add parallel and stacked memories support in read_bar and write_bar

2023-12-18 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Add support for parallel memories and stacked memories configuration
in read_bar and write_bar functions.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 55 +-
 1 file changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 3112f93af0..410f7320a8 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -885,12 +885,32 @@ static int clean_bar(struct spi_nor *nor)
 
 static int write_bar(struct spi_nor *nor, u32 offset)
 {
-   u8 cmd, bank_sel;
+   u8 cmd, bank_sel, upage_curr;
int ret;
+   struct mtd_info *mtd = >mtd;
+
+   /* Wait until previous write command is finished */
+   if (spi_nor_wait_till_ready(nor))
+   return 1;
+
+   if (nor->flags & (SNOR_F_HAS_PARALLEL | SNOR_F_HAS_STACKED) &&
+   mtd->size <= SZ_32M)
+   return 0;
+
+   if (mtd->size <= SZ_16M)
+   return 0;
+
+   offset = offset % (u32)mtd->size;
+   bank_sel = offset >> 24;
 
-   bank_sel = offset / SZ_16M;
-   if (bank_sel == nor->bank_curr)
-   goto bar_end;
+   upage_curr = nor->spi->flags & SPI_XFER_U_PAGE;
+
+   if (!(nor->flags & SNOR_F_HAS_STACKED) && bank_sel == nor->bank_curr)
+   return 0;
+   else if (upage_curr == nor->upage_prev && bank_sel == nor->bank_curr)
+   return 0;
+
+   nor->upage_prev = upage_curr;
 
cmd = nor->bank_write_cmd;
write_enable(nor);
@@ -900,15 +920,19 @@ static int write_bar(struct spi_nor *nor, u32 offset)
return ret;
}
 
-bar_end:
nor->bank_curr = bank_sel;
-   return nor->bank_curr;
+
+   return write_disable(nor);
 }
 
 static int read_bar(struct spi_nor *nor, const struct flash_info *info)
 {
u8 curr_bank = 0;
int ret;
+   struct mtd_info *mtd = >mtd;
+
+   if (mtd->size <= SZ_16M)
+   return 0;
 
switch (JEDEC_MFR(info)) {
case SNOR_MFR_SPANSION:
@@ -920,15 +944,30 @@ static int read_bar(struct spi_nor *nor, const struct 
flash_info *info)
nor->bank_write_cmd = SPINOR_OP_WREAR;
}
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   nor->spi->flags |= SPI_XFER_LOWER;
+
ret = nor->read_reg(nor, nor->bank_read_cmd,
-   _bank, 1);
+   _bank, 1);
if (ret) {
debug("SF: fail to read bank addr register\n");
return ret;
}
nor->bank_curr = curr_bank;
 
-   return 0;
+   // Make sure both chips use the same BAR
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   write_enable(nor);
+   ret = nor->write_reg(nor, nor->bank_write_cmd, _bank, 1);
+   if (ret)
+   return ret;
+
+   ret = write_disable(nor);
+   if (ret)
+   return ret;
+   }
+
+   return ret;
 }
 #endif
 
-- 
2.25.1



[PATCH v7 2/6] mtd: spi-nor: Add parallel memories support for read_sr and read_fsr

2023-12-18 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Add support for parallel memories flash configuration in read status
register and read flag status register functions.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 50 --
 1 file changed, 36 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 08319a881d..3112f93af0 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -438,8 +438,9 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, 
loff_t to, size_t len,
 }
 
 /*
- * Read the status register, returning its value in the location
- * Return the status register value.
+ * Return the status register value. If the chip is parallel, then the
+ * read will be striped, so we should read 2 bytes to get the sr
+ * register value from both of the parallel chips.
  * Returns negative if error occurred.
  */
 static int read_sr(struct spi_nor *nor)
@@ -471,18 +472,29 @@ static int read_sr(struct spi_nor *nor)
if (spi_nor_protocol_is_dtr(nor->reg_proto))
op.data.nbytes = 2;
 
-   ret = spi_nor_read_write_reg(nor, , val);
-   if (ret < 0) {
-   pr_debug("error %d reading SR\n", (int)ret);
-   return ret;
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   op.data.nbytes = 2;
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
+   val[0] |= val[1];
+   } else {
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
}
 
-   return *val;
+   return val[0];
 }
 
 /*
- * Read the flag status register, returning its value in the location
- * Return the status register value.
+ * Return the flag status register value. If the chip is parallel, then
+ * the read will be striped, so we should read 2 bytes to get the fsr
+ * register value from both of the parallel chips.
  * Returns negative if error occurred.
  */
 static int read_fsr(struct spi_nor *nor)
@@ -514,13 +526,23 @@ static int read_fsr(struct spi_nor *nor)
if (spi_nor_protocol_is_dtr(nor->reg_proto))
op.data.nbytes = 2;
 
-   ret = spi_nor_read_write_reg(nor, , val);
-   if (ret < 0) {
-   pr_debug("error %d reading FSR\n", ret);
-   return ret;
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   op.data.nbytes = 2;
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
+   val[0] &= val[1];
+   } else {
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading FSR\n", ret);
+   return ret;
+   }
}
 
-   return *val;
+   return val[0];
 }
 
 /*
-- 
2.25.1



[PATCH v7 1/6] mtd: spi-nor: Add parallel and stacked memories support

2023-12-18 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

In parallel mode, the current implementation assumes that a maximum of
two flashes are connected. The QSPI controller splits the data evenly
between both the flashes so, both the flashes that are connected in
parallel mode should be identical.
During each operation SPI-NOR sets 0th bit for CS0 & 1st bit for CS1 in
nor->flags.

In stacked mode the current implementation assumes that a maximum of two
flashes are connected and both the flashes are of same make but can
differ in sizes. So, except the sizes all other flash parameters of both
the flashes are identical

Spi-nor will pass on the appropriate flash select flag to low level
driver, and it will select pass all the data to that particular flash.

Write operation in parallel mode are performed in page size * 2 chunks as
each write operation results in writing both the flashes. For doubling
the address space each operation is performed at addr/2 flash offset,
where addr is the address specified by the user.

Similarly for read and erase operations it will read from both flashes,
so size and offset are divided by 2 and send to flash.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 293 +
 include/linux/mtd/spi-nor.h|  12 ++
 include/spi.h  |  11 ++
 3 files changed, 288 insertions(+), 28 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 9a1801ba93..08319a881d 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -639,12 +639,17 @@ static u8 spi_nor_convert_3to4_erase(u8 opcode)
 static void spi_nor_set_4byte_opcodes(struct spi_nor *nor,
  const struct flash_info *info)
 {
+   bool shift = 0;
+
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   shift = 1;
+
/* Do some manufacturer fixups first */
switch (JEDEC_MFR(info)) {
case SNOR_MFR_SPANSION:
/* No small sector erase for 4-byte command set */
nor->erase_opcode = SPINOR_OP_SE;
-   nor->mtd.erasesize = info->sector_size;
+   nor->mtd.erasesize = info->sector_size << shift;
break;
 
default:
@@ -965,8 +970,8 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 
addr)
 static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
+   u32 addr, len, rem, offset;
bool addr_known = false;
-   u32 addr, len, rem;
int ret, err;
 
dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
@@ -991,6 +996,19 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
ret = -EINTR;
goto erase_err;
}
+
+   offset = addr;
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   offset /= 2;
+
+   if (nor->flags & SNOR_F_HAS_STACKED) {
+   if (offset >= (mtd->size / 2)) {
+   offset = offset - (mtd->size / 2);
+   nor->spi->flags |= SPI_XFER_U_PAGE;
+   } else {
+   nor->spi->flags &= ~SPI_XFER_U_PAGE;
+   }
+   }
 #ifdef CONFIG_SPI_FLASH_BAR
ret = write_bar(nor, addr);
if (ret < 0)
@@ -1396,6 +1414,9 @@ static const struct flash_info *spi_nor_read_id(struct 
spi_nor *nor)
u8  id[SPI_NOR_MAX_ID_LEN];
const struct flash_info *info;
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   nor->spi->flags |= SPI_XFER_LOWER;
+
tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
if (tmp < 0) {
dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp);
@@ -1420,28 +1441,66 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t 
from, size_t len,
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
int ret;
+   u32 offset = from;
+   u32 stack_shift = 0;
+   u32 read_len = 0;
+   u32 rem_bank_len = 0;
+   u8 bank;
+   u8 is_ofst_odd = 0;
 
dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
 
+   if ((nor->flags & SNOR_F_HAS_PARALLEL) && (offset & 1)) {
+   /* We can hit this case when we use file system like ubifs */
+   from = (loff_t)(from - 1);
+   len = (size_t)(len + 1);
+   is_ofst_odd = 1;
+   }
+
while (len) {
-   loff_t addr = from;
-   size_t read_len = len;
+   if (nor->addr_width == 3) {
+   if (nor->

[PATCH v7 0/6] spi-nor: Add parallel and stacked memories support

2023-12-18 Thread Venkatesh Yadav Abbarapu
This series adds support for Xilinx qspi parallel and stacked memeories.

In parallel mode, the current implementation assumes that a maximum of two 
flashes are connected. The QSPI controller splits the data evenly between both 
the flashes so, both the flashes that are connected in parallel mode should be 
identical.
During each operation SPI-NOR sets 0th bit for CS0 & 1st bit for CS1 in
nor->flags.

In stacked mode the current implementation assumes that a maximum of two 
flashes are connected and both the flashes are of same make but can differ in 
sizes. So, except the sizes all other flash parameters of both the flashes are 
identical.

Spi-nor will pass on the appropriate flash select flag to low level driver, and 
it will select pass all the data to that particular flash.

Write operation in parallel mode are performed in page size * 2 chunks as each 
write operation results in writing both the flashes. For doubling the address 
space each operation is performed at addr/2 flash offset, where addr is the 
address specified by the user.

Similarly for read and erase operations it will read from both flashes, so size 
and offset are divided by 2 and send to flash.

Changes in v2:
- Fixed the compilation issues.
Changes in v3:
- Fixed the CI issues.
Changes in v4:
- Removed the dio,dummy_bytes variables from zynq_qspi driver.
- Fix the compilation issue by including the DM_SPI config.
Changes in v5:
- Fixed the issue reported by buildman.
Changes in v6:
- Fixed the issues reported while running the sandbox test cases.
Changes in v7:
- Fixed the issues reported while running these da850evm_defconfig,
  imx28_xea_defconfig configs.
- Fixed the issue when DM_SPI config is disabled.
- Fixed the issue while running the sandbox_noinst_defconfig with spl
  ./spl/u-boot-spl -d arch/sandbox/dts/test.dtb
   jedec_spi_nor spi.bin@0: has no valid 'reg' property (-12)
   jedec_spi_nor spi.bin@1: has no valid 'reg' property (-12)
   ### ERROR ### Please RESET the board ###

Ashok Reddy Soma (4):
  mtd: spi-nor: Add parallel and stacked memories support
  mtd: spi-nor: Add parallel memories support for read_sr and read_fsr
  mtd: spi-nor: Add parallel and stacked memories support in read_bar
and write_bar
  spi: spi-uclass: Read chipselect and restrict capabilities

Venkatesh Yadav Abbarapu (2):
  spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver
  spi: zynq_qspi: Add parallel memories support in QSPI driver

 drivers/mtd/spi/sandbox.c  |   2 +-
 drivers/mtd/spi/spi-nor-core.c | 398 -
 drivers/spi/altera_spi.c   |   4 +-
 drivers/spi/atcspi200_spi.c|   2 +-
 drivers/spi/ath79_spi.c|   2 +-
 drivers/spi/atmel_spi.c|   6 +-
 drivers/spi/bcm63xx_hsspi.c|  42 ++--
 drivers/spi/bcm63xx_spi.c  |   6 +-
 drivers/spi/bcmbca_hsspi.c |  34 +--
 drivers/spi/cf_spi.c   |   6 +-
 drivers/spi/davinci_spi.c  |   8 +-
 drivers/spi/fsl_dspi.c |  18 +-
 drivers/spi/fsl_espi.c |   4 +-
 drivers/spi/fsl_qspi.c |   4 +-
 drivers/spi/gxp_spi.c  |   2 +-
 drivers/spi/mpc8xx_spi.c   |   4 +-
 drivers/spi/mpc8xxx_spi.c  |  10 +-
 drivers/spi/mscc_bb_spi.c  |   4 +-
 drivers/spi/mxc_spi.c  |   6 +-
 drivers/spi/npcm_fiu_spi.c |  14 +-
 drivers/spi/nxp_fspi.c |   2 +-
 drivers/spi/octeon_spi.c   |   2 +-
 drivers/spi/omap3_spi.c|   4 +-
 drivers/spi/pic32_spi.c|   2 +-
 drivers/spi/rk_spi.c   |   4 +-
 drivers/spi/rockchip_sfc.c |   2 +-
 drivers/spi/spi-aspeed-smc.c   |  28 +--
 drivers/spi/spi-mxic.c |   6 +-
 drivers/spi/spi-qup.c  |   4 +-
 drivers/spi/spi-sifive.c   |   6 +-
 drivers/spi/spi-sn-f-ospi.c|   2 +-
 drivers/spi/spi-sunxi.c|   6 +-
 drivers/spi/spi-synquacer.c|   4 +-
 drivers/spi/spi-uclass.c   |  33 ++-
 drivers/spi/stm32_qspi.c   |   2 +-
 drivers/spi/stm32_spi.c|   4 +-
 drivers/spi/ti_qspi.c  |  14 +-
 drivers/spi/xilinx_spi.c   |   4 +-
 drivers/spi/zynq_qspi.c| 119 --
 drivers/spi/zynq_spi.c |   6 +-
 drivers/spi/zynqmp_gqspi.c | 141 ++--
 include/linux/mtd/spi-nor.h|  12 +
 include/spi.h  |  23 +-
 lib/acpi/acpi_device.c |   2 +-
 44 files changed, 781 insertions(+), 227 deletions(-)

-- 
2.25.1



[PATCH v6 5/6] spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver

2023-12-13 Thread Venkatesh Yadav Abbarapu
Add support for parallel memories in zynqmp_gqspi.c driver. In case of
parallel memories STRIPE bit is set and sent to the qspi ip, which will
send data bits to both the flashes in parallel. However for few commands
we should not use stripe, instead send same data to both the flashes.
Those commands are exclueded by using zynqmp_qspi_update_stripe().

Also update copyright info for this file.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/zynqmp_gqspi.c | 141 -
 include/spi.h  |   4 ++
 2 files changed, 129 insertions(+), 16 deletions(-)

diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index a323994fb2..dedf8270a8 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2018 Xilinx
- *
+ * (C) Copyright 2013 - 2022, Xilinx, Inc.
+ * (C) Copyright 2023, Advanced Micro Devices, Inc.
  * Xilinx ZynqMP Generic Quad-SPI(QSPI) controller driver(master mode only)
  */
 
@@ -25,6 +25,8 @@
 #include 
 #include 
 #include 
+#include 
+#include "../mtd/spi/sf_internal.h"
 #include 
 
 #define GQSPI_GFIFO_STRT_MODE_MASK BIT(29)
@@ -88,6 +90,9 @@
 #define SPI_XFER_ON_LOWER  1
 #define SPI_XFER_ON_UPPER  2
 
+#define GQSPI_SELECT_LOWER_CS  BIT(0)
+#define GQSPI_SELECT_UPPER_CS  BIT(1)
+
 #define GQSPI_DMA_ALIGN0x4
 #define GQSPI_MAX_BAUD_RATE_VAL7
 #define GQSPI_DFLT_BAUD_RATE_VAL   2
@@ -183,13 +188,14 @@ struct zynqmp_qspi_priv {
int bytes_to_transfer;
int bytes_to_receive;
const struct spi_mem_op *op;
+   unsigned int is_parallel;
+   unsigned int u_page;
+   unsigned int bus;
+   unsigned int stripe;
+   unsigned int flags;
+   u32 max_hz;
 };
 
-__weak int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 
value)
-{
-   return 0;
-}
-
 static int zynqmp_qspi_of_to_plat(struct udevice *bus)
 {
struct zynqmp_qspi_plat *plat = dev_get_plat(bus);
@@ -234,8 +240,30 @@ static u32 zynqmp_qspi_bus_select(struct zynqmp_qspi_priv 
*priv)
 {
u32 gqspi_fifo_reg = 0;
 
-   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
-GQSPI_GFIFO_CS_LOWER;
+   if (priv->is_parallel) {
+   if (priv->bus == SPI_XFER_ON_BOTH)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_CS_UPPER |
+GQSPI_GFIFO_CS_LOWER;
+   else if (priv->bus == SPI_XFER_ON_LOWER)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_UPPER |
+GQSPI_GFIFO_CS_LOWER;
+   else if (priv->bus == SPI_XFER_ON_UPPER)
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_CS_LOWER |
+GQSPI_GFIFO_CS_UPPER;
+   else
+   debug("Wrong Bus selection:0x%x\n", priv->bus);
+   } else {
+   if (priv->u_page)
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_UPPER;
+   else
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS |
+GQSPI_GFIFO_CS_LOWER;
+   }
 
return gqspi_fifo_reg;
 }
@@ -295,8 +323,15 @@ static void zynqmp_qspi_chipselect(struct zynqmp_qspi_priv 
*priv, int is_on)
gqspi_fifo_reg |= GQSPI_SPI_MODE_SPI |
  GQSPI_IMD_DATA_CS_ASSERT;
} else {
-   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS;
-   gqspi_fifo_reg |= GQSPI_IMD_DATA_CS_DEASSERT;
+   if (priv->is_parallel) {
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS |
+GQSPI_GFIFO_LOW_BUS;
+   } else if (priv->u_page) {
+   gqspi_fifo_reg = GQSPI_GFIFO_UP_BUS;
+   } else {
+   gqspi_fifo_reg = GQSPI_GFIFO_LOW_BUS;
+   gqspi_fifo_reg |= GQSPI_IMD_DATA_CS_DEASSERT;
+   }
}
 
zynqmp_qspi_fill_gen_fifo(priv, gqspi_fifo_reg);
@@ -366,12 +401,13 @@ static int zynqmp_qspi_set_speed(struct udevice *bus, 
uint speed)
 
log_debug("%s, Speed: %d, Max: %d\n", __func__, speed, plat->frequency);
 
-   if (speed > plat->frequency)
-   speed = plat->frequency;
+   /*
+* If speed == 0 or speed > max freq, then set speed to highest
+*/
+   if (!speed || speed > priv->max_hz)
+   speed = pr

[PATCH v6 6/6] spi: zynq_qspi: Add parallel memories support in QSPI driver

2023-12-13 Thread Venkatesh Yadav Abbarapu
Add support for parallel memories in zynq_qspi.c driver. In case of
parallel memories STRIPE bit is set and sent to the qspi ip, which will
send data bits to both the flashes in parallel. However for few commands
we should not use stripe, instead send same data to both the flashes.
Those commands are exclueded by using zynqmp_qspi_update_stripe().

Also update copyright info for this file.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/spi/zynq_qspi.c | 113 
 1 file changed, 102 insertions(+), 11 deletions(-)

diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c
index bc82acd0b6..41f7ae2ab2 100644
--- a/drivers/spi/zynq_qspi.c
+++ b/drivers/spi/zynq_qspi.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2013 Xilinx, Inc.
+ * (C) Copyright 2013 - 2022, Xilinx, Inc.
  * (C) Copyright 2015 Jagan Teki 
+ * (C) Copyright 2023, Advanced Micro Devices, Inc.
  *
  * Xilinx Zynq Quad-SPI(QSPI) controller driver (master mode only)
  */
@@ -13,10 +14,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include "../mtd/spi/sf_internal.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -42,6 +45,21 @@ DECLARE_GLOBAL_DATA_PTR;
 #define ZYNQ_QSPI_TXD_00_01_OFFSET 0x80/* Transmit 1-byte inst */
 #define ZYNQ_QSPI_TXD_00_10_OFFSET 0x84/* Transmit 2-byte inst */
 #define ZYNQ_QSPI_TXD_00_11_OFFSET 0x88/* Transmit 3-byte inst */
+#define ZYNQ_QSPI_FR_QOUT_CODE 0x6B/* read instruction code */
+
+#define QSPI_SELECT_LOWER_CSBIT(0)
+#define QSPI_SELECT_UPPER_CSBIT(1)
+
+/*
+ * QSPI Linear Configuration Register
+ *
+ * It is named Linear Configuration but it controls other modes when not in
+ * linear mode also.
+ */
+#define ZYNQ_QSPI_LCFG_TWO_MEM_MASK 0x4000 /* QSPI Enable Bit Mask */
+#define ZYNQ_QSPI_LCFG_SEP_BUS_MASK 0x2000 /* QSPI Enable Bit Mask */
+#define ZYNQ_QSPI_LCFG_U_PAGE   0x1000 /* QSPI Upper memory set */
+#define ZYNQ_QSPI_LCFG_DUMMY_SHIFT  8
 
 #define ZYNQ_QSPI_TXFIFO_THRESHOLD 1   /* Tx FIFO threshold level*/
 #define ZYNQ_QSPI_RXFIFO_THRESHOLD 32  /* Rx FIFO threshold level */
@@ -101,7 +119,11 @@ struct zynq_qspi_priv {
int bytes_to_transfer;
int bytes_to_receive;
unsigned int is_inst;
+   unsigned int is_parallel;
+   unsigned int is_stacked;
+   unsigned int u_page;
unsigned cs_change:1;
+   unsigned is_strip:1;
 };
 
 static int zynq_qspi_of_to_plat(struct udevice *bus)
@@ -112,7 +134,6 @@ static int zynq_qspi_of_to_plat(struct udevice *bus)
 
plat->regs = (struct zynq_qspi_regs *)fdtdec_get_addr(blob,
  node, "reg");
-
return 0;
 }
 
@@ -147,6 +168,9 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
/* Disable Interrupts */
writel(ZYNQ_QSPI_IXR_ALL_MASK, >idr);
 
+   /* Disable linear mode as the boot loader may have used it */
+   writel(0x0, >lqspicfg);
+
/* Clear the TX and RX threshold reg */
writel(ZYNQ_QSPI_TXFIFO_THRESHOLD, >txftr);
writel(ZYNQ_QSPI_RXFIFO_THRESHOLD, >rxftr);
@@ -164,12 +188,11 @@ static void zynq_qspi_init_hw(struct zynq_qspi_priv *priv)
confr |= ZYNQ_QSPI_CR_IFMODE_MASK | ZYNQ_QSPI_CR_MCS_MASK |
ZYNQ_QSPI_CR_PCS_MASK | ZYNQ_QSPI_CR_FW_MASK |
ZYNQ_QSPI_CR_MSTREN_MASK;
-   writel(confr, >cr);
 
-   /* Disable the LQSPI feature */
-   confr = readl(>lqspicfg);
-   confr &= ~ZYNQ_QSPI_LQSPICFG_LQMODE_MASK;
-   writel(confr, >lqspicfg);
+   if (priv->is_stacked)
+   confr |= 0x10;
+
+   writel(confr, >cr);
 
/* Enable SPI */
writel(ZYNQ_QSPI_ENR_SPI_EN_MASK, >enr);
@@ -181,6 +204,7 @@ static int zynq_qspi_child_pre_probe(struct udevice *bus)
struct zynq_qspi_priv *priv = dev_get_priv(bus->parent);
 
priv->max_hz = slave->max_hz;
+   slave->multi_cs_cap = true;
 
return 0;
 }
@@ -363,8 +387,8 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv 
*priv, u32 size)
unsigned len, offset;
struct zynq_qspi_regs *regs = priv->regs;
static const unsigned offsets[4] = {
-   ZYNQ_QSPI_TXD_00_00_OFFSET, ZYNQ_QSPI_TXD_00_01_OFFSET,
-   ZYNQ_QSPI_TXD_00_10_OFFSET, ZYNQ_QSPI_TXD_00_11_OFFSET };
+   ZYNQ_QSPI_TXD_00_01_OFFSET, ZYNQ_QSPI_TXD_00_10_OFFSET,
+   ZYNQ_QSPI_TXD_00_11_OFFSET, ZYNQ_QSPI_TXD_00_00_OFFSET };
 
while ((fifocount < size) &&
(priv->bytes_to_transfer > 0)) {
@@ -386,7 +410,11 @@ static void zynq_qspi_fill_tx_fifo(struct zynq_qspi_priv 
*priv, u32 size)
return;
  

[PATCH v6 4/6] spi: spi-uclass: Read chipselect and restrict capabilities

2023-12-13 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Read chipselect properties from DT which are populated using 'reg'
property and save it in plat->cs[] array for later use.

Also read multi chipselect capability which is used for
parallel-memories and return errors if they are passed on using DT but
driver is not capable of handling it.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/sandbox.c|  2 +-
 drivers/spi/altera_spi.c |  4 ++--
 drivers/spi/atcspi200_spi.c  |  2 +-
 drivers/spi/ath79_spi.c  |  2 +-
 drivers/spi/atmel_spi.c  |  6 +++---
 drivers/spi/bcm63xx_hsspi.c  | 42 ++--
 drivers/spi/bcm63xx_spi.c|  6 +++---
 drivers/spi/bcmbca_hsspi.c   | 34 ++---
 drivers/spi/cf_spi.c |  6 +++---
 drivers/spi/davinci_spi.c|  6 +++---
 drivers/spi/fsl_dspi.c   | 18 
 drivers/spi/fsl_espi.c   |  4 ++--
 drivers/spi/fsl_qspi.c   |  4 ++--
 drivers/spi/gxp_spi.c|  2 +-
 drivers/spi/mpc8xx_spi.c |  4 ++--
 drivers/spi/mpc8xxx_spi.c| 10 -
 drivers/spi/mscc_bb_spi.c|  4 ++--
 drivers/spi/mxc_spi.c|  6 +++---
 drivers/spi/npcm_fiu_spi.c   | 14 ++--
 drivers/spi/nxp_fspi.c   |  2 +-
 drivers/spi/octeon_spi.c |  2 +-
 drivers/spi/omap3_spi.c  |  4 ++--
 drivers/spi/pic32_spi.c  |  2 +-
 drivers/spi/rk_spi.c |  4 ++--
 drivers/spi/rockchip_sfc.c   |  2 +-
 drivers/spi/spi-aspeed-smc.c | 28 
 drivers/spi/spi-mxic.c   |  6 +++---
 drivers/spi/spi-qup.c|  4 ++--
 drivers/spi/spi-sifive.c |  6 +++---
 drivers/spi/spi-sn-f-ospi.c  |  2 +-
 drivers/spi/spi-sunxi.c  |  6 +++---
 drivers/spi/spi-synquacer.c  |  4 ++--
 drivers/spi/spi-uclass.c | 23 +++-
 drivers/spi/stm32_qspi.c |  2 +-
 drivers/spi/stm32_spi.c  |  4 ++--
 drivers/spi/ti_qspi.c| 14 ++--
 drivers/spi/xilinx_spi.c |  4 ++--
 drivers/spi/zynq_qspi.c  |  6 +++---
 drivers/spi/zynq_spi.c   |  6 +++---
 include/spi.h|  8 ++-
 lib/acpi/acpi_device.c   |  2 +-
 41 files changed, 168 insertions(+), 149 deletions(-)

diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 4fe547171a..72036d5a88 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -139,7 +139,7 @@ static int sandbox_sf_probe(struct udevice *dev)
return ret;
}
slave_plat = dev_get_parent_plat(dev);
-   cs = slave_plat->cs;
+   cs = slave_plat->cs[0];
debug("found at cs %d\n", cs);
 
if (!pdata->filename) {
diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c
index 989679e881..48782f81c1 100644
--- a/drivers/spi/altera_spi.c
+++ b/drivers/spi/altera_spi.c
@@ -96,7 +96,7 @@ static int altera_spi_xfer(struct udevice *dev, unsigned int 
bitlen,
uint32_t reg, data, start;
 
debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
- dev_seq(bus), slave_plat->cs, bitlen, bytes, flags);
+ dev_seq(bus), slave_plat->cs[0], bitlen, bytes, flags);
 
if (bitlen == 0)
goto done;
@@ -111,7 +111,7 @@ static int altera_spi_xfer(struct udevice *dev, unsigned 
int bitlen,
readl(>rxdata);
 
if (flags & SPI_XFER_BEGIN)
-   spi_cs_activate(dev, slave_plat->cs);
+   spi_cs_activate(dev, slave_plat->cs[0]);
 
while (bytes--) {
if (txp)
diff --git a/drivers/spi/atcspi200_spi.c b/drivers/spi/atcspi200_spi.c
index de9c14837c..acee743653 100644
--- a/drivers/spi/atcspi200_spi.c
+++ b/drivers/spi/atcspi200_spi.c
@@ -321,7 +321,7 @@ static int atcspi200_spi_claim_bus(struct udevice *dev)
struct udevice *bus = dev->parent;
struct nds_spi_slave *ns = dev_get_priv(bus);
 
-   if (slave_plat->cs >= ns->num_cs) {
+   if (slave_plat->cs[0] >= ns->num_cs) {
printf("Invalid SPI chipselect\n");
return -EINVAL;
}
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
index 205567ef54..ad10cec2a6 100644
--- a/drivers/spi/ath79_spi.c
+++ b/drivers/spi/ath79_spi.c
@@ -74,7 +74,7 @@ static int ath79_spi_xfer(struct udevice *dev, unsigned int 
bitlen,
if (restbits)
bytes++;
 
-   out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs));
+   out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs[0]));
while (bytes > 0) {
bytes--;
curbyte = 0;
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index aec6f4eca9..e2de39d1ef 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -126,7 +126,7 @@ static int atmel_spi_claim_bus(struct udevice *dev)
struct atmel_spi_priv *priv = dev_get_priv(bus

[PATCH v6 2/6] mtd: spi-nor: Add parallel memories support for read_sr and read_fsr

2023-12-13 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Add support for parallel memories flash configuration in read status
register and read flag status register functions.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 50 --
 1 file changed, 36 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 1ebb7d5c15..30dd2764c9 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -438,8 +438,9 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, 
loff_t to, size_t len,
 }
 
 /*
- * Read the status register, returning its value in the location
- * Return the status register value.
+ * Return the status register value. If the chip is parallel, then the
+ * read will be striped, so we should read 2 bytes to get the sr
+ * register value from both of the parallel chips.
  * Returns negative if error occurred.
  */
 static int read_sr(struct spi_nor *nor)
@@ -471,18 +472,29 @@ static int read_sr(struct spi_nor *nor)
if (spi_nor_protocol_is_dtr(nor->reg_proto))
op.data.nbytes = 2;
 
-   ret = spi_nor_read_write_reg(nor, , val);
-   if (ret < 0) {
-   pr_debug("error %d reading SR\n", (int)ret);
-   return ret;
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   op.data.nbytes = 2;
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
+   val[0] |= val[1];
+   } else {
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
}
 
-   return *val;
+   return val[0];
 }
 
 /*
- * Read the flag status register, returning its value in the location
- * Return the status register value.
+ * Return the flag status register value. If the chip is parallel, then
+ * the read will be striped, so we should read 2 bytes to get the fsr
+ * register value from both of the parallel chips.
  * Returns negative if error occurred.
  */
 static int read_fsr(struct spi_nor *nor)
@@ -514,13 +526,23 @@ static int read_fsr(struct spi_nor *nor)
if (spi_nor_protocol_is_dtr(nor->reg_proto))
op.data.nbytes = 2;
 
-   ret = spi_nor_read_write_reg(nor, , val);
-   if (ret < 0) {
-   pr_debug("error %d reading FSR\n", ret);
-   return ret;
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   op.data.nbytes = 2;
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading SR\n", (int)ret);
+   return ret;
+   }
+   val[0] &= val[1];
+   } else {
+   ret = spi_nor_read_write_reg(nor, , [0]);
+   if (ret < 0) {
+   pr_debug("error %d reading FSR\n", ret);
+   return ret;
+   }
}
 
-   return *val;
+   return val[0];
 }
 
 /*
-- 
2.25.1



[PATCH v6 3/6] mtd: spi-nor: Add parallel and stacked memories support in read_bar and write_bar

2023-12-13 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

Add support for parallel memories and stacked memories configuration
in read_bar and write_bar functions.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 55 +-
 1 file changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 30dd2764c9..2c6a203f82 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -885,12 +885,32 @@ static int clean_bar(struct spi_nor *nor)
 
 static int write_bar(struct spi_nor *nor, u32 offset)
 {
-   u8 cmd, bank_sel;
+   u8 cmd, bank_sel, upage_curr;
int ret;
+   struct mtd_info *mtd = >mtd;
+
+   /* Wait until previous write command is finished */
+   if (spi_nor_wait_till_ready(nor))
+   return 1;
+
+   if (nor->flags & (SNOR_F_HAS_PARALLEL | SNOR_F_HAS_STACKED) &&
+   mtd->size <= SZ_32M)
+   return 0;
+
+   if (mtd->size <= SZ_16M)
+   return 0;
+
+   offset = offset % (u32)mtd->size;
+   bank_sel = offset >> 24;
 
-   bank_sel = offset / SZ_16M;
-   if (bank_sel == nor->bank_curr)
-   goto bar_end;
+   upage_curr = nor->spi->flags & SPI_XFER_U_PAGE;
+
+   if (!(nor->flags & SNOR_F_HAS_STACKED) && bank_sel == nor->bank_curr)
+   return 0;
+   else if (upage_curr == nor->upage_prev && bank_sel == nor->bank_curr)
+   return 0;
+
+   nor->upage_prev = upage_curr;
 
cmd = nor->bank_write_cmd;
write_enable(nor);
@@ -900,15 +920,19 @@ static int write_bar(struct spi_nor *nor, u32 offset)
return ret;
}
 
-bar_end:
nor->bank_curr = bank_sel;
-   return nor->bank_curr;
+
+   return write_disable(nor);
 }
 
 static int read_bar(struct spi_nor *nor, const struct flash_info *info)
 {
u8 curr_bank = 0;
int ret;
+   struct mtd_info *mtd = >mtd;
+
+   if (mtd->size <= SZ_16M)
+   return 0;
 
switch (JEDEC_MFR(info)) {
case SNOR_MFR_SPANSION:
@@ -920,15 +944,30 @@ static int read_bar(struct spi_nor *nor, const struct 
flash_info *info)
nor->bank_write_cmd = SPINOR_OP_WREAR;
}
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   nor->spi->flags |= SPI_XFER_LOWER;
+
ret = nor->read_reg(nor, nor->bank_read_cmd,
-   _bank, 1);
+   _bank, 1);
if (ret) {
debug("SF: fail to read bank addr register\n");
return ret;
}
nor->bank_curr = curr_bank;
 
-   return 0;
+   // Make sure both chips use the same BAR
+   if (nor->flags & SNOR_F_HAS_PARALLEL) {
+   write_enable(nor);
+   ret = nor->write_reg(nor, nor->bank_write_cmd, _bank, 1);
+   if (ret)
+   return ret;
+
+   ret = write_disable(nor);
+   if (ret)
+   return ret;
+   }
+
+   return ret;
 }
 #endif
 
-- 
2.25.1



[PATCH v6 1/6] mtd: spi-nor: Add parallel and stacked memories support

2023-12-13 Thread Venkatesh Yadav Abbarapu
From: Ashok Reddy Soma 

In parallel mode, the current implementation assumes that a maximum of
two flashes are connected. The QSPI controller splits the data evenly
between both the flashes so, both the flashes that are connected in
parallel mode should be identical.
During each operation SPI-NOR sets 0th bit for CS0 & 1st bit for CS1 in
nor->flags.

In stacked mode the current implementation assumes that a maximum of two
flashes are connected and both the flashes are of same make but can
differ in sizes. So, except the sizes all other flash parameters of both
the flashes are identical

Spi-nor will pass on the appropriate flash select flag to low level
driver, and it will select pass all the data to that particular flash.

Write operation in parallel mode are performed in page size * 2 chunks as
each write operation results in writing both the flashes. For doubling
the address space each operation is performed at addr/2 flash offset,
where addr is the address specified by the user.

Similarly for read and erase operations it will read from both flashes,
so size and offset are divided by 2 and send to flash.

Signed-off-by: Ashok Reddy Soma 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-core.c | 296 +
 include/linux/mtd/spi-nor.h|  12 ++
 include/spi.h  |  11 ++
 3 files changed, 291 insertions(+), 28 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 9a1801ba93..1ebb7d5c15 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -639,12 +639,17 @@ static u8 spi_nor_convert_3to4_erase(u8 opcode)
 static void spi_nor_set_4byte_opcodes(struct spi_nor *nor,
  const struct flash_info *info)
 {
+   bool shift = 0;
+
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   shift = 1;
+
/* Do some manufacturer fixups first */
switch (JEDEC_MFR(info)) {
case SNOR_MFR_SPANSION:
/* No small sector erase for 4-byte command set */
nor->erase_opcode = SPINOR_OP_SE;
-   nor->mtd.erasesize = info->sector_size;
+   nor->mtd.erasesize = info->sector_size << shift;
break;
 
default:
@@ -965,8 +970,8 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 
addr)
 static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
+   u32 addr, len, rem, offset;
bool addr_known = false;
-   u32 addr, len, rem;
int ret, err;
 
dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
@@ -991,6 +996,19 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
ret = -EINTR;
goto erase_err;
}
+
+   offset = addr;
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   offset /= 2;
+
+   if (nor->flags & SNOR_F_HAS_STACKED) {
+   if (offset >= (mtd->size / 2)) {
+   offset = offset - (mtd->size / 2);
+   nor->spi->flags |= SPI_XFER_U_PAGE;
+   } else {
+   nor->spi->flags &= ~SPI_XFER_U_PAGE;
+   }
+   }
 #ifdef CONFIG_SPI_FLASH_BAR
ret = write_bar(nor, addr);
if (ret < 0)
@@ -1396,6 +1414,9 @@ static const struct flash_info *spi_nor_read_id(struct 
spi_nor *nor)
u8  id[SPI_NOR_MAX_ID_LEN];
const struct flash_info *info;
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   nor->spi->flags |= SPI_XFER_LOWER;
+
tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
if (tmp < 0) {
dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp);
@@ -1420,28 +1441,62 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t 
from, size_t len,
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
int ret;
+   u32 offset = from;
+   u32 stack_shift = 0;
+   u32 read_len = 0;
+   u32 rem_bank_len = 0;
+   u8 bank;
+   u8 is_ofst_odd = 0;
 
dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
 
+   if ((nor->flags & SNOR_F_HAS_PARALLEL) && (offset & 1)) {
+   /* We can hit this case when we use file system like ubifs */
+   from = (loff_t)(from - 1);
+   len = (size_t)(len + 1);
+   is_ofst_odd = 1;
+   }
+
while (len) {
-   loff_t addr = from;
-   size_t read_len = len;
+   if (nor->addr_width == 3) {
+   if (nor->

[PATCH v6 0/6] spi-nor: Add parallel and stacked memories support

2023-12-13 Thread Venkatesh Yadav Abbarapu
This series adds support for Xilinx qspi parallel and stacked memeories.

In parallel mode, the current implementation assumes that a maximum of
two flashes are connected. The QSPI controller splits the data evenly
between both the flashes so, both the flashes that are connected in
parallel mode should be identical.
During each operation SPI-NOR sets 0th bit for CS0 & 1st bit for CS1 in
nor->flags.

In stacked mode the current implementation assumes that a maximum of two
flashes are connected and both the flashes are of same make but can differ
in sizes. So, except the sizes all other flash parameters of both the flashes
are identical.

Spi-nor will pass on the appropriate flash select flag to low level driver,
and it will select pass all the data to that particular flash.

Write operation in parallel mode are performed in page size * 2 chunks as each
write operation results in writing both the flashes. For doubling the address
space each operation is performed at addr/2 flash offset, where addr is the
address specified by the user.

Similarly for read and erase operations it will read from both flashes, so size
and offset are divided by 2 and send to flash.

Changes in v2:
- Fixed the compilation issues.
Changes in v3:
- Fixed the CI issues.
Changes in v4:
- Removed the dio,dummy_bytes variables from zynq_qspi driver.
- Fix the compilation issue by including the DM_SPI config.
Changes in v5:
- Fixed the issue reported by buildman.
Changes in v6:
- Fixed the issues reported while running the sandbox test cases.

Ashok Reddy Soma (4):
  mtd: spi-nor: Add parallel and stacked memories support
  mtd: spi-nor: Add parallel memories support for read_sr and read_fsr
  mtd: spi-nor: Add parallel and stacked memories support in read_bar
and write_bar
  spi: spi-uclass: Read chipselect and restrict capabilities

Venkatesh Yadav Abbarapu (2):
  spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver
  spi: zynq_qspi: Add parallel memories support in QSPI driver

 drivers/mtd/spi/sandbox.c  |   2 +-
 drivers/mtd/spi/spi-nor-core.c | 401 +
 drivers/spi/altera_spi.c   |   4 +-
 drivers/spi/atcspi200_spi.c|   2 +-
 drivers/spi/ath79_spi.c|   2 +-
 drivers/spi/atmel_spi.c|   6 +-
 drivers/spi/bcm63xx_hsspi.c|  42 ++--
 drivers/spi/bcm63xx_spi.c  |   6 +-
 drivers/spi/bcmbca_hsspi.c |  34 +--
 drivers/spi/cf_spi.c   |   6 +-
 drivers/spi/davinci_spi.c  |   6 +-
 drivers/spi/fsl_dspi.c |  18 +-
 drivers/spi/fsl_espi.c |   4 +-
 drivers/spi/fsl_qspi.c |   4 +-
 drivers/spi/gxp_spi.c  |   2 +-
 drivers/spi/mpc8xx_spi.c   |   4 +-
 drivers/spi/mpc8xxx_spi.c  |  10 +-
 drivers/spi/mscc_bb_spi.c  |   4 +-
 drivers/spi/mxc_spi.c  |   6 +-
 drivers/spi/npcm_fiu_spi.c |  14 +-
 drivers/spi/nxp_fspi.c |   2 +-
 drivers/spi/octeon_spi.c   |   2 +-
 drivers/spi/omap3_spi.c|   4 +-
 drivers/spi/pic32_spi.c|   2 +-
 drivers/spi/rk_spi.c   |   4 +-
 drivers/spi/rockchip_sfc.c |   2 +-
 drivers/spi/spi-aspeed-smc.c   |  28 +--
 drivers/spi/spi-mxic.c |   6 +-
 drivers/spi/spi-qup.c  |   4 +-
 drivers/spi/spi-sifive.c   |   6 +-
 drivers/spi/spi-sn-f-ospi.c|   2 +-
 drivers/spi/spi-sunxi.c|   6 +-
 drivers/spi/spi-synquacer.c|   4 +-
 drivers/spi/spi-uclass.c   |  23 +-
 drivers/spi/stm32_qspi.c   |   2 +-
 drivers/spi/stm32_spi.c|   4 +-
 drivers/spi/ti_qspi.c  |  14 +-
 drivers/spi/xilinx_spi.c   |   4 +-
 drivers/spi/zynq_qspi.c| 119 --
 drivers/spi/zynq_spi.c |   6 +-
 drivers/spi/zynqmp_gqspi.c | 141 ++--
 include/linux/mtd/spi-nor.h|  12 +
 include/spi.h  |  23 +-
 lib/acpi/acpi_device.c |   2 +-
 44 files changed, 773 insertions(+), 226 deletions(-)

-- 
2.25.1



  1   2   3   >