mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-02-04 20:51:36 +00:00
bsps/xilinx-zynq: Flash driver commands per-instance
zqspi flash driver uses 3 or 4 byte commands per instance. The driver defaults to 3 byte addressing for flash chips smaller then 16MiB.
This commit is contained in:
committed by
Kinsey Moore
parent
40305e360f
commit
a640977c9f
@@ -240,12 +240,13 @@ static zqspi_error zqspi_transfer_buffer_copy_in(
|
||||
|
||||
static void zqspi_transfer_buffer_set_addr(
|
||||
zqspi_transfer_buffer* transfer,
|
||||
bool addr_4_byte,
|
||||
uint32_t address
|
||||
)
|
||||
{
|
||||
#if ZQSPI_FLASH_4BYTE_ADDRESSING
|
||||
zqspi_transfer_buffer_set8(transfer, (address >> 24) & 0xff);
|
||||
#endif
|
||||
if (addr_4_byte) {
|
||||
zqspi_transfer_buffer_set8(transfer, (address >> 24) & 0xff);
|
||||
}
|
||||
zqspi_transfer_buffer_set8(transfer, (address >> 16) & 0xff);
|
||||
zqspi_transfer_buffer_set8(transfer, (address >> 8) & 0xff);
|
||||
zqspi_transfer_buffer_set8(transfer, address & 0xff);
|
||||
@@ -417,11 +418,12 @@ zqspi_error zqspi_read(
|
||||
zqspi_transfer_buffer_clear(&driver->buf);
|
||||
zqspi_transfer_buffer_set_length(
|
||||
&driver->buf,
|
||||
ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE +
|
||||
ZQSPI_FLASH_COMMAND_SIZE + (driver->addr_4_byte ? 4 : 3) +
|
||||
driver->flash_read_dummies + size
|
||||
);
|
||||
zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_READ_CMD);
|
||||
zqspi_transfer_buffer_set_addr(&driver->buf, address);
|
||||
zqspi_transfer_buffer_set8(&driver->buf, driver->commands.fast_read);
|
||||
zqspi_transfer_buffer_set_addr(&driver->buf, driver->addr_4_byte,
|
||||
address);
|
||||
fe = zqspi_transfer_buffer_fill(&driver->buf, 0,
|
||||
driver->flash_read_dummies + size);
|
||||
if (fe != ZQSPI_FLASH_NO_ERROR) {
|
||||
@@ -429,7 +431,7 @@ zqspi_error zqspi_read(
|
||||
}
|
||||
zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_RX_TRANS);
|
||||
zqspi_transfer_buffer_set_command_len(&driver->buf,
|
||||
ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE +
|
||||
ZQSPI_FLASH_COMMAND_SIZE + (driver->addr_4_byte ? 4 : 3) +
|
||||
driver->flash_read_dummies);
|
||||
|
||||
fe = zqspi_transfer(&driver->buf, &driver->initialised);
|
||||
@@ -438,7 +440,7 @@ zqspi_error zqspi_read(
|
||||
}
|
||||
|
||||
zqspi_transfer_buffer_skip(&driver->buf,
|
||||
ZQSPI_FLASH_ADDRESS_SIZE + driver->flash_read_dummies);
|
||||
(driver->addr_4_byte ? 4 : 3) + driver->flash_read_dummies);
|
||||
|
||||
fe = zqspi_transfer_buffer_copy_out(&driver->buf, data, size);
|
||||
if (fe != ZQSPI_FLASH_NO_ERROR) {
|
||||
@@ -476,10 +478,11 @@ zqspi_error zqspi_blank(zqspiflash *driver, uint32_t address, size_t length)
|
||||
|
||||
zqspi_transfer_buffer_clear(&driver->buf);
|
||||
zqspi_transfer_buffer_set_length(&driver->buf,
|
||||
ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE
|
||||
ZQSPI_FLASH_COMMAND_SIZE + (driver->addr_4_byte ? 4 : 3)
|
||||
+ driver->flash_read_dummies + size);
|
||||
zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_READ_CMD);
|
||||
zqspi_transfer_buffer_set_addr(&driver->buf, address);
|
||||
zqspi_transfer_buffer_set8(&driver->buf, driver->commands.fast_read);
|
||||
zqspi_transfer_buffer_set_addr(&driver->buf, driver->addr_4_byte,
|
||||
address);
|
||||
fe = zqspi_transfer_buffer_fill(&driver->buf, 0,
|
||||
driver->flash_read_dummies + size);
|
||||
if (fe != ZQSPI_FLASH_NO_ERROR) {
|
||||
@@ -487,7 +490,7 @@ zqspi_error zqspi_blank(zqspiflash *driver, uint32_t address, size_t length)
|
||||
}
|
||||
zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_RX_TRANS);
|
||||
zqspi_transfer_buffer_set_command_len(&driver->buf,
|
||||
ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE
|
||||
ZQSPI_FLASH_COMMAND_SIZE + (driver->addr_4_byte ? 4 : 3)
|
||||
+ driver->flash_read_dummies);
|
||||
|
||||
fe = zqspi_transfer(&driver->buf, &driver->initialised);
|
||||
@@ -495,7 +498,7 @@ zqspi_error zqspi_blank(zqspiflash *driver, uint32_t address, size_t length)
|
||||
return fe;
|
||||
}
|
||||
|
||||
zqspi_transfer_buffer_skip(&driver->buf, ZQSPI_FLASH_ADDRESS_SIZE);
|
||||
zqspi_transfer_buffer_skip(&driver->buf, (driver->addr_4_byte ? 4 : 3));
|
||||
|
||||
length -= size;
|
||||
address += size;
|
||||
@@ -570,12 +573,13 @@ zqspi_error zqspi_erase_sector(zqspiflash *driver, uint32_t address)
|
||||
|
||||
zqspi_transfer_buffer_clear(&driver->buf);
|
||||
zqspi_transfer_buffer_set_length(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE
|
||||
+ ZQSPI_FLASH_ADDRESS_SIZE);
|
||||
zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_SEC_ERASE_CMD);
|
||||
zqspi_transfer_buffer_set_addr(&driver->buf, address);
|
||||
+ (driver->addr_4_byte ? 4 : 3));
|
||||
zqspi_transfer_buffer_set8(&driver->buf, driver->commands.sector_erase);
|
||||
zqspi_transfer_buffer_set_addr(&driver->buf, driver->addr_4_byte,
|
||||
address);
|
||||
zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_TX_TRANS);
|
||||
zqspi_transfer_buffer_set_command_len(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE
|
||||
+ ZQSPI_FLASH_ADDRESS_SIZE);
|
||||
+ (driver->addr_4_byte ? 4 : 3));
|
||||
|
||||
fe = zqspi_transfer(&driver->buf, &driver->initialised);
|
||||
if (fe != ZQSPI_FLASH_NO_ERROR)
|
||||
@@ -619,7 +623,8 @@ zqspi_error zqspi_erase_device(zqspiflash *driver)
|
||||
zqspi_transfer_buffer_set_length(&driver->buf, 1);
|
||||
zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_BULK_ERASE_CMD);
|
||||
zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_TX_TRANS);
|
||||
zqspi_transfer_buffer_set_command_len(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE);
|
||||
zqspi_transfer_buffer_set_command_len(&driver->buf,
|
||||
ZQSPI_FLASH_COMMAND_SIZE + (driver->addr_4_byte ? 4 : 3));
|
||||
|
||||
fe = zqspi_transfer(&driver->buf, &driver->initialised);
|
||||
if (fe != ZQSPI_FLASH_NO_ERROR)
|
||||
@@ -706,12 +711,13 @@ zqspi_error zqspi_write(
|
||||
|
||||
zqspi_transfer_buffer_clear(&driver->buf);
|
||||
zqspi_transfer_buffer_set_length(&driver->buf, ZQSPI_FLASH_COMMAND_SIZE
|
||||
+ ZQSPI_FLASH_ADDRESS_SIZE + size);
|
||||
zqspi_transfer_buffer_set8(&driver->buf, ZQSPI_FLASH_WRITE_CMD);
|
||||
zqspi_transfer_buffer_set_addr(&driver->buf, address);
|
||||
+ (driver->addr_4_byte ? 4 : 3) + size);
|
||||
zqspi_transfer_buffer_set8(&driver->buf, driver->commands.page_program);
|
||||
zqspi_transfer_buffer_set_addr(&driver->buf, driver->addr_4_byte,
|
||||
address);
|
||||
zqspi_transfer_buffer_set_dir(&driver->buf, ZQSPI_FLASH_TX_TRANS);
|
||||
zqspi_transfer_buffer_set_command_len(&driver->buf,
|
||||
ZQSPI_FLASH_COMMAND_SIZE + ZQSPI_FLASH_ADDRESS_SIZE);
|
||||
ZQSPI_FLASH_COMMAND_SIZE + (driver->addr_4_byte ? 4 : 3));
|
||||
fe = zqspi_transfer_buffer_copy_in(&driver->buf, data, size);
|
||||
if (fe != ZQSPI_FLASH_NO_ERROR)
|
||||
{
|
||||
@@ -831,9 +837,13 @@ zqspi_error zqspi_readid(zqspiflash *driver, uint32_t *jedec_id)
|
||||
driver->flash_page_size = nor_config.page_size;
|
||||
}
|
||||
|
||||
#if ZQSPI_FLASH_FAST_READ
|
||||
driver->flash_read_dummies = 1;
|
||||
#endif
|
||||
if (driver->flash_size > 16 * 1024 * 1024) {
|
||||
driver->addr_4_byte = true;
|
||||
driver->commands.fast_read = ZQSPI_FLASH_4B_FAST_READ_CMD;
|
||||
driver->commands.read = ZQSPI_FLASH_4B_READ_CMD;
|
||||
driver->commands.page_program = ZQSPI_FLASH_4B_WRITE_CMD;
|
||||
driver->commands.sector_erase = ZQSPI_FLASH_4B_SEC_ERASE_CMD;
|
||||
}
|
||||
|
||||
return ZQSPI_FLASH_NO_ERROR;
|
||||
}
|
||||
@@ -868,11 +878,16 @@ zqspi_error zqspi_init(zqspiflash *driver)
|
||||
driver->buf.sending = 0;
|
||||
driver->buf.start = false;
|
||||
driver->initialised = false;
|
||||
driver->addr_4_byte = false;
|
||||
driver->jedec_id = 0;
|
||||
driver->flash_size = 0;
|
||||
driver->flash_read_dummies = 0;
|
||||
driver->flash_read_dummies = 1;
|
||||
driver->flash_erase_sector_size = 0;
|
||||
driver->flash_page_size = 0;
|
||||
driver->commands.fast_read = ZQSPI_FLASH_3B_FAST_READ_CMD;
|
||||
driver->commands.read = ZQSPI_FLASH_3B_READ_CMD;
|
||||
driver->commands.page_program = ZQSPI_FLASH_3B_WRITE_CMD;
|
||||
driver->commands.sector_erase = ZQSPI_FLASH_3B_SEC_ERASE_CMD;
|
||||
|
||||
sc = rtems_interrupt_handler_install(
|
||||
ZQPSI_ZYNQ_QSPI_IRQ,
|
||||
|
||||
@@ -37,25 +37,16 @@
|
||||
*/
|
||||
|
||||
#define ZQSPI_FLASH_COMMAND_SIZE 1
|
||||
#if ZQSPI_FLASH_4BYTE_ADDRESSING
|
||||
#define ZQSPI_FLASH_ADDRESS_SIZE 4
|
||||
#define ZQSPI_FLASH_WRITE_CMD 0x12
|
||||
#if ZQSPI_FLASH_FAST_READ
|
||||
#define ZQSPI_FLASH_READ_CMD 0x0c
|
||||
#else
|
||||
#define ZQSPI_FLASH_READ_CMD 0x13
|
||||
#endif
|
||||
#define ZQSPI_FLASH_SEC_ERASE_CMD 0xDC
|
||||
#else
|
||||
#define ZQSPI_FLASH_ADDRESS_SIZE 3
|
||||
#define ZQSPI_FLASH_WRITE_CMD 0x02
|
||||
#if ZQSPI_FLASH_FAST_READ
|
||||
#define ZQSPI_FLASH_READ_CMD 0x0b
|
||||
#else
|
||||
#define ZQSPI_FLASH_READ_CMD 0x03
|
||||
#endif
|
||||
#define ZQSPI_FLASH_SEC_ERASE_CMD 0xD8
|
||||
#endif
|
||||
|
||||
#define ZQSPI_FLASH_4B_WRITE_CMD 0x12
|
||||
#define ZQSPI_FLASH_4B_FAST_READ_CMD 0x0C
|
||||
#define ZQSPI_FLASH_4B_READ_CMD 0x13
|
||||
#define ZQSPI_FLASH_4B_SEC_ERASE_CMD 0xDC
|
||||
|
||||
#define ZQSPI_FLASH_3B_WRITE_CMD 0x02
|
||||
#define ZQSPI_FLASH_3B_FAST_READ_CMD 0x0B
|
||||
#define ZQSPI_FLASH_3B_READ_CMD 0x03
|
||||
#define ZQSPI_FLASH_3B_SEC_ERASE_CMD 0xD8
|
||||
|
||||
#define ZQSPI_FLASH_READ_CONFIG_CMD 0x35
|
||||
#define ZQSPI_FLASH_WRITE_STATUS_CMD 0x01
|
||||
|
||||
@@ -34,19 +34,11 @@
|
||||
/*
|
||||
* Driver configuration.
|
||||
*/
|
||||
#define ZQSPI_FLASH_4BYTE_ADDRESSING 1
|
||||
#define ZQSPI_FLASH_FAST_READ 1
|
||||
|
||||
#define ZQSPI_FLASH_COMMAND_OFFSET (0) /* FLASH instruction */
|
||||
#define ZQSPI_FLASH_ADDRESS_1_OFFSET (1) /* Bits 31-24 of the address */
|
||||
#define ZQSPI_FLASH_ADDRESS_2_OFFSET (2) /* Bits 23-16 of the address */
|
||||
#define ZQSPI_FLASH_ADDRESS_3_OFFSET (3) /* Bits 16-8 of the address */
|
||||
#if ZQSPI_FLASH_4BYTE_ADDRESSING
|
||||
#define ZQSPI_FLASH_ADDRESS_4_OFFSET (4) /* Bits 8-0 of the address */
|
||||
#define ZQSPI_FLASH_DATA_OFFSET (5) /* Start of Data for Read/Write */
|
||||
#else
|
||||
#define ZQSPI_FLASH_DATA_OFFSET (4) /* Start of Data for Read/Write */
|
||||
#endif
|
||||
#define ZQSPI_FLASH_ADDRESS_4_OFFSET (4) /* Bits 8-0 of the address */
|
||||
#define ZQSPI_FLASH_SPI_MAX_PADDING (4) /* Maximum amount of padding. */
|
||||
|
||||
#define ZQSPI_FLASH_TX_TRANS 0
|
||||
@@ -108,13 +100,23 @@ typedef struct
|
||||
bool start;
|
||||
} zqspi_transfer_buffer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t fast_read;
|
||||
uint8_t read;
|
||||
uint8_t page_program;
|
||||
uint8_t sector_erase;
|
||||
} zqspi_flash_commands;
|
||||
|
||||
/*
|
||||
* A flash driver instance
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
zqspi_transfer_buffer buf;
|
||||
zqspi_flash_commands commands;
|
||||
bool initialised;
|
||||
bool addr_4_byte;
|
||||
uint32_t jedec_id;
|
||||
uint64_t flash_size;
|
||||
uint32_t flash_read_dummies;
|
||||
|
||||
Reference in New Issue
Block a user