Skip to content

Commit 73f907f

Browse files
author
Boris Brezillon
committed
mtd: nand: Fix data interface configuration logic
When changing from one data interface setting to another, one has to ensure a specific sequence which is described in the ONFI spec. One of these constraints is that the CE line has go high after a reset before a command can be sent with the new data interface setting, which is not guaranteed by the current implementation. Rework the nand_reset() function and all the call sites to make sure the CE line is asserted and released when required. Also make sure to actually apply the new data interface setting on the first die. Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Fixes: d8e725d ("mtd: nand: automate NAND timings selection") Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de> Tested-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
1 parent ce93bed commit 73f907f

2 files changed

Lines changed: 43 additions & 19 deletions

File tree

drivers/mtd/nand/nand_base.c

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,10 +1095,11 @@ static void nand_release_data_interface(struct nand_chip *chip)
10951095
/**
10961096
* nand_reset - Reset and initialize a NAND device
10971097
* @chip: The NAND chip
1098+
* @chipnr: Internal die id
10981099
*
10991100
* Returns 0 for success or negative error code otherwise
11001101
*/
1101-
int nand_reset(struct nand_chip *chip)
1102+
int nand_reset(struct nand_chip *chip, int chipnr)
11021103
{
11031104
struct mtd_info *mtd = nand_to_mtd(chip);
11041105
int ret;
@@ -1107,9 +1108,17 @@ int nand_reset(struct nand_chip *chip)
11071108
if (ret)
11081109
return ret;
11091110

1111+
/*
1112+
* The CS line has to be released before we can apply the new NAND
1113+
* interface settings, hence this weird ->select_chip() dance.
1114+
*/
1115+
chip->select_chip(mtd, chipnr);
11101116
chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
1117+
chip->select_chip(mtd, -1);
11111118

1119+
chip->select_chip(mtd, chipnr);
11121120
ret = nand_setup_data_interface(chip);
1121+
chip->select_chip(mtd, -1);
11131122
if (ret)
11141123
return ret;
11151124

@@ -1185,16 +1194,16 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
11851194
/* Shift to get chip number */
11861195
chipnr = ofs >> chip->chip_shift;
11871196

1188-
chip->select_chip(mtd, chipnr);
1189-
11901197
/*
11911198
* Reset the chip.
11921199
* If we want to check the WP through READ STATUS and check the bit 7
11931200
* we must reset the chip
11941201
* some operation can also clear the bit 7 of status register
11951202
* eg. erase/program a locked block
11961203
*/
1197-
nand_reset(chip);
1204+
nand_reset(chip, chipnr);
1205+
1206+
chip->select_chip(mtd, chipnr);
11981207

11991208
/* Check, if it is write protected */
12001209
if (nand_check_wp(mtd)) {
@@ -1244,16 +1253,16 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
12441253
/* Shift to get chip number */
12451254
chipnr = ofs >> chip->chip_shift;
12461255

1247-
chip->select_chip(mtd, chipnr);
1248-
12491256
/*
12501257
* Reset the chip.
12511258
* If we want to check the WP through READ STATUS and check the bit 7
12521259
* we must reset the chip
12531260
* some operation can also clear the bit 7 of status register
12541261
* eg. erase/program a locked block
12551262
*/
1256-
nand_reset(chip);
1263+
nand_reset(chip, chipnr);
1264+
1265+
chip->select_chip(mtd, chipnr);
12571266

12581267
/* Check, if it is write protected */
12591268
if (nand_check_wp(mtd)) {
@@ -2940,18 +2949,19 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
29402949
}
29412950

29422951
chipnr = (int)(to >> chip->chip_shift);
2943-
chip->select_chip(mtd, chipnr);
2944-
2945-
/* Shift to get page */
2946-
page = (int)(to >> chip->page_shift);
29472952

29482953
/*
29492954
* Reset the chip. Some chips (like the Toshiba TC5832DC found in one
29502955
* of my DiskOnChip 2000 test units) will clear the whole data page too
29512956
* if we don't do this. I have no clue why, but I seem to have 'fixed'
29522957
* it in the doc2000 driver in August 1999. dwmw2.
29532958
*/
2954-
nand_reset(chip);
2959+
nand_reset(chip, chipnr);
2960+
2961+
chip->select_chip(mtd, chipnr);
2962+
2963+
/* Shift to get page */
2964+
page = (int)(to >> chip->page_shift);
29552965

29562966
/* Check, if it is write protected */
29572967
if (nand_check_wp(mtd)) {
@@ -3984,14 +3994,14 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
39843994
int i, maf_idx;
39853995
u8 id_data[8];
39863996

3987-
/* Select the device */
3988-
chip->select_chip(mtd, 0);
3989-
39903997
/*
39913998
* Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
39923999
* after power-up.
39934000
*/
3994-
nand_reset(chip);
4001+
nand_reset(chip, 0);
4002+
4003+
/* Select the device */
4004+
chip->select_chip(mtd, 0);
39954005

39964006
/* Send the command for reading device ID */
39974007
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
@@ -4329,17 +4339,31 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
43294339
return PTR_ERR(type);
43304340
}
43314341

4342+
/* Initialize the ->data_interface field. */
43324343
ret = nand_init_data_interface(chip);
43334344
if (ret)
43344345
return ret;
43354346

4347+
/*
4348+
* Setup the data interface correctly on the chip and controller side.
4349+
* This explicit call to nand_setup_data_interface() is only required
4350+
* for the first die, because nand_reset() has been called before
4351+
* ->data_interface and ->default_onfi_timing_mode were set.
4352+
* For the other dies, nand_reset() will automatically switch to the
4353+
* best mode for us.
4354+
*/
4355+
ret = nand_setup_data_interface(chip);
4356+
if (ret)
4357+
return ret;
4358+
43364359
chip->select_chip(mtd, -1);
43374360

43384361
/* Check for a chip array */
43394362
for (i = 1; i < maxchips; i++) {
4340-
chip->select_chip(mtd, i);
43414363
/* See comment in nand_get_flash_type for reset */
4342-
nand_reset(chip);
4364+
nand_reset(chip, i);
4365+
4366+
chip->select_chip(mtd, i);
43434367
/* Send the command for reading device ID */
43444368
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
43454369
/* Read manufacturer and device IDs */

include/linux/mtd/nand.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1184,7 +1184,7 @@ int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
11841184
int page);
11851185

11861186
/* Reset and initialize a NAND device */
1187-
int nand_reset(struct nand_chip *chip);
1187+
int nand_reset(struct nand_chip *chip, int chipnr);
11881188

11891189
/* Free resources held by the NAND device */
11901190
void nand_cleanup(struct nand_chip *chip);

0 commit comments

Comments
 (0)