/* Parameters to configure a READ or WRITE FSM sequence */ struct seq_rw_config {
uint32_t flags; /* flags to support config */
uint8_t cmd; /* FLASH command */ int write; /* Write Sequence */
uint8_t addr_pads; /* No. of addr pads (MODE & DUMMY) */
uint8_t data_pads; /* No. of data pads */
uint8_t mode_data; /* MODE data */
uint8_t mode_cycles; /* No. of MODE cycles */
uint8_t dummy_cycles; /* No. of DUMMY cycles */
};
/* SPI Flash Device Table */ struct flash_info { char *name; /* * JEDEC id zero means "no ID" (most older chips); otherwise it has * a high byte of zero plus three data bytes: the manufacturer id, * then a two byte device id.
*/
u32 jedec_id;
u16 ext_id; /* * The size listed here is what works with SPINOR_OP_SE, which isn't * necessarily called a "sector" by the vendor.
*/ unsigned sector_size;
u16 n_sectors;
u32 flags; /* * Note, where FAST_READ is supported, freq_max specifies the * FAST_READ frequency, not the READ frequency.
*/
u32 max_freq; int (*config)(struct stfsm *);
};
/* * Spansion S25FLxxxS * - 256KiB and 64KiB sector variants (identified by ext. JEDEC) * - RESET# signal supported by die but not bristled out on all * package types. The package type is a function of board design, * so this information is captured in the board's flags. * - Supports 'DYB' sector protection. Depending on variant, sectors * may default to locked state on power-on.
*/ #define S25FLXXXS_FLAG (S25FLXXXP_FLAG | \
FLASH_FLAG_RESET | \
FLASH_FLAG_DYB_LOCKING)
{ "s25fl128s0", 0x012018, 0x0300, 256 * 1024, 64, S25FLXXXS_FLAG, 80,
stfsm_s25fl_config },
{ "s25fl128s1", 0x012018, 0x0301, 64 * 1024, 256, S25FLXXXS_FLAG, 80,
stfsm_s25fl_config },
{ "s25fl256s0", 0x010219, 0x4d00, 256 * 1024, 128,
S25FLXXXS_FLAG | FLASH_FLAG_32BIT_ADDR, 80, stfsm_s25fl_config },
{ "s25fl256s1", 0x010219, 0x4d01, 64 * 1024, 512,
S25FLXXXS_FLAG | FLASH_FLAG_32BIT_ADDR, 80, stfsm_s25fl_config },
/* N25Q 3-byte Address READ configurations * - 'FAST' variants configured for 8 dummy cycles. * * Note, the number of dummy cycles used for 'FAST' READ operations is * configurable and would normally be tuned according to the READ command and * operating frequency. However, this applies universally to all 'FAST' READ * commands, including those used by the SPIBoot controller, and remains in * force until the device is power-cycled. Since the SPIBoot controller is * hard-wired to use 8 dummy cycles, we must configure the device to also use 8 * cycles.
*/ staticstruct seq_rw_config n25q_read3_configs[] = {
{FLASH_FLAG_READ_1_4_4, SPINOR_OP_READ_1_4_4, 0, 4, 4, 0x00, 0, 8},
{FLASH_FLAG_READ_1_1_4, SPINOR_OP_READ_1_1_4, 0, 1, 4, 0x00, 0, 8},
{FLASH_FLAG_READ_1_2_2, SPINOR_OP_READ_1_2_2, 0, 2, 2, 0x00, 0, 8},
{FLASH_FLAG_READ_1_1_2, SPINOR_OP_READ_1_1_2, 0, 1, 2, 0x00, 0, 8},
{FLASH_FLAG_READ_FAST, SPINOR_OP_READ_FAST, 0, 1, 1, 0x00, 0, 8},
{FLASH_FLAG_READ_WRITE, SPINOR_OP_READ, 0, 1, 1, 0x00, 0, 0},
{0x00, 0, 0, 0, 0, 0x00, 0, 0},
};
/* * Clear the data FIFO * * Typically, this is only required during driver initialisation, where no * assumptions can be made regarding the state of the FIFO. * * The process of clearing the FIFO is complicated by fact that while it is * possible for the FIFO to contain an arbitrary number of bytes [1], the * SPI_FAST_SEQ_STA register only reports the number of complete 32-bit words * present. Furthermore, data can only be drained from the FIFO by reading * complete 32-bit words. * * With this in mind, a two stage process is used to the clear the FIFO: * * 1. Read any complete 32-bit words from the FIFO, as reported by the * SPI_FAST_SEQ_STA register. * * 2. Mop up any remaining bytes. At this point, it is not known if there * are 0, 1, 2, or 3 bytes in the FIFO. To handle all cases, a dummy FSM * sequence is used to load one byte at a time, until a complete 32-bit * word is formed; at most, 4 bytes will need to be loaded. * * [1] It is theoretically possible for the FIFO to contain an arbitrary number * of bits. However, since there are no known use-cases that leave * incomplete bytes in the FIFO, only words and bytes are considered here.
*/ staticvoid stfsm_clear_fifo(struct stfsm *fsm)
{ conststruct stfsm_seq *seq = &stfsm_seq_load_fifo_byte;
uint32_t words, i;
/* 1. Clear any 32-bit words */
words = stfsm_fifo_available(fsm); if (words) { for (i = 0; i < words; i++)
readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
dev_dbg(fsm->dev, "cleared %d words from FIFO\n", words);
}
/* * 2. Clear any remaining bytes * - Load the FIFO, one byte at a time, until a complete 32-bit word * is available.
*/ for (i = 0, words = 0; i < 4 && !words; i++) {
stfsm_load_seq(fsm, seq);
stfsm_wait_seq(fsm);
words = stfsm_fifo_available(fsm);
}
/* - A single word must be available now */ if (words != 1) {
dev_err(fsm->dev, "failed to clear bytes from the data FIFO\n"); return;
}
/* - Read the 32-bit word */
readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
dev_dbg(fsm->dev, "cleared %d byte(s) from the data FIFO\n", 4 - i);
}
/* * Repeat until busy bit is deasserted, or timeout, or error (S25FLxxxS)
*/
deadline = jiffies + FLASH_MAX_BUSY_WAIT; while (!timeout) { if (time_after_eq(jiffies, deadline))
timeout = 1;
/* * SoC reset on 'boot-from-spi' systems * * Certain modes of operation cause the Flash device to enter a particular state * for a period of time (e.g. 'Erase Sector', 'Quad Enable', and 'Enter 32-bit * Addr' commands). On boot-from-spi systems, it is important to consider what * happens if a warm reset occurs during this period. The SPIBoot controller * assumes that Flash device is in its default reset state, 24-bit address mode, * and ready to accept commands. This can be achieved using some form of * on-board logic/controller to force a device POR in response to a SoC-level * reset or by making use of the device reset signal if available (limited * number of devices only). * * Failure to take such precautions can cause problems following a warm reset. * For some operations (e.g. ERASE), there is little that can be done. For * other modes of operation (e.g. 32-bit addressing), options are often * available that can help minimise the window in which a reset could cause a * problem. *
*/ staticbool stfsm_can_handle_soc_reset(struct stfsm *fsm)
{ /* Reset signal is available on the board and supported by the device */ if (fsm->reset_signal && fsm->info->flags & FLASH_FLAG_RESET) returntrue;
/* Board-level logic forces a power-on-reset */ if (fsm->reset_por) returntrue;
/* Reset is not properly handled and may result in failure to reboot */ returnfalse;
}
/* Configure 'addr_cfg' according to addressing mode */ staticvoid stfsm_prepare_erasesec_seq(struct stfsm *fsm, struct stfsm_seq *seq)
{ int addr1_cycles = fsm->info->flags & FLASH_FLAG_32BIT_ADDR ? 16 : 8;
/* Search for preferred configuration based on available flags */ staticstruct seq_rw_config *
stfsm_search_seq_rw_configs(struct stfsm *fsm, struct seq_rw_config cfgs[])
{ struct seq_rw_config *config; int flags = fsm->info->flags;
for (config = cfgs; config->cmd != 0; config++) if ((config->flags & flags) == config->flags) return config;
return NULL;
}
/* Prepare a READ/WRITE sequence according to configuration parameters */ staticvoid stfsm_prepare_rw_seq(struct stfsm *fsm, struct stfsm_seq *seq, struct seq_rw_config *cfg)
{ int addr1_cycles, addr2_cycles; int i = 0;
/* * Use default READ/WRITE sequences
*/
ret = stfsm_prepare_rwe_seqs_default(fsm); if (ret) return ret;
/* * Configure 32-bit Address Support
*/ if (flags & FLASH_FLAG_32BIT_ADDR) { /* Configure 'enter_32bitaddr' FSM sequence */
stfsm_mx25_en_32bit_addr_seq(&fsm->stfsm_seq_en_32bit_addr);
soc_reset = stfsm_can_handle_soc_reset(fsm); if (soc_reset || !fsm->booted_from_spi) /* If we can handle SoC resets, we enable 32-bit address
* mode pervasively */
stfsm_enter_32bit_addr(fsm, 1);
if (flags & FLASH_FLAG_32BIT_ADDR) { /* * Prepare Read/Write/Erase sequences according to S25FLxxx * 32-bit address command set
*/
ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_read,
stfsm_s25fl_read4_configs); if (ret) return ret;
ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_write,
stfsm_s25fl_write4_configs); if (ret) return ret;
/* * S25FLxxx devices support Program and Error error flags. * Configure driver to check flags and clear if necessary.
*/
fsm->configuration |= CFG_S25FL_CHECK_ERROR_FLAGS;
return 0;
}
staticint stfsm_w25q_config(struct stfsm *fsm)
{
uint32_t data_pads;
uint8_t sr1, sr2;
uint16_t sr_wr; int update_sr = 0; int ret;
ret = stfsm_prepare_rwe_seqs_default(fsm); if (ret) return ret;
/* Check status of 'QE' bit, update if required. */
stfsm_read_status(fsm, SPINOR_OP_RDCR, &sr2, 1);
data_pads = ((fsm->stfsm_seq_read.seq_cfg >> 16) & 0x3) + 1; if (data_pads == 4) { if (!(sr2 & W25Q_STATUS_QE)) { /* Set 'QE' */
sr2 |= W25Q_STATUS_QE;
update_sr = 1;
}
} else { if (sr2 & W25Q_STATUS_QE) { /* Clear 'QE' */
sr2 &= ~W25Q_STATUS_QE;
update_sr = 1;
}
} if (update_sr) { /* Write status register */
stfsm_read_status(fsm, SPINOR_OP_RDSR, &sr1, 1);
sr_wr = ((uint16_t)sr2 << 8) | sr1;
stfsm_write_status(fsm, SPINOR_OP_WRSR, sr_wr, 2, 1);
}
/* Need to set FIFO to write mode, before writing data to FIFO (see * GNBvb79594)
*/
writel(0x00040000, fsm->base + SPI_FAST_SEQ_CFG);
/* * Before writing data to the FIFO, apply a small delay to allow a * potential change of FIFO direction to complete.
*/ if (fsm->fifo_dir_delay == 0)
readl(fsm->base + SPI_FAST_SEQ_CFG); else
udelay(fsm->fifo_dir_delay);
/* Write data to FIFO, before starting sequence (see GNBvd79593) */ if (size_lb) {
stfsm_write_fifo(fsm, (uint32_t *)p, size_lb);
p += size_lb;
}
/* Handle non-aligned size */ if (size_mop) {
memset(t, 0xff, write_mask + 1); /* fill with 0xff's */ for (i = 0; i < size_mop; i++)
t[i] = *p++;
stfsm_write_fifo(fsm, tmp, write_mask + 1);
}
/* Start sequence */
stfsm_load_seq(fsm, seq);
/* Wait for sequence to finish */
stfsm_wait_seq(fsm);
/* Wait for completion */
ret = stfsm_wait_busy(fsm); if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
stfsm_s25fl_clear_status_reg(fsm);
/* Exit 32-bit address mode, if required */ if (fsm->configuration & CFG_WRITE_TOGGLE_32BIT_ADDR)
stfsm_enter_32bit_addr(fsm, 0);
return 0;
}
/* * Read an address range from the flash chip. The address range * may be any size provided it is within the physical boundaries.
*/ staticint stfsm_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{ struct stfsm *fsm = dev_get_drvdata(mtd->dev.parent);
uint32_t bytes;
dev_dbg(fsm->dev, "%s from 0x%08x, len %zd\n",
__func__, (u32)from, len);
mutex_lock(&fsm->lock);
while (len > 0) {
bytes = min_t(size_t, len, FLASH_PAGESIZE);
/* * Write an address range to the flash chip. Data must be written in * FLASH_PAGESIZE chunks. The address range may be any size provided * it is within the physical boundaries.
*/ staticint stfsm_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf)
{ struct stfsm *fsm = dev_get_drvdata(mtd->dev.parent);
u32 page_offs;
u32 bytes;
uint8_t *b = (uint8_t *)buf; int ret = 0;
dev_dbg(fsm->dev, "%s to 0x%08x, len %zd\n", __func__, (u32)to, len);
/* Offset within page */
page_offs = to % FLASH_PAGESIZE;
mutex_lock(&fsm->lock);
while (len) { /* Write up to page boundary */
bytes = min_t(size_t, FLASH_PAGESIZE - page_offs, len);
ret = stfsm_write(fsm, b, bytes, to); if (ret) goto out1;
b += bytes;
len -= bytes;
to += bytes;
/* We are now page-aligned */
page_offs = 0;
*retlen += bytes;
}
out1:
mutex_unlock(&fsm->lock);
return ret;
}
/* * Erase an address range on the flash chip. The address range may extend * one or more erase sectors. Return an error is there is a problem erasing.
*/ staticint stfsm_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
{ struct stfsm *fsm = dev_get_drvdata(mtd->dev.parent);
u32 addr, len; int ret;
dev_dbg(fsm->dev, "%s at 0x%llx, len %lld\n", __func__,
(longlong)instr->addr, (longlong)instr->len);
addr = instr->addr;
len = instr->len;
mutex_lock(&fsm->lock);
/* Whole-chip erase? */ if (len == mtd->size) {
ret = stfsm_erase_chip(fsm); if (ret) goto out1;
} else { while (len) {
ret = stfsm_erase_sector(fsm, addr); if (ret) goto out1;
addr += mtd->erasesize;
len -= mtd->erasesize;
}
}
jedec = id[0] << 16 | id[1] << 8 | id[2]; /* * JEDEC also defines an optional "extended device information" * string for after vendor-specific data, after the three bytes * we use here. Supporting some chips might require using it.
*/
ext_jedec = id[3] << 8 | id[4];
/* * Calculate clk_div - values between 2 and 128 * Multiple of 2, rounded up
*/
clk_div = 2 * DIV_ROUND_UP(emi_freq, 2 * spi_freq); if (clk_div < 2)
clk_div = 2; elseif (clk_div > 128)
clk_div = 128;
/* * Determine a suitable delay for the IP to complete a change of * direction of the FIFO. The required delay is related to the clock * divider used. The following heuristics are based on empirical tests, * using a 100MHz EMI clock.
*/ if (clk_div <= 4)
fsm->fifo_dir_delay = 0; elseif (clk_div <= 10)
fsm->fifo_dir_delay = 1; else
fsm->fifo_dir_delay = DIV_ROUND_UP(clk_div, 10);
/* * Set the FSM 'WAIT' delay to the minimum workable value. Note, for * our purposes, the WAIT instruction is used purely to achieve * "sequence validity" rather than actually implement a delay.
*/
writel(0x00000001, fsm->base + SPI_PROGRAM_ERASE_TIME);
/* Clear FIFO, just in case */
stfsm_clear_fifo(fsm);
return 0;
}
staticvoid stfsm_fetch_platform_configs(struct platform_device *pdev)
{ struct stfsm *fsm = platform_get_drvdata(pdev); struct device_node *np = pdev->dev.of_node; struct regmap *regmap;
uint32_t boot_device_reg;
uint32_t boot_device_spi;
uint32_t boot_device; /* Value we read from *boot_device_reg */ int ret;
/* Booting from SPI NOR Flash is the default */
fsm->booted_from_spi = true;
regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); if (IS_ERR(regmap)) goto boot_device_fail;
/* Where in the syscon the boot device information lives */
ret = of_property_read_u32(np, "st,boot-device-reg", &boot_device_reg); if (ret) goto boot_device_fail;
/* Boot device value when booted from SPI NOR */
ret = of_property_read_u32(np, "st,boot-device-spi", &boot_device_spi); if (ret) goto boot_device_fail;
ret = regmap_read(regmap, boot_device_reg, &boot_device); if (ret) goto boot_device_fail;
if (boot_device != boot_device_spi)
fsm->booted_from_spi = false;
return;
boot_device_fail:
dev_warn(&pdev->dev, "failed to fetch boot device, assuming boot from SPI\n");
}
ret = stfsm_init(fsm); if (ret) {
dev_err(&pdev->dev, "Failed to initialise FSM Controller\n"); return ret;
}
stfsm_fetch_platform_configs(pdev);
/* Detect SPI FLASH device */
info = stfsm_jedec_probe(fsm); if (!info) return -ENODEV;
fsm->info = info;
/* Use device size to determine address width */ if (info->sector_size * info->n_sectors > 0x1000000)
info->flags |= FLASH_FLAG_32BIT_ADDR;
/* * Configure READ/WRITE/ERASE sequences according to platform and * device flags.
*/ if (info->config)
ret = info->config(fsm); else
ret = stfsm_prepare_rwe_seqs_default(fsm); if (ret) return ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.