RE: [PATCH] Add support for XMC XM25QH128C/XM25QH256C/XM25QU256C/XM25QH512C/XM25QU512C

2023-08-14 Thread Chin-Ting Kuo
> -Original Message-
> From: SSunk 
> Sent: Friday, August 11, 2023 4:20 PM
> Subject: [PATCH] Add support for XMC
> XM25QH128C/XM25QH256C/XM25QU256C/XM25QH512C/XM25QU512C
> 
> site: https://www.xmcwh.com/site/product
> 
> Signed-off-by: Kankan Sun 
> ---
>  configs/evb-ast2600_defconfig | 1 +
>  drivers/mtd/spi/spi-nor-ids.c | 4 
>  2 files changed, 5 insertions(+)
> 
> diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig
> index 9244654c82..f06c0e1fe1 100644
> --- a/configs/evb-ast2600_defconfig
> +++ b/configs/evb-ast2600_defconfig
> @@ -100,6 +100,7 @@ CONFIG_SPI_FLASH_SPANSION=y
> CONFIG_SPI_FLASH_STMICRO=y  CONFIG_SPI_FLASH_SST=y
> CONFIG_SPI_FLASH_WINBOND=y
> +CONFIG_SPI_FLASH_XMC=y
>  # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set  CONFIG_PHY_REALTEK=y
> CONFIG_PHY_NCSI=y diff --git a/drivers/mtd/spi/spi-nor-ids.c
> b/drivers/mtd/spi/spi-nor-ids.c index 4587215984..80d7678293 100644
> --- a/drivers/mtd/spi/spi-nor-ids.c
> +++ b/drivers/mtd/spi/spi-nor-ids.c
> @@ -531,6 +531,10 @@ const struct flash_info spi_nor_ids[] = {
>   { INFO("XM25QH64A", 0x207017, 0, 64 * 1024, 128, SECT_4K |
> SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>   { INFO("XM25QH64C", 0x204017, 0, 64 * 1024, 128, SECT_4K |
> SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>   { INFO("XM25QH128A", 0x207018, 0, 64 * 1024, 256, SECT_4K |
> SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> + { INFO("XM25QH256C", 0x204019, 0, 64 * 1024, 512, SECT_4K |
> SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
> + { INFO("XM25QU256C", 0x204119, 0, 64 * 1024, 512, SECT_4K |
> SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
> + { INFO("XM25QH512C", 0x204020, 0, 64 * 1024, 1024, SECT_4K |
> SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
> + { INFO("XM25QU512C", 0x204120, 0, 64 * 1024, 1024, SECT_4K |
> +SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
>  #endif
>  #ifdef CONFIG_SPI_FLASH_XTX
>   /* XTX Technology Limited */
> --
> 2.34.1

Reviewed-by: Chin-Ting Kuo 




[v5 10/14] configs: aspeed: Enable CONFIG_SPI_DIRMAP

2022-08-19 Thread Chin-Ting Kuo
Enable CONFIG_SPI_DIRMAP on ASPEED platforms.

Signed-off-by: Chin-Ting Kuo 
---
 configs/evb-ast2500_defconfig | 1 +
 configs/evb-ast2600_defconfig | 1 +
 2 files changed, 2 insertions(+)

diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index 5c157ca1d6..416ee66126 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -60,6 +60,7 @@ CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
+CONFIG_SPI_DIRMAP=y
 CONFIG_SPI_ASPEED_SMC=y
 CONFIG_SYSRESET=y
 CONFIG_TIMER=y
diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig
index 11678f914e..bf25efaa3e 100644
--- a/configs/evb-ast2600_defconfig
+++ b/configs/evb-ast2600_defconfig
@@ -111,6 +111,7 @@ CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
+CONFIG_SPI_DIRMAP=y
 CONFIG_SPI_ASPEED_SMC=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
-- 
2.25.1



[v5 12/14] spi: aspeed: Support customized decoded address ranges

2022-08-19 Thread Chin-Ting Kuo
If "decoded-ranges" is defined in the device tree, the
driver will apply the decoded address ranges from this
property to the controller during probe stage.

This patch refers to the following OpenBMC u-boot patch.
https://patchwork.ozlabs.org/project/openbmc/list/?series=306969

Signed-off-by: Chin-Ting Kuo 
---
 drivers/spi/spi-aspeed-smc.c | 136 ---
 1 file changed, 127 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
index 4287f5d8c0..2b6c4b48bd 100644
--- a/drivers/spi/spi-aspeed-smc.c
+++ b/drivers/spi/spi-aspeed-smc.c
@@ -74,6 +74,7 @@ struct aspeed_spi_priv {
struct aspeed_spi_regs *regs;
struct aspeed_spi_info *info;
struct aspeed_spi_flash flashes[ASPEED_SPI_MAX_CS];
+   bool fixed_decoded_range;
 };
 
 struct aspeed_spi_info {
@@ -87,7 +88,15 @@ struct aspeed_spi_info {
int (*adjust_decoded_sz)(struct udevice *bus);
 };
 
+struct aspeed_spi_decoded_range {
+   u32 cs;
+   u32 ahb_base;
+   u32 sz;
+};
+
 static const struct aspeed_spi_info ast2400_spi_info;
+static const struct aspeed_spi_info ast2500_fmc_info;
+static const struct aspeed_spi_info ast2500_spi_info;
 static int aspeed_spi_decoded_range_config(struct udevice *bus);
 static int aspeed_spi_trim_decoded_size(struct udevice *bus);
 
@@ -618,6 +627,9 @@ static void aspeed_spi_decoded_base_calculate(struct 
udevice *bus)
struct aspeed_spi_priv *priv = dev_get_priv(bus);
u32 cs;
 
+   if (priv->fixed_decoded_range)
+   return;
+
priv->flashes[0].ahb_base = plat->ahb_base;
 
for (cs = 1; cs < plat->max_cs; cs++) {
@@ -654,7 +666,8 @@ static int aspeed_spi_decoded_range_config(struct udevice 
*bus)
int ret = 0;
struct aspeed_spi_priv *priv = dev_get_priv(bus);
 
-   if (priv->info->adjust_decoded_sz) {
+   if (priv->info->adjust_decoded_sz &&
+   !priv->fixed_decoded_range) {
ret = priv->info->adjust_decoded_sz(bus);
if (ret != 0)
return ret;
@@ -666,6 +679,104 @@ static int aspeed_spi_decoded_range_config(struct udevice 
*bus)
return ret;
 }
 
+static int aspeed_spi_decoded_ranges_sanity(struct udevice *bus)
+{
+   struct aspeed_spi_plat *plat = dev_get_plat(bus);
+   struct aspeed_spi_priv *priv = dev_get_priv(bus);
+   u32 cs;
+   u32 total_sz = 0;
+
+   /* Check overall size. */
+   for (cs = 0; cs < plat->max_cs; cs++)
+   total_sz += priv->flashes[cs].ahb_decoded_sz;
+
+   if (total_sz > plat->ahb_sz) {
+   dev_err(bus, "invalid total size 0x%08x\n", total_sz);
+   return -EINVAL;
+   }
+
+   /* Check each decoded range size for AST2500. */
+   if (priv->info == _fmc_info ||
+   priv->info == _spi_info) {
+   for (cs = 0; cs < plat->max_cs; cs++) {
+   if (priv->flashes[cs].ahb_decoded_sz <
+   priv->info->min_decoded_sz) {
+   dev_err(bus, "insufficient decoded range.\n");
+   return -EINVAL;
+   }
+   }
+   }
+
+   /*
+* Check overlay. Here, we assume the deccded ranges and
+* address base are monotonic increasing with CE#.
+*/
+   for (cs = plat->max_cs - 1; cs > 0; cs--) {
+   if ((u32)priv->flashes[cs].ahb_base != 0 &&
+   (u32)priv->flashes[cs].ahb_base <
+   (u32)priv->flashes[cs - 1].ahb_base +
+   priv->flashes[cs - 1].ahb_decoded_sz) {
+   dev_err(bus, "decoded range overlay 0x%08x 0x%08x\n",
+   (u32)priv->flashes[cs].ahb_base,
+   (u32)priv->flashes[cs - 1].ahb_base);
+   return -EINVAL;
+   }
+   }
+
+   return 0;
+}
+
+static int aspeed_spi_read_fixed_decoded_ranges(struct udevice *bus)
+{
+   int ret = 0;
+   struct aspeed_spi_plat *plat = dev_get_plat(bus);
+   struct aspeed_spi_priv *priv = dev_get_priv(bus);
+   const char *range_prop = "decoded-ranges";
+   struct aspeed_spi_decoded_range ranges[ASPEED_SPI_MAX_CS];
+   const struct property *prop;
+   u32 prop_sz;
+   u32 count;
+   u32 i;
+
+   priv->fixed_decoded_range = false;
+
+   prop = dev_read_prop(bus, range_prop, _sz);
+   if (!prop)
+   return 0;
+
+   count = prop_sz / sizeof(struct aspeed_spi_decoded_range);
+   if (count > plat->max_cs || count < priv->num_cs) {
+   dev_err(bus, "invalid '%s' property %d %d\n",
+   range_prop, count, priv->num_cs);
+   

[v5 04/14] configs: aspeed: Enable SPI flash features

2022-08-19 Thread Chin-Ting Kuo
- Enable ASPEED SPI controller driver.
- Enable SPI flash memory configurations.
- Enable configurations for SPI flash manufacturers
  supported on both ASPEED AST2500 and AST2600 AVL.

Signed-off-by: Chin-Ting Kuo 
---
 configs/evb-ast2500_defconfig | 13 +
 configs/evb-ast2600_defconfig | 13 +
 2 files changed, 26 insertions(+)

diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index e7d93ec48b..5c157ca1d6 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -39,6 +39,16 @@ CONFIG_SYS_I2C_ASPEED=y
 CONFIG_I2C_EEPROM=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
 CONFIG_FTGMAC100=y
@@ -48,6 +58,9 @@ CONFIG_RAM=y
 CONFIG_DM_RESET=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_SPI_ASPEED_SMC=y
 CONFIG_SYSRESET=y
 CONFIG_TIMER=y
 CONFIG_WDT=y
diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig
index d07d3c41fe..11678f914e 100644
--- a/configs/evb-ast2600_defconfig
+++ b/configs/evb-ast2600_defconfig
@@ -87,6 +87,16 @@ CONFIG_SYS_I2C_ASPEED=y
 CONFIG_I2C_EEPROM=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
 CONFIG_DM_MDIO=y
@@ -99,6 +109,9 @@ CONFIG_SPL_RAM=y
 CONFIG_DM_RESET=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_SPI_ASPEED_SMC=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_WDT=y
-- 
2.25.1



[v5 09/14] spi: aspeed: SPI dirmap read support

2022-08-19 Thread Chin-Ting Kuo
>From the HW point of view, the performance of
command read mode is greater than user mode slightly.
Thus, dirmap read framework is introduced to achieve
this goal. In dirmap_create, command read mode is
configured. Usually, the decoded address area with flash
size is assigned to each CS. CPU can thus access the
SPI flash as normal memory in dirmap_read function.

Signed-off-by: Chin-Ting Kuo 
---
 drivers/spi/spi-aspeed-smc.c | 88 
 1 file changed, 88 insertions(+)

diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
index f858d36023..6099b85255 100644
--- a/drivers/spi/spi-aspeed-smc.c
+++ b/drivers/spi/spi-aspeed-smc.c
@@ -87,6 +87,7 @@ struct aspeed_spi_info {
 };
 
 static const struct aspeed_spi_info ast2400_spi_info;
+static int aspeed_spi_decoded_range_config(struct udevice *bus);
 
 static u32 aspeed_spi_get_io_mode(u32 bus_width)
 {
@@ -381,6 +382,91 @@ static int aspeed_spi_exec_op_user_mode(struct spi_slave 
*slave,
return 0;
 }
 
+static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
+{
+   int ret = 0;
+   struct udevice *dev = desc->slave->dev;
+   struct udevice *bus = dev->parent;
+   struct aspeed_spi_priv *priv = dev_get_priv(bus);
+   struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
+   const struct aspeed_spi_info *info = priv->info;
+   struct spi_mem_op op_tmpl = desc->info.op_tmpl;
+   u32 i;
+   u32 cs = slave_plat->cs;
+   u32 reg_val;
+   u32 ce_ctrl_reg;
+
+   if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT) {
+   /*
+* dirmap_write is not supported currently due to a HW
+* limitation for command write mode: The written data
+* length should be multiple of 4-byte.
+*/
+   return -EOPNOTSUPP;
+   }
+
+   ce_ctrl_reg = (u32)>regs->ce_ctrl[cs];
+   if (info == _spi_info)
+   ce_ctrl_reg = (u32)>regs->ctrl;
+
+   if (desc->info.length > 0x100)
+   priv->info->set_4byte(bus, cs);
+
+   /* AST2400 SPI1 doesn't have decoded address segment register. */
+   if (info != _spi_info) {
+   priv->flashes[cs].ahb_decoded_sz = desc->info.length;
+
+   for (i = 0; i < priv->num_cs; i++) {
+   dev_dbg(dev, "cs: %d, sz: 0x%x\n", i,
+   priv->flashes[cs].ahb_decoded_sz);
+   }
+
+   ret = aspeed_spi_decoded_range_config(bus);
+   if (ret)
+   return ret;
+   }
+
+   reg_val = aspeed_spi_get_io_mode(op_tmpl.data.buswidth) |
+ op_tmpl.cmd.opcode << 16 |
+ ((op_tmpl.dummy.nbytes) & 0x3) << 6 |
+ ((op_tmpl.dummy.nbytes) & 0x4) << 14 |
+ CTRL_IO_MODE_CMD_READ;
+
+   writel(reg_val, ce_ctrl_reg);
+
+   priv->flashes[cs].ce_ctrl_read = reg_val;
+
+   dev_dbg(dev, "read bus width: %d ce_ctrl_val: 0x%08x\n",
+   op_tmpl.data.buswidth, priv->flashes[cs].ce_ctrl_read);
+
+   return ret;
+}
+
+static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ u64 offs, size_t len, void *buf)
+{
+   struct udevice *dev = desc->slave->dev;
+   struct aspeed_spi_priv *priv = dev_get_priv(dev->parent);
+   struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
+   u32 cs = slave_plat->cs;
+   int ret;
+
+   dev_dbg(dev, "read op:0x%x, addr:0x%llx, len:0x%x\n",
+   desc->info.op_tmpl.cmd.opcode, offs, len);
+
+   if (priv->flashes[cs].ahb_decoded_sz < offs + len ||
+   (offs % 4) != 0) {
+   ret = aspeed_spi_exec_op_user_mode(desc->slave,
+  >info.op_tmpl);
+   if (ret != 0)
+   return 0;
+   } else {
+   memcpy_fromio(buf, priv->flashes[cs].ahb_base + offs, len);
+   }
+
+   return len;
+}
+
 static struct aspeed_spi_flash *aspeed_spi_get_flash(struct udevice *dev)
 {
struct udevice *bus = dev->parent;
@@ -662,6 +748,8 @@ static int aspeed_spi_probe(struct udevice *bus)
 static const struct spi_controller_mem_ops aspeed_spi_mem_ops = {
.supports_op = aspeed_spi_supports_op,
.exec_op = aspeed_spi_exec_op_user_mode,
+   .dirmap_create = aspeed_spi_dirmap_create,
+   .dirmap_read = aspeed_spi_dirmap_read,
 };
 
 static const struct dm_spi_ops aspeed_spi_ops = {
-- 
2.25.1



[v5 03/14] spi: aspeed: Add ASPEED SPI controller driver

2022-08-19 Thread Chin-Ting Kuo
Add ASPEED BMC FMC/SPI memory controller driver with
spi-mem interface for AST2500 and AST2600 platform.

There are three SPI memory controllers embedded in an ASPEED SoC.
- FMC: Named as Firmware Memory Controller. After AC on, MCU ROM
   fetches initial device boot image from FMC chip select(CS) 0.

- SPI1: Play the role of a SPI Master controller. Or, there is a
dedicated path for HOST(X86) to access its BIOS flash mounted
under BMC. spi-aspeed-smc.c implements the control sequence when
SPI1 is a SPI master.

- SPI2: It is a pure SPI flash controller. For most scenarios, flashes
mounted under it are for pure storage purpose.

ASPEED SPI controller supports 1-1-1, 1-1-2 and 1-1-4 SPI flash mode.
Three types of command mode are supported, normal mode, command
read/write mode and user mode.
- Normal mode: Default mode. After power on, normal read command 03h or
   13h is used to fetch boot image from SPI flash.
   - AST2500: Only 03h command can be used after power on
  or reset.
   - AST2600: If FMC04[6:4] is set, 13h command is used,
  otherwise, 03h command.
   The address length is decided by FMC04[2:0].

- Command mode: SPI controller can send command and address
automatically when CPU read/write the related remapped
or decoded address area. The command used by this mode
can be configured by FMC10/14/18[23:16]. Also, the
address length is decided by FMC04[2:0]. This mode will
be implemented in the following patch series.

- User mode: It is a traditional and pure SPI operation, where
 SPI transmission is controlled by CPU. It is the main
 mode in this patch.

Each SPI controller in ASPEED SoC has its own decoded address mapping.
Within each SPI controller decoded address, driver can assign a specific
address region for each CS of a SPI controller. The decoded address
cannot overlap to each other. With normal mode and command mode, the
decoded address accessed by the CPU determines which CS is active.
When user mode is adopted, the CS decoded address is a FIFO, CPU can
send/receive any SPI transmission by accessing the related decoded
address for the target CS.

This patch only implements user mode initially. Command read/write
mode will be implemented in the following patches.

Signed-off-by: Chin-Ting Kuo 
---
v2: Remove defconfig files from this patch.
v5: Separate main ASPEED SPI driver patch into different parts,
basic support, decoded range adjustment and clock settings.
Besides, "struct aspeed_spi_regs" is added to define the
layout of the controller registers.

 MAINTAINERS  |   7 +
 drivers/spi/Kconfig  |   8 +
 drivers/spi/Makefile |   1 +
 drivers/spi/spi-aspeed-smc.c | 603 +++
 4 files changed, 619 insertions(+)
 create mode 100644 drivers/spi/spi-aspeed-smc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4d1930f76e..eba472935a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -724,6 +724,13 @@ S: Maintained
 F: drivers/pci/pcie_phytium.c
 F: arch/arm/dts/phytium-durian.dts
 
+ASPEED FMC SPI DRIVER
+M: Chin-Ting Kuo 
+M: Cédric Le Goater 
+R: Aspeed BMC SW team 
+S: Maintained
+F: drivers/spi/spi-aspeed-smc.c
+
 BINMAN
 M: Simon Glass 
 M: Alper Nebi Yasak 
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 75b794548b..8ca9274ef4 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -401,6 +401,14 @@ config SANDBOX_SPI
};
  };
 
+config SPI_ASPEED_SMC
+   bool "ASPEED SPI flash controller driver"
+   depends on DM_SPI && SPI_MEM
+   default n
+   help
+ Enable ASPEED SPI flash controller driver for AST2500
+ and AST2600 SoCs.
+
 config SPI_SIFIVE
bool "SiFive SPI driver"
help
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 4de77c260a..7ba953d2df 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o 
cadence_qspi_apb.o
 obj-$(CONFIG_CADENCE_OSPI_VERSAL) += cadence_ospi_versal.o
 obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o
 obj-$(CONFIG_SOFT_SPI) += soft_spi.o
+obj-$(CONFIG_SPI_ASPEED_SMC) += spi-aspeed-smc.o
 obj-$(CONFIG_SPI_MEM) += spi-mem.o
 obj-$(CONFIG_TI_QSPI) += ti_qspi.o
 obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o
diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
new file mode 100644
index 00..25b490bcf4
--- /dev/null
+++ b/drivers/spi/spi-aspeed-smc.c
@@ -0,0 +1,603 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * ASPEED FMC/SPI Controller driver
+ *
+ * Copyright (c) 2022 ASPEED Corporation.
+ * Copyright (c) 2022 IBM Corporation.
+ *
+ * Author:
+ * Chin-Ting Kuo 
+ * Cedric Le Goater 
+ */
+
+#in

[v5 11/14] spi: aspeed: Adjust decoded range size support

2022-08-19 Thread Chin-Ting Kuo
There are some known HW problems about decoded
range register configurations on existing AST2500 and
AST2600 platforms. Additional callback function,
adjust_decoded_sz, is added to solve these problems
on each platform. Besides, aspeed_spi_trim_decoded_size
function is added to modify overall decoded address
size for fitting the maximum AHB decoded size.

Signed-off-by: Chin-Ting Kuo 
---
 drivers/spi/spi-aspeed-smc.c | 144 ++-
 1 file changed, 143 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
index 6099b85255..4287f5d8c0 100644
--- a/drivers/spi/spi-aspeed-smc.c
+++ b/drivers/spi/spi-aspeed-smc.c
@@ -84,10 +84,12 @@ struct aspeed_spi_info {
u32 (*segment_start)(struct udevice *bus, u32 reg);
u32 (*segment_end)(struct udevice *bus, u32 reg);
u32 (*segment_reg)(u32 start, u32 end);
+   int (*adjust_decoded_sz)(struct udevice *bus);
 };
 
 static const struct aspeed_spi_info ast2400_spi_info;
 static int aspeed_spi_decoded_range_config(struct udevice *bus);
+static int aspeed_spi_trim_decoded_size(struct udevice *bus);
 
 static u32 aspeed_spi_get_io_mode(u32 bus_width)
 {
@@ -195,6 +197,53 @@ static void ast2500_spi_chip_set_4byte(struct udevice 
*bus, u32 cs)
writel(reg_val, >regs->ctrl);
 }
 
+/*
+ * For AST2500, the minimum address decoded size for each CS
+ * is 8MB instead of zero. This address decoded size is
+ * mandatory for each CS no matter whether it will be used.
+ * This is a HW limitation.
+ */
+static int ast2500_adjust_decoded_size(struct udevice *bus)
+{
+   struct aspeed_spi_plat *plat = dev_get_plat(bus);
+   struct aspeed_spi_priv *priv = dev_get_priv(bus);
+   struct aspeed_spi_flash *flashes = >flashes[0];
+   int ret;
+   int i;
+   int cs;
+   u32 pre_sz;
+   u32 lack_sz;
+
+   /* Assign min_decoded_sz to unused CS. */
+   for (cs = priv->num_cs; cs < plat->max_cs; cs++)
+   flashes[cs].ahb_decoded_sz = priv->info->min_decoded_sz;
+
+   /*
+* If commnad mode or normal mode is used, the start address of a
+* decoded range should be multiple of its related flash size.
+* Namely, the total decoded size from flash 0 to flash N should
+* be multiple of the size of flash (N + 1).
+*/
+   for (cs = priv->num_cs - 1; cs >= 0; cs--) {
+   pre_sz = 0;
+   for (i = 0; i < cs; i++)
+   pre_sz += flashes[i].ahb_decoded_sz;
+
+   if (flashes[cs].ahb_decoded_sz != 0 &&
+   (pre_sz % flashes[cs].ahb_decoded_sz) != 0) {
+   lack_sz = flashes[cs].ahb_decoded_sz -
+ (pre_sz % flashes[cs].ahb_decoded_sz);
+   flashes[0].ahb_decoded_sz += lack_sz;
+   }
+   }
+
+   ret = aspeed_spi_trim_decoded_size(bus);
+   if (ret != 0)
+   return ret;
+
+   return 0;
+}
+
 static u32 ast2600_spi_segment_start(struct udevice *bus, u32 reg)
 {
struct aspeed_spi_plat *plat = dev_get_plat(bus);
@@ -236,6 +285,86 @@ static void ast2600_spi_chip_set_4byte(struct udevice 
*bus, u32 cs)
writel(reg_val, >regs->ctrl);
 }
 
+static int ast2600_adjust_decoded_size(struct udevice *bus)
+{
+   struct aspeed_spi_plat *plat = dev_get_plat(bus);
+   struct aspeed_spi_priv *priv = dev_get_priv(bus);
+   struct aspeed_spi_flash *flashes = >flashes[0];
+   int ret;
+   int i;
+   int cs;
+   u32 pre_sz;
+   u32 lack_sz;
+
+   /* Close unused CS. */
+   for (cs = priv->num_cs; cs < plat->max_cs; cs++)
+   flashes[cs].ahb_decoded_sz = 0;
+
+   /*
+* If commnad mode or normal mode is used, the start address of a
+* decoded range should be multiple of its related flash size.
+* Namely, the total decoded size from flash 0 to flash N should
+* be multiple of the size of flash (N + 1).
+*/
+   for (cs = priv->num_cs - 1; cs >= 0; cs--) {
+   pre_sz = 0;
+   for (i = 0; i < cs; i++)
+   pre_sz += flashes[i].ahb_decoded_sz;
+
+   if (flashes[cs].ahb_decoded_sz != 0 &&
+   (pre_sz % flashes[cs].ahb_decoded_sz) != 0) {
+   lack_sz = flashes[cs].ahb_decoded_sz -
+ (pre_sz % flashes[cs].ahb_decoded_sz);
+   flashes[0].ahb_decoded_sz += lack_sz;
+   }
+   }
+
+   ret = aspeed_spi_trim_decoded_size(bus);
+   if (ret != 0)
+   return ret;
+
+   return 0;
+}
+
+/*
+ * As the flash size grows up, we need to trim some decoded
+ * size if needed for the sake of conforming the maximum
+ * decoded size. We trim the decoded size from the largest
+ * CS in order to avoid affecting the def

[v5 13/14] spi: aspeed: Clock frequency adjustment support

2022-08-19 Thread Chin-Ting Kuo
Driver can configure the SPI clock frequnecy to the
target value of "spi-max-frequency" property in
the device tree. The frequency is divided from HCLK,
200MHz. Usually, the ASPEED SPI clock frequency range
is between 12.5MHz and 100MHz. On AST2600, the lowest
SPI clock frequency can be about 780kHz.

Signed-off-by: Chin-Ting Kuo 
---
 drivers/spi/spi-aspeed-smc.c | 196 +--
 1 file changed, 186 insertions(+), 10 deletions(-)

diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
index 2b6c4b48bd..a3c9633382 100644
--- a/drivers/spi/spi-aspeed-smc.c
+++ b/drivers/spi/spi-aspeed-smc.c
@@ -60,6 +60,7 @@ struct aspeed_spi_plat {
u8 max_cs;
void __iomem *ahb_base; /* AHB address base for all flash devices. */
fdt_size_t ahb_sz; /* Overall AHB window size for all flash device. */
+   u32 hclk_rate; /* AHB clock rate */
 };
 
 struct aspeed_spi_flash {
@@ -67,6 +68,7 @@ struct aspeed_spi_flash {
u32 ahb_decoded_sz;
u32 ce_ctrl_user;
u32 ce_ctrl_read;
+   u32 max_freq;
 };
 
 struct aspeed_spi_priv {
@@ -81,11 +83,13 @@ struct aspeed_spi_info {
u32 io_mode_mask;
u32 max_bus_width;
u32 min_decoded_sz;
+   u32 clk_ctrl_mask;
void (*set_4byte)(struct udevice *bus, u32 cs);
u32 (*segment_start)(struct udevice *bus, u32 reg);
u32 (*segment_end)(struct udevice *bus, u32 reg);
u32 (*segment_reg)(u32 start, u32 end);
int (*adjust_decoded_sz)(struct udevice *bus);
+   u32 (*get_clk_setting)(struct udevice *dev, uint hz);
 };
 
 struct aspeed_spi_decoded_range {
@@ -165,6 +169,44 @@ static void ast2400_spi_chip_set_4byte(struct udevice 
*bus, u32 cs)
writel(flash->ce_ctrl_read, >regs->ctrl);
 }
 
+/* Transfer maximum clock frequency to register setting */
+static u32 ast2400_get_clk_setting(struct udevice *dev, uint max_hz)
+{
+   struct aspeed_spi_plat *plat = dev_get_plat(dev->parent);
+   struct aspeed_spi_priv *priv = dev_get_priv(dev->parent);
+   struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
+   u32 hclk_clk = plat->hclk_rate;
+   u32 hclk_div = 0x; /* default value */
+   u32 i;
+   bool found = false;
+   /* HCLK/1 ..HCLK/16 */
+   u32 hclk_masks[] = {15, 7, 14, 6, 13, 5, 12, 4,
+   11, 3, 10, 2, 9,  1, 8,  0};
+
+   /* FMC/SPIR10[11:8] */
+   for (i = 0; i < ARRAY_SIZE(hclk_masks); i++) {
+   if (hclk_clk / (i + 1) <= max_hz) {
+   found = true;
+   break;
+   }
+   }
+
+   if (found) {
+   hclk_div = hclk_masks[i] << 8;
+   priv->flashes[slave_plat->cs].max_freq = hclk_clk / (i + 1);
+   }
+
+   dev_dbg(dev, "found: %s, hclk: %d, max_clk: %d\n", found ? "yes" : "no",
+   hclk_clk, max_hz);
+
+   if (found) {
+   dev_dbg(dev, "h_div: %d (mask %x), speed: %d\n",
+   i + 1, hclk_masks[i], 
priv->flashes[slave_plat->cs].max_freq);
+   }
+
+   return hclk_div;
+}
+
 static u32 ast2500_spi_segment_start(struct udevice *bus, u32 reg)
 {
struct aspeed_spi_plat *plat = dev_get_plat(bus);
@@ -253,6 +295,58 @@ static int ast2500_adjust_decoded_size(struct udevice *bus)
return 0;
 }
 
+static u32 ast2500_get_clk_setting(struct udevice *dev, uint max_hz)
+{
+   struct aspeed_spi_plat *plat = dev_get_plat(dev->parent);
+   struct aspeed_spi_priv *priv = dev_get_priv(dev->parent);
+   struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
+   u32 hclk_clk = plat->hclk_rate;
+   u32 hclk_div = 0x; /* default value */
+   u32 i;
+   bool found = false;
+   /* HCLK/1 ..HCLK/16 */
+   u32 hclk_masks[] = {15, 7, 14, 6, 13, 5, 12, 4,
+   11, 3, 10, 2, 9,  1, 8,  0};
+
+   /* FMC/SPIR10[11:8] */
+   for (i = 0; i < ARRAY_SIZE(hclk_masks); i++) {
+   if (hclk_clk / (i + 1) <= max_hz) {
+   found = true;
+   priv->flashes[slave_plat->cs].max_freq =
+   hclk_clk / (i + 1);
+   break;
+   }
+   }
+
+   if (found) {
+   hclk_div = hclk_masks[i] << 8;
+   goto end;
+   }
+
+   for (i = 0; i < ARRAY_SIZE(hclk_masks); i++) {
+   if (hclk_clk / ((i + 1) * 4) <= max_hz) {
+   found = true;
+   priv->flashes[slave_plat->cs].max_freq =
+   hclk_clk / ((i + 1) * 4);
+   break;
+   }
+   }
+
+   if (found)
+   hclk_div = BIT(13) | (hclk_masks[i] << 8);
+
+end

[v5 01/14] clk: aspeed: Get HCLK frequency support

2022-08-19 Thread Chin-Ting Kuo
User can get correct HCLK frequency during driver probe stage
by adding the following configuration in the device tree.
"clocks = < ASPEED_CLK_AHB>".

Signed-off-by: Chin-Ting Kuo 
Reviewed-by: Cédric Le Goater 
---
 drivers/clk/aspeed/clk_ast2500.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
index 623c6915b8..dc446ce9fb 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -30,6 +30,12 @@
 
 #define D2PLL_DEFAULT_RATE (250 * 1000 * 1000)
 
+/*
+ * AXI/AHB clock selection, taken from Aspeed SDK
+ */
+#define SCU_HWSTRAP_AXIAHB_DIV_SHIFT9
+#define SCU_HWSTRAP_AXIAHB_DIV_MASK (0x7 << SCU_HWSTRAP_AXIAHB_DIV_SHIFT)
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -86,6 +92,20 @@ static ulong ast2500_get_clkin(struct ast2500_scu *scu)
? 25 * 1000 * 1000 : 24 * 1000 * 1000;
 }
 
+static u32 ast2500_get_hclk(ulong clkin, struct ast2500_scu *scu)
+{
+   u32 hpll_reg = readl(>h_pll_param);
+   ulong axi_div = 2;
+   u32 rate;
+   ulong ahb_div = 1 + ((readl(>hwstrap)
+ & SCU_HWSTRAP_AXIAHB_DIV_MASK)
+>> SCU_HWSTRAP_AXIAHB_DIV_SHIFT);
+
+   rate = ast2500_get_hpll_rate(clkin, hpll_reg);
+
+   return (rate / axi_div / ahb_div);
+}
+
 /**
  * Get current rate or uart clock
  *
@@ -147,6 +167,9 @@ static ulong ast2500_clk_get_rate(struct clk *clk)
rate = rate / apb_div;
}
break;
+   case ASPEED_CLK_AHB:
+   rate = ast2500_get_hclk(clkin, priv->scu);
+   break;
case ASPEED_CLK_SDIO:
{
ulong apb_div = 4 + 4 * ((readl(>scu->clk_sel1)
-- 
2.25.1



[v5 05/14] spi: aspeed: Support AST2400 platform

2022-08-19 Thread Chin-Ting Kuo
Although AST2400 is EOL officially, in order to achieve
sustainability and completeness, AST2400 part is added.

For AST2400,
- Five CSs are supported by FMC controller.
- SPI1 controller only supports single CS and there is
  no address segment address register. The CE control
  register of SPI1 is located at the offset 0x04 and
  the 4-byte address mode control bit is bit 13 of
  this register.

Signed-off-by: Chin-Ting Kuo 
---
 drivers/spi/spi-aspeed-smc.c | 105 ---
 1 file changed, 98 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
index 25b490bcf4..f858d36023 100644
--- a/drivers/spi/spi-aspeed-smc.c
+++ b/drivers/spi/spi-aspeed-smc.c
@@ -26,7 +26,7 @@
 #include 
 #include 
 
-#define ASPEED_SPI_MAX_CS   3
+#define ASPEED_SPI_MAX_CS   5
 
 #define CTRL_IO_SINGLE_DATA 0
 #define CTRL_IO_QUAD_DATA   BIT(30)
@@ -42,10 +42,10 @@ struct aspeed_spi_regs {
u32 ctrl;   /* 0x04 CE Control */
u32 intr_ctrl;  /* 0x08 Interrupt Control and Status */
u32 cmd_ctrl;   /* 0x0c Command Control */
-   u32 ce_ctrl[ASPEED_SPI_MAX_CS]; /* 0x10 .. 0x18 CEx Control */
-   u32 _reserved0[5];  /* .. */
-   u32 segment_addr[ASPEED_SPI_MAX_CS]; /* 0x30 .. 0x38 Segment Address */
-   u32 _reserved1[5];  /* .. */
+   u32 ce_ctrl[ASPEED_SPI_MAX_CS]; /* 0x10 .. 0x20 CEx Control */
+   u32 _reserved0[3];  /* .. */
+   u32 segment_addr[ASPEED_SPI_MAX_CS]; /* 0x30 .. 0x40 Segment Address */
+   u32 _reserved1[3];  /* .. */
u32 soft_rst_cmd_ctrl;  /* 0x50 Auto Soft-Reset Command Control 
*/
u32 _reserved2[11]; /* .. */
u32 dma_ctrl;   /* 0x80 DMA Control/Status */
@@ -86,6 +86,8 @@ struct aspeed_spi_info {
u32 (*segment_reg)(u32 start, u32 end);
 };
 
+static const struct aspeed_spi_info ast2400_spi_info;
+
 static u32 aspeed_spi_get_io_mode(u32 bus_width)
 {
switch (bus_width) {
@@ -101,6 +103,56 @@ static u32 aspeed_spi_get_io_mode(u32 bus_width)
}
 }
 
+static u32 ast2400_spi_segment_start(struct udevice *bus, u32 reg)
+{
+   struct aspeed_spi_plat *plat = dev_get_plat(bus);
+   u32 start_offset = ((reg >> 16) & 0xff) << 23;
+
+   if (start_offset == 0)
+   return (u32)plat->ahb_base;
+
+   return (u32)plat->ahb_base + start_offset;
+}
+
+static u32 ast2400_spi_segment_end(struct udevice *bus, u32 reg)
+{
+   struct aspeed_spi_plat *plat = dev_get_plat(bus);
+   u32 end_offset = ((reg >> 24) & 0xff) << 23;
+
+   /* Meaningless end_offset, set to physical ahb base. */
+   if (end_offset == 0)
+   return (u32)plat->ahb_base;
+
+   return (u32)plat->ahb_base + end_offset;
+}
+
+static u32 ast2400_spi_segment_reg(u32 start, u32 end)
+{
+   if (start == end)
+   return 0;
+
+   return start) >> 23) & 0xff) << 16) | end) >> 23) & 0xff) << 
24);
+}
+
+static void ast2400_fmc_chip_set_4byte(struct udevice *bus, u32 cs)
+{
+   struct aspeed_spi_priv *priv = dev_get_priv(bus);
+   u32 reg_val;
+
+   reg_val = readl(>regs->ctrl);
+   reg_val |= 0x1 << cs;
+   writel(reg_val, >regs->ctrl);
+}
+
+static void ast2400_spi_chip_set_4byte(struct udevice *bus, u32 cs)
+{
+   struct aspeed_spi_priv *priv = dev_get_priv(bus);
+   struct aspeed_spi_flash *flash = >flashes[cs];
+
+   flash->ce_ctrl_read |= BIT(13);
+   writel(flash->ce_ctrl_read, >regs->ctrl);
+}
+
 static u32 ast2500_spi_segment_start(struct udevice *bus, u32 reg)
 {
struct aspeed_spi_plat *plat = dev_get_plat(bus);
@@ -272,6 +324,9 @@ static int aspeed_spi_exec_op_user_mode(struct spi_slave 
*slave,
op->addr.buswidth, op->dummy.nbytes, op->dummy.buswidth,
op->data.nbytes, op->data.buswidth);
 
+   if (priv->info == _spi_info)
+   ce_ctrl_reg = (u32)>regs->ctrl;
+
/*
 * Set controller to 4-byte address mode
 * if flash is in 4-byte address mode.
@@ -404,8 +459,12 @@ static int aspeed_spi_ctrl_init(struct udevice *bus)
 
/* Enable write capability for all CS. */
reg_val = readl(>regs->conf);
-   writel(reg_val | (GENMASK(plat->max_cs - 1, 0) << 16),
-  >regs->conf);
+   if (priv->info == _spi_info) {
+   writel(reg_val | BIT(0), >regs->conf);
+   } else {
+   writel(reg_val | (GENMASK(plat->max_cs - 1, 0) << 16),
+  >regs->conf);
+   }
 
memset(priv->flashes, 0x0,
   sizeof(struct aspeed_spi_flash) * ASPEED_SPI_MAX_CS);
@@ -416,6 +475,16 @@ static int 

[v5 08/14] mtd: spi-nor: Use spi-mem dirmap API

2022-08-19 Thread Chin-Ting Kuo
This adds support for the dirmap API to the spi-nor subsystem, as
introduced in Linux commit df5c21002cf4  ("mtd: spi-nor: use
spi-mem dirmap API").

This patch is synchronize from the following patch
https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504-4-sean...@gmail.com/
The corresponding Linux kernel SHA1 is df5c21002cf4.

Signed-off-by: Chin-Ting Kuo 
Signed-off-by: Sean Anderson 
Acked-by: Pratyush Yadav 
---
v2: Use "if (CONFIG_IS_ENABLED(SPI_DIRMAP))" to wrap
spi_dirmap related functions.

 drivers/mtd/spi/sf_probe.c | 76 ++
 drivers/mtd/spi/spi-nor-core.c | 55 +---
 include/linux/mtd/spi-nor.h| 18 
 3 files changed, 133 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index f461082e03..e192f97efd 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -10,13 +10,69 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include "sf_internal.h"
 
+static int spi_nor_create_read_dirmap(struct spi_nor *nor)
+{
+   struct spi_mem_dirmap_info info = {
+   .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),
+ SPI_MEM_OP_ADDR(nor->addr_width, 0, 0),
+ SPI_MEM_OP_DUMMY(nor->read_dummy, 0),
+ SPI_MEM_OP_DATA_IN(0, NULL, 0)),
+   .offset = 0,
+   .length = nor->mtd.size,
+   };
+   struct spi_mem_op *op = _tmpl;
+
+   /* get transfer protocols. */
+   spi_nor_setup_op(nor, op, nor->read_proto);
+   op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto);
+
+   /* convert the dummy cycles to the number of bytes */
+   op->dummy.nbytes = (nor->read_dummy * op->dummy.buswidth) / 8;
+   if (spi_nor_protocol_is_dtr(nor->read_proto))
+   op->dummy.nbytes *= 2;
+
+   nor->dirmap.rdesc = spi_mem_dirmap_create(nor->spi, );
+   if (IS_ERR(nor->dirmap.rdesc))
+   return PTR_ERR(nor->dirmap.rdesc);
+
+   return 0;
+}
+
+static int spi_nor_create_write_dirmap(struct spi_nor *nor)
+{
+   struct spi_mem_dirmap_info info = {
+   .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 0),
+ SPI_MEM_OP_ADDR(nor->addr_width, 0, 0),
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_DATA_OUT(0, NULL, 0)),
+   .offset = 0,
+   .length = nor->mtd.size,
+   };
+   struct spi_mem_op *op = _tmpl;
+
+   /* get transfer protocols. */
+   spi_nor_setup_op(nor, op, nor->write_proto);
+   op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);
+
+   if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
+   op->addr.nbytes = 0;
+
+   nor->dirmap.wdesc = spi_mem_dirmap_create(nor->spi, );
+   if (IS_ERR(nor->dirmap.wdesc))
+   return PTR_ERR(nor->dirmap.wdesc);
+
+   return 0;
+}
+
 /**
  * spi_flash_probe_slave() - Probe for a SPI flash device on a bus
  *
@@ -45,6 +101,16 @@ static int spi_flash_probe_slave(struct spi_flash *flash)
if (ret)
goto err_read_id;
 
+   if (CONFIG_IS_ENABLED(SPI_DIRMAP)) {
+   ret = spi_nor_create_read_dirmap(flash);
+   if (ret)
+   return ret;
+
+   ret = spi_nor_create_write_dirmap(flash);
+   if (ret)
+   return ret;
+   }
+
if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
ret = spi_flash_mtd_register(flash);
 
@@ -83,6 +149,11 @@ struct spi_flash *spi_flash_probe(unsigned int busnum, 
unsigned int cs,
 
 void spi_flash_free(struct spi_flash *flash)
 {
+   if (CONFIG_IS_ENABLED(SPI_DIRMAP)) {
+   spi_mem_dirmap_destroy(flash->dirmap.wdesc);
+   spi_mem_dirmap_destroy(flash->dirmap.rdesc);
+   }
+
if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
spi_flash_mtd_unregister(flash);
 
@@ -153,6 +224,11 @@ static int spi_flash_std_remove(struct udevice *dev)
struct spi_flash *flash = dev_get_uclass_priv(dev);
int ret;
 
+   if (CONFIG_IS_ENABLED(SPI_DIRMAP)) {
+   spi_mem_dirmap_destroy(flash->dirmap.wdesc);
+   spi_mem_dirmap_destroy(flash->dirmap.rdesc);
+   }
+
ret = spi_nor_remove(flash);
if (ret)
return ret;
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 26a356baf8..c82f85210b 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -245,9 +245,9 @@ static u8 spi_nor_get_cmd_ext(const struct sp

[v5 14/14] mtd: spi-nor-ids: Add Winbond W25Q512JVQ ID

2022-08-19 Thread Chin-Ting Kuo
Add ID for Winbond W25Q512JVQ device which is supported
on AST2600 EVB by default.

Signed-off-by: Chin-Ting Kuo 
Reviewed-by: Cédric Le Goater 
---
 drivers/mtd/spi/spi-nor-ids.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 4fe8b0d92c..65eb35a918 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -424,6 +424,11 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
+   {
+   INFO("w25q512jvq", 0xef4020, 0, 64 * 1024, 1024,
+SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+   },
{
INFO("w25q01jv", 0xef4021, 0, 64 * 1024, 2048,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-- 
2.25.1



[v5 02/14] pinctrl: aspeed: FWSPICS1 and SPI1CS1 pin support

2022-08-19 Thread Chin-Ting Kuo
Add FWSPICS1 and SPI1CS1 in AST2500 pinctrl group.
On AST2500 EVB, FWSPICS1 can be supported by default.
An extra jumper, J45, should be configured before
enabling SPI1CS1.

Signed-off-by: Chin-Ting Kuo 
Reviewed-by: Cédric Le Goater 
---
 drivers/pinctrl/aspeed/pinctrl_ast2500.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pinctrl/aspeed/pinctrl_ast2500.c 
b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
index 3c2e10b88e..93920a6389 100644
--- a/drivers/pinctrl/aspeed/pinctrl_ast2500.c
+++ b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
@@ -61,6 +61,8 @@ static const struct ast2500_group_config ast2500_groups[] = {
{ "MDIO2", 5, (1 << 2) },
{ "SD1", 5, (1 << 0) },
{ "SD2", 5, (1 << 1) },
+   { "FWSPICS1", 3, (1 << 24) },
+   { "SPI1CS1", 1, (1 << 15) },
 };
 
 static int ast2500_pinctrl_get_groups_count(struct udevice *dev)
-- 
2.25.1



[v5 07/14] spi-mem: Add dirmap API from Linux

2022-08-19 Thread Chin-Ting Kuo
This adds the dirmap API originally introduced in
Linux commit aa167f3fed0c
("spi: spi-mem: Add a new API to support direct mapping").
This also includes several follow-up patches and fixes.

Changes from Linux include:
* Added Kconfig option
* Changed struct device to struct udevice
* Changed struct spi_mem to struct spi_slave

This patch is obtained from the following patch
https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504-3-sean...@gmail.com/
The corresponding Linux kernel SHA1 is aa167f3fed0c.

Signed-off-by: Chin-Ting Kuo 
Signed-off-by: Sean Anderson 
Acked-by: Pratyush Yadav 
---
v2: Remove "#if CONFIG_SPI_DIRMAP" compile wrapper.
v3: Fix a grammatical error in spi-mem.h.

 drivers/spi/Kconfig   |  10 ++
 drivers/spi/spi-mem.c | 268 ++
 include/spi-mem.h |  79 +
 3 files changed, 357 insertions(+)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 8ca9274ef4..ac91d82258 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -40,6 +40,16 @@ config SPI_MEM
  This extension is meant to simplify interaction with SPI memories
  by providing an high-level interface to send memory-like commands.
 
+config SPI_DIRMAP
+   bool "SPI direct mapping"
+   depends on SPI_MEM
+   help
+ Enable the SPI direct mapping API. Most modern SPI controllers can
+ directly map a SPI memory (or a portion of the SPI memory) in the CPU
+ address space. Most of the time this brings significant performance
+ improvements as it automates the whole process of sending SPI memory
+ operations every time a new region is accessed.
+
 if DM_SPI
 
 config ALTERA_SPI
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 9c1ede1b61..8e8995fc53 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -21,6 +21,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #endif
 
 #ifndef __UBOOT__
@@ -491,6 +493,272 @@ int spi_mem_adjust_op_size(struct spi_slave *slave, 
struct spi_mem_op *op)
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
 
+static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ u64 offs, size_t len, void *buf)
+{
+   struct spi_mem_op op = desc->info.op_tmpl;
+   int ret;
+
+   op.addr.val = desc->info.offset + offs;
+   op.data.buf.in = buf;
+   op.data.nbytes = len;
+   ret = spi_mem_adjust_op_size(desc->slave, );
+   if (ret)
+   return ret;
+
+   ret = spi_mem_exec_op(desc->slave, );
+   if (ret)
+   return ret;
+
+   return op.data.nbytes;
+}
+
+static ssize_t spi_mem_no_dirmap_write(struct spi_mem_dirmap_desc *desc,
+  u64 offs, size_t len, const void *buf)
+{
+   struct spi_mem_op op = desc->info.op_tmpl;
+   int ret;
+
+   op.addr.val = desc->info.offset + offs;
+   op.data.buf.out = buf;
+   op.data.nbytes = len;
+   ret = spi_mem_adjust_op_size(desc->slave, );
+   if (ret)
+   return ret;
+
+   ret = spi_mem_exec_op(desc->slave, );
+   if (ret)
+   return ret;
+
+   return op.data.nbytes;
+}
+
+/**
+ * spi_mem_dirmap_create() - Create a direct mapping descriptor
+ * @mem: SPI mem device this direct mapping should be created for
+ * @info: direct mapping information
+ *
+ * This function is creating a direct mapping descriptor which can then be used
+ * to access the memory using spi_mem_dirmap_read() or spi_mem_dirmap_write().
+ * If the SPI controller driver does not support direct mapping, this function
+ * falls back to an implementation using spi_mem_exec_op(), so that the caller
+ * doesn't have to bother implementing a fallback on his own.
+ *
+ * Return: a valid pointer in case of success, and ERR_PTR() otherwise.
+ */
+struct spi_mem_dirmap_desc *
+spi_mem_dirmap_create(struct spi_slave *slave,
+ const struct spi_mem_dirmap_info *info)
+{
+   struct udevice *bus = slave->dev->parent;
+   struct dm_spi_ops *ops = spi_get_ops(bus);
+   struct spi_mem_dirmap_desc *desc;
+   int ret = -EOPNOTSUPP;
+
+   /* Make sure the number of address cycles is between 1 and 8 bytes. */
+   if (!info->op_tmpl.addr.nbytes || info->op_tmpl.addr.nbytes > 8)
+   return ERR_PTR(-EINVAL);
+
+   /* data.dir should either be SPI_MEM_DATA_IN or SPI_MEM_DATA_OUT. */
+   if (info->op_tmpl.data.dir == SPI_MEM_NO_DATA)
+   return ERR_PTR(-EINVAL);
+
+   desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+   if (!desc)
+   return ERR_PTR(-ENOMEM);
+
+   desc->slave = slave;
+   desc->info = *info;
+   if (ops->mem_ops && ops->mem_ops->dirmap_create)
+   ret = ops->mem_ops->dirmap_create(desc);
+
+   if (ret) {
+

[v5 00/14] Add ASPEED SPI controller driver

2022-08-19 Thread Chin-Ting Kuo
This patch series aims to porting ASPEED FMC/SPI memory controller 
driver with spi-mem interface. spi-mem dirmap framework is also 
synchronized from Linux. These patches have been verified on
AST2600, AST2500 and AST2400 EVBs.

Changes in v2:
  - Separate defconfig files from the SPI driver patch.
  - Use "if (CONFIG_IS_ENABLED(SPI_DIRMAP))" to wrap
spi_dirmap related functions.
  - Add Winbond w25q512jv flash ID.

Changes in v3:
  - Get AHB bus clock frequency from the function parameter.
  - Fix a grammatical error in spi-mem.h.

Changes in v4:
  - Fix bug when SPI_NOR_4B_OPCODES flag is set.

Changes in v5:
  - Separate main ASPEED SPI driver patch into different parts.
* basic support.
* decoded range adjustment.
* clock settings.
  - Add support customized decoded range.
  - Add AST2400 platform support.

Chin-Ting Kuo (14):
  clk: aspeed: Get HCLK frequency support
  pinctrl: aspeed: FWSPICS1 and SPI1CS1 pin support
  spi: aspeed: Add ASPEED SPI controller driver
  configs: aspeed: Enable SPI flash features
  spi: aspeed: Support AST2400 platform
  arm: dts: aspeed: Update SPI flash node settings
  spi-mem: Add dirmap API from Linux
  mtd: spi-nor: Use spi-mem dirmap API
  spi: aspeed: SPI dirmap read support
  configs: aspeed: Enable CONFIG_SPI_DIRMAP
  spi: aspeed: Adjust decoded range size support
  spi: aspeed: Support customized decoded address ranges
  spi: aspeed: Clock frequency adjustment support
  mtd: spi-nor-ids: Add Winbond W25Q512JVQ ID

 MAINTAINERS  |7 +
 arch/arm/dts/ast2500-evb.dts |   33 +
 arch/arm/dts/ast2500.dtsi|   23 +-
 arch/arm/dts/ast2600-evb.dts |8 -
 arch/arm/dts/ast2600.dtsi|   34 +-
 configs/evb-ast2500_defconfig|   14 +
 configs/evb-ast2600_defconfig|   14 +
 drivers/clk/aspeed/clk_ast2500.c |   23 +
 drivers/mtd/spi/sf_probe.c   |   76 ++
 drivers/mtd/spi/spi-nor-core.c   |   55 +-
 drivers/mtd/spi/spi-nor-ids.c|5 +
 drivers/pinctrl/aspeed/pinctrl_ast2500.c |2 +
 drivers/spi/Kconfig  |   18 +
 drivers/spi/Makefile |1 +
 drivers/spi/spi-aspeed-smc.c | 1218 ++
 drivers/spi/spi-mem.c|  268 +
 include/linux/mtd/spi-nor.h  |   18 +
 include/spi-mem.h|   79 ++
 18 files changed, 1850 insertions(+), 46 deletions(-)
 create mode 100644 drivers/spi/spi-aspeed-smc.c

-- 
2.25.1



[v5 06/14] arm: dts: aspeed: Update SPI flash node settings

2022-08-19 Thread Chin-Ting Kuo
For both AST2500 and AST2600, there are three
SPI controllers, FMC(Firmware Memory Controller),
SPI1 and SPI2. The clock source is HCLK. Following
is the basic information for ASPEED SPI controller.

AST2500:
  - FMC:
  CS number: 3
  controller reg: 0x1e62 - 0x1e62
  decoded address: 0x2000 - 0x2fff

  - SPI1:
  CS number: 2
  controller reg: 0x1e63 - 0x1e630fff
  decoded address: 0x3000 - 0x37ff

  - SPI2:
  CS number: 2
  controller reg: 0x1e631000 - 0x1e631fff
  decoded address: 0x3800 - 0x3fff

AST2600:
  - FMC:
  CS number: 3
  controller reg: 0x1e62 - 0x1e62
  decoded address: 0x2000 - 0x2fff

  - SPI1:
  CS number: 2
  controller reg: 0x1e63 - 0x1e630fff
  decoded address: 0x3000 - 0x3fff

  - SPI2:
  CS number: 3
  controller reg: 0x1e631000 - 0x1e631fff
  decoded address: 0x5000 - 0x5fff

Signed-off-by: Chin-Ting Kuo 
---
 arch/arm/dts/ast2500-evb.dts | 33 +
 arch/arm/dts/ast2500.dtsi| 23 ---
 arch/arm/dts/ast2600-evb.dts |  8 
 arch/arm/dts/ast2600.dtsi| 34 +++---
 4 files changed, 68 insertions(+), 30 deletions(-)

diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
index cc577761fa..1fbacf985f 100644
--- a/arch/arm/dts/ast2500-evb.dts
+++ b/arch/arm/dts/ast2500-evb.dts
@@ -78,6 +78,39 @@
pinctrl-0 = <_sd2_default>;
 };
 
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_fwspics1_default>;
+
+   flash@0 {
+   status = "okay";
+   spi-max-frequency = <5000>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+
+   flash@1 {
+   status = "okay";
+   spi-max-frequency = <5000>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+};
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_spi1cs1_default>;
+
+   flash@0 {
+   status = "okay";
+   spi-max-frequency = <5000>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+};
+
  {
 status = "okay";
 
diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
index cea08e6f08..320d2e5340 100644
--- a/arch/arm/dts/ast2500.dtsi
+++ b/arch/arm/dts/ast2500.dtsi
@@ -57,23 +57,26 @@
ranges;
 
fmc: flash-controller@1e62 {
-   reg = < 0x1e62 0xc4
-   0x2000 0x1000 >;
+   reg = <0x1e62 0xc4>, <0x2000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
compatible = "aspeed,ast2500-fmc";
+   clocks = < ASPEED_CLK_AHB>;
+   num-cs = <3>;
status = "disabled";
-   interrupts = <19>;
+
flash@0 {
reg = < 0 >;
compatible = "jedec,spi-nor";
status = "disabled";
};
+
flash@1 {
reg = < 1 >;
compatible = "jedec,spi-nor";
status = "disabled";
};
+
flash@2 {
reg = < 2 >;
compatible = "jedec,spi-nor";
@@ -82,17 +85,20 @@
};
 
spi1: flash-controller@1e63 {
-   reg = < 0x1e63 0xc4
-   0x3000 0x0800 >;
+   reg = <0x1e63 0xc4>, <0x3000 0x0800>;
#address-cells = <1>;
#size-cells = <0>;
compatible = "aspeed,ast2500-spi";
+   clocks = < ASPEED_CLK_AHB>;
+   num-cs = <2>;
status = "disabled";
+
flash@0 {
reg = < 0 >;
compatible = "jedec,spi-nor";
status = "disabled";
};
+
flash@1 {
reg = < 1 >;
compat

RE: [v4 00/12] Add ASPEED SPI controller driver

2022-08-10 Thread Chin-Ting Kuo
Hi Jagan,

> -Original Message-
> From: Jagan Teki 
> Sent: Friday, July 1, 2022 7:57 PM
> To: Chin-Ting Kuo 
> Subject: Re: [v4 00/12] Add ASPEED SPI controller driver
> 
> On Tue, May 24, 2022 at 11:27 AM Chin-Ting Kuo
>  wrote:
> >
> > This patch series aims to porting ASPEED FMC/SPI memory controller
> > driver with spi-mem interface. spi-mem dirmap framework is also
> > synchronized from Linux. These patches have been verified on both
> > AST2600 and AST2500 EVBs.
> >
> > Changes in v2:
> >   - Separate defconfig files from the SPI driver patch.
> >   - Use "if (CONFIG_IS_ENABLED(SPI_DIRMAP))" to wrap
> > spi_dirmap related functions.
> >   - Add Winbond w25q512jv flash ID.
> >
> > Changes in v3:
> >   - Get AHB bus clock frequency from the function parameter.
> >   - Fix a grammatical error in spi-mem.h.
> >
> > Changes in v4:
> >   - Fix bug when SPI_NOR_4B_OPCODES flag is set.
> >
> > Chin-Ting Kuo (12):
> >   clk: aspeed: Get HCLK frequency support
> >   pinctrl: aspeed: FWSPICS1 and SPI1CS1 pin support
> >   spi: aspeed: Add ASPEED SPI controller driver
> >   configs: aspeed: Enable SPI flash features
> >   MAINTAINERS: Add ASPEED SPI driver file
> >   arm: dts: aspeed: Update SPI flash node settings
> >   spi-mem: Add dirmap API from Linux
> >   mtd: spi-nor: Use spi-mem dirmap API
> >   spi: aspeed: SPI dirmap read support
> >   configs: aspeed: Enable CONFIG_SPI_DIRMAP
> >   mtd: spi-nor-ids: Add Winbond W25Q512JV ID
> >   spi: aspeed: Fix bug when SPI_NOR_4B_OPCODES flag is set
> 
> Sperate series for spi changes would really make it easier for review.
> please send it.
> 

The patches in this series depend on each other.
Patch with higher number relies on the one with lower number.
Thus, I think they cannot be separated into different series.

Chin-Ting

> Jagan.


RE: [v4 05/12] MAINTAINERS: Add ASPEED SPI driver file

2022-08-10 Thread Chin-Ting Kuo
Hi Jagan,

> -Original Message-
> From: Jagan Teki 
> Sent: Friday, July 1, 2022 7:53 PM
> To: Chin-Ting Kuo 
> Subject: Re: [v4 05/12] MAINTAINERS: Add ASPEED SPI driver file
> 
> On Tue, May 24, 2022 at 11:28 AM Chin-Ting Kuo
>  wrote:
> >
> > Add spi-aspeed.c file for ARM ASPEED.
> >
> > Signed-off-by: Chin-Ting Kuo 
> > ---
> >  MAINTAINERS | 7 +++
> >  1 file changed, 7 insertions(+)
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS index 56be0bfad0..f2cd707eda
> > 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -688,6 +688,13 @@ S: Maintained
> >  F: drivers/pci/pcie_phytium.c
> >  F: arch/arm/dts/phytium-durian.dts
> >
> > +ASPEED FMC SPI DRIVER
> > +M: Chin-Ting Kuo 
> > +M: Cédric Le Goater 
> > +R: Aspeed BMC SW team 
> > +S: Maintained
> > +F: drivers/spi/spi-aspeed.c
> 
> Squash this part of spi-aspeed.c driver patch

Okay and will be updated in the next patch version.


Chin-Ting


RE: [v4 07/12] spi-mem: Add dirmap API from Linux

2022-08-10 Thread Chin-Ting Kuo
Hi Jagan,

> -Original Message-
> From: Jagan Teki 
> Sent: Friday, July 1, 2022 8:05 PM
> To: Chin-Ting Kuo 
> Subject: Re: [v4 07/12] spi-mem: Add dirmap API from Linux
> 
> On Tue, May 24, 2022 at 11:28 AM Chin-Ting Kuo
>  wrote:
> >
> > This adds the dirmap API originally introduced in Linux commit aa167f3
> > ("spi: spi-mem: Add a new API to support direct mapping"). This also
> > includes several follow-up patches and fixes.
> >
> > Changes from Linux include:
> > * Added Kconfig option
> > * Changed struct device to struct udevice
> > * Changed struct spi_mem to struct spi_slave
> >
> > This patch is obtained from the following patch
> > https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504
> > -3-sean...@gmail.com/
> >
> > Signed-off-by: Chin-Ting Kuo 
> > Signed-off-by: Sean Anderson 
> > Acked-by: Pratyush Yadav 
> > ---
> > v2: Remove "#if CONFIG_SPI_DIRMAP" compile wrapper.
> > v3: Fix a grammatical error in spi-mem.h.
> >
> >  drivers/spi/Kconfig   |  10 ++
> >  drivers/spi/spi-mem.c | 268
> ++
> >  include/spi-mem.h |  79 +
> >  3 files changed, 357 insertions(+)
> >
> > diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index
> > a616294910..297253714a 100644
> > --- a/drivers/spi/Kconfig
> > +++ b/drivers/spi/Kconfig
> > @@ -40,6 +40,16 @@ config SPI_MEM
> >   This extension is meant to simplify interaction with SPI
> memories
> >   by providing an high-level interface to send memory-like
> commands.
> >
> > +config SPI_DIRMAP
> 
> Look like the following code is not part of this if construct, we need that to
> build only when SPI_DIRMAP is defined otherwise it footprint increase for
> non-DIRMAPs. Also please take care of unnecessary code while copying from
> Linux and add SHA1 in the commit message.
> 

Okay and I will take care the footprint for non-DITMAPs.


Chin-Ting

> Jagan.


RE: [v4 03/12] spi: aspeed: Add ASPEED SPI controller driver

2022-07-11 Thread Chin-Ting Kuo
Hi Cédric,

> -Original Message-
> From: Cédric Le Goater 
> Sent: Friday, July 8, 2022 4:52 PM
> To: Chin-Ting Kuo ; Joel Stanley
> 
> Subject: Re: [v4 03/12] spi: aspeed: Add ASPEED SPI controller driver
> 
> On 7/8/22 07:42, Chin-Ting Kuo wrote:
> > Hi Joel,
> >
> >> -Original Message-
> >> From: Joel Stanley 
> >> Sent: Thursday, July 7, 2022 1:37 PM
> >> Subject: Re: [v4 03/12] spi: aspeed: Add ASPEED SPI controller driver
> >>
> >> Hi Chin-Ting,
> >>
> >> On Tue, 24 May 2022 at 05:58, Chin-Ting Kuo
> >>  wrote:
> >>>
> >>> Add ASPEED BMC FMC/SPI memory controller driver with spi-mem
> >>> interface for AST2500 and AST2600 platform.
> >>
> >> Have you considered including 2400 support in your patch set?
> >>
> >
> > No. But in order to achieve sustainability and completeness, we will add
> AST2400 part in the next patch version.
> 
> Could you please provide the AST2400 support as a separate patch on top of
> the AST2500/AST2600 ? It helps to understand the differences.
> 

Okay, it will be more clear.


Best Wishes,
Chin-Ting

> Thanks,
> 
> C.


RE: [v4 03/12] spi: aspeed: Add ASPEED SPI controller driver

2022-07-07 Thread Chin-Ting Kuo
Hi Joel,

> -Original Message-
> From: Joel Stanley 
> Sent: Thursday, July 7, 2022 1:37 PM
> Subject: Re: [v4 03/12] spi: aspeed: Add ASPEED SPI controller driver
> 
> Hi Chin-Ting,
> 
> On Tue, 24 May 2022 at 05:58, Chin-Ting Kuo
>  wrote:
> >
> > Add ASPEED BMC FMC/SPI memory controller driver with spi-mem interface
> > for AST2500 and AST2600 platform.
> 
> Have you considered including 2400 support in your patch set?
> 

No. But in order to achieve sustainability and completeness, we will add 
AST2400 part in the next patch version.


Best Wishes,
Chin-Ting

> I have prepared a series that adds upstream support for the 2400. We already
> have support in other drivers (gpio, i2c, sdhci, timer, wdt) so there's no 
> blocker
> in including support in your patch.
> 
> Cheers,
> 
> Joel
> 
> >
> > There are three SPI memory controllers embedded in an ASPEED SoC.
> > - FMC: Named as Firmware Memory Controller. After AC on, MCU ROM
> >fetches initial device boot image from FMC chip select(CS) 0.
> >
> > - SPI1: Play the role of a SPI Master controller. Or, there is a
> > dedicated path for HOST(X86) to access its BIOS flash mounted
> > under BMC. spi-aspeed.c implements the control sequence when
> > SPI1 is a SPI master.
> >
> > - SPI2: It is a pure SPI flash controller. For most scenarios, flashes
> > mounted under it are for pure storage purpose.
> >
> > ASPEED SPI controller supports 1-1-1, 1-1-2 and 1-1-4 SPI flash mode.
> > Three types of command mode are supported, normal mode, command
> > read/write mode and user mode.
> > - Normal mode: Default mode. After power on, normal read command 03h
> or
> >13h is used to fetch boot image from SPI flash.
> >- AST2500: Only 03h command can be used after power
> on
> >   or reset.
> >- AST2600: If FMC04[6:4] is set, 13h command is used,
> >   otherwise, 03h command.
> >The address length is decided by FMC04[2:0].
> >
> > - Command mode: SPI controller can send command and address
> > automatically when CPU read/write the related
> remapped
> > or decoded address area. The command used by this
> mode
> > can be configured by FMC10/14/18[23:16]. Also, the
> > address length is decided by FMC04[2:0]. This mode will
> > be implemented in the following patch series.
> >
> > - User mode: It is a traditional and pure SPI operation, where
> >  SPI transmission is controlled by CPU. It is the main
> >  mode in this patch.
> >
> > Each SPI controller in ASPEED SoC has its own decoded address mapping.
> > Within each SPI controller decoded address, driver can assign a
> > specific address region for each CS of a SPI controller. The decoded
> > address cannot overlap to each other. With normal mode and command
> > mode, the decoded address accessed by the CPU determines which CS is
> active.
> > When user mode is adopted, the CS decoded address is a FIFO, CPU can
> > send/receive any SPI transmission by accessing the related decoded
> > address for the target CS.
> >
> > Signed-off-by: Chin-Ting Kuo 
> > ---
> > v2: Remove defconfig files from this patch.
> >
> >  drivers/spi/Kconfig  |   8 +
> >  drivers/spi/Makefile |   1 +
> >  drivers/spi/spi-aspeed.c | 822
> > +++
> >  3 files changed, 831 insertions(+)
> >  create mode 100644 drivers/spi/spi-aspeed.c
> >
> > diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index
> > a1e515cb2b..a616294910 100644
> > --- a/drivers/spi/Kconfig
> > +++ b/drivers/spi/Kconfig
> > @@ -387,6 +387,14 @@ config SANDBOX_SPI
> > };
> >   };
> >
> > +config SPI_ASPEED
> > +   bool "ASPEED SPI controller driver"
> > +   depends on DM_SPI && SPI_MEM
> > +   default n
> > +   help
> > + Enable ASPEED SPI controller driver for AST2500
> > + and AST2600 SoCs.
> > +
> >  config SPI_SIFIVE
> > bool "SiFive SPI driver"
> > help
> > diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index
> > 06e81b465b..36a4bd5dce 100644
> > --- a/drivers/spi/Makefile
> > +++ b/drivers/spi/Makefile
> > @@ -9,6 +9,7 @@ obj-y += spi-uclass.o
> >  obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cad

RE: [v4 03/12] spi: aspeed: Add ASPEED SPI controller driver

2022-07-06 Thread Chin-Ting Kuo
Hi Cédric,

> -Original Message-
> From: Cédric Le Goater 
> Sent: Monday, July 4, 2022 11:25 PM
> Subject: Re: [v4 03/12] spi: aspeed: Add ASPEED SPI controller driver
> 
> Hello Chin-Ting,
> 
> On 7/3/22 10:47, Chin-Ting Kuo wrote:
> > Hi Cédric,
> >
> > Thanks for the review.
> >
> >> -Original Message-
> >> From: Cédric Le Goater 
> >> Sent: Friday, July 1, 2022 5:28 PM
> >> To: Chin-Ting Kuo ; ChiaWei Wang
> >> ; lu...@denx.de; sean...@gmail.com;
> Ryan
> >> Chen ; BMC-SW
> ;
> >> ja...@amarulasolutions.com; vigne...@ti.com; u-boot@lists.denx.de;
> >> p.ya...@ti.com
> >> Subject: Re: [v4 03/12] spi: aspeed: Add ASPEED SPI controller driver
> >>
> >> Hello Chin-Ting,
> >>
> >> On 5/24/22 07:56, Chin-Ting Kuo wrote:
> >>> Add ASPEED BMC FMC/SPI memory controller driver with spi-mem
> >>> interface for AST2500 and AST2600 platform.
> >>>
> >>> There are three SPI memory controllers embedded in an ASPEED SoC.
> >>> - FMC: Named as Firmware Memory Controller. After AC on, MCU ROM
> >>>  fetches initial device boot image from FMC chip select(CS) 0.
> >>>
> >>> - SPI1: Play the role of a SPI Master controller. Or, there is a
> >>>   dedicated path for HOST(X86) to access its BIOS flash
> mounted
> >>>   under BMC. spi-aspeed.c implements the control sequence
> when
> >>>   SPI1 is a SPI master.
> >>>
> >>> - SPI2: It is a pure SPI flash controller. For most scenarios, flashes
> >>>   mounted under it are for pure storage purpose.
> >>>
> >>> ASPEED SPI controller supports 1-1-1, 1-1-2 and 1-1-4 SPI flash mode.
> >>> Three types of command mode are supported, normal mode, command
> >>> read/write mode and user mode.
> >>> - Normal mode: Default mode. After power on, normal read command
> 03h
> >> or
> >>>  13h is used to fetch boot image from SPI flash.
> >>>  - AST2500: Only 03h command can be used after
> power
> >> on
> >>> or reset.
> >>>  - AST2600: If FMC04[6:4] is set, 13h command is
> used,
> >>> otherwise, 03h command.
> >>>  The address length is decided by FMC04[2:0].
> >>>
> >>> - Command mode: SPI controller can send command and address
> >>>   automatically when CPU read/write the related
> >> remapped
> >>>   or decoded address area. The command used by
> this
> >> mode
> >>>   can be configured by FMC10/14/18[23:16]. Also,
> the
> >>>   address length is decided by FMC04[2:0]. This mode
> >> will
> >>>   be implemented in the following patch series.
> >>>
> >>> - User mode: It is a traditional and pure SPI operation, where
> >>>SPI transmission is controlled by CPU. It is the main
> >>>mode in this patch.
> >>>
> >>> Each SPI controller in ASPEED SoC has its own decoded address mapping.
> >>> Within each SPI controller decoded address, driver can assign a
> >>> specific address region for each CS of a SPI controller. The decoded
> >>> address cannot overlap to each other. With normal mode and command
> >>> mode, the decoded address accessed by the CPU determines which CS is
> >> active.
> >>> When user mode is adopted, the CS decoded address is a FIFO, CPU can
> >>> send/receive any SPI transmission by accessing the related decoded
> >>> address for the target CS.
> >>>
> >>> Signed-off-by: Chin-Ting Kuo 
> >>
> >> I would split the patch furthermore to ease reading.
> >
> > Okay, this will be update in the next version.
> >
> >>1 - Add basic support
> >>
> >>with default decoding ranges set for all possible CS, even
> >>without a device.
> >>
> >>WE only have USER mode for now. So it's not important to
> >>correctly set the ranges since we won't use them before
> >>direct mapping is introduced. They should not overlap,
> >>that's all.
> >>
> >>2 - decoding range adjustments
> >>
> >>On that topic

RE: [v4 04/12] configs: aspeed: Enable SPI flash features

2022-07-03 Thread Chin-Ting Kuo
Hi Cédric,

> -Original Message-
> From: Cédric Le Goater 
> Sent: Friday, July 1, 2022 7:51 PM
> Subject: Re: [v4 04/12] configs: aspeed: Enable SPI flash features
> 
> On 7/1/22 11:28, Cédric Le Goater wrote:
> > On 5/24/22 07:56, Chin-Ting Kuo wrote:
> >> - Enable ASPEED SPI controller driver.
> >> - Enable SPI flash memory configurations.
> >> - Enable configurations for SPI flash manufacturers
> >>    supported on both ASPEED AST2500 and AST2600 AVL.
> >>
> >> Signed-off-by: Chin-Ting Kuo 
> >> ---
> >>   configs/evb-ast2500_defconfig | 13 +
> >>   configs/evb-ast2600_defconfig | 13 +
> >>   2 files changed, 26 insertions(+)
> >>
> >> diff --git a/configs/evb-ast2500_defconfig
> >> b/configs/evb-ast2500_defconfig index 2371cc2742..fd04fe5a60 100644
> >> --- a/configs/evb-ast2500_defconfig
> >> +++ b/configs/evb-ast2500_defconfig
> >> @@ -35,6 +35,16 @@ CONFIG_DM_I2C=y
> >>   CONFIG_SYS_I2C_ASPEED=y
> >>   CONFIG_MMC_SDHCI=y
> >>   CONFIG_MMC_SDHCI_ASPEED=y
> >> +CONFIG_DM_SPI_FLASH=y
> >> +CONFIG_SPI_FLASH_SFDP_SUPPORT=y
> >> +CONFIG_SPI_FLASH_GIGADEVICE=y
> >> +CONFIG_SPI_FLASH_ISSI=y
> >> +CONFIG_SPI_FLASH_MACRONIX=y
> >> +CONFIG_SPI_FLASH_SPANSION=y
> >> +CONFIG_SPI_FLASH_STMICRO=y
> >> +CONFIG_SPI_FLASH_SST=y
> >> +CONFIG_SPI_FLASH_WINBOND=y
> >> +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
> >>   CONFIG_PHY_REALTEK=y
> >>   CONFIG_DM_ETH=y
> >>   CONFIG_FTGMAC100=y
> >> @@ -44,6 +54,9 @@ CONFIG_RAM=y
> >>   CONFIG_DM_RESET=y
> >>   CONFIG_DM_SERIAL=y
> >>   CONFIG_SYS_NS16550=y
> >> +CONFIG_SPI=y
> >> +CONFIG_DM_SPI=y
> >> +CONFIG_SPI_ASPEED=y
> >>   CONFIG_SYSRESET=y
> >>   CONFIG_TIMER=y
> >>   CONFIG_WDT=y
> >
> > This is breaking boot on the AST2500 evb (QEMU) . I haven't found why
> > yet. You might want to take a look.
> 
> The resulting binary is too big for the flash layout we use on OpenBMC.

What’s the flash layout used by you? I tested this patch series on AST2500 EVB, 
and it was okay before.


Chin-Ting

> 
> C.


RE: [v4 12/12] spi: aspeed: Fix bug when SPI_NOR_4B_OPCODES flag is set

2022-07-03 Thread Chin-Ting Kuo
Hi Cédric,

> -Original Message-
> From: Cédric Le Goater 
> Sent: Friday, July 1, 2022 5:45 PM
> Subject: Re: [v4 12/12] spi: aspeed: Fix bug when SPI_NOR_4B_OPCODES flag
> is set
> 
> On 5/24/22 07:56, Chin-Ting Kuo wrote:
> > When SPI_NOR_4B_OPCODES flag is set for a specific flash in
> > spi_nor_ids[] table, EN4B command will not be issued and 4-byte
> > dedicated commands will be used to access SPI flash.
> > Thus, instead of EN4B command, address length is more suitable for
> > deciding whether the controller should be set to 4-byte mode.
> >
> > Signed-off-by: Chin-Ting Kuo 
> > ---
> >   drivers/spi/spi-aspeed.c | 7 +++
> >   1 file changed, 3 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/spi/spi-aspeed.c b/drivers/spi/spi-aspeed.c index
> > e5e348eb7b..687ddc370b 100644
> > --- a/drivers/spi/spi-aspeed.c
> > +++ b/drivers/spi/spi-aspeed.c
> > @@ -504,10 +504,6 @@ static int aspeed_spi_exec_op_user_mode(struct
> spi_slave *slave,
> > /* Restore controller setting. */
> > writel(flash->ce_ctrl_read, ctrl_reg);
> >
> > -   /* Set controller to 4-byte mode when flash is in 4-byte mode. */
> > -   if (op->cmd.opcode == SPINOR_OP_EN4B)
> > -   priv->info->set_4byte(bus, cs);
> > -
> > return 0;
> >   }
> 
> 
> This should be part of the patch adding the driver.
> 

Okay.

Thanks.

Chin-Ting

> Thanks,
> 
> C.
> 
> 
> > @@ -561,6 +557,9 @@ static int aspeed_spi_dirmap_create(struct
> spi_mem_dirmap_desc *desc)
> >plat->ctrl_base + REG_CE0_CTRL_REG + cs * 4);
> > priv->flashes[cs].ce_ctrl_read = reg_val;
> >
> > +   if (op_tmpl.addr.nbytes == 4)
> > +   priv->info->set_4byte(bus, cs);
> > +
> > dev_dbg(dev, "read bus width: %d [0x%08x]\n",
> > op_tmpl.data.buswidth, priv->flashes[cs].ce_ctrl_read);
> > } else {



RE: [v4 06/12] arm: dts: aspeed: Update SPI flash node settings

2022-07-03 Thread Chin-Ting Kuo
Hi Cédric,

> -Original Message-
> From: Cédric Le Goater 
> Sent: Friday, July 1, 2022 5:42 PM
> To: Chin-Ting Kuo ; ChiaWei Wang
> ; lu...@denx.de; sean...@gmail.com;
> Ryan Chen ; BMC-SW
> ; ja...@amarulasolutions.com; vigne...@ti.com;
> u-boot@lists.denx.de; p.ya...@ti.com; Joel Stanley 
> Subject: Re: [v4 06/12] arm: dts: aspeed: Update SPI flash node settings
> 
> On 5/24/22 07:56, Chin-Ting Kuo wrote:
> > For both AST2500 and AST2600, there are three SPI controllers,
> > FMC(Firmware Memory Controller),
> > SPI1 and SPI2. The clock source is HCLK. Following is the basic
> > information for ASPEED SPI controller.
> >
> > AST2500:
> >- FMC:
> >CS number: 3
> >controller reg: 0x1e62 - 0x1e62
> >decoded address: 0x2000 - 0x2fff
> >
> >- SPI1:
> >CS number: 2
> >controller reg: 0x1e63 - 0x1e630fff
> >decoded address: 0x3000 - 0x37ff
> >
> >- SPI2:
> >CS number: 2
> >controller reg: 0x1e631000 - 0x1e631fff
> >decoded address: 0x3800 - 0x3fff
> >
> > AST2600:
> >- FMC:
> >CS number: 3
> >controller reg: 0x1e62 - 0x1e62
> >decoded address: 0x2000 - 0x2fff
> >
> >- SPI1:
> >CS number: 2
> >controller reg: 0x1e63 - 0x1e630fff
> >    decoded address: 0x3000 - 0x3fff
> >
> >- SPI2:
> >CS number: 3
> >controller reg: 0x1e631000 - 0x1e631fff
> >decoded address: 0x5000 - 0x5fff
> >
> > Signed-off-by: Chin-Ting Kuo 
> 
> I might be wrong for the comment I did on 'num-cs' in the patch adding the
> driver. Joel, what's your opinion ? Hard coded in the driver or a property in 
> the
> DT ?
> 

Do you mean " num_cs" or "max-cs" here?
If "num_cs", I think that it should be detected during runtime, as the original 
implementation.
If "max-cs", I think that both hard coded or a property in the DT are okay.


Thanks.

Chin-Ting

> Thanks,
> 
> C.
> 
> > ---
> >   arch/arm/dts/ast2500-evb.dts | 33
> +
> >   arch/arm/dts/ast2500.dtsi| 23 ---
> >   arch/arm/dts/ast2600-evb.dts |  8 
> >   arch/arm/dts/ast2600.dtsi| 34 +++---
> >   4 files changed, 68 insertions(+), 30 deletions(-)
> >
> > diff --git a/arch/arm/dts/ast2500-evb.dts
> > b/arch/arm/dts/ast2500-evb.dts index 4796ed445f..c6b7675902 100644
> > --- a/arch/arm/dts/ast2500-evb.dts
> > +++ b/arch/arm/dts/ast2500-evb.dts
> > @@ -73,3 +73,36 @@
> > pinctrl-names = "default";
> > pinctrl-0 = <_sd2_default>;
> >   };
> > +
> > + {
> > +   status = "okay";
> > +   pinctrl-names = "default";
> > +   pinctrl-0 = <_fwspics1_default>;
> > +
> > +   flash@0 {
> > +   status = "okay";
> > +   spi-max-frequency = <5000>;
> > +   spi-tx-bus-width = <2>;
> > +   spi-rx-bus-width = <2>;
> > +   };
> > +
> > +   flash@1 {
> > +   status = "okay";
> > +   spi-max-frequency = <5000>;
> > +   spi-tx-bus-width = <2>;
> > +   spi-rx-bus-width = <2>;
> > +   };
> > +};
> > +
> > + {
> > +   status = "okay";
> > +   pinctrl-names = "default";
> > +   pinctrl-0 = <_spi1cs1_default>;
> > +
> > +   flash@0 {
> > +   status = "okay";
> > +   spi-max-frequency = <5000>;
> > +   spi-tx-bus-width = <2>;
> > +   spi-rx-bus-width = <2>;
> > +   };
> > +};
> > diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
> > index ee66ef6704..d78a53aeb7 100644
> > --- a/arch/arm/dts/ast2500.dtsi
> > +++ b/arch/arm/dts/ast2500.dtsi
> > @@ -57,23 +57,26 @@
> > ranges;
> >
> > fmc: flash-controller@1e62 {
> > -   reg = < 0x1e62 0xc4
> > -   0x2000 0x1000 >;
> > +   reg = <0x1e62 0xc4>, <0x2000 0x1000>;
> > #address-cells = <1>;
> > #size-cells = <0>;
> > compatible = "aspeed,ast2500-fmc";
> 

RE: [v4 07/12] spi-mem: Add dirmap API from Linux

2022-07-03 Thread Chin-Ting Kuo
Hi Cédric,

> -Original Message-
> From: Cédric Le Goater 
> Sent: Friday, July 1, 2022 5:37 PM
> Subject: Re: [v4 07/12] spi-mem: Add dirmap API from Linux
> 
> On 5/24/22 07:56, Chin-Ting Kuo wrote:
> > This adds the dirmap API originally introduced in Linux commit aa167f3
> > ("spi: spi-mem: Add a new API to support direct mapping"). This also
> > includes several follow-up patches and fixes.
> >
> > Changes from Linux include:
> > * Added Kconfig option
> > * Changed struct device to struct udevice
> > * Changed struct spi_mem to struct spi_slave
> >
> > This patch is obtained from the following patch
> > https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504
> > -3-sean...@gmail.com/
> 
> 
> It has been sent long ago. Is there an issue with the backport from Linux ?

No.

> Is it the lack of drivers using it ?

Yes and thus, it is postponed at that time.

> 
> Thanks,
> 
> C.
> 
> >
> > Signed-off-by: Chin-Ting Kuo 
> > Signed-off-by: Sean Anderson 
> > Acked-by: Pratyush Yadav 
> > ---
> > v2: Remove "#if CONFIG_SPI_DIRMAP" compile wrapper.
> > v3: Fix a grammatical error in spi-mem.h.
> >
> >   drivers/spi/Kconfig   |  10 ++
> >   drivers/spi/spi-mem.c | 268
> ++
> >   include/spi-mem.h |  79 +
> >   3 files changed, 357 insertions(+)
> >
> > diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index
> > a616294910..297253714a 100644
> > --- a/drivers/spi/Kconfig
> > +++ b/drivers/spi/Kconfig
> > @@ -40,6 +40,16 @@ config SPI_MEM
> >   This extension is meant to simplify interaction with SPI memories
> >   by providing an high-level interface to send memory-like
> commands.
> >
> > +config SPI_DIRMAP
> > +   bool "SPI direct mapping"
> > +   depends on SPI_MEM
> > +   help
> > + Enable the SPI direct mapping API. Most modern SPI controllers can
> > + directly map a SPI memory (or a portion of the SPI memory) in the CPU
> > + address space. Most of the time this brings significant performance
> > + improvements as it automates the whole process of sending SPI
> memory
> > + operations every time a new region is accessed.
> > +
> >   if DM_SPI
> >
> >   config ALTERA_SPI
> > diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index
> > 9c1ede1b61..8e8995fc53 100644
> > --- a/drivers/spi/spi-mem.c
> > +++ b/drivers/spi/spi-mem.c
> > @@ -21,6 +21,8 @@
> >   #include 
> >   #include 
> >   #include 
> > +#include 
> > +#include 
> >   #endif
> >
> >   #ifndef __UBOOT__
> > @@ -491,6 +493,272 @@ int spi_mem_adjust_op_size(struct spi_slave
> *slave, struct spi_mem_op *op)
> >   }
> >   EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
> >
> > +static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc
> *desc,
> > + u64 offs, size_t len, void *buf) {
> > +   struct spi_mem_op op = desc->info.op_tmpl;
> > +   int ret;
> > +
> > +   op.addr.val = desc->info.offset + offs;
> > +   op.data.buf.in = buf;
> > +   op.data.nbytes = len;
> > +   ret = spi_mem_adjust_op_size(desc->slave, );
> > +   if (ret)
> > +   return ret;
> > +
> > +   ret = spi_mem_exec_op(desc->slave, );
> > +   if (ret)
> > +   return ret;
> > +
> > +   return op.data.nbytes;
> > +}
> > +
> > +static ssize_t spi_mem_no_dirmap_write(struct spi_mem_dirmap_desc
> *desc,
> > +  u64 offs, size_t len, const void *buf) {
> > +   struct spi_mem_op op = desc->info.op_tmpl;
> > +   int ret;
> > +
> > +   op.addr.val = desc->info.offset + offs;
> > +   op.data.buf.out = buf;
> > +   op.data.nbytes = len;
> > +   ret = spi_mem_adjust_op_size(desc->slave, );
> > +   if (ret)
> > +   return ret;
> > +
> > +   ret = spi_mem_exec_op(desc->slave, );
> > +   if (ret)
> > +   return ret;
> > +
> > +   return op.data.nbytes;
> > +}
> > +
> > +/**
> > + * spi_mem_dirmap_create() - Create a direct mapping descriptor
> > + * @mem: SPI mem device this direct mapping should be created for
> > + * @info: direct mapping information
> > + *
> > + * This function is creating a direct mapping descriptor which can
> > +then be used
> > + * to access the memory using spi_mem_dirmap_read() o

RE: [v4 03/12] spi: aspeed: Add ASPEED SPI controller driver

2022-07-03 Thread Chin-Ting Kuo
Hi Cédric,

Thanks for the review.

> -Original Message-
> From: Cédric Le Goater 
> Sent: Friday, July 1, 2022 5:28 PM
> To: Chin-Ting Kuo ; ChiaWei Wang
> ; lu...@denx.de; sean...@gmail.com;
> Ryan Chen ; BMC-SW
> ; ja...@amarulasolutions.com; vigne...@ti.com;
> u-boot@lists.denx.de; p.ya...@ti.com
> Subject: Re: [v4 03/12] spi: aspeed: Add ASPEED SPI controller driver
> 
> Hello Chin-Ting,
> 
> On 5/24/22 07:56, Chin-Ting Kuo wrote:
> > Add ASPEED BMC FMC/SPI memory controller driver with spi-mem interface
> > for AST2500 and AST2600 platform.
> >
> > There are three SPI memory controllers embedded in an ASPEED SoC.
> > - FMC: Named as Firmware Memory Controller. After AC on, MCU ROM
> > fetches initial device boot image from FMC chip select(CS) 0.
> >
> > - SPI1: Play the role of a SPI Master controller. Or, there is a
> >  dedicated path for HOST(X86) to access its BIOS flash mounted
> >  under BMC. spi-aspeed.c implements the control sequence when
> >  SPI1 is a SPI master.
> >
> > - SPI2: It is a pure SPI flash controller. For most scenarios, flashes
> >  mounted under it are for pure storage purpose.
> >
> > ASPEED SPI controller supports 1-1-1, 1-1-2 and 1-1-4 SPI flash mode.
> > Three types of command mode are supported, normal mode, command
> > read/write mode and user mode.
> > - Normal mode: Default mode. After power on, normal read command 03h
> or
> > 13h is used to fetch boot image from SPI flash.
> > - AST2500: Only 03h command can be used after power
> on
> >or reset.
> > - AST2600: If FMC04[6:4] is set, 13h command is used,
> >otherwise, 03h command.
> > The address length is decided by FMC04[2:0].
> >
> > - Command mode: SPI controller can send command and address
> >  automatically when CPU read/write the related
> remapped
> >  or decoded address area. The command used by this
> mode
> >  can be configured by FMC10/14/18[23:16]. Also, the
> >  address length is decided by FMC04[2:0]. This mode
> will
> >  be implemented in the following patch series.
> >
> > - User mode: It is a traditional and pure SPI operation, where
> >   SPI transmission is controlled by CPU. It is the main
> >   mode in this patch.
> >
> > Each SPI controller in ASPEED SoC has its own decoded address mapping.
> > Within each SPI controller decoded address, driver can assign a
> > specific address region for each CS of a SPI controller. The decoded
> > address cannot overlap to each other. With normal mode and command
> > mode, the decoded address accessed by the CPU determines which CS is
> active.
> > When user mode is adopted, the CS decoded address is a FIFO, CPU can
> > send/receive any SPI transmission by accessing the related decoded
> > address for the target CS.
> >
> > Signed-off-by: Chin-Ting Kuo 
> 
> I would split the patch furthermore to ease reading.

Okay, this will be update in the next version.

>   1 - Add basic support
> 
>   with default decoding ranges set for all possible CS, even
>   without a device.
> 
>   WE only have USER mode for now. So it's not important to
>   correctly set the ranges since we won't use them before
>   direct mapping is introduced. They should not overlap,
>   that's all.
> 
>   2 - decoding range adjustments
> 
>   On that topic, we might want to take the simple DT approach
>   with a "ranges" property defining the mapping windows of each
>   CE. I think it is safer than trying to compute perfect ranges
>   like on Linux.
> 
>   3 - clock settings
> 
>   That should simply be the property defined in the DT
> 
> 
> > ---
> > v2: Remove defconfig files from this patch.
> >
> >   drivers/spi/Kconfig  |   8 +
> >   drivers/spi/Makefile |   1 +
> >   drivers/spi/spi-aspeed.c | 822
> +++
> >   3 files changed, 831 insertions(+)
> >   create mode 100644 drivers/spi/spi-aspeed.c
> >
> > diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index
> > a1e515cb2b..a616294910 100644
> > --- a/drivers/spi/Kconfig
> > +++ b/drivers/spi/Kconfig
> > @@ -387,6 +387,14 @@ config SANDBOX_SPI
> > };
> >   };
> >
> > +config SPI_ASPEED
> > +   bool "ASPEED SPI controller driver&qu

RE: [v4 00/12] Add ASPEED SPI controller driver

2022-06-26 Thread Chin-Ting Kuo
Hi Cédric,

> -Original Message-
> From: Cédric Le Goater 
> Sent: Monday, June 27, 2022 12:16 AM
> To: Chin-Ting Kuo ; ChiaWei Wang
> ; lu...@denx.de; sean...@gmail.com;
> Ryan Chen ; BMC-SW
> ; ja...@amarulasolutions.com; vigne...@ti.com;
> u-boot@lists.denx.de; p.ya...@ti.com
> Cc: tr...@konsulko.com
> Subject: Re: [v4 00/12] Add ASPEED SPI controller driver
> 
> On 6/26/22 06:56, Chin-Ting Kuo wrote:
> > Hi All,
> >
> > Are there any comments about this patch series?*
> 
> Sorry, I haven't had time to take a look at the driver. I will try this week.

Okay and thanks for the reply.


Chin-Ting

> 
> Thanks,
> 
> C.
> 
> >
> >
> > Thanks.
> >
> > Best Wishes,
> > Chin-Ting
> >
> >> -Original Message-
> >> From: Chin-Ting Kuo 
> >> Sent: Tuesday, May 24, 2022 1:57 PM
> >> To: ChiaWei Wang ; lu...@denx.de;
> >> sean...@gmail.com; Ryan Chen ; BMC-SW
> >> ; ja...@amarulasolutions.com;
> vigne...@ti.com;
> >> c...@kaod.org; u-boot@lists.denx.de; p.ya...@ti.com
> >> Subject: [v4 00/12] Add ASPEED SPI controller driver
> >>
> >> This patch series aims to porting ASPEED FMC/SPI memory controller
> >> driver with spi-mem interface. spi-mem dirmap framework is also
> >> synchronized from Linux. These patches have been verified on both
> >> AST2600 and AST2500 EVBs.
> >>
> >> Changes in v2:
> >>- Separate defconfig files from the SPI driver patch.
> >>- Use "if (CONFIG_IS_ENABLED(SPI_DIRMAP))" to wrap
> >>  spi_dirmap related functions.
> >>- Add Winbond w25q512jv flash ID.
> >>
> >> Changes in v3:
> >>- Get AHB bus clock frequency from the function parameter.
> >>- Fix a grammatical error in spi-mem.h.
> >>
> >> Changes in v4:
> >>- Fix bug when SPI_NOR_4B_OPCODES flag is set.
> >>
> >> Chin-Ting Kuo (12):
> >>clk: aspeed: Get HCLK frequency support
> >>pinctrl: aspeed: FWSPICS1 and SPI1CS1 pin support
> >>spi: aspeed: Add ASPEED SPI controller driver
> >>configs: aspeed: Enable SPI flash features
> >>MAINTAINERS: Add ASPEED SPI driver file
> >>arm: dts: aspeed: Update SPI flash node settings
> >>spi-mem: Add dirmap API from Linux
> >>mtd: spi-nor: Use spi-mem dirmap API
> >>spi: aspeed: SPI dirmap read support
> >>configs: aspeed: Enable CONFIG_SPI_DIRMAP
> >>mtd: spi-nor-ids: Add Winbond W25Q512JV ID
> >>spi: aspeed: Fix bug when SPI_NOR_4B_OPCODES flag is set
> >>
> >>   MAINTAINERS  |   7 +
> >>   arch/arm/dts/ast2500-evb.dts |  33 +
> >>   arch/arm/dts/ast2500.dtsi|  23 +-
> >>   arch/arm/dts/ast2600-evb.dts |   8 -
> >>   arch/arm/dts/ast2600.dtsi|  34 +-
> >>   configs/evb-ast2500_defconfig|  14 +
> >>   configs/evb-ast2600_defconfig|  14 +
> >>   drivers/clk/aspeed/clk_ast2500.c |  23 +
> >>   drivers/mtd/spi/sf_probe.c   |  76 ++
> >>   drivers/mtd/spi/spi-nor-core.c   |  55 +-
> >>   drivers/mtd/spi/spi-nor-ids.c|   5 +
> >>   drivers/pinctrl/aspeed/pinctrl_ast2500.c |   2 +
> >>   drivers/spi/Kconfig  |  18 +
> >>   drivers/spi/Makefile |   1 +
> >>   drivers/spi/spi-aspeed.c | 914
> >> +++
> >>   drivers/spi/spi-mem.c| 268 +++
> >>   include/linux/mtd/spi-nor.h  |  18 +
> >>   include/spi-mem.h|  79 ++
> >>   18 files changed, 1546 insertions(+), 46 deletions(-)  create mode
> >> 100644 drivers/spi/spi-aspeed.c
> >>
> >> --
> >> 2.25.1
> >



RE: [v4 00/12] Add ASPEED SPI controller driver

2022-06-25 Thread Chin-Ting Kuo
Hi All,

Are there any comments about this patch series?


Thanks.

Best Wishes,
Chin-Ting

> -Original Message-
> From: Chin-Ting Kuo 
> Sent: Tuesday, May 24, 2022 1:57 PM
> To: ChiaWei Wang ; lu...@denx.de;
> sean...@gmail.com; Ryan Chen ; BMC-SW
> ; ja...@amarulasolutions.com; vigne...@ti.com;
> c...@kaod.org; u-boot@lists.denx.de; p.ya...@ti.com
> Subject: [v4 00/12] Add ASPEED SPI controller driver
> 
> This patch series aims to porting ASPEED FMC/SPI memory controller driver
> with spi-mem interface. spi-mem dirmap framework is also synchronized from
> Linux. These patches have been verified on both
> AST2600 and AST2500 EVBs.
> 
> Changes in v2:
>   - Separate defconfig files from the SPI driver patch.
>   - Use "if (CONFIG_IS_ENABLED(SPI_DIRMAP))" to wrap
> spi_dirmap related functions.
>   - Add Winbond w25q512jv flash ID.
> 
> Changes in v3:
>   - Get AHB bus clock frequency from the function parameter.
>   - Fix a grammatical error in spi-mem.h.
> 
> Changes in v4:
>   - Fix bug when SPI_NOR_4B_OPCODES flag is set.
> 
> Chin-Ting Kuo (12):
>   clk: aspeed: Get HCLK frequency support
>   pinctrl: aspeed: FWSPICS1 and SPI1CS1 pin support
>   spi: aspeed: Add ASPEED SPI controller driver
>   configs: aspeed: Enable SPI flash features
>   MAINTAINERS: Add ASPEED SPI driver file
>   arm: dts: aspeed: Update SPI flash node settings
>   spi-mem: Add dirmap API from Linux
>   mtd: spi-nor: Use spi-mem dirmap API
>   spi: aspeed: SPI dirmap read support
>   configs: aspeed: Enable CONFIG_SPI_DIRMAP
>   mtd: spi-nor-ids: Add Winbond W25Q512JV ID
>   spi: aspeed: Fix bug when SPI_NOR_4B_OPCODES flag is set
> 
>  MAINTAINERS  |   7 +
>  arch/arm/dts/ast2500-evb.dts |  33 +
>  arch/arm/dts/ast2500.dtsi|  23 +-
>  arch/arm/dts/ast2600-evb.dts |   8 -
>  arch/arm/dts/ast2600.dtsi|  34 +-
>  configs/evb-ast2500_defconfig|  14 +
>  configs/evb-ast2600_defconfig|  14 +
>  drivers/clk/aspeed/clk_ast2500.c |  23 +
>  drivers/mtd/spi/sf_probe.c   |  76 ++
>  drivers/mtd/spi/spi-nor-core.c   |  55 +-
>  drivers/mtd/spi/spi-nor-ids.c|   5 +
>  drivers/pinctrl/aspeed/pinctrl_ast2500.c |   2 +
>  drivers/spi/Kconfig  |  18 +
>  drivers/spi/Makefile |   1 +
>  drivers/spi/spi-aspeed.c | 914
> +++
>  drivers/spi/spi-mem.c| 268 +++
>  include/linux/mtd/spi-nor.h  |  18 +
>  include/spi-mem.h|  79 ++
>  18 files changed, 1546 insertions(+), 46 deletions(-)  create mode 100644
> drivers/spi/spi-aspeed.c
> 
> --
> 2.25.1



[v4 06/12] arm: dts: aspeed: Update SPI flash node settings

2022-05-24 Thread Chin-Ting Kuo
For both AST2500 and AST2600, there are three
SPI controllers, FMC(Firmware Memory Controller),
SPI1 and SPI2. The clock source is HCLK. Following
is the basic information for ASPEED SPI controller.

AST2500:
  - FMC:
  CS number: 3
  controller reg: 0x1e62 - 0x1e62
  decoded address: 0x2000 - 0x2fff

  - SPI1:
  CS number: 2
  controller reg: 0x1e63 - 0x1e630fff
  decoded address: 0x3000 - 0x37ff

  - SPI2:
  CS number: 2
  controller reg: 0x1e631000 - 0x1e631fff
  decoded address: 0x3800 - 0x3fff

AST2600:
  - FMC:
  CS number: 3
  controller reg: 0x1e62 - 0x1e62
  decoded address: 0x2000 - 0x2fff

  - SPI1:
  CS number: 2
  controller reg: 0x1e63 - 0x1e630fff
  decoded address: 0x3000 - 0x3fff

  - SPI2:
  CS number: 3
  controller reg: 0x1e631000 - 0x1e631fff
  decoded address: 0x5000 - 0x5fff

Signed-off-by: Chin-Ting Kuo 
---
 arch/arm/dts/ast2500-evb.dts | 33 +
 arch/arm/dts/ast2500.dtsi| 23 ---
 arch/arm/dts/ast2600-evb.dts |  8 
 arch/arm/dts/ast2600.dtsi| 34 +++---
 4 files changed, 68 insertions(+), 30 deletions(-)

diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
index 4796ed445f..c6b7675902 100644
--- a/arch/arm/dts/ast2500-evb.dts
+++ b/arch/arm/dts/ast2500-evb.dts
@@ -73,3 +73,36 @@
pinctrl-names = "default";
pinctrl-0 = <_sd2_default>;
 };
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_fwspics1_default>;
+
+   flash@0 {
+   status = "okay";
+   spi-max-frequency = <5000>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+
+   flash@1 {
+   status = "okay";
+   spi-max-frequency = <5000>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+};
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_spi1cs1_default>;
+
+   flash@0 {
+   status = "okay";
+   spi-max-frequency = <5000>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+};
diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
index ee66ef6704..d78a53aeb7 100644
--- a/arch/arm/dts/ast2500.dtsi
+++ b/arch/arm/dts/ast2500.dtsi
@@ -57,23 +57,26 @@
ranges;
 
fmc: flash-controller@1e62 {
-   reg = < 0x1e62 0xc4
-   0x2000 0x1000 >;
+   reg = <0x1e62 0xc4>, <0x2000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
compatible = "aspeed,ast2500-fmc";
+   clocks = < ASPEED_CLK_AHB>;
+   num-cs = <3>;
status = "disabled";
-   interrupts = <19>;
+
flash@0 {
reg = < 0 >;
compatible = "jedec,spi-nor";
status = "disabled";
};
+
flash@1 {
reg = < 1 >;
compatible = "jedec,spi-nor";
status = "disabled";
};
+
flash@2 {
reg = < 2 >;
compatible = "jedec,spi-nor";
@@ -82,17 +85,20 @@
};
 
spi1: flash-controller@1e63 {
-   reg = < 0x1e63 0xc4
-   0x3000 0x0800 >;
+   reg = <0x1e63 0xc4>, <0x3000 0x0800>;
#address-cells = <1>;
#size-cells = <0>;
compatible = "aspeed,ast2500-spi";
+   clocks = < ASPEED_CLK_AHB>;
+   num-cs = <2>;
status = "disabled";
+
flash@0 {
reg = < 0 >;
compatible = "jedec,spi-nor";
status = "disabled";
};
+
flash@1 {
reg = < 1 >;
compat

[v4 09/12] spi: aspeed: SPI dirmap read support

2022-05-24 Thread Chin-Ting Kuo
>From the HW point of view, the performance of
command read mode is greater than user mode slightly.
Thus, dirmap read framework is introduced to achieve
this goal.

In dirmap_create, a specific decoded address area with
flash size is assigned to each CS. CPU can thus access
the SPI flash as normal memory in dirmap_read function.

Signed-off-by: Chin-Ting Kuo 
---
 drivers/spi/spi-aspeed.c | 93 
 1 file changed, 93 insertions(+)

diff --git a/drivers/spi/spi-aspeed.c b/drivers/spi/spi-aspeed.c
index 9574aff793..e5e348eb7b 100644
--- a/drivers/spi/spi-aspeed.c
+++ b/drivers/spi/spi-aspeed.c
@@ -85,6 +85,8 @@ struct aspeed_spi_info {
 
 static int aspeed_spi_trim_decoded_size(struct udevice *bus,
u32 decoded_sz_arr[]);
+static int aspeed_spi_decoded_range_config(struct udevice *bus,
+  u32 decoded_sz_arr[]);
 
 static u32 aspeed_spi_get_io_mode(u32 bus_width)
 {
@@ -509,6 +511,95 @@ static int aspeed_spi_exec_op_user_mode(struct spi_slave 
*slave,
return 0;
 }
 
+static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
+{
+   int ret = 0;
+   struct udevice *dev = desc->slave->dev;
+   struct udevice *bus = dev->parent;
+   struct aspeed_spi_plat *plat = dev_get_plat(bus);
+   struct aspeed_spi_priv *priv = dev_get_priv(bus);
+   struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
+   const struct aspeed_spi_info *info = priv->info;
+   struct spi_mem_op op_tmpl = desc->info.op_tmpl;
+   u32 i;
+   u32 cs = slave_plat->cs;
+   u32 decoded_sz_arr[ASPEED_SPI_MAX_CS];
+   u32 reg_val;
+
+   if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN) {
+   for (i = 0; i < priv->num_cs; i++) {
+   reg_val = readl(plat->ctrl_base +
+   REG_CE0_DECODED_ADDR_REG + i * 4);
+   decoded_sz_arr[i] =
+   info->segment_end(bus, reg_val) -
+   info->segment_start(bus, reg_val);
+   }
+
+   decoded_sz_arr[cs] = desc->info.length;
+
+   if (info->adjust_decoded_sz)
+   info->adjust_decoded_sz(bus, decoded_sz_arr);
+
+   for (i = 0; i < priv->num_cs; i++) {
+   dev_dbg(dev, "cs: %d, sz: 0x%x\n", i,
+   decoded_sz_arr[i]);
+   }
+
+   ret = aspeed_spi_decoded_range_config(bus, decoded_sz_arr);
+   if (ret)
+   return ret;
+
+   reg_val = readl(plat->ctrl_base + REG_CE0_CTRL_REG + cs * 4) &
+ (~info->cmd_io_ctrl_mask);
+   reg_val |= aspeed_spi_get_io_mode(op_tmpl.data.buswidth) |
+  op_tmpl.cmd.opcode << 16 |
+  ((op_tmpl.dummy.nbytes) & 0x3) << 6 |
+  ((op_tmpl.dummy.nbytes) & 0x4) << 14 |
+  CTRL_IO_MODE_CMD_READ;
+
+   writel(reg_val,
+  plat->ctrl_base + REG_CE0_CTRL_REG + cs * 4);
+   priv->flashes[cs].ce_ctrl_read = reg_val;
+
+   dev_dbg(dev, "read bus width: %d [0x%08x]\n",
+   op_tmpl.data.buswidth, priv->flashes[cs].ce_ctrl_read);
+   } else {
+   /*
+* dirmap_write is not supported currently due to a HW
+* limitation for command write mode: The written data
+* length should be multiple of 4-byte.
+*/
+   return -EOPNOTSUPP;
+   }
+
+   return ret;
+}
+
+static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ u64 offs, size_t len, void *buf)
+{
+   struct udevice *dev = desc->slave->dev;
+   struct aspeed_spi_priv *priv = dev_get_priv(dev->parent);
+   struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
+   u32 cs = slave_plat->cs;
+   int ret;
+
+   dev_dbg(dev, "read op:0x%x, addr:0x%llx, len:0x%x\n",
+   desc->info.op_tmpl.cmd.opcode, offs, len);
+
+   if (priv->flashes[cs].ahb_win_sz < offs + len ||
+   (offs + len) % 4 != 0) {
+   ret = aspeed_spi_exec_op_user_mode(desc->slave,
+  >info.op_tmpl);
+   if (ret != 0)
+   return 0;
+   } else {
+   memcpy_fromio(buf, priv->flashes[cs].ahb_base + offs, len);
+   }
+
+   return len;
+}
+
 static struct aspeed_spi_flash *aspeed_spi_get_flash(struct udevice *dev)
 {
struct udevice *bus = dev->parent;
@@ -792,6 +883,8 @@ static int aspeed

[v4 07/12] spi-mem: Add dirmap API from Linux

2022-05-24 Thread Chin-Ting Kuo
This adds the dirmap API originally introduced in Linux commit aa167f3
("spi: spi-mem: Add a new API to support direct mapping"). This also
includes several follow-up patches and fixes.

Changes from Linux include:
* Added Kconfig option
* Changed struct device to struct udevice
* Changed struct spi_mem to struct spi_slave

This patch is obtained from the following patch
https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504-3-sean...@gmail.com/

Signed-off-by: Chin-Ting Kuo 
Signed-off-by: Sean Anderson 
Acked-by: Pratyush Yadav 
---
v2: Remove "#if CONFIG_SPI_DIRMAP" compile wrapper.
v3: Fix a grammatical error in spi-mem.h.

 drivers/spi/Kconfig   |  10 ++
 drivers/spi/spi-mem.c | 268 ++
 include/spi-mem.h |  79 +
 3 files changed, 357 insertions(+)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index a616294910..297253714a 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -40,6 +40,16 @@ config SPI_MEM
  This extension is meant to simplify interaction with SPI memories
  by providing an high-level interface to send memory-like commands.
 
+config SPI_DIRMAP
+   bool "SPI direct mapping"
+   depends on SPI_MEM
+   help
+ Enable the SPI direct mapping API. Most modern SPI controllers can
+ directly map a SPI memory (or a portion of the SPI memory) in the CPU
+ address space. Most of the time this brings significant performance
+ improvements as it automates the whole process of sending SPI memory
+ operations every time a new region is accessed.
+
 if DM_SPI
 
 config ALTERA_SPI
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 9c1ede1b61..8e8995fc53 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -21,6 +21,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #endif
 
 #ifndef __UBOOT__
@@ -491,6 +493,272 @@ int spi_mem_adjust_op_size(struct spi_slave *slave, 
struct spi_mem_op *op)
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
 
+static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ u64 offs, size_t len, void *buf)
+{
+   struct spi_mem_op op = desc->info.op_tmpl;
+   int ret;
+
+   op.addr.val = desc->info.offset + offs;
+   op.data.buf.in = buf;
+   op.data.nbytes = len;
+   ret = spi_mem_adjust_op_size(desc->slave, );
+   if (ret)
+   return ret;
+
+   ret = spi_mem_exec_op(desc->slave, );
+   if (ret)
+   return ret;
+
+   return op.data.nbytes;
+}
+
+static ssize_t spi_mem_no_dirmap_write(struct spi_mem_dirmap_desc *desc,
+  u64 offs, size_t len, const void *buf)
+{
+   struct spi_mem_op op = desc->info.op_tmpl;
+   int ret;
+
+   op.addr.val = desc->info.offset + offs;
+   op.data.buf.out = buf;
+   op.data.nbytes = len;
+   ret = spi_mem_adjust_op_size(desc->slave, );
+   if (ret)
+   return ret;
+
+   ret = spi_mem_exec_op(desc->slave, );
+   if (ret)
+   return ret;
+
+   return op.data.nbytes;
+}
+
+/**
+ * spi_mem_dirmap_create() - Create a direct mapping descriptor
+ * @mem: SPI mem device this direct mapping should be created for
+ * @info: direct mapping information
+ *
+ * This function is creating a direct mapping descriptor which can then be used
+ * to access the memory using spi_mem_dirmap_read() or spi_mem_dirmap_write().
+ * If the SPI controller driver does not support direct mapping, this function
+ * falls back to an implementation using spi_mem_exec_op(), so that the caller
+ * doesn't have to bother implementing a fallback on his own.
+ *
+ * Return: a valid pointer in case of success, and ERR_PTR() otherwise.
+ */
+struct spi_mem_dirmap_desc *
+spi_mem_dirmap_create(struct spi_slave *slave,
+ const struct spi_mem_dirmap_info *info)
+{
+   struct udevice *bus = slave->dev->parent;
+   struct dm_spi_ops *ops = spi_get_ops(bus);
+   struct spi_mem_dirmap_desc *desc;
+   int ret = -EOPNOTSUPP;
+
+   /* Make sure the number of address cycles is between 1 and 8 bytes. */
+   if (!info->op_tmpl.addr.nbytes || info->op_tmpl.addr.nbytes > 8)
+   return ERR_PTR(-EINVAL);
+
+   /* data.dir should either be SPI_MEM_DATA_IN or SPI_MEM_DATA_OUT. */
+   if (info->op_tmpl.data.dir == SPI_MEM_NO_DATA)
+   return ERR_PTR(-EINVAL);
+
+   desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+   if (!desc)
+   return ERR_PTR(-ENOMEM);
+
+   desc->slave = slave;
+   desc->info = *info;
+   if (ops->mem_ops && ops->mem_ops->dirmap_create)
+   ret = ops->mem_ops->dirmap_create(desc);
+
+   if (ret) {
+   desc->nodirmap = true;
+   if (!spi_mem_

[v4 08/12] mtd: spi-nor: Use spi-mem dirmap API

2022-05-24 Thread Chin-Ting Kuo
This adds support for the dirmap API to the spi-nor subsystem, as
introduced in Linux commit df5c210 ("mtd: spi-nor: use spi-mem
dirmap API").

This patch is synchronize from the following patch
https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504-4-sean...@gmail.com/

Signed-off-by: Chin-Ting Kuo 
Signed-off-by: Sean Anderson 
Acked-by: Pratyush Yadav 
---
v2: Use "if (CONFIG_IS_ENABLED(SPI_DIRMAP))" to wrap
spi_dirmap related functions.

 drivers/mtd/spi/sf_probe.c | 76 ++
 drivers/mtd/spi/spi-nor-core.c | 55 +---
 include/linux/mtd/spi-nor.h| 18 
 3 files changed, 133 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index f461082e03..e192f97efd 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -10,13 +10,69 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include "sf_internal.h"
 
+static int spi_nor_create_read_dirmap(struct spi_nor *nor)
+{
+   struct spi_mem_dirmap_info info = {
+   .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),
+ SPI_MEM_OP_ADDR(nor->addr_width, 0, 0),
+ SPI_MEM_OP_DUMMY(nor->read_dummy, 0),
+ SPI_MEM_OP_DATA_IN(0, NULL, 0)),
+   .offset = 0,
+   .length = nor->mtd.size,
+   };
+   struct spi_mem_op *op = _tmpl;
+
+   /* get transfer protocols. */
+   spi_nor_setup_op(nor, op, nor->read_proto);
+   op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto);
+
+   /* convert the dummy cycles to the number of bytes */
+   op->dummy.nbytes = (nor->read_dummy * op->dummy.buswidth) / 8;
+   if (spi_nor_protocol_is_dtr(nor->read_proto))
+   op->dummy.nbytes *= 2;
+
+   nor->dirmap.rdesc = spi_mem_dirmap_create(nor->spi, );
+   if (IS_ERR(nor->dirmap.rdesc))
+   return PTR_ERR(nor->dirmap.rdesc);
+
+   return 0;
+}
+
+static int spi_nor_create_write_dirmap(struct spi_nor *nor)
+{
+   struct spi_mem_dirmap_info info = {
+   .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 0),
+ SPI_MEM_OP_ADDR(nor->addr_width, 0, 0),
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_DATA_OUT(0, NULL, 0)),
+   .offset = 0,
+   .length = nor->mtd.size,
+   };
+   struct spi_mem_op *op = _tmpl;
+
+   /* get transfer protocols. */
+   spi_nor_setup_op(nor, op, nor->write_proto);
+   op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);
+
+   if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
+   op->addr.nbytes = 0;
+
+   nor->dirmap.wdesc = spi_mem_dirmap_create(nor->spi, );
+   if (IS_ERR(nor->dirmap.wdesc))
+   return PTR_ERR(nor->dirmap.wdesc);
+
+   return 0;
+}
+
 /**
  * spi_flash_probe_slave() - Probe for a SPI flash device on a bus
  *
@@ -45,6 +101,16 @@ static int spi_flash_probe_slave(struct spi_flash *flash)
if (ret)
goto err_read_id;
 
+   if (CONFIG_IS_ENABLED(SPI_DIRMAP)) {
+   ret = spi_nor_create_read_dirmap(flash);
+   if (ret)
+   return ret;
+
+   ret = spi_nor_create_write_dirmap(flash);
+   if (ret)
+   return ret;
+   }
+
if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
ret = spi_flash_mtd_register(flash);
 
@@ -83,6 +149,11 @@ struct spi_flash *spi_flash_probe(unsigned int busnum, 
unsigned int cs,
 
 void spi_flash_free(struct spi_flash *flash)
 {
+   if (CONFIG_IS_ENABLED(SPI_DIRMAP)) {
+   spi_mem_dirmap_destroy(flash->dirmap.wdesc);
+   spi_mem_dirmap_destroy(flash->dirmap.rdesc);
+   }
+
if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
spi_flash_mtd_unregister(flash);
 
@@ -153,6 +224,11 @@ static int spi_flash_std_remove(struct udevice *dev)
struct spi_flash *flash = dev_get_uclass_priv(dev);
int ret;
 
+   if (CONFIG_IS_ENABLED(SPI_DIRMAP)) {
+   spi_mem_dirmap_destroy(flash->dirmap.wdesc);
+   spi_mem_dirmap_destroy(flash->dirmap.rdesc);
+   }
+
ret = spi_nor_remove(flash);
if (ret)
return ret;
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 3b7c817c02..0c6262b7fd 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -239,9 +239,9 @@ static u8 spi_nor_get_cmd_ext(const struct spi_nor *nor,
  * need to be initialize

[v4 11/12] mtd: spi-nor-ids: Add Winbond W25Q512JV ID

2022-05-23 Thread Chin-Ting Kuo
Add ID for Winbond W25Q512JV device which is supported
on AST2600 EVB by default.

Signed-off-by: Chin-Ting Kuo 
---
 drivers/mtd/spi/spi-nor-ids.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 7050ddc397..444affb5af 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -362,6 +362,11 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
+   {
+   INFO("w25q512jv", 0xef4020, 0, 64 * 1024, 1024,
+SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+   },
{
INFO("w25q01jv", 0xef4021, 0, 64 * 1024, 2048,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-- 
2.25.1



[v4 12/12] spi: aspeed: Fix bug when SPI_NOR_4B_OPCODES flag is set

2022-05-23 Thread Chin-Ting Kuo
When SPI_NOR_4B_OPCODES flag is set for a specific flash
in spi_nor_ids[] table, EN4B command will not be issued and
4-byte dedicated commands will be used to access SPI flash.
Thus, instead of EN4B command, address length is more suitable
for deciding whether the controller should be set to 4-byte mode.

Signed-off-by: Chin-Ting Kuo 
---
 drivers/spi/spi-aspeed.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-aspeed.c b/drivers/spi/spi-aspeed.c
index e5e348eb7b..687ddc370b 100644
--- a/drivers/spi/spi-aspeed.c
+++ b/drivers/spi/spi-aspeed.c
@@ -504,10 +504,6 @@ static int aspeed_spi_exec_op_user_mode(struct spi_slave 
*slave,
/* Restore controller setting. */
writel(flash->ce_ctrl_read, ctrl_reg);
 
-   /* Set controller to 4-byte mode when flash is in 4-byte mode. */
-   if (op->cmd.opcode == SPINOR_OP_EN4B)
-   priv->info->set_4byte(bus, cs);
-
return 0;
 }
 
@@ -561,6 +557,9 @@ static int aspeed_spi_dirmap_create(struct 
spi_mem_dirmap_desc *desc)
   plat->ctrl_base + REG_CE0_CTRL_REG + cs * 4);
priv->flashes[cs].ce_ctrl_read = reg_val;
 
+   if (op_tmpl.addr.nbytes == 4)
+   priv->info->set_4byte(bus, cs);
+
dev_dbg(dev, "read bus width: %d [0x%08x]\n",
op_tmpl.data.buswidth, priv->flashes[cs].ce_ctrl_read);
} else {
-- 
2.25.1



[v4 10/12] configs: aspeed: Enable CONFIG_SPI_DIRMAP

2022-05-23 Thread Chin-Ting Kuo
Enable CONFIG_SPI_DIRMAP on ASPEED platforms.

Signed-off-by: Chin-Ting Kuo 
---
 configs/evb-ast2500_defconfig | 1 +
 configs/evb-ast2600_defconfig | 1 +
 2 files changed, 2 insertions(+)

diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index fd04fe5a60..097b991a1b 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -56,6 +56,7 @@ CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
+CONFIG_SPI_DIRMAP=y
 CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_TIMER=y
diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig
index ccf63ec6d0..7caa04d5b7 100644
--- a/configs/evb-ast2600_defconfig
+++ b/configs/evb-ast2600_defconfig
@@ -89,6 +89,7 @@ CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
+CONFIG_SPI_DIRMAP=y
 CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
-- 
2.25.1



[v4 02/12] pinctrl: aspeed: FWSPICS1 and SPI1CS1 pin support

2022-05-23 Thread Chin-Ting Kuo
Add FWSPICS1 and SPI1CS1 in AST2500 pinctrl group.
On AST2500 EVB, FWSPICS1 can be supported by default.
An extra jumper, J45, should be configured before
enabling SPI1CS1.

Signed-off-by: Chin-Ting Kuo 
Reviewed-by: Cédric Le Goater 
---
 drivers/pinctrl/aspeed/pinctrl_ast2500.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pinctrl/aspeed/pinctrl_ast2500.c 
b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
index 3c2e10b88e..93920a6389 100644
--- a/drivers/pinctrl/aspeed/pinctrl_ast2500.c
+++ b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
@@ -61,6 +61,8 @@ static const struct ast2500_group_config ast2500_groups[] = {
{ "MDIO2", 5, (1 << 2) },
{ "SD1", 5, (1 << 0) },
{ "SD2", 5, (1 << 1) },
+   { "FWSPICS1", 3, (1 << 24) },
+   { "SPI1CS1", 1, (1 << 15) },
 };
 
 static int ast2500_pinctrl_get_groups_count(struct udevice *dev)
-- 
2.25.1



[v4 05/12] MAINTAINERS: Add ASPEED SPI driver file

2022-05-23 Thread Chin-Ting Kuo
Add spi-aspeed.c file for ARM ASPEED.

Signed-off-by: Chin-Ting Kuo 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 56be0bfad0..f2cd707eda 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -688,6 +688,13 @@ S: Maintained
 F: drivers/pci/pcie_phytium.c
 F: arch/arm/dts/phytium-durian.dts
 
+ASPEED FMC SPI DRIVER
+M: Chin-Ting Kuo 
+M: Cédric Le Goater 
+R: Aspeed BMC SW team 
+S: Maintained
+F: drivers/spi/spi-aspeed.c
+
 BINMAN
 M: Simon Glass 
 M: Alper Nebi Yasak 
-- 
2.25.1



[v4 03/12] spi: aspeed: Add ASPEED SPI controller driver

2022-05-23 Thread Chin-Ting Kuo
Add ASPEED BMC FMC/SPI memory controller driver with
spi-mem interface for AST2500 and AST2600 platform.

There are three SPI memory controllers embedded in an ASPEED SoC.
- FMC: Named as Firmware Memory Controller. After AC on, MCU ROM
   fetches initial device boot image from FMC chip select(CS) 0.

- SPI1: Play the role of a SPI Master controller. Or, there is a
dedicated path for HOST(X86) to access its BIOS flash mounted
under BMC. spi-aspeed.c implements the control sequence when
SPI1 is a SPI master.

- SPI2: It is a pure SPI flash controller. For most scenarios, flashes
mounted under it are for pure storage purpose.

ASPEED SPI controller supports 1-1-1, 1-1-2 and 1-1-4 SPI flash mode.
Three types of command mode are supported, normal mode, command
read/write mode and user mode.
- Normal mode: Default mode. After power on, normal read command 03h or
   13h is used to fetch boot image from SPI flash.
   - AST2500: Only 03h command can be used after power on
  or reset.
   - AST2600: If FMC04[6:4] is set, 13h command is used,
  otherwise, 03h command.
   The address length is decided by FMC04[2:0].

- Command mode: SPI controller can send command and address
automatically when CPU read/write the related remapped
or decoded address area. The command used by this mode
can be configured by FMC10/14/18[23:16]. Also, the
address length is decided by FMC04[2:0]. This mode will
be implemented in the following patch series.

- User mode: It is a traditional and pure SPI operation, where
 SPI transmission is controlled by CPU. It is the main
 mode in this patch.

Each SPI controller in ASPEED SoC has its own decoded address mapping.
Within each SPI controller decoded address, driver can assign a specific
address region for each CS of a SPI controller. The decoded address
cannot overlap to each other. With normal mode and command mode, the
decoded address accessed by the CPU determines which CS is active.
When user mode is adopted, the CS decoded address is a FIFO, CPU can
send/receive any SPI transmission by accessing the related decoded
address for the target CS.

Signed-off-by: Chin-Ting Kuo 
---
v2: Remove defconfig files from this patch.

 drivers/spi/Kconfig  |   8 +
 drivers/spi/Makefile |   1 +
 drivers/spi/spi-aspeed.c | 822 +++
 3 files changed, 831 insertions(+)
 create mode 100644 drivers/spi/spi-aspeed.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index a1e515cb2b..a616294910 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -387,6 +387,14 @@ config SANDBOX_SPI
};
  };
 
