nand: update config for mtd driver

PD#142470: update nand config for mtd
1. update dts of skt&s400
2. update clock reg
3. update regbase
4. update bchmode for infopage
5. mtd: support desctrete uboot layout for slc
   change uboot layout for slc [3/3]

multi bootloaders were stored in mlc/slc/emmc.

For emmc/mlc, there's enough space at the begining.
bl2&fip can be stored together which we may call it
as compact mode.
    |bl2|fip|bl2|fip|bl2|fip|rsv|normal|

But for slc, space is restricted by romboot. bl2 and
fip had to be stored discretely.
    |bl2|bl2|bl2|bl2|rsv|fip|fip|fip|fip|normal|

If kernle want mtd driver use descrete mode.
1. bl_mode in dts should be set as 1.
2. fip_copies and fip_size should be the same as uboot which
   was described by marco CONFIG_TPL_COPY_NUM&CONFIG_TPL_SIZE_PER_COPY.
3. And the tpl partition should be added in mtd partition table whose
    offset and size are negligible.

when using, mtd0 is for bl2, mtd1 is for tpl(fip)

Change-Id: I0ed07168ba7497d674a7160f7966ebb484a123d5
Signed-off-by: Yonghui Yu <yonghui.yu@amlogic.com>
This commit is contained in:
Yonghui Yu
2017-05-15 11:49:39 +08:00
committed by Yun Cai
parent e95ed5b571
commit 6dc75c7438
15 changed files with 1617 additions and 536 deletions

View File

@@ -13615,6 +13615,8 @@ F: include/linux/mmc/host.h
AMLOGIC MTD DRIVER
M: Liang Yang <liang.yang@amlogic.com>
F: drivers/amlogic/mtd/
M: Yonghui Yu <yonghui.yu@amlogic.com>
F: drivers/amlogic/mtd/boot.c
AMLOGIC GPU DEVICETREE
M: Jiyu Yang <jiyu.yang@amlogic.com>

View File

