AnsweredAssumed Answered

MT29F16G08ABABA NAND flash on BF337 arch.

Question asked by jrc903 on Feb 15, 2012
Latest reply on Feb 21, 2012 by Aaronwu

Blackfin bf336 NAND FLASH ECC Linux 2.6.x

 

Hi: I am new here, so if this is somehow not the right place for this please let me know.

 

At any rate: We are attempting to configure the kernel on our bf 337-stamp derived board to handle the MT29F16G08ABABA NAND (16gb) flash from Micron. We believe we have low level functions as proven sing tools like nand_test etc.My primary question is is there anyone who has experience setting this particular chip up on the blackfin BF337 architecture. As I said, we think we have been able to write and read from the chip but the ECC stuff is killing us at this point. We think we may have even given gotten the chip into a mode where the ECC is out of sync permanently with reality.. Any help or suggestions on this perplexing problem would most certainly be appreciated.

 

What follows is as much of the code and setup information as i could get on this page.

 

I have done the usual things regarding setting up the board configuration file..

 

#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)

#define DEFAULT_SIZE 0x80000000

static struct mtd_partition bfin_plat_nand_partitions[] = {

 

        {

        .name   = "file system(nand)",

        .size   =  MTDPART_SIZ_FULL,

        .offset = 0,       

 

    },

 

};

 

static void bfin_plat_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)

{

 

    struct nand_chip *this = mtd->priv;

 

    if (cmd == NAND_CMD_NONE)

    return;

 

    if (ctrl & NAND_CLE)

        writeb(cmd, this->IO_ADDR_W + (1 << BFIN_NAND_PLAT_CLE));

    else

        writeb(cmd, this->IO_ADDR_W + (1 << BFIN_NAND_PLAT_ALE));

 

 

}

 

static int bfin_plat_nand_dev_ready(struct mtd_info *mtd)

{

 

    return gpio_get_value(BFIN_NAND_PLAT_READY);

 

}

 

const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };

 

static struct platform_nand_data bfin_plat_nand_data = {

    .chip = {

        .nr_chips = 1,

        .chip_delay = 40,// was 30

        .part_probe_types = part_probes,

        .partitions = bfin_plat_nand_partitions,

        .nr_partitions = ARRAY_SIZE(bfin_plat_nand_partitions),   

    },

    .ctrl = {

        .cmd_ctrl = bfin_plat_nand_cmd_ctrl,

        .dev_ready = bfin_plat_nand_dev_ready,

    },

 

 

};

 

//static void bfin_plat_nand_select_chip(struct mtd_info *mtd, int chip)

//{

 

//}

 

static struct resource bfin_plat_nand_resources[] = {

    {

        .start = 0x20300000,

        .end =   0x20300000 + 4,

        .flags = IORESOURCE_MEM,

    },

};

 

static struct  platform_device bfin_async_nand_device = {

    .name = "gen_nand",

    .id = -1,

    .num_resources = 1,

    .resource = &bfin_plat_nand_resources[0],

    .dev = {

        .platform_data = &bfin_plat_nand_data,

    },

 

 

 

};

 

static void bfin_plat_nand_init(void)

{

    gpio_request(BFIN_NAND_PLAT_READY, "bfin_nand_plat");

 

}

 

As an added issue. When I first ran this kernel is blew up on a kernel exception in the nand_base.c file.  Basically complaining that it did not

have provisions for 224 bytes of ECC. So.. I found this example and tired both of them for struct nand_ecclayout.. Currently using the first one.

 

static struct nand_ecclayout nand_oob_224 = {

    .eccbytes    = 104,

    .eccpos        = {

         120,   121,   122,   123,   124,   125,   126,   127,   128,   129,  130,  131,  132,

         133,  134,  135,  136,  137,  138,  139,  140,  141,  142,  143,  144,  145,

         146,  147,  148,  149,  150,  151,  152,  153,  154,  155,  156,  157,  158,

         159,  160,  161,  162,  163,  164,  165,  166,  167,  168,  169,  170,  171,

         172,  173,  174,  175,  176,  177,  178,  179, 180,  181,  182,  183,  184,

         185,  186,  187,  188,  189,  190,  191,  192,  193,  194,  195,  196,  197,

         198,  199,  200,  201,  202,  203,  204,  205,  206,  207,  208,  209,  210,

         211,  212,  213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,

        },

    .oobavail    = 32,

    .oobfree    = {

        {91, 32},

    }

};

 

 

/*

static struct nand_ecclayout nand_oob_224 = {

    .eccbytes    = 104,

    .eccpos        = {

          0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,

         13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,

         26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,

         39,  40,  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,

         52,  53,  54,  55,  56,  57,  58,  59,     60,  61,  62,  63,  64,

         65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,

         78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,

        123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,

        },

    .oobavail    = 32,

    .oobfree    = {

        {91, 32},

    }

};

 

 

Indeed we have low level access to the chip using the NAND_TOOLS( nand_test) etc.  The device appears in  as /dev/mdt4 and /dev/mdtblock4.

 

Our particular problem is in getting the the kernel and the ecc on the chip to sync.  

 

 

 

 

 

Kernel Config as follows

 

The kernel configuration is as follows:

 

 

 

 

 

Outcomes