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

add ondie and software ECC code to SPI NAND block device driver #15242

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "drivers/QSPI.h"
#include "blockdevice/BlockDevice.h"
#include "platform/Callback.h"
#include "bch.h"

#ifndef MBED_CONF_SPINAND_QSPI_IO0
#define MBED_CONF_SPINAND_QSPI_IO0 NC
Expand Down Expand Up @@ -237,6 +238,10 @@ class SPINANDBlockDevice : public mbed::BlockDevice {
*/
virtual const char *get_type() const;

virtual bool is_bad_block(uint16_t blk_idx);

virtual int mark_bad_block(uint16_t blk_idx);

private:
/********************************/
/* Different Device Csel Mgmt */
Expand All @@ -258,6 +263,9 @@ class SPINANDBlockDevice : public mbed::BlockDevice {
// Send Read command to Driver
qspi_status_t _qspi_send_read_command(mbed::qspi_inst_t read_instruction, void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size);

// Send Continuous Read command to Driver
qspi_status_t _qspi_send_continuous_read_command(mbed::qspi_inst_t read_instruction, void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size);

// Send Erase Instruction using command_transfer command to Driver
qspi_status_t _qspi_send_erase_command(mbed::qspi_inst_t erase_instruction, mbed::bd_addr_t addr, mbed::bd_size_t size);

Expand All @@ -272,6 +280,13 @@ class SPINANDBlockDevice : public mbed::BlockDevice {
/* Flash Configuration Functions */
/*********************************/

// Read OTP ONFI parameters
bool _read_otp_onfi();

int _read_oob(void *buffer, bd_addr_t addr, bd_size_t size);

int _program_oob(const void *buffer, bd_addr_t addr, bd_size_t size);

// Quad Enable in Security Register
int _set_quad_enable();

Expand All @@ -281,9 +296,19 @@ class SPINANDBlockDevice : public mbed::BlockDevice {
// Configure Write Enable in Status Register
int _set_write_enable();

int _set_conti_read_enable();

int _set_conti_read_disable();

int _conti_read_exit();

// Wait on status register until write not-in-progress
bool _is_mem_ready();

void _bch_init(uint8_t ecc_bits);
void _bch_free();
int _bch_calculate_ecc(unsigned char *buf, unsigned char *code);
int _bch_correct_data(unsigned char *buf, unsigned char *read_ecc, unsigned char *calc_ecc);
private:

// QSPI Driver Object
Expand Down Expand Up @@ -320,6 +345,23 @@ class SPINANDBlockDevice : public mbed::BlockDevice {

uint32_t _init_ref_count;
bool _is_initialized;
char _name[32];
uint32_t _page_size, _block_size, _flash_size;
uint8_t _page_shift, _block_shift;
uint16_t _block_num, _page_num, _oob_size;
uint8_t _ecc_bits, _ecc_bytes, _ecc_steps, _ecc_layout_pos;
uint32_t _ecc_size;
uint8_t *_ecc_calc;
uint8_t *_ecc_code;
uint8_t *_page_buf;
uint8_t _continuous_read;

struct nand_bch_control {
struct bch_code *bch;
unsigned int *errloc;
unsigned char *eccmask;
};
struct nand_bch_control _nbc;
};

#endif
43 changes: 43 additions & 0 deletions storage/blockdevice/COMPONENT_SPINAND/include/SPINAND/bch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2022 Macronix International Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef _BCH_H
#define _BCH_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>

#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))

struct bch_code {
unsigned int m;
unsigned int n;
unsigned int t;
unsigned int ecc_bits;
unsigned int ecc_words;
unsigned int len;
unsigned int *a_pow;
unsigned int *a_log;
unsigned int *mod_tab;
unsigned int *ecc;
unsigned int *syn;
unsigned int *elp;
unsigned int *buf;
unsigned int *buf2;
unsigned char *input_data;
unsigned int endian;
};

struct bch_code *bch_init(unsigned int m, unsigned int t);
void bch_free(struct bch_code *bch);
void bch_encode(struct bch_code *bch, unsigned char *data, unsigned int *ecc);
int bch_decode(struct bch_code *bch, unsigned char *data, unsigned int *ecc);
int fls(int x);

#ifdef __cplusplus
}
#endif
#endif
Loading