+config SPI_ASPEED
+   bool "ASPEED SPI controller driver"
+   depends on DM_SPI && SPI_MEM
+   default n
+   help
+ Enable ASPEED SPI controller driver for AST2500
+ and AST2600 SoCs.
+
 config SPI_SIFIVE
bool "SiFive SPI driver"
help
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 06e81b465b..36a4bd5dce 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -9,6 +9,7 @@ obj-y += spi-uclass.o
 obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o
 obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o
 obj-$(CONFIG_SOFT_SPI) += soft_spi.o
+obj-$(CONFIG_SPI_ASPEED) += spi-aspeed.o
 obj-$(CONFIG_SPI_MEM) += spi-mem.o
 obj-$(CONFIG_TI_QSPI) += ti_qspi.o
 obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o
diff --git a/drivers/spi/spi-aspeed.c b/drivers/spi/spi-aspeed.c
new file mode 100644
index 00..9574aff793
--- /dev/null
+++ b/drivers/spi/spi-aspeed.c
@@ -0,0 +1,822 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * ASPEED FMC/SPI Controller driver
+ *
+ * Copyright (c) 2022 ASPEED Corporation.
+ * Copyright (c) 2022 IBM Corporation.
+ *
+ * Author:
+ * Chin-Ting Kuo 
+ * Cedric Le Goater 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* ASPEED FMC/SPI memory control register related */
+#define REG_CE_TYPE_SETTING  0x00
+#define REG_CE_ADDR_MODE_CTRL0x04
+#define REG_INTR_CTRL_STATUS 0x08
+#define REG_CE0_CTRL_REG 0x10
+#define REG_CE0_DECODED_ADDR_REG 0x30
+
+#define ASPEED_SPI_MAX_CS   3
+#define FLASH_CALIBRATION_LEN   0x400
+
+#define CTRL_IO_SINGLE_DATA 0
+#define CTRL_IO_QUAD_DATA   BIT(30)
+#define CTRL_IO_DUAL_DATA   BIT(29)
+
+#define CTRL_IO_MODE_USER   GENMASK(1, 0)
+#define CTRL_IO_MODE_CMD_READ   BIT(0)
+#define CTRL_IO_MODE_CMD_WRITE  BIT(1)
+#define CTRL_STOP_ACTIVEBIT(2)
+
+struct aspeed_spi_plat {
+   fdt_addr_t ctrl_base;
+   void __iomem *ahb_base; /* AHB address base for all flash devices. 

[v4 04/12] configs: aspeed: Enable SPI flash features

2022-05-23 Thread Chin-Ting Kuo
- Enable ASPEED SPI controller driver.
- Enable SPI flash memory configurations.
- Enable configurations for SPI flash manufacturers
  supported on both ASPEED AST2500 and AST2600 AVL.

Signed-off-by: Chin-Ting Kuo 
---
 configs/evb-ast2500_defconfig | 13 +
 configs/evb-ast2600_defconfig | 13 +
 2 files changed, 26 insertions(+)

diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index 2371cc2742..fd04fe5a60 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -35,6 +35,16 @@ CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_ASPEED=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
 CONFIG_FTGMAC100=y
@@ -44,6 +54,9 @@ CONFIG_RAM=y
 CONFIG_DM_RESET=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_TIMER=y
 CONFIG_WDT=y
diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig
index f84b723bbb..ccf63ec6d0 100644
--- a/configs/evb-ast2600_defconfig
+++ b/configs/evb-ast2600_defconfig
@@ -65,6 +65,16 @@ CONFIG_DM_I2C=y
 CONFIG_MISC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
 CONFIG_DM_MDIO=y
@@ -77,6 +87,9 @@ CONFIG_SPL_RAM=y
 CONFIG_DM_RESET=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_WDT=y
-- 
2.25.1



[v4 00/12] Add ASPEED SPI controller driver

2022-05-23 Thread Chin-Ting Kuo
This patch series aims to porting ASPEED FMC/SPI memory controller
driver with spi-mem interface. spi-mem dirmap framework is also
synchronized from Linux. These patches have been verified on both
AST2600 and AST2500 EVBs.

Changes in v2:
  - Separate defconfig files from the SPI driver patch.
  - Use "if (CONFIG_IS_ENABLED(SPI_DIRMAP))" to wrap
spi_dirmap related functions.
  - Add Winbond w25q512jv flash ID.

Changes in v3:
  - Get AHB bus clock frequency from the function parameter.
  - Fix a grammatical error in spi-mem.h.

Changes in v4:
  - Fix bug when SPI_NOR_4B_OPCODES flag is set.

Chin-Ting Kuo (12):
  clk: aspeed: Get HCLK frequency support
  pinctrl: aspeed: FWSPICS1 and SPI1CS1 pin support
  spi: aspeed: Add ASPEED SPI controller driver
  configs: aspeed: Enable SPI flash features
  MAINTAINERS: Add ASPEED SPI driver file
  arm: dts: aspeed: Update SPI flash node settings
  spi-mem: Add dirmap API from Linux
  mtd: spi-nor: Use spi-mem dirmap API
  spi: aspeed: SPI dirmap read support
  configs: aspeed: Enable CONFIG_SPI_DIRMAP
  mtd: spi-nor-ids: Add Winbond W25Q512JV ID
  spi: aspeed: Fix bug when SPI_NOR_4B_OPCODES flag is set

 MAINTAINERS  |   7 +
 arch/arm/dts/ast2500-evb.dts |  33 +
 arch/arm/dts/ast2500.dtsi|  23 +-
 arch/arm/dts/ast2600-evb.dts |   8 -
 arch/arm/dts/ast2600.dtsi|  34 +-
 configs/evb-ast2500_defconfig|  14 +
 configs/evb-ast2600_defconfig|  14 +
 drivers/clk/aspeed/clk_ast2500.c |  23 +
 drivers/mtd/spi/sf_probe.c   |  76 ++
 drivers/mtd/spi/spi-nor-core.c   |  55 +-
 drivers/mtd/spi/spi-nor-ids.c|   5 +
 drivers/pinctrl/aspeed/pinctrl_ast2500.c |   2 +
 drivers/spi/Kconfig  |  18 +
 drivers/spi/Makefile |   1 +
 drivers/spi/spi-aspeed.c | 914 +++
 drivers/spi/spi-mem.c| 268 +++
 include/linux/mtd/spi-nor.h  |  18 +
 include/spi-mem.h|  79 ++
 18 files changed, 1546 insertions(+), 46 deletions(-)
 create mode 100644 drivers/spi/spi-aspeed.c

-- 
2.25.1



[v4 01/12] clk: aspeed: Get HCLK frequency support

2022-05-23 Thread Chin-Ting Kuo
User can get correct HCLK frequency during driver probe stage
by adding the following configuration in the device tree.
"clocks = < ASPEED_CLK_AHB>".

Signed-off-by: Chin-Ting Kuo 
Reviewed-by: Cédric Le Goater 
---
v3: Get AHB bus clock frequency from the function parameter.

 drivers/clk/aspeed/clk_ast2500.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
index a1b4496ca2..d99964fcd7 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -29,6 +29,12 @@
 
 #define D2PLL_DEFAULT_RATE (250 * 1000 * 1000)
 
+/*
+ * AXI/AHB clock selection, taken from Aspeed SDK
+ */
+#define SCU_HWSTRAP_AXIAHB_DIV_SHIFT9
+#define SCU_HWSTRAP_AXIAHB_DIV_MASK (0x7 << SCU_HWSTRAP_AXIAHB_DIV_SHIFT)
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -85,6 +91,20 @@ static ulong ast2500_get_clkin(struct ast2500_scu *scu)
? 25 * 1000 * 1000 : 24 * 1000 * 1000;
 }
 
