summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorarun-pm <arun.p.m@linux.intel.com>2019-12-03 14:52:28 +0300
committerJae Hyun Yoo <jae.hyun.yoo@linux.intel.com>2021-11-05 10:22:09 +0300
commit9b4da1ccbb55bff55dd0b1746eefdbfafbbeba05 (patch)
tree2b1c3e13259f6b3ab579182e6540fea3f4848fa0 /drivers
parent057cdbfd1cf64959f6d4b7233005b6a35e2efc55 (diff)
downloadlinux-9b4da1ccbb55bff55dd0b1746eefdbfafbbeba05.tar.xz
SPI Quad IO driver support AST2600
This commit adds spi driver quad io support for AST2600 Note:- Removed n25q00 Quad I/O support for the time being due to clock issue with chip 'Micron 8UA15 - rw182 (128MB)' while enabling Quad I/O mode. Signed-off-by: arun-pm <arun.p.m@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/spi-nor/controllers/aspeed-smc.c49
-rw-r--r--drivers/mtd/spi-nor/micron-st.c7
2 files changed, 48 insertions, 8 deletions
diff --git a/drivers/mtd/spi-nor/controllers/aspeed-smc.c b/drivers/mtd/spi-nor/controllers/aspeed-smc.c
index c421fad4b3f5..e066dd5f1457 100644
--- a/drivers/mtd/spi-nor/controllers/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/controllers/aspeed-smc.c
@@ -21,6 +21,11 @@
#include <linux/sysfs.h>
#define DEVICE_NAME "aspeed-smc"
+#define AST2600A0 0x05000303
+#define AST2600A0_MAX_FREQ 50000000
+#define AST2600A0_SAFE_FREQ 40000000
+#define AST_MAX_FREQ 100000000
+#define AST2600_REVISION_ID_SCU 0x1e6e2004
/*
* The driver only support SPI flash
@@ -543,6 +548,10 @@ static int aspeed_smc_get_io_mode(struct aspeed_smc_chip *chip)
return CONTROL_IO_DUAL_DATA;
case SNOR_PROTO_1_2_2:
return CONTROL_IO_DUAL_ADDR_DATA;
+ case SNOR_PROTO_1_1_4:
+ return CONTROL_IO_QUAD_DATA;
+ case SNOR_PROTO_1_4_4:
+ return CONTROL_IO_QUAD_ADDR_DATA;
default:
dev_err(chip->nor.dev, "unsupported SPI read mode\n");
return -EINVAL;
@@ -574,7 +583,7 @@ static ssize_t aspeed_smc_read_user(struct spi_nor *nor, loff_t from,
aspeed_smc_write_to_ahb(chip->ahb_base, &dummy, sizeof(dummy));
/* Set IO mode only for data */
- if (io_mode == CONTROL_IO_DUAL_DATA)
+ if (io_mode == CONTROL_IO_DUAL_DATA || io_mode == CONTROL_IO_QUAD_DATA)
aspeed_smc_set_io_mode(chip, io_mode);
aspeed_smc_read_from_ahb(read_buf, chip->ahb_base, len);
@@ -1223,6 +1232,25 @@ static int aspeed_smc_chip_setup_finish(struct aspeed_smc_chip *chip)
return 0;
}
+static void aspeed_allowed_max_freq(struct aspeed_smc_chip *chip)
+{
+ void __iomem *scu_ast_revision_id = ioremap(AST2600_REVISION_ID_SCU, 4);
+ u32 rev_id = readl(scu_ast_revision_id);
+
+ /*Limit max spi frequency less than 50MHz on AST2600-A0 due
+ * to FWSPICLK signal quality issue.
+ */
+ if(rev_id == AST2600A0 && chip->clk_rate > AST2600A0_MAX_FREQ)
+ chip->clk_rate = AST2600A0_MAX_FREQ;
+}
+
+static u32 get_hwcaps(unsigned int tx_width){
+ if(tx_width == 4)
+ return SNOR_HWCAPS_READ_1_1_4;
+ else
+ return SNOR_HWCAPS_READ_1_1_2;
+}
+
static const struct spi_nor_controller_ops aspeed_smc_controller_ops = {
.prepare = aspeed_smc_prep,
.unprepare = aspeed_smc_unprep,
@@ -1235,17 +1263,13 @@ static const struct spi_nor_controller_ops aspeed_smc_controller_ops = {
static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller,
struct device_node *np, struct resource *r)
{
- const struct spi_nor_hwcaps hwcaps = {
- .mask = SNOR_HWCAPS_READ |
- SNOR_HWCAPS_READ_FAST |
- SNOR_HWCAPS_READ_1_1_2 |
- SNOR_HWCAPS_PP,
- };
+ struct spi_nor_hwcaps hwcaps;
const struct aspeed_smc_info *info = controller->info;
struct device *dev = controller->dev;
struct device_node *child;
unsigned int cs;
int ret = -ENODEV;
+ unsigned int spi_tx_width;
for_each_available_child_of_node(np, child) {
struct aspeed_smc_chip *chip;
@@ -1286,9 +1310,20 @@ static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller,
&chip->clk_rate)) {
chip->clk_rate = ASPEED_SPI_DEFAULT_FREQ;
}
+ aspeed_allowed_max_freq(chip);
dev_info(dev, "Using %d MHz SPI frequency\n",
chip->clk_rate / 1000000);
+ if (of_property_read_u32(child, "spi-tx-bus-width",
+ &spi_tx_width)) {
+ spi_tx_width = 2;
+ }
+ dev_info(dev, "tx width: %ld\n", spi_tx_width);
+
+ hwcaps.mask = SNOR_HWCAPS_READ |
+ SNOR_HWCAPS_READ_FAST |
+ get_hwcaps(spi_tx_width) |
+ SNOR_HWCAPS_PP;
chip->controller = controller;
chip->ctl = controller->regs + info->ctl0 + cs * 4;
chip->cs = cs;
diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
index c224e59820a1..5222af071b3f 100644
--- a/drivers/mtd/spi-nor/micron-st.c
+++ b/drivers/mtd/spi-nor/micron-st.c
@@ -172,8 +172,13 @@ static const struct flash_info st_parts[] = {
SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
SPI_NOR_4BIT_BP | SPI_NOR_BP3_SR_BIT6) },
+ /* Removed n25q00 Quad I/O support for the time being due to clock issue with chip 'Micron 8UA15 - rw182 (128MB)'
+ * while enabling Quad I/O mode. As this chip is default shipped in platforms, marking it
+ * as Not supported for the time being. Once all chips are replaced with the new model, this can be enabled
+ * back(Note:- Certain other chips having same name(n25q00) but different part number has no issues).
+ */
{ "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048,
- SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
+ SECT_4K | USE_FSR |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
SPI_NOR_4BIT_BP | SPI_NOR_BP3_SR_BIT6 |
NO_CHIP_ERASE) },