@@ -56,7 +56,93 @@
};
};
mtd_nand {
compatible = "amlogic, aml_mtd_nand";
dev_name = "mtdnand";
status = "okay";
reg = <0x0 0xFFE07800 0x0 0x200>;
interrupts = < 0 34 1 >;
pinctrl-names = "nand_rb_mod","nand_norb_mod", "nand_cs_only";
pinctrl-0 = <&all_nand_pins>;
pinctrl-1 = <&all_nand_pins>;
pinctrl-2 = <&nand_cs_pins>;
device_id = <0>;
/*fip/tpl configurations, must be same
* with uboot if bl_mode was set as 1
* bl_mode: 0 compact mode; 1 descrete mode
* if bl_mode was set as 1, fip configeration will work
*/
bl_mode = <1>;
/*copy count of fip*/
fip_copies = <4>;
/*size of each fip copy */
fip_size = <0x200000>;
nand_clk_ctrl = <0xFFE07000>;
plat-names = "bootloader","nandnormal";
plat-num = <2>;
plat-part-0 = <&bootloader>;
plat-part-1 = <&nandnormal>;
bootloader: bootloader{
enable_pad ="ce0";
busy_pad = "rb0";
timming_mode = "mode5";
bch_mode = "bch8_1k";
t_rea = <20>;
t_rhoh = <15>;
chip_num = <1>;
part_num = <0>;
rb_detect = <1>;
};
nandnormal: nandnormal{
enable_pad ="ce0";
busy_pad = "rb0";
timming_mode = "mode5";
bch_mode = "bch8_1k";
plane_mode = "twoplane";
t_rea = <20>;
t_rhoh = <15>;
chip_num = <2>;
part_num = <3>;
partition = <&nand_partitions>;
rb_detect = <1>;
};
nand_partitions:nand_partition{
/*
* if bl_mode is 1, tpl size was generate by
* fip_copies * fip_size which
* will not skip bad when calculating
* the partition size;
*
* if bl_mode is 0,
* tpl partition must be comment out.
*/
tpl{
offset=<0x0 0x0>;
size=<0x0 0x0>;
};
logo{
offset=<0x0 0x0>;
size=<0x0 0x200000>;
};
recovery{
offset=<0x0 0x0>;
size=<0x0 0x1000000>;
};
boot{
offset=<0x0 0x0>;
size=<0x0 0xC00000>;
};
system{
offset=<0x0 0x0>;
size=<0x0 0xDC40000>;
};
data{
offset=<0xffffffff 0xffffffff>;
size=<0x0 0x0>;
};
};
};
dwc3: dwc3@ff500000 {
compatible = "synopsys, dwc3";

View File

@@ -55,6 +55,94 @@
no-map;
};
};
mtd_nand {
compatible = "amlogic, aml_mtd_nand";
dev_name = "mtdnand";
status = "okay";
reg = <0x0 0xFFE07800 0x0 0x200>;
interrupts = < 0 34 1 >;
pinctrl-names = "nand_rb_mod","nand_norb_mod", "nand_cs_only";
pinctrl-0 = <&all_nand_pins>;
pinctrl-1 = <&all_nand_pins>;
pinctrl-2 = <&nand_cs_pins>;
device_id = <0>;
/*fip/tpl configurations, must be same
* with uboot if bl_mode was set as 1
* bl_mode: 0 compact mode; 1 descrete mode
* if bl_mode was set as 1, fip configeration will work
*/
bl_mode = <1>;
/*copy count of fip*/
fip_copies = <4>;
/*size of each fip copy */
fip_size = <0x200000>;
nand_clk_ctrl = <0xFFE07000>;
plat-names = "bootloader","nandnormal";
plat-num = <2>;
plat-part-0 = <&bootloader>;
plat-part-1 = <&nandnormal>;
bootloader: bootloader{
enable_pad ="ce0";
busy_pad = "rb0";
timming_mode = "mode5";
bch_mode = "bch8_1k";
t_rea = <20>;
t_rhoh = <15>;
chip_num = <1>;
part_num = <0>;
rb_detect = <1>;
};
nandnormal: nandnormal{
enable_pad ="ce0";
busy_pad = "rb0";
timming_mode = "mode5";
bch_mode = "bch8_1k";
plane_mode = "twoplane";
t_rea = <20>;
t_rhoh = <15>;
chip_num = <2>;
part_num = <3>;
partition = <&nand_partitions>;
rb_detect = <1>;
};
nand_partitions:nand_partition{
/*
* if bl_mode is 1, tpl size was generate by
* fip_copies * fip_size which
* will not skip bad when calculating
* the partition size;
*
* if bl_mode is 0,
* tpl partition must be comment out.
*/
tpl{
offset=<0x0 0x0>;
size=<0x0 0x0>;
};
logo{
offset=<0x0 0x0>;
size=<0x0 0x200000>;
};
recovery{
offset=<0x0 0x0>;
size=<0x0 0x1000000>;
};
boot{
offset=<0x0 0x0>;
size=<0x0 0xC00000>;
};
system{
offset=<0x0 0x0>;
size=<0x0 0xDC40000>;
};
data{
offset=<0xffffffff 0xffffffff>;
size=<0x0 0x0>;
};
};
};
dwc3: dwc3@ff500000 {
compatible = "synopsys, dwc3";

View File

@@ -56,6 +56,94 @@
};
};
mtd_nand {
compatible = "amlogic, aml_mtd_nand";
dev_name = "mtdnand";
status = "okay";
reg = <0x0 0xFFE07800 0x0 0x200>;
interrupts = < 0 34 1 >;
pinctrl-names = "nand_rb_mod","nand_norb_mod", "nand_cs_only";
pinctrl-0 = <&all_nand_pins>;
pinctrl-1 = <&all_nand_pins>;
pinctrl-2 = <&nand_cs_pins>;
device_id = <0>;
/*fip/tpl configurations, must be same
* with uboot if bl_mode was set as 1
* bl_mode: 0 compact mode; 1 descrete mode
* if bl_mode was set as 1, fip configeration will work
*/
bl_mode = <1>;
/*copy count of fip*/
fip_copies = <4>;
/*size of each fip copy */
fip_size = <0x200000>;
nand_clk_ctrl = <0xFFE07000>;
plat-names = "bootloader","nandnormal";
plat-num = <2>;
plat-part-0 = <&bootloader>;
plat-part-1 = <&nandnormal>;
bootloader: bootloader{
enable_pad ="ce0";
busy_pad = "rb0";
timming_mode = "mode5";
bch_mode = "bch8_1k";
t_rea = <20>;
t_rhoh = <15>;
chip_num = <1>;
part_num = <0>;
rb_detect = <1>;
};
nandnormal: nandnormal{
enable_pad ="ce0";
busy_pad = "rb0";
timming_mode = "mode5";
bch_mode = "bch8_1k";
plane_mode = "twoplane";
t_rea = <20>;
t_rhoh = <15>;
chip_num = <2>;
part_num = <3>;
partition = <&nand_partitions>;
rb_detect = <1>;
};
nand_partitions:nand_partition{
/*
* if bl_mode is 1, tpl size was generate by
* fip_copies * fip_size which
* will not skip bad when calculating
* the partition size;
*
* if bl_mode is 0,
* tpl partition must be comment out.
*/
tpl{
offset=<0x0 0x0>;
size=<0x0 0x0>;
};
logo{
offset=<0x0 0x0>;
size=<0x0 0x200000>;
};
recovery{
offset=<0x0 0x0>;
size=<0x0 0x1000000>;
};
boot{
offset=<0x0 0x0>;
size=<0x0 0xC00000>;
};
system{
offset=<0x0 0x0>;
size=<0x0 0xDC40000>;
};
data{
offset=<0xffffffff 0xffffffff>;
size=<0x0 0x0>;
};
};
};
dwc3: dwc3@ff500000 {
compatible = "synopsys, dwc3";
status = "okay";

View File

@@ -244,6 +244,18 @@
pinctrl-1 = <&all_nand_pins>;
pinctrl-2 = <&nand_cs_pins>;
device_id = <0>;
/*fip/tpl configurations, must be same
* with uboot if bl_mode was set as 1
* bl_mode: 0 compact mode; 1 descrete mode
* if bl_mode was set as 1, fip configeration will work
*/
bl_mode = <1>;
/*copy count of fip*/
fip_copies = <4>;
/*size of each fip copy */
fip_size = <0x200000>;
nand_clk_ctrl = <0xd0074000>;
plat-names = "bootloader","nandnormal";
plat-num = <2>;
plat-part-0 = <&bootloader>;
@@ -273,6 +285,19 @@
rb_detect = <1>;
};
nand_partitions:nand_partition{
/*
* if bl_mode is 1, tpl size was generate by
* fip_copies * fip_size which
* will not skip bad when calculating
* the partition size;
*
* if bl_mode is 0,
* tpl partition must be comment out.
*/
tpl{
offset=<0x0 0x0>;
size=<0x0 0x0>;
};
logo{
offset=<0x0 0x0>;
size=<0x0 0x200000>;

View File

@@ -592,6 +592,57 @@
function = "spi_b";
};
};
nand_pulldown: nand_pulldown {
mux {
pins = "BOOT_0",
"BOOT_1",
"BOOT_2",
"BOOT_3",
"BOOT_4",
"BOOT_5",
"BOOT_6",
"BOOT_7",
"BOOT_13";
function = "nandflash";
bias-pull-down;
};
};
nand_pullup: nand_pullup {
mux {
pins = "BOOT_8";
function = "nandflash";
bias-pull-up;
};
};
all_nand_pins: all_nand_pins {
mux {
pins = "BOOT_0",
"BOOT_1",
"BOOT_2",
"BOOT_3",
"BOOT_4",
"BOOT_5",
"BOOT_6",
"BOOT_7",
"BOOT_8",
"BOOT_9",
"BOOT_10",
"BOOT_11",
"BOOT_12",
"BOOT_13";
function = "nandflash";
input-enable;
};
};
nand_cs_pins: nand_cs {
mux {
pins = "BOOT_8";
function = "nandflash";
};
};
}; /* end of pinctrl_periphs */

View File

@@ -10,4 +10,5 @@ obj-$(CONFIG_AMLOGIC_NAND) += aml_nand.o \
rsv_manage.o \
nand_flash.o \
mtd_driver.o \
new_nand.o
new_nand.o \
boot.o

View File

