From 05191cd937d6478137f40a9287f0f945fdb019ce Mon Sep 17 00:00:00 2001 From: Liang Yang Date: Thu, 1 Feb 2018 23:53:39 +0800 Subject: [PATCH] nand: mtd nand initial version PD#156734: nand: add nand support for G12A Change-Id: Ic696edd8ca00ec3010e17b25a842788cb95fd166 Signed-off-by: Liang Yang --- arch/arm64/boot/dts/amlogic/g12a_skt.dts | 89 ++++++++++++++++++++++++++++++ arch/arm64/boot/dts/amlogic/mesong12a.dtsi | 28 ++++++++++ drivers/amlogic/mtd/aml_nand.c | 33 +++-------- drivers/amlogic/mtd/boot.c | 2 +- drivers/amlogic/mtd/m3_nand.c | 19 ++++--- drivers/amlogic/mtd/nand_flash.c | 11 ++-- 6 files changed, 144 insertions(+), 38 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/g12a_skt.dts b/arch/arm64/boot/dts/amlogic/g12a_skt.dts index 5e0ade7..70e256c 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_skt.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_skt.dts @@ -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>; diff --git a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi index 9cc6274..34e2807 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi @@ -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", diff --git a/drivers/amlogic/mtd/aml_nand.c b/drivers/amlogic/mtd/aml_nand.c index 04e697a..f6f68da 100644 --- a/drivers/amlogic/mtd/aml_nand.c +++ b/drivers/amlogic/mtd/aml_nand.c @@ -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; diff --git a/drivers/amlogic/mtd/boot.c b/drivers/amlogic/mtd/boot.c index 1bd97ae..e5677bc 100644 --- a/drivers/amlogic/mtd/boot.c +++ b/drivers/amlogic/mtd/boot.c @@ -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; diff --git a/drivers/amlogic/mtd/m3_nand.c b/drivers/amlogic/mtd/m3_nand.c index 1cb3dee..23f334a 100644 --- a/drivers/amlogic/mtd/m3_nand.c +++ b/drivers/amlogic/mtd/m3_nand.c @@ -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)); diff --git a/drivers/amlogic/mtd/nand_flash.c b/drivers/amlogic/mtd/nand_flash.c index 75a5a64..fa8a037 100644 --- a/drivers/amlogic/mtd/nand_flash.c +++ b/drivers/amlogic/mtd/nand_flash.c @@ -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; } -- 2.7.4