blob: 97cc33448af5ddaa1312081ab2bc41d7a88b96c1 [file] [log] [blame]
#ifndef __AML_SLCNAND_H_
#define __AML_SLCNAND_H_
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/nand_ecc.h>
#include <nand.h>
#include <amlogic/aml_nand.h>
#include "aml_hwctrl.h"
#include <partition_table.h>
#include <linux/mtd/partitions.h>
#include <amlogic/aml_rsv.h>
#include <amlogic/aml_mtd.h>
#define NAND_MAX_DEVICE 4
#define CONFIG_MTD_PARTITIONS 1
/*MAX page list cnt for usrdef mode*/
#define NAND_PAGELIST_CNT 16
/*nand read retry info,max equal to zero,
*that means no need retry*/
struct nand_retry_t {
unsigned id;
unsigned max;
unsigned no_rb;
};
typedef struct _nand_cmd {
unsigned char type;
unsigned char val;
}nand_cmd_t;
struct meson_slcnand_platdata {
u32 reg_base;
u8 nand_user_mode;
u8 nand_ran_mode;
};
/**must same with arch/arm/include/asm/nand.h
*ext bits:
* bit 26: pagelist enable flag,
* bit 24: a2 cmd enable flag,
* bit 23: no_rb,
* bit 22: large. large for what?
* bit 19: randomizer mode.
* bit 14-16: ecc mode
* bit 13: short mode
* bit 6-12: short page size
* bit 0-5: ecc pages.
***/
typedef struct nand_setup {
union {
uint32_t d32;
struct {
unsigned cmd:22;
unsigned large_page:1; //22
unsigned no_rb:1; //23 from efuse
unsigned a2:1; //24
unsigned reserved25:1; //25
unsigned page_list:1; //26
unsigned sync_mode:2; //27 from efuse
unsigned size:2; //29 from efuse
unsigned active:1; //31
}b;
}cfg;
uint16_t id;
uint16_t max; //id:0x100 user,max:0 disable.
} nand_setup_t;
typedef struct _ext_info{
uint32_t read_info; //nand_read_info;
uint32_t new_type; //new_nand_type;
uint32_t page_per_blk; //pages_in_block;
uint32_t xlc; //slc=1,mlc=2,tlc=3;
uint32_t ce_mask;
/*copact mode: boot means whole uboot
it's easy to understand that copies off_type
bl2 and fip are the same.
* discrete mode,boot means the fip only*/
uint32_t boot_num;
uint32_t each_boot_pages;
/*for comptible reason*/
uint32_t bbt_occupy_pages;
uint32_t bbt_start_block;
} ext_info_t;
#define NAND_FIPMODE_COMPACT (0)
#define NAND_FIPMODE_DISCRETE (1)
/* if you don't need skip the bad blocks when address
* partitions,please enable this macro.
* #define CONFIG_NOT_SKIP_BAD_BLOCK
*/
typedef struct _fip_info {
uint16_t version; //version
uint16_t mode; //compact or discrete
uint32_t fip_start; //fip start,pages
}fip_info_t;
typedef struct _nand_page0 {
nand_setup_t nand_setup; //8
unsigned char page_list[16]; //16
nand_cmd_t retry_usr[32]; //64(32 cmd max I/F)
ext_info_t ext_info; //72
/*added for slc nand in mtd drivers 20170503*/
fip_info_t fip_info;
}nand_page0_t; //384 byte max.
typedef union nand_core_clk {
/*raw register data*/
uint32_t d32;
struct {
unsigned clk_div:7;
unsigned reserved0:1;
unsigned clk_en:1;
unsigned clk_sel:3;
unsigned not_used:20;
}b;
}nand_core_clk_t;
/***************ERROR CODING*******************/
#define NAND_CHIP_ID_ERR 1
#define NAND_SHIP_BAD_BLOCK_ERR 2
#define NAND_CHIP_REVB_HY_ERR 3
/** Register defination **/
#define NAND_BOOT_NAME "bootloader"
#define NAND_NORMAL_NAME "nandnormal"
#define NAND_RESERVED_NAME "nandreserved"
#define BOOT_PAGES_PER_COPY (1024)
#define BOOT_COPY_NUM (BOOT_TOTAL_PAGES/BOOT_PAGES_PER_COPY)
#define AML_CHIP_NONE_RB 4
#define AML_INTERLEAVING_MODE 8
#define AML_NAND_CE0 0xe
#define AML_NAND_CE1 0xd
#define AML_NAND_CE2 0xb
#define AML_NAND_CE3 0x7
#define AML_BADBLK_POS 0
#define NAND_ECC_OPTIONS_MASK 0x0000000f
#define NAND_PLANE_OPTIONS_MASK 0x000000f0
#define NAND_TIMING_OPTIONS_MASK 0x00000f00
#define NAND_BUSW_OPTIONS_MASK 0x0000f000
#define NAND_INTERLEAVING_OPTIONS_MASK 0x000f0000
#define NAND_TWO_PLANE_MODE 0x00000010
#define NAND_TIMING_MODE0 0x00000000
#define NAND_TIMING_MODE1 0x00000100
#define NAND_TIMING_MODE2 0x00000200
#define NAND_TIMING_MODE3 0x00000300
#define NAND_TIMING_MODE4 0x00000400
#define NAND_TIMING_MODE5 0x00000500
#define NAND_INTERLEAVING_MODE 0x00010000
#define DEFAULT_T_REA 40
#define DEFAULT_T_RHOH 0
#define NAND_DEFAULT_OPTIONS (NAND_TIMING_MODE5 | NAND_ECC_BCH8_MODE)
#define AML_NAND_BUSY_TIMEOUT 0x40000
#define AML_DMA_BUSY_TIMEOUT 0x100000
#define MAX_ID_LEN 8
#define NAND_CMD_PLANE2_READ_START 0x06
#define NAND_CMD_TWOPLANE_PREVIOS_READ 0x60
#define NAND_CMD_TWOPLANE_READ1 0x5a
#define NAND_CMD_TWOPLANE_READ2 0xa5
#define NAND_CMD_TWOPLANE_WRITE2_MICRO 0x80
#define NAND_CMD_TWOPLANE_WRITE2 0x81
#define NAND_CMD_DUMMY_PROGRAM 0x11
#define NAND_CMD_ERASE1_END 0xd1
#define NAND_CMD_MULTI_CHIP_STATUS 0x78
#define ONFI_TIMING_ADDR 0x01
#define NAND_STATUS_READY_MULTI 0x20
#define NAND_BLOCK_GOOD 0
#define NAND_BLOCK_BAD 1
#define NAND_FACTORY_BAD 2
#define BAD_BLK_LEVEL 2
#define FACTORY_BAD_BLOCK_ERROR 159
#define MINI_PART_SIZE 0x100000
#define NAND_MINI_PART_NUM 4
#define MAX_BAD_BLK_NUM 2000
#define MAX_MTD_PART_NUM 16
#define MAX_MTD_PART_NAME_LEN 24
#define NAND_SYS_PART_SIZE 0x8000000
struct aml_nand_flash_dev {
char *name;
u8 id[MAX_ID_LEN];
unsigned pagesize;
unsigned chipsize;
unsigned erasesize;
unsigned oobsize;
unsigned internal_chipnr;
unsigned T_REA;
unsigned T_RHOH;
u8 onfi_mode;
unsigned options;
};
struct aml_nand_part_info {
char mtd_part_magic[4];
char mtd_part_name[MAX_MTD_PART_NAME_LEN];
uint64_t size;
uint64_t offset;
u_int32_t mask_flags;
};
struct aml_nand_bch_desc {
char * name;
unsigned bch_mode;
unsigned bch_unit_size;
unsigned bch_bytes;
unsigned user_byte_mode;
};
struct aml_nand_chip {
struct nand_chip chip;
struct hw_controller *controller;
/* mtd info */
u8 mfr_type;
unsigned onfi_mode;
unsigned T_REA;
unsigned T_RHOH;
unsigned options;
unsigned page_size;
unsigned block_size;
unsigned oob_size;
unsigned virtual_page_size;
unsigned virtual_block_size;
u8 plane_num;
u8 internal_chipnr;
unsigned internal_page_nums;
unsigned internal_chip_shift;
unsigned int ran_mode;
unsigned int rbpin_mode;
unsigned int rbpin_detect;
unsigned int short_pgsz;
/* bch for infopage on short mode */
unsigned int bch_info;
unsigned bch_mode;
u8 user_byte_mode;
u8 ops_mode;
u8 cached_prog_status;
u8 max_bch_mode;
unsigned valid_chip[MAX_CHIP_NUM];
unsigned page_addr;
unsigned char *aml_nand_data_buf;
unsigned int *user_info_buf;
int8_t *block_status;
unsigned int toggle_mode;
u8 ecc_cnt_limit;
u8 ecc_cnt_cur;
u8 ecc_max;
unsigned zero_cnt;
unsigned oob_fill_cnt;
unsigned boot_oob_fill_cnt;
/*add property field for key private data*/
int dtbsize;
int keysize;
uint32_t boot_copy_num; /*tell how many bootloader copies*/
u8 key_protect;
unsigned char *rsv_data_buf;
struct meson_rsv_handler_t *rsv;
struct aml_nand_bch_desc *bch_desc;
/* platform info */
struct aml_nand_platform *platform;
/* device info */
struct device *device;
unsigned max_ecc;
struct ecc_desc_s * ecc;
// unsigned onfi_mode;
unsigned err_sts;
/* plateform operation function*/
void (*aml_nand_hw_init)(struct aml_nand_chip *aml_chip);
void (*aml_nand_adjust_timing)(struct aml_nand_chip *aml_chip);
int (*aml_nand_options_confirm)(struct aml_nand_chip *aml_chip);
void (*aml_nand_cmd_ctrl)(struct aml_nand_chip *aml_chip,
int cmd, unsigned int ctrl);
void (*aml_nand_select_chip)(struct aml_nand_chip *aml_chip,
int chipnr);
void (*aml_nand_write_byte)(struct aml_nand_chip *aml_chip,
uint8_t data);
void (*aml_nand_get_user_byte)(struct aml_nand_chip *aml_chip,
unsigned char *oob_buf, int byte_num);
void (*aml_nand_set_user_byte)(struct aml_nand_chip *aml_chip,
unsigned char *oob_buf, int byte_num);
void (*aml_nand_command)(struct aml_nand_chip *aml_chip,
unsigned command, int column, int page_addr, int chipnr);
int (*aml_nand_wait_devready)(struct aml_nand_chip *aml_chip,
int chipnr);
int (*aml_nand_dma_read)(struct aml_nand_chip *aml_chip,
unsigned char *buf, int len, unsigned bch_mode);
int (*aml_nand_dma_write)(struct aml_nand_chip *aml_chip,
unsigned char *buf, int len, unsigned bch_mode);
int (*aml_nand_hwecc_correct)(struct aml_nand_chip *aml_chip,
unsigned char *buf, unsigned size, unsigned char *oob_buf);
int (*aml_nand_block_bad_scrub)(struct mtd_info *mtd);
};
struct aml_nand_platform {
struct aml_nand_flash_dev *nand_flash_dev;
char *name;
unsigned chip_enable_pad;
unsigned ready_busy_pad;
/* DMA RD/WR delay loop timing */
unsigned int T_REA; /* for dma wating delay */
/* not equal of (nandchip->delay, which is for dev ready func)*/
unsigned int T_RHOH;
unsigned int ran_mode; /*def close, for all part*/
unsigned int rbpin_mode; /*may get from romboot*/
unsigned int rbpin_detect;
unsigned int short_pgsz; /*zero means no short*/
struct aml_nand_chip *aml_chip;
struct platform_nand_data platform_nand_data;
};
struct aml_nand_device {
struct aml_nand_platform *aml_nand_platform;
u8 dev_num;
};
static inline struct aml_nand_chip *mtd_to_nand_chip(struct mtd_info *mtd)
{
struct nand_chip *chip = mtd->priv;
return container_of(chip, struct aml_nand_chip, chip);
}
#ifdef CONFIG_PARAMETER_PAGE
struct parameter_page {
/*0~31 byte: Revision information and features block*/
unsigned char signature[4];
unsigned short ver;
unsigned short feature;
unsigned short opt_commd;
unsigned short reserve0;
unsigned short ex_para_page_len;
unsigned char num_para_page;
unsigned char reserve1[17];
/*32~79 byte: Manufacturer information block*/
unsigned char dev_manu[12];
unsigned char dev_model[20];
unsigned char JEDEC_manu_ID;
unsigned short date_code;
unsigned char reserve2[13];
/*80~127 byte: Memory organization block*/
unsigned int data_bytes_perpage;
unsigned short spare_bytes_perpage;
unsigned int data_bytes_perpartial;
unsigned short spare_bytes_perpartial;
unsigned int pages_perblk;
unsigned int blks_perLUN;
unsigned char num_LUN;
/* 4-7: column addr cycles; 0-3: row addr cycles*/
unsigned char num_addr_cycle;
unsigned char bits_percell;
unsigned short max_badblk_perLUN;
unsigned short blk_edurce;
/*Guaranteed valid blocks at beginning of target*/
unsigned char g_v_blk_begin;
unsigned short blk_edurce_g_v_blk;
unsigned char progm_perpage;
unsigned char prt_prog_att;//obsolete
unsigned char bits_ECC_corretable;
/*0-3: number of interleaved address bits*/
unsigned char bits_intleav_addr;
/*6-7 Reserved (0)
5 1 = lower bit XNOR block address restriction
4 1 = read cache supported
3 Address restrictions for cache operations
2 1 = program cache supported
1 1 = no block address restrictions
0 Overlapped / concurrent interleaving support
*/
unsigned char intleav_op_attr;
unsigned char reserve3[13];
/*128~163 byte: Electrical parameters block*/
unsigned char max_io_pin;
/*6-15 Reserved (0)
5 1 = supports timing mode 5
4 1 = supports timing mode 4
3 1 = supports timing mode 3
2 1 = supports timing mode 2
1 1 = supports timing mode 1
0 1 = supports timing mode 0, shall be 1
*/
unsigned short asy_time_mode;
unsigned short asy_prog_cach_time_mode; /*obsolete*/
unsigned short Tprog; /*Maximum page program time (Ts)*/
unsigned short Tbers; /*Maximum block erase time (Ts)*/
unsigned short Tr; /*Maximum page read time (Ts)*/
unsigned short Tccs; /*Minimum change column setup time (ns)*/
/* 6-15 Reserved (0)
5 1 = supports timing mode 5
4 1 = supports timing mode 4
3 1 = supports timing mode 3
2 1 = supports timing mode 2
1 1 = supports timing mode 1
0 1 = supports timing mode 0
*/
unsigned short src_syn_time_mode;
/*3-7 Reserved (0)
2 1 = device supports CLK stopped for data input
1 1 = typical capacitance values present
0 tCAD value to use
*/
unsigned char src_syn_feature;
unsigned short CLK_input_pin;
unsigned short IO_pin;
unsigned short input_pin;
unsigned char max_input_pin;
unsigned char dr_strgth;
/*Maximum interleaved page read time (Ts)*/
unsigned short Tir;
/*Program page register clear enhancement tADL value (ns)*/
unsigned short Tadl;
unsigned char reserve4[8];
/*164~255 byte: Vendor block*/
unsigned short vd_ver;
unsigned char vd_spec[88];
unsigned short int_CRC;
/*256~ byte: Redundant Parameter Pages*/
}__attribute__ ((__packed__));
#endif
int aml_nand_init(struct aml_nand_chip *aml_chip);
int aml_nand_read_page_raw(struct mtd_info *mtd,
struct nand_chip *chip, uint8_t *buf, int oob_required, int page);
int aml_nand_write_page_raw(struct mtd_info *mtd,
struct nand_chip *chip, const uint8_t *buf, int oob_required,
int page);
int aml_nand_read_page_hwecc(struct mtd_info *mtd,
struct nand_chip *chip, uint8_t *buf, int oob_required, int page);
int aml_nand_write_page_hwecc(struct mtd_info *mtd,
struct nand_chip *chip, const uint8_t *buf, int oob_required,
int page);
int aml_nand_read_oob(struct mtd_info *mtd,
struct nand_chip *chip, int page);
int aml_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip, int page);
int aml_nand_block_bad(struct mtd_info *mtd, loff_t ofs);
int aml_nand_block_markbad(struct mtd_info *mtd, loff_t ofs);
void aml_nand_dma_read_buf(struct mtd_info *mtd, uint8_t *buf, int len);
void aml_nand_dma_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
void aml_platform_cmd_ctrl(struct aml_nand_chip *aml_chip,
int cmd, unsigned int ctrl);
void aml_platform_write_byte(struct aml_nand_chip *aml_chip, uint8_t data);
int aml_platform_wait_devready(struct aml_nand_chip *aml_chip, int chipnr);
void aml_platform_get_user_byte(struct aml_nand_chip *aml_chip,
unsigned char *oob_buf, int byte_num);
void aml_platform_set_user_byte(struct aml_nand_chip *aml_chip,
unsigned char *oob_buf, int byte_num);
void aml_nand_base_command(struct aml_nand_chip *aml_chip,
unsigned command, int column, int page_addr, int chipnr);
int aml_nand_block_bad_scrub_update_bbt(struct mtd_info *mtd);
int aml_ubootenv_init(struct aml_nand_chip *aml_chip);
int amlnf_dtb_init(struct aml_nand_chip *aml_chip);
int aml_key_init(struct aml_nand_chip *aml_chip);
int aml_nand_erase_key(struct mtd_info *mtd);
int aml_nand_bbt_check(struct mtd_info *mtd);/*fixed by liuxj*/
int aml_nand_scan(struct mtd_info *mtd, int maxchips);
int aml_nand_write_page_raw(struct mtd_info *mtd,
struct nand_chip *chip, const uint8_t *buf, int oob_required,
int page);
int aml_nand_write_page(struct mtd_info *mtd,
struct nand_chip *chip, uint32_t offset,
int data_len,
const uint8_t *buf,
int oob_required, int page, int raw);
void aml_nand_base_command(struct aml_nand_chip *aml_chip,
unsigned command, int column, int page_addr, int chipnr);
void aml_nand_command(struct mtd_info *mtd,
unsigned command, int column, int page_addr);
int aml_nand_wait(struct mtd_info *mtd, struct nand_chip *chip);
int aml_nand_erase_cmd(struct mtd_info *mtd, int page);
int m3_nand_boot_erase_cmd(struct mtd_info *mtd, int page);
int m3_nand_boot_read_page_hwecc(struct mtd_info *mtd,
struct nand_chip *chip, uint8_t *buf, int oob_required, int page);
int m3_nand_boot_write_page_hwecc(struct mtd_info *mtd,
struct nand_chip *chip, const uint8_t *buf, int oob_required,
int page);
int m3_nand_boot_write_page(struct mtd_info *mtd, struct nand_chip *chip,
uint32_t offset, int data_len, const uint8_t *buf,
int oob_required, int page, int raw);
int aml_nand_get_fbb_issue(void);
void aml_nand_check_fbb_issue(u8 *dev_id);
#endif