Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

imxrt-flash: fast read fix for ISSI NOR flash #335

Merged
merged 1 commit into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions devices/flash-imxrt/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
FLEXSPI_OBJS := fspi/fspi.o

ifneq (, $(findstring imxrt117x, $(TARGET_SUBFAMILY)))
FLEXSPI_OBJS += flashdrv.o nor/nor.o nor/nor_mx.o
FLEXSPI_OBJS += flashdrv.o nor/nor.o nor/nor_mx.o nor/nor_issi.o
else ifneq (, $(findstring imxrt106x, $(TARGET_SUBFAMILY)))
FLEXSPI_OBJS += flashdrv.o nor/nor.o nor/nor_mx.o
FLEXSPI_OBJS += flashdrv.o nor/nor.o nor/nor_mx.o nor/nor_issi.o
else ifneq (, $(findstring imxrt105x, $(TARGET_SUBFAMILY)))
FLEXSPI_OBJS += flashdrv.o nor/nor.o nor/nor_mx.o hyperbus/hyper.o
FLEXSPI_OBJS += flashdrv.o nor/nor.o nor/nor_mx.o nor/nor_issi.o hyperbus/hyper.o
endif

OBJS += $(addprefix $(PREFIX_O)devices/flash-imxrt/, $(FLEXSPI_OBJS))
2 changes: 2 additions & 0 deletions devices/flash-imxrt/flashdrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,8 @@ static int flashdrv_init(unsigned int minor)
flashSz[port] = dev->nor->totalSz;
flexspi_setFlashSize(&dev->fspi, flashSz, FLEXSPI_PORTS);

flexspi_postinit(&dev->fspi);

lib_printf("\ndev/flash/nor: Configured %s %s %dMB nor flash(%d.%d)",
vendor, dev->nor->name, dev->nor->totalSz >> 20, DEV_STORAGE, minor);

