mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
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:
@@ -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>;
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user