[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



[PATCH v2] mtd: spi-nor: Add IS25LP02G flash support

2023-12-04 Thread Venkatesh Yadav Abbarapu
Add support for ISSI 256MB flash IS25LP02G. This part supports 4byte
opcodes. It also supports dual and quad read.

Signed-off-by: Sreekanth Sunnam 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
Changes in v2:
- Fixed the name to Sreekanth Sunnam.
---
 drivers/mtd/spi/spi-nor-ids.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 3cb132dcff..9a73198227 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -217,6 +217,8 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("is25lp01g",  0x9d601b, 0, 64 * 1024, 2048,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+   { INFO("is25lp02g",  0x9d6022, 0, 64 * 1024, 4096,
+   SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("is25wp008", 0x9d7014, 0, 64 * 1024,  16, SPI_NOR_QUAD_READ) },
{ INFO("is25wp016", 0x9d7015, 0, 64 * 1024,  32, SPI_NOR_QUAD_READ) },
{ INFO("is25wp032",  0x9d7016, 0, 64 * 1024,  64,
-- 
2.17.1



[PATCH v2] clk: zynqmp: enable topsw_lsbus clock

2023-12-04 Thread Venkatesh Yadav Abbarapu
Display port is using topsw_lsbus clock, it is failing
while enabling the clock, so enable the topsw_lsbus clock.

Signed-off-by: Sreekanth Sunnam 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
Changes in v2:
- Fixed the name to Sreekanth Sunnam.
---
 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 1cfe0e25b1..c059b9e8e6 100644
--- a/drivers/clk/clk_zynqmp.c
+++ b/drivers/clk/clk_zynqmp.c
@@ -844,6 +844,7 @@ static int zynqmp_clk_enable(struct clk *clk)
break;
case qspi_ref ... can1_ref:
case lpd_lsbus:
+   case topsw_lsbus:
clkact_shift = 24;
mask = 0x1;
break;
-- 
2.17.1



[PATCH] mtd: spi-nor: Add IS25LP02G flash support

2023-12-03 Thread Venkatesh Yadav Abbarapu
Add support for ISSI 256MB flash IS25LP02G. This part supports 4byte
opcodes. It also supports dual and quad read.

Signed-off-by: sreekanth sunnam 
Signed-off-by: Venkatesh Yadav Abbarapu 
---
 drivers/mtd/spi/spi-nor-ids.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 3cb132dcff..9a73198227 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -217,6 +217,8 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("is25lp01g",  0x9d601b, 0, 64 * 1024, 2048,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+   { INFO("is25lp02g",  0x9d6022, 0, 64 * 1024, 4096,
+   SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("is25wp008", 0x9d7014, 0, 64 * 1024,  16, SPI_NOR_QUAD_READ) },
{ INFO("is25wp016", 0x9d7015, 0, 64 * 1024,  32, SPI_NOR_QUAD_READ) },
{ INFO("is25wp032",  0x9d7016, 0, 64 * 1024,  64,
-- 
2.17.1



[PATCH] clk: zynqmp: enable topsw_lsbus clock

2023-12-03 Thread Venkatesh Yadav Abbarapu
Display port is using topsw_lsbus clock, it is failing
while enabling the clock, so enable the topsw_lsbus clock.

Signed-off-by: sreekanth sunnam 
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 1cfe0e25b1..c059b9e8e6 100644
--- a/drivers/clk/clk_zynqmp.c
+++ b/drivers/clk/clk_zynqmp.c
@@ -844,6 +844,7 @@ static int zynqmp_clk_enable(struct clk *clk)
break;
case qspi_ref ... can1_ref:
case lpd_lsbus:
+   case topsw_lsbus:
clkact_shift = 24;
mask = 0x1;
break;
-- 
2.17.1



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

2023-11-30 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 v5 5/6] spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver

2023-11-30 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..20e9914ea2 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 = priv->max

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

2023-11-30 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 | 114 
 1 file changed, 103 insertions(+), 11 deletions(-)

diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c
index 069d2a77de..90c94b1393 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 v5 3/6] mtd: spi-nor: Add parallel and stacked memories support in read_bar and write_bar

2023-11-30 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 0e29b3020c..5c3ffc80eb 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;
+   else
+   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 v5 2/6] mtd: spi-nor: Add parallel memories support for read_sr and read_fsr

2023-11-30 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 4e2d8c8231..0e29b3020c 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 v5 1/6] mtd: spi-nor: Add parallel and stacked memories support

2023-11-30 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 | 285 +
 include/linux/mtd/spi-nor.h|  13 ++
 include/spi.h  |  12 ++
 3 files changed, 282 insertions(+), 28 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 9a1801ba93..4e2d8c8231 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,57 @@ 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);
 
-   while (len) {
-   loff_t addr = from;
-   size_t read_len = 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;
+   }
 
-#ifdef CONFIG_SPI_FLASH_BAR
-   u32 remain_len;
+   while (len) {
+   i

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

2023-11-30 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_SERIAL config.
Changes in v5:
- Fixed the issue reported by buildman.


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 | 390 -
 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| 120 --
 drivers/spi/zynq_spi.c |   6 +-
 drivers/spi/zynqmp_gqspi.c | 141 ++--
 include/linux/mtd/spi-nor.h|  13 ++
 include/spi.h  |  24 +-
 lib/acpi/acpi_device.c |   2 +-
 44 files changed, 765 insertions(+), 226 deletions(-)

-- 
2.25.1



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

2023-11-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|  2 +-
 lib/acpi/acpi_device.c   |  2 +-
 41 files changed, 162 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 v4 6/6] spi: zynq_qspi: Add parallel memories support in QSPI driver

2023-11-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 | 114 
 1 file changed, 103 insertions(+), 11 deletions(-)

diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c
index 069d2a77de..90c94b1393 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 v4 5/6] spi: zynqmp_gqspi: Add parallel memories support in GQSPI driver

2023-11-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 | 140 -
 include/spi.h  |  12 
 2 files changed, 136 insertions(+), 16 deletions(-)

diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c
index a323994fb2..7e90a989dd 100644
--- a/drivers/spi/zynqmp_gqspi.c
+++ b/drivers/spi/zynqmp_gqspi.c
@@ -1,6 +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 +26,8 @@
 #include 
 #include 
 #include 
+#include 
+#include "../mtd/spi/sf_internal.h"
 #include 
 
 #define GQSPI_GFIFO_STRT_MODE_MASK BIT(29)
@@ -88,6 +91,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 +189,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,9 +241,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,14 @@ 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 +400,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 = priv->max_hz;
 
   

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

2023-11-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 c1c9d007f9..d245d5e415 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;
+   else
+   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.17.1



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

2023-11-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 2f49ca3365..c1c9d007f9 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.17.1



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

2023-11-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 | 284 +
 include/linux/mtd/spi-nor.h|  13 ++
 include/spi.h  |  12 ++
 3 files changed, 281 insertions(+), 28 deletions(-)

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 9a1801ba93..2f49ca3365 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,57 @@ 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);
 
-   while (len) {
-   loff_t addr = from;
-   size_t read_len = 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;
+   }
 
-#ifdef CONFIG_SPI_FLASH_BAR
-   u32 remain_len;
+   while (len) {
+   i

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

2023-11-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_SERIAL config.

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 | 389 -
 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| 120 --
 drivers/spi/zynq_spi.c |   6 +-
 drivers/spi/zynqmp_gqspi.c | 140 ++--
 include/linux/mtd/spi-nor.h|  13 ++
 include/spi.h  |  26 ++-
 lib/acpi/acpi_device.c |   2 +-
 44 files changed, 765 insertions(+), 226 deletions(-)

-- 
2.17.1



[PATCH v3] arm64: zynqmp: Introduce kria SOM defconfig

2023-11-08 Thread Venkatesh Yadav Abbarapu
Enable the initial kria SOM specific configurations like pinctrl,
pinconf etc. Also add the environment file.

Signed-off-by: Venkatesh Yadav Abbarapu 
---
Changes in v2:
- Updated the CONFIG_ENV_OFFSET_REDUND
- Updated the CONFIG_SF_DEFAULT_SPEED to 3000
- Enabled the CONFIG_VIDEO_ZYNQMP_DPSUB
- Fixed minor changes in zynqmp_kria.env
Changes in v3:
- Updated the CONFIG_ENV_OFFSET
- Updated the CONFIG_SYS_SPI_U_BOOT_OFFS to 0x28
- Removed the CONFIG_ENV_SPI_MAX_HZ
---
 board/xilinx/zynqmp/zynqmp_kria.env  |  67 
 configs/xilinx_zynqmp_kria_defconfig | 227 +++
 2 files changed, 294 insertions(+)
 create mode 100644 board/xilinx/zynqmp/zynqmp_kria.env
 create mode 100644 configs/xilinx_zynqmp_kria_defconfig

diff --git a/board/xilinx/zynqmp/zynqmp_kria.env 
b/board/xilinx/zynqmp/zynqmp_kria.env
new file mode 100644
index 00..9140694d41
--- /dev/null
+++ b/board/xilinx/zynqmp/zynqmp_kria.env
@@ -0,0 +1,67 @@
+autoload=no
+baudrate=115200
+boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} 
${prefix}${script}; source ${scriptaddr}
+boot_efi_binary=if fdt addr ${fdt_addr_r}; then bootefi bootmgr 
${fdt_addr_r};else bootefi bootmgr ${fdtcontroladdr};fi;load ${devtype} 
${devnum}:${distro_bootpart} ${kernel_addr_r} efi/boot/bootaa64.efi; if fdt 
addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r};else bootefi 
${kernel_addr_r} ${fdtcontroladdr};fi
+boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any 
${scriptaddr} ${prefix}${boot_syslinux_conf}
+boot_net_usb_start=usb start
+boot_prefixes=/ /boot/
+boot_script_dhcp=boot.scr.uimg
+boot_scripts=boot.scr.uimg boot.scr
+boot_syslinux_conf=extlinux/extlinux.conf
+bootcmd_dhcp=run boot_net_usb_start; if dhcp ${scriptaddr} 
${boot_script_dhcp}; then source ${scriptaddr}; fi;setenv efi_fdtfile 
${fdtfile}; setenv efi_old_vci ${bootp_vci};setenv efi_old_arch 
${bootp_arch};setenv bootp_vci PXEClient:Arch:00011:UNDI:003000;setenv 
bootp_arch 0xb;if dhcp ${kernel_addr_r}; then tftpboot ${fdt_addr_r} 
dtb/${efi_fdtfile};if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} 
${fdt_addr_r}; else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi;fi;setenv 
bootp_vci ${efi_old_vci};setenv bootp_arch ${efi_old_arch};setenv 
efi_fdtfile;setenv efi_old_arch;setenv efi_old_vci;
+bootcmd_jtag=echo JTAG: Trying to boot script at ${scriptaddr} && source 
${scriptaddr}; echo JTAG: SCRIPT FAILED: continuing...;
+bootcmd_mmc0=devnum=0; run mmc_boot
+bootcmd_mmc1=devnum=1; run mmc_boot
+bootcmd_pxe=run boot_net_usb_start; dhcp; if pxe get; then pxe boot; fi
+bootcmd_usb0=devnum=0; run usb_boot
+bootcmd_usb1=devnum=1; run usb_boot
+bootcmd_usb2=devnum=2; run usb_boot
+bootcmd_usb3=devnum=3; run usb_boot
+bootdelay=2
+bootfstype=fat
+bootm_low=0
+bootm_size=0x8000
+distro_bootcmd=scsi_need_init=; for target in ${boot_targets}; do run 
bootcmd_${target}; done
+efi_dtb_prefixes=/ /dtb/ /dtb/current/
+fdt_addr_r=0x4000
+fdt_high=0x1000
+fileaddr=0x1800
+initrd_high=0x7900
+kernel_addr_r=0x1800
+load_efi_dtb=load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} 
${prefix}${efi_fdtfile}
+mmc_boot=if mmc dev ${devnum}; then devtype=mmc; run scan_dev_for_boot_part; fi
+pxefile_addr_r=0x1000
+ramdisk_addr_r=0x0210
+scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; 
for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run 
scan_dev_for_scripts; done;run scan_dev_for_efi;
+scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env 
exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if 
fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run 
scan_dev_for_boot; fi; done; setenv devplist
+scan_dev_for_efi=setenv efi_fdtfile ${fdtfile}; for prefix in 
${efi_dtb_prefixes}; do if test -e ${devtype} ${devnum}:${distro_bootpart} 
${prefix}${efi_fdtfile}; then run load_efi_dtb; fi;done;if test -e ${devtype} 
${devnum}:${distro_bootpart} efi/boot/bootaa64.efi; then echo Found EFI 
removable media binary efi/boot/bootaa64.efi; run boot_efi_binary; echo EFI 
LOAD FAILED: continuing...; fi; setenv efi_fdtfile
+scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} 
${prefix}${boot_syslinux_conf}; then echo Found ${prefix}${boot_syslinux_conf}; 
run boot_extlinux; echo SCRIPT FAILED: continuing...; fi
+scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} 
${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script 
${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; 
done
+script_offset_f=0x3e8
+script_size_f=0x8
+scriptaddr=0x2000
+usb_boot=usb start; if usb dev ${devnum}; then devtype=usb; run 
scan_dev_for_boot_part; fi
+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 mm

  1   2   3   >