Re: OMAP3 NAND ECC selection
Le Mon, 9 Dec 2013 04:33:51 +, Gupta, Pekon pe...@ti.com a écrit : Hi, From: Thomas Petazzoni [mailto:thomas.petazz...@free-electrons.com] On Thu, 5 Dec 2013 11:24:18 -0800, Brian Norris wrote: [...] Using 1-bit ECC on NAND is not a long-term solution. Given that fact, I think your ROM code is what may need to change, not the entire MTD subsystem. As someone (Tom Rini maybe?) pointed out, today the shift is 1-bit ECC supported by ROM code vs. 4 or 8 bits required by NAND. But we can very well imagine that tomorrow ROM code will support BCH4 (and the NAND will ensure block 0 is OK for use with BCH4) but the rest of the NAND will require BCH16 or something like that. I'm not designing ROM code, and the fact that they today have this limitation, should be an indication that Linux should be capable of handling different ECC schemes to handle those hardware constraints. Just to highlight few more points: (1) ROM code on newer OMAP platforms like AM33xx do have the ability to select ECC scheme by reading a specific location from EEPROM connected to I2C0. AFAIK on omap3, the rom code first try to read data with bch and if it doesn't work it fallback on haming 1 bit ecc. (2) And going forward, ECC based NAND devices may be phased out, and BE-NAND (Built-in) NAND devices are becoming popular. As both cost and density wise they are same to SLC NANDs today. Thus issue of un-compatibility of ecc-scheme with ROM code, will not hold true. We already have some BE-NAND support in our generic driver. http://patchwork.ozlabs.org/patch/222186/ Yes but these flash are not always compatible with the ROM. If the rom is expecting some ECC and the internal controller expect other ecc you are stuck. Matthieu -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] mtd nand : onfi need to be probed in 8 bits mode
Matthieu CASTET a écrit : Hi Paul, Paul Walmsley a écrit : Hi Matthieu, On Tue, 22 Jan 2013, Paul Walmsley wrote: Any progress on updating and resending your omap3 nand : use NAND_BUSWIDTH_AUTO patch? We're in danger of missing the 3.9 merge window if it takes too much longer. Could you let us know if you're planning to update and repost this one? Sorry for the delay I attached an updated version of the patch. I was not able to test it : with mtd tree and my configuration I have to apply https://patchwork.kernel.org/patch/1810441/ https://patchwork.kernel.org/patch/1884341/ http://comments.gmane.org/gmane.linux.ports.arm.omap/91096 in order the kernel build. And after that the kernel doesn't seem to boot on my beagle board. Could you test the patch ? I have also a problem : how should I change nand bus size. It is done by gpmc_cs_configure(info-gpmc_cs, GPMC_CONFIG_DEV_SIZE, ...);, but now gpmc.h header is not public anymore. I have to do a '#include ../gpmc.h'. Any news on this ? Matthieu -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] mtd nand : onfi need to be probed in 8 bits mode
Hi Paul, Paul Walmsley a écrit : Hi Matthieu, On Tue, 22 Jan 2013, Paul Walmsley wrote: Any progress on updating and resending your omap3 nand : use NAND_BUSWIDTH_AUTO patch? We're in danger of missing the 3.9 merge window if it takes too much longer. Could you let us know if you're planning to update and repost this one? Sorry for the delay I attached an updated version of the patch. I was not able to test it : with mtd tree and my configuration I have to apply https://patchwork.kernel.org/patch/1810441/ https://patchwork.kernel.org/patch/1884341/ http://comments.gmane.org/gmane.linux.ports.arm.omap/91096 in order the kernel build. And after that the kernel doesn't seem to boot on my beagle board. Could you test the patch ? I have also a problem : how should I change nand bus size. It is done by gpmc_cs_configure(info-gpmc_cs, GPMC_CONFIG_DEV_SIZE, ...);, but now gpmc.h header is not public anymore. I have to do a '#include ../gpmc.h'. Matthieu 0001-omap3-nand-use-NAND_BUSWIDTH_AUTO.patch Description: application/mbox
Re: [PATCH 1/3] mtd nand : onfi need to be probed in 8 bits mode
Hi, Paul Walmsley a écrit : Hi On Wed, 2 Jan 2013, Matthieu CASTET wrote: which did not get merged because Tony requested that it should be based on top of his cleanup work (which takes priority over adding new features): http://thread.gmane.org/gmane.linux.ports.arm.omap/88550/focus=88549 Could you please update this omap3 nand : use NAND_BUSWIDTH_AUTO patch on v3.8-rc2 and repost? Do you know when this patchset will be submited to mtd ? I think I will wait it is merged in mtd and redo my patch after that. For drivers that can't support ONFI, I don't know what to do. May we should be replace the WARN_ON by a printk and early return. That sounds like a good idea to me. The traceback seems excessive, since the NAND was usable before this series. I submited a patch for doing that. Matthieu -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] mtd nand : onfi need to be probed in 8 bits mode
Hi Paul, Paul Walmsley a écrit : Hi On Mon, 3 Dec 2012, Artem Bityutskiy wrote: On Tue, 2012-11-06 at 11:51 +0100, Matthieu CASTET wrote: - NAND_CMD_READID want an address that it is not scaled on x16 device (it is always 0x20) - NAND_CMD_PARAM want 8 bits data Signed-off-by: Matthieu CASTET matthieu.cas...@parrot.com Pushed this one to l2-mtd.git, thanks! This patch (commit ff3206b2450499203532af2505a7f6f8413e92c0 in mainline) is causing warnings on OMAP3730 Beagle XM, OMAP3530 Beagle, and DM37xx EVM as of v3.8-rc1: [1.349456] [ cut here ] [1.351959] WARNING: at drivers/mtd/nand/nand_base.c:2861 nand_scan_ident+0xdb4/0xf90() [1.356292] Modules linked in: [1.357971] [c001bf50] (unwind_backtrace+0x0/0xf0) from [c0045cec] (warn_slowpath_common+0x4c/0x64) [1.363037] [c0045cec] (warn_slowpath_common+0x4c/0x64) from [c0045d20] (warn_slowpath_null+0x1c/0x24) [1.368194] [c0045d20] (warn_slowpath_null+0x1c/0x24) from [c039d304] (nand_scan_ident+0xdb4/0xf90) [1.373229] [c039d304] (nand_scan_ident+0xdb4/0xf90) from [c03a2448] (omap_nand_probe+0x2e8/0x678) [1.378234] [c03a2448] (omap_nand_probe+0x2e8/0x678) from [c0357f84] (platform_drv_probe+0x18/0x1c) [1.383239] [c0357f84] (platform_drv_probe+0x18/0x1c) from [c0356b84] (driver_probe_device+0x84/0x224) [1.388458] [c0356b84] (driver_probe_device+0x84/0x224) from [c0356db8] (__driver_attach+0x94/0x98) [1.393493] [c0356db8] (__driver_attach+0x94/0x98) from [c0355330] (bus_for_each_dev+0x50/0x7c) [1.398315] [c0355330] (bus_for_each_dev+0x50/0x7c) from [c0356250] (bus_add_driver+0xa0/0x2a0) [1.403198] [c0356250] (bus_add_driver+0xa0/0x2a0) from [c03572ec] (driver_register+0x78/0x18c) [1.408020] [c03572ec] (driver_register+0x78/0x18c) from [c00086a4] (do_one_initcall+0x34/0x194) [1.412933] [c00086a4] (do_one_initcall+0x34/0x194) from [c0528188] (kernel_init+0x154/0x2ec) [1.417724] [c0528188] (kernel_init+0x154/0x2ec) from [c0013d50] (ret_from_fork+0x14/0x24) [1.422454] ---[ end trace 7f5c9fb048cfa61e ]--- The patch also looks bogus. The patch states that ONFI need to be probed in 8 bits mode (sic). But if that's so, shouldn't nand_flash_detect_onfi() just fail immediately, rather than warn? I put a warning in order we fix drivers instead of a silent failure. The omap driver was fixed in the same series with http://article.gmane.org/gmane.linux.ports.arm.omap/88551 and http://article.gmane.org/gmane.linux.ports.arm.omap/88549 For drivers that can't support ONFI, I don't know what to do. May we should be replace the WARN_ON by a printk and early return. Matthieu -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] omap3 nand : use NAND_BUSWIDTH_AUTO
Artem Bityutskiy a écrit : On Tue, 2012-11-06 at 10:40 -0800, Tony Lindgren wrote: Where such tree could be found ? You should be able to use omap-for-v3.8/cleanup-headers-gpmc branch as a base for your patches [1]. Is this a stable branch which I may pull into l2-mtd.git? Then I could merge Matthieu's patches. patch 1 and 2 are not controller dependent. I added the support for the omap controller because I can easily test on it (and beagleboard got a x16 onfi flash). What a shame that omap workflow is so complex : - I think Artem want support for at least one controller before merging generic code - I can rebase on omap-for-v3.8/cleanup-headers-gpmc, but this is weird to add generic code for nand that is not specific to omap on it ? Matthieu -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] mtd nand : onfi need to be probed in 8 bits mode
- NAND_CMD_READID want an address that it is not scaled on x16 device (it is always 0x20) - NAND_CMD_PARAM want 8 bits data Signed-off-by: Matthieu CASTET matthieu.cas...@parrot.com --- drivers/mtd/nand/nand_base.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 5894c2c..abeb8e9 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2851,6 +2851,8 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, int i; int val; + /* ONFI need to be probed in 8 bits mode */ + WARN_ON(chip-options NAND_BUSWIDTH_16); /* Try ONFI for unknown chip or LP */ chip-cmdfunc(mtd, NAND_CMD_READID, 0x20, -1); if (chip-read_byte(mtd) != 'O' || chip-read_byte(mtd) != 'N' || -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] mtd nand : add NAND_BUSWIDTH_AUTO to autodetect bus width
The driver call nand_scan_ident in 8 bit mode, then readid or onfi detection are done (and detect bus width). The driver should update its bus width before calling nand_scan_tail. This work because readid and onfi are read work 8 byte mode. Note that nand_scan_ident send command (NAND_CMD_RESET, NAND_CMD_READID, NAND_CMD_PARAM), address and read data The ONFI specificication is not very clear for x16 device if high byte of address should be driven to 0, but according to [1] it should be ok to not drive it during autodetection. [1] 3.3.2. Target Initialization [...] The Read ID and Read Parameter Page commands only use the lower 8-bits of the data bus. The host shall not issue commands that use a word data width on x16 devices until the host determines the device supports a 16-bit data bus width in the parameter page. Signed-off-by: Matthieu CASTET matthieu.cas...@parrot.com --- drivers/mtd/nand/nand_base.c | 14 +- include/linux/mtd/nand.h |7 +++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index abeb8e9..c90ef66 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3245,11 +3245,15 @@ ident_done: break; } - /* -* Check, if buswidth is correct. Hardware drivers should set -* chip correct! -*/ - if (busw != (chip-options NAND_BUSWIDTH_16)) { + if (chip-options NAND_BUSWIDTH_AUTO) { + WARN_ON(chip-options NAND_BUSWIDTH_16); + chip-options |= busw; + nand_set_defaults(chip, busw); + } else if (busw != (chip-options NAND_BUSWIDTH_16)) { + /* +* Check, if buswidth is correct. Hardware drivers should set +* chip correct! +*/ pr_info(NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s)\n, *maf_id, *dev_id, nand_manuf_ids[maf_idx].name, mtd-name); diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 24e9159..c8518d4 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -219,6 +219,13 @@ typedef enum { #define NAND_OWN_BUFFERS 0x0002 /* Chip may not exist, so silence any errors in scan */ #define NAND_SCAN_SILENT_NODEV 0x0004 +/* + * Autodetect nand buswidth with readid/onfi. + * This suppose the driver will configure the hardware in 8 bits mode + * when calling nand_scan_ident, and update its configuration + * before calling nand_scan_tail. + */ +#define NAND_BUSWIDTH_AUTO 0x0008 /* Options set by nand scan */ /* Nand scan has allocated controller struct */ -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] omap3 nand : use NAND_BUSWIDTH_AUTO
This allow to clean the omap nand driver that were trying in x8 and x16 bits mode. This also make work onfi detection on beagleboard : Before : [1.954803] NAND device: Manufacturer ID: 0x2c, Chip ID: 0xba (Micron NAND 256MiB 1,8V 16-bit), page size: 2048, OOB size: 64 After : [1.914825] ONFI param page 0 valid [1.919158] ONFI flash detected [1.922515] NAND device: Manufacturer ID: 0x2c, Chip ID: 0xba (Micron MT29F2G16ABD), page size: 2048, OOB size: 64 platform data devsize is renamed bussize. It now indicate the maximun size of the nand bus. Signed-off-by: Matthieu CASTET matthieu.cas...@parrot.com --- arch/arm/mach-omap2/board-3630sdp.c |2 +- arch/arm/mach-omap2/board-devkit8000.c |2 +- arch/arm/mach-omap2/board-flash.c|8 ++--- arch/arm/mach-omap2/board-igep0020.c |2 +- arch/arm/mach-omap2/board-omap3beagle.c |2 +- arch/arm/mach-omap2/board-omap3evm.c |2 +- arch/arm/mach-omap2/board-omap3pandora.c |2 +- arch/arm/mach-omap2/board-omap3touchbook.c |2 +- arch/arm/mach-omap2/board-zoom.c |2 +- arch/arm/mach-omap2/common-board-devices.c |2 +- arch/arm/mach-omap2/gpmc-nand.c |5 --- drivers/mtd/nand/omap2.c | 42 ++ include/linux/platform_data/mtd-nand-omap2.h |7 - 13 files changed, 42 insertions(+), 38 deletions(-) diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index fc224ad..d7b981b 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -198,7 +198,7 @@ static void __init omap_sdp_init(void) h8mbx00u0mer0em_sdrc_params); zoom_display_init(); board_smc91x_init(); - board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16); + board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_OMAP_BUS_16); enable_board_wakeup_source(); usbhs_init(usbhs_bdata); } diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 1fd161e..b3487e1 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -621,7 +621,7 @@ static void __init devkit8000_init(void) usb_musb_init(NULL); usbhs_init(usbhs_bdata); - omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions, + omap_nand_flash_init(NAND_OMAP_BUS_16, devkit8000_nand_partitions, ARRAY_SIZE(devkit8000_nand_partitions)); omap_twl4030_audio_init(omap3beagle); diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index 0cabe61..488a1fa 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -133,12 +133,12 @@ static struct omap_nand_platform_data board_nand_data = { void __init board_nand_init(struct mtd_partition *nand_parts, - u8 nr_parts, u8 cs, int nand_type) + u8 nr_parts, u8 cs, int bus_type) { board_nand_data.cs = cs; board_nand_data.parts = nand_parts; board_nand_data.nr_parts= nr_parts; - board_nand_data.devsize = nand_type; + board_nand_data.bussize = bus_type; board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT; gpmc_nand_init(board_nand_data); @@ -185,7 +185,7 @@ unmap: * @return - void. */ void __init board_flash_init(struct flash_partitions partition_info[], - char chip_sel_board[][GPMC_CS_NUM], int nand_type) + char chip_sel_board[][GPMC_CS_NUM], int bus_type) { u8 cs = 0; u8 norcs = GPMC_CS_NUM + 1; @@ -238,5 +238,5 @@ void __init board_flash_init(struct flash_partitions partition_info[], pr_err(NAND: Unable to find configuration in GPMC\n); else board_nand_init(partition_info[2].parts, - partition_info[2].nr_parts, nandcs, nand_type); + partition_info[2].nr_parts, nandcs, bus_type); } diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 48d5e41..732f183 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -175,7 +175,7 @@ static void __init igep_flash_init(void) pr_info(IGEP: initializing NAND memory device\n); board_nand_init(igep_flash_partitions, ARRAY_SIZE(igep_flash_partitions), - 0, NAND_BUSWIDTH_16); + 0, NAND_OMAP_BUS_16); } else if (mux == IGEP_SYSBOOT_ONENAND) { pr_info(IGEP: initializing OneNAND memory device\n); board_onenand_init(igep_flash_partitions, diff --git a/arch/arm
[PATCH 2/3] mtd nand : get timings from onfi
We get from onfi param the max speed supported by the chip. A precomputed table for ONFI timings is generated. Signed-off-by: Matthieu CASTET matthieu.cas...@parrot.com --- drivers/mtd/nand/Makefile |2 +- drivers/mtd/nand/nand_base.c |1 + drivers/mtd/nand/nand_timing.c | 170 include/linux/mtd/nand.h | 56 + 4 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 drivers/mtd/nand/nand_timing.c diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 2cbd091..2fc1a99 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -54,4 +54,4 @@ obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ obj-$(CONFIG_MTD_NAND_XWAY)+= xway_nand.o -nand-objs := nand_base.o nand_bbt.o +nand-objs := nand_base.o nand_bbt.o nand_timing.o diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 8916bc6..0d6bd88 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3238,6 +3238,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, if (*maf_id != NAND_MFR_SAMSUNG !type-pagesize) chip-options = ~NAND_SAMSUNG_LP_OPTIONS; ident_done: + nand_select_speed(chip, *maf_id, *dev_id); /* Try to identify manufacturer */ for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) { diff --git a/drivers/mtd/nand/nand_timing.c b/drivers/mtd/nand/nand_timing.c new file mode 100644 index 000..7211c9c --- /dev/null +++ b/drivers/mtd/nand/nand_timing.c @@ -0,0 +1,170 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include linux/module.h +#include linux/types.h +#include linux/mtd/mtd.h +#include linux/mtd/nand.h + +/* + * this table is precomputed from onfi timings with the following program + */ +#if 0 +int print_timing(const struct onfi_timings *timings, int edo_off) +{ + struct reduced_onfi t; + int tmp; + int edo = timings-tRC 30 !edo_off; + + /* nWE low */ + t.twp = max(timings-tWP, timings-tDS); + + /* nCS low to nWE low */ + tmp = max(timings-tCLS, timings-tCS); + tmp = max(tmp, timings-tALS); + t.twsetup = tmp - t.twp; + assert(t.twsetup = 0); + + /* nWE high */ + tmp = max(timings-tWH, timings-tDH); /* nWE high data hold */ + tmp = max(tmp, timings-tCH); /* cs hold */ + tmp = max(tmp, timings-tCLH); /* cmd hold */ + t.twh = max(tmp, timings-tALH); /* addr hold */ + + assert(t.twp + t.twh = timings-tWC); + t.twc = timings-tWC; + + t.edo = edo; + if (edo == 0) { + + /* nRE low */ + t.trp = max(timings-tRP, timings-tREA); + + /* nRE high */ + t.treh = timings-tREH; + t.trc = max(timings-tRC, t.trp + t.treh); + } + else { + /* nRE low */ + t.trp = timings-tRP; + + /* nRE high */ + t.treh = timings-tREH; + + t.trc = max(timings-tRC, timings-tREA); + } + + /* nCS low to nRE low */ + t.trsetup = max(timings-tCEA - timings-tREA, timings-tCLR); + + /* Min time from rdn rising edge to output hi-Z */ + t.bta = timings-tRHZ; + + /* Min time from busy rising edge and rdn falling edge (read).*/ + t.tbusy = timings-tRR; + + /* Min time from wrn rising edge to rdn falling edge. */ + t.twhr = timings-tWHR; + assert(t.twhr = 0); + + t.tceh = 0; + + printf({\n); + printf(/* %s edo=%d */\n, timings-name, t.edo); + printf(.twp = %3d, .twh = %3d, .twc = %3d, .twsetup = %d,\n, + t.twp, t.twh, t.twc, t.twsetup); + printf(.trp = %3d, .treh = %3d, .trc = %3d, .trsetup = %d,\n, + t.trp, t.treh, t.trc, t.trsetup); + printf(.twhr = %d, .tceh = %d, .bta = %d, .tbusy = %d, .edo = %d,\n, + t.twhr, t.tceh, t.bta, t.tbusy, t.edo); + printf(},\n); +#endif + +static struct reduced_onfi nand_timing[] = +{ + { + /* onfi mode 0 edo=0 */ + .twp = 50, .twh = 30, .twc = 100, .twsetup = 20, + .trp = 50, .treh = 30, .trc = 100, .trsetup = 60, + .twhr = 120, .tceh = 0, .bta = 200, .tbusy = 39, .edo = 0, + }, + { + /* onfi mode 1 edo=0 */ + .twp = 25, .twh = 15, .twc = 45, .twsetup = 10, + .trp = 30, .treh = 15, .trc = 50, .trsetup = 15, + .twhr = 80, .tceh = 0, .bta = 100, .tbusy = 20, .edo = 0, + }, + { + /* onfi mode 2 edo=0 */ + .twp = 17, .twh = 15, .twc = 35, .twsetup = 8
[PATCH 3/3] omap nand : use onfi mode to compute optimized timings
If the platform data give us nand timings (in gpmc_t), we use them and not use onfi timings. Tested on omap 3630 (with onfi flash and mode {2, 4 , 5}) Signed-off-by: Matthieu CASTET matthieu.cas...@parrot.com --- drivers/mtd/nand/omap2.c | 134 ++ 1 file changed, 134 insertions(+) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 618cf42..6c45c59 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -29,6 +29,7 @@ #include plat/dma.h #include plat/gpmc.h +#include plat/cpu.h #include linux/platform_data/mtd-nand-omap2.h #defineDRIVER_NAME omap2-nand @@ -153,6 +154,8 @@ struct omap_nand_info { #endif }; +static int optim_rd, optim_wr; + /** * omap_prefetch_enable - configures and starts prefetch transfer * @cs: cs (chip select) number @@ -181,6 +184,13 @@ static int omap_prefetch_enable(int cs, int fifo_th, int dma_mode, val = ((cs PREFETCH_CONFIG1_CS_SHIFT) | PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH | (dma_mode DMA_MPU_MODE_SHIFT) | (0x1 is_write)); + if (is_write) { + if (optim_wr) + val |= (1 27) /* ENABLEOPTIMIZEDACCESS */| (optim_wr 28); + } else { + if (optim_rd) + val |= (1 27) /* ENABLEOPTIMIZEDACCESS */| (optim_rd 28); + } writel(val, info-reg.gpmc_prefetch_config1); /* Start the prefetch engine */ @@ -1239,6 +1249,122 @@ static void omap3_free_bch(struct mtd_info *mtd) } #endif /* CONFIG_MTD_NAND_OMAP_BCH */ +/* Update hardware configuration after device geometry has been queried */ +static int omap_onfi_set(struct mtd_info* mtd, int mode) +{ + struct omap_nand_info *info = container_of(mtd, + struct omap_nand_info, mtd); + +const struct reduced_onfi *tn = nand_get_timing(mode, 1); + int tmp; + struct gpmc_timings t; + + pr_info(omap nand : setting onfi mode %d\n, mode); + + + /* only tested on 3630 */ + if (!cpu_is_omap3630()) { + /* wr_access is shared with access */ + return -EINVAL; + } + + memset(t, 0, sizeof(t)); + + /* all signal start at the same time : + we could delay nRE, nWE, but this won't + work with prefetcher optimisation... +*/ + + t.cs_on = 0; + t.adv_on = 0; + t.oe_on = 0; + t.we_on = 0; + + tmp = gpmc_round_ns_to_ticks(tn-twp); + /* nCS low to nWE high */ + t.we_off = gpmc_round_ns_to_ticks(tn-twsetup) + tmp; + + /* nCS low to end */ + t.wr_cycle = t.we_off + max((int)tn-twh, tn-twc - tmp); + + /* BCH need 4 cycles */ + if (gpmc_ns_to_ticks(t.wr_cycle) 4) + t.wr_cycle = gpmc_ticks_to_ns(4); + else if (gpmc_ns_to_ticks(t.wr_cycle) 0x1f) + t.wr_cycle = gpmc_ticks_to_ns(0x1f); + + t.cs_wr_off = t.wr_cycle; + t.adv_wr_off = t.wr_cycle; + t.wr_access = t.we_off; + + tmp = gpmc_round_ns_to_ticks(tn-trp); + /* nCS low to nRE high */ + t.oe_off = gpmc_round_ns_to_ticks(tn-trsetup) + tmp; + + /* nCS low to end */ + t.rd_cycle = t.oe_off + max((int)tn-treh, tn-trc - tmp);; + + /* BCH need 4 cycles */ + if (gpmc_ns_to_ticks(t.rd_cycle) 4) + t.rd_cycle = gpmc_ticks_to_ns(4); + else if (gpmc_ns_to_ticks(t.rd_cycle) 0x1f) + t.rd_cycle = gpmc_ticks_to_ns(0x1f); + + t.cs_rd_off = t.rd_cycle; + t.adv_rd_off = t.rd_cycle; /* not used */ + if (tn-edo) + t.access = t.rd_cycle; + else + t.access = t.oe_off; + + t.page_burst_access = 0; /* not used */ + t.wr_data_mux_bus = 0; /* not used not in MUXADDDATA mode */ + + /* we often overflow here ... */ + tmp = gpmc_ns_to_ticks(tn-bta); + if (tmp 0xf) + tmp = 0xf; + t.busturnaround = gpmc_ticks_to_ns(tmp); + + tmp = gpmc_ns_to_ticks(tn-twhr); + if (tmp 0xf) + tmp = 0xf; + t.cycle2cycledelay = gpmc_ticks_to_ns(tmp); + + /* + XXX tbusy is not configurable + trm is not clear how much the gpmc wait between WAIT high and read. + But the linux driver doesn't use SYNCHROMODE in GPMC_PREFETCH_CONFIG1, + so we should be safe +*/ + pr_debug(nand timings\n); + pr_debug(oe_off=%d, rd_cycle=%d\n, t.oe_off, t.rd_cycle); + pr_debug(we_off=%d, wr_cycle=%d\n, t.we_off, t.wr_cycle); + + /* make sure timming register got sane default */ + gpmc_cs_write_reg(info-gpmc_cs, GPMC_CS_CONFIG2, 0); + gpmc_cs_write_reg(info-gpmc_cs, GPMC_CS_CONFIG3, 0); + gpmc_cs_write_reg(info-gpmc_cs, GPMC_CS_CONFIG4, 0); + gpmc_cs_write_reg(info-gpmc_cs, GPMC_CS_CONFIG5, 0); + gpmc_cs_write_reg(info-gpmc_cs, GPMC_CS_CONFIG6
[PATCH 1/3] omap gpmc : add support of setting CYCLE2CYCLEDELAY and BUSTURNAROUND
Signed-off-by: Matthieu CASTET matthieu.cas...@parrot.com --- arch/arm/mach-omap2/gpmc.c |7 ++- arch/arm/plat-omap/include/plat/gpmc.h |2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 8ab1e1b..3957ffc 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -333,8 +333,13 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) if (gpmc_capability GPMC_HAS_WR_DATA_MUX_BUS) GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus); - if (gpmc_capability GPMC_HAS_WR_ACCESS) + if (gpmc_capability GPMC_HAS_WR_ACCESS) { + /* XXX check on which hardware it is supported */ + GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, busturnaround); + GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycledelay); + GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access); + } /* caller is expected to have initialized CONFIG1 to cover * at least sync vs async diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 2e6e259..34ca454 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -131,6 +131,8 @@ struct gpmc_timings { /* The following are only on OMAP3430 */ u16 wr_access; /* WRACCESSTIME */ u16 wr_data_mux_bus;/* WRDATAONADMUXBUS */ + u16 cycle2cycledelay; /* CYCLE2CYCLEDELAY */ + u16 busturnaround; /* BUSTURNAROUND */ }; struct gpmc_nand_regs { -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] omap3 nand : use NAND_BUSWIDTH_AUTO
Igor Grinberg a écrit : Cc: Tony Lindgren, Afzal Mohammed, On 11/06/12 12:51, Matthieu CASTET wrote: This allow to clean the omap nand driver that were trying in x8 and x16 bits mode. This also make work onfi detection on beagleboard : Before : [1.954803] NAND device: Manufacturer ID: 0x2c, Chip ID: 0xba (Micron NAND 256MiB 1,8V 16-bit), page size: 2048, OOB size: 64 After : [1.914825] ONFI param page 0 valid [1.919158] ONFI flash detected [1.922515] NAND device: Manufacturer ID: 0x2c, Chip ID: 0xba (Micron MT29F2G16ABD), page size: 2048, OOB size: 64 platform data devsize is renamed bussize. It now indicate the maximun size of the nand bus. Signed-off-by: Matthieu CASTET matthieu.cas...@parrot.com I think, you should base on one of Tony's branches with that kind of patches. Because, for example the omap_nand_flash_init() function does not exist anymore in Tony's master and may be several more things will need to have adjustments. Also, the GPMC related stuff inside the NAND driver should probably be coordinated with Afzal, as he is reworking the whole GPMC related code. Thanks for the info. Where such tree could be found ? Matthieu -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] omap gpmc : add support of setting CYCLE2CYCLEDELAY and BUSTURNAROUND
Jon Hunter a écrit : On 11/06/2012 10:44 AM, Matthieu CASTET wrote: /* caller is expected to have initialized CONFIG1 to cover * at least sync vs async diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 2e6e259..34ca454 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -131,6 +131,8 @@ struct gpmc_timings { /* The following are only on OMAP3430 */ u16 wr_access; /* WRACCESSTIME */ u16 wr_data_mux_bus;/* WRDATAONADMUXBUS */ +u16 cycle2cycledelay; /* CYCLE2CYCLEDELAY */ +u16 busturnaround; /* BUSTURNAROUND */ So you should be able to move these out of OMAP3430 specific as they are generic. Thanks for the quick review. I will post another patch, unless this is already done in Afzal patch (Is there a tree where I can get Afzal pending patches ?) Matthieu -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Spurious ECC errors with mtd_subpagetest (OMAP3, NAND)
Hi, Orjan Friberg a écrit : On 03/02/2012 06:17 PM, Grazvydas Ignotas wrote: IIRC NAND in mainline was broken for very long time on OMAP3, I think it was only fixed in 2.6.39.1. That seems to be the case; the 2.6.39.1 diff contains the OMAP NAND sub page write fix (applied locally). Note that the omap driver is still broken : http://article.gmane.org/gmane.linux.drivers.mtd/36079/match= We detected this when stressing a board. Because all of these bugs in omap driver, I wonder how many people really use the mainline version. Also if you use a nand that need 4-bit ECC, you need a better ecc than hamming. You can use the bch code ( http://article.gmane.org/gmane.linux.drivers.mtd/37864/match=omap ) Matthieu PS : why omap driver use in omap_dev_ready GPMC*IRQ_STATUS instead of GPMC_STATUS. PS2 : ecc hamming look strange. Weird isEccFF code. Doesn't seem to handle bit flip in ecc. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] Change ECC algorithm from userspace
Hi, Javier Martinez Canillas a écrit : Hello, I want to be able to use 1-bit ECC for the first partition where I save the loader binary and has to be accessed by the ROM boot but use a 4-bit ECC for my rootfs partition. Does anyone have this same issue? We use raw programming and compute the ecc in software. What is the best approach to store data in a NAND device using different ECC techniques? I've think of two approaches: 1- Adding an ioctl to mtdchar (something like ECCSETBITS) to change the ECC technique used. But this won't work if there is concurrent acess to mtd. One program may want 1 bit ecc other want 4 bits ecc. 2- Use a platform data field to notify the omap2 nand driver that the ROM boot only supports 1-bit ECC. So it can use a 1-bit ECC to write and read the first 4 sectors but a 4-bit ECC for the rest. This may be better. Matthieu PS : note that some OMAP ROM support a better protection than Hamming (but the details are not public AFAIK) From OMAP34xx Multimedia Device, Silicon Revision 3.1.x, public version : Pages can contain errors caused by memory alteration. To correct these errors, the ROM code uses ECC, based on Hamming codes for SLC NAND and BCH (Bose, Ray-Chaudhuri, Hocquenghem) code for multilevel cell (MLC) devices. The computed ECC is compared to ECC stored in the spare area of the corresponding page. If there are uncorrectable errors, the ROM code returns with FAIL. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] Change ECC algorithm from userspace
Jon Povey a écrit : linux-mtd-boun...@lists.infradead.org wrote: I want to be able to use 1-bit ECC for the first partition where I save the loader binary and has to be accessed by the ROM boot but use a 4-bit ECC for my rootfs partition. Does anyone have this same issue? DM355 and DM365 has similar issues as the RBL expects a different OOB/ECC layout to Linux. What is the best approach to store data in a NAND device using different ECC techniques? What I have done is write a utility that calculates ECC and writes to the mtd device in RAW mode. So to rewrite the bootloader I take care of the ECC and layout at application level without changing the kernel. Note that the kernel raw mode doesn't write the page in one time : it write data and then ecc. This may cause problem with NOP1 nand. see http://lists.infradead.org/pipermail/linux-mtd/2010-August/031262.html Matthieu -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] Change ECC algorithm from userspace
Javier Martinez Canillas a écrit : On Fri, Oct 28, 2011 at 12:30 PM, Matthieu CASTET matthieu.cas...@parrot.com wrote: PS : note that some OMAP ROM support a better protection than Hamming (but the details are not public AFAIK) From OMAP34xx Multimedia Device, Silicon Revision 3.1.x, public version : Pages can contain errors caused by memory alteration. To correct these errors, the ROM code uses ECC, based on Hamming codes for SLC NAND and BCH (Bose, Ray-Chaudhuri, Hocquenghem) code for multilevel cell (MLC) devices. The computed ECC is compared to ECC stored in the spare area of the corresponding page. If there are uncorrectable errors, the ROM code returns with FAIL. Yes I've read that on the DM3730 TRM but as far as I understand only applies to MLC devices, but ours is SLC. It also works on SLC devices. We are using it on micron slc that need 4 bits ECC. Matthieu -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/2] omap_twl: Prevent SR to enable for am3517/am3505 devices
Abhilash K V a écrit : From: Vaibhav Hiremath hvaib...@ti.com In case of AM3517 AM3505, Smart Reflex is not applicable so we must not enable it. So add check for absence of SR feature in omap3_twl_init() and return -ENODEV if absence, else continue. I believe another check should be done : you have the same problem if you run a omap3630 with TPS65023. The check should take in account the pmu that is used and if it support SR. Matthieu Signed-off-by: Vaibhav Hiremath hvaib...@ti.com Signed-off-by: Abhilash K V abhilash...@ti.com --- arch/arm/mach-omap2/id.c |2 +- arch/arm/mach-omap2/omap_twl.c|8 arch/arm/plat-omap/include/plat/cpu.h |2 ++ 3 files changed, 11 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 37efb86..da71098 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -202,7 +202,7 @@ static void __init omap3_check_features(void) if (cpu_is_omap3630()) omap_features |= OMAP3_HAS_192MHZ_CLK; if (!cpu_is_omap3505() !cpu_is_omap3517()) - omap_features |= OMAP3_HAS_IO_WAKEUP; + omap_features |= (OMAP3_HAS_IO_WAKEUP | OMAP3_HAS_SR); omap_features |= OMAP3_HAS_SDRC; diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c index 07d6140..47e27b5 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c @@ -269,6 +269,14 @@ int __init omap3_twl_init(void) if (!cpu_is_omap34xx()) return -ENODEV; + /* + * In case of AM3517/AM3505 we should not be going down + * further, since SR is not applicable there. + */ + if (!omap3_has_sr()) { + return -ENODEV; + } + if (cpu_is_omap3630()) { omap3_mpu_volt_info.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN; omap3_mpu_volt_info.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX; diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 67b3d75..294e015 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -491,6 +491,7 @@ extern u32 omap_features; #define OMAP4_HAS_MPU_1GHZ BIT(8) #define OMAP4_HAS_MPU_1_2GHZ BIT(9) #define OMAP4_HAS_MPU_1_5GHZ BIT(10) +#define OMAP3_HAS_SR BIT(11) #define OMAP3_HAS_FEATURE(feat,flag) \ @@ -507,6 +508,7 @@ OMAP3_HAS_FEATURE(isp, ISP) OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) OMAP3_HAS_FEATURE(sdrc, SDRC) +OMAP3_HAS_FEATURE(sr, SR) /* * Runtime detection of OMAP4 features -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] MUSB: Workaround for Ethernet data alignment issue
Matthieu CASTET a écrit : Hi, Patra, Nilkesh a écrit : On the latest version of MUSB, DMA is not working properly if the Data in the packet doesn't start at 32bit aligned address. This issue was found while using MUSB as g_ether. The basic ping does not work, if the data in the Ethernet packet does not start at 32bit aligned address. To overcome this issue, we found one solution mentioned in the below patch. This patch moves data (skb-data) by 2 bytes backwards in ethernet packet, which is nothing but skb-head. I want to know, if there are any better approaches to fix this issue. What dma_mask are you using ? From what I understand, dma_map_single will use it to know if the dma buffer need to be aligned [1]. So you need to set the last 2 bits to 0 and it should do everything for you. Forget what I said it is only true in CONFIG_DMABOUNCE case... -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] MUSB: Workaround for Ethernet data alignment issue
Hi, Patra, Nilkesh a écrit : On the latest version of MUSB, DMA is not working properly if the Data in the packet doesn't start at 32bit aligned address. This issue was found while using MUSB as g_ether. The basic ping does not work, if the data in the Ethernet packet does not start at 32bit aligned address. To overcome this issue, we found one solution mentioned in the below patch. This patch moves data (skb-data) by 2 bytes backwards in ethernet packet, which is nothing but skb-head. I want to know, if there are any better approaches to fix this issue. What dma_mask are you using ? From what I understand, dma_map_single will use it to know if the dma buffer need to be aligned [1]. So you need to set the last 2 bits to 0 and it should do everything for you. Matthieu [1] /* * Figure out if we need to bounce from the DMA mask. */ needs_bounce = (dma_addr | (dma_addr + size - 1)) ~mask; } if (device_info (needs_bounce || dma_needs_bounce(dev, dma_addr, size))) { struct safe_buffer *buf; buf = alloc_safe_buffer(device_info, ptr, size, dir); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html