@@ -53,8 +53,8 @@ struct hw_controller {
void __iomem *nand_clk_reg;
u32 irq;
#ifndef AML_NAND_UBOOT
dma_addr_t data_dma_addr;
dma_addr_t info_dma_addr;
/*dma_addr_t data_dma_addr;*/
/*dma_addr_t info_dma_addr;*/
struct pinctrl *nand_pinctrl;
struct pinctrl_state *nand_pinstate;
struct pinctrl_state *nand_rbstate;
@@ -92,7 +92,9 @@ struct hw_controller {
#endif /* 0 */
/* gx, for pxp and ic. */
#define SD_EMMC_BASE_C (0xd0074000)
//#define SD_EMMC_BASE_C (0xd0074000)
/* axg */
#define SD_EMMC_BASE_C 0xFFE07000
#define P_NAND_BASE (SD_EMMC_BASE_C | (1<<11))
#define NAND_BASE_APB (P_NAND_BASE)
#define NAND_CLK_CNTL (SD_EMMC_BASE_C)
@@ -101,9 +103,10 @@ struct hw_controller {
#define A0_GP_CFG0 (0xc8100240)
#define A0_GP_CFG2 (0xc8100248)
#define NAND_CLK_CNTL (0xd0074000)
#define SD_EMMC_BASE_C 0xFFE07000
#define NAND_CLK_CNTL (SD_EMMC_BASE_C)
#define PINMUX_BASE (0xc8834400 + (0x2c << 2))
#define P_NAND_BASE (0xd0074000 | (1<<11))
#define P_NAND_BASE (SD_EMMC_BASE_C | (1<<11))
#define NAND_BASE_APB (P_NAND_BASE)
/* NAND Write Command And Read Status Register */

View File

@@ -57,6 +57,9 @@
/*#include "partition_table.h"*/
#define CONFIG_MTD_PARTITIONS 1
#define NAND_MAX_DEVICE 4
extern struct mtd_info *nand_info[NAND_MAX_DEVICE];
extern unsigned char pagelist_hynix256[128];
#define CONFIG_ENV_SIZE (64*1024U)
/*
@@ -117,10 +120,27 @@ struct _ext_info {
uint32_t page_per_blk;
uint32_t xlc;
uint32_t ce_mask;
/* copact mode: boot means whole uboot
* it's easy to understood that copies of
* bl2 and fip are the same.
* discrete mode, boot means the fip only
*/
uint32_t boot_num;
uint32_t each_boot_pages;
uint32_t rsv[2];
/* add new below, */
/* for comptible reason */
uint32_t bbt_occupy_pages;
uint32_t bbt_start_block;
};
#define NAND_FIPMODE_COMPACT (0)
#define NAND_FIPMODE_DISCRETE (1)
struct _fip_info {
/* version */
uint16_t version;
/* compact or discrete */
uint16_t mode;
/* fip start, pages */
uint32_t fip_start;
};
/*max size is 384 bytes*/
@@ -129,6 +149,8 @@ struct _nand_page0 {
unsigned char page_list[16];
struct _nand_cmd retry_usr[32];
struct _ext_info ext_info;
/* added for slc */
struct _fip_info fip_info;
};
@@ -476,6 +498,8 @@ struct aml_nand_chip {
unsigned int rbpin_mode;
unsigned int rbpin_detect;
unsigned int short_pgsz;
/* bch for infopage on short mode */
unsigned int bch_info;
unsigned int bch_mode;
u8 user_byte_mode;
@@ -497,6 +521,10 @@ struct aml_nand_chip {
/*add property field for key private data*/
int dtbsize;
int keysize;
int boot_copy_num; /*tell how many bootloader copies*/
unsigned int bl_mode;
unsigned int fip_copies;
unsigned int fip_size;
u8 key_protect;
unsigned char *rsv_data_buf;
@@ -553,6 +581,8 @@ struct aml_nand_chip {
int (*aml_nand_block_bad_scrub)(struct mtd_info *mtd);
};
struct aml_nand_device;
struct aml_nand_platform {
struct aml_nand_flash_dev *nand_flash_dev;
char *name;
@@ -567,8 +597,9 @@ struct aml_nand_platform {
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;
/* back pointer to the device*/
struct aml_nand_device *aml_nand_device;
struct platform_nand_data platform_nand_data;
};
@@ -577,6 +608,11 @@ struct aml_nand_device {
u8 dev_num;
#ifndef AML_NAND_UBOOT
struct notifier_block nb;
u32 bl_mode;
u32 fip_copies;
u32 fip_size;
/* for mapping regsters */
u32 nand_clk_ctrl;
#endif
};
@@ -803,7 +839,20 @@ void aml_nand_command(struct mtd_info *mtd,
int aml_nand_wait(struct mtd_info *mtd, struct nand_chip *chip);
int aml_nand_erase_cmd(struct mtd_info *mtd, int page);
/* for boot operations */
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 cached, int raw);
int boot_device_register(struct aml_nand_chip *aml_chip);
int add_mtd_partitions(struct mtd_info *mtd,
const struct mtd_partition *part, int num);

View File

@@ -234,6 +234,50 @@ static struct nand_ecclayout aml_nand_oob_1664 = {
.length = 32} }
};
#endif
int nand_get_device(struct mtd_info *mtd, int new_state)
{
struct nand_chip *chip = mtd->priv;
spinlock_t *lock = &chip->controller->lock;
wait_queue_head_t *wq = &chip->controller->wq;
DECLARE_WAITQUEUE(wait, current);
retry:
spin_lock(lock);
/* Hardware controller shared among independent devices */
if (!chip->controller->active)
chip->controller->active = chip;
if (chip->controller->active == chip && chip->state == FL_READY) {
chip->state = new_state;
spin_unlock(lock);
return 0;
}
if (new_state == FL_PM_SUSPENDED) {
if (chip->controller->active->state == FL_PM_SUSPENDED) {
chip->state = FL_PM_SUSPENDED;
spin_unlock(lock);
return 0;
}
}
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(wq, &wait);
spin_unlock(lock);
schedule();
remove_wait_queue(wq, &wait);
goto retry;
}
void nand_release_device(struct mtd_info *mtd)
{
struct nand_chip *chip = mtd->priv;
/* Release the controller and the chip */
spin_lock(&chip->controller->lock);
chip->controller->active = NULL;
chip->state = FL_READY;
wake_up(&chip->controller->wq);
spin_unlock(&chip->controller->lock);
}
void aml_platform_get_user_byte(struct aml_nand_chip *aml_chip,
unsigned char *oob_buf, int byte_num)
@@ -303,6 +347,8 @@ static int aml_nand_add_partition(struct aml_nand_chip *aml_chip)
uint64_t last_size = 0, start_blk = 0;
uint64_t mini_part_size;
int reserved_part_blk_num = RESERVED_BLOCK_NUM;
uint8_t bl_mode, base_part = 0;
uint32_t fip_copies, fip_size, fip_part_size = 0;
unsigned int bad_blk_addr[128];
mini_part_size =
@@ -329,20 +375,39 @@ static int aml_nand_add_partition(struct aml_nand_chip *aml_chip)
(1024 * mtd->writesize / aml_chip->plane_num);
part_num++;
start_blk = 0;
do {
offset = adjust_offset + start_blk * mtd->erasesize;
error = mtd->_block_isbad(mtd, offset);
if (error == FACTORY_BAD_BLOCK_ERROR) {
pr_info("%s:%d factory bad addr =%llx\n",
bl_mode = aml_chip->bl_mode;
if (bl_mode == NAND_FIPMODE_COMPACT) {
/* compact bootloader mode */
do {
offset = adjust_offset +
start_blk * mtd->erasesize;
error = mtd->_block_isbad(mtd, offset);
if (error == FACTORY_BAD_BLOCK_ERROR) {
pr_info("%s:%d factory bad addr =%llx\n",
__func__, __LINE__,
(uint64_t)(offset >> phys_erase_shift));
adjust_offset += mtd->erasesize;
continue;
}
start_blk++;
} while (start_blk < reserved_part_blk_num);
adjust_offset += reserved_part_blk_num * mtd->erasesize;
adjust_offset += mtd->erasesize;
continue;
}
start_blk++;
} while (start_blk < reserved_part_blk_num);
} else {
/* descrete bootloader mode */
/* calculate fip partition by dts config*/
fip_copies = aml_chip->fip_copies;
fip_size = aml_chip->fip_size;
fip_part_size = fip_copies * fip_size;
temp_parts = parts;
/* TODO: do name check! */
temp_parts->offset = adjust_offset
+ reserved_part_blk_num * mtd->erasesize;
temp_parts->size = fip_part_size;
pr_info("%s: off %lld, size %lld\n", temp_parts->name,
temp_parts->offset, temp_parts->size);
base_part = 1;
}
adjust_offset += reserved_part_blk_num * mtd->erasesize
+fip_part_size;
/*normal mtd device divide part from here(adjust_offset)*/
if (nr == 0) {
part_save_in_env = 0;
@@ -357,7 +422,7 @@ static int aml_nand_add_partition(struct aml_nand_chip *aml_chip)
mini_part_size =
(mtd->erasesize > MINI_PART_SIZE) ? mtd->erasesize : MINI_PART_SIZE;
}
for (i = 0; i < nr; i++) {
for (i = base_part; i < nr; i++) {
temp_parts = parts + i;
bad_block_cnt = 0;
memset((u8 *)bad_blk_addr, 0xff, 128 * sizeof(int));
@@ -2311,6 +2376,7 @@ int aml_nand_init(struct aml_nand_chip *aml_chip)
struct new_tech_nand_t *new_nand_info = &aml_chip->new_nand_info;
struct aml_nand_read_retry *nand_read_retry;
struct aml_nand_slc_program *slc_program_info;
/*#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 13)*/
#if 0
struct nand_oobfree *oobfree = NULL;
@@ -2356,6 +2422,9 @@ int aml_nand_init(struct aml_nand_chip *aml_chip)
aml_chip->aml_nand_hw_init(aml_chip);
aml_chip->toggle_mode = 0;
aml_chip->bch_info = NAND_ECC_BCH60_1K;
if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG)
aml_chip->bch_info = NAND_ECC_BCH8_1K;
if (nand_scan(mtd, controller->chip_num) == 0) {
chip->options = 0;
chip->options |= NAND_SKIP_BBTSCAN;

1043
drivers/amlogic/mtd/boot.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -25,15 +25,7 @@
int nand_curr_device = -1;
struct hw_controller *controller;
/* extern void nand_release_device(struct mtd_info *mtd); */
#define NAND_MAX_DEVICE 4
struct mtd_info nand_info[NAND_MAX_DEVICE] = {
{0},
{0},
{0},
{0}
};
struct mtd_info *nand_info[NAND_MAX_DEVICE];
#ifdef CONFIG_MTD_DEVICE
static __attribute__((unused)) char dev_name[CONFIG_SYS_MAX_NAND_DEVICE][8];
@@ -271,39 +263,36 @@ static void m3_nand_select_chip(struct aml_nand_chip *aml_chip, int chipnr)
void get_sys_clk_rate_mtd(struct hw_controller *controller, int *rate)
{
int clk_freq = *rate;
unsigned int always_on = 0x1 << 24;
unsigned int clk;
#ifdef AML_NAND_UBOOT
cpu_id_t cpu_id = get_cpu_id();
if ((cpu_id.family_id == MESON_CPU_MAJOR_ID_GXBB)
|| (cpu_id.family_id == MESON_CPU_MAJOR_ID_GXL)) {
if (cpu_id.family_id == MESON_CPU_MAJOR_ID_AXG)
#else
if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXBB)
|| (get_cpu_type() == MESON_CPU_MAJOR_ID_GXL)) {
if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG)
always_on = 0x1 << 28;
#endif
/* basic debug code using 24Mhz, fixme. */
if (clk_freq == 24) {
/* 24Mhz/1 = 24Mhz */
amlnf_write_reg32(controller->nand_clk_reg, 0x81000201);
} else if (clk_freq == 200) {
/* 1000Mhz/5 = 200Mhz */
amlnf_write_reg32(controller->nand_clk_reg, 0x81000245);
pr_info("%s() %d, clock setting 200!\n",
__func__, __LINE__);
} else if (clk_freq == 250) {
/* 1000Mhz/4 = 250Mhz */
amlnf_write_reg32(controller->nand_clk_reg, 0x81000244);
pr_info("%s() %d, clock setting 250!\n",
__func__, __LINE__);
} else {
/* 1000Mhz/5 = 200Mhz */
amlnf_write_reg32(controller->nand_clk_reg, 0x81000245);
pr_info("%s() %d, using default clock 200MHz !\n",
__func__, __LINE__);
if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXBB)
|| (get_cpu_type() == MESON_CPU_MAJOR_ID_GXL)
|| (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG)) {
switch (clk_freq) {
case 24:
clk = 0x80000201;
break;
case 200:
clk = 0x80000245;
break;
case 250:
clk = 0x80000244;
break;
default:
clk = 0x80000245;
break;
}
/*
*pr_info("clk_reg 0x%x\n",
* AMLNF_READ_REG(controller->nand_clk_reg));
**/
clk |= always_on;
amlnf_write_reg32(controller->nand_clk_reg, clk);
return;
} else
pr_info("%s %d: not support cpu type!!!\n",
__func__, __LINE__);
@@ -662,7 +651,7 @@ static int m3_nand_dma_write(struct aml_nand_chip *aml_chip,
NFC_SEND_CMD_M2N_RAW(controller, 0, len);
else
NFC_SEND_CMD_M2N(controller, aml_chip->ran_mode,
((bch_mode == NAND_ECC_BCH_SHORT) ? NAND_ECC_BCH60_1K : bch_mode),
((bch_mode == NAND_ECC_BCH_SHORT) ? aml_chip->bch_info : bch_mode),
((bch_mode == NAND_ECC_BCH_SHORT) ? 1 : 0), dma_unit_size, count);
ret = aml_platform_dma_waiting(aml_chip);
@@ -737,7 +726,7 @@ static int m3_nand_dma_read(struct aml_nand_chip *aml_chip,
NFC_SEND_CMD_N2M_RAW(controller, 0, len);
else
NFC_SEND_CMD_N2M(controller, aml_chip->ran_mode,
((bch_mode == NAND_ECC_BCH_SHORT)?NAND_ECC_BCH60_1K:bch_mode),
((bch_mode == NAND_ECC_BCH_SHORT)?aml_chip->bch_info:bch_mode),
((bch_mode == NAND_ECC_BCH_SHORT)?1:0), dma_unit_size, count);
ret = aml_platform_dma_waiting(aml_chip);
@@ -799,474 +788,6 @@ static int m3_nand_hwecc_correct(struct aml_nand_chip *aml_chip,
return 0;
}
static int m3_nand_boot_erase_cmd(struct mtd_info *mtd, int page)
{
struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd);
struct nand_chip *chip = mtd->priv;
loff_t ofs;
int i, page_addr;
if (page >= BOOT_PAGES_PER_COPY)
return -EPERM;
if (aml_chip->valid_chip[0]) {
for (i = 0; i < BOOT_COPY_NUM; i++) {
page_addr = page + i*BOOT_PAGES_PER_COPY;
ofs = (page_addr << chip->page_shift);
if (chip->block_bad(mtd, ofs))
continue;
aml_chip->aml_nand_select_chip(aml_chip, 0);
aml_chip->aml_nand_command(aml_chip,
NAND_CMD_ERASE1, -1, page_addr, 0);
aml_chip->aml_nand_command(aml_chip,
NAND_CMD_ERASE2, -1, -1, 0);
chip->waitfunc(mtd, chip);
}
}
return 0;
}
static int m3_nand_boot_read_page_hwecc(struct mtd_info *mtd,
struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
{
struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd);
uint8_t *oob_buf = chip->oob_poi;
unsigned int nand_page_size = chip->ecc.steps * chip->ecc.size;
uint32_t pages_per_blk_shift = chip->phys_erase_shift-chip->page_shift;
int user_byte_num = (chip->ecc.steps * aml_chip->user_byte_mode);
int bch_mode = aml_chip->bch_mode, ran_mode = 0;
int error = 0, i = 0, stat = 0;
int ecc_size, configure_data_w, pages_per_blk_w, configure_data;
int pages_per_blk, read_page;
int en_slc = 0;
/* using info page structure */
struct _nand_page0 *p_nand_page0 = NULL;
struct _ext_info *p_ext_info = NULL;
struct nand_setup *p_nand_setup = NULL;
u8 type = aml_chip->new_nand_info.type;
if (aml_chip->support_new_nand == 1)
en_slc = ((type < 10) && type) ? 1:0;
if (page >= (BOOT_PAGES_PER_COPY*BOOT_COPY_NUM)) {
memset(buf, 0, (1 << chip->page_shift));
pr_info("nand boot read out of uboot failed, page:%d\n", page);
goto exit;
}
/* nand page info */
if ((page % BOOT_PAGES_PER_COPY) == 0) {
if (aml_chip->bch_mode == NAND_ECC_BCH_SHORT)
configure_data_w =
NFC_CMD_N2M(aml_chip->ran_mode,
NAND_ECC_BCH60_1K, 1, (chip->ecc.size >> 3), chip->ecc.steps);
else
configure_data_w =
NFC_CMD_N2M(aml_chip->ran_mode,
aml_chip->bch_mode, 0, (chip->ecc.size >> 3), chip->ecc.steps);
ecc_size = chip->ecc.size; /* backup ecc size */
if (aml_chip->bch_mode != NAND_ECC_BCH_SHORT) {
nand_page_size =
(mtd->writesize / 512) * NAND_ECC_UNIT_SHORT;
bch_mode = NAND_ECC_BCH_SHORT;
chip->ecc.size = NAND_ECC_UNIT_SHORT;
} else
bch_mode = aml_chip->bch_mode;
chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
memset(buf, 0xff, (1 << chip->page_shift));
/* read back page0 and check it */
if (aml_chip->valid_chip[0]) {
if (!aml_chip->aml_nand_wait_devready(aml_chip, i)) {
pr_info("don't found selected chip:%d ready\n",
i);
error = -EBUSY;
}
if (aml_chip->ops_mode & AML_CHIP_NONE_RB)
chip->cmd_ctrl(mtd, NAND_CMD_READ0 & 0xff,
NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
if (en_slc == 0) {
ran_mode = aml_chip->ran_mode;
aml_chip->ran_mode = 1;
}
error = aml_chip->aml_nand_dma_read(aml_chip,
buf, nand_page_size, bch_mode);
if (en_slc == 0)
aml_chip->ran_mode = ran_mode;
if (error)
pr_info(" page0 aml_nand_dma_read failed\n");
aml_chip->aml_nand_get_user_byte(aml_chip,
oob_buf, user_byte_num);
stat = aml_chip->aml_nand_hwecc_correct(aml_chip,
buf, nand_page_size, oob_buf);
if (stat < 0) {
mtd->ecc_stats.failed++;
pr_info("page0 read ecc fail at blk0 chip0\n");
} else
mtd->ecc_stats.corrected += stat;
} else {
pr_info("nand boot page 0 no valid chip failed\n");
error = -ENODEV;
/* goto exit; */
}
/* check page 0 info here */
p_nand_page0 = (struct _nand_page0 *) buf;
p_nand_setup = &p_nand_page0->nand_setup;
p_ext_info = &p_nand_page0->ext_info;
configure_data = p_nand_setup->cfg.b.cmd;
pages_per_blk = p_ext_info->page_per_blk;
pages_per_blk_w =
(1 << (chip->phys_erase_shift - chip->page_shift));
if ((pages_per_blk_w != pages_per_blk)
|| (configure_data != configure_data_w)) {
pr_info("page%d fail ", page);
pr_info("configure:0x%x-0x%x pages_per_blk:0x%x-0x%x\n",
configure_data_w, configure_data,
pages_per_blk_w, pages_per_blk);
}
bch_mode = aml_chip->bch_mode;
chip->ecc.size = ecc_size;
nand_page_size = chip->ecc.steps * chip->ecc.size;
}
read_page = page;
read_page++;
if (aml_chip->support_new_nand == 1) {
if (en_slc) {
read_page = page % BOOT_PAGES_PER_COPY;
if (type == HYNIX_1YNM_8GB)
read_page =
pagelist_1ynm_hynix256_mtd[read_page + 1] +
(page / BOOT_PAGES_PER_COPY) * BOOT_PAGES_PER_COPY;
else
read_page =
pagelist_hynix256[read_page + 1] +
(page / BOOT_PAGES_PER_COPY)*BOOT_PAGES_PER_COPY;
}
}
chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, read_page);
memset(buf, 0xff, (1 << chip->page_shift));
if (aml_chip->valid_chip[0]) {
if (!aml_chip->aml_nand_wait_devready(aml_chip, 0)) {
pr_info("don't found selected chip0 ready, page: %d\n",
page);
error = -EBUSY;
goto exit;
}
if (aml_chip->ops_mode & AML_CHIP_NONE_RB)
chip->cmd_ctrl(mtd, NAND_CMD_READ0 & 0xff,
NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
error = aml_chip->aml_nand_dma_read(aml_chip,
buf, nand_page_size, bch_mode);
if (error) {
error = -ENODEV;
pr_info("aml_nand_dma_read failed: page:%d\n", page);
goto exit;
}
aml_chip->aml_nand_get_user_byte(aml_chip,
oob_buf, user_byte_num);
stat = aml_chip->aml_nand_hwecc_correct(aml_chip,
buf, nand_page_size, oob_buf);
if (stat < 0) {
error = -ENODEV;
mtd->ecc_stats.failed++;
pr_info("read data ecc failed at blk%d chip%d\n",
(page >> pages_per_blk_shift), i);
} else
mtd->ecc_stats.corrected += stat;
} else
error = -ENODEV;
exit:
return error;
}
/*
* set nand info into page0_buf for romboot.
*/
void __attribute__((unused)) nand_info_page_prepare(
struct aml_nand_chip *aml_chip,
u8 *page0_buf)
{
struct nand_chip *chip = &aml_chip->chip;
/* fixme,
*devops_len = devops->len which means the total operation of uboot
**/
u32 devops_len = (BOOT_PAGES_PER_COPY-1) * aml_chip->page_size;
/* struct hw_controller *controller = &(aml_chip->controller); */
int i, nand_read_info;
u32 en_slc, configure_data;
u32 boot_num = 1, each_boot_pages;
u32 valid_pages = BOOT_TOTAL_PAGES;
struct _nand_page0 *p_nand_page0 = NULL;
struct _ext_info *p_ext_info = NULL;
struct nand_setup *p_nand_setup = NULL;
p_nand_page0 = (struct _nand_page0 *) page0_buf;
p_nand_setup = &p_nand_page0->nand_setup;
p_ext_info = &p_nand_page0->ext_info;
configure_data = NFC_CMD_N2M(aml_chip->ran_mode,
aml_chip->bch_mode, 0, (chip->ecc.size >> 3),
chip->ecc.steps);
/* en_slc mode will not be used on slc */
en_slc = 0;
memset(p_nand_page0, 0x0, sizeof(struct _nand_page0));
/* info_cfg->ext = (configure_data | (1<<23) |(1<<22) | (2<<20)); */
/*
*p_nand_setup->cfg.d32 =
*(configure_data|(1<<23) | (1<<22) | (2<<20) | (1<<19));
**/
/* randomizer mode depends on chip's cofig */
p_nand_setup->cfg.d32 = (configure_data|(1<<23) | (1<<22) | (2<<20));
pr_info("cfg.d32 0x%x\n", p_nand_setup->cfg.d32);
/* need finish here for romboot retry */
p_nand_setup->id = 0;
p_nand_setup->max = 0;
memset(p_nand_page0->page_list,
0,
NAND_PAGELIST_CNT);
/* chip_num occupy the lowest 2 bit */
nand_read_info = controller->chip_num;
/*
*make it
*1)calu the number of boot saved and pages each boot needs.
*2)the number is 2*n but less than 4.
**/
pr_info("valid_pages = %d en_slc = %d devops_len = 0x%x",
valid_pages,
en_slc, devops_len);
valid_pages = (en_slc)?(valid_pages>>1):valid_pages;
for (i = 1;
i < ((valid_pages*aml_chip->page_size)/devops_len + 1); i++) {
if (((valid_pages*aml_chip->page_size)/(2*i) >= devops_len)
&& (boot_num < 4))
boot_num <<= 1;
else
break;
}
each_boot_pages = valid_pages/boot_num;
p_ext_info->read_info = nand_read_info;
p_ext_info->page_per_blk = aml_chip->block_size / aml_chip->page_size;
/* fixme, only ce0 is enabled! */
p_ext_info->ce_mask = 0x01;
/* xlc is not in using for now */
p_ext_info->xlc = 1;
p_ext_info->boot_num = boot_num;
p_ext_info->each_boot_pages = each_boot_pages;
/* pr_info("new_type = 0x%x\n", p_ext_info->new_type); */
pr_info("page_per_blk = 0x%x\n", p_ext_info->page_per_blk);
pr_info("boot_num = %d each_boot_pages = %d", boot_num,
each_boot_pages);
}
static int m3_nand_boot_write_page_hwecc(struct mtd_info *mtd,
struct nand_chip *chip, const uint8_t *buf, int oob_required, int page)
{
struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd);
uint8_t *oob_buf = chip->oob_poi;
unsigned int nand_page_size = chip->ecc.steps * chip->ecc.size;
int user_byte_num = (chip->ecc.steps * aml_chip->user_byte_mode);
int error = 0, i = 0, bch_mode, ecc_size;
ecc_size = chip->ecc.size;
if (((aml_chip->page_addr % BOOT_PAGES_PER_COPY) == 0)
&& (aml_chip->bch_mode != NAND_ECC_BCH_SHORT)) {
nand_page_size = (mtd->writesize / 512) * NAND_ECC_UNIT_SHORT;
bch_mode = NAND_ECC_BCH_SHORT;
chip->ecc.size = NAND_ECC_UNIT_SHORT;
} else
bch_mode = aml_chip->bch_mode;
/* setting magic for romboot checks. */
for (i = 0; i < mtd->oobavail; i += 2) {
oob_buf[i] = 0x55;
oob_buf[i+1] = 0xaa;
}
i = 0;
if (aml_chip->valid_chip[i]) {
aml_chip->aml_nand_select_chip(aml_chip, i);
aml_chip->aml_nand_set_user_byte(aml_chip,
oob_buf, user_byte_num);
error = aml_chip->aml_nand_dma_write(aml_chip,
(unsigned char *)buf, nand_page_size, bch_mode);
if (error)
goto exit;
aml_chip->aml_nand_command(aml_chip,
NAND_CMD_PAGEPROG, -1, -1, i);
} else {
error = -ENODEV;
goto exit;
}
exit:
if (((aml_chip->page_addr % BOOT_PAGES_PER_COPY) == 0)
&& (aml_chip->bch_mode != NAND_ECC_BCH_SHORT))
chip->ecc.size = ecc_size;
return error;
}
static 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 cached, int raw)
{
struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd);
int status, i, write_page, ran_mode = 0;
int new_nand_type = 0;
int pages_per_blk;
struct new_tech_nand_t *new_nand_info;
struct aml_nand_slc_program *slc_program_info;
int en_slc = 0;
unsigned char *fill_buf = NULL;
unsigned int priv_slc_page;
u8 type = aml_chip->new_nand_info.type;
new_nand_info = &aml_chip->new_nand_info;
slc_program_info = &new_nand_info->slc_program_info;
if (aml_chip->support_new_nand == 1) {
new_nand_type = type;
en_slc = ((type < 10) && type) ? 1 : 0;
if (new_nand_type == HYNIX_1YNM_8GB) {
fill_buf = kzalloc(mtd->writesize, GFP_KERNEL);
if (fill_buf == NULL) {
pr_info("malloc fill buf fail\n");
return -ENOMEM;
}
memset(fill_buf, 0xff, mtd->writesize);
}
if (en_slc) {
if (page >= (BOOT_PAGES_PER_COPY/2 - 1))
return 0;
if (slc_program_info->enter_enslc_mode)
slc_program_info->enter_enslc_mode(mtd);
} else {
if (page >= (BOOT_PAGES_PER_COPY - 1))
return 0;
}
pages_per_blk = (1<<(chip->phys_erase_shift-chip->page_shift));
} else {
if (page >= (BOOT_PAGES_PER_COPY - 1))
return 0;
}
/* write all copies at 1 time */
for (i = 0; i < BOOT_COPY_NUM; i++) {
/* actual page to be written */
write_page = page + i*BOOT_PAGES_PER_COPY;
/* zero page of each copy */
if ((write_page % BOOT_PAGES_PER_COPY) == 0) {
nand_info_page_prepare(aml_chip,
chip->buffers->databuf);
chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, write_page);
/* must enable ran_mode for info page */
if (en_slc == 0) {
ran_mode = aml_chip->ran_mode;
aml_chip->ran_mode = 1;
}
chip->ecc.write_page(mtd,
chip, chip->buffers->databuf, 0, write_page);
if (en_slc == 0)
aml_chip->ran_mode = ran_mode;
status = chip->waitfunc(mtd, chip);
if ((status & NAND_STATUS_FAIL) && (chip->errstat))
status = chip->errstat(mtd,
chip, FL_WRITING, status, write_page);
if (status & NAND_STATUS_FAIL) {
pr_info("uboot wr 0 page=0x%x, status=0x%x\n",
page, status);
return -EIO;
}
}
/* +1 for skipping nand info page */
if (en_slc) {
if (aml_chip->support_new_nand == 1) {
if (type == HYNIX_1YNM_8GB)
write_page =
pagelist_1ynm_hynix256_mtd[page + 1] +
i*BOOT_PAGES_PER_COPY;
else
write_page =
pagelist_hynix256[page + 1] +
i * BOOT_PAGES_PER_COPY;
}
} else
write_page++;
if (aml_chip->support_new_nand == 1) {
if (new_nand_type == HYNIX_1YNM_8GB) {
if ((page + 1) > 1)
priv_slc_page =
pagelist_1ynm_hynix256_mtd[page] +
i * BOOT_PAGES_PER_COPY;
else
priv_slc_page = page +
i * BOOT_PAGES_PER_COPY;
while ((priv_slc_page + 1) < write_page) {
chip->cmdfunc(mtd,
NAND_CMD_SEQIN,
0x00, ++priv_slc_page);
chip->ecc.write_page_raw(mtd,
chip, fill_buf, 0, priv_slc_page);
chip->waitfunc(mtd, chip);
pr_info("%s, fill page:0x%x\n",
__func__, priv_slc_page);
}
}
}
chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, write_page);
if (unlikely(raw))
chip->ecc.write_page_raw(mtd, chip, buf, 0, write_page);
else
chip->ecc.write_page(mtd, chip, buf, 0, write_page);
if (!cached || !(chip->options & NAND_CACHEPRG)) {
status = chip->waitfunc(mtd, chip);
if ((status & NAND_STATUS_FAIL) && (chip->errstat))
status = chip->errstat(mtd,
chip, FL_WRITING, status, write_page);
if (status & NAND_STATUS_FAIL) {
pr_info("uboot wr page=0x%x, status=0x%x\n",
page, status);
if (aml_chip->support_new_nand == 1) {
if (en_slc && slc_program_info->exit_enslc_mode)
slc_program_info->exit_enslc_mode(mtd);
}
return -EIO;
}
} else
status = chip->waitfunc(mtd, chip);
}
if (aml_chip->support_new_nand == 1) {
if (en_slc && slc_program_info->exit_enslc_mode)
slc_program_info->exit_enslc_mode(mtd);
}
return 0;
}
#ifndef AML_NAND_UBOOT
struct nand_hw_control upper_controller;
@@ -1331,6 +852,7 @@ static int m3_nand_probe(struct aml_nand_platform *plat, unsigned int dev_num)
struct mtd_info *mtd = NULL;
int err = 0;
unsigned int nand_type = 0;
struct aml_nand_device *aml_nand_device = NULL;
/*#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 13)*/
#if 0
int tmp_val, i;
@@ -1349,6 +871,7 @@ static int m3_nand_probe(struct aml_nand_platform *plat, unsigned int dev_num)
/* initialize mtd info data struct */
aml_chip->controller = controller;
/* to it's own plat data */
aml_chip->platform = plat;
aml_chip->bch_desc = m3_bch_list;
aml_chip->max_bch_mode = ARRAY_SIZE(m3_bch_list);
@@ -1362,6 +885,15 @@ static int m3_nand_probe(struct aml_nand_platform *plat, unsigned int dev_num)
#ifndef AML_NAND_UBOOT
/*fixit ,hardware support all address*/
/* dev->coherent_dma_mask = DMA_BIT_MASK(32); */
aml_nand_device = plat->aml_nand_device;
pr_info("%s() aml_nand_device %p\n", __func__, aml_nand_device);
if (aml_nand_device) {
aml_chip->bl_mode = aml_nand_device->bl_mode;
aml_chip->fip_copies = aml_nand_device->fip_copies;
aml_chip->fip_size = aml_nand_device->fip_size;
}
aml_chip->device = dev;
mtd->dev.parent = dev->parent;
mtd->owner = THIS_MODULE;
@@ -1434,7 +966,7 @@ static int m3_nand_probe(struct aml_nand_platform *plat, unsigned int dev_num)
/*need to set device_boot_flag here*/
device_boot_flag = NAND_BOOT_FLAG;
#endif
nand_info[dev_num] = *mtd;
nand_info[dev_num] = mtd;
return 0;
exit_error:
@@ -1477,7 +1009,6 @@ void nand_init(void)
pr_info("error for not platform data\n");
continue;
}
ret = m3_nand_probe(plat, i);
if (ret) {
pr_info("nand init faile: %d\n", ret);
@@ -1529,9 +1060,11 @@ int nand_init(struct platform_device *pdev)
dev_err(&pdev->dev, "ioremap Nand Flash IO fail\n");
return -ENOMEM;
}
pr_info("nand_clk_ctrl 0x%x\n",
aml_nand_mid_device.nand_clk_ctrl);
controller->nand_clk_reg = devm_ioremap_nocache(&pdev->dev,
NAND_CLK_CNTL,
aml_nand_mid_device.nand_clk_ctrl,
sizeof(int));
if (controller->nand_clk_reg == NULL) {
dev_err(&pdev->dev, "ioremap External Nand Clock IO fail\n");
@@ -1590,6 +1123,9 @@ int nand_init(struct platform_device *pdev)
continue;
}
#ifndef AML_NAND_UBOOT
/* to get the glb fip infos */
plat->aml_nand_device = &aml_nand_mid_device;
pr_info("plat->aml_nand_device %p\n", plat->aml_nand_device);
ret = m3_nand_probe(plat, i, &pdev->dev);
#else
ret = m3_nand_probe(plat, i);

View File

@@ -194,6 +194,38 @@ static int prase_get_dtb_nand_parameter(struct aml_nand_device *aml_nand_dev,
of_node_put(np_config);
}
}
ret = of_property_read_u32(np,
"bl_mode", (u32 *)&aml_nand_dev->bl_mode);
if (ret) {
pr_info("%s:%d,please config bl_mode item\n",
__func__, __LINE__);
}
pr_info("bl mode %s\n",
aml_nand_dev->bl_mode?"descrete":"compact");
ret = of_property_read_u32(np,
"fip_copies", (u32 *)&aml_nand_dev->fip_copies);
if (ret) {
pr_info("%s:%d,please config fip_copies item\n",
__func__, __LINE__);
}
pr_info("fip_copies %d\n", aml_nand_dev->fip_copies);
ret = of_property_read_u32(np,
"fip_size", (u32 *)&aml_nand_dev->fip_size);
pr_info("fip_size 0x%x\n", aml_nand_dev->fip_size);
if (ret) {
pr_info("%s:%d,please config fip_size item\n",
__func__, __LINE__);
}
ret = of_property_read_u32(np,
"nand_clk_ctrl", (u32 *)&aml_nand_dev->nand_clk_ctrl);
pr_info("nand_clk_ctrl 0x%x\n", aml_nand_dev->nand_clk_ctrl);
if (ret) {
aml_nand_dev->nand_clk_ctrl = NAND_CLK_CNTL;
pr_info("%s:%d, using default nand_clk_ctrl 0x%x\n",
__func__, __LINE__, NAND_CLK_CNTL);
}
};
pr_info("%s:%d,parse dts end\n", __func__, __LINE__);
return 0;

