#ifndef __FLASH_H__ #define __FLASH_H__ #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #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____ */ 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__ */