+static u32 ast2500_get_hclk(ulong clkin, struct ast2500_scu *scu)
+{
+   u32 hpll_reg = readl(>h_pll_param);
+   ulong axi_div = 2;
+   u32 rate;
+   ulong ahb_div = 1 + ((readl(>hwstrap)
+ & SCU_HWSTRAP_AXIAHB_DIV_MASK)
+>> SCU_HWSTRAP_AXIAHB_DIV_SHIFT);
+
+   rate = ast2500_get_hpll_rate(clkin, hpll_reg);
+
+   return (rate / axi_div / ahb_div);
+}
+
 /**
  * Get current rate or uart clock
  *
@@ -146,6 +166,9 @@ static ulong ast2500_clk_get_rate(struct clk *clk)
rate = rate / apb_div;
}
break;
+   case ASPEED_CLK_AHB:
+   rate = ast2500_get_hclk(clkin, priv->scu);
+   break;
case ASPEED_CLK_SDIO:
{
ulong apb_div = 4 + 4 * ((readl(>scu->clk_sel1)
-- 
2.25.1



RE: [v3 03/11] spi: aspeed: Add ASPEED SPI controller driver

2022-05-23 Thread Chin-Ting Kuo
Hi,

> -Original Message-
> From: Chin-Ting Kuo 
> Sent: Monday, May 23, 2022 11:14 AM
> Subject: [v3 03/11] spi: aspeed: Add ASPEED SPI controller driver
> 
> Add ASPEED BMC FMC/SPI memory controller driver with spi-mem interface
> for AST2500 and AST2600 platform.
> 
> There are three SPI memory controllers embedded in an ASPEED SoC.
> - FMC: Named as Firmware Memory Controller. After AC on, MCU ROM
>fetches initial device boot image from FMC chip select(CS) 0.
> 
> - SPI1: Play the role of a SPI Master controller. Or, there is a
> dedicated path for HOST(X86) to access its BIOS flash mounted
> under BMC. spi-aspeed.c implements the control sequence when
> SPI1 is a SPI master.
> 
> - SPI2: It is a pure SPI flash controller. For most scenarios, flashes
> mounted under it are for pure storage purpose.
> 
> ASPEED SPI controller supports 1-1-1, 1-1-2 and 1-1-4 SPI flash mode.
> Three types of command mode are supported, normal mode, command
> read/write mode and user mode.
> - Normal mode: Default mode. After power on, normal read command 03h or
>13h is used to fetch boot image from SPI flash.
>- AST2500: Only 03h command can be used after power on
>   or reset.
>- AST2600: If FMC04[6:4] is set, 13h command is used,
>   otherwise, 03h command.
>The address length is decided by FMC04[2:0].
> 
> - Command mode: SPI controller can send command and address
> automatically when CPU read/write the related remapped
> or decoded address area. The command used by this mode
> can be configured by FMC10/14/18[23:16]. Also, the
> address length is decided by FMC04[2:0]. This mode will
> be implemented in the following patch series.
> 
> - User mode: It is a traditional and pure SPI operation, where
>  SPI transmission is controlled by CPU. It is the main
>  mode in this patch.
> 
> Each SPI controller in ASPEED SoC has its own decoded address mapping.
> Within each SPI controller decoded address, driver can assign a specific
> address region for each CS of a SPI controller. The decoded address cannot
> overlap to each other. With normal mode and command mode, the decoded
> address accessed by the CPU determines which CS is active.
> When user mode is adopted, the CS decoded address is a FIFO, CPU can
> send/receive any SPI transmission by accessing the related decoded address for
> the target CS.
> 
> Signed-off-by: Chin-Ting Kuo 
> ---
> v2: Remove defconfig files from this patch.
> 
>  drivers/spi/Kconfig  |   8 +
>  drivers/spi/Makefile |   1 +
>  drivers/spi/spi-aspeed.c | 822
> +++
>  3 files changed, 831 insertions(+)
>  create mode 100644 drivers/spi/spi-aspeed.c
> 
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index
> a1e515cb2b..a616294910 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -387,6 +387,14 @@ config SANDBOX_SPI
>   };
> };
> 
> +config SPI_ASPEED
> + bool "ASPEED SPI controller driver"
> + depends on DM_SPI && SPI_MEM
> + default n
> + help
> +   Enable ASPEED SPI controller driver for AST2500
> +   and AST2600 SoCs.
> +
>  config SPI_SIFIVE
>   bool "SiFive SPI driver"
>   help
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index
> 06e81b465b..36a4bd5dce 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -9,6 +9,7 @@ obj-y += spi-uclass.o
>  obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o
>  obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o
>  obj-$(CONFIG_SOFT_SPI) += soft_spi.o
> +obj-$(CONFIG_SPI_ASPEED) += spi-aspeed.o
>  obj-$(CONFIG_SPI_MEM) += spi-mem.o
>  obj-$(CONFIG_TI_QSPI) += ti_qspi.o
>  obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o
> diff --git a/drivers/spi/spi-aspeed.c b/drivers/spi/spi-aspeed.c new file mode
> 100644 index 00..9574aff793
> --- /dev/null
> +++ b/drivers/spi/spi-aspeed.c
> @@ -0,0 +1,822 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * ASPEED FMC/SPI Controller driver
> + *
> + * Copyright (c) 2022 ASPEED Corporation.
> + * Copyright (c) 2022 IBM Corporation.
> + *
> + * Author:
> + * Chin-Ting Kuo 
> + * Cedric Le Goater 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
>

[v3 08/11] mtd: spi-nor: Use spi-mem dirmap API

2022-05-22 Thread Chin-Ting Kuo
This adds support for the dirmap API to the spi-nor subsystem, as
introduced in Linux commit df5c210 ("mtd: spi-nor: use spi-mem
dirmap API").

This patch is synchronize from the following patch
https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504-4-sean...@gmail.com/

Signed-off-by: Chin-Ting Kuo 
Signed-off-by: Sean Anderson 
Acked-by: Pratyush Yadav 
---
v2: Use "if (CONFIG_IS_ENABLED(SPI_DIRMAP))" to wrap
spi_dirmap related functions.

 drivers/mtd/spi/sf_probe.c | 76 ++
 drivers/mtd/spi/spi-nor-core.c | 55 +---
 include/linux/mtd/spi-nor.h| 18 
 3 files changed, 133 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index f461082e03..e192f97efd 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -10,13 +10,69 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include "sf_internal.h"
 
+static int spi_nor_create_read_dirmap(struct spi_nor *nor)
+{
+   struct spi_mem_dirmap_info info = {
+   .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),
+ SPI_MEM_OP_ADDR(nor->addr_width, 0, 0),
+ SPI_MEM_OP_DUMMY(nor->read_dummy, 0),
+ SPI_MEM_OP_DATA_IN(0, NULL, 0)),
+   .offset = 0,
+   .length = nor->mtd.size,
+   };
+   struct spi_mem_op *op = _tmpl;
+
+   /* get transfer protocols. */
+   spi_nor_setup_op(nor, op, nor->read_proto);
+   op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto);
+
+   /* convert the dummy cycles to the number of bytes */
+   op->dummy.nbytes = (nor->read_dummy * op->dummy.buswidth) / 8;
+   if (spi_nor_protocol_is_dtr(nor->read_proto))
+   op->dummy.nbytes *= 2;
+
+   nor->dirmap.rdesc = spi_mem_dirmap_create(nor->spi, );
+   if (IS_ERR(nor->dirmap.rdesc))
+   return PTR_ERR(nor->dirmap.rdesc);
+
+   return 0;
+}
+
+static int spi_nor_create_write_dirmap(struct spi_nor *nor)
+{
+   struct spi_mem_dirmap_info info = {
+   .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 0),
+ SPI_MEM_OP_ADDR(nor->addr_width, 0, 0),
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_DATA_OUT(0, NULL, 0)),
+   .offset = 0,
+   .length = nor->mtd.size,
+   };
+   struct spi_mem_op *op = _tmpl;
+
+   /* get transfer protocols. */
+   spi_nor_setup_op(nor, op, nor->write_proto);
+   op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);
+
+   if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
+   op->addr.nbytes = 0;
+
+   nor->dirmap.wdesc = spi_mem_dirmap_create(nor->spi, );
+   if (IS_ERR(nor->dirmap.wdesc))
+   return PTR_ERR(nor->dirmap.wdesc);
+
+   return 0;
+}
+
 /**
  * spi_flash_probe_slave() - Probe for a SPI flash device on a bus
  *
@@ -45,6 +101,16 @@ static int spi_flash_probe_slave(struct spi_flash *flash)
if (ret)
goto err_read_id;
 
+   if (CONFIG_IS_ENABLED(SPI_DIRMAP)) {
+   ret = spi_nor_create_read_dirmap(flash);
+   if (ret)
+   return ret;
+
+   ret = spi_nor_create_write_dirmap(flash);
+   if (ret)
+   return ret;
+   }
+
if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
ret = spi_flash_mtd_register(flash);
 
@@ -83,6 +149,11 @@ struct spi_flash *spi_flash_probe(unsigned int busnum, 
unsigned int cs,
 
 void spi_flash_free(struct spi_flash *flash)
 {
+   if (CONFIG_IS_ENABLED(SPI_DIRMAP)) {
+   spi_mem_dirmap_destroy(flash->dirmap.wdesc);
+   spi_mem_dirmap_destroy(flash->dirmap.rdesc);
+   }
+
if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
spi_flash_mtd_unregister(flash);
 
@@ -153,6 +224,11 @@ static int spi_flash_std_remove(struct udevice *dev)
struct spi_flash *flash = dev_get_uclass_priv(dev);
int ret;
 
+   if (CONFIG_IS_ENABLED(SPI_DIRMAP)) {
+   spi_mem_dirmap_destroy(flash->dirmap.wdesc);
+   spi_mem_dirmap_destroy(flash->dirmap.rdesc);
+   }
+
ret = spi_nor_remove(flash);
if (ret)
return ret;
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 3b7c817c02..0c6262b7fd 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -239,9 +239,9 @@ static u8 spi_nor_get_cmd_ext(const struct spi_nor *nor,
  * need to be initialize

[v3 05/11] MAINTAINERS: Add ASPEED SPI driver file

2022-05-22 Thread Chin-Ting Kuo
Add spi-aspeed.c file for ARM ASPEED.

Signed-off-by: Chin-Ting Kuo 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 56be0bfad0..f2cd707eda 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -688,6 +688,13 @@ S: Maintained
 F: drivers/pci/pcie_phytium.c
 F: arch/arm/dts/phytium-durian.dts
 
+ASPEED FMC SPI DRIVER
+M: Chin-Ting Kuo 
+M: Cédric Le Goater 
+R: Aspeed BMC SW team 
+S: Maintained
+F: drivers/spi/spi-aspeed.c
+
 BINMAN
 M: Simon Glass 
 M: Alper Nebi Yasak 
-- 
2.25.1



[v3 10/11] configs: aspeed: Enable CONFIG_SPI_DIRMAP

2022-05-22 Thread Chin-Ting Kuo
Enable CONFIG_SPI_DIRMAP on ASPEED platforms.

Signed-off-by: Chin-Ting Kuo 
---
 configs/evb-ast2500_defconfig | 1 +
 configs/evb-ast2600_defconfig | 1 +
 2 files changed, 2 insertions(+)

diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index fd04fe5a60..097b991a1b 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -56,6 +56,7 @@ CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
+CONFIG_SPI_DIRMAP=y
 CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_TIMER=y
diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig
index e013976bb0..279e5a6238 100644
--- a/configs/evb-ast2600_defconfig
+++ b/configs/evb-ast2600_defconfig
@@ -90,6 +90,7 @@ CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
+CONFIG_SPI_DIRMAP=y
 CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
-- 
2.25.1



[v3 09/11] spi: aspeed: SPI dirmap read support

2022-05-22 Thread Chin-Ting Kuo
>From the HW point of view, the performance of
command read mode is greater than user mode slightly.
Thus, dirmap read framework is introduced to achieve
this goal.

In dirmap_create, a specific decoded address area with
flash size is assigned to each CS. CPU can thus access
the SPI flash as normal memory in dirmap_read function.

Signed-off-by: Chin-Ting Kuo 
---
 drivers/spi/spi-aspeed.c | 93 
 1 file changed, 93 insertions(+)

diff --git a/drivers/spi/spi-aspeed.c b/drivers/spi/spi-aspeed.c
index 9574aff793..e5e348eb7b 100644
--- a/drivers/spi/spi-aspeed.c
+++ b/drivers/spi/spi-aspeed.c
@@ -85,6 +85,8 @@ struct aspeed_spi_info {
 
 static int aspeed_spi_trim_decoded_size(struct udevice *bus,
u32 decoded_sz_arr[]);
+static int aspeed_spi_decoded_range_config(struct udevice *bus,
+  u32 decoded_sz_arr[]);
 
 static u32 aspeed_spi_get_io_mode(u32 bus_width)
 {
@@ -509,6 +511,95 @@ static int aspeed_spi_exec_op_user_mode(struct spi_slave 
*slave,
return 0;
 }
 
+static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
+{
+   int ret = 0;
+   struct udevice *dev = desc->slave->dev;
+   struct udevice *bus = dev->parent;
+   struct aspeed_spi_plat *plat = dev_get_plat(bus);
+   struct aspeed_spi_priv *priv = dev_get_priv(bus);
+   struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
+   const struct aspeed_spi_info *info = priv->info;
+   struct spi_mem_op op_tmpl = desc->info.op_tmpl;
+   u32 i;
+   u32 cs = slave_plat->cs;
+   u32 decoded_sz_arr[ASPEED_SPI_MAX_CS];
+   u32 reg_val;
+
+   if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN) {
+   for (i = 0; i < priv->num_cs; i++) {
+   reg_val = readl(plat->ctrl_base +
+   REG_CE0_DECODED_ADDR_REG + i * 4);
+   decoded_sz_arr[i] =
+   info->segment_end(bus, reg_val) -
+   info->segment_start(bus, reg_val);
+   }
+
+   decoded_sz_arr[cs] = desc->info.length;
+
+   if (info->adjust_decoded_sz)
+   info->adjust_decoded_sz(bus, decoded_sz_arr);
+
+   for (i = 0; i < priv->num_cs; i++) {
+   dev_dbg(dev, "cs: %d, sz: 0x%x\n", i,
+   decoded_sz_arr[i]);
+   }
+
+   ret = aspeed_spi_decoded_range_config(bus, decoded_sz_arr);
+   if (ret)
+   return ret;
+
+   reg_val = readl(plat->ctrl_base + REG_CE0_CTRL_REG + cs * 4) &
+ (~info->cmd_io_ctrl_mask);
+   reg_val |= aspeed_spi_get_io_mode(op_tmpl.data.buswidth) |
+  op_tmpl.cmd.opcode << 16 |
+  ((op_tmpl.dummy.nbytes) & 0x3) << 6 |
+  ((op_tmpl.dummy.nbytes) & 0x4) << 14 |
+  CTRL_IO_MODE_CMD_READ;
+
+   writel(reg_val,
+  plat->ctrl_base + REG_CE0_CTRL_REG + cs * 4);
+   priv->flashes[cs].ce_ctrl_read = reg_val;
+
+   dev_dbg(dev, "read bus width: %d [0x%08x]\n",
+   op_tmpl.data.buswidth, priv->flashes[cs].ce_ctrl_read);
+   } else {
+   /*
+* dirmap_write is not supported currently due to a HW
+* limitation for command write mode: The written data
+* length should be multiple of 4-byte.
+*/
+   return -EOPNOTSUPP;
+   }
+
+   return ret;
+}
+
+static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ u64 offs, size_t len, void *buf)
+{
+   struct udevice *dev = desc->slave->dev;
+   struct aspeed_spi_priv *priv = dev_get_priv(dev->parent);
+   struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
+   u32 cs = slave_plat->cs;
+   int ret;
+
+   dev_dbg(dev, "read op:0x%x, addr:0x%llx, len:0x%x\n",
+   desc->info.op_tmpl.cmd.opcode, offs, len);
+
+   if (priv->flashes[cs].ahb_win_sz < offs + len ||
+   (offs + len) % 4 != 0) {
+   ret = aspeed_spi_exec_op_user_mode(desc->slave,
+  >info.op_tmpl);
+   if (ret != 0)
+   return 0;
+   } else {
+   memcpy_fromio(buf, priv->flashes[cs].ahb_base + offs, len);
+   }
+
+   return len;
+}
+
 static struct aspeed_spi_flash *aspeed_spi_get_flash(struct udevice *dev)
 {
struct udevice *bus = dev->parent;
@@ -792,6 +883,8 @@ static int aspeed

[v3 11/11] mtd: spi-nor-ids: Add Winbond W25Q512JV ID

2022-05-22 Thread Chin-Ting Kuo
Add ID for Winbond W25Q512JV device which is supported
on AST2600 EVB by default.

Signed-off-by: Chin-Ting Kuo 
---
 drivers/mtd/spi/spi-nor-ids.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 7050ddc397..444affb5af 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -362,6 +362,11 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
+   {
+   INFO("w25q512jv", 0xef4020, 0, 64 * 1024, 1024,
+SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+   },
{
INFO("w25q01jv", 0xef4021, 0, 64 * 1024, 2048,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-- 
2.25.1



[v3 07/11] spi-mem: Add dirmap API from Linux

2022-05-22 Thread Chin-Ting Kuo
This adds the dirmap API originally introduced in Linux commit aa167f3
("spi: spi-mem: Add a new API to support direct mapping"). This also
includes several follow-up patches and fixes.

Changes from Linux include:
* Added Kconfig option
* Changed struct device to struct udevice
* Changed struct spi_mem to struct spi_slave

This patch is obtained from the following patch
https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504-3-sean...@gmail.com/

Signed-off-by: Chin-Ting Kuo 
Signed-off-by: Sean Anderson 
Acked-by: Pratyush Yadav 
---
v2: Remove "#if CONFIG_SPI_DIRMAP" compile wrapper.
v3: Fix a grammatical error in spi-mem.h.

 drivers/spi/Kconfig   |  10 ++
 drivers/spi/spi-mem.c | 268 ++
 include/spi-mem.h |  79 +
 3 files changed, 357 insertions(+)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index a616294910..297253714a 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -40,6 +40,16 @@ config SPI_MEM
  This extension is meant to simplify interaction with SPI memories
  by providing an high-level interface to send memory-like commands.
 
+config SPI_DIRMAP
+   bool "SPI direct mapping"
+   depends on SPI_MEM
+   help
+ Enable the SPI direct mapping API. Most modern SPI controllers can
+ directly map a SPI memory (or a portion of the SPI memory) in the CPU
+ address space. Most of the time this brings significant performance
+ improvements as it automates the whole process of sending SPI memory
+ operations every time a new region is accessed.
+
 if DM_SPI
 
 config ALTERA_SPI
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 9c1ede1b61..8e8995fc53 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -21,6 +21,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #endif
 
 #ifndef __UBOOT__
@@ -491,6 +493,272 @@ int spi_mem_adjust_op_size(struct spi_slave *slave, 
struct spi_mem_op *op)
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
 
+static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ u64 offs, size_t len, void *buf)
+{
+   struct spi_mem_op op = desc->info.op_tmpl;
+   int ret;
+
+   op.addr.val = desc->info.offset + offs;
+   op.data.buf.in = buf;
+   op.data.nbytes = len;
+   ret = spi_mem_adjust_op_size(desc->slave, );
+   if (ret)
+   return ret;
+
+   ret = spi_mem_exec_op(desc->slave, );
+   if (ret)
+   return ret;
+
+   return op.data.nbytes;
+}
+
+static ssize_t spi_mem_no_dirmap_write(struct spi_mem_dirmap_desc *desc,
+  u64 offs, size_t len, const void *buf)
+{
+   struct spi_mem_op op = desc->info.op_tmpl;
+   int ret;
+
+   op.addr.val = desc->info.offset + offs;
+   op.data.buf.out = buf;
+   op.data.nbytes = len;
+   ret = spi_mem_adjust_op_size(desc->slave, );
+   if (ret)
+   return ret;
+
+   ret = spi_mem_exec_op(desc->slave, );
+   if (ret)
+   return ret;
+
+   return op.data.nbytes;
+}
+
+/**
+ * spi_mem_dirmap_create() - Create a direct mapping descriptor
+ * @mem: SPI mem device this direct mapping should be created for
+ * @info: direct mapping information
+ *
+ * This function is creating a direct mapping descriptor which can then be used
+ * to access the memory using spi_mem_dirmap_read() or spi_mem_dirmap_write().
+ * If the SPI controller driver does not support direct mapping, this function
+ * falls back to an implementation using spi_mem_exec_op(), so that the caller
+ * doesn't have to bother implementing a fallback on his own.
+ *
+ * Return: a valid pointer in case of success, and ERR_PTR() otherwise.
+ */
+struct spi_mem_dirmap_desc *
+spi_mem_dirmap_create(struct spi_slave *slave,
+ const struct spi_mem_dirmap_info *info)
+{
+   struct udevice *bus = slave->dev->parent;
+   struct dm_spi_ops *ops = spi_get_ops(bus);
+   struct spi_mem_dirmap_desc *desc;
+   int ret = -EOPNOTSUPP;
+
+   /* Make sure the number of address cycles is between 1 and 8 bytes. */
+   if (!info->op_tmpl.addr.nbytes || info->op_tmpl.addr.nbytes > 8)
+   return ERR_PTR(-EINVAL);
+
+   /* data.dir should either be SPI_MEM_DATA_IN or SPI_MEM_DATA_OUT. */
+   if (info->op_tmpl.data.dir == SPI_MEM_NO_DATA)
+   return ERR_PTR(-EINVAL);
+
+   desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+   if (!desc)
+   return ERR_PTR(-ENOMEM);
+
+   desc->slave = slave;
+   desc->info = *info;
+   if (ops->mem_ops && ops->mem_ops->dirmap_create)
+   ret = ops->mem_ops->dirmap_create(desc);
+
+   if (ret) {
+   desc->nodirmap = true;
+   if (!spi_mem_

[v3 06/11] arm: dts: aspeed: Update SPI flash node settings

2022-05-22 Thread Chin-Ting Kuo
For both AST2500 and AST2600, there are three
SPI controllers, FMC(Firmware Memory Controller),
SPI1 and SPI2. The clock source is HCLK. Following
is the basic information for ASPEED SPI controller.

AST2500:
  - FMC:
  CS number: 3
  controller reg: 0x1e62 - 0x1e62
  decoded address: 0x2000 - 0x2fff

  - SPI1:
  CS number: 2
  controller reg: 0x1e63 - 0x1e630fff
  decoded address: 0x3000 - 0x37ff

  - SPI2:
  CS number: 2
  controller reg: 0x1e631000 - 0x1e631fff
  decoded address: 0x3800 - 0x3fff

AST2600:
  - FMC:
  CS number: 3
  controller reg: 0x1e62 - 0x1e62
  decoded address: 0x2000 - 0x2fff

  - SPI1:
  CS number: 2
  controller reg: 0x1e63 - 0x1e630fff
  decoded address: 0x3000 - 0x3fff

  - SPI2:
  CS number: 3
  controller reg: 0x1e631000 - 0x1e631fff
  decoded address: 0x5000 - 0x5fff

Signed-off-by: Chin-Ting Kuo 
---
 arch/arm/dts/ast2500-evb.dts | 33 +
 arch/arm/dts/ast2500.dtsi| 23 ---
 arch/arm/dts/ast2600-evb.dts |  8 
 arch/arm/dts/ast2600.dtsi| 34 +++---
 4 files changed, 68 insertions(+), 30 deletions(-)

diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
index 4796ed445f..c6b7675902 100644
--- a/arch/arm/dts/ast2500-evb.dts
+++ b/arch/arm/dts/ast2500-evb.dts
@@ -73,3 +73,36 @@
pinctrl-names = "default";
pinctrl-0 = <_sd2_default>;
 };
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_fwspics1_default>;
+
+   flash@0 {
+   status = "okay";
+   spi-max-frequency = <5000>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+
+   flash@1 {
+   status = "okay";
+   spi-max-frequency = <5000>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+};
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_spi1cs1_default>;
+
+   flash@0 {
+   status = "okay";
+   spi-max-frequency = <5000>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+};
diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
index ee66ef6704..d78a53aeb7 100644
--- a/arch/arm/dts/ast2500.dtsi
+++ b/arch/arm/dts/ast2500.dtsi
@@ -57,23 +57,26 @@
ranges;
 
fmc: flash-controller@1e62 {
-   reg = < 0x1e62 0xc4
-   0x2000 0x1000 >;
+   reg = <0x1e62 0xc4>, <0x2000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
compatible = "aspeed,ast2500-fmc";
+   clocks = < ASPEED_CLK_AHB>;
+   num-cs = <3>;
status = "disabled";
-   interrupts = <19>;
+
flash@0 {
reg = < 0 >;
compatible = "jedec,spi-nor";
status = "disabled";
};
+
flash@1 {
reg = < 1 >;
compatible = "jedec,spi-nor";
status = "disabled";
};
+
flash@2 {
reg = < 2 >;
compatible = "jedec,spi-nor";
@@ -82,17 +85,20 @@
};
 
spi1: flash-controller@1e63 {
-   reg = < 0x1e63 0xc4
-   0x3000 0x0800 >;
+   reg = <0x1e63 0xc4>, <0x3000 0x0800>;
#address-cells = <1>;
#size-cells = <0>;
compatible = "aspeed,ast2500-spi";
+   clocks = < ASPEED_CLK_AHB>;
+   num-cs = <2>;
status = "disabled";
+
flash@0 {
reg = < 0 >;
compatible = "jedec,spi-nor";
status = "disabled";
};
+
flash@1 {
reg = < 1 >;
compat

[v3 04/11] configs: aspeed: Enable SPI flash features

2022-05-22 Thread Chin-Ting Kuo
- Enable ASPEED SPI controller driver.
- Enable SPI flash memory configurations.
- Enable configurations for SPI flash manufacturers
  supported on both ASPEED AST2500 and AST2600 AVL.

Signed-off-by: Chin-Ting Kuo 
---
 configs/evb-ast2500_defconfig | 13 +
 configs/evb-ast2600_defconfig | 13 +
 2 files changed, 26 insertions(+)

diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index 2371cc2742..fd04fe5a60 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -35,6 +35,16 @@ CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_ASPEED=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
 CONFIG_FTGMAC100=y
@@ -44,6 +54,9 @@ CONFIG_RAM=y
 CONFIG_DM_RESET=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_TIMER=y
 CONFIG_WDT=y
diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig
index ea75762926..e013976bb0 100644
--- a/configs/evb-ast2600_defconfig
+++ b/configs/evb-ast2600_defconfig
@@ -66,6 +66,16 @@ CONFIG_MISC=y
 CONFIG_SPL_MISC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
 CONFIG_DM_MDIO=y
@@ -78,6 +88,9 @@ CONFIG_SPL_RAM=y
 CONFIG_DM_RESET=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_WDT=y
-- 
2.25.1



[v3 03/11] spi: aspeed: Add ASPEED SPI controller driver

2022-05-22 Thread Chin-Ting Kuo
Add ASPEED BMC FMC/SPI memory controller driver with
spi-mem interface for AST2500 and AST2600 platform.

There are three SPI memory controllers embedded in an ASPEED SoC.
- FMC: Named as Firmware Memory Controller. After AC on, MCU ROM
   fetches initial device boot image from FMC chip select(CS) 0.

- SPI1: Play the role of a SPI Master controller. Or, there is a
dedicated path for HOST(X86) to access its BIOS flash mounted
under BMC. spi-aspeed.c implements the control sequence when
SPI1 is a SPI master.

- SPI2: It is a pure SPI flash controller. For most scenarios, flashes
mounted under it are for pure storage purpose.

ASPEED SPI controller supports 1-1-1, 1-1-2 and 1-1-4 SPI flash mode.
Three types of command mode are supported, normal mode, command
read/write mode and user mode.
- Normal mode: Default mode. After power on, normal read command 03h or
   13h is used to fetch boot image from SPI flash.
   - AST2500: Only 03h command can be used after power on
  or reset.
   - AST2600: If FMC04[6:4] is set, 13h command is used,
  otherwise, 03h command.
   The address length is decided by FMC04[2:0].

- Command mode: SPI controller can send command and address
automatically when CPU read/write the related remapped
or decoded address area. The command used by this mode
can be configured by FMC10/14/18[23:16]. Also, the
address length is decided by FMC04[2:0]. This mode will
be implemented in the following patch series.

- User mode: It is a traditional and pure SPI operation, where
 SPI transmission is controlled by CPU. It is the main
 mode in this patch.

Each SPI controller in ASPEED SoC has its own decoded address mapping.
Within each SPI controller decoded address, driver can assign a specific
address region for each CS of a SPI controller. The decoded address
cannot overlap to each other. With normal mode and command mode, the
decoded address accessed by the CPU determines which CS is active.
When user mode is adopted, the CS decoded address is a FIFO, CPU can
send/receive any SPI transmission by accessing the related decoded
address for the target CS.

Signed-off-by: Chin-Ting Kuo 
---
v2: Remove defconfig files from this patch.

 drivers/spi/Kconfig  |   8 +
 drivers/spi/Makefile |   1 +
 drivers/spi/spi-aspeed.c | 822 +++
 3 files changed, 831 insertions(+)
 create mode 100644 drivers/spi/spi-aspeed.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index a1e515cb2b..a616294910 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -387,6 +387,14 @@ config SANDBOX_SPI
};
  };
 
+config SPI_ASPEED
+   bool "ASPEED SPI controller driver"
+   depends on DM_SPI && SPI_MEM
+   default n
+   help
+ Enable ASPEED SPI controller driver for AST2500
+ and AST2600 SoCs.
+
 config SPI_SIFIVE
bool "SiFive SPI driver"
help
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 06e81b465b..36a4bd5dce 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -9,6 +9,7 @@ obj-y += spi-uclass.o
 obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o
 obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o
 obj-$(CONFIG_SOFT_SPI) += soft_spi.o
+obj-$(CONFIG_SPI_ASPEED) += spi-aspeed.o
 obj-$(CONFIG_SPI_MEM) += spi-mem.o
 obj-$(CONFIG_TI_QSPI) += ti_qspi.o
 obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o
diff --git a/drivers/spi/spi-aspeed.c b/drivers/spi/spi-aspeed.c
new file mode 100644
index 00..9574aff793
--- /dev/null
+++ b/drivers/spi/spi-aspeed.c
@@ -0,0 +1,822 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * ASPEED FMC/SPI Controller driver
+ *
+ * Copyright (c) 2022 ASPEED Corporation.
+ * Copyright (c) 2022 IBM Corporation.
+ *
+ * Author:
+ * Chin-Ting Kuo 
+ * Cedric Le Goater 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* ASPEED FMC/SPI memory control register related */
+#define REG_CE_TYPE_SETTING  0x00
+#define REG_CE_ADDR_MODE_CTRL0x04
+#define REG_INTR_CTRL_STATUS 0x08
+#define REG_CE0_CTRL_REG 0x10
+#define REG_CE0_DECODED_ADDR_REG 0x30
+
+#define ASPEED_SPI_MAX_CS   3
+#define FLASH_CALIBRATION_LEN   0x400
+
+#define CTRL_IO_SINGLE_DATA 0
+#define CTRL_IO_QUAD_DATA   BIT(30)
+#define CTRL_IO_DUAL_DATA   BIT(29)
+
+#define CTRL_IO_MODE_USER   GENMASK(1, 0)
+#define CTRL_IO_MODE_CMD_READ   BIT(0)
+#define CTRL_IO_MODE_CMD_WRITE  BIT(1)
+#define CTRL_STOP_ACTIVEBIT(2)
+
+struct aspeed_spi_plat {
+   fdt_addr_t ctrl_base;
+   void __iomem *ahb_base; /* AHB address base for all flash devices. 

[v3 00/11] Add ASPEED SPI controller driver

2022-05-22 Thread Chin-Ting Kuo
This patch series aims to porting ASPEED FMC/SPI memory controller
driver with spi-mem interface. spi-mem dirmap framework is also
synchronized from Linux. These patches have been verified on both
AST2600 and AST2500 EVBs.

Changes in v2:
  - Separate defconfig files from the SPI driver patch.
  - Use "if (CONFIG_IS_ENABLED(SPI_DIRMAP))" to wrap
spi_dirmap related functions.
  - Add Winbond w25q512jv flash ID.

Changes in v3:
  - Get AHB bus clock frequency from the function parameter.
  - Fix a grammatical error in spi-mem.h.

Chin-Ting Kuo (11):
  clk: aspeed: Get HCLK frequency support
  pinctrl: aspeed: FWSPICS1 and SPI1CS1 pin support
  spi: aspeed: Add ASPEED SPI controller driver
  configs: aspeed: Enable SPI flash features
  MAINTAINERS: Add ASPEED SPI driver file
  arm: dts: aspeed: Update SPI flash node settings
  spi-mem: Add dirmap API from Linux
  mtd: spi-nor: Use spi-mem dirmap API
  spi: aspeed: SPI dirmap read support
  configs: aspeed: Enable CONFIG_SPI_DIRMAP
  mtd: spi-nor-ids: Add Winbond W25Q512JV ID

 MAINTAINERS  |   7 +
 arch/arm/dts/ast2500-evb.dts |  33 +
 arch/arm/dts/ast2500.dtsi|  23 +-
 arch/arm/dts/ast2600-evb.dts |   8 -
 arch/arm/dts/ast2600.dtsi|  34 +-
 configs/evb-ast2500_defconfig|  14 +
 configs/evb-ast2600_defconfig|  14 +
 drivers/clk/aspeed/clk_ast2500.c |  23 +
 drivers/mtd/spi/sf_probe.c   |  76 ++
 drivers/mtd/spi/spi-nor-core.c   |  55 +-
 drivers/mtd/spi/spi-nor-ids.c|   5 +
 drivers/pinctrl/aspeed/pinctrl_ast2500.c |   2 +
 drivers/spi/Kconfig  |  18 +
 drivers/spi/Makefile |   1 +
 drivers/spi/spi-aspeed.c | 915 +++
 drivers/spi/spi-mem.c| 268 +++
 include/linux/mtd/spi-nor.h  |  18 +
 include/spi-mem.h|  79 ++
 18 files changed, 1547 insertions(+), 46 deletions(-)
 create mode 100644 drivers/spi/spi-aspeed.c

-- 
2.25.1



[v3 01/11] clk: aspeed: Get HCLK frequency support

2022-05-22 Thread Chin-Ting Kuo
User can get correct HCLK frequency during driver probe stage
by adding the following configuration in the device tree.
"clocks = < ASPEED_CLK_AHB>".

Signed-off-by: Chin-Ting Kuo 
Reviewed-by: Cédric Le Goater 
---
 drivers/clk/aspeed/clk_ast2500.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
index a1b4496ca2..d99964fcd7 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -29,6 +29,12 @@
 
 #define D2PLL_DEFAULT_RATE (250 * 1000 * 1000)
 
+/*
+ * AXI/AHB clock selection, taken from Aspeed SDK
+ */
+#define SCU_HWSTRAP_AXIAHB_DIV_SHIFT9
+#define SCU_HWSTRAP_AXIAHB_DIV_MASK (0x7 << SCU_HWSTRAP_AXIAHB_DIV_SHIFT)
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -85,6 +91,20 @@ static ulong ast2500_get_clkin(struct ast2500_scu *scu)
? 25 * 1000 * 1000 : 24 * 1000 * 1000;
 }
 
+static u32 ast2500_get_hclk(ulong clkin, struct ast2500_scu *scu)
+{
+   u32 hpll_reg = readl(>h_pll_param);
+   ulong axi_div = 2;
+   u32 rate;
+   ulong ahb_div = 1 + ((readl(>hwstrap)
+ & SCU_HWSTRAP_AXIAHB_DIV_MASK)
+>> SCU_HWSTRAP_AXIAHB_DIV_SHIFT);
+
+   rate = ast2500_get_hpll_rate(clkin, hpll_reg);
+
+   return (rate / axi_div / ahb_div);
+}
+
 /**
  * Get current rate or uart clock
  *
@@ -146,6 +166,9 @@ static ulong ast2500_clk_get_rate(struct clk *clk)
rate = rate / apb_div;
}
break;
+   case ASPEED_CLK_AHB:
+   rate = ast2500_get_hclk(clkin, priv->scu);
+   break;
case ASPEED_CLK_SDIO:
{
ulong apb_div = 4 + 4 * ((readl(>scu->clk_sel1)
-- 
2.25.1



[v3 02/11] pinctrl: aspeed: FWSPICS1 and SPI1CS1 pin support

2022-05-22 Thread Chin-Ting Kuo
Add FWSPICS1 and SPI1CS1 in AST2500 pinctrl group.
On AST2500 EVB, FWSPICS1 can be supported by default.
An extra jumper, J45, should be configured before
enabling SPI1CS1.

Signed-off-by: Chin-Ting Kuo 
Reviewed-by: Cédric Le Goater 
---
 drivers/pinctrl/aspeed/pinctrl_ast2500.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pinctrl/aspeed/pinctrl_ast2500.c 
b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
index 3c2e10b88e..93920a6389 100644
--- a/drivers/pinctrl/aspeed/pinctrl_ast2500.c
+++ b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
@@ -61,6 +61,8 @@ static const struct ast2500_group_config ast2500_groups[] = {
{ "MDIO2", 5, (1 << 2) },
{ "SD1", 5, (1 << 0) },
{ "SD2", 5, (1 << 1) },
+   { "FWSPICS1", 3, (1 << 24) },
+   { "SPI1CS1", 1, (1 << 15) },
 };
 
 static int ast2500_pinctrl_get_groups_count(struct udevice *dev)
-- 
2.25.1



RE: [PATCH v2 01/11] clk: aspeed: Get HCLK frequency support

2022-05-22 Thread Chin-Ting Kuo
Hi Cédric,

Thanks for the review.

> -Original Message-
> From: Cédric Le Goater 
> Sent: Tuesday, May 17, 2022 8:19 PM
> Subject: Re: [PATCH v2 01/11] clk: aspeed: Get HCLK frequency support
> 
> On 5/9/22 09:23, Chin-Ting Kuo wrote:
> > User can get correct HCLK frequency during driver probe stage by
> > adding the following configuration in the device tree.
> > "clocks = < ASPEED_CLK_AHB>".
> >
> > Signed-off-by: Chin-Ting Kuo 
> > ---
> >   drivers/clk/aspeed/clk_ast2500.c | 24 
> >   1 file changed, 24 insertions(+)
> >
> > diff --git a/drivers/clk/aspeed/clk_ast2500.c
> > b/drivers/clk/aspeed/clk_ast2500.c
> > index a1b4496ca2..d2a58a8462 100644
> > --- a/drivers/clk/aspeed/clk_ast2500.c
> > +++ b/drivers/clk/aspeed/clk_ast2500.c
> > @@ -29,6 +29,12 @@
> >
> >   #define D2PLL_DEFAULT_RATE(250 * 1000 * 1000)
> >
> > +/*
> > + * AXI/AHB clock selection, taken from Aspeed SDK  */
> > +#define SCU_HWSTRAP_AXIAHB_DIV_SHIFT9
> > +#define SCU_HWSTRAP_AXIAHB_DIV_MASK (0x7 <<
> SCU_HWSTRAP_AXIAHB_DIV_SHIFT)
> > +
> >   DECLARE_GLOBAL_DATA_PTR;
> >
> >   /*
> > @@ -85,6 +91,21 @@ static ulong ast2500_get_clkin(struct ast2500_scu
> *scu)
> > ? 25 * 1000 * 1000 : 24 * 1000 * 1000;
> >   }
> >
> > +static u32 ast2500_get_hclk(struct ast2500_scu *scu) {
> > +   ulong clkin = ast2500_get_clkin(scu);
> 
> you could avoid reading clkin and pass it as a parameter like the other
> routines do : ast2500_get_hpll_rate() and ast2500_get_mpll_rate()
> 
> It's minor.
> 

I may need to change the other patch in this patch series, this part will also 
be included.


Chin-Ting

> Reviewed-by: Cédric Le Goater 
> 
> Thanks,
> 
> C.
> 
> 
> > +   u32 hpll_reg = readl(>h_pll_param);
> > +   ulong axi_div = 2;
> > +   u32 rate;
> > +   ulong ahb_div = 1 + ((readl(>hwstrap)
> > + & SCU_HWSTRAP_AXIAHB_DIV_MASK)
> > +>> SCU_HWSTRAP_AXIAHB_DIV_SHIFT);
> > +
> > +   rate = ast2500_get_hpll_rate(clkin, hpll_reg);
> > +
> > +   return (rate / axi_div / ahb_div);
> > +}
> > +
> >   /**
> >* Get current rate or uart clock
> >*
> > @@ -146,6 +167,9 @@ static ulong ast2500_clk_get_rate(struct clk *clk)
> > rate = rate / apb_div;
> > }
> > break;
> > +   case ASPEED_CLK_AHB:
> > +   rate = ast2500_get_hclk(priv->scu);
> > +   break;
> > case ASPEED_CLK_SDIO:
> > {
> > ulong apb_div = 4 + 4 * ((readl(>scu->clk_sel1)



RE: [PATCH v2 07/11] spi-mem: Add dirmap API from Linux

2022-05-19 Thread Chin-Ting Kuo
Hi Anderson,

> -Original Message-
> From: Sean Anderson 
> Sent: Thursday, May 19, 2022 9:35 PM
> Subject: Re: [PATCH v2 07/11] spi-mem: Add dirmap API from Linux
> 
> On 5/9/22 3:23 AM, Chin-Ting Kuo wrote:
> > This adds the dirmap API originally introduced in Linux commit aa167f3
> > ("spi: spi-mem: Add a new API to support direct mapping"). This also
> > includes several follow-up patches and fixes.
> >
> > Changes from Linux include:
> > * Added Kconfig option
> > * Changed struct device to struct udevice
> > * Changed struct spi_mem to struct spi_slave
> >
> > This patch is obtained from the following patch
> >
> https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504
> > -3-sean...@gmail.com/
> >
> > Signed-off-by: Chin-Ting Kuo 
> > Signed-off-by: Sean Anderson 
> > Acked-by: Pratyush Yadav 
> > ---
> > v2: Remove "#if CONFIG_SPI_DIRMAP" compile wrapper.
> >
> >   drivers/spi/Kconfig   |  10 ++
> >   drivers/spi/spi-mem.c | 268
> ++
> >   include/spi-mem.h |  79 +
> >   3 files changed, 357 insertions(+)
> >
> > diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index
> > a616294910..297253714a 100644
> > --- a/drivers/spi/Kconfig
> > +++ b/drivers/spi/Kconfig
> > @@ -40,6 +40,16 @@ config SPI_MEM
> >   This extension is meant to simplify interaction with SPI
> memories
> >   by providing an high-level interface to send memory-like
> commands.
> >
> > +config SPI_DIRMAP
> > +   bool "SPI direct mapping"
> > +   depends on SPI_MEM
> > +   help
> > + Enable the SPI direct mapping API. Most modern SPI controllers can
> > + directly map a SPI memory (or a portion of the SPI memory) in the
> CPU
> > + address space. Most of the time this brings significant performance
> > + improvements as it automates the whole process of sending SPI
> memory
> > + operations every time a new region is accessed.
> > +
> >   if DM_SPI
> >
> >   config ALTERA_SPI
> > diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index
> > 9c1ede1b61..8e8995fc53 100644
> > --- a/drivers/spi/spi-mem.c
> > +++ b/drivers/spi/spi-mem.c
> > @@ -21,6 +21,8 @@
> >   #include 
> >   #include 
> >   #include 
> > +#include 
> > +#include 
> >   #endif
> >
> >   #ifndef __UBOOT__
> > @@ -491,6 +493,272 @@ int spi_mem_adjust_op_size(struct spi_slave
> *slave, struct spi_mem_op *op)
> >   }
> >   EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
> >
> > +static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc
> *desc,
> > + u64 offs, size_t len, void *buf) {
> > +   struct spi_mem_op op = desc->info.op_tmpl;
> > +   int ret;
> > +
> > +   op.addr.val = desc->info.offset + offs;
> > +   op.data.buf.in = buf;
> > +   op.data.nbytes = len;
> > +   ret = spi_mem_adjust_op_size(desc->slave, );
> > +   if (ret)
> > +   return ret;
> > +
> > +   ret = spi_mem_exec_op(desc->slave, );
> > +   if (ret)
> > +   return ret;
> > +
> > +   return op.data.nbytes;
> > +}
> > +
> > +static ssize_t spi_mem_no_dirmap_write(struct spi_mem_dirmap_desc
> *desc,
> > +  u64 offs, size_t len, const void *buf) {
> > +   struct spi_mem_op op = desc->info.op_tmpl;
> > +   int ret;
> > +
> > +   op.addr.val = desc->info.offset + offs;
> > +   op.data.buf.out = buf;
> > +   op.data.nbytes = len;
> > +   ret = spi_mem_adjust_op_size(desc->slave, );
> > +   if (ret)
> > +   return ret;
> > +
> > +   ret = spi_mem_exec_op(desc->slave, );
> > +   if (ret)
> > +   return ret;
> > +
> > +   return op.data.nbytes;
> > +}
> > +
> > +/**
> > + * spi_mem_dirmap_create() - Create a direct mapping descriptor
> > + * @mem: SPI mem device this direct mapping should be created for
> > + * @info: direct mapping information
> > + *
> > + * This function is creating a direct mapping descriptor which can
> > +then be used
> > + * to access the memory using spi_mem_dirmap_read() or
> spi_mem_dirmap_write().
> > + * If the SPI controller driver does not support direct mapping, this
> > +function
> > + * falls back to an implementation using spi_mem_exec_op(), so that
> > +the caller
> > + * doesn't have to

[PATCH v2 08/11] mtd: spi-nor: Use spi-mem dirmap API

2022-05-09 Thread Chin-Ting Kuo
This adds support for the dirmap API to the spi-nor subsystem, as
introduced in Linux commit df5c210 ("mtd: spi-nor: use spi-mem
dirmap API").

This patch is synchronize from the following patch
https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504-4-sean...@gmail.com/

Signed-off-by: Chin-Ting Kuo 
Signed-off-by: Sean Anderson 
Acked-by: Pratyush Yadav 
---
v2: Use "if (CONFIG_IS_ENABLED(SPI_DIRMAP))" to wrap
spi_dirmap related functions.

 drivers/mtd/spi/sf_probe.c | 76 ++
 drivers/mtd/spi/spi-nor-core.c | 55 +---
 include/linux/mtd/spi-nor.h| 18 
 3 files changed, 133 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index f461082e03..e192f97efd 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -10,13 +10,69 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include "sf_internal.h"
 
+static int spi_nor_create_read_dirmap(struct spi_nor *nor)
+{
+   struct spi_mem_dirmap_info info = {
+   .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),
+ SPI_MEM_OP_ADDR(nor->addr_width, 0, 0),
+ SPI_MEM_OP_DUMMY(nor->read_dummy, 0),
+ SPI_MEM_OP_DATA_IN(0, NULL, 0)),
+   .offset = 0,
+   .length = nor->mtd.size,
+   };
+   struct spi_mem_op *op = _tmpl;
+
+   /* get transfer protocols. */
+   spi_nor_setup_op(nor, op, nor->read_proto);
+   op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto);
+
+   /* convert the dummy cycles to the number of bytes */
+   op->dummy.nbytes = (nor->read_dummy * op->dummy.buswidth) / 8;
+   if (spi_nor_protocol_is_dtr(nor->read_proto))
+   op->dummy.nbytes *= 2;
+
+   nor->dirmap.rdesc = spi_mem_dirmap_create(nor->spi, );
+   if (IS_ERR(nor->dirmap.rdesc))
+   return PTR_ERR(nor->dirmap.rdesc);
+
+   return 0;
+}
+
+static int spi_nor_create_write_dirmap(struct spi_nor *nor)
+{
+   struct spi_mem_dirmap_info info = {
+   .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 0),
+ SPI_MEM_OP_ADDR(nor->addr_width, 0, 0),
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_DATA_OUT(0, NULL, 0)),
+   .offset = 0,
+   .length = nor->mtd.size,
+   };
+   struct spi_mem_op *op = _tmpl;
+
+   /* get transfer protocols. */
+   spi_nor_setup_op(nor, op, nor->write_proto);
+   op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);
+
+   if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
+   op->addr.nbytes = 0;
+
+   nor->dirmap.wdesc = spi_mem_dirmap_create(nor->spi, );
+   if (IS_ERR(nor->dirmap.wdesc))
+   return PTR_ERR(nor->dirmap.wdesc);
+
+   return 0;
+}
+
 /**
  * spi_flash_probe_slave() - Probe for a SPI flash device on a bus
  *
@@ -45,6 +101,16 @@ static int spi_flash_probe_slave(struct spi_flash *flash)
if (ret)
goto err_read_id;
 
+   if (CONFIG_IS_ENABLED(SPI_DIRMAP)) {
+   ret = spi_nor_create_read_dirmap(flash);
+   if (ret)
+   return ret;
+
+   ret = spi_nor_create_write_dirmap(flash);
+   if (ret)
+   return ret;
+   }
+
if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
ret = spi_flash_mtd_register(flash);
 
@@ -83,6 +149,11 @@ struct spi_flash *spi_flash_probe(unsigned int busnum, 
unsigned int cs,
 
 void spi_flash_free(struct spi_flash *flash)
 {
+   if (CONFIG_IS_ENABLED(SPI_DIRMAP)) {
+   spi_mem_dirmap_destroy(flash->dirmap.wdesc);
+   spi_mem_dirmap_destroy(flash->dirmap.rdesc);
+   }
+
if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
spi_flash_mtd_unregister(flash);
 
@@ -153,6 +224,11 @@ static int spi_flash_std_remove(struct udevice *dev)
struct spi_flash *flash = dev_get_uclass_priv(dev);
int ret;
 
+   if (CONFIG_IS_ENABLED(SPI_DIRMAP)) {
+   spi_mem_dirmap_destroy(flash->dirmap.wdesc);
+   spi_mem_dirmap_destroy(flash->dirmap.rdesc);
+   }
+
ret = spi_nor_remove(flash);
if (ret)
return ret;
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 3b7c817c02..0c6262b7fd 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -239,9 +239,9 @@ static u8 spi_nor_get_cmd_ext(const struct spi_nor *nor,
  * need to be initialize

[PATCH v2 07/11] spi-mem: Add dirmap API from Linux

2022-05-09 Thread Chin-Ting Kuo
This adds the dirmap API originally introduced in Linux commit aa167f3
("spi: spi-mem: Add a new API to support direct mapping"). This also
includes several follow-up patches and fixes.

Changes from Linux include:
* Added Kconfig option
* Changed struct device to struct udevice
* Changed struct spi_mem to struct spi_slave

This patch is obtained from the following patch
https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504-3-sean...@gmail.com/

Signed-off-by: Chin-Ting Kuo 
Signed-off-by: Sean Anderson 
Acked-by: Pratyush Yadav 
---
v2: Remove "#if CONFIG_SPI_DIRMAP" compile wrapper.

 drivers/spi/Kconfig   |  10 ++
 drivers/spi/spi-mem.c | 268 ++
 include/spi-mem.h |  79 +
 3 files changed, 357 insertions(+)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index a616294910..297253714a 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -40,6 +40,16 @@ config SPI_MEM
  This extension is meant to simplify interaction with SPI memories
  by providing an high-level interface to send memory-like commands.
 
+config SPI_DIRMAP
+   bool "SPI direct mapping"
+   depends on SPI_MEM
+   help
+ Enable the SPI direct mapping API. Most modern SPI controllers can
+ directly map a SPI memory (or a portion of the SPI memory) in the CPU
+ address space. Most of the time this brings significant performance
+ improvements as it automates the whole process of sending SPI memory
+ operations every time a new region is accessed.
+
 if DM_SPI
 
 config ALTERA_SPI
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 9c1ede1b61..8e8995fc53 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -21,6 +21,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #endif
 
 #ifndef __UBOOT__
@@ -491,6 +493,272 @@ int spi_mem_adjust_op_size(struct spi_slave *slave, 
struct spi_mem_op *op)
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
 
+static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ u64 offs, size_t len, void *buf)
+{
+   struct spi_mem_op op = desc->info.op_tmpl;
+   int ret;
+
+   op.addr.val = desc->info.offset + offs;
+   op.data.buf.in = buf;
+   op.data.nbytes = len;
+   ret = spi_mem_adjust_op_size(desc->slave, );
+   if (ret)
+   return ret;
+
+   ret = spi_mem_exec_op(desc->slave, );
+   if (ret)
+   return ret;
+
+   return op.data.nbytes;
+}
+
+static ssize_t spi_mem_no_dirmap_write(struct spi_mem_dirmap_desc *desc,
+  u64 offs, size_t len, const void *buf)
+{
+   struct spi_mem_op op = desc->info.op_tmpl;
+   int ret;
+
+   op.addr.val = desc->info.offset + offs;
+   op.data.buf.out = buf;
+   op.data.nbytes = len;
+   ret = spi_mem_adjust_op_size(desc->slave, );
+   if (ret)
+   return ret;
+
+   ret = spi_mem_exec_op(desc->slave, );
+   if (ret)
+   return ret;
+
+   return op.data.nbytes;
+}
+
+/**
+ * spi_mem_dirmap_create() - Create a direct mapping descriptor
+ * @mem: SPI mem device this direct mapping should be created for
+ * @info: direct mapping information
+ *
+ * This function is creating a direct mapping descriptor which can then be used
+ * to access the memory using spi_mem_dirmap_read() or spi_mem_dirmap_write().
+ * If the SPI controller driver does not support direct mapping, this function
+ * falls back to an implementation using spi_mem_exec_op(), so that the caller
+ * doesn't have to bother implementing a fallback on his own.
+ *
+ * Return: a valid pointer in case of success, and ERR_PTR() otherwise.
+ */
+struct spi_mem_dirmap_desc *
+spi_mem_dirmap_create(struct spi_slave *slave,
+ const struct spi_mem_dirmap_info *info)
+{
+   struct udevice *bus = slave->dev->parent;
+   struct dm_spi_ops *ops = spi_get_ops(bus);
+   struct spi_mem_dirmap_desc *desc;
+   int ret = -EOPNOTSUPP;
+
+   /* Make sure the number of address cycles is between 1 and 8 bytes. */
+   if (!info->op_tmpl.addr.nbytes || info->op_tmpl.addr.nbytes > 8)
+   return ERR_PTR(-EINVAL);
+
+   /* data.dir should either be SPI_MEM_DATA_IN or SPI_MEM_DATA_OUT. */
+   if (info->op_tmpl.data.dir == SPI_MEM_NO_DATA)
+   return ERR_PTR(-EINVAL);
+
+   desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+   if (!desc)
+   return ERR_PTR(-ENOMEM);
+
+   desc->slave = slave;
+   desc->info = *info;
+   if (ops->mem_ops && ops->mem_ops->dirmap_create)
+   ret = ops->mem_ops->dirmap_create(desc);
+
+   if (ret) {
+   desc->nodirmap = true;
+   if (!spi_mem_supports_op(desc->slave, >

[PATCH v2 09/11] spi: aspeed: SPI dirmap read support

2022-05-09 Thread Chin-Ting Kuo
>From the HW point of view, the performance of
command read mode is greater than user mode slightly.
Thus, dirmap read framework is introduced to achieve
this goal.

In dirmap_create, a specific decoded address area with
flash size is assigned to each CS. CPU can thus access
the SPI flash as normal memory in dirmap_read function.

Signed-off-by: Chin-Ting Kuo 
---
 drivers/spi/spi-aspeed.c | 93 
 1 file changed, 93 insertions(+)

diff --git a/drivers/spi/spi-aspeed.c b/drivers/spi/spi-aspeed.c
index 9574aff793..e5e348eb7b 100644
--- a/drivers/spi/spi-aspeed.c
+++ b/drivers/spi/spi-aspeed.c
@@ -85,6 +85,8 @@ struct aspeed_spi_info {
 
 static int aspeed_spi_trim_decoded_size(struct udevice *bus,
u32 decoded_sz_arr[]);
+static int aspeed_spi_decoded_range_config(struct udevice *bus,
+  u32 decoded_sz_arr[]);
 
 static u32 aspeed_spi_get_io_mode(u32 bus_width)
 {
@@ -509,6 +511,95 @@ static int aspeed_spi_exec_op_user_mode(struct spi_slave 
*slave,
return 0;
 }
 
+static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
+{
+   int ret = 0;
+   struct udevice *dev = desc->slave->dev;
+   struct udevice *bus = dev->parent;
+   struct aspeed_spi_plat *plat = dev_get_plat(bus);
+   struct aspeed_spi_priv *priv = dev_get_priv(bus);
+   struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
+   const struct aspeed_spi_info *info = priv->info;
+   struct spi_mem_op op_tmpl = desc->info.op_tmpl;
+   u32 i;
+   u32 cs = slave_plat->cs;
+   u32 decoded_sz_arr[ASPEED_SPI_MAX_CS];
+   u32 reg_val;
+
+   if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN) {
+   for (i = 0; i < priv->num_cs; i++) {
+   reg_val = readl(plat->ctrl_base +
+   REG_CE0_DECODED_ADDR_REG + i * 4);
+   decoded_sz_arr[i] =
+   info->segment_end(bus, reg_val) -
+   info->segment_start(bus, reg_val);
+   }
+
+   decoded_sz_arr[cs] = desc->info.length;
+
+   if (info->adjust_decoded_sz)
+   info->adjust_decoded_sz(bus, decoded_sz_arr);
+
+   for (i = 0; i < priv->num_cs; i++) {
+   dev_dbg(dev, "cs: %d, sz: 0x%x\n", i,
+   decoded_sz_arr[i]);
+   }
+
+   ret = aspeed_spi_decoded_range_config(bus, decoded_sz_arr);
+   if (ret)
+   return ret;
+
+   reg_val = readl(plat->ctrl_base + REG_CE0_CTRL_REG + cs * 4) &
+ (~info->cmd_io_ctrl_mask);
+   reg_val |= aspeed_spi_get_io_mode(op_tmpl.data.buswidth) |
+  op_tmpl.cmd.opcode << 16 |
+  ((op_tmpl.dummy.nbytes) & 0x3) << 6 |
+  ((op_tmpl.dummy.nbytes) & 0x4) << 14 |
+  CTRL_IO_MODE_CMD_READ;
+
+   writel(reg_val,
+  plat->ctrl_base + REG_CE0_CTRL_REG + cs * 4);
+   priv->flashes[cs].ce_ctrl_read = reg_val;
+
+   dev_dbg(dev, "read bus width: %d [0x%08x]\n",
+   op_tmpl.data.buswidth, priv->flashes[cs].ce_ctrl_read);
+   } else {
+   /*
+* dirmap_write is not supported currently due to a HW
+* limitation for command write mode: The written data
+* length should be multiple of 4-byte.
+*/
+   return -EOPNOTSUPP;
+   }
+
+   return ret;
+}
+
+static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ u64 offs, size_t len, void *buf)
+{
+   struct udevice *dev = desc->slave->dev;
+   struct aspeed_spi_priv *priv = dev_get_priv(dev->parent);
+   struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
+   u32 cs = slave_plat->cs;
+   int ret;
+
+   dev_dbg(dev, "read op:0x%x, addr:0x%llx, len:0x%x\n",
+   desc->info.op_tmpl.cmd.opcode, offs, len);
+
+   if (priv->flashes[cs].ahb_win_sz < offs + len ||
+   (offs + len) % 4 != 0) {
+   ret = aspeed_spi_exec_op_user_mode(desc->slave,
+  >info.op_tmpl);
+   if (ret != 0)
+   return 0;
+   } else {
+   memcpy_fromio(buf, priv->flashes[cs].ahb_base + offs, len);
+   }
+
+   return len;
+}
+
 static struct aspeed_spi_flash *aspeed_spi_get_flash(struct udevice *dev)
 {
struct udevice *bus = dev->parent;
@@ -792,6 +883,8 @@ static int aspeed

[PATCH v2 10/11] configs: aspeed: Enable CONFIG_SPI_DIRMAP

2022-05-09 Thread Chin-Ting Kuo
Enable CONFIG_SPI_DIRMAP on ASPEED platforms.

Signed-off-by: Chin-Ting Kuo 
---
 configs/evb-ast2500_defconfig | 1 +
 configs/evb-ast2600_defconfig | 1 +
 2 files changed, 2 insertions(+)

diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index fd04fe5a60..097b991a1b 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -56,6 +56,7 @@ CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
+CONFIG_SPI_DIRMAP=y
 CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_TIMER=y
diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig
index e013976bb0..279e5a6238 100644
--- a/configs/evb-ast2600_defconfig
+++ b/configs/evb-ast2600_defconfig
@@ -90,6 +90,7 @@ CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
+CONFIG_SPI_DIRMAP=y
 CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
-- 
2.25.1



[PATCH v2 11/11] mtd: spi-nor-ids: Add Winbond W25Q512JV ID

2022-05-09 Thread Chin-Ting Kuo
Add ID for Winbond W25Q512JV device which is supported
on AST2600 EVB by default.

Signed-off-by: Chin-Ting Kuo 
---
 drivers/mtd/spi/spi-nor-ids.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 7050ddc397..444affb5af 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -362,6 +362,11 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
+   {
+   INFO("w25q512jv", 0xef4020, 0, 64 * 1024, 1024,
+SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+   },
{
INFO("w25q01jv", 0xef4021, 0, 64 * 1024, 2048,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-- 
2.25.1



[PATCH v2 06/11] arm: dts: aspeed: Update SPI flash node settings

2022-05-09 Thread Chin-Ting Kuo
For both AST2500 and AST2600, there are three
SPI controllers, FMC(Firmware Memory Controller),
SPI1 and SPI2. The clock source is HCLK. Following
is the basic information for ASPEED SPI controller.

AST2500:
  - FMC:
  CS number: 3
  controller reg: 0x1e62 - 0x1e62
  decoded address: 0x2000 - 0x2fff

  - SPI1:
  CS number: 2
  controller reg: 0x1e63 - 0x1e630fff
  decoded address: 0x3000 - 0x37ff

  - SPI2:
  CS number: 2
  controller reg: 0x1e631000 - 0x1e631fff
  decoded address: 0x3800 - 0x3fff

AST2600:
  - FMC:
  CS number: 3
  controller reg: 0x1e62 - 0x1e62
  decoded address: 0x2000 - 0x2fff

  - SPI1:
  CS number: 2
  controller reg: 0x1e63 - 0x1e630fff
  decoded address: 0x3000 - 0x3fff

  - SPI2:
  CS number: 3
  controller reg: 0x1e631000 - 0x1e631fff
  decoded address: 0x5000 - 0x5fff

Signed-off-by: Chin-Ting Kuo 
---
 arch/arm/dts/ast2500-evb.dts | 33 +
 arch/arm/dts/ast2500.dtsi| 23 ---
 arch/arm/dts/ast2600-evb.dts |  8 
 arch/arm/dts/ast2600.dtsi| 34 +++---
 4 files changed, 68 insertions(+), 30 deletions(-)

diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
index 4796ed445f..c6b7675902 100644
--- a/arch/arm/dts/ast2500-evb.dts
+++ b/arch/arm/dts/ast2500-evb.dts
@@ -73,3 +73,36 @@
pinctrl-names = "default";
pinctrl-0 = <_sd2_default>;
 };
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_fwspics1_default>;
+
+   flash@0 {
+   status = "okay";
+   spi-max-frequency = <5000>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+
+   flash@1 {
+   status = "okay";
+   spi-max-frequency = <5000>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+};
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_spi1cs1_default>;
+
+   flash@0 {
+   status = "okay";
+   spi-max-frequency = <5000>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+};
diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
index ee66ef6704..d78a53aeb7 100644
--- a/arch/arm/dts/ast2500.dtsi
+++ b/arch/arm/dts/ast2500.dtsi
@@ -57,23 +57,26 @@
ranges;
 
fmc: flash-controller@1e62 {
-   reg = < 0x1e62 0xc4
-   0x2000 0x1000 >;
+   reg = <0x1e62 0xc4>, <0x2000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
compatible = "aspeed,ast2500-fmc";
+   clocks = < ASPEED_CLK_AHB>;
+   num-cs = <3>;
status = "disabled";
-   interrupts = <19>;
+
flash@0 {
reg = < 0 >;
compatible = "jedec,spi-nor";
status = "disabled";
};
+
flash@1 {
reg = < 1 >;
compatible = "jedec,spi-nor";
status = "disabled";
};
+
flash@2 {
reg = < 2 >;
compatible = "jedec,spi-nor";
@@ -82,17 +85,20 @@
};
 
spi1: flash-controller@1e63 {
-   reg = < 0x1e63 0xc4
-   0x3000 0x0800 >;
+   reg = <0x1e63 0xc4>, <0x3000 0x0800>;
#address-cells = <1>;
#size-cells = <0>;
compatible = "aspeed,ast2500-spi";
+   clocks = < ASPEED_CLK_AHB>;
+   num-cs = <2>;
status = "disabled";
+
flash@0 {
reg = < 0 >;
compatible = "jedec,spi-nor";
status = "disabled";
};
+
flash@1 {
reg = < 1 >;
compat

[PATCH v2 03/11] spi: aspeed: Add ASPEED SPI controller driver

2022-05-09 Thread Chin-Ting Kuo
Add ASPEED BMC FMC/SPI memory controller driver with
spi-mem interface for AST2500 and AST2600 platform.

There are three SPI memory controllers embedded in an ASPEED SoC.
- FMC: Named as Firmware Memory Controller. After AC on, MCU ROM
   fetches initial device boot image from FMC chip select(CS) 0.

- SPI1: Play the role of a SPI Master controller. Or, there is a
dedicated path for HOST(X86) to access its BIOS flash mounted
under BMC. spi-aspeed.c implements the control sequence when
SPI1 is a SPI master.

- SPI2: It is a pure SPI flash controller. For most scenarios, flashes
mounted under it are for pure storage purpose.

ASPEED SPI controller supports 1-1-1, 1-1-2 and 1-1-4 SPI flash mode.
Three types of command mode are supported, normal mode, command
read/write mode and user mode.
- Normal mode: Default mode. After power on, normal read command 03h or
   13h is used to fetch boot image from SPI flash.
   - AST2500: Only 03h command can be used after power on
  or reset.
   - AST2600: If FMC04[6:4] is set, 13h command is used,
  otherwise, 03h command.
   The address length is decided by FMC04[2:0].

- Command mode: SPI controller can send command and address
automatically when CPU read/write the related remapped
or decoded address area. The command used by this mode
can be configured by FMC10/14/18[23:16]. Also, the
address length is decided by FMC04[2:0]. This mode will
be implemented in the following patch series.

- User mode: It is a traditional and pure SPI operation, where
 SPI transmission is controlled by CPU. It is the main
 mode in this patch.

Each SPI controller in ASPEED SoC has its own decoded address mapping.
Within each SPI controller decoded address, driver can assign a specific
address region for each CS of a SPI controller. The decoded address
cannot overlap to each other. With normal mode and command mode, the
decoded address accessed by the CPU determines which CS is active.
When user mode is adopted, the CS decoded address is a FIFO, CPU can
send/receive any SPI transmission by accessing the related decoded
address for the target CS.

Signed-off-by: Chin-Ting Kuo 
---
v2: Remove defconfig files from this patch.

 drivers/spi/Kconfig  |   8 +
 drivers/spi/Makefile |   1 +
 drivers/spi/spi-aspeed.c | 822 +++
 3 files changed, 831 insertions(+)
 create mode 100644 drivers/spi/spi-aspeed.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index a1e515cb2b..a616294910 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -387,6 +387,14 @@ config SANDBOX_SPI
};
  };
 
+config SPI_ASPEED
+   bool "ASPEED SPI controller driver"
+   depends on DM_SPI && SPI_MEM
+   default n
+   help
+ Enable ASPEED SPI controller driver for AST2500
+ and AST2600 SoCs.
+
 config SPI_SIFIVE
bool "SiFive SPI driver"
help
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 06e81b465b..36a4bd5dce 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -9,6 +9,7 @@ obj-y += spi-uclass.o
 obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o
 obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o
 obj-$(CONFIG_SOFT_SPI) += soft_spi.o
+obj-$(CONFIG_SPI_ASPEED) += spi-aspeed.o
 obj-$(CONFIG_SPI_MEM) += spi-mem.o
 obj-$(CONFIG_TI_QSPI) += ti_qspi.o
 obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o
diff --git a/drivers/spi/spi-aspeed.c b/drivers/spi/spi-aspeed.c
new file mode 100644
index 00..9574aff793
--- /dev/null
+++ b/drivers/spi/spi-aspeed.c
@@ -0,0 +1,822 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * ASPEED FMC/SPI Controller driver
+ *
+ * Copyright (c) 2022 ASPEED Corporation.
+ * Copyright (c) 2022 IBM Corporation.
+ *
+ * Author:
+ * Chin-Ting Kuo 
+ * Cedric Le Goater 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* ASPEED FMC/SPI memory control register related */
+#define REG_CE_TYPE_SETTING  0x00
+#define REG_CE_ADDR_MODE_CTRL0x04
+#define REG_INTR_CTRL_STATUS 0x08
+#define REG_CE0_CTRL_REG 0x10
+#define REG_CE0_DECODED_ADDR_REG 0x30
+
+#define ASPEED_SPI_MAX_CS   3
+#define FLASH_CALIBRATION_LEN   0x400
+
+#define CTRL_IO_SINGLE_DATA 0
+#define CTRL_IO_QUAD_DATA   BIT(30)
+#define CTRL_IO_DUAL_DATA   BIT(29)
+
+#define CTRL_IO_MODE_USER   GENMASK(1, 0)
+#define CTRL_IO_MODE_CMD_READ   BIT(0)
+#define CTRL_IO_MODE_CMD_WRITE  BIT(1)
+#define CTRL_STOP_ACTIVEBIT(2)
+
+struct aspeed_spi_plat {
+   fdt_addr_t ctrl_base;
+   void __iomem *ahb_base; /* AHB address base for all flash devices. 

[PATCH v2 04/11] configs: aspeed: Enable SPI flash features

2022-05-09 Thread Chin-Ting Kuo
- Enable ASPEED SPI controller driver.
- Enable SPI flash memory configurations.
- Enable configurations for SPI flash manufacturers
  supported on both ASPEED AST2500 and AST2600 AVL.

Signed-off-by: Chin-Ting Kuo 
---
 configs/evb-ast2500_defconfig | 13 +
 configs/evb-ast2600_defconfig | 13 +
 2 files changed, 26 insertions(+)

diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index 2371cc2742..fd04fe5a60 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -35,6 +35,16 @@ CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_ASPEED=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
 CONFIG_FTGMAC100=y
@@ -44,6 +54,9 @@ CONFIG_RAM=y
 CONFIG_DM_RESET=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_TIMER=y
 CONFIG_WDT=y
diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig
index ea75762926..e013976bb0 100644
--- a/configs/evb-ast2600_defconfig
+++ b/configs/evb-ast2600_defconfig
@@ -66,6 +66,16 @@ CONFIG_MISC=y
 CONFIG_SPL_MISC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
 CONFIG_DM_MDIO=y
@@ -78,6 +88,9 @@ CONFIG_SPL_RAM=y
 CONFIG_DM_RESET=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_WDT=y
-- 
2.25.1



[PATCH v2 05/11] MAINTAINERS: Add ASPEED SPI driver file

2022-05-09 Thread Chin-Ting Kuo
Add spi-aspeed.c file for ARM ASPEED.

Signed-off-by: Chin-Ting Kuo 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 56be0bfad0..f2cd707eda 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -688,6 +688,13 @@ S: Maintained
 F: drivers/pci/pcie_phytium.c
 F: arch/arm/dts/phytium-durian.dts
 
+ASPEED FMC SPI DRIVER
+M: Chin-Ting Kuo 
+M: Cédric Le Goater 
+R: Aspeed BMC SW team 
+S: Maintained
+F: drivers/spi/spi-aspeed.c
+
 BINMAN
 M: Simon Glass 
 M: Alper Nebi Yasak 
-- 
2.25.1



[PATCH v2 00/11] Add ASPEED SPI controller driver

2022-05-09 Thread Chin-Ting Kuo
This patch series aims to porting ASPEED FMC/SPI memory controller
driver with spi-mem interface. spi-mem dirmap framework is also
synchronized from Linux. These patches have been verified on both
AST2600 and AST2500 EVBs.

Changes in v2:
  - Separate defconfig files from the SPI driver patch.
  - Use "if (CONFIG_IS_ENABLED(SPI_DIRMAP))" to wrap
spi_dirmap related functions.
  - Add Winbond w25q512jv flash ID.

Chin-Ting Kuo (11):
  clk: aspeed: Get HCLK frequency support
  pinctrl: aspeed: FWSPICS1 and SPI1CS1 pin support
  spi: aspeed: Add ASPEED SPI controller driver
  configs: aspeed: Enable SPI flash features
  MAINTAINERS: Add ASPEED SPI driver file
  arm: dts: aspeed: Update SPI flash node settings
  spi-mem: Add dirmap API from Linux
  mtd: spi-nor: Use spi-mem dirmap API
  spi: aspeed: SPI dirmap read support
  configs: aspeed: Enable CONFIG_SPI_DIRMAP
  mtd: spi-nor-ids: Add Winbond W25Q512JV ID

 MAINTAINERS  |   7 +
 arch/arm/dts/ast2500-evb.dts |  33 +
 arch/arm/dts/ast2500.dtsi|  23 +-
 arch/arm/dts/ast2600-evb.dts |   8 -
 arch/arm/dts/ast2600.dtsi|  34 +-
 configs/evb-ast2500_defconfig|  14 +
 configs/evb-ast2600_defconfig|  14 +
 drivers/clk/aspeed/clk_ast2500.c |  24 +
 drivers/mtd/spi/sf_probe.c   |  76 ++
 drivers/mtd/spi/spi-nor-core.c   |  55 +-
 drivers/mtd/spi/spi-nor-ids.c|   5 +
 drivers/pinctrl/aspeed/pinctrl_ast2500.c |   2 +
 drivers/spi/Kconfig  |  18 +
 drivers/spi/Makefile |   1 +
 drivers/spi/spi-aspeed.c | 915 +++
 drivers/spi/spi-mem.c| 268 +++
 include/linux/mtd/spi-nor.h  |  18 +
 include/spi-mem.h|  79 ++
 18 files changed, 1548 insertions(+), 46 deletions(-)
 create mode 100644 drivers/spi/spi-aspeed.c

-- 
2.25.1



[PATCH v2 01/11] clk: aspeed: Get HCLK frequency support

2022-05-09 Thread Chin-Ting Kuo
User can get correct HCLK frequency during driver probe stage
by adding the following configuration in the device tree.
"clocks = < ASPEED_CLK_AHB>".

Signed-off-by: Chin-Ting Kuo 
---
 drivers/clk/aspeed/clk_ast2500.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
index a1b4496ca2..d2a58a8462 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -29,6 +29,12 @@
 
 #define D2PLL_DEFAULT_RATE (250 * 1000 * 1000)
 
+/*
+ * AXI/AHB clock selection, taken from Aspeed SDK
+ */
+#define SCU_HWSTRAP_AXIAHB_DIV_SHIFT9
+#define SCU_HWSTRAP_AXIAHB_DIV_MASK (0x7 << SCU_HWSTRAP_AXIAHB_DIV_SHIFT)
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -85,6 +91,21 @@ static ulong ast2500_get_clkin(struct ast2500_scu *scu)
? 25 * 1000 * 1000 : 24 * 1000 * 1000;
 }
 
+static u32 ast2500_get_hclk(struct ast2500_scu *scu)
+{
+   ulong clkin = ast2500_get_clkin(scu);
+   u32 hpll_reg = readl(>h_pll_param);
+   ulong axi_div = 2;
+   u32 rate;
+   ulong ahb_div = 1 + ((readl(>hwstrap)
+ & SCU_HWSTRAP_AXIAHB_DIV_MASK)
+>> SCU_HWSTRAP_AXIAHB_DIV_SHIFT);
+
+   rate = ast2500_get_hpll_rate(clkin, hpll_reg);
+
+   return (rate / axi_div / ahb_div);
+}
+
 /**
  * Get current rate or uart clock
  *
@@ -146,6 +167,9 @@ static ulong ast2500_clk_get_rate(struct clk *clk)
rate = rate / apb_div;
}
break;
+   case ASPEED_CLK_AHB:
+   rate = ast2500_get_hclk(priv->scu);
+   break;
case ASPEED_CLK_SDIO:
{
ulong apb_div = 4 + 4 * ((readl(>scu->clk_sel1)
-- 
2.25.1



[PATCH v2 02/11] pinctrl: aspeed: FWSPICS1 and SPI1CS1 pin support

2022-05-09 Thread Chin-Ting Kuo
Add FWSPICS1 and SPI1CS1 in AST2500 pinctrl group.
On AST2500 EVB, FWSPICS1 can be supported by default.
An extra jumper, J45, should be configured before
enabling SPI1CS1.

Signed-off-by: Chin-Ting Kuo 
---
 drivers/pinctrl/aspeed/pinctrl_ast2500.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pinctrl/aspeed/pinctrl_ast2500.c 
b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
index 3c2e10b88e..93920a6389 100644
--- a/drivers/pinctrl/aspeed/pinctrl_ast2500.c
+++ b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
@@ -61,6 +61,8 @@ static const struct ast2500_group_config ast2500_groups[] = {
{ "MDIO2", 5, (1 << 2) },
{ "SD1", 5, (1 << 0) },
{ "SD2", 5, (1 << 1) },
+   { "FWSPICS1", 3, (1 << 24) },
+   { "SPI1CS1", 1, (1 << 15) },
 };
 
 static int ast2500_pinctrl_get_groups_count(struct udevice *dev)
-- 
2.25.1



RE: [PATCH 3/8] spi: aspeed: Add ASPEED SPI controller driver

2022-05-03 Thread Chin-Ting Kuo
Hi Jagan,

> -Original Message-
> From: Jagan Teki 
> Sent: Tuesday, May 3, 2022 9:23 PM
> To: Chin-Ting Kuo 
> Subject: Re: [PATCH 3/8] spi: aspeed: Add ASPEED SPI controller driver
> 
> On Tue, May 3, 2022 at 6:44 PM Chin-Ting Kuo
>  wrote:
> >
> > Hi Jagan,
> >
> > Thanks for the review.
> >
> > > -Original Message-
> > > From: Jagan Teki 
> > > Sent: Tuesday, May 3, 2022 8:32 PM
> > > To: Chin-Ting Kuo 
> > > Subject: Re: [PATCH 3/8] spi: aspeed: Add ASPEED SPI controller
> > > driver
> > >
> > > On Thu, Apr 14, 2022 at 4:54 PM Chin-Ting Kuo
> > >  wrote:
> > > >
> > > > Add ASPEED BMC FMC/SPI memory controller driver with spi-mem
> > > > interface for AST2500 and AST2600 platform.
> > > >
> > > > There are three SPI memory controllers embedded in an ASPEED SoC.
> > > > - FMC: Named as Firmware Memory Controller. After AC on, MCU ROM
> > > >fetches initial device boot image from FMC chip select(CS) 0.
> > > >
> > > > - SPI1: Play the role of a SPI Master controller. Or, there is a
> > > > dedicated path for HOST(X86) to access its BIOS flash mounted
> > > > under BMC. spi-aspeed.c implements the control sequence
> when
> > > > SPI1 is a SPI master.
> > > >
> > > > - SPI2: It is a pure SPI flash controller. For most scenarios, flashes
> > > > mounted under it are for pure storage purpose.
> > > >
> > > > ASPEED SPI controller supports 1-1-1, 1-1-2 and 1-1-4 SPI flash mode.
> > > > Three types of command mode are supported, normal mode, command
> > > > read/write mode and user mode.
> > > > - Normal mode: Default mode. After power on, normal read command
> > > > 03h
> > > or
> > > >13h is used to fetch boot image from SPI flash.
> > > >- AST2500: Only 03h command can be used after
> power
> > > on
> > > >   or reset.
> > > >- AST2600: If FMC04[6:4] is set, 13h command is used,
> > > >   otherwise, 03h command.
> > > >The address length is decided by FMC04[2:0].
> > > >
> > > > - Command mode: SPI controller can send command and address
> > > > automatically when CPU read/write the related
> > > remapped
> > > > or decoded address area. The command used by this
> > > mode
> > > > can be configured by FMC10/14/18[23:16]. Also, the
> > > > address length is decided by FMC04[2:0]. This mode
> will
> > > > be implemented in the following patch series.
> > > >
> > > > - User mode: It is a traditional and pure SPI operation, where
> > > >  SPI transmission is controlled by CPU. It is the main
> > > >  mode in this patch.
> > > >
> > > > Each SPI controller in ASPEED SoC has its own decoded address mapping.
> > > > Within each SPI controller decoded address, driver can assign a
> > > > specific address region for each CS of a SPI controller. The
> > > > decoded address cannot overlap to each other. With normal mode and
> > > > command mode, the decoded address accessed by the CPU determines
> > > > which CS is
> > > active.
> > > > When user mode is adopted, the CS decoded address is a FIFO, CPU
> > > > can send/receive any SPI transmission by accessing the related
> > > > decoded address for the target CS.
> > > >
> > > > Signed-off-by: Chin-Ting Kuo 
> > > > ---
> > > >  configs/evb-ast2500_defconfig |  13 +
> > > > configs/evb-ast2600_defconfig
> > > > |  13 +
> > > >  drivers/spi/Kconfig   |   8 +
> > > >  drivers/spi/Makefile  |   1 +
> > > >  drivers/spi/spi-aspeed.c  | 822
> > > ++
> > > >  5 files changed, 857 insertions(+)  create mode 100644
> > > > drivers/spi/spi-aspeed.c
> > > >
> > > > diff --git a/configs/evb-ast2500_defconfig
> > > > b/configs/evb-ast2500_defconfig index 53fe7776e9..f00bded237
> > > > 100644
> > > > --- a/configs/evb-ast2500_defconfig
> > > > +++ b/configs/evb-ast2500_defconfig
> > 

RE: [PATCH 3/8] spi: aspeed: Add ASPEED SPI controller driver

2022-05-03 Thread Chin-Ting Kuo
Hi Jagan,

Thanks for the review.

> -Original Message-
> From: Jagan Teki 
> Sent: Tuesday, May 3, 2022 8:32 PM
> To: Chin-Ting Kuo 
> Subject: Re: [PATCH 3/8] spi: aspeed: Add ASPEED SPI controller driver
> 
> On Thu, Apr 14, 2022 at 4:54 PM Chin-Ting Kuo
>  wrote:
> >
> > Add ASPEED BMC FMC/SPI memory controller driver with spi-mem interface
> > for AST2500 and AST2600 platform.
> >
> > There are three SPI memory controllers embedded in an ASPEED SoC.
> > - FMC: Named as Firmware Memory Controller. After AC on, MCU ROM
> >fetches initial device boot image from FMC chip select(CS) 0.
> >
> > - SPI1: Play the role of a SPI Master controller. Or, there is a
> > dedicated path for HOST(X86) to access its BIOS flash mounted
> > under BMC. spi-aspeed.c implements the control sequence when
> > SPI1 is a SPI master.
> >
> > - SPI2: It is a pure SPI flash controller. For most scenarios, flashes
> > mounted under it are for pure storage purpose.
> >
> > ASPEED SPI controller supports 1-1-1, 1-1-2 and 1-1-4 SPI flash mode.
> > Three types of command mode are supported, normal mode, command
> > read/write mode and user mode.
> > - Normal mode: Default mode. After power on, normal read command 03h
> or
> >13h is used to fetch boot image from SPI flash.
> >- AST2500: Only 03h command can be used after power
> on
> >   or reset.
> >- AST2600: If FMC04[6:4] is set, 13h command is used,
> >   otherwise, 03h command.
> >The address length is decided by FMC04[2:0].
> >
> > - Command mode: SPI controller can send command and address
> > automatically when CPU read/write the related
> remapped
> > or decoded address area. The command used by this
> mode
> > can be configured by FMC10/14/18[23:16]. Also, the
> > address length is decided by FMC04[2:0]. This mode will
> > be implemented in the following patch series.
> >
> > - User mode: It is a traditional and pure SPI operation, where
> >  SPI transmission is controlled by CPU. It is the main
> >  mode in this patch.
> >
> > Each SPI controller in ASPEED SoC has its own decoded address mapping.
> > Within each SPI controller decoded address, driver can assign a
> > specific address region for each CS of a SPI controller. The decoded
> > address cannot overlap to each other. With normal mode and command
> > mode, the decoded address accessed by the CPU determines which CS is
> active.
> > When user mode is adopted, the CS decoded address is a FIFO, CPU can
> > send/receive any SPI transmission by accessing the related decoded
> > address for the target CS.
> >
> > Signed-off-by: Chin-Ting Kuo 
> > ---
> >  configs/evb-ast2500_defconfig |  13 +  configs/evb-ast2600_defconfig
> > |  13 +
> >  drivers/spi/Kconfig   |   8 +
> >  drivers/spi/Makefile  |   1 +
> >  drivers/spi/spi-aspeed.c  | 822
> ++
> >  5 files changed, 857 insertions(+)
> >  create mode 100644 drivers/spi/spi-aspeed.c
> >
> > diff --git a/configs/evb-ast2500_defconfig
> > b/configs/evb-ast2500_defconfig index 53fe7776e9..f00bded237 100644
> > --- a/configs/evb-ast2500_defconfig
> > +++ b/configs/evb-ast2500_defconfig
> > @@ -36,6 +36,16 @@ CONFIG_DM_I2C=y
> >  CONFIG_SYS_I2C_ASPEED=y
> >  CONFIG_MMC_SDHCI=y
> >  CONFIG_MMC_SDHCI_ASPEED=y
> > +CONFIG_DM_SPI_FLASH=y
> > +CONFIG_SPI_FLASH_SFDP_SUPPORT=y
> > +CONFIG_SPI_FLASH_GIGADEVICE=y
> > +CONFIG_SPI_FLASH_ISSI=y
> > +CONFIG_SPI_FLASH_MACRONIX=y
> > +CONFIG_SPI_FLASH_SPANSION=y
> > +CONFIG_SPI_FLASH_STMICRO=y
> > +CONFIG_SPI_FLASH_SST=y
> > +CONFIG_SPI_FLASH_WINBOND=y
> > +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
> >  CONFIG_PHY_REALTEK=y
> >  CONFIG_DM_ETH=y
> >  CONFIG_FTGMAC100=y
> > @@ -45,6 +55,9 @@ CONFIG_RAM=y
> >  CONFIG_DM_RESET=y
> >  CONFIG_DM_SERIAL=y
> >  CONFIG_SYS_NS16550=y
> > +CONFIG_SPI=y
> > +CONFIG_DM_SPI=y
> > +CONFIG_SPI_ASPEED=y
> >  CONFIG_SYSRESET=y
> >  CONFIG_TIMER=y
> >  CONFIG_WDT=y
> > diff --git a/configs/evb-ast2600_defconfig
> > b/configs/evb-ast2600_defconfig index ea75762926..e013976bb0 100644
> > --- a/configs/evb-ast2600_defconfig
> > +++ b/configs/evb-ast2600_defconfig
> > @@ -66,6 +66,16 @@ CONFIG_MISC=y
> >  C

RE: [PATCH 7/8] mtd: spi-nor: use spi-mem dirmap API

2022-04-20 Thread Chin-Ting Kuo
Hi Pratyush,

Thanks for your review.

> -Original Message-
> From: Pratyush Yadav 
> Sent: Wednesday, April 20, 2022 4:21 PM
> To: Chin-Ting Kuo 
> Subject: Re: [PATCH 7/8] mtd: spi-nor: use spi-mem dirmap API
> 
> On 14/04/22 07:23PM, Chin-Ting Kuo wrote:
> > This adds support for the dirmap API to the spi-nor subsystem, as
> > introduced in Linux commit df5c210 ("mtd: spi-nor: use spi-mem dirmap
> > API").
> >
> > This patch is synchronize from the following patch
> > https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504
> > -4-sean...@gmail.com/
> >
> > Signed-off-by: Chin-Ting Kuo 
> > Signed-off-by: Sean Anderson 
> > ---
> >  drivers/mtd/spi/sf_probe.c | 82
> ++
> >  drivers/mtd/spi/spi-nor-core.c | 55 ---
> >  include/linux/mtd/spi-nor.h| 18 
> >  3 files changed, 139 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
> > index f461082e03..a3b38b6a29 100644
> > --- a/drivers/mtd/spi/sf_probe.c
> > +++ b/drivers/mtd/spi/sf_probe.c
> > @@ -10,13 +10,81 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >
> >  #include "sf_internal.h"
> >
> > +#if CONFIG_IS_ENABLED(SPI_DIRMAP)
> > +static int spi_nor_create_read_dirmap(struct spi_nor *nor) {
> > +   struct spi_mem_dirmap_info info = {
> > +   .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),
> > + SPI_MEM_OP_ADDR(nor->addr_width, 0, 0),
> > + SPI_MEM_OP_DUMMY(nor->read_dummy, 0),
> > + SPI_MEM_OP_DATA_IN(0, NULL, 0)),
> > +   .offset = 0,
> > +   .length = nor->mtd.size,
> > +   };
> > +   struct spi_mem_op *op = _tmpl;
> > +
> > +   /* get transfer protocols. */
> > +   spi_nor_setup_op(nor, op, nor->read_proto);
> > +   op->data.buswidth =
> > +spi_nor_get_protocol_data_nbits(nor->read_proto);
> > +
> > +   /* convert the dummy cycles to the number of bytes */
> > +   op->dummy.nbytes = (nor->read_dummy * op->dummy.buswidth) / 8;
> > +   if (spi_nor_protocol_is_dtr(nor->read_proto))
> > +   op->dummy.nbytes *= 2;
> > +
> > +   nor->dirmap.rdesc = spi_mem_dirmap_create(nor->spi, );
> > +   if (IS_ERR(nor->dirmap.rdesc))
> > +   return PTR_ERR(nor->dirmap.rdesc);
> > +
> > +   return 0;
> > +}
> > +
> > +static int spi_nor_create_write_dirmap(struct spi_nor *nor) {
> > +   struct spi_mem_dirmap_info info = {
> > +   .op_tmpl =
> SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 0),
> > + SPI_MEM_OP_ADDR(nor->addr_width, 0, 0),
> > + SPI_MEM_OP_NO_DUMMY,
> > + SPI_MEM_OP_DATA_OUT(0, NULL, 0)),
> > +   .offset = 0,
> > +   .length = nor->mtd.size,
> > +   };
> > +   struct spi_mem_op *op = _tmpl;
> > +
> > +   /* get transfer protocols. */
> > +   spi_nor_setup_op(nor, op, nor->write_proto);
> > +   op->data.buswidth =
> > +spi_nor_get_protocol_data_nbits(nor->write_proto);
> > +
> > +   if (nor->program_opcode == SPINOR_OP_AAI_WP &&
> nor->sst_write_second)
> > +   op->addr.nbytes = 0;
> > +
> > +   nor->dirmap.wdesc = spi_mem_dirmap_create(nor->spi, );
> > +   if (IS_ERR(nor->dirmap.wdesc))
> > +   return PTR_ERR(nor->dirmap.wdesc);
> > +
> > +   return 0;
> > +}
> > +#else
> > +static int spi_nor_create_read_dirmap(struct spi_nor *nor) {
> > +   return 0;
> > +}
> > +
> > +static int spi_nor_create_write_dirmap(struct spi_nor *nor) {
> > +   return 0;
> > +}
> > +#endif /* CONFIG_SPI_DIRMAP */
> > +
> 
> Instead of wrapping these in #ifdefs...
> 
> >  /**
> >   * spi_flash_probe_slave() - Probe for a SPI flash device on a bus
> >   *
> > @@ -45,6 +113,14 @@ static int spi_flash_probe_slave(struct spi_flash
> *flash)
> > if (ret)
> > goto err_read_id;
> >
> > +   ret = spi_nor_create_read_dirmap(flash);
> > +   if (ret)
> > +   return ret;
> > +
> > +   ret = spi_nor_create_write_dirmap(flash);
> > +   if (ret)
> &

[PATCH 5/8] arm: dts: aspeed: Update SPI flash node settings

2022-04-14 Thread Chin-Ting Kuo
For both AST2500 and AST2600, there are three
SPI controllers, FMC(Firmware Memory Controller),
SPI1 and SPI2. The clock source is HCLK. Following
is the basic information for ASPEED SPI controller.

AST2500:
  - FMC:
  CS number: 3
  controller reg: 0x1e62 - 0x1e62
  decoded address: 0x2000 - 0x2fff

  - SPI1:
  CS number: 2
  controller reg: 0x1e63 - 0x1e630fff
  decoded address: 0x3000 - 0x37ff

  - SPI2:
  CS number: 2
  controller reg: 0x1e631000 - 0x1e631fff
  decoded address: 0x3800 - 0x3fff

AST2600:
  - FMC:
  CS number: 3
  controller reg: 0x1e62 - 0x1e62
  decoded address: 0x2000 - 0x2fff

  - SPI1:
  CS number: 2
  controller reg: 0x1e63 - 0x1e630fff
  decoded address: 0x3000 - 0x3fff

  - SPI2:
  CS number: 3
  controller reg: 0x1e631000 - 0x1e631fff
  decoded address: 0x5000 - 0x5fff

Signed-off-by: Chin-Ting Kuo 
---
 arch/arm/dts/ast2500-evb.dts | 33 +
 arch/arm/dts/ast2500.dtsi| 23 ---
 arch/arm/dts/ast2600-evb.dts |  8 
 arch/arm/dts/ast2600.dtsi| 34 +++---
 4 files changed, 68 insertions(+), 30 deletions(-)

diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
index 4796ed445f..c6b7675902 100644
--- a/arch/arm/dts/ast2500-evb.dts
+++ b/arch/arm/dts/ast2500-evb.dts
@@ -73,3 +73,36 @@
pinctrl-names = "default";
pinctrl-0 = <_sd2_default>;
 };
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_fwspics1_default>;
+
+   flash@0 {
+   status = "okay";
+   spi-max-frequency = <5000>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+
+   flash@1 {
+   status = "okay";
+   spi-max-frequency = <5000>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+};
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_spi1cs1_default>;
+
+   flash@0 {
+   status = "okay";
+   spi-max-frequency = <5000>;
+   spi-tx-bus-width = <2>;
+   spi-rx-bus-width = <2>;
+   };
+};
diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi
index ee66ef6704..d78a53aeb7 100644
--- a/arch/arm/dts/ast2500.dtsi
+++ b/arch/arm/dts/ast2500.dtsi
@@ -57,23 +57,26 @@
ranges;
 
fmc: flash-controller@1e62 {
-   reg = < 0x1e62 0xc4
-   0x2000 0x1000 >;
+   reg = <0x1e62 0xc4>, <0x2000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
compatible = "aspeed,ast2500-fmc";
+   clocks = < ASPEED_CLK_AHB>;
+   num-cs = <3>;
status = "disabled";
-   interrupts = <19>;
+
flash@0 {
reg = < 0 >;
compatible = "jedec,spi-nor";
status = "disabled";
};
+
flash@1 {
reg = < 1 >;
compatible = "jedec,spi-nor";
status = "disabled";
};
+
flash@2 {
reg = < 2 >;
compatible = "jedec,spi-nor";
@@ -82,17 +85,20 @@
};
 
spi1: flash-controller@1e63 {
-   reg = < 0x1e63 0xc4
-   0x3000 0x0800 >;
+   reg = <0x1e63 0xc4>, <0x3000 0x0800>;
#address-cells = <1>;
#size-cells = <0>;
compatible = "aspeed,ast2500-spi";
+   clocks = < ASPEED_CLK_AHB>;
+   num-cs = <2>;
status = "disabled";
+
flash@0 {
reg = < 0 >;
compatible = "jedec,spi-nor";
status = "disabled";
};
+
flash@1 {
reg = < 1 >;
compat

[PATCH 6/8] spi-mem: Add dirmap API from Linux

2022-04-14 Thread Chin-Ting Kuo
This adds the dirmap API originally introduced in Linux commit aa167f3
("spi: spi-mem: Add a new API to support direct mapping"). This also
includes several follow-up patches and fixes.

Changes from Linux include:
* Added Kconfig option
* Changed struct device to struct udevice
* Changed struct spi_mem to struct spi_slave

This patch is obtained from the following patch
https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504-3-sean...@gmail.com/

Signed-off-by: Chin-Ting Kuo 
Signed-off-by: Sean Anderson 
---
 drivers/spi/Kconfig   |  10 ++
 drivers/spi/spi-mem.c | 270 ++
 include/spi-mem.h |  98 +++
 3 files changed, 378 insertions(+)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index dc05b3966f..cf0eaf1810 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -40,6 +40,16 @@ config SPI_MEM
  This extension is meant to simplify interaction with SPI memories
  by providing an high-level interface to send memory-like commands.
 
+config SPI_DIRMAP
+   bool "SPI direct mapping"
+   depends on SPI_MEM
+   help
+ Enable the SPI direct mapping API. Most modern SPI controllers can
+ directly map a SPI memory (or a portion of the SPI memory) in the CPU
+ address space. Most of the time this brings significant performance
+ improvements as it automates the whole process of sending SPI memory
+ operations every time a new region is accessed.
+
 if DM_SPI
 
 config ALTERA_SPI
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 9c1ede1b61..8e4f37fb50 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -21,6 +21,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #endif
 
 #ifndef __UBOOT__
@@ -491,6 +493,274 @@ int spi_mem_adjust_op_size(struct spi_slave *slave, 
struct spi_mem_op *op)
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
 
+#if CONFIG_IS_ENABLED(SPI_DIRMAP)
+static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ u64 offs, size_t len, void *buf)
+{
+   struct spi_mem_op op = desc->info.op_tmpl;
+   int ret;
+
+   op.addr.val = desc->info.offset + offs;
+   op.data.buf.in = buf;
+   op.data.nbytes = len;
+   ret = spi_mem_adjust_op_size(desc->slave, );
+   if (ret)
+   return ret;
+
+   ret = spi_mem_exec_op(desc->slave, );
+   if (ret)
+   return ret;
+
+   return op.data.nbytes;
+}
+
+static ssize_t spi_mem_no_dirmap_write(struct spi_mem_dirmap_desc *desc,
+  u64 offs, size_t len, const void *buf)
+{
+   struct spi_mem_op op = desc->info.op_tmpl;
+   int ret;
+
+   op.addr.val = desc->info.offset + offs;
+   op.data.buf.out = buf;
+   op.data.nbytes = len;
+   ret = spi_mem_adjust_op_size(desc->slave, );
+   if (ret)
+   return ret;
+
+   ret = spi_mem_exec_op(desc->slave, );
+   if (ret)
+   return ret;
+
+   return op.data.nbytes;
+}
+
+/**
+ * spi_mem_dirmap_create() - Create a direct mapping descriptor
+ * @mem: SPI mem device this direct mapping should be created for
+ * @info: direct mapping information
+ *
+ * This function is creating a direct mapping descriptor which can then be used
+ * to access the memory using spi_mem_dirmap_read() or spi_mem_dirmap_write().
+ * If the SPI controller driver does not support direct mapping, this function
+ * falls back to an implementation using spi_mem_exec_op(), so that the caller
+ * doesn't have to bother implementing a fallback on his own.
+ *
+ * Return: a valid pointer in case of success, and ERR_PTR() otherwise.
+ */
+struct spi_mem_dirmap_desc *
+spi_mem_dirmap_create(struct spi_slave *slave,
+ const struct spi_mem_dirmap_info *info)
+{
+   struct udevice *bus = slave->dev->parent;
+   struct dm_spi_ops *ops = spi_get_ops(bus);
+   struct spi_mem_dirmap_desc *desc;
+   int ret = -EOPNOTSUPP;
+
+   /* Make sure the number of address cycles is between 1 and 8 bytes. */
+   if (!info->op_tmpl.addr.nbytes || info->op_tmpl.addr.nbytes > 8)
+   return ERR_PTR(-EINVAL);
+
+   /* data.dir should either be SPI_MEM_DATA_IN or SPI_MEM_DATA_OUT. */
+   if (info->op_tmpl.data.dir == SPI_MEM_NO_DATA)
+   return ERR_PTR(-EINVAL);
+
+   desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+   if (!desc)
+   return ERR_PTR(-ENOMEM);
+
+   desc->slave = slave;
+   desc->info = *info;
+   if (ops->mem_ops && ops->mem_ops->dirmap_create)
+   ret = ops->mem_ops->dirmap_create(desc);
+
+   if (ret) {
+   desc->nodirmap = true;
+   if (!spi_mem_supports_op(desc->slave, >info.op_tmpl))
+   ret = -EOPNOTSUPP;
+ 

[PATCH 7/8] mtd: spi-nor: use spi-mem dirmap API

2022-04-14 Thread Chin-Ting Kuo
This adds support for the dirmap API to the spi-nor subsystem, as
introduced in Linux commit df5c210 ("mtd: spi-nor: use spi-mem
dirmap API").

This patch is synchronize from the following patch
https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504-4-sean...@gmail.com/

Signed-off-by: Chin-Ting Kuo 
Signed-off-by: Sean Anderson 
---
 drivers/mtd/spi/sf_probe.c | 82 ++
 drivers/mtd/spi/spi-nor-core.c | 55 ---
 include/linux/mtd/spi-nor.h| 18 
 3 files changed, 139 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index f461082e03..a3b38b6a29 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -10,13 +10,81 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include "sf_internal.h"
 
+#if CONFIG_IS_ENABLED(SPI_DIRMAP)
+static int spi_nor_create_read_dirmap(struct spi_nor *nor)
+{
+   struct spi_mem_dirmap_info info = {
+   .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),
+ SPI_MEM_OP_ADDR(nor->addr_width, 0, 0),
+ SPI_MEM_OP_DUMMY(nor->read_dummy, 0),
+ SPI_MEM_OP_DATA_IN(0, NULL, 0)),
+   .offset = 0,
+   .length = nor->mtd.size,
+   };
+   struct spi_mem_op *op = _tmpl;
+
+   /* get transfer protocols. */
+   spi_nor_setup_op(nor, op, nor->read_proto);
+   op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto);
+
+   /* convert the dummy cycles to the number of bytes */
+   op->dummy.nbytes = (nor->read_dummy * op->dummy.buswidth) / 8;
+   if (spi_nor_protocol_is_dtr(nor->read_proto))
+   op->dummy.nbytes *= 2;
+
+   nor->dirmap.rdesc = spi_mem_dirmap_create(nor->spi, );
+   if (IS_ERR(nor->dirmap.rdesc))
+   return PTR_ERR(nor->dirmap.rdesc);
+
+   return 0;
+}
+
+static int spi_nor_create_write_dirmap(struct spi_nor *nor)
+{
+   struct spi_mem_dirmap_info info = {
+   .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 0),
+ SPI_MEM_OP_ADDR(nor->addr_width, 0, 0),
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_DATA_OUT(0, NULL, 0)),
+   .offset = 0,
+   .length = nor->mtd.size,
+   };
+   struct spi_mem_op *op = _tmpl;
+
+   /* get transfer protocols. */
+   spi_nor_setup_op(nor, op, nor->write_proto);
+   op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);
+
+   if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
+   op->addr.nbytes = 0;
+
+   nor->dirmap.wdesc = spi_mem_dirmap_create(nor->spi, );
+   if (IS_ERR(nor->dirmap.wdesc))
+   return PTR_ERR(nor->dirmap.wdesc);
+
+   return 0;
+}
+#else
+static int spi_nor_create_read_dirmap(struct spi_nor *nor)
+{
+   return 0;
+}
+
+static int spi_nor_create_write_dirmap(struct spi_nor *nor)
+{
+   return 0;
+}
+#endif /* CONFIG_SPI_DIRMAP */
+
 /**
  * spi_flash_probe_slave() - Probe for a SPI flash device on a bus
  *
@@ -45,6 +113,14 @@ static int spi_flash_probe_slave(struct spi_flash *flash)
if (ret)
goto err_read_id;
 
+   ret = spi_nor_create_read_dirmap(flash);
+   if (ret)
+   return ret;
+
+   ret = spi_nor_create_write_dirmap(flash);
+   if (ret)
+   return ret;
+
if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
ret = spi_flash_mtd_register(flash);
 
@@ -83,6 +159,9 @@ struct spi_flash *spi_flash_probe(unsigned int busnum, 
unsigned int cs,
 
 void spi_flash_free(struct spi_flash *flash)
 {
+   spi_mem_dirmap_destroy(flash->dirmap.wdesc);
+   spi_mem_dirmap_destroy(flash->dirmap.rdesc);
+
if (CONFIG_IS_ENABLED(SPI_FLASH_MTD))
spi_flash_mtd_unregister(flash);
 
@@ -153,6 +232,9 @@ static int spi_flash_std_remove(struct udevice *dev)
struct spi_flash *flash = dev_get_uclass_priv(dev);
int ret;
 
+   spi_mem_dirmap_destroy(flash->dirmap.wdesc);
+   spi_mem_dirmap_destroy(flash->dirmap.rdesc);
+
ret = spi_nor_remove(flash);
if (ret)
return ret;
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 3b7c817c02..0c6262b7fd 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -239,9 +239,9 @@ static u8 spi_nor_get_cmd_ext(const struct spi_nor *nor,
  * need to be initialized.
  * @proto: the protocol from which the properties need to be set.
  */
-static void spi_nor_setup_op(const struct s

[PATCH 8/8] spi: aspeed: SPI dirmap read support

2022-04-14 Thread Chin-Ting Kuo
>From the HW point of view, the performance of
command read mode is greater than user mode slightly.
Thus, dirmap read framework is introduced to achieve
this goal.

In dirmap_create, a specific decoded address area with
flash size is assigned to each CS. CPU can thus access
the SPI flash as normal memory in dirmap_read function.

Signed-off-by: Chin-Ting Kuo 
---
 configs/evb-ast2500_defconfig |  1 +
 configs/evb-ast2600_defconfig |  1 +
 drivers/spi/spi-aspeed.c  | 93 +++
 3 files changed, 95 insertions(+)

diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index f00bded237..b702a92289 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -57,6 +57,7 @@ CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
+CONFIG_SPI_DIRMAP=y
 CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_TIMER=y
diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig
index e013976bb0..279e5a6238 100644
--- a/configs/evb-ast2600_defconfig
+++ b/configs/evb-ast2600_defconfig
@@ -90,6 +90,7 @@ CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
+CONFIG_SPI_DIRMAP=y
 CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
diff --git a/drivers/spi/spi-aspeed.c b/drivers/spi/spi-aspeed.c
index 9574aff793..e5e348eb7b 100644
--- a/drivers/spi/spi-aspeed.c
+++ b/drivers/spi/spi-aspeed.c
@@ -85,6 +85,8 @@ struct aspeed_spi_info {
 
 static int aspeed_spi_trim_decoded_size(struct udevice *bus,
u32 decoded_sz_arr[]);
+static int aspeed_spi_decoded_range_config(struct udevice *bus,
+  u32 decoded_sz_arr[]);
 
 static u32 aspeed_spi_get_io_mode(u32 bus_width)
 {
@@ -509,6 +511,95 @@ static int aspeed_spi_exec_op_user_mode(struct spi_slave 
*slave,
return 0;
 }
 
+static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
+{
+   int ret = 0;
+   struct udevice *dev = desc->slave->dev;
+   struct udevice *bus = dev->parent;
+   struct aspeed_spi_plat *plat = dev_get_plat(bus);
+   struct aspeed_spi_priv *priv = dev_get_priv(bus);
+   struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
+   const struct aspeed_spi_info *info = priv->info;
+   struct spi_mem_op op_tmpl = desc->info.op_tmpl;
+   u32 i;
+   u32 cs = slave_plat->cs;
+   u32 decoded_sz_arr[ASPEED_SPI_MAX_CS];
+   u32 reg_val;
+
+   if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN) {
+   for (i = 0; i < priv->num_cs; i++) {
+   reg_val = readl(plat->ctrl_base +
+   REG_CE0_DECODED_ADDR_REG + i * 4);
+   decoded_sz_arr[i] =
+   info->segment_end(bus, reg_val) -
+   info->segment_start(bus, reg_val);
+   }
+
+   decoded_sz_arr[cs] = desc->info.length;
+
+   if (info->adjust_decoded_sz)
+   info->adjust_decoded_sz(bus, decoded_sz_arr);
+
+   for (i = 0; i < priv->num_cs; i++) {
+   dev_dbg(dev, "cs: %d, sz: 0x%x\n", i,
+   decoded_sz_arr[i]);
+   }
+
+   ret = aspeed_spi_decoded_range_config(bus, decoded_sz_arr);
+   if (ret)
+   return ret;
+
+   reg_val = readl(plat->ctrl_base + REG_CE0_CTRL_REG + cs * 4) &
+ (~info->cmd_io_ctrl_mask);
+   reg_val |= aspeed_spi_get_io_mode(op_tmpl.data.buswidth) |
+  op_tmpl.cmd.opcode << 16 |
+  ((op_tmpl.dummy.nbytes) & 0x3) << 6 |
+  ((op_tmpl.dummy.nbytes) & 0x4) << 14 |
+  CTRL_IO_MODE_CMD_READ;
+
+   writel(reg_val,
+  plat->ctrl_base + REG_CE0_CTRL_REG + cs * 4);
+   priv->flashes[cs].ce_ctrl_read = reg_val;
+
+   dev_dbg(dev, "read bus width: %d [0x%08x]\n",
+   op_tmpl.data.buswidth, priv->flashes[cs].ce_ctrl_read);
+   } else {
+   /*
+* dirmap_write is not supported currently due to a HW
+* limitation for command write mode: The written data
+* length should be multiple of 4-byte.
+*/
+   return -EOPNOTSUPP;
+   }
+
+   return ret;
+}
+
+static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc,
+ u64 offs, size_t len, void *buf)
+{
+   struct udevice *dev = desc->slave->dev;
+   struct aspeed_spi_priv *priv = dev_get_priv(dev->parent);
+   struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
+ 

[PATCH 3/8] spi: aspeed: Add ASPEED SPI controller driver

2022-04-14 Thread Chin-Ting Kuo
Add ASPEED BMC FMC/SPI memory controller driver with
spi-mem interface for AST2500 and AST2600 platform.

There are three SPI memory controllers embedded in an ASPEED SoC.
- FMC: Named as Firmware Memory Controller. After AC on, MCU ROM
   fetches initial device boot image from FMC chip select(CS) 0.

- SPI1: Play the role of a SPI Master controller. Or, there is a
dedicated path for HOST(X86) to access its BIOS flash mounted
under BMC. spi-aspeed.c implements the control sequence when
SPI1 is a SPI master.

- SPI2: It is a pure SPI flash controller. For most scenarios, flashes
mounted under it are for pure storage purpose.

ASPEED SPI controller supports 1-1-1, 1-1-2 and 1-1-4 SPI flash mode.
Three types of command mode are supported, normal mode, command
read/write mode and user mode.
- Normal mode: Default mode. After power on, normal read command 03h or
   13h is used to fetch boot image from SPI flash.
   - AST2500: Only 03h command can be used after power on
  or reset.
   - AST2600: If FMC04[6:4] is set, 13h command is used,
  otherwise, 03h command.
   The address length is decided by FMC04[2:0].

- Command mode: SPI controller can send command and address
automatically when CPU read/write the related remapped
or decoded address area. The command used by this mode
can be configured by FMC10/14/18[23:16]. Also, the
address length is decided by FMC04[2:0]. This mode will
be implemented in the following patch series.

- User mode: It is a traditional and pure SPI operation, where
 SPI transmission is controlled by CPU. It is the main
 mode in this patch.

Each SPI controller in ASPEED SoC has its own decoded address mapping.
Within each SPI controller decoded address, driver can assign a specific
address region for each CS of a SPI controller. The decoded address
cannot overlap to each other. With normal mode and command mode, the
decoded address accessed by the CPU determines which CS is active.
When user mode is adopted, the CS decoded address is a FIFO, CPU can
send/receive any SPI transmission by accessing the related decoded
address for the target CS.

Signed-off-by: Chin-Ting Kuo 
---
 configs/evb-ast2500_defconfig |  13 +
 configs/evb-ast2600_defconfig |  13 +
 drivers/spi/Kconfig   |   8 +
 drivers/spi/Makefile  |   1 +
 drivers/spi/spi-aspeed.c  | 822 ++
 5 files changed, 857 insertions(+)
 create mode 100644 drivers/spi/spi-aspeed.c

diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index 53fe7776e9..f00bded237 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -36,6 +36,16 @@ CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_ASPEED=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
 CONFIG_FTGMAC100=y
@@ -45,6 +55,9 @@ CONFIG_RAM=y
 CONFIG_DM_RESET=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_TIMER=y
 CONFIG_WDT=y
diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig
index ea75762926..e013976bb0 100644
--- a/configs/evb-ast2600_defconfig
+++ b/configs/evb-ast2600_defconfig
@@ -66,6 +66,16 @@ CONFIG_MISC=y
 CONFIG_SPL_MISC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
 CONFIG_DM_MDIO=y
@@ -78,6 +88,9 @@ CONFIG_SPL_RAM=y
 CONFIG_DM_RESET=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_SPI_ASPEED=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_WDT=y
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 8dba95ae4e..dc05b3966f 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -381,6 +381,14 @@ config SANDBOX_SPI
};
  };
 
+config SPI_ASPEED
+   bool "ASPEED SPI controller driver"
+   depends on DM_SPI && SPI_MEM
+   default n
+   help
+ Enable ASPEED SPI controller driver for AST2500
+ and AST2600 SoCs.
+
 config SPI_SIFIVE
bool "SiFive SPI driver"
help
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 7f43f843ca..6fbb3f30be 100644
--- a/drivers/sp

[PATCH 1/8] clk: aspeed: Get HCLK frequency support

2022-04-14 Thread Chin-Ting Kuo
User can get correct HCLK frequency during driver probe stage
by adding the following configuration in the device tree.
"clocks = < ASPEED_CLK_AHB>".

Signed-off-by: Chin-Ting Kuo 
---
 drivers/clk/aspeed/clk_ast2500.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
index a1b4496ca2..d2a58a8462 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -29,6 +29,12 @@
 
 #define D2PLL_DEFAULT_RATE (250 * 1000 * 1000)
 
+/*
+ * AXI/AHB clock selection, taken from Aspeed SDK
+ */
+#define SCU_HWSTRAP_AXIAHB_DIV_SHIFT9
+#define SCU_HWSTRAP_AXIAHB_DIV_MASK (0x7 << SCU_HWSTRAP_AXIAHB_DIV_SHIFT)
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -85,6 +91,21 @@ static ulong ast2500_get_clkin(struct ast2500_scu *scu)
? 25 * 1000 * 1000 : 24 * 1000 * 1000;
 }
 
+static u32 ast2500_get_hclk(struct ast2500_scu *scu)
+{
+   ulong clkin = ast2500_get_clkin(scu);
+   u32 hpll_reg = readl(>h_pll_param);
+   ulong axi_div = 2;
+   u32 rate;
+   ulong ahb_div = 1 + ((readl(>hwstrap)
+ & SCU_HWSTRAP_AXIAHB_DIV_MASK)
+>> SCU_HWSTRAP_AXIAHB_DIV_SHIFT);
+
+   rate = ast2500_get_hpll_rate(clkin, hpll_reg);
+
+   return (rate / axi_div / ahb_div);
+}
+
 /**
  * Get current rate or uart clock
  *
@@ -146,6 +167,9 @@ static ulong ast2500_clk_get_rate(struct clk *clk)
rate = rate / apb_div;
}
break;
+   case ASPEED_CLK_AHB:
+   rate = ast2500_get_hclk(priv->scu);
+   break;
case ASPEED_CLK_SDIO:
{
ulong apb_div = 4 + 4 * ((readl(>scu->clk_sel1)
-- 
2.25.1



[PATCH 4/8] MAINTAINERS: Add ASPEED SPI driver file

2022-04-14 Thread Chin-Ting Kuo
Add spi-aspeed.c file for ARM ASPEED.

Signed-off-by: Chin-Ting Kuo 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0fc034f01f..c86ea34883 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -687,6 +687,13 @@ S: Maintained
 F: drivers/pci/pcie_phytium.c
 F: arch/arm/dts/phytium-durian.dts
 
+ASPEED FMC SPI DRIVER
+M: Chin-Ting Kuo 
+M: Cédric Le Goater 
+R: Aspeed BMC SW team 
+S: Maintained
+F: drivers/spi/spi-aspeed.c
+
 BINMAN
 M: Simon Glass 
 S: Maintained
-- 
2.25.1



[PATCH 0/8] Add ASPEED SPI controller driver

2022-04-14 Thread Chin-Ting Kuo
This patch series aims to porting ASPEED FMC/SPI memory controller
driver with spi-mem interface. spi-mem dirmap framework is also
synchronized from Linux. These patches have been verified on both
AST2600 and AST2500 EVBs.

Chin-Ting Kuo (8):
  clk: aspeed: Get HCLK frequency support
  pinctrl: aspeed: FWSPICS1 and SPI1CS1 pin support
  spi: aspeed: Add ASPEED SPI controller driver
  MAINTAINERS: Add ASPEED SPI driver file
  arm: dts: aspeed: Update SPI flash node settings
  spi-mem: Add dirmap API from Linux
  mtd: spi-nor: use spi-mem dirmap API
  spi: aspeed: SPI dirmap read support

 MAINTAINERS  |   7 +
 arch/arm/dts/ast2500-evb.dts |  33 +
 arch/arm/dts/ast2500.dtsi|  23 +-
 arch/arm/dts/ast2600-evb.dts |   8 -
 arch/arm/dts/ast2600.dtsi|  34 +-
 configs/evb-ast2500_defconfig|  14 +
 configs/evb-ast2600_defconfig|  14 +
 drivers/clk/aspeed/clk_ast2500.c |  24 +
 drivers/mtd/spi/sf_probe.c   |  82 ++
 drivers/mtd/spi/spi-nor-core.c   |  55 +-
 drivers/pinctrl/aspeed/pinctrl_ast2500.c |   2 +
 drivers/spi/Kconfig  |  18 +
 drivers/spi/Makefile |   1 +
 drivers/spi/spi-aspeed.c | 915 +++
 drivers/spi/spi-mem.c| 270 +++
 include/linux/mtd/spi-nor.h  |  18 +
 include/spi-mem.h|  98 +++
 17 files changed, 1570 insertions(+), 46 deletions(-)
 create mode 100644 drivers/spi/spi-aspeed.c

-- 
2.25.1



[PATCH 2/8] pinctrl: aspeed: FWSPICS1 and SPI1CS1 pin support

2022-04-14 Thread Chin-Ting Kuo
Add FWSPICS1 and SPI1CS1 in AST2500 pinctrl group.
On AST2500 EVB, FWSPICS1 can be supported by default.
An extra jumper, J45, should be configured before
enabling SPI1CS1.

Signed-off-by: Chin-Ting Kuo 
---
 drivers/pinctrl/aspeed/pinctrl_ast2500.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pinctrl/aspeed/pinctrl_ast2500.c 
b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
index 3c2e10b88e..93920a6389 100644
--- a/drivers/pinctrl/aspeed/pinctrl_ast2500.c
+++ b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
@@ -61,6 +61,8 @@ static const struct ast2500_group_config ast2500_groups[] = {
{ "MDIO2", 5, (1 << 2) },
{ "SD1", 5, (1 << 0) },
{ "SD2", 5, (1 << 1) },
+   { "FWSPICS1", 3, (1 << 24) },
+   { "SPI1CS1", 1, (1 << 15) },
 };
 
 static int ast2500_pinctrl_get_groups_count(struct udevice *dev)
-- 
2.25.1