static int nxp_spifi_setup_memory_cmd(struct nxp_spifi *spifi) { switch (spifi->nor.flash_read) { case SPI_NOR_NORMAL: case SPI_NOR_FAST: spifi->mcmd = SPIFI_CMD_FIELDFORM_ALL_SERIAL; break; case SPI_NOR_DUAL: case SPI_NOR_QUAD: spifi->mcmd = SPIFI_CMD_FIELDFORM_QUAD_DUAL_DATA; break; default: dev_err(spifi->dev, "unsupported SPI read mode\n"); return -EINVAL; } /* Memory mode supports address length between 1 and 4 */ if (spifi->nor.addr_width < 1 || spifi->nor.addr_width > 4) return -EINVAL; spifi->mcmd |= SPIFI_CMD_OPCODE(spifi->nor.read_opcode) | SPIFI_CMD_INTLEN(spifi->nor.read_dummy / 8) | SPIFI_CMD_FRAMEFORM(spifi->nor.addr_width + 1); return 0; }
static void nxp_spifi_write(struct spi_nor *nor, loff_t to, size_t len, size_t *retlen, const u_char *buf) { struct nxp_spifi *spifi = nor->priv; u32 cmd; int ret; ret = nxp_spifi_set_memory_mode_off(spifi); if (ret) return; writel(to, spifi->io_base + SPIFI_ADDR); *retlen += len; cmd = SPIFI_CMD_DOUT | SPIFI_CMD_DATALEN(len) | SPIFI_CMD_FIELDFORM_ALL_SERIAL | SPIFI_CMD_OPCODE(nor->program_opcode) | SPIFI_CMD_FRAMEFORM(spifi->nor.addr_width + 1); writel(cmd, spifi->io_base + SPIFI_CMD); while (len--) writeb(*buf++, spifi->io_base + SPIFI_DATA); nxp_spifi_wait_for_cmd(spifi); }
void SPIFI_SetCommand(SPIFI_Type *base, spifi_command_t *cmd) { /* Wait for the CMD and MCINT flag all be 0 */ while (SPIFI_GetStatusFlag(base) & (SPIFI_STAT_MCINIT_MASK | SPIFI_STAT_CMD_MASK)) { } base->CMD = SPIFI_CMD_DATALEN(cmd->dataLen) | SPIFI_CMD_POLL(cmd->isPollMode) | SPIFI_CMD_DOUT(cmd->direction) | SPIFI_CMD_INTLEN(cmd->intermediateBytes) | SPIFI_CMD_FIELDFORM(cmd->format) | SPIFI_CMD_FRAMEFORM(cmd->type) | SPIFI_CMD_OPCODE(cmd->opcode); /* Wait for the command written */ while ((base->STAT & SPIFI_STAT_CMD_MASK) == 0U) { } }
static int nxp_spifi_erase(struct spi_nor *nor, loff_t offs) { struct nxp_spifi *spifi = nor->priv; u32 cmd; int ret; ret = nxp_spifi_set_memory_mode_off(spifi); if (ret) return ret; writel(offs, spifi->io_base + SPIFI_ADDR); cmd = SPIFI_CMD_FIELDFORM_ALL_SERIAL | SPIFI_CMD_OPCODE(nor->erase_opcode) | SPIFI_CMD_FRAMEFORM(spifi->nor.addr_width + 1); writel(cmd, spifi->io_base + SPIFI_CMD); return nxp_spifi_wait_for_cmd(spifi); }