Expand Down
4 changes: 4 additions & 0 deletions devices/flash-imxrt/fspi.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ struct xferOp {
extern int flexspi_init(flexspi_t *fspi, int instance, u8 slPortMask);


/* Post-initialize single FlexSPI module */
extern int flexspi_postinit(flexspi_t *fspi);


/* Safely deinit leaving XIP working */
extern int flexspi_deinit(flexspi_t *fspi);

Expand Down
20 changes: 15 additions & 5 deletions devices/flash-imxrt/fspi/fspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ __attribute__((section(".noxip"))) int flexspi_init(flexspi_t *fspi, int instanc
hal_invalDCacheAll();
hal_cleanDCache();

flexspi_clockConfig(fspi);
/* Configure clock for normal read */
flexspi_clockConfig(fspi, 0);

/* Release FlexSPI from reset and power SRAM */
flexspi_disable(fspi, 0);
Expand Down Expand Up @@ -212,10 +213,10 @@ __attribute__((section(".noxip"))) int flexspi_init(flexspi_t *fspi, int instanc
/* Enable FlexSPI before updating LUT */
flexspi_disable(fspi, 0);

/* Default fast (up to 133MHz) read (single pad) used by AHB and XIP */
lut[0] = LUT_SEQ(lutCmd_SDR, lutPad1, 0x0b, lutCmdRADDR_SDR, lutPad1, 0x18);
lut[1] = LUT_SEQ(lutCmdDUMMY_SDR, lutPad1, 0x08, lutCmdREAD_SDR, lutPad1, 0x04);
lut[2] = LUT_SEQ(lutCmdSTOP, lutPad1, 0, 0, 0, 0);
/* Default normal (up to 80 MHz) read (single pad) used by AHB and XIP */
lut[0] = LUT_SEQ(lutCmd_SDR, lutPad1, 0x03, lutCmdRADDR_SDR, lutPad1, 0x18);
lut[1] = LUT_SEQ(lutCmdREAD_SDR, lutPad1, 0x04, lutCmdSTOP, lutPad1, 0);
lut[2] = 0;
lut[3] = 0;

/* Configure initial LUT sequences as needed (for AHB read and IP) */
Expand All @@ -233,6 +234,15 @@ __attribute__((section(".noxip"))) int flexspi_init(flexspi_t *fspi, int instanc
}


__attribute__((section(".noxip"))) int flexspi_postinit(flexspi_t *fspi)
{
/* Reconfigure clock for fast read */
flexspi_clockConfig(fspi, 1);

return EOK;
}


void flexspi_setFlashSize(flexspi_t *fspi, const size_t *flashSizes, size_t count)
{
unsigned int i;
Expand Down
8 changes: 4 additions & 4 deletions devices/flash-imxrt/fspi/fspi_rt105x.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ static inline void *flexspi_getBase(int instance)
}


__attribute__((section(".noxip"))) static void flexspi_clockConfig(flexspi_t *fspi)
__attribute__((section(".noxip"))) static void flexspi_clockConfig(flexspi_t *fspi, u8 fast)
{
_imxrt_ccmControlGate(pctl_clk_flexspi, clk_state_off);
_imxrt_ccmSetDiv(clk_div_flexspi, 1); /* div2 -> 130 MHz */
_imxrt_ccmSetMux(clk_mux_flexspi, 3); /* PLL3 PFD0 */
_imxrt_ccmInitUsb1Pfd(clk_pfd0, 33); /* PLL3_PDF0=261.818MHz */
_imxrt_ccmSetDiv(clk_div_flexspi, fast ? 1 : 3); /* Fast: 261 / (1 + 1) => 130 MHz, Normal: 261 / (3 + 1) => 65 MHz */
_imxrt_ccmSetMux(clk_mux_flexspi, 3); /* PLL3 PFD0 */
_imxrt_ccmInitUsb1Pfd(clk_pfd0, 33); /* PLL3_PDF0=261.818MHz */
_imxrt_ccmControlGate(pctl_clk_flexspi, clk_state_run_wait);
}

Expand Down
14 changes: 7 additions & 7 deletions devices/flash-imxrt/fspi/fspi_rt106x.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,20 @@ static void *flexspi_getBase(int instance)
}


__attribute__((section(".noxip"))) static void flexspi_clockConfig(flexspi_t *fspi)
__attribute__((section(".noxip"))) static void flexspi_clockConfig(flexspi_t *fspi, u8 fast)
{
if (fspi->instance == flexspi_instance1) {
_imxrt_ccmControlGate(pctl_clk_flexspi, clk_state_off);
_imxrt_ccmInitUsb1Pfd(clk_pfd0, 13); /* PLL3_PDF0=664.6MHz */
_imxrt_ccmSetDiv(clk_div_flexspi, 4); /* div5 */
_imxrt_ccmSetMux(clk_mux_flexspi, 3); /* PLL3 PFD0 */
_imxrt_ccmInitUsb1Pfd(clk_pfd0, 13); /* PLL3_PDF0=664.6MHz */
_imxrt_ccmSetDiv(clk_div_flexspi, fast ? 4 : 9); /* Fast: 664 / (4 + 1) => 132 MHz, Normal: 664 / (9 + 1) => 66 MHz */
_imxrt_ccmSetMux(clk_mux_flexspi, 3); /* PLL3 PFD0 */
_imxrt_ccmControlGate(pctl_clk_flexspi, clk_state_run_wait);
}
else if (fspi->instance == flexspi_instance2) {
_imxrt_ccmControlGate(pctl_clk_flexspi2, clk_state_off);
_imxrt_ccmInitUsb1Pfd(clk_pfd0, 13); /* PLL3_PDF0=664.6MHz */
_imxrt_ccmSetDiv(clk_div_flexspi2, 4); /* div5 */
_imxrt_ccmSetMux(clk_mux_flexspi2, 1); /* PLL3 PFD0 */
_imxrt_ccmInitUsb1Pfd(clk_pfd0, 13); /* PLL3_PDF0=664.6MHz */
_imxrt_ccmSetDiv(clk_div_flexspi2, fast ? 4 : 9); /* Fast: 664 / (4 + 1) => 132 MHz, Normal: 664 / (9 + 1) => 66 MHz */
_imxrt_ccmSetMux(clk_mux_flexspi2, 1); /* PLL3 PFD0 */
_imxrt_ccmControlGate(pctl_clk_flexspi2, clk_state_run_wait);
}
}
Expand Down
8 changes: 4 additions & 4 deletions devices/flash-imxrt/fspi/fspi_rt117x.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ static void *flexspi_getBase(int instance)
}


__attribute__((section(".noxip"))) static void flexspi_clockConfig(flexspi_t *fspi)
__attribute__((section(".noxip"))) static void flexspi_clockConfig(flexspi_t *fspi, u8 fast)
{
int gate, clk, div, mux, mfd, mfn;

switch (fspi->instance) {
case flexspi_instance1:
clk = pctl_clk_flexspi1;
gate = pctl_lpcg_flexspi1;
div = 3; /* SYS_PLL2_CLK / (3 + 1) => 132 MHz */
div = fast ? 3 : 7; /* Fast: 528 / (3 + 1) => 132 MHz, Normal: 528 / (7 + 1) => 66 MHz */
mux = mux_clkroot_flexspi1_syspll2out; /* Select main clock: SYS_PLL2_CLK = 528 MHz */
mfd = 0;
mfn = 0;
Expand All @@ -70,8 +70,8 @@ __attribute__((section(".noxip"))) static void flexspi_clockConfig(flexspi_t *fs
case flexspi_instance2:
clk = pctl_clk_flexspi2;
gate = pctl_lpcg_flexspi2;
div = 3; /* SYS_PLL2_CLK / (3 + 1) => 132 MHz */
mux = mux_clkroot_flexspi2_syspll2out; /* Select main clock: SYS_PLL2_CLK = 528 MHz */
div = fast ? 3 : 7; /* Fast: 528 / (3 + 1) => 132 MHz, Normal: 528 / (7 + 1) => 66 MHz */
mux = mux_clkroot_flexspi1_syspll2out; /* Select main clock: SYS_PLL2_CLK = 528 MHz */
mfd = 0;
mfn = 0;
break;
Expand Down
2 changes: 2 additions & 0 deletions devices/flash-imxrt/nor/flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@
#define FLASH_CMD_ERRS 0x7a /* Program/erase resume */
#define FLASH_CMD_EN4B 0xb7 /* Enter 4-byte address mode */
#define FLASH_CMD_EX4B 0xe9 /* Exit 4-byte address mode */
#define FLASH_CMD_RDRD 0x61 /* ISSI: Read Read Parameters (volatile) */
#define FLASH_CMD_SRPV 0x63 /* ISSI: Set Read Parameters (volatile) */


#endif /* _FLASH_H_ */
10 changes: 5 additions & 5 deletions devices/flash-imxrt/nor/nor.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ static const struct nor_info flashInfo[] = {
{ FLASH_ID(0xef, 0x8019), "W25Q256JW-M", 32 * 1024 * 1024, 0x100, 0x1000, NOR_CAPS_GENERIC, lutGeneric4Byte, NULL },

/* ISSI */
{ FLASH_ID(0x9d, 0x7016), "IS25WP032", 4 * 1024 * 1024, 0x100, 0x1000, NOR_CAPS_GENERIC, lutGeneric3Byte, NULL },
{ FLASH_ID(0x9d, 0x7017), "IS25WP064", 8 * 1024 * 1024, 0x100, 0x1000, NOR_CAPS_GENERIC, lutGeneric3Byte, NULL },
{ FLASH_ID(0x9d, 0x7018), "IS25WP128", 16 * 1024 * 1024, 0x100, 0x1000, NOR_CAPS_GENERIC, lutGeneric3Byte, NULL },
{ FLASH_ID(0x9d, 0x7019), "IS25WP256", 32 * 1024 * 1024, 0x100, 0x1000, NOR_CAPS_GENERIC, lutGeneric4Byte, nor_mxQuadEnable },
{ FLASH_ID(0x9d, 0x6019), "IS25LP256", 32 * 1024 * 1024, 0x100, 0x1000, NOR_CAPS_GENERIC, lutGeneric4Byte, nor_mxQuadEnable },
{ FLASH_ID(0x9d, 0x7016), "IS25WP032", 4 * 1024 * 1024, 0x100, 0x1000, NOR_CAPS_GENERIC, lutIssi3Byte, nor_issiInit },
{ FLASH_ID(0x9d, 0x7017), "IS25WP064", 8 * 1024 * 1024, 0x100, 0x1000, NOR_CAPS_GENERIC, lutIssi3Byte, nor_issiInit },
{ FLASH_ID(0x9d, 0x7018), "IS25WP128", 16 * 1024 * 1024, 0x100, 0x1000, NOR_CAPS_GENERIC, lutIssi3Byte, nor_issiInit },
{ FLASH_ID(0x9d, 0x7019), "IS25WP256", 32 * 1024 * 1024, 0x100, 0x1000, NOR_CAPS_GENERIC, lutIssi4Byte, nor_issiInit },
{ FLASH_ID(0x9d, 0x6019), "IS25LP256", 32 * 1024 * 1024, 0x100, 0x1000, NOR_CAPS_GENERIC, lutIssi4Byte, nor_issiInit },

/* Micron */
{ FLASH_ID(0x20, 0xba19), "MT25QL256", 32 * 1024 * 1024, 0x100, 0x1000, NOR_CAPS_GENERIC | NOR_CAPS_EN4B, lutMicronMono, NULL },
Expand Down
4 changes: 4 additions & 0 deletions devices/flash-imxrt/nor/nor.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,8 @@ extern int nor_probe(flexspi_t *fspi, u8 port, const struct nor_info **pInfo, co
int nor_mxQuadEnable(struct nor_device *dev);


/* ISSI chip init */
int nor_issiInit(struct nor_device *dev);


#endif /* _FLEXSPI_NOR_H_ */
118 changes: 118 additions & 0 deletions devices/flash-imxrt/nor/nor_issi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* Phoenix-RTOS
*
* Operating system loader
*
* i.MX RT nor flash device driver
* ISSI Specific
*
* Copyright 2024 Phoenix Systems
* Authors: Ziemowit Leszczynski
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/


#include <lib/lib.h>
#include <devices/devs.h>
#include "../fspi.h"
#include "../lut.h"

#include "flash.h"
#include "nor.h"


int nor_issiInit(struct nor_device *dev)
{
int res;
struct xferOp xfer;
u8 status, params;
const time_t timeout = 1000;

if (dev->active == 0) {
return -ENODEV;
}

/* Load only the necessary commands to enable quad mode and set dummy cycles. */
flexspi_lutUpdateEntries(&dev->fspi, fspi_readStatus * LUT_SEQSZ, dev->nor->lut + fspi_readStatus, 1, LUT_SEQSZ);
flexspi_lutUpdateEntries(&dev->fspi, fspi_writeStatus * LUT_SEQSZ, dev->nor->lut + fspi_writeStatus, 1, LUT_SEQSZ);
flexspi_lutUpdateEntries(&dev->fspi, fspi_writeEnable * LUT_SEQSZ, dev->nor->lut + fspi_writeEnable, 1, LUT_SEQSZ);
flexspi_lutUpdateEntries(&dev->fspi, fspi_cmdCustom1 * LUT_SEQSZ, dev->nor->lut + fspi_cmdCustom1, 1, LUT_SEQSZ);
flexspi_lutUpdateEntries(&dev->fspi, fspi_cmdCustom2 * LUT_SEQSZ, dev->nor->lut + fspi_cmdCustom2, 1, LUT_SEQSZ);

res = nor_readStatus(&dev->fspi, dev->port, &status, timeout);
if (res < EOK) {
return res;
}

if ((status & (1uL << 6u)) == 0uL) {
res = nor_writeEnable(&dev->fspi, dev->port, 1, timeout);
if (res < EOK) {
return res;
}

/* Quad Enable */
status |= (1uL << 6u);

xfer.op = xfer_opWrite;
xfer.port = dev->port;
xfer.timeout = timeout;
xfer.addr = 0;
xfer.seqIdx = LUT_SEQIDX(fspi_writeStatus);
xfer.seqNum = LUT_SEQNUM(fspi_writeStatus);
xfer.data.write.ptr = &status;
xfer.data.write.sz = 1;

res = flexspi_xferExec(&dev->fspi, &xfer);
if (res < EOK) {
return res;
}

res = nor_waitBusy(&dev->fspi, dev->port, timeout);
if (res < EOK) {
return res;
}
}

xfer.op = xfer_opRead;
xfer.port = dev->port;
xfer.timeout = timeout;
xfer.addr = 0;
xfer.seqIdx = LUT_SEQIDX(fspi_cmdCustom1);
xfer.seqNum = LUT_SEQNUM(fspi_cmdCustom1);
xfer.data.read.ptr = &params;
xfer.data.read.sz = 1;

res = flexspi_xferExec(&dev->fspi, &xfer);
if (res < EOK) {
return res;
}

if (((params & 0x87) >> 3u) != 11) {
/* 11 dummy cycles */
params = (params & 0x87) | (11uL << 3u);

xfer.op = xfer_opWrite;
xfer.port = dev->port;
xfer.timeout = timeout;
xfer.addr = 0;
xfer.seqIdx = LUT_SEQIDX(fspi_cmdCustom2);
xfer.seqNum = LUT_SEQNUM(fspi_cmdCustom2);
xfer.data.read.ptr = &params;
xfer.data.write.sz = 1;

res = flexspi_xferExec(&dev->fspi, &xfer);
if (res < EOK) {
return res;
}

res = nor_waitBusy(&dev->fspi, dev->port, timeout);
if (res < EOK) {
return res;
}
}

return EOK;
}
71 changes: 69 additions & 2 deletions devices/flash-imxrt/nor/nor_lut.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,42 @@ static const u32 seq_micronExit4Byte[NOR_LUTSEQSZ] = {
};


/* Generic chips: ISSI, Winbond, Macronix (3-byte address) */
/*
* ISSI NOR dedicated Command Sequences
*/

/* Read Fast Quad (3-byte address) for 133 MHz and 11 dummy cycles */
static const u32 seq_issiReadData3Byte[NOR_LUTSEQSZ] = {
LUT_SEQ(lutCmd_SDR, lutPad1, FLASH_CMD_QIOR, lutCmdRADDR_SDR, lutPad4, 0x18),
LUT_SEQ(lutCmdMODE8_SDR, lutPad4, 0x00, lutCmdDUMMY_SDR, lutPad4, 0x09),
LUT_SEQ(lutCmdREAD_SDR, lutPad4, 0x04, lutCmdSTOP, lutPad1, 0),
0
};

/* Read Fast Quad (4-byte address) for 133 MHz and 11 dummy cycles */
static const u32 seq_issiReadData4Byte[NOR_LUTSEQSZ] = {
LUT_SEQ(lutCmd_SDR, lutPad1, FLASH_CMD_4QIOR, lutCmdRADDR_SDR, lutPad4, 0x20),
LUT_SEQ(lutCmdMODE8_SDR, lutPad4, 0x00, lutCmdDUMMY_SDR, lutPad4, 0x09),
LUT_SEQ(lutCmdREAD_SDR, lutPad4, 0x04, lutCmdSTOP, lutPad1, 0),
0
};

/* Read Read Parameters */
static const u32 seq_issiReadReadParameters[NOR_LUTSEQSZ] = {
LUT_SEQ(lutCmd_SDR, lutPad1, FLASH_CMD_RDRD, lutCmdREAD_SDR, lutPad1, 0x01),
LUT_SEQ(lutCmdSTOP, lutPad1, 0, 0, 0, 0),
0, 0
};

/* Write Read Parameters */
static const u32 seq_issiWriteReadParameters[NOR_LUTSEQSZ] = {
LUT_SEQ(lutCmd_SDR, lutPad1, FLASH_CMD_SRPV, lutCmdWRITE_SDR, lutPad1, 0x01),
LUT_SEQ(lutCmdSTOP, lutPad1, 0, 0, 0, 0),
0, 0
};


/* Generic chips: Winbond, Macronix (3-byte address) */
static const u32 *lutGeneric3Byte[LUT_ENTRIES] = {
[fspi_readData] = seq_genericReadData3Byte,
[fspi_readStatus] = seq_genericReadStatus,
Expand All @@ -195,7 +230,7 @@ static const u32 *lutGeneric3Byte[LUT_ENTRIES] = {
[fspi_readID] = seq_genericReadID,
};

/* Generic chips: ISSI, Winbond, Macronix (4-byte address) */
/* Generic chips: Winbond, Macronix (4-byte address) */
static const u32 *lutGeneric4Byte[LUT_ENTRIES] = {
[fspi_readData] = seq_genericReadData4Byte,
[fspi_readStatus] = seq_genericReadStatus,
Expand Down Expand Up @@ -239,4 +274,36 @@ static const u32 *lutMicronDie[LUT_ENTRIES] = {
[fspi_exit4byteAddr] = seq_micronExit4Byte,
};

/* ISSI chips (3-byte address) */
static const u32 *lutIssi3Byte[LUT_ENTRIES] = {
[fspi_readData] = seq_issiReadData3Byte,
[fspi_readStatus] = seq_genericReadStatus,
[fspi_writeStatus] = seq_genericWriteStatus,
[fspi_writeEnable] = seq_genericWriteEnable,
[fspi_writeDisable] = seq_genericWriteDisable,
[fspi_eraseSector] = seq_genericEraseSector3Byte,
[fspi_eraseBlock] = seq_genericEraseBlock3Byte,
[fspi_eraseChip] = seq_genericEraseChip,
[fspi_programQPP] = seq_genericProgramQPP3Byte,
[fspi_readID] = seq_genericReadID,
[fspi_cmdCustom1] = seq_issiReadReadParameters,
[fspi_cmdCustom2] = seq_issiWriteReadParameters,
};

/* ISSI chips (4-byte address) */
static const u32 *lutIssi4Byte[LUT_ENTRIES] = {
[fspi_readData] = seq_issiReadData4Byte,
[fspi_readStatus] = seq_genericReadStatus,
[fspi_writeStatus] = seq_genericWriteStatus,
[fspi_writeEnable] = seq_genericWriteEnable,
[fspi_writeDisable] = seq_genericWriteDisable,
[fspi_eraseSector] = seq_genericEraseSector4Byte,
[fspi_eraseBlock] = seq_genericEraseBlock4Byte,
[fspi_eraseChip] = seq_genericEraseChip,
[fspi_programQPP] = seq_genericProgramQPP4Byte,
[fspi_readID] = seq_genericReadID,
[fspi_cmdCustom1] = seq_issiReadReadParameters,
[fspi_cmdCustom2] = seq_issiWriteReadParameters,
};

#endif /* _LUTTABLES_H_ */
Loading
Loading