mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 21:54:01 +00:00
Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-spi
- Support Infineon S28HS02GT (Takahiro)
This commit is contained in:
commit
8986be59e7
7 changed files with 119 additions and 154 deletions
|
@ -331,18 +331,42 @@ static int spansion_read_any_reg(struct spi_nor *nor, u32 addr, u8 dummy,
|
|||
u8 *val)
|
||||
{
|
||||
struct spi_mem_op op =
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDAR, 1),
|
||||
SPI_MEM_OP_ADDR(nor->addr_mode_nbytes, addr, 1),
|
||||
SPI_MEM_OP_DUMMY(dummy / 8, 1),
|
||||
SPI_MEM_OP_DATA_IN(1, NULL, 1));
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 0),
|
||||
SPI_MEM_OP_ADDR(nor->addr_mode_nbytes, addr, 0),
|
||||
SPI_MEM_OP_DUMMY(dummy, 0),
|
||||
SPI_MEM_OP_DATA_IN(1, NULL, 0));
|
||||
u8 buf[2];
|
||||
int ret;
|
||||
|
||||
return spi_nor_read_write_reg(nor, &op, val);
|
||||
spi_nor_setup_op(nor, &op, nor->reg_proto);
|
||||
|
||||
/*
|
||||
* In Octal DTR mode, the number of address bytes is always 4 regardless
|
||||
* of addressing mode setting.
|
||||
*/
|
||||
if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR)
|
||||
op.addr.nbytes = 4;
|
||||
|
||||
/*
|
||||
* We don't want to read only one byte in DTR mode. So, read 2 and then
|
||||
* discard the second byte.
|
||||
*/
|
||||
if (spi_nor_protocol_is_dtr(nor->reg_proto))
|
||||
op.data.nbytes = 2;
|
||||
|
||||
ret = spi_nor_read_write_reg(nor, &op, buf);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*val = buf[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spansion_write_any_reg(struct spi_nor *nor, u32 addr, u8 val)
|
||||
{
|
||||
struct spi_mem_op op =
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRAR, 1),
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
|
||||
SPI_MEM_OP_ADDR(nor->addr_mode_nbytes, addr, 1),
|
||||
SPI_MEM_OP_NO_DUMMY,
|
||||
SPI_MEM_OP_DATA_OUT(1, NULL, 1));
|
||||
|
@ -714,7 +738,7 @@ static int set_4byte(struct spi_nor *nor, const struct flash_info *info,
|
|||
*/
|
||||
static int spansion_sr_ready(struct spi_nor *nor, u32 addr_base, u8 dummy)
|
||||
{
|
||||
u32 reg_addr = addr_base + SPINOR_REG_ADDR_STR1V;
|
||||
u32 reg_addr = addr_base + SPINOR_REG_CYPRESS_STR1V;
|
||||
u8 sr;
|
||||
int ret;
|
||||
|
||||
|
@ -728,7 +752,7 @@ static int spansion_sr_ready(struct spi_nor *nor, u32 addr_base, u8 dummy)
|
|||
else
|
||||
dev_dbg(nor->dev, "Programming Error occurred\n");
|
||||
|
||||
nor->write_reg(nor, SPINOR_OP_CLSR, NULL, 0);
|
||||
nor->write_reg(nor, SPINOR_OP_CYPRESS_CLPEF, NULL, 0);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -1856,7 +1880,7 @@ static int macronix_quad_enable(struct spi_nor *nor)
|
|||
static int spansion_quad_enable_volatile(struct spi_nor *nor, u32 addr_base,
|
||||
u8 dummy)
|
||||
{
|
||||
u32 addr = addr_base + SPINOR_REG_ADDR_CFR1V;
|
||||
u32 addr = addr_base + SPINOR_REG_CYPRESS_CFR1V;
|
||||
|
||||
u8 cr;
|
||||
int ret;
|
||||
|
@ -3293,11 +3317,11 @@ static int s25fs_s_setup(struct spi_nor *nor, const struct flash_info *info,
|
|||
* Read CR3V to check if uniform sector is selected. If not, assign an
|
||||
* erase hook that supports non-uniform erase.
|
||||
*/
|
||||
ret = spansion_read_any_reg(nor, SPINOR_REG_ADDR_CFR3V,
|
||||
ret = spansion_read_any_reg(nor, SPINOR_REG_CYPRESS_CFR3V,
|
||||
S25FS_S_RDAR_DUMMY, &cfr3v);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!(cfr3v & CFR3V_UNHYSA))
|
||||
if (!(cfr3v & SPINOR_REG_CYPRESS_CFR3_UNISECT))
|
||||
nor->erase = s25fs_s_erase_non_uniform;
|
||||
|
||||
return spi_nor_default_setup(nor, info, params);
|
||||
|
@ -3346,13 +3370,13 @@ static struct spi_nor_fixups s25fs_s_fixups = {
|
|||
.post_sfdp = s25fs_s_post_sfdp_fixup,
|
||||
};
|
||||
|
||||
static int s25_mdp_ready(struct spi_nor *nor)
|
||||
static int s25_s28_mdp_ready(struct spi_nor *nor)
|
||||
{
|
||||
u32 addr;
|
||||
int ret;
|
||||
|
||||
for (addr = 0; addr < nor->mtd.size; addr += SZ_128M) {
|
||||
ret = spansion_sr_ready(nor, addr, 0);
|
||||
ret = spansion_sr_ready(nor, addr, nor->rdsr_dummy);
|
||||
if (!ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -3374,15 +3398,15 @@ static int s25_quad_enable(struct spi_nor *nor)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int s25_erase_non_uniform(struct spi_nor *nor, loff_t addr)
|
||||
static int s25_s28_erase_non_uniform(struct spi_nor *nor, loff_t addr)
|
||||
{
|
||||
/* Support 32 x 4KB sectors at bottom */
|
||||
return spansion_erase_non_uniform(nor, addr, SPINOR_OP_BE_4K_4B, 0,
|
||||
SZ_128K);
|
||||
}
|
||||
|
||||
static int s25_setup(struct spi_nor *nor, const struct flash_info *info,
|
||||
const struct spi_nor_flash_parameter *params)
|
||||
static int s25_s28_setup(struct spi_nor *nor, const struct flash_info *info,
|
||||
const struct spi_nor_flash_parameter *params)
|
||||
{
|
||||
int ret;
|
||||
u8 cr;
|
||||
|
@ -3396,7 +3420,8 @@ static int s25_setup(struct spi_nor *nor, const struct flash_info *info,
|
|||
* uniform 128KB only due to complexity of non-uniform layout.
|
||||
*/
|
||||
if (nor->info->id[4] == S25FS256T_ID4) {
|
||||
ret = spansion_read_any_reg(nor, SPINOR_REG_ADDR_ARCFN, 8, &cr);
|
||||
ret = spansion_read_any_reg(nor, SPINOR_REG_CYPRESS_ARCFN, 8,
|
||||
&cr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -3410,31 +3435,31 @@ static int s25_setup(struct spi_nor *nor, const struct flash_info *info,
|
|||
* Read CFR3V to check if uniform sector is selected. If not, assign an
|
||||
* erase hook that supports non-uniform erase.
|
||||
*/
|
||||
ret = spansion_read_any_reg(nor, SPINOR_REG_ADDR_CFR3V, 0, &cr);
|
||||
ret = spansion_read_any_reg(nor, SPINOR_REG_CYPRESS_CFR3V, 0, &cr);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!(cr & CFR3V_UNHYSA))
|
||||
nor->erase = s25_erase_non_uniform;
|
||||
if (!(cr & SPINOR_REG_CYPRESS_CFR3_UNISECT))
|
||||
nor->erase = s25_s28_erase_non_uniform;
|
||||
|
||||
/*
|
||||
* For the multi-die package parts, the ready() hook is needed to check
|
||||
* all dies' status via read any register.
|
||||
*/
|
||||
if (nor->mtd.size > SZ_128M)
|
||||
nor->ready = s25_mdp_ready;
|
||||
nor->ready = s25_s28_mdp_ready;
|
||||
|
||||
return spi_nor_default_setup(nor, info, params);
|
||||
}
|
||||
|
||||
static void s25_default_init(struct spi_nor *nor)
|
||||
{
|
||||
nor->setup = s25_setup;
|
||||
nor->setup = s25_s28_setup;
|
||||
}
|
||||
|
||||
static int s25_post_bfpt_fixup(struct spi_nor *nor,
|
||||
const struct sfdp_parameter_header *header,
|
||||
const struct sfdp_bfpt *bfpt,
|
||||
struct spi_nor_flash_parameter *params)
|
||||
static int s25_s28_post_bfpt_fixup(struct spi_nor *nor,
|
||||
const struct sfdp_parameter_header *header,
|
||||
const struct sfdp_bfpt *bfpt,
|
||||
struct spi_nor_flash_parameter *params)
|
||||
{
|
||||
int ret;
|
||||
u32 addr;
|
||||
|
@ -3474,12 +3499,13 @@ static int s25_post_bfpt_fixup(struct spi_nor *nor,
|
|||
* dies are configured to 512B buffer.
|
||||
*/
|
||||
for (addr = 0; addr < params->size; addr += SZ_128M) {
|
||||
ret = spansion_read_any_reg(nor, addr + SPINOR_REG_ADDR_CFR3V,
|
||||
0, &cfr3v);
|
||||
ret = spansion_read_any_reg(nor,
|
||||
addr + SPINOR_REG_CYPRESS_CFR3V, 0,
|
||||
&cfr3v);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!(cfr3v & CFR3V_PGMBUF)) {
|
||||
if (!(cfr3v & SPINOR_REG_CYPRESS_CFR3_PGSZ)) {
|
||||
params->page_size = 256;
|
||||
return 0;
|
||||
}
|
||||
|
@ -3507,7 +3533,7 @@ static void s25_post_sfdp_fixup(struct spi_nor *nor,
|
|||
|
||||
static struct spi_nor_fixups s25_fixups = {
|
||||
.default_init = s25_default_init,
|
||||
.post_bfpt = s25_post_bfpt_fixup,
|
||||
.post_bfpt = s25_s28_post_bfpt_fixup,
|
||||
.post_sfdp = s25_post_sfdp_fixup,
|
||||
};
|
||||
|
||||
|
@ -3539,97 +3565,57 @@ static struct spi_nor_fixups s25fl256l_fixups = {
|
|||
*/
|
||||
static int spi_nor_cypress_octal_dtr_enable(struct spi_nor *nor)
|
||||
{
|
||||
struct spi_mem_op op;
|
||||
u32 addr;
|
||||
u8 buf;
|
||||
u8 addr_width = 3;
|
||||
int ret;
|
||||
|
||||
/* Use 24 dummy cycles for memory array reads. */
|
||||
ret = write_enable(nor);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
buf = SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24;
|
||||
op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
|
||||
SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR2V, 1),
|
||||
SPI_MEM_OP_NO_DUMMY,
|
||||
SPI_MEM_OP_DATA_OUT(1, &buf, 1));
|
||||
ret = spi_mem_exec_op(nor->spi, &op);
|
||||
if (ret) {
|
||||
dev_warn(nor->dev,
|
||||
"failed to set default memory latency value: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
ret = spi_nor_wait_till_ready(nor);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* Use 24 dummy cycles for memory array reads. */
|
||||
for (addr = 0; addr < nor->mtd.size; addr += SZ_128M) {
|
||||
ret = spansion_read_any_reg(nor,
|
||||
addr + SPINOR_REG_CYPRESS_CFR2V, 0,
|
||||
&buf);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
buf &= ~SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK;
|
||||
buf |= SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24;
|
||||
ret = spansion_write_any_reg(nor,
|
||||
addr + SPINOR_REG_CYPRESS_CFR2V,
|
||||
buf);
|
||||
if (ret) {
|
||||
dev_warn(nor->dev, "failed to set default memory latency value: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
nor->read_dummy = 24;
|
||||
|
||||
/* Set the octal and DTR enable bits. */
|
||||
ret = write_enable(nor);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set the octal and DTR enable bits. */
|
||||
buf = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_EN;
|
||||
op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
|
||||
SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR5V, 1),
|
||||
SPI_MEM_OP_NO_DUMMY,
|
||||
SPI_MEM_OP_DATA_OUT(1, &buf, 1));
|
||||
ret = spi_mem_exec_op(nor->spi, &op);
|
||||
if (ret) {
|
||||
dev_warn(nor->dev, "Failed to enable octal DTR mode\n");
|
||||
return ret;
|
||||
for (addr = 0; addr < nor->mtd.size; addr += SZ_128M) {
|
||||
ret = spansion_write_any_reg(nor,
|
||||
addr + SPINOR_REG_CYPRESS_CFR5V,
|
||||
buf);
|
||||
if (ret) {
|
||||
dev_warn(nor->dev, "Failed to enable octal DTR mode\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s28hx_t_erase_non_uniform(struct spi_nor *nor, loff_t addr)
|
||||
{
|
||||
/* Factory default configuration: 32 x 4 KiB sectors at bottom. */
|
||||
return spansion_erase_non_uniform(nor, addr, SPINOR_OP_S28_SE_4K,
|
||||
0, SZ_128K);
|
||||
}
|
||||
|
||||
static int s28hx_t_setup(struct spi_nor *nor, const struct flash_info *info,
|
||||
const struct spi_nor_flash_parameter *params)
|
||||
{
|
||||
struct spi_mem_op op;
|
||||
u8 buf;
|
||||
u8 addr_width = 3;
|
||||
int ret;
|
||||
|
||||
ret = spi_nor_wait_till_ready(nor);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Check CFR3V to check if non-uniform sector mode is selected. If it
|
||||
* is, set the erase hook to the non-uniform erase procedure.
|
||||
*/
|
||||
op = (struct spi_mem_op)
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 1),
|
||||
SPI_MEM_OP_ADDR(addr_width,
|
||||
SPINOR_REG_CYPRESS_CFR3V, 1),
|
||||
SPI_MEM_OP_NO_DUMMY,
|
||||
SPI_MEM_OP_DATA_IN(1, &buf, 1));
|
||||
|
||||
ret = spi_mem_exec_op(nor->spi, &op);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!(buf & SPINOR_REG_CYPRESS_CFR3_UNISECT))
|
||||
nor->erase = s28hx_t_erase_non_uniform;
|
||||
|
||||
return spi_nor_default_setup(nor, info, params);
|
||||
}
|
||||
|
||||
static void s28hx_t_default_init(struct spi_nor *nor)
|
||||
{
|
||||
nor->octal_dtr_enable = spi_nor_cypress_octal_dtr_enable;
|
||||
nor->setup = s28hx_t_setup;
|
||||
nor->setup = s25_s28_setup;
|
||||
}
|
||||
|
||||
static void s28hx_t_post_sfdp_fixup(struct spi_nor *nor,
|
||||
|
@ -3663,50 +3649,10 @@ static void s28hx_t_post_sfdp_fixup(struct spi_nor *nor,
|
|||
params->rdsr_addr_nbytes = 4;
|
||||
}
|
||||
|
||||
static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor,
|
||||
const struct sfdp_parameter_header *bfpt_header,
|
||||
const struct sfdp_bfpt *bfpt,
|
||||
struct spi_nor_flash_parameter *params)
|
||||
{
|
||||
struct spi_mem_op op;
|
||||
u8 buf;
|
||||
u8 addr_width = 3;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* The BFPT table advertises a 512B page size but the page size is
|
||||
* actually configurable (with the default being 256B). Read from
|
||||
* CFR3V[4] and set the correct size.
|
||||
*/
|
||||
op = (struct spi_mem_op)
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 1),
|
||||
SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR3V, 1),
|
||||
SPI_MEM_OP_NO_DUMMY,
|
||||
SPI_MEM_OP_DATA_IN(1, &buf, 1));
|
||||
ret = spi_mem_exec_op(nor->spi, &op);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (buf & SPINOR_REG_CYPRESS_CFR3_PGSZ)
|
||||
params->page_size = 512;
|
||||
else
|
||||
params->page_size = 256;
|
||||
|
||||
/*
|
||||
* The BFPT advertises that it supports 4k erases, and the datasheet
|
||||
* says the same. But 4k erases did not work when testing. So, use 256k
|
||||
* erases for now.
|
||||
*/
|
||||
nor->erase_opcode = SPINOR_OP_SE_4B;
|
||||
nor->mtd.erasesize = 0x40000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_nor_fixups s28hx_t_fixups = {
|
||||
.default_init = s28hx_t_default_init,
|
||||
.post_sfdp = s28hx_t_post_sfdp_fixup,
|
||||
.post_bfpt = s28hx_t_post_bfpt_fixup,
|
||||
.post_bfpt = s25_s28_post_bfpt_fixup,
|
||||
};
|
||||
#endif /* CONFIG_SPI_FLASH_S28HX_T */
|
||||
|
||||
|
|
|
@ -239,6 +239,8 @@ const struct flash_info spi_nor_ids[] = {
|
|||
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
{ INFO("is25wx256", 0x9d5b19, 0, 128 * 1024, 256,
|
||||
SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) },
|
||||
{ INFO("is25lx512", 0x9d5a1a, 0, 64 * 1024, 1024,
|
||||
SECT_4K | USE_FSR | SPI_NOR_4B_OPCODES | SPI_NOR_HAS_TB) },
|
||||
#endif
|
||||
#ifdef CONFIG_SPI_FLASH_MACRONIX /* MACRONIX */
|
||||
/* Macronix */
|
||||
|
@ -381,6 +383,7 @@ const struct flash_info spi_nor_ids[] = {
|
|||
{ INFO("s28hl01gt", 0x345a1b, 0, 256 * 1024, 512, SPI_NOR_OCTAL_DTR_READ) },
|
||||
{ INFO("s28hs512t", 0x345b1a, 0, 256 * 1024, 256, SPI_NOR_OCTAL_DTR_READ) },
|
||||
{ INFO("s28hs01gt", 0x345b1b, 0, 256 * 1024, 512, SPI_NOR_OCTAL_DTR_READ) },
|
||||
{ INFO("s28hs02gt", 0x345b1c, 0, 256 * 1024, 1024, SPI_NOR_OCTAL_DTR_READ) },
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_SPI_FLASH_SST /* SST */
|
||||
|
@ -554,6 +557,10 @@ const struct flash_info spi_nor_ids[] = {
|
|||
{ 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("XM25QU128C", 0x204118, 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 */
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
#include "cadence_qspi.h"
|
||||
#include <dt-bindings/power/xlnx-versal-power.h>
|
||||
|
||||
#define CMD_4BYTE_READ 0x13
|
||||
#define CMD_4BYTE_FAST_READ 0x0C
|
||||
|
||||
int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv,
|
||||
const struct spi_mem_op *op)
|
||||
{
|
||||
|
|
|
@ -33,6 +33,10 @@
|
|||
#define CQSPI_DUMMY_BYTES_MAX 4
|
||||
#define CQSPI_DUMMY_CLKS_MAX 31
|
||||
|
||||
#define CMD_4BYTE_FAST_READ 0x0C
|
||||
#define CMD_4BYTE_OCTAL_READ 0x7c
|
||||
#define CMD_4BYTE_READ 0x13
|
||||
|
||||
/****************************************************************************
|
||||
* Controller's configuration and status register (offset from QSPI_BASE)
|
||||
****************************************************************************/
|
||||
|
|
|
@ -469,6 +469,9 @@ int cadence_qspi_apb_command_read(struct cadence_spi_priv *priv,
|
|||
else
|
||||
opcode = op->cmd.opcode;
|
||||
|
||||
if (opcode == CMD_4BYTE_OCTAL_READ && !priv->dtr)
|
||||
opcode = CMD_4BYTE_FAST_READ;
|
||||
|
||||
reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
|
||||
|
||||
/* Set up dummy cycles. */
|
||||
|
|
|
@ -111,6 +111,9 @@
|
|||
#define SR_TX_ERR BIT(5)
|
||||
#define SR_DCOL BIT(6)
|
||||
|
||||
/* Bit field in RISR */
|
||||
#define RISR_INT_RXOI BIT(3)
|
||||
|
||||
#define RX_TIMEOUT 1000 /* timeout in ms */
|
||||
|
||||
struct dw_spi_plat {
|
||||
|
@ -588,7 +591,7 @@ static int dw_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
|
|||
struct dw_spi_priv *priv = dev_get_priv(bus);
|
||||
u8 op_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes;
|
||||
u8 op_buf[op_len];
|
||||
u32 cr0;
|
||||
u32 cr0, sts;
|
||||
|
||||
if (read)
|
||||
priv->tmode = CTRLR0_TMOD_EPROMREAD;
|
||||
|
@ -632,12 +635,21 @@ static int dw_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
|
|||
* them to fail because we are not reading/writing the fifo fast enough.
|
||||
*/
|
||||
if (read) {
|
||||
priv->rx = op->data.buf.in;
|
||||
void *prev_rx = priv->rx = op->data.buf.in;
|
||||
priv->rx_end = priv->rx + op->data.nbytes;
|
||||
|
||||
dw_write(priv, DW_SPI_SER, 1 << spi_chip_select(slave->dev));
|
||||
while (priv->rx != priv->rx_end)
|
||||
while (priv->rx != priv->rx_end) {
|
||||
dw_reader(priv);
|
||||
if (prev_rx == priv->rx) {
|
||||
sts = dw_read(priv, DW_SPI_RISR);
|
||||
if (sts & RISR_INT_RXOI) {
|
||||
dev_err(bus, "FIFO overflow on Rx\n");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
prev_rx = priv->rx;
|
||||
}
|
||||
} else {
|
||||
u32 val;
|
||||
|
||||
|
|
|
@ -136,14 +136,6 @@
|
|||
#define SPINOR_OP_BRRD 0x16 /* Bank register read */
|
||||
#define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */
|
||||
#define SPINOR_OP_EX4B_CYPRESS 0xB8 /* Exit 4-byte mode */
|
||||
#define SPINOR_OP_RDAR 0x65 /* Read any register */
|
||||
#define SPINOR_OP_WRAR 0x71 /* Write any register */
|
||||
#define SPINOR_REG_ADDR_STR1V 0x00800000
|
||||
#define SPINOR_REG_ADDR_CFR1V 0x00800002
|
||||
#define SPINOR_REG_ADDR_CFR3V 0x00800004
|
||||
#define SPINOR_REG_ADDR_ARCFN 0x00000006
|
||||
#define CFR3V_UNHYSA BIT(3) /* Uniform sectors or not */
|
||||
#define CFR3V_PGMBUF BIT(4) /* Program buffer size */
|
||||
|
||||
/* Used for Micron flashes only. */
|
||||
#define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */
|
||||
|
@ -188,8 +180,12 @@
|
|||
/* For Cypress flash. */
|
||||
#define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */
|
||||
#define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */
|
||||
#define SPINOR_OP_S28_SE_4K 0x21
|
||||
#define SPINOR_OP_CYPRESS_CLPEF 0x82 /* Clear P/E err flag */
|
||||
#define SPINOR_REG_CYPRESS_ARCFN 0x00000006
|
||||
#define SPINOR_REG_CYPRESS_STR1V 0x00800000
|
||||
#define SPINOR_REG_CYPRESS_CFR1V 0x00800002
|
||||
#define SPINOR_REG_CYPRESS_CFR2V 0x00800003
|
||||
#define SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK GENMASK(3, 0)
|
||||
#define SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24 0xb
|
||||
#define SPINOR_REG_CYPRESS_CFR3V 0x00800004
|
||||
#define SPINOR_REG_CYPRESS_CFR3_PGSZ BIT(4) /* Page size. */
|
||||
|
|
Loading…
Reference in a new issue