BSP 3.10.53 support two NAND chip or Device?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

BSP 3.10.53 support two NAND chip or Device?

906 Views
eugenevolkov
Contributor IV

Hi, all.

I need You help! In my custom board i use two NAND. But, i can not change u-boot, and kernel, to get them working.

1 I change DTS file.

...

MX6QDL_PAD_NANDF_CS0__NAND_CE0_B   0xb0b1

MX6QDL_PAD_NANDF_CS2__NAND_CE2_B   0xb0b1

...

2 I add in nand_ids chip ID list in u- boot

{
"NAND 128MiB 3,3V 8-bit",0xf1, 2048, 128, 0x10000, 0},/* S34ML01G1 */

}

and in linux

{"S34ML01G100TFI00 1G 3.3V 8-bit", { .id = {0x01, 0xF1, 0x00, 0x1D} }, SZ_2K, SZ_128, SZ_128K, 0, 8, 64, NAND_ECC_INFO(1, SZ_512) },

3

in u-boot bard config i set SYS_MAX_NAND_DEVICE 2

I also tried  SYS_MAX_NAND_СHIP to 2

and combinations thereof

But this not work.

In u-boot, use command nand info i see when

Device 0: nand0, sector size 64 KiB

  Page size      2048 b

  OOB size         64 b

  Erase size    65536 b

Device 1: nand1, sector size 64 KiB

  Page size      2048 b

  OOB size         64 b

  Erase size    65536 b

I can set nand device 1, but when i read nand, use nand dump  - in osciloscope i see, that is always used NAND_CE0.

In kernel

......

nand: device found, Manufacturer ID: 0x01, Chip ID: 0xf1

nand: AMD/Spansion S34ML01G100TFI00 1G 3.3V 8-bit

nand: 128MiB, SLC, page size: 2048, OOB size: 64

Bad block table found at page 65472, version 0x01

Bad block table found at page 65408, version 0x01

gpmi-nand 112000.gpmi-nand: driver registered.

.

root@imx6solosabreauto:~# cat /proc/mtd

dev:    size   erasesize  name

mtd0: 08000000 00020000 "gpmi-nand"

Linux registered one NAND.

I began to look for the cause in the driver.

Function gpmi_nand_init     call  nand_scan_ident(mtd, GPMI_IS_MX6(this) ? 2 : 1, NULL).


In this  function, code that scan chip

/* Check for a chip array */

  for (i = 1; i < maxchips; i++) {

            chip->select_chip(mtd, i);

           /* See comment in nand_get_flash_type for reset */

            chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);

            /* Send the command for reading device ID */

            chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);

            /* Read manufacturer and device IDs */

            if (nand_maf_id != chip->read_byte(mtd) ||

               nand_dev_id != chip->read_byte(mtd)) {

                      chip->select_chip(mtd, -1);

                      break;

  }

select_chip(mtd, i) - should set CEn(CE0,CE1,CE2) in low level. Then it would be all worked fine.


But, this function not work do not do this


/**

* nand_select_chip - [DEFAULT] control CE line

* @mtd: MTD device structure

* @chipnr: chipnumber to select, -1 for deselect

*

* Default select function for 1 chip devices.

*/

static void nand_select_chip(struct mtd_info *mtd, int chipnr)

{

  struct nand_chip *chip = mtd->priv;

  switch (chipnr) {

       case -1:

                 chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);

                 break;

       case 0:

                 break;

       default:

                 BUG();

  }

}


It stopped me. I do not know how to write cmd_ctrl function, that set CE2 to low level. 

Maybe I'm wrong and this code is working, but I can not achieve that would choose, any other chip select.

Labels (1)
3 Replies

550 Views
eugenevolkov
Contributor IV

Hi, i continue to further understand the reason. About the functions select_chip of my judgments were wrong. It seems that this function is reloaded with another function that correctly sets the CSn.

Another problem seems to code:

  for (i = 1; i < maxchips; i++) {

            chip->select_chip(mtd, i);

           /* See comment in nand_get_flash_type for reset */

            chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);

            /* Send the command for reading device ID */

            chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);

            /* Read manufacturer and device IDs */

            if (nand_maf_id != chip->read_byte(mtd) ||

               nand_dev_id != chip->read_byte(mtd)) {

                      chip->select_chip(mtd, -1);

                      break;

  }


Implementation of this code is interrupted at the first reading failed NAND.

Thus, if two chips on the board are connected to e.g. CS0 and CS2, that chip is connected to CS2 is not identified.

How to fix it?

Waiting for suggestions from experts Freescale!

0 Kudos
Reply

550 Views
alejandrolozan1
NXP Employee
NXP Employee

Hi,

I am not an expert on this, but I just found this :

http://comments.gmane.org/gmane.linux.ports.arm.kernel/244738

I believe you may find it helpful. I have no tried it and we lack of a board that we can use to place two chips. I can try to get a chip with two dies and start working on this, but it may take a while.

Best Regards,

Alejandro

550 Views
eugenevolkov
Contributor IV

Hi, Alejandro.Thanks for your reply!

This path   has already been applied in the release 3.10.53. Moreover, some of the files in newer than в Patch.

The situation is the following - the driver is not designed to work with two NAND device, are connected to not in series

For example - the two devices connected to the CS0 and CS1, driver will work fine

But, the two devices connected to the CS0 and CS2, driver not work.

the reason why this is so - if I ask the address of the second chip, driver the driver tries to next device in CS1, but no in CS2.

0 Kudos
Reply