nand: mtd nand initial version

PD#156734: nand: add nand support for G12A

Change-Id: Ic696edd8ca00ec3010e17b25a842788cb95fd166
Signed-off-by: Liang Yang <liang.yang@amlogic.com>
This commit is contained in:
Liang Yang
2018-02-01 23:53:39 +08:00
committed by Yixun Lan
parent 52a80d4ddc
commit 05191cd937
6 changed files with 144 additions and 38 deletions

View File

@@ -180,6 +180,95 @@
};
};
nand: nfc@0 {
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 configuration 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 0xF00000>;
};
system{
offset=<0x0 0x0>;
size=<0x0 0x11800000>;
};
data{
offset=<0xffffffff 0xffffffff>;
size=<0x0 0x0>;
};
};
};
uart_A: serial@ffd24000 {
compatible = "amlogic, meson-uart";
reg = <0x0 0xffd24000 0x0 0x18>;

View File

@@ -560,6 +560,34 @@
};
};
all_nand_pins: all_nand_pins {
mux {
groups = "emmc_nand_d0",
"emmc_nand_d1",
"emmc_nand_d2",
"emmc_nand_d3",
"emmc_nand_d4",
"emmc_nand_d5",
"emmc_nand_d6",
"emmc_nand_d7",
"nand_ce0",
"nand_ale",
"nand_cle",
"nand_wen_clk",
"nand_ren_wr",
"nand_rb0";
function = "nand";
input-enable;
};
};
nand_cs_pins: nand_cs {
mux {
groups = "nand_ce0";
function = "nand";
};
};
a_uart_pins:a_uart {
mux {
groups = "uart_tx_a",

View File

@@ -2087,19 +2087,18 @@ int aml_nand_init(struct aml_nand_chip *aml_chip)
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;
chip->options |= NAND_NO_SUBPAGE_WRITE;
if (aml_nand_scan(mtd, controller->chip_num)) {
err = -ENXIO;
goto exit_error;
}
} else {
pr_info("pre nand scan failed\n");
mtd_set_ooblayout(mtd, &aml_ooblayout_ops);
mtd_ooblayout_free(mtd, 0, &oobregion);
mtd->oobavail = oobregion.length;
chip->options = 0;
chip->options |= NAND_SKIP_BBTSCAN;
chip->options |= NAND_NO_SUBPAGE_WRITE;
if (aml_nand_scan(mtd, controller->chip_num)) {
err = -ENXIO;
goto exit_error;
}
valid_chip_num = 0;
for (i = 0; i < controller->chip_num; i++) {
if (aml_chip->valid_chip[i])
@@ -2114,9 +2113,6 @@ int aml_nand_init(struct aml_nand_chip *aml_chip)
err = -ENXIO;
goto exit_error;
}
mtd_set_ooblayout(mtd, &aml_ooblayout_ops);
mtd_ooblayout_free(mtd, 0, &oobregion);
mtd->oobavail = oobregion.length;
aml_chip->virtual_page_size = mtd->writesize;
aml_chip->virtual_block_size = mtd->erasesize;
@@ -2154,17 +2150,6 @@ int aml_nand_init(struct aml_nand_chip *aml_chip)
goto exit_error;
}
#endif
/*
*if (chip->buffers)
* kfree(chip->buffers);
*if (mtd->oobsize >= NAND_MAX_OOBSIZE)
* chip->buffers =
* kzalloc((mtd->writesize + 3 * mtd->oobsize), GFP_KERNEL);
*else
* chip->buffers =
* kzalloc((mtd->writesize + 3 * NAND_MAX_OOBSIZE), GFP_KERNEL);
*/
if (chip->buffers == NULL) {
pr_info("no memory for flash data buf\n");
err = -ENOMEM;

View File

@@ -294,7 +294,7 @@ int m3_nand_boot_read_page_hwecc(struct mtd_info *mtd,
memset(oob_buf, 0xff, user_byte_num);
} else {
mtd->ecc_stats.failed++;
pr_info("page0 read ecc fail at blk0 chip0\n");
pr_info("page0 read ecc fail\n");
}
} else
mtd->ecc_stats.corrected += stat;

View File

@@ -270,12 +270,16 @@ void get_sys_clk_rate_mtd(struct hw_controller *controller, int *rate)
if (cpu_id.family_id == MESON_CPU_MAJOR_ID_AXG)
#else
if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG)
if ((get_cpu_type() == MESON_CPU_MAJOR_ID_AXG)
|| (get_cpu_type() == MESON_CPU_MAJOR_ID_G12A)
|| (get_cpu_type() == MESON_CPU_MAJOR_ID_G12B))
always_on = 0x1 << 28;
#endif
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)) {
|| (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG)
|| (get_cpu_type() == MESON_CPU_MAJOR_ID_G12A)
|| (get_cpu_type() == MESON_CPU_MAJOR_ID_G12B)) {
switch (clk_freq) {
case 24:
clk = 0x80000201;
@@ -305,12 +309,12 @@ static void m3_nand_hw_init(struct aml_nand_chip *aml_chip)
{
int sys_clk_rate, bus_cycle, bus_timing;
sys_clk_rate = 200;
sys_clk_rate = 24;
get_sys_clk_rate_mtd(controller, &sys_clk_rate);
/* sys_time = (10000 / sys_clk_rate); */
bus_cycle = 6;
bus_timing = bus_cycle + 1;
bus_cycle = 4;
bus_timing = 3;
NFC_SET_CFG(controller, 0);
NFC_SET_TIMING_ASYC(controller, bus_timing, (bus_cycle - 1));
@@ -333,12 +337,13 @@ static void m3_nand_adjust_timing(struct aml_nand_chip *aml_chip)
else
sys_clk_rate = 250;
sys_clk_rate = 24;
get_sys_clk_rate_mtd(controller, &sys_clk_rate);
/* sys_time = (10000 / sys_clk_rate); */
bus_cycle = 6;
bus_timing = bus_cycle + 1;
bus_cycle = 4;
bus_timing = 3;
NFC_SET_CFG(controller, 0);
NFC_SET_TIMING_ASYC(controller, bus_timing, (bus_cycle - 1));

View File

@@ -1404,7 +1404,6 @@ static struct aml_nand_flash_dev *aml_nand_get_flash_type(struct mtd_info *mtd,
return type;
}
static int aml_nand_scan_ident(struct mtd_info *mtd, int maxchips)
{
int i, busw, nand_maf_id, valid_chip_num = 1;
@@ -1414,6 +1413,11 @@ static int aml_nand_scan_ident(struct mtd_info *mtd, int maxchips)
u8 dev_id[MAX_ID_LEN], onfi_features[4];
unsigned int temp_chip_shift;
chip->cmdfunc = aml_nand_command;
chip->waitfunc = aml_nand_wait;
chip->erase = aml_nand_erase_cmd;
chip->write_page = aml_nand_write_page;
/* Get buswidth to select the correct functions */
busw = chip->options & NAND_BUSWIDTH_16;
@@ -1538,11 +1542,6 @@ static int aml_nand_scan_ident(struct mtd_info *mtd, int maxchips)
if (!strcmp(mtd->name, NAND_BOOT_NAME))
mtd->size = BOOT_TOTAL_PAGES * mtd->writesize;
chip->cmdfunc = aml_nand_command;
chip->waitfunc = aml_nand_wait;
chip->erase = aml_nand_erase_cmd;
chip->write_page = aml_nand_write_page;
return 0;
}