279 lines
9.1 KiB
C
279 lines
9.1 KiB
C
#ifndef __FLASH_H__
|
|
#define __FLASH_H__
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include <pt.h>
|
|
#include <process.h>
|
|
|
|
#ifndef FLASH_VERIFY_EN
|
|
#define FLASH_VERIFY_EN (1) /* defaultly need verify flash written data */
|
|
#endif
|
|
|
|
#ifndef FLASH_CHECK_FF_EN
|
|
#define FLASH_CHECK_FF_EN (1) /* defaultly need read flash and check whether are erased, all 0xFF */
|
|
#endif
|
|
|
|
#define FLASH_INFO_MAGIC 0x46494E46
|
|
#define MAX_FLASH_DEVICE_NAME 64
|
|
#define MAX_FLASH_DEVICE_TYPE 32
|
|
|
|
#define FLASH_TYPE_QSPI_NAND "QSPI_NAND"
|
|
/* the first QSPI flash, crane is extern QSPI flash, craneM/craneG is internal QSPI flash.*/
|
|
#define FLASH_TYPE_QSPI_NOR "QSPI_NOR"
|
|
#define FLASH_TYPE_SPI_NOR "SPI_NOR"
|
|
#define FLASH_TYPE_SPI_NAND "SPI_NAND"
|
|
#define FLASH_TYPE_EMMC "EMMC"
|
|
#define FLASH_TYPE_MEM "MEM"
|
|
#define FLASH_TYPE_DUMMY "DUMMY"
|
|
#define FLASH_TYPE_QSPI2_NOR "QSPI2_NOR"
|
|
|
|
#define FLASH_ERR_OTHERS (-1)
|
|
#define FLASH_ERR_BAD_BLOCK (-2)
|
|
#define FLASH_ERR_BAD_PARAMETER (-3)
|
|
#define FLASH_ERR_ECC_ERR (-4)
|
|
#define FLASH_ERR_PROGRAM_ERR (-5)
|
|
#define FLASH_ERR_ERASE_ERR (-6)
|
|
|
|
#define SPI_PORT_QSPI 0
|
|
#define SPI_PORT_QSPI0 0
|
|
#define SPI_PORT_SSP0 1
|
|
#define SPI_PORT_SSP1 2
|
|
#define SPI_PORT_SSP2 3
|
|
#define SPI_PORT_QSPI2 4
|
|
#define SPI_PORT_EMMC 5
|
|
#define SPI_PORT_MEM 6
|
|
#define SPI_PORT_QSPI1 7
|
|
|
|
/* SSP_<CLK>_<FRM>_<RXD>_<TXD> */
|
|
typedef enum {
|
|
SSP_GPIO_CONFIG_DEFAULT,
|
|
SSP_GPIO4_FUNC2_GPIO5_FUNC2_GPIO6_FUNC2_GPIO7_FUNC2,
|
|
SSP_GPIO4_FUNC7_GPIO5_FUNC7_GPIO6_FUNC7_GPIO7_FUNC7,
|
|
SSP_GPIO12_FUNC1_GPIO13_FUNC1_GPIO14_FUNC1_GPIO15_FUNC1,
|
|
SSP_GPIO16_FUNC2_GPIO17_FUNC2_GPIO19_FUNC2_GPIO18_FUNC2,
|
|
SSP_GPIO16_FUNC2_GPIO17_FUNC2_GPIO18_FUNC4_GPIO19_FUNC4,
|
|
SSP_GPIO33_FUNC1_GPIO34_FUNC1_GPIO35_FUNC1_GPIO36_FUNC1,
|
|
SSP_GPIO33_FUNC2_GPIO34_FUNC2_GPIO35_FUNC2_GPIO36_FUNC2,
|
|
SSP_GPIO64_FUNC7_GPIO63_FUNC7_GPIO61_FUNC7_GPIO62_FUNC7,
|
|
SSP_GPIO71_FUNC2_GPIO72_FUNC2_GPIO73_FUNC2_GPIO74_FUNC2,
|
|
SSP_QSPI_CLK_FUNC2_QSPI_CS1_FUNC2_QSPI_DAT1_FUNC2_QSPI_DAT0_FUNC2,
|
|
SSP_QSPI_CLK_FUNC4_QSPI_CS1_FUNC4_QSPI_DAT1_FUNC4_QSPI_DAT0_FUNC4,
|
|
SSP_GPIO4_FUNC2_GPIO55_FUNC0_GPIO6_FUNC2_GPIO7_FUNC2,
|
|
} ssp_gpio_config_t;
|
|
|
|
struct compatible_device {
|
|
uint16_t vendor_id;
|
|
uint16_t device_id;
|
|
uint32_t reserved1;
|
|
char device_name[MAX_FLASH_DEVICE_NAME];
|
|
};
|
|
|
|
/**
|
|
* \brief Flash information
|
|
*/
|
|
struct flash_info {
|
|
uint32_t magic;
|
|
uint16_t vendor_id;
|
|
uint16_t device_id;
|
|
char device_name[MAX_FLASH_DEVICE_NAME];
|
|
char device_type[MAX_FLASH_DEVICE_TYPE];
|
|
/* the following two parameters are used by ubi */
|
|
uint32_t min_io_size;
|
|
uint32_t peb_size;
|
|
/* the following three parameters are used by erase and program */
|
|
uint32_t page_size;
|
|
uint32_t sector_size;
|
|
uint32_t block_size;
|
|
uint8_t reserved1[3];
|
|
uint8_t ssp_gpio : 6;
|
|
uint8_t ssp_clk : 2;
|
|
/* total flash size */
|
|
uint64_t flash_size;
|
|
uint8_t erased_value; /*/< Contents of erased memory (usually 0xFF) */
|
|
uint8_t chained;
|
|
uint8_t spi_port;
|
|
uint8_t combined_flash_size_in_mb; /* combined flash size in MB */
|
|
uint32_t compatible_device_num;
|
|
struct compatible_device compatible_device_list[1];
|
|
};
|
|
|
|
typedef enum {
|
|
SSP_CLK_52M,
|
|
SSP_CLK_26M,
|
|
SSP_CLK_13M,
|
|
SSP_CLK_6500K,
|
|
} ssp_clk_config_t;
|
|
|
|
typedef struct {
|
|
uint32_t pnum;
|
|
uint32_t offset;
|
|
} ubi_addr_t;
|
|
|
|
typedef struct {
|
|
const void *flash;
|
|
size_t partition_size;
|
|
} sparse_param_t;
|
|
|
|
typedef struct {
|
|
/* Containers for the State */
|
|
struct pt pt;
|
|
|
|
/* Input Variables */
|
|
process_event_t ev;
|
|
union {
|
|
uint64_t addr;
|
|
ubi_addr_t ubi_addr;
|
|
sparse_param_t sparse_param;
|
|
};
|
|
const void *data;
|
|
size_t size;
|
|
size_t repeats;
|
|
|
|
/* Output Variables */
|
|
int result; /**< Result Code */
|
|
} flash_state_t;
|
|
|
|
/* support spi_nor_flash.c use qspi controller common interface, although spi did not use qspi controller */
|
|
typedef int (*qspi_read_t)(unsigned seqid, unsigned addr, void *data, size_t size);
|
|
typedef int (*qspi_write_t)(unsigned seqid, unsigned addr, const void *data, size_t size);
|
|
typedef void (*qspi_cmd_t)(unsigned seqid, unsigned addr);
|
|
|
|
typedef struct {
|
|
qspi_read_t qspi_read;
|
|
qspi_write_t qspi_write;
|
|
qspi_cmd_t qspi_cmd;
|
|
} qpsi_lut_operation_t;
|
|
|
|
typedef int (*flash_read_t)(uint64_t addr, void *data, size_t size);
|
|
typedef char (*flash_write_t)(flash_state_t *state);
|
|
typedef char (*flash_erase_t)(flash_state_t *state);
|
|
typedef const struct flash_info *(*flash_get_info_t)(void);
|
|
typedef int (*flash_erase_sync_t)(uint64_t addr, size_t size);
|
|
typedef int (*flash_write_sync_t)(uint64_t addr, const void *data, size_t size);
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
typedef void (*flash_quad_enable_cb_t)(const qpsi_lut_operation_t *lut_op, bool enable);
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
struct flash_operation {
|
|
flash_read_t read;
|
|
flash_write_t write;
|
|
flash_erase_t erase;
|
|
flash_write_sync_t write_sync;
|
|
flash_erase_sync_t erase_sync;
|
|
flash_get_info_t info;
|
|
};
|
|
|
|
typedef enum {
|
|
FLASH_ID_FIRST, /* first flash */
|
|
FLASH_ID_SECOND, /* second flash */
|
|
FLASH_ID_THIRD, /* third flash */
|
|
FLASH_ID_MAX
|
|
} flash_id_t;
|
|
|
|
/* start a protothread to do thread_fun(uint64_t address, const void *buf, size_t sz).
|
|
* state: supply parent pt for thread_fun.
|
|
* child_state: pt for thread_fun.(if multi pt threads, child_state may be custom defined)
|
|
* state->result: return result of thread_fun.
|
|
*
|
|
* eg: if thread_fun is partition_raw_flash(uint64_t address, const void *buf, size_t sz),
|
|
* invoke FLASH_BASE_TASK(state, partition_raw_flash_state, partition_raw_flash, address, buf, sz);
|
|
*/
|
|
#define FLASH_BASE_TASK(state, child_state, thread_fun, address, buf, sz, repts) \
|
|
{ \
|
|
static flash_state_t child_state; \
|
|
memset(&child_state, 0, sizeof(child_state)); \
|
|
child_state.ev = state->ev; \
|
|
child_state.addr = address; \
|
|
child_state.data = buf; \
|
|
child_state.size = sz; \
|
|
child_state.repeats = repts; \
|
|
PT_SPAWN(&state->pt, &(child_state.pt), thread_fun(&child_state)); \
|
|
state->result = child_state.result; \
|
|
}
|
|
|
|
#define INPUT_VOID_TASK(state, child_state, thread_fun) \
|
|
FLASH_BASE_TASK(state, child_state, thread_fun, 0, NULL, 0, 0)
|
|
|
|
/* start a protothread to do thread_fun(void).
|
|
* state: supply parent pt for thread_fun(void).
|
|
* state->result: return result of thread_fun(void).
|
|
*
|
|
* eg: if thread_fun(void) is wait_for_complete_task(void),
|
|
* invoke WAIT_TASK(state, wait_for_complete_task);
|
|
*/
|
|
#define WAIT_TASK(state, thread_fun) \
|
|
FLASH_BASE_TASK(state, wait_state, thread_fun, 0, NULL, 0, 0)
|
|
|
|
/* start a protothread to do thread_fun(uint64_t address, size_t sz).
|
|
* state: supply parent pt for thread_fun.
|
|
* state->result: return result of thread_fun.
|
|
*
|
|
* eg: if thread_fun is flash->erase(uint64_t address, size_t sz),
|
|
* invoke FLASH_ERASE_TASK(state, flash->erase, address, sz);
|
|
*/
|
|
#define FLASH_ERASE_TASK(state, thread_fun, address, sz) \
|
|
FLASH_BASE_TASK(state, erase_state, thread_fun, address, NULL, sz, 0)
|
|
|
|
/* start a protothread to do thread_fun(uint64_t address, const void *buf, size_t sz, size_t repeats).
|
|
* state: supply parent pt for thread_fun.
|
|
* state->result: return result of thread_fun.
|
|
*
|
|
* eg: if thread_fun is flash->write(uint64_t address, const void *buf, size_t sz, size_t repeats),
|
|
* invoke FLASH_WRITE_TASK(state, flash->write, address, buf, sz, repeats);
|
|
*/
|
|
#define FLASH_WRITE_TASK(state, thread_fun, address, buf, sz, repeats) \
|
|
FLASH_BASE_TASK(state, write_state, thread_fun, address, buf, sz, repeats)
|
|
|
|
int flash_info_init(const void *data, size_t size);
|
|
int flash_force_all_probe(void);
|
|
const struct flash_operation *flash_set_operation(flash_id_t flash_id);
|
|
const struct flash_operation *flash_get_operation(void);
|
|
const struct flash_operation *flash_get_operation_with_id(flash_id_t flash_id);
|
|
int flash_verify(uint64_t addr, const void *data, size_t size);
|
|
|
|
bool flash_is_chip_erased(flash_id_t id);
|
|
void flash_set_chip_erased(flash_id_t id);
|
|
void flash_reset_chip_erased(void);
|
|
flash_id_t flash_get_current_flash_id(void);
|
|
|
|
/* read current flash from any address */
|
|
int flash_read_unaligned(uint64_t addr, void *data, size_t size);
|
|
|
|
uint8_t *flash_get_tmp_buffer(size_t sz);
|
|
|
|
#define FLASH_IS_ALL_FF_TASK(state, address, sz) \
|
|
FLASH_BASE_TASK(state, flash_is_all_ff_state, flash_is_all_ff, address, NULL, sz, 0)
|
|
|
|
PT_THREAD(flash_is_all_ff(flash_state_t * state));
|
|
|
|
#define FLASH_VERIFY_TASK(state, address, data, sz) \
|
|
FLASH_BASE_TASK(state, flash_verify_state, flash_verify_pt, address, data, sz, 0)
|
|
|
|
PT_THREAD(flash_verify_pt(flash_state_t * state));
|
|
|
|
#ifdef USE_QSPI_NOR_FLASH
|
|
extern bool flash_with_qspi2_nor;
|
|
int flash_nor_write_by_page(uint64_t address, const void *data, size_t size);
|
|
int flash_nor_erase_by_sector(uint64_t address, size_t size);
|
|
#endif
|
|
|
|
#ifdef USE_QSPI_NAND_FLASH
|
|
int flash_nand_write_by_page(uint64_t address, const void *data, size_t size);
|
|
int flash_nand_erase_by_sector(uint64_t address, size_t size);
|
|
#endif
|
|
|
|
void flash_get_info_base(uintptr_t *base, size_t *size);
|
|
|
|
#ifdef __cplusplus
|
|
} /* extern "C" */
|
|
#endif
|
|
|
|
#endif /* __FLASH_H__ */
|