41 #define nfc_is_v1() (mxc_nf_info->mxc_version == MXC_VERSION_MX27 || \
42 mxc_nf_info->mxc_version == MXC_VERSION_MX31)
43 #define nfc_is_v2() (mxc_nf_info->mxc_version == MXC_VERSION_MX25 || \
44 mxc_nf_info->mxc_version == MXC_VERSION_MX35)
51 #undef _MXC_PRINT_STAT
55 "target must be halted to use mxc NAND flash controller";
57 "minimal granularity is one half-word, %" PRIu32
" is incorrect";
59 "trying to access out of SRAM buffer bound (addr=0x%" PRIx32
")";
82 LOG_ERROR(
"no memory for nand controller");
85 nand->controller_priv = mxc_nf_info;
88 LOG_ERROR(
"use \"nand device mxc target mx25|mx27|mx31|mx35 noecc|hwecc [biswap]\"");
95 if (strcmp(
CMD_ARGV[2],
"mx25") == 0) {
99 }
else if (strcmp(
CMD_ARGV[2],
"mx27") == 0) {
103 }
else if (strcmp(
CMD_ARGV[2],
"mx31") == 0) {
107 }
else if (strcmp(
CMD_ARGV[2],
"mx35") == 0) {
116 hwecc_needed = strcmp(
CMD_ARGV[3],
"hwecc");
117 if (hwecc_needed == 0)
144 if (CMD_ARGC < 1 || CMD_ARGC > 2)
155 if (strcmp(
CMD_ARGV[1],
"enable") == 0)
172 .handler = handle_mxc_biswap_command,
173 .help =
"Turns on/off bad block information swapping from main area, "
174 "without parameter query status.",
175 .usage =
"bank_id ['enable'|'disable']",
184 .help =
"MXC NAND flash controller commands",
196 int validate_target_result;
197 uint16_t buffsize_register_content;
198 uint32_t sreg_content;
203 uint16_t nand_status_content;
208 if (validate_target_result !=
ERROR_OK)
209 return validate_target_result;
234 nand->
bus_width = (sreg_content & sel_16bit) ? 16 : 8;
237 sreg_content |= ((nand->
bus_width == 16) ? sel_16bit : 0x00000000);
241 LOG_DEBUG(
"MXC_NF : bus is 16-bit width");
243 LOG_DEBUG(
"MXC_NF : bus is 8-bit width");
246 nand->
page_size = (sreg_content & sel_fms) ? 2048 : 512;
248 sreg_content |= ((nand->
page_size == 2048) ? sel_fms : 0x00000000);
252 LOG_ERROR(
"NAND controller have only 1 kb SRAM, so "
253 "pagesize 2048 is incompatible with it");
255 LOG_DEBUG(
"MXC_NF : NAND controller can handle pagesize of 2048");
258 LOG_ERROR(
"MXC driver does not have support for 4k pagesize.");
271 if (!(nand_status_content & 0x0080)) {
281 int validate_target_result;
282 int try_data_output_from_nand_chip;
287 if (validate_target_result !=
ERROR_OK)
288 return validate_target_result;
294 if (try_data_output_from_nand_chip !=
ERROR_OK) {
295 LOG_ERROR(
"mxc_read_data : read data failed : '%x'",
296 try_data_output_from_nand_chip);
297 return try_data_output_from_nand_chip;
310 LOG_ERROR(
"write_data() not implemented");
319 int validate_target_result;
321 if (validate_target_result !=
ERROR_OK)
322 return validate_target_result;
331 int validate_target_result;
337 if (validate_target_result !=
ERROR_OK)
338 return validate_target_result;
403 int validate_target_result;
409 if (validate_target_result !=
ERROR_OK)
410 return validate_target_result;
428 uint16_t poll_complete_status;
429 int validate_target_result;
435 if (validate_target_result !=
ERROR_OK)
436 return validate_target_result;
444 }
while (tout-- > 0);
449 uint8_t *data, uint32_t data_size,
450 uint8_t *oob, uint32_t oob_size)
455 uint16_t nand_status_content;
456 uint16_t swap1, swap2, new_swap1;
497 LOG_DEBUG(
"part of spare block will be overridden "
498 "by hardware ECC generator");
504 while (oob_size > 0) {
518 LOG_ERROR(
"Due to NFC Bug, oob is not correctly implemented in mxc driver");
522 new_swap1 = (swap1 & 0xFF00) | (swap2 >> 8);
523 swap2 = (swap1 << 8) | (swap2 & 0xFF);
539 for (uint8_t i = 0; i < bufs; ++i) {
565 if (nand_status_content & 0x0001) {
571 #ifdef _MXC_PRINT_STAT
572 LOG_INFO(
"%d bytes newly written", data_size);
578 uint8_t *data, uint32_t data_size,
579 uint8_t *oob, uint32_t oob_size)
585 uint16_t swap1, swap2, new_swap1;
630 for (uint8_t i = 0; i < bufs; ++i) {
635 LOG_ERROR(
"MXC_NF : Error reading page %d", i);
641 uint32_t spare_buffer3;
649 new_swap1 = (swap1 & 0xFF00) | (swap2 >> 8);
650 swap2 = (swap1 << 8) | (swap2 & 0xFF);
662 while (oob_size > 0) {
672 #ifdef _MXC_PRINT_STAT
677 LOG_INFO(
"%d bytes newly read", data_size);
699 uint16_t work_mode = 0;
709 LOG_DEBUG(
"MXC_NF : work in Big Endian mode");
712 LOG_DEBUG(
"MXC_NF : work in Little Endian mode");
714 LOG_DEBUG(
"MXC_NF : work with ECC mode");
717 LOG_DEBUG(
"MXC_NF : work without ECC mode");
733 if ((temp & 0x0007) == 1) {
734 LOG_ERROR(
"NAND flash is tight-locked, reset needed");
772 static uint8_t even_byte;
796 *value = temp & 0xff;
859 switch (ecc_status & 0x000c) {
861 LOG_INFO(
"main area read with 1 (correctable) error");
864 LOG_INFO(
"main area read with more than 1 (incorrectable) error");
867 switch (ecc_status & 0x0003) {
869 LOG_INFO(
"spare area read with 1 (correctable) error");
872 LOG_INFO(
"main area read with more than 1 (incorrectable) error");
890 err = ecc_status & 0xF;
892 LOG_INFO(
"UnCorrectable RS-ECC Error");
895 LOG_INFO(
"%d Symbol Correctable RS-ECC Error", err);
897 }
while (--no_subpages);
906 switch (mxc_nf_info->
fin) {
938 .nand_device_command = &mxc_nand_device_command,
void command_print(struct command_invocation *cmd, const char *format,...)
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
#define ERROR_COMMAND_ARGUMENT_INVALID
void alive_sleep(uint64_t ms)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
static int get_next_byte_from_sram_buffer(struct nand_device *nand, uint8_t *value)
static int mxc_write_page(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
static int poll_for_complete_op(struct nand_device *nand, const char *text)
static int mxc_nand_ready(struct nand_device *nand, int tout)
static int ecc_status_v2(struct nand_device *nand)
static int get_next_halfword_from_sram_buffer(struct nand_device *nand, uint16_t *value)
static uint32_t in_sram_address
static int mxc_read_data(struct nand_device *nand, void *data)
static uint32_t align_address_v2(struct nand_device *nand, uint32_t addr)
static unsigned char sign_of_sequental_byte_read
NAND_DEVICE_COMMAND_HANDLER(mxc_nand_device_command)
static const struct command_registration mxc_sub_command_handlers[]
struct nand_flash_controller mxc_nand_flash_controller
static int ecc_status_v1(struct nand_device *nand)
static int validate_target_state(struct nand_device *nand)
static int mxc_reset(struct nand_device *nand)
static const char sram_buffer_bounds_err_msg[]
static const char data_block_size_err_msg[]
static int mxc_command(struct nand_device *nand, uint8_t command)
static int do_data_output(struct nand_device *nand)
static const char target_not_halted_err_msg[]
static int mxc_write_data(struct nand_device *nand, uint16_t data)
static const struct command_registration mxc_nand_command_handler[]
static int mxc_read_page(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
static int mxc_init(struct nand_device *nand)
COMMAND_HANDLER(handle_mxc_biswap_command)
static int mxc_address(struct nand_device *nand, uint8_t address)
static const char get_status_register_err_msg[]
static int initialize_nf_controller(struct nand_device *nand)
#define MXC_NF_BIT_ECC_4BIT
#define MXC_NF_V1_SPARE_BUFFER3
#define MXC_NF_BIT_OP_FCI
#define MXC_NF_SPARE_BUFFER_MAX
#define MXC_NF_BIT_OP_FDI
#define MXC_NF_V2_UNLOCKEND3
#define MX25_RCSR_NF_16BIT_SEL
#define MXC_NF_V2_UNLOCKEND1
#define MXC_NF_MAIN_BUFFER3
#define MXC_NF_V2_UNLOCKEND2
#define MXC_NF_SPARE_BUFFER_LEN
#define MXC_NF_BIT_INT_DIS
#define MX2_FMCR_NF_16BIT_SEL
#define MXC_NF_BIT_OP_DONE
#define MXC_NF_BIT_ECC_EN
#define MXC_NF_V1_UNLOCKSTART
#define MX35_RCSR_NF_16BIT_SEL
#define MXC_NF_V2_UNLOCKSTART3
#define MXC_NF_V1_SPARE_BUFFER0
#define MXC_NF_V2_UNLOCKSTART1
#define MXC_NF_BIT_RESET_EN
#define MXC_NF_V2_UNLOCKSTART2
@ MXC_NF_DATAOUT_NANDSTATUS
#define MXC_NF_V2_SPARE_BUFFER0
#define MXC_NF_V1_UNLOCKEND
#define MXC_NF_MAIN_BUFFER0
#define MXC_NF_V2_SPARE_BUFFER3
#define MX3_PCSR_NF_16BIT_SEL
#define MXC_NF_BIT_OP_FAI
#define MXC_NF_V2_UNLOCKEND0
#define MXC_NF_V2_UNLOCKSTART0
#define MXC_NF_V2_LAST_BUFFADDR
#define MXC_NF_V2_CFG1_PPB(x)
#define MXC_NF_BIT_DATAOUT_TYPE(x)
#define MXC_NF_V1_LAST_BUFFADDR
#define ERROR_NAND_OPERATION_FAILED
target_addr_t addr
Start address to search for the control block.
const char * usage
a string listing the options and arguments, required or optional
enum mxc_version mxc_version
struct mxc_nf_flags flags
enum mxc_nf_finalize_action fin
enum mxc_dataout_type optype
unsigned int target_little_endian
unsigned int nand_readonly
unsigned int hw_ecc_enabled
unsigned int biswap_enabled
Interface for NAND flash controllers.
const char * name
Driver name that is used to select it from configuration files.
enum target_endianness endianness
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
int target_write_u16(struct target *target, target_addr_t address, uint16_t value)
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
int target_read_u16(struct target *target, target_addr_t address, uint16_t *value)
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)