View File

@@ -1281,7 +1281,7 @@ static int aml_nand_scan_ident(struct mtd_info *mtd, int maxchips)
/* overide bootloader's size consdering info page */
if (!strcmp(mtd->name, NAND_BOOT_NAME))
mtd->size = BOOT_PAGES_PER_COPY * mtd->writesize;
mtd->size = BOOT_TOTAL_PAGES * mtd->writesize;
chip->cmdfunc = aml_nand_command;
chip->waitfunc = aml_nand_wait;

View File

@@ -67,32 +67,40 @@ static const struct meson_desc_pin mesonaxg_periphs_pins[] = {
MESON_FUNCTION(0x0, "gpio")),
MESON_PINCTRL_PIN(MESON_PIN(BOOT_0, EE_OFF), 0x0, 0,
MESON_FUNCTION(0x0, "gpio"),
MESON_FUNCTION(0x1, "emmc")), /*EMMC_D0*/
MESON_FUNCTION(0x1, "emmc"), /*EMMC_D0*/
MESON_FUNCTION(0x1, "nandflash")), /*EMMC_D0*/
MESON_PINCTRL_PIN(MESON_PIN(BOOT_1, EE_OFF), 0x0, 4,
MESON_FUNCTION(0x0, "gpio"),
MESON_FUNCTION(0x1, "emmc")), /*EMMC_D1*/
MESON_FUNCTION(0x1, "emmc"),
MESON_FUNCTION(0x1, "nandflash")), /*EMMC_D1*/
MESON_PINCTRL_PIN(MESON_PIN(BOOT_2, EE_OFF), 0x0, 8,
MESON_FUNCTION(0x0, "gpio"),
MESON_FUNCTION(0x1, "emmc")), /*EMMC_D2*/
MESON_FUNCTION(0x1, "emmc"),
MESON_FUNCTION(0x1, "nandflash")), /*EMMC_D2*/
MESON_PINCTRL_PIN(MESON_PIN(BOOT_3, EE_OFF), 0x0, 12,
MESON_FUNCTION(0x0, "gpio"),
MESON_FUNCTION(0x1, "emmc"), /*EMMC_D3*/
MESON_FUNCTION(0x1, "nandflash"),
MESON_FUNCTION(0x3, "norflash")), /*NOR_HOLD*/
MESON_PINCTRL_PIN(MESON_PIN(BOOT_4, EE_OFF), 0x0, 16,
MESON_FUNCTION(0x0, "gpio"),
MESON_FUNCTION(0x1, "emmc"), /*EMMC_D4*/
MESON_FUNCTION(0x1, "nandflash"),
MESON_FUNCTION(0x3, "norflash")), /*NOR_D*/
MESON_PINCTRL_PIN(MESON_PIN(BOOT_5, EE_OFF), 0x0, 20,
MESON_FUNCTION(0x0, "gpio"),
MESON_FUNCTION(0x1, "emmc"), /*EMMC_D5*/
MESON_FUNCTION(0x1, "nandflash"),
MESON_FUNCTION(0x3, "norflash")), /*NOR_Q*/
MESON_PINCTRL_PIN(MESON_PIN(BOOT_6, EE_OFF), 0x0, 24,
MESON_FUNCTION(0x0, "gpio"),
MESON_FUNCTION(0x1, "emmc"), /*EMMC_D6*/
MESON_FUNCTION(0x1, "nandflash"),
MESON_FUNCTION(0x3, "norflash")), /*NOR_C*/
MESON_PINCTRL_PIN(MESON_PIN(BOOT_7, EE_OFF), 0x0, 28,
MESON_FUNCTION(0x0, "gpio"),
MESON_FUNCTION(0x1, "emmc")), /*EMMC_D7*/
MESON_FUNCTION(0x1, "emmc"),
MESON_FUNCTION(0x1, "nandflash")), /*EMMC_D7*/
MESON_PINCTRL_PIN(MESON_PIN(BOOT_8, EE_OFF), 0x1, 0,
MESON_FUNCTION(0x0, "gpio"),
MESON_FUNCTION(0x1, "emmc"), /*EMMC_CLK*/